Annotation of rpm2html/sql.c, revision 1.49

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>
1.49    ! veillard   11: #include <sys/wait.h>
        !            12: 
1.2       veillard   13: #ifdef HAVE_FCNTL_H
                     14: #include <fcntl.h>
                     15: #endif
1.1       veillard   16: #include <stdio.h>
                     17: #include <stdlib.h>
1.2       veillard   18: #include <string.h>
1.28      daniel     19: #include <time.h>
1.49    ! veillard   20: #include <errno.h>
        !            21: #include <signal.h>
1.2       veillard   22: #ifdef HAVE_UNISTD_H
                     23: #include <unistd.h>
                     24: #endif
                     25: /********
                     26: #include <rpm/rpmlib.h>
                     27:  ********/
                     28: 
1.1       veillard   29: #include <mysql/mysql.h>
1.16      veillard   30: #include <mysql/errmsg.h>
1.2       veillard   31: #include "rpm2html.h"
1.26      veillard   32: #include "rpmdata.h"
1.2       veillard   33: /********
                     34: #include "rpmdata.h"
                     35:  ********/
1.1       veillard   36: #include "sql.h"
1.28      daniel     37: #include "html.h"
1.1       veillard   38: 
1.39      daniel     39: /* #define SQL_DEBUG_TIMING */
1.45      veillard   40: #define SQL_DEBUG_MEM 
1.31      veillard   41: 
1.26      veillard   42: #define SQL_MAX_DISTRIBS 500
                     43: 
1.1       veillard   44: /************************************************************************
                     45:  *                                                                     *
                     46:  *             Generic inititialisation/close of the DB                *
                     47:  *                                                                     *
                     48:  ************************************************************************/
                     49: 
                     50: static MYSQL *sql = NULL;
1.16      veillard   51: static const char *myhost, *mybase, *myuser, *mypasswd;
1.1       veillard   52: 
1.11      veillard   53: int init_sql(const char *host, const char *base, const char *user, const char *passwd) {
1.16      veillard   54:     int attempts = 0;
                     55: 
                     56:     /*
                     57:      * Close the previous connection if any
                     58:      */
                     59:     if (sql != NULL) {
                     60:        close_sql();
                     61:        if (myhost != NULL) free((char *) myhost);
                     62:        myhost = NULL;
                     63:        if (mybase != NULL) free((char *) mybase);
                     64:        mybase = NULL;
                     65:        if (myuser != NULL) free((char *) myuser);
                     66:        myuser = NULL;
                     67:        if (mypasswd != NULL) free((char *) mypasswd);
                     68:        mypasswd = NULL;
                     69:     }
                     70: 
1.11      veillard   71:     if (host == NULL)
                     72:        host = getenv("MySQL_HOST");
                     73:     if (host == NULL)
                     74:        host = "localhost";
                     75:     if (base == NULL)
                     76:        base = getenv("MySQL_BASE");
1.1       veillard   77:     if (base == NULL)
                     78:        base = "rpmfind";
                     79:     if (passwd == NULL)
                     80:        passwd = getenv("MySQL_PASS");
                     81:     if (user == NULL)
                     82:        user = getenv("MySQL_USER");
                     83:     if (user == NULL)
                     84:        user = getenv("USER");
                     85:     if (user == NULL)
                     86:        user = getenv("USERNAME");
                     87:     if (user == NULL)
                     88:        user = getenv("LOGNAME");
                     89:     sql = mysql_init(NULL);
                     90:     if (mysql_errno(sql)) {
                     91:        fprintf(stderr, "mysql_init failed: %s\n", mysql_error(sql));
                     92:        return(-1);
                     93:     }
1.16      veillard   94:     for (attempts = 0; ;attempts ++) {
                     95:        mysql_real_connect(sql, host, user, passwd, base, 0, NULL, 0);
                     96:        if (mysql_errno(sql)) {
1.26      veillard   97:            if ((attempts == 0) && (passwd == NULL)) {
                     98:                fprintf(stderr, "No passwd defined, use MySQL_PASS env\n");
                     99:            }
1.16      veillard  100:            if (attempts >= 20) {
                    101:                fprintf(stderr,
                    102:                        "mysql: connect as %s to %s on host %s  failed: %s\n",
                    103:                        user, base, host, mysql_error(sql));
1.24      daniel    104:                return(-1);
                    105:            } else {
                    106:                fprintf(stderr,
                    107:                        "mysql: retrying connect as %s to %s on host %s  failed: %s\n",
                    108:                        user, base, host, mysql_error(sql));
1.16      veillard  109:            }
                    110:        } else {
                    111:            break;
                    112:        }
                    113:        sleep(15);
1.1       veillard  114:     }
1.16      veillard  115:     myhost = strdup(host);
                    116:     mybase = strdup(base);
                    117:     myuser = strdup(user);
                    118:     mypasswd = strdup(passwd);
1.2       veillard  119:     sql_check_tables();
1.1       veillard  120:     return(0);
                    121: }
                    122: 
                    123: int close_sql(void) {
                    124:     mysql_close(sql);
                    125:     if (mysql_errno(sql)) {
                    126:        fprintf(stderr, "mysql_close failed: %s\n", mysql_error(sql));
                    127:        return(-1);
                    128:     }
1.16      veillard  129:     sql = NULL;
1.1       veillard  130:     return(0);
                    131: }
                    132: 
1.16      veillard  133: int restart_sql(void) {
                    134:     int attempts = 0;
                    135: 
                    136:     /*
                    137:      * Close the previous connection if any
                    138:      */
                    139:     if (sql != NULL) {
                    140:        close_sql();
                    141:        sql = NULL;
                    142:     }
                    143: 
                    144:     sql = mysql_init(NULL);
                    145:     if (mysql_errno(sql)) {
                    146:        fprintf(stderr, "mysql_init failed: %s\n", mysql_error(sql));
                    147:        return(-1);
                    148:     }
                    149:     for (attempts = 0; ;attempts ++) {
                    150:        mysql_real_connect(sql, myhost, myuser, mypasswd, mybase, 0, NULL, 0);
                    151:        if (mysql_errno(sql)) {
                    152:            if (attempts >= 20) {
                    153:                fprintf(stderr,
                    154:                        "mysql: reconnect as %s to %s on host %s  failed: %s\n",
                    155:                        myuser, mybase, myhost, mysql_error(sql));
                    156:            return(-1);
                    157:            }
                    158:        } else {
                    159:            break;
                    160:        }
                    161:        sleep(15);
                    162:     }
                    163:     sql_check_tables();
                    164:     return(0);
                    165: }
                    166: 
                    167: /*
                    168:  * Handle disconnects by doing a reconnect and a retry.
                    169:  */
                    170: int do_sql_query(const char *query, int len) {
                    171:     int res;
                    172: 
                    173:     if (sql == NULL) {
                    174:        res = restart_sql();
                    175:        if (res != 0)
                    176:            return(res);
                    177:     }
                    178:     res = mysql_real_query(sql, query, len);
1.19      daniel    179:     if ((res == CR_SERVER_GONE_ERROR) || (res == CR_SERVER_LOST)) {
1.16      veillard  180:        res = restart_sql();
                    181:        if (res != 0)
                    182:            return(res);
                    183:        res = mysql_real_query(sql, query, len);
                    184:     }
                    185:     return(res);
                    186: }
                    187: 
1.1       veillard  188: /************************************************************************
                    189:  *                                                                     *
                    190:  *             Generic functions to access the tables                  *
                    191:  *                                                                     *
                    192:  ************************************************************************/
                    193: 
1.6       veillard  194: #define MAX_QUERY 8000
                    195: #define SMALL_QUERY 500
1.1       veillard  196: 
                    197: int sql_update_id(const char *table, int id,
                    198:                  const char *field, const char *value) {
                    199:     MYSQL_RES *result;
1.6       veillard  200:     char query[MAX_QUERY];
1.1       veillard  201:     int nb_fields = 0;
1.6       veillard  202:     int left = MAX_QUERY - 1;
                    203:     int len;
                    204:     char *end;
1.1       veillard  205: 
                    206:     if ((table == NULL) ||
                    207:        (field == NULL) || (value == NULL))
                    208:        return(-1);
                    209: 
1.6       veillard  210:     len = snprintf(query, left, "UPDATE %s SET %s='", table, field);
                    211:     if (len < 0) {
                    212:        fprintf(stderr, "sql_update_id : %s(%d).%s overflow\n",
                    213:                table, id, field);
                    214:        return(-1);
                    215:     }
                    216:     end = &query[len];
                    217:     left -= len;
                    218:     len = strlen(value);
                    219:     if (len * 2 >= left) {
                    220:        fprintf(stderr, "sql_update_id : %s(%d).%s overflow\n",
                    221:                table, id, field);
                    222:        return(-1);
                    223:     }
                    224:     len = mysql_escape_string(end, value, len);
                    225:     left -= len;
                    226:     if (left <= 0) {
                    227:        fprintf(stderr, "sql_update_id : %s(%d).%s overflow\n",
                    228:                table, id, field);
                    229:        return(-1);
                    230:     }
                    231:     end += len;
                    232:     len = snprintf(end, left, "' WHERE ID=%d", id);
                    233:     if (len < 0) {
                    234:        fprintf(stderr, "sql_update_id : %s(%d).%s overflow\n",
                    235:                table, id, field);
                    236:        return(-1);
                    237:     }
                    238:     end += len;
                    239:     query[MAX_QUERY - 1] = 0;
                    240: 
1.16      veillard  241:     if (do_sql_query(query, (unsigned int) (end - query))) {
1.1       veillard  242:        printf("sql_update_id: UPDATE %s %d failed: %s\n",
                    243:               table, id, mysql_error(sql));
                    244:        return(-1);
                    245:     }
                    246:     result = mysql_store_result(sql);
                    247:     if (result != NULL) {
                    248:        nb_fields = mysql_num_fields(result);
                    249:        mysql_free_result(result);
                    250:     } else {
                    251:        nb_fields = 1;
                    252:     }
                    253:     if(mysql_errno(sql)) {
                    254:        fprintf(stderr, "sql_update_id UPDATE error: %s\n",
                    255:                 mysql_error(sql));
                    256:        return(-1);
                    257:     }
                    258:     return(nb_fields);
                    259: }
                    260: 
                    261: int sql_blind_insert(const char *table, const char *key,
                    262:                      const char *value, int id) {
                    263:     MYSQL_RES *result;
1.6       veillard  264:     char query[MAX_QUERY];
                    265:     int left = MAX_QUERY - 1;
                    266:     int len;
                    267:     char *end;
1.8       veillard  268:     int insert = -1;
1.1       veillard  269: 
1.2       veillard  270:     if ((table == NULL) ||
1.1       veillard  271:        (key == NULL) || (value == NULL))
                    272:        return(-1);
                    273: 
                    274:     /*
                    275:      * Search first for the ID if it already exists
                    276:      */
1.2       veillard  277:     if (id > 0) {
1.6       veillard  278:        len = snprintf(query, left, "INSERT INTO %s (ID, %s) VALUES (%d, '",
                    279:                       table, key, id);
                    280:        if (len < 0) {
                    281:            fprintf(stderr, "sql_blind_insert : %s(%d).%s overflow\n",
                    282:                    table, id, key);
                    283:            return(-1);
                    284:        }
                    285:        end = &query[len];
                    286:        left -= len;
                    287:        len = strlen(value);
                    288:        if (len * 2 >= left) {
                    289:            fprintf(stderr, "sql_blind_insert : %s(%d).%s overflow\n",
                    290:                    table, id, key);
                    291:            return(-1);
                    292:        }
                    293:        len = mysql_escape_string(end, value, len);
                    294:        left -= len;
                    295:        if (left <= 0) {
                    296:            fprintf(stderr, "sql_blind_insert : %s(%d).%s overflow\n",
                    297:                    table, id, key);
                    298:            return(-1);
                    299:        }
                    300:        end += len;
                    301:        len = snprintf(end, left, "')");
                    302:        if (len < 0) {
                    303:            fprintf(stderr, "sql_blind_insert : %s(%d).%s overflow\n",
                    304:                    table, id, key);
                    305:            return(-1);
                    306:        }
                    307:        end += len;
                    308:        query[MAX_QUERY - 1] = 0;
                    309: 
1.2       veillard  310:     } else {
1.6       veillard  311:        len = snprintf(query, left, "INSERT INTO %s (%s) VALUES ('",
                    312:                       table, key);
                    313:        if (len < 0) {
                    314:            fprintf(stderr, "sql_blind_insert : %s.%s overflow\n",
                    315:                    table, key);
                    316:            return(-1);
                    317:        }
                    318:        end = &query[len];
                    319:        left -= len;
                    320:        len = strlen(value);
                    321:        if (len * 2 >= left) {
                    322:            fprintf(stderr, "sql_blind_insert : %s.%s overflow\n",
                    323:                    table, key);
                    324:            return(-1);
                    325:        }
                    326:        len = mysql_escape_string(end, value, len);
                    327:        left -= len;
                    328:        if (left <= 0) {
                    329:            fprintf(stderr, "sql_blind_insert : %s.%s overflow\n",
                    330:                    table, key);
                    331:            return(-1);
                    332:        }
                    333:        end += len;
                    334:        len = snprintf(end, left, "')");
                    335:        if (len < 0) {
                    336:            fprintf(stderr, "sql_blind_insert : %s.%s overflow\n",
                    337:                    table, key);
                    338:            return(-1);
                    339:        }
                    340:        end += len;
                    341:        query[MAX_QUERY - 1] = 0;
                    342: 
1.2       veillard  343:     }
1.6       veillard  344:     query[MAX_QUERY - 1] = 0;
1.16      veillard  345:     if (do_sql_query(query, (unsigned int) (end - query))) {
1.6       veillard  346: #ifdef SQL_DEBUG
                    347:        fprintf(stderr, "sql_blind_insert Error: %s\n", mysql_error(sql));
                    348: #endif
1.1       veillard  349:        return(-1);
                    350:     }
                    351:     result = mysql_store_result(sql);
1.8       veillard  352:     insert = mysql_insert_id(sql);
1.1       veillard  353:     if (result) {
                    354:        mysql_free_result(result);
1.8       veillard  355:        return(insert);
1.1       veillard  356:     }
                    357:     if(mysql_errno(sql)) {
                    358:        fprintf(stderr, "sql_blind_insert Error: %s\n", mysql_error(sql));
                    359:        return(-1);
                    360:     }
1.8       veillard  361:     return(insert);
1.1       veillard  362: }
                    363: 
                    364: int sql_update(const char *table, const char *name,
                    365:               const char *field, const char *value) {
                    366:     MYSQL_RES *result;
                    367:     MYSQL_ROW row;
1.6       veillard  368:     char query[MAX_QUERY];
1.1       veillard  369:     int id;
                    370:     int nb_fields = 0;
1.6       veillard  371:     int left = MAX_QUERY - 1;
                    372:     int len;
                    373:     char *end;
1.1       veillard  374: 
                    375:     if ((name == NULL) || (table == NULL) ||
                    376:        (field == NULL) || (value == NULL))
                    377:        return(-1);
                    378: 
                    379:     /*
                    380:      * Search first for the ID if it already exists
                    381:      */
1.6       veillard  382:     snprintf(query, MAX_QUERY - 1, "SELECT ID FROM %s WHERE Name='%s'", table, name);
                    383:     query[MAX_QUERY - 1] = 0;
1.1       veillard  384:     if (mysql_query(sql,query)) {
                    385:        printf("sql_update: SELECT failed\n");
                    386:        return(-1);
                    387:     }
                    388: 
                    389:     result = mysql_use_result(sql);
                    390:     if (result) {
                    391:        while((row = mysql_fetch_row(result)))
                    392:        {
                    393:            if (row[0] == NULL) {
                    394:                printf("sql_update: select ID for %s returns NULL !\n", name);
                    395:                return(-1);
                    396:            }
                    397:            if (sscanf(row[0], "%d", &id) != 1) {
                    398:                printf("sql_update: ID non numeric %s\n", row[0]);
                    399:                return(-1);
                    400:            }
1.6       veillard  401: 
                    402:            left = MAX_QUERY - 1;
                    403:            len = snprintf(query, left, "UPDATE %s SET %s='", table, field);
                    404:            if (len < 0) {
                    405:                fprintf(stderr, "sql_update : %s(%d).%s overflow\n",
                    406:                        table, id, field);
                    407:                return(-1);
                    408:            }
                    409:            end = &query[len];
                    410:            left -= len;
                    411:            len = strlen(value);
                    412:            if (len * 2 >= left) {
                    413:                fprintf(stderr, "sql_update : %s(%d).%s overflow\n",
                    414:                        table, id, field);
                    415:                return(-1);
                    416:            }
                    417:            len = mysql_escape_string(end, value, len);
                    418:            left -= len;
                    419:            if (left <= 0) {
                    420:                fprintf(stderr, "sql_update : %s(%d).%s overflow\n",
                    421:                        table, id, field);
                    422:                return(-1);
                    423:            }
                    424:            end += len;
                    425:            len = snprintf(end, left, "' WHERE ID=%d", id);
                    426:            if (len < 0) {
                    427:                fprintf(stderr, "sql_update : %s(%d).%s overflow\n",
                    428:                        table, id, field);
                    429:                return(-1);
                    430:            }
                    431:            end += len;
                    432:            query[MAX_QUERY - 1] = 0;
                    433: 
1.1       veillard  434:            mysql_free_result(result);
1.16      veillard  435:            if (do_sql_query(query, (unsigned int) (end - query))) {
1.2       veillard  436:                printf("sql_update: UPDATE failed: %s\n", mysql_error(sql));
1.1       veillard  437:                return(-1);
                    438:            }
                    439:            result = mysql_store_result(sql);
                    440:            if (result != NULL) {
                    441:                nb_fields = mysql_num_fields(result);
                    442:                mysql_free_result(result);
                    443:            } else {
1.2       veillard  444:                return(1);
1.1       veillard  445:            }
                    446:            /* Do not loop ... only the first */
                    447:            return(nb_fields);
                    448:        }
                    449:        mysql_free_result(result);
1.2       veillard  450:        if (nb_fields == 0) {
                    451:            /*
                    452:             * Propagate an insert
                    453:             */
1.6       veillard  454:            snprintf(query, MAX_QUERY - 1,
1.2       veillard  455:                    "INSERT INTO %s (Name,%s) VALUES ('%s','%s')",
                    456:                     table, field, name, value);
1.6       veillard  457:            query[MAX_QUERY - 1] = 0;
1.2       veillard  458:            mysql_free_result(result);
                    459:            if (mysql_query(sql, query)) {
                    460:                printf("sql_update: INSERT failed: %s\n", mysql_error(sql));
                    461:                return(-1);
                    462:            }
                    463:            result = mysql_store_result(sql);
                    464:            if (result != NULL) {
                    465:                nb_fields = mysql_num_fields(result);
                    466:                mysql_free_result(result);
                    467:            } else {
                    468:                return(1);
                    469:            }
                    470:        }
1.1       veillard  471:     }
                    472:     if(mysql_errno(sql)) {
                    473:        fprintf(stderr, "sql_update Error: %s\n", mysql_error(sql));
                    474:        return(-1);
                    475:     }
                    476:     return(nb_fields);
                    477: }
                    478: 
