Annotation of rpm2html/sql.c, revision 1.29

1.1       veillard    1: /*
                      2:  * sql.c: front-end for MySQL database
                      3:  */
                      4: 
1.2       veillard    5: #include "config.h"
                      6: 
                      7: #include <stdio.h>
                      8: #include <stdlib.h>
                      9: #include <sys/types.h>
                     10: #include <sys/stat.h>
                     11: #ifdef HAVE_FCNTL_H
                     12: #include <fcntl.h>
                     13: #endif
1.1       veillard   14: #include <stdio.h>
                     15: #include <stdlib.h>
1.2       veillard   16: #include <string.h>
1.28      daniel     17: #include <time.h>
1.2       veillard   18: #ifdef HAVE_UNISTD_H
                     19: #include <unistd.h>
                     20: #endif
                     21: /********
                     22: #include <rpm/rpmlib.h>
                     23:  ********/
                     24: 
1.1       veillard   25: #include <mysql/mysql.h>
1.16      veillard   26: #include <mysql/errmsg.h>
1.2       veillard   27: #include "rpm2html.h"
1.26      veillard   28: #include "rpmdata.h"
1.2       veillard   29: /********
                     30: #include "rpmdata.h"
                     31:  ********/
1.1       veillard   32: #include "sql.h"
1.28      daniel     33: #include "html.h"
1.1       veillard   34: 
1.26      veillard   35: #define SQL_MAX_DISTRIBS 500
                     36: 
1.1       veillard   37: /************************************************************************
                     38:  *                                                                     *
                     39:  *             Generic inititialisation/close of the DB                *
                     40:  *                                                                     *
                     41:  ************************************************************************/
                     42: 
                     43: static MYSQL *sql = NULL;
1.16      veillard   44: static const char *myhost, *mybase, *myuser, *mypasswd;
1.1       veillard   45: 
1.11      veillard   46: int init_sql(const char *host, const char *base, const char *user, const char *passwd) {
1.16      veillard   47:     int attempts = 0;
                     48: 
                     49:     /*
                     50:      * Close the previous connection if any
                     51:      */
                     52:     if (sql != NULL) {
                     53:        close_sql();
                     54:        if (myhost != NULL) free((char *) myhost);
                     55:        myhost = NULL;
                     56:        if (mybase != NULL) free((char *) mybase);
                     57:        mybase = NULL;
                     58:        if (myuser != NULL) free((char *) myuser);
                     59:        myuser = NULL;
                     60:        if (mypasswd != NULL) free((char *) mypasswd);
                     61:        mypasswd = NULL;
                     62:     }
                     63: 
1.11      veillard   64:     if (host == NULL)
                     65:        host = getenv("MySQL_HOST");
                     66:     if (host == NULL)
                     67:        host = "localhost";
                     68:     if (base == NULL)
                     69:        base = getenv("MySQL_BASE");
1.1       veillard   70:     if (base == NULL)
                     71:        base = "rpmfind";
                     72:     if (passwd == NULL)
                     73:        passwd = getenv("MySQL_PASS");
                     74:     if (user == NULL)
                     75:        user = getenv("MySQL_USER");
                     76:     if (user == NULL)
                     77:        user = getenv("USER");
                     78:     if (user == NULL)
                     79:        user = getenv("USERNAME");
                     80:     if (user == NULL)
                     81:        user = getenv("LOGNAME");
                     82:     sql = mysql_init(NULL);
                     83:     if (mysql_errno(sql)) {
                     84:        fprintf(stderr, "mysql_init failed: %s\n", mysql_error(sql));
                     85:        return(-1);
                     86:     }
1.16      veillard   87:     for (attempts = 0; ;attempts ++) {
                     88:        mysql_real_connect(sql, host, user, passwd, base, 0, NULL, 0);
                     89:        if (mysql_errno(sql)) {
1.26      veillard   90:            if ((attempts == 0) && (passwd == NULL)) {
                     91:                fprintf(stderr, "No passwd defined, use MySQL_PASS env\n");
                     92:            }
1.16      veillard   93:            if (attempts >= 20) {
                     94:                fprintf(stderr,
                     95:                        "mysql: connect as %s to %s on host %s  failed: %s\n",
                     96:                        user, base, host, mysql_error(sql));
1.24      daniel     97:                return(-1);
                     98:            } else {
                     99:                fprintf(stderr,
                    100:                        "mysql: retrying connect as %s to %s on host %s  failed: %s\n",
                    101:                        user, base, host, mysql_error(sql));
1.16      veillard  102:            }
                    103:        } else {
                    104:            break;
                    105:        }
                    106:        sleep(15);
1.1       veillard  107:     }
1.16      veillard  108:     myhost = strdup(host);
                    109:     mybase = strdup(base);
                    110:     myuser = strdup(user);
                    111:     mypasswd = strdup(passwd);
1.2       veillard  112:     sql_check_tables();
1.1       veillard  113:     return(0);
                    114: }
                    115: 
                    116: int close_sql(void) {
                    117:     mysql_close(sql);
                    118:     if (mysql_errno(sql)) {
                    119:        fprintf(stderr, "mysql_close failed: %s\n", mysql_error(sql));
                    120:        return(-1);
                    121:     }
1.16      veillard  122:     sql = NULL;
1.1       veillard  123:     return(0);
                    124: }
                    125: 
1.16      veillard  126: int restart_sql(void) {
                    127:     int attempts = 0;
                    128: 
                    129:     /*
                    130:      * Close the previous connection if any
                    131:      */
                    132:     if (sql != NULL) {
                    133:        close_sql();
                    134:        sql = NULL;
                    135:     }
                    136: 
                    137:     sql = mysql_init(NULL);
                    138:     if (mysql_errno(sql)) {
                    139:        fprintf(stderr, "mysql_init failed: %s\n", mysql_error(sql));
                    140:        return(-1);
                    141:     }
                    142:     for (attempts = 0; ;attempts ++) {
                    143:        mysql_real_connect(sql, myhost, myuser, mypasswd, mybase, 0, NULL, 0);
                    144:        if (mysql_errno(sql)) {
                    145:            if (attempts >= 20) {
                    146:                fprintf(stderr,
                    147:                        "mysql: reconnect as %s to %s on host %s  failed: %s\n",
                    148:                        myuser, mybase, myhost, mysql_error(sql));
                    149:            return(-1);
                    150:            }
                    151:        } else {
                    152:            break;
                    153:        }
                    154:        sleep(15);
                    155:     }
                    156:     sql_check_tables();
                    157:     return(0);
                    158: }
                    159: 
                    160: /*
                    161:  * Handle disconnects by doing a reconnect and a retry.
                    162:  */
                    163: int do_sql_query(const char *query, int len) {
                    164:     int res;
                    165: 
                    166:     if (sql == NULL) {
                    167:        res = restart_sql();
                    168:        if (res != 0)
                    169:            return(res);
                    170:     }
                    171:     res = mysql_real_query(sql, query, len);
1.19      daniel    172:     if ((res == CR_SERVER_GONE_ERROR) || (res == CR_SERVER_LOST)) {
1.16      veillard  173:        res = restart_sql();
                    174:        if (res != 0)
                    175:            return(res);
                    176:        res = mysql_real_query(sql, query, len);
                    177:     }
                    178:     return(res);
                    179: }
                    180: 
1.1       veillard  181: /************************************************************************
                    182:  *                                                                     *
                    183:  *             Generic functions to access the tables                  *
                    184:  *                                                                     *
                    185:  ************************************************************************/
                    186: 
1.6       veillard  187: #define MAX_QUERY 8000
                    188: #define SMALL_QUERY 500
