Annotation of rpm2html/sql.c, revision 1.40

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.39      daniel     35: /* #define SQL_DEBUG_TIMING */
1.31      veillard   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.38      veillard  478:     char query[MAX_QUERY];
                    479:     int left = MAX_QUERY - 1;
                    480:     int len;
                    481:     char *end;
1.1       veillard  482: 
                    483:     if ((table == NULL) || (name == NULL))
                    484:        return(-1);
                    485: 
1.38      veillard  486: 
1.1       veillard  487:     /*
                    488:      * Search first for the ID if it already exists
                    489:      */
1.38      veillard  490:     len = snprintf(query, left, "SELECT ID FROM %s WHERE %s='",
                    491:                   table, name);
                    492:     if (len < 0) {
                    493:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    494:                table, name, value);
                    495:        return(-1);
                    496:     }
                    497:     end = &query[len];
                    498:     left -= len;
                    499:     len = strlen(value);
                    500:     if (len * 2 >= left) {
                    501:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    502:                table, name, value);
                    503:        return(-1);
                    504:     }
                    505:     len = mysql_escape_string(end, value, len);
                    506:     left -= len;
                    507:     if (left <= 0) {
                    508:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    509:                table, name, value);
                    510:        return(-1);
                    511:     }
                    512:     end += len;
                    513:     len = snprintf(end, left, "'");
                    514:     if (len < 0) {
                    515:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    516:                table, name, value);
                    517:        return(-1);
                    518:     }
                    519:     end += len;
                    520:     query[MAX_QUERY - 1] = 0;
                    521: 
1.1       veillard  522:     if (mysql_query(sql,query)) {
1.38      veillard  523:        printf("sql_get_key: SELECT %s failed %s\n", name, mysql_error(sql));
1.1       veillard  524:        return(-1);
                    525:     }
                    526: 
                    527:     result = mysql_use_result(sql);
                    528:     if (result) {
                    529:        while((row = mysql_fetch_row(result)))
                    530:        {
                    531:            /*
                    532:             * Lookup the first ID and return it
                    533:             */
                    534:            if (row[0] == NULL) {
                    535:                mysql_free_result(result);
1.38      veillard  536:                printf("sql_get_key: select returns NULL !\n");
1.1       veillard  537:                return(-1);
                    538:            }
                    539:            if (sscanf(row[0], "%d", &id) != 1) {
                    540:                mysql_free_result(result);
1.38      veillard  541:                printf("sql_get_key: ID non numeric %s\n", row[0]);
1.1       veillard  542:                return(-1);
                    543:            }
                    544:            mysql_free_result(result);
                    545:            return(id);
                    546:        }
                    547:        mysql_free_result(result);
                    548:     }
                    549:     if(mysql_errno(sql)) {
                    550:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                    551:        return(-1);
                    552:     }
                    553: 
                    554:     /*
                    555:      * Do a creation
                    556:      */
                    557: 
1.6       veillard  558:     query[SMALL_QUERY - 1] = 0;
1.38      veillard  559:     len = snprintf(query, left, "INSERT INTO %s (%s) VALUES ('",
                    560:                   table, name);
                    561:     if (len < 0) {
                    562:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    563:                table, name, value);
                    564:        return(-1);
                    565:     }
                    566:     end = &query[len];
                    567:     left -= len;
                    568:     len = strlen(value);
                    569:     if (len * 2 >= left) {
                    570:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    571:                table, name, value);
                    572:        return(-1);
                    573:     }
                    574:     len = mysql_escape_string(end, value, len);
                    575:     left -= len;
                    576:     if (left <= 0) {
                    577:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    578:                table, name, value);
                    579:        return(-1);
                    580:     }
                    581:     end += len;
                    582:     len = snprintf(end, left, "')");
                    583:     if (len < 0) {
                    584:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    585:                table, name, value);
                    586:        return(-1);
                    587:     }
                    588:     end += len;
                    589:     query[MAX_QUERY - 1] = 0;
                    590: 
1.1       veillard  591:     if (mysql_query(sql,query)) {
1.2       veillard  592:        printf("sql_get_key: INSERT %s failed %s\n", name, mysql_error(sql));
1.1       veillard  593:        return(-1);
                    594:     }
                    595:     id = mysql_insert_id(sql);
                    596:     result = mysql_store_result(sql);
                    597:     if (result != NULL)
                    598:        mysql_free_result(result);
                    599:     return(id);
                    600: }
                    601: 
                    602: int sql_read_key(const char *table, const char *name) {
                    603:     int id;
                    604:     MYSQL_RES *result;
                    605:     MYSQL_ROW row;
1.6       veillard  606:     char query[SMALL_QUERY];
1.1       veillard  607: 
                    608:     if ((table == NULL) || (name == NULL))
                    609:        return(-1);
                    610: 
                    611:     /*
                    612:      * Search for the ID it has to exist
                    613:      */
1.6       veillard  614:     snprintf(query, SMALL_QUERY - 1, "SELECT ID FROM %s WHERE Name='%s'", table, name);
                    615:     query[SMALL_QUERY - 1] = 0;
1.2       veillard  616:     if (mysql_query(sql,query)) {
1.38      veillard  617:        printf("sql_read_key: SELECT %s failed %s\n", name, mysql_error(sql));
1.2       veillard  618:        return(-1);
                    619:     }
                    620: 
                    621:     result = mysql_use_result(sql);
                    622:     if (result) {
                    623:        while((row = mysql_fetch_row(result)))
                    624:        {
                    625:            /*
                    626:             * Lookup the first ID and return it
                    627:             */
                    628:            if (row[0] == NULL) {
                    629:                mysql_free_result(result);
1.38      veillard  630:                printf("sql_read_key: select returns NULL !\n");
1.2       veillard  631:                return(-1);
                    632:            }
                    633:            if (sscanf(row[0], "%d", &id) != 1) {
                    634:                mysql_free_result(result);
1.38      veillard  635:                printf("sql_read_key: ID non numeric %s\n", row[0]);
1.2       veillard  636:                return(-1);
                    637:            }
                    638:            mysql_free_result(result);
                    639:            return(id);
                    640:        }
                    641:        mysql_free_result(result);
                    642:     }
                    643:     if(mysql_errno(sql)) {
                    644:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                    645:        return(-1);
                    646:     }
                    647:     return(-1);
                    648: }
                    649: 
                    650: int sql_read_info_key(const char *table, const char *name, const char *value) {
                    651:     int id;
                    652:     MYSQL_RES *result;
                    653:     MYSQL_ROW row;
1.6       veillard  654:     char query[SMALL_QUERY];
1.2       veillard  655: 
                    656:     if ((table == NULL) || (name == NULL) || (value == NULL))
                    657:        return(-1);
                    658: 
                    659:     /*
                    660:      * Search for the ID it has to exist
                    661:      */
1.6       veillard  662:     snprintf(query, SMALL_QUERY - 1, "SELECT ID FROM %s WHERE %s='%s'", table, name, value);
                    663:     query[SMALL_QUERY - 1] = 0;
1.1       veillard  664:     if (mysql_query(sql,query)) {
1.38      veillard  665:        printf("sql_read_info_key: SELECT %s failed %s\n", name, mysql_error(sql));
1.1       veillard  666:        return(-1);
                    667:     }
                    668: 
                    669:     result = mysql_use_result(sql);
                    670:     if (result) {
                    671:        while((row = mysql_fetch_row(result)))
                    672:        {
                    673:            /*
                    674:             * Lookup the first ID and return it
                    675:             */
                    676:            if (row[0] == NULL) {
                    677:                mysql_free_result(result);
1.38      veillard  678:                printf("sql_read_info_key: select returns NULL !\n");
1.1       veillard  679:                return(-1);
                    680:            }
                    681:            if (sscanf(row[0], "%d", &id) != 1) {
                    682:                mysql_free_result(result);
1.38      veillard  683:                printf("sql_read_info_key: ID non numeric %s\n", row[0]);
1.1       veillard  684:                return(-1);
                    685:            }
                    686:            mysql_free_result(result);
                    687:            return(id);
                    688:        }
                    689:        mysql_free_result(result);
                    690:     }
                    691:     if(mysql_errno(sql)) {
                    692:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                    693:        return(-1);
                    694:     }
                    695:     return(-1);
                    696: }
                    697: 
                    698: /************************************************************************
                    699:  *                                                                     *
                    700:  *                             Tables handling                         *
                    701:  *                                                                     *
                    702:  ************************************************************************/
                    703: 
1.2       veillard  704: int sql_rebuild_config(void) {
                    705:     const char *query =
                    706: "CREATE TABLE Config ( \n\
                    707:     ID int(11) NOT NULL auto_increment, \n\
                    708:     Name varchar(50) NOT NULL, \n\
                    709:     Value varchar(255), \n\
                    710:     PRIMARY KEY (ID), \n\
                    711:     KEY Name (Name(10)) \n\
                    712: )";
                    713: 
                    714:     if (mysql_query(sql,query)) {
                    715:        printf("sql_rebuild_config: CREATE TABLE Config failed %s\n",
                    716:               mysql_error(sql));
                    717:        return(-1);
                    718:     }
                    719:     return(0);
                    720: }
                    721: 
1.1       veillard  722: int sql_rebuild_vendors(void) {
                    723:     const char *query =
                    724: "CREATE TABLE Vendors ( \n\
                    725:     ID int(11) NOT NULL auto_increment, \n\
                    726:     Name varchar(255) NOT NULL, \n\
                    727:     URL varchar(255), \n\
                    728:     Key1 text, \n\
                    729:     Key2 text, \n\
                    730:     Key3 text, \n\
                    731:     Description text, \n\
                    732:     PRIMARY KEY (ID), \n\
                    733:     KEY Name (Name(10)) \n\
                    734: )";
                    735: 
                    736:     if (mysql_query(sql,query)) {
1.2       veillard  737:        printf("sql_rebuild_vendors: CREATE TABLE Vendors failed %s\n",
1.1       veillard  738:               mysql_error(sql));
                    739:        return(-1);
                    740:     }
                    741:     return(0);
                    742: }
                    743: 
1.36      veillard  744: int sql_rebuild_distributions(void) {
                    745:     const char *query =
                    746: "CREATE TABLE Distributions ( \n\
                    747:     ID int(11) NOT NULL auto_increment, \n\
                    748:     Name varchar(255) NOT NULL, \n\
                    749:     URL varchar(255), \n\
                    750:     Key1 text, \n\
                    751:     Key2 text, \n\
                    752:     Key3 text, \n\
                    753:     Description text, \n\
                    754:     PRIMARY KEY (ID), \n\
                    755:     KEY Name (Name(10)) \n\
                    756: )";
                    757: 
                    758:     if (mysql_query(sql,query)) {
                    759:        printf("sql_rebuild_ditributions: CREATE TABLE Distributions failed %s\n",
                    760:               mysql_error(sql));
                    761:        return(-1);
                    762:     }
                    763:     return(0);
                    764: }
                    765: 