1.6       veillard  479: int sql_get_key(const char *table, const char *name, const char *value) {
1.1       veillard  480:     int id;
                    481:     MYSQL_RES *result;
                    482:     MYSQL_ROW row;
1.38      veillard  483:     char query[MAX_QUERY];
                    484:     int left = MAX_QUERY - 1;
                    485:     int len;
                    486:     char *end;
1.1       veillard  487: 
                    488:     if ((table == NULL) || (name == NULL))
                    489:        return(-1);
                    490: 
1.38      veillard  491: 
1.1       veillard  492:     /*
                    493:      * Search first for the ID if it already exists
                    494:      */
1.38      veillard  495:     len = snprintf(query, left, "SELECT ID FROM %s WHERE %s='",
                    496:                   table, name);
                    497:     if (len < 0) {
                    498:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    499:                table, name, value);
                    500:        return(-1);
                    501:     }
                    502:     end = &query[len];
                    503:     left -= len;
                    504:     len = strlen(value);
                    505:     if (len * 2 >= left) {
                    506:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    507:                table, name, value);
                    508:        return(-1);
                    509:     }
                    510:     len = mysql_escape_string(end, value, len);
                    511:     left -= len;
                    512:     if (left <= 0) {
                    513:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    514:                table, name, value);
                    515:        return(-1);
                    516:     }
                    517:     end += len;
                    518:     len = snprintf(end, left, "'");
                    519:     if (len < 0) {
                    520:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    521:                table, name, value);
                    522:        return(-1);
                    523:     }
                    524:     end += len;
                    525:     query[MAX_QUERY - 1] = 0;
                    526: 
1.1       veillard  527:     if (mysql_query(sql,query)) {
1.38      veillard  528:        printf("sql_get_key: SELECT %s failed %s\n", name, mysql_error(sql));
1.1       veillard  529:        return(-1);
                    530:     }
                    531: 
                    532:     result = mysql_use_result(sql);
                    533:     if (result) {
                    534:        while((row = mysql_fetch_row(result)))
                    535:        {
                    536:            /*
                    537:             * Lookup the first ID and return it
                    538:             */
                    539:            if (row[0] == NULL) {
                    540:                mysql_free_result(result);
1.38      veillard  541:                printf("sql_get_key: select returns NULL !\n");
1.1       veillard  542:                return(-1);
                    543:            }
                    544:            if (sscanf(row[0], "%d", &id) != 1) {
                    545:                mysql_free_result(result);
1.38      veillard  546:                printf("sql_get_key: ID non numeric %s\n", row[0]);
1.1       veillard  547:                return(-1);
                    548:            }
                    549:            mysql_free_result(result);
                    550:            return(id);
                    551:        }
                    552:        mysql_free_result(result);
                    553:     }
                    554:     if(mysql_errno(sql)) {
                    555:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                    556:        return(-1);
                    557:     }
                    558: 
                    559:     /*
                    560:      * Do a creation
                    561:      */
                    562: 
1.6       veillard  563:     query[SMALL_QUERY - 1] = 0;
1.38      veillard  564:     len = snprintf(query, left, "INSERT INTO %s (%s) VALUES ('",
                    565:                   table, name);
                    566:     if (len < 0) {
                    567:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    568:                table, name, value);
                    569:        return(-1);
                    570:     }
                    571:     end = &query[len];
                    572:     left -= len;
                    573:     len = strlen(value);
                    574:     if (len * 2 >= left) {
                    575:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    576:                table, name, value);
                    577:        return(-1);
                    578:     }
                    579:     len = mysql_escape_string(end, value, len);
                    580:     left -= len;
                    581:     if (left <= 0) {
                    582:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    583:                table, name, value);
                    584:        return(-1);
                    585:     }
                    586:     end += len;
                    587:     len = snprintf(end, left, "')");
                    588:     if (len < 0) {
                    589:        fprintf(stderr, "sql_get_key : %s(%s).%s overflow\n",
                    590:                table, name, value);
                    591:        return(-1);
                    592:     }
                    593:     end += len;
                    594:     query[MAX_QUERY - 1] = 0;
                    595: 
1.1       veillard  596:     if (mysql_query(sql,query)) {
1.2       veillard  597:        printf("sql_get_key: INSERT %s failed %s\n", name, mysql_error(sql));
1.1       veillard  598:        return(-1);
                    599:     }
                    600:     id = mysql_insert_id(sql);
                    601:     result = mysql_store_result(sql);
                    602:     if (result != NULL)
                    603:        mysql_free_result(result);
                    604:     return(id);
                    605: }
                    606: 
                    607: int sql_read_key(const char *table, const char *name) {
                    608:     int id;
                    609:     MYSQL_RES *result;
                    610:     MYSQL_ROW row;
1.6       veillard  611:     char query[SMALL_QUERY];
1.1       veillard  612: 
                    613:     if ((table == NULL) || (name == NULL))
                    614:        return(-1);
                    615: 
                    616:     /*
                    617:      * Search for the ID it has to exist
                    618:      */
1.6       veillard  619:     snprintf(query, SMALL_QUERY - 1, "SELECT ID FROM %s WHERE Name='%s'", table, name);
                    620:     query[SMALL_QUERY - 1] = 0;
1.2       veillard  621:     if (mysql_query(sql,query)) {
1.38      veillard  622:        printf("sql_read_key: SELECT %s failed %s\n", name, mysql_error(sql));
1.2       veillard  623:        return(-1);
                    624:     }
                    625: 
                    626:     result = mysql_use_result(sql);
                    627:     if (result) {
                    628:        while((row = mysql_fetch_row(result)))
                    629:        {
                    630:            /*
                    631:             * Lookup the first ID and return it
                    632:             */
                    633:            if (row[0] == NULL) {
                    634:                mysql_free_result(result);
1.38      veillard  635:                printf("sql_read_key: select returns NULL !\n");
1.2       veillard  636:                return(-1);
                    637:            }
                    638:            if (sscanf(row[0], "%d", &id) != 1) {
                    639:                mysql_free_result(result);
1.38      veillard  640:                printf("sql_read_key: ID non numeric %s\n", row[0]);
1.2       veillard  641:                return(-1);
                    642:            }
                    643:            mysql_free_result(result);
                    644:            return(id);
                    645:        }
                    646:        mysql_free_result(result);
                    647:     }
                    648:     if(mysql_errno(sql)) {
                    649:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                    650:        return(-1);
                    651:     }
                    652:     return(-1);
                    653: }
                    654: 
                    655: int sql_read_info_key(const char *table, const char *name, const char *value) {
                    656:     int id;
                    657:     MYSQL_RES *result;
                    658:     MYSQL_ROW row;
1.6       veillard  659:     char query[SMALL_QUERY];
1.2       veillard  660: 
                    661:     if ((table == NULL) || (name == NULL) || (value == NULL))
                    662:        return(-1);
                    663: 
                    664:     /*
                    665:      * Search for the ID it has to exist
                    666:      */
1.6       veillard  667:     snprintf(query, SMALL_QUERY - 1, "SELECT ID FROM %s WHERE %s='%s'", table, name, value);
                    668:     query[SMALL_QUERY - 1] = 0;
1.1       veillard  669:     if (mysql_query(sql,query)) {
1.38      veillard  670:        printf("sql_read_info_key: SELECT %s failed %s\n", name, mysql_error(sql));
1.1       veillard  671:        return(-1);
                    672:     }
                    673: 
                    674:     result = mysql_use_result(sql);
                    675:     if (result) {
                    676:        while((row = mysql_fetch_row(result)))
                    677:        {
                    678:            /*
                    679:             * Lookup the first ID and return it
                    680:             */
                    681:            if (row[0] == NULL) {
                    682:                mysql_free_result(result);
1.38      veillard  683:                printf("sql_read_info_key: select returns NULL !\n");
1.1       veillard  684:                return(-1);
                    685:            }
                    686:            if (sscanf(row[0], "%d", &id) != 1) {
                    687:                mysql_free_result(result);
1.38      veillard  688:                printf("sql_read_info_key: ID non numeric %s\n", row[0]);
1.1       veillard  689:                return(-1);
                    690:            }
                    691:            mysql_free_result(result);
                    692:            return(id);
                    693:        }
                    694:        mysql_free_result(result);
                    695:     }
                    696:     if(mysql_errno(sql)) {
                    697:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                    698:        return(-1);
                    699:     }
                    700:     return(-1);
                    701: }
                    702: 
                    703: /************************************************************************
                    704:  *                                                                     *
                    705:  *                             Tables handling                         *
                    706:  *                                                                     *
                    707:  ************************************************************************/
                    708: 
1.2       veillard  709: int sql_rebuild_config(void) {
                    710:     const char *query =
                    711: "CREATE TABLE Config ( \n\
                    712:     ID int(11) NOT NULL auto_increment, \n\
                    713:     Name varchar(50) NOT NULL, \n\
                    714:     Value varchar(255), \n\
                    715:     PRIMARY KEY (ID), \n\
                    716:     KEY Name (Name(10)) \n\
                    717: )";
                    718: 
                    719:     if (mysql_query(sql,query)) {
                    720:        printf("sql_rebuild_config: CREATE TABLE Config failed %s\n",
                    721:               mysql_error(sql));
                    722:        return(-1);
                    723:     }
                    724:     return(0);
                    725: }
                    726: 
1.1       veillard  727: int sql_rebuild_vendors(void) {
                    728:     const char *query =
                    729: "CREATE TABLE Vendors ( \n\
                    730:     ID int(11) NOT NULL auto_increment, \n\
                    731:     Name varchar(255) NOT NULL, \n\
                    732:     URL varchar(255), \n\
                    733:     Key1 text, \n\
                    734:     Key2 text, \n\
                    735:     Key3 text, \n\
                    736:     Description text, \n\
                    737:     PRIMARY KEY (ID), \n\
                    738:     KEY Name (Name(10)) \n\
                    739: )";
                    740: 
                    741:     if (mysql_query(sql,query)) {
1.2       veillard  742:        printf("sql_rebuild_vendors: CREATE TABLE Vendors failed %s\n",
1.1       veillard  743:               mysql_error(sql));
                    744:        return(-1);
                    745:     }
                    746:     return(0);
                    747: }
                    748: 
1.36      veillard  749: int sql_rebuild_distributions(void) {
                    750:     const char *query =
                    751: "CREATE TABLE Distributions ( \n\
                    752:     ID int(11) NOT NULL auto_increment, \n\
                    753:     Name varchar(255) NOT NULL, \n\
                    754:     URL varchar(255), \n\
                    755:     Key1 text, \n\
                    756:     Key2 text, \n\
                    757:     Key3 text, \n\
                    758:     Description text, \n\
                    759:     PRIMARY KEY (ID), \n\
                    760:     KEY Name (Name(10)) \n\
                    761: )";
                    762: 
                    763:     if (mysql_query(sql,query)) {
                    764:        printf("sql_rebuild_ditributions: CREATE TABLE Distributions failed %s\n",
                    765:               mysql_error(sql));
                    766:        return(-1);
                    767:     }
                    768:     return(0);
                    769: }
                    770: 
1.1       veillard  771: int sql_rebuild_mirrors(void) {
                    772:     const char *query =
                    773: "CREATE TABLE Mirrors ( \n\
                    774:     ID int(11), \n\
                    775:     URL varchar(255) NOT NULL, \n\
                    776:     Country int(11), \n\
                    777:     UNIQUE(URL) \n\
                    778: )";
                    779: 
                    780:     if (mysql_query(sql,query)) {
1.2       veillard  781:        printf("sql_rebuild_mirrors: CREATE TABLE Mirrors failed %s\n",
                    782:               mysql_error(sql));
                    783:        return(-1);
                    784:     }
                    785:     return(0);
                    786: }
                    787: 
                    788: int sql_rebuild_metadata(void) {
                    789:     const char *query =
                    790: "CREATE TABLE Metadata ( \n\
                    791:     URL varchar(255) NOT NULL, \n\
                    792:     Maintainer int(11), \n\
                    793:     Country int(11), \n\
                    794:     UNIQUE(URL) \n\
                    795: )";
                    796: 
                    797:     if (mysql_query(sql,query)) {
                    798:        printf("sql_rebuild_metadata: CREATE TABLE Metadata failed %s\n",
1.1       veillard  799:               mysql_error(sql));
                    800:        return(-1);
                    801:     }
                    802:     return(0);
                    803: }
                    804: 
                    805: int sql_rebuild_distribs(void) {
                    806:     const char *query =
                    807: "CREATE TABLE Distribs ( \n\
                    808:     ID int(11) NOT NULL auto_increment, \n\
                    809:     Name varchar(255) NOT NULL, \n\
                    810:     Vendor int(11), \n\
1.2       veillard  811:     Directory varchar(255), \n\
1.1       veillard  812:     Path varchar(100) NOT NULL, \n\
                    813:     URL varchar(255), \n\
                    814:     URLSrc varchar(255), \n\
1.9       veillard  815:     Html varchar(8), \n\
                    816:     Color varchar(10), \n\
1.1       veillard  817:     Key1 text, \n\
                    818:     Key2 text, \n\
                    819:     Description text, \n\
                    820:     PRIMARY KEY (ID), \n\
                    821:     KEY Name (Name(10)) \n\
                    822: )";
                    823: 
                    824:     if (mysql_query(sql,query)) {
1.2       veillard  825:        printf("sql_rebuild_distribs: CREATE TABLE Distribs failed %s\n",
                    826:               mysql_error(sql));
                    827:        return(-1);
                    828:     }
                    829:     return(0);
                    830: }
                    831: 
                    832: int sql_rebuild_packages(void) {
                    833:     const char *query =
                    834: "CREATE TABLE Packages ( \n\
                    835: ID int(11) NOT NULL auto_increment, \n\
                    836: filename varchar(255) NOT NULL, \n\
                    837: Name varchar(50) NOT NULL, \n\
                    838: Version varchar(50) NOT NULL, \n\
                    839: Release varchar(50) NOT NULL, \n\
1.6       veillard  840: Arch varchar(15) NOT NULL, \n\
1.2       veillard  841: Dist int(11), \n\
                    842: URL varchar(255), \n\
                    843: URLSrc varchar(255), \n\
                    844: Vendor int(11), \n\
                    845: Packager int(11), \n\
                    846: Category varchar(255), \n\
                    847: Summary varchar(255), \n\
                    848: Description text, \n\
                    849: Copyright varchar(255), \n\
1.25      veillard  850: Date int(11), \n\
1.41      veillard  851: Size int(11), \n\
1.33      veillard  852: Os varchar(12), \n\
1.2       veillard  853: PRIMARY KEY (ID), \n\
1.7       veillard  854: KEY filename (filename(80)), \n\
                    855: KEY Name (Name(15)) \n\
1.2       veillard  856: )";
                    857: 
                    858:     if (mysql_query(sql,query)) {
                    859:        printf("sql_rebuild_packages: CREATE TABLE Packages failed %s\n",
                    860:               mysql_error(sql));
                    861:        return(-1);
                    862:     }
                    863:     return(0);
                    864: }
                    865: 
                    866: int sql_rebuild_files(void) {
                    867:     const char *query =
                    868: "CREATE TABLE Files ( \n\
1.6       veillard  869:     ID int(11) NOT NULL, \n\
1.7       veillard  870:     Path varchar(35) NOT NULL, \n\
                    871:     UNIQUE KEY id (ID,Path(35)), \n\
1.6       veillard  872:     INDEX (ID), \n\
                    873:     INDEX (Path) \n\
1.2       veillard  874: )";
                    875: 
                    876:     if (mysql_query(sql,query)) {
                    877:        printf("sql_rebuild_files: CREATE TABLE Files failed %s\n",
1.1       veillard  878:               mysql_error(sql));
                    879:        return(-1);
                    880:     }
                    881:     return(0);
                    882: }
                    883: 
