/* * html.c: code concerning the dump as an HTML base. * * Copyright (c) 1997 Daniel Veillard * See COPYING for the status of this software. * * $Id: html.c,v 1.12 1997/11/15 00:05:49 veillard Exp $ */ #include #include #include #ifdef HAVE_FCNTL_H #include #endif #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include #include "rpm2html.h" #include "rpmdata.h" #include "html.h" /* * Global variables concerning the dump environment */ static char buf[500]; /* * Transformation function from group to filename. */ char *groupName(char *group) { static char gbuf[500]; char *cur = gbuf; while (*group != '\0') { if ((*group == '/') || (*group == ' ')) { *cur++ = '_'; group ++; } else *cur++ = *group++; } strcpy(cur, ".html"); return(gbuf); } /* * Transformation function from group to filename. */ char *distribName(char *distrib) { static char dbuf[500]; char *cur = dbuf; while (*distrib != '\0') { if ((*distrib == '/') || (*distrib == ' ')) { *cur++ = '_'; distrib ++; } else *cur++ = *distrib++; } strcpy(cur, ".html"); return(dbuf); } /* * Transformation function from vendor to filename. */ char *vendorName(char *vendor) { static char vbuf[500]; char *cur = vbuf; while (*vendor != '\0') { if ((*vendor == '/') || (*vendor == ' ')) { *cur++ = '_'; vendor ++; } else *cur++ = *vendor++; } strcpy(cur, ".html"); return(vbuf); } /* * Transformation function from ressource to filename. */ char *ressourceName(char *ressource) { static char rbuf[500]; char *cur = rbuf; while (*ressource != '\0') { if ((*ressource == '/') || (*ressource == ' ')) { *cur++ = '_'; ressource ++; } else *cur++ = *ressource++; } strcpy(cur, ".html"); return(rbuf); } /* * Generate an HTML header */ void generateHtmlHeader(FILE *html, char *title, char *color) { fprintf(html, "\n"); fprintf(html, "\n\n%s\n", title); fprintf(html, "\n", rpm2html_name, rpm2html_ver); if (color == NULL) fprintf(html, "\n\n"); else fprintf(html, "\n\n", color); } /* * Generate an HTML footer */ void generateHtmlFooter(FILE *html) { struct tm * tstruct; time_t current_time; current_time = time(NULL); tstruct = localtime(¤t_time); fprintf(html, "
\n"); fprintf(html, "

Generated by %s %s\n", rpm2html_url, rpm2html_name, rpm2html_ver); fprintf(html, "

%s, %s\n", rpm2html_mail, rpm2html_maint, asctime(tstruct)); fprintf(html, "\n\n"); } void dumpIndex(time_t start_time) { int i; FILE *html; char host[200]; rpmDirPtr cur = dirList; gethostname(host, sizeof(host)); #ifdef DEBUG printf("Dumping %s/Index.html\n", rpm2html_dir); #endif sprintf(buf, "%s/index.html", rpm2html_dir); html = fopen(buf, "w"); if (html == NULL) { fprintf(stderr, "Couldn't save to file %s: %s\n", buf, strerror(errno)); return; } sprintf(buf, "Welcome to the RPM repository on %s", host); generateHtmlHeader(html, buf, NULL); fprintf(html, "

Welcome to the RPM repository on %s

\n", host); fprintf(html, "

\n\ rpm2html generate automatically Web pages describing a set of\n\ RPM packages.

\n\

\n\ The goal of rpm2html is also to identify the dependancies between various\n\ packages, and being able to find the packages providing the ressources\n\ needed to install another package. Every package is analyzed to retrieve its\n\ dependancies and the ressources it offers. These relationship are expressed\n\ using hyperlinks in the the generated pages. Finding the package providing\n\ the ressource you need is just a matter of a few clicks!

\n\

\n\ The ultimate commodity is ensured by indexing this set of pages, allowing to\n\ find instantaneously packages providing the some functionnalities (as\n\ long as the package maintainer has properly commented the RPM).

\n\

\n\

This index lists %d RPMs representing %d MBytes of data

\n ", rpm2html_files, rpm2html_size / (1024 * 1024)); while (cur != NULL) { if (cur->name == NULL) fprintf(html, "

%s

\n", cur->urls[0], cur->urls[0]); else fprintf(html, "

%s

\n", cur->ftp, cur->name); if ((cur->ftpsrc != NULL) && (strcmp(cur->ftp, cur->ftpsrc))) fprintf(html, "

Repository for sources: %s