1.1       veillard  189: 
                    190: int sql_update_id(const char *table, int id,
                    191:                  const char *field, const char *value) {
                    192:     MYSQL_RES *result;
1.6       veillard  193:     char query[MAX_QUERY];
1.1       veillard  194:     int nb_fields = 0;
1.6       veillard  195:     int left = MAX_QUERY - 1;
                    196:     int len;
                    197:     char *end;
1.1       veillard  198: 
                    199:     if ((table == NULL) ||
                    200:        (field == NULL) || (value == NULL))
                    201:        return(-1);
                    202: 
1.6       veillard  203:     len = snprintf(query, left, "UPDATE %s SET %s='", table, field);
                    204:     if (len < 0) {
                    205:        fprintf(stderr, "sql_update_id : %s(%d).%s overflow\n",
                    206:                table, id, field);
                    207:        return(-1);
                    208:     }
                    209:     end = &query[len];
                    210:     left -= len;
                    211:     len = strlen(value);
                    212:     if (len * 2 >= left) {
                    213:        fprintf(stderr, "sql_update_id : %s(%d).%s overflow\n",
                    214:                table, id, field);
                    215:        return(-1);
                    216:     }
                    217:     len = mysql_escape_string(end, value, len);
                    218:     left -= len;
                    219:     if (left <= 0) {
                    220:        fprintf(stderr, "sql_update_id : %s(%d).%s overflow\n",
                    221:                table, id, field);
                    222:        return(-1);
                    223:     }
                    224:     end += len;
                    225:     len = snprintf(end, left, "' WHERE ID=%d", id);
                    226:     if (len < 0) {
                    227:        fprintf(stderr, "sql_update_id : %s(%d).%s overflow\n",
                    228:                table, id, field);
                    229:        return(-1);
                    230:     }
                    231:     end += len;
                    232:     query[MAX_QUERY - 1] = 0;
                    233: 
1.16      veillard  234:     if (do_sql_query(query, (unsigned int) (end - query))) {
1.1       veillard  235:        printf("sql_update_id: UPDATE %s %d failed: %s\n",
                    236:               table, id, mysql_error(sql));
                    237:        return(-1);
                    238:     }
                    239:     result = mysql_store_result(sql);
                    240:     if (result != NULL) {
                    241:        nb_fields = mysql_num_fields(result);
                    242:        mysql_free_result(result);
                    243:     } else {
                    244:        nb_fields = 1;
                    245:     }
                    246:     if(mysql_errno(sql)) {
                    247:        fprintf(stderr, "sql_update_id UPDATE error: %s\n",
                    248:                 mysql_error(sql));
                    249:        return(-1);
                    250:     }
                    251:     return(nb_fields);
                    252: }
                    253: 
                    254: int sql_blind_insert(const char *table, const char *key,
                    255:                      const char *value, int id) {
                    256:     MYSQL_RES *result;
1.6       veillard  257:     char query[MAX_QUERY];
                    258:     int left = MAX_QUERY - 1;
                    259:     int len;
                    260:     char *end;
1.8       veillard  261:     int insert = -1;
1.1       veillard  262: 
1.2       veillard  263:     if ((table == NULL) ||
1.1       veillard  264:        (key == NULL) || (value == NULL))
                    265:        return(-1);
                    266: 
                    267:     /*
                    268:      * Search first for the ID if it already exists
                    269:      */
1.2       veillard  270:     if (id > 0) {
1.6       veillard  271:        len = snprintf(query, left, "INSERT INTO %s (ID, %s) VALUES (%d, '",
                    272:                       table, key, id);
                    273:        if (len < 0) {
                    274:            fprintf(stderr, "sql_blind_insert : %s(%d).%s overflow\n",
                    275:                    table, id, key);
                    276:            return(-1);
                    277:        }
                    278:        end = &query[len];
                    279:        left -= len;
                    280:        len = strlen(value);
                    281:        if (len * 2 >= left) {
                    282:            fprintf(stderr, "sql_blind_insert : %s(%d).%s overflow\n",
                    283:                    table, id, key);
                    284:            return(-1);
                    285:        }
                    286:        len = mysql_escape_string(end, value, len);
                    287:        left -= len;
                    288:        if (left <= 0) {
                    289:            fprintf(stderr, "sql_blind_insert : %s(%d).%s overflow\n",
                    290:                    table, id, key);
                    291:            return(-1);
                    292:        }
                    293:        end += len;
                    294:        len = snprintf(end, left, "')");
                    295:        if (len < 0) {
                    296:            fprintf(stderr, "sql_blind_insert : %s(%d).%s overflow\n",
                    297:                    table, id, key);
                    298:            return(-1);
                    299:        }
                    300:        end += len;
                    301:        query[MAX_QUERY - 1] = 0;
                    302: 
1.2       veillard  303:     } else {
1.6       veillard  304:        len = snprintf(query, left, "INSERT INTO %s (%s) VALUES ('",
                    305:                       table, key);
                    306:        if (len < 0) {
                    307:            fprintf(stderr, "sql_blind_insert : %s.%s overflow\n",
                    308:                    table, key);
                    309:            return(-1);
                    310:        }
                    311:        end = &query[len];
                    312:        left -= len;
                    313:        len = strlen(value);
                    314:        if (len * 2 >= left) {
                    315:            fprintf(stderr, "sql_blind_insert : %s.%s overflow\n",
                    316:                    table, key);
                    317:            return(-1);
                    318:        }
                    319:        len = mysql_escape_string(end, value, len);
                    320:        left -= len;
                    321:        if (left <= 0) {
                    322:            fprintf(stderr, "sql_blind_insert : %s.%s overflow\n",
                    323:                    table, key);
                    324:            return(-1);
                    325:        }
                    326:        end += len;
                    327:        len = snprintf(end, left, "')");
                    328:        if (len < 0) {
                    329:            fprintf(stderr, "sql_blind_insert : %s.%s overflow\n",
                    330:                    table, key);
                    331:            return(-1);
                    332:        }
                    333:        end += len;
                    334:        query[MAX_QUERY - 1] = 0;
                    335: 
1.2       veillard  336:     }
1.6       veillard  337:     query[MAX_QUERY - 1] = 0;
1.16      veillard  338:     if (do_sql_query(query, (unsigned int) (end - query))) {
1.6       veillard  339: #ifdef SQL_DEBUG
                    340:        fprintf(stderr, "sql_blind_insert Error: %s\n", mysql_error(sql));
                    341: #endif
1.1       veillard  342:        return(-1);
                    343:     }
                    344:     result = mysql_store_result(sql);
1.8       veillard  345:     insert = mysql_insert_id(sql);
1.1       veillard  346:     if (result) {
                    347:        mysql_free_result(result);
1.8       veillard  348:        return(insert);
1.1       veillard  349:     }
                    350:     if(mysql_errno(sql)) {
                    351:        fprintf(stderr, "sql_blind_insert Error: %s\n", mysql_error(sql));
                    352:        return(-1);
                    353:     }
1.8       veillard  354:     return(insert);
1.1       veillard  355: }
                    356: 
                    357: int sql_update(const char *table, const char *name,
                    358:               const char *field, const char *value) {
                    359:     MYSQL_RES *result;
                    360:     MYSQL_ROW row;
1.6       veillard  361:     char query[MAX_QUERY];
1.1       veillard  362:     int id;
                    363:     int nb_fields = 0;
1.6       veillard  364:     int left = MAX_QUERY - 1;
                    365:     int len;
                    366:     char *end;
1.1       veillard  367: 
                    368:     if ((name == NULL) || (table == NULL) ||
                    369:        (field == NULL) || (value == NULL))
                    370:        return(-1);
                    371: 
                    372:     /*
                    373:      * Search first for the ID if it already exists
                    374:      */
1.6       veillard  375:     snprintf(query, MAX_QUERY - 1, "SELECT ID FROM %s WHERE Name='%s'", table, name);
                    376:     query[MAX_QUERY - 1] = 0;
1.1       veillard  377:     if (mysql_query(sql,query)) {
                    378:        printf("sql_update: SELECT failed\n");
                    379:        return(-1);
                    380:     }
                    381: 
                    382:     result = mysql_use_result(sql);
                    383:     if (result) {
                    384:        while((row = mysql_fetch_row(result)))
                    385:        {
                    386:            if (row[0] == NULL) {
                    387:                printf("sql_update: select ID for %s returns NULL !\n", name);
                    388:                return(-1);
                    389:            }
                    390:            if (sscanf(row[0], "%d", &id) != 1) {
                    391:                printf("sql_update: ID non numeric %s\n", row[0]);
                    392:                return(-1);
                    393:            }
1.6       veillard  394: 
                    395:            left = MAX_QUERY - 1;
                    396:            len = snprintf(query, left, "UPDATE %s SET %s='", table, field);
                    397:            if (len < 0) {
                    398:                fprintf(stderr, "sql_update : %s(%d).%s overflow\n",
                    399:                        table, id, field);
                    400:                return(-1);
                    401:            }
                    402:            end = &query[len];
                    403:            left -= len;
                    404:            len = strlen(value);
                    405:            if (len * 2 >= left) {
                    406:                fprintf(stderr, "sql_update : %s(%d).%s overflow\n",
                    407:                        table, id, field);
                    408:                return(-1);
                    409:            }
                    410:            len = mysql_escape_string(end, value, len);
                    411:            left -= len;
                    412:            if (left <= 0) {
                    413:                fprintf(stderr, "sql_update : %s(%d).%s overflow\n",
                    414:                        table, id, field);
                    415:                return(-1);
                    416:            }
                    417:            end += len;
                    418:            len = snprintf(end, left, "' WHERE ID=%d", id);
                    419:            if (len < 0) {
                    420:                fprintf(stderr, "sql_update : %s(%d).%s overflow\n",
                    421:                        table, id, field);
                    422:                return(-1);
                    423:            }
                    424:            end += len;
                    425:            query[MAX_QUERY - 1] = 0;
                    426: 
1.1       veillard  427:            mysql_free_result(result);
1.16      veillard  428:            if (do_sql_query(query, (unsigned int) (end - query))) {
1.2       veillard  429:                printf("sql_update: UPDATE failed: %s\n", mysql_error(sql));
1.1       veillard  430:                return(-1);
                    431:            }
                    432:            result = mysql_store_result(sql);
                    433:            if (result != NULL) {
                    434:                nb_fields = mysql_num_fields(result);
                    435:                mysql_free_result(result);
                    436:            } else {
1.2       veillard  437:                return(1);
1.1       veillard  438:            }
                    439:            /* Do not loop ... only the first */
                    440:            return(nb_fields);
                    441:        }
                    442:        mysql_free_result(result);
1.2       veillard  443:        if (nb_fields == 0) {
                    444:            /*
                    445:             * Propagate an insert
                    446:             */
1.6       veillard  447:            snprintf(query, MAX_QUERY - 1,
1.2       veillard  448:                    "INSERT INTO %s (Name,%s) VALUES ('%s','%s')",
                    449:                     table, field, name, value);
1.6       veillard  450:            query[MAX_QUERY - 1] = 0;
1.2       veillard  451:            mysql_free_result(result);
                    452:            if (mysql_query(sql, query)) {
                    453:                printf("sql_update: INSERT failed: %s\n", mysql_error(sql));
                    454:                return(-1);
                    455:            }
                    456:            result = mysql_store_result(sql);
                    457:            if (result != NULL) {
                    458:                nb_fields = mysql_num_fields(result);
                    459:                mysql_free_result(result);
                    460:            } else {
                    461:                return(1);
                    462:            }
                    463:        }
1.1       veillard  464:     }
                    465:     if(mysql_errno(sql)) {
                    466:        fprintf(stderr, "sql_update Error: %s\n", mysql_error(sql));
                    467:        return(-1);
                    468:     }
                    469:     return(nb_fields);
                    470: }
                    471: 
1.6       veillard  472: int sql_get_key(const char *table, const char *name, const char *value) {
1.1       veillard  473:     int id;
                    474:     MYSQL_RES *result;
                    475:     MYSQL_ROW row;
1.6       veillard  476:     char query[SMALL_QUERY];
1.1       veillard  477: 
                    478:     if ((table == NULL) || (name == NULL))
                    479:        return(-1);
                    480: 
                    481:     /*
                    482:      * Search first for the ID if it already exists
                    483:      */
1.6       veillard  484:     snprintf(query, SMALL_QUERY - 1, "SELECT ID FROM %s WHERE %s='%s'",
                    485:             table, name, value);
                    486:     query[SMALL_QUERY - 1] = 0;
1.1       veillard  487:     if (mysql_query(sql,query)) {
                    488:        printf("sql_create: SELECT %s failed %s\n", name, mysql_error(sql));
                    489:        return(-1);
                    490:     }
                    491: 
                    492:     result = mysql_use_result(sql);
                    493:     if (result) {
                    494:        while((row = mysql_fetch_row(result)))
                    495:        {
                    496:            /*
                    497:             * Lookup the first ID and return it
                    498:             */
                    499:            if (row[0] == NULL) {
                    500:                mysql_free_result(result);
                    501:                printf("sql_create: select returns NULL !\n");
                    502:                return(-1);
                    503:            }
                    504:            if (sscanf(row[0], "%d", &id) != 1) {
                    505:                mysql_free_result(result);
                    506:                printf("sql_create: ID non numeric %s\n", row[0]);
                    507:                return(-1);
                    508:            }
                    509:            mysql_free_result(result);
                    510:            return(id);
                    511:        }
                    512:        mysql_free_result(result);
                    513:     }
                    514:     if(mysql_errno(sql)) {
                    515:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                    516:        return(-1);
                    517:     }
                    518: 
                    519:     /*
                    520:      * Do a creation
                    521:      */
                    522: 
1.6       veillard  523:     snprintf(query, SMALL_QUERY - 1, "INSERT INTO %s (%s) VALUES ('%s')",
                    524:             table, name, value);
                    525:     query[SMALL_QUERY - 1] = 0;
1.1       veillard  526:     if (mysql_query(sql,query)) {
1.2       veillard  527:        printf("sql_get_key: INSERT %s failed %s\n", name, mysql_error(sql));
1.1       veillard  528:        return(-1);
                    529:     }
                    530:     id = mysql_insert_id(sql);
                    531:     result = mysql_store_result(sql);
                    532:     if (result != NULL)
                    533:        mysql_free_result(result);
                    534:     return(id);
                    535: }
                    536: 
                    537: int sql_read_key(const char *table, const char *name) {
                    538:     int id;
                    539:     MYSQL_RES *result;
                    540:     MYSQL_ROW row;
1.6       veillard  541:     char query[SMALL_QUERY];
1.1       veillard  542: 
                    543:     if ((table == NULL) || (name == NULL))
                    544:        return(-1);
                    545: 
                    546:     /*
                    547:      * Search for the ID it has to exist
                    548:      */
1.6       veillard  549:     snprintf(query, SMALL_QUERY - 1, "SELECT ID FROM %s WHERE Name='%s'", table, name);
                    550:     query[SMALL_QUERY - 1] = 0;
1.2       veillard  551:     if (mysql_query(sql,query)) {
                    552:        printf("sql_create: SELECT %s failed %s\n", name, mysql_error(sql));
                    553:        return(-1);
                    554:     }
                    555: 
                    556:     result = mysql_use_result(sql);
                    557:     if (result) {
                    558:        while((row = mysql_fetch_row(result)))
                    559:        {
                    560:            /*
                    561:             * Lookup the first ID and return it
                    562:             */
                    563:            if (row[0] == NULL) {
                    564:                mysql_free_result(result);
                    565:                printf("sql_create: select returns NULL !\n");
                    566:                return(-1);
                    567:            }
                    568:            if (sscanf(row[0], "%d", &id) != 1) {
                    569:                mysql_free_result(result);
                    570:                printf("sql_create: ID non numeric %s\n", row[0]);
                    571:                return(-1);
                    572:            }
                    573:            mysql_free_result(result);
                    574:            return(id);
                    575:        }
                    576:        mysql_free_result(result);
                    577:     }
                    578:     if(mysql_errno(sql)) {
                    579:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                    580:        return(-1);
                    581:     }
                    582:     return(-1);
                    583: }
                    584: 
                    585: int sql_read_info_key(const char *table, const char *name, const char *value) {
                    586:     int id;
                    587:     MYSQL_RES *result;
                    588:     MYSQL_ROW row;
1.6       veillard  589:     char query[SMALL_QUERY];
1.2       veillard  590: 
                    591:     if ((table == NULL) || (name == NULL) || (value == NULL))
                    592:        return(-1);
                    593: 
                    594:     /*
                    595:      * Search for the ID it has to exist
                    596:      */
1.6       veillard  597:     snprintf(query, SMALL_QUERY - 1, "SELECT ID FROM %s WHERE %s='%s'", table, name, value);
                    598:     query[SMALL_QUERY - 1] = 0;
1.1       veillard  599:     if (mysql_query(sql,query)) {
                    600:        printf("sql_create: SELECT %s failed %s\n", name, mysql_error(sql));
                    601:        return(-1);
                    602:     }
                    603: 
                    604:     result = mysql_use_result(sql);
                    605:     if (result) {
                    606:        while((row = mysql_fetch_row(result)))
                    607:        {
                    608:            /*
                    609:             * Lookup the first ID and return it
                    610:             */
                    611:            if (row[0] == NULL) {
                    612:                mysql_free_result(result);
                    613:                printf("sql_create: select returns NULL !\n");
                    614:                return(-1);
                    615:            }
                    616:            if (sscanf(row[0], "%d", &id) != 1) {
                    617:                mysql_free_result(result);
                    618:                printf("sql_create: ID non numeric %s\n", row[0]);
                    619:                return(-1);
                    620:            }
                    621:            mysql_free_result(result);
                    622:            return(id);
                    623:        }
                    624:        mysql_free_result(result);
                    625:     }
                    626:     if(mysql_errno(sql)) {
                    627:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                    628:        return(-1);
                    629:     }
                    630:     return(-1);
                    631: }
                    632: 
                    633: /************************************************************************
                    634:  *                                                                     *
                    635:  *                             Tables handling                         *
                    636:  *                                                                     *
                    637:  ************************************************************************/
                    638: 
