File:  [Public] / rpm2html / rdf.c
Revision 1.6: download - view: text, annotated - select for diffs
Sat May 9 07:16:26 1998 UTC (26 years, 1 month ago) by veillard
Branches: MAIN
CVS tags: HEAD
RDF based mirroring starts to work, Daniel.

/*
 * 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