\n", cur->ftpsrc, cur->ftpsrc); fprintf(html, "

Local mirror: %s

\n", cur->urls[0], cur->urls[0]); if (cur->nb_urls > 1) { fprintf(html, "

Mirrors:

\n
    \n"); for (i = 0;i < cur->nb_urls;i++) { fprintf(html, "
  • %s\n", cur->urls[i],cur->urls[i]); } fprintf(html, "
\n"); } cur = cur->next; } fprintf(html, "

Generation took %d seconds

\n", (int) (time(NULL) - start_time)); generateHtmlFooter(html); fclose(html); } /* * Dump an RPM block as an HTML file. */ void dumpRpmHtml(rpmDataPtr rpm) { struct tm * tstruct; rpmDirPtr dir = rpm->dir; FILE *html; int i; #ifdef DEBUG printf("Dumping %s/%s-%s-%s.html\n", rpm2html_dir, rpm->name, rpm->version, rpm->release); #endif sprintf(buf, "%s/%s-%s-%s.html", rpm2html_dir, rpm->name, rpm->version, rpm->release); html = fopen(buf, "w"); if (html == NULL) { fprintf(stderr, "Couldn't save to file %s: %s\n", buf, strerror(errno)); return; } sprintf(buf, "%s-%s-%s RPM", rpm->name, rpm->version, rpm->release); generateHtmlHeader(html, buf, dir->color); if (rpm->arch) { fprintf(html, "

\n", dir->urls[0], rpm->name, rpm->version, rpm->release, rpm->arch); fprintf(html, "%s-%s-%s RPM for %s

\n", rpm->name, rpm->version, rpm->release, rpm->arch); } else { fprintf(html, "

\n", dir->urls[0], rpm->name, rpm->version, rpm->release); fprintf(html, "%s-%s-%s RPM

\n", rpm->name, rpm->version, rpm->release); } if (dir->name) { fprintf(html, "

From %s

\n", dir->ftp, dir->name); } fprintf(html, ""); fprintf(html, "\n"); fprintf(html, "\n", rpm->name); fprintf(html, "\n", distribName(rpm->distribution), rpm->distribution); fprintf(html, "\n", rpm->version); fprintf(html, "\n", vendorName(rpm->vendor), rpm->vendor); tstruct = localtime(&(rpm->date)); #ifdef HAVE_STRFTIME strftime(buf, sizeof(buf) - 1, "%c", tstruct); #else #error "no strftime, please check !" #endif fprintf(html, "\n\n", rpm->release, buf); fprintf(html, "\n", groupName(rpm->group), rpm->group); fprintf(html, "\n", rpm->host); fprintf(html, "\n", rpm->size); if (dir->ftpsrc) { fprintf(html, "\n", dir->ftpsrc, rpm->srcrpm, rpm->srcrpm); } else { fprintf(html, "\n", rpm->srcrpm); } if (rpm->packager) { char *email = extractEMail(rpm->packager); if (email == NULL) fprintf(html, "\n", rpm->packager); else fprintf(html, "\n", email, rpm->packager); } if (rpm->url) fprintf(html, "\n", rpm->url, rpm->url); fprintf(html, "\n", rpm->summary); fprintf(html, "\n
Name: %sDistribution: %s
Version: %sVendor: %s
Release: %sBuild Date: %s
Group: %sBuild Host: %s
Size: %dSource RPM: %s
Source RPM: %s
Packager: %s
Packager: %s
Url: %s
Summary: %s
\n"); fprintf(html, "
%s\n
\n", rpm->description); if (rpm->nb_ressources > 0) { fprintf(html, "

Provides

\n"); fprintf(html, "
    \n"); for (i = 0;i < rpm->nb_ressources;i++) { fprintf(html, "
  • %s\n", ressourceName(rpm->ressources[i]->name), rpm->ressources[i]->name); } if (i >= MAX_RESS) fprintf(html, "
  • ...\n"); fprintf(html, "
\n"); } else fprintf(stderr, "package %s-%s-%s.%s.rpm doesn't provide ressource\n", rpm->name, rpm->version, rpm->release, rpm->arch); if (rpm->nb_requires > 0) { fprintf(html, "

Requires

\n"); fprintf(html, "
    \n"); for (i = 0;i < rpm->nb_requires;i++) { fprintf(html, "
  • %s\n", ressourceName(rpm->requires[i]->name), rpm->requires[i]->name); } if (i >= MAX_REQU) fprintf(html, "
  • ...\n"); fprintf(html, "
\n"); } if (rpm->copyright) { fprintf(html, "