1.2       veillard  639: int sql_rebuild_config(void) {
                    640:     const char *query =
                    641: "CREATE TABLE Config ( \n\
                    642:     ID int(11) NOT NULL auto_increment, \n\
                    643:     Name varchar(50) NOT NULL, \n\
                    644:     Value varchar(255), \n\
                    645:     PRIMARY KEY (ID), \n\
                    646:     KEY Name (Name(10)) \n\
                    647: )";
                    648: 
                    649:     if (mysql_query(sql,query)) {
                    650:        printf("sql_rebuild_config: CREATE TABLE Config failed %s\n",
                    651:               mysql_error(sql));
                    652:        return(-1);
                    653:     }
                    654:     return(0);
                    655: }
                    656: 
1.1       veillard  657: int sql_rebuild_vendors(void) {
                    658:     const char *query =
                    659: "CREATE TABLE Vendors ( \n\
                    660:     ID int(11) NOT NULL auto_increment, \n\
                    661:     Name varchar(255) NOT NULL, \n\
                    662:     URL varchar(255), \n\
                    663:     Key1 text, \n\
                    664:     Key2 text, \n\
                    665:     Key3 text, \n\
                    666:     Description text, \n\
                    667:     PRIMARY KEY (ID), \n\
                    668:     KEY Name (Name(10)) \n\
                    669: )";
                    670: 
                    671:     if (mysql_query(sql,query)) {
1.2       veillard  672:        printf("sql_rebuild_vendors: CREATE TABLE Vendors failed %s\n",
1.1       veillard  673:               mysql_error(sql));
                    674:        return(-1);
                    675:     }
                    676:     return(0);
                    677: }
                    678: 
                    679: int sql_rebuild_mirrors(void) {
                    680:     const char *query =
                    681: "CREATE TABLE Mirrors ( \n\
                    682:     ID int(11), \n\
                    683:     URL varchar(255) NOT NULL, \n\
                    684:     Country int(11), \n\
                    685:     UNIQUE(URL) \n\
                    686: )";
                    687: 
                    688:     if (mysql_query(sql,query)) {
1.2       veillard  689:        printf("sql_rebuild_mirrors: CREATE TABLE Mirrors failed %s\n",
                    690:               mysql_error(sql));
                    691:        return(-1);
                    692:     }
                    693:     return(0);
                    694: }
                    695: 
                    696: int sql_rebuild_metadata(void) {
                    697:     const char *query =
                    698: "CREATE TABLE Metadata ( \n\
                    699:     URL varchar(255) NOT NULL, \n\
                    700:     Maintainer int(11), \n\
                    701:     Country int(11), \n\
                    702:     UNIQUE(URL) \n\
                    703: )";
                    704: 
                    705:     if (mysql_query(sql,query)) {
                    706:        printf("sql_rebuild_metadata: CREATE TABLE Metadata failed %s\n",
1.1       veillard  707:               mysql_error(sql));
                    708:        return(-1);
                    709:     }
                    710:     return(0);
                    711: }
                    712: 
                    713: int sql_rebuild_distribs(void) {
                    714:     const char *query =
                    715: "CREATE TABLE Distribs ( \n\
                    716:     ID int(11) NOT NULL auto_increment, \n\
                    717:     Name varchar(255) NOT NULL, \n\
                    718:     Vendor int(11), \n\
1.2       veillard  719:     Directory varchar(255), \n\
1.1       veillard  720:     Path varchar(100) NOT NULL, \n\
                    721:     URL varchar(255), \n\
                    722:     URLSrc varchar(255), \n\
1.9       veillard  723:     Html varchar(8), \n\
                    724:     Color varchar(10), \n\
1.1       veillard  725:     Key1 text, \n\
                    726:     Key2 text, \n\
                    727:     Description text, \n\
                    728:     PRIMARY KEY (ID), \n\
                    729:     KEY Name (Name(10)) \n\
                    730: )";
                    731: 
                    732:     if (mysql_query(sql,query)) {
1.2       veillard  733:        printf("sql_rebuild_distribs: CREATE TABLE Distribs failed %s\n",
                    734:               mysql_error(sql));
                    735:        return(-1);
                    736:     }
                    737:     return(0);
                    738: }
                    739: 
                    740: int sql_rebuild_packages(void) {
                    741:     const char *query =
                    742: "CREATE TABLE Packages ( \n\
                    743: ID int(11) NOT NULL auto_increment, \n\
                    744: filename varchar(255) NOT NULL, \n\
                    745: Name varchar(50) NOT NULL, \n\
                    746: Version varchar(50) NOT NULL, \n\
                    747: Release varchar(50) NOT NULL, \n\
1.6       veillard  748: Arch varchar(15) NOT NULL, \n\
1.2       veillard  749: Dist int(11), \n\
                    750: URL varchar(255), \n\
                    751: URLSrc varchar(255), \n\
                    752: Vendor int(11), \n\
                    753: Packager int(11), \n\
                    754: Category varchar(255), \n\
                    755: Summary varchar(255), \n\
                    756: Description text, \n\
                    757: Copyright varchar(255), \n\
1.25      veillard  758: Date int(11), \n\
1.2       veillard  759: PRIMARY KEY (ID), \n\
1.7       veillard  760: KEY filename (filename(80)), \n\
                    761: KEY Name (Name(15)) \n\
1.2       veillard  762: )";
                    763: 
                    764:     if (mysql_query(sql,query)) {
                    765:        printf("sql_rebuild_packages: CREATE TABLE Packages failed %s\n",
                    766:               mysql_error(sql));
                    767:        return(-1);
                    768:     }
                    769:     return(0);
                    770: }
                    771: 
                    772: int sql_rebuild_files(void) {
                    773:     const char *query =
                    774: "CREATE TABLE Files ( \n\
1.6       veillard  775:     ID int(11) NOT NULL, \n\
1.7       veillard  776:     Path varchar(35) NOT NULL, \n\
                    777:     UNIQUE KEY id (ID,Path(35)), \n\
1.6       veillard  778:     INDEX (ID), \n\
                    779:     INDEX (Path) \n\
1.2       veillard  780: )";
                    781: 
                    782:     if (mysql_query(sql,query)) {
                    783:        printf("sql_rebuild_files: CREATE TABLE Files failed %s\n",
1.1       veillard  784:               mysql_error(sql));
                    785:        return(-1);
                    786:     }
                    787:     return(0);
                    788: }
                    789: 
1.8       veillard  790: int sql_rebuild_provides(void) {
                    791:     const char *query =
                    792: "CREATE TABLE Provides ( \n\
                    793:     ID int(11) NOT NULL, \n\
                    794:     Resource varchar(35) NOT NULL, \n\
                    795:     UNIQUE KEY id (ID,Resource(35)), \n\
                    796:     INDEX (ID), \n\
                    797:     INDEX (Resource) \n\
                    798: )";
                    799: 
                    800:     if (mysql_query(sql,query)) {
1.21      daniel    801:        printf("sql_rebuild_provides: CREATE TABLE Provides failed %s\n",
1.8       veillard  802:               mysql_error(sql));
                    803:        return(-1);
                    804:     }
                    805:     return(0);
                    806: }
                    807: 
                    808: int sql_rebuild_requires(void) {
                    809:     const char *query =
                    810: "CREATE TABLE Requires ( \n\
                    811:     ID int(11) NOT NULL, \n\
                    812:     Resource varchar(35) NOT NULL, \n\
                    813:     Rel char(2), \n\
                    814:     Value varchar(20), \n\
                    815:     UNIQUE KEY id (ID,Resource(35)), \n\
                    816:     INDEX (ID), \n\
                    817:     INDEX (Resource) \n\
                    818: )";
                    819: 
                    820:     if (mysql_query(sql,query)) {
1.21      daniel    821:        printf("sql_rebuild_requires: CREATE TABLE Requires failed %s\n",
                    822:               mysql_error(sql));
                    823:        return(-1);
                    824:     }
                    825:     return(0);
                    826: }
                    827: 
                    828: int sql_rebuild_queries(void) {
                    829:     const char *query =
                    830: "CREATE TABLE Queries ( \n\
                    831:     ID int(11) NOT NULL auto_increment,\n\
                    832:     Value varchar(50) NOT NULL, \n\
                    833:     Count int(11) NOT NULL, \n\
                    834:     Results int(11) NOT NULL, \n\
                    835:     UNIQUE KEY id (ID,Value(35)), \n\
                    836:     INDEX (ID), \n\
                    837:     INDEX (Value) \n\
                    838: )";
                    839: 
                    840:     if (mysql_query(sql,query)) {
                    841:        printf("sql_rebuild_queries: CREATE TABLE Queries failed %s\n",
1.8       veillard  842:               mysql_error(sql));
                    843:        return(-1);
                    844:     }
                    845:     return(0);
                    846: }
                    847: 