1.8       veillard  884: int sql_rebuild_provides(void) {
                    885:     const char *query =
                    886: "CREATE TABLE Provides ( \n\
                    887:     ID int(11) NOT NULL, \n\
                    888:     Resource varchar(35) NOT NULL, \n\
                    889:     UNIQUE KEY id (ID,Resource(35)), \n\
                    890:     INDEX (ID), \n\
                    891:     INDEX (Resource) \n\
                    892: )";
                    893: 
                    894:     if (mysql_query(sql,query)) {
1.21      daniel    895:        printf("sql_rebuild_provides: CREATE TABLE Provides failed %s\n",
1.8       veillard  896:               mysql_error(sql));
                    897:        return(-1);
                    898:     }
                    899:     return(0);
                    900: }
                    901: 
                    902: int sql_rebuild_requires(void) {
                    903:     const char *query =
                    904: "CREATE TABLE Requires ( \n\
                    905:     ID int(11) NOT NULL, \n\
                    906:     Resource varchar(35) NOT NULL, \n\
                    907:     Rel char(2), \n\
                    908:     Value varchar(20), \n\
                    909:     UNIQUE KEY id (ID,Resource(35)), \n\
                    910:     INDEX (ID), \n\
                    911:     INDEX (Resource) \n\
                    912: )";
                    913: 
                    914:     if (mysql_query(sql,query)) {
1.21      daniel    915:        printf("sql_rebuild_requires: CREATE TABLE Requires failed %s\n",
                    916:               mysql_error(sql));
                    917:        return(-1);
                    918:     }
                    919:     return(0);
                    920: }
                    921: 
                    922: int sql_rebuild_queries(void) {
                    923:     const char *query =
                    924: "CREATE TABLE Queries ( \n\
                    925:     ID int(11) NOT NULL auto_increment,\n\
                    926:     Value varchar(50) NOT NULL, \n\
                    927:     Count int(11) NOT NULL, \n\
                    928:     Results int(11) NOT NULL, \n\
                    929:     UNIQUE KEY id (ID,Value(35)), \n\
                    930:     INDEX (ID), \n\
                    931:     INDEX (Value) \n\
                    932: )";
                    933: 
                    934:     if (mysql_query(sql,query)) {
                    935:        printf("sql_rebuild_queries: CREATE TABLE Queries failed %s\n",
1.8       veillard  936:               mysql_error(sql));
                    937:        return(-1);
                    938:     }
                    939:     return(0);
                    940: }
                    941: 
1.1       veillard  942: 
                    943: int sql_check_tables(void) {
                    944:     const char *query = "SHOW TABLES";
                    945:     MYSQL_RES *result;
                    946:     MYSQL_ROW row;
1.2       veillard  947:     int config = 0;
1.1       veillard  948:     int distribs = 0;
1.8       veillard  949:     int requires = 0;
                    950:     int provides = 0;
1.1       veillard  951:     int vendors = 0;
                    952:     int mirrors = 0;
1.2       veillard  953:     int metadata = 0;
                    954:     int packages = 0;
                    955:     int files = 0;
1.21      daniel    956:     int queries = 0;
1.36      veillard  957:     int distributions = 0;
1.2       veillard  958: 
1.1       veillard  959:     int rebuilt = 0;
                    960: 
                    961:     if (mysql_query(sql,query)) {
1.2       veillard  962:        printf("sql_check_tables: SHOW TABLES failed %s\n",
1.1       veillard  963:               mysql_error(sql));
                    964:        return(-1);
                    965:     }
                    966: 
                    967:     result = mysql_use_result(sql);
                    968:     if (result) {
                    969:        while((row = mysql_fetch_row(result)))
                    970:        {
                    971:            if (row[0] == NULL) {
                    972:                mysql_free_result(result);
                    973:                printf("sql_check_tables: SHOW TABLES returns NULL !\n");
                    974:                return(-1);
                    975:            }
1.2       veillard  976:            if (!strcmp(row[0], "Config"))
                    977:                config = 1;
1.1       veillard  978:            if (!strcmp(row[0], "Distribs"))
                    979:                distribs = 1;
                    980:            if (!strcmp(row[0], "Vendors"))
                    981:                vendors = 1;
                    982:            if (!strcmp(row[0], "Mirrors"))
                    983:                mirrors = 1;
1.2       veillard  984:            if (!strcmp(row[0], "Metadata"))
                    985:                metadata = 1;
                    986:            if (!strcmp(row[0], "Packages"))
                    987:                packages = 1;
                    988:            if (!strcmp(row[0], "Files"))
                    989:                files = 1;
1.8       veillard  990:            if (!strcmp(row[0], "Requires"))
                    991:                requires = 1;
                    992:            if (!strcmp(row[0], "Provides"))
                    993:                provides = 1;
1.21      daniel    994:            if (!strcmp(row[0], "Queries"))
                    995:                queries = 1;
1.36      veillard  996:            if (!strcmp(row[0], "Distributions"))
                    997:                distributions = 1;
1.1       veillard  998:        }
                    999:        mysql_free_result(result);
                   1000:     }
                   1001:     if(mysql_errno(sql)) {
                   1002:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1003:        return(-1);
                   1004:     }
                   1005: 
1.2       veillard 1006:     if (!config) {
                   1007:        fprintf(stderr, "Table Config disapeared: rebuilding it\n");
                   1008:        if (!sql_rebuild_config())
                   1009:            rebuilt++;
                   1010:     }
1.1       veillard 1011:     if (!vendors) {
                   1012:        fprintf(stderr, "Table Vendors disapeared: rebuilding it\n");
                   1013:        if (!sql_rebuild_vendors())
                   1014:            rebuilt++;
                   1015:     }
                   1016:     if (!distribs) {
                   1017:        fprintf(stderr, "Table Distribs disapeared: rebuilding it\n");
                   1018:        if (!sql_rebuild_distribs())
                   1019:            rebuilt++;
                   1020:     }
                   1021:     if (!mirrors) {
                   1022:        fprintf(stderr, "Table Mirrors disapeared: rebuilding it\n");
                   1023:        if (!sql_rebuild_mirrors())
                   1024:            rebuilt++;
                   1025:     }
1.2       veillard 1026:     if (!metadata) {
                   1027:        fprintf(stderr, "Table Metadata disapeared: rebuilding it\n");
                   1028:        if (!sql_rebuild_metadata())
                   1029:            rebuilt++;
                   1030:     }
                   1031:     if (!packages) {
                   1032:        fprintf(stderr, "Table Packages disapeared: rebuilding it\n");
                   1033:        if (!sql_rebuild_packages())
                   1034:            rebuilt++;
                   1035:     }
                   1036:     if (!files) {
                   1037:        fprintf(stderr, "Table Files disapeared: rebuilding it\n");
                   1038:        if (!sql_rebuild_files())
                   1039:            rebuilt++;
                   1040:     }
1.8       veillard 1041:     if (!requires) {
                   1042:        fprintf(stderr, "Table Requires disapeared: rebuilding it\n");
                   1043:        if (!sql_rebuild_requires())
                   1044:            rebuilt++;
                   1045:     }
                   1046:     if (!provides) {
                   1047:        fprintf(stderr, "Table Provides disapeared: rebuilding it\n");
                   1048:        if (!sql_rebuild_provides())
1.21      daniel   1049:            rebuilt++;
                   1050:     }
                   1051:     if (!queries) {
                   1052:        fprintf(stderr, "Table Queries disapeared: rebuilding it\n");
                   1053:        if (!sql_rebuild_queries())
1.8       veillard 1054:            rebuilt++;
                   1055:     }
1.36      veillard 1056:     if (!distributions) {
                   1057:        fprintf(stderr, "Table Distributions disapeared: rebuilding it\n");
                   1058:        if (!sql_rebuild_distributions())
                   1059:            rebuilt++;
                   1060:     }
1.1       veillard 1061:     return(rebuilt);
                   1062: }
                   1063: 
                   1064: /************************************************************************
                   1065:  *                                                                     *
                   1066:  *                     Specific rpm2html functions                     *
                   1067:  *                                                                     *
                   1068:  ************************************************************************/
                   1069: 
1.5       veillard 1070: int sql_add_dist_mirror(int distrib, const char *URL, int country) {
1.1       veillard 1071:     if (URL == NULL)
                   1072:        return(-1);
                   1073:     if (distrib < 0)
                   1074:        return(-1);
                   1075:     return(sql_blind_insert("Mirrors", "URL", URL, distrib));
                   1076: }
                   1077: 
1.5       veillard 1078: int sql_add_mirror(const char *Name, const char *URL, int country) {
1.1       veillard 1079:     int distrib;
                   1080: 
                   1081:     if ((Name == NULL) || (URL == NULL))
                   1082:        return(-1);
                   1083:     distrib = sql_read_key("Distribs", Name);
                   1084:     if (distrib < 0)
                   1085:        return(distrib);
                   1086:     return(sql_blind_insert("Mirrors", "URL", URL, distrib));
                   1087: }
                   1088: 
1.6       veillard 1089: int sql_add_file(const char *filename, int package) {
                   1090:     if ((filename == NULL) || (package <= 0))
                   1091:        return(-1);
1.7       veillard 1092:     if (strlen(filename) > 35)
                   1093:        return(0);
1.6       veillard 1094: 
                   1095:     return(sql_blind_insert("Files", "Path", filename, package));
                   1096: }
                   1097: 
1.8       veillard 1098: int sql_add_provides(int package, const char *resource) {
                   1099:     if ((resource == NULL) || (package <= 0))
                   1100:        return(-1);
                   1101:     if (strlen(resource) > 35)
                   1102:        return(0);
                   1103: 
                   1104:     return(sql_blind_insert("Provides", "Resource", resource, package));
                   1105: }
                   1106: 
1.14      veillard 1107: int sql_add_requires(int package, const char *resource, rpm_dep_flag rel,
1.8       veillard 1108:                     const char *value) {
                   1109:     int record;
                   1110:     if ((resource == NULL) || (package <= 0))
                   1111:        return(-1);
                   1112:     if (strlen(resource) > 35)
                   1113:        return(0);
                   1114: 
                   1115:     record = sql_blind_insert("Requires", "Resource", resource, package);
1.14      veillard 1116:     if ((rel != RPM2HTML_REQ_NONE) && (value != NULL) &&
                   1117:        (strlen(value) <= 50)) {
1.8       veillard 1118:        char query[SMALL_QUERY];
1.14      veillard 1119: 
                   1120:        switch (rel) {
                   1121:            case RPM2HTML_REQ_LT:
                   1122:                snprintf(query, SMALL_QUERY - 1,
                   1123:                         "UPDATE Requires SET Rel='<',Value='%s' WHERE ID=%d",
                   1124:                         value, record);
1.15      daniel   1125:                break;
1.14      veillard 1126:            case RPM2HTML_REQ_LEQ:
                   1127:                snprintf(query, SMALL_QUERY - 1,
                   1128:                         "UPDATE Requires SET Rel='<=',Value='%s' WHERE ID=%d",
                   1129:                         value, record);
1.15      daniel   1130:                break;
1.14      veillard 1131:            case RPM2HTML_REQ_GT:
                   1132:                snprintf(query, SMALL_QUERY - 1,
                   1133:                         "UPDATE Requires SET Rel='>',Value='%s' WHERE ID=%d",
                   1134:                         value, record);
1.15      daniel   1135:                break;
1.14      veillard 1136:            case RPM2HTML_REQ_GEQ:
                   1137:                snprintf(query, SMALL_QUERY - 1,
                   1138:                         "UPDATE Requires SET Rel='>=',Value='%s' WHERE ID=%d",
                   1139:                         value, record);
1.15      daniel   1140:                break;
1.14      veillard 1141:            case RPM2HTML_REQ_EQU:
                   1142:                snprintf(query, SMALL_QUERY - 1,
                   1143:                         "UPDATE Requires SET Rel='=',Value='%s' WHERE ID=%d",
                   1144:                         value, record);
1.15      daniel   1145:                break;
1.14      veillard 1146:            case RPM2HTML_REQ_NONE:
                   1147:                query[0] = 0;
                   1148:        }
1.8       veillard 1149:        query[SMALL_QUERY - 1] = 0;
                   1150:        if (mysql_query(sql,query)) {
1.38      veillard 1151:            printf("sql_add_requires: UPDATE Requires %d failed %s\n",
1.8       veillard 1152:                   record, mysql_error(sql));
                   1153:            return(record);
                   1154:        }
                   1155:     }
                   1156:     return(record);
                   1157: }
                   1158: 
1.34      veillard 1159: int sql_add_vendor(const char *Name, const char *URL, const char *Description) {
                   1160:     int id;
                   1161: 
                   1162:     if (Name == NULL)
                   1163:        return(-1);
                   1164: 
                   1165:     id = sql_get_key("Vendors", "Name", Name);
                   1166:     if (id <= 0) {
                   1167:        id = sql_blind_insert("Vendors", "Name", Name, 0);
                   1168:        if (id <= 0)
                   1169:            return(id);
                   1170:     }
                   1171:     if (URL != NULL)
                   1172:        sql_update_id("Vendors", id, "URL", URL);
                   1173:     if (Description != NULL)
                   1174:        sql_update_id("Vendors", id,
                   1175:                                   "Description", Description);
                   1176:     
                   1177:     return(id);
                   1178: }
                   1179: 
1.36      veillard 1180: int sql_add_distribution(const char *Name, const char *URL, const char *Description) {
                   1181:     int id;
                   1182: 
                   1183:     if (Name == NULL)
                   1184:        return(-1);
                   1185: 
                   1186:     id = sql_get_key("Distributions", "Name", Name);
                   1187:     if (id <= 0) {
                   1188:        id = sql_blind_insert("Distributions", "Name", Name, 0);
                   1189:        if (id <= 0)
                   1190:            return(id);
                   1191:     }
                   1192:     if (URL != NULL)
                   1193:        sql_update_id("Distributions", id, "URL", URL);
                   1194:     if (Description != NULL)
                   1195:        sql_update_id("Distributions", id,
                   1196:                                   "Description", Description);
                   1197:     
                   1198:     return(id);
                   1199: }
                   1200: 
1.34      veillard 1201: 
1.5       veillard 1202: int sql_add_package(const char *filename,
1.2       veillard 1203:        const char *Name, const char *Version, const char *Release,
1.6       veillard 1204:        const char *Arch,
                   1205:        int dist, const char *URL, const char *URLSrc, int vendor,
1.2       veillard 1206:        const char *Packager, const char *Category, const char *Summary,
1.41      veillard 1207:        const char *Description, const char *Copyright, int Date, int Size,
1.43      veillard 1208:        const char *Os, const char *Distribution, const char *Vendor) {
1.2       veillard 1209:     int id;
                   1210:     int nb_fields = 0;
1.35      veillard 1211:     char installed_filename[500];
1.2       veillard 1212: 
1.35      veillard 1213:     if (filename == NULL) {
                   1214:        sprintf(installed_filename, "localbase/%s-%s-%s.%s.rpm",
                   1215:                Name,Version,Release,Arch);
                   1216:        filename = installed_filename;
                   1217:     }
1.6       veillard 1218: 
                   1219:     if (dist < 0)
1.2       veillard 1220:        return(-1);
1.6       veillard 1221:     if ((Name == NULL) || (Version == NULL) || (Release == NULL) ||
                   1222:        (Arch == NULL))
                   1223:        return(-1);
                   1224: 
                   1225:     id = sql_get_key("Packages", "filename", filename);
1.2       veillard 1226:     if (id <= 0)
                   1227:        return(-1);
                   1228:     nb_fields = 1;
1.8       veillard 1229: 
                   1230:     if (rpm2htmlVerbose > 1)
                   1231:        printf("Adding %s ID %d\n", filename, id);
                   1232: 
1.2       veillard 1233:     if (Name != NULL)
1.6       veillard 1234:        nb_fields += sql_update_id("Packages", id, "Name", Name);
1.2       veillard 1235:     if (Version != NULL)
                   1236:        nb_fields += sql_update_id("Packages", id, "Version", Version);
                   1237:     if (Release != NULL)
                   1238:        nb_fields += sql_update_id("Packages", id, "Release", Release);
1.6       veillard 1239:     if (Release != NULL)
                   1240:        nb_fields += sql_update_id("Packages", id, "Arch", Arch);
1.2       veillard 1241:     if (Category != NULL)
                   1242:        nb_fields += sql_update_id("Packages", id, "Category", Category);
                   1243:     if (URL != NULL)
                   1244:        nb_fields += sql_update_id("Packages", id, "URL", URL);
                   1245:     if (URLSrc != NULL)
                   1246:        nb_fields += sql_update_id("Packages", id, "URLSrc", URLSrc);
1.17      veillard 1247:     if (dist >= 0) {
                   1248:        char str[30];
                   1249:        snprintf(str, 30, "%d", dist);
                   1250:        str[29] = 0;
                   1251:        nb_fields += sql_update_id("Packages", id, "Dist", str);
                   1252:     }
1.38      veillard 1253:     if (Summary != NULL) {
1.2       veillard 1254:        nb_fields += sql_update_id("Packages", id, "Summary", Summary);
1.38      veillard 1255:     }
                   1256:     if (Description != NULL) {
1.2       veillard 1257:        nb_fields += sql_update_id("Packages", id,
                   1258:                                   "Description", Description);
1.38      veillard 1259:     }
1.2       veillard 1260:     if (Copyright != NULL)
                   1261:        nb_fields += sql_update_id("Packages", id, "Copyright", Copyright);
1.25      veillard 1262:     if (Date != 0) {
                   1263:        char str[30];
                   1264:        snprintf(str, 30, "%d", Date);
                   1265:        str[29] = 0;
                   1266:        nb_fields += sql_update_id("Packages", id, "Date", str);
                   1267:     }
1.41      veillard 1268:     if (Size != 0) {
                   1269:        char str[30];
                   1270:        snprintf(str, 30, "%d", Size);
                   1271:        str[29] = 0;
                   1272:        nb_fields += sql_update_id("Packages", id, "Size", str);
                   1273:     }
1.38      veillard 1274:     if (Os != NULL) {
1.33      veillard 1275:        nb_fields += sql_update_id("Packages", id, "Os", Os);
1.38      veillard 1276:     }
1.34      veillard 1277:     if (Packager != NULL) {
                   1278:        char str[30];
1.35      veillard 1279:        int packager = sql_add_vendor(Packager, NULL, NULL);
1.34      veillard 1280: 
1.35      veillard 1281:        if (packager > 0) {
                   1282:            snprintf(str, 30, "%d", packager);
1.34      veillard 1283:            str[29] = 0;
1.35      veillard 1284:            nb_fields += sql_update_id("Packages", id, "Packager", str);
1.34      veillard 1285:        }
                   1286:     }
1.36      veillard 1287:     if (Distribution != NULL) {
                   1288:        char str[30];
                   1289:        int packager = sql_add_distribution(Distribution, NULL, NULL);
                   1290: 
                   1291:        if (packager > 0) {
                   1292:            snprintf(str, 30, "%d", packager);
                   1293:            str[29] = 0;
                   1294:            nb_fields += sql_update_id("Packages", id, "Vendor", str);
                   1295:        }
                   1296:     }
                   1297:     /***************
                   1298:     if (vendor > 0) {
                   1299:        char str[30];
                   1300:        snprintf(str, 30, "%d", vendor);
                   1301:        str[29] = 0;
                   1302:        nb_fields += sql_update_id("Packages", id, "Vendor", str);
                   1303:     }
                   1304:      ***************/
1.2       veillard 1305:     
1.6       veillard 1306:     return(id);
1.17      veillard 1307: }
                   1308: 
                   1309: int sql_get_distrib_by_name(const char *Name) {
                   1310:     int ret;
                   1311: 
                   1312:     if (Name == NULL)
                   1313:        return(-1);
                   1314:     ret = sql_read_key("Distribs", Name);
                   1315: 
1.18      daniel   1316: #ifdef SQL_DEBUG
1.17      veillard 1317: fprintf(stderr, "sql_get_distrib_by_name(%s) => %d\n", Name, ret);
1.18      daniel   1318: #endif
1.17      veillard 1319: 
                   1320:     return(ret);
                   1321: }
                   1322: 
                   1323: int sql_get_distrib_by_directory(const char *Directory) {
                   1324:     int ret;
                   1325: 
                   1326:     if (Directory == NULL)
                   1327:        return(-1);
                   1328: 
                   1329:     ret = sql_get_key("Distribs", "Directory", Directory);
                   1330: 
1.18      daniel   1331: #ifdef SQL_DEBUG
1.17      veillard 1332: fprintf(stderr, "sql_get_distrib_by_directory(%s) => %d\n", Directory, ret);
1.18      daniel   1333: #endif
1.17      veillard 1334: 
                   1335:     return(ret);
1.2       veillard 1336: }
                   1337: 
