Annotation of rpm2html/sql.c, revision 1.53

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.51      daniel   1201: int sql_get_package_id(const char *filename) {
                   1202:     int id;
                   1203:     MYSQL_RES *result;
                   1204:     MYSQL_ROW row;
                   1205:     char query[MAX_QUERY];
                   1206:     int left = MAX_QUERY - 1;
                   1207:     int len;
                   1208:     char *end;
                   1209:     static int queries = 0;
                   1210: 
                   1211:     if (filename == NULL)
                   1212:        return(0);
                   1213: 
                   1214:     queries++;
                   1215: 
                   1216:     /*
                   1217:      * Search first for the ID if it already exists
                   1218:      */
                   1219:     len = snprintf(query, left, "SELECT ID FROM Packages WHERE filename='%s'",
                   1220:                   filename);
                   1221:     if (len < 0) {
                   1222:        fprintf(stderr, "sql_get_package_id : %s overflow\n",
                   1223:                filename);
                   1224:        return(0);
                   1225:     }
                   1226:     query[len] = 0;
                   1227: 
                   1228:     if (mysql_query(sql,query)) {
                   1229:        printf("sql_get_package_id: SELECT %s failed %s\n", filename,
                   1230:               mysql_error(sql));
                   1231:        return(0);
                   1232:     }
                   1233: 
                   1234:     result = mysql_use_result(sql);
                   1235:     if (result) {
                   1236:        if ((row = mysql_fetch_row(result)))
                   1237:        {
                   1238:            /*
                   1239:             * Lookup the first ID and return it
                   1240:             */
                   1241:            if (row[0] == NULL) {
                   1242:                mysql_free_result(result);
                   1243:                printf("sql_get_package_id: select returns NULL !\n");
                   1244:                return(0);
                   1245:            }
                   1246:            if (sscanf(row[0], "%d", &id) != 1) {
                   1247:                mysql_free_result(result);
                   1248:                printf("sql_get_package_id: ID non numeric %s\n", row[0]);
                   1249:                return(0);
                   1250:            }
                   1251:            mysql_free_result(result);
                   1252:            return(id);
                   1253:        }
                   1254:        mysql_free_result(result);
                   1255:     }
                   1256:     if (mysql_errno(sql)) {
                   1257:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1258:        return(-1);
                   1259:     }
                   1260: 
                   1261:     printf("%d New package %s\n", queries, filename);
                   1262:     return(0);
                   1263: }
1.34      veillard 1264: 
1.5       veillard 1265: int sql_add_package(const char *filename,
1.2       veillard 1266:        const char *Name, const char *Version, const char *Release,
1.6       veillard 1267:        const char *Arch,
                   1268:        int dist, const char *URL, const char *URLSrc, int vendor,
1.2       veillard 1269:        const char *Packager, const char *Category, const char *Summary,
1.41      veillard 1270:        const char *Description, const char *Copyright, int Date, int Size,
1.43      veillard 1271:        const char *Os, const char *Distribution, const char *Vendor) {
1.2       veillard 1272:     int id;
                   1273:     int nb_fields = 0;
1.35      veillard 1274:     char installed_filename[500];
1.2       veillard 1275: 
1.35      veillard 1276:     if (filename == NULL) {
                   1277:        sprintf(installed_filename, "localbase/%s-%s-%s.%s.rpm",
                   1278:                Name,Version,Release,Arch);
                   1279:        filename = installed_filename;
                   1280:     }
1.6       veillard 1281: 
                   1282:     if (dist < 0)
1.2       veillard 1283:        return(-1);
1.6       veillard 1284:     if ((Name == NULL) || (Version == NULL) || (Release == NULL) ||
                   1285:        (Arch == NULL))
                   1286:        return(-1);
                   1287: 
                   1288:     id = sql_get_key("Packages", "filename", filename);
1.2       veillard 1289:     if (id <= 0)
                   1290:        return(-1);
                   1291:     nb_fields = 1;
1.8       veillard 1292: 
                   1293:     if (rpm2htmlVerbose > 1)
                   1294:        printf("Adding %s ID %d\n", filename, id);
                   1295: 
1.2       veillard 1296:     if (Name != NULL)
1.6       veillard 1297:        nb_fields += sql_update_id("Packages", id, "Name", Name);
1.2       veillard 1298:     if (Version != NULL)
                   1299:        nb_fields += sql_update_id("Packages", id, "Version", Version);
                   1300:     if (Release != NULL)
                   1301:        nb_fields += sql_update_id("Packages", id, "Release", Release);
1.6       veillard 1302:     if (Release != NULL)
                   1303:        nb_fields += sql_update_id("Packages", id, "Arch", Arch);
1.2       veillard 1304:     if (Category != NULL)
                   1305:        nb_fields += sql_update_id("Packages", id, "Category", Category);
                   1306:     if (URL != NULL)
                   1307:        nb_fields += sql_update_id("Packages", id, "URL", URL);
                   1308:     if (URLSrc != NULL)
                   1309:        nb_fields += sql_update_id("Packages", id, "URLSrc", URLSrc);
1.17      veillard 1310:     if (dist >= 0) {
                   1311:        char str[30];
                   1312:        snprintf(str, 30, "%d", dist);
                   1313:        str[29] = 0;
                   1314:        nb_fields += sql_update_id("Packages", id, "Dist", str);
                   1315:     }
1.38      veillard 1316:     if (Summary != NULL) {
1.2       veillard 1317:        nb_fields += sql_update_id("Packages", id, "Summary", Summary);
1.38      veillard 1318:     }
                   1319:     if (Description != NULL) {
1.2       veillard 1320:        nb_fields += sql_update_id("Packages", id,
                   1321:                                   "Description", Description);
1.38      veillard 1322:     }
1.2       veillard 1323:     if (Copyright != NULL)
                   1324:        nb_fields += sql_update_id("Packages", id, "Copyright", Copyright);
1.25      veillard 1325:     if (Date != 0) {
                   1326:        char str[30];
                   1327:        snprintf(str, 30, "%d", Date);
                   1328:        str[29] = 0;
                   1329:        nb_fields += sql_update_id("Packages", id, "Date", str);
                   1330:     }
1.41      veillard 1331:     if (Size != 0) {
                   1332:        char str[30];
                   1333:        snprintf(str, 30, "%d", Size);
                   1334:        str[29] = 0;
                   1335:        nb_fields += sql_update_id("Packages", id, "Size", str);
                   1336:     }
1.38      veillard 1337:     if (Os != NULL) {
1.33      veillard 1338:        nb_fields += sql_update_id("Packages", id, "Os", Os);
1.38      veillard 1339:     }
1.34      veillard 1340:     if (Packager != NULL) {
                   1341:        char str[30];
1.35      veillard 1342:        int packager = sql_add_vendor(Packager, NULL, NULL);
1.34      veillard 1343: 
1.35      veillard 1344:        if (packager > 0) {
                   1345:            snprintf(str, 30, "%d", packager);
1.34      veillard 1346:            str[29] = 0;
1.35      veillard 1347:            nb_fields += sql_update_id("Packages", id, "Packager", str);
1.34      veillard 1348:        }
                   1349:     }
1.36      veillard 1350:     if (Distribution != NULL) {
                   1351:        char str[30];
                   1352:        int packager = sql_add_distribution(Distribution, NULL, NULL);
                   1353: 
                   1354:        if (packager > 0) {
                   1355:            snprintf(str, 30, "%d", packager);
                   1356:            str[29] = 0;
                   1357:            nb_fields += sql_update_id("Packages", id, "Vendor", str);
                   1358:        }
                   1359:     }
                   1360:     /***************
                   1361:     if (vendor > 0) {
                   1362:        char str[30];
                   1363:        snprintf(str, 30, "%d", vendor);
                   1364:        str[29] = 0;
                   1365:        nb_fields += sql_update_id("Packages", id, "Vendor", str);
                   1366:     }
                   1367:      ***************/
1.2       veillard 1368:     
1.6       veillard 1369:     return(id);
1.17      veillard 1370: }
                   1371: 
                   1372: int sql_get_distrib_by_name(const char *Name) {
                   1373:     int ret;
                   1374: 
                   1375:     if (Name == NULL)
                   1376:        return(-1);
                   1377:     ret = sql_read_key("Distribs", Name);
                   1378: 
1.18      daniel   1379: #ifdef SQL_DEBUG
1.17      veillard 1380: fprintf(stderr, "sql_get_distrib_by_name(%s) => %d\n", Name, ret);
1.18      daniel   1381: #endif
1.17      veillard 1382: 
                   1383:     return(ret);
                   1384: }
                   1385: 
                   1386: int sql_get_distrib_by_directory(const char *Directory) {
                   1387:     int ret;
                   1388: 
                   1389:     if (Directory == NULL)
                   1390:        return(-1);
                   1391: 
                   1392:     ret = sql_get_key("Distribs", "Directory", Directory);
                   1393: 
1.18      daniel   1394: #ifdef SQL_DEBUG
1.17      veillard 1395: fprintf(stderr, "sql_get_distrib_by_directory(%s) => %d\n", Directory, ret);
1.18      daniel   1396: #endif
1.17      veillard 1397: 
                   1398:     return(ret);
1.2       veillard 1399: }
                   1400: 
1.5       veillard 1401: int sql_add_distrib(const char *Name, const char *Vendor,
1.2       veillard 1402:        const char *Directory, const char *Path, const char *URL,
1.9       veillard 1403:        const char *URLSrc, const char *Description,
                   1404:        const char *Html, const char *Color) {
1.1       veillard 1405:     int id, vendor;
                   1406:     int nb_fields = 0;
                   1407:     char VendorStr[15];
                   1408: 
                   1409:     if (Name == NULL)
                   1410:        return(-1);
                   1411: 
1.6       veillard 1412:     id = sql_get_key("Distribs", "Name", Name);
1.1       veillard 1413:     nb_fields = 1;
                   1414:     if (Vendor != NULL) {
1.6       veillard 1415:        vendor = sql_get_key("Vendors", "Name", Vendor);
1.1       veillard 1416:        sprintf(VendorStr, "%d", vendor);
                   1417:        nb_fields += sql_update_id("Distribs", id, "Vendor", VendorStr);
                   1418:     }
1.2       veillard 1419:     if (Directory != NULL)
                   1420:        nb_fields += sql_update_id("Distribs", id, "Directory", Directory);
1.1       veillard 1421:     if (Path != NULL)
                   1422:        nb_fields += sql_update_id("Distribs", id, "Path", Path);
                   1423:     if (URL != NULL)
                   1424:        nb_fields += sql_update_id("Distribs", id, "URL", URL);
                   1425:     if (URLSrc != NULL)
                   1426:        nb_fields += sql_update_id("Distribs", id, "URLSrc", URLSrc);
1.9       veillard 1427:     if (Html != NULL)
                   1428:        nb_fields += sql_update_id("Distribs", id, "Html", Html);
                   1429:     if (Color != NULL)
                   1430:        nb_fields += sql_update_id("Distribs", id, "Color", Color);
1.1       veillard 1431:     if (Description != NULL)
                   1432:        nb_fields += sql_update_id("Distribs", id,
                   1433:                                   "Description", Description);
                   1434:     
                   1435:     return(nb_fields);
                   1436: }
                   1437: 
1.5       veillard 1438: void sql_add_config_info(const char *name, const char *value) {
1.2       veillard 1439:     sql_update("Config", name, "Value", value);
                   1440: }
                   1441: 
1.5       veillard 1442: void sql_add_metadata_base(const char *URL) {
1.2       veillard 1443:     sql_blind_insert("Metadata", "URL", URL, -1);
                   1444: }
                   1445: 