1.1       veillard  848: 
                    849: int sql_check_tables(void) {
                    850:     const char *query = "SHOW TABLES";
                    851:     MYSQL_RES *result;
                    852:     MYSQL_ROW row;
1.2       veillard  853:     int config = 0;
1.1       veillard  854:     int distribs = 0;
1.8       veillard  855:     int requires = 0;
                    856:     int provides = 0;
1.1       veillard  857:     int vendors = 0;
                    858:     int mirrors = 0;
1.2       veillard  859:     int metadata = 0;
                    860:     int packages = 0;
                    861:     int files = 0;
1.21      daniel    862:     int queries = 0;
1.2       veillard  863: 
1.1       veillard  864:     int rebuilt = 0;
                    865: 
                    866:     if (mysql_query(sql,query)) {
1.2       veillard  867:        printf("sql_check_tables: SHOW TABLES failed %s\n",
1.1       veillard  868:               mysql_error(sql));
                    869:        return(-1);
                    870:     }
                    871: 
                    872:     result = mysql_use_result(sql);
                    873:     if (result) {
                    874:        while((row = mysql_fetch_row(result)))
                    875:        {
                    876:            if (row[0] == NULL) {
                    877:                mysql_free_result(result);
                    878:                printf("sql_check_tables: SHOW TABLES returns NULL !\n");
                    879:                return(-1);
                    880:            }
1.2       veillard  881:            if (!strcmp(row[0], "Config"))
                    882:                config = 1;
1.1       veillard  883:            if (!strcmp(row[0], "Distribs"))
                    884:                distribs = 1;
                    885:            if (!strcmp(row[0], "Vendors"))
                    886:                vendors = 1;
                    887:            if (!strcmp(row[0], "Mirrors"))
                    888:                mirrors = 1;
1.2       veillard  889:            if (!strcmp(row[0], "Metadata"))
                    890:                metadata = 1;
                    891:            if (!strcmp(row[0], "Packages"))
                    892:                packages = 1;
                    893:            if (!strcmp(row[0], "Files"))
                    894:                files = 1;
1.8       veillard  895:            if (!strcmp(row[0], "Requires"))
                    896:                requires = 1;
                    897:            if (!strcmp(row[0], "Provides"))
                    898:                provides = 1;
1.21      daniel    899:            if (!strcmp(row[0], "Queries"))
                    900:                queries = 1;
1.1       veillard  901:        }
                    902:        mysql_free_result(result);
                    903:     }
                    904:     if(mysql_errno(sql)) {
                    905:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                    906:        return(-1);
                    907:     }
                    908: 
1.2       veillard  909:     if (!config) {
                    910:        fprintf(stderr, "Table Config disapeared: rebuilding it\n");
                    911:        if (!sql_rebuild_config())
                    912:            rebuilt++;
                    913:     }
1.1       veillard  914:     if (!vendors) {
                    915:        fprintf(stderr, "Table Vendors disapeared: rebuilding it\n");
                    916:        if (!sql_rebuild_vendors())
                    917:            rebuilt++;
                    918:     }
                    919:     if (!distribs) {
                    920:        fprintf(stderr, "Table Distribs disapeared: rebuilding it\n");
                    921:        if (!sql_rebuild_distribs())
                    922:            rebuilt++;
                    923:     }
                    924:     if (!mirrors) {
                    925:        fprintf(stderr, "Table Mirrors disapeared: rebuilding it\n");
                    926:        if (!sql_rebuild_mirrors())
                    927:            rebuilt++;
                    928:     }
1.2       veillard  929:     if (!metadata) {
                    930:        fprintf(stderr, "Table Metadata disapeared: rebuilding it\n");
                    931:        if (!sql_rebuild_metadata())
                    932:            rebuilt++;
                    933:     }
                    934:     if (!packages) {
                    935:        fprintf(stderr, "Table Packages disapeared: rebuilding it\n");
                    936:        if (!sql_rebuild_packages())
                    937:            rebuilt++;
                    938:     }
                    939:     if (!files) {
                    940:        fprintf(stderr, "Table Files disapeared: rebuilding it\n");
                    941:        if (!sql_rebuild_files())
                    942:            rebuilt++;
                    943:     }
1.8       veillard  944:     if (!requires) {
                    945:        fprintf(stderr, "Table Requires disapeared: rebuilding it\n");
                    946:        if (!sql_rebuild_requires())
                    947:            rebuilt++;
                    948:     }
                    949:     if (!provides) {
                    950:        fprintf(stderr, "Table Provides disapeared: rebuilding it\n");
                    951:        if (!sql_rebuild_provides())
1.21      daniel    952:            rebuilt++;
                    953:     }
                    954:     if (!queries) {
                    955:        fprintf(stderr, "Table Queries disapeared: rebuilding it\n");
                    956:        if (!sql_rebuild_queries())
1.8       veillard  957:            rebuilt++;
                    958:     }
1.1       veillard  959:     return(rebuilt);
                    960: }
                    961: 
                    962: /************************************************************************
                    963:  *                                                                     *
                    964:  *                     Specific rpm2html functions                     *
                    965:  *                                                                     *
                    966:  ************************************************************************/
                    967: 
1.5       veillard  968: int sql_add_dist_mirror(int distrib, const char *URL, int country) {
1.1       veillard  969:     if (URL == NULL)
                    970:        return(-1);
                    971:     if (distrib < 0)
                    972:        return(-1);
                    973:     return(sql_blind_insert("Mirrors", "URL", URL, distrib));
                    974: }
                    975: 
1.5       veillard  976: int sql_add_mirror(const char *Name, const char *URL, int country) {
1.1       veillard  977:     int distrib;
                    978: 
                    979:     if ((Name == NULL) || (URL == NULL))
                    980:        return(-1);
                    981:     distrib = sql_read_key("Distribs", Name);
                    982:     if (distrib < 0)
                    983:        return(distrib);
                    984:     return(sql_blind_insert("Mirrors", "URL", URL, distrib));
                    985: }
                    986: 
1.6       veillard  987: int sql_add_file(const char *filename, int package) {
                    988:     if ((filename == NULL) || (package <= 0))
                    989:        return(-1);
1.7       veillard  990:     if (strlen(filename) > 35)
                    991:        return(0);
1.6       veillard  992: 
                    993:     return(sql_blind_insert("Files", "Path", filename, package));
                    994: }
                    995: 
1.8       veillard  996: int sql_add_provides(int package, const char *resource) {
                    997:     if ((resource == NULL) || (package <= 0))
                    998:        return(-1);
                    999:     if (strlen(resource) > 35)
                   1000:        return(0);
                   1001: 
                   1002:     return(sql_blind_insert("Provides", "Resource", resource, package));
                   1003: }
                   1004: 
1.14      veillard 1005: int sql_add_requires(int package, const char *resource, rpm_dep_flag rel,
1.8       veillard 1006:                     const char *value) {
                   1007:     int record;
                   1008:     if ((resource == NULL) || (package <= 0))
                   1009:        return(-1);
                   1010:     if (strlen(resource) > 35)
                   1011:        return(0);
                   1012: 
                   1013:     record = sql_blind_insert("Requires", "Resource", resource, package);
1.14      veillard 1014:     if ((rel != RPM2HTML_REQ_NONE) && (value != NULL) &&
                   1015:        (strlen(value) <= 50)) {
1.8       veillard 1016:        char query[SMALL_QUERY];
1.14      veillard 1017: 
                   1018:        switch (rel) {
                   1019:            case RPM2HTML_REQ_LT:
                   1020:                snprintf(query, SMALL_QUERY - 1,
                   1021:                         "UPDATE Requires SET Rel='<',Value='%s' WHERE ID=%d",
                   1022:                         value, record);
1.15      daniel   1023:                break;
1.14      veillard 1024:            case RPM2HTML_REQ_LEQ:
                   1025:                snprintf(query, SMALL_QUERY - 1,
                   1026:                         "UPDATE Requires SET Rel='<=',Value='%s' WHERE ID=%d",
                   1027:                         value, record);
1.15      daniel   1028:                break;
1.14      veillard 1029:            case RPM2HTML_REQ_GT:
                   1030:                snprintf(query, SMALL_QUERY - 1,
                   1031:                         "UPDATE Requires SET Rel='>',Value='%s' WHERE ID=%d",
                   1032:                         value, record);
1.15      daniel   1033:                break;
1.14      veillard 1034:            case RPM2HTML_REQ_GEQ:
                   1035:                snprintf(query, SMALL_QUERY - 1,
                   1036:                         "UPDATE Requires SET Rel='>=',Value='%s' WHERE ID=%d",
                   1037:                         value, record);
1.15      daniel   1038:                break;
1.14      veillard 1039:            case RPM2HTML_REQ_EQU:
                   1040:                snprintf(query, SMALL_QUERY - 1,
                   1041:                         "UPDATE Requires SET Rel='=',Value='%s' WHERE ID=%d",
                   1042:                         value, record);
1.15      daniel   1043:                break;
1.14      veillard 1044:            case RPM2HTML_REQ_NONE:
                   1045:                query[0] = 0;
                   1046:        }
1.8       veillard 1047:        query[SMALL_QUERY - 1] = 0;
                   1048:        if (mysql_query(sql,query)) {
                   1049:            printf("sql_create: UPDATE Requires %d failed %s\n",
                   1050:                   record, mysql_error(sql));
                   1051:            return(record);
                   1052:        }
                   1053:     }
                   1054:     return(record);
                   1055: }
                   1056: 
1.5       veillard 1057: int sql_add_package(const char *filename,
1.2       veillard 1058:        const char *Name, const char *Version, const char *Release,
1.6       veillard 1059:        const char *Arch,
                   1060:        int dist, const char *URL, const char *URLSrc, int vendor,
1.2       veillard 1061:        const char *Packager, const char *Category, const char *Summary,
1.25      veillard 1062:        const char *Description, const char *Copyright, int Date) {
1.2       veillard 1063:     int id;
1.6       veillard 1064:     /* int packager;
                   1065:     char intStr[15]; */
1.2       veillard 1066:     int nb_fields = 0;
                   1067: 
1.6       veillard 1068:     if (filename == NULL)
1.2       veillard 1069:        return(-1);
1.6       veillard 1070: 
                   1071:     if (dist < 0)
1.2       veillard 1072:        return(-1);
1.6       veillard 1073:     if ((Name == NULL) || (Version == NULL) || (Release == NULL) ||
                   1074:        (Arch == NULL))
                   1075:        return(-1);
                   1076: 
                   1077:     id = sql_get_key("Packages", "filename", filename);
1.2       veillard 1078:     if (id <= 0)
                   1079:        return(-1);
                   1080:     nb_fields = 1;
1.8       veillard 1081: 
                   1082:     if (rpm2htmlVerbose > 1)
                   1083:        printf("Adding %s ID %d\n", filename, id);
                   1084: 
1.2       veillard 1085:     if (Name != NULL)
1.6       veillard 1086:        nb_fields += sql_update_id("Packages", id, "Name", Name);
1.2       veillard 1087:     if (Version != NULL)
                   1088:        nb_fields += sql_update_id("Packages", id, "Version", Version);
                   1089:     if (Release != NULL)
                   1090:        nb_fields += sql_update_id("Packages", id, "Release", Release);
1.6       veillard 1091:     if (Release != NULL)
                   1092:        nb_fields += sql_update_id("Packages", id, "Arch", Arch);
1.2       veillard 1093:     if (Category != NULL)
                   1094:        nb_fields += sql_update_id("Packages", id, "Category", Category);
                   1095:     if (URL != NULL)
                   1096:        nb_fields += sql_update_id("Packages", id, "URL", URL);
                   1097:     if (URLSrc != NULL)
                   1098:        nb_fields += sql_update_id("Packages", id, "URLSrc", URLSrc);
1.17      veillard 1099:     if (dist >= 0) {
                   1100:        char str[30];
                   1101:        snprintf(str, 30, "%d", dist);
                   1102:        str[29] = 0;
                   1103:        nb_fields += sql_update_id("Packages", id, "Dist", str);
                   1104:     }
1.2       veillard 1105:     if (Summary != NULL)
                   1106:        nb_fields += sql_update_id("Packages", id, "Summary", Summary);
                   1107:     if (Description != NULL)
                   1108:        nb_fields += sql_update_id("Packages", id,
                   1109:                                   "Description", Description);
                   1110:     if (Copyright != NULL)
                   1111:        nb_fields += sql_update_id("Packages", id, "Copyright", Copyright);
1.25      veillard 1112:     if (Date != 0) {
                   1113:        char str[30];
                   1114:        snprintf(str, 30, "%d", Date);
                   1115:        str[29] = 0;
                   1116:        nb_fields += sql_update_id("Packages", id, "Date", str);
                   1117:     }
1.2       veillard 1118:     
1.6       veillard 1119:     return(id);
1.17      veillard 1120: }
                   1121: 
                   1122: int sql_get_distrib_by_name(const char *Name) {
                   1123:     int ret;
                   1124: 
                   1125:     if (Name == NULL)
                   1126:        return(-1);
                   1127:     ret = sql_read_key("Distribs", Name);
                   1128: 
1.18      daniel   1129: #ifdef SQL_DEBUG
1.17      veillard 1130: fprintf(stderr, "sql_get_distrib_by_name(%s) => %d\n", Name, ret);
1.18      daniel   1131: #endif
1.17      veillard 1132: 
                   1133:     return(ret);
                   1134: }
                   1135: 
                   1136: int sql_get_distrib_by_directory(const char *Directory) {
                   1137:     int ret;
                   1138: 
                   1139:     if (Directory == NULL)
                   1140:        return(-1);
                   1141: 
                   1142:     ret = sql_get_key("Distribs", "Directory", Directory);
                   1143: 
1.18      daniel   1144: #ifdef SQL_DEBUG
1.17      veillard 1145: fprintf(stderr, "sql_get_distrib_by_directory(%s) => %d\n", Directory, ret);
1.18      daniel   1146: #endif
1.17      veillard 1147: 
                   1148:     return(ret);
1.2       veillard 1149: }
                   1150: 
