/* * distromatic - tool for RPM based repositories * * Copyright (C) 2004-2010 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. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #include "changelog.h" #include "reports.h" #include "rpmfunctions.h" #include "functions.h" #include "requirelist.h" #include #include #define HTMLSTATS_NUM 100 #define HTMLOLDSTATS_NUM 100 #define RSSSTATS_NUM 20 char *groupdirname(char *group,char *dest,unsigned int max) { strncpy(dest,group,max); unsigned int i=0; while (dest[i] && ipackager) return -1; else if (! (*(struct headerSourceList **)ptr2)->packager) return +1; else { ret=strcasecmp((*(struct headerSourceList **)ptr1)->packager->name, (*(struct headerSourceList **)ptr2)->packager->name); if (!ret) { ret=strcasecmp((*(struct headerSourceList **)ptr1)->name, (*(struct headerSourceList **)ptr2)->name); } return ret; } } int printHTMLWarnings(FILE *fout,struct configTag *configtag, struct headerSourceList* pkg, int mode) { char warningsfile[PATH_MAX]; char buf[1024]; struct stat s; FILE *fin; int n; struct warningList *currwarning; if (!pkg) return 0; currwarning = pkg->firstwarning; snprintf(warningsfile,PATH_MAX,"%swarnings/%s.in",configtag->html_dir,pkg->name); if (pkg->firstwarning || !stat(warningsfile,&s)) { if (mode == 0) { fprintf(fout, "configdefaults->url_dir); } else if (mode == 1) { fprintf(fout, "
 Beware, this package has warnings:
", configtag->configdefaults->url_dir); } } if (!stat(warningsfile,&s)) { if ((fin = fopen(warningsfile, "r")) == NULL) { perror(warningsfile); return 0; } fprintf(fout," • Comment:"); while (!feof(fin)) { n = fread(buf,1,1024,fin); fwrite(buf,1,n,fout); } if (mode == 0) { fprintf(fout,"\n"); } else if (mode == 1) { fprintf(fout,"
"); } fclose(fin); } while (currwarning) { if (mode == 0) { fprintf(fout," • %s\n",currwarning->text); } else if (mode == 1) { fprintf(fout," • %s
",currwarning->text); } currwarning = currwarning->next; } if (pkg->firstwarning || !stat(warningsfile,&s)) { if (mode == 0) { fprintf(fout,"\">"); } else if (mode == 1) { fprintf(fout,"

\n"); } return 1; } return 0; } void printpkgicon(FILE *fout, struct configTag *configtag, struct headerSourceList *s) { char buffer[PATH_MAX]; char strdate[16]; int i; if (s->updrepository >= 0) { fprintf(fout, "configdefaults->url_dir); } else { fprintf(fout, "configdefaults->url_dir); } if (s->changelog) { simpleTimeToHuman(s->changelog->time, (humanDate *) & strdate); fprintf(fout, "title=\"%s - %s (%s)\n%s", strdate, s->changelog->pkg->name, s->changelog->release, htmlcleanNoBr(s->changelog->text,buffer,PATH_MAX)); if (s->changelog->next) { simpleTimeToHuman(s->changelog->next->time, (humanDate *) & strdate); fprintf(fout, "\n%s - %s (%s)\n%s", strdate, s->changelog->next->pkg->name, s->changelog->next->release, htmlcleanNoBr(s->changelog->next->text,buffer,PATH_MAX)); } } else { fprintf(fout, "title=\"WARNING: missing changelog"); } fprintf(fout,"\n\nArchs:"); for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) { if (s->firstchild[i]) fprintf(fout," %s", configtag->arch[i]); } if (s->updrepository >= 0) { fprintf(fout, "\n\nUpdates package in %s\">", configtag->repository[s->updrepository]->tag); } else { fprintf(fout, "\">"); } } int generateMaintainersPages(struct configTag *configtag) { char idxfile[1024],outfile[1024],unmaintfile[1024]; FILE *idx=NULL,*out=NULL,*unmaint=NULL; int i,pkgnum,unmaintpkgnum; struct stat buf; struct Packager *currpackager = NULL; /* sort headersourcelistvec by packager name */ qsort((void *) &configtag->stats.headersourcelistvec[0], configtag->stats.headersourcecount, sizeof(struct headerSourceList *), comparePackagers); snprintf(outfile,1024,"%smaintainers",configtag->html_dir); if (stat(outfile,&buf)) { if (mkdir(outfile,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { logmsg(LOG_ERROR,"cannot create %s directory; aborting.",outfile); exit(1); } } else { if (!S_ISDIR(buf.st_mode)) { logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",outfile); exit(1); } } snprintf(idxfile,1024,"%s_maintainers.inc",configtag->html_dir); if ((idx = fopen(idxfile, "w")) == NULL) { perror(idxfile); return 1; } fprintf(idx, "
Maintainers for packages in the %s repository (%s):

\n", configtag->tag, configtag->description); snprintf(unmaintfile,1024,"%smaintainers/unmaintained.inc",configtag->html_dir); if ((unmaint = fopen(unmaintfile, "w")) == NULL) { perror(unmaintfile); return 1; } fprintf(unmaint, "
Packages that are unmaintained in the %s repository:

\n",configtag->tag); i=0; out=NULL; pkgnum=0; unmaintpkgnum=0; while (i < configtag->stats.headersourcecount) { if ((configtag->stats.headersourcelistvec[i])->packager) { if ((i == 0) || ((configtag->stats.headersourcelistvec[i-1])->packager != (configtag->stats.headersourcelistvec[i])->packager)) { if ((configtag->stats.headersourcelistvec[i])->packager->role & PACKAGER_ROLE_MAINTAINER) { snprintf(outfile,1024,"%smaintainers/%s.inc", configtag->html_dir, (configtag->stats.headersourcelistvec[i])->packager->name); if ((out = fopen(outfile, "w")) == NULL) { perror(outfile); return 1; } fprintf(out, "
Packages maintained by %s in the %s repository:

\n", (configtag->stats.headersourcelistvec[i])->packager->name, configtag->tag); } // new maintainer file created } // check for changed packager if ((configtag->stats.headersourcelistvec[i])->packager->role & PACKAGER_ROLE_MAINTAINER) { fprintf(out, "%s: %s
\n", configtag->configdefaults->url_prefix, configtag->tag, (configtag->stats.headersourcelistvec)[i]->name, (configtag->stats.headersourcelistvec)[i]->name, (configtag->stats.headersourcelistvec)[i]->summary); pkgnum++; if ((i+1 >= configtag->stats.headersourcecount) || ((configtag->stats.headersourcelistvec[i])->packager != (configtag->stats.headersourcelistvec[i+1])->packager)) { fprintf(idx, "%s (pkg:%d; act:%5.2f%%)
\n", configtag->configdefaults->url_prefix, configtag->tag, configtag->stats.headersourcelistvec[i]->packager->name, configtag->stats.headersourcelistvec[i]->packager->name, pkgnum, ((double)(configtag->stats.headersourcelistvec[i]->packager->changes_count) * 100) / configtag->stats.changelog_total ); pkgnum=0; fclose(out); } } else { // unmaintained package fprintf(unmaint, "%s: %s
\n", configtag->configdefaults->url_prefix, configtag->tag, (configtag->stats.headersourcelistvec)[i]->name, (configtag->stats.headersourcelistvec)[i]->name, (configtag->stats.headersourcelistvec)[i]->summary); unmaintpkgnum++; } } i++; } // while fclose(unmaint); currpackager = firstPackager(); // write stats for maintainer with 0 packages but changes (e.g. autodist) while (currpackager) { if ((currpackager->role & PACKAGER_ROLE_MAINTAINER) && (currpackager->packages_count == 0) && (currpackager->changes_count > 0) ) { fprintf(idx, "%s (pkg:%d; act:%5.2f%%)
\n", currpackager->name, 0, ((double)(currpackager->changes_count) * 100) / configtag->stats.changelog_total ); } /* else { printf("skipped %s packages:%d changes:%d\n",currpackager->name,currpackager->packages_count,currpackager->changes_count); }*/ currpackager = currpackager->next; } if (unmaintpkgnum) fprintf(idx, "unmaintained packages (pkg:%d)
\n", configtag->configdefaults->url_prefix, configtag->tag, unmaintpkgnum); fclose(idx); return 0; } int generateStats(struct configTag *configtag,int arch) { char outfile[1024]; char rssfile[1024]; char buffer[PATH_MAX]; FILE *htmlout=NULL,*htmloldout,*rssout,*groupout; struct stat buf; int i,pkgnum; humanDate strdate,strolddate; sizeString strsize; struct tm *ytm; time_t timesec; timesec = time(×ec); ytm = localtime((time_t *) ×ec); ytm->tm_sec = 0; ytm->tm_min = 0; ytm->tm_hour = 0; ytm->tm_mday = 1; ytm->tm_mon = 0; timesec = mktime(ytm); if (!configtag->configdefaults->html_basedir) { return 2; } /* sort headersourcelistvec by Group */ qsort((void *) &configtag->stats.headersourcelistvec[0], configtag->stats.headersourcecount, sizeof(struct headerSourceList *), compareGroup); snprintf(outfile,1024,"%s_groups.inc",configtag->html_dir); if ((groupout = fopen(outfile, "w")) == NULL) { perror(outfile); return 1; } /* create groups directory */ snprintf(outfile, PATH_MAX, "%sgroups",configtag->html_dir); if (stat(outfile,&buf)) { if (mkdir(outfile,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { logmsg(LOG_ERROR,"cannot create %s directory; aborting.",outfile); exit(1); } } else { if (!S_ISDIR(buf.st_mode)) { logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",outfile); exit(1); } } fprintf(groupout, "
Groups in the %s repository (%s):

\n", configtag->tag, configtag->description); i=0; pkgnum=0; if (configtag->stats.headersourcecount) do { if (pkgnum==0) { snprintf(outfile, PATH_MAX, "%sgroups/%s", configtag->html_dir, groupdirname(configtag->stats.headersourcelistvec[i]->group,buffer,PATH_MAX)); if (stat(outfile,&buf)) { if (mkdir(outfile,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { logmsg(LOG_ERROR,"cannot create %s directory; aborting.",outfile); exit(1); } } else { if (!S_ISDIR(buf.st_mode)) { logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",outfile); exit(1); } } strncat(outfile, "/_index.inc", 1024); if ((htmlout = fopen(outfile, "w")) == NULL) { perror(outfile); return 1; } fprintf(htmlout, "
Packages in the %s group of the %s repository (%s):

\n", configtag->stats.headersourcelistvec[i]->group, configtag->tag, configtag->description); } fprintf(htmlout, "%s: %s
\n", configtag->configdefaults->url_prefix, configtag->tag, (configtag->stats.headersourcelistvec)[i]->name, (configtag->stats.headersourcelistvec)[i]->name, (configtag->stats.headersourcelistvec)[i]->summary); i++; pkgnum++; if ((i >= configtag->stats.headersourcecount) || (strcmp(configtag->stats.headersourcelistvec[i-1]->group, configtag->stats.headersourcelistvec[i]->group))) { fprintf(groupout, "%s (%d)
\n", configtag->configdefaults->url_prefix, configtag->tag, groupdirname(configtag->stats.headersourcelistvec[i-1]->group,buffer,PATH_MAX), (configtag->stats.headersourcelistvec)[i-1]->group, pkgnum); pkgnum=0; fclose(htmlout); } } while (i < configtag->stats.headersourcecount); if (i>0) { fclose(groupout); } strncpy(outfile, configtag->html_dir, 1024); strncat(outfile, "_recent.inc", 1024); if ((htmlout = fopen(outfile, "w")) == NULL) { perror(outfile); return 1; } /*else { fprintf(htmlout, "" "", configtag->configdefaults->url_dir, configtag->tag, configtag->configdefaults->url_dir); fprintf(htmlout, "Recent builds:
\n"); }*/ strncpy(outfile, configtag->html_dir, 1024); strncat(outfile, "_oldest.inc", 1024); if ((htmloldout = fopen(outfile, "w")) == NULL) { perror(outfile); return 1; } /* else { fprintf(htmloldout, "Oldest builds:
\n"); }*/ strncpy(rssfile, configtag->html_dir, 1024); strncat(rssfile, "recent.rss", 1024); if ((rssout = fopen(rssfile, "w")) == NULL) { perror(rssfile); return 1; } else { fprintf(rssout,"\n"); fprintf(rssout,"\n"); fprintf(rssout,"\n"); fprintf(rssout," Recent packages for the %s repository\n",configtag->tag); fprintf(rssout," http://%s/%s\n", configtag->configdefaults->url_address, configtag->configdefaults->url_prefix); //fprintf(rssout," \n"); fprintf(rssout," en-us\n"); fprintf(rssout," http://blogs.law.harvard.edu/tech/rss"); fprintf(rssout," Distromatic %s\n",VERSION); } /* sort headersourcelistvec by BuildDate */ qsort((void *) &configtag->stats.headersourcelistvec[0], configtag->stats.headersourcecount, sizeof(struct headerSourceList *), compareSourceHeaderBuildDate); fprintf(htmlout, "SRPMS(%d;%s)", configtag->configdefaults->url_prefix, configtag->tag, configtag->stats.headersourcecount, humanSize(configtag->stats.headersourcesize, &strsize)); for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) { fprintf(htmlout, " %s(%d;%s) ", configtag->configdefaults->url_prefix, configtag->tag, configtag->arch[i], configtag->arch[i], configtag->stats.headercount[i], humanSize(configtag->stats.headersize[i], &strsize)); if (i % 2 == 0) fprintf(htmlout,"
"); } if (i % 2 == 0) fprintf(htmlout,"
"); i=0; while ((i < configtag->stats.headersourcecount) && ((i < HTMLSTATS_NUM) || (i < RSSSTATS_NUM))) { if ((configtag->stats.headersourcelistvec)[i]->buildtime < timesec) { simpleTimeToTemplate( (configtag->stats.headersourcelistvec)[i]->buildtime, "%Y/%m/%d",&strdate); } else { simpleTimeToTemplate( (configtag->stats.headersourcelistvec)[i]->buildtime, "%m/%d",&strdate); } if (i < HTMLSTATS_NUM) { // HTML statistics printpkgicon(htmlout, configtag, (configtag->stats.headersourcelistvec)[i]); fprintf(htmlout, "%s %s %s-%s ", configtag->configdefaults->url_prefix, configtag->tag, (configtag->stats.headersourcelistvec)[i]->name, htmlclean((configtag->stats.headersourcelistvec)[i]->summary,buffer,PATH_MAX), strdate, (configtag->stats.headersourcelistvec)[i]->name, (configtag->stats.headersourcelistvec)[i]->version, (configtag->stats.headersourcelistvec)[i]->release); // FIXME: warnings are printed before SRPMS warning are added below so SRPMS warning are missing in HTML pages printHTMLWarnings(htmlout,configtag,(configtag->stats.headersourcelistvec)[i],0); fprintf(htmlout,"
\n"); } if (i < HTMLOLDSTATS_NUM) { // HTML statistics simpleTimeToTemplate((configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->buildtime,"%Y/%m/%d",&strolddate); fprintf(htmloldout, "%s %s %s-%s
\n", configtag->configdefaults->url_prefix, configtag->tag, (configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->name, strolddate, (configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->name, (configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->version, (configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->release); } if (i < RSSSTATS_NUM) { // RSS recent packages fprintf(rssout," \n"); fprintf(rssout," %s %s %s-%s\n", strdate, (configtag->stats.headersourcelistvec)[i]->name, (configtag->stats.headersourcelistvec)[i]->version, (configtag->stats.headersourcelistvec)[i]->release); fprintf(rssout," http://%s%stag=%s&pkg=%s.source\n", configtag->configdefaults->url_address, configtag->configdefaults->url_prefix, configtag->tag, (configtag->stats.headersourcelistvec)[i]->name); fprintf(rssout," \n"); } i++; } fclose(htmlout); // fprintf(rssout, "\n"); fprintf(rssout, "
\n"); fprintf(rssout, "
\n"); fclose(rssout); /* create APT repository file */ snprintf(outfile,1024,"%s%s-%s.list", configtag->html_dir, configtag->configdefaults->distribution_name, configtag->tag); if ((htmlout = fopen(outfile, "w")) == NULL) { perror(outfile); return 1; } else { /* remove final slashes from download_prefix as required by apt */ strncpy(buffer, configtag->download_dir, PATH_MAX); i=strlen(buffer); while ((i > 0) && (buffer[i-1] == '/' )) { buffer[i-1]='\0'; i--; } fprintf(htmlout, "#\n# %s %s repository sources list for APT\n#\n\n", configtag->configdefaults->distribution_name, configtag->tag); fprintf(htmlout, "#\n# %s %s repository from %s\n#\n", configtag->tag, configtag->arch[arch], configtag->configdefaults->url_address); fprintf(htmlout, "rpm http://%s %s %s\n\n", configtag->configdefaults->url_address, buffer, configtag->arch[arch]); fprintf(htmlout, "#\n# %s sources repository from %s\n#\n", configtag->tag, configtag->configdefaults->url_address); fprintf(htmlout, "rpm-src http://%s %s base\n\n", configtag->configdefaults->url_address, buffer); fclose(htmlout); } /* create Smart Package Manager channel file */ snprintf(outfile,1024,"%s%s-%s.smart", configtag->html_dir, configtag->configdefaults->distribution_name, configtag->tag); if ((htmlout = fopen(outfile, "w")) == NULL) { perror(outfile); return 1; } else { /* remove final slashes from download_prefix as required by apt */ strncpy(buffer, configtag->download_dir, PATH_MAX); i=strlen(buffer); while ((i > 0) && (buffer[i-1] == '/' )) { buffer[i-1]='\0'; i--; } fprintf(htmlout, "#\n# %s %s channel configuration for Smart Package Manager\n#\n\n", configtag->configdefaults->distribution_name, configtag->tag); fprintf(htmlout, "[%s]\ntype = apt-rpm\n", configtag->tag); fprintf(htmlout, "name = %s\n", configtag->description); fprintf(htmlout, "baseurl = http://%s%s\n", configtag->configdefaults->url_address, buffer); fprintf(htmlout, "components ="); for (i = 0; i < ARCHS_MAX; i++) { if (configtag->arch[i]) fprintf(htmlout," %s", configtag->arch[i]); } fprintf(htmlout, "\n"); fclose(htmlout); } /* create Changelog page */ struct tm tmdate; tmdate.tm_min = 0; tmdate.tm_hour = 0; tmdate.tm_sec = 0; tmdate.tm_year = 90; tmdate.tm_mday = 1; tmdate.tm_mon = 0; snprintf(outfile,1024,"%s_changelog.inc",configtag->html_dir); if ((htmlout = fopen(outfile, "w")) == NULL) { perror(outfile); return 1; } fprintf(htmlout, "

Changelog for the %s repository (%s):

\n", configtag->tag, configtag->description); printChangelogSince(htmlout, configtag, &tmdate, 1); fclose(htmlout); return 0; } int generateHTMLMainIndex(struct configTag *configtag) { char indexfile[PATH_MAX],smartfile[PATH_MAX],buffer[PATH_MAX],smartpyfile[PATH_MAX]; FILE *fout,*fsmart,*fsmartpy; int i; if (!configtag->configdefaults->html_basedir) { return 2; } strncpy(indexfile, configtag->configdefaults->html_basedir, PATH_MAX); strncat(indexfile, "_index.inc", PATH_MAX); if ((fout = fopen(indexfile, "w")) == NULL) { perror(indexfile); return 1; } /* create Smart Package Manager channel files */ snprintf(smartfile,PATH_MAX,"%s%s.smart", configtag->configdefaults->html_basedir, configtag->configdefaults->distribution_name); snprintf(smartpyfile,PATH_MAX,"%s%s.smart.py", configtag->configdefaults->html_basedir, configtag->configdefaults->distribution_name); if ((fsmart = fopen(smartfile, "w")) == NULL) { perror(smartfile); return 1; } if ((fsmartpy = fopen(smartpyfile, "w")) == NULL) { perror(smartpyfile); return 1; } fprintf(fout,"Available repositories:

\n"); while (configtag) { fprintf(fout, "%s: %s
", configtag->configdefaults->url_prefix, configtag->tag, configtag->tag, configtag->description); /* remove final slashes from download_prefix as required by apt */ strncpy(buffer, configtag->download_dir, PATH_MAX); i=strlen(buffer); while ((i > 0) && (buffer[i-1] == '/' )) { buffer[i-1]='\0'; i--; } fprintf(fsmart, "#\n# %s %s channel configuration for Smart Package Manager\n#\n\n", configtag->configdefaults->distribution_name, configtag->tag); fprintf(fsmart, "[%s]\ntype = apt-rpm\n", configtag->tag); fprintf(fsmart, "name = %s\n", configtag->description); fprintf(fsmart, "disabled = yes\n"); fprintf(fsmart, "baseurl = http://%s%s\n", configtag->configdefaults->url_address, buffer); fprintf(fsmart, "components = %s\n\n", configtag->arch[0]); fprintf(fsmartpy, "#\n# %s %s channel configuration for Smart Package Manager\n#\n\n", configtag->configdefaults->distribution_name, configtag->tag); fprintf(fsmartpy, "if not sysconf.get((\"channels\", \"%s\")):\n", configtag->tag); fprintf(fsmartpy, "\tsysconf.set((\"channels\", \"%s\"),\n", configtag->tag); fprintf(fsmartpy, "\t\t\t{\"alias\": \"%s\",\n", configtag->tag); fprintf(fsmartpy, "\t\t\t\"type\": \"apt-rpm\",\n"); fprintf(fsmartpy, "\t\t\t\"name\": \"%s\",\n", configtag->description); fprintf(fsmartpy, "\t\t\t\"disabled\": \"yes\",\n"); fprintf(fsmartpy, "\t\t\t\"baseurl\": \"http://%s%s\",\n", configtag->configdefaults->url_address, buffer); fprintf(fsmartpy, "\t\t\t\"components\": \"%s\"})\n\n", configtag->arch[0]); configtag = configtag->next; } fclose(fout); fclose(fsmart); fclose(fsmartpy); return 0; } int get_pkg_icon(struct headerSourceList *h,char *buf,int bufsize) { int i=0,l=0; /* expecting urls in the form http://address/... */ if (h->url) { while ((iurl[i]) { buf[i]=h->url[i]; if (buf[i] == '/') { l++; if (l == 3) break; } i++; } buf[i]='\0'; } else { /* use current site as default icon */ strcat(buf,"/"); } return 0; } int generateHTML_SRPMSFiles(struct configTag *configtag) { humanDate strdate; char indexfile[PATH_MAX]; char htmlfile[PATH_MAX]; char warningsdir[PATH_MAX]; char buffer[PATH_MAX],buffer2[1024]; int c,i,j,arch,idx; char *st; char curr_letter,curr_anchor ='a'-1; FILE *findexout[ARCHS_MAX+1], *fout; struct changeLog *currchangelog; struct headerSourceList *currheadersourcelist; struct headerList *currchild; struct stat buf; sizeString strsize; snprintf(buffer,PATH_MAX,"%spackages",configtag->html_dir); if (stat(buffer,&buf)) { if (mkdir(buffer,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { logmsg(LOG_ERROR,"cannot create %s directory; aborting.",buffer); exit(1); } } else { if (!S_ISDIR(buf.st_mode)) { logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",buffer); exit(1); } } // write an empty index.html file to avoid directory files browsing snprintf(indexfile,PATH_MAX,"%sindex.html",configtag->html_dir); if ((fout = fopen(indexfile, "w")) == NULL) { perror(indexfile); return 1; } fclose(fout); // create warnings directory snprintf(warningsdir,PATH_MAX,"%swarnings",configtag->html_dir); if (stat(warningsdir,&buf)) { if (mkdir(warningsdir,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { logmsg(LOG_ERROR,"cannot create %s directory; aborting.",warningsdir); exit(1); } } else { if (!S_ISDIR(buf.st_mode)) { logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",warningsdir); exit(1); } } /* open full SRPM index file */ snprintf(indexfile,PATH_MAX,"%s_index.inc",configtag->html_dir); if ((findexout[0] = fopen(indexfile, "w")) == NULL) { perror(indexfile); return 1; } /* open arch specific SRPM index files */ for (arch = 0; arch < ARCHS_MAX; arch++) { if (configtag->arch[arch]) { snprintf(indexfile,PATH_MAX,"%s_index-%s.inc",configtag->html_dir,configtag->arch[arch]); if ((findexout[arch+1] = fopen(indexfile, "w")) == NULL) { perror(indexfile); return 1; } } else { findexout[arch+1] = NULL; } } for (arch = 0; arch < ARCHS_MAX + 1 && findexout[arch]; arch++) { fprintf(findexout[arch], "

%s - %s

\n", configtag->tag, configtag->description); if (configtag->repository_level > 0) { fprintf(findexout[arch],"

Depends on:

"); for (c=0; c < configtag->repository_level; c++) { fprintf(findexout[arch],"%s - %s
", configtag->configdefaults->url_prefix, configtag->repository[c]->tag, configtag->repository[c]->tag, configtag->repository[c]->description); } fprintf(findexout[arch],"\n"); } fprintf(findexout[arch], "

List of packages:

\n[ "); // SourceReleaseBuilds\n"); for (c='a'; c <= 'z'; c++) { fprintf(findexout[arch],"%c  ",c,c); } fprintf(findexout[arch]," ]

\n"); } currheadersourcelist = configtag->headersourcelist; while (currheadersourcelist) { if ((configtag->repository_level == 0) || (currheadersourcelist->altrepository == configtag->repository_level)) { curr_letter=currheadersourcelist->name[0]; if (curr_letter >= 'A' && curr_letter <= 'Z') curr_letter=curr_letter+'a'-'A'; snprintf(htmlfile,PATH_MAX,"%spackages/%s.source.inc",configtag->html_dir,currheadersourcelist->name); if ((fout = fopen(htmlfile, "w")) == NULL) { perror(htmlfile); return 1; } get_pkg_icon(currheadersourcelist,buffer2,1024); fprintf(fout, "

" " %s: %s (source)

\n", buffer2, currheadersourcelist->name, htmlclean(currheadersourcelist->summary,buffer,PATH_MAX)); fprintf(fout,"

"); printHTMLWarnings(fout,configtag,currheadersourcelist,1); fprintf(fout, "

\n", currheadersourcelist->name); if (currheadersourcelist->epoch > 0) { fprintf(fout, "\n", currheadersourcelist->epoch, currheadersourcelist->version, currheadersourcelist->release); } else { fprintf(fout, "\n", currheadersourcelist->version, currheadersourcelist->release); } /* fprintf(fout, "\n", htmlclean(currheadersourcelist->summary,buffer,PATH_MAX));*/ fprintf(fout, "\n", configtag->configdefaults->url_prefix, configtag->tag, groupdirname(currheadersourcelist->group,buffer2,1024), htmlclean(currheadersourcelist->group,buffer,PATH_MAX)); fprintf(fout, "\n", configtag->configdefaults->url_prefix, configtag->tag, currheadersourcelist->packager->name, currheadersourcelist->packager->name); // currheadersourcelist->packager->packages_count++; } else fprintf(fout, "unmaintained\n", configtag->configdefaults->url_prefix, configtag->tag); fprintf(fout, "\n", htmlclean(currheadersourcelist->description,buffer,PATH_MAX)); fprintf(fout, "\n", currheadersourcelist->license); fprintf(fout, "\n", humanSize(currheadersourcelist->size, &strsize)); if (configtag->download_prefix) { fprintf(fout,"\n"); } if (currheadersourcelist->url) fprintf(fout, "\n", currheadersourcelist->url, currheadersourcelist->url); fprintf(fout, "\n"); } if (currheadersourcelist->patch) { fprintf(fout,"\n"); } fprintf(fout, "\n", *simpleTimeToHuman(currheadersourcelist->buildtime, & strdate)); for (idx = 0; idx < ARCHS_MAX + 1; idx++) { if ((idx > 0) && ((!configtag->arch[idx-1]) || (!currheadersourcelist->firstchild[idx-1]))) continue; if (curr_anchor < curr_letter) { fprintf(findexout[idx],""); } fprintf(findexout[idx],"\n"); for (idx = 0; idx < ARCHS_MAX + 1 && findexout[idx]; idx++) { if ((idx > 0) && ((!configtag->arch[idx-1]) || (!currheadersourcelist->firstchild[idx-1]))) continue; fprintf(findexout[idx], "%s(source)\n", configtag->configdefaults->url_prefix, configtag->tag, currheadersourcelist->name, currheadersourcelist->name); } /* list build requirements */ fprintf(fout, "\n"); /* print changelog to fout */ fprintf(fout, "
Name:%s
Release:%ld:%s-%s
Release:%s-%s
Summary:%s
Group:%s
Maintainer:"); if (currheadersourcelist->packager && (currheadersourcelist->packager->role & PACKAGER_ROLE_MAINTAINER)) { fprintf(fout, "%s
Description:%s
License:%s
Size:%s
Download:"); fprintf(fout,"%s-%s-%s.src.rpm", configtag->download_prefix, configtag->download_dir, currheadersourcelist->name, currheadersourcelist->version, currheadersourcelist->release, currheadersourcelist->name, currheadersourcelist->version, currheadersourcelist->release); fprintf(fout,"
URL:%s
Specfile:%s.spec", configtag->showfile_prefix, configtag->download_dir, currheadersourcelist->name, currheadersourcelist->name); if (currheadersourcelist->source) { fprintf(fout,"
Sources:"); i=0; while (currheadersourcelist->source[i+1]) i++; for (; i>=0; i--) fprintf(fout,"%s ",currheadersourcelist->source[i]); fprintf(fout,"
Patches:"); i=0; while (currheadersourcelist->patch[i+1]) i++; for (; i>=0; i--) // fprintf(fout,"%s ",currheadersourcelist->patch[i]); fprintf(fout,"%s ", configtag->showfile_prefix, configtag->download_dir, currheadersourcelist->patch[i], currheadersourcelist->patch[i]); fprintf(fout,"
Build time:%s
"); while (curr_anchor < curr_letter) { curr_anchor += 1; fprintf(findexout[idx],"",curr_anchor); } fprintf(findexout[idx],"
"); printpkgicon(findexout[idx], configtag, currheadersourcelist); fprintf(findexout[idx],"%s: %s",currheadersourcelist->name,htmlclean(currheadersourcelist->summary,buffer,PATH_MAX)); st=strstr(currheadersourcelist->url,"://"); if (st) { strncpy(buffer,st+3,PATH_MAX); st=strchr(buffer,'/'); if (st) st[0]='\0'; fprintf(findexout[idx], " ", currheadersourcelist->url, configtag->configdefaults->url_dir, buffer); } fprintf(findexout[idx],"
"); if (currheadersourcelist->epoch) { fprintf(findexout[idx],"%ld:%s-%s", currheadersourcelist->epoch, currheadersourcelist->version, currheadersourcelist->release); } else { fprintf(findexout[idx], "%s-%s", currheadersourcelist->version, currheadersourcelist->release); } fprintf(findexout[idx]," - "); } fprintf(fout,"
Built RPMS:"); for (arch = 0; arch < ARCHS_MAX && configtag->arch[arch]; arch++) { /* write children to both fout and findexout */ currchild = currheadersourcelist->firstchild[arch]; c = 0; while (currchild) { for (idx = 0; idx < ARCHS_MAX + 1 && findexout[idx]; idx++) { if ((idx > 0) && ((!configtag->arch[idx-1]) || (arch != idx -1))) continue; fprintf(findexout[idx], "%s(%s) ", configtag->configdefaults->url_prefix, configtag->tag, currchild->name, configtag->arch[arch], currchild->name, configtag->arch[arch], currchild->name, configtag->configdefaults->url_dir); } fprintf(fout, "%s(%s) ", configtag->configdefaults->url_prefix, configtag->tag, currchild->name, configtag->arch[arch], currchild->name, configtag->arch[arch]); currchild = currchild->nextbrother; c++; } } fprintf(fout, "

Build requirements:"); for (i = 0; i < currheadersourcelist->requirecount; i++) { if (currheadersourcelist->require[i]->resolved) { if (currheadersourcelist->require[i]->resolved->numbuildproviders == 0) { // missing provider fprintf(fout,"%s(unresolved)",currheadersourcelist->require[i]->resolved->name); } else if (currheadersourcelist->require[i]->resolved->numbuildproviders == 1) { // single provider if ((i == 0 || strcmp(currheadersourcelist->require[i-1]->name, currheadersourcelist->require[i]->name)) && strcmp(currheadersourcelist->name, currheadersourcelist->require[i]->name)) { if ((configtag->repository_level == 0) || (currheadersourcelist->require[i]->resolved->buildprovider[0]->sourceheader && currheadersourcelist->require[i]->resolved->buildprovider[0]->altrepository == configtag->repository_level)) { fprintf(fout,"%s", configtag->configdefaults->url_prefix, configtag->tag, currheadersourcelist->require[i]->resolved->name, configtag->arch[0], currheadersourcelist->require[i]->resolved->name); if (configtag->repository_level > 0) { snprintf(buffer, PATH_MAX, "has build requirement %s which is provided in this repository", currheadersourcelist->require[i]->resolved->name); addWarning(currheadersourcelist, buffer); } } else { fprintf(fout,"%s",currheadersourcelist->require[i]->resolved->name); } } } else { // multiple providers if (i == 0 || strcmp(currheadersourcelist->require[i-1]->resolved->name, currheadersourcelist->require[i]->resolved->name)) fprintf(fout,"%s(",currheadersourcelist->require[i]->resolved->name); for (j = 0; j < currheadersourcelist->require[i]->resolved->numbuildproviders; j++) { if ((configtag->repository_level == 0) || (currheadersourcelist->require[i]->resolved->buildprovider[j]->sourceheader && currheadersourcelist->require[i]->resolved->buildprovider[j]->altrepository == configtag->repository_level)) fprintf(fout,"%s", configtag->configdefaults->url_prefix, configtag->tag, currheadersourcelist->require[i]->resolved->buildprovider[j]->name, configtag->arch[0], currheadersourcelist->require[i]->resolved->buildprovider[j]->name); else fprintf(fout,"%s",currheadersourcelist->require[i]->resolved->buildprovider[j]->name); if (j+1 < currheadersourcelist->require[i]->resolved->numbuildproviders) fprintf(fout,"|"); } fprintf(fout,")"); } // if numproviders if (currheadersourcelist->require[i]->flags & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL)) { fprintf(fout,"["); if (currheadersourcelist->require[i]->flags & RPMSENSE_LESS) fprintf(fout, "<"); if (currheadersourcelist->require[i]->flags & RPMSENSE_GREATER) fprintf(fout, ">"); if (currheadersourcelist->require[i]->flags & RPMSENSE_EQUAL) fprintf(fout, "="); fprintf(fout, "%s", currheadersourcelist->require[i]->version); fprintf(fout,"]"); } fprintf(fout," "); } // if required } // for fprintf(fout, "
Changelog:"); currchangelog = currheadersourcelist->changelog; while (currchangelog) { // changelog_total++; simpleTimeToHuman(currchangelog->time, (humanDate *) & strdate); if (currchangelog->pkg) { if ((currchangelog->pkg->role & PACKAGER_ROLE_MAINTAINER) && (currchangelog->pkg->packages_count)) { fprintf(fout, "%s - %s (%s)
%s
", &strdate[0], configtag->configdefaults->url_prefix, configtag->tag, currchangelog->pkg->name, currchangelog->pkg->name, currchangelog->release, htmlclean(currchangelog->text,buffer,PATH_MAX)); // currchangelog->pkg->changes_count++; } else { fprintf(fout, "%s - %s (%s)
%s
", &strdate[0], currchangelog->pkg->name, currchangelog->release, htmlclean(currchangelog->text,buffer,PATH_MAX)); // currchangelog->pkg->changes_count++; } } else fprintf(fout, "%s - (noname) (%s)
%s
", &strdate[0], currchangelog->release, htmlclean(currchangelog->text,buffer,PATH_MAX)); currchangelog = currchangelog->next; } /* close fout */ fprintf(fout, "
"); fclose(fout); } currheadersourcelist = currheadersourcelist->next; } for (idx = 0; idx < ARCHS_MAX + 1 && findexout[idx]; idx++) { fprintf(findexout[idx], "\n"); fclose(findexout[idx]); } return 0; } static int htmlincselector(const struct dirent *entry) { char *ptr; ptr = strstr(entry->d_name, ".inc"); if (entry->d_type != DT_REG) return 0; /* skip if not a file */ if (ptr == NULL) { return 0; } return 1; } int cleanHTMLFilesInc(char* dir) { int n,cnt,r; struct dirent **namelist; const char* errstr; char uf[PATH_MAX]; n = scansdir(dir, &namelist, htmlincselector, NULL); if (n < 0) { errstr = strerror(errno); logmsg(LOG_ERROR, "cannot scan directory '%s' (%s)", dir, errstr); return 1; } for (cnt = 0; cnt < n; ++cnt) { snprintf(uf,PATH_MAX,"%s/%s",dir,namelist[cnt]->d_name); logmsg(LOG_DEBUG,"unlinking %s",uf); r=unlink(uf); if (r < 0) { errstr = strerror(errno); logmsg(LOG_WARNING, "cannot remove file '%s' (%s)", uf, errstr); } } return 0; } int cleanHTMLPackagesFiles(struct configTag *ct) { char dir[PATH_MAX]; snprintf(dir,PATH_MAX,"%spackages",ct->html_dir); if (cleanHTMLFilesInc(dir)) { logmsg(LOG_WARNING,"cannot clean %s directory",dir); } return 0; } int cleanHTMLFiles(struct configTag *ct) { int s; char uf[PATH_MAX],dir[PATH_MAX]; const char* clean_subdir[] = { "", "maintainers" }; struct headerSourceList *currheadersourcelist; struct stat buf; for (s = 0; s < 2; s++) { snprintf(dir,PATH_MAX,"%s%s",ct->html_dir,clean_subdir[s]); if (cleanHTMLFilesInc(dir)) { logmsg(LOG_WARNING,"cannot clean %s directory",dir); } } currheadersourcelist = ct->headersourcelist; while (currheadersourcelist) { snprintf(dir, PATH_MAX, "%sgroups/%s", ct->html_dir, groupdirname(currheadersourcelist->group,uf,PATH_MAX)); if (!stat(dir,&buf)) { logmsg(LOG_DEBUG,"removing directory %s",dir); if (cleanHTMLFilesInc(dir)) { logmsg(LOG_ERROR,"cannot clean %s directory; aborting",dir); exit(1); } if (rmdir(dir)) { logmsg(LOG_ERROR,"cannot remove %s directory; aborting.",dir); exit(1); } } /* legacy: clean old group dirs */ snprintf(dir, PATH_MAX, "%s%s", ct->html_dir, groupdirname(currheadersourcelist->group,uf,PATH_MAX)); if (!stat(dir,&buf)) { logmsg(LOG_DEBUG,"removing legacy directory %s",dir); if (cleanHTMLFilesInc(dir)) { logmsg(LOG_ERROR,"cannot clean %s directory; aborting.",dir); exit(1); } if (rmdir(dir)) { logmsg(LOG_ERROR,"cannot remove %s directory; aborting.",dir); exit(1); } } currheadersourcelist = currheadersourcelist->next; } return 0; } int generateHTMLFiles(struct configTag *ct, int arch) { char buffer[PATH_MAX]; char htmlfile[PATH_MAX]; int i,j; sizeString strsize; FILE *fout; struct headerList *currheaderlist, *auxheaderlist; struct headerSourceList *auxheadersourcelist; int found; struct stat buf; snprintf(buffer,PATH_MAX,"%spackages",ct->html_dir); if (stat(buffer,&buf)) { if (mkdir(buffer,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { logmsg(LOG_ERROR,"cannot create %s directory; aborting.",buffer); exit(1); } } else { if (!S_ISDIR(buf.st_mode)) { logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",buffer); exit(1); } } currheaderlist = ct->headerlist[arch]; while (currheaderlist) { if ((ct->repository_level == 0) || ((currheaderlist->sourceheader) && (currheaderlist->altrepository == ct->repository_level))) { logmsg(LOG_DEBUG,"generating HTML pages for %s",currheaderlist->name); snprintf(htmlfile,PATH_MAX,"%spackages/%s.%s.inc",ct->html_dir,currheaderlist->name,ct->arch[arch]); if ((fout = fopen(htmlfile, "w")) == NULL) { perror(htmlfile); return 1; } get_pkg_icon(currheaderlist->sourceheader,buffer,1024); fprintf(fout, "

" " %s: %s

", buffer, currheaderlist->name, currheaderlist->summary); fprintf(fout, "\n", currheaderlist->name); fprintf(fout, "\n", currheaderlist->version, currheaderlist->release); fprintf(fout, "\n", currheaderlist->arch); /* fprintf(fout, "\n", htmlclean(currheaderlist->summary,buffer,PATH_MAX));*/ fprintf(fout, "\n", htmlclean(currheaderlist->group,buffer,PATH_MAX)); fprintf(fout, "\n", htmlclean(currheaderlist->description,buffer,PATH_MAX)); fprintf(fout, "\n", humanSize(currheaderlist->size, &strsize)); /* fprintf(fout, "\n", currheaderlist->arch);*/ if (ct->download_prefix) { fprintf(fout,"\n"); } if (currheaderlist->sourcename && currheaderlist->sourceheader) { fprintf(fout, "\n", ct->configdefaults->url_prefix, ct->tag, currheaderlist->sourceheader->name, currheaderlist->sourcename); } /* list obsoletes */ if (currheaderlist->obsoletecount > 0) { fprintf(fout, "\n"); } /* list provides */ fprintf(fout, "\n"); /* list requires */ fprintf(fout, "\n"); /* list RPM requirements */ fprintf(fout, "\n"); /* list required by */ fprintf(fout, "\n"); /* list build required by */ fprintf(fout, "\n"); /* list filenames */ fprintf(fout, "
Name:%s
Release:%s-%s
Architecture:%s
Summary:%s
Group:%s
Description:%s
Size:%s
Arch:%s
Download:"); fprintf(fout,"%s-%s-%s.%s.rpm", ct->download_prefix, ct->download_dir, ct->arch[arch], currheaderlist->name, currheaderlist->version, currheaderlist->release, currheaderlist->arch, currheaderlist->name, currheaderlist->version, currheaderlist->release, currheaderlist->arch); fprintf(fout,"
Source RPM:%s
Obsoletes:"); for (i = 0; i < currheaderlist->obsoletecount; i++) { fprintf(fout, "%s", currheaderlist->obsoletename[i]); if (currheaderlist->obsoleteflags[i] & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL)) { fprintf(fout, "["); if (currheaderlist->obsoleteflags[i] & RPMSENSE_LESS) fprintf(fout, "<"); if (currheaderlist->obsoleteflags[i] & RPMSENSE_GREATER) fprintf(fout, ">"); if (currheaderlist->obsoleteflags[i] & RPMSENSE_EQUAL) fprintf(fout, "="); fprintf(fout, "%s]", currheaderlist->obsoleteversion[i]); } fprintf(fout," "); } fprintf(fout, "
Provides:"); for (i = 0; i < currheaderlist->providecount; i++) { fprintf(fout, "%s", currheaderlist->providename[i]); if (currheaderlist->provideflags[i] & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL)) { fprintf(fout, "["); if (currheaderlist->provideflags[i] & RPMSENSE_LESS) fprintf(fout, "<"); if (currheaderlist->provideflags[i] & RPMSENSE_GREATER) fprintf(fout, ">"); if (currheaderlist->provideflags[i] & RPMSENSE_EQUAL) fprintf(fout, "="); fprintf(fout, "%s]", currheaderlist->provideversion[i]); } fprintf(fout," "); } fprintf(fout, "
Requires:"); for (i = 0; i < currheaderlist->requirecount; i++) { if (currheaderlist->require[i]->resolved) { if (currheaderlist->require[i]->resolved->numproviders == 0) { // no provider fprintf(fout,"%s",currheaderlist->require[i]->resolved->name); } else if (currheaderlist->require[i]->resolved->numproviders == 1) { // single provider if ((ct->repository_level == 0) || (currheaderlist->require[i]->resolved->provider[0]->sourceheader && currheaderlist->require[i]->resolved->provider[0]->altrepository == ct->repository_level)) { fprintf(fout,"%s", ct->configdefaults->url_prefix, ct->tag, currheaderlist->require[i]->resolved->provider[0]->name, ct->arch[arch], currheaderlist->require[i]->resolved->name); } else { fprintf(fout,"%s",currheaderlist->require[i]->resolved->name); } } else { // multiple providers logmsg(LOG_DEBUG,"Requirement %s has multiple providers",currheaderlist->require[i]->resolved->name); fprintf(fout,"%s(",currheaderlist->require[i]->resolved->name); for (j = 0; j < currheaderlist->require[i]->resolved->numproviders; j++) { if ((ct->repository_level == 0) || (currheaderlist->require[i]->resolved->provider[j]->sourceheader && currheaderlist->require[i]->resolved->provider[j]->altrepository == ct->repository_level)) fprintf(fout,"%s", ct->configdefaults->url_prefix, ct->tag, currheaderlist->require[i]->resolved->provider[j]->name, ct->arch[arch], currheaderlist->require[i]->resolved->provider[j]->name); else fprintf(fout,"%s",currheaderlist->require[i]->resolved->provider[j]->name); if (j+1 < currheaderlist->require[i]->resolved->numproviders) fprintf(fout,"|"); } fprintf(fout,")"); } // if numproviders if (currheaderlist->require[i]->flags & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL)) { fprintf(fout,"["); if (currheaderlist->require[i]->flags & RPMSENSE_LESS) fprintf(fout, "<"); if (currheaderlist->require[i]->flags & RPMSENSE_GREATER) fprintf(fout, ">"); if (currheaderlist->require[i]->flags & RPMSENSE_EQUAL) fprintf(fout, "="); fprintf(fout, "%s", currheaderlist->require[i]->version); fprintf(fout,"]"); } fprintf(fout," "); } // if required } // for fprintf(fout, "
RPM requirements:"); for (i = 0; i < currheaderlist->requirecount; i++) { if (currheaderlist->require[i]->resolved) { if (currheaderlist->require[i]->resolved->numproviders == 0) { // missing provider fprintf(fout,"%s(unresolved) ",currheaderlist->require[i]->resolved->name); } else if (currheaderlist->require[i]->resolved->numproviders == 1) { // single provider if ((i == 0 || !currheaderlist->require[i-1]->resolved || !currheaderlist->require[i-1]->resolved->numproviders || strcmp(currheaderlist->require[i-1]->resolved->provider[0]->name, currheaderlist->require[i]->resolved->provider[0]->name)) && strcmp(currheaderlist->name, currheaderlist->require[i]->resolved->provider[0]->name)) { if ((ct->repository_level == 0) || (currheaderlist->require[i]->resolved->provider[0]->sourceheader && currheaderlist->require[i]->resolved->provider[0]->altrepository == ct->repository_level)) { fprintf(fout,"%s ", ct->configdefaults->url_prefix, ct->tag, currheaderlist->require[i]->resolved->provider[0]->name, ct->arch[arch], currheaderlist->require[i]->resolved->provider[0]->name); if ((ct->repository_level > 0) && (currheaderlist->sourceheader != currheaderlist->require[i]->resolved->provider[0]->sourceheader)) { snprintf(buffer, PATH_MAX, "%s(%s,%s) requires %s(%s,%s) which is in this repository", currheaderlist->name, ct->arch[arch], ct->repository[currheaderlist->altrepository]->tag, currheaderlist->require[i]->resolved->provider[0]->name, ct->arch[arch], ct->repository[currheaderlist->require[i]->resolved->provider[0]->altrepository]->tag); addWarning(currheaderlist->sourceheader, buffer); } } else fprintf(fout,"%s ",currheaderlist->require[i]->resolved->provider[0]->name); } } else { // multiple providers if (i == 0 || !currheaderlist->require[i-1]->resolved || !currheaderlist->require[i-1]->resolved->numproviders || strcmp(currheaderlist->require[i-1]->resolved->name, currheaderlist->require[i]->resolved->name)) { fprintf(fout,"%s(",currheaderlist->require[i]->resolved->name); for (j = 0; j < currheaderlist->require[i]->resolved->numproviders; j++) { if ((ct->repository_level == 0) || (currheaderlist->require[i]->resolved->provider[j]->sourceheader && currheaderlist->require[i]->resolved->provider[j]->altrepository == ct->repository_level)) fprintf(fout,"%s", ct->configdefaults->url_prefix, ct->tag, currheaderlist->require[i]->resolved->provider[j]->name, ct->arch[arch], currheaderlist->require[i]->resolved->provider[j]->name); else fprintf(fout,"%s",currheaderlist->require[i]->resolved->provider[j]->name); if (j+1 < currheaderlist->require[i]->resolved->numproviders) fprintf(fout,"|"); } fprintf(fout,") "); } } // if numproviders } // if required } // for fprintf(fout, "
Required by:"); auxheaderlist = ct->headerlist[arch]; while (auxheaderlist) { if (auxheaderlist != currheaderlist) for (i = 0; i < auxheaderlist->requirecount; i++) { if (auxheaderlist->require[i]->resolved && (auxheaderlist->require[i]->resolved->numproviders == 1) && !strcmp(auxheaderlist->require[i]->resolved->provider[0]->name, currheaderlist->name)) { if ((ct->repository_level == 0) || auxheaderlist->altrepository == ct->repository_level) { fprintf(fout, "%s(%s) ", ct->configdefaults->url_prefix, ct->tag, auxheaderlist->name, ct->arch[arch], auxheaderlist->name, ct->arch[arch]); } else { fprintf(fout,"%s\n",auxheaderlist->name); } break; } } auxheaderlist = auxheaderlist->next; } fprintf(fout, "
Build required by:"); auxheadersourcelist = ct->headersourcelist; while (auxheadersourcelist) { found=0; if (auxheadersourcelist != currheaderlist->sourceheader) { for (i = 0; i < auxheadersourcelist->requirecount; i++) { if (auxheadersourcelist->require[i]->resolved) { for (j = 0; j < auxheadersourcelist->require[i]->resolved->numbuildproviders; j++) { if (!strcmp(auxheadersourcelist->require[i]->resolved->buildprovider[j]->name, currheaderlist->name)) { if ((ct->repository_level == 0) || auxheadersourcelist->altrepository == ct->repository_level) { fprintf(fout, "%s ", ct->configdefaults->url_prefix, ct->tag, auxheadersourcelist->name, auxheadersourcelist->name); } else { fprintf(fout, "%s ", auxheadersourcelist->name); } found=1; } } } if (found) break; } } auxheadersourcelist = auxheadersourcelist->next; } fprintf(fout, "
Filenames:"); for (i = 0; i < currheaderlist->filenamecount; i++) { ftname((currheaderlist->file)[i], buffer, PATH_MAX); fprintf(fout, "/%s ",buffer); } fprintf(fout, "
\n"); fclose(fout); } currheaderlist = currheaderlist->next; } return 0; } char *ftname(struct fileTree* ft, char* buf, unsigned int bufsize) { buf[0]='\0'; int l; if (ft) { strncpy(buf,ft->name,bufsize); ft=ft->parent; } while (ft) { l=strlen(ft->name); if (strlen(buf)+l+1 <= bufsize) { memmove(buf+l+1,buf,strlen(buf)+1); memcpy(buf,ft->name,l); buf[l]='/'; } else break; ft=ft->parent; } return buf; } void print_contents_subtree(FILE *f, struct fileTree* ft, struct configTag* ct, char* buf, int bufsize) { int i,j,k; while (ft) { if (ft->firstchild) { print_contents_subtree(f,ft->firstchild,ct,buf,bufsize); } else { for (k = 0; k < ft->numproviders; k++) { if ((ct->repository_level == 0) || ((ft->provider[k]) && (ft->provider[k]->sourceheader) && (ft->provider[k]->altrepository == ct->repository_level))) { ftname(ft,buf,bufsize); if ((j=strlen(buf)) < 60) { for (i=(60-j)/8; i>0; i--) strncat(buf,"\t",1024); while (strlen(buf) < 60) strncat(buf," ",1024); } fprintf(f, "%s %s/%s\n",buf,ct->tag,ft->provider[0]->name); } } } ft=ft->next; } } int print_datatables(struct configTag *ct, int arch) { FILE *fbd,*fd,*fv,*fb,*fbsh,*fs,*fc; char builddeps_filename[1024], deps_filename[1024], virtual_filename[1024], builds_filename[1024], builds_sh_filename[1024], sources_filename[1024], contents_filename[1024], buf[1024]; char obsoletebuf[1024]; struct headerList *currheaderlist, *currchild; struct headerSourceList * currheadersourcelist; int i, depscnt, nonobsoletednumproviders; snprintf(builddeps_filename,1024,"%sbuilddeps-%s",ct->html_dir,ct->arch[arch]); snprintf(deps_filename,1024,"%sdeps-%s",ct->html_dir,ct->arch[arch]); snprintf(virtual_filename,1024,"%svirtual-%s",ct->html_dir,ct->arch[arch]); snprintf(builds_filename,1024,"%sbuilds-%s",ct->html_dir,ct->arch[arch]); snprintf(builds_sh_filename,1024,"%sbuilds-%s.sh",ct->html_dir,ct->arch[arch]); snprintf(sources_filename,1024,"%ssources-%s",ct->html_dir,ct->arch[arch]); snprintf(contents_filename,1024,"%scontentslist-%s",ct->repository_dir,ct->arch[arch]); fbd=fopen(builddeps_filename,"w"); if (!fbd) { fprintf(stderr, "Error: can't open file for writing: %s. Aborting.\n", builddeps_filename); return 1; } fd=fopen(deps_filename,"w"); if (!fd) { fprintf(stderr, "Error: can't open file for writing: %s. Aborting.\n", deps_filename); return 1; } fv=fopen(virtual_filename,"w"); if (!fv) { fprintf(stderr, "Error: can't open file for writing: %s. Aborting.\n", virtual_filename); return 1; } fb=fopen(builds_filename,"w"); if (!fb) { fprintf(stderr, "Error: can't open file for writing: %s. Aborting.\n", builds_filename); return 1; } fbsh=fopen(builds_sh_filename,"w"); if (!fbsh) { fprintf(stderr, "Error: can't open file for writing: %s. Aborting.\n", builds_filename); return 1; } fs=fopen(sources_filename,"w"); if (!fs) { fprintf(stderr, "Error: can't open file for writing: %s. Aborting.\n", sources_filename); return 1; } fc=fopen(contents_filename,"w"); if (!fc) { fprintf(stderr, "Error: can't open file for writing: %s. Aborting.\n", contents_filename); return 1; } // // headerlist scan: write top of deps and sources files // fprintf(fd,"ALL_PACKAGES = "); fprintf(fb,"ALL_BUILDS="); currheaderlist = ct->headerlist[arch]; while (currheaderlist) { fprintf(fs,"%s: _%s\n", currheaderlist->name, currheaderlist->sourceheader->name); if (!currheaderlist->obsoleted) { fprintf(fd,"%s ", currheaderlist->name); fprintf(fb,"%s ",currheaderlist->name); } currheaderlist = currheaderlist->next; } fprintf(fd,"\n"); // // source headerlist scan: write top of deps and sources files // fprintf(fbd,"ALL_SOURCES = "); fprintf(fs,"ALL_SOURCES = "); currheadersourcelist = ct->headersourcelist; while (currheadersourcelist) { if (currheadersourcelist->firstchild[arch]) { fprintf(fbd,"%s ", currheadersourcelist->name); fprintf(fs,"_%s ", currheadersourcelist->name); } currheadersourcelist = currheadersourcelist->next; } fprintf(fbd,"\n"); fprintf(fs,"\n"); fprintf(fb,"\n"); // write deps file struct providedList* provided = ct->providedlist_idx[arch][0]; while (provided) { nonobsoletednumproviders=0; for (i = 0; i < provided->numproviders; i++) { if (!provided->provider[i]->obsoleted) nonobsoletednumproviders++; } if (nonobsoletednumproviders > 1) { fprintf(fd,"ifndef "); fprintf_depstable_filtered_var(fd,provided->name); fprintf(fd,"\n"); fprintf_depstable_filtered_var(fd,provided->name); fprintf(fd," := "); fprintf_depstable_filtered_var(fd,provided->name); fprintf(fd,"_to_be_defined # "); fprintf_depstable_filtered_var(fs,provided->name); fprintf(fs,":"); for (i = 0; i < provided->numproviders; i++) { if (!provided->provider[i]->obsoleted) { fprintf(fd,"%s ",provided->provider[i]->name); fprintf(fs," _%s",provided->provider[i]->sourceheader->name); } } fprintf(fs,"\n"); fprintf(fd,"\nendif\n"); fprintf_depstable_filtered_var(fd,provided->name); fprintf(fd,": "); fprintf(fd,"$("); fprintf_depstable_filtered_var(fd,provided->name); fprintf(fd,")\n"); fprintf(fv,"%s= # ",provided->name); for (i = 0; i < provided->numproviders; i++) { if (!provided->provider[i]->obsoleted) { fprintf(fv,"%s ",provided->provider[i]->name); } } fprintf(fv,"\n"); } else if (nonobsoletednumproviders == 1) { for (i = 0; i < provided->numproviders; i++) { if (!provided->provider[i]->obsoleted) break; } if (strcmp(provided->name,provided->provider[i]->name)) { fprintf_depstable_filtered_var(fd,provided->name); fprintf(fd,": "); fprintf(fd,"%s\n",provided->provider[i]->name); fprintf_depstable_filtered_var(fs,provided->name); fprintf(fs,": _%s\n",provided->provider[i]->sourceheader->name); } } else { fprintf_depstable_filtered_var(fd,provided->name); fprintf(fd,": "); fprintf(fd,"__missing_provider_for_"); fprintf_depstable_filtered_var(fd,provided->name); fprintf(fd,"\n"); } provided = provided->next; } //write contents (filenames) print_contents_subtree(fc,ct->filetree[arch],ct,buf,1024); currheaderlist = ct->headerlist[arch]; while (currheaderlist) { fprintf(fd,"%s: ", currheaderlist->name); for (i = 0; i < currheaderlist->requirecount; i++) { if (currheaderlist->require[i]->resolved) { if (currheaderlist->require[i]->resolved->numproviders == 0) { fprintf_depstable_filtered_var(fd,currheaderlist->require[i]->resolved->name); fprintf(fd,"_unresolved_ "); } else if (currheaderlist->require[i]->resolved->numproviders == 1) { if ((i == 0 || !currheaderlist->require[i-1]->resolved || !currheaderlist->require[i-1]->resolved->numproviders || strcmp(currheaderlist->require[i-1]->resolved->provider[0]->name, currheaderlist->require[i]->resolved->provider[0]->name)) && strcmp(currheaderlist->name, currheaderlist->require[i]->resolved->provider[0]->name)) fprintf(fd,"%s ",currheaderlist->require[i]->resolved->provider[0]->name); } else { if (i == 0 || !currheaderlist->require[i-1]->resolved || !currheaderlist->require[i-1]->resolved->numproviders || strcmp(currheaderlist->require[i-1]->resolved->name, currheaderlist->require[i]->resolved->name)) { fprintf_depstable_filtered_var(fd,currheaderlist->require[i]->resolved->name); fprintf(fd," "); } } } } fprintf(fd,"\n"); // // write builddeps file // fprintf(fbd,"%s:",currheaderlist->name); for (i = 0; i < currheaderlist->sourceheader->requirecount; i++) { if (strncmp("rpmlib(",currheaderlist->sourceheader->require[i]->name,7) != 0) { fprintf(fbd," "); fprintf_depstable_filtered_var(fbd,currheaderlist->sourceheader->require[i]->name); } } fprintf(fbd,"\n"); /* for (i = 0; i < currheaderlist->obsoletecount; i++) { fprintf(fbd,"%s: %s\n",currheaderlist->obsoletename[i],currheaderlist->name); }*/ for (i = 0; i < currheaderlist->providecount; i++) { if (strncmp(currheaderlist->provided[i]->name,currheaderlist->name,PATH_MAX) != 0) { fprintf_depstable_filtered_var(fbd,currheaderlist->provided[i]->name); fprintf(fbd,": %s\n",currheaderlist->name); } } currheaderlist = currheaderlist->next; } // // headersourcelist scan: write builds and sources files // fprintf(fbsh,"pkg_list=("); currheadersourcelist = ct->headersourcelist; while (currheadersourcelist != NULL) { if (((ct->repository_level == 0) || (currheadersourcelist->altrepository == ct->repository_level)) && (currheadersourcelist->firstchild[arch])) { fprintf(fbsh,"%s ",currheadersourcelist->name); } currheadersourcelist = currheadersourcelist->next; } fprintf(fbsh,");\n"); depscnt = 0; currheadersourcelist = ct->headersourcelist; while (currheadersourcelist != NULL) { currchild = currheadersourcelist->firstchild[arch]; if (currchild) { if (!strncmp(currheadersourcelist->arch,"noarch",1024)) snprintf(obsoletebuf,1024,"noarch"); else snprintf(obsoletebuf,1024,"%s",ct->arch[arch]); fprintf(fbsh,"[ \"$pkg\" = \"%s\" ] && { pkg_header=(%s %s %s %s \"%s\" \"%s\" %ld %ld %d %s); ", currheadersourcelist->name, currheadersourcelist->name, obsoletebuf, currheadersourcelist->version, currheadersourcelist->release, currheadersourcelist->group, currheadersourcelist->license, currheadersourcelist->size, currheadersourcelist->buildtime, currheadersourcelist->altrepository, ct->repository[currheadersourcelist->altrepository]->tag); fprintf(fb,"%s:", currheadersourcelist->name); fprintf(fbsh,"pkg_builds=("); obsoletebuf[0] = '\0'; while (currchild) { fprintf(fbsh,"%s",currchild->name); fprintf(fb," %s",currchild->name); for (i = 0; i < currchild->obsoletecount; i++ ) { if (obsoletebuf[0] != '\0') strncat(obsoletebuf," ",1024); strncat(obsoletebuf,currchild->obsoletename[i],1024); } currchild = currchild->nextbrother; if (currchild) fprintf(fbsh," "); } fprintf(fbsh,"); pkg_obsoletes=(%s); }\n",obsoletebuf); fprintf(fb,"\n"); } currheadersourcelist = currheadersourcelist->next; } fclose(fd); fclose(fv); fclose(fbsh); fclose(fb); fclose(fs); fclose(fc); return 0; } int generateSrcPkgList(struct configTag *ct) { FILE *fd; char fn[PATH_MAX]; struct headerSourceList *currheadersourcelist; humanDate strdate; int i; snprintf(fn, PATH_MAX, "%ssrcpkglist",ct->repository_dir); fd=fopen(fn,"w"); if (!fd) { fprintf(stderr, "Error: can't open file for writing: %s\n", fn); return 1; } currheadersourcelist = ct->headersourcelist; while (currheadersourcelist != NULL) { fprintf(fd, "%s %s %s %s %ld %s ", currheadersourcelist->name, currheadersourcelist->version, (char *)simpleTimeToTemplate(currheadersourcelist->buildtime,"%Y%m%d",&strdate), ct->repository[currheadersourcelist->altrepository]->tag, currheadersourcelist->epoch, currheadersourcelist->release); if (currheadersourcelist->source) { i=0; while (currheadersourcelist->source[i+1]) i++; for (; i>=0; i--) fprintf(fd, "%s ",currheadersourcelist->source[i]); } fprintf(fd, "\n"); currheadersourcelist = currheadersourcelist->next; } fclose(fd); return 0; } int generatePkgList(struct configTag *ct, int arch) { FILE *fd; char fn[PATH_MAX]; struct headerList *currheaderlist; snprintf(fn, PATH_MAX, "%spkglist.%s",ct->repository_dir,ct->arch[arch]); fd=fopen(fn,"w"); if (!fd) { fprintf(stderr, "Error: can't open file for writing: %s\n", fn); return 1; } /* currheaderlist = headerlist; */ currheaderlist = ct->headerlist[arch]; while (currheaderlist != NULL) { fprintf(fd, "%s %s %ld %d %s %ld %s\n", currheaderlist->name, currheaderlist->version, currheaderlist->size, currheaderlist->filenamecount, ct->repository[currheaderlist->altrepository]->tag, currheaderlist->epoch, currheaderlist->release); currheaderlist = currheaderlist->next; } fclose(fd); return 0; }