1.6       veillard 1446: /************************************************************************
                   1447:  *                                                                     *
1.8       veillard 1448:  *                     Cleanup functions                               *
                   1449:  *                                                                     *
                   1450:  ************************************************************************/
                   1451: 
                   1452: int sql_remove_package(int id) {
                   1453:     char query[SMALL_QUERY];
                   1454: 
                   1455:     if (id <= 0)
                   1456:        return(-1);
                   1457: 
                   1458:     /*
                   1459:      * remove the ID from the package list
                   1460:      */
                   1461:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Packages WHERE ID=%d", id);
                   1462:     query[SMALL_QUERY - 1] = 0;
                   1463:     if (mysql_query(sql,query)) {
1.38      veillard 1464:        printf("sql_remove_package: DELETE package %d failed %s\n", id, mysql_error(sql));
1.8       veillard 1465:        return(-1);
                   1466:     }
                   1467:     if(mysql_errno(sql)) {
                   1468:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1469:        return(-1);
                   1470:     }
                   1471: 
                   1472:     /*
                   1473:      * remove the associated files from the Files list
                   1474:      */
                   1475:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Files WHERE ID=%d", id);
                   1476:     query[SMALL_QUERY - 1] = 0;
                   1477:     if (mysql_query(sql,query)) {
1.38      veillard 1478:        printf("sql_remove_package: DELETE Files %d failed %s\n", id, mysql_error(sql));
1.8       veillard 1479:        return(-1);
                   1480:     }
                   1481:     if(mysql_errno(sql)) {
                   1482:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1483:        return(-1);
                   1484:     }
                   1485: 
                   1486:     /*
                   1487:      * remove the associated Provides entries
                   1488:      */
                   1489:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Provides WHERE ID=%d", id);
                   1490:     query[SMALL_QUERY - 1] = 0;
                   1491:     if (mysql_query(sql,query)) {
1.38      veillard 1492:        printf("sql_remove_package: DELETE Provides %d failed %s\n", id, mysql_error(sql));
1.8       veillard 1493:        return(-1);
                   1494:     }
                   1495:     if(mysql_errno(sql)) {
                   1496:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1497:        return(-1);
                   1498:     }
                   1499: 
                   1500:     /*
                   1501:      * remove the associated Requires entries
                   1502:      */
                   1503:     snprintf(query, SMALL_QUERY - 1, "DELETE FROM Requires WHERE ID=%d", id);
                   1504:     query[SMALL_QUERY - 1] = 0;
                   1505:     if (mysql_query(sql,query)) {
1.38      veillard 1506:        printf("sql_remove_package: DELETE Requires %d failed %s\n", id, mysql_error(sql));
1.8       veillard 1507:        return(-1);
                   1508:     }
                   1509:     if(mysql_errno(sql)) {
                   1510:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   1511:        return(-1);
                   1512:     }
                   1513: 
1.42      veillard 1514:     /*
                   1515:      * Remove the RDF and HTML files.
                   1516:      * TODO
                   1517:      */
1.8       veillard 1518:     return(-1);
                   1519: }
                   1520: 
                   1521: int sql_check_packages(void) {
                   1522:     MYSQL_RES *result;
                   1523:     MYSQL_ROW row;
1.20      daniel   1524:     char *query = "SELECT filename,ID FROM Packages";
1.8       veillard 1525:     struct stat buf;
                   1526:     int id;
1.22      daniel   1527:     int ids[2500]; /* Do not remove more than 2500 package per run */
1.8       veillard 1528:     int index;
                   1529:     int total = 0;
                   1530: 
                   1531:     if (rpm2htmlVerbose)
                   1532:        printf("Database cleanup\n");
1.42      veillard 1533:     sqlInitSqlDistributionList();
1.8       veillard 1534:     index = 0;
                   1535:     /*
                   1536:      * Search first for the ID if it already exists
                   1537:      */
                   1538:     if (mysql_query(sql,query)) {
                   1539:        printf("sql_check_packages: SELECT from Packages failed: %s\n",
                   1540:               mysql_error(sql));
                   1541:        return(-1);
                   1542:     }
                   1543: 
                   1544:     result = mysql_use_result(sql);
                   1545:     if (result) {
                   1546:        while((row = mysql_fetch_row(result)))
                   1547:        {
                   1548:            if ((row[0] == NULL) || (row[1] == NULL)) {
                   1549:                printf("sql_check_packages: Path or ID is NULL !\n");
                   1550:                continue;
                   1551:            }
1.35      veillard 1552:            if (!strncmp(row[0], "localbase", 9))
                   1553:                continue;
                   1554: 
1.8       veillard 1555:            if ((stat(row[0], &buf) < 0) || (buf.st_size < 50)) {
                   1556:                /*
                   1557:                 * Need to remove the package from the database.
                   1558:                 */
                   1559:                if (sscanf(row[1], "%d", &id) != 1) {
                   1560:                    printf("sql_check_packages: ID non numeric %s\n", row[1]);
                   1561:                    continue;
                   1562:                }
                   1563:                ids[index++] = id;
1.20      daniel   1564:                if (rpm2htmlVerbose)
1.8       veillard 1565:                    printf("Removing %s ID %d\n", row[0], id);
1.22      daniel   1566:                if (index >= 2500)
1.8       veillard 1567:                    break;
                   1568:            }
                   1569:        }
                   1570:        mysql_free_result(result);
                   1571:     }
                   1572:     if(mysql_errno(sql)) {
                   1573:        fprintf(stderr, "sql_update Error: %s\n", mysql_error(sql));
                   1574:        return(-1);
                   1575:     }
                   1576: 
                   1577:     /*
                   1578:      * Do the cleanup.
                   1579:      */
1.20      daniel   1580:     if (rpm2htmlVerbose)
                   1581:        printf("Database cleanup : removing %d entries...\n", index);
1.8       veillard 1582:     for (id = 0;id < index;id++) {
                   1583:        sql_remove_package(ids[id]);
                   1584:     }
                   1585: 
1.34      veillard 1586:     printf("Database cleanup : removed %d entries\n", index);
1.8       veillard 1587:     return(total);
                   1588: }
                   1589: 
                   1590: /************************************************************************
1.26      veillard 1591:  *                                                                     *
                   1592:  *                     Package lists extraction                        *
                   1593:  *                                                                     *
                   1594:  ************************************************************************/
                   1595: int sqlDirListInitialized = 0;
                   1596: rpmDirPtr sqlDirList[SQL_MAX_DISTRIBS];
1.35      veillard 1597: int sqlVendorListInitialized = 0;
                   1598: int sqlVendorListLen;
                   1599: char **sqlVendorList;
1.36      veillard 1600: int sqlDistributionListInitialized = 0;
                   1601: int sqlDistributionListLen;
                   1602: char **sqlDistributionList;
1.40      veillard 1603: int sqlResourceListInitialized = 0;
                   1604: int sqlResourceListLen = 0;
                   1605: int sqlResourceListMax = 0;
                   1606: char **sqlResourceList;
                   1607: 
                   1608: char *
                   1609: sqlRpmAnalyzeResourceRow(MYSQL_ROW row) {
                   1610:     const char *name;
                   1611:     char **tmp, *ret;
                   1612: 
                   1613:     if (row == NULL)
                   1614:        return(NULL);
                   1615:     name = row[0];
                   1616:     if (name == NULL)
                   1617:        return(NULL);
                   1618: 
                   1619:     if (sqlResourceListLen >= sqlResourceListMax) {
                   1620:        sqlResourceListMax *= 2;
1.45      veillard 1621:        tmp = (char **) xmlRealloc(sqlResourceList,
1.40      veillard 1622:                                     (sqlResourceListMax) * sizeof(char *));
                   1623:        if (sqlResourceList == NULL) {
                   1624:            fprintf(stderr, "sqlInitSqlResourceList Error: out of memory\n");
                   1625:            return(NULL);
                   1626:        }
                   1627:        sqlResourceList = tmp;
                   1628:     }
                   1629: 
1.45      veillard 1630:     ret = sqlResourceList[sqlResourceListLen++] = xmlStrdup(name);
1.40      veillard 1631:     return(ret);
                   1632: }
                   1633: 
                   1634: void
                   1635: sqlInitSqlResourceList(void) {
                   1636:     MYSQL_RES *result;
                   1637:     MYSQL_ROW row;
                   1638:     char *query;
                   1639:     int i;
                   1640: 
                   1641:     if (sqlResourceListInitialized != 0)
                   1642:        return;
                   1643: 
1.45      veillard 1644: #ifdef SQL_DEBUG_MEM
                   1645:     printf("sqlInitSqlResourceList\n");
                   1646: #endif
1.40      veillard 1647:     if (rpm2htmlVerbose)
                   1648:        printf("sqlInitSqlResourceList query\n");
                   1649: 
                   1650:     /*
                   1651:      * Allocate the array
                   1652:      */
                   1653:     sqlResourceListLen = 0;
                   1654:     sqlResourceListMax = 1000;
1.45      veillard 1655:     sqlResourceList = (char **) xmlMalloc((sqlResourceListMax) *
1.40      veillard 1656:                                            sizeof(char *));
                   1657:     if (sqlResourceList == NULL) {
                   1658:        fprintf(stderr, "sqlInitSqlResourceList Error: out of memory\n");
                   1659:        return;
                   1660:     }
                   1661:     
                   1662:     /*
                   1663:      * query the database for the values
                   1664:      */
                   1665:     query = "select Resource from Provides group by Resource";
                   1666: 
                   1667:     if (mysql_query(sql,query)) {
                   1668:        printf("sqlInitSqlResourceList: SELECT from Provides failed: %s\n",
                   1669:               mysql_error(sql));
                   1670:        return;
                   1671:     }
                   1672: 
                   1673:     i = 0;
                   1674:     result = mysql_use_result(sql);
                   1675:     if (result) {
                   1676:        while((row = mysql_fetch_row(result)))
                   1677:        {
                   1678:            if (sqlRpmAnalyzeResourceRow(row) != NULL)
                   1679:                i++;
                   1680:        }
                   1681:        mysql_free_result(result);
                   1682:     }
                   1683:     if(mysql_errno(sql)) {
                   1684:        fprintf(stderr, "sqlInitSqlResourceList Error: %s\n", mysql_error(sql));
                   1685:        return;
                   1686:     }
                   1687: 
                   1688: 
                   1689:     if (rpm2htmlVerbose)
                   1690:        printf("sqlInitSqlResourceList done: %d entries\n", i);
                   1691:     sqlResourceListInitialized++;
                   1692:     return;
                   1693: }