1.1       veillard  766: int sql_rebuild_mirrors(void) {
                    767:     const char *query =
                    768: "CREATE TABLE Mirrors ( \n\
                    769:     ID int(11), \n\
                    770:     URL varchar(255) NOT NULL, \n\
                    771:     Country int(11), \n\
                    772:     UNIQUE(URL) \n\
                    773: )";
                    774: 
                    775:     if (mysql_query(sql,query)) {
1.2       veillard  776:        printf("sql_rebuild_mirrors: CREATE TABLE Mirrors failed %s\n",
                    777:               mysql_error(sql));
                    778:        return(-1);
                    779:     }
                    780:     return(0);
                    781: }
                    782: 
                    783: int sql_rebuild_metadata(void) {
                    784:     const char *query =
                    785: "CREATE TABLE Metadata ( \n\
                    786:     URL varchar(255) NOT NULL, \n\
                    787:     Maintainer int(11), \n\
                    788:     Country int(11), \n\
                    789:     UNIQUE(URL) \n\
                    790: )";
                    791: 
                    792:     if (mysql_query(sql,query)) {
                    793:        printf("sql_rebuild_metadata: CREATE TABLE Metadata failed %s\n",
1.1       veillard  794:               mysql_error(sql));
                    795:        return(-1);
                    796:     }
                    797:     return(0);
                    798: }
                    799: 
                    800: int sql_rebuild_distribs(void) {
                    801:     const char *query =
                    802: "CREATE TABLE Distribs ( \n\
                    803:     ID int(11) NOT NULL auto_increment, \n\
                    804:     Name varchar(255) NOT NULL, \n\
                    805:     Vendor int(11), \n\
1.2       veillard  806:     Directory varchar(255), \n\
1.1       veillard  807:     Path varchar(100) NOT NULL, \n\
                    808:     URL varchar(255), \n\
                    809:     URLSrc varchar(255), \n\
1.9       veillard  810:     Html varchar(8), \n\
                    811:     Color varchar(10), \n\
1.1       veillard  812:     Key1 text, \n\
                    813:     Key2 text, \n\
                    814:     Description text, \n\
                    815:     PRIMARY KEY (ID), \n\
                    816:     KEY Name (Name(10)) \n\
                    817: )";
                    818: 
                    819:     if (mysql_query(sql,query)) {
1.2       veillard  820:        printf("sql_rebuild_distribs: CREATE TABLE Distribs failed %s\n",
                    821:               mysql_error(sql));
                    822:        return(-1);
                    823:     }
                    824:     return(0);
                    825: }
                    826: 
                    827: int sql_rebuild_packages(void) {
                    828:     const char *query =
                    829: "CREATE TABLE Packages ( \n\
                    830: ID int(11) NOT NULL auto_increment, \n\
                    831: filename varchar(255) NOT NULL, \n\
                    832: Name varchar(50) NOT NULL, \n\
                    833: Version varchar(50) NOT NULL, \n\
                    834: Release varchar(50) NOT NULL, \n\
1.6       veillard  835: Arch varchar(15) NOT NULL, \n\
1.2       veillard  836: Dist int(11), \n\
                    837: URL varchar(255), \n\
                    838: URLSrc varchar(255), \n\
                    839: Vendor int(11), \n\
                    840: Packager int(11), \n\
                    841: Category varchar(255), \n\
                    842: Summary varchar(255), \n\
                    843: Description text, \n\
                    844: Copyright varchar(255), \n\
1.25      veillard  845: Date int(11), \n\
1.33      veillard  846: Os varchar(12), \n\
1.2       veillard  847: PRIMARY KEY (ID), \n\
1.7       veillard  848: KEY filename (filename(80)), \n\
                    849: KEY Name (Name(15)) \n\
1.2       veillard  850: )";
                    851: 
                    852:     if (mysql_query(sql,query)) {
                    853:        printf("sql_rebuild_packages: CREATE TABLE Packages failed %s\n",
                    854:               mysql_error(sql));
                    855:        return(-1);
                    856:     }
                    857:     return(0);
                    858: }
                    859: 
                    860: int sql_rebuild_files(void) {
                    861:     const char *query =
                    862: "CREATE TABLE Files ( \n\
1.6       veillard  863:     ID int(11) NOT NULL, \n\
1.7       veillard  864:     Path varchar(35) NOT NULL, \n\
                    865:     UNIQUE KEY id (ID,Path(35)), \n\
1.6       veillard  866:     INDEX (ID), \n\
                    867:     INDEX (Path) \n\
1.2       veillard  868: )";
                    869: 
                    870:     if (mysql_query(sql,query)) {
                    871:        printf("sql_rebuild_files: CREATE TABLE Files failed %s\n",
1.1       veillard  872:               mysql_error(sql));
                    873:        return(-1);
                    874:     }
                    875:     return(0);
                    876: }
                    877: 
1.8       veillard  878: int sql_rebuild_provides(void) {
                    879:     const char *query =
                    880: "CREATE TABLE Provides ( \n\
                    881:     ID int(11) NOT NULL, \n\
                    882:     Resource varchar(35) NOT NULL, \n\
                    883:     UNIQUE KEY id (ID,Resource(35)), \n\
                    884:     INDEX (ID), \n\
                    885:     INDEX (Resource) \n\
                    886: )";
                    887: 
                    888:     if (mysql_query(sql,query)) {
1.21      daniel    889:        printf("sql_rebuild_provides: CREATE TABLE Provides failed %s\n",
1.8       veillard  890:               mysql_error(sql));
                    891:        return(-1);
                    892:     }
                    893:     return(0);
                    894: }
                    895: 
                    896: int sql_rebuild_requires(void) {
                    897:     const char *query =
                    898: "CREATE TABLE Requires ( \n\
                    899:     ID int(11) NOT NULL, \n\
                    900:     Resource varchar(35) NOT NULL, \n\
                    901:     Rel char(2), \n\
                    902:     Value varchar(20), \n\
                    903:     UNIQUE KEY id (ID,Resource(35)), \n\
                    904:     INDEX (ID), \n\
                    905:     INDEX (Resource) \n\
                    906: )";
                    907: 
                    908:     if (mysql_query(sql,query)) {
1.21      daniel    909:        printf("sql_rebuild_requires: CREATE TABLE Requires failed %s\n",
                    910:               mysql_error(sql));
                    911:        return(-1);
                    912:     }
                    913:     return(0);
                    914: }
                    915: 
                    916: int sql_rebuild_queries(void) {
                    917:     const char *query =
                    918: "CREATE TABLE Queries ( \n\
                    919:     ID int(11) NOT NULL auto_increment,\n\
                    920:     Value varchar(50) NOT NULL, \n\
                    921:     Count int(11) NOT NULL, \n\
                    922:     Results int(11) NOT NULL, \n\
                    923:     UNIQUE KEY id (ID,Value(35)), \n\
                    924:     INDEX (ID), \n\
                    925:     INDEX (Value) \n\
                    926: )";
                    927: 
                    928:     if (mysql_query(sql,query)) {
                    929:        printf("sql_rebuild_queries: CREATE TABLE Queries failed %s\n",
1.8       veillard  930:               mysql_error(sql));
                    931:        return(-1);
                    932:     }
                    933:     return(0);
                    934: }
                    935: 
1.1       veillard  936: 
                    937: int sql_check_tables(void) {
                    938:     const char *query = "SHOW TABLES";
                    939:     MYSQL_RES *result;
                    940:     MYSQL_ROW row;
1.2       veillard  941:     int config = 0;
1.1       veillard  942:     int distribs = 0;
1.8       veillard  943:     int requires = 0;
                    944:     int provides = 0;
1.1       veillard  945:     int vendors = 0;
                    946:     int mirrors = 0;
1.2       veillard  947:     int metadata = 0;
                    948:     int packages = 0;
                    949:     int files = 0;
1.21      daniel    950:     int queries = 0;
1.36      veillard  951:     int distributions = 0;
1.2       veillard  952: 
1.1       veillard  953:     int rebuilt = 0;
                    954: 
                    955:     if (mysql_query(sql,query)) {
1.2       veillard  956:        printf("sql_check_tables: SHOW TABLES failed %s\n",
1.1       veillard  957:               mysql_error(sql));
                    958:        return(-1);
                    959:     }
                    960: 
                    961:     result = mysql_use_result(sql);
                    962:     if (result) {
                    963:        while((row = mysql_fetch_row(result)))
                    964:        {
                    965:            if (row[0] == NULL) {
                    966:                mysql_free_result(result);
                    967:                printf("sql_check_tables: SHOW TABLES returns NULL !\n");
                    968:                return(-1);
                    969:            }
1.2       veillard  970:            if (!strcmp(row[0], "Config"))
                    971:                config = 1;
1.1       veillard  972:            if (!strcmp(row[0], "Distribs"))
                    973:                distribs = 1;
                    974:            if (!strcmp(row[0], "Vendors"))
                    975:                vendors = 1;
                    976:            if (!strcmp(row[0], "Mirrors"))
                    977:                mirrors = 1;
1.2       veillard  978:            if (!strcmp(row[0], "Metadata"))
                    979:                metadata = 1;
                    980:            if (!strcmp(row[0], "Packages"))
                    981:                packages = 1;
                    982:            if (!strcmp(row[0], "Files"))
                    983:                files = 1;
1.8       veillard  984:            if (!strcmp(row[0], "Requires"))
                    985:                requires = 1;
                    986:            if (!strcmp(row[0], "Provides"))
                    987:                provides = 1;
1.21      daniel    988:            if (!strcmp(row[0], "Queries"))
                    989:                queries = 1;
1.36      veillard  990:            if (!strcmp(row[0], "Distributions"))
                    991:                distributions = 1;
1.1       veillard  992:        }
                    993:        mysql_free_result(result);
                    994:     }
                    995:     if(mysql_errno(sql)) {
                    996:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                    997:        return(-1);
                    998:     }
                    999: 
1.2       veillard 1000:     if (!config) {
                   1001:        fprintf(stderr, "Table Config disapeared: rebuilding it\n");
                   1002:        if (!sql_rebuild_config())
                   1003:            rebuilt++;
                   1004:     }
1.1       veillard 1005:     if (!vendors) {
                   1006:        fprintf(stderr, "Table Vendors disapeared: rebuilding it\n");
                   1007:        if (!sql_rebuild_vendors())
                   1008:            rebuilt++;
                   1009:     }
                   1010:     if (!distribs) {
                   1011:        fprintf(stderr, "Table Distribs disapeared: rebuilding it\n");
                   1012:        if (!sql_rebuild_distribs())
                   1013:            rebuilt++;
                   1014:     }
                   1015:     if (!mirrors) {
                   1016:        fprintf(stderr, "Table Mirrors disapeared: rebuilding it\n");
                   1017:        if (!sql_rebuild_mirrors())
                   1018:            rebuilt++;
                   1019:     }
1.2       veillard 1020:     if (!metadata) {
                   1021:        fprintf(stderr, "Table Metadata disapeared: rebuilding it\n");
                   1022:        if (!sql_rebuild_metadata())
                   1023:            rebuilt++;
                   1024:     }
                   1025:     if (!packages) {
                   1026:        fprintf(stderr, "Table Packages disapeared: rebuilding it\n");
                   1027:        if (!sql_rebuild_packages())
                   1028:            rebuilt++;
                   1029:     }
                   1030:     if (!files) {
                   1031:        fprintf(stderr, "Table Files disapeared: rebuilding it\n");
                   1032:        if (!sql_rebuild_files())
                   1033:            rebuilt++;
                   1034:     }
1.8       veillard 1035:     if (!requires) {
                   1036:        fprintf(stderr, "Table Requires disapeared: rebuilding it\n");
                   1037:        if (!sql_rebuild_requires())
                   1038:            rebuilt++;
                   1039:     }
                   1040:     if (!provides) {
                   1041:        fprintf(stderr, "Table Provides disapeared: rebuilding it\n");
                   1042:        if (!sql_rebuild_provides())
1.21      daniel   1043:            rebuilt++;
                   1044:     }
                   1045:     if (!queries) {
                   1046:        fprintf(stderr, "Table Queries disapeared: rebuilding it\n");
                   1047:        if (!sql_rebuild_queries())
1.8       veillard 1048:            rebuilt++;
                   1049:     }
1.36      veillard 1050:     if (!distributions) {
                   1051:        fprintf(stderr, "Table Distributions disapeared: rebuilding it\n");
                   1052:        if (!sql_rebuild_distributions())
                   1053:            rebuilt++;
                   1054:     }
1.1       veillard 1055:     return(rebuilt);
                   1056: }
                   1057: 
                   1058: /************************************************************************
                   1059:  *                                                                     *
                   1060:  *                     Specific rpm2html functions                     *
                   1061:  *                                                                     *
                   1062:  ************************************************************************/
                   1063: 
1.5       veillard 1064: int sql_add_dist_mirror(int distrib, const char *URL, int country) {
1.1       veillard 1065:     if (URL == NULL)
                   1066:        return(-1);
                   1067:     if (distrib < 0)
                   1068:        return(-1);
                   1069:     return(sql_blind_insert("Mirrors", "URL", URL, distrib));
                   1070: }
                   1071: 
1.5       veillard 1072: int sql_add_mirror(const char *Name, const char *URL, int country) {
1.1       veillard 1073:     int distrib;
                   1074: 
                   1075:     if ((Name == NULL) || (URL == NULL))
                   1076:        return(-1);
                   1077:     distrib = sql_read_key("Distribs", Name);
                   1078:     if (distrib < 0)
                   1079:        return(distrib);
                   1080:     return(sql_blind_insert("Mirrors", "URL", URL, distrib));
                   1081: }
                   1082: 
1.6       veillard 1083: int sql_add_file(const char *filename, int package) {
                   1084:     if ((filename == NULL) || (package <= 0))
                   1085:        return(-1);
1.7       veillard 1086:     if (strlen(filename) > 35)
                   1087:        return(0);
1.6       veillard 1088: 
                   1089:     return(sql_blind_insert("Files", "Path", filename, package));
                   1090: }
                   1091: 
