Annotation of rpm2html/rdf.c, revision 1.31
1.1 httpng 1: /*
2: * rdf.c : implementation for the RDF encoding/decoding of RPM informations.
1.19 veillard 3: *
4: * See Copyright for the status of this software.
5: *
1.31 ! daniel 6: * $Id: rdf.c,v 1.30 1998/10/26 06:42:10 daniel Exp $
1.1 httpng 7: */
8:
1.2 httpng 9: #include "config.h"
1.6 veillard 10: #include <sys/stat.h>
1.2 httpng 11: #ifdef HAVE_FCNTL_H
12: #include <fcntl.h>
13: #endif
14: #include <stdio.h>
15: #include <stdlib.h>
16: #include <string.h>
17: #ifdef HAVE_UNISTD_H
18: #include <unistd.h>
19: #endif
20: #include <time.h>
1.1 httpng 21: #include <errno.h>
1.2 httpng 22: #include <ctype.h>
1.22 daniel 23: #include <zlib.h>
1.1 httpng 24:
25: #include "rpm2html.h"
26: #include "rpmdata.h"
1.4 veillard 27: #include "html.h"
1.7 veillard 28: #include "language.h"
1.4 veillard 29:
30: #include "rdf_api.h"
1.1 httpng 31: #include "rdf.h"
32:
33: /*
1.16 veillard 34: * Open and process an RDF file in the incoming tree of an rpm2html mirror.
35: */
36: rpmDataPtr rpmOpenRdf(char *nameRdf, rpmDirPtr dir, rpmSubdirPtr tree) {
37: char file[1000];
38: rpmDataPtr rpm;
39:
40: /*
41: * create path
42: */
43: if (tree->htmlpath[0] != '\0')
44: sprintf(file, "%s/%s/%s", dir->rpmdir, tree->rpmpath, nameRdf);
45: else
46: sprintf(file, "%s/%s", dir->rpmdir, nameRdf);
47:
48: rpm = rpmOpenRdfFile(file);
49:
50: if (rpm != NULL) {
51: /* setup tree and subdir informations */
52: rpm->dir = dir;
53: if (tree) {
54: if ((tree->rpmpath != NULL) && (tree->rpmpath[0] != '\0'))
55: rpm->subdir = strdup(tree->rpmpath);
56: else
57: rpm->subdir = NULL;
58: } else
59: rpm->subdir = NULL;
60:
61: /* Add the package files to the real filesystem tree if asked for */
1.28 daniel 62: if ((dir->build_tree != 0) && (rpm->extra->filelist != NULL)) {
1.16 veillard 63: char *cur, *filename;
64:
1.28 daniel 65: cur = rpm->extra->filelist;
1.16 veillard 66: while ((*cur != '\0') && (*cur != '/')) cur++;
67: filename = cur;
68: while (*cur != '\0') {
69: if ((*cur == '\n') || (*cur == '\r')) {
70: if (cur != filename)
71: rpmAddRealFile(dir->root, filename, rpm);
72: while ((*cur != '\0') && (*cur != '/')) cur++;
73: filename = cur;
74: } else
75: cur++;
76: }
77: if (cur != filename)
78: rpmAddRealFile(dir->root, filename, rpm);
79: }
80:
81: /* Register this package */
82: rpmAddSoftware(rpm);
83:
84: /* dump the HTML related to this package */
85: if (rpm2html_dump_html)
86: dumpRpmHtml(rpm, tree);
87: if (rpm2html_dump_rdf)
88: dumpRpmRdf(rpm, tree);
89:
90: /* free large amount of data not used later */
1.28 daniel 91: rpmFreeExtraData(rpm);
1.16 veillard 92:
93: /* increment the counters */
94: rpm2html_files++;
95: rpm2html_size += rpm->size / 1024;
96: }
97: return(rpm);
98: }
99:
100: /*
1.1 httpng 101: * Open an RDF file call the parser to create a XML tree
102: * Then walk the tree and build an rpmData structure for
103: * the corresponding package.
104: */
1.16 veillard 105: rpmDataPtr rpmOpenRdfFile(char *file) {
1.6 veillard 106: char nameBuffer[200];
1.5 veillard 107: rdfSchema rdf;
108: rdfNamespace rpmNs;
109: rdfNamespace rdfNs;
110: rdfDescription desc;
111: rdfBag bag;
1.7 veillard 112: rdfElement elem;
1.5 veillard 113: char *value;
114: rpmDataPtr rpm;
1.6 veillard 115: struct stat buf;
1.7 veillard 116: int i;
1.5 veillard 117:
118: rdf = rdfRead(file);
119: if (rdf == NULL) return(NULL);
120:
121: /*
122: * Start the analyze, check that's an RDf for RPM packages.
123: */
124: rdfNs = rdfGetNamespace(rdf, "http://www.w3.org/TR/WD-rdf-syntax#");
125: if (rdfNs == NULL) {
126: fprintf(stderr, "%s is not an RDF schema\n", file);
127: rdfDestroySchema(rdf);
128: return(NULL);
129: }
130: rpmNs = rdfGetNamespace(rdf, "http://www.rpm.org/");
131: if (rdfNs == NULL) {
132: fprintf(stderr, "%s is not an RPM specific RDF schema\n", file);
133: rdfDestroySchema(rdf);
134: return(NULL);
135: }
136: desc = rdfFirstDescription(rdf);
137: if (rdfNs == NULL) {
138: fprintf(stderr, "%s RDF schema seems empty\n", file);
139: rdfDestroySchema(rdf);
140: return(NULL);
141: }
142:
143: /*
144: * We are pretty sure that it will be a valid schema,
1.28 daniel 145: * allocate a new rpmData block, and an rpmExtraData block fill them
1.5 veillard 146: */
147: rpm = (rpmDataPtr) malloc(sizeof(rpmData));
148: if (rpm == NULL) {
1.28 daniel 149: fprintf(stderr, "cannot allocate %d bytes: %s\n", sizeof(rpmData),
150: strerror(errno));
151: return(NULL);
1.5 veillard 152: }
1.6 veillard 153: memset(rpm, 0, sizeof(rpmData));
1.28 daniel 154: rpm->extra = (rpmExtraDataPtr) malloc(sizeof(rpmExtraData));
155: if (rpm == NULL) {
156: fprintf(stderr, "cannot allocate %d bytes: %s\n", sizeof(rpmExtraData),
157: strerror(errno));
158: return(NULL);
159: }
160: memset(rpm->extra, 0, sizeof(rpmExtraData));
1.5 veillard 161:
1.6 veillard 162: stat(file, &buf);
1.28 daniel 163: rpm->extra->stamp = buf.st_mtime;
1.6 veillard 164:
165: /*
166: * Now extract all the metadata informations from the RDF tree
167: */
1.5 veillard 168: rdfGetValue(desc, "Name", rpmNs, &value, NULL);
1.30 daniel 169: if (value != NULL) rpm->name = value;
1.5 veillard 170: else {
171: fprintf(stderr, "%s RDF schema invalid : no Name\n", file);
172: rdfDestroySchema(rdf);
173: return(NULL);
174: }
175: rdfGetValue(desc, "Version", rpmNs, &value, NULL);
1.30 daniel 176: if (value != NULL) rpm->version = value;
1.5 veillard 177: else {
178: fprintf(stderr, "%s RDF schema invalid : no Version\n", file);
179: rdfDestroySchema(rdf);
180: return(NULL);
181: }
182: rdfGetValue(desc, "Release", rpmNs, &value, NULL);
1.30 daniel 183: if (value != NULL) rpm->release = value;
1.5 veillard 184: else {
185: fprintf(stderr, "%s RDF schema invalid : no Release\n", file);
186: rdfDestroySchema(rdf);
187: return(NULL);
188: }
189: rdfGetValue(desc, "URL", rpmNs, &value, NULL);
1.30 daniel 190: if (value != NULL) rpm->url = value;
1.7 veillard 191: else rpm->url = NULL;
192:
1.5 veillard 193: rdfGetValue(desc, "Arch", rpmNs, &value, NULL);
1.30 daniel 194: if (value != NULL) rpm->arch = value;
1.24 daniel 195: else rpm->arch = strdup("noarch");
1.7 veillard 196:
1.5 veillard 197: rdfGetValue(desc, "Os", rpmNs, &value, NULL);
1.30 daniel 198: if (value != NULL) rpm->os = value;
1.7 veillard 199: else rpm->os = strdup("linux");
200:
1.5 veillard 201: rdfGetValue(desc, "Distribution", rpmNs, &value, NULL);
1.30 daniel 202: if (value != NULL) rpm->distribution = value;
1.7 veillard 203: else rpm->distribution = strdup(localizedStrings[LANG_UNKNOWN]);
204:
1.5 veillard 205: rdfGetValue(desc, "Vendor", rpmNs, &value, NULL);
1.30 daniel 206: if (value != NULL) rpm->vendor = value;
1.7 veillard 207: else rpm->vendor = strdup(localizedStrings[LANG_UNKNOWN]);
208:
1.5 veillard 209: rdfGetValue(desc, "Packager", rpmNs, &value, NULL);
1.30 daniel 210: if (value != NULL) rpm->extra->packager = value;
1.28 daniel 211: else rpm->extra->packager = NULL;
1.7 veillard 212:
1.5 veillard 213: rdfGetValue(desc, "Group", rpmNs, &value, NULL);
1.30 daniel 214: if (value != NULL) rpm->group = value;
1.7 veillard 215: else rpm->group = strdup(localizedStrings[LANG_NO_GROUP]);
216:
1.5 veillard 217: rdfGetValue(desc, "Summary", rpmNs, &value, NULL);
1.30 daniel 218: if (value != NULL) rpm->summary = value;
1.7 veillard 219: else rpm->summary = strdup(localizedStrings[LANG_NO_SUMMARY]);
220:
1.5 veillard 221: rdfGetValue(desc, "Description", rpmNs, &value, NULL);
1.30 daniel 222: if (value != NULL) rpm->extra->description = value;
1.28 daniel 223: else rpm->extra->description = strdup(localizedStrings[LANG_NO_DESCRIPTION]);
1.7 veillard 224:
1.5 veillard 225: rdfGetValue(desc, "Copyright", rpmNs, &value, NULL);
1.30 daniel 226: if (value != NULL) rpm->extra->copyright = value;
1.28 daniel 227: else rpm->extra->copyright = NULL;
1.7 veillard 228:
1.5 veillard 229: rdfGetValue(desc, "Changelog", rpmNs, &value, NULL);
1.30 daniel 230: if (value != NULL) rpm->extra->changelog = value;
1.28 daniel 231: else rpm->extra->changelog = NULL;
1.7 veillard 232:
233: rdfGetValue(desc, "Sources", rpmNs, &value, NULL);
234: if (value != NULL) {
1.30 daniel 235: rpm->extra->srcrpm = value;
1.28 daniel 236: } else rpm->extra->srcrpm = strdup("");
1.7 veillard 237:
238: rdfGetValue(desc, "Size", rpmNs, &value, NULL);
239: if (value != NULL) {
240: if (sscanf(value, "%d", &(rpm->size)) != 1)
241: rpm->size = 0;
242: } else rpm->size = 0;
243:
244: rdfGetValue(desc, "Date", rpmNs, &value, NULL);
245: if (value != NULL) {
1.8 veillard 246: if (sscanf(value, "%d", &i) != 1)
1.7 veillard 247: rpm->date = 0;
1.8 veillard 248: else
249: rpm->date = i;
1.7 veillard 250: } else rpm->date = 0;
251:
252: rdfGetValue(desc, "BuildHost", rpmNs, &value, NULL);
1.30 daniel 253: if (value != NULL) rpm->extra->host = value;
1.28 daniel 254: else rpm->extra->host = strdup(localizedStrings[LANG_NO_HOST]);
1.7 veillard 255:
256: rdfGetValue(desc, "Files", rpmNs, &value, NULL);
1.30 daniel 257: if (value != NULL) rpm->extra->filelist = value;
1.28 daniel 258: else rpm->extra->filelist = NULL;
1.7 veillard 259:
260: /*
261: * Fetching packages provided is a bit more tricky, one have to
262: * find the RDF Bag, and scan it's values.
263: */
1.28 daniel 264: rpm->extra->nb_resources = 0;
1.7 veillard 265: rdfGetValue(desc, "Provides", rpmNs, NULL, &bag);
266: if (bag != NULL) {
267: elem = rdfFirstChild(bag);
1.28 daniel 268: rpm->extra->max_resources = 5;
269: rpm->extra->resources = (rpmRessPtr *) malloc(rpm->extra->max_resources *
1.11 veillard 270: sizeof(rpmRessPtr));
1.28 daniel 271: if (rpm->extra->resources == NULL) {
1.11 veillard 272: fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
273: exit(1);
274: }
1.7 veillard 275: i = 0;
276: while (elem != NULL) {
1.28 daniel 277: if (i >= rpm->extra->max_resources) {
278: rpm->extra->max_resources *= 2;
279: rpm->extra->resources = (rpmRessPtr *) realloc(rpm->extra->resources,
280: rpm->extra->max_resources * sizeof(rpmRessPtr));
281: if (rpm->extra->resources == NULL) {
1.11 veillard 282: fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
283: exit(1);
284: }
1.7 veillard 285: }
286: /*
287: * Check that we are scanning an RPM Resource.
288: */
289: if ((!strcmp(rdfElemGetPropertyName(elem), "Resource")) &&
290: (rdfElemGetNamespace(elem) == rpmNs)) {
291: value = rdfElemGetValue(elem);
292: if (value != NULL) {
1.28 daniel 293: rpm->extra->resources[i] = rpmRessAdd(value, rpm, 0);
1.7 veillard 294: i++;
1.28 daniel 295: rpm->extra->nb_resources++;
1.20 veillard 296: } else if (rpm2htmlVerbose > 1) {
1.7 veillard 297: fprintf(stderr, "%s : malformed Resource element !\n", file);
298: }
1.20 veillard 299: } else if (rpm2htmlVerbose > 1) {
1.7 veillard 300: fprintf(stderr, "%s : malformed Provides bag !\n", file);
301: }
302: elem = rdfNextElem(elem);
303: }
1.20 veillard 304: } else if (rpm2htmlVerbose > 1) {
1.7 veillard 305: fprintf(stderr, "%s doesn't export any resource\n", file);
306: }
307:
308: /*
309: * idem for the dependencies.
310: */
1.28 daniel 311: rpm->extra->nb_requires = 0;
1.7 veillard 312: rdfGetValue(desc, "Requires", rpmNs, NULL, &bag);
313: if (bag != NULL) {
314: elem = rdfFirstChild(bag);
1.28 daniel 315: rpm->extra->max_requires = 5;
316: rpm->extra->requires = (rpmRessPtr *) malloc(rpm->extra->max_requires *
1.11 veillard 317: sizeof(rpmRessPtr));
1.28 daniel 318: if (rpm->extra->requires == NULL) {
1.11 veillard 319: fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
320: exit(1);
321: }
1.7 veillard 322: i = 0;
323: while (elem != NULL) {
1.28 daniel 324: if (i >= rpm->extra->max_requires) {
325: rpm->extra->max_requires *= 2;
326: rpm->extra->requires = (rpmRessPtr *) realloc(rpm->extra->requires,
327: rpm->extra->max_requires * sizeof(rpmRessPtr));
328: if (rpm->extra->requires == NULL) {
1.11 veillard 329: fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
330: exit(1);
331: }
1.7 veillard 332: }
333: /*
334: * Check that we are scanning an RPM Resource.
335: */
336: if ((!strcmp(rdfElemGetPropertyName(elem), "Resource")) &&
337: (rdfElemGetNamespace(elem) == rpmNs)) {
338: value = rdfElemGetValue(elem);
339: if (value != NULL) {
1.28 daniel 340: rpm->extra->requires[i] = rpmRequAdd(value, rpm, 0);
1.7 veillard 341: i++;
1.28 daniel 342: rpm->extra->nb_requires++;
1.20 veillard 343: } else if (rpm2htmlVerbose > 1) {
1.7 veillard 344: fprintf(stderr, "%s : malformed Resource element !\n", file);
345: }
1.20 veillard 346: } else if (rpm2htmlVerbose > 1) {
1.7 veillard 347: fprintf(stderr, "%s : malformed Provides bag !\n", file);
348: }
349: elem = rdfNextElem(elem);
350: }
351: }
1.5 veillard 352:
1.6 veillard 353: /*
354: * Finish filling the rpmData structure.
355: */
1.31 ! daniel 356: value = rdfGetDescriptionAbout(rdf, desc);
! 357: if (value != NULL) {
! 358: char *filename = &value[strlen(value)];
! 359:
! 360: while ((filename > value) && (*filename != '/'))
! 361: filename --;
! 362: rpm->filename = strdup(filename);
! 363: } else {
1.6 veillard 364: #ifdef HAVE_SNPRINTF
1.31 ! daniel 365: sprintf(nameBuffer, "%s-%s-%s.%s.rpm",
! 366: rpm->name, rpm->version, rpm->release, rpm->arch);
1.6 veillard 367: #else
1.31 ! daniel 368: snprintf(nameBuffer, 200, "%s-%s-%s.%s.rpm",
! 369: rpm->name, rpm->version, rpm->release, rpm->arch);
1.6 veillard 370: #endif
1.31 ! daniel 371: rpm->filename = strdup(nameBuffer);
! 372: }
1.6 veillard 373:
374:
375: /*
376: * Cleanup.
377: */
1.5 veillard 378: rdfDestroySchema(rdf);
379: return(rpm);
1.1 httpng 380: }
381:
382: /*
1.4 veillard 383: * Create and RDF file containing the description for the given RPM data.
1.1 httpng 384: */
385: void dumpRpmRdf(rpmDataPtr rpm, rpmSubdirPtr tree) {
1.12 veillard 386: FILE *output;
387: struct stat stat_buf;
1.1 httpng 388: struct tm * tstruct;
389: rpmDirPtr dir = rpm->dir;
1.3 veillard 390: char *base = dir->dir;
1.1 httpng 391: int i;
1.4 veillard 392: char buf[10000];
393: char file[1000];
1.29 daniel 394: char dotdot[50];
1.12 veillard 395: char *buffer;
396: int size;
1.27 daniel 397: int stat_res = 0;
1.4 veillard 398: rdfSchema rdf;
399: rdfNamespace rpmNs;
400: rdfDescription desc;
1.29 daniel 401: rdfElement elem;
1.4 veillard 402: rdfBag bag;
1.29 daniel 403: int deep;
404: char *ptr;
1.1 httpng 405:
1.7 veillard 406: if (!rpm2html_dump_rdf) return;
407:
1.3 veillard 408: if (rpm2html_rdf_dir != NULL) base = rpm2html_rdf_dir;
409:
1.29 daniel 410: deep = 0;
411: if (rpm->subdir != NULL)
412: for (ptr = rpm->subdir, deep++;*ptr != 0;ptr++)
413: if (*ptr == '/') deep++;
414: if (dir->subdir != NULL)
415: for (ptr = dir->subdir, deep++;*ptr != 0;ptr++)
416: if (*ptr == '/') deep++;
417:
1.1 httpng 418: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
419: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
1.4 veillard 420: sprintf(file, "%s/%s/%s/%s.rdf", base, dir->subdir,
1.1 httpng 421: rpm->subdir, rpmName(rpm));
422: else
1.4 veillard 423: sprintf(file, "%s/%s/%s.rdf", base, dir->subdir, rpmName(rpm));
1.1 httpng 424: } else {
425: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
1.4 veillard 426: sprintf(file, "%s/%s/%s.rdf", base, rpm->subdir, rpmName(rpm));
1.1 httpng 427: else
1.4 veillard 428: sprintf(file, "%s/%s.rdf", base, rpmName(rpm));
1.1 httpng 429: }
1.29 daniel 430: dotdot[0] = '\0';
431: for (;deep > 0;deep --)
432: strcat(dotdot, "../");
1.1 httpng 433:
1.12 veillard 434: /*
435: * Check wether the RPM timestamp is older than the filestamp.
436: if ((stat_res = stat(file, &stat_buf)) == 0) {
437: if (stat_buf.st_mtime > rpm->stamp) return;
438: }
1.27 daniel 439: */
440: stat_res = stat(file, &stat_buf);
1.9 veillard 441:
442: /*
443: * Create the directory if needed
444: */
445: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
446: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
447: sprintf(buf, "%s/%s/%s", base, dir->subdir, rpm->subdir);
448: else
449: sprintf(buf, "%s/%s", base, dir->subdir);
450: } else {
451: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
452: sprintf(buf, "%s/%s", base, rpm->subdir);
453: else
454: sprintf(buf, "%s", base);
455: }
456: createDirectory(buf);
457:
1.4 veillard 458: /*
459: * build the RDF document tree
460: * Note : the order is not important but following the rpmData
461: * structure order is easier to check.
462: */
463: rdf = rdfNewSchema();
464: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
465:
1.2 httpng 466: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
467: if (dir->mirrors[0] != NULL)
1.4 veillard 468: sprintf(buf, "%s/%s/%s",
1.2 httpng 469: dir->mirrors[0], rpm->subdir, rpm->filename);
470: else
1.4 veillard 471: sprintf(buf, "%s/%s/%s",
1.2 httpng 472: dir->ftp, rpm->subdir, rpm->filename);
473: } else {
474: if (dir->mirrors[0] != NULL)
1.4 veillard 475: sprintf(buf, "%s/%s",
1.2 httpng 476: dir->mirrors[0], rpm->filename);
477: else
1.4 veillard 478: sprintf(buf, "%s/%s",
1.2 httpng 479: dir->ftp, rpm->filename);
480: }
1.4 veillard 481: desc = rdfAddDescription(rdf, NULL, buf);
482:
483: rdfSetValue(desc, "Name", rpmNs, rpm->name);
484: rdfSetValue(desc, "Version", rpmNs, rpm->version);
485: rdfSetValue(desc, "Release", rpmNs, rpm->release);
486: if (rpm->url)
487: rdfSetValue(desc, "URL", rpmNs, rpm->url);
488: if (rpm->arch)
489: rdfSetValue(desc, "Arch", rpmNs, rpm->arch);
490: if (rpm->os)
491: rdfSetValue(desc, "Os", rpmNs, rpm->os);
1.2 httpng 492: if (rpm->distribution)
1.4 veillard 493: rdfSetValue(desc, "Distribution", rpmNs, rpm->distribution);
1.2 httpng 494: if (rpm->vendor)
1.4 veillard 495: rdfSetValue(desc, "Vendor", rpmNs, rpm->vendor);
1.28 daniel 496: if (rpm->extra->packager)
497: rdfSetValue(desc, "Packager", rpmNs, rpm->extra->packager);
1.4 veillard 498: if (rpm->group)
499: rdfSetValue(desc, "Group", rpmNs, rpm->group);
500: if (rpm->summary)
501: rdfSetValue(desc, "Summary", rpmNs, rpm->summary);
1.28 daniel 502: if (rpm->extra->description)
503: rdfSetValue(desc, "Description", rpmNs, rpm->extra->description);
504: if (rpm->extra->copyright)
505: rdfSetValue(desc, "Copyright", rpmNs, rpm->extra->copyright);
506: if (rpm->extra->changelog)
507: rdfSetValue(desc, "Changelog", rpmNs, rpm->extra->changelog);
508: if (rpm->extra->srcrpm) {
509: rdfSetValue(desc, "Sources", rpmNs, rpm->extra->srcrpm);
1.4 veillard 510: if (dir->ftpsrc) {
1.7 veillard 511: rdfSetValue(desc, "SourcesFtp", rpmNs, dir->ftpsrc);
1.4 veillard 512: }
513: }
1.2 httpng 514: tstruct = localtime(&(rpm->date));
515: #ifdef HAVE_STRFTIME
516: strftime(buf, sizeof(buf) - 1, "%c", tstruct);
517: #else
518: #error "no strftime, please check !"
519: #endif
1.4 veillard 520: rdfSetValue(desc, "BuildDate", rpmNs, buf);
1.12 veillard 521: sprintf(buf, "%d", (int) rpm->date);
1.10 veillard 522: rdfSetValue(desc, "Date", rpmNs, buf);
1.4 veillard 523: sprintf(buf, "%d", rpm->size);
524: rdfSetValue(desc, "Size", rpmNs, buf);
1.28 daniel 525: if (rpm->extra->host)
526: rdfSetValue(desc, "BuildHost", rpmNs, rpm->extra->host);
527: if (rpm->extra->nb_resources > 0) {
1.4 veillard 528: bag = rdfBagCreate(rdf, desc, "Provides", rpmNs);
1.28 daniel 529: for (i = 0;i < rpm->extra->nb_resources;i++) {
1.29 daniel 530: elem = rdfBagAddValue(bag, "Resource", rpmNs,
1.28 daniel 531: rpm->extra->resources[i]->name, NULL);
1.29 daniel 532: if (rpm->extra->resources[i]->name[0] != '/') {
533: snprintf(buf, sizeof(buf) - 1, "%sresources/%s.rdf",
534: dotdot, rpm->extra->resources[i]->name);
535: xmlSetProp(elem, "href", buf);
536: }
1.2 httpng 537: }
538: }
1.28 daniel 539: if (rpm->extra->nb_requires > 0) {
1.4 veillard 540: bag = rdfBagCreate(rdf, desc, "Requires", rpmNs);
1.28 daniel 541: for (i = 0;i < rpm->extra->nb_requires;i++) {
1.29 daniel 542: elem = rdfBagAddValue(bag, "Resource", rpmNs,
1.28 daniel 543: rpm->extra->requires[i]->name, NULL);
1.29 daniel 544: if (rpm->extra->requires[i]->name[0] != '/') {
545: snprintf(buf, sizeof(buf) - 1, "%sresources/%s.rdf",
546: dotdot, rpm->extra->requires[i]->name);
547: xmlSetProp(elem, "href", buf);
548: }
1.2 httpng 549: }
550: }
1.28 daniel 551: if (rpm->extra->filelist)
552: rdfSetValue(desc, "Files", rpmNs, rpm->extra->filelist);
1.4 veillard 553:
554: /*
1.12 veillard 555: * Save the RDF to a buffer, remove the tree.
1.4 veillard 556: */
1.12 veillard 557: rdfWriteMemory(rdf, &buffer, &size);
1.4 veillard 558: rdfDestroySchema(rdf);
1.12 veillard 559:
560: /*
561: * if the file already exists avoid to overwrite it if the content
562: * didn't change.
563: */
564: if ((stat_res == 0) && (stat_buf.st_size == size)) {
565: char *buffer2 = malloc(size * sizeof(char));
566:
567: if (buffer2 == NULL) {
568: fprintf(stderr, " : running out of memory\n");
569: return;
570: }
571: output = fopen(file, "r");
572: if (output == NULL) {
573: fprintf(stderr, "couldn't open %s for reading !\n", file);
574: return;
575: }
576: if (fread(buffer2, size, 1, output) != 1) {
577: fprintf(stderr, "Problem reading from %s !\n", file);
578: }
579: fclose(output);
580:
581: /*
582: * Now compare the content !
583: */
584: if (!memcmp(buffer, buffer2, size)) {
585: free(buffer2);
1.20 veillard 586: if (rpm2htmlVerbose > 1)
1.12 veillard 587: fprintf(stderr, "File %s : Content identical !\n", file);
588: return;
589: }
590: free(buffer2);
591: }
592:
593: /*
594: * Dump the file.
595: */
1.20 veillard 596: if (rpm2htmlVerbose > 1) {
1.12 veillard 597: printf("Dumping %s\n", file);
598: }
599: output = fopen(file, "w");
600: if (output == NULL) {
601: fprintf(stderr, "couldn't open %s for writing !\n", file);
602: return;
603: }
604: if (fwrite(buffer, size, 1, output) != 1) {
605: fprintf(stderr, "Problem writing to %s !\n", file);
606: }
607: fclose(output);
1.1 httpng 608: }
609:
1.13 veillard 610: /*
611: * Create and RDF file containing informations about a resource.
612: */
613:
614: void dumpResRdf(rpmRessPtr res) {
615: FILE *output;
616: struct stat stat_buf;
617: char *base;
618: int i;
619: char buf[10000];
620: char file[1000];
621: char *buffer;
622: int size;
623: int stat_res;
624: rpmDataPtr rpm;
625: rpmDirPtr dir;
626: rdfSchema rdf;
627: rdfNamespace rpmNs;
628: rdfDescription desc;
629: static int initialized = 0;
630:
631: if (!rpm2html_dump_rdf_resources) return;
632:
633: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
634: else return;
635:
636: if (res->nb_provider == 0) return;
637:
1.15 veillard 638: sprintf(file, "%s/%s.rdf", base, res->name);
1.13 veillard 639:
640: /*
641: * Create the directory if needed
642: */
643: if (!initialized) {
644: sprintf(buf, "%s", base);
645: createDirectory(buf);
646: initialized = 1;
647: }
648:
649: /*
650: * build the RDF document tree
651: * Note : the order is not important but following the rpmData
652: * structure order is easier to check.
653: */
654: rdf = rdfNewSchema();
655: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
656: for (i = 0;i < res->nb_provider;i++) {
657: rpm = res->provider[i];
658: dir = rpm->dir;
659: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
660: if (dir->mirrors[0] != NULL)
661: sprintf(buf, "%s/%s/%s",
662: dir->mirrors[0], rpm->subdir, rpm->filename);
663: else
664: sprintf(buf, "%s/%s/%s",
665: dir->ftp, rpm->subdir, rpm->filename);
666: } else {
667: if (dir->mirrors[0] != NULL)
668: sprintf(buf, "%s/%s",
669: dir->mirrors[0], rpm->filename);
670: else
671: sprintf(buf, "%s/%s",
672: dir->ftp, rpm->filename);
673: }
674: desc = rdfAddDescription(rdf, NULL, buf);
1.29 daniel 675: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
676: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
677: sprintf(buf, "../%s/%s/%s.rdf", dir->subdir,
678: rpm->subdir, rpmName(rpm));
679: else
680: sprintf(buf, "../%s/%s.rdf", dir->subdir, rpmName(rpm));
681: } else {
682: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
683: sprintf(buf, "../%s/%s.rdf", rpm->subdir, rpmName(rpm));
684: else
685: sprintf(buf, "../%s.rdf", rpmName(rpm));
686: }
687: xmlSetProp(desc, "href", buf);
1.13 veillard 688: rdfSetValue(desc, "Name", rpmNs, rpm->name);
689: rdfSetValue(desc, "Version", rpmNs, rpm->version);
690: rdfSetValue(desc, "Release", rpmNs, rpm->release);
691: if (rpm->arch)
692: rdfSetValue(desc, "Arch", rpmNs, rpm->arch);
693: if (rpm->os)
694: rdfSetValue(desc, "Os", rpmNs, rpm->os);
695: if (rpm->distribution)
696: rdfSetValue(desc, "Distribution", rpmNs, rpm->distribution);
697: if (rpm->vendor)
698: rdfSetValue(desc, "Vendor", rpmNs, rpm->vendor);
699: sprintf(buf, "%d", (int) rpm->date);
700: rdfSetValue(desc, "Date", rpmNs, buf);
1.17 veillard 701: sprintf(buf, "%d", (int) rpm->size);
702: rdfSetValue(desc, "Size", rpmNs, buf);
1.14 httpng 703: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
704: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0'))
705: sprintf(buf, "%s/%s",
706: dir->subdir, rpm->subdir);
707: else
708: sprintf(buf, "%s",
709: rpm->subdir);
710: } else {
711: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0'))
712: sprintf(buf, "%s",
713: dir->subdir);
714: else
715: buf[0] = '\0';
716: }
717: if (buf[0] != '\0')
718: rdfSetValue(desc, "Subdir", rpmNs, buf);
1.13 veillard 719: }
720:
721: /*
722: * Save the RDF to a buffer, remove the tree.
723: */
724: rdfWriteMemory(rdf, &buffer, &size);
725: rdfDestroySchema(rdf);
726:
727: /*
728: * if the file already exists avoid to overwrite it if the content
729: * didn't change.
730: */
731: stat_res = stat(file, &stat_buf);
732:
733: if ((stat_res == 0) && (stat_buf.st_size == size)) {
734: char *buffer2 = malloc(size * sizeof(char));
735:
736: if (buffer2 == NULL) {
737: fprintf(stderr, " : running out of memory\n");
738: return;
739: }
740: output = fopen(file, "r");
741: if (output == NULL) {
742: fprintf(stderr, "couldn't open %s for reading !\n", file);
743: return;
744: }
745: if (fread(buffer2, size, 1, output) != 1) {
746: fprintf(stderr, "Problem reading from %s !\n", file);
747: }
748: fclose(output);
749:
750: /*
751: * Now compare the content !
752: */
753: if (!memcmp(buffer, buffer2, size)) {
754: free(buffer2);
1.20 veillard 755: if (rpm2htmlVerbose > 1)
1.13 veillard 756: fprintf(stderr, "File %s : Content identical !\n", file);
757: return;
758: }
759: free(buffer2);
760: }
761:
762: /*
763: * Dump the file.
764: */
1.20 veillard 765: if (rpm2htmlVerbose > 1) {
1.13 veillard 766: printf("Dumping %s\n", file);
767: }
768: output = fopen(file, "w");
769: if (output == NULL) {
770: fprintf(stderr, "couldn't open %s for writing !\n", file);
771: return;
772: }
773: if (fwrite(buffer, size, 1, output) != 1) {
774: fprintf(stderr, "Problem writing to %s !\n", file);
775: }
776: fclose(output);
777: }
778:
779: /*
780: * Dump all the RDf files about known resources.
781: */
782:
783: void dumpAllResRdf(void) {
784: rpmRessPtr cur;
785:
786: if (!rpm2html_dump_rdf_resources) return;
787:
788: cur = ressList;
789:
790: while (cur != NULL) {
791: dumpResRdf(cur);
792: cur = cur->next;
793: }
1.21 daniel 794: }
795:
796: /*
797: * Dump an apropos RDF file for all packages.
1.22 daniel 798: * Since the file is really too big to be kept as-if, it is compressed
1.21 daniel 799: */
800:
801: void dumpAproposRdf(void) {
802: rpmDataPtr rpm;
803: char file[1000];
804: char buf[1000];
805: rdfSchema rdf;
806: rdfNamespace rpmNs;
807: rdfDescription desc;
808: rpmDirPtr dir;
809: char *base;
1.22 daniel 810: char *buffer;
811: int size;
812: gzFile output;
813: int res;
1.21 daniel 814:
815: if (!rpm2html_dump_rdf_resources) return;
816:
817: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
818: else return;
819:
1.22 daniel 820: sprintf(file, "%s/fullIndex.rdf.gz", base);
1.21 daniel 821: if (rpm2htmlVerbose > 1) {
822: printf("Dumping %s\n", file);
823: }
824:
825: /*
826: * build the RDF document tree, one only dump the minimum needed
827: * for searching.
828: */
829: rdf = rdfNewSchema();
830: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
831:
832: rpm = rpmSoftwareList;
833:
834: while (rpm != NULL) {
835: dir = rpm->dir;
836: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
837: if (dir->mirrors[0] != NULL)
838: sprintf(buf, "%s/%s/%s",
839: dir->mirrors[0], rpm->subdir, rpm->filename);
840: else
841: sprintf(buf, "%s/%s/%s",
842: dir->ftp, rpm->subdir, rpm->filename);
843: } else {
844: if (dir->mirrors[0] != NULL)
845: sprintf(buf, "%s/%s",
846: dir->mirrors[0], rpm->filename);
847: else
848: sprintf(buf, "%s/%s",
849: dir->ftp, rpm->filename);
850: }
851: desc = rdfAddDescription(rdf, NULL, buf);
852: rdfSetValue(desc, "Name", rpmNs, rpm->name);
1.23 veillard 853: rdfSetValue(desc, "Summary", rpmNs, rpm->summary);
854: rpm = rpm->nextSoft;
1.21 daniel 855: }
856:
857: /*
858: * Dump the RDF tree, and cleanup.
859: */
1.22 daniel 860: rdfWriteMemory(rdf, &buffer, &size);
1.21 daniel 861: rdfDestroySchema(rdf);
1.22 daniel 862:
863: /*
864: * Write the compressed version of the RDF base.
865: */
866: output = gzopen(file, "w9");
867: if (output == NULL) {
868: fprintf(stderr, "Could not write %s : gzopen failed\n", file);
869: return;
870: }
871: res = gzwrite(output, buffer, size);
872: if (res <= 0) {
873: fprintf(stderr, "Could not write %s : gzwrite failed\n", file);
874: return;
875: }
876: gzclose(output);
1.13 veillard 877: }
878:
1.25 veillard 879: /*
880: * Dump the distribs/xxx.rdf file giving information about a
881: * specific distribution
882: */
883:
884: void dumpDistRdf(rpmDirPtr dir) {
885: char buf[100];
886: char file[1000];
887: rdfSchema rdf;
888: rdfNamespace rpmNs;
889: rdfDescription desc;
890: rdfBag mirrors;
891: rdfElement mirror;
892: struct stat stat_buf;
893: int stat_res;
894: char *base, *ptr;
895: char *buffer;
896: int size;
897: FILE *output;
898: int i;
899:
900: if (!rpm2html_dump_rdf_resources) return;
901:
902: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
903: else return;
904:
905: sprintf(buf, "%s", dir->subdir);
906: for (ptr = &buf[0]; *ptr; ptr++) if (*ptr == '/') *ptr = '_';
907: sprintf(file, "%s/distribs", base);
908: createDirectory(file);
909: sprintf(file, "%s/distribs/%s.rdf", base, buf);
910:
911: /*
912: * build the RDF document tree, one only dump the minimum needed
913: * for searching distributions informations.
914: */
915: rdf = rdfNewSchema();
916: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
917:
918: desc = rdfAddDescription(rdf, NULL, dir->ftp);
919: rdfSetValue(desc, "ID", rpmNs, dir->subdir);
920: rdfSetValue(desc, "Name", rpmNs, dir->name);
921: rdfSetValue(desc, "Origin", rpmNs, dir->ftp);
922: rdfSetValue(desc, "Sources", rpmNs, dir->ftpsrc);
923: sprintf(buf, "%d", dir->files);
924: mirrors = rdfBagCreate(rdf, desc, "Mirrors", rpmNs);
925: for (i = 0;i < dir->nb_mirrors;i++) {
926: mirror = rdfBagAddValue(mirrors, "Mirror", rpmNs, NULL, NULL);
927: rdfSetElementResource(rdf, mirror, dir->mirrors[i]);
928: }
929:
930: /*
931: * Dump the RDF tree, and cleanup.
932: */
933: rdfWriteMemory(rdf, &buffer, &size);
934: rdfDestroySchema(rdf);
935:
936: /*
937: * if the file already exists avoid to overwrite it if the content
938: * didn't change.
939: */
940: stat_res = stat(file, &stat_buf);
941:
942: if ((stat_res == 0) && (stat_buf.st_size == size)) {
943: char *buffer2 = malloc(size * sizeof(char));
944:
945: if (buffer2 == NULL) {
946: fprintf(stderr, " : running out of memory\n");
947: return;
948: }
949: output = fopen(file, "r");
950: if (output == NULL) {
951: fprintf(stderr, "couldn't open %s for reading !\n", file);
952: return;
953: }
954: if (fread(buffer2, size, 1, output) != 1) {
955: fprintf(stderr, "Problem reading from %s !\n", file);
956: }
957: fclose(output);
958:
959: /*
960: * Now compare the content !
961: */
962: if (!memcmp(buffer, buffer2, size)) {
963: free(buffer2);
964: if (rpm2htmlVerbose > 1)
965: fprintf(stderr, "File %s : Content identical !\n", file);
966: return;
967: }
968: free(buffer2);
969: }
970:
971: /*
972: * Dump the file.
973: */
974: if (rpm2htmlVerbose > 1) {
975: printf("Dumping %s\n", file);
976: }
977: output = fopen(file, "w");
978: if (output == NULL) {
979: fprintf(stderr, "couldn't open %s for writing !\n", file);
980: return;
981: }
982: if (fwrite(buffer, size, 1, output) != 1) {
983: fprintf(stderr, "Problem writing to %s !\n", file);
984: }
985: fclose(output);
986: }
1.26 daniel 987:
988: /*
989: * Dump the distribs/metadata.rdf file listing all the recognized
990: * metadata mirrors sites.
991: */
992:
993: void dumpMetadataListRdf(void) {
994: char file[1000];
995: rdfSchema rdf;
996: rdfNamespace rpmNs;
997: rdfDescription desc;
998: struct stat stat_buf;
999: int stat_res;
1000: char *base;
1001: char *buffer;
1002: int size;
1003: FILE *output;
1004: int i;
1005:
1006: if (!rpm2html_dump_rdf_resources) return;
1007:
1008: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
1009: else return;
1010:
1011: sprintf(file, "%s/distribs", base);
1012: createDirectory(file);
1013: sprintf(file, "%s/distribs/metadata.rdf", base);
1014:
1015: /*
1016: * build the RDF document tree, one only dump the minimum needed
1017: * for searching distributions informations.
1018: */
1019: rdf = rdfNewSchema();
1020: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
1021:
1022: for (i = 0;i < nb_metadata_mirrors;i++){
1023: desc = rdfAddDescription(rdf, NULL, metadata_mirrors[i]);
1024: rdfSetValue(desc, "URI", rpmNs, metadata_mirrors[i]);
1025: }
1026:
1027: /*
1028: * Dump the RDF tree, and cleanup.
1029: */
1030: rdfWriteMemory(rdf, &buffer, &size);
1031: rdfDestroySchema(rdf);
1032:
1033: /*
1034: * if the file already exists avoid to overwrite it if the content
1035: * didn't change.
1036: */
1037: stat_res = stat(file, &stat_buf);
1038:
1039: if ((stat_res == 0) && (stat_buf.st_size == size)) {
1040: char *buffer2 = malloc(size * sizeof(char));
1041:
1042: if (buffer2 == NULL) {
1043: fprintf(stderr, " : running out of memory\n");
1044: return;
1045: }
1046: output = fopen(file, "r");
1047: if (output == NULL) {
1048: fprintf(stderr, "couldn't open %s for reading !\n", file);
1049: return;
1050: }
1051: if (fread(buffer2, size, 1, output) != 1) {
1052: fprintf(stderr, "Problem reading from %s !\n", file);
1053: }
1054: fclose(output);
1055:
1056: /*
1057: * Now compare the content !
1058: */
1059: if (!memcmp(buffer, buffer2, size)) {
1060: free(buffer2);
1061: if (rpm2htmlVerbose > 1)
1062: fprintf(stderr, "File %s : Content identical !\n", file);
1063: return;
1064: }
1065: free(buffer2);
1066: }
1067:
1068: /*
1069: * Dump the file.
1070: */
1071: if (rpm2htmlVerbose > 1) {
1072: printf("Dumping %s\n", file);
1073: }
1074: output = fopen(file, "w");
1075: if (output == NULL) {
1076: fprintf(stderr, "couldn't open %s for writing !\n", file);
1077: return;
1078: }
1079: if (fwrite(buffer, size, 1, output) != 1) {
1080: fprintf(stderr, "Problem writing to %s !\n", file);
1081: }
1082: fclose(output);
1083: }
1084:
1.25 veillard 1085: /*
1086: * Dump the distribs/list.rdf file listing all the recognized distributions
1.26 daniel 1087: * as well as the metadata mirrors list.
1.25 veillard 1088: */
1089:
1090: void dumpDistListRdf(void) {
1091: rpmDirPtr dir;
1092: char file[1000];
1093: rdfSchema rdf;
1094: rdfNamespace rpmNs;
1095: rdfDescription desc;
1096: struct stat stat_buf;
1097: int stat_res;
1098: char *base;
1099: char *buffer;
1100: int size;
1101: FILE *output;
1102:
1103: if (!rpm2html_dump_rdf_resources) return;
1104:
1105: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
1106: else return;
1107:
1.26 daniel 1108: dumpMetadataListRdf();
1109:
1.25 veillard 1110: sprintf(file, "%s/distribs", base);
1111: createDirectory(file);
1112: sprintf(file, "%s/distribs/list.rdf", base);
1113:
1114: /*
1115: * build the RDF document tree, one only dump the minimum needed
1116: * for searching distributions informations.
1117: */
1118: rdf = rdfNewSchema();
1119: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
1120:
1121: dir = dirList;
1122: while (dir != NULL) {
1123: desc = rdfAddDescription(rdf, NULL, dir->ftp);
1124: rdfSetValue(desc, "ID", rpmNs, dir->subdir);
1125: dumpDistRdf(dir);
1126: dir = dir->next;
1127: }
1128: /*
1129: * Dump the RDF tree, and cleanup.
1130: */
1131: rdfWriteMemory(rdf, &buffer, &size);
1132: rdfDestroySchema(rdf);
1133:
1134: /*
1135: * if the file already exists avoid to overwrite it if the content
1136: * didn't change.
1137: */
1138: stat_res = stat(file, &stat_buf);
1139:
1140: if ((stat_res == 0) && (stat_buf.st_size == size)) {
1141: char *buffer2 = malloc(size * sizeof(char));
1142:
1143: if (buffer2 == NULL) {
1144: fprintf(stderr, " : running out of memory\n");
1145: return;
1146: }
1147: output = fopen(file, "r");
1148: if (output == NULL) {
1149: fprintf(stderr, "couldn't open %s for reading !\n", file);
1150: return;
1151: }
1152: if (fread(buffer2, size, 1, output) != 1) {
1153: fprintf(stderr, "Problem reading from %s !\n", file);
1154: }
1155: fclose(output);
1156:
1157: /*
1158: * Now compare the content !
1159: */
1160: if (!memcmp(buffer, buffer2, size)) {
1161: free(buffer2);
1162: if (rpm2htmlVerbose > 1)
1163: fprintf(stderr, "File %s : Content identical !\n", file);
1164: return;
1165: }
1166: free(buffer2);
1167: }
1168:
1169: /*
1170: * Dump the file.
1171: */
1172: if (rpm2htmlVerbose > 1) {
1173: printf("Dumping %s\n", file);
1174: }
1175: output = fopen(file, "w");
1176: if (output == NULL) {
1177: fprintf(stderr, "couldn't open %s for writing !\n", file);
1178: return;
1179: }
1180: if (fwrite(buffer, size, 1, output) != 1) {
1181: fprintf(stderr, "Problem writing to %s !\n", file);
1182: }
1183: fclose(output);
1184: }
1.26 daniel 1185:
Webmaster