Copyright

\n"); fprintf(html, "
%s\n
\n", rpm->copyright); } fprintf(html, "

Files

\n"); if (rpm->filelist == NULL) fprintf(html, "No Filelist in the Package !\n\n"); else fprintf(html, "
%s\n
\n", rpm->filelist); generateHtmlFooter(html); fclose(html); } /* * Dump a ressource block as an HTML file. */ void dumpRessHtml(rpmRessPtr ress) { rpmDataPtr rpm; FILE *html; int i; #ifdef DEBUG printf("Dumping %s/%s\n", rpm2html_dir, ressourceName(ress->name)); #endif sprintf(buf, "%s/%s", rpm2html_dir, ressourceName(ress->name)); html = fopen(buf, "w"); if (html == NULL) { fprintf(stderr, "Couldn't save to file %s: %s\n", buf, strerror(errno)); return; } sprintf(buf, "RPM ressource %s", ress->name); generateHtmlHeader(html, buf, NULL); fprintf(html, "

RPM ressource %s

\n", ress->name); fprintf(html, "

Provided by

\n"); fprintf(html, "\n"); generateHtmlFooter(html); fclose(html); } /* * Dump all RPM blocks in the HTML files. * Not used anymore there are dumped are they are parsed * to minimize memory requirements void dumpAllRpmHtml() { rpmDataPtr cur = rpmList; while (cur != NULL) { dumpRpmHtml(cur); cur = cur->next; } } */ /* * Dump all RPM blocks in the HTML files. */ void dumpAllRessHtml() { rpmRessPtr cur = ressList; while (cur != NULL) { dumpRessHtml(cur); cur = cur->next; } } /* * Dump the Groups HTML files. * One expect that the RPM files have been sorted by group. */ void dumpRpmGroups() { FILE *Groups; FILE *currentGroup = NULL; rpmDataPtr cur = rpmList, prev = NULL; #ifdef DEBUG printf("Dumping %s/Groups.html\n", rpm2html_dir); #endif sprintf(buf, "%s/Groups.html", rpm2html_dir); Groups = fopen(buf, "w"); if (Groups == NULL) { fprintf(stderr, "Couldn't save to file %s: %s\n", buf, strerror(errno)); return; } generateHtmlHeader(Groups, "RPM sorted by Group", NULL); fprintf(Groups, "

RPM sorted by Group

\n"); fprintf(Groups, "
    \n"); while (cur != NULL) { if ((cur->group != NULL) && (strlen(cur->group) > 0)) { if ((prev == NULL) || (strcasecmp(prev->group, cur->group))) { if (currentGroup != NULL) { /* one need to close the current group list */ fprintf(currentGroup,"\n"); generateHtmlFooter(currentGroup); fclose(currentGroup); } /* Add the current group in the Group list */ fprintf(Groups, "
  • %s
  • \n", groupName(cur->group), cur->group); /* open the new HTML group file */ #ifdef DEBUG printf("Dumping %s/%s\n", rpm2html_dir, groupName(cur->group)); #endif sprintf(buf, "%s/%s", rpm2html_dir, groupName(cur->group)); currentGroup = fopen(buf, "w"); if (currentGroup == NULL) { fprintf(stderr, "Couldn't save to file %s: %s\n", buf, strerror(errno)); return; } sprintf(buf, "RPM of Group %s", cur->group); generateHtmlHeader(currentGroup, buf, NULL); fprintf(currentGroup, "

    RPM of Group %s

    \n", cur->group); fprintf(currentGroup,"
    \n"); } fprintf(currentGroup, "
    ", cur->name, cur->version, cur->release); fprintf(currentGroup, "%s-%s-%s
    \n", cur->name, cur->version, cur->release); fprintf(currentGroup, "
    %s
    \n", cur->summary); } prev = cur; cur = cur->next; } if (currentGroup != NULL) { /* one need to close the current group list */ generateHtmlFooter(currentGroup); fclose(currentGroup); } fprintf(Groups, "
\n"); generateHtmlFooter(Groups); fclose(Groups); } /* * Dump the Distribs HTML files. * One expect that the RPM files have been sorted by distribution. */ void dumpRpmDistribs() { FILE *Distribs; FILE *currentDistrib = NULL; rpmDataPtr cur = rpmList, prev = NULL; #ifdef DEBUG printf("Dumping %s/Distributions.html\n", rpm2html_dir); #endif sprintf(buf, "%s/Distributions.html", rpm2html_dir); Distribs = fopen(buf, "w"); if (Distribs == NULL) { fprintf(stderr, "Couldn't save to file %s: %s\n", buf, strerror(errno)); return; } generateHtmlHeader(Distribs, "RPM sorted by Distribution", NULL); fprintf(Distribs, "

