distromatic/src/changelog.c
Silvan Calarco 07548364d6 Restructure popup information and provide Changelog information in recent packages HTML boxes
Cleanup old HTML files just before recreating new ones to avoid having them missing during distromatic execution
2012-04-15 12:08:10 +02:00

306 lines
10 KiB
C

/*
* distromatic - tool for RPM based repositories
*
* Copyright (C) 2004-2007 by Silvan Calarco <silvan.calarco@mambasoft.it>
* Copyright (C) 2006 by Davide Madrisan <davide.madrisan@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of version 2 of the GNU General Public License as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY, to the extent permitted by law; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#if HAVE_STRING_H
# if !STDC_HEADERS && HAVE_MEMORY_H
# include <memory.h>
# endif
# include <string.h>
#endif
#if HAVE_STRINGS_H
# include <strings.h>
#endif
#include "distromatic.h"
#include "changelog.h"
#include "functions.h"
#if !HAVE_STRCHR
# define strchr index
#endif
static struct Packager *firstpackager = NULL;
static struct changeLogFull *firstchangelogfull = NULL;
static struct changeLogFull *currchangelogfull = NULL;
struct Packager *firstPackager() {
return firstpackager;
}
struct Packager *
getPackagerByName(char *name, int create)
{
int i, match=0;
struct Packager *newpackager,
*lastpackager = NULL,
*currpackager = NULL;
if (!name) {
return NULL;
}
currpackager = firstpackager;
while (currpackager && !match) {
if (!strcmp(name, currpackager->name)) match=1;
else {
i=0;
while (currpackager->alias[i] && !match) {
if (!strcmp(name, currpackager->alias[i])) match=1;
i++;
}
}
if (!match) {
lastpackager = currpackager;
currpackager = currpackager->next;
}
}
if (match) {
return currpackager;
}
else if ((!currpackager) && create) {
newpackager = malloc(sizeof(struct Packager));
newpackager->name = (char *) strdup(name);
for (i=0; i<PACKAGER_MAXALIASES; i++) newpackager->alias[i]=NULL;
newpackager->next = NULL;
newpackager->changes_count = 0;
newpackager->packages_count = 0;
newpackager->role = 0;
if (lastpackager)
lastpackager->next = newpackager;
if (!firstpackager)
firstpackager = newpackager;
return newpackager;
}
return NULL;
}
struct changeLog *
getPackageChangelog(Header h, struct headerSourceList* headersource)
{
int count, i;
struct changeLogFull *newchangelogfull, *prevchangelogfull;
struct changeLog *newchangelog,
*oldchangelog = NULL,
*firstchangelog = NULL;
struct Packager *currpackager = NULL;
char **changelogtext, **changelogrelease;
char *endp;
// long *changelogtime;
long *changelogtime;
char changelogname[255];
changelogtime = headerGetUIntArrayEntry(h, RPMTAG_CHANGELOGTIME, &count);
changelogrelease = headerGetStringArrayEntry(h, RPMTAG_CHANGELOGNAME, &count);
changelogtext = headerGetStringArrayEntry(h, RPMTAG_CHANGELOGTEXT, &count);
for (i = 0; i < count; i++) {
newchangelog = malloc(sizeof(struct changeLog));
if (oldchangelog) {
oldchangelog->next = newchangelog;
}
newchangelog->time = changelogtime[i];
strncpy(changelogname, changelogrelease[i], 255);
endp = strchr(changelogname, '>');
if (endp) {
endp[1] = '\0';
}
changelogrelease[i] = strrchr(changelogrelease[i], ' ')+1;
newchangelog->release = changelogrelease[i];
if ((currpackager = getPackagerByName(changelogname, 1))) {
newchangelog->pkg = currpackager;
} else {
newchangelog->pkg = NULL;
}
if (changelogtext[i]) {
newchangelog->text = (char *) strdup(changelogtext[i]);
} else {
newchangelog->text = NULL;
}
newchangelog->next = NULL;
if (!firstchangelog) {
firstchangelog = newchangelog;
}
oldchangelog = newchangelog;
newchangelogfull = malloc(sizeof(struct changeLogFull));
newchangelogfull->changelog = newchangelog;
newchangelogfull->source = headersource;
newchangelogfull->next = NULL;
currchangelogfull = firstchangelogfull;
prevchangelogfull = NULL;
while (currchangelogfull &&
(currchangelogfull->changelog->time > newchangelogfull->changelog->time)) {
prevchangelogfull = currchangelogfull;
currchangelogfull = currchangelogfull->next;
}
if(prevchangelogfull) {
prevchangelogfull->next = newchangelogfull;
} else {
firstchangelogfull = newchangelogfull;
}
newchangelogfull->next = currchangelogfull;
}
headersource->changelog = firstchangelog;
return firstchangelog;
}
char *changeLogTimeStr(char buf[16], struct changeLog *changelog)
{
struct tm *changelogtime;
changelogtime = localtime((time_t *) & changelog->time);
strftime((char *) buf, 16, "%a %h %d %Y", changelogtime);
return buf;
}
int
printChangelogSince(FILE *fout, struct configTag *ct,
struct tm *sincetime, int html)
{
struct changeLogFull *changelogfull;
char strdate[16];
char buffer[PATH_MAX];
struct Packager *currpackager = firstpackager;
time_t simpletime = mktime(sincetime), lasttime = 0;
strftime((char *) &strdate, 16, "%a %h %d %Y", sincetime);
if (!html) {
fprintf(fout,"\nPackagers statistics (changelog since %s):\n\n",
(char *) &strdate);
/* FIXME: `packages_count' is never incremented, so its value is `0' */
fprintf(fout,"Summary (name, packages, updates)\n");
fprintf(fout,"---------------------------------\n");
while (currpackager) {
fprintf(fout,"%s %d, %d\n",
strcmp(currpackager->name, "") ?
currpackager->name : "(noname)",
currpackager->packages_count,
currpackager->changes_count);
currpackager = currpackager->next;
}
fprintf(fout,"\nDetails\n-------");
}
changelogfull = firstchangelogfull;
while (changelogfull) {
if ((changelogfull->changelog->time >= simpletime) &&
(changelogfull->source->altrepository == ct->repository_level)) {
if (!html) {
fprintf(fout,"\n[%s %s] ",
changelogfull->source->name,
changelogfull->changelog->release);
fprintf(fout,"%s %s\n%s\n",
changeLogTimeStr(strdate, changelogfull->changelog),
strcmp(changelogfull->changelog->pkg->name, "") ?
changelogfull->changelog->pkg->name : "(noname)",
changelogfull->changelog->text);
} else {
if (changelogfull->changelog->time != lasttime) {
if (lasttime) fprintf(fout,"<hr>");
fprintf(fout,"<p><h2>%s</h2>",
changeLogTimeStr(strdate, changelogfull->changelog));
lasttime=changelogfull->changelog->time;
}
fprintf(fout,"<p><a href=\"%stag=%s&amp;pkg=%s.source\">%s</a> %s - ",
ct->configdefaults->url_prefix,
ct->tag,
changelogfull->source->name,
changelogfull->source->name,
changelogfull->changelog->release);
if (strcmp(changelogfull->changelog->pkg->name, "")) {
if ((changelogfull->changelog->pkg->role & PACKAGER_ROLE_MAINTAINER) &&
(changelogfull->changelog->pkg->packages_count)) {
fprintf(fout,"<a href=\"%stag=%s&amp;maintainer=%s\">%s</a>",
ct->configdefaults->url_prefix,
ct->tag,
changelogfull->changelog->pkg->name,
changelogfull->changelog->pkg->name);
} else {
fprintf(fout,"%s",changelogfull->changelog->pkg->name);
}
} else {
fprintf(fout,"(noname)");
}
fprintf(fout,"<br>%s<br>\n",
htmlclean(changelogfull->changelog->text,buffer,PATH_MAX));
}
}
changelogfull = changelogfull->next;
// pkgchanged = 0;
// headersourcelist = headersourcelist->next;
}
fprintf(fout,"\n");
return 0;
}
int
printChangelog(struct changeLog *changelog)
{
printf("Changelog:\n");
while (changelog) {
char strdate[16];
changeLogTimeStr(strdate, changelog),
printf("%s - %s\n%s\n",
changeLogTimeStr(strdate, changelog),
changelog->pkg->name ? changelog->pkg->name : "(noname)",
changelog->text);
changelog = changelog->next;
}
return 0;
}