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