Annotation of rpm2html/sql.c, revision 1.51

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.29      veillard 2166: rpmDataPtr
                   2167: sqlRpmAll(void) {
                   2168:     rpmDataPtr list = NULL;
                   2169:     rpmDataPtr cur, last = NULL;
                   2170:     MYSQL_RES *result;
                   2171:     MYSQL_ROW row;
                   2172:     char *query;
                   2173: 
                   2174:     sqlInitSqlDirList();
1.35      veillard 2175:     sqlInitSqlVendorList();
1.36      veillard 2176:     sqlInitSqlDistributionList();
1.29      veillard 2177:     if (rpm2htmlVerbose)
                   2178:        printf("sqlRpmAll query\n");
                   2179: 
1.35      veillard 2180:     query = "select ID,Name,Version,Release,Arch,Date,Summary,filename,Dist,Category,Os,Packager,Vendor from Packages";
1.29      veillard 2181: 
                   2182:     /*
                   2183:      * Search first for the ID if it already exists
                   2184:      */
                   2185:     if (mysql_query(sql,query)) {
                   2186:        printf("sqlRpmByDate: SELECT from Packages failed: %s\n",
                   2187:               mysql_error(sql));
                   2188:        return(NULL);
                   2189:     }
                   2190: 
                   2191:     result = mysql_use_result(sql);
                   2192:     if (result) {
                   2193:        while((row = mysql_fetch_row(result)))
                   2194:        {
                   2195:            cur = sqlRpmAnalyzeRow(row);
                   2196:            if (cur != NULL) {
                   2197:                if (last == NULL)
                   2198:                    list = cur;
                   2199:                else
                   2200:                    last->next = cur;
                   2201:                last = cur;
1.32      daniel   2202: 
                   2203:                rpmAddSoftware(cur);
1.29      veillard 2204:            }
                   2205:        }
                   2206:        mysql_free_result(result);
                   2207:     }
                   2208:     if(mysql_errno(sql)) {
                   2209:        fprintf(stderr, "sqlRpmByDate Error: %s\n", mysql_error(sql));
                   2210:        return(NULL);
                   2211:     }
                   2212: 
                   2213:     if (rpm2htmlVerbose)
                   2214:        printf("sqlRpmAll done\n");
                   2215:     return(list);
                   2216: }
                   2217: 
1.45      veillard 2218: void sqlListsCleanup(void) {
                   2219:     int i;
                   2220: 
                   2221: #ifdef SQL_DEBUG_MEM
                   2222:     printf("sqlListsCleanup\n");
                   2223: #endif
                   2224:     if (sqlDirListInitialized) {
                   2225: #ifdef SQL_DEBUG_MEM
                   2226:        printf("sqlListsCleanup: freeing sqlDirList\n");
                   2227: #endif
                   2228:        for (i = 0 ; i < SQL_MAX_DISTRIBS; i++) {
                   2229:            if (sqlDirList[i] != NULL)
                   2230:                rpmDirFree(sqlDirList[i]);
                   2231:            sqlDirList[i] = NULL;
                   2232:        }
                   2233:        sqlDirListInitialized = 0;
                   2234:     }
                   2235:     if (sqlVendorListInitialized) {
                   2236: #ifdef SQL_DEBUG_MEM
                   2237:        printf("sqlListsCleanup: freeing sqlVendorList\n");
                   2238: #endif
                   2239:        for (i = 0 ; i < sqlVendorListLen;i++) {
                   2240:            if (sqlVendorList[i] != NULL)
                   2241:                xmlFree(sqlVendorList[i]);
                   2242:            sqlVendorList[i] = NULL;
                   2243:        }
                   2244:        xmlFree(sqlVendorList);
                   2245:        sqlVendorListInitialized = 0;
                   2246:     }
                   2247:     if (sqlDistributionListInitialized) {
                   2248: #ifdef SQL_DEBUG_MEM
                   2249:        printf("sqlListsCleanup: freeing sqlDistributionList\n");
                   2250: #endif
                   2251:        for (i = 0 ; i < sqlDistributionListLen;i++) {
                   2252:            if (sqlDistributionList[i] != NULL)
                   2253:                xmlFree(sqlDistributionList[i]);
                   2254:            sqlDistributionList[i] = NULL;
                   2255:        }
                   2256:        xmlFree(sqlDistributionList);
                   2257:        sqlDistributionListInitialized = 0;
                   2258:     }
                   2259:     if (sqlResourceListInitialized) {
                   2260: #ifdef SQL_DEBUG_MEM
                   2261:        printf("sqlListsCleanup: freeing sqlResourceList\n");
                   2262: #endif
                   2263:        for (i = 0 ; i < sqlResourceListLen;i++) {
                   2264:            if (sqlResourceList[i] != NULL)
                   2265:                xmlFree(sqlResourceList[i]);
                   2266:            sqlResourceList[i] = NULL;
                   2267:        }
                   2268:        xmlFree(sqlResourceList);
                   2269:        sqlResourceListInitialized = 0;
                   2270:     }
                   2271: }
                   2272: 
1.26      veillard 2273: /************************************************************************
1.8       veillard 2274:  *                                                                     *
1.6       veillard 2275:  *                     Export functions                                *
                   2276:  *                                                                     *
                   2277:  ************************************************************************/
                   2278: 