1.36      veillard 1694: 
                   1695: char *
                   1696: sqlRpmAnalyzeDistributionRow(MYSQL_ROW row) {
                   1697:     const char *id;
                   1698:     const char *name;
                   1699:     char **tmp;
                   1700:     int distribution;
                   1701: 
                   1702:     if (row == NULL)
                   1703:        return(NULL);
                   1704:     id = row[0];
                   1705:     name = row[1];
                   1706:     if ((id == NULL) || (name == NULL))
                   1707:        return(NULL);
                   1708: 
                   1709:     if (sscanf(id, "%d", &distribution) != 1)
                   1710:        return(NULL);
                   1711:     if ((distribution <= 0) || (distribution > 100000)) {
                   1712:        fprintf(stderr, "Dist number out of range %d\n", distribution);
                   1713:        return(NULL);
                   1714:     }
                   1715:     if (distribution >= sqlDistributionListLen) {
                   1716:        int i = sqlDistributionListLen;
                   1717:        sqlDistributionListLen = distribution + 100;
1.45      veillard 1718:        tmp = (char **) xmlRealloc(sqlDistributionList,
1.36      veillard 1719:                                     (sqlDistributionListLen) * sizeof(char *));
                   1720:        if (sqlDistributionList == NULL) {
                   1721:            fprintf(stderr, "sqlInitSqlDistributionList Error: out of memory\n");
                   1722:            return(NULL);
                   1723:        }
                   1724:        sqlDistributionList = tmp;
                   1725:        memset(&sqlDistributionList[i], 0, sizeof(char *) * (sqlDistributionListLen - i));
                   1726:     }
                   1727: 
1.45      veillard 1728:     sqlDistributionList[distribution] = xmlStrdup(name);
1.36      veillard 1729:     return(sqlDistributionList[distribution]);
                   1730: }
                   1731: 
                   1732: void
                   1733: sqlInitSqlDistributionList(void) {
                   1734:     MYSQL_RES *result;
                   1735:     MYSQL_ROW row;
                   1736:     char *query;
                   1737:     int i;
                   1738: 
                   1739:     if (sqlDistributionListInitialized != 0)
                   1740:        return;
                   1741: 
1.45      veillard 1742: #ifdef SQL_DEBUG_MEM
                   1743:     printf("sqlInitSqlDistributionList\n");
                   1744: #endif
1.36      veillard 1745:     if (rpm2htmlVerbose)
                   1746:        printf("sqlInitSqlDistributionList query\n");
                   1747: 
                   1748:     /*
                   1749:      * Allocate the array
                   1750:      */
                   1751:     sqlDistributionListLen = 100;
1.45      veillard 1752:     sqlDistributionList = (char **) xmlMalloc((sqlDistributionListLen) * sizeof(char *));
1.36      veillard 1753:     if (sqlDistributionList == NULL) {
                   1754:        fprintf(stderr, "sqlInitSqlDistributionList Error: out of memory\n");
                   1755:        return;
                   1756:     }
1.40      veillard 1757:     memset(sqlDistributionList, 0, (sqlDistributionListLen) * sizeof(char *));
                   1758: 
1.36      veillard 1759:     /*
                   1760:      * query the database for the values
                   1761:      */
                   1762:     query = "select ID,Name from Distributions";
                   1763: 
                   1764:     if (mysql_query(sql,query)) {
                   1765:        printf("sqlInitSqlDistributionList: SELECT from Distributions failed: %s\n",
                   1766:               mysql_error(sql));
                   1767:        return;
                   1768:     }
                   1769: 
                   1770:     i = 0;
                   1771:     result = mysql_use_result(sql);
                   1772:     if (result) {
                   1773:        while((row = mysql_fetch_row(result)))
                   1774:        {
                   1775:            if (sqlRpmAnalyzeDistributionRow(row) != NULL)
                   1776:                i++;
                   1777:        }
                   1778:        mysql_free_result(result);
                   1779:     }
                   1780:     if(mysql_errno(sql)) {
                   1781:        fprintf(stderr, "sqlInitSqlDistributionList Error: %s\n", mysql_error(sql));
                   1782:        return;
                   1783:     }
                   1784: 
                   1785: 
                   1786:     if (rpm2htmlVerbose)
                   1787:        printf("sqlInitSqlDistributionList done: %d entries\n", i);
                   1788:     sqlDistributionListInitialized++;
                   1789:     return;
                   1790: }
                   1791: 
1.35      veillard 1792: 
                   1793: char *
                   1794: sqlRpmAnalyzeVendorRow(MYSQL_ROW row) {
                   1795:     const char *id;
                   1796:     const char *name;
                   1797:     char **tmp;
                   1798:     int vendor;
                   1799: 
                   1800:     if (row == NULL)
                   1801:        return(NULL);
                   1802:     id = row[0];
                   1803:     name = row[1];
                   1804:     if ((id == NULL) || (name == NULL))
                   1805:        return(NULL);
                   1806: 
                   1807:     if (sscanf(id, "%d", &vendor) != 1)
                   1808:        return(NULL);
                   1809:     if ((vendor <= 0) || (vendor > 100000)) {
                   1810:        fprintf(stderr, "Dist number out of range %d\n", vendor);
                   1811:        return(NULL);
                   1812:     }
                   1813:     if (vendor >= sqlVendorListLen) {
                   1814:        int i = sqlVendorListLen;
                   1815:        sqlVendorListLen = vendor + 100;
1.45      veillard 1816:        tmp = (char **) xmlRealloc(sqlVendorList,
1.35      veillard 1817:                                     (sqlVendorListLen) * sizeof(char *));
                   1818:        if (sqlVendorList == NULL) {
                   1819:            fprintf(stderr, "sqlInitSqlVendorList Error: out of memory\n");
                   1820:            return(NULL);
                   1821:        }
                   1822:        sqlVendorList = tmp;
                   1823:        memset(&sqlVendorList[i], 0, sizeof(char *) * (sqlVendorListLen - i));
                   1824:     }
                   1825: 
1.45      veillard 1826:     sqlVendorList[vendor] = xmlStrdup(name);
1.35      veillard 1827:     return(sqlVendorList[vendor]);
                   1828: }
                   1829: 
                   1830: void
                   1831: sqlInitSqlVendorList(void) {
                   1832:     MYSQL_RES *result;
                   1833:     MYSQL_ROW row;
                   1834:     char *query;
                   1835:     int i;
                   1836: 
                   1837:     if (sqlVendorListInitialized != 0)
                   1838:        return;
                   1839: 
1.45      veillard 1840: #ifdef SQL_DEBUG_MEM
                   1841:     printf("sqlInitSqlVendorList\n");
                   1842: #endif
1.35      veillard 1843:     if (rpm2htmlVerbose)
                   1844:        printf("sqlInitSqlVendorList query\n");
                   1845: 
                   1846:     /*
                   1847:      * Allocate the array
                   1848:      */
                   1849:     sqlVendorListLen = 100;
1.45      veillard 1850:     sqlVendorList = (char **) xmlMalloc((sqlVendorListLen) * sizeof(char *));
1.35      veillard 1851:     if (sqlVendorList == NULL) {
                   1852:        fprintf(stderr, "sqlInitSqlVendorList Error: out of memory\n");
                   1853:        return;
                   1854:     }
                   1855:     
                   1856:     /*
                   1857:      * query the database for the values
                   1858:      */
                   1859:     query = "select ID,Name from Vendors";
                   1860: 
                   1861:     if (mysql_query(sql,query)) {
1.36      veillard 1862:        printf("sqlInitSqlVendorList: SELECT from Vendors failed: %s\n",
1.35      veillard 1863:               mysql_error(sql));
                   1864:        return;
                   1865:     }
                   1866: 
                   1867:     i = 0;
                   1868:     result = mysql_use_result(sql);
                   1869:     if (result) {
                   1870:        while((row = mysql_fetch_row(result)))
                   1871:        {
                   1872:            if (sqlRpmAnalyzeVendorRow(row) != NULL)
                   1873:                i++;
                   1874:        }
                   1875:        mysql_free_result(result);
                   1876:     }
                   1877:     if(mysql_errno(sql)) {
                   1878:        fprintf(stderr, "sqlInitSqlVendorList Error: %s\n", mysql_error(sql));
                   1879:        return;
                   1880:     }
                   1881: 
                   1882: 
                   1883:     if (rpm2htmlVerbose)
                   1884:        printf("sqlInitSqlVendorList done: %d entries\n", i);
                   1885:     sqlVendorListInitialized++;
                   1886:     return;
                   1887: }