1.5       veillard 1151: int sql_add_distrib(const char *Name, const char *Vendor,
1.2       veillard 1152:        const char *Directory, const char *Path, const char *URL,
1.9       veillard 1153:        const char *URLSrc, const char *Description,
                   1154:        const char *Html, const char *Color) {
1.1       veillard 1155:     int id, vendor;
                   1156:     int nb_fields = 0;
                   1157:     char VendorStr[15];
                   1158: 
                   1159:     if (Name == NULL)
                   1160:        return(-1);
                   1161: 
1.6       veillard 1162:     id = sql_get_key("Distribs", "Name", Name);
1.1       veillard 1163:     nb_fields = 1;
                   1164:     if (Vendor != NULL) {
1.6       veillard 1165:        vendor = sql_get_key("Vendors", "Name", Vendor);
1.1       veillard 1166:        sprintf(VendorStr, "%d", vendor);
                   1167:        nb_fields += sql_update_id("Distribs", id, "Vendor", VendorStr);
                   1168:     }
1.2       veillard 1169:     if (Directory != NULL)
                   1170:        nb_fields += sql_update_id("Distribs", id, "Directory", Directory);
1.1       veillard 1171:     if (Path != NULL)
                   1172:        nb_fields += sql_update_id("Distribs", id, "Path", Path);
                   1173:     if (URL != NULL)
                   1174:        nb_fields += sql_update_id("Distribs", id, "URL", URL);
                   1175:     if (URLSrc != NULL)
                   1176:        nb_fields += sql_update_id("Distribs", id, "URLSrc", URLSrc);
1.9       veillard 1177:     if (Html != NULL)
                   1178:        nb_fields += sql_update_id("Distribs", id, "Html", Html);
                   1179:     if (Color != NULL)
                   1180:        nb_fields += sql_update_id("Distribs", id, "Color", Color);
1.1       veillard 1181:     if (Description != NULL)
                   1182:        nb_fields += sql_update_id("Distribs", id,
                   1183:                                   "Description", Description);
                   1184:     
                   1185:     return(nb_fields);
                   1186: }
                   1187: 
1.5       veillard 1188: int sql_add_vendor(const char *Name, const char *URL, const char *Description) {
1.1       veillard 1189:     int id;
                   1190:     int nb_fields = 0;
                   1191: 
                   1192:     if (Name == NULL)
                   1193:        return(-1);
                   1194: 
1.6       veillard 1195:     id = sql_get_key("Vendors", "Name", Name);
1.1       veillard 1196:     nb_fields = 1;
                   1197:     if (URL != NULL)
                   1198:        nb_fields += sql_update_id("Vendors", id, "URL", URL);
                   1199:     if (Description != NULL)
                   1200:        nb_fields += sql_update_id("Vendors", id,
                   1201:                                   "Description", Description);
                   1202:     
                   1203:     return(nb_fields);
                   1204: }
                   1205: 
1.5       veillard 1206: void sql_add_config_info(const char *name, const char *value) {
1.2       veillard 1207:     sql_update("Config", name, "Value", value);
                   1208: }
                   1209: 
1.5       veillard 1210: void sql_add_metadata_base(const char *URL) {
1.2       veillard 1211:     sql_blind_insert("Metadata", "URL", URL, -1);
                   1212: }
                   1213: 