1.5       veillard 1338: int sql_add_distrib(const char *Name, const char *Vendor,
1.2       veillard 1339:        const char *Directory, const char *Path, const char *URL,
1.9       veillard 1340:        const char *URLSrc, const char *Description,
                   1341:        const char *Html, const char *Color) {
1.1       veillard 1342:     int id, vendor;
                   1343:     int nb_fields = 0;
                   1344:     char VendorStr[15];
                   1345: 
                   1346:     if (Name == NULL)
                   1347:        return(-1);
                   1348: 
1.6       veillard 1349:     id = sql_get_key("Distribs", "Name", Name);
1.1       veillard 1350:     nb_fields = 1;
                   1351:     if (Vendor != NULL) {
1.6       veillard 1352:        vendor = sql_get_key("Vendors", "Name", Vendor);
1.1       veillard 1353:        sprintf(VendorStr, "%d", vendor);
                   1354:        nb_fields += sql_update_id("Distribs", id, "Vendor", VendorStr);
                   1355:     }
1.2       veillard 1356:     if (Directory != NULL)
                   1357:        nb_fields += sql_update_id("Distribs", id, "Directory", Directory);
1.1       veillard 1358:     if (Path != NULL)
                   1359:        nb_fields += sql_update_id("Distribs", id, "Path", Path);
                   1360:     if (URL != NULL)
                   1361:        nb_fields += sql_update_id("Distribs", id, "URL", URL);
                   1362:     if (URLSrc != NULL)
                   1363:        nb_fields += sql_update_id("Distribs", id, "URLSrc", URLSrc);
1.9       veillard 1364:     if (Html != NULL)
                   1365:        nb_fields += sql_update_id("Distribs", id, "Html", Html);
                   1366:     if (Color != NULL)
                   1367:        nb_fields += sql_update_id("Distribs", id, "Color", Color);
1.1       veillard 1368:     if (Description != NULL)
                   1369:        nb_fields += sql_update_id("Distribs", id,
                   1370:                                   "Description", Description);
                   1371:     
                   1372:     return(nb_fields);
                   1373: }
                   1374: 
1.5       veillard 1375: void sql_add_config_info(const char *name, const char *value) {
1.2       veillard 1376:     sql_update("Config", name, "Value", value);
                   1377: }
                   1378: 
1.5       veillard 1379: void sql_add_metadata_base(const char *URL) {
1.2       veillard 1380:     sql_blind_insert("Metadata", "URL", URL, -1);
                   1381: }
                   1382: 
1.6       veillard 1383: /************************************************************************
                   1384:  *                                                                     *
1.8       veillard 1385:  *                     Cleanup functions                               *
                   1386:  *                                                                     *
                   1387:  ************************************************************************/
                   1388: 
                   1389: int sql_remove_package(int id) {
                   1390:     char query[SMALL_QUERY];
                   1391: 
                   1392:     if (id <= 0)
                   1393:        return(-1);
                   1394: 
                   1395:     /*
                   1396:      * remove the ID from the package list
                   1397:      */
                   1398:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Packages WHERE ID=%d", id);
                   1399:     query[SMALL_QUERY - 1] = 0;
                   1400:     if (mysql_query(sql,query)) {
1.38      veillard 1401:        printf("sql_remove_package: DELETE package %d failed %s\n", id, mysql_error(sql));
1.8       veillard 1402:        return(-1);
                   1403:     }
                   1404:     if(mysql_errno(sql)) {
                   1405:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1406:        return(-1);
                   1407:     }
                   1408: 
                   1409:     /*
                   1410:      * remove the associated files from the Files list
                   1411:      */
                   1412:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Files WHERE ID=%d", id);
                   1413:     query[SMALL_QUERY - 1] = 0;
                   1414:     if (mysql_query(sql,query)) {
1.38      veillard 1415:        printf("sql_remove_package: DELETE Files %d failed %s\n", id, mysql_error(sql));
1.8       veillard 1416:        return(-1);
                   1417:     }
                   1418:     if(mysql_errno(sql)) {
                   1419:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1420:        return(-1);
                   1421:     }
                   1422: 
                   1423:     /*
                   1424:      * remove the associated Provides entries
                   1425:      */
                   1426:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Provides WHERE ID=%d", id);
                   1427:     query[SMALL_QUERY - 1] = 0;
                   1428:     if (mysql_query(sql,query)) {
1.38      veillard 1429:        printf("sql_remove_package: DELETE Provides %d failed %s\n", id, mysql_error(sql));
1.8       veillard 1430:        return(-1);
                   1431:     }
                   1432:     if(mysql_errno(sql)) {
                   1433:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1434:        return(-1);
                   1435:     }
                   1436: 
                   1437:     /*
                   1438:      * remove the associated Requires entries
                   1439:      */
                   1440:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Requires WHERE ID=%d", id);
                   1441:     query[SMALL_QUERY - 1] = 0;
                   1442:     if (mysql_query(sql,query)) {
1.38      veillard 1443:        printf("sql_remove_package: DELETE Requires %d failed %s\n", id, mysql_error(sql));
1.8       veillard 1444:        return(-1);
                   1445:     }
                   1446:     if(mysql_errno(sql)) {
                   1447:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1448:        return(-1);
                   1449:     }
                   1450: 
1.42      veillard 1451:     /*
                   1452:      * Remove the RDF and HTML files.
                   1453:      * TODO
                   1454:      */
1.8       veillard 1455:     return(-1);
                   1456: }
                   1457: 
                   1458: int sql_check_packages(void) {
                   1459:     MYSQL_RES *result;
                   1460:     MYSQL_ROW row;
1.20      daniel   1461:     char *query = "SELECT filename,ID FROM Packages";
1.8       veillard 1462:     struct stat buf;
                   1463:     int id;
1.22      daniel   1464:     int ids[2500]; /* Do not remove more than 2500 package per run */
1.8       veillard 1465:     int index;
                   1466:     int total = 0;
                   1467: 
                   1468:     if (rpm2htmlVerbose)
                   1469:        printf("Database cleanup\n");
1.42      veillard 1470:     sqlInitSqlDistributionList();
1.8       veillard 1471:     index = 0;
                   1472:     /*
                   1473:      * Search first for the ID if it already exists
                   1474:      */
                   1475:     if (mysql_query(sql,query)) {
                   1476:        printf("sql_check_packages: SELECT from Packages failed: %s\n",
                   1477:               mysql_error(sql));
                   1478:        return(-1);
                   1479:     }
                   1480: 
                   1481:     result = mysql_use_result(sql);
                   1482:     if (result) {
                   1483:        while((row = mysql_fetch_row(result)))
                   1484:        {
                   1485:            if ((row[0] == NULL) || (row[1] == NULL)) {
                   1486:                printf("sql_check_packages: Path or ID is NULL !\n");
                   1487:                continue;
                   1488:            }
1.35      veillard 1489:            if (!strncmp(row[0], "localbase", 9))
                   1490:                continue;
                   1491: 
1.8       veillard 1492:            if ((stat(row[0], &buf) < 0) || (buf.st_size < 50)) {
                   1493:                /*
                   1494:                 * Need to remove the package from the database.
                   1495:                 */
                   1496:                if (sscanf(row[1], "%d", &id) != 1) {
                   1497:                    printf("sql_check_packages: ID non numeric %s\n", row[1]);
                   1498:                    continue;
                   1499:                }
                   1500:                ids[index++] = id;
1.20      daniel   1501:                if (rpm2htmlVerbose)
1.8       veillard 1502:                    printf("Removing %s ID %d\n", row[0], id);
1.22      daniel   1503:                if (index >= 2500)
1.8       veillard 1504:                    break;
                   1505:            }
                   1506:        }
                   1507:        mysql_free_result(result);
                   1508:     }
                   1509:     if(mysql_errno(sql)) {
                   1510:        fprintf(stderr, "sql_update Error: %s\n", mysql_error(sql));
                   1511:        return(-1);
                   1512:     }
                   1513: 
                   1514:     /*
                   1515:      * Do the cleanup.
                   1516:      */
1.20      daniel   1517:     if (rpm2htmlVerbose)
                   1518:        printf("Database cleanup : removing %d entries...\n", index);
1.8       veillard 1519:     for (id = 0;id < index;id++) {
                   1520:        sql_remove_package(ids[id]);
                   1521:     }
                   1522: 
1.34      veillard 1523:     printf("Database cleanup : removed %d entries\n", index);
1.8       veillard 1524:     return(total);
                   1525: }
                   1526: 
                   1527: /************************************************************************
1.26      veillard 1528:  *                                                                     *
                   1529:  *                     Package lists extraction                        *
                   1530:  *                                                                     *
                   1531:  ************************************************************************/
                   1532: int sqlDirListInitialized = 0;
                   1533: rpmDirPtr sqlDirList[SQL_MAX_DISTRIBS];
1.35      veillard 1534: int sqlVendorListInitialized = 0;
                   1535: int sqlVendorListLen;
                   1536: char **sqlVendorList;
1.36      veillard 1537: int sqlDistributionListInitialized = 0;
                   1538: int sqlDistributionListLen;
                   1539: char **sqlDistributionList;
1.40      veillard 1540: int sqlResourceListInitialized = 0;
                   1541: int sqlResourceListLen = 0;
                   1542: int sqlResourceListMax = 0;
                   1543: char **sqlResourceList;
                   1544: 
                   1545: char *
                   1546: sqlRpmAnalyzeResourceRow(MYSQL_ROW row) {
                   1547:     const char *name;
                   1548:     char **tmp, *ret;
                   1549: 
                   1550:     if (row == NULL)
                   1551:        return(NULL);
                   1552:     name = row[0];
                   1553:     if (name == NULL)
                   1554:        return(NULL);
                   1555: 
                   1556:     if (sqlResourceListLen >= sqlResourceListMax) {
                   1557:        sqlResourceListMax *= 2;
1.45      veillard 1558:        tmp = (char **) xmlRealloc(sqlResourceList,
1.40      veillard 1559:                                     (sqlResourceListMax) * sizeof(char *));
                   1560:        if (sqlResourceList == NULL) {
                   1561:            fprintf(stderr, "sqlInitSqlResourceList Error: out of memory\n");
                   1562:            return(NULL);
                   1563:        }
                   1564:        sqlResourceList = tmp;
                   1565:     }
                   1566: 
1.45      veillard 1567:     ret = sqlResourceList[sqlResourceListLen++] = xmlStrdup(name);
1.40      veillard 1568:     return(ret);
                   1569: }
                   1570: 
                   1571: void
                   1572: sqlInitSqlResourceList(void) {
                   1573:     MYSQL_RES *result;
                   1574:     MYSQL_ROW row;
                   1575:     char *query;
                   1576:     int i;
                   1577: 
                   1578:     if (sqlResourceListInitialized != 0)
                   1579:        return;
                   1580: 
1.45      veillard 1581: #ifdef SQL_DEBUG_MEM
                   1582:     printf("sqlInitSqlResourceList\n");
                   1583: #endif
1.40      veillard 1584:     if (rpm2htmlVerbose)
                   1585:        printf("sqlInitSqlResourceList query\n");
                   1586: 
                   1587:     /*
                   1588:      * Allocate the array
                   1589:      */
                   1590:     sqlResourceListLen = 0;
                   1591:     sqlResourceListMax = 1000;
1.45      veillard 1592:     sqlResourceList = (char **) xmlMalloc((sqlResourceListMax) *
1.40      veillard 1593:                                            sizeof(char *));
                   1594:     if (sqlResourceList == NULL) {
                   1595:        fprintf(stderr, "sqlInitSqlResourceList Error: out of memory\n");
                   1596:        return;
                   1597:     }
                   1598:     
                   1599:     /*
                   1600:      * query the database for the values
                   1601:      */
                   1602:     query = "select Resource from Provides group by Resource";
                   1603: 
                   1604:     if (mysql_query(sql,query)) {
                   1605:        printf("sqlInitSqlResourceList: SELECT from Provides failed: %s\n",
                   1606:               mysql_error(sql));
                   1607:        return;
                   1608:     }
                   1609: 
                   1610:     i = 0;
                   1611:     result = mysql_use_result(sql);
                   1612:     if (result) {
                   1613:        while((row = mysql_fetch_row(result)))
                   1614:        {
                   1615:            if (sqlRpmAnalyzeResourceRow(row) != NULL)
                   1616:                i++;
                   1617:        }
                   1618:        mysql_free_result(result);
                   1619:     }
                   1620:     if(mysql_errno(sql)) {
                   1621:        fprintf(stderr, "sqlInitSqlResourceList Error: %s\n", mysql_error(sql));
                   1622:        return;
                   1623:     }
                   1624: 
                   1625: 
                   1626:     if (rpm2htmlVerbose)
                   1627:        printf("sqlInitSqlResourceList done: %d entries\n", i);
                   1628:     sqlResourceListInitialized++;
                   1629:     return;
                   1630: }