RPM sorted by Distribution

\n"); fprintf(Distribs, "
    \n"); while (cur != NULL) { if ((cur->distribution != NULL) && (strlen(cur->distribution) > 0)) { if ((prev == NULL) || (strcasecmp(prev->distribution, cur->distribution))) { if (currentDistrib != NULL) { /* one need to close the current distribution list */ fprintf(currentDistrib,"\n"); generateHtmlFooter(currentDistrib); fclose(currentDistrib); } /* Add the current distribution in the Distrib list */ fprintf(Distribs, "
  • %s
  • \n", distribName(cur->distribution), cur->distribution); /* open the new HTML distribution file */ #ifdef DEBUG printf("Dumping %s/%s\n", rpm2html_dir, distribName(cur->distribution)); #endif sprintf(buf, "%s/%s", rpm2html_dir, distribName(cur->distribution)); currentDistrib = fopen(buf, "w"); if (currentDistrib == NULL) { fprintf(stderr, "Couldn't save to file %s: %s\n", buf, strerror(errno)); return; } sprintf(buf, "RPM of Distrib %s", cur->distribution); generateHtmlHeader(currentDistrib, buf, NULL); fprintf(currentDistrib, "

    RPM of Distrib %s

    \n", cur->distribution); fprintf(currentDistrib,"
    \n"); } fprintf(currentDistrib, "
    ", cur->name, cur->version, cur->release); fprintf(currentDistrib, "%s-%s-%s
    \n", cur->name, cur->version, cur->release); fprintf(currentDistrib, "
    %s
    \n", cur->summary); } prev = cur; cur = cur->next; } if (currentDistrib != NULL) { /* one need to close the current distribution list */ generateHtmlFooter(currentDistrib); fclose(currentDistrib); } fprintf(Distribs, "
\n"); generateHtmlFooter(Distribs); fclose(Distribs); } /* * Dump the Vendors HTML files. * One expect that the RPM files have been sorted by vendors. */ void dumpRpmVendors() { FILE *Vendors; FILE *currentVendor = NULL; rpmDataPtr cur = rpmList, prev = NULL; #ifdef DEBUG printf("Dumping %s/Vendors.html\n", rpm2html_dir); #endif sprintf(buf, "%s/Vendors.html", rpm2html_dir); Vendors = fopen(buf, "w"); if (Vendors == NULL) { fprintf(stderr, "Couldn't save to file %s: %s\n", buf, strerror(errno)); return; } generateHtmlHeader(Vendors, "RPM sorted by Maintainer", NULL); fprintf(Vendors, "

RPM sorted by Maintainer

\n"); fprintf(Vendors, "
    \n"); while (cur != NULL) { if ((cur->vendor != NULL) && (strlen(cur->vendor) > 0)) { if ((prev == NULL) || (strcasecmp(prev->vendor, cur->vendor))) { if (currentVendor != NULL) { /* one need to close the current vendor list */ fprintf(currentVendor,"\n"); generateHtmlFooter(currentVendor); fclose(currentVendor); } /* Add the current vendor in the Vendor list */ fprintf(Vendors, "
  • %s
  • \n", vendorName(cur->vendor), cur->vendor); /* open the new HTML vendor file */ #ifdef DEBUG printf("Dumping %s/%s\n", rpm2html_dir, vendorName(cur->vendor)); #endif sprintf(buf, "%s/%s", rpm2html_dir, vendorName(cur->vendor)); currentVendor = fopen(buf, "w"); if (currentVendor == NULL) { fprintf(stderr, "Couldn't save to file %s: %s\n", buf, strerror(errno)); return; } sprintf(buf, "RPM shipped by %s", cur->vendor); generateHtmlHeader(currentVendor, buf, NULL); fprintf(currentVendor, "

    RPM shipped by %s

    \n", cur->vendor); fprintf(currentVendor,"
    \n"); } fprintf(currentVendor, "
    ", cur->name, cur->version, cur->release); fprintf(currentVendor, "%s-%s-%s
    \n", cur->name, cur->version, cur->release); fprintf(currentVendor, "
    %s
    \n", cur->summary); } prev = cur; cur = cur->next; } if (currentVendor != NULL) { /* one need to close the current vendor list */ generateHtmlFooter(currentVendor); fclose(currentVendor); } fprintf(Vendors, "