1.6       veillard 1214: /************************************************************************
                   1215:  *                                                                     *
1.8       veillard 1216:  *                     Cleanup functions                               *
                   1217:  *                                                                     *
                   1218:  ************************************************************************/
                   1219: 
                   1220: int sql_remove_package(int id) {
                   1221:     char query[SMALL_QUERY];
                   1222: 
                   1223:     if (id <= 0)
                   1224:        return(-1);
                   1225: 
                   1226:     /*
                   1227:      * remove the ID from the package list
                   1228:      */
                   1229:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Packages WHERE ID=%d", id);
                   1230:     query[SMALL_QUERY - 1] = 0;
                   1231:     if (mysql_query(sql,query)) {
                   1232:        printf("sql_create: DELETE package %d failed %s\n", id, mysql_error(sql));
                   1233:        return(-1);
                   1234:     }
                   1235:     if(mysql_errno(sql)) {
                   1236:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1237:        return(-1);
                   1238:     }
                   1239: 
                   1240:     /*
                   1241:      * remove the associated files from the Files list
                   1242:      */
                   1243:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Files WHERE ID=%d", id);
                   1244:     query[SMALL_QUERY - 1] = 0;
                   1245:     if (mysql_query(sql,query)) {
                   1246:        printf("sql_create: DELETE Files %d failed %s\n", id, mysql_error(sql));
                   1247:        return(-1);
                   1248:     }
                   1249:     if(mysql_errno(sql)) {
                   1250:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1251:        return(-1);
                   1252:     }
                   1253: 
                   1254:     /*
                   1255:      * remove the associated Provides entries
                   1256:      */
                   1257:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Provides WHERE ID=%d", id);
                   1258:     query[SMALL_QUERY - 1] = 0;
                   1259:     if (mysql_query(sql,query)) {
                   1260:        printf("sql_create: DELETE Provides %d failed %s\n", id, mysql_error(sql));
                   1261:        return(-1);
                   1262:     }
                   1263:     if(mysql_errno(sql)) {
                   1264:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1265:        return(-1);
                   1266:     }
                   1267: 
                   1268:     /*
                   1269:      * remove the associated Requires entries
                   1270:      */
                   1271:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Requires WHERE ID=%d", id);
                   1272:     query[SMALL_QUERY - 1] = 0;
                   1273:     if (mysql_query(sql,query)) {
                   1274:        printf("sql_create: DELETE Requires %d failed %s\n", id, mysql_error(sql));
                   1275:        return(-1);
                   1276:     }
                   1277:     if(mysql_errno(sql)) {
                   1278:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1279:        return(-1);
                   1280:     }
                   1281: 
                   1282:     return(-1);
                   1283: }
                   1284: 
                   1285: int sql_check_packages(void) {
                   1286:     MYSQL_RES *result;
                   1287:     MYSQL_ROW row;
1.20      daniel   1288:     char *query = "SELECT filename,ID FROM Packages";
1.8       veillard 1289:     struct stat buf;
                   1290:     int id;
1.22      daniel   1291:     int ids[2500]; /* Do not remove more than 2500 package per run */
1.8       veillard 1292:     int index;
                   1293:     int total = 0;
                   1294: 
                   1295:     if (rpm2htmlVerbose)
                   1296:        printf("Database cleanup\n");
                   1297:     index = 0;
                   1298:     /*
                   1299:      * Search first for the ID if it already exists
                   1300:      */
                   1301:     if (mysql_query(sql,query)) {
                   1302:        printf("sql_check_packages: SELECT from Packages failed: %s\n",
                   1303:               mysql_error(sql));
                   1304:        return(-1);
                   1305:     }
                   1306: 
                   1307:     result = mysql_use_result(sql);
                   1308:     if (result) {
                   1309:        while((row = mysql_fetch_row(result)))
                   1310:        {
                   1311:            if ((row[0] == NULL) || (row[1] == NULL)) {
                   1312:                printf("sql_check_packages: Path or ID is NULL !\n");
                   1313:                continue;
                   1314:            }
                   1315:            if ((stat(row[0], &buf) < 0) || (buf.st_size < 50)) {
                   1316:                /*
                   1317:                 * Need to remove the package from the database.
                   1318:                 */
                   1319:                if (sscanf(row[1], "%d", &id) != 1) {
                   1320:                    printf("sql_check_packages: ID non numeric %s\n", row[1]);
                   1321:                    continue;
                   1322:                }
                   1323:                ids[index++] = id;
1.20      daniel   1324:                if (rpm2htmlVerbose)
1.8       veillard 1325:                    printf("Removing %s ID %d\n", row[0], id);
1.22      daniel   1326:                if (index >= 2500)
1.8       veillard 1327:                    break;
                   1328:            }
                   1329:        }
                   1330:        mysql_free_result(result);
                   1331:     }
                   1332:     if(mysql_errno(sql)) {
                   1333:        fprintf(stderr, "sql_update Error: %s\n", mysql_error(sql));
                   1334:        return(-1);
                   1335:     }
                   1336: 
                   1337:     /*
                   1338:      * Do the cleanup.
                   1339:      */
1.20      daniel   1340:     if (rpm2htmlVerbose)
                   1341:        printf("Database cleanup : removing %d entries...\n", index);
1.8       veillard 1342:     for (id = 0;id < index;id++) {
                   1343:        sql_remove_package(ids[id]);
                   1344:     }
                   1345: 
                   1346:     if (rpm2htmlVerbose)
1.20      daniel   1347:        printf("Database cleanup : removed %d entries\n", index);
1.8       veillard 1348:     return(total);
                   1349: }
                   1350: 
                   1351: /************************************************************************
1.26      veillard 1352:  *                                                                     *
                   1353:  *                     Package lists extraction                        *
                   1354:  *                                                                     *
                   1355:  ************************************************************************/
                   1356: int sqlDirListInitialized = 0;
                   1357: rpmDirPtr sqlDirList[SQL_MAX_DISTRIBS];
                   1358: 
                   1359: rpmDirPtr
                   1360: sqlRpmAnalyzeDirRow(MYSQL_ROW row) {
                   1361:     rpmDirPtr ret;
                   1362:     const char *id;
                   1363:     const char *name;
                   1364:     const char *vendor;
                   1365:     const char *directory;
                   1366:     const char *path;
                   1367:     const char *url;
                   1368:     const char *urlSrc;
                   1369:     const char *html;
                   1370:     const char *color;
                   1371:     int dist;
                   1372: 
                   1373:     if (row == NULL)
                   1374:        return(NULL);
                   1375:     id = row[0];
                   1376:     name = row[1];
                   1377:     vendor = row[2];
                   1378:     directory = row[3];
                   1379:     path = row[4];
                   1380:     url = row[5];
                   1381:     urlSrc = row[6];
                   1382:     html = row[7];
                   1383:     color = row[8];
                   1384:     if ((id == NULL) || (name == NULL) ||
                   1385:         (directory == NULL) || (path == NULL) || (url == NULL))
                   1386:        return(NULL);
                   1387: 
                   1388:     if (sscanf(id, "%d", &dist) != 1)
                   1389:        return(NULL);
                   1390:     if ((dist <= 0) || (dist > SQL_MAX_DISTRIBS)) {
                   1391:        fprintf(stderr, "Dist number out of range %d\n", dist);
                   1392:        return(NULL);
                   1393:     }
                   1394: 
                   1395: 
                   1396:     ret = (rpmDirPtr) debugMalloc(sizeof(rpmDir));
                   1397:     if (ret == NULL)
                   1398:        return(NULL);
                   1399:     memset(ret, 0, sizeof(rpmDir));
                   1400:     /* Generic stuff */
1.28      daniel   1401:     if (rpm2html_dir != NULL)
1.26      veillard 1402:     ret->dir = debugStrdup(rpm2html_dir);
1.28      daniel   1403:     if (rpm2html_host != NULL)
1.26      veillard 1404:     ret->host = debugStrdup(rpm2html_host);
1.28      daniel   1405:     if (rpm2html_maint != NULL)
1.26      veillard 1406:     ret->maint = debugStrdup(rpm2html_maint);
1.28      daniel   1407:     if (rpm2html_mail != NULL)
1.26      veillard 1408:     ret->mail = debugStrdup(rpm2html_mail);
1.28      daniel   1409:     if (rpm2html_url != NULL)
1.26      veillard 1410:     ret->url = debugStrdup(rpm2html_url);
                   1411:     /* specific stuff */
                   1412:     ret->no = dist;
                   1413:     ret->rpmdir = debugStrdup(directory);
                   1414:     ret->subdir = debugStrdup(path);
                   1415:     ret->name = debugStrdup(name);
                   1416:     ret->ftp = debugStrdup(url);
                   1417:     if (color != NULL)
                   1418:        ret->color = debugStrdup(color);
1.28      daniel   1419:     else
                   1420:        ret->color = debugStrdup("#ffffff");
1.26      veillard 1421:     if (urlSrc != NULL)
                   1422:        ret->ftpsrc = debugStrdup(urlSrc);
                   1423:     return(ret);
                   1424: }
                   1425: 
                   1426: void
                   1427: sqlInitSqlDirList(void) {
1.28      daniel   1428:     char host[200];
1.26      veillard 1429:     rpmDirPtr cur;
                   1430:     MYSQL_RES *result;
                   1431:     MYSQL_ROW row;
                   1432:     char *query;
                   1433:     int i;
                   1434: 
                   1435:     if (sqlDirListInitialized != 0)
                   1436:        return;
                   1437: 
1.28      daniel   1438:     gethostname(host, sizeof(host));
                   1439:     currentTime = time(NULL);
                   1440:     rpm2html_rpm2html_thishost = &host[0];
                   1441:     readConfigSql();
                   1442:     if (rpm2html_host == NULL) {
                   1443:        rpm2html_host = strdup(rpm2html_rpm2html_thishost);
                   1444:     }
1.26      veillard 1445:     for (i = 0; i < SQL_MAX_DISTRIBS;i++)
                   1446:         sqlDirList[i] = NULL;
                   1447: 
                   1448:     if (rpm2htmlVerbose)
                   1449:        printf("sqlInitSqlDirList query\n");
                   1450: 
1.29    ! veillard 1451:     query = "select ID,Name,Vendor,Directory,Path,URL,URLSrc,Html,Color from Distribs";
1.26      veillard 1452: 
                   1453:     /*
                   1454:      * Search first for the ID if it already exists
                   1455:      */
                   1456:     if (mysql_query(sql,query)) {
                   1457:        printf("sqlInitSqlDirList: SELECT from Packages failed: %s\n",
                   1458:               mysql_error(sql));
                   1459:        return;
                   1460:     }
                   1461: 
                   1462:     i = 0;
                   1463:     result = mysql_use_result(sql);
                   1464:     if (result) {
                   1465:        while((row = mysql_fetch_row(result)))
                   1466:        {
                   1467:            cur = sqlRpmAnalyzeDirRow(row);
                   1468:            if (cur != NULL) {
                   1469:                sqlDirList[cur->no] = cur;
                   1470:                i++;
                   1471:            }
                   1472:        }
                   1473:        mysql_free_result(result);
                   1474:     }
                   1475:     if(mysql_errno(sql)) {
                   1476:        fprintf(stderr, "sqlInitSqlDirList Error: %s\n", mysql_error(sql));
                   1477:        return;
                   1478:     }
                   1479: 
                   1480:     if (rpm2htmlVerbose)
                   1481:        printf("sqlInitSqlDirList done: %d entries\n", i);
                   1482:     sqlDirListInitialized++;
                   1483:     return;
                   1484: }
                   1485: 
                   1486: rpmDataPtr
                   1487: sqlRpmAnalyzeRow(MYSQL_ROW row) {
                   1488:     rpmDataPtr ret;
                   1489:     const char *id;
                   1490:     const char *name;
                   1491:     const char *version;
                   1492:     const char *release;
                   1493:     const char *arch;
                   1494:     const char *date;
                   1495:     const char *summary;
                   1496:     const char *filename;
                   1497:     const char *distrib;
                   1498:     int dist;
                   1499: 
                   1500:     if (row == NULL)
                   1501:        return(NULL);
                   1502:     id = row[0];
                   1503:     name = row[1];
                   1504:     version = row[2];
                   1505:     release = row[3];
                   1506:     arch = row[4];
                   1507:     date = row[5];
                   1508:     summary = row[6];
                   1509:     filename = row[7];
                   1510:     distrib = row[8];
                   1511:     if ((id == NULL) || (name == NULL) || (version == NULL) ||
                   1512:         (release == NULL) || (arch == NULL) || (date == NULL) ||
                   1513:        (summary == NULL) || (filename == NULL) || (distrib == NULL))
                   1514:        return(NULL);
                   1515: 
                   1516:     ret = (rpmDataPtr) debugMalloc(sizeof(rpmData));
                   1517:     if (ret == NULL)
                   1518:        return(NULL);
                   1519:     memset(ret, 0, sizeof(rpmData));
                   1520:     ret->name = debugStrdup(name);
                   1521:     ret->version = debugStrdup(version);
                   1522:     ret->release = debugStrdup(release);
                   1523:     ret->arch = debugStrdup(arch);
                   1524:     ret->summary = debugStrdup(summary);
                   1525:     ret->name = debugStrdup(name);
                   1526:     ret->filename = debugStrdup(filename);
                   1527:     sscanf(date, "%d", (int *) &(ret->date));
                   1528:     sscanf(distrib, "%d", &dist);
                   1529:     ret->dir = sqlDirList[dist];
1.28      daniel   1530:     if ((ret->dir != NULL) && (ret->dir->rpmdir != NULL)) {
                   1531:        int len = strlen(ret->dir->rpmdir);
                   1532:        if (!strncmp(ret->filename, ret->dir->rpmdir, len)) {
                   1533:            char *start, *end;
                   1534:            start = &(ret->filename[len]);
                   1535:            while (*start == '/') start++;
                   1536:            end = &start[strlen(start) - 1];
                   1537:            while ((end >= start) && (*end != '/')) end--;
                   1538:             if (end > start) {
                   1539:                char *tmp;
                   1540:                tmp = debugMalloc((end - start) + 1);
                   1541:                if (tmp != NULL) {
                   1542:                    strncpy(tmp, start, end - start);
                   1543:                    tmp[end - start] = 0;
                   1544:                    ret->subdir = tmp;
                   1545:                }
                   1546:            }
                   1547:        }
                   1548:     }
1.26      veillard 1549:     return(ret);
                   1550: }
                   1551: 
                   1552: rpmDataPtr
                   1553: sqlRpmByDate(void) {
                   1554:     rpmDataPtr list = NULL;
                   1555:     rpmDataPtr cur, last = NULL;
                   1556:     MYSQL_RES *result;
                   1557:     MYSQL_ROW row;
                   1558:     char *query;
                   1559: 
                   1560:     sqlInitSqlDirList();
                   1561:     if (rpm2htmlVerbose)
                   1562:        printf("sqlRpmByDate query\n");
                   1563: 
1.29    ! veillard 1564:     query = "select ID,Name,Version,Release,Arch,Date,Summary,filename,Dist from Packages where Date IS NOT NULL  and Date < UNIX_TIMESTAMP() + 300000 order by Date desc limit 1000";
1.26      veillard 1565: 
                   1566:     /*
                   1567:      * Search first for the ID if it already exists
                   1568:      */
                   1569:     if (mysql_query(sql,query)) {
                   1570:        printf("sqlRpmByDate: SELECT from Packages failed: %s\n",
                   1571:               mysql_error(sql));
                   1572:        return(NULL);
                   1573:     }
                   1574: 
                   1575:     result = mysql_use_result(sql);
                   1576:     if (result) {
                   1577:        while((row = mysql_fetch_row(result)))
                   1578:        {
                   1579:            cur = sqlRpmAnalyzeRow(row);
                   1580:            if (cur != NULL) {
                   1581:                if (last == NULL)
                   1582:                    list = cur;
                   1583:                else
                   1584:                    last->next = cur;
                   1585:                last = cur;
                   1586:            }
                   1587:        }
                   1588:        mysql_free_result(result);
                   1589:     }
                   1590:     if(mysql_errno(sql)) {
                   1591:        fprintf(stderr, "sqlRpmByDate Error: %s\n", mysql_error(sql));
                   1592:        return(NULL);
                   1593:     }
                   1594: 
                   1595:     if (rpm2htmlVerbose)
                   1596:        printf("sqlRpmByDate done\n");
                   1597:     return(list);
                   1598: }
                   1599: 
1.29    ! veillard 1600: rpmDataPtr
        !          1601: sqlRpmAll(void) {
        !          1602:     rpmDataPtr list = NULL;
        !          1603:     rpmDataPtr cur, last = NULL;
        !          1604:     MYSQL_RES *result;
        !          1605:     MYSQL_ROW row;
        !          1606:     char *query;
        !          1607: 
        !          1608:     sqlInitSqlDirList();
        !          1609:     if (rpm2htmlVerbose)
        !          1610:        printf("sqlRpmAll query\n");
        !          1611: 
        !          1612:     query = "select ID,Name,Version,Release,Arch,Date,Summary,filename,Dist from Packages";
        !          1613: 
        !          1614:     /*
        !          1615:      * Search first for the ID if it already exists
        !          1616:      */
        !          1617:     if (mysql_query(sql,query)) {
        !          1618:        printf("sqlRpmByDate: SELECT from Packages failed: %s\n",
        !          1619:               mysql_error(sql));
        !          1620:        return(NULL);
        !          1621:     }
        !          1622: 
        !          1623:     result = mysql_use_result(sql);
        !          1624:     if (result) {
        !          1625:        while((row = mysql_fetch_row(result)))
        !          1626:        {
        !          1627:            cur = sqlRpmAnalyzeRow(row);
        !          1628:            if (cur != NULL) {
        !          1629:                if (last == NULL)
        !          1630:                    list = cur;
        !          1631:                else
        !          1632:                    last->next = cur;
        !          1633:                last = cur;
        !          1634:            }
        !          1635:        }
        !          1636:        mysql_free_result(result);
        !          1637:     }
        !          1638:     if(mysql_errno(sql)) {
        !          1639:        fprintf(stderr, "sqlRpmByDate Error: %s\n", mysql_error(sql));
        !          1640:        return(NULL);
        !          1641:     }
        !          1642: 
        !          1643:     if (rpm2htmlVerbose)
        !          1644:        printf("sqlRpmAll done\n");
        !          1645:     return(list);
        !          1646: }
        !          1647: 
