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