Annotation of rpm2html/rdf.c, revision 1.29
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.29 ! daniel 6: * $Id: rdf.c,v 1.28 1998/09/14 14:46:11 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);
169: if (value != NULL) rpm->name = strdup(value);
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);
176: if (value != NULL) rpm->version = strdup(value);
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);
183: if (value != NULL) rpm->release = strdup(value);
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);
190: if (value != NULL) rpm->url = strdup(value);
1.7 veillard 191: else rpm->url = NULL;
192:
1.5 veillard 193: rdfGetValue(desc, "Arch", rpmNs, &value, NULL);
194: if (value != NULL) rpm->arch = strdup(value);
1.24 daniel 195: else rpm->arch = strdup("noarch");
1.7 veillard 196:
1.5 veillard 197: rdfGetValue(desc, "Os", rpmNs, &value, NULL);
198: if (value != NULL) rpm->os = strdup(value);
1.7 veillard 199: else rpm->os = strdup("linux");
200:
1.5 veillard 201: rdfGetValue(desc, "Distribution", rpmNs, &value, NULL);
202: if (value != NULL) rpm->distribution = strdup(value);
1.7 veillard 203: else rpm->distribution = strdup(localizedStrings[LANG_UNKNOWN]);
204:
1.5 veillard 205: rdfGetValue(desc, "Vendor", rpmNs, &value, NULL);
206: if (value != NULL) rpm->vendor = strdup(value);
1.7 veillard 207: else rpm->vendor = strdup(localizedStrings[LANG_UNKNOWN]);
208:
1.5 veillard 209: rdfGetValue(desc, "Packager", rpmNs, &value, NULL);
1.28 daniel 210: if (value != NULL) rpm->extra->packager = strdup(value);
211: else rpm->extra->packager = NULL;
1.7 veillard 212:
1.5 veillard 213: rdfGetValue(desc, "Group", rpmNs, &value, NULL);
214: if (value != NULL) rpm->group = strdup(value);
1.7 veillard 215: else rpm->group = strdup(localizedStrings[LANG_NO_GROUP]);
216:
1.5 veillard 217: rdfGetValue(desc, "Summary", rpmNs, &value, NULL);
218: if (value != NULL) rpm->summary = strdup(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.28 daniel 222: if (value != NULL) rpm->extra->description = strdup(value);
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.28 daniel 226: if (value != NULL) rpm->extra->copyright = strdup(value);
227: else rpm->extra->copyright = NULL;
1.7 veillard 228:
1.5 veillard 229: rdfGetValue(desc, "Changelog", rpmNs, &value, NULL);
1.28 daniel 230: if (value != NULL) rpm->extra->changelog = strdup(value);
231: else rpm->extra->changelog = NULL;
1.7 veillard 232:
233: rdfGetValue(desc, "Sources", rpmNs, &value, NULL);
234: if (value != NULL) {
1.28 daniel 235: rpm->extra->srcrpm = strdup(value);
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.28 daniel 253: if (value != NULL) rpm->extra->host = strdup(value);
254: else rpm->extra->host = strdup(localizedStrings[LANG_NO_HOST]);
1.7 veillard 255:
256: rdfGetValue(desc, "Files", rpmNs, &value, NULL);
1.28 daniel 257: if (value != NULL) rpm->extra->filelist = strdup(value);
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: */
356: #ifdef HAVE_SNPRINTF
1.24 daniel 357: sprintf(nameBuffer, "%s-%s-%s.%s.rpm",
358: rpm->name, rpm->version, rpm->release, rpm->arch);
1.6 veillard 359: #else
1.24 daniel 360: snprintf(nameBuffer, 200, "%s-%s-%s.%s.rpm",
361: rpm->name, rpm->version, rpm->release, rpm->arch);
1.6 veillard 362: #endif
363: rpm->filename = strdup(nameBuffer);
364:
365:
366: /*
367: * Cleanup.
368: */
1.5 veillard 369: rdfDestroySchema(rdf);
370: return(rpm);
1.1 httpng 371: }
372:
373: /*
1.4 veillard 374: * Create and RDF file containing the description for the given RPM data.
1.1 httpng 375: */
376: void dumpRpmRdf(rpmDataPtr rpm, rpmSubdirPtr tree) {
1.12 veillard 377: FILE *output;
378: struct stat stat_buf;
1.1 httpng 379: struct tm * tstruct;
380: rpmDirPtr dir = rpm->dir;
1.3 veillard 381: char *base = dir->dir;
1.1 httpng 382: int i;
1.4 veillard 383: char buf[10000];
384: char file[1000];
1.29 ! daniel 385: char dotdot[50];
1.12 veillard 386: char *buffer;
387: int size;
1.27 daniel 388: int stat_res = 0;
1.4 veillard 389: rdfSchema rdf;
390: rdfNamespace rpmNs;
391: rdfDescription desc;
1.29 ! daniel 392: rdfElement elem;
1.4 veillard 393: rdfBag bag;
1.29 ! daniel 394: int deep;
! 395: char *ptr;
1.1 httpng 396:
1.7 veillard 397: if (!rpm2html_dump_rdf) return;
398:
1.3 veillard 399: if (rpm2html_rdf_dir != NULL) base = rpm2html_rdf_dir;
400:
1.29 ! daniel 401: deep = 0;
! 402: if (rpm->subdir != NULL)
! 403: for (ptr = rpm->subdir, deep++;*ptr != 0;ptr++)
! 404: if (*ptr == '/') deep++;
! 405: if (dir->subdir != NULL)
! 406: for (ptr = dir->subdir, deep++;*ptr != 0;ptr++)
! 407: if (*ptr == '/') deep++;
! 408:
1.1 httpng 409: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
410: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
1.4 veillard 411: sprintf(file, "%s/%s/%s/%s.rdf", base, dir->subdir,
1.1 httpng 412: rpm->subdir, rpmName(rpm));
413: else
1.4 veillard 414: sprintf(file, "%s/%s/%s.rdf", base, dir->subdir, rpmName(rpm));
1.1 httpng 415: } else {
416: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
1.4 veillard 417: sprintf(file, "%s/%s/%s.rdf", base, rpm->subdir, rpmName(rpm));
1.1 httpng 418: else
1.4 veillard 419: sprintf(file, "%s/%s.rdf", base, rpmName(rpm));
1.1 httpng 420: }
1.29 ! daniel 421: dotdot[0] = '\0';
! 422: for (;deep > 0;deep --)
! 423: strcat(dotdot, "../");
1.1 httpng 424:
1.12 veillard 425: /*
426: * Check wether the RPM timestamp is older than the filestamp.
427: if ((stat_res = stat(file, &stat_buf)) == 0) {
428: if (stat_buf.st_mtime > rpm->stamp) return;
429: }
1.27 daniel 430: */
431: stat_res = stat(file, &stat_buf);
1.9 veillard 432:
433: /*
434: * Create the directory if needed
435: */
436: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
437: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
438: sprintf(buf, "%s/%s/%s", base, dir->subdir, rpm->subdir);
439: else
440: sprintf(buf, "%s/%s", base, dir->subdir);
441: } else {
442: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
443: sprintf(buf, "%s/%s", base, rpm->subdir);
444: else
445: sprintf(buf, "%s", base);
446: }
447: createDirectory(buf);
448:
1.4 veillard 449: /*
450: * build the RDF document tree
451: * Note : the order is not important but following the rpmData
452: * structure order is easier to check.
453: */
454: rdf = rdfNewSchema();
455: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
456:
1.2 httpng 457: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
458: if (dir->mirrors[0] != NULL)
1.4 veillard 459: sprintf(buf, "%s/%s/%s",
1.2 httpng 460: dir->mirrors[0], rpm->subdir, rpm->filename);
461: else
1.4 veillard 462: sprintf(buf, "%s/%s/%s",
1.2 httpng 463: dir->ftp, rpm->subdir, rpm->filename);
464: } else {
465: if (dir->mirrors[0] != NULL)
1.4 veillard 466: sprintf(buf, "%s/%s",
1.2 httpng 467: dir->mirrors[0], rpm->filename);
468: else
1.4 veillard 469: sprintf(buf, "%s/%s",
1.2 httpng 470: dir->ftp, rpm->filename);
471: }
1.4 veillard 472: desc = rdfAddDescription(rdf, NULL, buf);
473:
474: rdfSetValue(desc, "Name", rpmNs, rpm->name);
475: rdfSetValue(desc, "Version", rpmNs, rpm->version);
476: rdfSetValue(desc, "Release", rpmNs, rpm->release);
477: if (rpm->url)
478: rdfSetValue(desc, "URL", rpmNs, rpm->url);
479: if (rpm->arch)
480: rdfSetValue(desc, "Arch", rpmNs, rpm->arch);
481: if (rpm->os)
482: rdfSetValue(desc, "Os", rpmNs, rpm->os);
1.2 httpng 483: if (rpm->distribution)
1.4 veillard 484: rdfSetValue(desc, "Distribution", rpmNs, rpm->distribution);
1.2 httpng 485: if (rpm->vendor)
1.4 veillard 486: rdfSetValue(desc, "Vendor", rpmNs, rpm->vendor);
1.28 daniel 487: if (rpm->extra->packager)
488: rdfSetValue(desc, "Packager", rpmNs, rpm->extra->packager);
1.4 veillard 489: if (rpm->group)
490: rdfSetValue(desc, "Group", rpmNs, rpm->group);
491: if (rpm->summary)
492: rdfSetValue(desc, "Summary", rpmNs, rpm->summary);
1.28 daniel 493: if (rpm->extra->description)
494: rdfSetValue(desc, "Description", rpmNs, rpm->extra->description);
495: if (rpm->extra->copyright)
496: rdfSetValue(desc, "Copyright", rpmNs, rpm->extra->copyright);
497: if (rpm->extra->changelog)
498: rdfSetValue(desc, "Changelog", rpmNs, rpm->extra->changelog);
499: if (rpm->extra->srcrpm) {
500: rdfSetValue(desc, "Sources", rpmNs, rpm->extra->srcrpm);
1.4 veillard 501: if (dir->ftpsrc) {
1.7 veillard 502: rdfSetValue(desc, "SourcesFtp", rpmNs, dir->ftpsrc);
1.4 veillard 503: }
504: }
1.2 httpng 505: tstruct = localtime(&(rpm->date));
506: #ifdef HAVE_STRFTIME
507: strftime(buf, sizeof(buf) - 1, "%c", tstruct);
508: #else
509: #error "no strftime, please check !"
510: #endif
1.4 veillard 511: rdfSetValue(desc, "BuildDate", rpmNs, buf);
1.12 veillard 512: sprintf(buf, "%d", (int) rpm->date);
1.10 veillard 513: rdfSetValue(desc, "Date", rpmNs, buf);
1.4 veillard 514: sprintf(buf, "%d", rpm->size);
515: rdfSetValue(desc, "Size", rpmNs, buf);
1.28 daniel 516: if (rpm->extra->host)
517: rdfSetValue(desc, "BuildHost", rpmNs, rpm->extra->host);
518: if (rpm->extra->nb_resources > 0) {
1.4 veillard 519: bag = rdfBagCreate(rdf, desc, "Provides", rpmNs);
1.28 daniel 520: for (i = 0;i < rpm->extra->nb_resources;i++) {
1.29 ! daniel 521: elem = rdfBagAddValue(bag, "Resource", rpmNs,
1.28 daniel 522: rpm->extra->resources[i]->name, NULL);
1.29 ! daniel 523: if (rpm->extra->resources[i]->name[0] != '/') {
! 524: snprintf(buf, sizeof(buf) - 1, "%sresources/%s.rdf",
! 525: dotdot, rpm->extra->resources[i]->name);
! 526: xmlSetProp(elem, "href", buf);
! 527: }
1.2 httpng 528: }
529: }
1.28 daniel 530: if (rpm->extra->nb_requires > 0) {
1.4 veillard 531: bag = rdfBagCreate(rdf, desc, "Requires", rpmNs);
1.28 daniel 532: for (i = 0;i < rpm->extra->nb_requires;i++) {
1.29 ! daniel 533: elem = rdfBagAddValue(bag, "Resource", rpmNs,
1.28 daniel 534: rpm->extra->requires[i]->name, NULL);
1.29 ! daniel 535: if (rpm->extra->requires[i]->name[0] != '/') {
! 536: snprintf(buf, sizeof(buf) - 1, "%sresources/%s.rdf",
! 537: dotdot, rpm->extra->requires[i]->name);
! 538: xmlSetProp(elem, "href", buf);
! 539: }
1.2 httpng 540: }
541: }
1.28 daniel 542: if (rpm->extra->filelist)
543: rdfSetValue(desc, "Files", rpmNs, rpm->extra->filelist);
1.4 veillard 544:
545: /*
1.12 veillard 546: * Save the RDF to a buffer, remove the tree.
1.4 veillard 547: */
1.12 veillard 548: rdfWriteMemory(rdf, &buffer, &size);
1.4 veillard 549: rdfDestroySchema(rdf);
1.12 veillard 550:
551: /*
552: * if the file already exists avoid to overwrite it if the content
553: * didn't change.
554: */
555: if ((stat_res == 0) && (stat_buf.st_size == size)) {
556: char *buffer2 = malloc(size * sizeof(char));
557:
558: if (buffer2 == NULL) {
559: fprintf(stderr, " : running out of memory\n");
560: return;
561: }
562: output = fopen(file, "r");
563: if (output == NULL) {
564: fprintf(stderr, "couldn't open %s for reading !\n", file);
565: return;
566: }
567: if (fread(buffer2, size, 1, output) != 1) {
568: fprintf(stderr, "Problem reading from %s !\n", file);
569: }
570: fclose(output);
571:
572: /*
573: * Now compare the content !
574: */
575: if (!memcmp(buffer, buffer2, size)) {
576: free(buffer2);
1.20 veillard 577: if (rpm2htmlVerbose > 1)
1.12 veillard 578: fprintf(stderr, "File %s : Content identical !\n", file);
579: return;
580: }
581: free(buffer2);
582: }
583:
584: /*
585: * Dump the file.
586: */
1.20 veillard 587: if (rpm2htmlVerbose > 1) {
1.12 veillard 588: printf("Dumping %s\n", file);
589: }
590: output = fopen(file, "w");
591: if (output == NULL) {
592: fprintf(stderr, "couldn't open %s for writing !\n", file);
593: return;
594: }
595: if (fwrite(buffer, size, 1, output) != 1) {
596: fprintf(stderr, "Problem writing to %s !\n", file);
597: }
598: fclose(output);
1.1 httpng 599: }
600:
1.13 veillard 601: /*
602: * Create and RDF file containing informations about a resource.
603: */
604:
605: void dumpResRdf(rpmRessPtr res) {
606: FILE *output;
607: struct stat stat_buf;
608: char *base;
609: int i;
610: char buf[10000];
611: char file[1000];
612: char *buffer;
613: int size;
614: int stat_res;
615: rpmDataPtr rpm;
616: rpmDirPtr dir;
617: rdfSchema rdf;
618: rdfNamespace rpmNs;
619: rdfDescription desc;
620: static int initialized = 0;
621:
622: if (!rpm2html_dump_rdf_resources) return;
623:
624: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
625: else return;
626:
627: if (res->nb_provider == 0) return;
628:
1.15 veillard 629: sprintf(file, "%s/%s.rdf", base, res->name);
1.13 veillard 630:
631: /*
632: * Create the directory if needed
633: */
634: if (!initialized) {
635: sprintf(buf, "%s", base);
636: createDirectory(buf);
637: initialized = 1;
638: }
639:
640: /*
641: * build the RDF document tree
642: * Note : the order is not important but following the rpmData
643: * structure order is easier to check.
644: */
645: rdf = rdfNewSchema();
646: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
647: for (i = 0;i < res->nb_provider;i++) {
648: rpm = res->provider[i];
649: dir = rpm->dir;
650: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
651: if (dir->mirrors[0] != NULL)
652: sprintf(buf, "%s/%s/%s",
653: dir->mirrors[0], rpm->subdir, rpm->filename);
654: else
655: sprintf(buf, "%s/%s/%s",
656: dir->ftp, rpm->subdir, rpm->filename);
657: } else {
658: if (dir->mirrors[0] != NULL)
659: sprintf(buf, "%s/%s",
660: dir->mirrors[0], rpm->filename);
661: else
662: sprintf(buf, "%s/%s",
663: dir->ftp, rpm->filename);
664: }
665: desc = rdfAddDescription(rdf, NULL, buf);
1.29 ! daniel 666: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
! 667: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
! 668: sprintf(buf, "../%s/%s/%s.rdf", dir->subdir,
! 669: rpm->subdir, rpmName(rpm));
! 670: else
! 671: sprintf(buf, "../%s/%s.rdf", dir->subdir, rpmName(rpm));
! 672: } else {
! 673: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
! 674: sprintf(buf, "../%s/%s.rdf", rpm->subdir, rpmName(rpm));
! 675: else
! 676: sprintf(buf, "../%s.rdf", rpmName(rpm));
! 677: }
! 678: xmlSetProp(desc, "href", buf);
1.13 veillard 679: rdfSetValue(desc, "Name", rpmNs, rpm->name);
680: rdfSetValue(desc, "Version", rpmNs, rpm->version);
681: rdfSetValue(desc, "Release", rpmNs, rpm->release);
682: if (rpm->arch)
683: rdfSetValue(desc, "Arch", rpmNs, rpm->arch);
684: if (rpm->os)
685: rdfSetValue(desc, "Os", rpmNs, rpm->os);
686: if (rpm->distribution)
687: rdfSetValue(desc, "Distribution", rpmNs, rpm->distribution);
688: if (rpm->vendor)
689: rdfSetValue(desc, "Vendor", rpmNs, rpm->vendor);
690: sprintf(buf, "%d", (int) rpm->date);
691: rdfSetValue(desc, "Date", rpmNs, buf);
1.17 veillard 692: sprintf(buf, "%d", (int) rpm->size);
693: rdfSetValue(desc, "Size", rpmNs, buf);
1.14 httpng 694: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
695: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0'))
696: sprintf(buf, "%s/%s",
697: dir->subdir, rpm->subdir);
698: else
699: sprintf(buf, "%s",
700: rpm->subdir);
701: } else {
702: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0'))
703: sprintf(buf, "%s",
704: dir->subdir);
705: else
706: buf[0] = '\0';
707: }
708: if (buf[0] != '\0')
709: rdfSetValue(desc, "Subdir", rpmNs, buf);
1.13 veillard 710: }
711:
712: /*
713: * Save the RDF to a buffer, remove the tree.
714: */
715: rdfWriteMemory(rdf, &buffer, &size);
716: rdfDestroySchema(rdf);
717:
718: /*
719: * if the file already exists avoid to overwrite it if the content
720: * didn't change.
721: */
722: stat_res = stat(file, &stat_buf);
723:
724: if ((stat_res == 0) && (stat_buf.st_size == size)) {
725: char *buffer2 = malloc(size * sizeof(char));
726:
727: if (buffer2 == NULL) {
728: fprintf(stderr, " : running out of memory\n");
729: return;
730: }
731: output = fopen(file, "r");
732: if (output == NULL) {
733: fprintf(stderr, "couldn't open %s for reading !\n", file);
734: return;
735: }
736: if (fread(buffer2, size, 1, output) != 1) {
737: fprintf(stderr, "Problem reading from %s !\n", file);
738: }
739: fclose(output);
740:
741: /*
742: * Now compare the content !
743: */
744: if (!memcmp(buffer, buffer2, size)) {
745: free(buffer2);
1.20 veillard 746: if (rpm2htmlVerbose > 1)
1.13 veillard 747: fprintf(stderr, "File %s : Content identical !\n", file);
748: return;
749: }
750: free(buffer2);
751: }
752:
753: /*
754: * Dump the file.
755: */
1.20 veillard 756: if (rpm2htmlVerbose > 1) {
1.13 veillard 757: printf("Dumping %s\n", file);
758: }
759: output = fopen(file, "w");
760: if (output == NULL) {
761: fprintf(stderr, "couldn't open %s for writing !\n", file);
762: return;
763: }
764: if (fwrite(buffer, size, 1, output) != 1) {
765: fprintf(stderr, "Problem writing to %s !\n", file);
766: }
767: fclose(output);
768: }
769:
770: /*
771: * Dump all the RDf files about known resources.
772: */
773:
774: void dumpAllResRdf(void) {
775: rpmRessPtr cur;
776:
777: if (!rpm2html_dump_rdf_resources) return;
778:
779: cur = ressList;
780:
781: while (cur != NULL) {
782: dumpResRdf(cur);
783: cur = cur->next;
784: }
1.21 daniel 785: }
786:
787: /*
788: * Dump an apropos RDF file for all packages.
1.22 daniel 789: * Since the file is really too big to be kept as-if, it is compressed
1.21 daniel 790: */
791:
792: void dumpAproposRdf(void) {
793: rpmDataPtr rpm;
794: char file[1000];
795: char buf[1000];
796: rdfSchema rdf;
797: rdfNamespace rpmNs;
798: rdfDescription desc;
799: rpmDirPtr dir;
800: char *base;
1.22 daniel 801: char *buffer;
802: int size;
803: gzFile output;
804: int res;
1.21 daniel 805:
806: if (!rpm2html_dump_rdf_resources) return;
807:
808: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
809: else return;
810:
1.22 daniel 811: sprintf(file, "%s/fullIndex.rdf.gz", base);
1.21 daniel 812: if (rpm2htmlVerbose > 1) {
813: printf("Dumping %s\n", file);
814: }
815:
816: /*
817: * build the RDF document tree, one only dump the minimum needed
818: * for searching.
819: */
820: rdf = rdfNewSchema();
821: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
822:
823: rpm = rpmSoftwareList;
824:
825: while (rpm != NULL) {
826: dir = rpm->dir;
827: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
828: if (dir->mirrors[0] != NULL)
829: sprintf(buf, "%s/%s/%s",
830: dir->mirrors[0], rpm->subdir, rpm->filename);
831: else
832: sprintf(buf, "%s/%s/%s",
833: dir->ftp, rpm->subdir, rpm->filename);
834: } else {
835: if (dir->mirrors[0] != NULL)
836: sprintf(buf, "%s/%s",
837: dir->mirrors[0], rpm->filename);
838: else
839: sprintf(buf, "%s/%s",
840: dir->ftp, rpm->filename);
841: }
842: desc = rdfAddDescription(rdf, NULL, buf);
843: rdfSetValue(desc, "Name", rpmNs, rpm->name);
1.23 veillard 844: rdfSetValue(desc, "Summary", rpmNs, rpm->summary);
845: rpm = rpm->nextSoft;
1.21 daniel 846: }
847:
848: /*
849: * Dump the RDF tree, and cleanup.
850: */
1.22 daniel 851: rdfWriteMemory(rdf, &buffer, &size);
1.21 daniel 852: rdfDestroySchema(rdf);
1.22 daniel 853:
854: /*
855: * Write the compressed version of the RDF base.
856: */
857: output = gzopen(file, "w9");
858: if (output == NULL) {
859: fprintf(stderr, "Could not write %s : gzopen failed\n", file);
860: return;
861: }
862: res = gzwrite(output, buffer, size);
863: if (res <= 0) {
864: fprintf(stderr, "Could not write %s : gzwrite failed\n", file);
865: return;
866: }
867: gzclose(output);
1.13 veillard 868: }
869:
1.25 veillard 870: /*
871: * Dump the distribs/xxx.rdf file giving information about a
872: * specific distribution
873: */
874:
875: void dumpDistRdf(rpmDirPtr dir) {
876: char buf[100];
877: char file[1000];
878: rdfSchema rdf;
879: rdfNamespace rpmNs;
880: rdfDescription desc;
881: rdfBag mirrors;
882: rdfElement mirror;
883: struct stat stat_buf;
884: int stat_res;
885: char *base, *ptr;
886: char *buffer;
887: int size;
888: FILE *output;
889: int i;
890:
891: if (!rpm2html_dump_rdf_resources) return;
892:
893: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
894: else return;
895:
896: sprintf(buf, "%s", dir->subdir);
897: for (ptr = &buf[0]; *ptr; ptr++) if (*ptr == '/') *ptr = '_';
898: sprintf(file, "%s/distribs", base);
899: createDirectory(file);
900: sprintf(file, "%s/distribs/%s.rdf", base, buf);
901:
902: /*
903: * build the RDF document tree, one only dump the minimum needed
904: * for searching distributions informations.
905: */
906: rdf = rdfNewSchema();
907: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
908:
909: desc = rdfAddDescription(rdf, NULL, dir->ftp);
910: rdfSetValue(desc, "ID", rpmNs, dir->subdir);
911: rdfSetValue(desc, "Name", rpmNs, dir->name);
912: rdfSetValue(desc, "Origin", rpmNs, dir->ftp);
913: rdfSetValue(desc, "Sources", rpmNs, dir->ftpsrc);
914: sprintf(buf, "%d", dir->files);
915: mirrors = rdfBagCreate(rdf, desc, "Mirrors", rpmNs);
916: for (i = 0;i < dir->nb_mirrors;i++) {
917: mirror = rdfBagAddValue(mirrors, "Mirror", rpmNs, NULL, NULL);
918: rdfSetElementResource(rdf, mirror, dir->mirrors[i]);
919: }
920:
921: /*
922: * Dump the RDF tree, and cleanup.
923: */
924: rdfWriteMemory(rdf, &buffer, &size);
925: rdfDestroySchema(rdf);
926:
927: /*
928: * if the file already exists avoid to overwrite it if the content
929: * didn't change.
930: */
931: stat_res = stat(file, &stat_buf);
932:
933: if ((stat_res == 0) && (stat_buf.st_size == size)) {
934: char *buffer2 = malloc(size * sizeof(char));
935:
936: if (buffer2 == NULL) {
937: fprintf(stderr, " : running out of memory\n");
938: return;
939: }
940: output = fopen(file, "r");
941: if (output == NULL) {
942: fprintf(stderr, "couldn't open %s for reading !\n", file);
943: return;
944: }
945: if (fread(buffer2, size, 1, output) != 1) {
946: fprintf(stderr, "Problem reading from %s !\n", file);
947: }
948: fclose(output);
949:
950: /*
951: * Now compare the content !
952: */
953: if (!memcmp(buffer, buffer2, size)) {
954: free(buffer2);
955: if (rpm2htmlVerbose > 1)
956: fprintf(stderr, "File %s : Content identical !\n", file);
957: return;
958: }
959: free(buffer2);
960: }
961:
962: /*
963: * Dump the file.
964: */
965: if (rpm2htmlVerbose > 1) {
966: printf("Dumping %s\n", file);
967: }
968: output = fopen(file, "w");
969: if (output == NULL) {
970: fprintf(stderr, "couldn't open %s for writing !\n", file);
971: return;
972: }
973: if (fwrite(buffer, size, 1, output) != 1) {
974: fprintf(stderr, "Problem writing to %s !\n", file);
975: }
976: fclose(output);
977: }
1.26 daniel 978:
979: /*
980: * Dump the distribs/metadata.rdf file listing all the recognized
981: * metadata mirrors sites.
982: */
983:
984: void dumpMetadataListRdf(void) {
985: char file[1000];
986: rdfSchema rdf;
987: rdfNamespace rpmNs;
988: rdfDescription desc;
989: struct stat stat_buf;
990: int stat_res;
991: char *base;
992: char *buffer;
993: int size;
994: FILE *output;
995: int i;
996:
997: if (!rpm2html_dump_rdf_resources) return;
998:
999: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
1000: else return;
1001:
1002: sprintf(file, "%s/distribs", base);
1003: createDirectory(file);
1004: sprintf(file, "%s/distribs/metadata.rdf", base);
1005:
1006: /*
1007: * build the RDF document tree, one only dump the minimum needed
1008: * for searching distributions informations.
1009: */
1010: rdf = rdfNewSchema();
1011: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
1012:
1013: for (i = 0;i < nb_metadata_mirrors;i++){
1014: desc = rdfAddDescription(rdf, NULL, metadata_mirrors[i]);
1015: rdfSetValue(desc, "URI", rpmNs, metadata_mirrors[i]);
1016: }
1017:
1018: /*
1019: * Dump the RDF tree, and cleanup.
1020: */
1021: rdfWriteMemory(rdf, &buffer, &size);
1022: rdfDestroySchema(rdf);
1023:
1024: /*
1025: * if the file already exists avoid to overwrite it if the content
1026: * didn't change.
1027: */
1028: stat_res = stat(file, &stat_buf);
1029:
1030: if ((stat_res == 0) && (stat_buf.st_size == size)) {
1031: char *buffer2 = malloc(size * sizeof(char));
1032:
1033: if (buffer2 == NULL) {
1034: fprintf(stderr, " : running out of memory\n");
1035: return;
1036: }
1037: output = fopen(file, "r");
1038: if (output == NULL) {
1039: fprintf(stderr, "couldn't open %s for reading !\n", file);
1040: return;
1041: }
1042: if (fread(buffer2, size, 1, output) != 1) {
1043: fprintf(stderr, "Problem reading from %s !\n", file);
1044: }
1045: fclose(output);
1046:
1047: /*
1048: * Now compare the content !
1049: */
1050: if (!memcmp(buffer, buffer2, size)) {
1051: free(buffer2);
1052: if (rpm2htmlVerbose > 1)
1053: fprintf(stderr, "File %s : Content identical !\n", file);
1054: return;
1055: }
1056: free(buffer2);
1057: }
1058:
1059: /*
1060: * Dump the file.
1061: */
1062: if (rpm2htmlVerbose > 1) {
1063: printf("Dumping %s\n", file);
1064: }
1065: output = fopen(file, "w");
1066: if (output == NULL) {
1067: fprintf(stderr, "couldn't open %s for writing !\n", file);
1068: return;
1069: }
1070: if (fwrite(buffer, size, 1, output) != 1) {
1071: fprintf(stderr, "Problem writing to %s !\n", file);
1072: }
1073: fclose(output);
1074: }
1075:
1.25 veillard 1076: /*
1077: * Dump the distribs/list.rdf file listing all the recognized distributions
1.26 daniel 1078: * as well as the metadata mirrors list.
1.25 veillard 1079: */
1080:
1081: void dumpDistListRdf(void) {
1082: rpmDirPtr dir;
1083: char file[1000];
1084: rdfSchema rdf;
1085: rdfNamespace rpmNs;
1086: rdfDescription desc;
1087: struct stat stat_buf;
1088: int stat_res;
1089: char *base;
1090: char *buffer;
1091: int size;
1092: FILE *output;
1093:
1094: if (!rpm2html_dump_rdf_resources) return;
1095:
1096: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
1097: else return;
1098:
1.26 daniel 1099: dumpMetadataListRdf();
1100:
1.25 veillard 1101: sprintf(file, "%s/distribs", base);
1102: createDirectory(file);
1103: sprintf(file, "%s/distribs/list.rdf", base);
1104:
1105: /*
1106: * build the RDF document tree, one only dump the minimum needed
1107: * for searching distributions informations.
1108: */
1109: rdf = rdfNewSchema();
1110: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
1111:
1112: dir = dirList;
1113: while (dir != NULL) {
1114: desc = rdfAddDescription(rdf, NULL, dir->ftp);
1115: rdfSetValue(desc, "ID", rpmNs, dir->subdir);
1116: dumpDistRdf(dir);
1117: dir = dir->next;
1118: }
1119: /*
1120: * Dump the RDF tree, and cleanup.
1121: */
1122: rdfWriteMemory(rdf, &buffer, &size);
1123: rdfDestroySchema(rdf);
1124:
1125: /*
1126: * if the file already exists avoid to overwrite it if the content
1127: * didn't change.
1128: */
1129: stat_res = stat(file, &stat_buf);
1130:
1131: if ((stat_res == 0) && (stat_buf.st_size == size)) {
1132: char *buffer2 = malloc(size * sizeof(char));
1133:
1134: if (buffer2 == NULL) {
1135: fprintf(stderr, " : running out of memory\n");
1136: return;
1137: }
1138: output = fopen(file, "r");
1139: if (output == NULL) {
1140: fprintf(stderr, "couldn't open %s for reading !\n", file);
1141: return;
1142: }
1143: if (fread(buffer2, size, 1, output) != 1) {
1144: fprintf(stderr, "Problem reading from %s !\n", file);
1145: }
1146: fclose(output);
1147:
1148: /*
1149: * Now compare the content !
1150: */
1151: if (!memcmp(buffer, buffer2, size)) {
1152: free(buffer2);
1153: if (rpm2htmlVerbose > 1)
1154: fprintf(stderr, "File %s : Content identical !\n", file);
1155: return;
1156: }
1157: free(buffer2);
1158: }
1159:
1160: /*
1161: * Dump the file.
1162: */
1163: if (rpm2htmlVerbose > 1) {
1164: printf("Dumping %s\n", file);
1165: }
1166: output = fopen(file, "w");
1167: if (output == NULL) {
1168: fprintf(stderr, "couldn't open %s for writing !\n", file);
1169: return;
1170: }
1171: if (fwrite(buffer, size, 1, output) != 1) {
1172: fprintf(stderr, "Problem writing to %s !\n", file);
1173: }
1174: fclose(output);
1175: }
1.26 daniel 1176:
Webmaster