1.26      veillard 1648: /************************************************************************
1.8       veillard 1649:  *                                                                     *
1.6       veillard 1650:  *                     Export functions                                *
                   1651:  *                                                                     *
                   1652:  ************************************************************************/
                   1653: 
                   1654: void sql_show_config(void) {
                   1655:     MYSQL_RES *result;
                   1656:     MYSQL_ROW row;
1.8       veillard 1657:     int id, i;
                   1658:     int index = 0;
                   1659:     int ids[500];
                   1660:     char query[SMALL_QUERY];
1.6       veillard 1661: 
                   1662: 
1.8       veillard 1663:     printf(";\n; Configuration file for rpm2html\n");
                   1664:     printf("; http://rpmfind.net/linux/rpm2html/\n;\n\n");
                   1665:     mysql_query(sql,"SELECT Name,Value FROM Config");
1.6       veillard 1666:     result = mysql_use_result(sql);
                   1667: 
                   1668:     while((row = mysql_fetch_row(result)))
                   1669:     {
1.8       veillard 1670:        if (row[0] == NULL) {
                   1671:            printf("\n");
                   1672:        } else {
                   1673:            if (!strcmp(row[0], "maint"))
                   1674:                printf("; maintainer of the local rpm mirror\n");
                   1675:            else if (!strcmp(row[0], "mail"))
                   1676:                printf("; mail for the maintainer\n");
                   1677:            else if (!strcmp(row[0], "dir"))
                   1678:                 printf("; Directory to store the HTML pages produced\n");
                   1679:            else if (!strcmp(row[0], "url"))
                   1680:                 printf("; The relative URL for front pages\n");
                   1681:            else if (!strcmp(row[0], "header"))
                   1682:                 printf("; Extra link in the navigation bar\n");
                   1683:            else if (!strcmp(row[0], "html"))
                   1684:                 printf("; Export the local packages in HTML format\n");
                   1685:            else if (!strcmp(row[0], "tree"))
                   1686:                 printf("; Build the tree for the distributions\n");
                   1687:            else if (!strcmp(row[0], "rdf"))
                   1688:                 printf("; Export the local packages in RDF format\n");
                   1689:            else if (!strcmp(row[0], "rdf_dir"))
                   1690:                 printf("; Directory to store the RDf tree\n");
                   1691:            else if (!strcmp(row[0], "rdf_resources"))
                   1692:                 printf("; Compile a list of resources in RDF format\n");
                   1693:            else if (!strcmp(row[0], "rdf_resources_dir"))
                   1694:                 printf("; Directory to store the RDf resources tree\n");
                   1695: 
1.6       veillard 1696:            if (row[1] == NULL)
1.8       veillard 1697:                printf("%s\n\n", row[0]);
1.6       veillard 1698:            else
1.8       veillard 1699:                printf("%s=%s\n\n", row[0], row[1]);
                   1700:        }
                   1701:     }
                   1702:     mysql_free_result(result);
                   1703:     if(mysql_errno(sql)) {
                   1704:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1705:     }
                   1706: 
                   1707:     /*
                   1708:      * Dump the Metadata
                   1709:      */
                   1710:     printf(";\n; The metadata mirrors list\n;\n\n[metadata]\n");
                   1711:     mysql_query(sql,"SELECT URL FROM Metadata");
                   1712:     result = mysql_use_result(sql);
                   1713: 
                   1714:     while((row = mysql_fetch_row(result)))
                   1715:     {
                   1716:        if (row[0] != NULL) {
                   1717:            printf("mirror=%s\n", row[0]);
1.6       veillard 1718:        }
                   1719:     }
1.8       veillard 1720:     mysql_free_result(result);
1.6       veillard 1721:     if(mysql_errno(sql)) {
                   1722:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1723:     }
                   1724: 
1.8       veillard 1725:     /*
                   1726:      * Dump the distributions informations
                   1727:      * 1/ collect the list of IDs for the distribs
                   1728:      */
                   1729:     printf("\n\n;\n; The distribution list\n;\n\n");
                   1730:     mysql_query(sql,"SELECT ID FROM Distribs");
                   1731:     result = mysql_use_result(sql);
                   1732: 
                   1733:     while((row = mysql_fetch_row(result)))
                   1734:     {
                   1735:        if (row[0] != NULL) {
                   1736:            if (sscanf(row[0], "%d", &id) == 1) {
                   1737:                ids[index++] = id;
                   1738:            }
                   1739:        }
                   1740:     }
                   1741:     mysql_free_result(result);
                   1742: 
                   1743:     /*
                   1744:      * Dump each distribution separately.
                   1745:      */
                   1746:     for (i = 0;i < index;i++) {
                   1747: 
                   1748:        snprintf(query, SMALL_QUERY - 1,
1.10      veillard 1749:  "SELECT Directory,Name,Vendor,Path,URL,URLSrc,Description,Html,Color \
1.8       veillard 1750:                  FROM Distribs WHERE ID=%d", ids[i]);
                   1751:        query[SMALL_QUERY - 1] = 0;
                   1752:        if (mysql_query(sql,query)) {
                   1753:            printf("sql_show_config: SELECT Distrib %d failed: %s\n",
                   1754:                   ids[i], mysql_error(sql));
                   1755:            continue;
                   1756:        }
                   1757: 
                   1758:        result = mysql_use_result(sql);
                   1759:        if (result) {
                   1760:            while((row = mysql_fetch_row(result)))
                   1761:            {
                   1762:                if (row[0] == NULL)
                   1763:                    break;
                   1764:                printf("[%s]\n", row[0]);
                   1765:                if (row[1] != NULL)
                   1766:                    printf("name=%s\n", row[1]);
                   1767:                if (row[3] != NULL)
                   1768:                    printf("subdir=%s\n", row[3]);
                   1769:                if (row[4] != NULL)
                   1770:                    printf("ftp=%s\n", row[4]);
                   1771:                if (row[5] != NULL)
                   1772:                    printf("ftpsrc=%s\n", row[5]);
1.10      veillard 1773:                if (row[7] != NULL)
                   1774:                    printf("html=%s\n", row[7]);
                   1775:                if (row[8] != NULL)
                   1776:                    printf("color=%s\n", row[8]);
1.8       veillard 1777:            }
                   1778:        }
                   1779:        mysql_free_result(result);
1.12      veillard 1780: 
                   1781:        /*
                   1782:         * Extract the mirrors for this distribution.
                   1783:         */
                   1784:        snprintf(query, SMALL_QUERY - 1,
                   1785:                 "SELECT URL FROM Mirrors WHERE ID=%d", ids[i]);
                   1786:        query[SMALL_QUERY - 1] = 0;
                   1787:        if (mysql_query(sql,query)) {
                   1788:            printf("sql_show_config: SELECT Mirrors %d failed: %s\n",
                   1789:                   ids[i], mysql_error(sql));
                   1790:            printf("\n\n");
                   1791:            continue;
                   1792:        }
                   1793:        result = mysql_use_result(sql);
                   1794:        if (result) {
                   1795:            while((row = mysql_fetch_row(result)))
                   1796:            {
                   1797:                if (row[0] == NULL)
                   1798:                    continue;
                   1799:                printf("mirror=%s\n", row[0]);
                   1800:            }
                   1801:        }
                   1802:        mysql_free_result(result);
                   1803: 
1.8       veillard 1804:        printf("\n\n");
                   1805:     }
                   1806: 
                   1807:     printf(";\n; End of the configuration file for rpm2html\n;\n");
1.6       veillard 1808: }
                   1809: 
                   1810: void sql_show_metadata(void) {
                   1811:     MYSQL_RES *result;
                   1812:     MYSQL_ROW row;
                   1813: 
                   1814: 
                   1815:     mysql_query(sql,"SELECT URL FROM Metadata");
                   1816:     result = mysql_use_result(sql);
                   1817: 
                   1818:     while((row = mysql_fetch_row(result)))
                   1819:     {
                   1820:        if (row[0] == NULL)
                   1821:            printf("NULL !\n");
                   1822:        else {
                   1823:            printf("%s\n", row[0]);
                   1824:        }
                   1825:     }
                   1826:     if(mysql_errno(sql)) {
                   1827:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1828:     }
                   1829: 
                   1830: }
                   1831: 
                   1832: void sql_show_mirrors(void) {
                   1833:     MYSQL_RES *result;
                   1834:     MYSQL_ROW row;
                   1835: 
                   1836: 
                   1837:     mysql_query(sql,"SELECT URL FROM Mirrors");
                   1838:     result = mysql_use_result(sql);
                   1839: 
                   1840:     while((row = mysql_fetch_row(result)))
                   1841:     {
                   1842:        if (row[0] == NULL)
                   1843:            printf("NULL !\n");
                   1844:        else {
                   1845:            printf("%s\n", row[0]);
                   1846:        }
                   1847:     }
                   1848:     if(mysql_errno(sql)) {
                   1849:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1850:     }
                   1851: }
                   1852: 
1.5       veillard 1853: void sql_show_vendors(void) {
1.1       veillard 1854:     MYSQL_RES *result;
                   1855:     MYSQL_ROW row;
                   1856: 
                   1857: 
                   1858:     mysql_query(sql,"SELECT Name, URL FROM Vendors");
                   1859:     result = mysql_use_result(sql);
                   1860: 
                   1861:     while((row = mysql_fetch_row(result)))
                   1862:     {
                   1863:        if (row[0] == NULL)
                   1864:            printf("NULL !\n");
                   1865:        else {
                   1866:            if (row[1] == NULL)
                   1867:                printf("%s : no url\n", row[0]);
                   1868:            else
                   1869:                printf("%s : %s\n", row[0], row[1]);
                   1870:        }
                   1871:     }
                   1872:     if(mysql_errno(sql)) {
                   1873:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1874:     }
                   1875: 
                   1876: }
                   1877: 
1.5       veillard 1878: void sql_show_distribs(void) {
1.1       veillard 1879:     MYSQL_RES *result;
                   1880:     MYSQL_ROW row;
                   1881: 
                   1882: 
                   1883:     mysql_query(sql,"SELECT Name, Path, URL FROM Distribs");
                   1884:     result = mysql_use_result(sql);
                   1885: 
                   1886:     while((row = mysql_fetch_row(result)))
                   1887:     {
                   1888:        if (row[0] == NULL)
                   1889:            printf("NULL !\n");
                   1890:        else {
                   1891:            if (row[1] == NULL)
                   1892:                printf("%s : no Path\n", row[0]);
                   1893:            else {
                   1894:                if (row[2] == NULL)
                   1895:                    printf("%s : %s : no url\n", row[0], row[1]);
                   1896:                else
                   1897:                    printf("%s : %s : %s\n", row[0], row[1], row[2]);
                   1898:            }
                   1899:        }
                   1900:     }
                   1901:     if(mysql_errno(sql)) {
                   1902:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1903:     }
                   1904: 
                   1905: }
                   1906: 
1.5       veillard 1907: int sql_show_table_stats(const char *table, const char *key) {
1.6       veillard 1908:     char query[MAX_QUERY];
1.2       veillard 1909:     MYSQL_RES *result;
                   1910:     MYSQL_ROW row;
                   1911:     int res;
                   1912: 
                   1913:     /*
                   1914:      * Search first for the ID if it already exists
                   1915:      */
1.6       veillard 1916:     snprintf(query, MAX_QUERY - 1, "SELECT COUNT(%s) FROM %s", key, table);
                   1917:     query[MAX_QUERY - 1] = 0;
1.2       veillard 1918:     if (mysql_query(sql,query)) {
1.5       veillard 1919:        printf("sql_show_table_stats: SELECT COUNT failed: %s\n",
1.2       veillard 1920:               mysql_error(sql));
                   1921:        return(-1);
                   1922:     }
                   1923: 
                   1924:     result = mysql_use_result(sql);
                   1925:     if (result) {
                   1926:        while((row = mysql_fetch_row(result)))
                   1927:        {
                   1928:            /*
                   1929:             * Lookup the value and return it
                   1930:             */
                   1931:            if (row[0] == NULL) {
                   1932:                mysql_free_result(result);
1.5       veillard 1933:                printf("sql_show_table_stats: select count returns NULL !\n");
1.2       veillard 1934:                return(-1);
                   1935:            }
                   1936:            if (sscanf(row[0], "%d", &res) != 1) {
                   1937:                mysql_free_result(result);
1.5       veillard 1938:                printf("sql_show_table_stats: value non numeric %s\n", row[0]);
1.2       veillard 1939:                return(-1);
                   1940:            }
                   1941:            mysql_free_result(result);
                   1942:            if (res <= 0)
                   1943:                printf("   %s is empty\n", table);
                   1944:            else
                   1945:                printf("   %s contains %d records\n", table, res);
                   1946:            return(res);
                   1947:        }
                   1948:        mysql_free_result(result);
                   1949:     }
                   1950:     if(mysql_errno(sql)) {
1.5       veillard 1951:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.2       veillard 1952:     }
                   1953:     return(-1);
                   1954: }
                   1955: 