1.26      veillard 1888: 
                   1889: rpmDirPtr
                   1890: sqlRpmAnalyzeDirRow(MYSQL_ROW row) {
                   1891:     rpmDirPtr ret;
                   1892:     const char *id;
                   1893:     const char *name;
                   1894:     const char *vendor;
                   1895:     const char *directory;
                   1896:     const char *path;
                   1897:     const char *url;
                   1898:     const char *urlSrc;
                   1899:     const char *html;
                   1900:     const char *color;
                   1901:     int dist;
                   1902: 
                   1903:     if (row == NULL)
                   1904:        return(NULL);
                   1905:     id = row[0];
                   1906:     name = row[1];
                   1907:     vendor = row[2];
                   1908:     directory = row[3];
                   1909:     path = row[4];
                   1910:     url = row[5];
                   1911:     urlSrc = row[6];
                   1912:     html = row[7];
                   1913:     color = row[8];
                   1914:     if ((id == NULL) || (name == NULL) ||
                   1915:         (directory == NULL) || (path == NULL) || (url == NULL))
                   1916:        return(NULL);
                   1917: 
                   1918:     if (sscanf(id, "%d", &dist) != 1)
                   1919:        return(NULL);
                   1920:     if ((dist <= 0) || (dist > SQL_MAX_DISTRIBS)) {
                   1921:        fprintf(stderr, "Dist number out of range %d\n", dist);
                   1922:        return(NULL);
                   1923:     }
                   1924: 
                   1925: 
1.45      veillard 1926:     ret = (rpmDirPtr) xmlMalloc(sizeof(rpmDir));
1.26      veillard 1927:     if (ret == NULL)
                   1928:        return(NULL);
                   1929:     memset(ret, 0, sizeof(rpmDir));
                   1930:     /* Generic stuff */
1.28      daniel   1931:     if (rpm2html_dir != NULL)
1.45      veillard 1932:     ret->dir = xmlStrdup(rpm2html_dir);
1.28      daniel   1933:     if (rpm2html_host != NULL)
1.45      veillard 1934:     ret->host = xmlStrdup(rpm2html_host);
1.28      daniel   1935:     if (rpm2html_maint != NULL)
1.45      veillard 1936:     ret->maint = xmlStrdup(rpm2html_maint);
1.28      daniel   1937:     if (rpm2html_mail != NULL)
1.45      veillard 1938:     ret->mail = xmlStrdup(rpm2html_mail);
1.28      daniel   1939:     if (rpm2html_url != NULL)
1.45      veillard 1940:     ret->url = xmlStrdup(rpm2html_url);
1.26      veillard 1941:     /* specific stuff */
                   1942:     ret->no = dist;
1.45      veillard 1943:     ret->rpmdir = xmlStrdup(directory);
                   1944:     ret->subdir = xmlStrdup(path);
                   1945:     ret->name = xmlStrdup(name);
                   1946:     ret->ftp = xmlStrdup(url);
1.26      veillard 1947:     if (color != NULL)
1.45      veillard 1948:        ret->color = xmlStrdup(color);
1.28      daniel   1949:     else
1.45      veillard 1950:        ret->color = xmlStrdup("#ffffff");
1.26      veillard 1951:     if (urlSrc != NULL)
1.45      veillard 1952:        ret->ftpsrc = xmlStrdup(urlSrc);
1.26      veillard 1953:     return(ret);
                   1954: }
                   1955: 
                   1956: void
                   1957: sqlInitSqlDirList(void) {
1.28      daniel   1958:     char host[200];
1.26      veillard 1959:     rpmDirPtr cur;
                   1960:     MYSQL_RES *result;
                   1961:     MYSQL_ROW row;
                   1962:     char *query;
                   1963:     int i;
                   1964: 
                   1965:     if (sqlDirListInitialized != 0)
                   1966:        return;
                   1967: 
1.45      veillard 1968: #ifdef SQL_DEBUG_MEM
                   1969:     printf("sqlInitSqlDirList\n");
                   1970: #endif
1.28      daniel   1971:     gethostname(host, sizeof(host));
                   1972:     currentTime = time(NULL);
                   1973:     rpm2html_rpm2html_thishost = &host[0];
                   1974:     readConfigSql();
                   1975:     if (rpm2html_host == NULL) {
                   1976:        rpm2html_host = strdup(rpm2html_rpm2html_thishost);
                   1977:     }
1.26      veillard 1978:     for (i = 0; i < SQL_MAX_DISTRIBS;i++)
                   1979:         sqlDirList[i] = NULL;
                   1980: 
                   1981:     if (rpm2htmlVerbose)
                   1982:        printf("sqlInitSqlDirList query\n");
                   1983: 
1.29      veillard 1984:     query = "select ID,Name,Vendor,Directory,Path,URL,URLSrc,Html,Color from Distribs";
1.26      veillard 1985: 
                   1986:     if (mysql_query(sql,query)) {
                   1987:        printf("sqlInitSqlDirList: SELECT from Packages failed: %s\n",
                   1988:               mysql_error(sql));
                   1989:        return;
                   1990:     }
                   1991: 
                   1992:     i = 0;
                   1993:     result = mysql_use_result(sql);
                   1994:     if (result) {
                   1995:        while((row = mysql_fetch_row(result)))
                   1996:        {
                   1997:            cur = sqlRpmAnalyzeDirRow(row);
                   1998:            if (cur != NULL) {
                   1999:                sqlDirList[cur->no] = cur;
                   2000:                i++;
                   2001:            }
                   2002:        }
                   2003:        mysql_free_result(result);
                   2004:     }
                   2005:     if(mysql_errno(sql)) {
                   2006:        fprintf(stderr, "sqlInitSqlDirList Error: %s\n", mysql_error(sql));
                   2007:        return;
                   2008:     }
                   2009: 
                   2010:     if (rpm2htmlVerbose)
                   2011:        printf("sqlInitSqlDirList done: %d entries\n", i);
                   2012:     sqlDirListInitialized++;
                   2013:     return;
                   2014: }
                   2015: 
                   2016: rpmDataPtr
                   2017: sqlRpmAnalyzeRow(MYSQL_ROW row) {
                   2018:     rpmDataPtr ret;
                   2019:     const char *id;
                   2020:     const char *name;
                   2021:     const char *version;
                   2022:     const char *release;
                   2023:     const char *arch;
                   2024:     const char *date;
                   2025:     const char *summary;
                   2026:     const char *filename;
                   2027:     const char *distrib;
1.30      daniel   2028:     const char *group;
1.33      veillard 2029:     const char *os;
1.35      veillard 2030:     const char *packager;
1.36      veillard 2031:     const char *vendor;
1.26      veillard 2032:     int dist;
                   2033: 
                   2034:     if (row == NULL)
                   2035:        return(NULL);
                   2036:     id = row[0];
                   2037:     name = row[1];
                   2038:     version = row[2];
                   2039:     release = row[3];
                   2040:     arch = row[4];
                   2041:     date = row[5];
                   2042:     summary = row[6];
                   2043:     filename = row[7];
                   2044:     distrib = row[8];
1.30      daniel   2045:     group = row[9];
1.33      veillard 2046:     os = row[10];
1.35      veillard 2047:     packager = row[11];
1.36      veillard 2048:     vendor = row[12];
1.26      veillard 2049:     if ((id == NULL) || (name == NULL) || (version == NULL) ||
                   2050:         (release == NULL) || (arch == NULL) || (date == NULL) ||
                   2051:        (summary == NULL) || (filename == NULL) || (distrib == NULL))
                   2052:        return(NULL);
                   2053: 
1.45      veillard 2054:     ret = (rpmDataPtr) xmlMalloc(sizeof(rpmData));
1.26      veillard 2055:     if (ret == NULL)
                   2056:        return(NULL);
                   2057:     memset(ret, 0, sizeof(rpmData));
1.45      veillard 2058:     ret->name = xmlStrdup(name);
                   2059:     ret->version = xmlStrdup(version);
                   2060:     ret->release = xmlStrdup(release);
                   2061:     ret->arch = xmlStrdup(arch);
                   2062:     ret->summary = xmlStrdup(summary);
                   2063:     ret->name = xmlStrdup(name);
                   2064:     ret->filename = xmlStrdup(filename);
1.33      veillard 2065:     if (os == NULL)
1.45      veillard 2066:        ret->os = xmlStrdup("Linux");
1.33      veillard 2067:     else
1.45      veillard 2068:        ret->os = xmlStrdup(os);
1.30      daniel   2069:     if (group != NULL)
1.45      veillard 2070:        ret->group = xmlStrdup(group);
1.26      veillard 2071:     sscanf(date, "%d", (int *) &(ret->date));
1.35      veillard 2072:     if (packager != NULL) {
                   2073:        int tmp = 0;
                   2074:        sscanf(packager, "%d", (int *) &tmp);
                   2075:        if ((tmp > 0) && (tmp < sqlVendorListLen)) {
                   2076:            if (sqlVendorList[tmp] != NULL)
1.45      veillard 2077:                ret->vendor = xmlStrdup(sqlVendorList[tmp]);
1.35      veillard 2078:        }
                   2079:     }
1.36      veillard 2080:     if (vendor != NULL) {
                   2081:        int tmp = 0;
                   2082:        sscanf(vendor, "%d", (int *) &tmp);
                   2083:        if ((tmp > 0) && (tmp < sqlDistributionListLen)) {
                   2084:            if (sqlVendorList[tmp] != NULL)
1.45      veillard 2085:                ret->distribution = xmlStrdup(sqlDistributionList[tmp]);
1.36      veillard 2086:        }
                   2087:     }
1.35      veillard 2088:     if (ret->vendor == NULL)
1.45      veillard 2089:        ret->vendor =  xmlStrdup("Unknown");
1.35      veillard 2090:     if (ret->distribution == NULL)
1.45      veillard 2091:        ret->distribution =  xmlStrdup("Unknown");
1.26      veillard 2092:     sscanf(distrib, "%d", &dist);
                   2093:     ret->dir = sqlDirList[dist];
1.28      daniel   2094:     if ((ret->dir != NULL) && (ret->dir->rpmdir != NULL)) {
                   2095:        int len = strlen(ret->dir->rpmdir);
                   2096:        if (!strncmp(ret->filename, ret->dir->rpmdir, len)) {
                   2097:            char *start, *end;
                   2098:            start = &(ret->filename[len]);
                   2099:            while (*start == '/') start++;
                   2100:            end = &start[strlen(start) - 1];
                   2101:            while ((end >= start) && (*end != '/')) end--;
                   2102:             if (end > start) {
                   2103:                char *tmp;
1.45      veillard 2104:                tmp = xmlMalloc((end - start) + 1);
1.28      daniel   2105:                if (tmp != NULL) {
                   2106:                    strncpy(tmp, start, end - start);
                   2107:                    tmp[end - start] = 0;
                   2108:                    ret->subdir = tmp;
                   2109:                }
                   2110:            }
                   2111:        }
                   2112:     }
1.26      veillard 2113:     return(ret);
                   2114: }
                   2115: 
                   2116: rpmDataPtr
                   2117: sqlRpmByDate(void) {
                   2118:     rpmDataPtr list = NULL;
                   2119:     rpmDataPtr cur, last = NULL;
                   2120:     MYSQL_RES *result;
                   2121:     MYSQL_ROW row;
                   2122:     char *query;
                   2123: 
                   2124:     sqlInitSqlDirList();
1.35      veillard 2125:     sqlInitSqlVendorList();
1.36      veillard 2126:     sqlInitSqlDistributionList();
1.26      veillard 2127:     if (rpm2htmlVerbose)
                   2128:        printf("sqlRpmByDate query\n");
                   2129: 
1.35      veillard 2130:     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 2131: 
                   2132:     /*
                   2133:      * Search first for the ID if it already exists
                   2134:      */
                   2135:     if (mysql_query(sql,query)) {
                   2136:        printf("sqlRpmByDate: SELECT from Packages failed: %s\n",
                   2137:               mysql_error(sql));
                   2138:        return(NULL);
                   2139:     }
                   2140: 
                   2141:     result = mysql_use_result(sql);
                   2142:     if (result) {
                   2143:        while((row = mysql_fetch_row(result)))
                   2144:        {
                   2145:            cur = sqlRpmAnalyzeRow(row);
                   2146:            if (cur != NULL) {
                   2147:                if (last == NULL)
                   2148:                    list = cur;
                   2149:                else
                   2150:                    last->next = cur;
                   2151:                last = cur;
                   2152:            }
                   2153:        }
                   2154:        mysql_free_result(result);
                   2155:     }
                   2156:     if(mysql_errno(sql)) {
                   2157:        fprintf(stderr, "sqlRpmByDate Error: %s\n", mysql_error(sql));
                   2158:        return(NULL);
                   2159:     }
                   2160: 
                   2161:     if (rpm2htmlVerbose)
                   2162:        printf("sqlRpmByDate done\n");
                   2163:     return(list);
                   2164: }
                   2165: 
1.53    ! veillard 2166: void 
        !          2167: sql_top_index(void) {
        !          2168:     sqlInitSqlDirList();
        !          2169:     dumpTopIndex(time(NULL), 0);
        !          2170: }
        !          2171: 
1.29      veillard 2172: rpmDataPtr
                   2173: sqlRpmAll(void) {
                   2174:     rpmDataPtr list = NULL;
                   2175:     rpmDataPtr cur, last = NULL;
                   2176:     MYSQL_RES *result;
                   2177:     MYSQL_ROW row;
                   2178:     char *query;
                   2179: 
                   2180:     sqlInitSqlDirList();
1.35      veillard 2181:     sqlInitSqlVendorList();
1.36      veillard 2182:     sqlInitSqlDistributionList();
1.29      veillard 2183:     if (rpm2htmlVerbose)
                   2184:        printf("sqlRpmAll query\n");
1.53    ! veillard 2185: 
        !          2186:     dumpTopIndex();
1.29      veillard 2187: 
1.35      veillard 2188:     query = "select ID,Name,Version,Release,Arch,Date,Summary,filename,Dist,Category,Os,Packager,Vendor from Packages";
1.29      veillard 2189: 
                   2190:     /*
                   2191:      * Search first for the ID if it already exists
                   2192:      */
                   2193:     if (mysql_query(sql,query)) {
                   2194:        printf("sqlRpmByDate: SELECT from Packages failed: %s\n",
                   2195:               mysql_error(sql));
                   2196:        return(NULL);
                   2197:     }
                   2198: 
                   2199:     result = mysql_use_result(sql);
                   2200:     if (result) {
                   2201:        while((row = mysql_fetch_row(result)))
                   2202:        {
                   2203:            cur = sqlRpmAnalyzeRow(row);
                   2204:            if (cur != NULL) {
                   2205:                if (last == NULL)
                   2206:                    list = cur;
                   2207:                else
                   2208:                    last->next = cur;
                   2209:                last = cur;
1.32      daniel   2210: 
                   2211:                rpmAddSoftware(cur);
1.29      veillard 2212:            }
                   2213:        }
                   2214:        mysql_free_result(result);
                   2215:     }
                   2216:     if(mysql_errno(sql)) {
                   2217:        fprintf(stderr, "sqlRpmByDate Error: %s\n", mysql_error(sql));
                   2218:        return(NULL);
                   2219:     }
                   2220: 
                   2221:     if (rpm2htmlVerbose)
                   2222:        printf("sqlRpmAll done\n");
                   2223:     return(list);
                   2224: }
                   2225: 
