/* * distromatic - tool for RPM based repositories * * Copyright (C) 2004-2020 by Silvan Calarco * Copyright (C) 2006 by Davide Madrisan * * 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. */ #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #include "distromatic.h" #include "config.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; } static long packagerListId = 0; 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; ialias[i]=NULL; newpackager->next = NULL; newpackager->changes_count = 0; newpackager->packages_count = 0; newpackager->role = 0; newpackager->id = ++packagerListId; 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; uint_32 *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,"
"); fprintf(fout,"

%s

", changeLogTimeStr(strdate, changelogfull->changelog)); lasttime=changelogfull->changelog->time; } fprintf(fout,"

%s %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,"%s", 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,"
%s
\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; }