1.8       veillard 1092: int sql_add_provides(int package, const char *resource) {
                   1093:     if ((resource == NULL) || (package <= 0))
                   1094:        return(-1);
                   1095:     if (strlen(resource) > 35)
                   1096:        return(0);
                   1097: 
                   1098:     return(sql_blind_insert("Provides", "Resource", resource, package));
                   1099: }
                   1100: 
1.14      veillard 1101: int sql_add_requires(int package, const char *resource, rpm_dep_flag rel,
1.8       veillard 1102:                     const char *value) {
                   1103:     int record;
                   1104:     if ((resource == NULL) || (package <= 0))
                   1105:        return(-1);
                   1106:     if (strlen(resource) > 35)
                   1107:        return(0);
                   1108: 
                   1109:     record = sql_blind_insert("Requires", "Resource", resource, package);
1.14      veillard 1110:     if ((rel != RPM2HTML_REQ_NONE) && (value != NULL) &&
                   1111:        (strlen(value) <= 50)) {
1.8       veillard 1112:        char query[SMALL_QUERY];
1.14      veillard 1113: 
                   1114:        switch (rel) {
                   1115:            case RPM2HTML_REQ_LT:
                   1116:                snprintf(query, SMALL_QUERY - 1,
                   1117:                         "UPDATE Requires SET Rel='<',Value='%s' WHERE ID=%d",
                   1118:                         value, record);
1.15      daniel   1119:                break;
1.14      veillard 1120:            case RPM2HTML_REQ_LEQ:
                   1121:                snprintf(query, SMALL_QUERY - 1,
                   1122:                         "UPDATE Requires SET Rel='<=',Value='%s' WHERE ID=%d",
                   1123:                         value, record);
1.15      daniel   1124:                break;
1.14      veillard 1125:            case RPM2HTML_REQ_GT:
                   1126:                snprintf(query, SMALL_QUERY - 1,
                   1127:                         "UPDATE Requires SET Rel='>',Value='%s' WHERE ID=%d",
                   1128:                         value, record);
1.15      daniel   1129:                break;
1.14      veillard 1130:            case RPM2HTML_REQ_GEQ:
                   1131:                snprintf(query, SMALL_QUERY - 1,
                   1132:                         "UPDATE Requires SET Rel='>=',Value='%s' WHERE ID=%d",
                   1133:                         value, record);
1.15      daniel   1134:                break;
1.14      veillard 1135:            case RPM2HTML_REQ_EQU:
                   1136:                snprintf(query, SMALL_QUERY - 1,
                   1137:                         "UPDATE Requires SET Rel='=',Value='%s' WHERE ID=%d",
                   1138:                         value, record);
1.15      daniel   1139:                break;
1.14      veillard 1140:            case RPM2HTML_REQ_NONE:
                   1141:                query[0] = 0;
                   1142:        }
1.8       veillard 1143:        query[SMALL_QUERY - 1] = 0;
                   1144:        if (mysql_query(sql,query)) {
1.38      veillard 1145:            printf("sql_add_requires: UPDATE Requires %d failed %s\n",
1.8       veillard 1146:                   record, mysql_error(sql));
                   1147:            return(record);
                   1148:        }
                   1149:     }
                   1150:     return(record);
                   1151: }
                   1152: 
1.34      veillard 1153: int sql_add_vendor(const char *Name, const char *URL, const char *Description) {
                   1154:     int id;
                   1155: 
                   1156:     if (Name == NULL)
                   1157:        return(-1);
                   1158: 
                   1159:     id = sql_get_key("Vendors", "Name", Name);
                   1160:     if (id <= 0) {
                   1161:        id = sql_blind_insert("Vendors", "Name", Name, 0);
                   1162:        if (id <= 0)
                   1163:            return(id);
                   1164:     }
                   1165:     if (URL != NULL)
                   1166:        sql_update_id("Vendors", id, "URL", URL);
                   1167:     if (Description != NULL)
                   1168:        sql_update_id("Vendors", id,
                   1169:                                   "Description", Description);
                   1170:     
                   1171:     return(id);
                   1172: }
                   1173: 
1.36      veillard 1174: int sql_add_distribution(const char *Name, const char *URL, const char *Description) {
                   1175:     int id;
                   1176: 
                   1177:     if (Name == NULL)
                   1178:        return(-1);
                   1179: 
                   1180:     id = sql_get_key("Distributions", "Name", Name);
                   1181:     if (id <= 0) {
                   1182:        id = sql_blind_insert("Distributions", "Name", Name, 0);
                   1183:        if (id <= 0)
                   1184:            return(id);
                   1185:     }
                   1186:     if (URL != NULL)
                   1187:        sql_update_id("Distributions", id, "URL", URL);
                   1188:     if (Description != NULL)
                   1189:        sql_update_id("Distributions", id,
                   1190:                                   "Description", Description);
                   1191:     
                   1192:     return(id);
                   1193: }
                   1194: 
1.34      veillard 1195: 
1.5       veillard 1196: int sql_add_package(const char *filename,
1.2       veillard 1197:        const char *Name, const char *Version, const char *Release,
1.6       veillard 1198:        const char *Arch,
                   1199:        int dist, const char *URL, const char *URLSrc, int vendor,
1.2       veillard 1200:        const char *Packager, const char *Category, const char *Summary,
1.33      veillard 1201:        const char *Description, const char *Copyright, int Date,
1.36      veillard 1202:        const char *Os, const char *Distribution) {
1.2       veillard 1203:     int id;
                   1204:     int nb_fields = 0;
1.35      veillard 1205:     char installed_filename[500];
1.2       veillard 1206: 
1.35      veillard 1207:     if (filename == NULL) {
                   1208:        sprintf(installed_filename, "localbase/%s-%s-%s.%s.rpm",
                   1209:                Name,Version,Release,Arch);
                   1210:        filename = installed_filename;
                   1211:     }
1.6       veillard 1212: 
                   1213:     if (dist < 0)
1.2       veillard 1214:        return(-1);
1.6       veillard 1215:     if ((Name == NULL) || (Version == NULL) || (Release == NULL) ||
                   1216:        (Arch == NULL))
                   1217:        return(-1);
                   1218: 
                   1219:     id = sql_get_key("Packages", "filename", filename);
1.2       veillard 1220:     if (id <= 0)
                   1221:        return(-1);
                   1222:     nb_fields = 1;
1.8       veillard 1223: 
                   1224:     if (rpm2htmlVerbose > 1)
                   1225:        printf("Adding %s ID %d\n", filename, id);
                   1226: 
1.2       veillard 1227:     if (Name != NULL)
1.6       veillard 1228:        nb_fields += sql_update_id("Packages", id, "Name", Name);
1.2       veillard 1229:     if (Version != NULL)
                   1230:        nb_fields += sql_update_id("Packages", id, "Version", Version);
                   1231:     if (Release != NULL)
                   1232:        nb_fields += sql_update_id("Packages", id, "Release", Release);
1.6       veillard 1233:     if (Release != NULL)
                   1234:        nb_fields += sql_update_id("Packages", id, "Arch", Arch);
1.2       veillard 1235:     if (Category != NULL)
                   1236:        nb_fields += sql_update_id("Packages", id, "Category", Category);
                   1237:     if (URL != NULL)
                   1238:        nb_fields += sql_update_id("Packages", id, "URL", URL);
                   1239:     if (URLSrc != NULL)
                   1240:        nb_fields += sql_update_id("Packages", id, "URLSrc", URLSrc);
1.17      veillard 1241:     if (dist >= 0) {
                   1242:        char str[30];
                   1243:        snprintf(str, 30, "%d", dist);
                   1244:        str[29] = 0;
                   1245:        nb_fields += sql_update_id("Packages", id, "Dist", str);
                   1246:     }
1.38      veillard 1247:     if (Summary != NULL) {
1.2       veillard 1248:        nb_fields += sql_update_id("Packages", id, "Summary", Summary);
1.38      veillard 1249:     }
                   1250:     if (Description != NULL) {
1.2       veillard 1251:        nb_fields += sql_update_id("Packages", id,
                   1252:                                   "Description", Description);
1.38      veillard 1253:     }
1.2       veillard 1254:     if (Copyright != NULL)
                   1255:        nb_fields += sql_update_id("Packages", id, "Copyright", Copyright);
1.25      veillard 1256:     if (Date != 0) {
                   1257:        char str[30];
                   1258:        snprintf(str, 30, "%d", Date);
                   1259:        str[29] = 0;
                   1260:        nb_fields += sql_update_id("Packages", id, "Date", str);
                   1261:     }
1.38      veillard 1262:     if (Os != NULL) {
1.33      veillard 1263:        nb_fields += sql_update_id("Packages", id, "Os", Os);
1.38      veillard 1264:     }
1.34      veillard 1265:     if (Packager != NULL) {
                   1266:        char str[30];
1.35      veillard 1267:        int packager = sql_add_vendor(Packager, NULL, NULL);
1.34      veillard 1268: 
1.35      veillard 1269:        if (packager > 0) {
                   1270:            snprintf(str, 30, "%d", packager);
1.34      veillard 1271:            str[29] = 0;
1.35      veillard 1272:            nb_fields += sql_update_id("Packages", id, "Packager", str);
1.34      veillard 1273:        }
                   1274:     }
1.36      veillard 1275:     if (Distribution != NULL) {
                   1276:        char str[30];
                   1277:        int packager = sql_add_distribution(Distribution, NULL, NULL);
                   1278: 
                   1279:        if (packager > 0) {
                   1280:            snprintf(str, 30, "%d", packager);
                   1281:            str[29] = 0;
                   1282:            nb_fields += sql_update_id("Packages", id, "Vendor", str);
                   1283:        }
                   1284:     }
                   1285:     /***************
                   1286:     if (vendor > 0) {
                   1287:        char str[30];
                   1288:        snprintf(str, 30, "%d", vendor);
                   1289:        str[29] = 0;
                   1290:        nb_fields += sql_update_id("Packages", id, "Vendor", str);
                   1291:     }
                   1292:      ***************/
1.2       veillard 1293:     
1.6       veillard 1294:     return(id);
1.17      veillard 1295: }
                   1296: 
                   1297: int sql_get_distrib_by_name(const char *Name) {
                   1298:     int ret;
                   1299: 
                   1300:     if (Name == NULL)
                   1301:        return(-1);
                   1302:     ret = sql_read_key("Distribs", Name);
                   1303: 
1.18      daniel   1304: #ifdef SQL_DEBUG
1.17      veillard 1305: fprintf(stderr, "sql_get_distrib_by_name(%s) => %d\n", Name, ret);
1.18      daniel   1306: #endif
1.17      veillard 1307: 
                   1308:     return(ret);
                   1309: }
                   1310: 
                   1311: int sql_get_distrib_by_directory(const char *Directory) {
                   1312:     int ret;
                   1313: 
                   1314:     if (Directory == NULL)
                   1315:        return(-1);
                   1316: 
                   1317:     ret = sql_get_key("Distribs", "Directory", Directory);
                   1318: 
1.18      daniel   1319: #ifdef SQL_DEBUG
1.17      veillard 1320: fprintf(stderr, "sql_get_distrib_by_directory(%s) => %d\n", Directory, ret);
1.18      daniel   1321: #endif
1.17      veillard 1322: 
                   1323:     return(ret);
1.2       veillard 1324: }
                   1325: 
1.5       veillard 1326: int sql_add_distrib(const char *Name, const char *Vendor,
1.2       veillard 1327:        const char *Directory, const char *Path, const char *URL,
1.9       veillard 1328:        const char *URLSrc, const char *Description,
                   1329:        const char *Html, const char *Color) {
1.1       veillard 1330:     int id, vendor;
                   1331:     int nb_fields = 0;
                   1332:     char VendorStr[15];
                   1333: 
                   1334:     if (Name == NULL)
                   1335:        return(-1);
                   1336: 
1.6       veillard 1337:     id = sql_get_key("Distribs", "Name", Name);
1.1       veillard 1338:     nb_fields = 1;
                   1339:     if (Vendor != NULL) {
1.6       veillard 1340:        vendor = sql_get_key("Vendors", "Name", Vendor);
1.1       veillard 1341:        sprintf(VendorStr, "%d", vendor);
                   1342:        nb_fields += sql_update_id("Distribs", id, "Vendor", VendorStr);
                   1343:     }
1.2       veillard 1344:     if (Directory != NULL)
                   1345:        nb_fields += sql_update_id("Distribs", id, "Directory", Directory);
1.1       veillard 1346:     if (Path != NULL)
                   1347:        nb_fields += sql_update_id("Distribs", id, "Path", Path);
                   1348:     if (URL != NULL)
                   1349:        nb_fields += sql_update_id("Distribs", id, "URL", URL);
                   1350:     if (URLSrc != NULL)
                   1351:        nb_fields += sql_update_id("Distribs", id, "URLSrc", URLSrc);
1.9       veillard 1352:     if (Html != NULL)
                   1353:        nb_fields += sql_update_id("Distribs", id, "Html", Html);
                   1354:     if (Color != NULL)
                   1355:        nb_fields += sql_update_id("Distribs", id, "Color", Color);
1.1       veillard 1356:     if (Description != NULL)
                   1357:        nb_fields += sql_update_id("Distribs", id,
                   1358:                                   "Description", Description);
                   1359:     
                   1360:     return(nb_fields);
                   1361: }
                   1362: 