1.5       veillard 1956: int sql_show_stats(void) {
1.2       veillard 1957:     const char *query = "SHOW TABLES";
                   1958:     MYSQL_RES *result;
                   1959:     MYSQL_ROW row;
                   1960: 
                   1961:     int tables = 0;
                   1962:     int records = 0;
                   1963: 
                   1964:     if (mysql_query(sql,query)) {
                   1965:        printf("sql_check_tables: SHOW TABLES failed %s\n",
                   1966:               mysql_error(sql));
                   1967:        return(-1);
                   1968:     }
                   1969: 
                   1970:     result = mysql_use_result(sql);
                   1971:     if (result) {
                   1972:        while((row = mysql_fetch_row(result)))
                   1973:        {
                   1974:            if (row[0] == NULL) {
                   1975:                mysql_free_result(result);
                   1976:                printf("sql_check_tables: SHOW TABLES returns NULL !\n");
                   1977:                return(-1);
                   1978:            }
                   1979:            tables++;
                   1980:        }
                   1981:        mysql_free_result(result);
                   1982:     }
                   1983:     if(mysql_errno(sql)) {
1.5       veillard 1984:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.2       veillard 1985:     }
                   1986:     printf("%d tables in use\n", tables);
1.5       veillard 1987:     records += sql_show_table_stats("Config", "Name");
                   1988:     records += sql_show_table_stats("Distribs", "Name");
                   1989:     records += sql_show_table_stats("Vendors", "Name");
                   1990:     records += sql_show_table_stats("Mirrors", "URL");
                   1991:     records += sql_show_table_stats("Metadata", "URL");
                   1992:     records += sql_show_table_stats("Packages", "Name");
1.8       veillard 1993:     records += sql_show_table_stats("Requires", "Resource");
                   1994:     records += sql_show_table_stats("Provides", "Resource");
1.5       veillard 1995:     records += sql_show_table_stats("Files", "Path");
1.2       veillard 1996:     printf("Total: %d records\n", records);
                   1997:     return(records);
                   1998: }
                   1999: 
1.26      veillard 2000: void sql_show_latests(void) {
                   2001:     rpmDataPtr list;
                   2002: 
                   2003:     list = sqlRpmByDate();
                   2004:     if (list == NULL) {
                   2005:        fprintf(stderr, "no package in database\n");
                   2006:        return;
                   2007:     }
1.28      daniel   2008:     dumpRpmByDate(list, 0);
1.29    ! veillard 2009: }
        !          2010: 
        !          2011: void sql_show_all(void) {
        !          2012:     rpmDataPtr list;
        !          2013: 
        !          2014:     list = sqlRpmAll();
        !          2015:     if (list == NULL) {
        !          2016:        fprintf(stderr, "no package in database\n");
        !          2017:        return;
        !          2018:     }
        !          2019:     sleep(30);
        !          2020:     /* dumpRpmByDate(list, 0); */
1.26      veillard 2021: }
                   2022: 
1.2       veillard 2023: /************************************************************************
                   2024:  *                                                                     *
                   2025:  *                     rpm2html configuration functions                *
                   2026:  *                                                                     *
                   2027:  ************************************************************************/
                   2028: 
                   2029: int readConfigSql(void) {
1.6       veillard 2030:     char query[MAX_QUERY];
1.3       veillard 2031:     MYSQL_RES *result;
                   2032:     MYSQL_ROW row;
1.4       veillard 2033:     int dir = 0;
1.3       veillard 2034: 
1.2       veillard 2035:     /*
1.3       veillard 2036:      * General configuration informations
1.2       veillard 2037:      */
1.6       veillard 2038:     snprintf(query, MAX_QUERY - 1, "SELECT Name,Value FROM Config");
                   2039:     query[MAX_QUERY - 1] = 0;
1.3       veillard 2040:     if (mysql_query(sql,query)) {
                   2041:        printf("sql_check_tables: SELECT Config failed %s\n",
                   2042:               mysql_error(sql));
                   2043:        return(-1);
                   2044:     }
                   2045: 
                   2046:     result = mysql_use_result(sql);
                   2047:     if (result) {
                   2048:        while((row = mysql_fetch_row(result)))
                   2049:        {
                   2050:            if ((row[0] == NULL) || (row[1] == NULL)) {
                   2051:                fprintf(stderr, "readConfigSql : found NULL value\n");
                   2052:                continue;
                   2053:            }
1.4       veillard 2054:            if (!strcmp(row[0], "dir"))
                   2055:                dir = 1;
1.3       veillard 2056:            addConfigEntry(RPM2HTML_NAME, row[0], row[1]);
                   2057:        }
                   2058:        mysql_free_result(result);
                   2059:     }
                   2060:     if(mysql_errno(sql)) {
1.5       veillard 2061:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.4       veillard 2062:     }
                   2063:     if (dir == 0) {
                   2064:        fprintf(stderr, "readConfigSql : no directory\n");
                   2065:        return(-1);
1.3       veillard 2066:     }
                   2067: 
                   2068:     /*
                   2069:      * The metadata mirror list.
                   2070:      */
1.6       veillard 2071:     snprintf(query, MAX_QUERY - 1, "SELECT URL FROM Metadata");
                   2072:     query[MAX_QUERY - 1] = 0;
1.3       veillard 2073:     if (mysql_query(sql,query)) {
                   2074:        printf("sql_check_tables: SELECT Metadata failed %s\n",
                   2075:               mysql_error(sql));
                   2076:        return(-1);
                   2077:     }
                   2078: 
                   2079:     result = mysql_use_result(sql);
                   2080:     if (result) {
                   2081:        while((row = mysql_fetch_row(result)))
                   2082:        {
                   2083:            if (row[0] == NULL) {
                   2084:                fprintf(stderr, "readConfigSql : found NULL metadata\n");
                   2085:                continue;
                   2086:            }
                   2087:            addConfigEntry("metadata", "mirror", row[0]);
                   2088:        }
                   2089:        mysql_free_result(result);
                   2090:     }
                   2091:     if(mysql_errno(sql)) {
1.5       veillard 2092:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 2093:     }
                   2094: 
                   2095:     /*
                   2096:      * The distribution lists
                   2097:      */
1.6       veillard 2098:     snprintf(query, MAX_QUERY - 1, "SELECT Directory,Name,URL,URLSrc,Path FROM Distribs");
                   2099:     query[MAX_QUERY - 1] = 0;
1.3       veillard 2100:     if (mysql_query(sql,query)) {
                   2101:        printf("sql_check_tables: SELECT Distribs failed %s\n",
                   2102:               mysql_error(sql));
                   2103:        return(-1);
                   2104:     }
                   2105: 
                   2106:     result = mysql_use_result(sql);
                   2107:     if (result) {
                   2108:        while((row = mysql_fetch_row(result)))
                   2109:        {
                   2110:            if (row[0] == NULL) {
                   2111:                fprintf(stderr, "readConfigSql : found NULL distro\n");
                   2112:                continue;
                   2113:            }
                   2114: 
                   2115:            if (row[1] != NULL)
                   2116:                addConfigEntry(row[0], "name", row[1]);
                   2117:            if (row[2] != NULL)
                   2118:                addConfigEntry(row[0], "ftp", row[2]);
                   2119:            if (row[3] != NULL)
                   2120:                addConfigEntry(row[0], "ftp", row[3]);
                   2121:            if (row[4] != NULL)
                   2122:                addConfigEntry(row[0], "subdir", row[4]);
                   2123:        }
                   2124:        mysql_free_result(result);
                   2125:     }
                   2126:     if(mysql_errno(sql)) {
1.5       veillard 2127:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 2128:     }
                   2129: 
                   2130:     /*
                   2131:      * The Mirrors
                   2132:      */
1.6       veillard 2133:     snprintf(query, MAX_QUERY - 1, "SELECT Distribs.Directory,Mirrors.URL FROM Distribs,Mirrors WHERE Distribs.ID = Mirrors.ID");
                   2134:     query[MAX_QUERY - 1] = 0;
1.3       veillard 2135:     if (mysql_query(sql,query)) {
                   2136:        printf("sql_check_tables: SELECT Distribs failed %s\n",
                   2137:               mysql_error(sql));
                   2138:        return(-1);
                   2139:     }
                   2140: 
                   2141:     result = mysql_use_result(sql);
                   2142:     if (result) {
                   2143:        while((row = mysql_fetch_row(result)))
                   2144:        {
                   2145:            if ((row[0] == NULL) || (row[1] == NULL)) {
                   2146:                fprintf(stderr, "readConfigSql : found NULL mirror\n");
                   2147:                continue;
                   2148:            }
                   2149: 
                   2150:            addConfigEntry(row[0], "mirror", row[1]);
                   2151:        }
                   2152:        mysql_free_result(result);
                   2153:     }
                   2154:     if(mysql_errno(sql)) {
1.5       veillard 2155:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 2156:     }
                   2157: 
1.5       veillard 2158:     /*
                   2159:      * TODO: add the language(s) stuff
                   2160:      */
1.3       veillard 2161:     return(0);
1.2       veillard 2162: }
                   2163: 
                   2164: void sqlConfigEntry(const char *rpmdir, const char *name, const char *value) {
                   2165:     int distrib;
                   2166: 
                   2167:     if (rpm2htmlVerbose > 1)
                   2168:        printf("sqlConfigEntry(\"%s\", \"%s\", \"%s\")\n", rpmdir, name, value);
                   2169: 
                   2170:     /*
                   2171:      * case of global option for rpm2html.
                   2172:      */
                   2173:     if (!strcasecmp(rpmdir, RPM2HTML_NAME)) {
1.5       veillard 2174:        sql_add_config_info(name, value);
1.2       veillard 2175:        return;
                   2176:     }
                   2177: 
                   2178:     /*
                   2179:      * Options for the metadata mirrors.
                   2180:      */
                   2181:     if (!strcasecmp(rpmdir, "metadata")) {
                   2182:        if (!strcasecmp(name, "mirror")) {
1.5       veillard 2183:            sql_add_metadata_base(value);
1.2       veillard 2184:        } else {
                   2185:            printf("Config file : %s entry for [metadata] ignored\n", name);
                   2186:        }
                   2187:        return;
                   2188:     }
                   2189: 
                   2190:     /*
                   2191:      * option for a directory.
                   2192:      */
                   2193:     if (!strcasecmp(name, "name")) {
1.9       veillard 2194:        sql_add_distrib(value, NULL, rpmdir, NULL, NULL, NULL, NULL,
                   2195:                        NULL, NULL);
1.2       veillard 2196:     } else if (!strcasecmp(name, "subdir")) {
                   2197:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   2198:        if (distrib > 0)
                   2199:             sql_update_id("Distribs", distrib, "Path", value);
                   2200:     } else if (!strcasecmp(name, "url")) {
                   2201:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   2202:        if (distrib > 0)
                   2203:             sql_update_id("Distribs", distrib, "URL", value);
                   2204:     } else if (!strcasecmp(name, "ftp")) {
                   2205:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   2206:        if (distrib > 0)
                   2207:             sql_update_id("Distribs", distrib, "URL", value);
                   2208:     } else if (!strcasecmp(name, "ftpsrc")) {
                   2209:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   2210:        if (distrib > 0)
                   2211:             sql_update_id("Distribs", distrib, "URLSrc", value);
1.9       veillard 2212:     } else if (!strcasecmp(name, "html")) {
                   2213:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   2214:        if (distrib > 0)
                   2215:             sql_update_id("Distribs", distrib, "Html", value);
                   2216:     } else if (!strcasecmp(name, "color")) {
                   2217:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   2218:        if (distrib > 0)
                   2219:             sql_update_id("Distribs", distrib, "Color", value);
1.2       veillard 2220:     } else if (!strcasecmp(name, "mirror")) {
                   2221:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   2222:        if (distrib > 0)
1.5       veillard 2223:            sql_add_dist_mirror(distrib, value, 0);
1.2       veillard 2224:     } else {
                   2225:        printf("Config file : %s entry for [%s] ignored\n", name, rpmdir);
                   2226:     }
                   2227: }
1.1       veillard 2228: 

Webmaster