Annotation of rpm2html/rdf.c, revision 1.16
1.1 httpng 1: /*
2: * rdf.c : implementation for the RDF encoding/decoding of RPM informations.
3: */
4:
1.2 httpng 5: #include "config.h"
1.6 veillard 6: #include <sys/stat.h>
1.2 httpng 7: #ifdef HAVE_FCNTL_H
8: #include <fcntl.h>
9: #endif
10: #include <stdio.h>
11: #include <stdlib.h>
12: #include <string.h>
13: #ifdef HAVE_UNISTD_H
14: #include <unistd.h>
15: #endif
16: #include <time.h>
1.1 httpng 17: #include <errno.h>
1.2 httpng 18: #include <ctype.h>
1.1 httpng 19:
20: #include "rpm2html.h"
21: #include "rpmdata.h"
1.4 veillard 22: #include "html.h"
1.7 veillard 23: #include "language.h"
1.4 veillard 24:
25: #include "rdf_api.h"
1.1 httpng 26: #include "rdf.h"
27:
28: /*
1.16 ! veillard 29: * Open and process an RDF file in the incoming tree of an rpm2html mirror.
! 30: */
! 31: rpmDataPtr rpmOpenRdf(char *nameRdf, rpmDirPtr dir, rpmSubdirPtr tree) {
! 32: char file[1000];
! 33: rpmDataPtr rpm;
! 34:
! 35: /*
! 36: * create path
! 37: */
! 38: if (tree->htmlpath[0] != '\0')
! 39: sprintf(file, "%s/%s/%s", dir->rpmdir, tree->rpmpath, nameRdf);
! 40: else
! 41: sprintf(file, "%s/%s", dir->rpmdir, nameRdf);
! 42:
! 43: rpm = rpmOpenRdfFile(file);
! 44:
! 45: if (rpm != NULL) {
! 46: /* setup tree and subdir informations */
! 47: rpm->dir = dir;
! 48: if (tree) {
! 49: if ((tree->rpmpath != NULL) && (tree->rpmpath[0] != '\0'))
! 50: rpm->subdir = strdup(tree->rpmpath);
! 51: else
! 52: rpm->subdir = NULL;
! 53: } else
! 54: rpm->subdir = NULL;
! 55:
! 56: /* Add the package files to the real filesystem tree if asked for */
! 57: if ((dir->build_tree != 0) && (rpm->filelist != NULL)) {
! 58: char *cur, *filename;
! 59:
! 60: cur = rpm->filelist;
! 61: while ((*cur != '\0') && (*cur != '/')) cur++;
! 62: filename = cur;
! 63: while (*cur != '\0') {
! 64: if ((*cur == '\n') || (*cur == '\r')) {
! 65: if (cur != filename)
! 66: rpmAddRealFile(dir->root, filename, rpm);
! 67: while ((*cur != '\0') && (*cur != '/')) cur++;
! 68: filename = cur;
! 69: } else
! 70: cur++;
! 71: }
! 72: if (cur != filename)
! 73: rpmAddRealFile(dir->root, filename, rpm);
! 74: }
! 75:
! 76: /* Register this package */
! 77: rpmAddSoftware(rpm);
! 78:
! 79: /* dump the HTML related to this package */
! 80: if (rpm2html_dump_html)
! 81: dumpRpmHtml(rpm, tree);
! 82: if (rpm2html_dump_rdf)
! 83: dumpRpmRdf(rpm, tree);
! 84:
! 85: /* free large amount of data not used later */
! 86: if (rpm->filelist) free(rpm->filelist);
! 87: rpm->filelist = NULL;
! 88: if (rpm->copyright) free(rpm->copyright);
! 89: rpm->copyright = NULL;
! 90: if (rpm->changelog) free(rpm->changelog);
! 91: rpm->changelog = NULL;
! 92: if (rpm->description) free(rpm->description);
! 93: rpm->description = NULL;
! 94:
! 95: /* increment the counters */
! 96: rpm2html_files++;
! 97: rpm2html_size += rpm->size / 1024;
! 98: }
! 99: return(rpm);
! 100: }
! 101:
! 102: /*
1.1 httpng 103: * Open an RDF file call the parser to create a XML tree
104: * Then walk the tree and build an rpmData structure for
105: * the corresponding package.
106: */
1.16 ! veillard 107: rpmDataPtr rpmOpenRdfFile(char *file) {
1.6 veillard 108: char nameBuffer[200];
1.5 veillard 109: rdfSchema rdf;
110: rdfNamespace rpmNs;
111: rdfNamespace rdfNs;
112: rdfDescription desc;
113: rdfBag bag;
1.7 veillard 114: rdfElement elem;
1.5 veillard 115: char *value;
116: rpmDataPtr rpm;
1.6 veillard 117: struct stat buf;
1.7 veillard 118: int i;
1.5 veillard 119:
120: rdf = rdfRead(file);
121: if (rdf == NULL) return(NULL);
122:
123: /*
124: * Start the analyze, check that's an RDf for RPM packages.
125: */
126: rdfNs = rdfGetNamespace(rdf, "http://www.w3.org/TR/WD-rdf-syntax#");
127: if (rdfNs == NULL) {
128: fprintf(stderr, "%s is not an RDF schema\n", file);
129: rdfDestroySchema(rdf);
130: return(NULL);
131: }
132: rpmNs = rdfGetNamespace(rdf, "http://www.rpm.org/");
133: if (rdfNs == NULL) {
134: fprintf(stderr, "%s is not an RPM specific RDF schema\n", file);
135: rdfDestroySchema(rdf);
136: return(NULL);
137: }
138: desc = rdfFirstDescription(rdf);
139: if (rdfNs == NULL) {
140: fprintf(stderr, "%s RDF schema seems empty\n", file);
141: rdfDestroySchema(rdf);
142: return(NULL);
143: }
144:
145: /*
146: * We are pretty sure that it will be a valid schema,
1.6 veillard 147: * Allocate the rpmData structure, initialize it.
1.5 veillard 148: */
149: rpm = (rpmDataPtr) malloc(sizeof(rpmData));
150: if (rpm == NULL) {
151: fprintf(stderr, "rpmOpenRdf : out of memory !\n");
152: rdfDestroySchema(rdf);
153: return(NULL);
154: }
1.6 veillard 155: memset(rpm, 0, sizeof(rpmData));
1.5 veillard 156:
1.6 veillard 157: stat(file, &buf);
158: rpm->stamp = buf.st_mtime;
159:
160: /*
161: * Now extract all the metadata informations from the RDF tree
162: */
1.5 veillard 163: rdfGetValue(desc, "Name", rpmNs, &value, NULL);
164: if (value != NULL) rpm->name = strdup(value);
165: else {
166: fprintf(stderr, "%s RDF schema invalid : no Name\n", file);
167: rdfDestroySchema(rdf);
168: return(NULL);
169: }
170: rdfGetValue(desc, "Version", rpmNs, &value, NULL);
171: if (value != NULL) rpm->version = strdup(value);
172: else {
173: fprintf(stderr, "%s RDF schema invalid : no Version\n", file);
174: rdfDestroySchema(rdf);
175: return(NULL);
176: }
177: rdfGetValue(desc, "Release", rpmNs, &value, NULL);
178: if (value != NULL) rpm->release = strdup(value);
179: else {
180: fprintf(stderr, "%s RDF schema invalid : no Release\n", file);
181: rdfDestroySchema(rdf);
182: return(NULL);
183: }
184: rdfGetValue(desc, "URL", rpmNs, &value, NULL);
185: if (value != NULL) rpm->url = strdup(value);
1.7 veillard 186: else rpm->url = NULL;
187:
1.5 veillard 188: rdfGetValue(desc, "Arch", rpmNs, &value, NULL);
189: if (value != NULL) rpm->arch = strdup(value);
1.7 veillard 190: else rpm->arch = strdup(localizedStrings[LANG_NONE]);
191:
1.5 veillard 192: rdfGetValue(desc, "Os", rpmNs, &value, NULL);
193: if (value != NULL) rpm->os = strdup(value);
1.7 veillard 194: else rpm->os = strdup("linux");
195:
1.5 veillard 196: rdfGetValue(desc, "Distribution", rpmNs, &value, NULL);
197: if (value != NULL) rpm->distribution = strdup(value);
1.7 veillard 198: else rpm->distribution = strdup(localizedStrings[LANG_UNKNOWN]);
199:
1.5 veillard 200: rdfGetValue(desc, "Vendor", rpmNs, &value, NULL);
201: if (value != NULL) rpm->vendor = strdup(value);
1.7 veillard 202: else rpm->vendor = strdup(localizedStrings[LANG_UNKNOWN]);
203:
1.5 veillard 204: rdfGetValue(desc, "Packager", rpmNs, &value, NULL);
205: if (value != NULL) rpm->packager = strdup(value);
1.7 veillard 206: else rpm->packager = NULL;
207:
1.5 veillard 208: rdfGetValue(desc, "Group", rpmNs, &value, NULL);
209: if (value != NULL) rpm->group = strdup(value);
1.7 veillard 210: else rpm->group = strdup(localizedStrings[LANG_NO_GROUP]);
211:
1.5 veillard 212: rdfGetValue(desc, "Summary", rpmNs, &value, NULL);
213: if (value != NULL) rpm->summary = strdup(value);
1.7 veillard 214: else rpm->summary = strdup(localizedStrings[LANG_NO_SUMMARY]);
215:
1.5 veillard 216: rdfGetValue(desc, "Description", rpmNs, &value, NULL);
217: if (value != NULL) rpm->description = strdup(value);
1.7 veillard 218: else rpm->description = strdup(localizedStrings[LANG_NO_DESCRIPTION]);
219:
1.5 veillard 220: rdfGetValue(desc, "Copyright", rpmNs, &value, NULL);
221: if (value != NULL) rpm->copyright = strdup(value);
1.7 veillard 222: else rpm->copyright = NULL;
223:
1.5 veillard 224: rdfGetValue(desc, "Changelog", rpmNs, &value, NULL);
225: if (value != NULL) rpm->changelog = strdup(value);
1.7 veillard 226: else rpm->changelog = NULL;
227:
228: rdfGetValue(desc, "Sources", rpmNs, &value, NULL);
229: if (value != NULL) {
230: rpm->srcrpm = strdup(value);
231: } else rpm->srcrpm = strdup("");
232:
233: rdfGetValue(desc, "Size", rpmNs, &value, NULL);
234: if (value != NULL) {
235: if (sscanf(value, "%d", &(rpm->size)) != 1)
236: rpm->size = 0;
237: } else rpm->size = 0;
238:
239: rdfGetValue(desc, "Date", rpmNs, &value, NULL);
240: if (value != NULL) {
1.8 veillard 241: if (sscanf(value, "%d", &i) != 1)
1.7 veillard 242: rpm->date = 0;
1.8 veillard 243: else
244: rpm->date = i;
1.7 veillard 245: } else rpm->date = 0;
246:
247: rdfGetValue(desc, "BuildHost", rpmNs, &value, NULL);
248: if (value != NULL) rpm->host = strdup(value);
249: else rpm->host = strdup(localizedStrings[LANG_NO_HOST]);
250:
251: rdfGetValue(desc, "Files", rpmNs, &value, NULL);
252: if (value != NULL) rpm->filelist = strdup(value);
253: else rpm->filelist = NULL;
254:
255: /*
256: * Fetching packages provided is a bit more tricky, one have to
257: * find the RDF Bag, and scan it's values.
258: */
259: rpm->nb_resources = 0;
260: rdfGetValue(desc, "Provides", rpmNs, NULL, &bag);
261: if (bag != NULL) {
262: elem = rdfFirstChild(bag);
1.11 veillard 263: rpm->max_resources = 5;
264: rpm->resources = (rpmRessPtr *) malloc(rpm->max_resources *
265: sizeof(rpmRessPtr));
266: if (rpm->resources == NULL) {
267: fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
268: exit(1);
269: }
1.7 veillard 270: i = 0;
271: while (elem != NULL) {
1.11 veillard 272: if (i >= rpm->max_resources) {
273: rpm->max_resources *= 2;
274: rpm->resources = (rpmRessPtr *) realloc(rpm->resources,
275: rpm->max_resources * sizeof(rpmRessPtr));
276: if (rpm->resources == NULL) {
277: fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
278: exit(1);
279: }
1.7 veillard 280: }
281: /*
282: * Check that we are scanning an RPM Resource.
283: */
284: if ((!strcmp(rdfElemGetPropertyName(elem), "Resource")) &&
285: (rdfElemGetNamespace(elem) == rpmNs)) {
286: value = rdfElemGetValue(elem);
287: if (value != NULL) {
288: rpm->resources[i] = rpmRessAdd(value, rpm, 0);
289: i++;
290: rpm->nb_resources++;
1.8 veillard 291: } else if (verbose > 1) {
1.7 veillard 292: fprintf(stderr, "%s : malformed Resource element !\n", file);
293: }
1.8 veillard 294: } else if (verbose > 1) {
1.7 veillard 295: fprintf(stderr, "%s : malformed Provides bag !\n", file);
296: }
297: elem = rdfNextElem(elem);
298: }
1.8 veillard 299: } else if (verbose > 1) {
1.7 veillard 300: fprintf(stderr, "%s doesn't export any resource\n", file);
301: }
302:
303: /*
304: * idem for the dependencies.
305: */
306: rpm->nb_requires = 0;
307: rdfGetValue(desc, "Requires", rpmNs, NULL, &bag);
308: if (bag != NULL) {
309: elem = rdfFirstChild(bag);
1.11 veillard 310: rpm->max_requires = 5;
311: rpm->requires = (rpmRessPtr *) malloc(rpm->max_requires *
312: sizeof(rpmRessPtr));
313: if (rpm->requires == NULL) {
314: fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
315: exit(1);
316: }
1.7 veillard 317: i = 0;
318: while (elem != NULL) {
1.11 veillard 319: if (i >= rpm->max_requires) {
320: rpm->max_requires *= 2;
321: rpm->requires = (rpmRessPtr *) realloc(rpm->requires,
322: rpm->max_requires * sizeof(rpmRessPtr));
323: if (rpm->requires == NULL) {
324: fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
325: exit(1);
326: }
1.7 veillard 327: }
328: /*
329: * Check that we are scanning an RPM Resource.
330: */
331: if ((!strcmp(rdfElemGetPropertyName(elem), "Resource")) &&
332: (rdfElemGetNamespace(elem) == rpmNs)) {
333: value = rdfElemGetValue(elem);
334: if (value != NULL) {
335: rpm->requires[i] = rpmRequAdd(value, rpm, 0);
336: i++;
337: rpm->nb_requires++;
1.8 veillard 338: } else if (verbose > 1) {
1.7 veillard 339: fprintf(stderr, "%s : malformed Resource element !\n", file);
340: }
1.8 veillard 341: } else if (verbose > 1) {
1.7 veillard 342: fprintf(stderr, "%s : malformed Provides bag !\n", file);
343: }
344: elem = rdfNextElem(elem);
345: }
346: }
1.5 veillard 347:
1.6 veillard 348: /*
349: * Finish filling the rpmData structure.
350: */
351: #ifdef HAVE_SNPRINTF
352: sprintf(nameBuffer, "%s-%s-%s.rpm",
353: rpm->name, rpm->version, rpm->release);
354: #else
355: snprintf(nameBuffer, 200, "%s-%s-%s.rpm",
356: rpm->name, rpm->version, rpm->release);
357: #endif
358: rpm->filename = strdup(nameBuffer);
359:
360:
361: /*
362: * Cleanup.
363: */
1.5 veillard 364: rdfDestroySchema(rdf);
365: return(rpm);
1.1 httpng 366: }
367:
368: /*
1.4 veillard 369: * Create and RDF file containing the description for the given RPM data.
1.1 httpng 370: */
371: void dumpRpmRdf(rpmDataPtr rpm, rpmSubdirPtr tree) {
1.12 veillard 372: FILE *output;
373: struct stat stat_buf;
1.1 httpng 374: struct tm * tstruct;
375: rpmDirPtr dir = rpm->dir;
1.3 veillard 376: char *base = dir->dir;
1.1 httpng 377: int i;
1.4 veillard 378: char buf[10000];
379: char file[1000];
1.12 veillard 380: char *buffer;
381: int size;
382: int stat_res;
1.4 veillard 383: rdfSchema rdf;
384: rdfNamespace rpmNs;
385: rdfDescription desc;
386: rdfBag bag;
1.1 httpng 387:
1.7 veillard 388: if (!rpm2html_dump_rdf) return;
389:
1.3 veillard 390: if (rpm2html_rdf_dir != NULL) base = rpm2html_rdf_dir;
391:
1.1 httpng 392: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
393: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
1.4 veillard 394: sprintf(file, "%s/%s/%s/%s.rdf", base, dir->subdir,
1.1 httpng 395: rpm->subdir, rpmName(rpm));
396: else
1.4 veillard 397: sprintf(file, "%s/%s/%s.rdf", base, dir->subdir, rpmName(rpm));
1.1 httpng 398: } else {
399: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
1.4 veillard 400: sprintf(file, "%s/%s/%s.rdf", base, rpm->subdir, rpmName(rpm));
1.1 httpng 401: else
1.4 veillard 402: sprintf(file, "%s/%s.rdf", base, rpmName(rpm));
1.1 httpng 403: }
404:
1.12 veillard 405: /*
406: * Check wether the RPM timestamp is older than the filestamp.
407: */
408: if ((stat_res = stat(file, &stat_buf)) == 0) {
409: if (stat_buf.st_mtime > rpm->stamp) return;
410: }
1.9 veillard 411:
412: /*
413: * Create the directory if needed
414: */
415: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
416: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
417: sprintf(buf, "%s/%s/%s", base, dir->subdir, rpm->subdir);
418: else
419: sprintf(buf, "%s/%s", base, dir->subdir);
420: } else {
421: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
422: sprintf(buf, "%s/%s", base, rpm->subdir);
423: else
424: sprintf(buf, "%s", base);
425: }
426: createDirectory(buf);
427:
1.4 veillard 428: /*
429: * build the RDF document tree
430: * Note : the order is not important but following the rpmData
431: * structure order is easier to check.
432: */
433: rdf = rdfNewSchema();
434: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
435:
1.2 httpng 436: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
437: if (dir->mirrors[0] != NULL)
1.4 veillard 438: sprintf(buf, "%s/%s/%s",
1.2 httpng 439: dir->mirrors[0], rpm->subdir, rpm->filename);
440: else
1.4 veillard 441: sprintf(buf, "%s/%s/%s",
1.2 httpng 442: dir->ftp, rpm->subdir, rpm->filename);
443: } else {
444: if (dir->mirrors[0] != NULL)
1.4 veillard 445: sprintf(buf, "%s/%s",
1.2 httpng 446: dir->mirrors[0], rpm->filename);
447: else
1.4 veillard 448: sprintf(buf, "%s/%s",
1.2 httpng 449: dir->ftp, rpm->filename);
450: }
1.4 veillard 451: desc = rdfAddDescription(rdf, NULL, buf);
452:
453: rdfSetValue(desc, "Name", rpmNs, rpm->name);
454: rdfSetValue(desc, "Version", rpmNs, rpm->version);
455: rdfSetValue(desc, "Release", rpmNs, rpm->release);
456: if (rpm->url)
457: rdfSetValue(desc, "URL", rpmNs, rpm->url);
458: if (rpm->arch)
459: rdfSetValue(desc, "Arch", rpmNs, rpm->arch);
460: if (rpm->os)
461: rdfSetValue(desc, "Os", rpmNs, rpm->os);
1.2 httpng 462: if (rpm->distribution)
1.4 veillard 463: rdfSetValue(desc, "Distribution", rpmNs, rpm->distribution);
1.2 httpng 464: if (rpm->vendor)
1.4 veillard 465: rdfSetValue(desc, "Vendor", rpmNs, rpm->vendor);
466: if (rpm->packager)
467: rdfSetValue(desc, "Packager", rpmNs, rpm->packager);
468: if (rpm->group)
469: rdfSetValue(desc, "Group", rpmNs, rpm->group);
470: if (rpm->summary)
471: rdfSetValue(desc, "Summary", rpmNs, rpm->summary);
472: if (rpm->description)
473: rdfSetValue(desc, "Description", rpmNs, rpm->description);
474: if (rpm->copyright)
475: rdfSetValue(desc, "Copyright", rpmNs, rpm->copyright);
476: if (rpm->changelog)
477: rdfSetValue(desc, "Changelog", rpmNs, rpm->changelog);
478: if (rpm->srcrpm) {
1.7 veillard 479: rdfSetValue(desc, "Sources", rpmNs, rpm->srcrpm);
1.4 veillard 480: if (dir->ftpsrc) {
1.7 veillard 481: rdfSetValue(desc, "SourcesFtp", rpmNs, dir->ftpsrc);
1.4 veillard 482: }
483: }
1.2 httpng 484: tstruct = localtime(&(rpm->date));
485: #ifdef HAVE_STRFTIME
486: strftime(buf, sizeof(buf) - 1, "%c", tstruct);
487: #else
488: #error "no strftime, please check !"
489: #endif
1.4 veillard 490: rdfSetValue(desc, "BuildDate", rpmNs, buf);
1.12 veillard 491: sprintf(buf, "%d", (int) rpm->date);
1.10 veillard 492: rdfSetValue(desc, "Date", rpmNs, buf);
1.4 veillard 493: sprintf(buf, "%d", rpm->size);
494: rdfSetValue(desc, "Size", rpmNs, buf);
1.2 httpng 495: if (rpm->host)
1.4 veillard 496: rdfSetValue(desc, "BuildHost", rpmNs, rpm->host);
1.2 httpng 497: if (rpm->nb_resources > 0) {
1.7 veillard 498: /** !!!!!
499: sprintf(buf, "%d", rpm->nb_resources);
500: rdfSetValue(desc, "NbProvides", rpmNs, buf);
501: */
1.4 veillard 502: bag = rdfBagCreate(rdf, desc, "Provides", rpmNs);
1.2 httpng 503: for (i = 0;i < rpm->nb_resources;i++) {
1.4 veillard 504: rdfBagAddValue(bag, "Resource", rpmNs,
505: rpm->resources[i]->name, NULL);
1.2 httpng 506: }
507: }
508: if (rpm->nb_requires > 0) {
1.7 veillard 509: /** !!!!!
510: sprintf(buf, "%d", rpm->nb_requires);
511: rdfSetValue(desc, "NbRequires", rpmNs, buf);
512: */
1.4 veillard 513: bag = rdfBagCreate(rdf, desc, "Requires", rpmNs);
1.2 httpng 514: for (i = 0;i < rpm->nb_requires;i++) {
1.4 veillard 515: rdfBagAddValue(bag, "Resource", rpmNs,
516: rpm->requires[i]->name, NULL);
1.2 httpng 517: }
518: }
519: if (rpm->filelist)
1.4 veillard 520: rdfSetValue(desc, "Files", rpmNs, rpm->filelist);
521:
522: /*
1.12 veillard 523: * Save the RDF to a buffer, remove the tree.
1.4 veillard 524: */
1.12 veillard 525: rdfWriteMemory(rdf, &buffer, &size);
1.4 veillard 526: rdfDestroySchema(rdf);
1.12 veillard 527:
528: /*
529: * if the file already exists avoid to overwrite it if the content
530: * didn't change.
531: */
532: if ((stat_res == 0) && (stat_buf.st_size == size)) {
533: char *buffer2 = malloc(size * sizeof(char));
534:
535: if (buffer2 == NULL) {
536: fprintf(stderr, " : running out of memory\n");
537: return;
538: }
539: output = fopen(file, "r");
540: if (output == NULL) {
541: fprintf(stderr, "couldn't open %s for reading !\n", file);
542: return;
543: }
544: if (fread(buffer2, size, 1, output) != 1) {
545: fprintf(stderr, "Problem reading from %s !\n", file);
546: }
547: fclose(output);
548:
549: /*
550: * Now compare the content !
551: */
552: if (!memcmp(buffer, buffer2, size)) {
553: free(buffer2);
554: if (verbose > 1)
555: fprintf(stderr, "File %s : Content identical !\n", file);
556: return;
557: }
558: free(buffer2);
559: }
560:
561: /*
562: * Dump the file.
563: */
564: if (verbose > 1) {
565: printf("Dumping %s\n", file);
566: }
567: output = fopen(file, "w");
568: if (output == NULL) {
569: fprintf(stderr, "couldn't open %s for writing !\n", file);
570: return;
571: }
572: if (fwrite(buffer, size, 1, output) != 1) {
573: fprintf(stderr, "Problem writing to %s !\n", file);
574: }
575: fclose(output);
1.1 httpng 576: }
577:
1.13 veillard 578: /*
579: * Create and RDF file containing informations about a resource.
580: */
581:
582: void dumpResRdf(rpmRessPtr res) {
583: FILE *output;
584: struct stat stat_buf;
585: char *base;
586: int i;
587: char buf[10000];
588: char file[1000];
589: char *buffer;
590: int size;
591: int stat_res;
592: rpmDataPtr rpm;
593: rpmDirPtr dir;
594: rdfSchema rdf;
595: rdfNamespace rpmNs;
596: rdfDescription desc;
597: static int initialized = 0;
598:
599: if (!rpm2html_dump_rdf_resources) return;
600:
601: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
602: else return;
603:
604: if (res->nb_provider == 0) return;
605:
1.15 veillard 606: sprintf(file, "%s/%s.rdf", base, res->name);
607: fprintf(stderr, "%s\n", res->name);
1.13 veillard 608:
609: /*
610: * Create the directory if needed
611: */
612: if (!initialized) {
613: sprintf(buf, "%s", base);
614: createDirectory(buf);
615: initialized = 1;
616: }
617:
618: /*
619: * build the RDF document tree
620: * Note : the order is not important but following the rpmData
621: * structure order is easier to check.
622: */
623: rdf = rdfNewSchema();
624: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
625:
626: for (i = 0;i < res->nb_provider;i++) {
627: rpm = res->provider[i];
628: dir = rpm->dir;
629: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
630: if (dir->mirrors[0] != NULL)
631: sprintf(buf, "%s/%s/%s",
632: dir->mirrors[0], rpm->subdir, rpm->filename);
633: else
634: sprintf(buf, "%s/%s/%s",
635: dir->ftp, rpm->subdir, rpm->filename);
636: } else {
637: if (dir->mirrors[0] != NULL)
638: sprintf(buf, "%s/%s",
639: dir->mirrors[0], rpm->filename);
640: else
641: sprintf(buf, "%s/%s",
642: dir->ftp, rpm->filename);
643: }
644: desc = rdfAddDescription(rdf, NULL, buf);
645: rdfSetValue(desc, "Name", rpmNs, rpm->name);
646: rdfSetValue(desc, "Version", rpmNs, rpm->version);
647: rdfSetValue(desc, "Release", rpmNs, rpm->release);
648: if (rpm->arch)
649: rdfSetValue(desc, "Arch", rpmNs, rpm->arch);
650: if (rpm->os)
651: rdfSetValue(desc, "Os", rpmNs, rpm->os);
652: if (rpm->distribution)
653: rdfSetValue(desc, "Distribution", rpmNs, rpm->distribution);
654: if (rpm->vendor)
655: rdfSetValue(desc, "Vendor", rpmNs, rpm->vendor);
656: sprintf(buf, "%d", (int) rpm->date);
657: rdfSetValue(desc, "Date", rpmNs, buf);
1.14 httpng 658: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
659: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0'))
660: sprintf(buf, "%s/%s",
661: dir->subdir, rpm->subdir);
662: else
663: sprintf(buf, "%s",
664: rpm->subdir);
665: } else {
666: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0'))
667: sprintf(buf, "%s",
668: dir->subdir);
669: else
670: buf[0] = '\0';
671: }
672: if (buf[0] != '\0')
673: rdfSetValue(desc, "Subdir", rpmNs, buf);
1.13 veillard 674: }
675:
676: /*
677: * Save the RDF to a buffer, remove the tree.
678: */
679: rdfWriteMemory(rdf, &buffer, &size);
680: rdfDestroySchema(rdf);
681:
682: /*
683: * if the file already exists avoid to overwrite it if the content
684: * didn't change.
685: */
686: stat_res = stat(file, &stat_buf);
687:
688: if ((stat_res == 0) && (stat_buf.st_size == size)) {
689: char *buffer2 = malloc(size * sizeof(char));
690:
691: if (buffer2 == NULL) {
692: fprintf(stderr, " : running out of memory\n");
693: return;
694: }
695: output = fopen(file, "r");
696: if (output == NULL) {
697: fprintf(stderr, "couldn't open %s for reading !\n", file);
698: return;
699: }
700: if (fread(buffer2, size, 1, output) != 1) {
701: fprintf(stderr, "Problem reading from %s !\n", file);
702: }
703: fclose(output);
704:
705: /*
706: * Now compare the content !
707: */
708: if (!memcmp(buffer, buffer2, size)) {
709: free(buffer2);
710: if (verbose > 1)
711: fprintf(stderr, "File %s : Content identical !\n", file);
712: return;
713: }
714: free(buffer2);
715: }
716:
717: /*
718: * Dump the file.
719: */
720: if (verbose > 1) {
721: printf("Dumping %s\n", file);
722: }
1.15 veillard 723: fprintf(stderr, "Dumping %s\n", file);
1.13 veillard 724: output = fopen(file, "w");
725: if (output == NULL) {
726: fprintf(stderr, "couldn't open %s for writing !\n", file);
727: return;
728: }
729: if (fwrite(buffer, size, 1, output) != 1) {
730: fprintf(stderr, "Problem writing to %s !\n", file);
731: }
732: fclose(output);
733: }
734:
735: /*
736: * Dump all the RDf files about known resources.
737: */
738:
739: void dumpAllResRdf(void) {
740: rpmRessPtr cur;
741:
742: if (!rpm2html_dump_rdf_resources) return;
743:
744: cur = ressList;
745:
746: while (cur != NULL) {
747: dumpResRdf(cur);
748: cur = cur->next;
749: }
750: }
751:
Webmaster