1.5       veillard 1363: void sql_add_config_info(const char *name, const char *value) {
1.2       veillard 1364:     sql_update("Config", name, "Value", value);
                   1365: }
                   1366: 
1.5       veillard 1367: void sql_add_metadata_base(const char *URL) {
1.2       veillard 1368:     sql_blind_insert("Metadata", "URL", URL, -1);
                   1369: }
                   1370: 
1.6       veillard 1371: /************************************************************************
                   1372:  *                                                                     *
1.8       veillard 1373:  *                     Cleanup functions                               *
                   1374:  *                                                                     *
                   1375:  ************************************************************************/
                   1376: 
                   1377: int sql_remove_package(int id) {
                   1378:     char query[SMALL_QUERY];
                   1379: 
                   1380:     if (id <= 0)
                   1381:        return(-1);
                   1382: 
                   1383:     /*
                   1384:      * remove the ID from the package list
                   1385:      */
                   1386:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Packages WHERE ID=%d", id);
                   1387:     query[SMALL_QUERY - 1] = 0;
                   1388:     if (mysql_query(sql,query)) {
1.38      veillard 1389:        printf("sql_remove_package: DELETE package %d failed %s\n", id, mysql_error(sql));
1.8       veillard 1390:        return(-1);
                   1391:     }
                   1392:     if(mysql_errno(sql)) {
                   1393:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1394:        return(-1);
                   1395:     }
                   1396: 
                   1397:     /*
                   1398:      * remove the associated files from the Files list
                   1399:      */
                   1400:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Files WHERE ID=%d", id);
                   1401:     query[SMALL_QUERY - 1] = 0;
                   1402:     if (mysql_query(sql,query)) {
1.38      veillard 1403:        printf("sql_remove_package: DELETE Files %d failed %s\n", id, mysql_error(sql));
1.8       veillard 1404:        return(-1);
                   1405:     }
                   1406:     if(mysql_errno(sql)) {
                   1407:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1408:        return(-1);
                   1409:     }
                   1410: 
                   1411:     /*
                   1412:      * remove the associated Provides entries
                   1413:      */
                   1414:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Provides WHERE ID=%d", id);
                   1415:     query[SMALL_QUERY - 1] = 0;
                   1416:     if (mysql_query(sql,query)) {
1.38      veillard 1417:        printf("sql_remove_package: DELETE Provides %d failed %s\n", id, mysql_error(sql));
1.8       veillard 1418:        return(-1);
                   1419:     }
                   1420:     if(mysql_errno(sql)) {
                   1421:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1422:        return(-1);
                   1423:     }
                   1424: 
                   1425:     /*
                   1426:      * remove the associated Requires entries
                   1427:      */
                   1428:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Requires WHERE ID=%d", id);
                   1429:     query[SMALL_QUERY - 1] = 0;
                   1430:     if (mysql_query(sql,query)) {
1.38      veillard 1431:        printf("sql_remove_package: DELETE Requires %d failed %s\n", id, mysql_error(sql));
1.8       veillard 1432:        return(-1);
                   1433:     }
                   1434:     if(mysql_errno(sql)) {
                   1435:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1436:        return(-1);
                   1437:     }
                   1438: 
                   1439:     return(-1);
                   1440: }
                   1441: 
                   1442: int sql_check_packages(void) {
                   1443:     MYSQL_RES *result;
                   1444:     MYSQL_ROW row;
1.20      daniel   1445:     char *query = "SELECT filename,ID FROM Packages";
1.8       veillard 1446:     struct stat buf;
                   1447:     int id;
1.22      daniel   1448:     int ids[2500]; /* Do not remove more than 2500 package per run */
1.8       veillard 1449:     int index;
                   1450:     int total = 0;
                   1451: 
                   1452:     if (rpm2htmlVerbose)
                   1453:        printf("Database cleanup\n");
                   1454:     index = 0;
                   1455:     /*
                   1456:      * Search first for the ID if it already exists
                   1457:      */
                   1458:     if (mysql_query(sql,query)) {
                   1459:        printf("sql_check_packages: SELECT from Packages failed: %s\n",
                   1460:               mysql_error(sql));
                   1461:        return(-1);
                   1462:     }
                   1463: 
                   1464:     result = mysql_use_result(sql);
                   1465:     if (result) {
                   1466:        while((row = mysql_fetch_row(result)))
                   1467:        {
                   1468:            if ((row[0] == NULL) || (row[1] == NULL)) {
                   1469:                printf("sql_check_packages: Path or ID is NULL !\n");
                   1470:                continue;
                   1471:            }
1.35      veillard 1472:            if (!strncmp(row[0], "localbase", 9))
                   1473:                continue;
                   1474: 
1.8       veillard 1475:            if ((stat(row[0], &buf) < 0) || (buf.st_size < 50)) {
                   1476:                /*
                   1477:                 * Need to remove the package from the database.
                   1478:                 */
                   1479:                if (sscanf(row[1], "%d", &id) != 1) {
                   1480:                    printf("sql_check_packages: ID non numeric %s\n", row[1]);
                   1481:                    continue;
                   1482:                }
                   1483:                ids[index++] = id;
1.20      daniel   1484:                if (rpm2htmlVerbose)
1.8       veillard 1485:                    printf("Removing %s ID %d\n", row[0], id);
1.22      daniel   1486:                if (index >= 2500)
1.8       veillard 1487:                    break;
                   1488:            }
                   1489:        }
                   1490:        mysql_free_result(result);
                   1491:     }
                   1492:     if(mysql_errno(sql)) {
                   1493:        fprintf(stderr, "sql_update Error: %s\n", mysql_error(sql));
                   1494:        return(-1);
                   1495:     }
                   1496: 
                   1497:     /*
                   1498:      * Do the cleanup.
                   1499:      */
1.20      daniel   1500:     if (rpm2htmlVerbose)
                   1501:        printf("Database cleanup : removing %d entries...\n", index);
1.8       veillard 1502:     for (id = 0;id < index;id++) {
                   1503:        sql_remove_package(ids[id]);
                   1504:     }
                   1505: 
1.34      veillard 1506:     printf("Database cleanup : removed %d entries\n", index);
1.8       veillard 1507:     return(total);
                   1508: }
                   1509: 
                   1510: /************************************************************************
1.26      veillard 1511:  *                                                                     *
                   1512:  *                     Package lists extraction                        *
                   1513:  *                                                                     *
                   1514:  ************************************************************************/
                   1515: int sqlDirListInitialized = 0;
                   1516: rpmDirPtr sqlDirList[SQL_MAX_DISTRIBS];
1.35      veillard 1517: int sqlVendorListInitialized = 0;
                   1518: int sqlVendorListLen;
                   1519: char **sqlVendorList;
1.36      veillard 1520: int sqlDistributionListInitialized = 0;
                   1521: int sqlDistributionListLen;
                   1522: char **sqlDistributionList;
1.40    ! veillard 1523: int sqlResourceListInitialized = 0;
        !          1524: int sqlResourceListLen = 0;
        !          1525: int sqlResourceListMax = 0;
        !          1526: char **sqlResourceList;
        !          1527: 
        !          1528: char *
        !          1529: sqlRpmAnalyzeResourceRow(MYSQL_ROW row) {
        !          1530:     const char *name;
        !          1531:     char **tmp, *ret;
        !          1532: 
        !          1533:     if (row == NULL)
        !          1534:        return(NULL);
        !          1535:     name = row[0];
        !          1536:     if (name == NULL)
        !          1537:        return(NULL);
        !          1538: 
        !          1539:     if (sqlResourceListLen >= sqlResourceListMax) {
        !          1540:        sqlResourceListMax *= 2;
        !          1541:        tmp = (char **) debugRealloc(sqlResourceList,
        !          1542:                                     (sqlResourceListMax) * sizeof(char *));
        !          1543:        if (sqlResourceList == NULL) {
        !          1544:            fprintf(stderr, "sqlInitSqlResourceList Error: out of memory\n");
        !          1545:            return(NULL);
        !          1546:        }
        !          1547:        sqlResourceList = tmp;
        !          1548:     }
        !          1549: 
        !          1550:     ret = sqlResourceList[sqlResourceListLen++] = debugStrdup(name);
        !          1551:     return(ret);
        !          1552: }
        !          1553: 
        !          1554: void
        !          1555: sqlInitSqlResourceList(void) {
        !          1556:     MYSQL_RES *result;
        !          1557:     MYSQL_ROW row;
        !          1558:     char *query;
        !          1559:     int i;
        !          1560: 
        !          1561:     if (sqlResourceListInitialized != 0)
        !          1562:        return;
        !          1563: 
        !          1564:     if (rpm2htmlVerbose)
        !          1565:        printf("sqlInitSqlResourceList query\n");
        !          1566: 
        !          1567:     /*
        !          1568:      * Allocate the array
        !          1569:      */
        !          1570:     sqlResourceListLen = 0;
        !          1571:     sqlResourceListMax = 1000;
        !          1572:     sqlResourceList = (char **) debugMalloc((sqlResourceListMax) *
        !          1573:                                            sizeof(char *));
        !          1574:     if (sqlResourceList == NULL) {
        !          1575:        fprintf(stderr, "sqlInitSqlResourceList Error: out of memory\n");
        !          1576:        return;
        !          1577:     }
        !          1578:     
        !          1579:     /*
        !          1580:      * query the database for the values
        !          1581:      */
        !          1582:     query = "select Resource from Provides group by Resource";
        !          1583: 
        !          1584:     if (mysql_query(sql,query)) {
        !          1585:        printf("sqlInitSqlResourceList: SELECT from Provides failed: %s\n",
        !          1586:               mysql_error(sql));
        !          1587:        return;
        !          1588:     }
        !          1589: 
        !          1590:     i = 0;
        !          1591:     result = mysql_use_result(sql);
        !          1592:     if (result) {
        !          1593:        while((row = mysql_fetch_row(result)))
        !          1594:        {
        !          1595:            if (sqlRpmAnalyzeResourceRow(row) != NULL)
        !          1596:                i++;
        !          1597:        }
        !          1598:        mysql_free_result(result);
        !          1599:     }
        !          1600:     if(mysql_errno(sql)) {
        !          1601:        fprintf(stderr, "sqlInitSqlResourceList Error: %s\n", mysql_error(sql));
        !          1602:        return;
        !          1603:     }
        !          1604: 
        !          1605: 
        !          1606:     if (rpm2htmlVerbose)
        !          1607:        printf("sqlInitSqlResourceList done: %d entries\n", i);
        !          1608:     sqlResourceListInitialized++;
        !          1609:     return;
        !          1610: }