1.45      veillard 2226: void sqlListsCleanup(void) {
                   2227:     int i;
                   2228: 
                   2229: #ifdef SQL_DEBUG_MEM
                   2230:     printf("sqlListsCleanup\n");
                   2231: #endif
                   2232:     if (sqlDirListInitialized) {
                   2233: #ifdef SQL_DEBUG_MEM
                   2234:        printf("sqlListsCleanup: freeing sqlDirList\n");
                   2235: #endif
                   2236:        for (i = 0 ; i < SQL_MAX_DISTRIBS; i++) {
                   2237:            if (sqlDirList[i] != NULL)
                   2238:                rpmDirFree(sqlDirList[i]);
                   2239:            sqlDirList[i] = NULL;
                   2240:        }
                   2241:        sqlDirListInitialized = 0;
                   2242:     }
                   2243:     if (sqlVendorListInitialized) {
                   2244: #ifdef SQL_DEBUG_MEM
                   2245:        printf("sqlListsCleanup: freeing sqlVendorList\n");
                   2246: #endif
                   2247:        for (i = 0 ; i < sqlVendorListLen;i++) {
                   2248:            if (sqlVendorList[i] != NULL)
                   2249:                xmlFree(sqlVendorList[i]);
                   2250:            sqlVendorList[i] = NULL;
                   2251:        }
                   2252:        xmlFree(sqlVendorList);
                   2253:        sqlVendorListInitialized = 0;
                   2254:     }
                   2255:     if (sqlDistributionListInitialized) {
                   2256: #ifdef SQL_DEBUG_MEM
                   2257:        printf("sqlListsCleanup: freeing sqlDistributionList\n");
                   2258: #endif
                   2259:        for (i = 0 ; i < sqlDistributionListLen;i++) {
                   2260:            if (sqlDistributionList[i] != NULL)
                   2261:                xmlFree(sqlDistributionList[i]);
                   2262:            sqlDistributionList[i] = NULL;
                   2263:        }
                   2264:        xmlFree(sqlDistributionList);
                   2265:        sqlDistributionListInitialized = 0;
                   2266:     }
                   2267:     if (sqlResourceListInitialized) {
                   2268: #ifdef SQL_DEBUG_MEM
                   2269:        printf("sqlListsCleanup: freeing sqlResourceList\n");
                   2270: #endif
                   2271:        for (i = 0 ; i < sqlResourceListLen;i++) {
                   2272:            if (sqlResourceList[i] != NULL)
                   2273:                xmlFree(sqlResourceList[i]);
                   2274:            sqlResourceList[i] = NULL;
                   2275:        }
                   2276:        xmlFree(sqlResourceList);
                   2277:        sqlResourceListInitialized = 0;
                   2278:     }
                   2279: }
                   2280: 
1.26      veillard 2281: /************************************************************************
1.8       veillard 2282:  *                                                                     *
1.6       veillard 2283:  *                     Export functions                                *
                   2284:  *                                                                     *
                   2285:  ************************************************************************/
                   2286: 
1.45      veillard 2287: void sql_dump_rdf_full_index(void) {
                   2288:     MYSQL_RES *result;
                   2289:     MYSQL_ROW row;
                   2290:     char query[SMALL_QUERY];
                   2291:     gzFile rdf;
                   2292:     char *filename;
                   2293:     char *dist;
                   2294:     char *name;
                   2295:     char *version;
                   2296:     char *release;
                   2297:     char *arch;
                   2298:     char *summary;
                   2299:     char *subdir;
                   2300:     char *psubdir;
                   2301:     char *rpmdir;
                   2302:     char *start, *end;
                   2303:     int distrib;
                   2304:     int len;
                   2305:     char path[500];
                   2306: 
                   2307:     if (!rpm2html_dump_rdf_resources)
                   2308:        return;
                   2309:     if (!rpm2html_rdf_resources_dir)
                   2310:        return;
                   2311:     if ((rpm2html_host == NULL) || (rpm2html_url == NULL))
                   2312:        return;
                   2313: 
                   2314:     /*
                   2315:      * Open the RDF resource descritpion.
                   2316:      */
                   2317:     mkdir(rpm2html_rdf_resources_dir, 0755);
                   2318:     snprintf(path, 500, "%s/fullIndex.rdf.gz",
                   2319:             rpm2html_rdf_resources_dir);
                   2320:     path[499] = 0;
                   2321:     rdf = gzopen(path, "w9");
                   2322:     if (rdf == NULL) {
                   2323:        fprintf(stderr, "unable to write to %s\n", path);
                   2324:        return;
                   2325:     }
                   2326:     gzprintf(rdf, "<?xml version=\"1.0\"?>\n");
                   2327:     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");
                   2328: 
                   2329:     /*
                   2330:      * Query the database for the informations providing the resource.
                   2331:      */
                   2332:     snprintf(query, SMALL_QUERY,
                   2333:        "select filename,Dist,Name,Version,Release,Arch,Summary from Packages");
                   2334:     query[SMALL_QUERY - 1] = 0;
                   2335:     if (mysql_query(sql, query)) {
                   2336:        printf("sql_dump_rdf_full_index: SELECT from Packages failed: %s\n",
                   2337:               mysql_error(sql));
                   2338:         gzprintf(rdf, "</rdf:RDF>\n");
                   2339:        fclose(rdf);
                   2340:        return;
                   2341:     }
                   2342:     result = mysql_use_result(sql);
                   2343:     if (result == NULL) {
                   2344:        printf("sql_dump_rdf_full_index: SELECT from Packages failed: %s\n",
                   2345:               mysql_error(sql));
                   2346:         gzprintf(rdf, "</rdf:RDF>\n");
                   2347:        fclose(rdf);
                   2348:        return;
                   2349:     }
                   2350:     while((row = mysql_fetch_row(result))) {
                   2351:        filename = row[0];
                   2352:        dist = row[1];
                   2353:        name = row[2];
                   2354:        version = row[3];
                   2355:        release = row[4];
                   2356:        arch = row[5];
                   2357:        summary = row[6];
                   2358:        if ((filename == NULL) || (dist == NULL) || (name == NULL) ||
                   2359:            (summary == NULL)) {
                   2360:            continue;
                   2361:        }
                   2362:        if (!strncmp(filename, "localbase", 9))
                   2363:            continue;
                   2364:        if (sscanf(dist, "%d", &distrib) != 1)
                   2365:            continue;
                   2366:        if ((distrib < 1) || (distrib >= SQL_MAX_DISTRIBS) ||
                   2367:            (sqlDirList[distrib] == NULL))
                   2368:            continue;
                   2369: 
                   2370:        subdir = sqlDirList[distrib]->subdir;
                   2371:        rpmdir = sqlDirList[distrib]->rpmdir;
                   2372:        len = strlen(rpmdir);
                   2373:        if (strncmp(filename, rpmdir, len)) {
                   2374:            fprintf(stderr, "%s out of subdir %s\n", filename, subdir);
                   2375:            continue;
                   2376:        }
                   2377:        start = &(filename[len]);
                   2378:        while (*start == '/') start++;
                   2379:        end = &start[strlen(start) - 1];
                   2380:        while ((end >= start) && (*end != '/')) end--;
                   2381:        if (end <= start) {
                   2382:            psubdir = xmlStrdup("");
                   2383:        } else {
                   2384:            psubdir = xmlMalloc((end - start) + 1);
                   2385:            if (psubdir == NULL) {
                   2386:                fprintf(stderr, "Out of memory\n");
                   2387:                continue;
                   2388:            }
                   2389:            strncpy(psubdir, start, end - start);
                   2390:            psubdir[end - start] = 0;
                   2391:        }
                   2392:         gzprintf(rdf, "  <rdf:Description about=\"%s/%s/%s-%s-%s.%s.rpm\">\n",
                   2393:                sqlDirList[distrib]->ftp,psubdir,name,version,release,arch);
                   2394:        gzprintf(rdf, "    <RPM:Name>%s</RPM:Name>\n", name);
1.46      veillard 2395:        gzprintf(rdf, "    <RPM:Summary>%s</RPM:Summary>\n", 
                   2396:                 convertXML(summary));
1.45      veillard 2397:        gzprintf(rdf, "  </rdf:Description>\n");
                   2398:        xmlFree(psubdir);
                   2399:     }
                   2400:     gzprintf(rdf, "</rdf:RDF>\n");
                   2401:     gzclose(rdf);
                   2402:     mysql_free_result(result);
                   2403:     if(mysql_errno(sql)) {
                   2404:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2405:     }
                   2406: }
                   2407: 
                   2408: 
1.41      veillard 2409: void sql_dump_rdf(const char *resource) {
                   2410:     MYSQL_RES *result;
                   2411:     MYSQL_ROW row;
                   2412:     char query[SMALL_QUERY];
                   2413:     FILE *rdf;
                   2414:     char *filename;
                   2415:     char *dist;
                   2416:     char *name;
                   2417:     char *version;
                   2418:     char *release;
                   2419:     char *arch;
                   2420:     char *os;
                   2421:     char *packager;
                   2422:     char *date;
                   2423:     char *size;
1.44      daniel   2424:     char *vendorstr;
1.41      veillard 2425:     char *subdir;
1.42      veillard 2426:     char *psubdir;
                   2427:     char *rpmdir;
                   2428:     char *start, *end;
1.41      veillard 2429:     int distrib;
1.42      veillard 2430:     int vendor;
1.44      daniel   2431:     int person;
1.42      veillard 2432:     int len;
                   2433:     char path[500];
1.41      veillard 2434: 
                   2435:     if (resource == NULL)
                   2436:        return;
1.44      daniel   2437:     if (resource[0] == '/')
                   2438:        return;
1.41      veillard 2439:     if (!rpm2html_dump_rdf_resources)
                   2440:        return;
1.42      veillard 2441:     if (!rpm2html_rdf_resources_dir)
                   2442:        return;
1.41      veillard 2443:     if ((rpm2html_host == NULL) || (rpm2html_url == NULL))
                   2444:        return;
                   2445: 
1.42      veillard 2446:     /*
                   2447:      * Open the RDF resource descritpion.
                   2448:      */
                   2449:     mkdir(rpm2html_rdf_resources_dir, 0755);
                   2450:     snprintf(path, 500, "%s/%s.rdf",
                   2451:             rpm2html_rdf_resources_dir, resource);
                   2452:     path[499] = 0;
                   2453:     rdf = fopen(path, "w");
                   2454:     if (rdf == NULL) {
                   2455:        fprintf(stderr, "unable to write to %s\n", path);
                   2456:        return;
                   2457:     }
                   2458:     fprintf(rdf, "<?xml version=\"1.0\"?>\n");
                   2459:     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");
                   2460: 
                   2461:     /*
                   2462:      * Query the database for the informations providing the resource.
                   2463:      */
1.41      veillard 2464:     snprintf(query, SMALL_QUERY,
1.44      daniel   2465: "select filename,Dist,Name,Version,Release,Arch,Os,Packager,Date,Size,Vendor from Packages where Name=\"%s\"",
1.41      veillard 2466:              resource);
                   2467:     query[SMALL_QUERY - 1] = 0;
                   2468:     if (mysql_query(sql, query)) {
                   2469:        printf("sql_dump_rdf: SELECT from Packages failed: %s\n",
                   2470:               mysql_error(sql));
1.42      veillard 2471:         fprintf(rdf, "</rdf:RDF>\n");
                   2472:        fclose(rdf);
1.41      veillard 2473:        return;
                   2474:     }
                   2475:     result = mysql_use_result(sql);
                   2476:     if (result == NULL) {
                   2477:        printf("sql_dump_rdf: SELECT from Packages failed: %s\n",
                   2478:               mysql_error(sql));
1.42      veillard 2479:         fprintf(rdf, "</rdf:RDF>\n");
                   2480:        fclose(rdf);
1.41      veillard 2481:        return;
                   2482:     }
                   2483:     while((row = mysql_fetch_row(result))) {
                   2484:        filename = row[0];
                   2485:        dist = row[1];
                   2486:        name = row[2];
                   2487:        version = row[3];
                   2488:        release = row[4];
                   2489:        arch = row[5];
                   2490:        os = row[6];
                   2491:        packager = row[7];
                   2492:        date = row[8];
                   2493:        size = row[9];
1.44      daniel   2494:        vendorstr = row[10];
1.41      veillard 2495:        if ((filename == NULL) || (dist == NULL) || (name == NULL) ||
                   2496:            (version == NULL) || (release == NULL) || (arch == NULL) ||
1.44      daniel   2497:            (os == NULL) || (date == NULL) || (vendorstr == NULL) ||
1.41      veillard 2498:            (size == NULL)) {
                   2499:            continue;
                   2500:        }
1.42      veillard 2501:        if (!strncmp(filename, "localbase", 9))
                   2502:            continue;
1.41      veillard 2503:        if (sscanf(dist, "%d", &distrib) != 1)
                   2504:            continue;
1.44      daniel   2505:        if ((distrib < 1) || (distrib >= SQL_MAX_DISTRIBS) ||
                   2506:            (sqlDirList[distrib] == NULL))
1.42      veillard 2507:            continue;
1.44      daniel   2508:        if (vendorstr != NULL) {
                   2509:            if (sscanf(vendorstr, "%d", &vendor) != 1)
1.42      veillard 2510:                continue;
                   2511:        }
                   2512:        if ((vendor < 1) || (vendor >= sqlDistributionListLen) ||
                   2513:            (sqlDistributionList[vendor] == NULL))
1.41      veillard 2514:            continue;
1.44      daniel   2515:        if (packager != NULL) {
                   2516:            if (sscanf(packager, "%d", &person) != 1)
                   2517:                continue;
                   2518:        }
                   2519:        if ((person < 1) || (person >= sqlVendorListLen) ||
                   2520:            (sqlVendorList[person] == NULL))
                   2521:            continue;
1.41      veillard 2522: 
                   2523:        subdir = sqlDirList[distrib]->subdir;
1.42      veillard 2524:        rpmdir = sqlDirList[distrib]->rpmdir;
                   2525:        len = strlen(rpmdir);
                   2526:        if (strncmp(filename, rpmdir, len)) {
                   2527:            fprintf(stderr, "%s out of subdir %s\n", filename, subdir);
                   2528:            continue;
                   2529:        }
                   2530:        start = &(filename[len]);
                   2531:        while (*start == '/') start++;
                   2532:        end = &start[strlen(start) - 1];
                   2533:        while ((end >= start) && (*end != '/')) end--;
                   2534:        if (end <= start) {
1.45      veillard 2535:            psubdir = xmlStrdup("");
1.42      veillard 2536:        } else {
1.45      veillard 2537:            psubdir = xmlMalloc((end - start) + 1);
1.42      veillard 2538:            if (psubdir == NULL) {
                   2539:                fprintf(stderr, "Out of memory\n");
                   2540:                continue;
1.41      veillard 2541:            }
1.42      veillard 2542:            strncpy(psubdir, start, end - start);
                   2543:            psubdir[end - start] = 0;
1.41      veillard 2544:        }
1.42      veillard 2545:         fprintf(rdf, "  <rdf:Description about=\"%s/%s/%s-%s-%s.%s.rpm\" ",
                   2546:                sqlDirList[distrib]->ftp,psubdir,name,version,release,arch);
                   2547:        fprintf(rdf, "href=\"../%s/%s/%s-%s-%s.%s.rdf\">\n",
                   2548:                subdir,psubdir,name,version,release,arch);
                   2549:        fprintf(rdf, "    <RPM:Name>%s</RPM:Name>\n", name);
                   2550:        fprintf(rdf, "    <RPM:Version>%s</RPM:Version>\n", version);
                   2551:        fprintf(rdf, "    <RPM:Release>%s</RPM:Release>\n", release);
                   2552:        fprintf(rdf, "    <RPM:Arch>%s</RPM:Arch>\n", arch);
                   2553:        fprintf(rdf, "    <RPM:Os>%s</RPM:Os>\n", os);
                   2554:        if (packager == NULL)
                   2555:            fprintf(rdf, "    <RPM:Distribution>Unknown</RPM:Distribution>\n");
                   2556:        else
                   2557:            fprintf(rdf, "    <RPM:Distribution>%s</RPM:Distribution>\n",
1.48      daniel   2558:                    convertXML(sqlDistributionList[vendor]));
1.42      veillard 2559:        fprintf(rdf, "    <RPM:Vendor>%s</RPM:Vendor>\n",
1.48      daniel   2560:            convertXML(sqlVendorList[person]));
1.42      veillard 2561:        fprintf(rdf, "    <RPM:Date>%s</RPM:Date>\n", date);
                   2562:        fprintf(rdf, "    <RPM:Size>%s</RPM:Size>\n", size);
                   2563:        fprintf(rdf, "    <RPM:Subdir>%s</RPM:Subdir>\n", subdir);
                   2564:        fprintf(rdf, "  </rdf:Description>\n");
1.45      veillard 2565:        xmlFree(psubdir);
1.41      veillard 2566:     }
1.42      veillard 2567:     fprintf(rdf, "</rdf:RDF>\n");
                   2568:     fclose(rdf);
1.45      veillard 2569:     mysql_free_result(result);
                   2570:     if(mysql_errno(sql)) {
                   2571:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2572:     }
1.41      veillard 2573: }
                   2574: 
