/*
* rdf.c : implementation for the RDF encoding/decoding of RPM informations.
*/
#include "config.h"
#include <sys/stat.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <time.h>
#include <errno.h>
#include <ctype.h>
#include "rpm2html.h"
#include "rpmdata.h"
#include "html.h"
#include "rdf_api.h"
#include "rdf.h"
/*
* 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 rpmOpenRdf(char *nameRdf, rpmDirPtr dir, rpmSubdirPtr tree) {
char file[1000];
char nameBuffer[200];
rdfSchema rdf;
rdfNamespace rpmNs;
rdfNamespace rdfNs;
rdfDescription desc;
rdfBag bag;
char *value;
rpmDataPtr rpm;
struct stat buf;
/*
* open the file for reading
*/
if (tree->htmlpath[0] != '\0')
sprintf(file, "%s/%s/%s", dir->rpmdir, tree->rpmpath, nameRdf);
else
sprintf(file, "%s/%s", dir->rpmdir, nameRdf);
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));
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;
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);
rdfGetValue(desc, "Arch", rpmNs, &value, NULL);
if (value != NULL) rpm->arch = strdup(value);
rdfGetValue(desc, "Os", rpmNs, &value, NULL);
if (value != NULL) rpm->os = strdup(value);
rdfGetValue(desc, "Distribution", rpmNs, &value, NULL);
if (value != NULL) rpm->distribution = strdup(value);
rdfGetValue(desc, "Vendor", rpmNs, &value, NULL);
if (value != NULL) rpm->vendor = strdup(value);
rdfGetValue(desc, "Packager", rpmNs, &value, NULL);
if (value != NULL) rpm->packager = strdup(value);
rdfGetValue(desc, "Group", rpmNs, &value, NULL);
if (value != NULL) rpm->group = strdup(value);
rdfGetValue(desc, "Summary", rpmNs, &value, NULL);
if (value != NULL) rpm->summary = strdup(value);
rdfGetValue(desc, "Description", rpmNs, &value, NULL);
if (value != NULL) rpm->description = strdup(value);
rdfGetValue(desc, "Copyright", rpmNs, &value, NULL);
if (value != NULL) rpm->copyright = strdup(value);
rdfGetValue(desc, "Changelog", rpmNs, &value, NULL);
if (value != NULL) rpm->changelog = strdup(value);
/*
* Finish filling the rpmData structure.
*/
#ifdef HAVE_SNPRINTF
sprintf(nameBuffer, "%s-%s-%s.rpm",
rpm->name, rpm->version, rpm->release);
#else
snprintf(nameBuffer, 200, "%s-%s-%s.rpm",
rpm->name, rpm->version, rpm->release);
#endif
rpm->filename = strdup(nameBuffer);
/* package-xxx.rpm provides the resource "package" */
rpm->nb_resources = 1;
rpm->resources[0] = rpmRessAdd(rpm->name, rpm, 0);
/* 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;
/*
* Cleanup.
*/
rdfDestroySchema(rdf);
return(rpm);
}
/*
* Create and RDF file containing the description for the given RPM data.
*/
void dumpRpmRdf(rpmDataPtr rpm, rpmSubdirPtr tree) {
struct tm * tstruct;
rpmDirPtr dir = rpm->dir;
char *base = dir->dir;
int i;
char buf[10000];
char file[1000];
rdfSchema rdf;
rdfNamespace rpmNs;
rdfDescription desc;
rdfBag bag;
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));
}
if (checkDate(file, rpm->stamp)) return;
if (verbose > 1) {
printf("Dumping %s\n", file);
}
/*
* 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) {
if (dir->ftpsrc) {
sprintf(buf, "%s/%s", dir->ftpsrc, rpm->srcrpm);
rdfSetValue(desc, "Sources", rpmNs, buf);
} else {
rdfSetValue(desc, "Sources", rpmNs, rpm->srcrpm);
}
}
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", rpm->size);
rdfSetValue(desc, "Size", rpmNs, buf);
if (rpm->host)
rdfSetValue(desc, "BuildHost", rpmNs, rpm->host);
if (rpm->nb_resources > 0) {
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) {
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 file and cleanup the tree.
*/
rdfWrite(rdf, file);
rdfDestroySchema(rdf);
}
Webmaster