1.36      veillard 1611: 
                   1612: char *
                   1613: sqlRpmAnalyzeDistributionRow(MYSQL_ROW row) {
                   1614:     const char *id;
                   1615:     const char *name;
                   1616:     char **tmp;
                   1617:     int distribution;
                   1618: 
                   1619:     if (row == NULL)
                   1620:        return(NULL);
                   1621:     id = row[0];
                   1622:     name = row[1];
                   1623:     if ((id == NULL) || (name == NULL))
                   1624:        return(NULL);
                   1625: 
                   1626:     if (sscanf(id, "%d", &distribution) != 1)
                   1627:        return(NULL);
                   1628:     if ((distribution <= 0) || (distribution > 100000)) {
                   1629:        fprintf(stderr, "Dist number out of range %d\n", distribution);
                   1630:        return(NULL);
                   1631:     }
                   1632:     if (distribution >= sqlDistributionListLen) {
                   1633:        int i = sqlDistributionListLen;
                   1634:        sqlDistributionListLen = distribution + 100;
                   1635:        tmp = (char **) debugRealloc(sqlDistributionList,
                   1636:                                     (sqlDistributionListLen) * sizeof(char *));
                   1637:        if (sqlDistributionList == NULL) {
                   1638:            fprintf(stderr, "sqlInitSqlDistributionList Error: out of memory\n");
                   1639:            return(NULL);
                   1640:        }
                   1641:        sqlDistributionList = tmp;
                   1642:        memset(&sqlDistributionList[i], 0, sizeof(char *) * (sqlDistributionListLen - i));
                   1643:     }
                   1644: 
                   1645:     sqlDistributionList[distribution] = debugStrdup(name);
                   1646:     return(sqlDistributionList[distribution]);
                   1647: }
                   1648: 
                   1649: void
                   1650: sqlInitSqlDistributionList(void) {
                   1651:     MYSQL_RES *result;
                   1652:     MYSQL_ROW row;
                   1653:     char *query;
                   1654:     int i;
                   1655: 
                   1656:     if (sqlDistributionListInitialized != 0)
                   1657:        return;
                   1658: 
                   1659:     if (rpm2htmlVerbose)
                   1660:        printf("sqlInitSqlDistributionList query\n");
                   1661: 
                   1662:     /*
                   1663:      * Allocate the array
                   1664:      */
                   1665:     sqlDistributionListLen = 100;
                   1666:     sqlDistributionList = (char **) debugMalloc((sqlDistributionListLen) * sizeof(char *));
                   1667:     if (sqlDistributionList == NULL) {
                   1668:        fprintf(stderr, "sqlInitSqlDistributionList Error: out of memory\n");
                   1669:        return;
                   1670:     }
1.40    ! veillard 1671:     memset(sqlDistributionList, 0, (sqlDistributionListLen) * sizeof(char *));
        !          1672: 
1.36      veillard 1673:     /*
                   1674:      * query the database for the values
                   1675:      */
                   1676:     query = "select ID,Name from Distributions";
                   1677: 
                   1678:     if (mysql_query(sql,query)) {
                   1679:        printf("sqlInitSqlDistributionList: SELECT from Distributions failed: %s\n",
                   1680:               mysql_error(sql));
                   1681:        return;
                   1682:     }
                   1683: 
                   1684:     i = 0;
                   1685:     result = mysql_use_result(sql);
                   1686:     if (result) {
                   1687:        while((row = mysql_fetch_row(result)))
                   1688:        {
                   1689:            if (sqlRpmAnalyzeDistributionRow(row) != NULL)
                   1690:                i++;
                   1691:        }
                   1692:        mysql_free_result(result);
                   1693:     }
                   1694:     if(mysql_errno(sql)) {
                   1695:        fprintf(stderr, "sqlInitSqlDistributionList Error: %s\n", mysql_error(sql));
                   1696:        return;
                   1697:     }
                   1698: 
                   1699: 
                   1700:     if (rpm2htmlVerbose)
                   1701:        printf("sqlInitSqlDistributionList done: %d entries\n", i);
                   1702:     sqlDistributionListInitialized++;
                   1703:     return;
                   1704: }
                   1705: 
1.35      veillard 1706: 
                   1707: char *
                   1708: sqlRpmAnalyzeVendorRow(MYSQL_ROW row) {
                   1709:     const char *id;
                   1710:     const char *name;
                   1711:     char **tmp;
                   1712:     int vendor;
                   1713: 
                   1714:     if (row == NULL)
                   1715:        return(NULL);
                   1716:     id = row[0];
                   1717:     name = row[1];
                   1718:     if ((id == NULL) || (name == NULL))
                   1719:        return(NULL);
                   1720: 
                   1721:     if (sscanf(id, "%d", &vendor) != 1)
                   1722:        return(NULL);
                   1723:     if ((vendor <= 0) || (vendor > 100000)) {
                   1724:        fprintf(stderr, "Dist number out of range %d\n", vendor);
                   1725:        return(NULL);
                   1726:     }
                   1727:     if (vendor >= sqlVendorListLen) {
                   1728:        int i = sqlVendorListLen;
                   1729:        sqlVendorListLen = vendor + 100;
                   1730:        tmp = (char **) debugRealloc(sqlVendorList,
                   1731:                                     (sqlVendorListLen) * sizeof(char *));
                   1732:        if (sqlVendorList == NULL) {
                   1733:            fprintf(stderr, "sqlInitSqlVendorList Error: out of memory\n");
                   1734:            return(NULL);
                   1735:        }
                   1736:        sqlVendorList = tmp;
                   1737:        memset(&sqlVendorList[i], 0, sizeof(char *) * (sqlVendorListLen - i));
                   1738:     }
                   1739: 
                   1740:     sqlVendorList[vendor] = debugStrdup(name);
                   1741:     return(sqlVendorList[vendor]);
                   1742: }
                   1743: 
                   1744: void
                   1745: sqlInitSqlVendorList(void) {
                   1746:     MYSQL_RES *result;
                   1747:     MYSQL_ROW row;
                   1748:     char *query;
                   1749:     int i;
                   1750: 
                   1751:     if (sqlVendorListInitialized != 0)
                   1752:        return;
                   1753: 
                   1754:     if (rpm2htmlVerbose)
                   1755:        printf("sqlInitSqlVendorList query\n");
                   1756: 
                   1757:     /*
                   1758:      * Allocate the array
                   1759:      */
                   1760:     sqlVendorListLen = 100;
                   1761:     sqlVendorList = (char **) debugMalloc((sqlVendorListLen) * sizeof(char *));
                   1762:     if (sqlVendorList == NULL) {
                   1763:        fprintf(stderr, "sqlInitSqlVendorList Error: out of memory\n");
                   1764:        return;
                   1765:     }
                   1766:     
                   1767:     /*
                   1768:      * query the database for the values
                   1769:      */
                   1770:     query = "select ID,Name from Vendors";
                   1771: 
                   1772:     if (mysql_query(sql,query)) {
1.36      veillard 1773:        printf("sqlInitSqlVendorList: SELECT from Vendors failed: %s\n",
1.35      veillard 1774:               mysql_error(sql));
                   1775:        return;
                   1776:     }
                   1777: 
                   1778:     i = 0;
                   1779:     result = mysql_use_result(sql);
                   1780:     if (result) {
                   1781:        while((row = mysql_fetch_row(result)))
                   1782:        {
                   1783:            if (sqlRpmAnalyzeVendorRow(row) != NULL)
                   1784:                i++;
                   1785:        }
                   1786:        mysql_free_result(result);
                   1787:     }
                   1788:     if(mysql_errno(sql)) {
                   1789:        fprintf(stderr, "sqlInitSqlVendorList Error: %s\n", mysql_error(sql));
                   1790:        return;
                   1791:     }
                   1792: 
                   1793: 
                   1794:     if (rpm2htmlVerbose)
                   1795:        printf("sqlInitSqlVendorList done: %d entries\n", i);
                   1796:     sqlVendorListInitialized++;
                   1797:     return;
                   1798: }