1.36      veillard 1631: 
                   1632: char *
                   1633: sqlRpmAnalyzeDistributionRow(MYSQL_ROW row) {
                   1634:     const char *id;
                   1635:     const char *name;
                   1636:     char **tmp;
                   1637:     int distribution;
                   1638: 
                   1639:     if (row == NULL)
                   1640:        return(NULL);
                   1641:     id = row[0];
                   1642:     name = row[1];
                   1643:     if ((id == NULL) || (name == NULL))
                   1644:        return(NULL);
                   1645: 
                   1646:     if (sscanf(id, "%d", &distribution) != 1)
                   1647:        return(NULL);
                   1648:     if ((distribution <= 0) || (distribution > 100000)) {
                   1649:        fprintf(stderr, "Dist number out of range %d\n", distribution);
                   1650:        return(NULL);
                   1651:     }
                   1652:     if (distribution >= sqlDistributionListLen) {
                   1653:        int i = sqlDistributionListLen;
                   1654:        sqlDistributionListLen = distribution + 100;
1.45      veillard 1655:        tmp = (char **) xmlRealloc(sqlDistributionList,
1.36      veillard 1656:                                     (sqlDistributionListLen) * sizeof(char *));
                   1657:        if (sqlDistributionList == NULL) {
                   1658:            fprintf(stderr, "sqlInitSqlDistributionList Error: out of memory\n");
                   1659:            return(NULL);
                   1660:        }
                   1661:        sqlDistributionList = tmp;
                   1662:        memset(&sqlDistributionList[i], 0, sizeof(char *) * (sqlDistributionListLen - i));
                   1663:     }
                   1664: 
1.45      veillard 1665:     sqlDistributionList[distribution] = xmlStrdup(name);
1.36      veillard 1666:     return(sqlDistributionList[distribution]);
                   1667: }
                   1668: 
                   1669: void
                   1670: sqlInitSqlDistributionList(void) {
                   1671:     MYSQL_RES *result;
                   1672:     MYSQL_ROW row;
                   1673:     char *query;
                   1674:     int i;
                   1675: 
                   1676:     if (sqlDistributionListInitialized != 0)
                   1677:        return;
                   1678: 
1.45      veillard 1679: #ifdef SQL_DEBUG_MEM
                   1680:     printf("sqlInitSqlDistributionList\n");
                   1681: #endif
1.36      veillard 1682:     if (rpm2htmlVerbose)
                   1683:        printf("sqlInitSqlDistributionList query\n");
                   1684: 
                   1685:     /*
                   1686:      * Allocate the array
                   1687:      */
                   1688:     sqlDistributionListLen = 100;
1.45      veillard 1689:     sqlDistributionList = (char **) xmlMalloc((sqlDistributionListLen) * sizeof(char *));
1.36      veillard 1690:     if (sqlDistributionList == NULL) {
                   1691:        fprintf(stderr, "sqlInitSqlDistributionList Error: out of memory\n");
                   1692:        return;
                   1693:     }
1.40      veillard 1694:     memset(sqlDistributionList, 0, (sqlDistributionListLen) * sizeof(char *));
                   1695: 
1.36      veillard 1696:     /*
                   1697:      * query the database for the values
                   1698:      */
                   1699:     query = "select ID,Name from Distributions";
                   1700: 
                   1701:     if (mysql_query(sql,query)) {
                   1702:        printf("sqlInitSqlDistributionList: SELECT from Distributions failed: %s\n",
                   1703:               mysql_error(sql));
                   1704:        return;
                   1705:     }
                   1706: 
                   1707:     i = 0;
                   1708:     result = mysql_use_result(sql);
                   1709:     if (result) {
                   1710:        while((row = mysql_fetch_row(result)))
                   1711:        {
                   1712:            if (sqlRpmAnalyzeDistributionRow(row) != NULL)
                   1713:                i++;
                   1714:        }
                   1715:        mysql_free_result(result);
                   1716:     }
                   1717:     if(mysql_errno(sql)) {
                   1718:        fprintf(stderr, "sqlInitSqlDistributionList Error: %s\n", mysql_error(sql));
                   1719:        return;
                   1720:     }
                   1721: 
                   1722: 
                   1723:     if (rpm2htmlVerbose)
                   1724:        printf("sqlInitSqlDistributionList done: %d entries\n", i);
                   1725:     sqlDistributionListInitialized++;
                   1726:     return;
                   1727: }
                   1728: 
1.35      veillard 1729: 
                   1730: char *
                   1731: sqlRpmAnalyzeVendorRow(MYSQL_ROW row) {
                   1732:     const char *id;
                   1733:     const char *name;
                   1734:     char **tmp;
                   1735:     int vendor;
                   1736: 
                   1737:     if (row == NULL)
                   1738:        return(NULL);
                   1739:     id = row[0];
                   1740:     name = row[1];
                   1741:     if ((id == NULL) || (name == NULL))
                   1742:        return(NULL);
                   1743: 
                   1744:     if (sscanf(id, "%d", &vendor) != 1)
                   1745:        return(NULL);
                   1746:     if ((vendor <= 0) || (vendor > 100000)) {
                   1747:        fprintf(stderr, "Dist number out of range %d\n", vendor);
                   1748:        return(NULL);
                   1749:     }
                   1750:     if (vendor >= sqlVendorListLen) {
                   1751:        int i = sqlVendorListLen;
                   1752:        sqlVendorListLen = vendor + 100;
1.45      veillard 1753:        tmp = (char **) xmlRealloc(sqlVendorList,
1.35      veillard 1754:                                     (sqlVendorListLen) * sizeof(char *));
                   1755:        if (sqlVendorList == NULL) {
                   1756:            fprintf(stderr, "sqlInitSqlVendorList Error: out of memory\n");
                   1757:            return(NULL);
                   1758:        }
                   1759:        sqlVendorList = tmp;
                   1760:        memset(&sqlVendorList[i], 0, sizeof(char *) * (sqlVendorListLen - i));
                   1761:     }
                   1762: 
1.45      veillard 1763:     sqlVendorList[vendor] = xmlStrdup(name);
1.35      veillard 1764:     return(sqlVendorList[vendor]);
                   1765: }
                   1766: 
                   1767: void
                   1768: sqlInitSqlVendorList(void) {
                   1769:     MYSQL_RES *result;
                   1770:     MYSQL_ROW row;
                   1771:     char *query;
                   1772:     int i;
                   1773: 
                   1774:     if (sqlVendorListInitialized != 0)
                   1775:        return;
                   1776: 
1.45      veillard 1777: #ifdef SQL_DEBUG_MEM
                   1778:     printf("sqlInitSqlVendorList\n");
                   1779: #endif
1.35      veillard 1780:     if (rpm2htmlVerbose)
                   1781:        printf("sqlInitSqlVendorList query\n");
                   1782: 
                   1783:     /*
                   1784:      * Allocate the array
                   1785:      */
                   1786:     sqlVendorListLen = 100;
1.45      veillard 1787:     sqlVendorList = (char **) xmlMalloc((sqlVendorListLen) * sizeof(char *));
1.35      veillard 1788:     if (sqlVendorList == NULL) {
                   1789:        fprintf(stderr, "sqlInitSqlVendorList Error: out of memory\n");
                   1790:        return;
                   1791:     }
                   1792:     
                   1793:     /*
                   1794:      * query the database for the values
                   1795:      */
                   1796:     query = "select ID,Name from Vendors";
                   1797: 
                   1798:     if (mysql_query(sql,query)) {
1.36      veillard 1799:        printf("sqlInitSqlVendorList: SELECT from Vendors failed: %s\n",
1.35      veillard 1800:               mysql_error(sql));
                   1801:        return;
                   1802:     }
                   1803: 
                   1804:     i = 0;
                   1805:     result = mysql_use_result(sql);
                   1806:     if (result) {
                   1807:        while((row = mysql_fetch_row(result)))
                   1808:        {
                   1809:            if (sqlRpmAnalyzeVendorRow(row) != NULL)
                   1810:                i++;
                   1811:        }
                   1812:        mysql_free_result(result);
                   1813:     }
                   1814:     if(mysql_errno(sql)) {
                   1815:        fprintf(stderr, "sqlInitSqlVendorList Error: %s\n", mysql_error(sql));
                   1816:        return;
                   1817:     }
                   1818: 
                   1819: 
                   1820:     if (rpm2htmlVerbose)
                   1821:        printf("sqlInitSqlVendorList done: %d entries\n", i);
                   1822:     sqlVendorListInitialized++;
                   1823:     return;
                   1824: }
1.26      veillard 1825: 
                   1826: rpmDirPtr
                   1827: sqlRpmAnalyzeDirRow(MYSQL_ROW row) {
                   1828:     rpmDirPtr ret;
                   1829:     const char *id;
                   1830:     const char *name;
                   1831:     const char *vendor;
                   1832:     const char *directory;
                   1833:     const char *path;
                   1834:     const char *url;
                   1835:     const char *urlSrc;
                   1836:     const char *html;
                   1837:     const char *color;
                   1838:     int dist;
                   1839: 
                   1840:     if (row == NULL)
                   1841:        return(NULL);
                   1842:     id = row[0];
                   1843:     name = row[1];
                   1844:     vendor = row[2];
                   1845:     directory = row[3];
                   1846:     path = row[4];
                   1847:     url = row[5];
                   1848:     urlSrc = row[6];
                   1849:     html = row[7];
                   1850:     color = row[8];
                   1851:     if ((id == NULL) || (name == NULL) ||
                   1852:         (directory == NULL) || (path == NULL) || (url == NULL))
                   1853:        return(NULL);
                   1854: 
                   1855:     if (sscanf(id, "%d", &dist) != 1)
                   1856:        return(NULL);
                   1857:     if ((dist <= 0) || (dist > SQL_MAX_DISTRIBS)) {
                   1858:        fprintf(stderr, "Dist number out of range %d\n", dist);
                   1859:        return(NULL);
                   1860:     }
                   1861: 
                   1862: 
1.45      veillard 1863:     ret = (rpmDirPtr) xmlMalloc(sizeof(rpmDir));
1.26      veillard 1864:     if (ret == NULL)
                   1865:        return(NULL);
                   1866:     memset(ret, 0, sizeof(rpmDir));
                   1867:     /* Generic stuff */
1.28      daniel   1868:     if (rpm2html_dir != NULL)
1.45      veillard 1869:     ret->dir = xmlStrdup(rpm2html_dir);
1.28      daniel   1870:     if (rpm2html_host != NULL)
1.45      veillard 1871:     ret->host = xmlStrdup(rpm2html_host);
1.28      daniel   1872:     if (rpm2html_maint != NULL)
1.45      veillard 1873:     ret->maint = xmlStrdup(rpm2html_maint);
1.28      daniel   1874:     if (rpm2html_mail != NULL)
1.45      veillard 1875:     ret->mail = xmlStrdup(rpm2html_mail);
1.28      daniel   1876:     if (rpm2html_url != NULL)
1.45      veillard 1877:     ret->url = xmlStrdup(rpm2html_url);
1.26      veillard 1878:     /* specific stuff */
                   1879:     ret->no = dist;
1.45      veillard 1880:     ret->rpmdir = xmlStrdup(directory);
                   1881:     ret->subdir = xmlStrdup(path);
                   1882:     ret->name = xmlStrdup(name);
                   1883:     ret->ftp = xmlStrdup(url);
1.26      veillard 1884:     if (color != NULL)
1.45      veillard 1885:        ret->color = xmlStrdup(color);
1.28      daniel   1886:     else
1.45      veillard 1887:        ret->color = xmlStrdup("#ffffff");
1.26      veillard 1888:     if (urlSrc != NULL)
1.45      veillard 1889:        ret->ftpsrc = xmlStrdup(urlSrc);
1.26      veillard 1890:     return(ret);
                   1891: }
                   1892: 
                   1893: void
                   1894: sqlInitSqlDirList(void) {
1.28      daniel   1895:     char host[200];
1.26      veillard 1896:     rpmDirPtr cur;
                   1897:     MYSQL_RES *result;
                   1898:     MYSQL_ROW row;
                   1899:     char *query;
                   1900:     int i;
                   1901: 
                   1902:     if (sqlDirListInitialized != 0)
                   1903:        return;
                   1904: 
1.45      veillard 1905: #ifdef SQL_DEBUG_MEM
                   1906:     printf("sqlInitSqlDirList\n");
                   1907: #endif
1.28      daniel   1908:     gethostname(host, sizeof(host));
                   1909:     currentTime = time(NULL);
                   1910:     rpm2html_rpm2html_thishost = &host[0];
                   1911:     readConfigSql();
                   1912:     if (rpm2html_host == NULL) {
                   1913:        rpm2html_host = strdup(rpm2html_rpm2html_thishost);
                   1914:     }
1.26      veillard 1915:     for (i = 0; i < SQL_MAX_DISTRIBS;i++)
                   1916:         sqlDirList[i] = NULL;
                   1917: 
                   1918:     if (rpm2htmlVerbose)
                   1919:        printf("sqlInitSqlDirList query\n");
                   1920: 
1.29      veillard 1921:     query = "select ID,Name,Vendor,Directory,Path,URL,URLSrc,Html,Color from Distribs";
1.26      veillard 1922: 
                   1923:     if (mysql_query(sql,query)) {
                   1924:        printf("sqlInitSqlDirList: SELECT from Packages failed: %s\n",
                   1925:               mysql_error(sql));
                   1926:        return;
                   1927:     }
                   1928: 
                   1929:     i = 0;
                   1930:     result = mysql_use_result(sql);
                   1931:     if (result) {
                   1932:        while((row = mysql_fetch_row(result)))
                   1933:        {
                   1934:            cur = sqlRpmAnalyzeDirRow(row);
                   1935:            if (cur != NULL) {
                   1936:                sqlDirList[cur->no] = cur;
                   1937:                i++;
                   1938:            }
                   1939:        }
                   1940:        mysql_free_result(result);
                   1941:     }
                   1942:     if(mysql_errno(sql)) {
                   1943:        fprintf(stderr, "sqlInitSqlDirList Error: %s\n", mysql_error(sql));
                   1944:        return;
                   1945:     }
                   1946: 
                   1947:     if (rpm2htmlVerbose)
                   1948:        printf("sqlInitSqlDirList done: %d entries\n", i);
                   1949:     sqlDirListInitialized++;
                   1950:     return;
                   1951: }
                   1952: 
                   1953: rpmDataPtr
                   1954: sqlRpmAnalyzeRow(MYSQL_ROW row) {
                   1955:     rpmDataPtr ret;
                   1956:     const char *id;
                   1957:     const char *name;
                   1958:     const char *version;
                   1959:     const char *release;
                   1960:     const char *arch;
                   1961:     const char *date;
                   1962:     const char *summary;
                   1963:     const char *filename;
                   1964:     const char *distrib;
1.30      daniel   1965:     const char *group;
1.33      veillard 1966:     const char *os;
1.35      veillard 1967:     const char *packager;
1.36      veillard 1968:     const char *vendor;
1.26      veillard 1969:     int dist;
                   1970: 
                   1971:     if (row == NULL)
                   1972:        return(NULL);
                   1973:     id = row[0];
                   1974:     name = row[1];
                   1975:     version = row[2];
                   1976:     release = row[3];
                   1977:     arch = row[4];
                   1978:     date = row[5];
                   1979:     summary = row[6];
                   1980:     filename = row[7];
                   1981:     distrib = row[8];
1.30      daniel   1982:     group = row[9];
1.33      veillard 1983:     os = row[10];
1.35      veillard 1984:     packager = row[11];
1.36      veillard 1985:     vendor = row[12];
1.26      veillard 1986:     if ((id == NULL) || (name == NULL) || (version == NULL) ||
                   1987:         (release == NULL) || (arch == NULL) || (date == NULL) ||
                   1988:        (summary == NULL) || (filename == NULL) || (distrib == NULL))
                   1989:        return(NULL);
                   1990: 
1.45      veillard 1991:     ret = (rpmDataPtr) xmlMalloc(sizeof(rpmData));
1.26      veillard 1992:     if (ret == NULL)
                   1993:        return(NULL);
                   1994:     memset(ret, 0, sizeof(rpmData));
1.45      veillard 1995:     ret->name = xmlStrdup(name);
                   1996:     ret->version = xmlStrdup(version);
                   1997:     ret->release = xmlStrdup(release);
                   1998:     ret->arch = xmlStrdup(arch);
                   1999:     ret->summary = xmlStrdup(summary);
                   2000:     ret->name = xmlStrdup(name);
                   2001:     ret->filename = xmlStrdup(filename);
1.33      veillard 2002:     if (os == NULL)
1.45      veillard 2003:        ret->os = xmlStrdup("Linux");
1.33      veillard 2004:     else
1.45      veillard 2005:        ret->os = xmlStrdup(os);
1.30      daniel   2006:     if (group != NULL)
1.45      veillard 2007:        ret->group = xmlStrdup(group);
1.26      veillard 2008:     sscanf(date, "%d", (int *) &(ret->date));
1.35      veillard 2009:     if (packager != NULL) {
                   2010:        int tmp = 0;
                   2011:        sscanf(packager, "%d", (int *) &tmp);
                   2012:        if ((tmp > 0) && (tmp < sqlVendorListLen)) {
                   2013:            if (sqlVendorList[tmp] != NULL)
1.45      veillard 2014:                ret->vendor = xmlStrdup(sqlVendorList[tmp]);
1.35      veillard 2015:        }
                   2016:     }
1.36      veillard 2017:     if (vendor != NULL) {
                   2018:        int tmp = 0;
                   2019:        sscanf(vendor, "%d", (int *) &tmp);
                   2020:        if ((tmp > 0) && (tmp < sqlDistributionListLen)) {
                   2021:            if (sqlVendorList[tmp] != NULL)
1.45      veillard 2022:                ret->distribution = xmlStrdup(sqlDistributionList[tmp]);
1.36      veillard 2023:        }
                   2024:     }
1.35      veillard 2025:     if (ret->vendor == NULL)
1.45      veillard 2026:        ret->vendor =  xmlStrdup("Unknown");
1.35      veillard 2027:     if (ret->distribution == NULL)
1.45      veillard 2028:        ret->distribution =  xmlStrdup("Unknown");
1.26      veillard 2029:     sscanf(distrib, "%d", &dist);
                   2030:     ret->dir = sqlDirList[dist];
1.28      daniel   2031:     if ((ret->dir != NULL) && (ret->dir->rpmdir != NULL)) {
                   2032:        int len = strlen(ret->dir->rpmdir);
                   2033:        if (!strncmp(ret->filename, ret->dir->rpmdir, len)) {
                   2034:            char *start, *end;
                   2035:            start = &(ret->filename[len]);
                   2036:            while (*start == '/') start++;
                   2037:            end = &start[strlen(start) - 1];
                   2038:            while ((end >= start) && (*end != '/')) end--;
                   2039:             if (end > start) {
                   2040:                char *tmp;
1.45      veillard 2041:                tmp = xmlMalloc((end - start) + 1);
1.28      daniel   2042:                if (tmp != NULL) {
                   2043:                    strncpy(tmp, start, end - start);
                   2044:                    tmp[end - start] = 0;
                   2045:                    ret->subdir = tmp;
                   2046:                }
                   2047:            }
                   2048:        }
                   2049:     }
1.26      veillard 2050:     return(ret);
                   2051: }
                   2052: 
                   2053: rpmDataPtr
                   2054: sqlRpmByDate(void) {
                   2055:     rpmDataPtr list = NULL;
                   2056:     rpmDataPtr cur, last = NULL;
                   2057:     MYSQL_RES *result;
                   2058:     MYSQL_ROW row;
                   2059:     char *query;
                   2060: 
                   2061:     sqlInitSqlDirList();
1.35      veillard 2062:     sqlInitSqlVendorList();
1.36      veillard 2063:     sqlInitSqlDistributionList();
1.26      veillard 2064:     if (rpm2htmlVerbose)
                   2065:        printf("sqlRpmByDate query\n");
                   2066: 
1.35      veillard 2067:     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 2068: 
                   2069:     /*
                   2070:      * Search first for the ID if it already exists
                   2071:      */
                   2072:     if (mysql_query(sql,query)) {
                   2073:        printf("sqlRpmByDate: SELECT from Packages failed: %s\n",
                   2074:               mysql_error(sql));
                   2075:        return(NULL);
                   2076:     }
                   2077: 
                   2078:     result = mysql_use_result(sql);
                   2079:     if (result) {
                   2080:        while((row = mysql_fetch_row(result)))
                   2081:        {
                   2082:            cur = sqlRpmAnalyzeRow(row);
                   2083:            if (cur != NULL) {
                   2084:                if (last == NULL)
                   2085:                    list = cur;
                   2086:                else
                   2087:                    last->next = cur;
                   2088:                last = cur;
                   2089:            }
                   2090:        }
                   2091:        mysql_free_result(result);
                   2092:     }
                   2093:     if(mysql_errno(sql)) {
                   2094:        fprintf(stderr, "sqlRpmByDate Error: %s\n", mysql_error(sql));
                   2095:        return(NULL);
                   2096:     }
                   2097: 
                   2098:     if (rpm2htmlVerbose)
                   2099:        printf("sqlRpmByDate done\n");
                   2100:     return(list);
                   2101: }
                   2102: 
