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