1.26      veillard 1799: 
                   1800: rpmDirPtr
                   1801: sqlRpmAnalyzeDirRow(MYSQL_ROW row) {
                   1802:     rpmDirPtr ret;
                   1803:     const char *id;
                   1804:     const char *name;
                   1805:     const char *vendor;
                   1806:     const char *directory;
                   1807:     const char *path;
                   1808:     const char *url;
                   1809:     const char *urlSrc;
                   1810:     const char *html;
                   1811:     const char *color;
                   1812:     int dist;
                   1813: 
                   1814:     if (row == NULL)
                   1815:        return(NULL);
                   1816:     id = row[0];
                   1817:     name = row[1];
                   1818:     vendor = row[2];
                   1819:     directory = row[3];
                   1820:     path = row[4];
                   1821:     url = row[5];
                   1822:     urlSrc = row[6];
                   1823:     html = row[7];
                   1824:     color = row[8];
                   1825:     if ((id == NULL) || (name == NULL) ||
                   1826:         (directory == NULL) || (path == NULL) || (url == NULL))
                   1827:        return(NULL);
                   1828: 
                   1829:     if (sscanf(id, "%d", &dist) != 1)
                   1830:        return(NULL);
                   1831:     if ((dist <= 0) || (dist > SQL_MAX_DISTRIBS)) {
                   1832:        fprintf(stderr, "Dist number out of range %d\n", dist);
                   1833:        return(NULL);
                   1834:     }
                   1835: 
                   1836: 
                   1837:     ret = (rpmDirPtr) debugMalloc(sizeof(rpmDir));
                   1838:     if (ret == NULL)
                   1839:        return(NULL);
                   1840:     memset(ret, 0, sizeof(rpmDir));
                   1841:     /* Generic stuff */
1.28      daniel   1842:     if (rpm2html_dir != NULL)
1.26      veillard 1843:     ret->dir = debugStrdup(rpm2html_dir);
1.28      daniel   1844:     if (rpm2html_host != NULL)
1.26      veillard 1845:     ret->host = debugStrdup(rpm2html_host);
1.28      daniel   1846:     if (rpm2html_maint != NULL)
1.26      veillard 1847:     ret->maint = debugStrdup(rpm2html_maint);
1.28      daniel   1848:     if (rpm2html_mail != NULL)
1.26      veillard 1849:     ret->mail = debugStrdup(rpm2html_mail);
1.28      daniel   1850:     if (rpm2html_url != NULL)
1.26      veillard 1851:     ret->url = debugStrdup(rpm2html_url);
                   1852:     /* specific stuff */
                   1853:     ret->no = dist;
                   1854:     ret->rpmdir = debugStrdup(directory);
                   1855:     ret->subdir = debugStrdup(path);
                   1856:     ret->name = debugStrdup(name);
                   1857:     ret->ftp = debugStrdup(url);
                   1858:     if (color != NULL)
                   1859:        ret->color = debugStrdup(color);
1.28      daniel   1860:     else
                   1861:        ret->color = debugStrdup("#ffffff");
1.26      veillard 1862:     if (urlSrc != NULL)
                   1863:        ret->ftpsrc = debugStrdup(urlSrc);
                   1864:     return(ret);
                   1865: }
                   1866: 
                   1867: void
                   1868: sqlInitSqlDirList(void) {
1.28      daniel   1869:     char host[200];
1.26      veillard 1870:     rpmDirPtr cur;
                   1871:     MYSQL_RES *result;
                   1872:     MYSQL_ROW row;
                   1873:     char *query;
                   1874:     int i;
                   1875: 
                   1876:     if (sqlDirListInitialized != 0)
                   1877:        return;
                   1878: 
1.28      daniel   1879:     gethostname(host, sizeof(host));
                   1880:     currentTime = time(NULL);
                   1881:     rpm2html_rpm2html_thishost = &host[0];
                   1882:     readConfigSql();
                   1883:     if (rpm2html_host == NULL) {
                   1884:        rpm2html_host = strdup(rpm2html_rpm2html_thishost);
                   1885:     }
1.26      veillard 1886:     for (i = 0; i < SQL_MAX_DISTRIBS;i++)
                   1887:         sqlDirList[i] = NULL;
                   1888: 
                   1889:     if (rpm2htmlVerbose)
                   1890:        printf("sqlInitSqlDirList query\n");
                   1891: 
1.29      veillard 1892:     query = "select ID,Name,Vendor,Directory,Path,URL,URLSrc,Html,Color from Distribs";
1.26      veillard 1893: 
                   1894:     if (mysql_query(sql,query)) {
                   1895:        printf("sqlInitSqlDirList: SELECT from Packages failed: %s\n",
                   1896:               mysql_error(sql));
                   1897:        return;
                   1898:     }
                   1899: 
                   1900:     i = 0;
                   1901:     result = mysql_use_result(sql);
                   1902:     if (result) {
                   1903:        while((row = mysql_fetch_row(result)))
                   1904:        {
                   1905:            cur = sqlRpmAnalyzeDirRow(row);
                   1906:            if (cur != NULL) {
                   1907:                sqlDirList[cur->no] = cur;
                   1908:                i++;
                   1909:            }
                   1910:        }
                   1911:        mysql_free_result(result);
                   1912:     }
                   1913:     if(mysql_errno(sql)) {
                   1914:        fprintf(stderr, "sqlInitSqlDirList Error: %s\n", mysql_error(sql));
                   1915:        return;
                   1916:     }
                   1917: 
                   1918:     if (rpm2htmlVerbose)
                   1919:        printf("sqlInitSqlDirList done: %d entries\n", i);
                   1920:     sqlDirListInitialized++;
                   1921:     return;
                   1922: }
                   1923: 
                   1924: rpmDataPtr
                   1925: sqlRpmAnalyzeRow(MYSQL_ROW row) {
                   1926:     rpmDataPtr ret;
                   1927:     const char *id;
                   1928:     const char *name;
                   1929:     const char *version;
                   1930:     const char *release;
                   1931:     const char *arch;
                   1932:     const char *date;
                   1933:     const char *summary;
                   1934:     const char *filename;
                   1935:     const char *distrib;
1.30      daniel   1936:     const char *group;
1.33      veillard 1937:     const char *os;
1.35      veillard 1938:     const char *packager;
1.36      veillard 1939:     const char *vendor;
1.26      veillard 1940:     int dist;
                   1941: 
                   1942:     if (row == NULL)
                   1943:        return(NULL);
                   1944:     id = row[0];
                   1945:     name = row[1];
                   1946:     version = row[2];
                   1947:     release = row[3];
                   1948:     arch = row[4];
                   1949:     date = row[5];
                   1950:     summary = row[6];
                   1951:     filename = row[7];
                   1952:     distrib = row[8];
1.30      daniel   1953:     group = row[9];
1.33      veillard 1954:     os = row[10];
1.35      veillard 1955:     packager = row[11];
1.36      veillard 1956:     vendor = row[12];
1.26      veillard 1957:     if ((id == NULL) || (name == NULL) || (version == NULL) ||
                   1958:         (release == NULL) || (arch == NULL) || (date == NULL) ||
                   1959:        (summary == NULL) || (filename == NULL) || (distrib == NULL))
                   1960:        return(NULL);
                   1961: 
                   1962:     ret = (rpmDataPtr) debugMalloc(sizeof(rpmData));
                   1963:     if (ret == NULL)
                   1964:        return(NULL);
                   1965:     memset(ret, 0, sizeof(rpmData));
                   1966:     ret->name = debugStrdup(name);
                   1967:     ret->version = debugStrdup(version);
                   1968:     ret->release = debugStrdup(release);
                   1969:     ret->arch = debugStrdup(arch);
                   1970:     ret->summary = debugStrdup(summary);
                   1971:     ret->name = debugStrdup(name);
                   1972:     ret->filename = debugStrdup(filename);
1.33      veillard 1973:     if (os == NULL)
                   1974:        ret->os = debugStrdup("Linux");
                   1975:     else
                   1976:        ret->os = debugStrdup(os);
1.30      daniel   1977:     if (group != NULL)
                   1978:        ret->group = debugStrdup(group);
1.26      veillard 1979:     sscanf(date, "%d", (int *) &(ret->date));
1.35      veillard 1980:     if (packager != NULL) {
                   1981:        int tmp = 0;
                   1982:        sscanf(packager, "%d", (int *) &tmp);
                   1983:        if ((tmp > 0) && (tmp < sqlVendorListLen)) {
                   1984:            if (sqlVendorList[tmp] != NULL)
                   1985:                ret->vendor = debugStrdup(sqlVendorList[tmp]);
                   1986:        }
                   1987:     }
1.36      veillard 1988:     if (vendor != NULL) {
                   1989:        int tmp = 0;
                   1990:        sscanf(vendor, "%d", (int *) &tmp);
                   1991:        if ((tmp > 0) && (tmp < sqlDistributionListLen)) {
                   1992:            if (sqlVendorList[tmp] != NULL)
                   1993:                ret->distribution = debugStrdup(sqlDistributionList[tmp]);
                   1994:        }
                   1995:     }
1.35      veillard 1996:     if (ret->vendor == NULL)
                   1997:        ret->vendor =  debugStrdup("Unknown");
                   1998:     if (ret->distribution == NULL)
                   1999:        ret->distribution =  debugStrdup("Unknown");
1.26      veillard 2000:     sscanf(distrib, "%d", &dist);
                   2001:     ret->dir = sqlDirList[dist];
1.28      daniel   2002:     if ((ret->dir != NULL) && (ret->dir->rpmdir != NULL)) {
                   2003:        int len = strlen(ret->dir->rpmdir);
                   2004:        if (!strncmp(ret->filename, ret->dir->rpmdir, len)) {
                   2005:            char *start, *end;
                   2006:            start = &(ret->filename[len]);
                   2007:            while (*start == '/') start++;
                   2008:            end = &start[strlen(start) - 1];
                   2009:            while ((end >= start) && (*end != '/')) end--;
                   2010:             if (end > start) {
                   2011:                char *tmp;
                   2012:                tmp = debugMalloc((end - start) + 1);
                   2013:                if (tmp != NULL) {
                   2014:                    strncpy(tmp, start, end - start);
                   2015:                    tmp[end - start] = 0;
                   2016:                    ret->subdir = tmp;
                   2017:                }
                   2018:            }
                   2019:        }
                   2020:     }
1.26      veillard 2021:     return(ret);
                   2022: }
                   2023: 
                   2024: rpmDataPtr
                   2025: sqlRpmByDate(void) {
                   2026:     rpmDataPtr list = NULL;
                   2027:     rpmDataPtr cur, last = NULL;
                   2028:     MYSQL_RES *result;
                   2029:     MYSQL_ROW row;
                   2030:     char *query;
                   2031: 
                   2032:     sqlInitSqlDirList();
1.35      veillard 2033:     sqlInitSqlVendorList();
1.36      veillard 2034:     sqlInitSqlDistributionList();
1.26      veillard 2035:     if (rpm2htmlVerbose)
                   2036:        printf("sqlRpmByDate query\n");
                   2037: 
1.35      veillard 2038:     query = "select ID,Name,Version,Release,Arch,Date,Summary,filename,Dist,Category,Os,Packager,Vendor from Packages where Date IS NOT NULL  and Date < UNIX_TIMESTAMP() + 300000 order by Date desc limit 1000";
1.26      veillard 2039: 
                   2040:     /*
                   2041:      * Search first for the ID if it already exists
                   2042:      */
                   2043:     if (mysql_query(sql,query)) {
                   2044:        printf("sqlRpmByDate: SELECT from Packages failed: %s\n",
                   2045:               mysql_error(sql));
                   2046:        return(NULL);
                   2047:     }
                   2048: 
                   2049:     result = mysql_use_result(sql);
                   2050:     if (result) {
                   2051:        while((row = mysql_fetch_row(result)))
                   2052:        {
                   2053:            cur = sqlRpmAnalyzeRow(row);
                   2054:            if (cur != NULL) {
                   2055:                if (last == NULL)
                   2056:                    list = cur;
                   2057:                else
                   2058:                    last->next = cur;
                   2059:                last = cur;
                   2060:            }
                   2061:        }
                   2062:        mysql_free_result(result);
                   2063:     }
                   2064:     if(mysql_errno(sql)) {
                   2065:        fprintf(stderr, "sqlRpmByDate Error: %s\n", mysql_error(sql));
                   2066:        return(NULL);
                   2067:     }
                   2068: 
                   2069:     if (rpm2htmlVerbose)
                   2070:        printf("sqlRpmByDate done\n");
                   2071:     return(list);
                   2072: }
                   2073: 
1.29      veillard 2074: rpmDataPtr
                   2075: sqlRpmAll(void) {
                   2076:     rpmDataPtr list = NULL;
                   2077:     rpmDataPtr cur, last = NULL;
                   2078:     MYSQL_RES *result;
                   2079:     MYSQL_ROW row;
                   2080:     char *query;
                   2081: 
                   2082:     sqlInitSqlDirList();
1.35      veillard 2083:     sqlInitSqlVendorList();
1.36      veillard 2084:     sqlInitSqlDistributionList();
1.29      veillard 2085:     if (rpm2htmlVerbose)
                   2086:        printf("sqlRpmAll query\n");
                   2087: 
1.35      veillard 2088:     query = "select ID,Name,Version,Release,Arch,Date,Summary,filename,Dist,Category,Os,Packager,Vendor from Packages";
1.29      veillard 2089: 
                   2090:     /*
                   2091:      * Search first for the ID if it already exists
                   2092:      */
                   2093:     if (mysql_query(sql,query)) {
                   2094:        printf("sqlRpmByDate: SELECT from Packages failed: %s\n",
                   2095:               mysql_error(sql));
                   2096:        return(NULL);
                   2097:     }
                   2098: 
                   2099:     result = mysql_use_result(sql);
                   2100:     if (result) {
                   2101:        while((row = mysql_fetch_row(result)))
                   2102:        {
                   2103:            cur = sqlRpmAnalyzeRow(row);
                   2104:            if (cur != NULL) {
                   2105:                if (last == NULL)
                   2106:                    list = cur;
                   2107:                else
                   2108:                    last->next = cur;
                   2109:                last = cur;
1.32      daniel   2110: 
                   2111:                rpmAddSoftware(cur);
1.29      veillard 2112:            }
                   2113:        }
                   2114:        mysql_free_result(result);
                   2115:     }
                   2116:     if(mysql_errno(sql)) {
                   2117:        fprintf(stderr, "sqlRpmByDate Error: %s\n", mysql_error(sql));
                   2118:        return(NULL);
                   2119:     }
                   2120: 
                   2121:     if (rpm2htmlVerbose)
                   2122:        printf("sqlRpmAll done\n");
                   2123:     return(list);
                   2124: }
                   2125: 