1.29      veillard 2103: rpmDataPtr
                   2104: sqlRpmAll(void) {
                   2105:     rpmDataPtr list = NULL;
                   2106:     rpmDataPtr cur, last = NULL;
                   2107:     MYSQL_RES *result;
                   2108:     MYSQL_ROW row;
                   2109:     char *query;
                   2110: 
                   2111:     sqlInitSqlDirList();
1.35      veillard 2112:     sqlInitSqlVendorList();
1.36      veillard 2113:     sqlInitSqlDistributionList();
1.29      veillard 2114:     if (rpm2htmlVerbose)
                   2115:        printf("sqlRpmAll query\n");
                   2116: 
1.35      veillard 2117:     query = "select ID,Name,Version,Release,Arch,Date,Summary,filename,Dist,Category,Os,Packager,Vendor from Packages";
1.29      veillard 2118: 
                   2119:     /*
                   2120:      * Search first for the ID if it already exists
                   2121:      */
                   2122:     if (mysql_query(sql,query)) {
                   2123:        printf("sqlRpmByDate: SELECT from Packages failed: %s\n",
                   2124:               mysql_error(sql));
                   2125:        return(NULL);
                   2126:     }
                   2127: 
                   2128:     result = mysql_use_result(sql);
                   2129:     if (result) {
                   2130:        while((row = mysql_fetch_row(result)))
                   2131:        {
                   2132:            cur = sqlRpmAnalyzeRow(row);
                   2133:            if (cur != NULL) {
                   2134:                if (last == NULL)
                   2135:                    list = cur;
                   2136:                else
                   2137:                    last->next = cur;
                   2138:                last = cur;
1.32      daniel   2139: 
                   2140:                rpmAddSoftware(cur);
1.29      veillard 2141:            }
                   2142:        }
                   2143:        mysql_free_result(result);
                   2144:     }
                   2145:     if(mysql_errno(sql)) {
                   2146:        fprintf(stderr, "sqlRpmByDate Error: %s\n", mysql_error(sql));
                   2147:        return(NULL);
                   2148:     }
                   2149: 
                   2150:     if (rpm2htmlVerbose)
                   2151:        printf("sqlRpmAll done\n");
                   2152:     return(list);
                   2153: }
                   2154: 
1.45      veillard 2155: void sqlListsCleanup(void) {
                   2156:     int i;
                   2157: 
                   2158: #ifdef SQL_DEBUG_MEM
                   2159:     printf("sqlListsCleanup\n");
                   2160: #endif
                   2161:     if (sqlDirListInitialized) {
                   2162: #ifdef SQL_DEBUG_MEM
                   2163:        printf("sqlListsCleanup: freeing sqlDirList\n");
                   2164: #endif
                   2165:        for (i = 0 ; i < SQL_MAX_DISTRIBS; i++) {
                   2166:            if (sqlDirList[i] != NULL)
                   2167:                rpmDirFree(sqlDirList[i]);
                   2168:            sqlDirList[i] = NULL;
                   2169:        }
                   2170:        sqlDirListInitialized = 0;
                   2171:     }
                   2172:     if (sqlVendorListInitialized) {
                   2173: #ifdef SQL_DEBUG_MEM
                   2174:        printf("sqlListsCleanup: freeing sqlVendorList\n");
                   2175: #endif
                   2176:        for (i = 0 ; i < sqlVendorListLen;i++) {
                   2177:            if (sqlVendorList[i] != NULL)
                   2178:                xmlFree(sqlVendorList[i]);
                   2179:            sqlVendorList[i] = NULL;
                   2180:        }
                   2181:        xmlFree(sqlVendorList);
                   2182:        sqlVendorListInitialized = 0;
                   2183:     }
                   2184:     if (sqlDistributionListInitialized) {
                   2185: #ifdef SQL_DEBUG_MEM
                   2186:        printf("sqlListsCleanup: freeing sqlDistributionList\n");
                   2187: #endif
                   2188:        for (i = 0 ; i < sqlDistributionListLen;i++) {
                   2189:            if (sqlDistributionList[i] != NULL)
                   2190:                xmlFree(sqlDistributionList[i]);
                   2191:            sqlDistributionList[i] = NULL;
                   2192:        }
                   2193:        xmlFree(sqlDistributionList);
                   2194:        sqlDistributionListInitialized = 0;
                   2195:     }
                   2196:     if (sqlResourceListInitialized) {
                   2197: #ifdef SQL_DEBUG_MEM
                   2198:        printf("sqlListsCleanup: freeing sqlResourceList\n");
                   2199: #endif
                   2200:        for (i = 0 ; i < sqlResourceListLen;i++) {
                   2201:            if (sqlResourceList[i] != NULL)
                   2202:                xmlFree(sqlResourceList[i]);
                   2203:            sqlResourceList[i] = NULL;
                   2204:        }
                   2205:        xmlFree(sqlResourceList);
                   2206:        sqlResourceListInitialized = 0;
                   2207:     }
                   2208: }
                   2209: 
1.26      veillard 2210: /************************************************************************
1.8       veillard 2211:  *                                                                     *
1.6       veillard 2212:  *                     Export functions                                *
                   2213:  *                                                                     *
                   2214:  ************************************************************************/
                   2215: 
1.45      veillard 2216: void sql_dump_rdf_full_index(void) {
                   2217:     MYSQL_RES *result;
                   2218:     MYSQL_ROW row;
                   2219:     char query[SMALL_QUERY];
                   2220:     gzFile rdf;
                   2221:     char *filename;
                   2222:     char *dist;
                   2223:     char *name;
                   2224:     char *version;
                   2225:     char *release;
                   2226:     char *arch;
                   2227:     char *summary;
                   2228:     char *subdir;
                   2229:     char *psubdir;
                   2230:     char *rpmdir;
                   2231:     char *start, *end;
                   2232:     int distrib;
                   2233:     int len;
                   2234:     char path[500];
                   2235: 
                   2236:     if (!rpm2html_dump_rdf_resources)
                   2237:        return;
                   2238:     if (!rpm2html_rdf_resources_dir)
                   2239:        return;
                   2240:     if ((rpm2html_host == NULL) || (rpm2html_url == NULL))
                   2241:        return;
                   2242: 
                   2243:     /*
                   2244:      * Open the RDF resource descritpion.
                   2245:      */
                   2246:     mkdir(rpm2html_rdf_resources_dir, 0755);
                   2247:     snprintf(path, 500, "%s/fullIndex.rdf.gz",
                   2248:             rpm2html_rdf_resources_dir);
                   2249:     path[499] = 0;
                   2250:     rdf = gzopen(path, "w9");
                   2251:     if (rdf == NULL) {
                   2252:        fprintf(stderr, "unable to write to %s\n", path);
                   2253:        return;
                   2254:     }
                   2255:     gzprintf(rdf, "<?xml version=\"1.0\"?>\n");
                   2256:     gzprintf(rdf, "<rdf:RDF xmlns:RDF=\"http://www.w3.org/TR/WD-rdf-syntax#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:RPM=\"http://www.rpm.org/\">\n");
                   2257: 
                   2258:     /*
                   2259:      * Query the database for the informations providing the resource.
                   2260:      */
                   2261:     snprintf(query, SMALL_QUERY,
                   2262:        "select filename,Dist,Name,Version,Release,Arch,Summary from Packages");
                   2263:     query[SMALL_QUERY - 1] = 0;
                   2264:     if (mysql_query(sql, query)) {
                   2265:        printf("sql_dump_rdf_full_index: SELECT from Packages failed: %s\n",
                   2266:               mysql_error(sql));
                   2267:         gzprintf(rdf, "</rdf:RDF>\n");
                   2268:        fclose(rdf);
                   2269:        return;
                   2270:     }
                   2271:     result = mysql_use_result(sql);
                   2272:     if (result == NULL) {
                   2273:        printf("sql_dump_rdf_full_index: SELECT from Packages failed: %s\n",
                   2274:               mysql_error(sql));
                   2275:         gzprintf(rdf, "</rdf:RDF>\n");
                   2276:        fclose(rdf);
                   2277:        return;
                   2278:     }
                   2279:     while((row = mysql_fetch_row(result))) {
                   2280:        filename = row[0];
                   2281:        dist = row[1];
                   2282:        name = row[2];
                   2283:        version = row[3];
                   2284:        release = row[4];
                   2285:        arch = row[5];
                   2286:        summary = row[6];
                   2287:        if ((filename == NULL) || (dist == NULL) || (name == NULL) ||
                   2288:            (summary == NULL)) {
                   2289:            continue;
                   2290:        }
                   2291:        if (!strncmp(filename, "localbase", 9))
                   2292:            continue;
                   2293:        if (sscanf(dist, "%d", &distrib) != 1)
                   2294:            continue;
                   2295:        if ((distrib < 1) || (distrib >= SQL_MAX_DISTRIBS) ||
                   2296:            (sqlDirList[distrib] == NULL))
                   2297:            continue;
                   2298: 
                   2299:        subdir = sqlDirList[distrib]->subdir;
                   2300:        rpmdir = sqlDirList[distrib]->rpmdir;
                   2301:        len = strlen(rpmdir);
                   2302:        if (strncmp(filename, rpmdir, len)) {
                   2303:            fprintf(stderr, "%s out of subdir %s\n", filename, subdir);
                   2304:            continue;
                   2305:        }
                   2306:        start = &(filename[len]);
                   2307:        while (*start == '/') start++;
                   2308:        end = &start[strlen(start) - 1];
                   2309:        while ((end >= start) && (*end != '/')) end--;
                   2310:        if (end <= start) {
                   2311:            psubdir = xmlStrdup("");
                   2312:        } else {
                   2313:            psubdir = xmlMalloc((end - start) + 1);
                   2314:            if (psubdir == NULL) {
                   2315:                fprintf(stderr, "Out of memory\n");
                   2316:                continue;
                   2317:            }
                   2318:            strncpy(psubdir, start, end - start);
                   2319:            psubdir[end - start] = 0;
                   2320:        }
                   2321:         gzprintf(rdf, "  <rdf:Description about=\"%s/%s/%s-%s-%s.%s.rpm\">\n",
                   2322:                sqlDirList[distrib]->ftp,psubdir,name,version,release,arch);
                   2323:        gzprintf(rdf, "    <RPM:Name>%s</RPM:Name>\n", name);
1.46      veillard 2324:        gzprintf(rdf, "    <RPM:Summary>%s</RPM:Summary>\n", 
                   2325:                 convertXML(summary));
1.45      veillard 2326:        gzprintf(rdf, "  </rdf:Description>\n");
                   2327:        xmlFree(psubdir);
                   2328:     }
                   2329:     gzprintf(rdf, "</rdf:RDF>\n");
                   2330:     gzclose(rdf);
                   2331:     mysql_free_result(result);
                   2332:     if(mysql_errno(sql)) {
                   2333:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2334:     }
                   2335: }
                   2336: 
                   2337: 
