Annotation of rpm2html/rdf.c, revision 1.44
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.44 ! veillard 6: * $Id: rdf.c,v 1.43 2000/11/17 17:30:51 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.44 ! veillard 77: rpm->extra->copyright, rpm->date, rpm->os,
! 78: rpm->distribution);
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.33 daniel 191: rpm = (rpmDataPtr) debugMalloc(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.33 daniel 198: rpm->extra = (rpmExtraDataPtr) debugMalloc(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.37 veillard 215: debugFree(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.37 veillard 224: debugFree(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.37 veillard 233: debugFree(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.37 veillard 246: debugFree(value);
1.33 daniel 247: } else rpm->arch = debugStrdup("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.37 veillard 252: debugFree(value);
1.33 daniel 253: } else rpm->os = debugStrdup("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.37 veillard 258: debugFree(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.37 veillard 264: debugFree(value);
1.33 daniel 265: } else rpm->vendor = debugStrdup(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.37 veillard 274: debugFree(value);
1.33 daniel 275: } else rpm->group = debugStrdup(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.33 daniel 279: else rpm->summary = debugStrdup(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.33 daniel 283: else rpm->extra->description = debugStrdup(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.33 daniel 296: } else rpm->extra->srcrpm = debugStrdup("");
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.33 daniel 302: debugFree(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.33 daniel 311: debugFree(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.33 daniel 316: else rpm->extra->host = debugStrdup(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.33 daniel 331: rpm->extra->resources = (rpmRessPtr *) debugMalloc(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.33 daniel 342: rpm->extra->resources = (rpmRessPtr *) debugRealloc(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.33 daniel 361: debugFree(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.33 daniel 368: if (name != NULL) debugFree(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.33 daniel 383: rpm->extra->requires = (rpmRessPtr *) debugMalloc(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.33 daniel 394: rpm->extra->requires = (rpmRessPtr *) debugRealloc(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.33 daniel 432: debugFree(value);
1.41 veillard 433: if (reqval != NULL)
434: debugFree(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.33 daniel 441: if (name != NULL) debugFree(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.33 daniel 455: rpm->filename = debugStrdup(filename);
456: debugFree(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.33 daniel 460: rpm->filename = debugStrdup(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.33 daniel 682: char *buffer2 = debugMalloc(size * sizeof(char));
1.12 veillard 683:
684: if (buffer2 == NULL) {
685: fprintf(stderr, " : running out of memory\n");
1.37 veillard 686: debugFree(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.37 veillard 692: debugFree(buffer);
1.12 veillard 693: return;
694: }
695: if (fread(buffer2, size, 1, output) != 1) {
696: fprintf(stderr, "Problem reading from %s !\n", file);
1.37 veillard 697: debugFree(buffer);
1.12 veillard 698: }
699: fclose(output);
700:
701: /*
702: * Now compare the content !
703: */
704: if (!memcmp(buffer, buffer2, size)) {
1.33 daniel 705: debugFree(buffer2);
1.20 veillard 706: if (rpm2htmlVerbose > 1)
1.12 veillard 707: fprintf(stderr, "File %s : Content identical !\n", file);
1.37 veillard 708: debugFree(buffer);
1.12 veillard 709: return;
710: }
1.33 daniel 711: debugFree(buffer2);
1.12 veillard 712: }
713:
714: /*
715: * Dump the file.
716: */
1.20 veillard 717: if (rpm2htmlVerbose > 1) {
1.12 veillard 718: printf("Dumping %s\n", file);
719: }
720: output = fopen(file, "w");
721: if (output == NULL) {
722: fprintf(stderr, "couldn't open %s for writing !\n", file);
723: return;
724: }
725: if (fwrite(buffer, size, 1, output) != 1) {
726: fprintf(stderr, "Problem writing to %s !\n", file);
727: }
1.37 veillard 728: debugFree(buffer);
1.12 veillard 729: fclose(output);
1.1 httpng 730: }
731:
1.13 veillard 732: /*
733: * Create and RDF file containing informations about a resource.
734: */
735:
736: void dumpResRdf(rpmRessPtr res) {
737: FILE *output;
738: struct stat stat_buf;
739: char *base;
740: int i;
741: char buf[10000];
742: char file[1000];
743: char *buffer;
744: int size;
745: int stat_res;
746: rpmDataPtr rpm;
747: rpmDirPtr dir;
748: rdfSchema rdf;
749: rdfNamespace rpmNs;
750: rdfDescription desc;
751: static int initialized = 0;
752:
753: if (!rpm2html_dump_rdf_resources) return;
754:
755: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
756: else return;
757:
758: if (res->nb_provider == 0) return;
759:
1.35 daniel 760: snprintf(file, sizeof(file), "%s/%s.rdf", base, res->name);
1.13 veillard 761:
762: /*
763: * Create the directory if needed
764: */
765: if (!initialized) {
1.35 daniel 766: snprintf(buf, sizeof(buf), "%s", base);
1.13 veillard 767: createDirectory(buf);
768: initialized = 1;
769: }
770:
771: /*
772: * build the RDF document tree
773: * Note : the order is not important but following the rpmData
774: * structure order is easier to check.
775: */
776: rdf = rdfNewSchema();
777: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
778: for (i = 0;i < res->nb_provider;i++) {
779: rpm = res->provider[i];
780: dir = rpm->dir;
781: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
782: if (dir->mirrors[0] != NULL)
1.35 daniel 783: snprintf(buf, sizeof(buf), "%s/%s/%s",
1.13 veillard 784: dir->mirrors[0], rpm->subdir, rpm->filename);
785: else
1.35 daniel 786: snprintf(buf, sizeof(buf), "%s/%s/%s",
1.13 veillard 787: dir->ftp, rpm->subdir, rpm->filename);
788: } else {
789: if (dir->mirrors[0] != NULL)
1.35 daniel 790: snprintf(buf, sizeof(buf), "%s/%s",
1.13 veillard 791: dir->mirrors[0], rpm->filename);
792: else
1.35 daniel 793: snprintf(buf, sizeof(buf), "%s/%s",
1.13 veillard 794: dir->ftp, rpm->filename);
795: }
796: desc = rdfAddDescription(rdf, NULL, buf);
1.29 daniel 797: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
798: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
1.35 daniel 799: snprintf(buf, sizeof(buf), "../%s/%s/%s.rdf", dir->subdir,
1.29 daniel 800: rpm->subdir, rpmName(rpm));
801: else
1.35 daniel 802: snprintf(buf, sizeof(buf), "../%s/%s.rdf", dir->subdir, rpmName(rpm));
1.29 daniel 803: } else {
804: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
1.35 daniel 805: snprintf(buf, sizeof(buf), "../%s/%s.rdf", rpm->subdir, rpmName(rpm));
1.29 daniel 806: else
1.35 daniel 807: snprintf(buf, sizeof(buf), "../%s.rdf", rpmName(rpm));
1.29 daniel 808: }
809: xmlSetProp(desc, "href", buf);
1.13 veillard 810: rdfSetValue(desc, "Name", rpmNs, rpm->name);
811: rdfSetValue(desc, "Version", rpmNs, rpm->version);
812: rdfSetValue(desc, "Release", rpmNs, rpm->release);
813: if (rpm->arch)
814: rdfSetValue(desc, "Arch", rpmNs, rpm->arch);
815: if (rpm->os)
816: rdfSetValue(desc, "Os", rpmNs, rpm->os);
817: if (rpm->distribution)
818: rdfSetValue(desc, "Distribution", rpmNs, rpm->distribution);
819: if (rpm->vendor)
820: rdfSetValue(desc, "Vendor", rpmNs, rpm->vendor);
1.35 daniel 821: snprintf(buf, sizeof(buf), "%d", (int) rpm->date);
1.13 veillard 822: rdfSetValue(desc, "Date", rpmNs, buf);
1.35 daniel 823: snprintf(buf, sizeof(buf), "%d", (int) rpm->size);
1.17 veillard 824: rdfSetValue(desc, "Size", rpmNs, buf);
1.14 httpng 825: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
826: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0'))
1.35 daniel 827: snprintf(buf, sizeof(buf), "%s/%s",
1.14 httpng 828: dir->subdir, rpm->subdir);
829: else
1.35 daniel 830: snprintf(buf, sizeof(buf), "%s",
1.14 httpng 831: rpm->subdir);
832: } else {
833: if ((dir->subdir != NULL) && (dir->subdir[0] != '\0'))
1.35 daniel 834: snprintf(buf, sizeof(buf), "%s",
1.14 httpng 835: dir->subdir);
836: else
837: buf[0] = '\0';
838: }
839: if (buf[0] != '\0')
840: rdfSetValue(desc, "Subdir", rpmNs, buf);
1.13 veillard 841: }
842:
843: /*
844: * Save the RDF to a buffer, remove the tree.
845: */
846: rdfWriteMemory(rdf, &buffer, &size);
847: rdfDestroySchema(rdf);
1.34 veillard 848: if (buffer == NULL) return;
1.13 veillard 849:
850: /*
851: * if the file already exists avoid to overwrite it if the content
852: * didn't change.
853: */
854: stat_res = stat(file, &stat_buf);
855:
856: if ((stat_res == 0) && (stat_buf.st_size == size)) {
1.33 daniel 857: char *buffer2 = debugMalloc(size * sizeof(char));
1.13 veillard 858:
859: if (buffer2 == NULL) {
860: fprintf(stderr, " : running out of memory\n");
1.37 veillard 861: debugFree(buffer);
1.13 veillard 862: return;
863: }
864: output = fopen(file, "r");
865: if (output == NULL) {
866: fprintf(stderr, "couldn't open %s for reading !\n", file);
1.37 veillard 867: debugFree(buffer);
1.13 veillard 868: return;
869: }
870: if (fread(buffer2, size, 1, output) != 1) {
871: fprintf(stderr, "Problem reading from %s !\n", file);
872: }
873: fclose(output);
874:
875: /*
876: * Now compare the content !
877: */
878: if (!memcmp(buffer, buffer2, size)) {
1.33 daniel 879: debugFree(buffer2);
1.20 veillard 880: if (rpm2htmlVerbose > 1)
1.13 veillard 881: fprintf(stderr, "File %s : Content identical !\n", file);
1.37 veillard 882: debugFree(buffer);
1.13 veillard 883: return;
884: }
1.33 daniel 885: debugFree(buffer2);
1.13 veillard 886: }
887:
888: /*
889: * Dump the file.
890: */
1.20 veillard 891: if (rpm2htmlVerbose > 1) {
1.13 veillard 892: printf("Dumping %s\n", file);
893: }
894: output = fopen(file, "w");
895: if (output == NULL) {
896: fprintf(stderr, "couldn't open %s for writing !\n", file);
1.37 veillard 897: debugFree(buffer);
1.13 veillard 898: return;
899: }
900: if (fwrite(buffer, size, 1, output) != 1) {
901: fprintf(stderr, "Problem writing to %s !\n", file);
1.37 veillard 902: debugFree(buffer);
1.13 veillard 903: }
904: fclose(output);
1.37 veillard 905: debugFree(buffer);
1.13 veillard 906: }
907:
908: /*
909: * Dump all the RDf files about known resources.
910: */
911:
912: void dumpAllResRdf(void) {
913: rpmRessPtr cur;
914:
915: if (!rpm2html_dump_rdf_resources) return;
916:
917: cur = ressList;
918:
919: while (cur != NULL) {
920: dumpResRdf(cur);
921: cur = cur->next;
922: }
1.21 daniel 923: }
924:
925: /*
926: * Dump an apropos RDF file for all packages.
1.22 daniel 927: * Since the file is really too big to be kept as-if, it is compressed
1.21 daniel 928: */
929:
930: void dumpAproposRdf(void) {
931: rpmDataPtr rpm;
932: char file[1000];
933: char buf[1000];
934: rdfSchema rdf;
935: rdfNamespace rpmNs;
936: rdfDescription desc;
937: rpmDirPtr dir;
938: char *base;
1.22 daniel 939: char *buffer;
940: int size;
941: gzFile output;
942: int res;
1.21 daniel 943:
944: if (!rpm2html_dump_rdf_resources) return;
945:
946: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
947: else return;
948:
1.35 daniel 949: snprintf(file, sizeof(file), "%s/fullIndex.rdf.gz", base);
1.21 daniel 950: if (rpm2htmlVerbose > 1) {
951: printf("Dumping %s\n", file);
952: }
953:
954: /*
955: * build the RDF document tree, one only dump the minimum needed
956: * for searching.
957: */
958: rdf = rdfNewSchema();
959: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
960:
961: rpm = rpmSoftwareList;
962:
963: while (rpm != NULL) {
964: dir = rpm->dir;
965: if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
966: if (dir->mirrors[0] != NULL)
1.35 daniel 967: snprintf(buf, sizeof(buf), "%s/%s/%s",
1.21 daniel 968: dir->mirrors[0], rpm->subdir, rpm->filename);
969: else
1.35 daniel 970: snprintf(buf, sizeof(buf), "%s/%s/%s",
1.21 daniel 971: dir->ftp, rpm->subdir, rpm->filename);
972: } else {
973: if (dir->mirrors[0] != NULL)
1.35 daniel 974: snprintf(buf, sizeof(buf), "%s/%s",
1.21 daniel 975: dir->mirrors[0], rpm->filename);
976: else
1.35 daniel 977: snprintf(buf, sizeof(buf), "%s/%s",
1.21 daniel 978: dir->ftp, rpm->filename);
979: }
980: desc = rdfAddDescription(rdf, NULL, buf);
981: rdfSetValue(desc, "Name", rpmNs, rpm->name);
1.23 veillard 982: rdfSetValue(desc, "Summary", rpmNs, rpm->summary);
983: rpm = rpm->nextSoft;
1.21 daniel 984: }
985:
986: /*
987: * Dump the RDF tree, and cleanup.
988: */
1.22 daniel 989: rdfWriteMemory(rdf, &buffer, &size);
1.21 daniel 990: rdfDestroySchema(rdf);
1.34 veillard 991: if (buffer == NULL) return;
1.22 daniel 992:
993: /*
994: * Write the compressed version of the RDF base.
995: */
996: output = gzopen(file, "w9");
997: if (output == NULL) {
998: fprintf(stderr, "Could not write %s : gzopen failed\n", file);
1.37 veillard 999: debugFree(buffer);
1.22 daniel 1000: return;
1001: }
1002: res = gzwrite(output, buffer, size);
1003: if (res <= 0) {
1004: fprintf(stderr, "Could not write %s : gzwrite failed\n", file);
1.37 veillard 1005: debugFree(buffer);
1.22 daniel 1006: return;
1007: }
1008: gzclose(output);
1.37 veillard 1009: debugFree(buffer);
1.13 veillard 1010: }
1011:
1.25 veillard 1012: /*
1013: * Dump the distribs/xxx.rdf file giving information about a
1014: * specific distribution
1015: */
1016:
1017: void dumpDistRdf(rpmDirPtr dir) {
1.34 veillard 1018: char buf[101] = "";
1.25 veillard 1019: char file[1000];
1020: rdfSchema rdf;
1021: rdfNamespace rpmNs;
1022: rdfDescription desc;
1023: rdfBag mirrors;
1024: rdfElement mirror;
1025: struct stat stat_buf;
1026: int stat_res;
1027: char *base, *ptr;
1028: char *buffer;
1029: int size;
1030: FILE *output;
1031: int i;
1032:
1033: if (!rpm2html_dump_rdf_resources) return;
1034:
1035: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
1036: else return;
1037:
1.34 veillard 1038: if (dir->subdir)
1.35 daniel 1039: snprintf(buf, sizeof(buf), "%s", dir->subdir);
1.25 veillard 1040: for (ptr = &buf[0]; *ptr; ptr++) if (*ptr == '/') *ptr = '_';
1.35 daniel 1041: snprintf(file, sizeof(file), "%s/distribs", base);
1.25 veillard 1042: createDirectory(file);
1.35 daniel 1043: snprintf(file, sizeof(file), "%s/distribs/%s.rdf", base, buf);
1.25 veillard 1044:
1045: /*
1046: * build the RDF document tree, one only dump the minimum needed
1047: * for searching distributions informations.
1048: */
1049: rdf = rdfNewSchema();
1050: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
1051:
1052: desc = rdfAddDescription(rdf, NULL, dir->ftp);
1053: rdfSetValue(desc, "ID", rpmNs, dir->subdir);
1054: rdfSetValue(desc, "Name", rpmNs, dir->name);
1055: rdfSetValue(desc, "Origin", rpmNs, dir->ftp);
1056: rdfSetValue(desc, "Sources", rpmNs, dir->ftpsrc);
1.35 daniel 1057: snprintf(buf, sizeof(buf), "%d", dir->files);
1.25 veillard 1058: mirrors = rdfBagCreate(rdf, desc, "Mirrors", rpmNs);
1059: for (i = 0;i < dir->nb_mirrors;i++) {
1060: mirror = rdfBagAddValue(mirrors, "Mirror", rpmNs, NULL, NULL);
1061: rdfSetElementResource(rdf, mirror, dir->mirrors[i]);
1062: }
1063:
1064: /*
1065: * Dump the RDF tree, and cleanup.
1066: */
1067: rdfWriteMemory(rdf, &buffer, &size);
1068: rdfDestroySchema(rdf);
1.34 veillard 1069: if (buffer == NULL) return;
1.25 veillard 1070:
1071: /*
1072: * if the file already exists avoid to overwrite it if the content
1073: * didn't change.
1074: */
1075: stat_res = stat(file, &stat_buf);
1076:
1077: if ((stat_res == 0) && (stat_buf.st_size == size)) {
1.33 daniel 1078: char *buffer2 = debugMalloc(size * sizeof(char));
1.25 veillard 1079:
1080: if (buffer2 == NULL) {
1081: fprintf(stderr, " : running out of memory\n");
1.37 veillard 1082: debugFree(buffer);
1.25 veillard 1083: return;
1084: }
1085: output = fopen(file, "r");
1086: if (output == NULL) {
1087: fprintf(stderr, "couldn't open %s for reading !\n", file);
1.37 veillard 1088: debugFree(buffer);
1.25 veillard 1089: return;
1090: }
1091: if (fread(buffer2, size, 1, output) != 1) {
1092: fprintf(stderr, "Problem reading from %s !\n", file);
1093: }
1094: fclose(output);
1095:
1096: /*
1097: * Now compare the content !
1098: */
1099: if (!memcmp(buffer, buffer2, size)) {
1.33 daniel 1100: debugFree(buffer2);
1.25 veillard 1101: if (rpm2htmlVerbose > 1)
1102: fprintf(stderr, "File %s : Content identical !\n", file);
1.37 veillard 1103: debugFree(buffer);
1.25 veillard 1104: return;
1105: }
1.33 daniel 1106: debugFree(buffer2);
1.25 veillard 1107: }
1108:
1109: /*
1110: * Dump the file.
1111: */
1112: if (rpm2htmlVerbose > 1) {
1113: printf("Dumping %s\n", file);
1114: }
1115: output = fopen(file, "w");
1116: if (output == NULL) {
1117: fprintf(stderr, "couldn't open %s for writing !\n", file);
1.37 veillard 1118: debugFree(buffer);
1.25 veillard 1119: return;
1120: }
1121: if (fwrite(buffer, size, 1, output) != 1) {
1122: fprintf(stderr, "Problem writing to %s !\n", file);
1.37 veillard 1123: debugFree(buffer);
1.25 veillard 1124: }
1125: fclose(output);
1.37 veillard 1126: debugFree(buffer);
1.25 veillard 1127: }
1.26 daniel 1128:
1129: /*
1130: * Dump the distribs/metadata.rdf file listing all the recognized
1131: * metadata mirrors sites.
1132: */
1133:
1134: void dumpMetadataListRdf(void) {
1135: char file[1000];
1136: rdfSchema rdf;
1137: rdfNamespace rpmNs;
1138: rdfDescription desc;
1139: struct stat stat_buf;
1140: int stat_res;
1141: char *base;
1142: char *buffer;
1143: int size;
1144: FILE *output;
1145: int i;
1146:
1147: if (!rpm2html_dump_rdf_resources) return;
1148:
1149: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
1150: else return;
1151:
1.35 daniel 1152: snprintf(file, sizeof(file), "%s/distribs", base);
1.26 daniel 1153: createDirectory(file);
1.35 daniel 1154: snprintf(file, sizeof(file), "%s/distribs/metadata.rdf", base);
1.26 daniel 1155:
1156: /*
1157: * build the RDF document tree, one only dump the minimum needed
1158: * for searching distributions informations.
1159: */
1160: rdf = rdfNewSchema();
1161: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
1162:
1163: for (i = 0;i < nb_metadata_mirrors;i++){
1164: desc = rdfAddDescription(rdf, NULL, metadata_mirrors[i]);
1165: rdfSetValue(desc, "URI", rpmNs, metadata_mirrors[i]);
1166: }
1167:
1168: /*
1169: * Dump the RDF tree, and cleanup.
1170: */
1171: rdfWriteMemory(rdf, &buffer, &size);
1172: rdfDestroySchema(rdf);
1.34 veillard 1173: if (buffer == NULL) return;
1.26 daniel 1174:
1175: /*
1176: * if the file already exists avoid to overwrite it if the content
1177: * didn't change.
1178: */
1179: stat_res = stat(file, &stat_buf);
1180:
1181: if ((stat_res == 0) && (stat_buf.st_size == size)) {
1.33 daniel 1182: char *buffer2 = debugMalloc(size * sizeof(char));
1.26 daniel 1183:
1184: if (buffer2 == NULL) {
1185: fprintf(stderr, " : running out of memory\n");
1.37 veillard 1186: debugFree(buffer);
1.26 daniel 1187: return;
1188: }
1189: output = fopen(file, "r");
1190: if (output == NULL) {
1191: fprintf(stderr, "couldn't open %s for reading !\n", file);
1.37 veillard 1192: debugFree(buffer);
1.26 daniel 1193: return;
1194: }
1195: if (fread(buffer2, size, 1, output) != 1) {
1196: fprintf(stderr, "Problem reading from %s !\n", file);
1197: }
1198: fclose(output);
1199:
1200: /*
1201: * Now compare the content !
1202: */
1203: if (!memcmp(buffer, buffer2, size)) {
1.33 daniel 1204: debugFree(buffer2);
1.26 daniel 1205: if (rpm2htmlVerbose > 1)
1206: fprintf(stderr, "File %s : Content identical !\n", file);
1.37 veillard 1207: debugFree(buffer);
1.26 daniel 1208: return;
1209: }
1.33 daniel 1210: debugFree(buffer2);
1.26 daniel 1211: }
1212:
1213: /*
1214: * Dump the file.
1215: */
1216: if (rpm2htmlVerbose > 1) {
1217: printf("Dumping %s\n", file);
1218: }
1219: output = fopen(file, "w");
1220: if (output == NULL) {
1221: fprintf(stderr, "couldn't open %s for writing !\n", file);
1222: return;
1223: }
1224: if (fwrite(buffer, size, 1, output) != 1) {
1225: fprintf(stderr, "Problem writing to %s !\n", file);
1226: }
1227: fclose(output);
1.37 veillard 1228: debugFree(buffer);
1.26 daniel 1229: }
1230:
1.25 veillard 1231: /*
1232: * Dump the distribs/list.rdf file listing all the recognized distributions
1.26 daniel 1233: * as well as the metadata mirrors list.
1.25 veillard 1234: */
1235:
1236: void dumpDistListRdf(void) {
1237: rpmDirPtr dir;
1238: char file[1000];
1239: rdfSchema rdf;
1240: rdfNamespace rpmNs;
1241: rdfDescription desc;
1242: struct stat stat_buf;
1243: int stat_res;
1244: char *base;
1245: char *buffer;
1246: int size;
1247: FILE *output;
1248:
1249: if (!rpm2html_dump_rdf_resources) return;
1250:
1251: if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
1252: else return;
1253:
1.26 daniel 1254: dumpMetadataListRdf();
1255:
1.35 daniel 1256: snprintf(file, sizeof(file), "%s/distribs", base);
1.25 veillard 1257: createDirectory(file);
1.35 daniel 1258: snprintf(file, sizeof(file), "%s/distribs/list.rdf", base);
1.25 veillard 1259:
1260: /*
1261: * build the RDF document tree, one only dump the minimum needed
1262: * for searching distributions informations.
1263: */
1264: rdf = rdfNewSchema();
1265: rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
1266:
1267: dir = dirList;
1268: while (dir != NULL) {
1269: desc = rdfAddDescription(rdf, NULL, dir->ftp);
1270: rdfSetValue(desc, "ID", rpmNs, dir->subdir);
1271: dumpDistRdf(dir);
1272: dir = dir->next;
1273: }
1274: /*
1275: * Dump the RDF tree, and cleanup.
1276: */
1277: rdfWriteMemory(rdf, &buffer, &size);
1278: rdfDestroySchema(rdf);
1.34 veillard 1279: if (buffer == NULL) return;
1.25 veillard 1280:
1281: /*
1282: * if the file already exists avoid to overwrite it if the content
1283: * didn't change.
1284: */
1285: stat_res = stat(file, &stat_buf);
1286:
1287: if ((stat_res == 0) && (stat_buf.st_size == size)) {
1.33 daniel 1288: char *buffer2 = debugMalloc(size * sizeof(char));
1.25 veillard 1289:
1290: if (buffer2 == NULL) {
1291: fprintf(stderr, " : running out of memory\n");
1.37 veillard 1292: debugFree(buffer);
1.25 veillard 1293: return;
1294: }
1295: output = fopen(file, "r");
1296: if (output == NULL) {
1297: fprintf(stderr, "couldn't open %s for reading !\n", file);
1.37 veillard 1298: debugFree(buffer);
1.25 veillard 1299: return;
1300: }
1301: if (fread(buffer2, size, 1, output) != 1) {
1302: fprintf(stderr, "Problem reading from %s !\n", file);
1303: }
1304: fclose(output);
1305:
1306: /*
1307: * Now compare the content !
1308: */
1309: if (!memcmp(buffer, buffer2, size)) {
1.33 daniel 1310: debugFree(buffer2);
1.25 veillard 1311: if (rpm2htmlVerbose > 1)
1312: fprintf(stderr, "File %s : Content identical !\n", file);
1.37 veillard 1313: debugFree(buffer);
1.25 veillard 1314: return;
1315: }
1.33 daniel 1316: debugFree(buffer2);
1.25 veillard 1317: }
1318:
1319: /*
1320: * Dump the file.
1321: */
1322: if (rpm2htmlVerbose > 1) {
1323: printf("Dumping %s\n", file);
1324: }
1325: output = fopen(file, "w");
1326: if (output == NULL) {
1327: fprintf(stderr, "couldn't open %s for writing !\n", file);
1328: return;
1329: }
1330: if (fwrite(buffer, size, 1, output) != 1) {
1331: fprintf(stderr, "Problem writing to %s !\n", file);
1332: }
1333: fclose(output);
1.37 veillard 1334: debugFree(buffer);
1.25 veillard 1335: }
1.26 daniel 1336:
Webmaster