1.26      veillard 2126: /************************************************************************
1.8       veillard 2127:  *                                                                     *
1.6       veillard 2128:  *                     Export functions                                *
                   2129:  *                                                                     *
                   2130:  ************************************************************************/
                   2131: 
                   2132: void sql_show_config(void) {
                   2133:     MYSQL_RES *result;
                   2134:     MYSQL_ROW row;
1.8       veillard 2135:     int id, i;
                   2136:     int index = 0;
                   2137:     int ids[500];
                   2138:     char query[SMALL_QUERY];
1.6       veillard 2139: 
                   2140: 
1.8       veillard 2141:     printf(";\n; Configuration file for rpm2html\n");
                   2142:     printf("; http://rpmfind.net/linux/rpm2html/\n;\n\n");
                   2143:     mysql_query(sql,"SELECT Name,Value FROM Config");
1.6       veillard 2144:     result = mysql_use_result(sql);
                   2145: 
                   2146:     while((row = mysql_fetch_row(result)))
                   2147:     {
1.8       veillard 2148:        if (row[0] == NULL) {
                   2149:            printf("\n");
                   2150:        } else {
                   2151:            if (!strcmp(row[0], "maint"))
                   2152:                printf("; maintainer of the local rpm mirror\n");
                   2153:            else if (!strcmp(row[0], "mail"))
                   2154:                printf("; mail for the maintainer\n");
                   2155:            else if (!strcmp(row[0], "dir"))
                   2156:                 printf("; Directory to store the HTML pages produced\n");
                   2157:            else if (!strcmp(row[0], "url"))
                   2158:                 printf("; The relative URL for front pages\n");
                   2159:            else if (!strcmp(row[0], "header"))
                   2160:                 printf("; Extra link in the navigation bar\n");
                   2161:            else if (!strcmp(row[0], "html"))
                   2162:                 printf("; Export the local packages in HTML format\n");
                   2163:            else if (!strcmp(row[0], "tree"))
                   2164:                 printf("; Build the tree for the distributions\n");
                   2165:            else if (!strcmp(row[0], "rdf"))
                   2166:                 printf("; Export the local packages in RDF format\n");
                   2167:            else if (!strcmp(row[0], "rdf_dir"))
                   2168:                 printf("; Directory to store the RDf tree\n");
                   2169:            else if (!strcmp(row[0], "rdf_resources"))
                   2170:                 printf("; Compile a list of resources in RDF format\n");
                   2171:            else if (!strcmp(row[0], "rdf_resources_dir"))
                   2172:                 printf("; Directory to store the RDf resources tree\n");
                   2173: 
1.6       veillard 2174:            if (row[1] == NULL)
1.8       veillard 2175:                printf("%s\n\n", row[0]);
1.6       veillard 2176:            else
1.8       veillard 2177:                printf("%s=%s\n\n", row[0], row[1]);
                   2178:        }
                   2179:     }
                   2180:     mysql_free_result(result);
                   2181:     if(mysql_errno(sql)) {
                   2182:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2183:     }
                   2184: 
                   2185:     /*
                   2186:      * Dump the Metadata
                   2187:      */
                   2188:     printf(";\n; The metadata mirrors list\n;\n\n[metadata]\n");
                   2189:     mysql_query(sql,"SELECT URL FROM Metadata");
                   2190:     result = mysql_use_result(sql);
                   2191: 
                   2192:     while((row = mysql_fetch_row(result)))
                   2193:     {
                   2194:        if (row[0] != NULL) {
                   2195:            printf("mirror=%s\n", row[0]);
1.6       veillard 2196:        }
                   2197:     }
1.8       veillard 2198:     mysql_free_result(result);
1.6       veillard 2199:     if(mysql_errno(sql)) {
                   2200:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2201:     }
                   2202: 
1.8       veillard 2203:     /*
                   2204:      * Dump the distributions informations
                   2205:      * 1/ collect the list of IDs for the distribs
                   2206:      */
                   2207:     printf("\n\n;\n; The distribution list\n;\n\n");
                   2208:     mysql_query(sql,"SELECT ID FROM Distribs");
                   2209:     result = mysql_use_result(sql);
                   2210: 
                   2211:     while((row = mysql_fetch_row(result)))
                   2212:     {
                   2213:        if (row[0] != NULL) {
                   2214:            if (sscanf(row[0], "%d", &id) == 1) {
                   2215:                ids[index++] = id;
                   2216:            }
                   2217:        }
                   2218:     }
                   2219:     mysql_free_result(result);
                   2220: 
                   2221:     /*
                   2222:      * Dump each distribution separately.
                   2223:      */
                   2224:     for (i = 0;i < index;i++) {
                   2225: 
                   2226:        snprintf(query, SMALL_QUERY - 1,
1.10      veillard 2227:  "SELECT Directory,Name,Vendor,Path,URL,URLSrc,Description,Html,Color \
1.8       veillard 2228:                  FROM Distribs WHERE ID=%d", ids[i]);
                   2229:        query[SMALL_QUERY - 1] = 0;
                   2230:        if (mysql_query(sql,query)) {
                   2231:            printf("sql_show_config: SELECT Distrib %d failed: %s\n",
                   2232:                   ids[i], mysql_error(sql));
                   2233:            continue;
                   2234:        }
                   2235: 
                   2236:        result = mysql_use_result(sql);
                   2237:        if (result) {
                   2238:            while((row = mysql_fetch_row(result)))
                   2239:            {
                   2240:                if (row[0] == NULL)
                   2241:                    break;
                   2242:                printf("[%s]\n", row[0]);
                   2243:                if (row[1] != NULL)
                   2244:                    printf("name=%s\n", row[1]);
                   2245:                if (row[3] != NULL)
                   2246:                    printf("subdir=%s\n", row[3]);
                   2247:                if (row[4] != NULL)
                   2248:                    printf("ftp=%s\n", row[4]);
                   2249:                if (row[5] != NULL)
                   2250:                    printf("ftpsrc=%s\n", row[5]);
1.10      veillard 2251:                if (row[7] != NULL)
                   2252:                    printf("html=%s\n", row[7]);
                   2253:                if (row[8] != NULL)
                   2254:                    printf("color=%s\n", row[8]);
1.8       veillard 2255:            }
                   2256:        }
                   2257:        mysql_free_result(result);
1.12      veillard 2258: 
                   2259:        /*
                   2260:         * Extract the mirrors for this distribution.
                   2261:         */
                   2262:        snprintf(query, SMALL_QUERY - 1,
                   2263:                 "SELECT URL FROM Mirrors WHERE ID=%d", ids[i]);
                   2264:        query[SMALL_QUERY - 1] = 0;
                   2265:        if (mysql_query(sql,query)) {
                   2266:            printf("sql_show_config: SELECT Mirrors %d failed: %s\n",
                   2267:                   ids[i], mysql_error(sql));
                   2268:            printf("\n\n");
                   2269:            continue;
                   2270:        }
                   2271:        result = mysql_use_result(sql);
                   2272:        if (result) {
                   2273:            while((row = mysql_fetch_row(result)))
                   2274:            {
                   2275:                if (row[0] == NULL)
                   2276:                    continue;
                   2277:                printf("mirror=%s\n", row[0]);
                   2278:            }
                   2279:        }
                   2280:        mysql_free_result(result);
                   2281: 
1.8       veillard 2282:        printf("\n\n");
                   2283:     }
                   2284: 
                   2285:     printf(";\n; End of the configuration file for rpm2html\n;\n");
1.6       veillard 2286: }
                   2287: 
                   2288: void sql_show_metadata(void) {
                   2289:     MYSQL_RES *result;
                   2290:     MYSQL_ROW row;
                   2291: 
                   2292: 
                   2293:     mysql_query(sql,"SELECT URL FROM Metadata");
                   2294:     result = mysql_use_result(sql);
                   2295: 
                   2296:     while((row = mysql_fetch_row(result)))
                   2297:     {
                   2298:        if (row[0] == NULL)
                   2299:            printf("NULL !\n");
                   2300:        else {
                   2301:            printf("%s\n", row[0]);
                   2302:        }
                   2303:     }
                   2304:     if(mysql_errno(sql)) {
                   2305:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2306:     }
                   2307: 
                   2308: }
                   2309: 
                   2310: void sql_show_mirrors(void) {
                   2311:     MYSQL_RES *result;
                   2312:     MYSQL_ROW row;
                   2313: 
                   2314: 
                   2315:     mysql_query(sql,"SELECT URL FROM Mirrors");
                   2316:     result = mysql_use_result(sql);
                   2317: 
                   2318:     while((row = mysql_fetch_row(result)))
                   2319:     {
                   2320:        if (row[0] == NULL)
                   2321:            printf("NULL !\n");
                   2322:        else {
                   2323:            printf("%s\n", row[0]);
                   2324:        }
                   2325:     }
                   2326:     if(mysql_errno(sql)) {
                   2327:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2328:     }
                   2329: }
                   2330: 
1.5       veillard 2331: void sql_show_vendors(void) {
1.1       veillard 2332:     MYSQL_RES *result;
                   2333:     MYSQL_ROW row;
                   2334: 
                   2335: 
                   2336:     mysql_query(sql,"SELECT Name, URL FROM Vendors");
                   2337:     result = mysql_use_result(sql);
                   2338: 
                   2339:     while((row = mysql_fetch_row(result)))
                   2340:     {
                   2341:        if (row[0] == NULL)
                   2342:            printf("NULL !\n");
                   2343:        else {
                   2344:            if (row[1] == NULL)
                   2345:                printf("%s : no url\n", row[0]);
                   2346:            else
                   2347:                printf("%s : %s\n", row[0], row[1]);
                   2348:        }
                   2349:     }
                   2350:     if(mysql_errno(sql)) {
                   2351:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2352:     }
                   2353: 
                   2354: }
                   2355: 
1.5       veillard 2356: void sql_show_distribs(void) {
1.1       veillard 2357:     MYSQL_RES *result;
                   2358:     MYSQL_ROW row;
                   2359: 
                   2360: 
                   2361:     mysql_query(sql,"SELECT Name, Path, URL FROM Distribs");
                   2362:     result = mysql_use_result(sql);
                   2363: 
                   2364:     while((row = mysql_fetch_row(result)))
                   2365:     {
                   2366:        if (row[0] == NULL)
                   2367:            printf("NULL !\n");
                   2368:        else {
                   2369:            if (row[1] == NULL)
                   2370:                printf("%s : no Path\n", row[0]);
                   2371:            else {
                   2372:                if (row[2] == NULL)
                   2373:                    printf("%s : %s : no url\n", row[0], row[1]);
                   2374:                else
                   2375:                    printf("%s : %s : %s\n", row[0], row[1], row[2]);
                   2376:            }
                   2377:        }
                   2378:     }
                   2379:     if(mysql_errno(sql)) {
                   2380:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2381:     }
                   2382: 
                   2383: }
                   2384: 
1.5       veillard 2385: int sql_show_table_stats(const char *table, const char *key) {
1.6       veillard 2386:     char query[MAX_QUERY];
1.2       veillard 2387:     MYSQL_RES *result;
                   2388:     MYSQL_ROW row;
                   2389:     int res;
                   2390: 
                   2391:     /*
                   2392:      * Search first for the ID if it already exists
                   2393:      */
1.6       veillard 2394:     snprintf(query, MAX_QUERY - 1, "SELECT COUNT(%s) FROM %s", key, table);
                   2395:     query[MAX_QUERY - 1] = 0;
1.2       veillard 2396:     if (mysql_query(sql,query)) {
1.5       veillard 2397:        printf("sql_show_table_stats: SELECT COUNT failed: %s\n",
1.2       veillard 2398:               mysql_error(sql));
                   2399:        return(-1);
                   2400:     }
                   2401: 
                   2402:     result = mysql_use_result(sql);
                   2403:     if (result) {
                   2404:        while((row = mysql_fetch_row(result)))
                   2405:        {
                   2406:            /*
                   2407:             * Lookup the value and return it
                   2408:             */
                   2409:            if (row[0] == NULL) {
                   2410:                mysql_free_result(result);
1.5       veillard 2411:                printf("sql_show_table_stats: select count returns NULL !\n");
1.2       veillard 2412:                return(-1);
                   2413:            }
                   2414:            if (sscanf(row[0], "%d", &res) != 1) {
                   2415:                mysql_free_result(result);
1.5       veillard 2416:                printf("sql_show_table_stats: value non numeric %s\n", row[0]);
1.2       veillard 2417:                return(-1);
                   2418:            }
                   2419:            mysql_free_result(result);
                   2420:            if (res <= 0)
                   2421:                printf("   %s is empty\n", table);
                   2422:            else
                   2423:                printf("   %s contains %d records\n", table, res);
                   2424:            return(res);
                   2425:        }
                   2426:        mysql_free_result(result);
                   2427:     }
                   2428:     if(mysql_errno(sql)) {
1.5       veillard 2429:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.2       veillard 2430:     }
                   2431:     return(-1);
                   2432: }
                   2433: 
1.5       veillard 2434: int sql_show_stats(void) {
1.2       veillard 2435:     const char *query = "SHOW TABLES";
                   2436:     MYSQL_RES *result;
                   2437:     MYSQL_ROW row;
                   2438: 
                   2439:     int tables = 0;
                   2440:     int records = 0;
                   2441: 
                   2442:     if (mysql_query(sql,query)) {
                   2443:        printf("sql_check_tables: SHOW TABLES failed %s\n",
                   2444:               mysql_error(sql));
                   2445:        return(-1);
                   2446:     }
                   2447: 
                   2448:     result = mysql_use_result(sql);
                   2449:     if (result) {
                   2450:        while((row = mysql_fetch_row(result)))
                   2451:        {
                   2452:            if (row[0] == NULL) {
                   2453:                mysql_free_result(result);
                   2454:                printf("sql_check_tables: SHOW TABLES returns NULL !\n");
                   2455:                return(-1);
                   2456:            }
                   2457:            tables++;
                   2458:        }
                   2459:        mysql_free_result(result);
                   2460:     }
                   2461:     if(mysql_errno(sql)) {
1.5       veillard 2462:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.2       veillard 2463:     }
                   2464:     printf("%d tables in use\n", tables);
1.5       veillard 2465:     records += sql_show_table_stats("Config", "Name");
                   2466:     records += sql_show_table_stats("Distribs", "Name");
                   2467:     records += sql_show_table_stats("Vendors", "Name");
                   2468:     records += sql_show_table_stats("Mirrors", "URL");
                   2469:     records += sql_show_table_stats("Metadata", "URL");
                   2470:     records += sql_show_table_stats("Packages", "Name");
1.8       veillard 2471:     records += sql_show_table_stats("Requires", "Resource");
                   2472:     records += sql_show_table_stats("Provides", "Resource");
1.5       veillard 2473:     records += sql_show_table_stats("Files", "Path");
1.2       veillard 2474:     printf("Total: %d records\n", records);
                   2475:     return(records);
                   2476: }
                   2477: 
1.26      veillard 2478: void sql_show_latests(void) {
                   2479:     rpmDataPtr list;
                   2480: 
                   2481:     list = sqlRpmByDate();
                   2482:     if (list == NULL) {
                   2483:        fprintf(stderr, "no package in database\n");
                   2484:        return;
                   2485:     }
1.28      daniel   2486:     dumpRpmByDate(list, 0);
1.29      veillard 2487: }
                   2488: 
1.40    ! veillard 2489: 
        !          2490: void sql_show_resources(void) {
        !          2491:     int i;
        !          2492: 
        !          2493:     sqlInitSqlDirList();
        !          2494:     sqlInitSqlResourceList();
        !          2495:     for (i = 0;i < sqlResourceListLen;i++) {
        !          2496:        if (sqlResourceList[i] == NULL)
        !          2497:            break;
        !          2498:        dumpRessRedirHtml(sqlResourceList[i]);
        !          2499:     }
        !          2500:     fprintf(stderr, "Dumped %d redirrect resource pages\n", i);
        !          2501: }
        !          2502: 
