Annotation of rpm2html/rpmopen.c, revision 1.80
1.1 veillard 1: /*
2: * rpmopen.c : open an extract informations from RPM files.
3: *
1.50 veillard 4: * See Copyright for the status of this software.
1.1 veillard 5: *
1.80 ! veillard 6: * $Id: rpmopen.c,v 1.79 2000/09/08 10:54:03 veillard Exp $
1.1 veillard 7: */
8:
1.9 veillard 9: #include <config.h>
1.1 veillard 10: #include <sys/types.h>
11: #include <sys/stat.h>
1.9 veillard 12: #ifdef HAVE_FCNTL_H
1.1 veillard 13: #include <fcntl.h>
1.9 veillard 14: #endif
1.1 veillard 15: #include <stdio.h>
16: #include <stdlib.h>
17: #include <string.h>
1.9 veillard 18: #ifdef HAVE_UNISTD_H
1.1 veillard 19: #include <unistd.h>
1.9 veillard 20: #endif
1.6 veillard 21: #include <dirent.h>
1.13 veillard 22: #include <errno.h>
1.31 veillard 23: #include <time.h>
1.1 veillard 24:
25: #include <rpm/rpmlib.h>
1.70 daniel 26: #include <rpm/rpmmacro.h> /* Added by A. Gibert */
1.1 veillard 27:
1.77 veillard 28: #include "rpm2html.h"
1.1 veillard 29: #include "rpmdata.h"
1.7 veillard 30: #include "html.h"
1.40 httpng 31: #include "rdf.h"
1.12 veillard 32: #include "language.h"
1.75 veillard 33: #ifdef WITH_SQL
34: #include "sql.h"
35: #endif
1.1 veillard 36:
1.66 daniel 37: #ifndef HAVE_SNPRINTF
38: #error You really need snprintf ...
39: #endif
1.1 veillard 40: /*
1.69 daniel 41: * Get the internal number associated with an RPM tag.
1.1 veillard 42: */
43: static int getTagNumber(char *tag) {
44: int i;
45: const struct headerTagTableEntry * t;
46:
47: for (i = 0, t = rpmTagTable; i < rpmTagTableSize; i++, t++) {
48: if (!strcasecmp(tag, t->name)) return(t->val);
49: }
50: fprintf(stderr, "getTagNumber(%s) : unknown tag !\n", tag);
51: return(-1);
52: }
53:
54: /*
1.58 daniel 55: * Free up the extra data not needed for the last stage processing.
56: */
57:
58: void rpmFreeExtraData(rpmDataPtr rpm) {
59: rpmExtraDataPtr extra;
60:
61: if ((rpm == NULL) || (rpm->extra == NULL)) return;
62: extra = rpm->extra;
1.61 daniel 63: if (extra->packager != NULL) debugFree(extra->packager);
64: if (extra->description != NULL) debugFree(extra->description);
65: if (extra->copyright != NULL) debugFree(extra->copyright);
66: if (extra->changelog != NULL) debugFree(extra->changelog);
67: if (extra->srcrpm != NULL) debugFree(extra->srcrpm);
68: if (extra->host != NULL) debugFree(extra->host);
69: if (extra->resources != NULL) debugFree(extra->resources);
70: if (extra->requires != NULL) debugFree(extra->requires);
71: if (extra->filelist != NULL) debugFree(extra->filelist);
72: debugFree(extra);
1.58 daniel 73: }
74:
75: /*
1.59 daniel 76: * check a dependancy name to get rid of bad deps due to bad scripts
1.55 daniel 77: * or spec files.
1.53 veillard 78: */
79: int checkResourceName(const char *res) {
1.59 daniel 80: int isname = 0;
81: const char *base = res;
1.55 daniel 82:
1.53 veillard 83: if (*res == 0) return(0);
1.55 daniel 84:
85: /*
1.59 daniel 86: * we only accept absolute pathnames.
1.55 daniel 87: */
1.59 daniel 88: if (*res == '/') isname = 1;
1.53 veillard 89: while (*res != 0) {
1.59 daniel 90: if (((*res >= 'A') && (*res <= 'Z')) ||
91: ((*res >= 'a') && (*res <= 'z')) ||
1.53 veillard 92: ((*res >= '0') && (*res <= '9')) ||
1.55 daniel 93: (*res == '-') || (*res == '.') ||
94: (*res == '@') || (*res == '_') ||
1.59 daniel 95: (*res == '+') ||
96: ((*res == '/') && (isname == 1)))
1.53 veillard 97: res++;
98: else
99: return(0);
1.59 daniel 100: if ((res - base) > 100) return(0);
101: }
102: return(1);
103: }
104:
105: /*
106: * check a release name
107: */
108: int checkReleaseName(const char *res) {
109: const char *base = res;
110:
111: if (*res == 0) return(0);
112:
113: while (*res != 0) {
114: if (((*res >= 'A') && (*res <= 'Z')) ||
115: ((*res >= 'a') && (*res <= 'z')) ||
116: ((*res >= '0') && (*res <= '9')) ||
117: (*res == '-') || (*res == '.') ||
118: (*res == '@') || (*res == '_') ||
119: (*res == '+'))
120: res++;
121: else
122: return(0);
123: if ((res - base) > 20) return(0);
124: }
125: return(1);
126: }
127:
128: /*
129: * check a group name
130: */
131: int checkGroupName(const char *res) {
132: const char *base = res;
133:
134: /* Grrr !!! Suse packages have an empty Group name
135: if (*res == 0) return(0);
136: */
137:
138: while (*res != 0) {
139: if (((*res >= 'A') && (*res <= 'Z')) ||
140: ((*res >= 'a') && (*res <= 'z')) ||
141: ((*res >= '0') && (*res <= '9')) ||
142: (*res == ' ') || (*res == '.') ||
143: (*res == '+') || (*res == '/') ||
144: (*res == '-'))
145: res++;
146: else
147: return(0);
148: if ((res - base) > 60) return(0);
149: }
150: return(1);
151: }
152:
153: /*
154: * check a version name
155: */
156: int checkVersionName(const char *res) {
157: const char *base = res;
158:
159: if (*res == 0) return(0);
160:
161: while (*res != 0) {
162: if (((*res >= 'A') && (*res <= 'Z')) ||
163: ((*res >= 'a') && (*res <= 'z')) ||
164: ((*res >= '0') && (*res <= '9')) ||
165: (*res == '-') || (*res == '.') ||
166: (*res == '@') || (*res == '_') ||
167: (*res == '+'))
168: res++;
169: else
170: return(0);
171: if ((res - base) > 20) return(0);
1.53 veillard 172: }
173: return(1);
174: }
1.60 daniel 175:
1.53 veillard 176: /*
1.11 veillard 177: * rpmAnalyze : analyze an RPM record, read and parse the header and
178: * fill the informations in the database.
1.1 veillard 179: */
1.62 daniel 180: #define ENTRY_CLEANUP(p) \
181: if ((type == RPM_STRING_ARRAY_TYPE || type == RPM_I18NSTRING_TYPE)&&\
182: (p != NULL)) { free((p)); p = NULL; }
183:
1.60 daniel 184: static char *buffer = NULL;
185: static int buffer_size = 50 * 1024 * sizeof(char);
1.61 daniel 186:
1.75 veillard 187: rpmDataPtr rpmAnalyze(char *path, char *nameRpm, Header h, rpmDirPtr dir,
1.52 daniel 188: rpmSubdirPtr tree, time_t stamp, int isSource) {
1.11 veillard 189: int installed = dir->installbase;
1.2 veillard 190: char * name = NULL, * version = NULL, * release = NULL;
1.1 veillard 191: int_32 count, type;
1.2 veillard 192: void * p = NULL;
1.10 veillard 193: int val, i, j;
1.1 veillard 194: rpmDataPtr rpm = NULL;
1.11 veillard 195: static char nameBuffer[500];
1.75 veillard 196: #ifdef WITH_SQL
197: int id;
198: #endif
1.1 veillard 199:
1.41 veillard 200: if (buffer == NULL) {
1.61 daniel 201: buffer = (char *) debugMalloc(buffer_size);
1.41 veillard 202: if (buffer == NULL) {
203: fprintf(stderr, "cannot allocate %d bytes: %s\n", buffer_size,
204: strerror(errno));
205: exit(1);
206: }
207: }
208:
1.1 veillard 209: /* extract informations from the header */
210: headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &count);
1.49 veillard 211: if (name == NULL) {
212: fprintf(stderr, "Invalid package %s : no name\n", nameRpm);
213: return(NULL);
214: }
215: if (!(((name[0] >= 'a') && (name[0] <= 'z')) ||
216: ((name[0] >= 'A') && (name[0] <= 'Z')) ||
217: ((name[0] >= '0') && (name[0] <= '9')))) {
218: fprintf(stderr, "Invalid package %s : garbled name\n", nameRpm);
1.62 daniel 219: ENTRY_CLEANUP(name)
1.49 veillard 220: return(NULL);
221: }
1.59 daniel 222: if (!checkResourceName(name)) {
223: fprintf(stderr, "Invalid package %s : garbled name\n", nameRpm);
1.62 daniel 224: ENTRY_CLEANUP(name)
1.59 daniel 225: return(NULL);
226: }
1.1 veillard 227: headerGetEntry(h, RPMTAG_VERSION, &type, (void **) &version, &count);
1.49 veillard 228: if ((version == NULL) || (version[0] == 0)) {
229: fprintf(stderr, "Invalid package %s : version invalid\n", nameRpm);
1.62 daniel 230: ENTRY_CLEANUP(name)
231: ENTRY_CLEANUP(version)
1.49 veillard 232: return(NULL);
233: }
1.59 daniel 234: if (!checkVersionName(version)) {
235: fprintf(stderr, "Invalid package %s : garbled version\n", nameRpm);
1.62 daniel 236: ENTRY_CLEANUP(name)
237: ENTRY_CLEANUP(version)
1.59 daniel 238: return(NULL);
239: }
1.1 veillard 240: headerGetEntry(h, RPMTAG_RELEASE, &type, (void **) &release, &count);
1.49 veillard 241: if ((release == NULL) || (release[0] == 0)) {
242: fprintf(stderr, "Invalid package %s : release invalid\n", nameRpm);
1.62 daniel 243: ENTRY_CLEANUP(name)
244: ENTRY_CLEANUP(version)
245: ENTRY_CLEANUP(release)
1.49 veillard 246: return(NULL);
247: }
1.59 daniel 248: if (!checkReleaseName(release)) {
249: fprintf(stderr, "Invalid package %s : garbled release\n", nameRpm);
1.62 daniel 250: ENTRY_CLEANUP(name)
251: ENTRY_CLEANUP(version)
252: ENTRY_CLEANUP(release)
1.59 daniel 253: return(NULL);
254: }
1.1 veillard 255:
1.58 daniel 256: /* allocate a new rpmData block, and an rpmExtraData block fill them */
1.61 daniel 257: rpm = (rpmDataPtr) debugMalloc(sizeof(rpmData));
1.1 veillard 258: if (rpm == NULL) {
1.41 veillard 259: fprintf(stderr, "cannot allocate %d bytes: %s\n", sizeof(rpmData),
260: strerror(errno));
261: return(NULL);
1.1 veillard 262: }
1.44 veillard 263: memset(rpm, 0, sizeof(rpmData));
1.61 daniel 264: rpm->extra = (rpmExtraDataPtr) debugMalloc(sizeof(rpmExtraData));
1.58 daniel 265: if (rpm == NULL) {
266: fprintf(stderr, "cannot allocate %d bytes: %s\n", sizeof(rpmExtraData),
267: strerror(errno));
268: return(NULL);
269: }
270: memset(rpm->extra, 0, sizeof(rpmExtraData));
1.6 veillard 271: rpm->dir = dir;
1.36 veillard 272: if (tree) {
273: if ((tree->rpmpath != NULL) && (tree->rpmpath[0] != '\0'))
1.61 daniel 274: rpm->subdir = stringAdd(tree->rpmpath);
1.36 veillard 275: else
276: rpm->subdir = NULL;
277: } else
278: rpm->subdir = NULL;
1.58 daniel 279: rpm->extra->stamp = stamp;
1.61 daniel 280: rpm->name = stringAdd(name);
1.62 daniel 281: ENTRY_CLEANUP(name)
1.61 daniel 282: rpm->version = stringAdd(version);
1.62 daniel 283: ENTRY_CLEANUP(version)
1.61 daniel 284: rpm->release = stringAdd(release);
1.62 daniel 285: ENTRY_CLEANUP(release)
1.1 veillard 286:
1.26 veillard 287: /* get all the resources provided by this RPM */
1.2 veillard 288: if (!headerGetEntry(h, RPMTAG_SUMMARY, &type, &p, &count) || !p) {
1.61 daniel 289: rpm->summary = debugStrdup(localizedStrings[LANG_NO_SUMMARY]);
1.2 veillard 290: } else {
1.61 daniel 291: rpm->summary = debugStrdup((char *) p);
1.2 veillard 292: }
1.62 daniel 293: ENTRY_CLEANUP(p);
1.28 veillard 294: if (!headerGetEntry(h, RPMTAG_DESCRIPTION, &type, &p, &count) || !p ||
295: (type != RPM_STRING_TYPE)) {
1.61 daniel 296: rpm->extra->description = debugStrdup(localizedStrings[LANG_NO_DESCRIPTION]);
1.2 veillard 297: } else {
1.61 daniel 298: rpm->extra->description = debugStrdup((char *) p);
1.2 veillard 299: }
1.62 daniel 300: ENTRY_CLEANUP(p);
1.28 veillard 301: if (!headerGetEntry(h, RPMTAG_DISTRIBUTION, &type, &p, &count) || !p ||
302: (type != RPM_STRING_TYPE)) {
1.61 daniel 303: rpm->distribution = stringAdd(localizedStrings[LANG_UNKNOWN]);
1.2 veillard 304: } else {
1.61 daniel 305: rpm->distribution = stringAdd((char *) p);
1.2 veillard 306: }
1.62 daniel 307: ENTRY_CLEANUP(p);
1.52 daniel 308: if (isSource) {
1.61 daniel 309: rpm->arch = stringAdd("src");
1.11 veillard 310: if (nameRpm == NULL) {
1.66 daniel 311: snprintf(nameBuffer, sizeof(nameBuffer), "%s-%s-%s.src.rpm",
1.52 daniel 312: name, version, release);
1.11 veillard 313: nameRpm = nameBuffer;
314: }
1.2 veillard 315: } else {
1.52 daniel 316: if (!headerGetEntry(h, RPMTAG_ARCH, &type, &p, &count) || !p ||
317: (type != RPM_STRING_TYPE)) {
318: if (type == RPM_INT8_TYPE) {
319: /*
320: * Old packages.
321: */
322: switch (*((char *) p)) {
323: case 1:
1.61 daniel 324: rpm->arch = stringAdd("i386");
1.52 daniel 325: break;
326: default:
1.61 daniel 327: rpm->arch = stringAdd("src");
1.52 daniel 328: break;
329: }
330: } else
1.61 daniel 331: rpm->arch = stringAdd(localizedStrings[LANG_NONE]);
1.52 daniel 332: if (nameRpm == NULL) {
1.66 daniel 333: snprintf(nameBuffer, sizeof(nameBuffer), "%s-%s-%s.rpm", name, version, release);
1.52 daniel 334: nameRpm = nameBuffer;
335: }
336: } else {
1.61 daniel 337: rpm->arch = stringAdd((char *) p);
1.52 daniel 338: if (nameRpm == NULL) {
1.66 daniel 339: snprintf(nameBuffer, sizeof(nameBuffer), "%s-%s-%s.%s.rpm",
1.52 daniel 340: name, version, release, (char *)p);
341: nameRpm = nameBuffer;
342: }
1.11 veillard 343: }
1.62 daniel 344: ENTRY_CLEANUP(p);
1.2 veillard 345: }
1.28 veillard 346: if (!headerGetEntry(h, RPMTAG_OS, &type, &p, &count) || !p ||
347: (type != RPM_STRING_TYPE)) {
1.29 veillard 348: if (type == RPM_INT8_TYPE) {
349: /*
1.32 veillard 350: * Old packages.
1.29 veillard 351: */
352: switch (*((char *) p)) {
353: case 1:
1.61 daniel 354: rpm->os = stringAdd("linux");
1.29 veillard 355: break;
356: default:
1.61 daniel 357: rpm->os = stringAdd("linux");
1.29 veillard 358: break;
359: }
360: } else
1.61 daniel 361: rpm->os = stringAdd("");
1.7 veillard 362: } else {
1.61 daniel 363: rpm->os = stringAdd((char *) p);
1.7 veillard 364: }
1.62 daniel 365: ENTRY_CLEANUP(p);
1.28 veillard 366: if (!headerGetEntry(h, RPMTAG_VENDOR, &type, &p, &count) || !p ||
367: (type != RPM_STRING_TYPE)) {
1.7 veillard 368: rpm->vendor = NULL;
1.2 veillard 369: } else {
1.61 daniel 370: rpm->vendor = stringAdd((char *) p);
1.2 veillard 371: }
1.62 daniel 372: ENTRY_CLEANUP(p);
1.28 veillard 373: if (!headerGetEntry(h, RPMTAG_GROUP, &type, &p, &count) || !p ||
374: (type != RPM_STRING_TYPE)) {
1.61 daniel 375: rpm->group = stringAdd(localizedStrings[LANG_NO_GROUP]);
1.2 veillard 376: } else {
1.61 daniel 377: rpm->group = stringAdd((char *) p);
1.59 daniel 378: }
1.62 daniel 379: ENTRY_CLEANUP(p);
1.59 daniel 380: if (!checkGroupName(rpm->group)) {
381: fprintf(stderr, "Invalid package %s : garbled group\n", nameRpm);
1.74 daniel 382: if (rpm->name)
383: stringFree(rpm->name);
384: if (rpm->version)
385: stringFree(rpm->version);
386: if (rpm->release)
387: stringFree(rpm->release);
388: if (rpm->summary)
389: debugFree(rpm->summary);
390: if (rpm->distribution)
391: stringFree(rpm->distribution);
392: if (rpm->arch)
393: stringFree(rpm->arch);
394: if (rpm->os)
395: stringFree(rpm->os);
396: if (rpm->vendor != NULL)
397: stringFree(rpm->vendor);
398: if (rpm->group != NULL)
399: stringFree(rpm->group);
1.61 daniel 400: debugFree(rpm);
1.59 daniel 401: return(NULL);
1.2 veillard 402: }
1.28 veillard 403: if (!headerGetEntry(h, RPMTAG_BUILDHOST, &type, &p, &count) || !p ||
404: (type != RPM_STRING_TYPE)) {
1.61 daniel 405: rpm->extra->host = debugStrdup(localizedStrings[LANG_NO_HOST]);
1.2 veillard 406: } else {
1.61 daniel 407: rpm->extra->host = debugStrdup((char *) p);
1.2 veillard 408: }
1.62 daniel 409: ENTRY_CLEANUP(p);
1.2 veillard 410: if (!headerGetEntry(h, RPMTAG_SIZE, &type, &p, &count) || !p) {
411: rpm->size = 0;
412: } else {
413: rpm->size = *((int *) p);
414: }
1.62 daniel 415: ENTRY_CLEANUP(p);
1.11 veillard 416: if (installed) {
417: if (!headerGetEntry(h, RPMTAG_INSTALLTIME, &type, &p, &count) || !p) {
418: rpm->date = 0;
419: } else {
420: rpm->date = *((int_32 *) p);
421: }
1.62 daniel 422: ENTRY_CLEANUP(p);
1.2 veillard 423: } else {
1.11 veillard 424: if (!headerGetEntry(h, RPMTAG_BUILDTIME, &type, &p, &count) || !p) {
425: rpm->date = 0;
426: } else {
427: rpm->date = *((int_32 *) p);
428: }
1.62 daniel 429: ENTRY_CLEANUP(p);
1.2 veillard 430: }
1.28 veillard 431: if (!headerGetEntry(h, RPMTAG_SOURCERPM, &type, &p, &count) || !p ||
432: (type != RPM_STRING_TYPE)) {
1.61 daniel 433: rpm->extra->srcrpm = debugStrdup("");
1.2 veillard 434: } else {
1.61 daniel 435: rpm->extra->srcrpm = debugStrdup((char *) p);
1.2 veillard 436: }
1.62 daniel 437: ENTRY_CLEANUP(p);
1.28 veillard 438: if (!headerGetEntry(h, RPMTAG_URL, &type, &p, &count) || !p ||
439: (type != RPM_STRING_TYPE)) {
1.7 veillard 440: rpm->url = NULL;
441: } else {
1.61 daniel 442: rpm->url = debugStrdup((char *) p);
1.7 veillard 443: }
1.62 daniel 444: ENTRY_CLEANUP(p);
1.28 veillard 445: if (!headerGetEntry(h, RPMTAG_PACKAGER, &type, &p, &count) || !p ||
446: (type != RPM_STRING_TYPE)) {
1.58 daniel 447: rpm->extra->packager = NULL;
1.7 veillard 448: } else {
1.61 daniel 449: rpm->extra->packager = debugStrdup((char *) p);
1.7 veillard 450: }
1.62 daniel 451: ENTRY_CLEANUP(p);
1.28 veillard 452: if (!headerGetEntry(h, RPMTAG_COPYRIGHT, &type, &p, &count) || !p ||
453: (type != RPM_STRING_TYPE)) {
1.58 daniel 454: rpm->extra->copyright = NULL;
1.7 veillard 455: } else {
1.61 daniel 456: rpm->extra->copyright = debugStrdup((char *) p);
1.7 veillard 457: }
1.62 daniel 458: ENTRY_CLEANUP(p);
1.31 veillard 459: /* Pick up changelog entries */
460: if (!headerGetEntry(h, RPMTAG_CHANGELOGTEXT, &type, &p, &count) || !p) {
1.58 daniel 461: rpm->extra->changelog = NULL;
1.31 veillard 462: } else {
463: time_t *dates;
464: char **names;
465: char **holdp = (char **)p;
466: char *cp;
467: struct tm *tm_buf;
468: int i, len, pos;
469: char date_string[50];
470: char *res = buffer;
1.42 veillard 471:
1.31 veillard 472: *res = '\0';
473: headerGetEntry(h, RPMTAG_CHANGELOGTIME, &type, (void *)&dates, &count);
474: headerGetEntry(h, RPMTAG_CHANGELOGNAME, &type, (void *)&names, &count);
475: for (i = 0; i < count; i++) {
1.42 veillard 476: if ((res - buffer) > (buffer_size - 1024)) {
477: int delta = res - buffer;
478:
1.41 veillard 479: buffer_size *= 2;
1.61 daniel 480: buffer = (char *) debugRealloc(buffer, buffer_size);
1.42 veillard 481: if (buffer == NULL) {
482: fprintf(stderr, "cannot re-allocate %d bytes: %s\n",
483: buffer_size, strerror(errno));
484: exit(1);
485: }
486: res = &buffer[delta];
1.41 veillard 487: }
1.31 veillard 488: tm_buf = localtime(&dates[i]);
489: strftime(date_string, sizeof(date_string) - 1, "%a %b %d %Y", tm_buf);
1.66 daniel 490: len = snprintf(res, buffer_size, "* %s %s\n", date_string, names[i]);
1.31 veillard 491: res += len;
492: cp = holdp[i];
493: pos = 0;
494: while (*cp) {
495: if (pos++ == 0) {
496: *res++ = ' ';
497: *res++ = ' ';
498: }
499: *res++ = *cp;
500: if (*cp++ == '\n') pos = 0;
501: }
502: *res++ = '\n';
503: }
504: *res = '\0';
1.61 daniel 505: rpm->extra->changelog = debugStrdup(buffer);
1.31 veillard 506: }
1.62 daniel 507: ENTRY_CLEANUP(p);
1.7 veillard 508: if (rpm->vendor == NULL) {
1.61 daniel 509: if (rpm->extra->packager != NULL) rpm->vendor = debugStrdup(rpm->extra->packager);
510: else rpm->vendor = debugStrdup(localizedStrings[LANG_UNKNOWN]);
1.7 veillard 511: }
1.2 veillard 512:
1.61 daniel 513: rpm->filename = debugStrdup(nameRpm);
1.11 veillard 514:
1.48 veillard 515: /* package-xxx.rpm provides at least the resource "package" */
1.1 veillard 516: val = getTagNumber("RPMTAG_PROVIDES");
517: if (!headerGetEntry(h, val, &type, &p, &count) || !p) {
1.58 daniel 518: rpm->extra->nb_resources = 1;
519: rpm->extra->max_resources = 1;
1.61 daniel 520: rpm->extra->resources = (rpmRessPtr *) debugMalloc(sizeof(rpmRessPtr) *
1.58 daniel 521: rpm->extra->max_resources);
522: if (rpm->extra->resources == NULL) {
1.48 veillard 523: fprintf(stderr, ": ran out of memory\n");
524: exit(1);
525: }
1.58 daniel 526: rpm->extra->resources[0] = rpmRessAdd(name, rpm, installed);
1.1 veillard 527: } else {
1.58 daniel 528: rpm->extra->max_resources = count + 1;
1.61 daniel 529: rpm->extra->resources = (rpmRessPtr *) debugMalloc(sizeof(rpmRessPtr) *
1.58 daniel 530: rpm->extra->max_resources);
531: if (rpm->extra->resources == NULL) {
1.48 veillard 532: fprintf(stderr, ": ran out of memory\n");
533: exit(1);
1.1 veillard 534: }
1.58 daniel 535: rpm->extra->resources[0] = rpmRessAdd(name, rpm, installed);
536: rpm->extra->nb_resources = 1;
1.1 veillard 537:
1.58 daniel 538: for (i = 0, j = rpm->extra->nb_resources; i < count;i++) {
1.53 veillard 539: if (!checkResourceName(((char **) p)[i])) continue;
1.58 daniel 540: rpm->extra->resources[j++] = rpmRessAdd(((char **) p)[i], rpm, installed);
1.4 veillard 541: }
1.58 daniel 542: rpm->extra->nb_resources = j;
1.4 veillard 543: }
1.62 daniel 544: ENTRY_CLEANUP(p);
1.4 veillard 545:
546: val = getTagNumber("RPMTAG_REQUIRENAME");
547: if (!headerGetEntry(h, val, &type, &p, &count) || !p) {
1.73 daniel 548: rpm->extra->nb_requires = 0;
1.58 daniel 549: rpm->extra->requires = NULL;
1.4 veillard 550: } else {
1.73 daniel 551: int_32 count2, count3, type2, type3;
552: void * q = NULL;
553: void * r = NULL;
554: int valv, valf;
1.4 veillard 555:
1.70 daniel 556: rpm->extra->max_requires = count;
557: rpm->extra->requires = (rpmRessPtr *) debugMalloc(sizeof(rpmRessPtr) *
558: rpm->extra->max_requires);
559: if (rpm->extra->requires == NULL) {
560: fprintf(stderr, ": ran out of memory\n");
561: exit(1);
562: }
1.73 daniel 563: valv = getTagNumber("RPMTAG_REQUIREVERSION");
564: valf = getTagNumber("RPMTAG_REQUIREFLAGS");
565: headerGetEntry(h, valv, &type2, &q, &count2);
566: headerGetEntry(h, valf, &type3, &r, &count3);
1.70 daniel 567:
568: rpm->extra->nb_requires = 0;
569:
1.73 daniel 570: for (i = 0, j = 0; (i < count2) && (i < count3);i++) {
1.70 daniel 571: long anint = *(((long *)r)+i);
1.77 veillard 572: rpm_dep_flag flag = RPM2HTML_REQ_NONE;
1.70 daniel 573:
1.77 veillard 574: if ((anint & RPMSENSE_LESS) && (anint & RPMSENSE_EQUAL))
575: flag = RPM2HTML_REQ_LEQ;
576: else if (anint & RPMSENSE_LESS)
577: flag = RPM2HTML_REQ_LT;
578: if ((anint & RPMSENSE_GREATER) && (anint & RPMSENSE_EQUAL))
579: flag = RPM2HTML_REQ_GEQ;
580: else if (anint & RPMSENSE_GREATER)
581: flag = RPM2HTML_REQ_GT;
582: else if (anint & RPMSENSE_EQUAL)
583: flag = RPM2HTML_REQ_EQU;
1.53 veillard 584: if (!checkResourceName(((char **) p)[i])) continue;
1.70 daniel 585: rpm->extra->requires[j++] =
586: rpmRequAdd(((char **) p)[i],((char **) q)[i],
1.77 veillard 587: flag , rpm, installed);
1.1 veillard 588: }
1.58 daniel 589: rpm->extra->nb_requires = j;
1.73 daniel 590: if ((type2 == RPM_STRING_ARRAY_TYPE || type2 == RPM_I18NSTRING_TYPE)&&
591: (q != NULL)) { free((q)); q = NULL; }
592: if ((type3 == RPM_STRING_ARRAY_TYPE || type3 == RPM_I18NSTRING_TYPE)&&
593: (r != NULL)) { free((r)); r = NULL; }
594: for (;i < count;i++)
1.77 veillard 595: rpmRequAdd(((char **) p)[i], NULL, RPM2HTML_REQ_NONE,
596: rpm, installed);
1.5 veillard 597: }
1.62 daniel 598: ENTRY_CLEANUP(p);
1.69 daniel 599:
600: #if defined(RPMTAG_FILENAMES)
1.5 veillard 601: val = getTagNumber("RPMTAG_FILENAMES");
1.69 daniel 602: headerGetEntry(h, val, &type, &p, &count);
603: #else
604: rpmBuildFileList(h, (const char ***) &p, &count);
605: #endif
606:
607: if (count == 0) {
1.58 daniel 608: rpm->extra->filelist = NULL; /* No filelist in the package ! */
1.5 veillard 609: } else {
610: char *ptr = buffer;
1.42 veillard 611:
1.5 veillard 612: for (i = 0; i < count;i++) {
1.42 veillard 613: if ((ptr - buffer) > (buffer_size - 1024)) {
614: int delta = ptr - buffer;
615:
1.41 veillard 616: buffer_size *= 2;
1.61 daniel 617: buffer = (char *) debugRealloc(buffer, buffer_size);
1.42 veillard 618: if (buffer == NULL) {
619: fprintf(stderr, "cannot re-allocate %d bytes: %s\n",
620: buffer_size, strerror(errno));
621: exit(1);
622: }
623: ptr = &buffer[delta];
1.41 veillard 624: }
1.66 daniel 625: ptr += snprintf(ptr, buffer_size, "%s\n", ((char **) p)[i]);
1.5 veillard 626: }
1.61 daniel 627: rpm->extra->filelist = debugStrdup(buffer);
1.1 veillard 628: }
1.62 daniel 629: ENTRY_CLEANUP(p);
1.1 veillard 630:
1.75 veillard 631: #ifdef WITH_SQL
632: id = sql_add_package(path, rpm->name, rpm->version, rpm->release,
633: rpm->arch, dir->no, rpm->url, rpm->extra->srcrpm,
634: dir->vendor, rpm->extra->packager,
635: rpm->group, rpm->summary, rpm->extra->description,
636: rpm->extra->copyright);
1.76 veillard 637: if (id > 0) {
638: for (i = 0;i < rpm->extra->nb_resources;i++)
639: sql_add_provides(id, rpm->extra->resources[i]->name);
640: for (i = 0;i < rpm->extra->nb_requires;i++)
641: sql_add_requires(id, rpm->extra->requires[i]->name,
1.77 veillard 642: rpm->extra->requires[i]->flag,
1.76 veillard 643: rpm->extra->requires[i]->version);
644: }
1.75 veillard 645: #endif
646:
1.37 veillard 647: /* Add the package files to the real filesystem tree if asked for */
1.75 veillard 648: #ifdef WITH_SQL
649: if ((rpm->extra->filelist != NULL) &&
650: ((dir->build_tree != 0) || (id > 0))) {
651: #else
1.58 daniel 652: if ((dir->build_tree != 0) && (rpm->extra->filelist != NULL)) {
1.75 veillard 653: #endif
1.37 veillard 654: char *cur, *filename;
655:
1.58 daniel 656: cur = rpm->extra->filelist;
1.37 veillard 657: while ((*cur != '\0') && (*cur != '/')) cur++;
658: filename = cur;
659: while (*cur != '\0') {
660: if ((*cur == '\n') || (*cur == '\r')) {
1.75 veillard 661: if (cur != filename) {
662: #ifdef WITH_SQL
663: if (dir->build_tree != 0)
664: rpmAddRealFile(dir->root, filename, rpm);
665: if (id > 0) {
666: *cur = 0;
667: sql_add_file(filename,id);
668: *cur = '\n';
669: }
670: #else
1.37 veillard 671: rpmAddRealFile(dir->root, filename, rpm);
1.75 veillard 672: #endif
673: }
1.37 veillard 674: while ((*cur != '\0') && (*cur != '/')) cur++;
675: filename = cur;
676: } else
677: cur++;
678: }
679: if (cur != filename)
680: rpmAddRealFile(dir->root, filename, rpm);
681: }
1.17 veillard 682:
683: /* Register this package */
684: rpmAddSoftware(rpm);
1.7 veillard 685:
686: /* dump the HTML related to this package */
1.56 daniel 687: if ((rpm2html_dump_html) && (dir->html))
1.40 httpng 688: dumpRpmHtml(rpm, tree);
689: if (rpm2html_dump_rdf)
690: dumpRpmRdf(rpm, tree);
1.7 veillard 691:
1.58 daniel 692: /* free the extra data */
693: rpmFreeExtraData(rpm);
1.8 veillard 694:
695: /* increment the counters */
1.11 veillard 696: if (installed) {
697: rpm2html_install_files++;
1.21 veillard 698: rpm2html_install_size += rpm->size / 1024;
1.11 veillard 699: } else {
700: rpm2html_files++;
1.21 veillard 701: rpm2html_size += rpm->size / 1024;
1.11 veillard 702: }
1.7 veillard 703:
1.32 veillard 704: return(rpm);
1.11 veillard 705: }
706:
707: /*
708: * rpmOpen : open an RPM file, read and parse the header and
709: * fill the informations in the database.
710: */
1.35 veillard 711: rpmDataPtr rpmOpen(char *nameRpm, rpmDirPtr dir, rpmSubdirPtr tree) {
1.32 veillard 712: rpmDataPtr cur;
1.64 daniel 713: #if defined(HAVE_RPM_RPMIO_H)
714: FD_t fd;
715: #else
1.11 veillard 716: int fd;
1.64 daniel 717: #define fdOpen(_a, _b, _c) open((_a), (_b))
718: #define fdClose(_a) close(_a)
719: #endif
1.11 veillard 720: int rc;
721: Header h = NULL;
722: int isSource;
723: char buffer[500];
1.20 veillard 724: struct stat buf;
1.11 veillard 725:
726: /* open the file for reading */
1.35 veillard 727: if (tree->htmlpath[0] != '\0')
1.66 daniel 728: snprintf(buffer, sizeof(buffer), "%s/%s/%s", dir->rpmdir, tree->rpmpath, nameRpm);
1.24 veillard 729: else
1.66 daniel 730: snprintf(buffer, sizeof(buffer), "%s/%s", dir->rpmdir, nameRpm);
1.72 daniel 731:
1.78 daniel 732: if (access(buffer, R_OK) < 0) {
733: fprintf(stderr, "open of %s failed: %s\n", buffer,
734: strerror(errno));
735: return(NULL);
736: }
1.72 daniel 737: #if defined(USE_RPMIO)
738: fd = Fopen(buffer, "r.fdio");
739: if (fd == NULL || Ferror(fd)) {
740: fprintf(stderr, "Fopen of %s failed: %s\n", buffer,
741: Fstrerror(fd));
742: return(NULL);
743: }
744: #else
1.64 daniel 745: if ((fd = fdOpen(buffer, O_RDONLY, 0)) < 0) {
1.11 veillard 746: fprintf(stderr, "open of %s failed: %s\n", buffer,
747: strerror(errno));
1.32 veillard 748: return(NULL);
1.11 veillard 749: }
1.72 daniel 750: #endif
1.11 veillard 751:
1.20 veillard 752: stat(buffer, &buf);
753:
1.11 veillard 754: /* read the RPM header */
755: rc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
756: switch (rc) {
757: case 0:
758: if (!h) {
759: fprintf(stderr,
760: "old format source packages cannot be queried\n");
1.68 veillard 761: fdClose(fd);
1.32 veillard 762: return(NULL);
1.11 veillard 763: }
764: break;
765: case 1:
766: fprintf(stderr, "%s does not appear to be a RPM package\n",
767: nameRpm);
1.68 veillard 768: fdClose(fd);
1.32 veillard 769: return(NULL);
1.11 veillard 770: case 2:
771: fprintf(stderr, "query of %s failed\n", nameRpm);
1.68 veillard 772: fdClose(fd);
1.32 veillard 773: return(NULL);
1.11 veillard 774: default:
775: fprintf(stderr, "rpmReadPackageHeader(%s): unknown error %d\n",
776: nameRpm, rc);
1.68 veillard 777: fdClose(fd);
1.32 veillard 778: return(NULL);
1.11 veillard 779: }
780:
1.75 veillard 781: cur = rpmAnalyze(buffer, nameRpm, h, dir, tree, buf.st_mtime, isSource);
1.11 veillard 782:
783: /* free the header and close the descriptor */
784: headerFree(h);
1.72 daniel 785: #if defined(USE_RPMIO)
786: Fclose(fd);
787: #else
1.64 daniel 788: fdClose(fd);
1.72 daniel 789: #endif
1.1 veillard 790:
1.32 veillard 791: return(cur);
1.6 veillard 792: }
793:
794: /*
1.22 veillard 795: * Scan one directory for RPM files this is where the recursive handling
796: * is done.
1.6 veillard 797: */
1.35 veillard 798: static rpmDataPtr rpmOneDirScan(rpmDirPtr dir, rpmSubdirPtr tree) {
799: rpmSubdirPtr subtree;
1.32 veillard 800: rpmDataPtr ret = NULL, cur;
1.7 veillard 801: char *filename;
1.22 veillard 802: static char path[2000];
1.23 veillard 803: struct stat buf;
1.7 veillard 804: int len;
1.39 veillard 805: DIR *d;
806: struct dirent *file;
1.6 veillard 807:
1.24 veillard 808:
809: /*
810: * Create the directory for the HTML pages
811: */
1.56 daniel 812: if ((rpm2html_dump_html) && (dir->html)) {
1.45 veillard 813: if (tree->htmlpath[0] != '\0')
1.66 daniel 814: snprintf(path, sizeof(path), "%s/%s", dir->dir, tree->htmlpath);
1.45 veillard 815: else
1.66 daniel 816: snprintf(path, sizeof(path), "%s", dir->dir);
1.45 veillard 817: createDirectory(path);
818: }
1.43 veillard 819:
820: /*
821: * Create the directory for the RDF pages
822: if (rpm2html_rdf_dir != NULL) {
823: if (tree->htmlpath[0] != '\0')
1.66 daniel 824: snprintf(path, sizeof(path), "%s/%s", rpm2html_rdf_dir, tree->htmlpath);
1.43 veillard 825: else
1.66 daniel 826: snprintf(path, sizeof(path), "%s", rpm2html_rdf_dir);
1.43 veillard 827: createDirectory(path);
828: }
1.47 veillard 829: */
1.24 veillard 830:
831: /*
832: * Scan the repository.
833: */
1.35 veillard 834: if (tree->rpmpath[0] != '\0')
1.66 daniel 835: snprintf(path, sizeof(path), "%s/%s", dir->rpmdir, tree->rpmpath);
1.24 veillard 836: else
1.66 daniel 837: snprintf(path, sizeof(path), "%s", dir->rpmdir);
1.51 veillard 838: if (rpm2htmlVerbose > 1)
1.66 daniel 839: printf("Scanning directory %s\n", path);
1.24 veillard 840:
1.39 veillard 841: d = opendir(path);
842: if (d == NULL) {
1.24 veillard 843: fprintf(stderr, "Listing of %s failed: %s\n", path,
1.6 veillard 844: strerror(errno));
1.35 veillard 845: rpmRemoveSubdir(tree);
1.36 veillard 846: rpmFreeSubdir(tree);
1.32 veillard 847: return(NULL);
1.6 veillard 848: } else {
1.39 veillard 849: while ((file = readdir(d)) != NULL) {
1.32 veillard 850: cur = NULL;
1.39 veillard 851: filename = file->d_name;
1.7 veillard 852: len = strlen(filename);
1.24 veillard 853:
854: /*
855: * Compute the full path
856: */
1.35 veillard 857: if (tree->rpmpath[0] != '\0')
1.66 daniel 858: snprintf(path, sizeof(path), "%s/%s/%s", dir->rpmdir, tree->rpmpath,
1.35 veillard 859: filename);
1.22 veillard 860: else
1.66 daniel 861: snprintf(path, sizeof(path), "%s/%s", dir->rpmdir, filename);
1.22 veillard 862:
863: /*
1.25 veillard 864: * Stat() the file to detect directory and symlimks
865: */
1.30 veillard 866: if (lstat(path, &buf) != 0) {
1.25 veillard 867: fprintf(stderr, "Couldn't stat(%s)\n", path);
868: continue;
869: }
1.35 veillard 870:
1.25 veillard 871: /*
1.23 veillard 872: * Check for RPM files by looking at the suffix
1.54 veillard 873: * Note that SuSE source RPMs have a ".spm" suffix
1.63 daniel 874: * We may or may not follow symlinks to RPM files
1.22 veillard 875: */
1.63 daniel 876: if (((len >= 5) &&
1.54 veillard 877: (!strcasecmp(&filename[len - 4], ".rpm"))) ||
878: ((len >= 5) &&
879: (!strcasecmp(&filename[len - 4], ".spm")))) {
1.63 daniel 880:
1.65 daniel 881: if ((S_ISLNK(buf.st_mode)) && (dir->rpm_symlinks == 0)) {
1.66 daniel 882: if (rpm2htmlVerbose > 1)
1.63 daniel 883: fprintf(stderr, "Dropping symlink %s\n", path);
884: continue;
885: }
1.35 veillard 886: cur = rpmOpen(filename, dir, tree);
1.63 daniel 887: }
888:
889: /*
890: * Don't follow of analyze symlinks,
891: */
1.65 daniel 892: else if ((S_ISLNK(buf.st_mode)) && (dir->follow_symlinks == 0)) {
1.66 daniel 893: if (rpm2htmlVerbose > 1)
1.63 daniel 894: fprintf(stderr, "Dropping symlink %s\n", path);
895: continue;
1.44 veillard 896: }
897:
898: /*
899: * Check for RDF files by looking at the suffix
900: */
901: else if ((len >= 5) && (!strcasecmp(&filename[len - 4], ".rdf"))) {
902: cur = rpmOpenRdf(filename, dir, tree);
1.22 veillard 903: }
1.35 veillard 904:
1.22 veillard 905: /*
1.23 veillard 906: * Else if this is a directory, recurse !
1.22 veillard 907: */
1.25 veillard 908: else if (S_ISDIR(buf.st_mode)) {
909: if (filename[0] != '.') {
1.57 daniel 910: subtree = rpmNewSubdir(tree, filename, NULL, NULL, NULL, 0);
1.35 veillard 911: cur = rpmOneDirScan(dir, subtree);
1.25 veillard 912: }
1.22 veillard 913: }
1.32 veillard 914: if (cur != NULL) ret = rpmAddList(ret, cur);
1.7 veillard 915: }
1.6 veillard 916: }
1.39 veillard 917: closedir(d);
1.33 veillard 918:
919: /*
920: * Dump the pages related to this directory.
921: */
1.35 veillard 922: if (ret != NULL) ret = dumpDirIndex(dir, tree, ret);
1.36 veillard 923: else {
924: rpmRemoveSubdir(tree);
925: rpmFreeSubdir(tree);
926: }
1.35 veillard 927:
1.32 veillard 928: return(ret);
1.22 veillard 929: }
930:
931: /*
932: * Scan a directory for RPM files.
933: */
1.35 veillard 934: static rpmDataPtr rpmDirScan(rpmDirPtr dir, rpmSubdirPtr tree) {
1.37 veillard 935: rpmSubdirPtr cur;
936: rpmDataPtr ret;
937:
1.56 daniel 938: if ((rpm2html_dump_html) && (dir->html) && (dir->build_tree != 0)) {
1.37 veillard 939: dir->root = rpmCreateRealRoot();
940: }
941: cur = rpmNewSubdir(tree, dir->name,
1.57 daniel 942: dir->subdir == NULL ? "" : dir->subdir, "", dir->color,
943: dir->html);
1.37 veillard 944: ret = rpmOneDirScan(dir, cur);
1.38 veillard 945: rpmDumpHtmlRealRoot(dir);
1.37 veillard 946: return(ret);
1.6 veillard 947: }
948:
949: /*
1.11 veillard 950: * Scan the local RPM database for RPM files.
951: */
1.32 veillard 952: static rpmDataPtr rpmBaseScan(rpmDirPtr dir) {
1.37 veillard 953: static char path[2000];
1.32 veillard 954: rpmDataPtr ret = NULL, cur;
1.11 veillard 955: rpmdb db;
956: Header h = NULL;
1.72 daniel 957: #ifndef USE_RPMIO
1.32 veillard 958: int offset;
1.71 daniel 959: #endif
1.11 veillard 960: char *prefix = "/";
961:
1.37 veillard 962: /*
963: * Create the directory for the HTML pages
964: */
1.56 daniel 965: if ((rpm2html_dump_html) && (dir->html)) {
1.45 veillard 966: if (dir->subdir)
1.66 daniel 967: snprintf(path, sizeof(path), "%s/%s", dir->dir, dir->subdir);
1.45 veillard 968: else
1.66 daniel 969: snprintf(path, sizeof(path), "%s", dir->dir);
1.45 veillard 970: createDirectory(path);
971: }
972:
973: /*
974: * Create the directory for the RDF pages
975: */
976: if (rpm2html_rdf_dir != NULL) {
977: if (dir->subdir)
1.66 daniel 978: snprintf(path, sizeof(path), "%s/%s", rpm2html_rdf_dir, dir->subdir);
1.45 veillard 979: else
1.66 daniel 980: snprintf(path, sizeof(path), "%s", rpm2html_rdf_dir);
1.45 veillard 981: createDirectory(path);
982: }
1.37 veillard 983:
1.66 daniel 984: if (rpm2htmlVerbose)
985: printf("Scanning the database of installed RPMs\n");
1.70 daniel 986:
987: if (dir->dbpath != NULL)
988: addMacro(NULL, "_dbpath", NULL, dir->dbpath, -7); /* Added by A.Gibert */
1.66 daniel 989:
1.11 veillard 990: if (rpmdbOpen(prefix, &db, O_RDONLY, 0644)) {
1.32 veillard 991: return(NULL);
1.11 veillard 992: }
1.71 daniel 993:
1.72 daniel 994: #ifdef USE_RPMIO
1.71 daniel 995: { rpmdbMatchIterator mi;
996: mi = rpmdbInitIterator(db, RPMDBI_PACKAGES, NULL, 0);
997: while ((h = rpmdbNextIterator(mi)) != NULL) {
1.75 veillard 998: cur = rpmAnalyze(NULL, NULL, h, dir, NULL, 0, 0);
1.71 daniel 999: if (cur != NULL) ret = rpmAddList(ret, cur);
1000: }
1001: rpmdbFreeIterator(mi);
1002: }
1.72 daniel 1003: #else /* USE_RPMIO */
1.11 veillard 1004: offset = rpmdbFirstRecNum(db);
1005: while (offset) {
1006: h = rpmdbGetRecord(db, offset);
1007: if (!h) {
1008: fprintf(stderr, "could not read database record!\n");
1.32 veillard 1009: return(ret);
1.11 veillard 1010: }
1.75 veillard 1011: cur = rpmAnalyze(NULL, NULL, h, dir, NULL, 0, 0);
1.32 veillard 1012: if (cur != NULL) ret = rpmAddList(ret, cur);
1.11 veillard 1013: headerFree(h);
1014: offset = rpmdbNextRecNum(db, offset);
1015: }
1.72 daniel 1016: #endif /* USE_RPMIO */
1.71 daniel 1017:
1.11 veillard 1018: rpmdbClose(db);
1019:
1.32 veillard 1020: return(ret);
1.80 ! veillard 1021: }
! 1022:
! 1023:
! 1024: /*
! 1025: * Scan one distribution only
! 1026: */
! 1027:
! 1028: void rpmDirScanOneDist(const char *dist) {
! 1029: rpmDirPtr dir;
! 1030: rpmDataPtr cur;
! 1031:
! 1032: /*
! 1033: * first try to find the distrib
! 1034: */
! 1035: dir = dirList;
! 1036: while (dir != NULL) {
! 1037: if (!strcasecmp(dir->name, dist))
! 1038: break;
! 1039: if (!strcasecmp(dir->subdir, dist))
! 1040: break;
! 1041: if (!strcasecmp(dir->rpmdir, dist))
! 1042: break;
! 1043: dir = dir->next;
! 1044: }
! 1045: if (dir == NULL) {
! 1046: dir = dirList;
! 1047: while (dir != NULL) {
! 1048: if (!strstr(dir->name, dist))
! 1049: break;
! 1050: if (!strstr(dir->subdir, dist))
! 1051: break;
! 1052: if (!strstr(dir->rpmdir, dist))
! 1053: break;
! 1054: dir = dir->next;
! 1055: }
! 1056: }
! 1057: if (dir == NULL) {
! 1058: fprintf(stderr, "rpmDirScanOneDist(%s): distribution not found\n",
! 1059: dist);
! 1060: return;
! 1061: }
! 1062: if (rpm2htmlVerbose)
! 1063: printf("indexing %s\n", dir->name);
! 1064:
! 1065: /*
! 1066: * Allocate a directory tree.
! 1067: */
! 1068: dirTree = rpmNewSubdir(NULL, "", "", "", NULL, 1);
! 1069:
! 1070: cur = NULL;
! 1071:
! 1072: /*
! 1073: * Override default setting.
! 1074: */
! 1075: if ((dir->maint == NULL) && (rpm2html_maint != NULL))
! 1076: dir->maint = debugStrdup(rpm2html_maint);
! 1077: if ((dir->mail == NULL) && (rpm2html_mail != NULL))
! 1078: dir->mail = debugStrdup(rpm2html_mail);
! 1079: if ((dir->ftp == NULL) && (rpm2html_ftp != NULL))
! 1080: dir->ftp = debugStrdup(rpm2html_ftp);
! 1081: if ((dir->ftpsrc == NULL) && (rpm2html_ftpsrc != NULL))
! 1082: dir->ftpsrc = debugStrdup(rpm2html_ftpsrc);
! 1083: if ((dir->dir == NULL) && (rpm2html_dir != NULL))
! 1084: dir->dir = debugStrdup(rpm2html_dir);
! 1085: if ((dir->host == NULL) && (rpm2html_host != NULL))
! 1086: dir->host = debugStrdup(rpm2html_host);
! 1087: if ((dir->name == NULL) && (rpm2html_name != NULL))
! 1088: dir->name = debugStrdup(rpm2html_name);
! 1089: if ((dir->url == NULL) && (rpm2html_url != NULL))
! 1090: dir->url = debugStrdup(rpm2html_url);
! 1091:
! 1092: if (dir->rpmdir == NULL) {
! 1093: fprintf(stderr, "?!? rpmDir without directory ?!? disabled !\n");
! 1094: } else if (!strncmp(dir->rpmdir, "localbase", 9)) {
! 1095: /* Scan the local RPM database instead of a directory */
! 1096: cur = rpmBaseScan(dir);
! 1097: } else if (dir->ftp == NULL) {
! 1098: fprintf(stderr, "Directory %s disabled : no ftp field\n",
! 1099: dir->rpmdir);
! 1100: } else {
! 1101: dir->no = sql_get_distrib_by_directory(dir->rpmdir);
! 1102: if (rpm2htmlVerbose)
! 1103: printf("Scanning directory %s for RPMs\n",dir->rpmdir);
! 1104: cur = rpmDirScan(dir, dirTree);
! 1105: }
! 1106:
! 1107: if (cur != NULL) {
! 1108: rpmDataListFree(&cur);
! 1109: }
! 1110: if (dir->root != NULL) {
! 1111: rpmDestroyRealRoot(dir->root);
! 1112: dir->root = NULL;
! 1113: }
1.11 veillard 1114: }
1115:
1116: /*
1.6 veillard 1117: * Scan all registered directories.
1118: * One fist check for completeness of the informations in
1119: * the rpmDir structure.
1120: */
1121:
1.32 veillard 1122: rpmDataPtr rpmDirScanAll(void) {
1.18 veillard 1123: rpmDirPtr dir, next;
1.32 veillard 1124: rpmDataPtr ret = NULL, cur;
1.46 veillard 1125: int maxLists = 50;
1126: rpmDataPtr *rpmLists;
1.35 veillard 1127: int nbLists = 0;
1128: int i;
1.18 veillard 1129:
1130: /*
1131: * first reverse the list ....
1132: */
1133: dir = dirList;
1134: dirList = NULL;
1135: while (dir != NULL) {
1136: next = dir->next;
1137: dir->next = dirList;
1138: dirList = dir;
1139: dir = next;
1140: }
1.57 daniel 1141: dir = dirList;
1.18 veillard 1142:
1.35 veillard 1143: /*
1144: * Allocate a directory tree.
1145: */
1.57 daniel 1146: dirTree = rpmNewSubdir(NULL, "", "", "", NULL, 1);
1.6 veillard 1147:
1.61 daniel 1148: rpmLists = (rpmDataPtr *) debugMalloc(maxLists * sizeof(rpmDataPtr));
1.46 veillard 1149: if (rpmLists == NULL) {
1150: fprintf(stderr, "rpmDirScanAll : running out of memory !\n");
1151: exit(1);
1152: }
1153:
1.6 veillard 1154: while (dir != NULL) {
1.32 veillard 1155: cur = NULL;
1156:
1.14 veillard 1157: /*
1158: * Override default setting.
1159: */
1.15 veillard 1160: if ((dir->maint == NULL) && (rpm2html_maint != NULL))
1.61 daniel 1161: dir->maint = debugStrdup(rpm2html_maint);
1.15 veillard 1162: if ((dir->mail == NULL) && (rpm2html_mail != NULL))
1.61 daniel 1163: dir->mail = debugStrdup(rpm2html_mail);
1.15 veillard 1164: if ((dir->ftp == NULL) && (rpm2html_ftp != NULL))
1.61 daniel 1165: dir->ftp = debugStrdup(rpm2html_ftp);
1.15 veillard 1166: if ((dir->ftpsrc == NULL) && (rpm2html_ftpsrc != NULL))
1.61 daniel 1167: dir->ftpsrc = debugStrdup(rpm2html_ftpsrc);
1.15 veillard 1168: if ((dir->dir == NULL) && (rpm2html_dir != NULL))
1.61 daniel 1169: dir->dir = debugStrdup(rpm2html_dir);
1.15 veillard 1170: if ((dir->host == NULL) && (rpm2html_host != NULL))
1.61 daniel 1171: dir->host = debugStrdup(rpm2html_host);
1.15 veillard 1172: if ((dir->name == NULL) && (rpm2html_name != NULL))
1.61 daniel 1173: dir->name = debugStrdup(rpm2html_name);
1.15 veillard 1174: if ((dir->url == NULL) && (rpm2html_url != NULL))
1.61 daniel 1175: dir->url = debugStrdup(rpm2html_url);
1.14 veillard 1176:
1177: if (dir->rpmdir == NULL) {
1.6 veillard 1178: fprintf(stderr, "?!? rpmDir without directory ?!? disabled !\n");
1.67 daniel 1179: } else if (!strncmp(dir->rpmdir, "localbase", 9)) { /* Added by A. Gibert */
1.11 veillard 1180: /* Scan the local RPM database instead of a directory */
1.32 veillard 1181: cur = rpmBaseScan(dir);
1.7 veillard 1182: } else if (dir->ftp == NULL) {
1183: fprintf(stderr, "Directory %s disabled : no ftp field\n",
1.14 veillard 1184: dir->rpmdir);
1.6 veillard 1185: } else {
1.79 veillard 1186: dir->no = sql_get_distrib_by_directory(dir->rpmdir);
1.51 veillard 1187: if (rpm2htmlVerbose)
1.66 daniel 1188: printf("Scanning directory %s for RPMs\n",dir->rpmdir);
1.35 veillard 1189: cur = rpmDirScan(dir, dirTree);
1.6 veillard 1190: }
1191:
1.35 veillard 1192: if (cur != NULL) {
1.46 veillard 1193: if (nbLists >= maxLists) {
1194: maxLists *= 2;
1.61 daniel 1195: rpmLists = (rpmDataPtr *) debugRealloc(rpmLists,
1.46 veillard 1196: maxLists * sizeof(rpmDataPtr));
1197: if (rpmLists == NULL) {
1198: fprintf(stderr, "rpmDirScanAll : running out of memory!\n");
1199: exit(1);
1.35 veillard 1200: }
1201: }
1.46 veillard 1202: rpmLists[nbLists] = cur;
1203: nbLists++;
1.39 veillard 1204: }
1205: if (dir->root != NULL) {
1.48 veillard 1206: /************************************************
1.39 veillard 1207: if (rpm2html_build_tree)
1208: treeRoot = rpmMergeRealRoots(treeRoot, dir->root);
1209: else
1.48 veillard 1210: ************************************************/
1211: rpmDestroyRealRoot(dir->root);
1212: dir->root = NULL;
1.35 veillard 1213: }
1.32 veillard 1214:
1.6 veillard 1215: dir = dir->next;
1216: }
1.35 veillard 1217: for (i = 0;i < nbLists;i++)
1218: ret = rpmAddList(ret, rpmLists[i]);
1.61 daniel 1219: debugFree(rpmLists);
1.32 veillard 1220: return(ret);
1.60 daniel 1221: }
1222:
1223: /*
1224: * Cleanup the global variables from this module
1225: */
1226: void rpmopenCleanup(void) {
1227: if (buffer != NULL)
1.61 daniel 1228: debugFree(buffer);
1.60 daniel 1229: buffer = NULL;
1230: buffer_size = 50 * 1024 * sizeof(char);
1.1 veillard 1231: }
1232:
Webmaster