1.41      veillard 2338: void sql_dump_rdf(const char *resource) {
                   2339:     MYSQL_RES *result;
                   2340:     MYSQL_ROW row;
                   2341:     char query[SMALL_QUERY];
                   2342:     FILE *rdf;
                   2343:     char *filename;
                   2344:     char *dist;
                   2345:     char *name;
                   2346:     char *version;
                   2347:     char *release;
                   2348:     char *arch;
                   2349:     char *os;
                   2350:     char *packager;
                   2351:     char *date;
                   2352:     char *size;
1.44      daniel   2353:     char *vendorstr;
1.41      veillard 2354:     char *subdir;
1.42      veillard 2355:     char *psubdir;
                   2356:     char *rpmdir;
                   2357:     char *start, *end;
1.41      veillard 2358:     int distrib;
1.42      veillard 2359:     int vendor;
1.44      daniel   2360:     int person;
1.42      veillard 2361:     int len;
                   2362:     char path[500];
1.41      veillard 2363: 
                   2364:     if (resource == NULL)
                   2365:        return;
1.44      daniel   2366:     if (resource[0] == '/')
                   2367:        return;
1.41      veillard 2368:     if (!rpm2html_dump_rdf_resources)
                   2369:        return;
1.42      veillard 2370:     if (!rpm2html_rdf_resources_dir)
                   2371:        return;
1.41      veillard 2372:     if ((rpm2html_host == NULL) || (rpm2html_url == NULL))
                   2373:        return;
                   2374: 
1.42      veillard 2375:     /*
                   2376:      * Open the RDF resource descritpion.
                   2377:      */
                   2378:     mkdir(rpm2html_rdf_resources_dir, 0755);
                   2379:     snprintf(path, 500, "%s/%s.rdf",
                   2380:             rpm2html_rdf_resources_dir, resource);
                   2381:     path[499] = 0;
                   2382:     rdf = fopen(path, "w");
                   2383:     if (rdf == NULL) {
                   2384:        fprintf(stderr, "unable to write to %s\n", path);
                   2385:        return;
                   2386:     }
                   2387:     fprintf(rdf, "<?xml version=\"1.0\"?>\n");
                   2388:     fprintf(rdf, "<rdf:RDF xmlns:RDF=\"http://www.w3.org/TR/WD-rdf-syntax#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:RPM=\"http://www.rpm.org/\">\n");
                   2389: 
                   2390:     /*
                   2391:      * Query the database for the informations providing the resource.
                   2392:      */
1.41      veillard 2393:     snprintf(query, SMALL_QUERY,
1.44      daniel   2394: "select filename,Dist,Name,Version,Release,Arch,Os,Packager,Date,Size,Vendor from Packages where Name=\"%s\"",
1.41      veillard 2395:              resource);
                   2396:     query[SMALL_QUERY - 1] = 0;
                   2397:     if (mysql_query(sql, query)) {
                   2398:        printf("sql_dump_rdf: SELECT from Packages failed: %s\n",
                   2399:               mysql_error(sql));
1.42      veillard 2400:         fprintf(rdf, "</rdf:RDF>\n");
                   2401:        fclose(rdf);
1.41      veillard 2402:        return;
                   2403:     }
                   2404:     result = mysql_use_result(sql);
                   2405:     if (result == NULL) {
                   2406:        printf("sql_dump_rdf: SELECT from Packages failed: %s\n",
                   2407:               mysql_error(sql));
1.42      veillard 2408:         fprintf(rdf, "</rdf:RDF>\n");
                   2409:        fclose(rdf);
1.41      veillard 2410:        return;
                   2411:     }
                   2412:     while((row = mysql_fetch_row(result))) {
                   2413:        filename = row[0];
                   2414:        dist = row[1];
                   2415:        name = row[2];
                   2416:        version = row[3];
                   2417:        release = row[4];
                   2418:        arch = row[5];
                   2419:        os = row[6];
                   2420:        packager = row[7];
                   2421:        date = row[8];
                   2422:        size = row[9];
1.44      daniel   2423:        vendorstr = row[10];
1.41      veillard 2424:        if ((filename == NULL) || (dist == NULL) || (name == NULL) ||
                   2425:            (version == NULL) || (release == NULL) || (arch == NULL) ||
1.44      daniel   2426:            (os == NULL) || (date == NULL) || (vendorstr == NULL) ||
1.41      veillard 2427:            (size == NULL)) {
                   2428:            continue;
                   2429:        }
1.42      veillard 2430:        if (!strncmp(filename, "localbase", 9))
                   2431:            continue;
1.41      veillard 2432:        if (sscanf(dist, "%d", &distrib) != 1)
                   2433:            continue;
1.44      daniel   2434:        if ((distrib < 1) || (distrib >= SQL_MAX_DISTRIBS) ||
                   2435:            (sqlDirList[distrib] == NULL))
1.42      veillard 2436:            continue;
1.44      daniel   2437:        if (vendorstr != NULL) {
                   2438:            if (sscanf(vendorstr, "%d", &vendor) != 1)
1.42      veillard 2439:                continue;
                   2440:        }
                   2441:        if ((vendor < 1) || (vendor >= sqlDistributionListLen) ||
                   2442:            (sqlDistributionList[vendor] == NULL))
1.41      veillard 2443:            continue;
1.44      daniel   2444:        if (packager != NULL) {
                   2445:            if (sscanf(packager, "%d", &person) != 1)
                   2446:                continue;
                   2447:        }
                   2448:        if ((person < 1) || (person >= sqlVendorListLen) ||
                   2449:            (sqlVendorList[person] == NULL))
                   2450:            continue;
1.41      veillard 2451: 
                   2452:        subdir = sqlDirList[distrib]->subdir;
1.42      veillard 2453:        rpmdir = sqlDirList[distrib]->rpmdir;
                   2454:        len = strlen(rpmdir);
                   2455:        if (strncmp(filename, rpmdir, len)) {
                   2456:            fprintf(stderr, "%s out of subdir %s\n", filename, subdir);
                   2457:            continue;
                   2458:        }
                   2459:        start = &(filename[len]);
                   2460:        while (*start == '/') start++;
                   2461:        end = &start[strlen(start) - 1];
                   2462:        while ((end >= start) && (*end != '/')) end--;
                   2463:        if (end <= start) {
1.45      veillard 2464:            psubdir = xmlStrdup("");
1.42      veillard 2465:        } else {
1.45      veillard 2466:            psubdir = xmlMalloc((end - start) + 1);
1.42      veillard 2467:            if (psubdir == NULL) {
                   2468:                fprintf(stderr, "Out of memory\n");
                   2469:                continue;
1.41      veillard 2470:            }
1.42      veillard 2471:            strncpy(psubdir, start, end - start);
                   2472:            psubdir[end - start] = 0;
1.41      veillard 2473:        }
1.42      veillard 2474:         fprintf(rdf, "  <rdf:Description about=\"%s/%s/%s-%s-%s.%s.rpm\" ",
                   2475:                sqlDirList[distrib]->ftp,psubdir,name,version,release,arch);
                   2476:        fprintf(rdf, "href=\"../%s/%s/%s-%s-%s.%s.rdf\">\n",
                   2477:                subdir,psubdir,name,version,release,arch);
                   2478:        fprintf(rdf, "    <RPM:Name>%s</RPM:Name>\n", name);
                   2479:        fprintf(rdf, "    <RPM:Version>%s</RPM:Version>\n", version);
                   2480:        fprintf(rdf, "    <RPM:Release>%s</RPM:Release>\n", release);
                   2481:        fprintf(rdf, "    <RPM:Arch>%s</RPM:Arch>\n", arch);
                   2482:        fprintf(rdf, "    <RPM:Os>%s</RPM:Os>\n", os);
                   2483:        if (packager == NULL)
                   2484:            fprintf(rdf, "    <RPM:Distribution>Unknown</RPM:Distribution>\n");
                   2485:        else
                   2486:            fprintf(rdf, "    <RPM:Distribution>%s</RPM:Distribution>\n",
1.48      daniel   2487:                    convertXML(sqlDistributionList[vendor]));
1.42      veillard 2488:        fprintf(rdf, "    <RPM:Vendor>%s</RPM:Vendor>\n",
1.48      daniel   2489:            convertXML(sqlVendorList[person]));
1.42      veillard 2490:        fprintf(rdf, "    <RPM:Date>%s</RPM:Date>\n", date);
                   2491:        fprintf(rdf, "    <RPM:Size>%s</RPM:Size>\n", size);
                   2492:        fprintf(rdf, "    <RPM:Subdir>%s</RPM:Subdir>\n", subdir);
                   2493:        fprintf(rdf, "  </rdf:Description>\n");
1.45      veillard 2494:        xmlFree(psubdir);
1.41      veillard 2495:     }
1.42      veillard 2496:     fprintf(rdf, "</rdf:RDF>\n");
                   2497:     fclose(rdf);
1.45      veillard 2498:     mysql_free_result(result);
                   2499:     if(mysql_errno(sql)) {
                   2500:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2501:     }
1.41      veillard 2502: }
                   2503: 
1.6       veillard 2504: void sql_show_config(void) {
                   2505:     MYSQL_RES *result;
                   2506:     MYSQL_ROW row;
1.8       veillard 2507:     int id, i;
                   2508:     int index = 0;
                   2509:     int ids[500];
                   2510:     char query[SMALL_QUERY];
1.6       veillard 2511: 
                   2512: 
1.8       veillard 2513:     printf(";\n; Configuration file for rpm2html\n");
                   2514:     printf("; http://rpmfind.net/linux/rpm2html/\n;\n\n");
                   2515:     mysql_query(sql,"SELECT Name,Value FROM Config");
1.6       veillard 2516:     result = mysql_use_result(sql);
                   2517: 
                   2518:     while((row = mysql_fetch_row(result)))
                   2519:     {
1.8       veillard 2520:        if (row[0] == NULL) {
                   2521:            printf("\n");
                   2522:        } else {
                   2523:            if (!strcmp(row[0], "maint"))
                   2524:                printf("; maintainer of the local rpm mirror\n");
                   2525:            else if (!strcmp(row[0], "mail"))
                   2526:                printf("; mail for the maintainer\n");
                   2527:            else if (!strcmp(row[0], "dir"))
                   2528:                 printf("; Directory to store the HTML pages produced\n");
                   2529:            else if (!strcmp(row[0], "url"))
                   2530:                 printf("; The relative URL for front pages\n");
                   2531:            else if (!strcmp(row[0], "header"))
                   2532:                 printf("; Extra link in the navigation bar\n");
                   2533:            else if (!strcmp(row[0], "html"))
                   2534:                 printf("; Export the local packages in HTML format\n");
                   2535:            else if (!strcmp(row[0], "tree"))
                   2536:                 printf("; Build the tree for the distributions\n");
                   2537:            else if (!strcmp(row[0], "rdf"))
                   2538:                 printf("; Export the local packages in RDF format\n");
                   2539:            else if (!strcmp(row[0], "rdf_dir"))
                   2540:                 printf("; Directory to store the RDf tree\n");
                   2541:            else if (!strcmp(row[0], "rdf_resources"))
                   2542:                 printf("; Compile a list of resources in RDF format\n");
                   2543:            else if (!strcmp(row[0], "rdf_resources_dir"))
                   2544:                 printf("; Directory to store the RDf resources tree\n");
                   2545: 
1.6       veillard 2546:            if (row[1] == NULL)
1.8       veillard 2547:                printf("%s\n\n", row[0]);
1.6       veillard 2548:            else
1.8       veillard 2549:                printf("%s=%s\n\n", row[0], row[1]);
                   2550:        }
                   2551:     }
                   2552:     mysql_free_result(result);
                   2553:     if(mysql_errno(sql)) {
                   2554:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2555:     }
                   2556: 
                   2557:     /*
                   2558:      * Dump the Metadata
                   2559:      */
                   2560:     printf(";\n; The metadata mirrors list\n;\n\n[metadata]\n");
                   2561:     mysql_query(sql,"SELECT URL FROM Metadata");
                   2562:     result = mysql_use_result(sql);
                   2563: 
                   2564:     while((row = mysql_fetch_row(result)))
                   2565:     {
                   2566:        if (row[0] != NULL) {
                   2567:            printf("mirror=%s\n", row[0]);
1.6       veillard 2568:        }
                   2569:     }
1.8       veillard 2570:     mysql_free_result(result);
1.6       veillard 2571:     if(mysql_errno(sql)) {
                   2572:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2573:     }
                   2574: 
1.8       veillard 2575:     /*
                   2576:      * Dump the distributions informations
                   2577:      * 1/ collect the list of IDs for the distribs
                   2578:      */
                   2579:     printf("\n\n;\n; The distribution list\n;\n\n");
                   2580:     mysql_query(sql,"SELECT ID FROM Distribs");
                   2581:     result = mysql_use_result(sql);
                   2582: 
                   2583:     while((row = mysql_fetch_row(result)))
                   2584:     {
                   2585:        if (row[0] != NULL) {
                   2586:            if (sscanf(row[0], "%d", &id) == 1) {
                   2587:                ids[index++] = id;
                   2588:            }
                   2589:        }
                   2590:     }
                   2591:     mysql_free_result(result);
                   2592: 
                   2593:     /*
                   2594:      * Dump each distribution separately.
                   2595:      */
                   2596:     for (i = 0;i < index;i++) {
                   2597: 
                   2598:        snprintf(query, SMALL_QUERY - 1,
1.10      veillard 2599:  "SELECT Directory,Name,Vendor,Path,URL,URLSrc,Description,Html,Color \
1.8       veillard 2600:                  FROM Distribs WHERE ID=%d", ids[i]);
                   2601:        query[SMALL_QUERY - 1] = 0;
                   2602:        if (mysql_query(sql,query)) {
                   2603:            printf("sql_show_config: SELECT Distrib %d failed: %s\n",
                   2604:                   ids[i], mysql_error(sql));
                   2605:            continue;
                   2606:        }
                   2607: 
                   2608:        result = mysql_use_result(sql);
                   2609:        if (result) {
                   2610:            while((row = mysql_fetch_row(result)))
                   2611:            {
                   2612:                if (row[0] == NULL)
                   2613:                    break;
                   2614:                printf("[%s]\n", row[0]);
                   2615:                if (row[1] != NULL)
                   2616:                    printf("name=%s\n", row[1]);
                   2617:                if (row[3] != NULL)
                   2618:                    printf("subdir=%s\n", row[3]);
                   2619:                if (row[4] != NULL)
                   2620:                    printf("ftp=%s\n", row[4]);
                   2621:                if (row[5] != NULL)
                   2622:                    printf("ftpsrc=%s\n", row[5]);
1.10      veillard 2623:                if (row[7] != NULL)
                   2624:                    printf("html=%s\n", row[7]);
                   2625:                if (row[8] != NULL)
                   2626:                    printf("color=%s\n", row[8]);
1.8       veillard 2627:            }
                   2628:        }
                   2629:        mysql_free_result(result);
1.12      veillard 2630: 
                   2631:        /*
                   2632:         * Extract the mirrors for this distribution.
                   2633:         */
                   2634:        snprintf(query, SMALL_QUERY - 1,
                   2635:                 "SELECT URL FROM Mirrors WHERE ID=%d", ids[i]);
                   2636:        query[SMALL_QUERY - 1] = 0;
                   2637:        if (mysql_query(sql,query)) {
                   2638:            printf("sql_show_config: SELECT Mirrors %d failed: %s\n",
                   2639:                   ids[i], mysql_error(sql));
                   2640:            printf("\n\n");
                   2641:            continue;
                   2642:        }
                   2643:        result = mysql_use_result(sql);
                   2644:        if (result) {
                   2645:            while((row = mysql_fetch_row(result)))
                   2646:            {
                   2647:                if (row[0] == NULL)
                   2648:                    continue;
                   2649:                printf("mirror=%s\n", row[0]);
                   2650:            }
                   2651:        }
                   2652:        mysql_free_result(result);
                   2653: 
1.8       veillard 2654:        printf("\n\n");
                   2655:     }
                   2656: 
                   2657:     printf(";\n; End of the configuration file for rpm2html\n;\n");
1.6       veillard 2658: }
                   2659: 
                   2660: void sql_show_metadata(void) {
                   2661:     MYSQL_RES *result;
                   2662:     MYSQL_ROW row;
                   2663: 
                   2664: 
                   2665:     mysql_query(sql,"SELECT URL FROM Metadata");
                   2666:     result = mysql_use_result(sql);
                   2667: 
                   2668:     while((row = mysql_fetch_row(result)))
                   2669:     {
                   2670:        if (row[0] == NULL)
                   2671:            printf("NULL !\n");
                   2672:        else {
                   2673:            printf("%s\n", row[0]);
                   2674:        }
                   2675:     }
                   2676:     if(mysql_errno(sql)) {
                   2677:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2678:     }
                   2679: 
                   2680: }
                   2681: 
                   2682: void sql_show_mirrors(void) {
                   2683:     MYSQL_RES *result;
                   2684:     MYSQL_ROW row;
                   2685: 
                   2686: 
                   2687:     mysql_query(sql,"SELECT URL FROM Mirrors");
                   2688:     result = mysql_use_result(sql);
                   2689: 
                   2690:     while((row = mysql_fetch_row(result)))
                   2691:     {
                   2692:        if (row[0] == NULL)
                   2693:            printf("NULL !\n");
                   2694:        else {
                   2695:            printf("%s\n", row[0]);
                   2696:        }
                   2697:     }
                   2698:     if(mysql_errno(sql)) {
                   2699:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2700:     }
                   2701: }
                   2702: 
1.5       veillard 2703: void sql_show_vendors(void) {
1.1       veillard 2704:     MYSQL_RES *result;
                   2705:     MYSQL_ROW row;
                   2706: 
                   2707: 
                   2708:     mysql_query(sql,"SELECT Name, URL FROM Vendors");
                   2709:     result = mysql_use_result(sql);
                   2710: 
                   2711:     while((row = mysql_fetch_row(result)))
                   2712:     {
                   2713:        if (row[0] == NULL)
                   2714:            printf("NULL !\n");
                   2715:        else {
                   2716:            if (row[1] == NULL)
                   2717:                printf("%s : no url\n", row[0]);
                   2718:            else
                   2719:                printf("%s : %s\n", row[0], row[1]);
                   2720:        }
                   2721:     }
                   2722:     if(mysql_errno(sql)) {
                   2723:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2724:     }
                   2725: 
                   2726: }
                   2727: 
1.5       veillard 2728: void sql_show_distribs(void) {
1.1       veillard 2729:     MYSQL_RES *result;
                   2730:     MYSQL_ROW row;
                   2731: 
                   2732: 
                   2733:     mysql_query(sql,"SELECT Name, Path, URL FROM Distribs");
                   2734:     result = mysql_use_result(sql);
                   2735: 
                   2736:     while((row = mysql_fetch_row(result)))
                   2737:     {
                   2738:        if (row[0] == NULL)
                   2739:            printf("NULL !\n");
                   2740:        else {
                   2741:            if (row[1] == NULL)
                   2742:                printf("%s : no Path\n", row[0]);
                   2743:            else {
                   2744:                if (row[2] == NULL)
                   2745:                    printf("%s : %s : no url\n", row[0], row[1]);
                   2746:                else
                   2747:                    printf("%s : %s : %s\n", row[0], row[1], row[2]);
                   2748:            }
                   2749:        }
                   2750:     }
                   2751:     if(mysql_errno(sql)) {
                   2752:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2753:     }
                   2754: 
                   2755: }
                   2756: 
1.5       veillard 2757: int sql_show_table_stats(const char *table, const char *key) {
1.6       veillard 2758:     char query[MAX_QUERY];
1.2       veillard 2759:     MYSQL_RES *result;
                   2760:     MYSQL_ROW row;
                   2761:     int res;
                   2762: 
                   2763:     /*
                   2764:      * Search first for the ID if it already exists
                   2765:      */
1.6       veillard 2766:     snprintf(query, MAX_QUERY - 1, "SELECT COUNT(%s) FROM %s", key, table);
                   2767:     query[MAX_QUERY - 1] = 0;
1.2       veillard 2768:     if (mysql_query(sql,query)) {
1.5       veillard 2769:        printf("sql_show_table_stats: SELECT COUNT failed: %s\n",
1.2       veillard 2770:               mysql_error(sql));
                   2771:        return(-1);
                   2772:     }
                   2773: 
                   2774:     result = mysql_use_result(sql);
                   2775:     if (result) {
                   2776:        while((row = mysql_fetch_row(result)))
                   2777:        {
                   2778:            /*
                   2779:             * Lookup the value and return it
                   2780:             */
                   2781:            if (row[0] == NULL) {
                   2782:                mysql_free_result(result);
1.5       veillard 2783:                printf("sql_show_table_stats: select count returns NULL !\n");
1.2       veillard 2784:                return(-1);
                   2785:            }
                   2786:            if (sscanf(row[0], "%d", &res) != 1) {
                   2787:                mysql_free_result(result);
1.5       veillard 2788:                printf("sql_show_table_stats: value non numeric %s\n", row[0]);
1.2       veillard 2789:                return(-1);
                   2790:            }
                   2791:            mysql_free_result(result);
                   2792:            if (res <= 0)
                   2793:                printf("   %s is empty\n", table);
                   2794:            else
                   2795:                printf("   %s contains %d records\n", table, res);
                   2796:            return(res);
                   2797:        }
                   2798:        mysql_free_result(result);
                   2799:     }
                   2800:     if(mysql_errno(sql)) {
1.5       veillard 2801:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.2       veillard 2802:     }
                   2803:     return(-1);
                   2804: }
                   2805: 