1.6       veillard 2575: void sql_show_config(void) {
                   2576:     MYSQL_RES *result;
                   2577:     MYSQL_ROW row;
1.8       veillard 2578:     int id, i;
                   2579:     int index = 0;
                   2580:     int ids[500];
                   2581:     char query[SMALL_QUERY];
1.6       veillard 2582: 
                   2583: 
1.8       veillard 2584:     printf(";\n; Configuration file for rpm2html\n");
                   2585:     printf("; http://rpmfind.net/linux/rpm2html/\n;\n\n");
                   2586:     mysql_query(sql,"SELECT Name,Value FROM Config");
1.6       veillard 2587:     result = mysql_use_result(sql);
                   2588: 
                   2589:     while((row = mysql_fetch_row(result)))
                   2590:     {
1.8       veillard 2591:        if (row[0] == NULL) {
                   2592:            printf("\n");
                   2593:        } else {
                   2594:            if (!strcmp(row[0], "maint"))
                   2595:                printf("; maintainer of the local rpm mirror\n");
                   2596:            else if (!strcmp(row[0], "mail"))
                   2597:                printf("; mail for the maintainer\n");
                   2598:            else if (!strcmp(row[0], "dir"))
                   2599:                 printf("; Directory to store the HTML pages produced\n");
                   2600:            else if (!strcmp(row[0], "url"))
                   2601:                 printf("; The relative URL for front pages\n");
                   2602:            else if (!strcmp(row[0], "header"))
                   2603:                 printf("; Extra link in the navigation bar\n");
                   2604:            else if (!strcmp(row[0], "html"))
                   2605:                 printf("; Export the local packages in HTML format\n");
                   2606:            else if (!strcmp(row[0], "tree"))
                   2607:                 printf("; Build the tree for the distributions\n");
                   2608:            else if (!strcmp(row[0], "rdf"))
                   2609:                 printf("; Export the local packages in RDF format\n");
                   2610:            else if (!strcmp(row[0], "rdf_dir"))
                   2611:                 printf("; Directory to store the RDf tree\n");
                   2612:            else if (!strcmp(row[0], "rdf_resources"))
                   2613:                 printf("; Compile a list of resources in RDF format\n");
                   2614:            else if (!strcmp(row[0], "rdf_resources_dir"))
                   2615:                 printf("; Directory to store the RDf resources tree\n");
                   2616: 
1.6       veillard 2617:            if (row[1] == NULL)
1.8       veillard 2618:                printf("%s\n\n", row[0]);
1.6       veillard 2619:            else
1.8       veillard 2620:                printf("%s=%s\n\n", row[0], row[1]);
                   2621:        }
                   2622:     }
                   2623:     mysql_free_result(result);
                   2624:     if(mysql_errno(sql)) {
                   2625:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2626:     }
                   2627: 
                   2628:     /*
                   2629:      * Dump the Metadata
                   2630:      */
                   2631:     printf(";\n; The metadata mirrors list\n;\n\n[metadata]\n");
                   2632:     mysql_query(sql,"SELECT URL FROM Metadata");
                   2633:     result = mysql_use_result(sql);
                   2634: 
                   2635:     while((row = mysql_fetch_row(result)))
                   2636:     {
                   2637:        if (row[0] != NULL) {
                   2638:            printf("mirror=%s\n", row[0]);
1.6       veillard 2639:        }
                   2640:     }
1.8       veillard 2641:     mysql_free_result(result);
1.6       veillard 2642:     if(mysql_errno(sql)) {
                   2643:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2644:     }
                   2645: 
1.8       veillard 2646:     /*
                   2647:      * Dump the distributions informations
                   2648:      * 1/ collect the list of IDs for the distribs
                   2649:      */
                   2650:     printf("\n\n;\n; The distribution list\n;\n\n");
                   2651:     mysql_query(sql,"SELECT ID FROM Distribs");
                   2652:     result = mysql_use_result(sql);
                   2653: 
                   2654:     while((row = mysql_fetch_row(result)))
                   2655:     {
                   2656:        if (row[0] != NULL) {
                   2657:            if (sscanf(row[0], "%d", &id) == 1) {
                   2658:                ids[index++] = id;
                   2659:            }
                   2660:        }
                   2661:     }
                   2662:     mysql_free_result(result);
                   2663: 
                   2664:     /*
                   2665:      * Dump each distribution separately.
                   2666:      */
                   2667:     for (i = 0;i < index;i++) {
                   2668: 
                   2669:        snprintf(query, SMALL_QUERY - 1,
1.10      veillard 2670:  "SELECT Directory,Name,Vendor,Path,URL,URLSrc,Description,Html,Color \
1.8       veillard 2671:                  FROM Distribs WHERE ID=%d", ids[i]);
                   2672:        query[SMALL_QUERY - 1] = 0;
                   2673:        if (mysql_query(sql,query)) {
                   2674:            printf("sql_show_config: SELECT Distrib %d failed: %s\n",
                   2675:                   ids[i], mysql_error(sql));
                   2676:            continue;
                   2677:        }
                   2678: 
                   2679:        result = mysql_use_result(sql);
                   2680:        if (result) {
                   2681:            while((row = mysql_fetch_row(result)))
                   2682:            {
                   2683:                if (row[0] == NULL)
                   2684:                    break;
                   2685:                printf("[%s]\n", row[0]);
                   2686:                if (row[1] != NULL)
                   2687:                    printf("name=%s\n", row[1]);
                   2688:                if (row[3] != NULL)
                   2689:                    printf("subdir=%s\n", row[3]);
                   2690:                if (row[4] != NULL)
                   2691:                    printf("ftp=%s\n", row[4]);
                   2692:                if (row[5] != NULL)
                   2693:                    printf("ftpsrc=%s\n", row[5]);
1.10      veillard 2694:                if (row[7] != NULL)
                   2695:                    printf("html=%s\n", row[7]);
                   2696:                if (row[8] != NULL)
                   2697:                    printf("color=%s\n", row[8]);
1.8       veillard 2698:            }
                   2699:        }
                   2700:        mysql_free_result(result);
1.12      veillard 2701: 
                   2702:        /*
                   2703:         * Extract the mirrors for this distribution.
                   2704:         */
                   2705:        snprintf(query, SMALL_QUERY - 1,
                   2706:                 "SELECT URL FROM Mirrors WHERE ID=%d", ids[i]);
                   2707:        query[SMALL_QUERY - 1] = 0;
                   2708:        if (mysql_query(sql,query)) {
                   2709:            printf("sql_show_config: SELECT Mirrors %d failed: %s\n",
                   2710:                   ids[i], mysql_error(sql));
                   2711:            printf("\n\n");
                   2712:            continue;
                   2713:        }
                   2714:        result = mysql_use_result(sql);
                   2715:        if (result) {
                   2716:            while((row = mysql_fetch_row(result)))
                   2717:            {
                   2718:                if (row[0] == NULL)
                   2719:                    continue;
                   2720:                printf("mirror=%s\n", row[0]);
                   2721:            }
                   2722:        }
                   2723:        mysql_free_result(result);
                   2724: 
1.8       veillard 2725:        printf("\n\n");
                   2726:     }
                   2727: 
                   2728:     printf(";\n; End of the configuration file for rpm2html\n;\n");
1.6       veillard 2729: }
                   2730: 
                   2731: void sql_show_metadata(void) {
                   2732:     MYSQL_RES *result;
                   2733:     MYSQL_ROW row;
                   2734: 
                   2735: 
                   2736:     mysql_query(sql,"SELECT URL FROM Metadata");
                   2737:     result = mysql_use_result(sql);
                   2738: 
                   2739:     while((row = mysql_fetch_row(result)))
                   2740:     {
                   2741:        if (row[0] == NULL)
                   2742:            printf("NULL !\n");
                   2743:        else {
                   2744:            printf("%s\n", row[0]);
                   2745:        }
                   2746:     }
                   2747:     if(mysql_errno(sql)) {
                   2748:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2749:     }
                   2750: 
                   2751: }
                   2752: 
                   2753: void sql_show_mirrors(void) {
                   2754:     MYSQL_RES *result;
                   2755:     MYSQL_ROW row;
                   2756: 
                   2757: 
                   2758:     mysql_query(sql,"SELECT URL FROM Mirrors");
                   2759:     result = mysql_use_result(sql);
                   2760: 
                   2761:     while((row = mysql_fetch_row(result)))
                   2762:     {
                   2763:        if (row[0] == NULL)
                   2764:            printf("NULL !\n");
                   2765:        else {
                   2766:            printf("%s\n", row[0]);
                   2767:        }
                   2768:     }
                   2769:     if(mysql_errno(sql)) {
                   2770:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2771:     }
                   2772: }
                   2773: 
