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