1.5       veillard 2806: int sql_show_stats(void) {
1.2       veillard 2807:     const char *query = "SHOW TABLES";
                   2808:     MYSQL_RES *result;
                   2809:     MYSQL_ROW row;
                   2810: 
                   2811:     int tables = 0;
                   2812:     int records = 0;
                   2813: 
                   2814:     if (mysql_query(sql,query)) {
                   2815:        printf("sql_check_tables: SHOW TABLES failed %s\n",
                   2816:               mysql_error(sql));
                   2817:        return(-1);
                   2818:     }
                   2819: 
                   2820:     result = mysql_use_result(sql);
                   2821:     if (result) {
                   2822:        while((row = mysql_fetch_row(result)))
                   2823:        {
                   2824:            if (row[0] == NULL) {
                   2825:                mysql_free_result(result);
                   2826:                printf("sql_check_tables: SHOW TABLES returns NULL !\n");
                   2827:                return(-1);
                   2828:            }
                   2829:            tables++;
                   2830:        }
                   2831:        mysql_free_result(result);
                   2832:     }
                   2833:     if(mysql_errno(sql)) {
1.5       veillard 2834:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.2       veillard 2835:     }
                   2836:     printf("%d tables in use\n", tables);
1.5       veillard 2837:     records += sql_show_table_stats("Config", "Name");
                   2838:     records += sql_show_table_stats("Distribs", "Name");
                   2839:     records += sql_show_table_stats("Vendors", "Name");
                   2840:     records += sql_show_table_stats("Mirrors", "URL");
                   2841:     records += sql_show_table_stats("Metadata", "URL");
                   2842:     records += sql_show_table_stats("Packages", "Name");
1.8       veillard 2843:     records += sql_show_table_stats("Requires", "Resource");
                   2844:     records += sql_show_table_stats("Provides", "Resource");
1.5       veillard 2845:     records += sql_show_table_stats("Files", "Path");
1.2       veillard 2846:     printf("Total: %d records\n", records);
                   2847:     return(records);
                   2848: }
                   2849: 
1.26      veillard 2850: void sql_show_latests(void) {
                   2851:     rpmDataPtr list;
                   2852: 
                   2853:     list = sqlRpmByDate();
                   2854:     if (list == NULL) {
                   2855:        fprintf(stderr, "no package in database\n");
                   2856:        return;
                   2857:     }
1.28      daniel   2858:     dumpRpmByDate(list, 0);
1.29      veillard 2859: }
                   2860: 
1.40      veillard 2861: 
                   2862: void sql_show_resources(void) {
                   2863:     int i;
                   2864: 
                   2865:     sqlInitSqlDirList();
                   2866:     sqlInitSqlResourceList();
1.42      veillard 2867:     sqlInitSqlDistributionList();
                   2868:     sqlInitSqlVendorList();
1.40      veillard 2869:     for (i = 0;i < sqlResourceListLen;i++) {
                   2870:        if (sqlResourceList[i] == NULL)
                   2871:            break;
                   2872:        dumpRessRedirHtml(sqlResourceList[i]);
1.41      veillard 2873:        if (rpm2html_dump_rdf_resources)
                   2874:            sql_dump_rdf(sqlResourceList[i]);
1.40      veillard 2875:     }
1.44      daniel   2876:     if (rpm2htmlVerbose)
                   2877:        fprintf(stderr, "Dumped %d redirrect resource pages\n", i);
1.45      veillard 2878:     if (rpm2html_dump_rdf_resources)
                   2879:        sql_dump_rdf_full_index();
1.49    ! veillard 2880:     sqlListsCleanup();
        !          2881: }
        !          2882: 
        !          2883: void sql_reindex(void) {
        !          2884:     int i;
        !          2885:     int pid, status;
        !          2886: 
        !          2887:     sqlInitSqlDistributionList();
        !          2888: 
        !          2889: #ifdef SQL_DEBUG
        !          2890:     printf("sql_reindex\n");
        !          2891: #endif
        !          2892:     if (sqlDistributionListInitialized) {
        !          2893:        for (i = 0 ; i < sqlDistributionListLen;i++) {
        !          2894:            if (sqlDistributionList[i] != NULL) {
        !          2895:                printf("indexing: %s\n", sqlDistributionList[i]);
        !          2896:                pid = fork();
        !          2897:                if (pid < 0) {
        !          2898:                    fprintf(stderr, "fork failed \n");
        !          2899:                    continue;
        !          2900:                }
        !          2901:                if (pid == 0) {
        !          2902:                    execl("rpm2html", "-dist", sqlDistributionList[i],
        !          2903:                          "rpm2html-en.config", NULL);
        !          2904:                    fprintf(stderr, "Unable to launch rpm2html\n");
        !          2905:                    exit(127);
        !          2906:                }
        !          2907:                do {
        !          2908:                    if (waitpid(pid, &status, 0) == -1) {
        !          2909:                        if (errno != EINTR)
        !          2910:                            goto done;
        !          2911:                    } else {
        !          2912:                        if (status != 0)
        !          2913:                            printf("indexing: %s exit %d\n",
        !          2914:                                sqlDistributionList[i], status);
        !          2915:                        break;
        !          2916:                    }
        !          2917:                } while(1);
        !          2918: 
        !          2919:            }
        !          2920:        }
        !          2921:     }
        !          2922: done:
1.47      veillard 2923:     sqlListsCleanup();
                   2924: }
                   2925: 
                   2926: void sql_show_index(void) {
                   2927:     sqlInitSqlDirList();
                   2928:     sqlInitSqlDistributionList();
                   2929:     if (rpm2html_dump_rdf_resources)
                   2930:        sql_dump_rdf_full_index();
                   2931:     sqlListsCleanup();
1.40      veillard 2932: }
                   2933: 
1.29      veillard 2934: void sql_show_all(void) {
                   2935:     rpmDataPtr list;
1.31      veillard 2936: #ifdef SQL_DEBUG_TIMING
                   2937:     time_t cur, last;
1.29      veillard 2938: 
1.31      veillard 2939:     last = time(NULL);
                   2940: #endif
1.29      veillard 2941:     list = sqlRpmAll();
                   2942:     if (list == NULL) {
                   2943:        fprintf(stderr, "no package in database\n");
                   2944:        return;
                   2945:     }
1.31      veillard 2946: #ifdef SQL_DEBUG_TIMING
                   2947:     cur = time(NULL);
                   2948:     fprintf(stderr, "sqlRpmAll took %d seconds\n", (int)(cur - last));
                   2949:     last = cur;
                   2950: #endif
                   2951: 
                   2952:     rpmNameSort(&list, 0);
                   2953:     dumpRpmByName(rpmSoftwareList, 0);
                   2954: 
                   2955: #ifdef SQL_DEBUG_TIMING
                   2956:     cur = time(NULL);
                   2957:     fprintf(stderr, "dumpRpmByName took %d seconds\n", (int)(cur - last));
                   2958:     last = cur;
                   2959: #endif
                   2960: 
                   2961:     rpmGroupSort(&list, 0);
1.32      daniel   2962:     dumpRpmByGroups(rpmSoftwareList, 0);
1.31      veillard 2963: 
                   2964: #ifdef SQL_DEBUG_TIMING
                   2965:     cur = time(NULL);
                   2966:     fprintf(stderr, "dumpRpmByGroups took %d seconds\n", (int)(cur - last));
                   2967:     last = cur;
                   2968: #endif
1.35      veillard 2969: 
                   2970:     rpmVendorSort(&list, 0);
                   2971:     dumpRpmByVendors(list, 0);
                   2972: 
                   2973: #ifdef SQL_DEBUG_TIMING
                   2974:     cur = time(NULL);
                   2975:     fprintf(stderr, "dumpRpmByVendors took %d seconds\n", (int)(cur - last));
1.36      veillard 2976:     last = cur;
                   2977: #endif
                   2978: 
                   2979:     rpmDistribSort(&list, 0);
                   2980:     dumpRpmByDistribs(list, 0);
                   2981: 
                   2982: #ifdef SQL_DEBUG_TIMING
                   2983:     cur = time(NULL);
                   2984:     fprintf(stderr, "dumpRpmByDistribs took %d seconds\n", (int)(cur - last));
1.35      veillard 2985:     last = cur;
                   2986: #endif
                   2987: 
1.39      daniel   2988:     rpmDateSort(&list, 0);
1.37      veillard 2989:     dumpRpmByDate(list, 0);
                   2990: 
                   2991: #ifdef SQL_DEBUG_TIMING
                   2992:     cur = time(NULL);
                   2993:     fprintf(stderr, "dumpRpmByDate took %d seconds\n", (int)(cur - last));
                   2994:     last = cur;
                   2995: #endif
                   2996: 
1.40      veillard 2997:     rpmdataCleanup();
                   2998:     sleep(30);
1.26      veillard 2999: }
                   3000: 
1.2       veillard 3001: /************************************************************************
                   3002:  *                                                                     *
                   3003:  *                     rpm2html configuration functions                *
                   3004:  *                                                                     *
                   3005:  ************************************************************************/
                   3006: 
                   3007: int readConfigSql(void) {
1.6       veillard 3008:     char query[MAX_QUERY];
1.3       veillard 3009:     MYSQL_RES *result;
                   3010:     MYSQL_ROW row;
1.4       veillard 3011:     int dir = 0;
1.3       veillard 3012: 
1.2       veillard 3013:     /*
1.3       veillard 3014:      * General configuration informations
1.2       veillard 3015:      */
1.6       veillard 3016:     snprintf(query, MAX_QUERY - 1, "SELECT Name,Value FROM Config");
                   3017:     query[MAX_QUERY - 1] = 0;
1.3       veillard 3018:     if (mysql_query(sql,query)) {
                   3019:        printf("sql_check_tables: SELECT Config failed %s\n",
                   3020:               mysql_error(sql));
                   3021:        return(-1);
                   3022:     }
                   3023: 
                   3024:     result = mysql_use_result(sql);
                   3025:     if (result) {
                   3026:        while((row = mysql_fetch_row(result)))
                   3027:        {
                   3028:            if ((row[0] == NULL) || (row[1] == NULL)) {
                   3029:                fprintf(stderr, "readConfigSql : found NULL value\n");
                   3030:                continue;
                   3031:            }
1.4       veillard 3032:            if (!strcmp(row[0], "dir"))
                   3033:                dir = 1;
1.3       veillard 3034:            addConfigEntry(RPM2HTML_NAME, row[0], row[1]);
                   3035:        }
                   3036:        mysql_free_result(result);
                   3037:     }
                   3038:     if(mysql_errno(sql)) {
1.5       veillard 3039:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.4       veillard 3040:     }
                   3041:     if (dir == 0) {
                   3042:        fprintf(stderr, "readConfigSql : no directory\n");
                   3043:        return(-1);
1.3       veillard 3044:     }
                   3045: 
                   3046:     /*
                   3047:      * The metadata mirror list.
                   3048:      */
1.6       veillard 3049:     snprintf(query, MAX_QUERY - 1, "SELECT URL FROM Metadata");
                   3050:     query[MAX_QUERY - 1] = 0;
1.3       veillard 3051:     if (mysql_query(sql,query)) {
                   3052:        printf("sql_check_tables: SELECT Metadata failed %s\n",
                   3053:               mysql_error(sql));
                   3054:        return(-1);
                   3055:     }
                   3056: 
                   3057:     result = mysql_use_result(sql);
                   3058:     if (result) {
                   3059:        while((row = mysql_fetch_row(result)))
                   3060:        {
                   3061:            if (row[0] == NULL) {
                   3062:                fprintf(stderr, "readConfigSql : found NULL metadata\n");
                   3063:                continue;
                   3064:            }
                   3065:            addConfigEntry("metadata", "mirror", row[0]);
                   3066:        }
                   3067:        mysql_free_result(result);
                   3068:     }
                   3069:     if(mysql_errno(sql)) {
1.5       veillard 3070:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 3071:     }
                   3072: 
                   3073:     /*
                   3074:      * The distribution lists
                   3075:      */
1.6       veillard 3076:     snprintf(query, MAX_QUERY - 1, "SELECT Directory,Name,URL,URLSrc,Path FROM Distribs");
                   3077:     query[MAX_QUERY - 1] = 0;
1.3       veillard 3078:     if (mysql_query(sql,query)) {
                   3079:        printf("sql_check_tables: SELECT Distribs failed %s\n",
                   3080:               mysql_error(sql));
                   3081:        return(-1);
                   3082:     }
                   3083: 
                   3084:     result = mysql_use_result(sql);
                   3085:     if (result) {
                   3086:        while((row = mysql_fetch_row(result)))
                   3087:        {
                   3088:            if (row[0] == NULL) {
                   3089:                fprintf(stderr, "readConfigSql : found NULL distro\n");
                   3090:                continue;
                   3091:            }
                   3092: 
                   3093:            if (row[1] != NULL)
                   3094:                addConfigEntry(row[0], "name", row[1]);
                   3095:            if (row[2] != NULL)
                   3096:                addConfigEntry(row[0], "ftp", row[2]);
                   3097:            if (row[3] != NULL)
                   3098:                addConfigEntry(row[0], "ftp", row[3]);
                   3099:            if (row[4] != NULL)
                   3100:                addConfigEntry(row[0], "subdir", row[4]);
                   3101:        }
                   3102:        mysql_free_result(result);
                   3103:     }
                   3104:     if(mysql_errno(sql)) {
1.5       veillard 3105:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 3106:     }
                   3107: 
                   3108:     /*
                   3109:      * The Mirrors
                   3110:      */
1.6       veillard 3111:     snprintf(query, MAX_QUERY - 1, "SELECT Distribs.Directory,Mirrors.URL FROM Distribs,Mirrors WHERE Distribs.ID = Mirrors.ID");
                   3112:     query[MAX_QUERY - 1] = 0;
1.3       veillard 3113:     if (mysql_query(sql,query)) {
                   3114:        printf("sql_check_tables: SELECT Distribs failed %s\n",
                   3115:               mysql_error(sql));
                   3116:        return(-1);
                   3117:     }
                   3118: 
                   3119:     result = mysql_use_result(sql);
                   3120:     if (result) {
                   3121:        while((row = mysql_fetch_row(result)))
                   3122:        {
                   3123:            if ((row[0] == NULL) || (row[1] == NULL)) {
                   3124:                fprintf(stderr, "readConfigSql : found NULL mirror\n");
                   3125:                continue;
                   3126:            }
                   3127: 
                   3128:            addConfigEntry(row[0], "mirror", row[1]);
                   3129:        }
                   3130:        mysql_free_result(result);
                   3131:     }
                   3132:     if(mysql_errno(sql)) {
1.5       veillard 3133:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 3134:     }
                   3135: 
1.5       veillard 3136:     /*
                   3137:      * TODO: add the language(s) stuff
                   3138:      */
1.3       veillard 3139:     return(0);
1.2       veillard 3140: }
                   3141: 
                   3142: void sqlConfigEntry(const char *rpmdir, const char *name, const char *value) {
                   3143:     int distrib;
                   3144: 
                   3145:     if (rpm2htmlVerbose > 1)
                   3146:        printf("sqlConfigEntry(\"%s\", \"%s\", \"%s\")\n", rpmdir, name, value);
                   3147: 
                   3148:     /*
                   3149:      * case of global option for rpm2html.
                   3150:      */
                   3151:     if (!strcasecmp(rpmdir, RPM2HTML_NAME)) {
1.5       veillard 3152:        sql_add_config_info(name, value);
1.2       veillard 3153:        return;
                   3154:     }
                   3155: 
                   3156:     /*
                   3157:      * Options for the metadata mirrors.
                   3158:      */
                   3159:     if (!strcasecmp(rpmdir, "metadata")) {
                   3160:        if (!strcasecmp(name, "mirror")) {
1.5       veillard 3161:            sql_add_metadata_base(value);
1.2       veillard 3162:        } else {
                   3163:            printf("Config file : %s entry for [metadata] ignored\n", name);
                   3164:        }
                   3165:        return;
                   3166:     }
                   3167: 
                   3168:     /*
                   3169:      * option for a directory.
                   3170:      */
                   3171:     if (!strcasecmp(name, "name")) {
1.9       veillard 3172:        sql_add_distrib(value, NULL, rpmdir, NULL, NULL, NULL, NULL,
                   3173:                        NULL, NULL);
1.2       veillard 3174:     } else if (!strcasecmp(name, "subdir")) {
                   3175:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3176:        if (distrib > 0)
                   3177:             sql_update_id("Distribs", distrib, "Path", value);
                   3178:     } else if (!strcasecmp(name, "url")) {
                   3179:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3180:        if (distrib > 0)
                   3181:             sql_update_id("Distribs", distrib, "URL", value);
                   3182:     } else if (!strcasecmp(name, "ftp")) {
                   3183:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3184:        if (distrib > 0)
                   3185:             sql_update_id("Distribs", distrib, "URL", value);
                   3186:     } else if (!strcasecmp(name, "ftpsrc")) {
                   3187:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3188:        if (distrib > 0)
                   3189:             sql_update_id("Distribs", distrib, "URLSrc", value);
1.9       veillard 3190:     } else if (!strcasecmp(name, "html")) {
                   3191:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3192:        if (distrib > 0)
                   3193:             sql_update_id("Distribs", distrib, "Html", value);
                   3194:     } else if (!strcasecmp(name, "color")) {
                   3195:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3196:        if (distrib > 0)
                   3197:             sql_update_id("Distribs", distrib, "Color", value);
1.2       veillard 3198:     } else if (!strcasecmp(name, "mirror")) {
                   3199:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3200:        if (distrib > 0)
1.5       veillard 3201:            sql_add_dist_mirror(distrib, value, 0);
1.2       veillard 3202:     } else {
                   3203:        printf("Config file : %s entry for [%s] ignored\n", name, rpmdir);
                   3204:     }
                   3205: }
1.1       veillard 3206: 

Webmaster