"Fossies" - the Fresh Open Source Software Archive

Member "rpm2html-1.11.2/html.c" (9 Nov 2010, 144498 Bytes) of package /linux/privat/rpm2html-1.11.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "html.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * html.c: code concerning the dump as an HTML base.
    3  *
    4  * See Copyright for the status of this software.
    5  *
    6  * $Id: html.c,v 1.127 2010/11/09 22:16:29 hany Exp $
    7  */
    8 
    9 #include <config.h>
   10 #include <sys/types.h>
   11 #include <sys/stat.h>
   12 #ifdef HAVE_FCNTL_H
   13 #include <fcntl.h>
   14 #endif
   15 #include <stdio.h>
   16 #include <stdlib.h>
   17 #include <string.h>
   18 #ifdef HAVE_UNISTD_H
   19 #include <unistd.h>
   20 #endif
   21 #include <time.h>
   22 #include <errno.h>
   23 #include <ctype.h>
   24 
   25 #include <rpmlib.h>
   26 
   27 #include "rpm2html.h"
   28 #include "rpmdata.h"
   29 #include "html.h"
   30 #include "language.h"
   31 
   32 #ifdef HAVE_LIBTEMPLATE
   33 #include "template.h"
   34 #endif
   35 
   36 #ifndef HAVE_SNPRINTF
   37 #error You really need snprintf ...
   38 #endif
   39 
   40 /*
   41  * Global variables concerning the dump environment
   42  */
   43 
   44 static char buf[500];
   45 
   46 /*
   47  * The entities list for the extended ASCII charset.
   48  */
   49 static char *html_flags[] = {
   50     "",
   51     "&lt;",
   52     "&lt;=",
   53     "&gt;",
   54     "&gt;=",
   55     "="
   56 };
   57 
   58 /*
   59  * The entities list for the extended ASCII charset.
   60  */
   61 static char *entities[256] = {
   62 NULL,       /* 000 */
   63 NULL,       /* 001 */
   64 NULL,       /* 002 */
   65 NULL,       /* 003 */
   66 NULL,       /* 004 */
   67 NULL,       /* 005 */
   68 NULL,       /* 006 */
   69 NULL,       /* 007 */
   70 NULL,       /* 008 */
   71 NULL,       /* 009 */
   72 NULL,       /* 010 */
   73 NULL,       /* 011 */
   74 NULL,       /* 012 */
   75 NULL,       /* 013 */
   76 NULL,       /* 014 */
   77 NULL,       /* 015 */
   78 NULL,       /* 016 */
   79 NULL,       /* 017 */
   80 NULL,       /* 018 */
   81 NULL,       /* 019 */
   82 NULL,       /* 020 */
   83 NULL,       /* 021 */
   84 NULL,       /* 022 */
   85 NULL,       /* 023 */
   86 NULL,       /* 024 */
   87 NULL,       /* 025 */
   88 NULL,       /* 026 */
   89 NULL,       /* 027 */
   90 NULL,       /* 028 */
   91 NULL,       /* 029 */
   92 NULL,       /* 030 */
   93 NULL,       /* 031 */
   94 NULL,       /* 032 */
   95 NULL,       /* 033 */
   96 "&quot;",   /* 034 */
   97 NULL,       /* 035 */
   98 NULL,       /* 036 */
   99 NULL,       /* 037 */
  100 "&amp;",    /* 038 */
  101 NULL,       /* 039 */
  102 NULL,       /* 040 */
  103 NULL,       /* 041 */
  104 NULL,       /* 042 */
  105 NULL,       /* 043 */
  106 NULL,       /* 044 */
  107 NULL,       /* 045 */
  108 NULL,       /* 046 */
  109 NULL,       /* 047 */
  110 NULL,       /* 048 */
  111 NULL,       /* 049 */
  112 NULL,       /* 050 */
  113 NULL,       /* 051 */
  114 NULL,       /* 052 */
  115 NULL,       /* 053 */
  116 NULL,       /* 054 */
  117 NULL,       /* 055 */
  118 NULL,       /* 056 */
  119 NULL,       /* 057 */
  120 NULL,       /* 058 */
  121 NULL,       /* 059 */
  122 "&lt;",     /* 060 */
  123 NULL,       /* 061 */
  124 "&gt;",     /* 062 */
  125 NULL,       /* 063 */
  126 NULL,       /* 064 */
  127 NULL,       /* 065 */
  128 NULL,       /* 066 */
  129 NULL,       /* 067 */
  130 NULL,       /* 068 */
  131 NULL,       /* 069 */
  132 NULL,       /* 070 */
  133 NULL,       /* 071 */
  134 NULL,       /* 072 */
  135 NULL,       /* 073 */
  136 NULL,       /* 074 */
  137 NULL,       /* 075 */
  138 NULL,       /* 076 */
  139 NULL,       /* 077 */
  140 NULL,       /* 078 */
  141 NULL,       /* 079 */
  142 NULL,       /* 080 */
  143 NULL,       /* 081 */
  144 NULL,       /* 082 */
  145 NULL,       /* 083 */
  146 NULL,       /* 084 */
  147 NULL,       /* 085 */
  148 NULL,       /* 086 */
  149 NULL,       /* 087 */
  150 NULL,       /* 088 */
  151 NULL,       /* 089 */
  152 NULL,       /* 090 */
  153 NULL,       /* 091 */
  154 NULL,       /* 092 */
  155 NULL,       /* 093 */
  156 NULL,       /* 094 */
  157 NULL,       /* 095 */
  158 NULL,       /* 096 */
  159 NULL,       /* 097 */
  160 NULL,       /* 098 */
  161 NULL,       /* 099 */
  162 NULL,       /* 100 */
  163 NULL,       /* 101 */
  164 NULL,       /* 102 */
  165 NULL,       /* 103 */
  166 NULL,       /* 104 */
  167 NULL,       /* 105 */
  168 NULL,       /* 106 */
  169 NULL,       /* 107 */
  170 NULL,       /* 108 */
  171 NULL,       /* 109 */
  172 NULL,       /* 110 */
  173 NULL,       /* 111 */
  174 NULL,       /* 112 */
  175 NULL,       /* 113 */
  176 NULL,       /* 114 */
  177 NULL,       /* 115 */
  178 NULL,       /* 116 */
  179 NULL,       /* 117 */
  180 NULL,       /* 118 */
  181 NULL,       /* 119 */
  182 NULL,       /* 120 */
  183 NULL,       /* 121 */
  184 NULL,       /* 122 */
  185 NULL,       /* 123 */
  186 NULL,       /* 124 */
  187 NULL,       /* 125 */
  188 NULL,       /* 126 */
  189 NULL,       /* 127 */
  190 NULL,       /* 128 */
  191 NULL,       /* 129 */
  192 NULL,       /* 130 */
  193 NULL,       /* 131 */
  194 NULL,       /* 132 */
  195 NULL,       /* 133 */
  196 NULL,       /* 134 */
  197 NULL,       /* 135 */
  198 NULL,       /* 136 */
  199 NULL,       /* 137 */
  200 NULL,       /* 138 */
  201 NULL,       /* 139 */
  202 NULL,       /* 140 */
  203 NULL,       /* 141 */
  204 NULL,       /* 142 */
  205 NULL,       /* 143 */
  206 NULL,       /* 144 */
  207 NULL,       /* 145 */
  208 NULL,       /* 146 */
  209 NULL,       /* 147 */
  210 NULL,       /* 148 */
  211 NULL,       /* 149 */
  212 NULL,       /* 150 */
  213 NULL,       /* 151 */
  214 NULL,       /* 152 */
  215 NULL,       /* 153 */
  216 NULL,       /* 154 */
  217 NULL,       /* 155 */
  218 NULL,       /* 156 */
  219 NULL,       /* 157 */
  220 NULL,       /* 158 */
  221 NULL,       /* 159 */
  222 "&nbsp;",   /* 160 */
  223 "&iexcl;",  /* 161 */
  224 "&cent;",   /* 162 */
  225 "&pound;",  /* 163 */
  226 "&curren;", /* 164 */
  227 "&yen;",    /* 165 */
  228 "&brvbar;", /* 166 */
  229 "&sect;",   /* 167 */
  230 "&uml;",    /* 168 */
  231 "&copy;",   /* 169 */
  232 "&ordf;",   /* 170 */
  233 "&laquo;",  /* 171 */
  234 "&not;",    /* 172 */
  235 "&shy;",    /* 173 */
  236 "&reg;",    /* 174 */
  237 "&macr;",   /* 175 */
  238 "&deg;",    /* 176 */
  239 "&plusmn;", /* 177 */
  240 "&sup;",    /* 178 */
  241 "&sup;",    /* 179 */
  242 "&acute;",  /* 180 */
  243 "&micro;",  /* 181 */
  244 "&para;",   /* 182 */
  245 "&middot;", /* 183 */
  246 "&cedil;",  /* 184 */
  247 "&sup;",    /* 185 */
  248 "&ordm;",   /* 186 */
  249 "&raquo;",  /* 187 */
  250 "&frac;",   /* 188 */
  251 "&frac;",   /* 189 */
  252 "&frac;",   /* 190 */
  253 "&iquest;", /* 191 */
  254 "&Agrave;", /* 192 */
  255 "&Aacute;", /* 193 */
  256 "&Acirc;",  /* 194 */
  257 "&Atilde;", /* 195 */
  258 "&Auml;",   /* 196 */
  259 "&Aring;",  /* 197 */
  260 "&AElig;",  /* 198 */
  261 "&Ccedil;", /* 199 */
  262 "&Egrave;", /* 200 */
  263 "&Eacute;", /* 201 */
  264 "&Ecirc;",  /* 202 */
  265 "&Euml;",   /* 203 */
  266 "&Igrave;", /* 204 */
  267 "&Iacute;", /* 205 */
  268 "&Icirc;",  /* 206 */
  269 "&Iuml;",   /* 207 */
  270 "&ETH;",    /* 208 */
  271 "&Ntilde;", /* 209 */
  272 "&Ograve;", /* 210 */
  273 "&Oacute;", /* 211 */
  274 "&Ocirc;",  /* 212 */
  275 "&Otilde;", /* 213 */
  276 "&Ouml;",   /* 214 */
  277 "&times;",  /* 215 */
  278 "&Oslash;", /* 216 */
  279 "&Ugrave;", /* 217 */
  280 "&Uacute;", /* 218 */
  281 "&Ucirc;",  /* 219 */
  282 "&Uuml;",   /* 220 */
  283 "&Yacute;", /* 221 */
  284 "&THORN;",  /* 222 */
  285 "&szlig;",  /* 223 */
  286 "&agrave;", /* 224 */
  287 "&aacute;", /* 225 */
  288 "&acirc;",  /* 226 */
  289 "&atilde;", /* 227 */
  290 "&auml;",   /* 228 */
  291 "&aring;",  /* 229 */
  292 "&aelig;",  /* 230 */
  293 "&ccedil;", /* 231 */
  294 "&egrave;", /* 232 */
  295 "&eacute;", /* 233 */
  296 "&ecirc;",  /* 234 */
  297 "&euml;",   /* 235 */
  298 "&igrave;", /* 236 */
  299 "&iacute;", /* 237 */
  300 "&icirc;",  /* 238 */
  301 "&iuml;",   /* 239 */
  302 "&eth;",    /* 240 */
  303 "&ntilde;", /* 241 */
  304 "&ograve;", /* 242 */
  305 "&oacute;", /* 243 */
  306 "&ocirc;",  /* 244 */
  307 "&otilde;", /* 245 */
  308 "&ouml;",   /* 246 */
  309 "&divide;", /* 247 */
  310 "&oslash;", /* 248 */
  311 "&ugrave;", /* 249 */
  312 "&uacute;", /* 250 */
  313 "&ucirc;",  /* 251 */
  314 "&uuml;",   /* 252 */
  315 "&yacute;", /* 253 */
  316 "&thorn;",  /* 254 */
  317 "&yuml;"    /* 255 */
  318 };
  319 
  320 #ifdef HAVE_LIBTEMPLATE
  321 /*
  322  * Template engine used to produce HTML output
  323  */
  324 struct tpl_engine* engine = NULL;
  325 
  326 void templateError(enum tpl_error tplerrno) {
  327     switch (tplerrno) {
  328         case tpl_not_found:
  329             fprintf(stderr, "template not found\n");
  330             break;
  331         case tpl_empty:
  332             fprintf(stderr, "template is empty\n");
  333             break;
  334         case tpl_element_not_found:
  335             fprintf(stderr, "template element not found\n");
  336             break;
  337         case tpl_element_empty:
  338             fprintf(stderr, "template element empty\n");
  339             break;
  340         case tpl_error_external:
  341             fprintf(stderr, "external template error\n");
  342             break;
  343         default:
  344             fprintf(stderr, "unknown template error\n");
  345             break;
  346     }
  347     perror("template engine error");
  348     exit(1);
  349 }
  350 
  351 void initTemplateEngine(const char *templateFile) {
  352     if (rpm2htmlVerbose)
  353         printf("Using HTML template: %s\n", templateFile);
  354 
  355     engine = tpl_engine_new();
  356     tpl_file_load(engine, templateFile);
  357     if (engine->tplerrno)
  358         templateError(engine->tplerrno);
  359 }
  360 
  361 void destroyTemplateEngine() {
  362     tpl_engine_delete(engine);
  363 }
  364 #endif
  365 
  366 /*
  367  * Converting extended ASCII charset to valid HTML text.
  368  * The string returned is a shared location.
  369  */
  370 
  371 static unsigned char *buffer = NULL;
  372 static int buffer_size = 2000;
  373 char *convertHTML(const char *str) {
  374 
  375     unsigned char *cur, *end;
  376     unsigned char c;
  377 
  378     if (buffer == NULL) {
  379         buffer = (char *) xmlMalloc(buffer_size * sizeof(char));
  380     if (buffer == NULL) {
  381         perror("xmlMalloc failed");
  382         exit(1);
  383     }
  384     }
  385     cur = &buffer[0];
  386     end = &buffer[buffer_size - 20];
  387 
  388     while (*str != '\0') {
  389         if (cur >= end) {
  390         int delta = cur - buffer;
  391 
  392         buffer_size *= 2;
  393         buffer = (char *) xmlRealloc(buffer, buffer_size * sizeof(char));
  394         if (buffer == NULL) {
  395         perror("xmlRealloc failed");
  396         exit(1);
  397         }
  398         end = &buffer[buffer_size - 20];
  399         cur = &buffer[delta];
  400     }
  401         c = (unsigned char) *(str++);
  402     if (entities[(unsigned int) c] == NULL) {
  403         *(cur++) = c;
  404     } else {
  405         strcpy(cur, entities[(unsigned int) c]);
  406         cur += strlen(entities[(unsigned int) c]);
  407     }
  408     }
  409     *cur = '\0';
  410     return(buffer);
  411 }
  412 
  413 /*
  414  * Converting extended ASCII charset to valid XML text.
  415  * The string returned is a shared location.
  416  */
  417 
  418 char *convertXML(const char *str) {
  419 
  420     unsigned char *cur, *end;
  421     unsigned char c;
  422 
  423     if (buffer == NULL) {
  424         buffer = (char *) xmlMalloc(buffer_size * sizeof(char));
  425     if (buffer == NULL) {
  426         perror("xmlMalloc failed");
  427         exit(1);
  428     }
  429     }
  430     cur = &buffer[0];
  431     end = &buffer[buffer_size - 20];
  432 
  433     while (*str != '\0') {
  434         if (cur >= end) {
  435         int delta = cur - buffer;
  436 
  437         buffer_size *= 2;
  438         buffer = (char *) xmlRealloc(buffer, buffer_size * sizeof(char));
  439         if (buffer == NULL) {
  440         perror("xmlRealloc failed");
  441         exit(1);
  442         }
  443         end = &buffer[buffer_size - 20];
  444         cur = &buffer[delta];
  445     }
  446         c = (unsigned char) *(str++);
  447     if (((c) == 0x09) || ((c) == 0x0A) || ((c) == 0x0D) ||
  448         (((c) >= 0x20) && ((c) <= 0x8F))) {
  449         if (entities[(unsigned int) c] == NULL) {
  450         *(cur++) = c;
  451         } else {
  452         strcpy(cur, entities[(unsigned int) c]);
  453         cur += strlen(entities[(unsigned int) c]);
  454         }
  455     }
  456     }
  457     *cur = '\0';
  458     return(buffer);
  459 }
  460 
  461 /*
  462  * Convert CAN-yyyy-nnnn and CVE-yyyy-nnnn to hyperlinks
  463  * The string returned is a shared location.
  464  */
  465 static unsigned char *buffer2 = NULL;
  466 static int buffer2_size = 2000;
  467 enum STATE { C = 1, CV = 2, CVE = 3, CA = 4, CAN = 5,
  468              DIGIT1 = 6, DIGIT2 = 7 };
  469 char *convertCVE(const char *str) {
  470     unsigned char *cur, *end;
  471     unsigned char c;
  472     int state = 0;
  473     int count = 0;
  474     unsigned char parse[14]; /* "CVE-yyyy-nnnn" */
  475     unsigned char *p = parse;
  476 
  477     if (rpm2html_cve_linking == 0)
  478         return str;
  479 
  480     if (buffer2 == NULL) {
  481         buffer2 = (char *) xmlMalloc(buffer2_size * sizeof(char));
  482     if (buffer2 == NULL) {
  483         perror("xmlMalloc failed");
  484         exit(1);
  485     }
  486     }
  487     cur = &buffer2[0];
  488     end = &buffer2[buffer2_size - 100];
  489 
  490     while (*str != '\0') {
  491         if (cur >= end) {
  492         int delta = cur - buffer2;
  493 
  494         buffer2_size *= 2;
  495         buffer2 = (char *) xmlRealloc(buffer2, buffer2_size * sizeof(char));
  496         if (buffer2 == NULL) {
  497         perror("xmlRealloc failed");
  498         exit(1);
  499         }
  500         end = &buffer2[buffer2_size - 100];
  501         cur = &buffer2[delta];
  502         }
  503  
  504     c = (unsigned char) *(str++);
  505     switch (c) {
  506     case 'C':
  507         if (state == 0) {
  508         *p++ = c;
  509         state = C;
  510         continue;
  511         }
  512         break;
  513     case 'V':
  514         if (state == C) {
  515         *p++ = c;
  516         state = CV;
  517         continue;
  518         }
  519         break;
  520     case 'E':
  521         if (state == CV) {
  522         *p++ = c;
  523         state = CVE;
  524         continue;
  525         }
  526         break;
  527     case 'A':
  528         if (state == C) {
  529         *p++ = c;
  530         state = CA;
  531         continue;
  532         }
  533         break;
  534     case 'N':
  535         if (state == CA) {
  536         *p++ = c;
  537         state = CAN;
  538         continue;
  539         }
  540         break;
  541     case '-':
  542         if (state == CVE || state == CAN) {
  543         *p++ = c;
  544         state = DIGIT1;
  545         count = 0;
  546         continue;
  547         }
  548         else if (state == DIGIT1 && count == 4) {
  549         *p++ = c;
  550         state = DIGIT2;
  551         count = 0;
  552         continue;
  553         }
  554         break;
  555     case '0':
  556     case '1':
  557     case '2':
  558     case '3':
  559     case '4':
  560     case '5':
  561     case '6':
  562     case '7':
  563     case '8':
  564     case '9':
  565         if (state == DIGIT1 || state == DIGIT2) {
  566         count++;
  567         if (count == 4) {
  568             *p++ = c;
  569             if (state == DIGIT2) {
  570             unsigned char url[90];
  571             *p = '\0';
  572             sprintf(url, "<a href=\"http://cve.mitre.org/cgi-bin/cvename.cgi?"
  573                          "name=%s\">%s</a>", parse, parse);
  574             strcpy(cur, url);
  575             cur += strlen(url);
  576             p = parse;
  577             state = 0;
  578              }
  579              continue;
  580         }
  581         else if (count < 4) {
  582              *p++ = c;
  583              continue;
  584         }
  585         }
  586         break;
  587     default:
  588         break;
  589     }
  590     if (p != parse) {
  591         memcpy(cur, parse, p - parse);
  592         cur += p - parse;
  593         p = parse;
  594     }
  595     state = 0;
  596     *(cur++) = c;
  597     }
  598     *cur = '\0';
  599     return(buffer2);
  600 }
  601 
  602 /*
  603  * Generates signature info (extended ASCII charset)
  604  * The string returned is a shared location.
  605  */
  606 #define X(_x)   (unsigned)((_x) & 0xff)
  607 
  608 static unsigned char *sigInfoMD5 = "internal MD5: ";
  609 #if defined(WITH_GPG)
  610 static unsigned char *sigInfoGPG = "GPG:\n";
  611 static unsigned char *sigInfoPGP = "PGP:\n";
  612 #else
  613 static unsigned char *sigInfoGPG = "GPG";
  614 static unsigned char *sigInfoPGP = "PGP";
  615 #endif
  616 static unsigned char *sigInfoU = "unknown";
  617 
  618 static unsigned char *sbuffer = NULL;
  619 static int sbuffer_size = 2000;
  620 static unsigned char *sbuffer2 = NULL;
  621 static int sbuffer2_size = 3;
  622 char *convertSIG(rpmSigPtr sig) {
  623     int n1;
  624     unsigned char *md5sum = (unsigned char *) sig->sig;
  625 
  626     if (sbuffer == NULL) {
  627         sbuffer = (char *) xmlMalloc(sbuffer_size * sizeof(char));
  628     if (sbuffer == NULL) {
  629         perror("xmlMalloc failed");
  630         exit(1);
  631     }
  632     }
  633     if (sbuffer2 == NULL) {
  634         sbuffer2 = (char *) xmlMalloc(sbuffer2_size * sizeof(char));
  635     if (sbuffer2 == NULL) {
  636         perror("xmlMalloc failed");
  637         exit(1);
  638     }
  639     }
  640 
  641     switch(sig->tag) {
  642         case RPMSIGTAG_MD5:
  643             strncpy(sbuffer, sigInfoMD5, sbuffer_size);
  644             for(n1 = 0; n1 < sig->size; n1++) {
  645                 snprintf(sbuffer2, sbuffer2_size, "%02x", X(md5sum[n1]));
  646                 strncat(sbuffer, sbuffer2, sbuffer_size);
  647             }
  648             return(sbuffer);
  649         case RPMSIGTAG_GPG:
  650             #if defined(WITH_GPG)
  651             strncpy(sbuffer, sigInfoGPG, sbuffer_size);
  652             if (sig->resolve != NULL)
  653                 strncat(sbuffer, sig->resolve, sbuffer_size);
  654             return(sbuffer);
  655             #else
  656             return(sigInfoGPG);
  657             #endif
  658         case RPMSIGTAG_PGP:
  659             #if defined(WITH_GPG)
  660             strncpy(sbuffer, sigInfoPGP, sbuffer_size);
  661             if (sig->resolve != NULL)
  662                 strncat(sbuffer, sig->resolve, sbuffer_size);
  663             return(sbuffer);
  664             #else
  665             return(sigInfoPGP);
  666             #endif
  667         default:
  668             return(sigInfoU);
  669     }
  670 }
  671 
  672 /*
  673  * Determine whether given HTML output file is older than given timestamp and thus needs updating.
  674  *
  675  * Returned 0 means that no update is needed for HTML, non-zero means update is needed.
  676  *
  677  * TODO: Make it used also by "resource pages": Resource page gets the timestamp of newest RPM file which contributes
  678  * to its content and that is used for compare.
  679  */
  680 int needsDump(char *htmlFileName, time_t rpmFileTimestamp) {
  681     struct stat buf;
  682 
  683     if (!rpm2html_dump_html_only_if_rpm_newer)
  684         // option turned off => update needed always
  685         return 1;
  686 
  687     // determine the last modification time of the HTML file
  688     if (stat(htmlFileName, &buf) != 0)
  689         // well, something bad happened so we err in the direction of caution and tell the caller update is needed
  690         return 1;
  691 
  692     // compare time stamps
  693     if (rpmFileTimestamp < buf.st_mtime)
  694         return 0;
  695 
  696     return 1;
  697 }
  698 
  699 /*
  700  * Cleanup the global varibales of this module
  701  */
  702 void htmlCleanup(void) {
  703     if (buffer != NULL)
  704         xmlFree(buffer);
  705     if (buffer2 != NULL)
  706         xmlFree(buffer2);
  707     if (sbuffer != NULL)
  708         xmlFree(sbuffer);
  709     if (sbuffer2 != NULL)
  710         xmlFree(sbuffer2);
  711     buffer = NULL;
  712     buffer_size = 2000;
  713     buffer2 = NULL;
  714     buffer2_size = 2000;
  715     sbuffer = NULL;
  716     sbuffer_size = 2000;
  717     sbuffer2 = NULL;
  718     sbuffer2_size = 3;
  719 }
  720 
  721 /*
  722  * Converting extended ASCII charset to valid HTML text.
  723  * A new memory area is allocated for the returned value.
  724  */
  725 
  726 char *xmlStrdupHTML(const char *str) {
  727     return(xmlStrdup(convertHTML(str)));
  728 }
  729 
  730 /*
  731  * createDirectory : create a directory. It does recurse and create the
  732  *                   father dir if needed.
  733  */
  734 
  735 void createDirectory(const char *dirname) {
  736     static char last_dir[2000] = "";
  737 
  738     /*
  739      * avoid costly syscalls.
  740      */
  741     if (!strcmp(last_dir, dirname)) return;
  742 
  743     if (mkdir(dirname, 0777) != 0) {
  744         switch (errno) {
  745 #ifdef EEXIST
  746             case EEXIST:
  747         if (rpm2htmlVerbose > 1)
  748             fprintf(stderr, "Directory \"%s\" already exists\n",
  749                     dirname);
  750         return;
  751 #endif
  752         case ENOENT: {
  753             char *father = xmlStrdup(dirname);
  754         char *cur = &father[strlen(father)];
  755 
  756         while (cur > father) {
  757             if (*cur == '/') {
  758                 *cur = '\0';
  759             break;
  760                 }
  761             cur--;
  762         }
  763         if (cur > father) {
  764             createDirectory(father);
  765             if (mkdir(dirname, 0777) != 0) {
  766             fprintf(stderr, "createDirectory \"%s\" failed\n",
  767                     dirname);
  768             perror("mkdir failed:");
  769             return;
  770             }
  771         }
  772         xmlFree(father);
  773         
  774             break;
  775         }
  776             default:
  777             fprintf(stderr, "createDirectory \"%s\" failed\n", dirname);
  778             perror("mkdir failed:");
  779         return;
  780     }
  781     } else if (rpm2htmlVerbose)
  782         fprintf(stderr, "Created directory \"%s\"\n", dirname);
  783 }
  784 
  785 /*
  786  * Stuff needed for the icon creation.
  787  */
  788 
  789 #include <zlib.h>
  790 #include "dir.png.h"
  791 #include "new.png.h"
  792 
  793 void dumpDirIcon(void) {
  794     char path[500];
  795     char *content;
  796     int fd;
  797     /* struct stat *buf; !!!!!! */
  798 
  799     if (!rpm2html_dump_html) return;
  800 
  801     createDirectory(rpm2html_dir);
  802     snprintf(path, sizeof(path), "%s/dir.png", rpm2html_dir);
  803     content = read_data_buffer_dir_png();
  804     if ((fd = creat(path, 0644)) < 0) {
  805         fprintf(stderr, "creat() failed on %s\n", path);
  806     return;
  807     }
  808     write(fd, content, data_buffer_dir_png_size);
  809     close(fd);
  810     snprintf(path, sizeof(path), "%s/new.png", rpm2html_dir);
  811     content = read_data_buffer_new_png();
  812     if ((fd = creat(path, 0644)) < 0) {
  813         fprintf(stderr, "creat() failed on %s\n", path);
  814     return;
  815     }
  816     write(fd, content, data_buffer_new_png_size);
  817     close(fd);
  818 }
  819 
  820 /*
  821  * checkDate : check whether the last modification time of a file
  822  *             is anterior to a given time
  823  */
  824 
  825 int checkDate(const char *filename, time_t stamp) {
  826     struct stat buf;
  827 
  828     if (force) return(0);
  829     if ((stat(filename, &buf)) != 0) {
  830         return(0);
  831     }
  832     if (buf.st_size < 10) {
  833         return(0);
  834     }
  835     return(buf.st_mtime > stamp);
  836 }
  837 
  838 /*
  839  * checkDirectory : check if this directory exist
  840  */
  841 
  842 int checkDirectory(const char *filename) {
  843     struct stat buf;
  844 
  845     if (force) return(0);
  846     if ((stat(filename, &buf)) != 0) {
  847         return(0);
  848     }
  849     if ((S_ISDIR(buf.st_mode)) || (S_ISLNK(buf.st_mode)))
  850         return(1);
  851     return(0);
  852 }
  853 
  854 /*
  855  * checkFile : check if this file exist
  856  */
  857 
  858 int checkFile(const char *filename) {
  859     struct stat buf;
  860 
  861     if (force) return(0);
  862     if ((stat(filename, &buf)) != 0) {
  863         return(0);
  864     }
  865     return(1);
  866 }
  867 
  868 /*
  869  * Transformation function from rpm to filename.
  870  */
  871 
  872 const char *rpmName(rpmDataPtr cur) {
  873     static char rbuf[500];
  874 
  875     if (cur->arch != NULL)
  876     snprintf(rbuf, sizeof(rbuf), "%s-%s-%s.%s", 
  877         cur->name, cur->version, cur->release, cur->arch);
  878     else
  879     snprintf(rbuf, sizeof(rbuf), "%s-%s-%s", 
  880         cur->name, cur->version, cur->release);
  881     return(rbuf);
  882 }
  883 
  884 /*
  885  * Transformation function from rpm to Software name.
  886  */
  887 
  888 const char *rpmSoftwareName(rpmDataPtr cur) {
  889     static char rbuf[500];
  890 
  891     snprintf(rbuf, sizeof(rbuf), "%s-%s-%s", 
  892     cur->name, cur->version, cur->release);
  893     return(rbuf);
  894 }
  895 
  896 /*
  897  * remove symbols that we do not want in filenames..
  898  */
  899 const char *cleanName (const char *name) {
  900     static char cbuf[500];
  901     char *cur = cbuf;
  902  
  903     while (*name != '\0') {
  904         if ((*name == '/')
  905      || (*name == ' ')
  906      || (*name == '/')
  907      || (*name == '"')
  908      || (*name == '<')
  909      || (*name == '>')
  910      || (*name == ':')
  911      || (*name == '|')
  912      || (*name == '@')
  913      || (*name == '\t')
  914      || (*name == '\r')
  915      || (*name == '\n')) {
  916         *cur++ = '_';
  917         name++;
  918     } else *cur++ = *name++;
  919     }
  920     *cur = '\0';
  921     return (cbuf);
  922 }
  923 
  924 /*
  925  * do the URI escaping needed for that name.
  926  */
  927 const char *escapeName (const char *name) {
  928     static char cbuf[500];
  929     char *cur = cbuf, *end = &cbuf[495];
  930     char tmp;
  931  
  932     while ((*name != '\0') && (cur < end)) {
  933     tmp = *name++;
  934         if (((tmp >= 'a') && (tmp <= 'z')) ||
  935             ((tmp >= 'A') && (tmp <= 'Z')) ||
  936         ((tmp >= '0') && (tmp <= '9')) ||
  937         (tmp == '-') || (tmp == '_') || (tmp == '.') ||
  938         (tmp == '!') || (tmp == '~') || (tmp == '*') || (tmp == '\'') ||
  939         (tmp == '(') || (tmp == ')')) {
  940         *cur++ = tmp;
  941 
  942     } else {
  943         int val = (unsigned char)tmp;
  944         int hi = val / 0x10, lo = val % 0x10;
  945         *cur++ = '%';
  946         *cur++ = hi + (hi > 9? 'A'-10 : '0');
  947         *cur++ = lo + (lo > 9? 'A'-10 : '0');
  948     }
  949     }
  950     *cur = '\0';
  951     return (cbuf);
  952 }
  953 
  954 /*
  955  * Transformation function from group to filename.
  956  */
  957 
  958 const char *groupName(const char *group) {
  959     static char gbuf[500];
  960 
  961     strncpy(gbuf, cleanName (group), 500);
  962     strncat(gbuf, localizedStrings[LANG_HTML_SUFFIX], 500);
  963     return(gbuf);
  964 }
  965 
  966 /*
  967  * Transformation function from group to filename.
  968  */
  969 
  970 const char *distribName(const char *distrib) {
  971     static char dbuf[500];
  972 
  973     strncpy(dbuf, cleanName (distrib), 500);
  974     strncat(dbuf, localizedStrings[LANG_HTML_SUFFIX], 500);
  975     return(dbuf);
  976 }
  977 
  978 /*
  979  * Generate a full URL
  980  */
  981 
  982 void fullURL(char *buf, int len, rpmDirPtr dir, const char *subdir, const char *filename) {
  983     if (dir == NULL) {
  984     snprintf(buf, len, "http://%s%s", rpm2html_host, rpm2html_url);
  985     } else {
  986         if (subdir == NULL)
  987             snprintf(buf, len, "http://%s%s/%s",
  988              rpm2html_host, rpm2html_url,
  989              filename);
  990             else
  991             snprintf(buf, len, "http://%s%s/%s/%s",
  992              rpm2html_host, rpm2html_url,
  993              subdir, filename);
  994     }
  995 }
  996 
  997 /*
  998  * Generate a full directory path.
  999  */
 1000 
 1001 void fullPathName(char *buf, int len, rpmDirPtr dir, const char *subdir, const char *filename) {
 1002     if (dir == NULL) {
 1003     snprintf(buf, len, "%s/%s", rpm2html_dir, filename);
 1004     } else {
 1005         if (subdir == NULL)
 1006             snprintf(buf, len, "%s/%s", dir->dir, filename);
 1007             else
 1008             snprintf(buf, len, "%s/%s/%s", dir->dir, subdir, filename);
 1009     }
 1010 }
 1011 
 1012 /*
 1013  * Generate a full directory path plus ditinguish with a letter.
 1014  */
 1015 
 1016 void fullPathNameLr(char *buf, int len, rpmDirPtr dir, char *subdir,
 1017                     char *filename, char letter) {
 1018     if (dir == NULL) {
 1019     snprintf(buf, len, "%s/%c%s", rpm2html_dir, letter, filename);
 1020     } else {
 1021     if (subdir == NULL)
 1022         snprintf(buf, len, "%s/%c%s", dir->dir, letter, filename);
 1023     else
 1024         snprintf(buf, len, "%s/%s/%c%s", dir->dir, subdir, letter, filename);
 1025     }
 1026 }
 1027 
 1028 /*
 1029  * Generate a full directory path plus ditinguish with a number.
 1030  */
 1031 
 1032 void fullPathNameNr(char *buf, int len, rpmDirPtr dir, char *subdir,
 1033                     char *filename, int number) {
 1034     if (dir == NULL) {
 1035     snprintf(buf, len, "%s/%d%s", rpm2html_dir, number, filename);
 1036     } else {
 1037     if (subdir == NULL)
 1038         snprintf(buf, len, "%s/%d%s", dir->dir, number, filename);
 1039     else
 1040         snprintf(buf, len, "%s/%s/%d%s", dir->dir, subdir, number, filename);
 1041     }
 1042 }
 1043 
 1044 /*
 1045  * Transformation function from vendor to filename.
 1046  */
 1047 
 1048 const char *vendorName(const char *vendor) {
 1049     static char vbuf[500];
 1050 
 1051     strncpy(vbuf, cleanName (vendor), 500);
 1052     strncat(vbuf, localizedStrings[LANG_HTML_SUFFIX], 500);
 1053     return(vbuf);
 1054 }
 1055 
 1056 /*
 1057  * Transformation function from resource to filename.
 1058  */
 1059 
 1060 const char *resourceName(const char *resource) {
 1061     static char rbuf[500];
 1062 
 1063     strncpy(rbuf, cleanName (resource), 500);
 1064     strncat(rbuf, localizedStrings[LANG_HTML_SUFFIX], 500);
 1065     return(rbuf);
 1066 }
 1067 
 1068 #ifdef HAVE_LIBTEMPLATE
 1069 /*
 1070  * Parse template item and write the result to file
 1071  */
 1072 void parseNwriteTemplate(FILE *html, struct tpl_engine *engine, char *template_name) {
 1073     char* result = NULL;
 1074 
 1075     tpl_parse(engine, template_name, "parse_result", 0);
 1076     result = tpl_element_get(engine, "parse_result");
 1077     if (result)
 1078         fprintf(html, "%s", result);
 1079     else {
 1080         perror("template item parsing failed");
 1081         exit(1);
 1082     }
 1083 }
 1084 
 1085 /*
 1086  * Parse meaningfull value into 'p_new_item' element
 1087  */
 1088 void fillNewItemElement(struct tpl_engine *engine) {
 1089     tpl_element_set(engine, "url", rpm2html_url);
 1090     tpl_parse(engine, "new_item", "p_new_item", 0); // XXX maybe not necessary to call this more than once? => optimize to call just once
 1091     tpl_element_set(engine, "new", tpl_element_get(engine, "p_new_item"));
 1092 }
 1093 
 1094 /*
 1095  * Clear 'p_new_item' element
 1096  */
 1097 void clearNewItemElement(struct tpl_engine *engine) {
 1098     tpl_element_set(engine, "new", "");
 1099 }
 1100 #endif
 1101 
 1102 /*
 1103  * Generate an HTML header
 1104  */
 1105 
 1106 void generateHtmlHeader(FILE *html, char *title, char *color) {
 1107 #ifdef HAVE_LIBTEMPLATE
 1108     tpl_element_set(engine, "generator_name", rpm2html_rpm2html_name);
 1109     tpl_element_set(engine, "generator_version", rpm2html_rpm2html_ver);
 1110     tpl_parse(engine, title, "p_title", 0);
 1111     tpl_element_set(engine, "title", tpl_element_get(engine, "p_title"));
 1112 
 1113     parseNwriteTemplate(html, engine, "header");
 1114 
 1115 #else   // ifdef HAVE_LIBTEMPLATE
 1116 
 1117     fprintf(html, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n");
 1118     fprintf(html, "<html>\n<head>\n<title>%s</title>\n", title);
 1119     fprintf(html, "<meta name=\"GENERATOR\" content=\"%s %s\">\n",
 1120             rpm2html_rpm2html_name, rpm2html_rpm2html_ver);
 1121     if (color == NULL)
 1122         fprintf(html,
 1123             "</head>\n<body bgcolor=\"#ffffff\" text=\"#000000\">\n");
 1124     else 
 1125         fprintf(html, "</head>\n<body bgcolor=\"%s\" text=\"#000000\">\n",
 1126             color);
 1127 #endif  // ifdef HAVE_LIBTEMPLATE
 1128 }
 1129 
 1130 /*
 1131  * Generate an HTML footer
 1132  */
 1133 
 1134 void generateHtmlFooter(FILE *html) {
 1135     struct tm * tstruct;
 1136 
 1137     tstruct = localtime(&currentTime);
 1138 
 1139 #ifdef HAVE_LIBTEMPLATE
 1140     tpl_element_set(engine, "generator_name", rpm2html_rpm2html_name);
 1141     tpl_element_set(engine, "generator_version", rpm2html_rpm2html_ver);
 1142     tpl_element_set(engine, "generator_url", rpm2html_rpm2html_url);
 1143     tpl_element_set(engine, "maintainer_mail", rpm2html_mail);
 1144     tpl_element_set(engine, "maintainer_name", rpm2html_maint);
 1145     tpl_element_set(engine, "time", asctime(tstruct));
 1146 
 1147     parseNwriteTemplate(html, engine, "footer");
 1148 
 1149 #else   // ifdef HAVE_LIBTEMPLATE
 1150 
 1151     fprintf(html, "<hr>\n");
 1152     fprintf(html, "<p>%s <a href=\"%s\">%s %s</a>\n",
 1153             localizedStrings[LANG_GENERATED],
 1154         rpm2html_rpm2html_url, rpm2html_rpm2html_name,
 1155         rpm2html_rpm2html_ver);
 1156     if (rpm2html_help != NULL) {
 1157     fprintf(html, "<p><a href=\"%s\">%s</a>, %s\n",
 1158         rpm2html_help, rpm2html_maint, asctime(tstruct));
 1159     } else {
 1160     fprintf(html, "<p><a href=\"mailto:%s\">%s</a>, %s\n",
 1161         rpm2html_mail, rpm2html_maint, asctime(tstruct));
 1162     }
 1163     fprintf(html, "</body>\n</html>\n");
 1164 #endif  // ifdef HAVE_LIBTEMPLATE
 1165 }
 1166 
 1167 /*
 1168  * Generate a the opening anchor tag for a package
 1169  */
 1170 #ifdef HAVE_LIBTEMPLATE
 1171 /* note: we diverge here from "ussual templatization" while we do not want to have just
 1172    '<a href="{uri}">' in the template - too small item; instead, this function will return just
 1173    URI and caller function will do the rest */
 1174 char *generateHtmlRpmAnchor(rpmDataPtr cur) {
 1175     if (buffer == NULL) {
 1176         buffer = (char *) xmlMalloc(buffer_size * sizeof(char));
 1177     if (buffer == NULL) {
 1178         perror("xmlMalloc failed");
 1179         exit(1);
 1180     }
 1181     }
 1182     /* carefull: initial value for buffer_size is 2000 so if URI generated here is longer,
 1183        it'll be truncated thus very likely invalid */
 1184 
 1185     if (cur->dir == NULL) {
 1186     buffer[0] = '\0';
 1187     return buffer;
 1188     }
 1189     if ((cur->dir->subdir != NULL) && (cur->dir->subdir[0] != '\0')) {
 1190         /*
 1191      * More than one mirror, there is an HTML subdir
 1192      */
 1193     if ((cur->subdir != NULL) && (cur->subdir[0] != '\0')) {
 1194         if (cur->dir->url)
 1195         snprintf(buffer, buffer_size, "%s/%s/%s/%s.html",
 1196             cur->dir->url, cur->dir->subdir,
 1197             cur->subdir, rpmName(cur));
 1198         else
 1199         snprintf(buffer, buffer_size, "%s/%s/%s.html",
 1200             cur->subdir, cur->dir->subdir, rpmName(cur));
 1201     } else {
 1202         if (cur->dir->url)
 1203         snprintf(buffer, buffer_size, "%s/%s/%s.html",
 1204                 cur->dir->url, cur->dir->subdir, rpmName(cur));
 1205         else
 1206         snprintf(buffer, buffer_size, "%s/%s.html",
 1207                 cur->dir->subdir, rpmName(cur));
 1208     }
 1209     } else {
 1210         /*
 1211      * Only one mirror, no HTML subdir
 1212      */
 1213     if ((cur->subdir != NULL) && (cur->subdir[0] != '\0')) {
 1214         if (cur->dir->url)
 1215         snprintf(buffer, buffer_size, "%s/%s/%s.html",
 1216             cur->dir->url, cur->subdir, rpmName(cur));
 1217         else
 1218         snprintf(buffer, buffer_size, "%s/%s.html",
 1219             cur->subdir, rpmName(cur));
 1220     } else {
 1221         if (cur->dir->url)
 1222         snprintf(buffer, buffer_size, "%s/%s.html",
 1223                 cur->dir->url, rpmName(cur));
 1224         else
 1225         snprintf(buffer, buffer_size, "%s.html",
 1226                 rpmName(cur));
 1227     }
 1228     }
 1229 
 1230     return buffer;
 1231 }
 1232 #else   // ifdef HAVE_LIBTEMPLATE
 1233 void generateHtmlRpmAnchor(FILE *html, rpmDataPtr cur) {
 1234     if (cur->dir == NULL) {
 1235     fprintf(html, "<a href=\"\">");
 1236     return;
 1237     }
 1238     if ((cur->dir->subdir != NULL) && (cur->dir->subdir[0] != '\0')) {
 1239         /*
 1240      * More than one mirror, there is an HTML subdir
 1241      */
 1242     if ((cur->subdir != NULL) && (cur->subdir[0] != '\0')) {
 1243         if (cur->dir->url)
 1244         fprintf(html, "<a href=\"%s/%s/%s/%s.html\">",
 1245             cur->dir->url, cur->dir->subdir,
 1246             cur->subdir, rpmName(cur));
 1247         else
 1248         fprintf(html, "<a href=\"%s/%s/%s.html\">",
 1249             cur->subdir, cur->dir->subdir, rpmName(cur));
 1250     } else {
 1251         if (cur->dir->url)
 1252         fprintf(html, "<a href=\"%s/%s/%s.html\">",
 1253                 cur->dir->url, cur->dir->subdir, rpmName(cur));
 1254         else
 1255         fprintf(html, "<a href=\"%s/%s.html\">",
 1256                 cur->dir->subdir, rpmName(cur));
 1257     }
 1258     } else {
 1259         /*
 1260      * Only one mirror, no HTML subdir
 1261      */
 1262     if ((cur->subdir != NULL) && (cur->subdir[0] != '\0')) {
 1263         if (cur->dir->url)
 1264         fprintf(html, "<a href=\"%s/%s/%s.html\">",
 1265             cur->dir->url, cur->subdir, rpmName(cur));
 1266         else
 1267         fprintf(html, "<a href=\"%s/%s.html\">",
 1268             cur->subdir, rpmName(cur));
 1269     } else {
 1270         if (cur->dir->url)
 1271         fprintf(html, "<a href=\"%s/%s.html\">",
 1272                 cur->dir->url, rpmName(cur));
 1273         else
 1274         fprintf(html, "<a href=\"%s.html\">",
 1275                 rpmName(cur));
 1276     }
 1277     }
 1278 }
 1279 #endif  // ifdef HAVE_LIBTEMPLATE
 1280 
 1281 /*
 1282  * Generate an RSS link element for a package
 1283  */
 1284 void generateRSSLink(FILE *RSS, rpmDataPtr cur) {
 1285     fprintf(RSS, "    <link>http://%s", rpm2html_host);
 1286     if ((cur->dir->subdir != NULL) && (cur->dir->subdir[0] != '\0')) {
 1287         /*
 1288      * More than one mirror, there is an HTML subdir
 1289      */
 1290     if ((cur->subdir != NULL) && (cur->subdir[0] != '\0')) {
 1291         if (cur->dir->url)
 1292         fprintf(RSS, "%s/%s/%s/%s.html",
 1293             cur->dir->url, cur->dir->subdir,
 1294             cur->subdir, rpmName(cur));
 1295         else
 1296         fprintf(RSS, "%s/%s/%s.html",
 1297             cur->subdir, cur->dir->subdir, rpmName(cur));
 1298     } else {
 1299         if (cur->dir->url)
 1300         fprintf(RSS, "%s/%s/%s.html",
 1301                 cur->dir->url, cur->dir->subdir, rpmName(cur));
 1302         else
 1303         fprintf(RSS, "%s/%s.html",
 1304                 cur->dir->subdir, rpmName(cur));
 1305     }
 1306     } else {
 1307         /*
 1308      * Only one mirror, no HTML subdir
 1309      */
 1310     if ((cur->subdir != NULL) && (cur->subdir[0] != '\0')) {
 1311         if (cur->dir->url)
 1312         fprintf(RSS, "%s/%s/%s.html",
 1313             cur->dir->url, cur->subdir, rpmName(cur));
 1314         else
 1315         fprintf(RSS, "%s/%s.html",
 1316             cur->subdir, rpmName(cur));
 1317     } else {
 1318         if (cur->dir->url)
 1319         fprintf(RSS, "%s/%s.html",
 1320                 cur->dir->url, rpmName(cur));
 1321         else
 1322         fprintf(RSS, "%s.html",
 1323                 rpmName(cur));
 1324     }
 1325     }
 1326     fprintf(RSS, "</link>\n");
 1327 }
 1328 
 1329 /*
 1330  * Generate a line in a table for a RPM.
 1331  * Don't list the source RPMs
 1332  */
 1333 
 1334 void generateHtmlRpmRow(FILE *html, rpmDataPtr cur, int shownew) {
 1335 #ifdef SHOW_DATE
 1336     static char buf[500];
 1337     struct tm * tstruct;
 1338 #endif
 1339 
 1340     if (!strcmp(cur->arch, "src")) return;
 1341 
 1342 #ifdef SHOW_DATE
 1343     tstruct = localtime(&(cur->date));
 1344 #ifdef HAVE_STRFTIME
 1345     strftime(buf, sizeof(buf) - 1, "%c", tstruct);
 1346 #else
 1347 #error "no strftime, please check !"
 1348 #endif
 1349 #endif
 1350 
 1351 #ifdef HAVE_LIBTEMPLATE
 1352     if (cur->dir != NULL)
 1353         tpl_element_set(engine, "bgcolor", cur->dir->color);
 1354     tpl_element_set(engine, "uri", generateHtmlRpmAnchor(cur));
 1355     tpl_element_set(engine, "name", rpmName(cur));
 1356     if ((shownew) && (cur->date > 0) &&
 1357         ((currentTime - cur->date) < (24 * 60 * 60 * 15)))
 1358         fillNewItemElement(engine);
 1359     else
 1360         clearNewItemElement(engine);
 1361     tpl_element_set(engine, "summary", convertHTML(cur->summary));
 1362 #ifdef SHOW_DATE
 1363     tpl_element_set(engine, "system", buf);
 1364 #else
 1365     if ((cur->dir != NULL) && (cur->dir->name != NULL))
 1366         tpl_element_set(engine, "system", cur->dir->name);
 1367     else
 1368         tpl_element_set(engine, "system", "");
 1369 #endif
 1370 
 1371     parseNwriteTemplate(html, engine, "rpm_row");
 1372 
 1373 #else   // ifdef HAVE_LIBTEMPLATE
 1374 
 1375     if (cur->dir != NULL) {
 1376     fprintf(html, "<tr bgcolor=\"%s\"><td width=\"%d\">",
 1377         cur->dir->color, PACKAGE_FIELD_WIDTH);
 1378     } else {
 1379     fprintf(html, "<tr><td width=\"%d\">",
 1380         PACKAGE_FIELD_WIDTH);
 1381     }
 1382     generateHtmlRpmAnchor(html, cur);
 1383     fprintf(html, "%s</a>", rpmName(cur));
 1384     if ((shownew) && (cur->date > 0) &&
 1385         ((currentTime - cur->date) < (24 * 60 * 60 * 15)))
 1386     fprintf(html, "<img src=\"%s/new.png\" alt=\"New\">", rpm2html_url);
 1387     fprintf(html, "</td>\n<td width=\"%d\">%s</td>\n",
 1388             DESCRIPTION_FIELD_WIDTH,
 1389         convertHTML(cur->summary));
 1390 #ifdef SHOW_DATE
 1391     fprintf(html, "<td>%s</td></tr>\n", buf);
 1392 #else
 1393     if ((cur->dir != NULL) && (cur->dir->name != NULL))
 1394     fprintf(html, "<td>%s</td></tr>\n", cur->dir->name);
 1395 #endif
 1396 #endif  // ifdef HAVE_LIBTEMPLATE
 1397 }
 1398 
 1399 /*
 1400  * Generate an entry in an RSS channel for an RPM.
 1401  */
 1402 void generateRSSItem(FILE *RSS, rpmDataPtr cur) {
 1403     fprintf(RSS, "  <item>\n");
 1404     fprintf(RSS, "    <title>%s</title>\n", rpmName(cur));
 1405     if (cur->summary != NULL)
 1406     fprintf(RSS, "    <description>%s</description>\n",
 1407         convertHTML(cur->summary));
 1408     generateRSSLink(RSS, cur);
 1409     fprintf(RSS, "  </item>\n");
 1410 }
 1411 
 1412 /*
 1413  * Generate a line in a table for an RPM software and all it's architectures.
 1414  */
 1415 
 1416 void generateHtmlRpmArchRow(FILE *html, rpmDataPtr cur) {
 1417 
 1418     rpmDataPtr tmp;
 1419 
 1420 #ifdef HAVE_LIBTEMPLATE
 1421     tpl_element_set(engine, "name", rpmSoftwareName(cur));
 1422     tpl_element_set(engine, "summary", convertHTML(cur->summary));
 1423     parseNwriteTemplate(html, engine, "arch_row");
 1424 
 1425     /* dump the archs list */
 1426     tmp = cur;
 1427     while (tmp != NULL) {
 1428     if (strcmp(tmp->arch, "src")) {
 1429         tpl_element_set(engine, "uri", generateHtmlRpmAnchor(tmp));
 1430         tpl_element_set(engine, "os", tmp->os);
 1431         tpl_element_set(engine, "arch", tmp->arch);
 1432         if ((currentTime - tmp->date) < (24 * 60 * 60 * 15))
 1433             fillNewItemElement(engine);
 1434         else
 1435             clearNewItemElement(engine);
 1436         if (tmp->dir != NULL) {
 1437             tpl_element_set(engine, "bgcolor", tmp->dir->color);
 1438             parseNwriteTemplate(html, engine, "arch_row_item_dir");
 1439         }
 1440         else
 1441             parseNwriteTemplate(html, engine, "arch_row_item");
 1442     }
 1443     tmp = tmp->nextArch;
 1444     }
 1445     parseNwriteTemplate(html, engine, "arch_row_end");
 1446 
 1447 #else   // ifdef HAVE_LIBTEMPLATE
 1448 
 1449     fprintf(html, "<tr><td width=\"%d\">", PACKAGE_FIELD_WIDTH);
 1450     fprintf(html, "%s</td>\n", rpmSoftwareName(cur));
 1451     fprintf(html, "<td width=\"%d\">%s</td>\n",
 1452             DESCRIPTION_FIELD_WIDTH, convertHTML(cur->summary));
 1453     /* dump the archs list */
 1454     tmp = cur;
 1455     while (tmp != NULL) {
 1456     if (strcmp(tmp->arch, "src")) {
 1457         if (tmp->dir != NULL)
 1458         fprintf(html, "<td bgcolor=\"%s\" width=\"%d\">",
 1459             tmp->dir->color, SYSTEM_FIELD_WIDTH);
 1460         else
 1461         fprintf(html, "<td width=\"%d\">",
 1462             SYSTEM_FIELD_WIDTH);
 1463         generateHtmlRpmAnchor(html, tmp);
 1464         fprintf(html, "%s/%s</a>", tmp->os, tmp->arch);
 1465         if ((currentTime - tmp->date) < (24 * 60 * 60 * 15))
 1466         fprintf(html, "<img src=\"%s/new.png\" alt=\"New\">",
 1467                 rpm2html_url);
 1468         fprintf(html, "</td>");
 1469     }
 1470     tmp = tmp->nextArch;
 1471     }
 1472     fprintf(html, "\n</tr>\n");
 1473 #endif  // ifdef HAVE_LIBTEMPLATE
 1474 }
 1475 
 1476 /*
 1477  * Generate the Links for the main pages
 1478  */
 1479 
 1480 void generateLinks(FILE *html, int installed) {
 1481     int i;
 1482 
 1483 #ifdef HAVE_LIBTEMPLATE
 1484     tpl_element_set(engine, "url", rpm2html_url);
 1485 
 1486     parseNwriteTemplate(html, engine, "main_header");
 1487 
 1488 #else   // ifdef HAVE_LIBTEMPLATE
 1489 
 1490     fprintf(html, "<table border=5 cellspacing=5 cellpadding=5>\n");
 1491     fprintf(html, "<tbody>\n<tr>\n");
 1492 
 1493     fprintf(html, "<td><a href=\"%s/%s\">%s</a></td>\n",
 1494             rpm2html_url, localizedStrings[LANG_INDEX_HTML],
 1495         localizedStrings[LANG_INDEX]);
 1496     fprintf(html, "<td><a href=\"%s/%s\">%s</a></td>\n",
 1497             rpm2html_url, localizedStrings[LANG_GROUP_HTML],
 1498         localizedStrings[LANG_SORTED_BY_GROUP]);
 1499     fprintf(html, "<td><a href=\"%s/%s\">%s</a></td>\n",
 1500             rpm2html_url, localizedStrings[LANG_DISTRIB_HTML],
 1501         localizedStrings[LANG_SORTED_BY_DISTRIB]);
 1502     fprintf(html, "<td><a href=\"%s/%s\">%s</a></td>\n",
 1503             rpm2html_url, localizedStrings[LANG_VENDOR_HTML],
 1504         localizedStrings[LANG_SORTED_BY_VENDOR]);
 1505     if (installed)
 1506     fprintf(html, "<td><a href=\"%s/%s\">%s</a></td>\n",
 1507         rpm2html_url, localizedStrings[LANG_BYDATE_HTML],
 1508         localizedStrings[LANG_SORTED_BY_IDATE]);
 1509     else
 1510     fprintf(html, "<td><a href=\"%s/%s\">%s</a></td>\n",
 1511         rpm2html_url, localizedStrings[LANG_BYDATE_HTML],
 1512         localizedStrings[LANG_SORTED_BY_CDATE]);
 1513     fprintf(html, "<td><a href=\"%s/%s\">%s</a></td>\n",
 1514             rpm2html_url, localizedStrings[LANG_BYNAME_HTML],
 1515         localizedStrings[LANG_SORTED_BY_NAME]);
 1516 #endif  // ifdef HAVE_LIBTEMPLATE
 1517 
 1518 #ifdef HAVE_LIBTEMPLATE
 1519     if (buffer == NULL) {
 1520         buffer = (char *) xmlMalloc(buffer_size * sizeof(char));
 1521         if (buffer == NULL) {
 1522             perror("xmlMalloc failed");
 1523             exit(1);
 1524         }
 1525     }
 1526 #endif
 1527     for (i = 0;i < rpm2html_nb_extra_headers;i++) {
 1528 #ifdef HAVE_LIBTEMPLATE
 1529         if ((*rpm2html_headers_url[i] == '/') ||
 1530         (!strncmp(rpm2html_headers_url[i], "http://", 7)) ||
 1531         (!strncmp(rpm2html_headers_url[i], "ftp://", 6)) ||
 1532         (!strncmp(rpm2html_headers_url[i], "mailto", 6)))
 1533         tpl_element_set(engine, "url", rpm2html_headers_url[i]);
 1534     else {
 1535         /* carefull: initial value for buffer_size is 2000 so if URI generated here is longer,
 1536            it'll be truncated thus very likely invalid */
 1537         snprintf(buffer, buffer_size, "%s/%s", rpm2html_url, rpm2html_headers_url[i]);
 1538         tpl_element_set(engine, "url", buffer);
 1539     }
 1540     tpl_element_set(engine, "name", rpm2html_headers_name[i]);
 1541 
 1542         parseNwriteTemplate(html, engine, "main_item");
 1543 
 1544 #else   // ifdef HAVE_LIBTEMPLATE
 1545 
 1546         if ((*rpm2html_headers_url[i] == '/') ||
 1547         (!strncmp(rpm2html_headers_url[i], "http://", 7)) ||
 1548         (!strncmp(rpm2html_headers_url[i], "ftp://", 6)) ||
 1549         (!strncmp(rpm2html_headers_url[i], "mailto", 6)))
 1550         fprintf(html, "<td><a href=\"%s\">%s</a></td>\n",
 1551                 rpm2html_headers_url[i], rpm2html_headers_name[i]);
 1552     else
 1553         fprintf(html, "<td><a href=\"%s/%s\">%s</a></td>\n",
 1554                 rpm2html_url, rpm2html_headers_url[i],
 1555             rpm2html_headers_name[i]);
 1556 #endif  // ifdef HAVE_LIBTEMPLATE
 1557     }
 1558 
 1559 #ifdef HAVE_LIBTEMPLATE
 1560     parseNwriteTemplate(html, engine, "main_footer");
 1561 #else   // ifdef HAVE_LIBTEMPLATE
 1562     fprintf(html, "</tr>\n</tbody></table>\n");
 1563 #endif  // ifdef HAVE_LIBTEMPLATE
 1564 }
 1565 
 1566 /*
 1567  * Generate a color indicator
 1568  */
 1569 
 1570 void generateColorIndicator(FILE *html) {
 1571 #ifdef SHOW_DATE
 1572     int nb = 0;
 1573     rpmDirPtr dir = dirList;
 1574 
 1575 #ifdef HAVE_LIBTEMPLATE
 1576     parseNwriteTemplate(html, engine, "color_indicator_header");
 1577     while (dir != NULL) {
 1578     if (strcasecmp(dir->color, "#ffffff")) {
 1579         if ((nb > 0) && ((nb % MAX_COLOR_PER_LINE) == 0))
 1580         parseNwriteTemplate(html, engine, "color_indicator_eol");
 1581         tpl_element_set(engine, "color", dir->color);
 1582         if (dir->name != NULL)
 1583         tpl_element_set(engine, "item", dir->name);
 1584         else if (dir->mirrors[0] != NULL)
 1585         tpl_element_set(engine, "item", dir->mirrors[0]);
 1586         else
 1587         tpl_element_set(engine, "item", dir->ftp));
 1588             parseNwriteTemplate(html, engine, "color_indicator_item");
 1589         nb++;
 1590     }
 1591     dir = dir->next;
 1592     }
 1593     parseNwriteTemplate(html, engine, "color_indicator_footer");
 1594 
 1595 #else   // ifdef HAVE_LIBTEMPLATE
 1596 
 1597     fprintf(html, "<table align=\"center\"><tbody>\n<tr>\n");
 1598     while (dir != NULL) {
 1599     if (strcasecmp(dir->color, "#ffffff")) {
 1600         if ((nb > 0) && ((nb % MAX_COLOR_PER_LINE) == 0))
 1601         fprintf(html, "</tr><tr>\n");
 1602         fprintf(html, "<td bgcolor=\"%s\">", dir->color);
 1603         if (dir->name != NULL)
 1604         fprintf(html, "%s</td>", dir->name);
 1605         else if (dir->mirrors[0] != NULL)
 1606         fprintf(html, "%s</td>", dir->mirrors[0]);
 1607         else
 1608         fprintf(html, "%s</td>", dir->ftp);
 1609         nb++;
 1610     }
 1611     dir = dir->next;
 1612     }
 1613     fprintf(html, "</tr>\n</tbody></table>\n");
 1614 #endif  // ifdef HAVE_LIBTEMPLATE
 1615 #endif
 1616 }
 1617 
 1618 /*
 1619  * Dump a subtree in an HTML page with all the links
 1620  */
 1621 
 1622 void generateHtmlTree(FILE *html, rpmSubdirPtr tree, int level, int full) {
 1623     int i;
 1624 
 1625     if (tree->html == 0) return;
 1626 
 1627 #ifdef HAVE_LIBTEMPLATE
 1628     if (buffer == NULL) {
 1629         buffer = (char *) xmlMalloc(buffer_size * sizeof(char));
 1630     if (buffer == NULL) {
 1631         perror("xmlMalloc failed");
 1632         exit(1);
 1633     }
 1634     }
 1635     /* carefull: initial value for buffer_size is 2000 so if URI generated here is longer,
 1636        it'll be truncated thus very likely invalid */
 1637 
 1638     if ((tree->nb_subdirs > 0) || (tree->parent != NULL)) {
 1639     if (level == 0) {
 1640         parseNwriteTemplate(html, engine, "html_tree_sublevel_header");
 1641         }
 1642     if (tree->color) {
 1643             tpl_element_set(engine, "color", tree->color);
 1644             tpl_parse(engine, "html_tree_header_color", "p_html_tree_header_color", 0); // XXX maybe not necessary to call this more than once? => optimize to call just once
 1645             tpl_element_set(engine, "color", tpl_element_get(engine, "p_html_tree_header_color"));
 1646         }
 1647         else
 1648             tpl_element_set(engine, "color", "");
 1649     parseNwriteTemplate(html, engine, "html_tree_color");
 1650     if ((level == 0) && (tree->parent != NULL)) {
 1651         if (tree->parent->htmlpath[0] != '\0') {
 1652                 snprintf(buffer, buffer_size, "%s/%s", rpm2html_url, tree->parent->htmlpath);
 1653             tpl_element_set(engine, "url", buffer);
 1654         } else {
 1655                 tpl_element_set(engine, "url", rpm2html_url);
 1656         }
 1657         tpl_element_set(engine, "rpm2html_url", rpm2html_url);
 1658         parseNwriteTemplate(html, engine, "html_tree_header");
 1659     }
 1660     for (i = 0;i < tree->nb_subdirs;i++) {
 1661         if (tree->subdirs[i]->html == 0) continue;
 1662         tpl_element_set(engine, "url", rpm2html_url);
 1663         tpl_element_set(engine, "suburi", tree->subdirs[i]->htmlpath);
 1664         tpl_element_set(engine, "name", tree->subdirs[i]->name);
 1665         parseNwriteTemplate(html, engine, "html_tree_item");
 1666         if (full)
 1667         generateHtmlTree(html, tree->subdirs[i], level + 1, full);
 1668     }
 1669     parseNwriteTemplate(html, engine, "html_tree_footer");
 1670     }
 1671 
 1672 #else   // ifdef HAVE_LIBTEMPLATE
 1673 
 1674     if ((tree->nb_subdirs > 0) || (tree->parent != NULL)) {
 1675     if (level == 0)
 1676         fprintf(html, "<h3>%s</h3>\n", localizedStrings[LANG_SUBDIRS]);
 1677     if (tree->color)
 1678         fprintf(html, "<blockquote style=\"background : %s\">\n",
 1679                 tree->color);
 1680     else
 1681         fprintf(html, "<blockquote>\n");
 1682     if ((level == 0) && (tree->parent != NULL)) {
 1683         if (tree->parent->htmlpath[0] != '\0') {
 1684         fprintf(html, "<p><strong><a href=\"%s/%s/%s\">",
 1685             rpm2html_url, tree->parent->htmlpath,
 1686             localizedStrings[LANG_INDEX_HTML]);
 1687         } else {
 1688         fprintf(html, "<p><strong><a href=\"%s/%s\">",
 1689             rpm2html_url, localizedStrings[LANG_INDEX_HTML]);
 1690         }
 1691         fprintf(html,
 1692             "<img src=\"%s/dir.png\" alt=\"parent-directory\" border=0>",
 1693                 rpm2html_url);
 1694         fprintf(html, " ..</a></strong></p>\n");
 1695     }
 1696     for (i = 0;i < tree->nb_subdirs;i++) {
 1697         if (tree->subdirs[i]->html == 0) continue;
 1698         fprintf(html, "<p><strong><a href=\"%s/%s/%s\">",
 1699             rpm2html_url, tree->subdirs[i]->htmlpath,
 1700             localizedStrings[LANG_INDEX_HTML]);
 1701         fprintf(html,
 1702             "<img src=\"%s/dir.png\" alt=\"sub-directory\" border=0>",
 1703                 rpm2html_url);
 1704         fprintf(html, " %s</a></strong></p>\n", tree->subdirs[i]->name);
 1705         if (full)
 1706         generateHtmlTree(html, tree->subdirs[i], level + 1, full);
 1707     }
 1708     fprintf(html, "</blockquote>\n");
 1709     }
 1710 #endif  // ifdef HAVE_LIBTEMPLATE
 1711 }
 1712 
 1713 /*
 1714  * Dump the parent names in an HTML page with all the links
 1715  */
 1716 
 1717 void generateHtmlParentsNames(FILE *html, rpmSubdirPtr tree) {
 1718     int i, j, k;
 1719     rpmSubdirPtr parent;
 1720 
 1721     if (tree->parent == NULL) return;
 1722 
 1723     /*
 1724      * get the tree depth.
 1725      */
 1726     i = 0;
 1727     parent = tree->parent;
 1728     while ((parent != NULL) && (parent->parent != NULL)) {
 1729         i++;
 1730     parent = parent->parent;
 1731     }
 1732 
 1733     /*
 1734      * Dump each level in the parent tree.
 1735      */
 1736 #ifdef HAVE_LIBTEMPLATE
 1737     if (buffer == NULL) {
 1738         buffer = (char *) xmlMalloc(buffer_size * sizeof(char));
 1739     if (buffer == NULL) {
 1740         perror("xmlMalloc failed");
 1741         exit(1);
 1742     }
 1743     }
 1744     /* carefull: initial value for buffer_size is 2000 so if URI generated here is longer,
 1745        it'll be truncated thus very likely invalid */
 1746 
 1747     for (j = i; j >= 0;j--) {
 1748     parent = tree;
 1749         for (k = 0;k < j;k++) parent = parent->parent;
 1750     if (parent->htmlpath[0] != '\0') {
 1751             snprintf(buffer, buffer_size, "%s/%s", rpm2html_url, parent->htmlpath);
 1752             tpl_element_set(engine, "url", buffer);
 1753     } else {
 1754             tpl_element_set(engine, "url", rpm2html_url);
 1755     }
 1756     tpl_element_set(engine, "name", parent->name);
 1757     if (j != 0) {
 1758         tpl_parse(engine, "parent_names_separator", "p_parent_names_separator", 0); // XXX maybe not necessary to call this more than once? => optimize to call just once
 1759             tpl_element_set(engine, "separator", tpl_element_get(engine, "p_parent_names_separator"));
 1760         }
 1761         else
 1762             tpl_element_set(engine, "separator", "");
 1763     parseNwriteTemplate(html, engine, "parent_names");
 1764     }
 1765 
 1766 #else   // ifdef HAVE_LIBTEMPLATE
 1767 
 1768     for (j = i; j >= 0;j--) {
 1769     parent = tree;
 1770         for (k = 0;k < j;k++) parent = parent->parent;
 1771     if (parent->htmlpath[0] != '\0') {
 1772         fprintf(html, "<a href=\"%s/%s/%s\">",
 1773             rpm2html_url, parent->htmlpath,
 1774             localizedStrings[LANG_INDEX_HTML]);
 1775     } else {
 1776         fprintf(html, "<a href=\"%s/%s\">", rpm2html_url,
 1777             localizedStrings[LANG_INDEX_HTML]);
 1778     }
 1779     fprintf(html, "%s</a>\n", parent->name);
 1780     if (j != 0) fprintf(html, " / ");
 1781     }
 1782 #endif  // ifdef HAVE_LIBTEMPLATE
 1783 }
 1784 
 1785 /*
 1786  * Dump the whole index for a full complete config file.
 1787  */
 1788 void dumpIndex(time_t start_time, int installed) {
 1789     FILE *html;
 1790 
 1791     if (!rpm2html_dump_html) return;
 1792 
 1793     if (rpm2htmlVerbose > 1) {
 1794     printf("Dumping %s/%s\n", rpm2html_dir, localizedStrings[LANG_INDEX_HTML]);
 1795     }
 1796     snprintf(buf, sizeof(buf), "%s/%s", rpm2html_dir, localizedStrings[LANG_INDEX_HTML]);
 1797 
 1798     html = fopen(buf, "w");
 1799     if (html == NULL) {
 1800         fprintf(stderr, "Couldn't save to file %s: %s\n",
 1801             buf, strerror(errno));
 1802         return;
 1803     }
 1804 
 1805 #ifdef HAVE_LIBTEMPLATE
 1806     tpl_element_set(engine, "host", rpm2html_host);
 1807     if (installed) {
 1808     generateHtmlHeader(html, "header_title_install", NULL);
 1809     generateLinks(html, installed);
 1810     } else {
 1811     generateHtmlHeader(html, "header_title_repository", NULL);
 1812     generateLinks(html, installed);
 1813     }
 1814 #ifdef WITH_SQL
 1815     tpl_element_set(engine, "search_host", rpm2html_host);
 1816 #else
 1817     tpl_element_set(engine, "search_host", "rpmfind.net");
 1818 #endif
 1819 
 1820     if (rpm2html_install_files != 0) {
 1821         snprintf(buf, sizeof(buf), "%d", rpm2html_install_files);
 1822         tpl_element_set(engine, "count", buf);
 1823         snprintf(buf, sizeof(buf), "%d", rpm2html_install_size / 1024);
 1824         tpl_element_set(engine, "size", buf);
 1825         tpl_parse(engine, "index_header_stats_installed", "p_stats", 0);
 1826     }
 1827     if (rpm2html_files != 0) {
 1828         snprintf(buf, sizeof(buf), "%d", rpm2html_files);
 1829         tpl_element_set(engine, "count", buf);
 1830         snprintf(buf, sizeof(buf), "%d", rpm2html_size / 1024);
 1831         tpl_element_set(engine, "size", buf);
 1832         tpl_parse(engine, "index_header_stats_repository", "p_stats", 0);
 1833     }
 1834     tpl_element_set(engine, "stats", tpl_element_get(engine, "p_stats"));
 1835 
 1836     parseNwriteTemplate(html, engine, "index_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 1837       // later reconsider usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 1838 
 1839     generateHtmlTree(html, dirTree, 0, 0);
 1840 
 1841     snprintf(buf, sizeof(buf), "%d", (int) (time(NULL) - start_time));
 1842     tpl_element_set(engine, "generation_time", buf);
 1843     
 1844     parseNwriteTemplate(html, engine, "index_footer");
 1845 
 1846 #else   // ifdef HAVE_LIBTEMPLATE
 1847 
 1848     if (installed) {
 1849     snprintf(buf, sizeof(buf), "%s %s", localizedStrings[LANG_WELCOME_INSTALL],
 1850             rpm2html_host);
 1851     generateHtmlHeader(html, buf, NULL);
 1852     generateLinks(html, installed);
 1853     fprintf(html, "<h1 align=center>%s %s</h1>\n",
 1854         localizedStrings[LANG_WELCOME_INSTALL], rpm2html_host);
 1855     } else {
 1856     snprintf(buf, sizeof(buf), "%s %s", localizedStrings[LANG_WELCOME_REPOSITORY],
 1857             rpm2html_host);
 1858     generateHtmlHeader(html, buf, NULL);
 1859     generateLinks(html, installed);
 1860     fprintf(html, "<h1 align=center>%s %s</h1>\n",
 1861         localizedStrings[LANG_WELCOME_REPOSITORY], rpm2html_host);
 1862     }
 1863 
 1864     fprintf(html, "%s\n", localizedStrings[LANG_RPM2HTML_INTRO]);
 1865 #ifdef WITH_SQL
 1866     snprintf(buf, sizeof(buf), "http://%s/linux/rpm2html", rpm2html_host);
 1867     fprintf(html, localizedStrings[LANG_SEARCH_FORM], buf);
 1868 #else
 1869     fprintf(html, localizedStrings[LANG_SEARCH_FORM],
 1870         "http://rpmfind.net/linux/rpm2html");
 1871 #endif
 1872     if (rpm2html_install_files != 0) {
 1873     fprintf(html, "<h3>");
 1874     fprintf(html, localizedStrings[LANG_INSTALLED_STATS],
 1875         rpm2html_install_files, rpm2html_install_size / 1024);
 1876     fprintf(html, "</h3>\n");
 1877     }
 1878     if (rpm2html_files != 0) {
 1879     fprintf(html, "<h3>");
 1880     fprintf(html, localizedStrings[LANG_STATS],
 1881         rpm2html_files, rpm2html_size / 1024);
 1882     fprintf(html, "</h3>\n");
 1883     }
 1884     fprintf(html, "<ul>\n");
 1885     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 1886             localizedStrings[LANG_LIST],
 1887         localizedStrings[LANG_GROUP_HTML],
 1888         localizedStrings[LANG_INDEX_GROUP]);
 1889     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 1890             localizedStrings[LANG_LIST],
 1891         localizedStrings[LANG_BYDATE_HTML],
 1892         localizedStrings[LANG_INDEX_CREATION]);
 1893     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 1894             localizedStrings[LANG_LIST],
 1895         localizedStrings[LANG_BYNAME_HTML],
 1896         localizedStrings[LANG_INDEX_NAME]);
 1897     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 1898             localizedStrings[LANG_LIST],
 1899         localizedStrings[LANG_VENDOR_HTML],
 1900         localizedStrings[LANG_INDEX_VENDOR]);
 1901     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 1902             localizedStrings[LANG_LIST],
 1903         localizedStrings[LANG_DISTRIB_HTML],
 1904         localizedStrings[LANG_INDEX_DISTRIB]);
 1905     fprintf(html, "</ul>\n");
 1906 
 1907     generateHtmlTree(html, dirTree, 0, 0);
 1908 
 1909     fprintf(html, "<p>%s %d %s</p>\n",
 1910             localizedStrings[LANG_GENERATION_TIME],
 1911             (int) (time(NULL) - start_time),
 1912             localizedStrings[LANG_SECONDS]);
 1913 #endif  // ifdef HAVE_LIBTEMPLATE
 1914     generateHtmlFooter(html);
 1915     fclose(html);
 1916 }
 1917 
 1918 /*
 1919  * Dump the whole index for a full complete config file.
 1920  */
 1921 void dumpTopIndex(rpmDirPtr *sqlDirList) {
 1922     FILE *html;
 1923     int i;
 1924 
 1925     if (!rpm2html_dump_html) return;
 1926 
 1927     if (rpm2htmlVerbose > 1) {
 1928     printf("Dumping %s/%s\n", rpm2html_dir, localizedStrings[LANG_INDEX_HTML]);
 1929     }
 1930     snprintf(buf, sizeof(buf), "%s/%s", rpm2html_dir, localizedStrings[LANG_INDEX_HTML]);
 1931 
 1932     html = fopen(buf, "w");
 1933     if (html == NULL) {
 1934         fprintf(stderr, "Couldn't save to file %s: %s\n",
 1935             buf, strerror(errno));
 1936         return;
 1937     }
 1938 
 1939 #ifdef HAVE_LIBTEMPLATE
 1940     tpl_element_set(engine, "host", rpm2html_host);
 1941     generateHtmlHeader(html, "header_title_repository", NULL);
 1942     generateLinks(html, 0);
 1943 #ifdef WITH_SQL
 1944     tpl_element_set(engine, "search_host", rpm2html_host);
 1945 #else
 1946     tpl_element_set(engine, "search_host", "rpmfind.net");
 1947 #endif
 1948 
 1949     if (rpm2html_install_files != 0) {
 1950         snprintf(buf, sizeof(buf), "%d", rpm2html_install_files);
 1951         tpl_element_set(engine, "count", buf);
 1952         snprintf(buf, sizeof(buf), "%d", rpm2html_install_size / 1024);
 1953         tpl_element_set(engine, "size", buf);
 1954         tpl_parse(engine, "index_header_stats_installed", "p_stats", 0);
 1955     }
 1956     if (rpm2html_files != 0) {
 1957         snprintf(buf, sizeof(buf), "%d", rpm2html_files);
 1958         tpl_element_set(engine, "count", buf);
 1959         snprintf(buf, sizeof(buf), "%d", rpm2html_size / 1024);
 1960         tpl_element_set(engine, "size", buf);
 1961         tpl_parse(engine, "index_header_stats_repository", "p_stats", 0);
 1962     }
 1963     tpl_element_set(engine, "stats", tpl_element_get(engine, "p_stats"));
 1964 
 1965     parseNwriteTemplate(html, engine, "index_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 1966       // later reconsicer usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 1967 
 1968     if (sqlDirList != NULL) {
 1969     for (i = 0; i < 500;i++)
 1970         if (sqlDirList[i] != NULL) {
 1971         /*
 1972          * Check first that the distro is still active and that
 1973          * the index has been generated
 1974          */
 1975         if (!checkDirectory(sqlDirList[i]->rpmdir))
 1976             continue;
 1977         snprintf(buf, sizeof(buf), "%s/%s/index.html",
 1978              sqlDirList[i]->dir, sqlDirList[i]->subdir);
 1979         if (!checkFile(buf))
 1980             continue;
 1981 
 1982                 tpl_element_set(engine, "url", sqlDirList[i]->url);
 1983                 tpl_element_set(engine, "suburl", sqlDirList[i]->subdir);
 1984                 tpl_element_set(engine, "name", sqlDirList[i]->name);
 1985                 parseNwriteTemplate(html, engine, "index_sql_dirlist");
 1986         }
 1987     }
 1988 
 1989 #else   // ifdef HAVE_LIBTEMPLATE
 1990 
 1991     snprintf(buf, sizeof(buf), "%s %s", localizedStrings[LANG_WELCOME_REPOSITORY],
 1992         rpm2html_host);
 1993     generateHtmlHeader(html, buf, NULL);
 1994     generateLinks(html, 0);
 1995     fprintf(html, "<h1 align=center>%s %s</h1>\n",
 1996         localizedStrings[LANG_WELCOME_REPOSITORY], rpm2html_host);
 1997 
 1998     fprintf(html, "%s\n", localizedStrings[LANG_RPM2HTML_INTRO]);
 1999 #ifdef WITH_SQL
 2000     snprintf(buf, sizeof(buf), "http://%s/linux/rpm2html", rpm2html_host);
 2001     fprintf(html, localizedStrings[LANG_SEARCH_FORM], buf);
 2002 #else
 2003     fprintf(html, localizedStrings[LANG_SEARCH_FORM],
 2004         "http://rpmfind.net/linux/rpm2html");
 2005 #endif
 2006     if (rpm2html_install_files != 0) {
 2007     fprintf(html, "<h3>");
 2008     fprintf(html, localizedStrings[LANG_INSTALLED_STATS],
 2009         rpm2html_install_files, rpm2html_install_size / 1024);
 2010     fprintf(html, "</h3>\n");
 2011     }
 2012     if (rpm2html_files != 0) {
 2013     fprintf(html, "<h3>");
 2014     fprintf(html, localizedStrings[LANG_STATS],
 2015         rpm2html_files, rpm2html_size / 1024);
 2016     fprintf(html, "</h3>\n");
 2017     }
 2018     fprintf(html, "<ul>\n");
 2019     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 2020             localizedStrings[LANG_LIST],
 2021         localizedStrings[LANG_GROUP_HTML],
 2022         localizedStrings[LANG_INDEX_GROUP]);
 2023     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 2024             localizedStrings[LANG_LIST],
 2025         localizedStrings[LANG_BYDATE_HTML],
 2026         localizedStrings[LANG_INDEX_CREATION]);
 2027     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 2028             localizedStrings[LANG_LIST],
 2029         localizedStrings[LANG_BYNAME_HTML],
 2030         localizedStrings[LANG_INDEX_NAME]);
 2031     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 2032             localizedStrings[LANG_LIST],
 2033         localizedStrings[LANG_VENDOR_HTML],
 2034         localizedStrings[LANG_INDEX_VENDOR]);
 2035     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 2036             localizedStrings[LANG_LIST],
 2037         localizedStrings[LANG_DISTRIB_HTML],
 2038         localizedStrings[LANG_INDEX_DISTRIB]);
 2039     fprintf(html, "</ul>\n");
 2040 
 2041     if (sqlDirList != NULL) {
 2042     for (i = 0; i < 500;i++)
 2043         if (sqlDirList[i] != NULL) {
 2044         /*
 2045          * Check first that the distro is still active and that
 2046          * the index has been generated
 2047          */
 2048         if (!checkDirectory(sqlDirList[i]->rpmdir))
 2049             continue;
 2050         snprintf(buf, sizeof(buf), "%s/%s/index.html",
 2051              sqlDirList[i]->dir, sqlDirList[i]->subdir);
 2052         if (!checkFile(buf))
 2053             continue;
 2054 
 2055         fprintf(html,
 2056 "<p><strong><a href=\"%s/%s/index.html\"><img src=\"/linux/RPM/dir.png\" alt=\"sub-directory\" border=0>%s</a></strong></p>\n",
 2057                         sqlDirList[i]->url, sqlDirList[i]->subdir,
 2058             sqlDirList[i]->name);
 2059 
 2060         }
 2061     }
 2062 #endif  // ifdef HAVE_LIBTEMPLATE
 2063 
 2064     generateHtmlFooter(html);
 2065     fclose(html);
 2066 }
 2067 
 2068 /*
 2069  * Dump an RPM block as an HTML file.
 2070  */
 2071 
 2072 void dumpRpmHtml(rpmDataPtr rpm, rpmSubdirPtr tree) {
 2073     struct tm * tstruct;
 2074     rpmDirPtr dir = rpm->dir;
 2075     int installed = dir->installbase;
 2076     FILE *html;
 2077     int i;
 2078 
 2079     if (!rpm2html_dump_html) return;
 2080 
 2081     /*
 2082      * create the directory on the fly if needed.
 2083      */
 2084     if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
 2085     if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
 2086         snprintf(buf, sizeof(buf), "%s/%s/%s", dir->dir, dir->subdir,
 2087                 rpm->subdir);
 2088     else
 2089         snprintf(buf, sizeof(buf), "%s/%s", dir->dir, dir->subdir);
 2090     } else {
 2091     if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
 2092         snprintf(buf, sizeof(buf), "%s/%s", dir->dir, rpm->subdir);
 2093     else
 2094         snprintf(buf, sizeof(buf), "%s", dir->dir);
 2095     }
 2096 
 2097     createDirectory(buf);
 2098     strcat(buf, "/");
 2099     strcat(buf, rpmName(rpm));
 2100     strcat(buf, ".html");
 2101 
 2102     if (!needsDump(buf, rpm->extra->stamp))
 2103         return;
 2104 
 2105     if (rpm2htmlVerbose > 1) {
 2106         printf("Dumping %s\n", buf);
 2107     }
 2108 
 2109     html = fopen(buf, "w");
 2110     if (html == NULL) {
 2111         fprintf(stderr, "Couldn't save to file %s: %s\n",
 2112             buf, strerror(errno));
 2113         return;
 2114     }
 2115 #ifdef HAVE_LIBTEMPLATE
 2116     tpl_element_set(engine, "name", rpmName(rpm));
 2117     generateHtmlHeader(html, "rpm_title", NULL);
 2118     generateLinks(html, installed);
 2119     if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
 2120     if (dir->mirrors[0] != NULL)
 2121         snprintf(buf, sizeof(buf), "%s/%s/%s", dir->mirrors[0], rpm->subdir, rpm->filename);
 2122     else
 2123         snprintf(buf, sizeof(buf), "%s/%s/%s", dir->ftp, rpm->subdir, rpm->filename);
 2124     } else {
 2125     if (dir->mirrors[0] != NULL)
 2126         snprintf(buf, sizeof(buf), "%s/%s", dir->mirrors[0], rpm->filename);
 2127     else
 2128         snprintf(buf, sizeof(buf), "%s/%s", dir->ftp, rpm->filename);
 2129     }
 2130     tpl_element_set(engine, "url", buf);
 2131     tpl_element_set(engine, "name", rpm->name);
 2132     tpl_element_set(engine, "version", rpm->version);
 2133     tpl_element_set(engine, "release", rpm->release);
 2134     if (rpm->arch) {
 2135         if (!strcmp(rpm->arch, "src"))
 2136             tpl_parse(engine, "rpm_subtitle_src", "p_subtitle", 0);
 2137         else {
 2138             tpl_element_set(engine, "arch", rpm->arch);
 2139             tpl_parse(engine, "rpm_subtitle_arch", "p_subtitle", 0);
 2140         }
 2141     } else
 2142         tpl_parse(engine, "rpm_subtitle_arch_unknown", "p_subtitle", 0);
 2143     tpl_element_set(engine, "subtitle", tpl_element_get(engine, "p_subtitle"));
 2144     parseNwriteTemplate(html, engine, "rpm_subtitle");
 2145 
 2146     parseNwriteTemplate(html, engine, "rpm_subsubtitle_begin");
 2147     if ((tree != NULL) && (tree->parent != NULL)) {
 2148     generateHtmlParentsNames(html, tree);
 2149     } else if (dir->name) {
 2150         tpl_element_set(engine, "name", dir->name);
 2151         if (dir->ftp) {
 2152             tpl_element_set(engine, "url", dir->ftp);
 2153             parseNwriteTemplate(html, engine, "rpm_subsubtitle_body");
 2154         }
 2155         else
 2156             parseNwriteTemplate(html, engine, "rpm_subsubtitle_body_nourl");
 2157     }
 2158     parseNwriteTemplate(html, engine, "rpm_subsubtitle_end");
 2159 
 2160     tpl_element_set(engine, "color", dir->color);
 2161     tpl_element_set(engine, "name", rpm->name);
 2162     tpl_element_set(engine, "url", rpm2html_url);
 2163     tpl_element_set(engine, "distrib_url", distribName(rpm->distribution));
 2164     tpl_element_set(engine, "distribution", convertHTML(rpm->distribution));
 2165     tpl_element_set(engine, "version", rpm->version);
 2166     tpl_element_set(engine, "vendor_url", vendorName(rpm->vendor));
 2167     tpl_element_set(engine, "vendor", convertHTML(rpm->vendor));
 2168     tstruct = localtime(&(rpm->date));
 2169 #ifdef HAVE_STRFTIME
 2170     strftime(buf, sizeof(buf) - 1, "%c", tstruct);
 2171 #else
 2172 #error "no strftime, please check !"
 2173 #endif
 2174     tpl_element_set(engine, "release", rpm->release);
 2175     tpl_element_set(engine, "date", buf);
 2176     if (installed)
 2177         tpl_parse(engine, "rpm_body_date_install", "p_date_title", 0);
 2178     else
 2179         tpl_parse(engine, "rpm_body_date_build", "p_date_title", 0);
 2180     tpl_element_set(engine, "date_title", tpl_element_get(engine, "p_date_title"));
 2181     if (rpm2html_url != NULL) {
 2182         snprintf(buf, sizeof(buf), "%s/%s", rpm2html_url, groupName(rpm->group));
 2183         tpl_element_set(engine, "group_url", buf);
 2184     }
 2185     else
 2186         tpl_element_set(engine, "group_url", groupName(rpm->group));
 2187     tpl_element_set(engine, "group_url", buf);
 2188     tpl_element_set(engine, "group", convertHTML(rpm->group));
 2189     tpl_element_set(engine, "build_host", rpm->extra->host);
 2190     snprintf(buf, sizeof(buf), "%d", rpm->size);
 2191     tpl_element_set(engine, "size", buf);
 2192     tpl_element_set(engine, "srcrpm_name", rpm->extra->srcrpm);
 2193     if (dir->ftpsrc) {
 2194         snprintf(buf, sizeof(buf), "%s/%s", dir->ftpsrc, rpm->extra->srcrpm);
 2195         tpl_element_set(engine, "srcrpm_url", buf);
 2196         tpl_parse(engine, "rpm_body_src_rpm_name_and_url", "p_source_rpm", 0);
 2197     } else {
 2198         tpl_parse(engine, "rpm_body_src_rpm_name", "p_source_rpm", 0);
 2199     }
 2200     tpl_element_set(engine, "source_rpm", tpl_element_get(engine, "p_source_rpm"));
 2201     if (rpm->extra->packager) {
 2202         tpl_element_set(engine, "packager", convertHTML(rpm->extra->packager));
 2203         char *email = extractEMail(rpm->extra->packager);
 2204     if (email == NULL)
 2205         tpl_parse(engine, "rpm_body_packager_without_email", "p_packager", 0);
 2206         else {
 2207         tpl_element_set(engine, "packager_email", email);
 2208         tpl_parse(engine, "rpm_body_packager_with_email", "p_packager", 0);
 2209         }
 2210         tpl_element_set(engine, "packager", tpl_element_get(engine, "p_packager"));
 2211     }
 2212     else
 2213         tpl_element_set(engine, "packager", "");
 2214     if (rpm->url)
 2215         tpl_element_set(engine, "home_url", rpm->url);
 2216     else
 2217         tpl_element_set(engine, "home_url", "");
 2218     tpl_element_set(engine, "summary", convertHTML(rpm->summary));
 2219     tpl_element_set(engine, "description", convertHTML(rpm->extra->description));
 2220     parseNwriteTemplate(html, engine, "rpm_body");
 2221 
 2222     if ((rpm->extra->nb_resources + rpm->extra->nb_requires < 2) &&
 2223         (!strstr(rpm->name, "lib")) &&
 2224     (!strcmp(rpm->arch, "src"))) {
 2225 
 2226         if (rpm2htmlVerbose > 1)
 2227             fprintf(stderr, "Resource lists problem : %s\n", rpmName(rpm));
 2228         tpl_element_set(engine, "url", rpm2html_url);
 2229         tpl_element_set(engine, "suburl", resourceName(rpm->name));
 2230         parseNwriteTemplate(html, engine, "rpm_resource_list_problem");
 2231     }
 2232     if (rpm->extra->nb_resources > 0) {
 2233        parseNwriteTemplate(html, engine, "rpm_provides_header");
 2234        for (i = 0;i < rpm->extra->nb_resources;i++) {
 2235 #ifdef WITH_SQL
 2236            if (rpm2html_search != NULL)
 2237                snprintf(buf, sizeof(buf), "%s?query=%s", rpm2html_search,
 2238                    escapeName(rpm->extra->resources[i]->name));
 2239        else
 2240 #endif
 2241        if (rpm2html_url != NULL)
 2242            snprintf(buf, sizeof(buf), "%s/%s", rpm2html_url,
 2243                resourceName(rpm->extra->resources[i]->name));
 2244        else
 2245            snprintf(buf, sizeof(buf), "%s", resourceName(rpm->extra->resources[i]->name));
 2246            tpl_element_set(engine, "url", buf);
 2247            tpl_element_set(engine, "name", rpm->extra->resources[i]->name);
 2248            parseNwriteTemplate(html, engine, "rpm_provides_item");
 2249        }
 2250        parseNwriteTemplate(html, engine, "rpm_provides_footer");
 2251     }
 2252     if (rpm->extra->nb_requires > 0) {
 2253        parseNwriteTemplate(html, engine, "rpm_requires_header");
 2254        for (i = 0;i < rpm->extra->nb_requires;i++) {
 2255        if ((rpm->extra->requires[i]->flag != RPM2HTML_REQ_NONE) &&
 2256            (rpm->extra->requires[i]->version != NULL)) {
 2257            snprintf(buf, sizeof(buf), " %s %s", html_flags[rpm->extra->requires[i]->flag],
 2258                rpm->extra->requires[i]->version);
 2259                tpl_element_set(engine, "version", buf);
 2260            } else
 2261                tpl_element_set(engine, "version", "");
 2262 #ifdef WITH_SQL
 2263            if (rpm2html_search != NULL) {
 2264                snprintf(buf, sizeof(buf), "%s?query=%s", rpm2html_search,
 2265            escapeName(rpm->extra->requires[i]->name));
 2266                tpl_element_set(engine, "url", buf);
 2267        } else 
 2268 #endif
 2269        if (rpm2html_url != NULL) {
 2270            snprintf(buf, sizeof(buf), "%s/%s", rpm2html_url,
 2271                resourceName(rpm->extra->requires[i]->name));
 2272                tpl_element_set(engine, "url", buf);
 2273        } else {
 2274            tpl_element_set(engine, "url", resourceName(rpm->extra->requires[i]->name));
 2275        }
 2276            tpl_element_set(engine, "name", rpm->extra->requires[i]->name);
 2277            parseNwriteTemplate(html, engine, "rpm_requires_item");
 2278        }
 2279        parseNwriteTemplate(html, engine, "rpm_requires_footer");
 2280     }
 2281     if (rpm->extra->copyright) {
 2282        tpl_element_set(engine, "copyright", convertHTML(rpm->extra->copyright));
 2283        parseNwriteTemplate(html, engine, "rpm_copyright");
 2284     }
 2285     if (rpm->extra->sigs != NULL) {
 2286         parseNwriteTemplate(html, engine, "rpm_signatures_header");
 2287     for(i = 0; i < rpm->extra->nb_sigs; i++) {
 2288         tpl_element_set(engine, "signature", convertHTML(convertSIG(rpm->extra->sigs[i])));
 2289         parseNwriteTemplate(html, engine, "rpm_signatures_item");
 2290         }
 2291     }
 2292     if (rpm->extra->changelog) {
 2293         tpl_element_set(engine, "changelog", convertCVE(convertHTML(rpm->extra->changelog)));
 2294         parseNwriteTemplate(html, engine, "rpm_changelog");
 2295     }
 2296     parseNwriteTemplate(html, engine, "rpm_files_header");
 2297     if (rpm->extra->filelist == NULL)
 2298         parseNwriteTemplate(html, engine, "rpm_files_body_no_files");
 2299     else {
 2300         tpl_element_set(engine, "files", rpm->extra->filelist);
 2301         parseNwriteTemplate(html, engine, "rpm_files_body");
 2302     }
 2303 
 2304 #else   // ifdef HAVE_LIBTEMPLATE
 2305 
 2306     snprintf(buf, sizeof(buf), "%s RPM", rpmName(rpm));
 2307     generateHtmlHeader(html, buf, NULL);
 2308     generateLinks(html, installed);
 2309     if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
 2310     if (dir->mirrors[0] != NULL)
 2311         fprintf(html, "<h1 align=center><a href=\"%s/%s/%s\">\n",
 2312         dir->mirrors[0], rpm->subdir, rpm->filename);
 2313     else
 2314         fprintf(html, "<h1 align=center><a href=\"%s/%s/%s\">\n",
 2315         dir->ftp, rpm->subdir, rpm->filename);
 2316     } else {
 2317     if (dir->mirrors[0] != NULL)
 2318         fprintf(html, "<h1 align=center><a href=\"%s/%s\">\n",
 2319         dir->mirrors[0], rpm->filename);
 2320     else
 2321         fprintf(html, "<h1 align=center><a href=\"%s/%s\">\n",
 2322         dir->ftp, rpm->filename);
 2323     }
 2324     if (rpm->arch) {
 2325         if (!strcmp(rpm->arch, "src"))
 2326         fprintf(html, "%s-%s-%s Source RPM</a></h1>\n",
 2327                 rpm->name, rpm->version, rpm->release);
 2328         else
 2329         fprintf(html, "%s-%s-%s RPM for %s</a></h1>\n",
 2330         rpm->name, rpm->version, rpm->release, rpm->arch);
 2331     } else {
 2332     fprintf(html, "%s-%s-%s RPM</a></h1>\n",
 2333             rpm->name, rpm->version, rpm->release);
 2334     }
 2335 
 2336     if ((tree != NULL) && (tree->parent != NULL)) {
 2337     fprintf(html, "<h3 align=center>%s ", localizedStrings[LANG_FROM]);
 2338     generateHtmlParentsNames(html, tree);
 2339     fprintf(html, "</h3>\n");
 2340     } else if (dir->name) {
 2341         fprintf(html, "<h3 align=center>%s <a href=\"%s\">%s</a></h3>\n",
 2342           localizedStrings[LANG_FROM],
 2343           dir->ftp, dir->name);
 2344     }
 2345 
 2346     fprintf(html, "<table align=center border=5 cellspacing=5 cellpadding=5 bgcolor=\"%s\">", dir->color);
 2347     fprintf(html, "<tbody>\n");
 2348     fprintf(html, "<tr><td>%s: %s</td>\n",
 2349         localizedStrings[LANG_NAME],
 2350             rpm->name);
 2351     fprintf(html, "<td>%s: <a href=\"%s/%s\">%s</a></td></tr>\n",
 2352         localizedStrings[LANG_DISTRIBUTION], rpm2html_url,
 2353             distribName(rpm->distribution), convertHTML(rpm->distribution));
 2354     fprintf(html, "<tr><td>%s: %s</td>\n",
 2355         localizedStrings[LANG_VERSION],
 2356             rpm->version);
 2357     fprintf(html, "<td>%s: <a href=\"%s/%s\">%s</a></td></tr>\n",
 2358         localizedStrings[LANG_VENDOR], rpm2html_url,
 2359             vendorName(rpm->vendor), convertHTML(rpm->vendor));
 2360     tstruct = localtime(&(rpm->date));
 2361 #ifdef HAVE_STRFTIME
 2362     strftime(buf, sizeof(buf) - 1, "%c", tstruct);
 2363 #else
 2364 #error "no strftime, please check !"
 2365 #endif
 2366     if (installed) {
 2367     fprintf(html, "<tr><td>%s: %s</td>\n<td>%s: %s</td></tr>\n",
 2368         localizedStrings[LANG_RELEASE],
 2369         rpm->release,
 2370         localizedStrings[LANG_INSTALL_DATE],
 2371         buf);
 2372     } else {
 2373     fprintf(html, "<tr><td>%s: %s</td>\n<td>%s: %s</td></tr>\n",
 2374         localizedStrings[LANG_RELEASE],
 2375         rpm->release,
 2376         localizedStrings[LANG_BUILD_DATE],
 2377         buf);
 2378     }
 2379     if (rpm2html_url != NULL)
 2380     fprintf(html, "<tr><td>%s: <a href=\"%s/%s\">%s</a></td>\n",
 2381         localizedStrings[LANG_GROUP], rpm2html_url,
 2382         groupName(rpm->group), convertHTML(rpm->group));
 2383     else
 2384     fprintf(html, "<tr><td>%s: <a href=\"%s\">%s</a></td>\n",
 2385         localizedStrings[LANG_GROUP],
 2386         groupName(rpm->group), convertHTML(rpm->group));
 2387     fprintf(html, "<td>%s: %s</td></tr>\n",
 2388         localizedStrings[LANG_BUILD_HOST], rpm->extra->host);
 2389     fprintf(html, "<tr><td>%s: %d</td>\n",
 2390         localizedStrings[LANG_SIZE],
 2391             rpm->size);
 2392     if (dir->ftpsrc) {
 2393     fprintf(html, "<td>%s: <a href=\"%s/%s\">%s</a></td></tr>\n",
 2394             localizedStrings[LANG_RPM_SRC],
 2395         dir->ftpsrc, rpm->extra->srcrpm, rpm->extra->srcrpm);
 2396     } else {
 2397     fprintf(html, "<td>%s: %s</td></tr>\n",
 2398             localizedStrings[LANG_RPM_SRC],
 2399         rpm->extra->srcrpm);
 2400     }
 2401     if (rpm->extra->packager) {
 2402         char *email = extractEMail(rpm->extra->packager);
 2403     if (email == NULL)
 2404         fprintf(html, "<tr><td colspan=\"2\">%s: %s</td></tr>\n",
 2405             localizedStrings[LANG_PACKAGER],
 2406             convertHTML(rpm->extra->packager));
 2407         else
 2408         fprintf(html, "<tr><td colspan=\"2\">%s: <a href=\"mailto:%s\">%s</a></td></tr>\n",
 2409             localizedStrings[LANG_PACKAGER],
 2410             email, convertHTML(rpm->extra->packager));
 2411     }
 2412     if (rpm->url)
 2413     fprintf(html, "<tr><td colspan=\"2\">%s: <a href=\"%s\">%s</a></td></tr>\n",
 2414         localizedStrings[LANG_URL],
 2415         rpm->url, rpm->url);
 2416     fprintf(html, "<tr><td colspan=\"2\">%s: %s</td></tr>\n",
 2417         localizedStrings[LANG_SUMMARY],
 2418             convertHTML(rpm->summary));
 2419     fprintf(html, "</tbody>\n</table>\n");
 2420     fprintf(html, "<pre>%s\n</pre>\n", convertHTML(rpm->extra->description));
 2421     if ((rpm->extra->nb_resources + rpm->extra->nb_requires < 2) &&
 2422         (!strstr(rpm->name, "lib")) &&
 2423     (!strcmp(rpm->arch, "src"))) {
 2424        if (rpm2htmlVerbose > 1)
 2425        fprintf(stderr, "Resource lists problem : %s\n", rpmName(rpm));
 2426        fprintf(html, "<h2 align=center style=\"color : #ff0000\">%s</h2>\n",
 2427                localizedStrings[LANG_WARNING_RESOURCES]);
 2428        fprintf(html, "<h2 align=center><a href=\"%s/%s\">%s</a></h2>\n",
 2429                rpm2html_url, resourceName(rpm->name),
 2430                localizedStrings[LANG_CHOOSE_ANOTHER]);
 2431     }
 2432     if (rpm->extra->nb_resources > 0) {
 2433        fprintf(html, "<h3>%s</h3>\n",
 2434         localizedStrings[LANG_PROVIDE]);
 2435        fprintf(html, "<ul>\n");
 2436        for (i = 0;i < rpm->extra->nb_resources;i++) {
 2437 #ifdef WITH_SQL
 2438            if (rpm2html_search != NULL)
 2439            fprintf(html, "<li><a href=\"%s?query=%s\">%s</a>\n",
 2440            rpm2html_search,
 2441            escapeName(rpm->extra->resources[i]->name),
 2442            rpm->extra->resources[i]->name);
 2443        else
 2444 #endif
 2445        if (rpm2html_url != NULL)
 2446            fprintf(html, "<li><a href=\"%s/%s\">%s</a>\n",
 2447            rpm2html_url,
 2448            resourceName(rpm->extra->resources[i]->name),
 2449            rpm->extra->resources[i]->name);
 2450        else
 2451            fprintf(html, "<li><a href=\"%s\">%s</a>\n",
 2452                resourceName(rpm->extra->resources[i]->name),
 2453                rpm->extra->resources[i]->name);
 2454        }
 2455        fprintf(html, "</ul>\n");
 2456     }
 2457     if (rpm->extra->nb_requires > 0) {
 2458        fprintf(html, "<h3>%s</h3>\n",
 2459         localizedStrings[LANG_REQUIRE]);
 2460        fprintf(html, "<ul>\n");
 2461        for (i = 0;i < rpm->extra->nb_requires;i++) {
 2462 #ifdef WITH_SQL
 2463            if (rpm2html_search != NULL) {
 2464            if ((rpm->extra->requires[i]->flag != RPM2HTML_REQ_NONE) &&
 2465            (rpm->extra->requires[i]->version != NULL)) {
 2466            fprintf(html, "<li><a href=\"%s?query=%s\">%s</a> %s %s\n",
 2467                rpm2html_search,
 2468                escapeName(rpm->extra->requires[i]->name), 
 2469                rpm->extra->requires[i]->name,
 2470                html_flags[rpm->extra->requires[i]->flag],
 2471                rpm->extra->requires[i]->version);
 2472            } else {
 2473            fprintf(html, "<li><a href=\"%s?query=%s\">%s</a>\n",
 2474                rpm2html_search,
 2475                escapeName(rpm->extra->requires[i]->name), 
 2476                rpm->extra->requires[i]->name);
 2477            }
 2478        } else 
 2479 #endif
 2480        if (rpm2html_url != NULL) {
 2481            if ((rpm->extra->requires[i]->flag != RPM2HTML_REQ_NONE) &&
 2482            (rpm->extra->requires[i]->version != NULL)) {
 2483            fprintf(html, "<li><a href=\"%s/%s\">%s</a> %s %s\n",
 2484                rpm2html_url,
 2485                resourceName(rpm->extra->requires[i]->name), 
 2486                rpm->extra->requires[i]->name,
 2487                html_flags[rpm->extra->requires[i]->flag],
 2488                rpm->extra->requires[i]->version);
 2489            } else {
 2490            fprintf(html, "<li><a href=\"%s/%s\">%s</a>\n",
 2491                rpm2html_url,
 2492                resourceName(rpm->extra->requires[i]->name), 
 2493                rpm->extra->requires[i]->name);
 2494            }
 2495        } else {
 2496            if ((rpm->extra->requires[i]->flag != RPM2HTML_REQ_NONE) &&
 2497            (rpm->extra->requires[i]->version != NULL)) {
 2498            fprintf(html, "<li><a href=\"%s\">%s</a> %s %s\n",
 2499                resourceName(rpm->extra->requires[i]->name),
 2500                rpm->extra->requires[i]->name,
 2501                html_flags[rpm->extra->requires[i]->flag],
 2502                rpm->extra->requires[i]->version);
 2503            } else {
 2504            fprintf(html, "<li><a href=\"%s\">%s</a>\n",
 2505                resourceName(rpm->extra->requires[i]->name),
 2506                rpm->extra->requires[i]->name);
 2507            }
 2508        }
 2509        }
 2510        fprintf(html, "</ul>\n");
 2511     }
 2512     if (rpm->extra->copyright) {
 2513        fprintf(html, "<h3>%s</h3>\n",
 2514         localizedStrings[LANG_COPYRIGHT]);
 2515     fprintf(html, "<pre>%s\n</pre>\n", convertHTML(rpm->extra->copyright));
 2516     }
 2517     if (rpm->extra->sigs != NULL) {
 2518        fprintf(html, "<h3>%s</h3>\n",
 2519         localizedStrings[LANG_SIGNATURES]);
 2520     for(i = 0; i < rpm->extra->nb_sigs; i++)
 2521         fprintf(html, "<pre>%s\n</pre>\n", convertHTML(convertSIG(rpm->extra->sigs[i])));
 2522     }
 2523     if (rpm->extra->changelog) {
 2524         fprintf(html, "<h3>%s</h3>\n",
 2525         localizedStrings[LANG_CHANGELOG]);
 2526     fprintf(html, "<pre>%s\n</pre>\n", convertCVE(convertHTML(rpm->extra->changelog)));
 2527     }
 2528     fprintf(html, "<h3>%s</h3>\n",
 2529     localizedStrings[LANG_FILES]);
 2530     if (rpm->extra->filelist == NULL) 
 2531     fprintf(html, "<bold>%s</bold>\n",
 2532          localizedStrings[LANG_NO_FILES]);
 2533     else
 2534     fprintf(html, "<pre>%s\n</pre>\n", rpm->extra->filelist);
 2535 #endif  // ifdef HAVE_LIBTEMPLATE
 2536     
 2537     generateHtmlFooter(html);
 2538     fclose(html);
 2539 }
 2540 
 2541 #ifdef WITH_SQL
 2542 /*
 2543  * Dump a resource HTML file redirecting to the search engine.
 2544  */
 2545 
 2546 void dumpRessRedirHtml(const char *name) {
 2547     FILE *html;
 2548 
 2549     if (!rpm2html_dump_html) return;
 2550 
 2551     /*
 2552      * Guess why ??? index.html gets ovewritten !
 2553      */
 2554     if (!strcmp(name, "index"))
 2555     return;
 2556 
 2557     snprintf(buf, sizeof(buf), "%s/%s", rpm2html_dir, resourceName(name));
 2558 
 2559     if (rpm2htmlVerbose > 1) {
 2560     printf("Dumping %s/%s\n", rpm2html_dir, resourceName(name));
 2561     }
 2562 
 2563     html = fopen(buf, "w");
 2564     if (html == NULL) {
 2565         fprintf(stderr, "Couldn't save to file %s: %s\n",
 2566             buf, strerror(errno));
 2567         return;
 2568     }
 2569     snprintf(buf, sizeof(buf), "%s %s",
 2570      localizedStrings[LANG_RPM_RESOURCE], name);
 2571     fprintf(html, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n");
 2572     fprintf(html, "<html>\n<head>\n<title>%s</title>\n", buf);
 2573     fprintf(html, "<meta name=\"GENERATOR\" content=\"%s %s\">\n",
 2574             rpm2html_rpm2html_name, rpm2html_rpm2html_ver);
 2575     if (rpm2html_search != NULL)
 2576     fprintf(html,
 2577         "<META HTTP-EQUIV=\"refresh\" CONTENT=\"0; URL=%s?query=%s\">\n", 
 2578         rpm2html_search, escapeName(name));
 2579     else
 2580     fprintf(html,
 2581         "<META HTTP-EQUIV=\"refresh\" CONTENT=\"0; URL=http://rpmfind.net/linux/rpm2html/search.php?query=%s\">\n", 
 2582             escapeName(name));
 2583     fprintf(html, "</head>\n<body bgcolor=\"#ffffff\" text=\"#000000\">\n");
 2584     generateLinks(html, 0);
 2585     
 2586     fprintf(html, "<h1 align=center>%s %s</h1>\n",
 2587      localizedStrings[LANG_RPM_RESOURCE], name);
 2588     fprintf(html, "<p>This static page has been replaced\n");
 2589     if (rpm2html_search != NULL)
 2590     fprintf(html, "<a href=\"%s?query=%s\">",
 2591         rpm2html_search, escapeName(name));
 2592     else
 2593     fprintf(html,
 2594       "<a href=\"http://rpmfind.net/linux/rpm2html/search.php?query=%s\">",
 2595             escapeName(name));
 2596     fprintf(html, "by a dynamic one</a></p>\n");
 2597     fprintf(html, "<p>Thank you for updating your bookmarks</p>\n");
 2598     generateHtmlFooter(html);
 2599     fclose(html);
 2600 }
 2601 #endif
 2602 
 2603 /*
 2604  * Dump a resource block as an HTML file.
 2605  */
 2606 
 2607 void dumpRessHtml(rpmRessPtr ress, int installed) {
 2608     rpmDataPtr rpm;
 2609     FILE *html;
 2610     int i;
 2611     const char *name = NULL;
 2612 
 2613     if (!rpm2html_dump_html) return;
 2614 #ifdef WITH_SQL
 2615     if (rpm2html_search != NULL) {
 2616     dumpRessRedirHtml(ress->name);
 2617     return;
 2618     }
 2619 #endif
 2620 
 2621     /*
 2622      * Guess why ??? index.html gets ovewritten !
 2623      */
 2624     if (!strcmp(ress->name, "index"))
 2625     return;
 2626 
 2627     rpmRessSort(ress);
 2628 
 2629     snprintf(buf, sizeof(buf), "%s/%s", rpm2html_dir,
 2630            resourceName(ress->name));
 2631     /*
 2632      * !!!!!
 2633      * if (checkDate(buf, ress->stamp)) return;
 2634      */
 2635     if (rpm2htmlVerbose > 1) {
 2636     printf("Dumping %s/%s\n", rpm2html_dir,
 2637            resourceName(ress->name));
 2638     }
 2639 
 2640     html = fopen(buf, "w");
 2641     if (html == NULL) {
 2642         fprintf(stderr, "Couldn't save to file %s: %s\n",
 2643             buf, strerror(errno));
 2644         return;
 2645     }
 2646 
 2647 #ifdef HAVE_LIBTEMPLATE
 2648     tpl_element_set(engine, "name", ress->name);
 2649     generateHtmlHeader(html, "resource_title", NULL);
 2650     generateLinks(html, installed);
 2651     generateColorIndicator(html);
 2652     
 2653     parseNwriteTemplate(html, engine, "resource_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 2654       // later reconsicer usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 2655 
 2656     parseNwriteTemplate(html, engine, "resource_body_begin");
 2657     for (i = 0;i < ress->nb_provider;i++) {
 2658         rpm = ress->provider[i];
 2659     if ((name != NULL) && (strcmp(rpm->name, name))) {
 2660         parseNwriteTemplate(html, engine, "resource_body_end");
 2661         parseNwriteTemplate(html, engine, "resource_body_begin");
 2662         }
 2663     name = rpm->name;
 2664     generateHtmlRpmRow(html, rpm, 1);
 2665     }
 2666     parseNwriteTemplate(html, engine, "resource_body_end");
 2667 
 2668 #else   // ifdef HAVE_LIBTEMPLATE
 2669 
 2670     snprintf(buf, sizeof(buf), "%s %s",
 2671      localizedStrings[LANG_RPM_RESOURCE], ress->name);
 2672     generateHtmlHeader(html, buf, NULL);
 2673     generateLinks(html, installed);
 2674     generateColorIndicator(html);
 2675     fprintf(html, "<h1 align=center>%s %s</h1>\n",
 2676      localizedStrings[LANG_RPM_RESOURCE], ress->name);
 2677     fprintf(html, "<h3>%s</h3>\n",
 2678      localizedStrings[LANG_PROVIDED_BY]);
 2679     fprintf(html, "<table><tbody>\n");
 2680     for (i = 0;i < ress->nb_provider;i++) {
 2681         rpm = ress->provider[i];
 2682     if ((name != NULL) && (strcmp(rpm->name, name)))
 2683         fprintf(html, "</tbody></table>\n<br>\n<table><tbody>\n");
 2684     name = rpm->name;
 2685     generateHtmlRpmRow(html, rpm, 1);
 2686     }
 2687     fprintf(html, "</tbody></table>\n");
 2688 #endif  // ifdef HAVE_LIBTEMPLATE
 2689     
 2690     generateHtmlFooter(html);
 2691     fclose(html);
 2692 }
 2693 
 2694 /*
 2695  * Dump all RPM blocks in the HTML files.
 2696  */
 2697 void dumpAllRessHtml(int installed) {
 2698     rpmRessPtr cur;
 2699 
 2700     if (!rpm2html_dump_html) return;
 2701 
 2702     if (rpm2htmlVerbose)
 2703       printf("Dumping resource HTML pages\n");
 2704 
 2705     if (installed) cur = ressInstalledList;
 2706     else cur = ressList;
 2707 
 2708     while (cur != NULL) {
 2709         dumpRessHtml(cur, installed);
 2710     cur = cur->next;
 2711     }
 2712 }
 2713 
 2714 /*
 2715  * Dump the Groups of all HTML files.
 2716  * One expect that the RPM files have been sorted by group.
 2717  */
 2718 void dumpDirRpmByGroups(rpmDataPtr list, rpmDirPtr dir,
 2719                    char *subdir, int installed) {
 2720     FILE *Groups;
 2721     FILE *currentGroup = NULL;
 2722     rpmDataPtr cur, prev = NULL;
 2723     int count = 0;
 2724     int pcount = 0;
 2725 
 2726     if (!rpm2html_dump_html) return;
 2727     if ((dir != NULL) && (!dir->html)) return;
 2728 
 2729     cur = list;
 2730     
 2731     fullPathName(buf, sizeof(buf), dir, subdir, localizedStrings[LANG_GROUP_HTML]);
 2732     if (rpm2htmlVerbose > 1) {
 2733         printf("Dumping %s\n", buf);
 2734     }
 2735 
 2736     Groups = fopen(buf, "w");
 2737     if (Groups == NULL) {
 2738         fprintf(stderr, "Couldn't save to file %s: %s\n",
 2739             buf, strerror(errno));
 2740         return;
 2741     }
 2742 
 2743 #ifdef HAVE_LIBTEMPLATE
 2744     generateHtmlHeader(Groups, "groups_title", NULL);
 2745     generateLinks(Groups, installed);
 2746     parseNwriteTemplate(Groups, engine, "groups_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 2747       // later reconsicer usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 2748 
 2749     rpmDataPtr lastCur = NULL;
 2750     while (cur != NULL) {
 2751         if ((cur->group != NULL) && (strlen(cur->group) > 0)) {
 2752         if ((prev == NULL) || (strcasecmp(prev->group, cur->group))) {
 2753         if (pcount != 0) {
 2754             /* Add the current group in the Group list */
 2755             tpl_element_set(engine, "url", groupName(lastCur->group));
 2756             tpl_element_set(engine, "name", convertHTML(lastCur->group));
 2757             snprintf(buf, sizeof(buf), "%d", pcount);
 2758             tpl_element_set(engine, "count", buf);
 2759             parseNwriteTemplate(Groups, engine, "groups_item");
 2760                 }
 2761         pcount = 0;
 2762             if (currentGroup != NULL) {
 2763             /* one need to close the current group list */
 2764             parseNwriteTemplate(currentGroup, engine, "group_end");
 2765             generateHtmlFooter(currentGroup);
 2766             fclose(currentGroup);
 2767         }
 2768 
 2769         lastCur = cur;
 2770 
 2771         /* open the new HTML group file */
 2772                 fullPathName(buf, sizeof(buf), dir, subdir, groupName(cur->group));
 2773         if (rpm2htmlVerbose > 1) {
 2774             printf("Dumping %s\n", buf);
 2775         }
 2776 
 2777         currentGroup = fopen(buf, "w");
 2778         if (currentGroup == NULL) {
 2779             fprintf(stderr, "Couldn't save to file %s: %s\n",
 2780                 buf, strerror(errno));
 2781             return;
 2782         }
 2783         tpl_element_set(engine, "name", convertHTML(cur->group));
 2784                 generateHtmlHeader(currentGroup, "group_title", NULL);
 2785         generateLinks(currentGroup, installed);
 2786                 parseNwriteTemplate(currentGroup, engine, "group_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 2787                     // later reconsider usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 2788         generateColorIndicator(currentGroup);
 2789         parseNwriteTemplate(currentGroup, engine, "group_begin");
 2790         count = 0;
 2791         }
 2792         generateHtmlRpmArchRow(currentGroup, cur);
 2793         count++;
 2794         pcount++;
 2795         if ((count % MAX_TABLE_LENGHT) == 0) {
 2796             parseNwriteTemplate(currentGroup, engine, "group_end");
 2797             parseNwriteTemplate(currentGroup, engine, "group_begin");
 2798             }
 2799     }
 2800     prev = cur;
 2801     if ((dir == NULL) && (subdir == NULL))
 2802         cur = cur->nextSoft;
 2803     else
 2804         cur = cur->next;
 2805     }
 2806 
 2807     /* Add the last group in the Group list */
 2808     if (pcount != 0) {
 2809         tpl_element_set(engine, "url", groupName(lastCur->group));
 2810         tpl_element_set(engine, "name", convertHTML(lastCur->group));
 2811         snprintf(buf, sizeof(buf), "%d", pcount);
 2812         tpl_element_set(engine, "count", buf);
 2813         parseNwriteTemplate(Groups, engine, "groups_item");
 2814     }
 2815 
 2816     if (currentGroup != NULL) {
 2817     /* one need to close the current group list */
 2818     parseNwriteTemplate(currentGroup, engine, "group_end");
 2819     generateHtmlFooter(currentGroup);
 2820     fclose(currentGroup);
 2821     }
 2822     parseNwriteTemplate(Groups, engine, "groups_footer");
 2823 
 2824 #else   // ifdef HAVE_LIBTEMPLATE
 2825 
 2826     generateHtmlHeader(Groups, localizedStrings[LANG_SORTED_BY_GROUP], NULL);
 2827     generateLinks(Groups, installed);
 2828     fprintf(Groups, "<h1 align=center>%s</h1>\n",
 2829         localizedStrings[LANG_SORTED_BY_GROUP]);
 2830     fprintf(Groups, "<ul>\n");
 2831 
 2832     while (cur != NULL) {
 2833         if ((cur->group != NULL) && (strlen(cur->group) > 0)) {
 2834         if ((prev == NULL) || (strcasecmp(prev->group, cur->group))) {
 2835         if (pcount != 0)
 2836             fprintf(Groups, " (%d)</a></li>\n", pcount);
 2837         pcount = 0;
 2838             if (currentGroup != NULL) {
 2839             /* one need to close the current group list */
 2840             fprintf(currentGroup,"</tbody></table>\n");
 2841             generateHtmlFooter(currentGroup);
 2842             fclose(currentGroup);
 2843         }
 2844 
 2845         /* Add the current group in the Group list */
 2846         fprintf(Groups, "<li><a href=\"%s\">%s",
 2847                 groupName(cur->group), convertHTML(cur->group));
 2848 
 2849         /* open the new HTML group file */
 2850                 fullPathName(buf, sizeof(buf), dir, subdir, groupName(cur->group));
 2851         if (rpm2htmlVerbose > 1) {
 2852             printf("Dumping %s\n", buf);
 2853         }
 2854 
 2855         currentGroup = fopen(buf, "w");
 2856         if (currentGroup == NULL) {
 2857             fprintf(stderr, "Couldn't save to file %s: %s\n",
 2858                 buf, strerror(errno));
 2859             return;
 2860         }
 2861                 snprintf(buf, sizeof(buf), "%s %s", localizedStrings[LANG_OF_GROUP],
 2862                 convertHTML(cur->group));
 2863                 generateHtmlHeader(currentGroup, buf, NULL);
 2864         generateLinks(currentGroup, installed);
 2865         fprintf(currentGroup,
 2866           "<h1 align=center>%s %s</h1>\n",
 2867              localizedStrings[LANG_OF_GROUP], convertHTML(cur->group));
 2868         generateColorIndicator(currentGroup);
 2869         fprintf(currentGroup,"<table><tbody>\n");
 2870         count = 0;
 2871         }
 2872         generateHtmlRpmArchRow(currentGroup, cur);
 2873         count++;
 2874         pcount++;
 2875         if ((count % MAX_TABLE_LENGHT) == 0)
 2876         fprintf(currentGroup, "</tbody></table>\n<table><tbody>\n");
 2877     }
 2878     prev = cur;
 2879     if ((dir == NULL) && (subdir == NULL))
 2880         cur = cur->nextSoft;
 2881     else
 2882         cur = cur->next;
 2883     }
 2884 
 2885     /*
 2886      * finish the last group line.
 2887      */
 2888     if (pcount != 0)
 2889     fprintf(Groups, " (%d)</a></li>\n", pcount);
 2890 
 2891     if (currentGroup != NULL) {
 2892     /* one need to close the current group list */
 2893     fprintf(currentGroup,"</tbody></table>\n");
 2894     generateHtmlFooter(currentGroup);
 2895     fclose(currentGroup);
 2896     }
 2897     fprintf(Groups, "</ul>\n");
 2898 #endif  // ifdef HAVE_LIBTEMPLATE
 2899 
 2900     generateHtmlFooter(Groups);
 2901     fclose(Groups);
 2902 }
 2903 
 2904 /*
 2905  * Dump the full set of  RPM by Group HTML file.
 2906  * One expect that the RPM files have been sorted by groups.
 2907  */
 2908 void dumpRpmByGroups(rpmDataPtr list, int installed) {
 2909     if (!rpm2html_dump_html) return;
 2910 
 2911     if (rpm2htmlVerbose)
 2912       printf("Dumping \"by group\" HTML pages\n");
 2913 
 2914     dumpDirRpmByGroups(list, NULL, NULL, installed);
 2915 }
 2916 
 2917 /*
 2918  * Dump the Distribs HTML files.
 2919  * One expect that the RPM files have been sorted by distribution.
 2920  */
 2921 void dumpDirRpmByDistribs(rpmDataPtr list, rpmDirPtr dir,
 2922                       char *subdir, int installed) {
 2923     FILE *Distribs;
 2924     FILE *currentDistrib = NULL;
 2925     rpmDataPtr cur, prev = NULL;
 2926     int count = 0;
 2927     int pcount = 0;
 2928 
 2929     if (!rpm2html_dump_html) return;
 2930     if ((dir != NULL) && (!dir->html)) return;
 2931 
 2932     cur = list;
 2933 
 2934     fullPathName(buf, sizeof(buf), dir, subdir, localizedStrings[LANG_DISTRIB_HTML]);
 2935     if (rpm2htmlVerbose > 1) {
 2936         printf("Dumping %s\n", buf);
 2937     }
 2938 
 2939     Distribs = fopen(buf, "w");
 2940     if (Distribs == NULL) {
 2941         fprintf(stderr, "Couldn't save to file %s: %s\n",
 2942             buf, strerror(errno));
 2943         return;
 2944     }
 2945     
 2946 #ifdef HAVE_LIBTEMPLATE
 2947     generateHtmlHeader(Distribs, "distribs_title", NULL);
 2948     generateLinks(Distribs, installed);
 2949     parseNwriteTemplate(Distribs, engine, "distribs_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 2950       // later reconsicer usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 2951 
 2952     rpmDataPtr lastCur = NULL;
 2953     while (cur != NULL) {
 2954         if ((cur->distribution != NULL) && (strlen(cur->distribution) > 0)) {
 2955         if ((prev == NULL) || (strcasecmp(prev->distribution, cur->distribution))) {
 2956         if (pcount != 0) {
 2957             /* Add the current distribution in the Distrib list */
 2958             tpl_element_set(engine, "url", distribName(lastCur->distribution));
 2959             tpl_element_set(engine, "name", convertHTML(lastCur->distribution));
 2960             snprintf(buf, sizeof(buf), "%d", pcount);
 2961             tpl_element_set(engine, "count", buf);
 2962             parseNwriteTemplate(Distribs, engine, "distribs_item");
 2963                 }
 2964         pcount = 0;
 2965 
 2966             if (currentDistrib != NULL) {
 2967             /* one need to close the current distribution list */
 2968             parseNwriteTemplate(currentDistrib, engine, "distrib_end");
 2969             generateHtmlFooter(currentDistrib);
 2970             fclose(currentDistrib);
 2971         }
 2972 
 2973         lastCur = cur;
 2974 
 2975         /* open the new HTML distribution file */
 2976                 fullPathName(buf, sizeof(buf), dir, subdir, distribName(cur->distribution));
 2977         if (rpm2htmlVerbose > 1) {
 2978             printf("Dumping %s\n", buf);
 2979         }
 2980 
 2981         currentDistrib = fopen(buf, "w");
 2982         if (currentDistrib == NULL) {
 2983             fprintf(stderr, "Couldn't save to file %s: %s\n",
 2984                 buf, strerror(errno));
 2985             return;
 2986         }
 2987         tpl_element_set(engine, "name", convertHTML(cur->distribution));
 2988                 generateHtmlHeader(currentDistrib, "distrib_title", NULL);
 2989         generateLinks(currentDistrib, installed);
 2990                 parseNwriteTemplate(currentDistrib, engine, "distrib_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 2991                     // later reconsider usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 2992         if (!installed) generateColorIndicator(currentDistrib);
 2993         parseNwriteTemplate(currentDistrib, engine, "distrib_begin");
 2994         count = 0;
 2995         }
 2996         generateHtmlRpmRow(currentDistrib, cur, 1);
 2997         count++;
 2998         pcount++;
 2999         if ((count % MAX_TABLE_LENGHT) == 0) {
 3000             parseNwriteTemplate(currentDistrib, engine, "distrib_end");
 3001             parseNwriteTemplate(currentDistrib, engine, "distrib_begin");
 3002             }
 3003     }
 3004     prev = cur;
 3005     cur = cur->next;
 3006     }
 3007     /* Add the last distribution in the Distrib list */
 3008     if (pcount != 0) {
 3009         tpl_element_set(engine, "url", distribName(lastCur->distribution));
 3010         tpl_element_set(engine, "name", convertHTML(lastCur->distribution));
 3011         snprintf(buf, sizeof(buf), "%d", pcount);
 3012         tpl_element_set(engine, "count", buf);
 3013         parseNwriteTemplate(Distribs, engine, "distribs_item");
 3014     }
 3015 
 3016     if (currentDistrib != NULL) {
 3017     /* one need to close the current distribution list */
 3018     parseNwriteTemplate(currentDistrib, engine, "distrib_end");
 3019     generateHtmlFooter(currentDistrib);
 3020     fclose(currentDistrib);
 3021     }
 3022     parseNwriteTemplate(Distribs, engine, "distribs_footer");
 3023 
 3024 #else   // ifdef HAVE_LIBTEMPLATE
 3025 
 3026     generateHtmlHeader(Distribs,
 3027         localizedStrings[LANG_SORTED_BY_DISTRIB], NULL);
 3028     generateLinks(Distribs, installed);
 3029     fprintf(Distribs, "<h1 align=center>%s</h1>\n",
 3030         localizedStrings[LANG_SORTED_BY_DISTRIB]);
 3031     fprintf(Distribs, "<ul>\n");
 3032 
 3033     while (cur != NULL) {
 3034         if ((cur->distribution != NULL) && (strlen(cur->distribution) > 0)) {
 3035         if ((prev == NULL) || (strcasecmp(prev->distribution, cur->distribution))) {
 3036         if (pcount != 0)
 3037             fprintf(Distribs, " (%d)</a></li>\n", pcount);
 3038         pcount = 0;
 3039 
 3040             if (currentDistrib != NULL) {
 3041             /* one need to close the current distribution list */
 3042             fprintf(currentDistrib,"</tbody></table>\n");
 3043             generateHtmlFooter(currentDistrib);
 3044             fclose(currentDistrib);
 3045         }
 3046 
 3047         /* Add the current distribution in the Distrib list */
 3048         fprintf(Distribs, "<li><a href=\"%s\">%s",
 3049                 distribName(cur->distribution),
 3050             convertHTML(cur->distribution));
 3051 
 3052         /* open the new HTML distribution file */
 3053                 fullPathName(buf, sizeof(buf), dir, subdir, distribName(cur->distribution));
 3054         if (rpm2htmlVerbose > 1) {
 3055             printf("Dumping %s\n", buf);
 3056         }
 3057 
 3058         currentDistrib = fopen(buf, "w");
 3059         if (currentDistrib == NULL) {
 3060             fprintf(stderr, "Couldn't save to file %s: %s\n",
 3061                 buf, strerror(errno));
 3062             return;
 3063         }
 3064                 snprintf(buf, sizeof(buf), "%s %s",
 3065             localizedStrings[LANG_OF_DISTRIB],
 3066             convertHTML(cur->distribution));
 3067                 generateHtmlHeader(currentDistrib, buf, NULL);
 3068         generateLinks(currentDistrib, installed);
 3069         fprintf(currentDistrib,
 3070           "<h1 align=center>%s %s</h1>\n",
 3071           localizedStrings[LANG_OF_DISTRIB],
 3072           convertHTML(cur->distribution));
 3073         if (!installed) generateColorIndicator(currentDistrib);
 3074         fprintf(currentDistrib,"<table><tbody>\n");
 3075         count = 0;
 3076         }
 3077         generateHtmlRpmRow(currentDistrib, cur, 1);
 3078         count++;
 3079         pcount++;
 3080         if ((count % MAX_TABLE_LENGHT) == 0)
 3081         fprintf(currentDistrib, "</tbody></table>\n<table><tbody>\n");
 3082     }
 3083     prev = cur;
 3084     cur = cur->next;
 3085     }
 3086     /*
 3087      * finish the last group line.
 3088      */
 3089     if (pcount != 0)
 3090     fprintf(Distribs, " (%d)</a></li>\n", pcount);
 3091 
 3092     if (currentDistrib != NULL) {
 3093     /* one need to close the current distribution list */
 3094     fprintf(currentDistrib,"</tbody></table>\n");
 3095     generateHtmlFooter(currentDistrib);
 3096     fclose(currentDistrib);
 3097     }
 3098     fprintf(Distribs, "</ul>\n");
 3099 #endif  // ifdef HAVE_LIBTEMPLATE
 3100 
 3101     generateHtmlFooter(Distribs);
 3102     fclose(Distribs);
 3103 }
 3104 
 3105 /*
 3106  * Dump the full set of  RPM by Distribution HTML file.
 3107  * One expect that the RPM files have been sorted by distributions.
 3108  */
 3109 void dumpRpmByDistribs(rpmDataPtr list, int installed) {
 3110     if (!rpm2html_dump_html) return;
 3111 
 3112     if (rpm2htmlVerbose)
 3113       printf("Dumping \"by distribution\" HTML pages\n");
 3114 
 3115     dumpDirRpmByDistribs(list, NULL, NULL, installed);
 3116 }
 3117 
 3118 /*
 3119  * Dump the Vendors HTML files.
 3120  * One expect that the RPM files have been sorted by vendors.
 3121  */
 3122 void dumpDirRpmByVendors(rpmDataPtr list, rpmDirPtr dir,
 3123                       char *subdir, int installed) {
 3124     FILE *Vendors;
 3125     FILE *currentVendor = NULL;
 3126     rpmDataPtr cur, prev = NULL;
 3127     int count = 0;
 3128     int pcount = 0;
 3129 
 3130     if (!rpm2html_dump_html) return;
 3131 
 3132     cur = list;
 3133 
 3134     fullPathName(buf, sizeof(buf), dir, subdir, localizedStrings[LANG_VENDOR_HTML]);
 3135     if (rpm2htmlVerbose > 1) {
 3136         printf("Dumping %s\n", buf);
 3137     }
 3138 
 3139     Vendors = fopen(buf, "w");
 3140     if (Vendors == NULL) {
 3141         fprintf(stderr, "Couldn't save to file %s: %s\n",
 3142             buf, strerror(errno));
 3143         return;
 3144     }
 3145 #ifdef HAVE_LIBTEMPLATE
 3146     generateHtmlHeader(Vendors, "vendors_title", NULL);
 3147     generateLinks(Vendors, installed);
 3148     parseNwriteTemplate(Vendors, engine, "vendors_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 3149       // later reconsicer usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 3150 
 3151     rpmDataPtr lastCur = NULL;
 3152     while (cur != NULL) {
 3153         if ((cur->vendor != NULL) && (strlen(cur->vendor) > 0)) {
 3154         if ((prev == NULL) || (strcasecmp(prev->vendor, cur->vendor))) {
 3155         if (pcount != 0) {
 3156             /* Add the current vendor in the Vendor list */
 3157             tpl_element_set(engine, "url", vendorName(lastCur->vendor));
 3158             tpl_element_set(engine, "name", convertHTML(lastCur->vendor));
 3159             snprintf(buf, sizeof(buf), "%d", pcount);
 3160             tpl_element_set(engine, "count", buf);
 3161             parseNwriteTemplate(Vendors, engine, "vendors_item");
 3162                 }
 3163                 pcount = 0;
 3164 
 3165             if (currentVendor != NULL) {
 3166             /* one need to close the current vendor list */
 3167             parseNwriteTemplate(currentVendor, engine, "vendor_end");
 3168             generateHtmlFooter(currentVendor);
 3169             fclose(currentVendor);
 3170         }
 3171 
 3172         lastCur = cur;
 3173 
 3174         /* open the new HTML vendor file */
 3175                 fullPathName(buf, sizeof(buf), dir, subdir, vendorName(cur->vendor));
 3176         if (rpm2htmlVerbose > 1) {
 3177             printf("Dumping %s\n", buf);
 3178         }
 3179 
 3180         currentVendor = fopen(buf, "w");
 3181         if (currentVendor == NULL) {
 3182             fprintf(stderr, "Couldn't save to file %s: %s\n",
 3183                 buf, strerror(errno));
 3184             return;
 3185         }
 3186         tpl_element_set(engine, "name", convertHTML(cur->vendor));
 3187                 generateHtmlHeader(currentVendor, "vendor_title", NULL);
 3188         generateLinks(currentVendor, installed);
 3189                 parseNwriteTemplate(currentVendor, engine, "vendor_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 3190                     // later reconsider usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 3191         if (!installed) generateColorIndicator(currentVendor);
 3192         parseNwriteTemplate(currentVendor, engine, "vendor_begin");
 3193         count = 0;
 3194         }
 3195         generateHtmlRpmRow(currentVendor, cur, 1);
 3196         count++;
 3197         pcount++;
 3198         if ((count % MAX_TABLE_LENGHT) == 0) {
 3199                 parseNwriteTemplate(currentVendor, engine, "vendor_end");
 3200                 parseNwriteTemplate(currentVendor, engine, "vendor_begin");
 3201             }
 3202     }
 3203     prev = cur;
 3204     cur = cur->next;
 3205     }
 3206 
 3207     /* Add the last vendor in the Vendor list */
 3208     if (pcount != 0) {
 3209     tpl_element_set(engine, "url", vendorName(lastCur->vendor));
 3210     tpl_element_set(engine, "name", convertHTML(lastCur->vendor));
 3211     snprintf(buf, sizeof(buf), "%d", pcount);
 3212     tpl_element_set(engine, "count", buf);
 3213     parseNwriteTemplate(Vendors, engine, "vendors_item");
 3214     }
 3215 
 3216     if (currentVendor != NULL) {
 3217     /* one need to close the current vendor list */
 3218     parseNwriteTemplate(currentVendor, engine, "vendor_end");
 3219     generateHtmlFooter(currentVendor);
 3220     fclose(currentVendor);
 3221     }
 3222     parseNwriteTemplate(Vendors, engine, "vendors_footer");
 3223 
 3224 #else   // ifdef HAVE_LIBTEMPLATE
 3225     generateHtmlHeader(Vendors, localizedStrings[LANG_SORTED_BY_VENDOR], NULL);
 3226     generateLinks(Vendors, installed);
 3227     fprintf(Vendors, "<h1 align=center>%s</h1>\n",
 3228         localizedStrings[LANG_SORTED_BY_VENDOR]);
 3229     fprintf(Vendors, "<ul>\n");
 3230 
 3231     while (cur != NULL) {
 3232         if ((cur->vendor != NULL) && (strlen(cur->vendor) > 0)) {
 3233         if ((prev == NULL) || (strcasecmp(prev->vendor, cur->vendor))) {
 3234         if (pcount != 0)
 3235             fprintf(Vendors, " (%d)</a></li>\n", pcount);
 3236         pcount = 0;
 3237 
 3238             if (currentVendor != NULL) {
 3239             /* one need to close the current vendor list */
 3240             fprintf(currentVendor,"</tbody></table>\n");
 3241             generateHtmlFooter(currentVendor);
 3242             fclose(currentVendor);
 3243         }
 3244 
 3245         /* Add the current vendor in the Vendor list */
 3246         fprintf(Vendors, "<li><a href=\"%s\">%s",
 3247                 vendorName(cur->vendor), convertHTML(cur->vendor));
 3248 
 3249         /* open the new HTML vendor file */
 3250                 fullPathName(buf, sizeof(buf), dir, subdir, vendorName(cur->vendor));
 3251         if (rpm2htmlVerbose > 1) {
 3252             printf("Dumping %s\n", buf);
 3253         }
 3254 
 3255         currentVendor = fopen(buf, "w");
 3256         if (currentVendor == NULL) {
 3257             fprintf(stderr, "Couldn't save to file %s: %s\n",
 3258                 buf, strerror(errno));
 3259             return;
 3260         }
 3261                 snprintf(buf, sizeof(buf), "%s %s", localizedStrings[LANG_OF_VENDOR],
 3262             convertHTML(cur->vendor));
 3263                 generateHtmlHeader(currentVendor, buf, NULL);
 3264         generateLinks(currentVendor, installed);
 3265         fprintf(currentVendor,
 3266           "<h1 align=center>%s %s</h1>\n",
 3267           localizedStrings[LANG_OF_VENDOR], convertHTML(cur->vendor));
 3268         if (!installed) generateColorIndicator(currentVendor);
 3269         fprintf(currentVendor,"<table><tbody>\n");
 3270         count = 0;
 3271         }
 3272         generateHtmlRpmRow(currentVendor, cur, 1);
 3273         count++;
 3274         pcount++;
 3275         if ((count % MAX_TABLE_LENGHT) == 0)
 3276         fprintf(currentVendor, "</tbody></table>\n<table><tbody>\n");
 3277     }
 3278     prev = cur;
 3279     cur = cur->next;
 3280     }
 3281 
 3282     /*
 3283      * finish the last group line.
 3284      */
 3285     if (pcount != 0)
 3286     fprintf(Vendors, " (%d)</a></li>\n", pcount);
 3287 
 3288     if (currentVendor != NULL) {
 3289     /* one need to close the current vendor list */
 3290     fprintf(currentVendor,"</tbody></table>\n");
 3291     generateHtmlFooter(currentVendor);
 3292     fclose(currentVendor);
 3293     }
 3294     fprintf(Vendors, "</ul>\n");
 3295 #endif  // ifdef HAVE_LIBTEMPLATE
 3296 
 3297     generateHtmlFooter(Vendors);
 3298     fclose(Vendors);
 3299 }
 3300 
 3301 /*
 3302  * Dump the full set of  RPM by Vendor HTML file.
 3303  * One expect that the RPM files have been sorted by vendors.
 3304  */
 3305 void dumpRpmByVendors(rpmDataPtr list, int installed) {
 3306     if (!rpm2html_dump_html) return;
 3307 
 3308     if (rpm2htmlVerbose)
 3309       printf("Dumping \"by vendor\" HTML pages\n");
 3310 
 3311     dumpDirRpmByVendors(list, NULL, NULL, installed);
 3312 }
 3313 
 3314 #ifdef HAVE_LIBTEMPLATE
 3315 /*
 3316  * Helper function for dumpDirRpmByDate(): it performs subdumps for given package age.
 3317  * Returns actualised page counter.
 3318  */
 3319 int subdumpDirRpmByDate(rpmDataPtr list, rpmDirPtr dir,
 3320                       char *subdir, int installed,
 3321                       FILE **html, FILE *RSS, int *rdfcount,
 3322                       char *title, int maxAge, rpmDataPtr *cur, int *page, int *count) {
 3323 
 3324     tpl_parse(engine, title, "p_title", 0);
 3325     tpl_element_set(engine, "title", tpl_element_get(engine, "p_title"));
 3326     parseNwriteTemplate((*html), engine, "dates_subheader");
 3327     parseNwriteTemplate((*html), engine, "dates_begin");
 3328     while (((*cur) != NULL) && (((currentTime - (*cur)->date) < maxAge) || (maxAge < 0))) {
 3329     generateHtmlRpmRow((*html), (*cur), 0);
 3330     if ((RSS != NULL) && ((*rdfcount)++ < rpm2html_rdf_count_limit)) {
 3331         generateRSSItem(RSS, (*cur));
 3332     }
 3333     (*cur) = (*cur)->next;
 3334     (*count)++;
 3335     if (((*count) % MAX_TABLE_LENGHT) == 0) {
 3336         parseNwriteTemplate((*html), engine, "dates_end");
 3337         parseNwriteTemplate((*html), engine, "dates_begin");
 3338         }
 3339     if ((*count) > MAX_PAGE_LENGHT) {
 3340         (*count) = 0;
 3341         parseNwriteTemplate((*html), engine, "dates_end");
 3342         snprintf(buf, sizeof(buf), "%d", (*page));
 3343         tpl_element_set(engine, "next_page", buf);
 3344         parseNwriteTemplate((*html), engine, "dates_next_page");
 3345         generateHtmlFooter((*html));
 3346         fclose((*html));
 3347         fullPathNameNr(buf, sizeof(buf), dir, subdir, localizedStrings[LANG_BYDATE_HTML], (*page)++);
 3348         if (rpm2htmlVerbose > 1) {
 3349         printf("Dumping %s\n", buf);
 3350         }
 3351         (*html) = fopen(buf, "w");
 3352         if ((*html) == NULL) {
 3353         fprintf(stderr, "Couldn't save to file %s: %s\n",
 3354             buf, strerror(errno));
 3355         if (RSS) {
 3356             fprintf(RSS, "  </channel>\n");
 3357             fprintf(RSS, "</rss>\n");
 3358             fclose(RSS);
 3359         }
 3360         return;
 3361         }
 3362         if (installed) {
 3363             generateHtmlHeader((*html), "idates_title", NULL);
 3364             generateLinks((*html), installed);
 3365             parseNwriteTemplate((*html), engine, "dates_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 3366               // later reconsicer usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 3367             } else {
 3368                 generateHtmlHeader((*html), "cdates_title", NULL);
 3369                 generateLinks((*html), installed);
 3370                 parseNwriteTemplate((*html), engine, "dates_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 3371                   // later reconsicer usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 3372             }
 3373             //tpl_parse(engine, title, "p_title", 0);
 3374             //tpl_element_set(engine, "title", tpl_element_get(engine, "p_title")); - I hope it is still preserved from the begining of the function?
 3375             parseNwriteTemplate((*html), engine, "dates_subheader");
 3376             parseNwriteTemplate((*html), engine, "dates_begin");
 3377     }
 3378     }
 3379     parseNwriteTemplate((*html), engine, "dates_end");
 3380 
 3381     return (*page);
 3382 }
 3383 #endif
 3384 
 3385 /*
 3386  * Dump the RPM by Date HTML file.
 3387  * One expect that the RPM files have been sorted by date.
 3388  */
 3389 void dumpDirRpmByDate(rpmDataPtr list, rpmDirPtr dir,
 3390                       char *subdir, int installed) {
 3391     FILE *ByDate;
 3392     FILE *RSS;
 3393     rpmDataPtr cur;
 3394     int count = 0;
 3395     int rdfcount = 0;
 3396     int page = 1;
 3397 
 3398     if (!rpm2html_dump_html) return;
 3399     if ((dir != NULL) && (!dir->html)) return;
 3400 
 3401     cur = list;
 3402 
 3403     fullPathName(buf, sizeof(buf), dir, subdir, localizedStrings[LANG_BYDATE_HTML]);
 3404     if (rpm2htmlVerbose > 1) {
 3405     printf("Dumping %s\n", buf);
 3406     }
 3407 
 3408     ByDate = fopen(buf, "w");
 3409     if (ByDate == NULL) {
 3410         fprintf(stderr, "Couldn't save to file %s: %s\n",
 3411             buf, strerror(errno));
 3412         return;
 3413     }
 3414     fullPathName(buf, sizeof(buf), dir, subdir, "rdf");
 3415     if (rpm2htmlVerbose > 1) {
 3416     printf("Dumping RSS channel %s\n", buf);
 3417     }
 3418 
 3419     RSS = fopen(buf, "w");
 3420     if (RSS == NULL) {
 3421         fprintf(stderr, "Couldn't save to file %s: %s\n",
 3422             buf, strerror(errno));
 3423     fclose(ByDate);
 3424         return;
 3425     }
 3426 #ifdef HAVE_LIBTEMPLATE
 3427     if (installed) {
 3428     generateHtmlHeader(ByDate, "idates_title", NULL);
 3429     generateLinks(ByDate, installed);
 3430         parseNwriteTemplate(ByDate, engine, "dates_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 3431           // later reconsicer usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 3432     } else {
 3433     generateHtmlHeader(ByDate, "cdates_title", NULL);
 3434     generateLinks(ByDate, installed);
 3435         parseNwriteTemplate(ByDate, engine, "dates_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 3436           // later reconsicer usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 3437     }
 3438 
 3439 #else   // ifdef HAVE_LIBTEMPLATE
 3440 
 3441     if (installed) {
 3442     generateHtmlHeader(ByDate, localizedStrings[LANG_SORTED_BY_IDATE], NULL);
 3443     generateLinks(ByDate, installed);
 3444     fprintf(ByDate, "<h1 align=center>%s</h1>\n",
 3445         localizedStrings[LANG_SORTED_BY_IDATE]);
 3446     } else {
 3447     generateHtmlHeader(ByDate, localizedStrings[LANG_SORTED_BY_CDATE], NULL);
 3448     generateLinks(ByDate, installed);
 3449     fprintf(ByDate, "<h1 align=center>%s</h1>\n",
 3450         localizedStrings[LANG_SORTED_BY_CDATE]);
 3451     }
 3452 #endif  // ifdef HAVE_LIBTEMPLATE
 3453     if (RSS) {
 3454     fprintf(RSS, "<?xml version=\"1.0\"?>\n");
 3455     fprintf(RSS,
 3456     "<!DOCTYPE rss PUBLIC \"-//Netscape Communications//DTD RSS 0.91//EN\"\n");
 3457     fprintf(RSS,
 3458     "        \"http://my.netscape.com/publish/formats/rss-0.91.dtd\">\n"); 
 3459     fprintf(RSS, "<rss version=\"0.91\">\n");
 3460     fprintf(RSS, "  <channel>\n");
 3461     if (dir != NULL) {
 3462         fprintf(RSS, "    <title>Rpmfind %s index on %s</title>\n",
 3463             dir->name, rpm2html_host);
 3464         fullURL(buf, sizeof(buf), dir, subdir,
 3465             localizedStrings[LANG_INDEX_HTML]);
 3466         fprintf(RSS, "    <link>%s</link>\n", buf);
 3467         fprintf(RSS, "    <description>Rpmfind %s News on %s</description>\n",
 3468             rpm2html_host, dir->name);
 3469     } else {
 3470         fprintf(RSS, "    <title>Rpmfind index on %s</title>\n",
 3471             rpm2html_host);
 3472         fullURL(buf, sizeof(buf), dir, subdir,
 3473             localizedStrings[LANG_INDEX_HTML]);
 3474         fprintf(RSS, "    <link>%s</link>\n", buf);
 3475         fprintf(RSS, "    <description>Rpmfind News on %s</description>\n",
 3476             rpm2html_host);
 3477     }
 3478 #ifdef HAVE_LIBTEMPLATE
 3479         parseNwriteTemplate(ByDate, engine, "dates_rdf");
 3480 #else
 3481     fprintf(ByDate, localizedStrings[LANG_RDF_CHANNEL], "rdf");
 3482 #endif
 3483     }
 3484 
 3485     /*
 3486      * Skip all the RPMs with date in the futur :-(
 3487      */
 3488     while ((cur != NULL) && ((cur->date < 0) || (currentTime < cur->date))) {
 3489     if (rpm2htmlVerbose > 1) {
 3490         fprintf(stderr, "dropping %s, date %d > current time %d\n",
 3491             rpmSoftwareName(cur), (int) cur->date, (int) currentTime);
 3492     }
 3493     cur = cur->next;
 3494     }
 3495 
 3496 #ifdef HAVE_LIBTEMPLATE
 3497     #define MAX_AGE_LESS_3D (3 * 24 * 60 * 60)
 3498     #define MAX_AGE_LESS_1W (7 * 24 * 60 * 60)
 3499     #define MAX_AGE_LESS_2W (14 * 24 * 60 * 60)
 3500     #define MAX_AGE_LESS_1M (30 * 24 * 60 * 60)
 3501     #define MAX_AGE_MORE_1M -1
 3502 
 3503     /*
 3504      * First dump RPMs less than 3 days old.
 3505      */
 3506     if (!installed) generateColorIndicator(ByDate);
 3507     if (installed)
 3508     subdumpDirRpmByDate(list, dir, subdir, installed,
 3509         &ByDate, RSS, &rdfcount,
 3510         "idates_title_less_3d_old", MAX_AGE_LESS_3D, &cur, &page, &count);
 3511     else
 3512         subdumpDirRpmByDate(list, dir, subdir, installed,
 3513             &ByDate, RSS, &rdfcount,
 3514             "cdates_title_less_3d_old", MAX_AGE_LESS_3D, &cur, &page, &count);
 3515 
 3516     /*
 3517      * Then dump RPMs less than one week old.
 3518      */
 3519     if (installed)
 3520         subdumpDirRpmByDate(list, dir, subdir, installed,
 3521             &ByDate, RSS, &rdfcount,
 3522             "idates_title_less_1w_old", MAX_AGE_LESS_1W, &cur, &page, &count);
 3523     else
 3524     subdumpDirRpmByDate(list, dir, subdir, installed,
 3525         &ByDate, RSS, &rdfcount,
 3526             "cdates_title_less_1w_old", MAX_AGE_LESS_1W, &cur, &page, &count);
 3527 
 3528     /*
 3529      * Then dump RPMs less than two weeks old.
 3530      */
 3531     if (installed)
 3532         subdumpDirRpmByDate(list, dir, subdir, installed,
 3533             &ByDate, RSS, &rdfcount,
 3534             "idates_title_less_2w_old", MAX_AGE_LESS_2W, &cur, &page, &count);
 3535     else
 3536         subdumpDirRpmByDate(list, dir, subdir, installed,
 3537             &ByDate, RSS, &rdfcount,
 3538             "cdates_title_less_2w_old", MAX_AGE_LESS_2W, &cur, &page, &count);
 3539 
 3540     /*
 3541      * Then dump RPMs less than one month old.
 3542      */
 3543     if (installed)
 3544     subdumpDirRpmByDate(list, dir, subdir, installed,
 3545         &ByDate, RSS, &rdfcount,
 3546             "idates_title_less_1m_old", MAX_AGE_LESS_1M, &cur, &page, &count);
 3547     else
 3548     subdumpDirRpmByDate(list, dir, subdir, installed,
 3549         &ByDate, RSS, &rdfcount,
 3550             "cdates_title_less_1m_old", MAX_AGE_LESS_1M, &cur, &page, &count);
 3551 
 3552     /*
 3553      * Then dump RPMs more than one month old.
 3554      */
 3555     if (installed)
 3556     subdumpDirRpmByDate(list, dir, subdir, installed,
 3557         &ByDate, RSS, &rdfcount,
 3558             "idates_title_more_1m_old", MAX_AGE_MORE_1M, &cur, &page, &count);
 3559     else
 3560     subdumpDirRpmByDate(list, dir, subdir, installed,
 3561         &ByDate, RSS, &rdfcount,
 3562             "cdates_title_more_1m_old", MAX_AGE_MORE_1M, &cur, &page, &count);
 3563 
 3564 #else   // ifdef HAVE_LIBTEMPLATE
 3565 
 3566     /*
 3567      * First dump RPMs less than 3 days old.
 3568      */
 3569     if (!installed) generateColorIndicator(ByDate);
 3570     if (installed)
 3571     fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_I_LESS_3D_OLD]);
 3572     else
 3573     fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_LESS_3D_OLD]);
 3574     fprintf(ByDate, "<table><tbody>\n");
 3575     while ((cur != NULL) && ((currentTime - cur->date) < (3 * 24 * 60 * 60))) {
 3576     generateHtmlRpmRow(ByDate, cur, 0);
 3577     if ((RSS != NULL) && (rdfcount++ < rpm2html_rdf_count_limit)) {
 3578         generateRSSItem(RSS, cur);
 3579     }
 3580     cur = cur->next;
 3581     count++;
 3582     if ((count % MAX_TABLE_LENGHT) == 0)
 3583         fprintf(ByDate, "</tbody></table>\n<table><tbody>\n");
 3584     if (count > MAX_PAGE_LENGHT) {
 3585         count = 0;
 3586         fprintf(ByDate, "</tbody></table>\n");
 3587         fprintf(ByDate, "<a href=\"%d%s\">...</a>\n",
 3588                 page, localizedStrings[LANG_BYDATE_HTML]);
 3589         generateHtmlFooter(ByDate);
 3590         fclose(ByDate);
 3591         fullPathNameNr(buf, sizeof(buf), dir, subdir, localizedStrings[LANG_BYDATE_HTML], page++);
 3592         if (rpm2htmlVerbose > 1) {
 3593         printf("Dumping %s\n", buf);
 3594         }
 3595         ByDate = fopen(buf, "w");
 3596         if (ByDate == NULL) {
 3597         fprintf(stderr, "Couldn't save to file %s: %s\n",
 3598             buf, strerror(errno));
 3599         if (RSS) {
 3600             fprintf(RSS, "  </channel>\n");
 3601             fprintf(RSS, "</rss>\n");
 3602             fclose(RSS);
 3603         }
 3604         return;
 3605         }
 3606         if (installed) {
 3607         generateHtmlHeader(ByDate,
 3608                   localizedStrings[LANG_SORTED_BY_IDATE], NULL);
 3609         generateLinks(ByDate, installed);
 3610         fprintf(ByDate, "<h1 align=center>%s</h1>\n",
 3611             localizedStrings[LANG_SORTED_BY_IDATE]);
 3612         } else {
 3613         generateHtmlHeader(ByDate,
 3614                   localizedStrings[LANG_SORTED_BY_CDATE], NULL);
 3615         generateLinks(ByDate, installed);
 3616         fprintf(ByDate, "<h1 align=center>%s</h1>\n",
 3617             localizedStrings[LANG_SORTED_BY_CDATE]);
 3618         }
 3619         if (installed)
 3620         fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_I_LESS_3D_OLD]);
 3621         else
 3622         fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_LESS_3D_OLD]);
 3623         fprintf(ByDate, "<table><tbody>\n");
 3624     }
 3625     }
 3626     fprintf(ByDate, "</tbody></table>\n");
 3627 
 3628     /*
 3629      * Then dump RPMs less than one week old.
 3630      */
 3631     if (installed)
 3632     fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_I_LESS_1W_OLD]);
 3633     else
 3634     fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_LESS_1W_OLD]);
 3635     fprintf(ByDate, "<table><tbody>\n");
 3636     while ((cur != NULL) && ((currentTime - cur->date) < (7 * 24 * 60 * 60))) {
 3637     generateHtmlRpmRow(ByDate, cur, 0);
 3638     if ((RSS != NULL) && (rdfcount++ < rpm2html_rdf_count_limit)) {
 3639         generateRSSItem(RSS, cur);
 3640     }
 3641     cur = cur->next;
 3642     count++;
 3643     if ((count % MAX_TABLE_LENGHT) == 0)
 3644         fprintf(ByDate, "</tbody></table>\n<table><tbody>\n");
 3645     if (count > MAX_PAGE_LENGHT) {
 3646         count = 0;
 3647         fprintf(ByDate, "</tbody></table>\n");
 3648         fprintf(ByDate, "<a href=\"%d%s\">...</a>\n",
 3649                 page, localizedStrings[LANG_BYDATE_HTML]);
 3650         generateHtmlFooter(ByDate);
 3651         fclose(ByDate);
 3652         fullPathNameNr(buf, sizeof(buf), dir, subdir,
 3653                        localizedStrings[LANG_BYDATE_HTML], page++);
 3654         if (rpm2htmlVerbose > 1) {
 3655         printf("Dumping %s\n", buf);
 3656         }
 3657         ByDate = fopen(buf, "w");
 3658         if (ByDate == NULL) {
 3659         fprintf(stderr, "Couldn't save to file %s: %s\n",
 3660             buf, strerror(errno));
 3661         if (RSS) {
 3662             fprintf(RSS, "  </channel>\n");
 3663             fprintf(RSS, "</rss>\n");
 3664             fclose(RSS);
 3665         }
 3666         return;
 3667         }
 3668         if (installed) {
 3669         generateHtmlHeader(ByDate,
 3670                   localizedStrings[LANG_SORTED_BY_IDATE], NULL);
 3671         generateLinks(ByDate, installed);
 3672         fprintf(ByDate, "<h1 align=center>%s</h1>\n",
 3673             localizedStrings[LANG_SORTED_BY_IDATE]);
 3674         } else {
 3675         generateHtmlHeader(ByDate,
 3676                   localizedStrings[LANG_SORTED_BY_CDATE], NULL);
 3677         generateLinks(ByDate, installed);
 3678         fprintf(ByDate, "<h1 align=center>%s</h1>\n",
 3679             localizedStrings[LANG_SORTED_BY_CDATE]);
 3680         }
 3681         if (installed)
 3682         fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_I_LESS_1W_OLD]);
 3683         else
 3684         fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_LESS_1W_OLD]);
 3685         fprintf(ByDate, "<table><tbody>\n");
 3686     }
 3687     }
 3688     fprintf(ByDate, "</tbody></table>\n");
 3689 
 3690     /*
 3691      * Then dump RPMs less than two weeks old.
 3692      */
 3693     if (installed)
 3694     fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_I_LESS_2W_OLD]);
 3695     else
 3696     fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_LESS_2W_OLD]);
 3697     fprintf(ByDate, "<table><tbody>\n");
 3698     while ((cur != NULL) && ((currentTime - cur->date) < (14 * 24 * 60 * 60))) {
 3699     generateHtmlRpmRow(ByDate, cur, 0);
 3700     if ((RSS != NULL) && (rdfcount++ < rpm2html_rdf_count_limit)) {
 3701         generateRSSItem(RSS, cur);
 3702     }
 3703     cur = cur->next;
 3704     count++;
 3705     if ((count % MAX_TABLE_LENGHT) == 0)
 3706         fprintf(ByDate, "</tbody></table>\n<table><tbody>\n");
 3707     if (count > MAX_PAGE_LENGHT) {
 3708         count = 0;
 3709         fprintf(ByDate, "</tbody></table>\n");
 3710         fprintf(ByDate, "<a href=\"%d%s\">...</a>\n",
 3711                 page, localizedStrings[LANG_BYDATE_HTML]);
 3712         generateHtmlFooter(ByDate);
 3713         fclose(ByDate);
 3714         fullPathNameNr(buf, sizeof(buf), dir, subdir,
 3715                        localizedStrings[LANG_BYDATE_HTML], page++);
 3716         if (rpm2htmlVerbose > 1) {
 3717         printf("Dumping %s\n", buf);
 3718         }
 3719         ByDate = fopen(buf, "w");
 3720         if (ByDate == NULL) {
 3721         fprintf(stderr, "Couldn't save to file %s: %s\n",
 3722             buf, strerror(errno));
 3723         if (RSS) {
 3724             fprintf(RSS, "  </channel>\n");
 3725             fprintf(RSS, "</rss>\n");
 3726             fclose(RSS);
 3727         }
 3728         return;
 3729         }
 3730         if (installed) {
 3731         generateHtmlHeader(ByDate,
 3732                   localizedStrings[LANG_SORTED_BY_IDATE], NULL);
 3733         generateLinks(ByDate, installed);
 3734         fprintf(ByDate, "<h1 align=center>%s</h1>\n",
 3735             localizedStrings[LANG_SORTED_BY_IDATE]);
 3736         } else {
 3737         generateHtmlHeader(ByDate,
 3738                   localizedStrings[LANG_SORTED_BY_CDATE], NULL);
 3739         generateLinks(ByDate, installed);
 3740         fprintf(ByDate, "<h1 align=center>%s</h1>\n",
 3741             localizedStrings[LANG_SORTED_BY_CDATE]);
 3742         }
 3743         if (installed)
 3744         fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_I_LESS_2W_OLD]);
 3745         else
 3746         fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_LESS_2W_OLD]);
 3747         fprintf(ByDate, "<table><tbody>\n");
 3748     }
 3749     }
 3750     fprintf(ByDate, "</tbody></table>\n");
 3751 
 3752     /*
 3753      * Then dump RPMs less than one month old.
 3754      */
 3755     if (installed)
 3756     fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_I_LESS_1M_OLD]);
 3757     else
 3758     fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_LESS_1M_OLD]);
 3759     fprintf(ByDate, "<table><tbody>\n");
 3760     while ((cur != NULL) && ((currentTime - cur->date) < (30 * 24 * 60 * 60))) {
 3761     generateHtmlRpmRow(ByDate, cur, 0);
 3762     if ((RSS != NULL) && (rdfcount++ < rpm2html_rdf_count_limit)) {
 3763         generateRSSItem(RSS, cur);
 3764     }
 3765     cur = cur->next;
 3766     count++;
 3767     if ((count % MAX_TABLE_LENGHT) == 0)
 3768         fprintf(ByDate, "</tbody></table>\n<table><tbody>\n");
 3769     if (count > MAX_PAGE_LENGHT) {
 3770         count = 0;
 3771         fprintf(ByDate, "</tbody></table>\n");
 3772         fprintf(ByDate, "<a href=\"%d%s\">...</a>\n",
 3773                 page, localizedStrings[LANG_BYDATE_HTML]);
 3774         generateHtmlFooter(ByDate);
 3775         fclose(ByDate);
 3776         fullPathNameNr(buf, sizeof(buf), dir, subdir,
 3777                        localizedStrings[LANG_BYDATE_HTML], page++);
 3778         if (rpm2htmlVerbose > 1) {
 3779         printf("Dumping %s\n", buf);
 3780         }
 3781         ByDate = fopen(buf, "w");
 3782         if (ByDate == NULL) {
 3783         fprintf(stderr, "Couldn't save to file %s: %s\n",
 3784             buf, strerror(errno));
 3785         if (RSS) {
 3786             fprintf(RSS, "  </channel>\n");
 3787             fprintf(RSS, "</rss>\n");
 3788             fclose(RSS);
 3789         }
 3790         return;
 3791         }
 3792         if (installed) {
 3793         generateHtmlHeader(ByDate,
 3794                   localizedStrings[LANG_SORTED_BY_IDATE], NULL);
 3795         generateLinks(ByDate, installed);
 3796         fprintf(ByDate, "<h1 align=center>%s</h1>\n",
 3797             localizedStrings[LANG_SORTED_BY_IDATE]);
 3798         } else {
 3799         generateHtmlHeader(ByDate,
 3800                   localizedStrings[LANG_SORTED_BY_CDATE], NULL);
 3801         generateLinks(ByDate, installed);
 3802         fprintf(ByDate, "<h1 align=center>%s</h1>\n",
 3803             localizedStrings[LANG_SORTED_BY_CDATE]);
 3804         }
 3805         if (installed)
 3806         fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_I_LESS_1M_OLD]);
 3807         else
 3808         fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_LESS_1M_OLD]);
 3809         fprintf(ByDate, "<table><tbody>\n");
 3810     }
 3811     }
 3812     fprintf(ByDate, "</tbody></table>\n");
 3813 
 3814     /*
 3815      * Then dump RPMs more than one month old.
 3816      */
 3817     if (installed)
 3818     fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_I_MORE_1M_OLD]);
 3819     else
 3820     fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_MORE_1M_OLD]);
 3821     fprintf(ByDate, "<table><tbody>\n");
 3822     while (cur != NULL) {
 3823     generateHtmlRpmRow(ByDate, cur, 0);
 3824     if ((RSS != NULL) && (rdfcount++ < rpm2html_rdf_count_limit)) {
 3825         generateRSSItem(RSS, cur);
 3826     }
 3827     cur = cur->next;
 3828     count++;
 3829     if ((count % MAX_TABLE_LENGHT) == 0)
 3830         fprintf(ByDate, "</tbody></table>\n<table><tbody>\n");
 3831     if (count > MAX_PAGE_LENGHT) {
 3832         count = 0;
 3833         fprintf(ByDate, "</tbody></table>\n");
 3834         fprintf(ByDate, "<a href=\"%d%s\">...</a>\n",
 3835                 page, localizedStrings[LANG_BYDATE_HTML]);
 3836         generateHtmlFooter(ByDate);
 3837         fclose(ByDate);
 3838         fullPathNameNr(buf, sizeof(buf), dir, subdir,
 3839                        localizedStrings[LANG_BYDATE_HTML], page++);
 3840         if (rpm2htmlVerbose > 1) {
 3841         printf("Dumping %s\n", buf);
 3842         }
 3843         ByDate = fopen(buf, "w");
 3844         if (ByDate == NULL) {
 3845         fprintf(stderr, "Couldn't save to file %s: %s\n",
 3846             buf, strerror(errno));
 3847         if (RSS) {
 3848             fprintf(RSS, "  </channel>\n");
 3849             fprintf(RSS, "</rss>\n");
 3850             fclose(RSS);
 3851         }
 3852         return;
 3853         }
 3854         if (installed) {
 3855         generateHtmlHeader(ByDate,
 3856                   localizedStrings[LANG_SORTED_BY_IDATE], NULL);
 3857         generateLinks(ByDate, installed);
 3858         fprintf(ByDate, "<h1 align=center>%s</h1>\n",
 3859             localizedStrings[LANG_SORTED_BY_IDATE]);
 3860         } else {
 3861         generateHtmlHeader(ByDate,
 3862                   localizedStrings[LANG_SORTED_BY_CDATE], NULL);
 3863         generateLinks(ByDate, installed);
 3864         fprintf(ByDate, "<h1 align=center>%s</h1>\n",
 3865             localizedStrings[LANG_SORTED_BY_CDATE]);
 3866         }
 3867         if (installed)
 3868         fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_I_MORE_1M_OLD]);
 3869         else
 3870         fprintf(ByDate, "<h2>%s</h2>\n", localizedStrings[LANG_MORE_1M_OLD]);
 3871         fprintf(ByDate, "<table><tbody>\n");
 3872     }
 3873     }
 3874     fprintf(ByDate, "</tbody></table>\n");
 3875 #endif  // ifdef HAVE_LIBTEMPLATE
 3876 
 3877     generateHtmlFooter(ByDate);
 3878     fclose(ByDate);
 3879     if (RSS) {
 3880     fprintf(RSS, "  </channel>\n");
 3881     fprintf(RSS, "</rss>\n");
 3882     fclose(RSS);
 3883     }
 3884 }
 3885 
 3886 /*
 3887  * Dump the full set of  RPM by Date HTML file.
 3888  * One expect that the RPM files have been sorted by date.
 3889  */
 3890 void dumpRpmByDate(rpmDataPtr list, int installed) {
 3891     if (!rpm2html_dump_html) return;
 3892 
 3893     if (rpm2htmlVerbose)
 3894       printf("Dumping \"by date\" HTML pages\n");
 3895 
 3896     dumpDirRpmByDate(list, NULL, NULL, installed);
 3897 }
 3898 
 3899 /*
 3900  * Dump the RPM in a flat list sorted by Name.
 3901  * One expect that the RPM files have been sorted by name.
 3902  */
 3903 void dumpDirRpmByNameFlat(rpmDataPtr list, rpmDirPtr dir,
 3904                       char *subdir, int installed) {
 3905     FILE *ByName;
 3906     rpmDataPtr cur;
 3907 
 3908     if (!rpm2html_dump_html) return;
 3909 
 3910     cur = list;
 3911 
 3912     fullPathName(buf, sizeof(buf), dir, subdir, localizedStrings[LANG_BYNAME_HTML]);
 3913     if (rpm2htmlVerbose > 1) {
 3914         printf("Dumping %s\n", buf);
 3915     }
 3916 
 3917     ByName = fopen(buf, "w");
 3918     if (ByName == NULL) {
 3919         fprintf(stderr, "Couldn't save to file %s: %s\n",
 3920             buf, strerror(errno));
 3921         return;
 3922     }
 3923 #ifdef HAVE_LIBTEMPLATE
 3924     generateHtmlHeader(ByName, "names_title", NULL);
 3925     generateLinks(ByName, installed);
 3926     if (!installed) generateColorIndicator(ByName);
 3927 
 3928     parseNwriteTemplate(ByName, engine, "names_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 3929       // later reconsicer usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 3930 
 3931     while (cur != NULL) {
 3932     generateHtmlRpmArchRow(ByName, cur);
 3933     if ((dir == NULL) && (subdir == NULL))
 3934         cur = cur->nextSoft;
 3935     else
 3936         cur = cur->next;
 3937     }
 3938 
 3939     parseNwriteTemplate(ByName, engine, "name_end");
 3940 
 3941 #else   // ifdef HAVE_LIBTEMPLATE
 3942 
 3943     generateHtmlHeader(ByName, localizedStrings[LANG_SORTED_BY_NAME], NULL);
 3944     generateLinks(ByName, installed);
 3945     fprintf(ByName, "<h1 align=center>%s</h1>\n",
 3946         localizedStrings[LANG_SORTED_BY_NAME]);
 3947     if (!installed) generateColorIndicator(ByName);
 3948     fprintf(ByName, "<table><tbody>\n");
 3949 
 3950     while (cur != NULL) {
 3951     generateHtmlRpmArchRow(ByName, cur);
 3952     if ((dir == NULL) && (subdir == NULL))
 3953         cur = cur->nextSoft;
 3954     else
 3955         cur = cur->next;
 3956     }
 3957 
 3958     fprintf(ByName, "</tbody></table>\n");
 3959 #endif  // ifdef HAVE_LIBTEMPLATE
 3960 
 3961     generateHtmlFooter(ByName);
 3962     fclose(ByName);
 3963 }
 3964 
 3965 /*
 3966  * Dump the RPM in a subtree by Name HTML file.
 3967  * One expect that the RPM files have been sorted by name.
 3968  */
 3969 void dumpDirRpmByName(rpmDataPtr list, rpmDirPtr dir,
 3970                       char *subdir, int installed) {
 3971     FILE *ByName;
 3972     FILE *CurrName = NULL;
 3973     rpmDataPtr cur;
 3974     int i = 0;
 3975     char last_letter = '\0', letter;
 3976 
 3977     if (!rpm2html_dump_html) return;
 3978 
 3979     if ((dir == NULL) && (subdir == NULL))
 3980     for (cur = list; cur != NULL; cur = cur->nextSoft) i++;
 3981     else
 3982     for (cur = list; cur != NULL; cur = cur->next) i++;
 3983     if (i < MAX_NAME_LIST_LENGHT) {
 3984         dumpDirRpmByNameFlat(list, dir, subdir, installed);
 3985         return;
 3986     }
 3987     i = 0;
 3988     cur = list;
 3989 
 3990     fullPathName(buf, sizeof(buf), dir, subdir, localizedStrings[LANG_BYNAME_HTML]);
 3991     if (rpm2htmlVerbose > 1) {
 3992         printf("Dumping %s\n", buf);
 3993     }
 3994 
 3995     ByName = fopen(buf, "w");
 3996     if (ByName == NULL) {
 3997         fprintf(stderr, "Couldn't save to file %s: %s\n",
 3998             buf, strerror(errno));
 3999         return;
 4000     }
 4001 
 4002 #ifdef HAVE_LIBTEMPLATE
 4003     generateHtmlHeader(ByName, "names_title", NULL);
 4004     generateLinks(ByName, installed);
 4005     parseNwriteTemplate(ByName, engine, "names_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 4006       // later reconsicer usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 4007 
 4008     while (cur != NULL) {
 4009     letter = toupper(cur->name[0]);
 4010     if (letter != last_letter) {
 4011         if (CurrName != NULL) {
 4012         /*
 4013          * Finish the previous file.
 4014          */
 4015         parseNwriteTemplate(CurrName, engine, "name_end");
 4016         generateHtmlFooter(CurrName);
 4017         fclose(CurrName);
 4018         }
 4019         if (i != 0) {
 4020             snprintf(buf, sizeof(buf), "%c", last_letter);
 4021             tpl_element_set(engine, "letter", buf);
 4022             snprintf(buf, sizeof(buf), "%d", i);
 4023             tpl_element_set(engine, "count", buf);
 4024             parseNwriteTemplate(ByName, engine, "names_item");
 4025         }
 4026         fullPathNameLr(buf, sizeof(buf), dir, subdir,
 4027                        localizedStrings[LANG_BYNAME_HTML], letter);
 4028         if (rpm2htmlVerbose > 1) {
 4029         printf("Dumping %s\n", buf);
 4030         }
 4031 
 4032         CurrName = fopen(buf, "w");
 4033         if (CurrName == NULL) {
 4034         fprintf(stderr, "Couldn't save to file %s: %s\n",
 4035             buf, strerror(errno));
 4036         return;
 4037         }
 4038         snprintf(buf, sizeof(buf), "%c", letter);
 4039         tpl_element_set(engine, "letter", buf);
 4040         generateHtmlHeader(CurrName, "name_title", NULL);
 4041         generateLinks(CurrName, installed);
 4042             parseNwriteTemplate(CurrName, engine, "name_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 4043               // later reconsider usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 4044         if (!installed) generateColorIndicator(CurrName);
 4045         parseNwriteTemplate(CurrName, engine, "name_begin");
 4046         i = 0;
 4047     }
 4048     i++;
 4049     if ((i % MAX_TABLE_LENGHT) == 0) {
 4050         parseNwriteTemplate(CurrName, engine, "name_end");
 4051         parseNwriteTemplate(CurrName, engine, "name_begin");
 4052         }
 4053     last_letter = letter;
 4054     generateHtmlRpmArchRow(CurrName, cur);
 4055     if ((dir == NULL) && (subdir == NULL))
 4056         cur = cur->nextSoft;
 4057     else
 4058         cur = cur->next;
 4059     }
 4060 
 4061     if (i != 0) {
 4062     snprintf(buf, sizeof(buf), "%c", last_letter);
 4063     tpl_element_set(engine, "letter", buf);
 4064     snprintf(buf, sizeof(buf), "%d", i);
 4065     tpl_element_set(engine, "count", buf);
 4066     parseNwriteTemplate(ByName, engine, "names_item");
 4067     }
 4068     if (CurrName != NULL) {
 4069     /*
 4070      * Finish the previous file.
 4071      */
 4072     parseNwriteTemplate(CurrName, engine, "name_end");
 4073     generateHtmlFooter(CurrName);
 4074     fclose(CurrName);
 4075     }
 4076 
 4077 #else   // ifdef HAVE_LIBTEMPLATE
 4078 
 4079     generateHtmlHeader(ByName, localizedStrings[LANG_SORTED_BY_NAME], NULL);
 4080     generateLinks(ByName, installed);
 4081     fprintf(ByName, "<h1 align=center>%s</h1>\n",
 4082         localizedStrings[LANG_SORTED_BY_NAME]);
 4083 
 4084     while (cur != NULL) {
 4085     letter = toupper(cur->name[0]);
 4086     if (letter != last_letter) {
 4087         if (CurrName != NULL) {
 4088         /*
 4089          * Finish the previous file.
 4090          */
 4091         fprintf(CurrName, "</tbody></table>\n");
 4092         generateHtmlFooter(CurrName);
 4093         fclose(CurrName);
 4094         }
 4095         if (i != 0)
 4096         fprintf(ByName, "<p><a href=\"%c%s\">%d %s %c</a></p>\n",
 4097                 last_letter, localizedStrings[LANG_BYNAME_HTML],
 4098             i, localizedStrings[LANG_BEGINNING_LETTER],
 4099             last_letter);
 4100         fullPathNameLr(buf, sizeof(buf), dir, subdir,
 4101                        localizedStrings[LANG_BYNAME_HTML], letter);
 4102         if (rpm2htmlVerbose > 1) {
 4103         printf("Dumping %s\n", buf);
 4104         }
 4105 
 4106         CurrName = fopen(buf, "w");
 4107         if (CurrName == NULL) {
 4108         fprintf(stderr, "Couldn't save to file %s: %s\n",
 4109             buf, strerror(errno));
 4110         return;
 4111         }
 4112         snprintf(buf, sizeof(buf), "%s %c", localizedStrings[LANG_BEGINNING_LETTER],
 4113                 letter);
 4114         generateHtmlHeader(CurrName, buf, NULL);
 4115         generateLinks(CurrName, installed);
 4116         fprintf(CurrName, "<h1 align=center>%s</h1>\n", buf);
 4117         if (!installed) generateColorIndicator(CurrName);
 4118         fprintf(CurrName, "<table><tbody>\n");
 4119         i = 0;
 4120     }
 4121     i++;
 4122     if ((i % MAX_TABLE_LENGHT) == 0)
 4123         fprintf(CurrName, "</tbody></table>\n<table><tbody>\n");
 4124     last_letter = letter;
 4125     generateHtmlRpmArchRow(CurrName, cur);
 4126     if ((dir == NULL) && (subdir == NULL))
 4127         cur = cur->nextSoft;
 4128     else
 4129         cur = cur->next;
 4130     }
 4131 
 4132     if (i != 0)
 4133     fprintf(ByName, "<p><a href=\"%c%s\">%d %s %c</a></p>\n",
 4134         last_letter, localizedStrings[LANG_BYNAME_HTML],
 4135         i, localizedStrings[LANG_BEGINNING_LETTER],
 4136         last_letter);
 4137     if (CurrName != NULL) {
 4138     /*
 4139      * Finish the previous file.
 4140      */
 4141     fprintf(CurrName, "</tbody></table>\n");
 4142     generateHtmlFooter(CurrName);
 4143     fclose(CurrName);
 4144     }
 4145 #endif  // ifdef HAVE_LIBTEMPLATE
 4146 
 4147     generateHtmlFooter(ByName);
 4148     fclose(ByName);
 4149 }
 4150 
 4151 /*
 4152  * Dump the full set of  RPM by Name HTML file.
 4153  * One expect that the RPM files have been sorted by name.
 4154  */
 4155 void dumpRpmByName(rpmDataPtr list, int installed) {
 4156     if (!rpm2html_dump_html) return;
 4157 
 4158     if (rpm2htmlVerbose)
 4159       printf("Dumping \"by name\" HTML pages\n");
 4160 
 4161     dumpDirRpmByName(list, NULL, NULL, installed);
 4162 }
 4163 
 4164 /*
 4165  * Dump the index for a directory and its subdirectories.
 4166  */
 4167 rpmDataPtr dumpDirIndex(rpmDirPtr dir, rpmSubdirPtr tree, rpmDataPtr list) {
 4168     FILE *html;
 4169     int i;
 4170 
 4171     if (!rpm2html_dump_html) return(list);
 4172     if ((dir != NULL) && (!dir->html)) return(list);
 4173 
 4174     if (tree->htmlpath[0] != '\0')
 4175     snprintf(buf, sizeof(buf), "%s/%s/%s", rpm2html_dir, tree->htmlpath,
 4176         localizedStrings[LANG_INDEX_HTML]);
 4177     else
 4178     snprintf(buf, sizeof(buf), "%s/%s", rpm2html_dir,
 4179         localizedStrings[LANG_INDEX_HTML]);
 4180 
 4181     if (rpm2htmlVerbose > 1) {
 4182     printf("Dumping %s\n", buf);
 4183     }
 4184 
 4185     html = fopen(buf, "w");
 4186     if (html == NULL) {
 4187         fprintf(stderr, "Couldn't save to file %s: %s\n",
 4188             buf, strerror(errno));
 4189         return(list);
 4190     }
 4191     if (tree->htmlpath[0] != '\0')
 4192         snprintf(buf, sizeof(buf), "%s : %s", dir->name, tree->htmlpath);
 4193     else
 4194         snprintf(buf, sizeof(buf), "%s", dir->name);
 4195 
 4196 #ifdef HAVE_LIBTEMPLATE
 4197     tpl_element_set(engine, "dir", buf);
 4198     generateHtmlHeader(html, "dirs_title", NULL);
 4199     generateLinks(html, 0);
 4200     if (((tree->rpmpath == NULL) || (tree->rpmpath[0] == '\0')) &&
 4201         (dir->build_tree)) {
 4202         tpl_parse(engine, "dirs_parent", "p_title", 0);
 4203         tpl_element_set(engine, "title", tpl_element_get(engine, "p_title"));
 4204     }
 4205     else
 4206         tpl_element_set(engine, "title", "");
 4207     parseNwriteTemplate(html, engine, "dirs_header");  // XXX ugly hack: here we assume that generateHtmlHeader() alredy filled proper value into "title" element of engine
 4208       // later reconsicer usage of rpm2html only with libtemplate and then a) remove all those ifdefs and b) restructure html.c so as this ugy hack is not necessary
 4209 
 4210     if (((tree->rpmpath == NULL) || (tree->rpmpath[0] == '\0')) &&
 4211         (dir->build_tree)) {
 4212     if (tree->color) {
 4213             tpl_element_set(engine, "color", tree->color);
 4214             tpl_parse(engine, "dirs_tree_color", "p_html_tree_header_color", 0);    // XXX maybe not necessary to call this more than once? => optimize to call just once
 4215             tpl_element_set(engine, "color", tpl_element_get(engine, "p_html_tree_header_color"));
 4216         }
 4217     else
 4218         tpl_element_set(engine, "color", "");
 4219     tpl_element_set(engine, "url", rpm2html_url);
 4220     parseNwriteTemplate(html, engine, "dirs_tree");
 4221     }
 4222 
 4223     generateHtmlTree(html, tree, 0, 1);
 4224 
 4225     tpl_element_set(engine, "color", dir->color);
 4226     tpl_element_set(engine, "url", dir->ftp);
 4227     if (dir->name == NULL)
 4228         tpl_element_set(engine, "name", dir->ftp);
 4229     else
 4230         tpl_element_set(engine, "name", dir->name);
 4231     parseNwriteTemplate(html, engine, "dir_begin");
 4232 
 4233     if ((dir->ftpsrc != NULL) && (strcmp(dir->ftp, dir->ftpsrc))) {
 4234         tpl_element_set(engine, "color", dir->color);
 4235         tpl_element_set(engine, "url", dir->ftpsrc);
 4236         tpl_element_set(engine, "name", dir->ftpsrc);
 4237         parseNwriteTemplate(html, engine, "dir_src");
 4238     }
 4239     if (dir->nb_mirrors > 0) {
 4240         tpl_element_set(engine, "color", dir->color);
 4241         tpl_element_set(engine, "url", dir->mirrors[0]);
 4242         tpl_element_set(engine, "name", dir->mirrors[0]);
 4243         parseNwriteTemplate(html, engine, "dir_mirrors");
 4244     }
 4245     if (dir->nb_mirrors > 1) {
 4246         tpl_element_set(engine, "color", dir->color);
 4247         parseNwriteTemplate(html, engine, "dir_mirrors_list_begin");
 4248     for (i = 1;i < dir->nb_mirrors;i++) {
 4249         //tpl_element_set(engine, "color", dir->color); - we've still got it
 4250         tpl_element_set(engine, "url", dir->mirrors[i]);
 4251         tpl_element_set(engine, "name", dir->mirrors[i]);
 4252         parseNwriteTemplate(html, engine, "dir_mirrors_list_item");
 4253     }
 4254     }
 4255     parseNwriteTemplate(html, engine, "dir_mirrors_list_end");
 4256 
 4257 #else   // ifdef HAVE_LIBTEMPLATE
 4258 
 4259     generateHtmlHeader(html, buf, NULL);
 4260     generateLinks(html, 0);
 4261     if (((tree->rpmpath == NULL) || (tree->rpmpath[0] == '\0')) &&
 4262         (dir->build_tree))
 4263         snprintf(buf, sizeof(buf), "<a href=\"Root%s\">%s</a>",
 4264             localizedStrings[LANG_TREE_HTML],
 4265         localizedStrings[LANG_INDEX_HTML]);
 4266     fprintf(html, "<h1 align=center>%s</h1>\n", buf);
 4267 
 4268     fprintf(html, "<ul>\n");
 4269     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 4270             localizedStrings[LANG_LIST],
 4271         localizedStrings[LANG_GROUP_HTML],
 4272         localizedStrings[LANG_INDEX_GROUP]);
 4273     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 4274             localizedStrings[LANG_LIST],
 4275         localizedStrings[LANG_BYDATE_HTML],
 4276         localizedStrings[LANG_INDEX_CREATION]);
 4277     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 4278             localizedStrings[LANG_LIST],
 4279         localizedStrings[LANG_BYNAME_HTML],
 4280         localizedStrings[LANG_INDEX_NAME]);
 4281     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 4282             localizedStrings[LANG_LIST],
 4283         localizedStrings[LANG_VENDOR_HTML],
 4284         localizedStrings[LANG_INDEX_VENDOR]);
 4285     fprintf(html, "<li>\n%s <a href=\"%s\">%s</a>\n",
 4286             localizedStrings[LANG_LIST],
 4287         localizedStrings[LANG_DISTRIB_HTML],
 4288         localizedStrings[LANG_INDEX_DISTRIB]);
 4289     fprintf(html, "</ul>\n\n");
 4290     if (((tree->rpmpath == NULL) || (tree->rpmpath[0] == '\0')) &&
 4291         (dir->build_tree)) {
 4292     fprintf(html, "<h3>%s</h3>\n",
 4293         localizedStrings[LANG_BROWSE_TREE]);
 4294     if (tree->color)
 4295         fprintf(html, "<blockquote style=\"background : %s\">\n",
 4296                 tree->color);
 4297     else
 4298         fprintf(html, "<blockquote>\n");
 4299     fprintf(html, "<p><strong><a href=\"%s\">",
 4300             localizedStrings[LANG_TREE_HTML]);
 4301     fprintf(html,
 4302             "<img src=\"%s/dir.png\" alt=\"Directory\" border=0>",
 4303                 rpm2html_url);
 4304     fprintf(html, " ..</a></strong></p></blockquote>\n");
 4305     }
 4306 
 4307     generateHtmlTree(html, tree, 0, 1);
 4308     
 4309     fprintf(html, "<table bgcolor=\"%s\"><tbody>\n<tr>\n",
 4310         dir->color);
 4311     if (dir->name == NULL)
 4312     fprintf(html, "<td bgcolor=\"%s\" colspan=2><a href=\"%s\">%s</a></td>\n",
 4313         dir->color, dir->ftp, dir->ftp);
 4314     else
 4315     fprintf(html, "<td bgcolor=\"%s\" colspan=2><a href=\"%s\">%s</a></td>\n",
 4316         dir->color, dir->ftp, dir->name);
 4317     fprintf(html, "</tr>\n");
 4318     if ((dir->ftpsrc != NULL) && (strcmp(dir->ftp, dir->ftpsrc)))
 4319     fprintf(html, 
 4320         "<tr><td bgcolor=\"%s\">%s:</td><td bgcolor=\"%s\"><a href=\"%s\">%s</a></td></tr>\n",
 4321         dir->color, localizedStrings[LANG_SOURCES_REPOSITORY],
 4322         dir->color, dir->ftpsrc, dir->ftpsrc);
 4323     if (dir->nb_mirrors > 0)
 4324     fprintf(html,
 4325         "<tr><td bgcolor=\"%s\">%s:</td><td bgcolor=\"%s\"><a href=\"%s\">%s</a></td></tr>\n",
 4326         dir->color, localizedStrings[LANG_LOCAL_MIRROR],
 4327         dir->color, dir->mirrors[0], dir->mirrors[0]);
 4328     if (dir->nb_mirrors > 1) {
 4329     fprintf(html, "<tr><td bgcolor=\"%s\" colspan=2>%s</td></tr>\n",
 4330         dir->color, localizedStrings[LANG_MIRRORS]);
 4331     for (i = 1;i < dir->nb_mirrors;i++) {
 4332         fprintf(html,
 4333         "<tr><td bgcolor=\"%s\" colspan=2><a href=\"%s\">%s</a></td></tr>\n",
 4334         dir->color, dir->mirrors[i], dir->mirrors[i]);
 4335     }
 4336     }
 4337     fprintf(html, "</tbody></table>\n");
 4338 #endif  // ifdef HAVE_LIBTEMPLATE
 4339 
 4340     generateHtmlFooter(html);
 4341     fclose(html);
 4342 
 4343     rpmDistribSort(&list, 0);
 4344     dumpDirRpmByDistribs(list, dir, tree->htmlpath, 0);
 4345     rpmGroupSort(&list, 0);
 4346     dumpDirRpmByGroups(list, dir, tree->htmlpath, 0);
 4347     rpmVendorSort(&list, 0);
 4348     dumpDirRpmByVendors(list, dir, tree->htmlpath, 0);
 4349     rpmDateSort(&list, 0);
 4350     dumpDirRpmByDate(list, dir, tree->htmlpath, 0);
 4351     rpmNameSort(&list, 0);
 4352     dumpDirRpmByName(list, dir, tree->htmlpath, 0);
 4353     return(list);
 4354 }
 4355 
 4356 /*
 4357  * Dump a real tree subdir title with links to parents and whole tree.
 4358  */
 4359 
 4360 void rpmDumpHtmlRealTreeTitle(FILE *subdir, rpmDirPtr dir, char *buffer) {
 4361 #ifndef HAVE_LIBTEMPLATE
 4362     char buf[3000];
 4363 #endif
 4364     char tmp[1000];
 4365     char path[1000];
 4366     char loc[200];
 4367     int i = 0, j = 0, k = 0; /* indexes for buffer, loc and path resp. */
 4368     int l = 0; /* index for directory depth */
 4369 
 4370     /* link for the root */
 4371 #ifdef HAVE_LIBTEMPLATE
 4372     tpl_element_set(engine, "name", dir->name);
 4373     parseNwriteTemplate(subdir, engine, "realtree_title_header");
 4374     while (buffer[i] != '\0') {
 4375         if (buffer[i] == '_') {
 4376         loc[j] = '\0';
 4377         path[k++] = '_';
 4378         path[k] = '\0';
 4379         tpl_element_set(engine, "path", path);
 4380         if (l++) {
 4381             snprintf(tmp, sizeof(tmp), "/%s</a>", loc);
 4382             tpl_element_set(engine, "name", tmp);
 4383             }
 4384         else
 4385             tpl_element_set(engine, "name", loc);
 4386             parseNwriteTemplate(subdir, engine, "realtree_title_link");
 4387         j = 0;
 4388     } else {
 4389         loc[j++] = buffer[i];
 4390         path[k++] = buffer[i];
 4391     }
 4392         i++;
 4393     }
 4394 
 4395     parseNwriteTemplate(subdir, engine, "realtree_title_footer");
 4396 
 4397 #else   // ifdef HAVE_LIBTEMPLATE
 4398 
 4399     snprintf(buf, sizeof(buf), "<a href=\"%s\">/</a>",
 4400          localizedStrings[LANG_TREE_HTML]);
 4401     while (buffer[i] != '\0') {
 4402         if (buffer[i] == '_') {
 4403         loc[j] = '\0';
 4404         path[k++] = '_';
 4405         path[k] = '\0';
 4406         if (l++)
 4407             snprintf(tmp, sizeof(tmp), " <a href=\"%s%s\">/%s</a>", path,
 4408                     localizedStrings[LANG_TREE_HTML], loc);
 4409         else
 4410             snprintf(tmp, sizeof(tmp), " <a href=\"%s%s\">%s</a>", path,
 4411                     localizedStrings[LANG_TREE_HTML], loc);
 4412             strcat(buf, tmp);
 4413         j = 0;
 4414     } else {
 4415         loc[j++] = buffer[i];
 4416         path[k++] = buffer[i];
 4417     }
 4418         i++;
 4419     }
 4420 
 4421     fprintf(subdir, "<h1 align=center><a href=\"Root%s\">%s</a> : %s</h1>\n",
 4422             localizedStrings[LANG_TREE_HTML], dir->name, buf);
 4423 #endif  // ifdef HAVE_LIBTEMPLATE
 4424 }
 4425 
 4426 /*
 4427  * Dump a real tree subdir.
 4428  */
 4429 
 4430 void rpmDumpHtmlRealTree(FILE *html, rpmDirPtr dir, rpmRealDirPtr tree,
 4431                          char *buffer, int index) {
 4432     FILE *subdir;
 4433     char buf[1000];
 4434     int has_subdir = 0;
 4435     int has_file = 0;
 4436     int i;
 4437 
 4438     if (!rpm2html_dump_html) return;
 4439     if ((dir != NULL) &&am