Annotation of rpm2html/sql.c, revision 1.34

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

Webmaster