\n"); generateHtmlFooter(Vendors); fclose(Vendors); } /* * Dump the RPM by Date HTML file. * One expect that the RPM files have been sorted by date. */ void dumpRpmByDate() { FILE *ByDate; rpmDataPtr cur = rpmList; time_t current_time = time(NULL); #ifdef DEBUG printf("Dumping %s/ByDate.html\n", rpm2html_dir); #endif sprintf(buf, "%s/ByDate.html", rpm2html_dir); ByDate = fopen(buf, "w"); if (ByDate == NULL) { fprintf(stderr, "Couldn't save to file %s: %s\n", buf, strerror(errno)); return; } generateHtmlHeader(ByDate, "RPM sorted by Date", NULL); fprintf(ByDate, "

RPM sorted by Date

\n"); /* * First dump RPMs less than 3 days old. */ fprintf(ByDate, "

RPMs less than three days old

\n"); fprintf(ByDate, "
\n"); while ((cur != NULL) && ((current_time - cur->date) < (3 * 24 * 60 * 60))) { fprintf(ByDate, "
", cur->name, cur->version, cur->release); fprintf(ByDate, "%s-%s-%s
\n", cur->name, cur->version, cur->release); fprintf(ByDate, "
%s
\n", cur->summary); cur = cur->next; } fprintf(ByDate, "
\n"); /* * Then dump RPMs less than one week old. */ fprintf(ByDate, "

RPMs less than one week old

\n"); fprintf(ByDate, "
\n"); while ((cur != NULL) && ((current_time - cur->date) < (7 * 24 * 60 * 60))) { fprintf(ByDate, "
", cur->name, cur->version, cur->release); fprintf(ByDate, "%s-%s-%s
\n", cur->name, cur->version, cur->release); fprintf(ByDate, "
%s
\n", cur->summary); cur = cur->next; } fprintf(ByDate, "
\n"); /* * Then dump RPMs less than two weeks old. */ fprintf(ByDate, "

RPMs less than two weeks old

\n"); fprintf(ByDate, "
\n"); while ((cur != NULL) && ((current_time - cur->date) < (14 * 24 * 60 * 60))) { fprintf(ByDate, "
", cur->name, cur->version, cur->release); fprintf(ByDate, "%s-%s-%s
\n", cur->name, cur->version, cur->release); fprintf(ByDate, "
%s
\n", cur->summary); cur = cur->next; } fprintf(ByDate, "
\n"); /* * Then dump RPMs less than one month old. */ fprintf(ByDate, "

RPMs less than one month old

\n"); fprintf(ByDate, "
\n"); while ((cur != NULL) && ((current_time - cur->date) < (30 * 24 * 60 * 60))) { fprintf(ByDate, "
", cur->name, cur->version, cur->release); fprintf(ByDate, "%s-%s-%s
\n", cur->name, cur->version, cur->release); fprintf(ByDate, "
%s
\n", cur->summary); cur = cur->next; } fprintf(ByDate, "
\n"); /* * Then dump RPMs more than one month old. */ fprintf(ByDate, "

RPMs more than one month old

\n"); fprintf(ByDate, "
\n"); while (cur != NULL) { fprintf(ByDate, "
", cur->name, cur->version, cur->release); fprintf(ByDate, "%s-%s-%s
\n", cur->name, cur->version, cur->release); fprintf(ByDate, "
%s
\n", cur->summary); cur = cur->next; } fprintf(ByDate, "
\n"); generateHtmlFooter(ByDate); fclose(ByDate); } /* * Dump the RPM by Name HTML file. * One expect that the RPM files have been sorted by name. */ void dumpRpmByName() { FILE *ByName; rpmDataPtr cur = rpmList; #ifdef DEBUG printf("Dumping %s/ByName.html\n", rpm2html_dir); #endif sprintf(buf, "%s/ByName.html", rpm2html_dir); ByName = fopen(buf, "w"); if (ByName == NULL) { fprintf(stderr, "Couldn't save to file %s: %s\n", buf, strerror(errno)); return; } generateHtmlHeader(ByName, "RPM sorted by Name", NULL); fprintf(ByName, "

RPM sorted by Name

\n"); fprintf(ByName, "
\n"); while (cur != NULL) { fprintf(ByName, "
", cur->name, cur->version, cur->release); fprintf(ByName, "%s-%s-%s
\n", cur->name, cur->version, cur->release); fprintf(ByName, "
%s
\n", cur->summary); cur = cur->next; } fprintf(ByName, "
\n"); generateHtmlFooter(ByName); fclose(ByName); }