1.5       veillard 2774: void sql_show_vendors(void) {
1.1       veillard 2775:     MYSQL_RES *result;
                   2776:     MYSQL_ROW row;
                   2777: 
                   2778: 
                   2779:     mysql_query(sql,"SELECT Name, URL FROM Vendors");
                   2780:     result = mysql_use_result(sql);
                   2781: 
                   2782:     while((row = mysql_fetch_row(result)))
                   2783:     {
                   2784:        if (row[0] == NULL)
                   2785:            printf("NULL !\n");
                   2786:        else {
                   2787:            if (row[1] == NULL)
                   2788:                printf("%s : no url\n", row[0]);
                   2789:            else
                   2790:                printf("%s : %s\n", row[0], row[1]);
                   2791:        }
                   2792:     }
                   2793:     if(mysql_errno(sql)) {
                   2794:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2795:     }
                   2796: 
                   2797: }
                   2798: 
1.5       veillard 2799: void sql_show_distribs(void) {
1.1       veillard 2800:     MYSQL_RES *result;
                   2801:     MYSQL_ROW row;
                   2802: 
                   2803: 
                   2804:     mysql_query(sql,"SELECT Name, Path, URL FROM Distribs");
                   2805:     result = mysql_use_result(sql);
                   2806: 
                   2807:     while((row = mysql_fetch_row(result)))
                   2808:     {
                   2809:        if (row[0] == NULL)
                   2810:            printf("NULL !\n");
                   2811:        else {
                   2812:            if (row[1] == NULL)
                   2813:                printf("%s : no Path\n", row[0]);
                   2814:            else {
                   2815:                if (row[2] == NULL)
                   2816:                    printf("%s : %s : no url\n", row[0], row[1]);
                   2817:                else
                   2818:                    printf("%s : %s : %s\n", row[0], row[1], row[2]);
                   2819:            }
                   2820:        }
                   2821:     }
                   2822:     if(mysql_errno(sql)) {
                   2823:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2824:     }
                   2825: 
                   2826: }
                   2827: 
1.5       veillard 2828: int sql_show_table_stats(const char *table, const char *key) {
1.6       veillard 2829:     char query[MAX_QUERY];
1.2       veillard 2830:     MYSQL_RES *result;
                   2831:     MYSQL_ROW row;
                   2832:     int res;
                   2833: 
                   2834:     /*
                   2835:      * Search first for the ID if it already exists
                   2836:      */
1.6       veillard 2837:     snprintf(query, MAX_QUERY - 1, "SELECT COUNT(%s) FROM %s", key, table);
                   2838:     query[MAX_QUERY - 1] = 0;
1.2       veillard 2839:     if (mysql_query(sql,query)) {
1.5       veillard 2840:        printf("sql_show_table_stats: SELECT COUNT failed: %s\n",
1.2       veillard 2841:               mysql_error(sql));
                   2842:        return(-1);
                   2843:     }
                   2844: 
                   2845:     result = mysql_use_result(sql);
                   2846:     if (result) {
                   2847:        while((row = mysql_fetch_row(result)))
                   2848:        {
                   2849:            /*
                   2850:             * Lookup the value and return it
                   2851:             */
                   2852:            if (row[0] == NULL) {
                   2853:                mysql_free_result(result);
1.5       veillard 2854:                printf("sql_show_table_stats: select count returns NULL !\n");
1.2       veillard 2855:                return(-1);
                   2856:            }
                   2857:            if (sscanf(row[0], "%d", &res) != 1) {
                   2858:                mysql_free_result(result);
1.5       veillard 2859:                printf("sql_show_table_stats: value non numeric %s\n", row[0]);
1.2       veillard 2860:                return(-1);
                   2861:            }
                   2862:            mysql_free_result(result);
                   2863:            if (res <= 0)
                   2864:                printf("   %s is empty\n", table);
                   2865:            else
                   2866:                printf("   %s contains %d records\n", table, res);
                   2867:            return(res);
                   2868:        }
                   2869:        mysql_free_result(result);
                   2870:     }
                   2871:     if(mysql_errno(sql)) {
1.5       veillard 2872:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.2       veillard 2873:     }
                   2874:     return(-1);
                   2875: }
                   2876: 
1.5       veillard 2877: int sql_show_stats(void) {
1.2       veillard 2878:     const char *query = "SHOW TABLES";
                   2879:     MYSQL_RES *result;
                   2880:     MYSQL_ROW row;
                   2881: 
                   2882:     int tables = 0;
                   2883:     int records = 0;
                   2884: 
                   2885:     if (mysql_query(sql,query)) {
                   2886:        printf("sql_check_tables: SHOW TABLES failed %s\n",
                   2887:               mysql_error(sql));
                   2888:        return(-1);
                   2889:     }
                   2890: 
                   2891:     result = mysql_use_result(sql);
                   2892:     if (result) {
                   2893:        while((row = mysql_fetch_row(result)))
                   2894:        {
                   2895:            if (row[0] == NULL) {
                   2896:                mysql_free_result(result);
                   2897:                printf("sql_check_tables: SHOW TABLES returns NULL !\n");
                   2898:                return(-1);
                   2899:            }
                   2900:            tables++;
                   2901:        }
                   2902:        mysql_free_result(result);
                   2903:     }
                   2904:     if(mysql_errno(sql)) {
1.5       veillard 2905:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.2       veillard 2906:     }
                   2907:     printf("%d tables in use\n", tables);
1.5       veillard 2908:     records += sql_show_table_stats("Config", "Name");
                   2909:     records += sql_show_table_stats("Distribs", "Name");
                   2910:     records += sql_show_table_stats("Vendors", "Name");
                   2911:     records += sql_show_table_stats("Mirrors", "URL");
                   2912:     records += sql_show_table_stats("Metadata", "URL");
                   2913:     records += sql_show_table_stats("Packages", "Name");
1.8       veillard 2914:     records += sql_show_table_stats("Requires", "Resource");
                   2915:     records += sql_show_table_stats("Provides", "Resource");
1.5       veillard 2916:     records += sql_show_table_stats("Files", "Path");
1.2       veillard 2917:     printf("Total: %d records\n", records);
                   2918:     return(records);
                   2919: }
                   2920: 
1.26      veillard 2921: void sql_show_latests(void) {
                   2922:     rpmDataPtr list;
                   2923: 
                   2924:     list = sqlRpmByDate();
                   2925:     if (list == NULL) {
                   2926:        fprintf(stderr, "no package in database\n");
                   2927:        return;
                   2928:     }
1.28      daniel   2929:     dumpRpmByDate(list, 0);
1.29      veillard 2930: }
                   2931: 
1.40      veillard 2932: 
                   2933: void sql_show_resources(void) {
                   2934:     int i;
                   2935: 
                   2936:     sqlInitSqlDirList();
                   2937:     sqlInitSqlResourceList();
1.42      veillard 2938:     sqlInitSqlDistributionList();
                   2939:     sqlInitSqlVendorList();
1.40      veillard 2940:     for (i = 0;i < sqlResourceListLen;i++) {
                   2941:        if (sqlResourceList[i] == NULL)
                   2942:            break;
                   2943:        dumpRessRedirHtml(sqlResourceList[i]);
1.41      veillard 2944:        if (rpm2html_dump_rdf_resources)
                   2945:            sql_dump_rdf(sqlResourceList[i]);
1.40      veillard 2946:     }
1.44      daniel   2947:     if (rpm2htmlVerbose)
                   2948:        fprintf(stderr, "Dumped %d redirrect resource pages\n", i);
1.45      veillard 2949:     if (rpm2html_dump_rdf_resources)
                   2950:        sql_dump_rdf_full_index();
1.49      veillard 2951:     sqlListsCleanup();
                   2952: }
                   2953: 
                   2954: void sql_reindex(void) {
                   2955:     int i;
                   2956:     int pid, status;
                   2957: 
1.50      daniel   2958:     sqlInitSqlDirList();
1.49      veillard 2959: 
                   2960: #ifdef SQL_DEBUG
                   2961:     printf("sql_reindex\n");
                   2962: #endif
1.50      daniel   2963:     if (sqlDirListInitialized) {
                   2964:        for (i = 0 ; i < SQL_MAX_DISTRIBS;i++) {
                   2965:            if (sqlDirList[i] == NULL)
                   2966:                continue;
                   2967:            if (sqlDirList[i]->rpmdir != NULL) {
                   2968:                printf("sqltools indexing: %s\n", sqlDirList[i]->name);
1.49      veillard 2969:                pid = fork();
                   2970:                if (pid < 0) {
                   2971:                    fprintf(stderr, "fork failed \n");
                   2972:                    continue;
                   2973:                }
                   2974:                if (pid == 0) {
1.50      daniel   2975:                    printf("%s %s %s %s\n",
1.52      daniel   2976:                           "./rpm2html", "-dir", sqlDirList[i]->rpmdir,
                   2977:                           "./rpm2html-en.config");
                   2978:                    execlp("./rpm2html",
                   2979:                          "./rpm2html", "-dir", sqlDirList[i]->rpmdir,
                   2980:                          "./rpm2html-en.config", NULL);
1.49      veillard 2981:                    fprintf(stderr, "Unable to launch rpm2html\n");
                   2982:                    exit(127);
                   2983:                }
                   2984:                do {
                   2985:                    if (waitpid(pid, &status, 0) == -1) {
                   2986:                        if (errno != EINTR)
                   2987:                            goto done;
                   2988:                    } else {
                   2989:                        if (status != 0)
                   2990:                            printf("indexing: %s exit %d\n",
1.50      daniel   2991:                                   sqlDirList[i]->name, status);
1.49      veillard 2992:                        break;
                   2993:                    }
                   2994:                } while(1);
                   2995: 
                   2996:            }
                   2997:        }
                   2998:     }
                   2999: done:
1.47      veillard 3000:     sqlListsCleanup();
                   3001: }
                   3002: 
                   3003: void sql_show_index(void) {
                   3004:     sqlInitSqlDirList();
                   3005:     sqlInitSqlDistributionList();
                   3006:     if (rpm2html_dump_rdf_resources)
                   3007:        sql_dump_rdf_full_index();
                   3008:     sqlListsCleanup();
1.40      veillard 3009: }
                   3010: 