1.45      veillard 2279: void sql_dump_rdf_full_index(void) {
                   2280:     MYSQL_RES *result;
                   2281:     MYSQL_ROW row;
                   2282:     char query[SMALL_QUERY];
                   2283:     gzFile rdf;
                   2284:     char *filename;
                   2285:     char *dist;
                   2286:     char *name;
                   2287:     char *version;
                   2288:     char *release;
                   2289:     char *arch;
                   2290:     char *summary;
                   2291:     char *subdir;
                   2292:     char *psubdir;
                   2293:     char *rpmdir;
                   2294:     char *start, *end;
                   2295:     int distrib;
                   2296:     int len;
                   2297:     char path[500];
                   2298: 
                   2299:     if (!rpm2html_dump_rdf_resources)
                   2300:        return;
                   2301:     if (!rpm2html_rdf_resources_dir)
                   2302:        return;
                   2303:     if ((rpm2html_host == NULL) || (rpm2html_url == NULL))
                   2304:        return;
                   2305: 
                   2306:     /*
                   2307:      * Open the RDF resource descritpion.
                   2308:      */
                   2309:     mkdir(rpm2html_rdf_resources_dir, 0755);
                   2310:     snprintf(path, 500, "%s/fullIndex.rdf.gz",
                   2311:             rpm2html_rdf_resources_dir);
                   2312:     path[499] = 0;
                   2313:     rdf = gzopen(path, "w9");
                   2314:     if (rdf == NULL) {
                   2315:        fprintf(stderr, "unable to write to %s\n", path);
                   2316:        return;
                   2317:     }
                   2318:     gzprintf(rdf, "<?xml version=\"1.0\"?>\n");
                   2319:     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");
                   2320: 
                   2321:     /*
                   2322:      * Query the database for the informations providing the resource.
                   2323:      */
                   2324:     snprintf(query, SMALL_QUERY,
                   2325:        "select filename,Dist,Name,Version,Release,Arch,Summary from Packages");
                   2326:     query[SMALL_QUERY - 1] = 0;
                   2327:     if (mysql_query(sql, query)) {
                   2328:        printf("sql_dump_rdf_full_index: SELECT from Packages failed: %s\n",
                   2329:               mysql_error(sql));
                   2330:         gzprintf(rdf, "</rdf:RDF>\n");
                   2331:        fclose(rdf);
                   2332:        return;
                   2333:     }
                   2334:     result = mysql_use_result(sql);
                   2335:     if (result == NULL) {
                   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:     while((row = mysql_fetch_row(result))) {
                   2343:        filename = row[0];
                   2344:        dist = row[1];
                   2345:        name = row[2];
                   2346:        version = row[3];
                   2347:        release = row[4];
                   2348:        arch = row[5];
                   2349:        summary = row[6];
                   2350:        if ((filename == NULL) || (dist == NULL) || (name == NULL) ||
                   2351:            (summary == NULL)) {
                   2352:            continue;
                   2353:        }
                   2354:        if (!strncmp(filename, "localbase", 9))
                   2355:            continue;
                   2356:        if (sscanf(dist, "%d", &distrib) != 1)
                   2357:            continue;
                   2358:        if ((distrib < 1) || (distrib >= SQL_MAX_DISTRIBS) ||
                   2359:            (sqlDirList[distrib] == NULL))
                   2360:            continue;
                   2361: 
                   2362:        subdir = sqlDirList[distrib]->subdir;
                   2363:        rpmdir = sqlDirList[distrib]->rpmdir;
                   2364:        len = strlen(rpmdir);
                   2365:        if (strncmp(filename, rpmdir, len)) {
                   2366:            fprintf(stderr, "%s out of subdir %s\n", filename, subdir);
                   2367:            continue;
                   2368:        }
                   2369:        start = &(filename[len]);
                   2370:        while (*start == '/') start++;
                   2371:        end = &start[strlen(start) - 1];
                   2372:        while ((end >= start) && (*end != '/')) end--;
                   2373:        if (end <= start) {
                   2374:            psubdir = xmlStrdup("");
                   2375:        } else {
                   2376:            psubdir = xmlMalloc((end - start) + 1);
                   2377:            if (psubdir == NULL) {
                   2378:                fprintf(stderr, "Out of memory\n");
                   2379:                continue;
                   2380:            }
                   2381:            strncpy(psubdir, start, end - start);
                   2382:            psubdir[end - start] = 0;
                   2383:        }
                   2384:         gzprintf(rdf, "  <rdf:Description about=\"%s/%s/%s-%s-%s.%s.rpm\">\n",
                   2385:                sqlDirList[distrib]->ftp,psubdir,name,version,release,arch);
                   2386:        gzprintf(rdf, "    <RPM:Name>%s</RPM:Name>\n", name);
1.46      veillard 2387:        gzprintf(rdf, "    <RPM:Summary>%s</RPM:Summary>\n", 
                   2388:                 convertXML(summary));
1.45      veillard 2389:        gzprintf(rdf, "  </rdf:Description>\n");
                   2390:        xmlFree(psubdir);
                   2391:     }
                   2392:     gzprintf(rdf, "</rdf:RDF>\n");
                   2393:     gzclose(rdf);
                   2394:     mysql_free_result(result);
                   2395:     if(mysql_errno(sql)) {
                   2396:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2397:     }
                   2398: }
                   2399: 
                   2400: 
1.41      veillard 2401: void sql_dump_rdf(const char *resource) {
                   2402:     MYSQL_RES *result;
                   2403:     MYSQL_ROW row;
                   2404:     char query[SMALL_QUERY];
                   2405:     FILE *rdf;
                   2406:     char *filename;
                   2407:     char *dist;
                   2408:     char *name;
                   2409:     char *version;
                   2410:     char *release;
                   2411:     char *arch;
                   2412:     char *os;
                   2413:     char *packager;
                   2414:     char *date;
                   2415:     char *size;
1.44      daniel   2416:     char *vendorstr;
1.41      veillard 2417:     char *subdir;
1.42      veillard 2418:     char *psubdir;
                   2419:     char *rpmdir;
                   2420:     char *start, *end;
1.41      veillard 2421:     int distrib;
1.42      veillard 2422:     int vendor;
1.44      daniel   2423:     int person;
1.42      veillard 2424:     int len;
                   2425:     char path[500];
1.41      veillard 2426: 
                   2427:     if (resource == NULL)
                   2428:        return;
1.44      daniel   2429:     if (resource[0] == '/')
                   2430:        return;
1.41      veillard 2431:     if (!rpm2html_dump_rdf_resources)
                   2432:        return;
1.42      veillard 2433:     if (!rpm2html_rdf_resources_dir)
                   2434:        return;
1.41      veillard 2435:     if ((rpm2html_host == NULL) || (rpm2html_url == NULL))
                   2436:        return;
                   2437: 
1.42      veillard 2438:     /*
                   2439:      * Open the RDF resource descritpion.
                   2440:      */
                   2441:     mkdir(rpm2html_rdf_resources_dir, 0755);
                   2442:     snprintf(path, 500, "%s/%s.rdf",
                   2443:             rpm2html_rdf_resources_dir, resource);
                   2444:     path[499] = 0;
                   2445:     rdf = fopen(path, "w");
                   2446:     if (rdf == NULL) {
                   2447:        fprintf(stderr, "unable to write to %s\n", path);
                   2448:        return;
                   2449:     }
                   2450:     fprintf(rdf, "<?xml version=\"1.0\"?>\n");
                   2451:     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");
                   2452: 
                   2453:     /*
                   2454:      * Query the database for the informations providing the resource.
                   2455:      */
1.41      veillard 2456:     snprintf(query, SMALL_QUERY,
1.44      daniel   2457: "select filename,Dist,Name,Version,Release,Arch,Os,Packager,Date,Size,Vendor from Packages where Name=\"%s\"",
1.41      veillard 2458:              resource);
                   2459:     query[SMALL_QUERY - 1] = 0;
                   2460:     if (mysql_query(sql, query)) {
                   2461:        printf("sql_dump_rdf: SELECT from Packages failed: %s\n",
                   2462:               mysql_error(sql));
1.42      veillard 2463:         fprintf(rdf, "</rdf:RDF>\n");
                   2464:        fclose(rdf);
1.41      veillard 2465:        return;
                   2466:     }
                   2467:     result = mysql_use_result(sql);
                   2468:     if (result == NULL) {
                   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:     while((row = mysql_fetch_row(result))) {
                   2476:        filename = row[0];
                   2477:        dist = row[1];
                   2478:        name = row[2];
                   2479:        version = row[3];
                   2480:        release = row[4];
                   2481:        arch = row[5];
                   2482:        os = row[6];
                   2483:        packager = row[7];
                   2484:        date = row[8];
                   2485:        size = row[9];
1.44      daniel   2486:        vendorstr = row[10];
1.41      veillard 2487:        if ((filename == NULL) || (dist == NULL) || (name == NULL) ||
                   2488:            (version == NULL) || (release == NULL) || (arch == NULL) ||
1.44      daniel   2489:            (os == NULL) || (date == NULL) || (vendorstr == NULL) ||
1.41      veillard 2490:            (size == NULL)) {
                   2491:            continue;
                   2492:        }
1.42      veillard 2493:        if (!strncmp(filename, "localbase", 9))
                   2494:            continue;
1.41      veillard 2495:        if (sscanf(dist, "%d", &distrib) != 1)
                   2496:            continue;
1.44      daniel   2497:        if ((distrib < 1) || (distrib >= SQL_MAX_DISTRIBS) ||
                   2498:            (sqlDirList[distrib] == NULL))
1.42      veillard 2499:            continue;
1.44      daniel   2500:        if (vendorstr != NULL) {
                   2501:            if (sscanf(vendorstr, "%d", &vendor) != 1)
1.42      veillard 2502:                continue;
                   2503:        }
                   2504:        if ((vendor < 1) || (vendor >= sqlDistributionListLen) ||
                   2505:            (sqlDistributionList[vendor] == NULL))
1.41      veillard 2506:            continue;
1.44      daniel   2507:        if (packager != NULL) {
                   2508:            if (sscanf(packager, "%d", &person) != 1)
                   2509:                continue;
                   2510:        }
                   2511:        if ((person < 1) || (person >= sqlVendorListLen) ||
                   2512:            (sqlVendorList[person] == NULL))
                   2513:            continue;
1.41      veillard 2514: 
                   2515:        subdir = sqlDirList[distrib]->subdir;
1.42      veillard 2516:        rpmdir = sqlDirList[distrib]->rpmdir;
                   2517:        len = strlen(rpmdir);
                   2518:        if (strncmp(filename, rpmdir, len)) {
                   2519:            fprintf(stderr, "%s out of subdir %s\n", filename, subdir);
                   2520:            continue;
                   2521:        }
                   2522:        start = &(filename[len]);
                   2523:        while (*start == '/') start++;
                   2524:        end = &start[strlen(start) - 1];
                   2525:        while ((end >= start) && (*end != '/')) end--;
                   2526:        if (end <= start) {
1.45      veillard 2527:            psubdir = xmlStrdup("");
1.42      veillard 2528:        } else {
1.45      veillard 2529:            psubdir = xmlMalloc((end - start) + 1);
1.42      veillard 2530:            if (psubdir == NULL) {
                   2531:                fprintf(stderr, "Out of memory\n");
                   2532:                continue;
1.41      veillard 2533:            }
1.42      veillard 2534:            strncpy(psubdir, start, end - start);
                   2535:            psubdir[end - start] = 0;
1.41      veillard 2536:        }
1.42      veillard 2537:         fprintf(rdf, "  <rdf:Description about=\"%s/%s/%s-%s-%s.%s.rpm\" ",
                   2538:                sqlDirList[distrib]->ftp,psubdir,name,version,release,arch);
                   2539:        fprintf(rdf, "href=\"../%s/%s/%s-%s-%s.%s.rdf\">\n",
                   2540:                subdir,psubdir,name,version,release,arch);
                   2541:        fprintf(rdf, "    <RPM:Name>%s</RPM:Name>\n", name);
                   2542:        fprintf(rdf, "    <RPM:Version>%s</RPM:Version>\n", version);
                   2543:        fprintf(rdf, "    <RPM:Release>%s</RPM:Release>\n", release);
                   2544:        fprintf(rdf, "    <RPM:Arch>%s</RPM:Arch>\n", arch);
                   2545:        fprintf(rdf, "    <RPM:Os>%s</RPM:Os>\n", os);
                   2546:        if (packager == NULL)
                   2547:            fprintf(rdf, "    <RPM:Distribution>Unknown</RPM:Distribution>\n");
                   2548:        else
                   2549:            fprintf(rdf, "    <RPM:Distribution>%s</RPM:Distribution>\n",
1.48      daniel   2550:                    convertXML(sqlDistributionList[vendor]));
1.42      veillard 2551:        fprintf(rdf, "    <RPM:Vendor>%s</RPM:Vendor>\n",
1.48      daniel   2552:            convertXML(sqlVendorList[person]));
1.42      veillard 2553:        fprintf(rdf, "    <RPM:Date>%s</RPM:Date>\n", date);
                   2554:        fprintf(rdf, "    <RPM:Size>%s</RPM:Size>\n", size);
                   2555:        fprintf(rdf, "    <RPM:Subdir>%s</RPM:Subdir>\n", subdir);
                   2556:        fprintf(rdf, "  </rdf:Description>\n");
1.45      veillard 2557:        xmlFree(psubdir);
1.41      veillard 2558:     }
1.42      veillard 2559:     fprintf(rdf, "</rdf:RDF>\n");
                   2560:     fclose(rdf);
1.45      veillard 2561:     mysql_free_result(result);
                   2562:     if(mysql_errno(sql)) {
                   2563:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2564:     }
1.41      veillard 2565: }
                   2566: 
1.6       veillard 2567: void sql_show_config(void) {
                   2568:     MYSQL_RES *result;
                   2569:     MYSQL_ROW row;
1.8       veillard 2570:     int id, i;
                   2571:     int index = 0;
                   2572:     int ids[500];
                   2573:     char query[SMALL_QUERY];
1.6       veillard 2574: 
                   2575: 
1.8       veillard 2576:     printf(";\n; Configuration file for rpm2html\n");
                   2577:     printf("; http://rpmfind.net/linux/rpm2html/\n;\n\n");
                   2578:     mysql_query(sql,"SELECT Name,Value FROM Config");
1.6       veillard 2579:     result = mysql_use_result(sql);
                   2580: 
                   2581:     while((row = mysql_fetch_row(result)))
                   2582:     {
1.8       veillard 2583:        if (row[0] == NULL) {
                   2584:            printf("\n");
                   2585:        } else {
                   2586:            if (!strcmp(row[0], "maint"))
                   2587:                printf("; maintainer of the local rpm mirror\n");
                   2588:            else if (!strcmp(row[0], "mail"))
                   2589:                printf("; mail for the maintainer\n");
                   2590:            else if (!strcmp(row[0], "dir"))
                   2591:                 printf("; Directory to store the HTML pages produced\n");
                   2592:            else if (!strcmp(row[0], "url"))
                   2593:                 printf("; The relative URL for front pages\n");
                   2594:            else if (!strcmp(row[0], "header"))
                   2595:                 printf("; Extra link in the navigation bar\n");
                   2596:            else if (!strcmp(row[0], "html"))
                   2597:                 printf("; Export the local packages in HTML format\n");
                   2598:            else if (!strcmp(row[0], "tree"))
                   2599:                 printf("; Build the tree for the distributions\n");
                   2600:            else if (!strcmp(row[0], "rdf"))
                   2601:                 printf("; Export the local packages in RDF format\n");
                   2602:            else if (!strcmp(row[0], "rdf_dir"))
                   2603:                 printf("; Directory to store the RDf tree\n");
                   2604:            else if (!strcmp(row[0], "rdf_resources"))
                   2605:                 printf("; Compile a list of resources in RDF format\n");
                   2606:            else if (!strcmp(row[0], "rdf_resources_dir"))
                   2607:                 printf("; Directory to store the RDf resources tree\n");
                   2608: 
1.6       veillard 2609:            if (row[1] == NULL)
1.8       veillard 2610:                printf("%s\n\n", row[0]);
1.6       veillard 2611:            else
1.8       veillard 2612:                printf("%s=%s\n\n", row[0], row[1]);
                   2613:        }
                   2614:     }
                   2615:     mysql_free_result(result);
                   2616:     if(mysql_errno(sql)) {
                   2617:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2618:     }
                   2619: 
                   2620:     /*
                   2621:      * Dump the Metadata
                   2622:      */
                   2623:     printf(";\n; The metadata mirrors list\n;\n\n[metadata]\n");
                   2624:     mysql_query(sql,"SELECT URL FROM Metadata");
                   2625:     result = mysql_use_result(sql);
                   2626: 
                   2627:     while((row = mysql_fetch_row(result)))
                   2628:     {
                   2629:        if (row[0] != NULL) {
                   2630:            printf("mirror=%s\n", row[0]);
1.6       veillard 2631:        }
                   2632:     }
1.8       veillard 2633:     mysql_free_result(result);
1.6       veillard 2634:     if(mysql_errno(sql)) {
                   2635:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2636:     }
                   2637: 
1.8       veillard 2638:     /*
                   2639:      * Dump the distributions informations
                   2640:      * 1/ collect the list of IDs for the distribs
                   2641:      */
                   2642:     printf("\n\n;\n; The distribution list\n;\n\n");
                   2643:     mysql_query(sql,"SELECT ID FROM Distribs");
                   2644:     result = mysql_use_result(sql);
                   2645: 
                   2646:     while((row = mysql_fetch_row(result)))
                   2647:     {
                   2648:        if (row[0] != NULL) {
                   2649:            if (sscanf(row[0], "%d", &id) == 1) {
                   2650:                ids[index++] = id;
                   2651:            }
                   2652:        }
                   2653:     }
                   2654:     mysql_free_result(result);
                   2655: 
                   2656:     /*
                   2657:      * Dump each distribution separately.
                   2658:      */
                   2659:     for (i = 0;i < index;i++) {
                   2660: 
                   2661:        snprintf(query, SMALL_QUERY - 1,
1.10      veillard 2662:  "SELECT Directory,Name,Vendor,Path,URL,URLSrc,Description,Html,Color \
1.8       veillard 2663:                  FROM Distribs WHERE ID=%d", ids[i]);
                   2664:        query[SMALL_QUERY - 1] = 0;
                   2665:        if (mysql_query(sql,query)) {
                   2666:            printf("sql_show_config: SELECT Distrib %d failed: %s\n",
                   2667:                   ids[i], mysql_error(sql));
                   2668:            continue;
                   2669:        }
                   2670: 
                   2671:        result = mysql_use_result(sql);
                   2672:        if (result) {
                   2673:            while((row = mysql_fetch_row(result)))
                   2674:            {
                   2675:                if (row[0] == NULL)
                   2676:                    break;
                   2677:                printf("[%s]\n", row[0]);
                   2678:                if (row[1] != NULL)
                   2679:                    printf("name=%s\n", row[1]);
                   2680:                if (row[3] != NULL)
                   2681:                    printf("subdir=%s\n", row[3]);
                   2682:                if (row[4] != NULL)
                   2683:                    printf("ftp=%s\n", row[4]);
                   2684:                if (row[5] != NULL)
                   2685:                    printf("ftpsrc=%s\n", row[5]);
1.10      veillard 2686:                if (row[7] != NULL)
                   2687:                    printf("html=%s\n", row[7]);
                   2688:                if (row[8] != NULL)
                   2689:                    printf("color=%s\n", row[8]);
1.8       veillard 2690:            }
                   2691:        }
                   2692:        mysql_free_result(result);
1.12      veillard 2693: 
                   2694:        /*
                   2695:         * Extract the mirrors for this distribution.
                   2696:         */
                   2697:        snprintf(query, SMALL_QUERY - 1,
                   2698:                 "SELECT URL FROM Mirrors WHERE ID=%d", ids[i]);
                   2699:        query[SMALL_QUERY - 1] = 0;
                   2700:        if (mysql_query(sql,query)) {
                   2701:            printf("sql_show_config: SELECT Mirrors %d failed: %s\n",
                   2702:                   ids[i], mysql_error(sql));
                   2703:            printf("\n\n");
                   2704:            continue;
                   2705:        }
                   2706:        result = mysql_use_result(sql);
                   2707:        if (result) {
                   2708:            while((row = mysql_fetch_row(result)))
                   2709:            {
                   2710:                if (row[0] == NULL)
                   2711:                    continue;
                   2712:                printf("mirror=%s\n", row[0]);
                   2713:            }
                   2714:        }
                   2715:        mysql_free_result(result);
                   2716: 
1.8       veillard 2717:        printf("\n\n");
                   2718:     }
                   2719: 
                   2720:     printf(";\n; End of the configuration file for rpm2html\n;\n");
1.6       veillard 2721: }
                   2722: 
                   2723: void sql_show_metadata(void) {
                   2724:     MYSQL_RES *result;
                   2725:     MYSQL_ROW row;
                   2726: 
                   2727: 
                   2728:     mysql_query(sql,"SELECT URL FROM Metadata");
                   2729:     result = mysql_use_result(sql);
                   2730: 
                   2731:     while((row = mysql_fetch_row(result)))
                   2732:     {
                   2733:        if (row[0] == NULL)
                   2734:            printf("NULL !\n");
                   2735:        else {
                   2736:            printf("%s\n", row[0]);
                   2737:        }
                   2738:     }
                   2739:     if(mysql_errno(sql)) {
                   2740:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2741:     }
                   2742: 
                   2743: }
                   2744: 
                   2745: void sql_show_mirrors(void) {
                   2746:     MYSQL_RES *result;
                   2747:     MYSQL_ROW row;
                   2748: 
                   2749: 
                   2750:     mysql_query(sql,"SELECT URL FROM Mirrors");
                   2751:     result = mysql_use_result(sql);
                   2752: 
                   2753:     while((row = mysql_fetch_row(result)))
                   2754:     {
                   2755:        if (row[0] == NULL)
                   2756:            printf("NULL !\n");
                   2757:        else {
                   2758:            printf("%s\n", row[0]);
                   2759:        }
                   2760:     }
                   2761:     if(mysql_errno(sql)) {
                   2762:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2763:     }
                   2764: }
                   2765: 
1.5       veillard 2766: void sql_show_vendors(void) {
1.1       veillard 2767:     MYSQL_RES *result;
                   2768:     MYSQL_ROW row;
                   2769: 
                   2770: 
                   2771:     mysql_query(sql,"SELECT Name, URL FROM Vendors");
                   2772:     result = mysql_use_result(sql);
                   2773: 
                   2774:     while((row = mysql_fetch_row(result)))
                   2775:     {
                   2776:        if (row[0] == NULL)
                   2777:            printf("NULL !\n");
                   2778:        else {
                   2779:            if (row[1] == NULL)
                   2780:                printf("%s : no url\n", row[0]);
                   2781:            else
                   2782:                printf("%s : %s\n", row[0], row[1]);
                   2783:        }
                   2784:     }
                   2785:     if(mysql_errno(sql)) {
                   2786:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2787:     }
                   2788: 
                   2789: }
                   2790: 
1.5       veillard 2791: void sql_show_distribs(void) {
1.1       veillard 2792:     MYSQL_RES *result;
                   2793:     MYSQL_ROW row;
                   2794: 
                   2795: 
                   2796:     mysql_query(sql,"SELECT Name, Path, URL FROM Distribs");
                   2797:     result = mysql_use_result(sql);
                   2798: 
                   2799:     while((row = mysql_fetch_row(result)))
                   2800:     {
                   2801:        if (row[0] == NULL)
                   2802:            printf("NULL !\n");
                   2803:        else {
                   2804:            if (row[1] == NULL)
                   2805:                printf("%s : no Path\n", row[0]);
                   2806:            else {
                   2807:                if (row[2] == NULL)
                   2808:                    printf("%s : %s : no url\n", row[0], row[1]);
                   2809:                else
                   2810:                    printf("%s : %s : %s\n", row[0], row[1], row[2]);
                   2811:            }
                   2812:        }
                   2813:     }
                   2814:     if(mysql_errno(sql)) {
                   2815:        fprintf(stderr, "Error: %s\n", mysql_error(sql));
                   2816:     }
                   2817: 
                   2818: }
                   2819: 
1.5       veillard 2820: int sql_show_table_stats(const char *table, const char *key) {
1.6       veillard 2821:     char query[MAX_QUERY];
1.2       veillard 2822:     MYSQL_RES *result;
                   2823:     MYSQL_ROW row;
                   2824:     int res;
                   2825: 
                   2826:     /*
                   2827:      * Search first for the ID if it already exists
                   2828:      */
1.6       veillard 2829:     snprintf(query, MAX_QUERY - 1, "SELECT COUNT(%s) FROM %s", key, table);
                   2830:     query[MAX_QUERY - 1] = 0;
1.2       veillard 2831:     if (mysql_query(sql,query)) {
1.5       veillard 2832:        printf("sql_show_table_stats: SELECT COUNT failed: %s\n",
1.2       veillard 2833:               mysql_error(sql));
                   2834:        return(-1);
                   2835:     }
                   2836: 
                   2837:     result = mysql_use_result(sql);
                   2838:     if (result) {
                   2839:        while((row = mysql_fetch_row(result)))
                   2840:        {
                   2841:            /*
                   2842:             * Lookup the value and return it
                   2843:             */
                   2844:            if (row[0] == NULL) {
                   2845:                mysql_free_result(result);
1.5       veillard 2846:                printf("sql_show_table_stats: select count returns NULL !\n");
1.2       veillard 2847:                return(-1);
                   2848:            }
                   2849:            if (sscanf(row[0], "%d", &res) != 1) {
                   2850:                mysql_free_result(result);
1.5       veillard 2851:                printf("sql_show_table_stats: value non numeric %s\n", row[0]);
1.2       veillard 2852:                return(-1);
                   2853:            }
                   2854:            mysql_free_result(result);
                   2855:            if (res <= 0)
                   2856:                printf("   %s is empty\n", table);
                   2857:            else
                   2858:                printf("   %s contains %d records\n", table, res);
                   2859:            return(res);
                   2860:        }
                   2861:        mysql_free_result(result);
                   2862:     }
                   2863:     if(mysql_errno(sql)) {
1.5       veillard 2864:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.2       veillard 2865:     }
                   2866:     return(-1);
                   2867: }
                   2868: 
1.5       veillard 2869: int sql_show_stats(void) {
1.2       veillard 2870:     const char *query = "SHOW TABLES";
                   2871:     MYSQL_RES *result;
                   2872:     MYSQL_ROW row;
                   2873: 
                   2874:     int tables = 0;
                   2875:     int records = 0;
                   2876: 
                   2877:     if (mysql_query(sql,query)) {
                   2878:        printf("sql_check_tables: SHOW TABLES failed %s\n",
                   2879:               mysql_error(sql));
                   2880:        return(-1);
                   2881:     }
                   2882: 
                   2883:     result = mysql_use_result(sql);
                   2884:     if (result) {
                   2885:        while((row = mysql_fetch_row(result)))
                   2886:        {
                   2887:            if (row[0] == NULL) {
                   2888:                mysql_free_result(result);
                   2889:                printf("sql_check_tables: SHOW TABLES returns NULL !\n");
                   2890:                return(-1);
                   2891:            }
                   2892:            tables++;
                   2893:        }
                   2894:        mysql_free_result(result);
                   2895:     }
                   2896:     if(mysql_errno(sql)) {
1.5       veillard 2897:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.2       veillard 2898:     }
                   2899:     printf("%d tables in use\n", tables);
1.5       veillard 2900:     records += sql_show_table_stats("Config", "Name");
                   2901:     records += sql_show_table_stats("Distribs", "Name");
                   2902:     records += sql_show_table_stats("Vendors", "Name");
                   2903:     records += sql_show_table_stats("Mirrors", "URL");
                   2904:     records += sql_show_table_stats("Metadata", "URL");
                   2905:     records += sql_show_table_stats("Packages", "Name");
1.8       veillard 2906:     records += sql_show_table_stats("Requires", "Resource");
                   2907:     records += sql_show_table_stats("Provides", "Resource");
1.5       veillard 2908:     records += sql_show_table_stats("Files", "Path");
1.2       veillard 2909:     printf("Total: %d records\n", records);
                   2910:     return(records);
                   2911: }
                   2912: 
1.26      veillard 2913: void sql_show_latests(void) {
                   2914:     rpmDataPtr list;
                   2915: 
                   2916:     list = sqlRpmByDate();
                   2917:     if (list == NULL) {
                   2918:        fprintf(stderr, "no package in database\n");
                   2919:        return;
                   2920:     }
1.28      daniel   2921:     dumpRpmByDate(list, 0);
1.29      veillard 2922: }
                   2923: 
1.40      veillard 2924: 
                   2925: void sql_show_resources(void) {
                   2926:     int i;
                   2927: 
                   2928:     sqlInitSqlDirList();
                   2929:     sqlInitSqlResourceList();
1.42      veillard 2930:     sqlInitSqlDistributionList();
                   2931:     sqlInitSqlVendorList();
1.40      veillard 2932:     for (i = 0;i < sqlResourceListLen;i++) {
                   2933:        if (sqlResourceList[i] == NULL)
                   2934:            break;
                   2935:        dumpRessRedirHtml(sqlResourceList[i]);
1.41      veillard 2936:        if (rpm2html_dump_rdf_resources)
                   2937:            sql_dump_rdf(sqlResourceList[i]);
1.40      veillard 2938:     }
1.44      daniel   2939:     if (rpm2htmlVerbose)
                   2940:        fprintf(stderr, "Dumped %d redirrect resource pages\n", i);
1.45      veillard 2941:     if (rpm2html_dump_rdf_resources)
                   2942:        sql_dump_rdf_full_index();
1.49      veillard 2943:     sqlListsCleanup();
                   2944: }
                   2945: 
                   2946: void sql_reindex(void) {
                   2947:     int i;
                   2948:     int pid, status;
                   2949: 
1.50      daniel   2950:     sqlInitSqlDirList();
1.49      veillard 2951: 
                   2952: #ifdef SQL_DEBUG
                   2953:     printf("sql_reindex\n");
                   2954: #endif
1.50      daniel   2955:     if (sqlDirListInitialized) {
                   2956:        for (i = 0 ; i < SQL_MAX_DISTRIBS;i++) {
                   2957:            if (sqlDirList[i] == NULL)
                   2958:                continue;
                   2959:            if (sqlDirList[i]->rpmdir != NULL) {
                   2960:                printf("sqltools indexing: %s\n", sqlDirList[i]->name);
1.49      veillard 2961:                pid = fork();
                   2962:                if (pid < 0) {
                   2963:                    fprintf(stderr, "fork failed \n");
                   2964:                    continue;
                   2965:                }
                   2966:                if (pid == 0) {
1.50      daniel   2967:                    printf("%s %s %s %s\n",
                   2968:                           "rpm2html", "-dir", sqlDirList[i]->rpmdir,
                   2969:                           "rpm2html-en.config");
                   2970:                    execlp("rpm2html",
                   2971:                          "rpm2html", "-dir", sqlDirList[i]->rpmdir,
1.49      veillard 2972:                          "rpm2html-en.config", NULL);
                   2973:                    fprintf(stderr, "Unable to launch rpm2html\n");
                   2974:                    exit(127);
                   2975:                }
                   2976:                do {
                   2977:                    if (waitpid(pid, &status, 0) == -1) {
                   2978:                        if (errno != EINTR)
                   2979:                            goto done;
                   2980:                    } else {
                   2981:                        if (status != 0)
                   2982:                            printf("indexing: %s exit %d\n",
1.50      daniel   2983:                                   sqlDirList[i]->name, status);
1.49      veillard 2984:                        break;
                   2985:                    }
                   2986:                } while(1);
                   2987: 
                   2988:            }
                   2989:        }
                   2990:     }
                   2991: done:
1.47      veillard 2992:     sqlListsCleanup();
                   2993: }
                   2994: 
                   2995: void sql_show_index(void) {
                   2996:     sqlInitSqlDirList();
                   2997:     sqlInitSqlDistributionList();
                   2998:     if (rpm2html_dump_rdf_resources)
                   2999:        sql_dump_rdf_full_index();
                   3000:     sqlListsCleanup();
1.40      veillard 3001: }
                   3002: 
1.29      veillard 3003: void sql_show_all(void) {
                   3004:     rpmDataPtr list;
1.31      veillard 3005: #ifdef SQL_DEBUG_TIMING
                   3006:     time_t cur, last;
1.29      veillard 3007: 
1.31      veillard 3008:     last = time(NULL);
                   3009: #endif
1.29      veillard 3010:     list = sqlRpmAll();
                   3011:     if (list == NULL) {
                   3012:        fprintf(stderr, "no package in database\n");
                   3013:        return;
                   3014:     }
1.31      veillard 3015: #ifdef SQL_DEBUG_TIMING
                   3016:     cur = time(NULL);
                   3017:     fprintf(stderr, "sqlRpmAll took %d seconds\n", (int)(cur - last));
                   3018:     last = cur;
                   3019: #endif
                   3020: 
                   3021:     rpmNameSort(&list, 0);
                   3022:     dumpRpmByName(rpmSoftwareList, 0);
                   3023: 
                   3024: #ifdef SQL_DEBUG_TIMING
                   3025:     cur = time(NULL);
                   3026:     fprintf(stderr, "dumpRpmByName took %d seconds\n", (int)(cur - last));
                   3027:     last = cur;
                   3028: #endif
                   3029: 
                   3030:     rpmGroupSort(&list, 0);
1.32      daniel   3031:     dumpRpmByGroups(rpmSoftwareList, 0);
1.31      veillard 3032: 
                   3033: #ifdef SQL_DEBUG_TIMING
                   3034:     cur = time(NULL);
                   3035:     fprintf(stderr, "dumpRpmByGroups took %d seconds\n", (int)(cur - last));
                   3036:     last = cur;
                   3037: #endif
1.35      veillard 3038: 
                   3039:     rpmVendorSort(&list, 0);
                   3040:     dumpRpmByVendors(list, 0);
                   3041: 
                   3042: #ifdef SQL_DEBUG_TIMING
                   3043:     cur = time(NULL);
                   3044:     fprintf(stderr, "dumpRpmByVendors took %d seconds\n", (int)(cur - last));
1.36      veillard 3045:     last = cur;
                   3046: #endif
                   3047: 
                   3048:     rpmDistribSort(&list, 0);
                   3049:     dumpRpmByDistribs(list, 0);
                   3050: 
                   3051: #ifdef SQL_DEBUG_TIMING
                   3052:     cur = time(NULL);
                   3053:     fprintf(stderr, "dumpRpmByDistribs took %d seconds\n", (int)(cur - last));
1.35      veillard 3054:     last = cur;
                   3055: #endif
                   3056: 
1.39      daniel   3057:     rpmDateSort(&list, 0);
1.37      veillard 3058:     dumpRpmByDate(list, 0);
                   3059: 
                   3060: #ifdef SQL_DEBUG_TIMING
                   3061:     cur = time(NULL);
                   3062:     fprintf(stderr, "dumpRpmByDate took %d seconds\n", (int)(cur - last));
                   3063:     last = cur;
                   3064: #endif
                   3065: 
1.40      veillard 3066:     rpmdataCleanup();
                   3067:     sleep(30);
1.26      veillard 3068: }
                   3069: 
1.2       veillard 3070: /************************************************************************
                   3071:  *                                                                     *
                   3072:  *                     rpm2html configuration functions                *
                   3073:  *                                                                     *
                   3074:  ************************************************************************/
                   3075: 
                   3076: int readConfigSql(void) {
1.6       veillard 3077:     char query[MAX_QUERY];
1.3       veillard 3078:     MYSQL_RES *result;
                   3079:     MYSQL_ROW row;
1.4       veillard 3080:     int dir = 0;
1.3       veillard 3081: 
1.2       veillard 3082:     /*
1.3       veillard 3083:      * General configuration informations
1.2       veillard 3084:      */
1.6       veillard 3085:     snprintf(query, MAX_QUERY - 1, "SELECT Name,Value FROM Config");
                   3086:     query[MAX_QUERY - 1] = 0;
1.3       veillard 3087:     if (mysql_query(sql,query)) {
                   3088:        printf("sql_check_tables: SELECT Config failed %s\n",
                   3089:               mysql_error(sql));
                   3090:        return(-1);
                   3091:     }
                   3092: 
                   3093:     result = mysql_use_result(sql);
                   3094:     if (result) {
                   3095:        while((row = mysql_fetch_row(result)))
                   3096:        {
                   3097:            if ((row[0] == NULL) || (row[1] == NULL)) {
                   3098:                fprintf(stderr, "readConfigSql : found NULL value\n");
                   3099:                continue;
                   3100:            }
1.4       veillard 3101:            if (!strcmp(row[0], "dir"))
                   3102:                dir = 1;
1.3       veillard 3103:            addConfigEntry(RPM2HTML_NAME, row[0], row[1]);
                   3104:        }
                   3105:        mysql_free_result(result);
                   3106:     }
                   3107:     if(mysql_errno(sql)) {
1.5       veillard 3108:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.4       veillard 3109:     }
                   3110:     if (dir == 0) {
                   3111:        fprintf(stderr, "readConfigSql : no directory\n");
                   3112:        return(-1);
1.3       veillard 3113:     }
                   3114: 
                   3115:     /*
                   3116:      * The metadata mirror list.
                   3117:      */
1.6       veillard 3118:     snprintf(query, MAX_QUERY - 1, "SELECT URL FROM Metadata");
                   3119:     query[MAX_QUERY - 1] = 0;
1.3       veillard 3120:     if (mysql_query(sql,query)) {
                   3121:        printf("sql_check_tables: SELECT Metadata failed %s\n",
                   3122:               mysql_error(sql));
                   3123:        return(-1);
                   3124:     }
                   3125: 
                   3126:     result = mysql_use_result(sql);
                   3127:     if (result) {
                   3128:        while((row = mysql_fetch_row(result)))
                   3129:        {
                   3130:            if (row[0] == NULL) {
                   3131:                fprintf(stderr, "readConfigSql : found NULL metadata\n");
                   3132:                continue;
                   3133:            }
                   3134:            addConfigEntry("metadata", "mirror", row[0]);
                   3135:        }
                   3136:        mysql_free_result(result);
                   3137:     }
                   3138:     if(mysql_errno(sql)) {
1.5       veillard 3139:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 3140:     }
                   3141: 
                   3142:     /*
                   3143:      * The distribution lists
                   3144:      */
1.6       veillard 3145:     snprintf(query, MAX_QUERY - 1, "SELECT Directory,Name,URL,URLSrc,Path FROM Distribs");
                   3146:     query[MAX_QUERY - 1] = 0;
1.3       veillard 3147:     if (mysql_query(sql,query)) {
                   3148:        printf("sql_check_tables: SELECT Distribs failed %s\n",
                   3149:               mysql_error(sql));
                   3150:        return(-1);
                   3151:     }
                   3152: 
                   3153:     result = mysql_use_result(sql);
                   3154:     if (result) {
                   3155:        while((row = mysql_fetch_row(result)))
                   3156:        {
                   3157:            if (row[0] == NULL) {
                   3158:                fprintf(stderr, "readConfigSql : found NULL distro\n");
                   3159:                continue;
                   3160:            }
                   3161: 
                   3162:            if (row[1] != NULL)
                   3163:                addConfigEntry(row[0], "name", row[1]);
                   3164:            if (row[2] != NULL)
                   3165:                addConfigEntry(row[0], "ftp", row[2]);
                   3166:            if (row[3] != NULL)
                   3167:                addConfigEntry(row[0], "ftp", row[3]);
                   3168:            if (row[4] != NULL)
                   3169:                addConfigEntry(row[0], "subdir", row[4]);
                   3170:        }
                   3171:        mysql_free_result(result);
                   3172:     }
                   3173:     if(mysql_errno(sql)) {
1.5       veillard 3174:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 3175:     }
                   3176: 
                   3177:     /*
                   3178:      * The Mirrors
                   3179:      */
1.6       veillard 3180:     snprintf(query, MAX_QUERY - 1, "SELECT Distribs.Directory,Mirrors.URL FROM Distribs,Mirrors WHERE Distribs.ID = Mirrors.ID");
                   3181:     query[MAX_QUERY - 1] = 0;
1.3       veillard 3182:     if (mysql_query(sql,query)) {
                   3183:        printf("sql_check_tables: SELECT Distribs failed %s\n",
                   3184:               mysql_error(sql));
                   3185:        return(-1);
                   3186:     }
                   3187: 
                   3188:     result = mysql_use_result(sql);
                   3189:     if (result) {
                   3190:        while((row = mysql_fetch_row(result)))
                   3191:        {
                   3192:            if ((row[0] == NULL) || (row[1] == NULL)) {
                   3193:                fprintf(stderr, "readConfigSql : found NULL mirror\n");
                   3194:                continue;
                   3195:            }
                   3196: 
                   3197:            addConfigEntry(row[0], "mirror", row[1]);
                   3198:        }
                   3199:        mysql_free_result(result);
                   3200:     }
                   3201:     if(mysql_errno(sql)) {
1.5       veillard 3202:        fprintf(stderr, "sql_show_stats error: %s\n", mysql_error(sql));
1.3       veillard 3203:     }
                   3204: 
1.5       veillard 3205:     /*
                   3206:      * TODO: add the language(s) stuff
                   3207:      */
1.3       veillard 3208:     return(0);
1.2       veillard 3209: }
                   3210: 
                   3211: void sqlConfigEntry(const char *rpmdir, const char *name, const char *value) {
                   3212:     int distrib;
                   3213: 
                   3214:     if (rpm2htmlVerbose > 1)
                   3215:        printf("sqlConfigEntry(\"%s\", \"%s\", \"%s\")\n", rpmdir, name, value);
                   3216: 
                   3217:     /*
                   3218:      * case of global option for rpm2html.
                   3219:      */
                   3220:     if (!strcasecmp(rpmdir, RPM2HTML_NAME)) {
1.5       veillard 3221:        sql_add_config_info(name, value);
1.2       veillard 3222:        return;
                   3223:     }
                   3224: 
                   3225:     /*
                   3226:      * Options for the metadata mirrors.
                   3227:      */
                   3228:     if (!strcasecmp(rpmdir, "metadata")) {
                   3229:        if (!strcasecmp(name, "mirror")) {
1.5       veillard 3230:            sql_add_metadata_base(value);
1.2       veillard 3231:        } else {
                   3232:            printf("Config file : %s entry for [metadata] ignored\n", name);
                   3233:        }
                   3234:        return;
                   3235:     }
                   3236: 
                   3237:     /*
                   3238:      * option for a directory.
                   3239:      */
                   3240:     if (!strcasecmp(name, "name")) {
1.9       veillard 3241:        sql_add_distrib(value, NULL, rpmdir, NULL, NULL, NULL, NULL,
                   3242:                        NULL, NULL);
1.2       veillard 3243:     } else if (!strcasecmp(name, "subdir")) {
                   3244:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3245:        if (distrib > 0)
                   3246:             sql_update_id("Distribs", distrib, "Path", value);
                   3247:     } else if (!strcasecmp(name, "url")) {
                   3248:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3249:        if (distrib > 0)
                   3250:             sql_update_id("Distribs", distrib, "URL", value);
                   3251:     } else if (!strcasecmp(name, "ftp")) {
                   3252:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3253:        if (distrib > 0)
                   3254:             sql_update_id("Distribs", distrib, "URL", value);
                   3255:     } else if (!strcasecmp(name, "ftpsrc")) {
                   3256:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3257:        if (distrib > 0)
                   3258:             sql_update_id("Distribs", distrib, "URLSrc", value);
1.9       veillard 3259:     } else if (!strcasecmp(name, "html")) {
                   3260:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3261:        if (distrib > 0)
                   3262:             sql_update_id("Distribs", distrib, "Html", value);
                   3263:     } else if (!strcasecmp(name, "color")) {
                   3264:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3265:        if (distrib > 0)
                   3266:             sql_update_id("Distribs", distrib, "Color", value);
1.2       veillard 3267:     } else if (!strcasecmp(name, "mirror")) {
                   3268:        distrib = sql_read_info_key("Distribs", "Directory", rpmdir);
                   3269:        if (distrib > 0)
1.5       veillard 3270:            sql_add_dist_mirror(distrib, value, 0);
1.2       veillard 3271:     } else {
                   3272:        printf("Config file : %s entry for [%s] ignored\n", name, rpmdir);
                   3273:     }
                   3274: }
1.1       veillard 3275: 

Webmaster