Annotation of rpm2html/rpmopen.c, revision 1.50
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.50 ! veillard 6: * $Id: rpmopen.c,v 1.49 1998/05/24 19:23:48 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>
26:
27: #include "rpmdata.h"
1.7 veillard 28: #include "html.h"
1.40 httpng 29: #include "rdf.h"
1.8 veillard 30: #include "rpm2html.h"
1.12 veillard 31: #include "language.h"
1.1 veillard 32:
33: /*
34: * Get the internal number associated to an RPM tag.
35: */
36: static int getTagNumber(char *tag) {
37: int i;
38: const struct headerTagTableEntry * t;
39:
40: for (i = 0, t = rpmTagTable; i < rpmTagTableSize; i++, t++) {
41: if (!strcasecmp(tag, t->name)) return(t->val);
42: }
43: fprintf(stderr, "getTagNumber(%s) : unknown tag !\n", tag);
44: return(-1);
45: }
46:
47: /*
1.11 veillard 48: * rpmAnalyze : analyze an RPM record, read and parse the header and
49: * fill the informations in the database.
1.1 veillard 50: */
1.36 veillard 51: rpmDataPtr rpmAnalyze(char *nameRpm, Header h, rpmDirPtr dir,
52: rpmSubdirPtr tree, time_t stamp) {
1.11 veillard 53: int installed = dir->installbase;
1.2 veillard 54: char * name = NULL, * version = NULL, * release = NULL;
1.1 veillard 55: int_32 count, type;
1.2 veillard 56: void * p = NULL;
1.10 veillard 57: int val, i, j;
1.1 veillard 58: rpmDataPtr rpm = NULL;
1.41 veillard 59: static char *buffer = NULL;
60: static int buffer_size = 50 * 1024 * sizeof(char);
1.11 veillard 61: static char nameBuffer[500];
1.1 veillard 62:
1.41 veillard 63: if (buffer == NULL) {
64: buffer = (char *) malloc(buffer_size);
65: if (buffer == NULL) {
66: fprintf(stderr, "cannot allocate %d bytes: %s\n", buffer_size,
67: strerror(errno));
68: exit(1);
69: }
70: }
71:
1.1 veillard 72: /* extract informations from the header */
73: headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &count);
1.49 veillard 74: if (name == NULL) {
75: fprintf(stderr, "Invalid package %s : no name\n", nameRpm);
76: return(NULL);
77: }
78: if (!(((name[0] >= 'a') && (name[0] <= 'z')) ||
79: ((name[0] >= 'A') && (name[0] <= 'Z')) ||
80: ((name[0] >= '0') && (name[0] <= '9')))) {
81: fprintf(stderr, "Invalid package %s : garbled name\n", nameRpm);
82: return(NULL);
83: }
1.1 veillard 84: headerGetEntry(h, RPMTAG_VERSION, &type, (void **) &version, &count);
1.49 veillard 85: if ((version == NULL) || (version[0] == 0)) {
86: fprintf(stderr, "Invalid package %s : version invalid\n", nameRpm);
87: return(NULL);
88: }
1.1 veillard 89: headerGetEntry(h, RPMTAG_RELEASE, &type, (void **) &release, &count);
1.49 veillard 90: if ((release == NULL) || (release[0] == 0)) {
91: fprintf(stderr, "Invalid package %s : release invalid\n", nameRpm);
92: return(NULL);
93: }
1.1 veillard 94:
95: /* allocate a new rpmData block, fill it */
96: rpm = (rpmDataPtr) malloc(sizeof(rpmData));
97: if (rpm == NULL) {
1.41 veillard 98: fprintf(stderr, "cannot allocate %d bytes: %s\n", sizeof(rpmData),
99: strerror(errno));
100: return(NULL);
1.1 veillard 101: }
1.44 veillard 102: memset(rpm, 0, sizeof(rpmData));
1.6 veillard 103: rpm->dir = dir;
1.36 veillard 104: if (tree) {
105: if ((tree->rpmpath != NULL) && (tree->rpmpath[0] != '\0'))
106: rpm->subdir = strdup(tree->rpmpath);
107: else
108: rpm->subdir = NULL;
109: } else
110: rpm->subdir = NULL;
1.20 veillard 111: rpm->stamp = stamp;
1.1 veillard 112: rpm->name = strdup(name);
113: rpm->version = strdup(version);
114: rpm->release = strdup(release);
115:
1.26 veillard 116: /* get all the resources provided by this RPM */
1.2 veillard 117: if (!headerGetEntry(h, RPMTAG_SUMMARY, &type, &p, &count) || !p) {
1.27 veillard 118: rpm->summary = strdup(localizedStrings[LANG_NO_SUMMARY]);
1.2 veillard 119: } else {
1.40 httpng 120: rpm->summary = strdup((char *) p);
1.2 veillard 121: }
1.28 veillard 122: if (!headerGetEntry(h, RPMTAG_DESCRIPTION, &type, &p, &count) || !p ||
123: (type != RPM_STRING_TYPE)) {
1.27 veillard 124: rpm->description = strdup(localizedStrings[LANG_NO_DESCRIPTION]);
1.2 veillard 125: } else {
1.40 httpng 126: rpm->description = strdup((char *) p);
1.2 veillard 127: }
1.28 veillard 128: if (!headerGetEntry(h, RPMTAG_DISTRIBUTION, &type, &p, &count) || !p ||
129: (type != RPM_STRING_TYPE)) {
1.27 veillard 130: rpm->distribution = strdup(localizedStrings[LANG_UNKNOWN]);
1.2 veillard 131: } else {
132: rpm->distribution = strdup((char *) p);
133: }
1.28 veillard 134: if (!headerGetEntry(h, RPMTAG_ARCH, &type, &p, &count) || !p ||
135: (type != RPM_STRING_TYPE)) {
1.29 veillard 136: if (type == RPM_INT8_TYPE) {
137: /*
1.32 veillard 138: * Old packages.
1.29 veillard 139: */
140: switch (*((char *) p)) {
141: case 1:
142: rpm->arch = strdup("i386");
143: break;
144: default:
145: rpm->arch = strdup("i386");
146: break;
147: }
148: } else
149: rpm->arch = strdup(localizedStrings[LANG_NONE]);
1.11 veillard 150: if (nameRpm == NULL) {
1.12 veillard 151: sprintf(nameBuffer, "%s-%s-%s.rpm", name, version, release);
1.11 veillard 152: nameRpm = nameBuffer;
153: }
1.2 veillard 154: } else {
155: rpm->arch = strdup((char *) p);
1.11 veillard 156: if (nameRpm == NULL) {
1.12 veillard 157: sprintf(nameBuffer, "%s-%s-%s.%s.rpm",
158: name, version, release, (char *)p);
1.11 veillard 159: nameRpm = nameBuffer;
160: }
1.2 veillard 161: }
1.28 veillard 162: if (!headerGetEntry(h, RPMTAG_OS, &type, &p, &count) || !p ||
163: (type != RPM_STRING_TYPE)) {
1.29 veillard 164: if (type == RPM_INT8_TYPE) {
165: /*
1.32 veillard 166: * Old packages.
1.29 veillard 167: */
168: switch (*((char *) p)) {
169: case 1:
170: rpm->os = strdup("linux");
171: break;
172: default:
173: rpm->os = strdup("linux");
174: break;
175: }
176: } else
177: rpm->os = strdup("");
1.7 veillard 178: } else {
179: rpm->os = strdup((char *) p);
180: }
1.28 veillard 181: if (!headerGetEntry(h, RPMTAG_VENDOR, &type, &p, &count) || !p ||
182: (type != RPM_STRING_TYPE)) {
1.7 veillard 183: rpm->vendor = NULL;
1.2 veillard 184: } else {
185: rpm->vendor = strdup((char *) p);
186: }
1.28 veillard 187: if (!headerGetEntry(h, RPMTAG_GROUP, &type, &p, &count) || !p ||
188: (type != RPM_STRING_TYPE)) {
1.27 veillard 189: rpm->group = strdup(localizedStrings[LANG_NO_GROUP]);
1.2 veillard 190: } else {
191: rpm->group = strdup((char *) p);
192: }
1.28 veillard 193: if (!headerGetEntry(h, RPMTAG_BUILDHOST, &type, &p, &count) || !p ||
194: (type != RPM_STRING_TYPE)) {
1.27 veillard 195: rpm->host = strdup(localizedStrings[LANG_NO_HOST]);
1.2 veillard 196: } else {
197: rpm->host = strdup((char *) p);
198: }
199: if (!headerGetEntry(h, RPMTAG_SIZE, &type, &p, &count) || !p) {
200: rpm->size = 0;
201: } else {
202: rpm->size = *((int *) p);
203: }
1.11 veillard 204: if (installed) {
205: if (!headerGetEntry(h, RPMTAG_INSTALLTIME, &type, &p, &count) || !p) {
206: rpm->date = 0;
207: } else {
208: rpm->date = *((int_32 *) p);
209: }
1.2 veillard 210: } else {
1.11 veillard 211: if (!headerGetEntry(h, RPMTAG_BUILDTIME, &type, &p, &count) || !p) {
212: rpm->date = 0;
213: } else {
214: rpm->date = *((int_32 *) p);
215: }
1.2 veillard 216: }
1.28 veillard 217: if (!headerGetEntry(h, RPMTAG_SOURCERPM, &type, &p, &count) || !p ||
218: (type != RPM_STRING_TYPE)) {
1.27 veillard 219: rpm->srcrpm = strdup("");
1.2 veillard 220: } else {
221: rpm->srcrpm = strdup((char *) p);
222: }
1.28 veillard 223: if (!headerGetEntry(h, RPMTAG_URL, &type, &p, &count) || !p ||
224: (type != RPM_STRING_TYPE)) {
1.7 veillard 225: rpm->url = NULL;
226: } else {
227: rpm->url = strdup((char *) p);
228: }
1.28 veillard 229: if (!headerGetEntry(h, RPMTAG_PACKAGER, &type, &p, &count) || !p ||
230: (type != RPM_STRING_TYPE)) {
1.7 veillard 231: rpm->packager = NULL;
232: } else {
233: rpm->packager = strdup((char *) p);
234: }
1.28 veillard 235: if (!headerGetEntry(h, RPMTAG_COPYRIGHT, &type, &p, &count) || !p ||
236: (type != RPM_STRING_TYPE)) {
1.7 veillard 237: rpm->copyright = NULL;
238: } else {
239: rpm->copyright = strdup((char *) p);
240: }
1.31 veillard 241: /* Pick up changelog entries */
242: if (!headerGetEntry(h, RPMTAG_CHANGELOGTEXT, &type, &p, &count) || !p) {
243: rpm->changelog = NULL;
244: } else {
245: time_t *dates;
246: char **names;
247: char **holdp = (char **)p;
248: char *cp;
249: struct tm *tm_buf;
250: int i, len, pos;
251: char date_string[50];
252: char *res = buffer;
1.42 veillard 253:
1.31 veillard 254: *res = '\0';
255: headerGetEntry(h, RPMTAG_CHANGELOGTIME, &type, (void *)&dates, &count);
256: headerGetEntry(h, RPMTAG_CHANGELOGNAME, &type, (void *)&names, &count);
257: for (i = 0; i < count; i++) {
1.42 veillard 258: if ((res - buffer) > (buffer_size - 1024)) {
259: int delta = res - buffer;
260:
1.41 veillard 261: buffer_size *= 2;
262: buffer = (char *) realloc(buffer, buffer_size);
1.42 veillard 263: if (buffer == NULL) {
264: fprintf(stderr, "cannot re-allocate %d bytes: %s\n",
265: buffer_size, strerror(errno));
266: exit(1);
267: }
268: res = &buffer[delta];
1.41 veillard 269: }
1.31 veillard 270: tm_buf = localtime(&dates[i]);
271: strftime(date_string, sizeof(date_string) - 1, "%a %b %d %Y", tm_buf);
272: len = sprintf(res, "* %s %s\n", date_string, names[i]);
273: res += len;
274: cp = holdp[i];
275: pos = 0;
276: while (*cp) {
277: if (pos++ == 0) {
278: *res++ = ' ';
279: *res++ = ' ';
280: }
281: *res++ = *cp;
282: if (*cp++ == '\n') pos = 0;
283: }
284: *res++ = '\n';
285: }
286: *res = '\0';
287: rpm->changelog = strdup(buffer);
288: }
1.7 veillard 289: if (rpm->vendor == NULL) {
1.15 veillard 290: if (rpm->packager != NULL) rpm->vendor = strdup(rpm->packager);
291: else rpm->vendor = strdup(localizedStrings[LANG_UNKNOWN]);
1.7 veillard 292: }
1.2 veillard 293:
1.11 veillard 294: rpm->filename = strdup(nameRpm);
295:
1.48 veillard 296: /* package-xxx.rpm provides at least the resource "package" */
1.1 veillard 297: val = getTagNumber("RPMTAG_PROVIDES");
298: if (!headerGetEntry(h, val, &type, &p, &count) || !p) {
1.26 veillard 299: rpm->nb_resources = 1;
1.48 veillard 300: rpm->max_resources = 1;
301: rpm->resources = (rpmRessPtr *) malloc(sizeof(rpmRessPtr) *
302: rpm->max_resources);
303: if (rpm->resources == NULL) {
304: fprintf(stderr, ": ran out of memory\n");
305: exit(1);
306: }
307: rpm->resources[0] = rpmRessAdd(name, rpm, installed);
1.1 veillard 308: } else {
1.48 veillard 309: rpm->max_resources = count + 1;
310: rpm->resources = (rpmRessPtr *) malloc(sizeof(rpmRessPtr) *
311: rpm->max_resources);
312: if (rpm->resources == NULL) {
313: fprintf(stderr, ": ran out of memory\n");
314: exit(1);
1.1 veillard 315: }
1.48 veillard 316: rpm->resources[0] = rpmRessAdd(name, rpm, installed);
317: rpm->nb_resources = 1;
1.1 veillard 318:
1.26 veillard 319: for (i = 0, j = rpm->nb_resources; i < count;j++, i++) {
320: rpm->resources[j] = rpmRessAdd(((char **) p)[i], rpm, installed);
1.4 veillard 321: }
1.26 veillard 322: rpm->nb_resources += count;
1.4 veillard 323: }
324:
325: val = getTagNumber("RPMTAG_REQUIRENAME");
326: if (!headerGetEntry(h, val, &type, &p, &count) || !p) {
327: rpm->nb_requires = 0;
1.48 veillard 328: rpm->requires = NULL;
1.4 veillard 329: } else {
1.48 veillard 330: rpm->max_requires = count;
331: rpm->requires = (rpmRessPtr *) malloc(sizeof(rpmRessPtr) *
332: rpm->max_requires);
333: if (rpm->requires == NULL) {
334: fprintf(stderr, ": ran out of memory\n");
335: exit(1);
1.4 veillard 336: }
337:
338: rpm->nb_requires = count;
339: for (i = 0; i < count;i++) {
1.11 veillard 340: rpm->requires[i] = rpmRequAdd(((char **) p)[i], rpm, installed);
1.1 veillard 341: }
1.5 veillard 342: }
343: val = getTagNumber("RPMTAG_FILENAMES");
344: if (!headerGetEntry(h, val, &type, &p, &count) || !p) {
1.7 veillard 345: rpm->filelist = NULL; /* No filelist in the package ! */
1.5 veillard 346: } else {
347: char *ptr = buffer;
1.42 veillard 348:
1.5 veillard 349: for (i = 0; i < count;i++) {
1.42 veillard 350: if ((ptr - buffer) > (buffer_size - 1024)) {
351: int delta = ptr - buffer;
352:
1.41 veillard 353: buffer_size *= 2;
354: buffer = (char *) realloc(buffer, buffer_size);
1.42 veillard 355: if (buffer == NULL) {
356: fprintf(stderr, "cannot re-allocate %d bytes: %s\n",
357: buffer_size, strerror(errno));
358: exit(1);
359: }
360: ptr = &buffer[delta];
1.41 veillard 361: }
1.5 veillard 362: ptr += sprintf(ptr, "%s\n", ((char **) p)[i]);
363: }
364: rpm->filelist = strdup(buffer);
1.1 veillard 365: }
366:
1.37 veillard 367: /* Add the package files to the real filesystem tree if asked for */
368: if ((dir->build_tree != 0) && (rpm->filelist != NULL)) {
369: char *cur, *filename;
370:
371: cur = rpm->filelist;
372: while ((*cur != '\0') && (*cur != '/')) cur++;
373: filename = cur;
374: while (*cur != '\0') {
375: if ((*cur == '\n') || (*cur == '\r')) {
376: if (cur != filename)
377: rpmAddRealFile(dir->root, filename, rpm);
378: while ((*cur != '\0') && (*cur != '/')) cur++;
379: filename = cur;
380: } else
381: cur++;
382: }
383: if (cur != filename)
384: rpmAddRealFile(dir->root, filename, rpm);
385: }
1.17 veillard 386:
387: /* Register this package */
388: rpmAddSoftware(rpm);
1.7 veillard 389:
390: /* dump the HTML related to this package */
1.40 httpng 391: if (rpm2html_dump_html)
392: dumpRpmHtml(rpm, tree);
393: if (rpm2html_dump_rdf)
394: dumpRpmRdf(rpm, tree);
1.7 veillard 395:
396: /* free large amount of data not used later */
397: if (rpm->filelist) free(rpm->filelist);
1.15 veillard 398: rpm->filelist = NULL;
1.7 veillard 399: if (rpm->copyright) free(rpm->copyright);
1.15 veillard 400: rpm->copyright = NULL;
1.31 veillard 401: if (rpm->changelog) free(rpm->changelog);
402: rpm->changelog = NULL;
1.15 veillard 403: if (rpm->description) free(rpm->description);
404: rpm->description = NULL;
1.8 veillard 405:
406: /* increment the counters */
1.11 veillard 407: if (installed) {
408: rpm2html_install_files++;
1.21 veillard 409: rpm2html_install_size += rpm->size / 1024;
1.11 veillard 410: } else {
411: rpm2html_files++;
1.21 veillard 412: rpm2html_size += rpm->size / 1024;
1.11 veillard 413: }
1.7 veillard 414:
1.32 veillard 415: return(rpm);
1.11 veillard 416: }
417:
418: /*
419: * rpmOpen : open an RPM file, read and parse the header and
420: * fill the informations in the database.
421: */
1.35 veillard 422: rpmDataPtr rpmOpen(char *nameRpm, rpmDirPtr dir, rpmSubdirPtr tree) {
1.32 veillard 423: rpmDataPtr cur;
1.11 veillard 424: int fd;
425: int rc;
426: Header h = NULL;
427: int isSource;
428: char buffer[500];
1.20 veillard 429: struct stat buf;
1.11 veillard 430:
431: /* open the file for reading */
1.35 veillard 432: if (tree->htmlpath[0] != '\0')
433: sprintf(buffer, "%s/%s/%s", dir->rpmdir, tree->rpmpath, nameRpm);
1.24 veillard 434: else
435: sprintf(buffer, "%s/%s", dir->rpmdir, nameRpm);
1.11 veillard 436: if ((fd = open(buffer, O_RDONLY)) < 0) {
437: fprintf(stderr, "open of %s failed: %s\n", buffer,
438: strerror(errno));
1.32 veillard 439: return(NULL);
1.11 veillard 440: }
441:
1.20 veillard 442: stat(buffer, &buf);
443:
1.11 veillard 444: /* read the RPM header */
445: rc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
446: switch (rc) {
447: case 0:
448: if (!h) {
449: fprintf(stderr,
450: "old format source packages cannot be queried\n");
1.32 veillard 451: return(NULL);
1.11 veillard 452: }
453: break;
454: case 1:
455: fprintf(stderr, "%s does not appear to be a RPM package\n",
456: nameRpm);
1.32 veillard 457: return(NULL);
1.11 veillard 458: case 2:
459: fprintf(stderr, "query of %s failed\n", nameRpm);
1.32 veillard 460: return(NULL);
1.11 veillard 461: default:
462: fprintf(stderr, "rpmReadPackageHeader(%s): unknown error %d\n",
463: nameRpm, rc);
1.32 veillard 464: return(NULL);
1.11 veillard 465: }
466:
1.36 veillard 467: cur = rpmAnalyze(nameRpm, h, dir, tree, buf.st_mtime);
1.11 veillard 468:
469: /* free the header and close the descriptor */
470: headerFree(h);
471: close(fd);
1.1 veillard 472:
1.32 veillard 473: return(cur);
1.6 veillard 474: }
475:
476: /*
1.22 veillard 477: * Scan one directory for RPM files this is where the recursive handling
478: * is done.
1.6 veillard 479: */
1.35 veillard 480: static rpmDataPtr rpmOneDirScan(rpmDirPtr dir, rpmSubdirPtr tree) {
481: rpmSubdirPtr subtree;
1.32 veillard 482: rpmDataPtr ret = NULL, cur;
1.7 veillard 483: char *filename;
1.22 veillard 484: static char path[2000];
1.23 veillard 485: struct stat buf;
1.7 veillard 486: int len;
1.39 veillard 487: DIR *d;
488: struct dirent *file;
1.6 veillard 489:
1.24 veillard 490:
491: /*
492: * Create the directory for the HTML pages
493: */
1.45 veillard 494: if (rpm2html_dump_html) {
495: if (tree->htmlpath[0] != '\0')
496: sprintf(path, "%s/%s", dir->dir, tree->htmlpath);
497: else
498: sprintf(path, "%s", dir->dir);
499: createDirectory(path);
500: }
1.43 veillard 501:
502: /*
503: * Create the directory for the RDF pages
504: if (rpm2html_rdf_dir != NULL) {
505: if (tree->htmlpath[0] != '\0')
506: sprintf(path, "%s/%s", rpm2html_rdf_dir, tree->htmlpath);
507: else
508: sprintf(path, "%s", rpm2html_rdf_dir);
509: createDirectory(path);
510: }
1.47 veillard 511: */
1.24 veillard 512:
513: /*
514: * Scan the repository.
515: */
1.35 veillard 516: if (tree->rpmpath[0] != '\0')
517: sprintf(path, "%s/%s", dir->rpmdir, tree->rpmpath);
1.24 veillard 518: else
519: sprintf(path, "%s", dir->rpmdir);
1.35 veillard 520: if (verbose > 1)
1.24 veillard 521: fprintf(stderr, "Scanning directory %s\n", path);
522:
1.39 veillard 523: d = opendir(path);
524: if (d == NULL) {
1.24 veillard 525: fprintf(stderr, "Listing of %s failed: %s\n", path,
1.6 veillard 526: strerror(errno));
1.35 veillard 527: rpmRemoveSubdir(tree);
1.36 veillard 528: rpmFreeSubdir(tree);
1.32 veillard 529: return(NULL);
1.6 veillard 530: } else {
1.39 veillard 531: while ((file = readdir(d)) != NULL) {
1.32 veillard 532: cur = NULL;
1.39 veillard 533: filename = file->d_name;
1.7 veillard 534: len = strlen(filename);
1.24 veillard 535:
536: /*
537: * Compute the full path
538: */
1.35 veillard 539: if (tree->rpmpath[0] != '\0')
540: sprintf(path, "%s/%s/%s", dir->rpmdir, tree->rpmpath,
541: filename);
1.22 veillard 542: else
1.24 veillard 543: sprintf(path, "%s/%s", dir->rpmdir, filename);
1.22 veillard 544:
545: /*
1.25 veillard 546: * Stat() the file to detect directory and symlimks
547: */
1.30 veillard 548: if (lstat(path, &buf) != 0) {
1.25 veillard 549: fprintf(stderr, "Couldn't stat(%s)\n", path);
550: continue;
551: }
1.35 veillard 552:
1.25 veillard 553: /*
554: * Don't follow of analyze symlinks,
555: */
556: if (S_ISLNK(buf.st_mode)) {
557: if (verbose)
558: fprintf(stderr, "Dropping symlink %s\n", path);
559: continue;
560: }
1.35 veillard 561:
1.25 veillard 562: /*
1.23 veillard 563: * Check for RPM files by looking at the suffix
1.22 veillard 564: */
1.25 veillard 565: else if ((len >= 5) && (!strcasecmp(&filename[len - 4], ".rpm"))) {
1.35 veillard 566: cur = rpmOpen(filename, dir, tree);
1.44 veillard 567: }
568:
569: /*
570: * Check for RDF files by looking at the suffix
571: */
572: else if ((len >= 5) && (!strcasecmp(&filename[len - 4], ".rdf"))) {
573: cur = rpmOpenRdf(filename, dir, tree);
1.22 veillard 574: }
1.35 veillard 575:
1.22 veillard 576: /*
1.23 veillard 577: * Else if this is a directory, recurse !
1.22 veillard 578: */
1.25 veillard 579: else if (S_ISDIR(buf.st_mode)) {
580: if (filename[0] != '.') {
1.35 veillard 581: subtree = rpmNewSubdir(tree, filename, NULL, NULL, NULL);
582: cur = rpmOneDirScan(dir, subtree);
1.25 veillard 583: }
1.22 veillard 584: }
1.32 veillard 585: if (cur != NULL) ret = rpmAddList(ret, cur);
1.7 veillard 586: }
1.6 veillard 587: }
1.39 veillard 588: closedir(d);
1.33 veillard 589:
590: /*
591: * Dump the pages related to this directory.
592: */
1.35 veillard 593: if (ret != NULL) ret = dumpDirIndex(dir, tree, ret);
1.36 veillard 594: else {
595: rpmRemoveSubdir(tree);
596: rpmFreeSubdir(tree);
597: }
1.35 veillard 598:
1.32 veillard 599: return(ret);
1.22 veillard 600: }
601:
602: /*
603: * Scan a directory for RPM files.
604: */
1.35 veillard 605: static rpmDataPtr rpmDirScan(rpmDirPtr dir, rpmSubdirPtr tree) {
1.37 veillard 606: rpmSubdirPtr cur;
607: rpmDataPtr ret;
608:
1.45 veillard 609: if ((rpm2html_dump_html) && (dir->build_tree != 0)) {
1.37 veillard 610: dir->root = rpmCreateRealRoot();
611: }
612: cur = rpmNewSubdir(tree, dir->name,
613: dir->subdir == NULL ? "" : dir->subdir, "", dir->color);
614: ret = rpmOneDirScan(dir, cur);
1.38 veillard 615: rpmDumpHtmlRealRoot(dir);
1.37 veillard 616: return(ret);
1.6 veillard 617: }
618:
619: /*
1.11 veillard 620: * Scan the local RPM database for RPM files.
621: */
1.32 veillard 622: static rpmDataPtr rpmBaseScan(rpmDirPtr dir) {
1.37 veillard 623: static char path[2000];
1.32 veillard 624: rpmDataPtr ret = NULL, cur;
1.11 veillard 625: rpmdb db;
626: Header h = NULL;
1.32 veillard 627: int offset;
1.11 veillard 628: char *prefix = "/";
629:
1.37 veillard 630: /*
631: * Create the directory for the HTML pages
632: */
1.45 veillard 633: if (rpm2html_dump_html) {
634: if (dir->subdir)
635: sprintf(path, "%s/%s", dir->dir, dir->subdir);
636: else
637: sprintf(path, "%s", dir->dir);
638: createDirectory(path);
639: }
640:
641: /*
642: * Create the directory for the RDF pages
643: */
644: if (rpm2html_rdf_dir != NULL) {
645: if (dir->subdir)
646: sprintf(path, "%s/%s", rpm2html_rdf_dir, dir->subdir);
647: else
648: sprintf(path, "%s", rpm2html_rdf_dir);
649: createDirectory(path);
650: }
1.37 veillard 651:
1.11 veillard 652: if (rpmdbOpen(prefix, &db, O_RDONLY, 0644)) {
1.32 veillard 653: return(NULL);
1.11 veillard 654: }
655: offset = rpmdbFirstRecNum(db);
656: while (offset) {
657: h = rpmdbGetRecord(db, offset);
658: if (!h) {
659: fprintf(stderr, "could not read database record!\n");
1.32 veillard 660: return(ret);
1.11 veillard 661: }
1.36 veillard 662: cur = rpmAnalyze(NULL, h, dir, NULL, 0);
1.32 veillard 663: if (cur != NULL) ret = rpmAddList(ret, cur);
1.11 veillard 664: headerFree(h);
665: offset = rpmdbNextRecNum(db, offset);
666: }
667: rpmdbClose(db);
668:
1.32 veillard 669: return(ret);
1.11 veillard 670: }
671:
672: /*
1.6 veillard 673: * Scan all registered directories.
674: * One fist check for completeness of the informations in
675: * the rpmDir structure.
676: */
677:
1.32 veillard 678: rpmDataPtr rpmDirScanAll(void) {
1.18 veillard 679: rpmDirPtr dir, next;
1.32 veillard 680: rpmDataPtr ret = NULL, cur;
1.46 veillard 681: int maxLists = 50;
682: rpmDataPtr *rpmLists;
1.35 veillard 683: int nbLists = 0;
684: int i;
1.18 veillard 685:
686: /*
687: * first reverse the list ....
688: */
689: dir = dirList;
690: dirList = NULL;
691: while (dir != NULL) {
692: next = dir->next;
693: dir->next = dirList;
694: dirList = dir;
695: dir = next;
696: }
697:
1.35 veillard 698: /*
699: * Allocate a directory tree.
700: */
701: dirTree = rpmNewSubdir(NULL, "", "", "", NULL);
1.37 veillard 702:
1.18 veillard 703: dir = dirList;
1.6 veillard 704:
1.46 veillard 705: rpmLists = (rpmDataPtr *) malloc(maxLists * sizeof(rpmDataPtr));
706: if (rpmLists == NULL) {
707: fprintf(stderr, "rpmDirScanAll : running out of memory !\n");
708: exit(1);
709: }
710:
1.6 veillard 711: while (dir != NULL) {
1.32 veillard 712: cur = NULL;
713:
1.14 veillard 714: /*
715: * Override default setting.
716: */
1.15 veillard 717: if ((dir->maint == NULL) && (rpm2html_maint != NULL))
718: dir->maint = strdup(rpm2html_maint);
719: if ((dir->mail == NULL) && (rpm2html_mail != NULL))
720: dir->mail = strdup(rpm2html_mail);
721: if ((dir->ftp == NULL) && (rpm2html_ftp != NULL))
722: dir->ftp = strdup(rpm2html_ftp);
723: if ((dir->ftpsrc == NULL) && (rpm2html_ftpsrc != NULL))
724: dir->ftpsrc = strdup(rpm2html_ftpsrc);
725: if ((dir->dir == NULL) && (rpm2html_dir != NULL))
726: dir->dir = strdup(rpm2html_dir);
727: if ((dir->host == NULL) && (rpm2html_host != NULL))
728: dir->host = strdup(rpm2html_host);
729: if ((dir->name == NULL) && (rpm2html_name != NULL))
730: dir->name = strdup(rpm2html_name);
731: if ((dir->url == NULL) && (rpm2html_url != NULL))
732: dir->url = strdup(rpm2html_url);
1.14 veillard 733:
734: if (dir->rpmdir == NULL) {
1.6 veillard 735: fprintf(stderr, "?!? rpmDir without directory ?!? disabled !\n");
1.14 veillard 736: } else if (!strcmp(dir->rpmdir, "localbase")) {
1.11 veillard 737: /* Scan the local RPM database instead of a directory */
1.32 veillard 738: cur = rpmBaseScan(dir);
1.7 veillard 739: } else if (dir->ftp == NULL) {
740: fprintf(stderr, "Directory %s disabled : no ftp field\n",
1.14 veillard 741: dir->rpmdir);
1.6 veillard 742: } else {
1.16 veillard 743: if (verbose)
744: fprintf(stderr, "Scanning directory %s for RPMs\n",dir->rpmdir);
1.35 veillard 745: cur = rpmDirScan(dir, dirTree);
1.6 veillard 746: }
747:
1.35 veillard 748: if (cur != NULL) {
1.46 veillard 749: if (nbLists >= maxLists) {
750: maxLists *= 2;
751: rpmLists = (rpmDataPtr *) realloc(rpmLists,
752: maxLists * sizeof(rpmDataPtr));
753: if (rpmLists == NULL) {
754: fprintf(stderr, "rpmDirScanAll : running out of memory!\n");
755: exit(1);
1.35 veillard 756: }
757: }
1.46 veillard 758: rpmLists[nbLists] = cur;
759: nbLists++;
1.39 veillard 760: }
761: if (dir->root != NULL) {
1.48 veillard 762: /************************************************
1.39 veillard 763: if (rpm2html_build_tree)
764: treeRoot = rpmMergeRealRoots(treeRoot, dir->root);
765: else
1.48 veillard 766: ************************************************/
767: rpmDestroyRealRoot(dir->root);
768: dir->root = NULL;
1.35 veillard 769: }
1.32 veillard 770:
1.6 veillard 771: dir = dir->next;
772: }
1.35 veillard 773: for (i = 0;i < nbLists;i++)
774: ret = rpmAddList(ret, rpmLists[i]);
1.46 veillard 775: free(rpmLists);
1.32 veillard 776: return(ret);
1.1 veillard 777: }
778:
Webmaster