/* * rdf.c : implementation for the RDF encoding/decoding of RPM informations. * * See Copyright for the status of this software. * * $Id: rdf.c,v 1.25 1998/07/28 05:58:10 veillard Exp $ */ #include "config.h" #include #ifdef HAVE_FCNTL_H #include #endif #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include "rpm2html.h" #include "rpmdata.h" #include "html.h" #include "language.h" #include "rdf_api.h" #include "rdf.h" /* * Open and process an RDF file in the incoming tree of an rpm2html mirror. */ rpmDataPtr rpmOpenRdf(char *nameRdf, rpmDirPtr dir, rpmSubdirPtr tree) { char file[1000]; rpmDataPtr rpm; /* * create path */ if (tree->htmlpath[0] != '\0') sprintf(file, "%s/%s/%s", dir->rpmdir, tree->rpmpath, nameRdf); else sprintf(file, "%s/%s", dir->rpmdir, nameRdf); rpm = rpmOpenRdfFile(file); if (rpm != NULL) { /* setup tree and subdir informations */ rpm->dir = dir; if (tree) { if ((tree->rpmpath != NULL) && (tree->rpmpath[0] != '\0')) rpm->subdir = strdup(tree->rpmpath); else rpm->subdir = NULL; } else rpm->subdir = NULL; /* Add the package files to the real filesystem tree if asked for */ if ((dir->build_tree != 0) && (rpm->filelist != NULL)) { char *cur, *filename; cur = rpm->filelist; while ((*cur != '\0') && (*cur != '/')) cur++; filename = cur; while (*cur != '\0') { if ((*cur == '\n') || (*cur == '\r')) { if (cur != filename) rpmAddRealFile(dir->root, filename, rpm); while ((*cur != '\0') && (*cur != '/')) cur++; filename = cur; } else cur++; } if (cur != filename) rpmAddRealFile(dir->root, filename, rpm); } /* Register this package */ rpmAddSoftware(rpm); /* dump the HTML related to this package */ if (rpm2html_dump_html) dumpRpmHtml(rpm, tree); if (rpm2html_dump_rdf) dumpRpmRdf(rpm, tree); /* free large amount of data not used later */ if (rpm->filelist) free(rpm->filelist); rpm->filelist = NULL; if (rpm->copyright) free(rpm->copyright); rpm->copyright = NULL; if (rpm->changelog) free(rpm->changelog); rpm->changelog = NULL; if (rpm->description) free(rpm->description); rpm->description = NULL; /* increment the counters */ rpm2html_files++; rpm2html_size += rpm->size / 1024; } return(rpm); } /* * Open an RDF file call the parser to create a XML tree * Then walk the tree and build an rpmData structure for * the corresponding package. */ rpmDataPtr rpmOpenRdfFile(char *file) { char nameBuffer[200]; rdfSchema rdf; rdfNamespace rpmNs; rdfNamespace rdfNs; rdfDescription desc; rdfBag bag; rdfElement elem; char *value; rpmDataPtr rpm; struct stat buf; int i; rdf = rdfRead(file); if (rdf == NULL) return(NULL); /* * Start the analyze, check that's an RDf for RPM packages. */ rdfNs = rdfGetNamespace(rdf, "http://www.w3.org/TR/WD-rdf-syntax#"); if (rdfNs == NULL) { fprintf(stderr, "%s is not an RDF schema\n", file); rdfDestroySchema(rdf); return(NULL); } rpmNs = rdfGetNamespace(rdf, "http://www.rpm.org/"); if (rdfNs == NULL) { fprintf(stderr, "%s is not an RPM specific RDF schema\n", file); rdfDestroySchema(rdf); return(NULL); } desc = rdfFirstDescription(rdf); if (rdfNs == NULL) { fprintf(stderr, "%s RDF schema seems empty\n", file); rdfDestroySchema(rdf); return(NULL); } /* * We are pretty sure that it will be a valid schema, * Allocate the rpmData structure, initialize it. */ rpm = (rpmDataPtr) malloc(sizeof(rpmData)); if (rpm == NULL) { fprintf(stderr, "rpmOpenRdf : out of memory !\n"); rdfDestroySchema(rdf); return(NULL); } memset(rpm, 0, sizeof(rpmData)); stat(file, &buf); rpm->stamp = buf.st_mtime; /* * Now extract all the metadata informations from the RDF tree */ rdfGetValue(desc, "Name", rpmNs, &value, NULL); if (value != NULL) rpm->name = strdup(value); else { fprintf(stderr, "%s RDF schema invalid : no Name\n", file); rdfDestroySchema(rdf); return(NULL); } rdfGetValue(desc, "Version", rpmNs, &value, NULL); if (value != NULL) rpm->version = strdup(value); else { fprintf(stderr, "%s RDF schema invalid : no Version\n", file); rdfDestroySchema(rdf); return(NULL); } rdfGetValue(desc, "Release", rpmNs, &value, NULL); if (value != NULL) rpm->release = strdup(value); else { fprintf(stderr, "%s RDF schema invalid : no Release\n", file); rdfDestroySchema(rdf); return(NULL); } rdfGetValue(desc, "URL", rpmNs, &value, NULL); if (value != NULL) rpm->url = strdup(value); else rpm->url = NULL; rdfGetValue(desc, "Arch", rpmNs, &value, NULL); if (value != NULL) rpm->arch = strdup(value); else rpm->arch = strdup("noarch"); rdfGetValue(desc, "Os", rpmNs, &value, NULL); if (value != NULL) rpm->os = strdup(value); else rpm->os = strdup("linux"); rdfGetValue(desc, "Distribution", rpmNs, &value, NULL); if (value != NULL) rpm->distribution = strdup(value); else rpm->distribution = strdup(localizedStrings[LANG_UNKNOWN]); rdfGetValue(desc, "Vendor", rpmNs, &value, NULL); if (value != NULL) rpm->vendor = strdup(value); else rpm->vendor = strdup(localizedStrings[LANG_UNKNOWN]); rdfGetValue(desc, "Packager", rpmNs, &value, NULL); if (value != NULL) rpm->packager = strdup(value); else rpm->packager = NULL; rdfGetValue(desc, "Group", rpmNs, &value, NULL); if (value != NULL) rpm->group = strdup(value); else rpm->group = strdup(localizedStrings[LANG_NO_GROUP]); rdfGetValue(desc, "Summary", rpmNs, &value, NULL); if (value != NULL) rpm->summary = strdup(value); else rpm->summary = strdup(localizedStrings[LANG_NO_SUMMARY]); rdfGetValue(desc, "Description", rpmNs, &value, NULL); if (value != NULL) rpm->description = strdup(value); else rpm->description = strdup(localizedStrings[LANG_NO_DESCRIPTION]); rdfGetValue(desc, "Copyright", rpmNs, &value, NULL); if (value != NULL) rpm->copyright = strdup(value); else rpm->copyright = NULL; rdfGetValue(desc, "Changelog", rpmNs, &value, NULL); if (value != NULL) rpm->changelog = strdup(value); else rpm->changelog = NULL; rdfGetValue(desc, "Sources", rpmNs, &value, NULL); if (value != NULL) { rpm->srcrpm = strdup(value); } else rpm->srcrpm = strdup(""); rdfGetValue(desc, "Size", rpmNs, &value, NULL); if (value != NULL) { if (sscanf(value, "%d", &(rpm->size)) != 1) rpm->size = 0; } else rpm->size = 0; rdfGetValue(desc, "Date", rpmNs, &value, NULL); if (value != NULL) { if (sscanf(value, "%d", &i) != 1) rpm->date = 0; else rpm->date = i; } else rpm->date = 0; rdfGetValue(desc, "BuildHost", rpmNs, &value, NULL); if (value != NULL) rpm->host = strdup(value); else rpm->host = strdup(localizedStrings[LANG_NO_HOST]); rdfGetValue(desc, "Files", rpmNs, &value, NULL); if (value != NULL) rpm->filelist = strdup(value); else rpm->filelist = NULL; /* * Fetching packages provided is a bit more tricky, one have to * find the RDF Bag, and scan it's values. */ rpm->nb_resources = 0; rdfGetValue(desc, "Provides", rpmNs, NULL, &bag); if (bag != NULL) { elem = rdfFirstChild(bag); rpm->max_resources = 5; rpm->resources = (rpmRessPtr *) malloc(rpm->max_resources * sizeof(rpmRessPtr)); if (rpm->resources == NULL) { fprintf(stderr, "rpmOpenRdf : ran out of memory\n"); exit(1); } i = 0; while (elem != NULL) { if (i >= rpm->max_resources) { rpm->max_resources *= 2; rpm->resources = (rpmRessPtr *) realloc(rpm->resources, rpm->max_resources * sizeof(rpmRessPtr)); if (rpm->resources == NULL) { fprintf(stderr, "rpmOpenRdf : ran out of memory\n"); exit(1); } } /* * Check that we are scanning an RPM Resource. */ if ((!strcmp(rdfElemGetPropertyName(elem), "Resource")) && (rdfElemGetNamespace(elem) == rpmNs)) { value = rdfElemGetValue(elem); if (value != NULL) { rpm->resources[i] = rpmRessAdd(value, rpm, 0); i++; rpm->nb_resources++; } else if (rpm2htmlVerbose > 1) { fprintf(stderr, "%s : malformed Resource element !\n", file); } } else if (rpm2htmlVerbose > 1) { fprintf(stderr, "%s : malformed Provides bag !\n", file); } elem = rdfNextElem(elem); } } else if (rpm2htmlVerbose > 1) { fprintf(stderr, "%s doesn't export any resource\n", file); } /* * idem for the dependencies. */ rpm->nb_requires = 0; rdfGetValue(desc, "Requires", rpmNs, NULL, &bag); if (bag != NULL) { elem = rdfFirstChild(bag); rpm->max_requires = 5; rpm->requires = (rpmRessPtr *) malloc(rpm->max_requires * sizeof(rpmRessPtr)); if (rpm->requires == NULL) { fprintf(stderr, "rpmOpenRdf : ran out of memory\n"); exit(1); } i = 0; while (elem != NULL) { if (i >= rpm->max_requires) { rpm->max_requires *= 2; rpm->requires = (rpmRessPtr *) realloc(rpm->requires, rpm->max_requires * sizeof(rpmRessPtr)); if (rpm->requires == NULL) { fprintf(stderr, "rpmOpenRdf : ran out of memory\n"); exit(1); } } /* * Check that we are scanning an RPM Resource. */ if ((!strcmp(rdfElemGetPropertyName(elem), "Resource")) && (rdfElemGetNamespace(elem) == rpmNs)) { value = rdfElemGetValue(elem); if (value != NULL) { rpm->requires[i] = rpmRequAdd(value, rpm, 0); i++; rpm->nb_requires++; } else if (rpm2htmlVerbose > 1) { fprintf(stderr, "%s : malformed Resource element !\n", file); } } else if (rpm2htmlVerbose > 1) { fprintf(stderr, "%s : malformed Provides bag !\n", file); } elem = rdfNextElem(elem); } } /* * Finish filling the rpmData structure. */ #ifdef HAVE_SNPRINTF sprintf(nameBuffer, "%s-%s-%s.%s.rpm", rpm->name, rpm->version, rpm->release, rpm->arch); #else snprintf(nameBuffer, 200, "%s-%s-%s.%s.rpm", rpm->name, rpm->version, rpm->release, rpm->arch); #endif rpm->filename = strdup(nameBuffer); /* * Cleanup. */ rdfDestroySchema(rdf); return(rpm); } /* * Create and RDF file containing the description for the given RPM data. */ void dumpRpmRdf(rpmDataPtr rpm, rpmSubdirPtr tree) { FILE *output; struct stat stat_buf; struct tm * tstruct; rpmDirPtr dir = rpm->dir; char *base = dir->dir; int i; char buf[10000]; char file[1000]; char *buffer; int size; int stat_res; rdfSchema rdf; rdfNamespace rpmNs; rdfDescription desc; rdfBag bag; if (!rpm2html_dump_rdf) return; if (rpm2html_rdf_dir != NULL) base = rpm2html_rdf_dir; if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) { if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) sprintf(file, "%s/%s/%s/%s.rdf", base, dir->subdir, rpm->subdir, rpmName(rpm)); else sprintf(file, "%s/%s/%s.rdf", base, dir->subdir, rpmName(rpm)); } else { if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) sprintf(file, "%s/%s/%s.rdf", base, rpm->subdir, rpmName(rpm)); else sprintf(file, "%s/%s.rdf", base, rpmName(rpm)); } /* * Check wether the RPM timestamp is older than the filestamp. */ if ((stat_res = stat(file, &stat_buf)) == 0) { if (stat_buf.st_mtime > rpm->stamp) return; } /* * Create the directory if needed */ if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) { if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) sprintf(buf, "%s/%s/%s", base, dir->subdir, rpm->subdir); else sprintf(buf, "%s/%s", base, dir->subdir); } else { if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) sprintf(buf, "%s/%s", base, rpm->subdir); else sprintf(buf, "%s", base); } createDirectory(buf); /* * build the RDF document tree * Note : the order is not important but following the rpmData * structure order is easier to check. */ rdf = rdfNewSchema(); rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM"); if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) { if (dir->mirrors[0] != NULL) sprintf(buf, "%s/%s/%s", dir->mirrors[0], rpm->subdir, rpm->filename); else sprintf(buf, "%s/%s/%s", dir->ftp, rpm->subdir, rpm->filename); } else { if (dir->mirrors[0] != NULL) sprintf(buf, "%s/%s", dir->mirrors[0], rpm->filename); else sprintf(buf, "%s/%s", dir->ftp, rpm->filename); } desc = rdfAddDescription(rdf, NULL, buf); rdfSetValue(desc, "Name", rpmNs, rpm->name); rdfSetValue(desc, "Version", rpmNs, rpm->version); rdfSetValue(desc, "Release", rpmNs, rpm->release); if (rpm->url) rdfSetValue(desc, "URL", rpmNs, rpm->url); if (rpm->arch) rdfSetValue(desc, "Arch", rpmNs, rpm->arch); if (rpm->os) rdfSetValue(desc, "Os", rpmNs, rpm->os); if (rpm->distribution) rdfSetValue(desc, "Distribution", rpmNs, rpm->distribution); if (rpm->vendor) rdfSetValue(desc, "Vendor", rpmNs, rpm->vendor); if (rpm->packager) rdfSetValue(desc, "Packager", rpmNs, rpm->packager); if (rpm->group) rdfSetValue(desc, "Group", rpmNs, rpm->group); if (rpm->summary) rdfSetValue(desc, "Summary", rpmNs, rpm->summary); if (rpm->description) rdfSetValue(desc, "Description", rpmNs, rpm->description); if (rpm->copyright) rdfSetValue(desc, "Copyright", rpmNs, rpm->copyright); if (rpm->changelog) rdfSetValue(desc, "Changelog", rpmNs, rpm->changelog); if (rpm->srcrpm) { rdfSetValue(desc, "Sources", rpmNs, rpm->srcrpm); if (dir->ftpsrc) { rdfSetValue(desc, "SourcesFtp", rpmNs, dir->ftpsrc); } } tstruct = localtime(&(rpm->date)); #ifdef HAVE_STRFTIME strftime(buf, sizeof(buf) - 1, "%c", tstruct); #else #error "no strftime, please check !" #endif rdfSetValue(desc, "BuildDate", rpmNs, buf); sprintf(buf, "%d", (int) rpm->date); rdfSetValue(desc, "Date", rpmNs, buf); sprintf(buf, "%d", rpm->size); rdfSetValue(desc, "Size", rpmNs, buf); if (rpm->host) rdfSetValue(desc, "BuildHost", rpmNs, rpm->host); if (rpm->nb_resources > 0) { /** !!!!! sprintf(buf, "%d", rpm->nb_resources); rdfSetValue(desc, "NbProvides", rpmNs, buf); */ bag = rdfBagCreate(rdf, desc, "Provides", rpmNs); for (i = 0;i < rpm->nb_resources;i++) { rdfBagAddValue(bag, "Resource", rpmNs, rpm->resources[i]->name, NULL); } } if (rpm->nb_requires > 0) { /** !!!!! sprintf(buf, "%d", rpm->nb_requires); rdfSetValue(desc, "NbRequires", rpmNs, buf); */ bag = rdfBagCreate(rdf, desc, "Requires", rpmNs); for (i = 0;i < rpm->nb_requires;i++) { rdfBagAddValue(bag, "Resource", rpmNs, rpm->requires[i]->name, NULL); } } if (rpm->filelist) rdfSetValue(desc, "Files", rpmNs, rpm->filelist); /* * Save the RDF to a buffer, remove the tree. */ rdfWriteMemory(rdf, &buffer, &size); rdfDestroySchema(rdf); /* * if the file already exists avoid to overwrite it if the content * didn't change. */ if ((stat_res == 0) && (stat_buf.st_size == size)) { char *buffer2 = malloc(size * sizeof(char)); if (buffer2 == NULL) { fprintf(stderr, " : running out of memory\n"); return; } output = fopen(file, "r"); if (output == NULL) { fprintf(stderr, "couldn't open %s for reading !\n", file); return; } if (fread(buffer2, size, 1, output) != 1) { fprintf(stderr, "Problem reading from %s !\n", file); } fclose(output); /* * Now compare the content ! */ if (!memcmp(buffer, buffer2, size)) { free(buffer2); if (rpm2htmlVerbose > 1) fprintf(stderr, "File %s : Content identical !\n", file); return; } free(buffer2); } /* * Dump the file. */ if (rpm2htmlVerbose > 1) { printf("Dumping %s\n", file); } output = fopen(file, "w"); if (output == NULL) { fprintf(stderr, "couldn't open %s for writing !\n", file); return; } if (fwrite(buffer, size, 1, output) != 1) { fprintf(stderr, "Problem writing to %s !\n", file); } fclose(output); } /* * Create and RDF file containing informations about a resource. */ void dumpResRdf(rpmRessPtr res) { FILE *output; struct stat stat_buf; char *base; int i; char buf[10000]; char file[1000]; char *buffer; int size; int stat_res; rpmDataPtr rpm; rpmDirPtr dir; rdfSchema rdf; rdfNamespace rpmNs; rdfDescription desc; static int initialized = 0; if (!rpm2html_dump_rdf_resources) return; if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir; else return; if (res->nb_provider == 0) return; sprintf(file, "%s/%s.rdf", base, res->name); /* * Create the directory if needed */ if (!initialized) { sprintf(buf, "%s", base); createDirectory(buf); initialized = 1; } /* * build the RDF document tree * Note : the order is not important but following the rpmData * structure order is easier to check. */ rdf = rdfNewSchema(); rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM"); for (i = 0;i < res->nb_provider;i++) { rpm = res->provider[i]; dir = rpm->dir; if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) { if (dir->mirrors[0] != NULL) sprintf(buf, "%s/%s/%s", dir->mirrors[0], rpm->subdir, rpm->filename); else sprintf(buf, "%s/%s/%s", dir->ftp, rpm->subdir, rpm->filename); } else { if (dir->mirrors[0] != NULL) sprintf(buf, "%s/%s", dir->mirrors[0], rpm->filename); else sprintf(buf, "%s/%s", dir->ftp, rpm->filename); } desc = rdfAddDescription(rdf, NULL, buf); rdfSetValue(desc, "Name", rpmNs, rpm->name); rdfSetValue(desc, "Version", rpmNs, rpm->version); rdfSetValue(desc, "Release", rpmNs, rpm->release); if (rpm->arch) rdfSetValue(desc, "Arch", rpmNs, rpm->arch); if (rpm->os) rdfSetValue(desc, "Os", rpmNs, rpm->os); if (rpm->distribution) rdfSetValue(desc, "Distribution", rpmNs, rpm->distribution); if (rpm->vendor) rdfSetValue(desc, "Vendor", rpmNs, rpm->vendor); sprintf(buf, "%d", (int) rpm->date); rdfSetValue(desc, "Date", rpmNs, buf); sprintf(buf, "%d", (int) rpm->size); rdfSetValue(desc, "Size", rpmNs, buf); if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) { if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) sprintf(buf, "%s/%s", dir->subdir, rpm->subdir); else sprintf(buf, "%s", rpm->subdir); } else { if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) sprintf(buf, "%s", dir->subdir); else buf[0] = '\0'; } if (buf[0] != '\0') rdfSetValue(desc, "Subdir", rpmNs, buf); } /* * Save the RDF to a buffer, remove the tree. */ rdfWriteMemory(rdf, &buffer, &size); rdfDestroySchema(rdf); /* * if the file already exists avoid to overwrite it if the content * didn't change. */ stat_res = stat(file, &stat_buf); if ((stat_res == 0) && (stat_buf.st_size == size)) { char *buffer2 = malloc(size * sizeof(char)); if (buffer2 == NULL) { fprintf(stderr, " : running out of memory\n"); return; } output = fopen(file, "r"); if (output == NULL) { fprintf(stderr, "couldn't open %s for reading !\n", file); return; } if (fread(buffer2, size, 1, output) != 1) { fprintf(stderr, "Problem reading from %s !\n", file); } fclose(output); /* * Now compare the content ! */ if (!memcmp(buffer, buffer2, size)) { free(buffer2); if (rpm2htmlVerbose > 1) fprintf(stderr, "File %s : Content identical !\n", file); return; } free(buffer2); } /* * Dump the file. */ if (rpm2htmlVerbose > 1) { printf("Dumping %s\n", file); } output = fopen(file, "w"); if (output == NULL) { fprintf(stderr, "couldn't open %s for writing !\n", file); return; } if (fwrite(buffer, size, 1, output) != 1) { fprintf(stderr, "Problem writing to %s !\n", file); } fclose(output); } /* * Dump all the RDf files about known resources. */ void dumpAllResRdf(void) { rpmRessPtr cur; if (!rpm2html_dump_rdf_resources) return; cur = ressList; while (cur != NULL) { dumpResRdf(cur); cur = cur->next; } } /* * Dump an apropos RDF file for all packages. * Since the file is really too big to be kept as-if, it is compressed */ void dumpAproposRdf(void) { rpmDataPtr rpm; char file[1000]; char buf[1000]; rdfSchema rdf; rdfNamespace rpmNs; rdfDescription desc; rpmDirPtr dir; char *base; char *buffer; int size; gzFile output; int res; if (!rpm2html_dump_rdf_resources) return; if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir; else return; sprintf(file, "%s/fullIndex.rdf.gz", base); if (rpm2htmlVerbose > 1) { printf("Dumping %s\n", file); } /* * build the RDF document tree, one only dump the minimum needed * for searching. */ rdf = rdfNewSchema(); rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM"); rpm = rpmSoftwareList; while (rpm != NULL) { dir = rpm->dir; if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) { if (dir->mirrors[0] != NULL) sprintf(buf, "%s/%s/%s", dir->mirrors[0], rpm->subdir, rpm->filename); else sprintf(buf, "%s/%s/%s", dir->ftp, rpm->subdir, rpm->filename); } else { if (dir->mirrors[0] != NULL) sprintf(buf, "%s/%s", dir->mirrors[0], rpm->filename); else sprintf(buf, "%s/%s", dir->ftp, rpm->filename); } desc = rdfAddDescription(rdf, NULL, buf); rdfSetValue(desc, "Name", rpmNs, rpm->name); rdfSetValue(desc, "Summary", rpmNs, rpm->summary); rpm = rpm->nextSoft; } /* * Dump the RDF tree, and cleanup. */ rdfWriteMemory(rdf, &buffer, &size); rdfDestroySchema(rdf); /* * Write the compressed version of the RDF base. */ output = gzopen(file, "w9"); if (output == NULL) { fprintf(stderr, "Could not write %s : gzopen failed\n", file); return; } res = gzwrite(output, buffer, size); if (res <= 0) { fprintf(stderr, "Could not write %s : gzwrite failed\n", file); return; } gzclose(output); } /* * Dump the distribs/xxx.rdf file giving information about a * specific distribution */ void dumpDistRdf(rpmDirPtr dir) { char buf[100]; char file[1000]; rdfSchema rdf; rdfNamespace rpmNs; rdfDescription desc; rdfBag mirrors; rdfElement mirror; struct stat stat_buf; int stat_res; char *base, *ptr; char *buffer; int size; FILE *output; int i; if (!rpm2html_dump_rdf_resources) return; if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir; else return; sprintf(buf, "%s", dir->subdir); for (ptr = &buf[0]; *ptr; ptr++) if (*ptr == '/') *ptr = '_'; sprintf(file, "%s/distribs", base); createDirectory(file); sprintf(file, "%s/distribs/%s.rdf", base, buf); /* * build the RDF document tree, one only dump the minimum needed * for searching distributions informations. */ rdf = rdfNewSchema(); rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM"); desc = rdfAddDescription(rdf, NULL, dir->ftp); rdfSetValue(desc, "ID", rpmNs, dir->subdir); rdfSetValue(desc, "Name", rpmNs, dir->name); rdfSetValue(desc, "Origin", rpmNs, dir->ftp); rdfSetValue(desc, "Sources", rpmNs, dir->ftpsrc); sprintf(buf, "%d", dir->files); mirrors = rdfBagCreate(rdf, desc, "Mirrors", rpmNs); for (i = 0;i < dir->nb_mirrors;i++) { mirror = rdfBagAddValue(mirrors, "Mirror", rpmNs, NULL, NULL); rdfSetElementResource(rdf, mirror, dir->mirrors[i]); } /* * Dump the RDF tree, and cleanup. */ rdfWriteMemory(rdf, &buffer, &size); rdfDestroySchema(rdf); /* * if the file already exists avoid to overwrite it if the content * didn't change. */ stat_res = stat(file, &stat_buf); if ((stat_res == 0) && (stat_buf.st_size == size)) { char *buffer2 = malloc(size * sizeof(char)); if (buffer2 == NULL) { fprintf(stderr, " : running out of memory\n"); return; } output = fopen(file, "r"); if (output == NULL) { fprintf(stderr, "couldn't open %s for reading !\n", file); return; } if (fread(buffer2, size, 1, output) != 1) { fprintf(stderr, "Problem reading from %s !\n", file); } fclose(output); /* * Now compare the content ! */ if (!memcmp(buffer, buffer2, size)) { free(buffer2); if (rpm2htmlVerbose > 1) fprintf(stderr, "File %s : Content identical !\n", file); return; } free(buffer2); } /* * Dump the file. */ if (rpm2htmlVerbose > 1) { printf("Dumping %s\n", file); } output = fopen(file, "w"); if (output == NULL) { fprintf(stderr, "couldn't open %s for writing !\n", file); return; } if (fwrite(buffer, size, 1, output) != 1) { fprintf(stderr, "Problem writing to %s !\n", file); } fclose(output); } /* * Dump the distribs/list.rdf file listing all the recognized distributions */ void dumpDistListRdf(void) { rpmDirPtr dir; char file[1000]; rdfSchema rdf; rdfNamespace rpmNs; rdfDescription desc; struct stat stat_buf; int stat_res; char *base; char *buffer; int size; FILE *output; if (!rpm2html_dump_rdf_resources) return; if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir; else return; sprintf(file, "%s/distribs", base); createDirectory(file); sprintf(file, "%s/distribs/list.rdf", base); /* * build the RDF document tree, one only dump the minimum needed * for searching distributions informations. */ rdf = rdfNewSchema(); rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM"); dir = dirList; while (dir != NULL) { desc = rdfAddDescription(rdf, NULL, dir->ftp); rdfSetValue(desc, "ID", rpmNs, dir->subdir); dumpDistRdf(dir); dir = dir->next; } /* * Dump the RDF tree, and cleanup. */ rdfWriteMemory(rdf, &buffer, &size); rdfDestroySchema(rdf); /* * if the file already exists avoid to overwrite it if the content * didn't change. */ stat_res = stat(file, &stat_buf); if ((stat_res == 0) && (stat_buf.st_size == size)) { char *buffer2 = malloc(size * sizeof(char)); if (buffer2 == NULL) { fprintf(stderr, " : running out of memory\n"); return; } output = fopen(file, "r"); if (output == NULL) { fprintf(stderr, "couldn't open %s for reading !\n", file); return; } if (fread(buffer2, size, 1, output) != 1) { fprintf(stderr, "Problem reading from %s !\n", file); } fclose(output); /* * Now compare the content ! */ if (!memcmp(buffer, buffer2, size)) { free(buffer2); if (rpm2htmlVerbose > 1) fprintf(stderr, "File %s : Content identical !\n", file); return; } free(buffer2); } /* * Dump the file. */ if (rpm2htmlVerbose > 1) { printf("Dumping %s\n", file); } output = fopen(file, "w"); if (output == NULL) { fprintf(stderr, "couldn't open %s for writing !\n", file); return; } if (fwrite(buffer, size, 1, output) != 1) { fprintf(stderr, "Problem writing to %s !\n", file); } fclose(output); }