1.29      veillard 3011: void sql_show_all(void) {
                   3012:     rpmDataPtr list;
1.31      veillard 3013: #ifdef SQL_DEBUG_TIMING
                   3014:     time_t cur, last;
1.29      veillard 3015: 
1.31      veillard 3016:     last = time(NULL);
                   3017: #endif
1.29      veillard 3018:     list = sqlRpmAll();
                   3019:     if (list == NULL) {
                   3020:        fprintf(stderr, "no package in database\n");
                   3021:        return;
                   3022:     }
1.31      veillard 3023: #ifdef SQL_DEBUG_TIMING
                   3024:     cur = time(NULL);
                   3025:     fprintf(stderr, "sqlRpmAll took %d seconds\n", (int)(cur - last));
                   3026:     last = cur;
                   3027: #endif
                   3028: 
                   3029:     rpmNameSort(&list, 0);
                   3030:     dumpRpmByName(rpmSoftwareList, 0);
                   3031: 
                   3032: #ifdef SQL_DEBUG_TIMING
                   3033:     cur = time(NULL);
                   3034:     fprintf(stderr, "dumpRpmByName took %d seconds\n", (int)(cur - last));
                   3035:     last = cur;
                   3036: #endif
                   3037: 
                   3038:     rpmGroupSort(&list, 0);
1.32      daniel   3039:     dumpRpmByGroups(rpmSoftwareList, 0);
1.31      veillard 3040: 
                   3041: #ifdef SQL_DEBUG_TIMING
                   3042:     cur = time(NULL);
                   3043:     fprintf(stderr, "dumpRpmByGroups took %d seconds\n", (int)(cur - last));
                   3044:     last = cur;
                   3045: #endif
1.35      veillard 3046: 
                   3047:     rpmVendorSort(&list, 0);
                   3048:     dumpRpmByVendors(list, 0);
                   3049: 
                   3050: #ifdef SQL_DEBUG_TIMING
                   3051:     cur = time(NULL);
                   3052:     fprintf(stderr, "dumpRpmByVendors took %d seconds\n", (int)(cur - last));
1.36      veillard 3053:     last = cur;
                   3054: #endif
                   3055: 
                   3056:     rpmDistribSort(&list, 0);
                   3057:     dumpRpmByDistribs(list, 0);
                   3058: 
                   3059: #ifdef SQL_DEBUG_TIMING
                   3060:     cur = time(NULL);
                   3061:     fprintf(stderr, "dumpRpmByDistribs took %d seconds\n", (int)(cur - last));
1.35      veillard 3062:     last = cur;
                   3063: #endif
                   3064: 
1.39      daniel   3065:     rpmDateSort(&list, 0);
1.37      veillard 3066:     dumpRpmByDate(list, 0);
                   3067: 
                   3068: #ifdef SQL_DEBUG_TIMING
                   3069:     cur = time(NULL);
                   3070:     fprintf(stderr, "dumpRpmByDate took %d seconds\n", (int)(cur - last));
                   3071:     last = cur;
                   3072: #endif
                   3073: 
1.40      veillard 3074:     rpmdataCleanup();
                   3075:     sleep(30);
1.26      veillard 3076: }
                   3077: 
1.2       veillard 3078: /************************************************************************
                   3079:  *                                                                     *
                   3080:  *                     rpm2html configuration functions                *
                   3081:  *                                                                     *
                   3082:  ************************************************************************/
                   3083: 
                   3084: int readConfigSql(void) {
1.6       veillard 3085:     char query[MAX_QUERY];
1.3       veillard 3086:     MYSQL_RES *result;
                   3087:     MYSQL_ROW row;
1.4       veillard 3088:     int dir = 0;
1.3       veillard 3089: 
1.2       veillard 3090:     /*
1.3       veillard 3091:      * General configuration informations
1.2       veillard 3092:      */
1.6       veillard 3093:     snprintf(query, MAX_QUERY - 1, "SELECT Name,Value FROM Config");
                   3094:     query[MAX_QUERY - 1] = 0;
1.3       veillard 3095:     if (mysql_query(sql,query)) {
                   3096:        printf("sql_check_tables: SELECT Config failed %s\n",
                   3097:               mysql_error(sql));
                   3098:        return(-1);
                   3099:     }
                   3100: 
                   3101:     result = mysql_use_result(sql);
                   3102:     if (result) {
                   3103:        while((row = mysql_fetch_row(result)))
                   3104:        {
                   3105:            if ((row[0] == NULL) || (row[1] == NULL)) {
                   3106:                fprintf(stderr, "readConfigSql : found NULL value\n");
                   3107:                continue;
                   3108:            }
1.4       veillard 3109:            if (!strcmp(row[0], "dir"))
                   3110:                dir = 1;
1.3       veillard 3111:            addConfigEntry(RPM2HTML_NAME, row[0], row[1]);
                   3112:        }
                   3113:        mysql_free_result(result);
                   3114:     }
                   3115:     if(mysql_errno(sql)) {
1.5       veillard 3116:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.4       veillard 3117:     }
                   3118:     if (dir == 0) {
                   3119:        fprintf(stderr, "readConfigSql : no directory\n");
                   3120:        return(-1);
1.3       veillard 3121:     }
                   3122: 
                   3123:     /*
                   3124:      * The metadata mirror list.
                   3125:      */
1.6       veillard 3126:     snprintf(query, MAX_QUERY - 1, "SELECT URL FROM Metadata");
                   3127:     query[MAX_QUERY - 1] = 0;
1.3       veillard 3128:     if (mysql_query(sql,query)) {
                   3129:        printf("sql_check_tables: SELECT Metadata failed %s\n",
                   3130:               mysql_error(sql));
                   3131:        return(-1);
                   3132:     }
                   3133: 
                   3134:     result = mysql_use_result(sql);
                   3135:     if (result) {
                   3136:        while((row = mysql_fetch_row(result)))
                   3137:        {
                   3138:            if (row[0] == NULL) {
                   3139:                fprintf(stderr, "readConfigSql : found NULL metadata\n");
                   3140:                continue;
                   3141:            }
                   3142:            addConfigEntry("metadata", "mirror", row[0]);
                   3143:        }
                   3144:        mysql_free_result(result);
                   3145:     }
                   3146:     if(mysql_errno(sql)) {
1.5       veillard 3147:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 3148:     }
                   3149: 
                   3150:     /*
                   3151:      * The distribution lists
                   3152:      */
1.6       veillard 3153:     snprintf(query, MAX_QUERY - 1, "SELECT Directory,Name,URL,URLSrc,Path FROM Distribs");
                   3154:     query[MAX_QUERY - 1] = 0;
1.3       veillard 3155:     if (mysql_query(sql,query)) {
                   3156:        printf("sql_check_tables: SELECT Distribs failed %s\n",
                   3157:               mysql_error(sql));
                   3158:        return(-1);
                   3159:     }
                   3160: 
                   3161:     result = mysql_use_result(sql);
                   3162:     if (result) {
                   3163:        while((row = mysql_fetch_row(result)))
                   3164:        {
                   3165:            if (row[0] == NULL) {
                   3166:                fprintf(stderr, "readConfigSql : found NULL distro\n");
                   3167:                continue;
                   3168:            }
                   3169: 
                   3170:            if (row[1] != NULL)
                   3171:                addConfigEntry(row[0], "name", row[1]);
                   3172:            if (row[2] != NULL)
                   3173:                addConfigEntry(row[0], "ftp", row[2]);
                   3174:            if (row[3] != NULL)
                   3175:                addConfigEntry(row[0], "ftp", row[3]);
                   3176:            if (row[4] != NULL)
                   3177:                addConfigEntry(row[0], "subdir", row[4]);
                   3178:        }
                   3179:        mysql_free_result(result);
                   3180:     }
                   3181:     if(mysql_errno(sql)) {
1.5       veillard 3182:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 3183:     }
                   3184: 
                   3185:     /*
                   3186:      * The Mirrors
                   3187:      */
1.6       veillard 3188:     snprintf(query, MAX_QUERY - 1, "SELECT Distribs.Directory,Mirrors.URL FROM Distribs,Mirrors WHERE Distribs.ID = Mirrors.ID");
                   3189:     query[MAX_QUERY - 1] = 0;
1.3       veillard 3190:     if (mysql_query(sql,query)) {
                   3191:        printf("sql_check_tables: SELECT Distribs failed %s\n",
                   3192:               mysql_error(sql));
                   3193:        return(-1);
                   3194:     }
                   3195: 
                   3196:     result = mysql_use_result(sql);
                   3197:     if (result) {
                   3198:        while((row = mysql_fetch_row(result)))
                   3199:        {
                   3200:            if ((row[0] == NULL) || (row[1] == NULL)) {
                   3201:                fprintf(stderr, "readConfigSql : found NULL mirror\n");
                   3202:                continue;
                   3203:            }
                   3204: 
                   3205:            addConfigEntry(row[0], "mirror", row[1]);
                   3206:        }
                   3207:        mysql_free_result(result);
                   3208:     }
                   3209:     if(mysql_errno(sql)) {
1.5       veillard 3210:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 3211:     }
                   3212: 
1.5       veillard 3213:     /*
                   3214:      * TODO: add the language(s) stuff
                   3215:      */
1.3       veillard 3216:     return(0);
1.2       veillard 3217: }
                   3218: 
                   3219: void sqlConfigEntry(const char *rpmdir, const char *name, const char *value) {
                   3220:     int distrib;
                   3221: 
                   3222:     if (rpm2htmlVerbose > 1)
                   3223:        printf("sqlConfigEntry(\"%s\", \"%s\", \"%s\")\n", rpmdir, name, value);
                   3224: 
                   3225:     /*
                   3226:      * case of global option for rpm2html.
                   3227:      */
                   3228:     if (!strcasecmp(rpmdir, RPM2HTML_NAME)) {
1.5       veillard 3229:        sql_add_config_info(name, value);
1.2       veillard 3230:        return;
                   3231:     }
                   3232: 
                   3233:     /*
                   3234:      * Options for the metadata mirrors.
                   3235:      */
                   3236:     if (!strcasecmp(rpmdir, "metadata")) {
                   3237:        if (!strcasecmp(name, "mirror")) {
1.5       veillard 3238:            sql_add_metadata_base(value);
1.2       veillard 3239:        } else {
                   3240:            printf("Config file : %s entry for [metadata] ignored\n", name);
                   3241:        }
                   3242:        return;
                   3243:     }
                   3244: 
                   3245:     /*
                   3246:      * option for a directory.
                   3247:      */
                   3248:     if (!strcasecmp(name, "name")) {
1.9       veillard 3249:        sql_add_distrib(value, NULL, rpmdir, NULL, NULL, NULL, NULL,
                   3250:                        NULL, NULL);
1.2       veillard 3251:     } else if (!strcasecmp(name, "subdir")) {
                   3252:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3253:        if (distrib > 0)
                   3254:             sql_update_id("Distribs", distrib, "Path", value);
                   3255:     } else if (!strcasecmp(name, "url")) {
                   3256:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3257:        if (distrib > 0)
                   3258:             sql_update_id("Distribs", distrib, "URL", value);
                   3259:     } else if (!strcasecmp(name, "ftp")) {
                   3260:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3261:        if (distrib > 0)
                   3262:             sql_update_id("Distribs", distrib, "URL", value);
                   3263:     } else if (!strcasecmp(name, "ftpsrc")) {
                   3264:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3265:        if (distrib > 0)
                   3266:             sql_update_id("Distribs", distrib, "URLSrc", value);
1.9       veillard 3267:     } else if (!strcasecmp(name, "html")) {
                   3268:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3269:        if (distrib > 0)
                   3270:             sql_update_id("Distribs", distrib, "Html", value);
                   3271:     } else if (!strcasecmp(name, "color")) {
                   3272:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3273:        if (distrib > 0)
                   3274:             sql_update_id("Distribs", distrib, "Color", value);
1.2       veillard 3275:     } else if (!strcasecmp(name, "mirror")) {
                   3276:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3277:        if (distrib > 0)
1.5       veillard 3278:            sql_add_dist_mirror(distrib, value, 0);
1.2       veillard 3279:     } else {
                   3280:        printf("Config file : %s entry for [%s] ignored\n", name, rpmdir);
                   3281:     }
                   3282: }
1.1       veillard 3283: 

Webmaster