1.29      veillard 2503: void sql_show_all(void) {
                   2504:     rpmDataPtr list;
1.31      veillard 2505: #ifdef SQL_DEBUG_TIMING
                   2506:     time_t cur, last;
1.29      veillard 2507: 
1.31      veillard 2508:     last = time(NULL);
                   2509: #endif
1.29      veillard 2510:     list = sqlRpmAll();
                   2511:     if (list == NULL) {
                   2512:        fprintf(stderr, "no package in database\n");
                   2513:        return;
                   2514:     }
1.31      veillard 2515: #ifdef SQL_DEBUG_TIMING
                   2516:     cur = time(NULL);
                   2517:     fprintf(stderr, "sqlRpmAll took %d seconds\n", (int)(cur - last));
                   2518:     last = cur;
                   2519: #endif
                   2520: 
                   2521:     rpmNameSort(&list, 0);
                   2522:     dumpRpmByName(rpmSoftwareList, 0);
                   2523: 
                   2524: #ifdef SQL_DEBUG_TIMING
                   2525:     cur = time(NULL);
                   2526:     fprintf(stderr, "dumpRpmByName took %d seconds\n", (int)(cur - last));
                   2527:     last = cur;
                   2528: #endif
                   2529: 
                   2530:     rpmGroupSort(&list, 0);
1.32      daniel   2531:     dumpRpmByGroups(rpmSoftwareList, 0);
1.31      veillard 2532: 
                   2533: #ifdef SQL_DEBUG_TIMING
                   2534:     cur = time(NULL);
                   2535:     fprintf(stderr, "dumpRpmByGroups took %d seconds\n", (int)(cur - last));
                   2536:     last = cur;
                   2537: #endif
1.35      veillard 2538: 
                   2539:     rpmVendorSort(&list, 0);
                   2540:     dumpRpmByVendors(list, 0);
                   2541: 
                   2542: #ifdef SQL_DEBUG_TIMING
                   2543:     cur = time(NULL);
                   2544:     fprintf(stderr, "dumpRpmByVendors took %d seconds\n", (int)(cur - last));
1.36      veillard 2545:     last = cur;
                   2546: #endif
                   2547: 
                   2548:     rpmDistribSort(&list, 0);
                   2549:     dumpRpmByDistribs(list, 0);
                   2550: 
                   2551: #ifdef SQL_DEBUG_TIMING
                   2552:     cur = time(NULL);
                   2553:     fprintf(stderr, "dumpRpmByDistribs took %d seconds\n", (int)(cur - last));
1.35      veillard 2554:     last = cur;
                   2555: #endif
                   2556: 
1.39      daniel   2557:     rpmDateSort(&list, 0);
1.37      veillard 2558:     dumpRpmByDate(list, 0);
                   2559: 
                   2560: #ifdef SQL_DEBUG_TIMING
                   2561:     cur = time(NULL);
                   2562:     fprintf(stderr, "dumpRpmByDate took %d seconds\n", (int)(cur - last));
                   2563:     last = cur;
                   2564: #endif
                   2565: 
1.40    ! veillard 2566:     rpmdataCleanup();
        !          2567:     sleep(30);
1.26      veillard 2568: }
                   2569: 
1.2       veillard 2570: /************************************************************************
                   2571:  *                                                                     *
                   2572:  *                     rpm2html configuration functions                *
                   2573:  *                                                                     *
                   2574:  ************************************************************************/
                   2575: 
                   2576: int readConfigSql(void) {
1.6       veillard 2577:     char query[MAX_QUERY];
1.3       veillard 2578:     MYSQL_RES *result;
                   2579:     MYSQL_ROW row;
1.4       veillard 2580:     int dir = 0;
1.3       veillard 2581: 
1.2       veillard 2582:     /*
1.3       veillard 2583:      * General configuration informations
1.2       veillard 2584:      */
1.6       veillard 2585:     snprintf(query, MAX_QUERY - 1, "SELECT Name,Value FROM Config");
                   2586:     query[MAX_QUERY - 1] = 0;
1.3       veillard 2587:     if (mysql_query(sql,query)) {
                   2588:        printf("sql_check_tables: SELECT Config failed %s\n",
                   2589:               mysql_error(sql));
                   2590:        return(-1);
                   2591:     }
                   2592: 
                   2593:     result = mysql_use_result(sql);
                   2594:     if (result) {
                   2595:        while((row = mysql_fetch_row(result)))
                   2596:        {
                   2597:            if ((row[0] == NULL) || (row[1] == NULL)) {
                   2598:                fprintf(stderr, "readConfigSql : found NULL value\n");
                   2599:                continue;
                   2600:            }
1.4       veillard 2601:            if (!strcmp(row[0], "dir"))
                   2602:                dir = 1;
1.3       veillard 2603:            addConfigEntry(RPM2HTML_NAME, row[0], row[1]);
                   2604:        }
                   2605:        mysql_free_result(result);
                   2606:     }
                   2607:     if(mysql_errno(sql)) {
1.5       veillard 2608:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.4       veillard 2609:     }
                   2610:     if (dir == 0) {
                   2611:        fprintf(stderr, "readConfigSql : no directory\n");
                   2612:        return(-1);
1.3       veillard 2613:     }
                   2614: 
                   2615:     /*
                   2616:      * The metadata mirror list.
                   2617:      */
1.6       veillard 2618:     snprintf(query, MAX_QUERY - 1, "SELECT URL FROM Metadata");
                   2619:     query[MAX_QUERY - 1] = 0;
1.3       veillard 2620:     if (mysql_query(sql,query)) {
                   2621:        printf("sql_check_tables: SELECT Metadata failed %s\n",
                   2622:               mysql_error(sql));
                   2623:        return(-1);
                   2624:     }
                   2625: 
                   2626:     result = mysql_use_result(sql);
                   2627:     if (result) {
                   2628:        while((row = mysql_fetch_row(result)))
                   2629:        {
                   2630:            if (row[0] == NULL) {
                   2631:                fprintf(stderr, "readConfigSql : found NULL metadata\n");
                   2632:                continue;
                   2633:            }
                   2634:            addConfigEntry("metadata", "mirror", row[0]);
                   2635:        }
                   2636:        mysql_free_result(result);
                   2637:     }
                   2638:     if(mysql_errno(sql)) {
1.5       veillard 2639:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 2640:     }
                   2641: 
                   2642:     /*
                   2643:      * The distribution lists
                   2644:      */
1.6       veillard 2645:     snprintf(query, MAX_QUERY - 1, "SELECT Directory,Name,URL,URLSrc,Path FROM Distribs");
                   2646:     query[MAX_QUERY - 1] = 0;
1.3       veillard 2647:     if (mysql_query(sql,query)) {
                   2648:        printf("sql_check_tables: SELECT Distribs failed %s\n",
                   2649:               mysql_error(sql));
                   2650:        return(-1);
                   2651:     }
                   2652: 
                   2653:     result = mysql_use_result(sql);
                   2654:     if (result) {
                   2655:        while((row = mysql_fetch_row(result)))
                   2656:        {
                   2657:            if (row[0] == NULL) {
                   2658:                fprintf(stderr, "readConfigSql : found NULL distro\n");
                   2659:                continue;
                   2660:            }
                   2661: 
                   2662:            if (row[1] != NULL)
                   2663:                addConfigEntry(row[0], "name", row[1]);
                   2664:            if (row[2] != NULL)
                   2665:                addConfigEntry(row[0], "ftp", row[2]);
                   2666:            if (row[3] != NULL)
                   2667:                addConfigEntry(row[0], "ftp", row[3]);
                   2668:            if (row[4] != NULL)
                   2669:                addConfigEntry(row[0], "subdir", row[4]);
                   2670:        }
                   2671:        mysql_free_result(result);
                   2672:     }
                   2673:     if(mysql_errno(sql)) {
1.5       veillard 2674:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 2675:     }
                   2676: 
                   2677:     /*
                   2678:      * The Mirrors
                   2679:      */
1.6       veillard 2680:     snprintf(query, MAX_QUERY - 1, "SELECT Distribs.Directory,Mirrors.URL FROM Distribs,Mirrors WHERE Distribs.ID = Mirrors.ID");
                   2681:     query[MAX_QUERY - 1] = 0;
1.3       veillard 2682:     if (mysql_query(sql,query)) {
                   2683:        printf("sql_check_tables: SELECT Distribs failed %s\n",
                   2684:               mysql_error(sql));
                   2685:        return(-1);
                   2686:     }
                   2687: 
                   2688:     result = mysql_use_result(sql);
                   2689:     if (result) {
                   2690:        while((row = mysql_fetch_row(result)))
                   2691:        {
                   2692:            if ((row[0] == NULL) || (row[1] == NULL)) {
                   2693:                fprintf(stderr, "readConfigSql : found NULL mirror\n");
                   2694:                continue;
                   2695:            }
                   2696: 
                   2697:            addConfigEntry(row[0], "mirror", row[1]);
                   2698:        }
                   2699:        mysql_free_result(result);
                   2700:     }
                   2701:     if(mysql_errno(sql)) {
1.5       veillard 2702:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 2703:     }
                   2704: 
1.5       veillard 2705:     /*
                   2706:      * TODO: add the language(s) stuff
                   2707:      */
1.3       veillard 2708:     return(0);
1.2       veillard 2709: }
                   2710: 
                   2711: void sqlConfigEntry(const char *rpmdir, const char *name, const char *value) {
                   2712:     int distrib;
                   2713: 
                   2714:     if (rpm2htmlVerbose > 1)
                   2715:        printf("sqlConfigEntry(\"%s\", \"%s\", \"%s\")\n", rpmdir, name, value);
                   2716: 
                   2717:     /*
                   2718:      * case of global option for rpm2html.
                   2719:      */
                   2720:     if (!strcasecmp(rpmdir, RPM2HTML_NAME)) {
1.5       veillard 2721:        sql_add_config_info(name, value);
1.2       veillard 2722:        return;
                   2723:     }
                   2724: 
                   2725:     /*
                   2726:      * Options for the metadata mirrors.
                   2727:      */
                   2728:     if (!strcasecmp(rpmdir, "metadata")) {
                   2729:        if (!strcasecmp(name, "mirror")) {
1.5       veillard 2730:            sql_add_metadata_base(value);
1.2       veillard 2731:        } else {
                   2732:            printf("Config file : %s entry for [metadata] ignored\n", name);
                   2733:        }
                   2734:        return;
                   2735:     }
                   2736: 
                   2737:     /*
                   2738:      * option for a directory.
                   2739:      */
                   2740:     if (!strcasecmp(name, "name")) {
1.9       veillard 2741:        sql_add_distrib(value, NULL, rpmdir, NULL, NULL, NULL, NULL,
                   2742:                        NULL, NULL);
1.2       veillard 2743:     } else if (!strcasecmp(name, "subdir")) {
                   2744:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   2745:        if (distrib > 0)
                   2746:             sql_update_id("Distribs", distrib, "Path", value);
                   2747:     } else if (!strcasecmp(name, "url")) {
                   2748:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   2749:        if (distrib > 0)
                   2750:             sql_update_id("Distribs", distrib, "URL", value);
                   2751:     } else if (!strcasecmp(name, "ftp")) {
                   2752:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   2753:        if (distrib > 0)
                   2754:             sql_update_id("Distribs", distrib, "URL", value);
                   2755:     } else if (!strcasecmp(name, "ftpsrc")) {
                   2756:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   2757:        if (distrib > 0)
                   2758:             sql_update_id("Distribs", distrib, "URLSrc", value);
1.9       veillard 2759:     } else if (!strcasecmp(name, "html")) {
                   2760:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   2761:        if (distrib > 0)
                   2762:             sql_update_id("Distribs", distrib, "Html", value);
                   2763:     } else if (!strcasecmp(name, "color")) {
                   2764:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   2765:        if (distrib > 0)
                   2766:             sql_update_id("Distribs", distrib, "Color", value);
1.2       veillard 2767:     } else if (!strcasecmp(name, "mirror")) {
                   2768:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   2769:        if (distrib > 0)
1.5       veillard 2770:            sql_add_dist_mirror(distrib, value, 0);
1.2       veillard 2771:     } else {
                   2772:        printf("Config file : %s entry for [%s] ignored\n", name, rpmdir);
                   2773:     }
                   2774: }
1.1       veillard 2775: 

Webmaster