298 lines
9.9 KiB
C
298 lines
9.9 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;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
printChangelogSince(FILE *fout, struct configTag *ct,
|
||
|
struct tm *sincetime, int html)
|
||
|
{
|
||
|
struct changeLogFull *changelogfull;
|
||
|
struct tm *changelogtime;
|
||
|
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)) {
|
||
|
changelogtime = localtime((time_t *) & changelogfull->changelog->time);
|
||
|
strftime((char *) &strdate, 16, "%a %h %d %Y", changelogtime);
|
||
|
if (!html) {
|
||
|
fprintf(fout,"\n[%s %s] ",
|
||
|
changelogfull->source->name,
|
||
|
changelogfull->changelog->release);
|
||
|
fprintf(fout,"%s %s\n%s\n", (char *) &strdate,
|
||
|
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>",(char *) &strdate);
|
||
|
lasttime=changelogfull->changelog->time;
|
||
|
}
|
||
|
fprintf(fout,"<p><a href=\"%stag=%s&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&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) {
|
||
|
struct tm *changelogtime;
|
||
|
char strdate[16];
|
||
|
|
||
|
changelogtime = localtime((time_t *) & changelog->time);
|
||
|
strftime((char *) &strdate, 16, "%a %h %d %Y", changelogtime);
|
||
|
printf("%s - %s\n%s\n", (char *) &strdate,
|
||
|
changelog->pkg->name ? changelog->pkg->name : "(noname)",
|
||
|
changelog->text);
|
||
|
changelog = changelog->next;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|