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