home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / analg211.zip / output2.c < prev    next >
Text File  |  1997-03-14  |  51KB  |  1,859 lines

  1. /*** analog 2.11 ***/
  2. /* Please read Readme.html, or http://www.statslab.cam.ac.uk/~sret1/analog/  */
  3.  
  4. /*** output2.c; subsiduary output functions. ***/
  5. /* See also output.c */
  6.  
  7. #include "analhea2.h"
  8.  
  9. /* used in lots of functions, so I declare it here */
  10. extern char *lngstr[NOLNGSTRS];
  11.  
  12. /*** The first function prints the "goto" line; links to all reports except
  13.      possibly one (the one we're on). If called gotos('\0') won't omit one.
  14.      If called gotos('z') will omit 'Top'. ***/
  15.  
  16. void gotos(FILE *outf, char c)
  17. {
  18.   extern char reportorder[];
  19.   extern flag bq, Bq, cq, dq, Dq, eq, fq, hq, Hq, iq, tq, mq, oq, rq, Sq, Wq;
  20.   extern flag xq;
  21.  
  22.   char *i;
  23.  
  24.   if (xq) {  /* NB Have already tested aq == HTML */
  25.     fprintf(outf, "\n\n<p>(<b>%s</b>", lngstr[goto_]);
  26.  
  27.     if (c != 'z')
  28.       fprintf(outf, ": <a HREF=\"#Top\">%s</a>", lngstr[top_]);
  29.  
  30.     for (i = reportorder; *i != '\0'; i++) {
  31.       if (c != *i) {   /* o/wise we don't want this one */
  32.     switch(*i) {
  33.     case 'b':
  34.       if (bq)
  35.         fprintf(outf, "%s <a HREF=\"#Browser\">%s</a>", lngstr[colon_],
  36.             lngstr[browsum_]);
  37.       break;
  38.     case 'B':
  39.       if (Bq)
  40.         fprintf(outf, "%s <a HREF=\"#FullBrowser\">%s</a>",
  41.             lngstr[colon_], lngstr[browrep_]);
  42.       break;
  43.     case 'c':
  44.       if (cq)
  45.         fprintf(outf, "%s <a HREF=\"#Status\">%s</a>", lngstr[colon_],
  46.             lngstr[statrep_]);
  47.       break;
  48.     case 'd':
  49.       if (dq)
  50.         fprintf(outf, "%s <a HREF=\"#Daily\">%s</a>", lngstr[colon_],
  51.             lngstr[daysum_]);
  52.       break;
  53.     case 'D':
  54.       if (Dq)
  55.         fprintf(outf, "%s <a HREF=\"#FullDaily\">%s</a>", lngstr[colon_],
  56.             lngstr[dayrep_]);
  57.       break;
  58.     case 'e':
  59.       if (eq)
  60.         fprintf(outf, "%s <a HREF=\"#Error\">%s</a>", lngstr[colon_],
  61.             lngstr[errrep_]);
  62.       break;
  63.     case 'f':
  64.       if (fq)
  65.         fprintf(outf, "%s <a HREF=\"#Referrer\">%s</a>", lngstr[colon_],
  66.             lngstr[refrep_]);
  67.       break;
  68.     case 'H':
  69.       if (Hq)
  70.         fprintf(outf, "%s <a HREF=\"#FullHourly\">%s</a>",
  71.             lngstr[colon_], lngstr[hourrep_]);
  72.       break;
  73.     case 'h':
  74.       if (hq)
  75.         fprintf(outf, "%s <a HREF=\"#Hourly\">%s</a>", lngstr[colon_],
  76.             lngstr[hoursum_]);
  77.       break;
  78.     case 'i':
  79.       if (iq)
  80.         fprintf(outf, "%s <a HREF=\"#Directory\">%s</a>", lngstr[colon_],
  81.             lngstr[dirrep_]);
  82.       break;
  83.     case 'm':
  84.       if (mq)
  85.         fprintf(outf, "%s <a HREF=\"#Monthly\">%s</a>", lngstr[colon_],
  86.             lngstr[monthrep_]);
  87.       break;
  88.     case 'o':
  89.       if (oq)
  90.         fprintf(outf, "%s <a HREF=\"#Domain\">%s</a>", lngstr[colon_],
  91.             lngstr[domrep_]);
  92.       break;
  93.     case 'r':
  94.       if (rq)
  95.         fprintf(outf, "%s <a HREF=\"#Request\">%s</a>", lngstr[colon_],
  96.             lngstr[reqrep_]);
  97.       break;
  98.     case 'S':
  99.       if (Sq)
  100.         fprintf(outf, "%s <a HREF=\"#Host\">%s</a>", lngstr[colon_],
  101.             lngstr[hostrep_]);
  102.       break;
  103.     case 't':
  104.       if (tq)
  105.         fprintf(outf, "%s <a HREF=\"#FileType\">%s</a>", lngstr[colon_],
  106.             lngstr[typerep_]);
  107.       break;
  108.     case 'W':
  109.       if (Wq)
  110.         fprintf(outf, "%s <a HREF=\"#Weekly\">%s</a>", lngstr[colon_],
  111.             lngstr[weekrep_]);
  112.       break;
  113.     }   /* end switch */
  114.       }     /* end if this i wanted */
  115.     }       /* end for i */
  116.  
  117.     fprintf(outf, ")\n");
  118.  
  119.   }         /* end if xq */
  120. }           /* end function gotos() */
  121.  
  122. /*** Next, to print strings with HTML reserved characters translated ***/
  123.  
  124. void htmlputc(char c, FILE *outf)
  125. {
  126.   if (c == '<')
  127.     fprintf(outf, "<");
  128.   else if (c == '>')
  129.     fprintf(outf, ">");
  130.   else if (c == '&')
  131.     fprintf(outf, "&");
  132.   else if (c == '"')
  133.     fprintf(outf, """);
  134.   else
  135.     putc(c, outf);
  136. }
  137.  
  138. void htmlfprintf(FILE *outf, char string[MAXSTRINGLENGTH])
  139. {
  140.   extern flag html2;
  141.  
  142.   char *c;
  143.  
  144.   for (c = string; *c != '\0'; c++) {
  145.     if (*c == '\\' && *(c + 1) != '\0') {
  146.       html2 = OFF;
  147.       putc(*(++c), outf);
  148.     }
  149.     else
  150.       htmlputc(*c, outf);
  151.   }
  152. }
  153.  
  154. /*** Print some character to the same length as a (poss. HTML) string ***/
  155. /*** Assume string contains no &'s except as markup ***/
  156.  
  157. size_t htmlstrlen(char *s)
  158. {
  159.   size_t i = 0;
  160.   flag f = TRUE;
  161.  
  162.   for ( ; *s != '\0'; s++) {
  163.     if (*s == '&')
  164.       f = OFF;
  165.     else if (*s == ';')
  166.       f = ON;
  167.     if (f)
  168.       i++;
  169.   }
  170.   return(i);
  171. }
  172.  
  173. void matchlength(FILE *outf, char *s, char c)
  174. {
  175.   int i;
  176.  
  177.   for (i = (int)htmlstrlen(s); i > 0; i--)
  178.     fprintf(outf, "%c", c);
  179. }
  180.  
  181. /*** Date printing routine ***/
  182.  
  183. size_t datefmtlen(char *fmt)
  184. {
  185.   extern char dayname[7][11];
  186.   extern char monthname[12][12];
  187.  
  188.   size_t i = 0;
  189.   char *c;
  190.  
  191.   for (c = fmt; *c != '\0'; c++) {
  192.     if (*c == '%' && *(c + 1) != '\0') {
  193.       c++;
  194.       if (*c == 'd' || *c == 'D' || *c == 'y' || *c == 'h' || *c == 'H' ||
  195.       *c == 'n')
  196.     i += 2;
  197.       else if (*c == 'Y')
  198.     i += 4;
  199.       else if (*c == 'm')
  200.     i += htmlstrlen(monthname[0]);
  201.       else if (*c == 'w')
  202.     i += htmlstrlen(dayname[0]);
  203.     }
  204.     else
  205.       i += 1;
  206.   }
  207.   return(i);
  208. }
  209.  
  210. void dateprintf(FILE *outf, char *fmt, int date, int month, int year, int hr,
  211.         int min)
  212. {
  213.   extern char dayname[7][11];
  214.   extern char monthname[12][12];
  215.  
  216.   char *c;
  217.  
  218.   for (c = fmt; *c != '\0'; c++) {
  219.     if (*c == '%' && *(c + 1) != '\0') {
  220.       c++;
  221.       switch (*c) {
  222.       case 'd':
  223.     fprintf(outf, "%2d", date);
  224.     break;
  225.       case 'D':
  226.     fprintf(outf, "%02d", date);
  227.     break;
  228.       case 'm':
  229.     fprintf(outf, "%s", monthname[month]);
  230.     break;
  231.       case 'y':
  232.     fprintf(outf, "%02d", year % 100);
  233.     break;
  234.       case 'Y':
  235.     fprintf(outf, "%d", year);
  236.     break;
  237.       case 'h':
  238.     fprintf(outf, "%2d", hr);
  239.     break;
  240.       case 'H':
  241.     fprintf(outf, "%02d", hr);
  242.     break;
  243.       case 'n':
  244.     fprintf(outf, "%02d", min);
  245.     break;
  246.       case 'w':
  247.     fprintf(outf, "%s", dayname[dayofdate(date, month, year)]);
  248.     break;
  249.       }
  250.     }
  251.     else
  252.       fprintf(outf, "%c", *c);
  253.   }
  254. }
  255.  
  256. /*** Now a little routine to find the correct divider for large numbers of
  257.      bytes. Also sets bprefix[0] as a side effect. ***/
  258.  
  259. double finddivider(double bytes, char *bprefix)
  260. {
  261.   extern flag rawbytes;
  262.  
  263.   double bdivider;
  264.  
  265.   if (rawbytes)
  266.     bdivider = 1.0;
  267.   else
  268.     for (bdivider = 1; bytes / bdivider >= 999999.5;
  269.      bdivider *= 1024)
  270.       ;  /* run bdivider to right multiplier */
  271.  
  272.   if (bdivider == 1.0)
  273.     *bprefix = '\0';
  274.   else if (bdivider == 1024.0)
  275.     *bprefix = 'k';
  276.   else if (bdivider == 1048576.0)
  277.     *bprefix = 'M';
  278.   else if (bdivider == 1073741824.0)
  279.     *bprefix = 'G';
  280.   else if (bdivider == 1099511627776.0)
  281.     *bprefix = 'T';
  282.   else       /* 10^6 terabytes should be enough. Just about. */
  283.     *bprefix = '?';
  284.  
  285.   return(bdivider);
  286. }
  287.  
  288. /*** print a line across the page, assuming ASCII mode ***/
  289.  
  290. void asciiline(FILE *outf)
  291. {
  292.   extern int pagewidth;
  293.  
  294.   int i;
  295.  
  296.   for (i = 0; i < pagewidth; i++)
  297.     fprintf(outf, "-");
  298.   fprintf(outf, "\n\n");
  299. }
  300.  
  301. /*** a barchart bar, length n, within <pre><tt> ***/
  302.  
  303. void barplot(FILE *outf, int n)
  304. {
  305.   extern int aq;
  306.   extern flag graphical;
  307.   extern char *imagedir;
  308.   extern char markchar;
  309.  
  310.   int i, k;
  311.   flag first = TRUE;
  312.  
  313.   if (aq || !graphical) {
  314.     for ( ; n > 0; n--)
  315.       fprintf(outf, "%c", markchar);
  316.   }
  317.  
  318.   else {
  319.     for (k = 32; k >= 1; k /= 2) {
  320.       while (n >= k) {
  321.     fprintf(outf, "<img src=\"");
  322.     htmlfprintf(outf, imagedir);
  323.     fprintf(outf, "bar%d.gif\" alt=\"", k);
  324.     if (first) {
  325.       for (i = n; i > 0; i--)
  326.         htmlputc(markchar, outf);
  327.       first = FALSE;
  328.     }
  329.     fprintf(outf, "\">");
  330.     n -= k;
  331.       }
  332.     }
  333.   }
  334. }
  335.  
  336. /*** Left hand two columns in OUTPUT PREFORMATTED ***/
  337. /* NB: Check (aq == PREFORMATTED) elsewhere */
  338.  
  339. void precols(FILE *outf, char *wantcols, char codeletter, flag byq, flag pageq)
  340. {
  341.   extern char *presep;
  342.  
  343.   char *cols;
  344.  
  345.   fprintf(outf, "%c%s", codeletter, presep);
  346.   for (cols = wantcols; *cols != '\0'; cols++) {
  347.     switch(*cols) {
  348.     case 'R':
  349.     case 'r': 
  350.       fprintf(outf, "%c", *cols);
  351.       break;
  352.     case 'P':
  353.     case 'p':
  354.       if (pageq)
  355.     fprintf(outf, "%c", *cols);
  356.       break;
  357.     case 'b':
  358.     case 'B':
  359.       if (byq)
  360.     fprintf(outf, "%c", *cols);
  361.       break;
  362.     }
  363.   }
  364.   fprintf(outf, "%s", presep);
  365. }
  366.  
  367. /*** Two functions to print R,r,P,p,B,b cols given various parameters ***/
  368.  
  369. void printcolheads(FILE *outf, char *wantcols, int fieldwidth, int pfieldwidth,
  370.            int bfieldwidth, char bprefix[2], char name[20], int width,
  371.            char type, flag byq, flag pageq, flag name1st)
  372. {   /* assume aq != PREFORMATTED already tested */
  373.   char *cols;
  374.   int i;
  375.  
  376.   if (name1st) {
  377.     for (i = (int)htmlstrlen(name); i < width; i++)
  378.       fprintf(outf, " ");
  379.     fprintf(outf, "%s: ", name);
  380.   }
  381.   for (cols = wantcols; *cols != '\0'; cols++) {
  382.     switch(*cols) {
  383.     case 'R':
  384.       for (i = (int)strlen(lngstr[(type == 'c' || type == 'e')?noccs_:nreqs_]);
  385.        i < fieldwidth; i++)
  386.     fprintf(outf, " ");
  387.       if (type == 'o')
  388.     fprintf(outf, " %s : ", lngstr[nreqs_]);
  389.       else if (type == 'c' || type == 'e')
  390.     fprintf(outf, "%s: ", lngstr[noccs_]);
  391.       else
  392.     fprintf(outf, "%s: ", lngstr[nreqs_]);
  393.       break;
  394.     case 'r':
  395.       for (i = (int)strlen(lngstr[(type == 'c' || type == 'e')?poccs_:preqs_]);
  396.        i < 6; i++)
  397.     fprintf(outf, " ");
  398.       if (type == 'o')
  399.     fprintf(outf, " %s : ", lngstr[preqs_]);
  400.       else if (type == 'c' || type == 'e')
  401.     fprintf(outf, "%s: ", lngstr[poccs_]);
  402.       else
  403.     fprintf(outf, "%s: ", lngstr[preqs_]);
  404.       break;
  405.     case 'P':
  406.       if (pageq) {
  407.     for (i = (int)strlen(lngstr[npgs_]); i < pfieldwidth; i++)
  408.       fprintf(outf, " ");
  409.     if (type == 'o')
  410.       fprintf(outf, " %s : ", lngstr[npgs_]);
  411.     else
  412.       fprintf(outf, "%s: ", lngstr[npgs_]);
  413.       }
  414.       break;
  415.     case 'p':
  416.       for (i = (int)strlen(lngstr[ppgs_]); i < 6; i++)
  417.     fprintf(outf, " ");
  418.       if (pageq) {
  419.     if (type == 'o')
  420.       fprintf(outf, " %s : ", lngstr[ppgs_]);
  421.     else
  422.       fprintf(outf, "%s: ", lngstr[ppgs_]);
  423.       }
  424.       break;
  425.     case 'B':
  426.       if (byq) {
  427.     for (i = 1 + (int)strlen(lngstr[nbytes_]); i < bfieldwidth; i++)
  428.       fprintf(outf, " ");
  429.     if (type == 'o')
  430.       fprintf(outf, " %s%s : ", (bprefix[0] == '\0')?" ":bprefix,
  431.           lngstr[nbytes_]);
  432.     else
  433.       fprintf(outf, "%s%s: ", (bprefix[0] == '\0')?" ":bprefix,
  434.           lngstr[nbytes_]);
  435.       }
  436.       break;
  437.     case 'b':
  438.       if (byq) {
  439.     for (i = (int)strlen(lngstr[pbytes_]); i < 6; i++)
  440.       fprintf(outf, " ");
  441.     if (type == 'o')
  442.       fprintf(outf, " %s : ", lngstr[pbytes_]);
  443.     else
  444.       fprintf(outf, "%s: ", lngstr[pbytes_]);
  445.       }
  446.       break;
  447.     }
  448.   }
  449.   if (!name1st) {
  450.     for (i = (int)htmlstrlen(name); i < width; i++)
  451.       fprintf(outf, " ");
  452.     fprintf(outf, "%s", name);
  453.   }
  454.   fprintf(outf, "\n");
  455.  
  456.   if (name1st) {
  457.     for (i = 0; i < width; i++)
  458.       fprintf(outf, "-");
  459.     fprintf(outf, "  ");
  460.   }
  461.  
  462.   for (cols = wantcols; *cols != '\0'; cols++) {
  463.     switch(*cols) {
  464.     case 'R':
  465.       for (i = 1; i <= fieldwidth + 2 * (type == 'o'); i++)
  466.     fprintf(outf, "-");
  467.       fprintf(outf, "  ");
  468.       break;
  469.     case 'r':
  470.       fprintf(outf, "%s------  ", (type == 'o')?"--":"");
  471.       break;
  472.     case 'P':
  473.       if (pageq) {
  474.     for (i = 1; i <= pfieldwidth + 2 * (type == 'o'); i++)
  475.       fprintf(outf, "-");
  476.     fprintf(outf, "  ");
  477.       }
  478.       break;
  479.     case 'p':
  480.       if (pageq)
  481.     fprintf(outf, "%s------  ", (type == 'o')?"--":"");
  482.       break;
  483.     case 'B':
  484.       if (byq) {
  485.     for (i = 1; i <= bfieldwidth + 2 * (type == 'o'); i++)
  486.       fprintf(outf, "-");
  487.     fprintf(outf, "  ");
  488.       }
  489.       break;
  490.     case 'b':
  491.       if (byq)
  492.     fprintf(outf, "%s------  ", (type == 'o')?"--":"");
  493.       break;
  494.     }
  495.   }
  496.   if (!name1st)
  497.     matchlength(outf, name, '-');
  498.   fprintf(outf, "\n");
  499. }
  500.  
  501. void printcols(FILE *outf, char *wantcols, int reqs, int pages, double bytes,
  502.            int fieldwidth, int pfieldwidth, int bfieldwidth,
  503.            double bdivider, int totreqs, int totpages, double totbytes,
  504.            char type, flag byq, flag pageq)
  505. {
  506.   extern char *presep;
  507.   extern char repsepchar, decpoint;
  508.   extern flag aq;
  509.  
  510.   char *cols;
  511.   double pc;
  512.   int pc1, pc2;
  513.   int k;
  514.  
  515.   for (cols = wantcols; *cols != '\0'; cols++) {
  516.     switch(*cols) {
  517.     case 'R':
  518.       if (aq == PREFORMATTED)
  519.     fprintf(outf, "%d%s", reqs, presep);
  520.       else {
  521.     if (type == 'o')
  522.       fprintf(outf, " ");
  523.     else if (type == 'O')
  524.       fprintf(outf, "(");
  525.     int3printf(outf, reqs, repsepchar, fieldwidth);
  526.     if (type == 'o')
  527.       fprintf(outf, " : ");
  528.     else if (type == 'O')
  529.       fprintf(outf, "): ");
  530.     else
  531.       fprintf(outf, ": ");
  532.       }
  533.       break;
  534.     case 'r':
  535.       if (totreqs == 0)
  536.     pc = 0;
  537.       else
  538.     pc = (reqs + 0.0) / ((totreqs + 0.0) / 10000);
  539.       pc1 = ((int)(pc + 0.5)) / 100;     /* whole no. of %reqs */
  540.       pc2 = ((int)(pc + 0.5)) % 100;     /* remaining 100ths. */
  541.       if (aq != PREFORMATTED) {
  542.     if (type == 'o')
  543.       fprintf(outf, " ");
  544.     else if (type == 'O')
  545.       fprintf(outf, "(");
  546.       }
  547.       if (pc1 == 100) {
  548.     if (aq == PREFORMATTED)
  549.       fprintf(outf, "100.00");
  550.     else
  551.       fprintf(outf, "  100%%");
  552.       }
  553.       else if (pc1 > 0 || pc2 > 0) {
  554.     if (aq == PREFORMATTED)
  555.       fprintf(outf, "%d.%02d", pc1, pc2);
  556.     else
  557.       fprintf(outf, "%2d%c%02d%%", pc1, decpoint, pc2);
  558.       }
  559.       else if (aq == PREFORMATTED)
  560.     fprintf(outf, "0.00");
  561.       else
  562.     fprintf(outf, "      ");
  563.       if (aq == PREFORMATTED)
  564.     fprintf(outf, "%s", presep);
  565.       else if (type == 'o')
  566.     fprintf(outf, " : ");
  567.       else if (type == 'O')
  568.     fprintf(outf, "): ");
  569.       else
  570.     fprintf(outf, ": ");
  571.       break;
  572.     case 'P':
  573.       if (pageq) {
  574.     if (aq == PREFORMATTED)
  575.       fprintf(outf, "%d%s", pages, presep);
  576.     else {
  577.       if (type == 'o')
  578.         fprintf(outf, " ");
  579.       else if (type == 'O')
  580.         fprintf(outf, "(");
  581.       int3printf(outf, pages, repsepchar, pfieldwidth);
  582.       if (type == 'o')
  583.         fprintf(outf, " : ");
  584.       else if (type == 'O')
  585.         fprintf(outf, "): ");
  586.       else
  587.         fprintf(outf, ": ");
  588.     }
  589.       }
  590.       break;
  591.     case 'p':
  592.       if (pageq) {
  593.     if (totpages == 0)
  594.       pc = 0;
  595.     else
  596.       pc = (pages + 0.0) / ((totpages + 0.0) / 10000);
  597.     pc1 = ((int)(pc + 0.5)) / 100;
  598.     pc2 = ((int)(pc + 0.5)) % 100;
  599.     if (aq != PREFORMATTED) {
  600.       if (type == 'o')
  601.         fprintf(outf, " ");
  602.       else if (type == 'O')
  603.         fprintf(outf, "(");
  604.     }
  605.     if (pc1 == 100) {
  606.       if (aq == PREFORMATTED)
  607.         fprintf(outf, "100.00");
  608.       else
  609.         fprintf(outf, "  100%%");
  610.     }
  611.     else if (pc1 > 0 || pc2 > 0) {
  612.       if (aq == PREFORMATTED)
  613.         fprintf(outf, "%d.%02d", pc1, pc2);
  614.       else
  615.         fprintf(outf, "%2d%c%02d%%", pc1, decpoint, pc2);
  616.     }
  617.     else if (aq == PREFORMATTED)
  618.       fprintf(outf, "0.00");
  619.     else
  620.       fprintf(outf, "      ");
  621.     if (aq == PREFORMATTED)
  622.       fprintf(outf, "%s", presep);
  623.     else if (type == 'o')
  624.       fprintf(outf, " : ");
  625.     else if (type == 'O')
  626.       fprintf(outf, "): ");
  627.     else
  628.       fprintf(outf, ": ");
  629.       }
  630.       break;
  631.     case 'B':
  632.       if (byq) {
  633.     if (aq == PREFORMATTED)
  634.       fprintf(outf, "%.0f", bytes);
  635.     else if (bytes / bdivider > 0.5) {
  636.       if (type == 'o')
  637.         fprintf(outf, " ");
  638.       else if (type == 'O')
  639.         fprintf(outf, "(");
  640.       double3printf(outf, ROUND(bytes / bdivider), repsepchar,
  641.             bfieldwidth);
  642.       if (type == 'o')
  643.         fprintf(outf, " ");
  644.       else if (type == 'O')
  645.         fprintf(outf, ")");
  646.     }
  647.     else for (k = 0; k < bfieldwidth + 2 * (type == 'o' || type == 'O');
  648.           k++)
  649.       fprintf(outf, " ");
  650.     fprintf(outf, "%s", (aq == PREFORMATTED)?presep:": ");
  651.       }
  652.       break;
  653.     case 'b':
  654.       if (byq) {
  655.     if (totbytes < 0.5)
  656.       pc = 0;
  657.     else
  658.       pc = bytes / (totbytes / 10000);
  659.     pc1 = ((int)(pc + 0.5)) / 100;    /* whole no. of %bytes */
  660.     pc2 = ((int)(pc + 0.5)) % 100;    /* remaining 100ths. */
  661.     if (aq != PREFORMATTED) {
  662.       if (type == 'o')
  663.         fprintf(outf, " ");
  664.       else if (type == 'O')
  665.         fprintf(outf, "(");
  666.     }
  667.     if (pc1 == 100) {
  668.       if (aq == PREFORMATTED)
  669.         fprintf(outf, "100.00");
  670.       else
  671.         fprintf(outf, "  100%%");
  672.     }
  673.     else if (pc1 > 0 || pc2 > 0) {
  674.       if (aq == PREFORMATTED)
  675.         fprintf(outf, "%d.%02d", pc1, pc2);
  676.       else
  677.         fprintf(outf, "%2d%c%02d%%", pc1, decpoint, pc2);
  678.     }
  679.     else if (aq == PREFORMATTED)
  680.       fprintf(outf, "0.00");
  681.     else
  682.       fprintf(outf, "      ");
  683.     if (aq == PREFORMATTED)
  684.       fprintf(outf, "%s", presep);
  685.     else if (type == 'o')
  686.       fprintf(outf, " : ");
  687.     else if (type == 'O')
  688.       fprintf(outf, "): ");
  689.     else
  690.       fprintf(outf, ": ");
  691.       }
  692.       break;
  693.     }
  694.   }
  695. }
  696.  
  697.  
  698. /*** A nasty header bit. Return rough floor -- accurate if negative. ***/
  699. /* (NB: good enough to use total_bytes in place of total_brow_bytes etc. */
  700. int whatincluded(FILE *outf, int sortby, char *minreqstr, char *minpagestr,
  701.          char *minbytestr, char singular[27], char plural[29],
  702.          flag subdoms, char gender)
  703. {
  704.   extern double total_bytes;
  705.   extern int total_succ_reqs, total_page_reqs;
  706.  
  707.   int genfloor;
  708.   int tempint;
  709.   char tempc;
  710.   char *minstr;
  711.  
  712.   if (sortby == BYBYTES) {
  713.     minstr = minbytestr;
  714.     if (minstr[0] == '-')
  715.       genfloor = (int)bytefloor(total_bytes, minbytestr);
  716.     else
  717.       genfloor = (int)(ceil(bytefloor(total_bytes, minbytestr)));
  718.   }
  719.   else if (sortby == BYPAGES) {
  720.     minstr = minpagestr;
  721.     genfloor = reqfloor(total_page_reqs, minpagestr);
  722.   }
  723.   else {
  724.     minstr = minreqstr;
  725.     genfloor = reqfloor(total_succ_reqs, minreqstr);
  726.   }
  727.  
  728.   if (minstr[0] == '-') {
  729.     if (genfloor == -1) {
  730.       if (gender == 'm')
  731.     fprintf(outf, lngstr[firstsm_], singular);
  732.       else if (gender == 'f')
  733.     fprintf(outf, lngstr[firstsf_], singular);
  734.       else /* gender == 'n' */
  735.     fprintf(outf, lngstr[firstsn_], singular);
  736.     }
  737.     else {
  738.       if (gender == 'm')
  739.     fprintf(outf, lngstr[firstdsm_], -genfloor, plural);
  740.       else if (gender == 'f')
  741.     fprintf(outf, lngstr[firstdsf_], -genfloor, plural);
  742.       else /* gender == 'n' */
  743.     fprintf(outf, lngstr[firstdsn_], -genfloor, plural);
  744.     }
  745.   }  /* end if minstr[0] == '-' */
  746.   else {
  747.     if (gender == 'm')
  748.       fprintf(outf, lngstr[allsm_], plural);
  749.     else if (gender == 'f')
  750.       fprintf(outf, lngstr[allsf_], plural);
  751.     else /* gender == 'n' */
  752.       fprintf(outf, lngstr[allsn_], plural);
  753.       
  754.     if (genfloor > 0) {
  755.       fprintf(outf, " %s ", lngstr[atleast_]);
  756.       tempint = MAX((int)strlen(minstr) - 1, 0);
  757.       if (minstr[tempint] == '%') {
  758.     minstr[tempint] = '\0';
  759.     doublefprintf(outf, atof(minstr));
  760.     if (sortby == BYBYTES)
  761.       fprintf(outf, lngstr[ptraffic_]);
  762.     else if (sortby == BYPAGES)
  763.       fprintf(outf, lngstr[ppages_]);
  764.     else if (sortby == BYREQUESTS)
  765.       fprintf(outf, lngstr[prequests_]);
  766.       }
  767.       else if (sortby == BYBYTES) {
  768.     if (minbytestr[tempint] == 'k' || minbytestr[tempint] == 'M' ||
  769.         minbytestr[tempint] == 'G' || minbytestr[tempint] == 'T') {
  770.       tempc = minbytestr[tempint];
  771.       minbytestr[tempint] = '\0';
  772.       doublefprintf(outf, atof(minbytestr));
  773.       fprintf(outf, " %c%s", tempc, lngstr[btraffic_]);
  774.     }
  775.     else {
  776.       doublefprintf(outf, atof(minbytestr));
  777.       fprintf(outf, " %s", lngstr[btraffic_]);
  778.     }
  779.       }
  780.       else if (sortby == BYPAGES) {
  781.     fprintf(outf, "%d %s", atoi(minpagestr),
  782.         (atoi(minpagestr) == 1)?lngstr[pagereq_]:lngstr[pagereqs_]);
  783.       }
  784.       else { /* sortby not BYTES or PAGES */
  785.     fprintf(outf, "%d %s", atoi(minreqstr),
  786.         (atoi(minreqstr) == 1)?lngstr[request_]:lngstr[requests_]);
  787.       }
  788.     }    /* end if genfloor > 0 */
  789.   }      /* end if minstr[0] != '-' */
  790.   if (subdoms)
  791.     fprintf(outf, ".\n");
  792.   else if (sortby == BYBYTES || sortby == BYPAGES || sortby == BYREQUESTS) {
  793.     if (gender == 'm')
  794.       fprintf(outf, ",%s%s", (genfloor > 0)?"\n  ":" ",
  795.           (genfloor == -1)?lngstr[sortedms_]:lngstr[sortedmp_]);
  796.     else if (gender == 'f')
  797.       fprintf(outf, ",%s%s", (genfloor > 0)?"\n  ":" ",
  798.           (genfloor == -1)?lngstr[sortedfs_]:lngstr[sortedfp_]);
  799.     else /* gender == 'n' */
  800.       fprintf(outf, ",%s%s", (genfloor > 0)?"\n  ":" ",
  801.           (genfloor == -1)?lngstr[sortedns_]:lngstr[sortednp_]);
  802.     if (sortby == BYBYTES)
  803.       fprintf(outf, " %s.\n", lngstr[traffic_]);
  804.     else if (sortby == BYPAGES)
  805.       fprintf(outf, " %s.\n", lngstr[npages_]);
  806.     else /* sortby == BYREQUESTS */
  807.       fprintf(outf, " %s.\n", lngstr[nrequests_]);
  808.   }
  809.   else if (sortby == ALPHABETICAL) {
  810.     if (gender == 'm')
  811.       fprintf(outf, ",%s%s.\n", (genfloor > 0)?"\n  ":" ",
  812.           (genfloor == -1)?lngstr[alphasortms_]:lngstr[alphasortmp_]);
  813.     else if (gender == 'f')
  814.       fprintf(outf, ",%s%s.\n", (genfloor > 0)?"\n  ":" ",
  815.           (genfloor == -1)?lngstr[alphasortfs_]:lngstr[alphasortfp_]);
  816.     else /* gender == 'n' */
  817.       fprintf(outf, ",%s%s.\n", (genfloor > 0)?"\n  ":" ",
  818.           (genfloor == -1)?lngstr[alphasortns_]:lngstr[alphasortnp_]);
  819.   }
  820.   else {  /* unsorted */
  821.     if (gender == 'm')
  822.       fprintf(outf, ", %s.\n",
  823.           (genfloor == -1)?lngstr[unsortedms_]:lngstr[unsortedmp_]);
  824.     else if (gender == 'f')
  825.       fprintf(outf, ", %s.\n",
  826.           (genfloor == -1)?lngstr[unsortedfs_]:lngstr[unsortedfp_]);
  827.     else /* gender == 'n' */
  828.       fprintf(outf, ", %s.\n",
  829.           (genfloor == -1)?lngstr[unsortedns_]:lngstr[unsortednp_]);
  830.   }
  831.  
  832.   return(genfloor);
  833.  
  834. }
  835.  
  836. /* The same without the printing (just to return the right value). */
  837.  
  838. int whatincludednop(int sortby, char *minreqstr, char *minpagestr,
  839.             char *minbytestr)
  840. {
  841.   extern double total_bytes;
  842.   extern int total_succ_reqs, total_page_reqs;
  843.  
  844.   int genfloor;
  845.  
  846.   if (sortby == BYBYTES) {
  847.     if (minbytestr[0] == '-')
  848.       genfloor = (int)bytefloor(total_bytes, minbytestr);
  849.     else
  850.       genfloor = (int)(ceil(bytefloor(total_bytes, minbytestr)));
  851.   }
  852.   else if (sortby == BYPAGES)
  853.     genfloor = reqfloor(total_page_reqs, minpagestr);
  854.   else
  855.     genfloor = reqfloor(total_succ_reqs, minreqstr);
  856.  
  857.   return(genfloor);
  858.  
  859. }
  860.  
  861. /*** Generic output function for generic objects ***/
  862.  
  863. void genout(FILE *outf, struct genstruct *sorthead, int tot_reqs,
  864.         int tot_pages, double tot_bytes, int sortby, char *minreqstr,
  865.         char *minpagestr, char *minbytestr, int max_reqs, int max_pages,
  866.         double max_bytes, char *wantcols, char anchor[10], char title[36],
  867.         char singular[22], char plural[24], char colhead[24], char gender,
  868.         char codeletter, flag alphahost, flag byq, flag pageq,
  869.         struct include *links, struct alias *aka,
  870.         char baseurl[MAXSTRINGLENGTH])
  871. {
  872.   extern int pagewidth;
  873.   extern int dirlevel;
  874.   extern int Smaxlength;
  875.   extern int aq;
  876.   extern flag rawbytes;
  877.   extern char repsepchar;
  878.  
  879.   struct genstruct *p;
  880.   int fieldwidth, pfieldwidth, bfieldwidth, graphwidth;
  881.   int genfloor;
  882.   double bdivider;
  883.   char bprefix[2];
  884.   char akaname[MAXSTRINGLENGTH];
  885.   char *cols;
  886.   int i, j, tempint;
  887.   char *tempc;
  888.   
  889.   bprefix[0] = '\0';
  890.   bprefix[1] = '\0';
  891.  
  892.   if (aq != PREFORMATTED) {
  893.  
  894.     if (!aq) {
  895.       fprintf(outf, "\n\n<hr>\n<h2><a NAME=\"%s\">%s</a></h2>\n\n", anchor,
  896.           title);
  897.       gotos(outf, codeletter);
  898.       fprintf(outf, "<p>");
  899.     }
  900.     else {
  901.       fprintf(outf, "%s\n", title);
  902.       for (tempc = title; *tempc != '\0'; tempc++)
  903.     fprintf(outf, "-");
  904.       fprintf(outf, "\n");
  905.     }
  906.     
  907.     genfloor = whatincluded(outf, sortby, minreqstr, minpagestr, minbytestr,
  908.                 singular, plural, FALSE, gender);
  909.     if (codeletter == 'i') {
  910.       if (!aq)
  911.     fprintf(outf, "<br>");
  912.       fprintf(outf, lngstr[dirlevel_], dirlevel);
  913.       fprintf(outf, ".\n");
  914.     }
  915.  
  916.     if (aq)
  917.       fprintf(outf, "\n");
  918.     else
  919.       fprintf(outf, "<pre>");
  920.  
  921.     tempint = 10000;
  922.     for (fieldwidth = 5; max_reqs / tempint >= 10; fieldwidth++)
  923.       tempint *= 10;
  924.     if (repsepchar != '\0' && max_reqs >= 10000)
  925.       fieldwidth = fieldwidth + ((fieldwidth - 1) / 3);
  926.  
  927.     if (pageq) {
  928.       tempint = 10000;
  929.       for (pfieldwidth = 5; max_pages / tempint >= 10; pfieldwidth++)
  930.     tempint *= 10;
  931.       if (repsepchar != '\0' && max_pages >= 10000)
  932.     pfieldwidth = pfieldwidth + ((pfieldwidth - 1) / 3);
  933.     }
  934.  
  935.     if (byq) {
  936.       bdivider = finddivider(max_bytes, bprefix);
  937.       if (rawbytes) {
  938.     tempint = 100000;
  939.     for (bfieldwidth = 6; max_bytes / tempint >= 10; bfieldwidth++)
  940.       tempint *= 10;
  941.       }
  942.       else
  943.     bfieldwidth = 6;
  944.       if (repsepchar != '\0' && max_bytes / bdivider >= 99999.5)
  945.     bfieldwidth = bfieldwidth + ((bfieldwidth - 1) / 3);
  946.     }
  947.  
  948.     printcolheads(outf, wantcols, fieldwidth, pfieldwidth, bfieldwidth,
  949.           bprefix, colhead, 0, codeletter, byq, pageq, FALSE);
  950.  
  951.     if (alphahost) {
  952.       graphwidth = pagewidth;
  953.       for (cols = wantcols; *cols != '\0'; cols++) {
  954.     switch(*cols) {
  955.     case 'R':
  956.       graphwidth -= fieldwidth + 2;
  957.       break;
  958.     case 'P':
  959.       graphwidth -= pfieldwidth + 2;
  960.       break;
  961.     case 'B':
  962.       graphwidth -= bfieldwidth + 2;
  963.       break;
  964.     case 'r':
  965.     case 'p':
  966.     case 'b':
  967.       graphwidth -= 8;
  968.       break;
  969.     }
  970.       }
  971.       graphwidth = MIN(graphwidth, Smaxlength);
  972.     }
  973.   }
  974.  
  975.   else /* aq == PREFORMATTED */
  976.     genfloor = whatincludednop(sortby, minreqstr, minpagestr, minbytestr);
  977.  
  978.   if (genfloor < 0)
  979.     j = genfloor;
  980.   else j = 1;
  981.  
  982.   for(p = sorthead; p -> name != NULL && (j++) != 0;
  983.       p = p -> next) {
  984.  
  985.     if (aq == PREFORMATTED)
  986.       precols(outf, wantcols, codeletter, byq, pageq);
  987.  
  988.     printcols(outf, wantcols, p -> reqs, p -> pages, p -> bytes, fieldwidth,
  989.           pfieldwidth, bfieldwidth, bdivider, tot_reqs, tot_pages,
  990.           tot_bytes, codeletter, byq, pageq);
  991.  
  992.     if (alphahost && !isdigit(p -> name[0])) {  /* we've swapped the names */
  993.       reversehostname(p -> name);
  994.       strcpy(akaname, p -> name);
  995.       if (aka != NULL)
  996.     doaliaslist(akaname, aka);
  997.       /* Also in that case right align names */
  998.       if (aq != PREFORMATTED) {
  999.     for (i = graphwidth - (int)strlen(akaname); i > 0; i--)
  1000.       fprintf(outf, " ");
  1001.       }
  1002.     }
  1003.     else {
  1004.       strcpy(akaname, p -> name);
  1005.       if (aka != NULL)
  1006.     doaliaslist(akaname, aka);
  1007.     }
  1008.  
  1009.     if (links != NULL && included(p -> name, p -> ispage, links)) {
  1010.       fprintf(outf, "<a HREF=\"");
  1011.       htmlfprintf(outf, baseurl);
  1012.       htmlfprintf(outf, p -> name);
  1013.       fprintf(outf, "\">");
  1014.       htmlfprintf(outf, akaname);
  1015.       fprintf(outf, "</a>");
  1016.     }
  1017.     else   /* (the usual case for most reports) */
  1018.       if (aq == HTML)
  1019.     htmlfprintf(outf, akaname);
  1020.       else
  1021.     fprintf(outf, "%s", akaname);
  1022.     fprintf(outf, "\n");
  1023.  
  1024.   }
  1025.       
  1026.   if (aq == ASCII)
  1027.     asciiline(outf);
  1028.   else if (aq == HTML)
  1029.     fprintf(outf, "</pre>");
  1030.     
  1031. }
  1032.  
  1033. /*** The domain report is similar to the generic ones. It differs in that
  1034.      the domains are stored in a different structure, and that subdomains
  1035.      must be printed. ***/
  1036.  
  1037. void domout(FILE *outf, int firstdom)
  1038. {
  1039.   extern struct domain **ohead;
  1040.   extern int aq;
  1041.   extern flag byq, rawbytes;
  1042.   extern int osortby;
  1043.   extern char *ominbytestr, *ominpagestr, *ominreqstr;
  1044.   extern char *Ominbytestr, *Ominpagestr, *Ominreqstr;
  1045.   extern int omaxreqs, omaxpages;
  1046.   extern double omaxbytes;
  1047.   extern int Onumber;
  1048.   extern char ocols[];
  1049.   extern double total_bytes;
  1050.   extern int total_succ_reqs, total_page_reqs;
  1051.   extern char *presep;
  1052.   extern char repsepchar;
  1053.  
  1054.   int ofloor;
  1055.  
  1056.   struct domain *p;
  1057.   double bdivider;
  1058.   char bprefix[2];
  1059.   int fieldwidth, pfieldwidth, bfieldwidth;
  1060.   int i, j, tempint;
  1061.   char *tempp;
  1062.  
  1063.   bprefix[0] = '\0';
  1064.   bprefix[1] = '\0';
  1065.  
  1066.   if (aq != PREFORMATTED) {
  1067.     if (!aq) {
  1068.       fprintf(outf,
  1069.           "\n\n<hr>\n<h2><a NAME=\"Domain\">%s</a></h2>\n\n",
  1070.           lngstr[domrep_]);
  1071.       gotos(outf, 'o');
  1072.     }
  1073.     else {
  1074.       fprintf(outf, "%s\n", lngstr[domrep_]);
  1075.       matchlength(outf, lngstr[domrep_], '-');
  1076.       fprintf(outf, "\n");
  1077.     }
  1078.   
  1079.     if (!aq)
  1080.       fprintf(outf, "<p>");
  1081.  
  1082.     ofloor = whatincluded(outf, osortby, ominreqstr, ominpagestr, ominbytestr,
  1083.               lngstr[domgs_], lngstr[domgp_], FALSE,
  1084.               lngstr[domgen_][0]);
  1085.     if (Onumber > 0) {
  1086.       if (!aq)
  1087.     fprintf(outf, "<br>");
  1088.       whatincluded(outf, osortby, Ominreqstr, Ominpagestr, Ominbytestr,
  1089.            lngstr[subdomgs_], lngstr[subdomgp_], TRUE,
  1090.            lngstr[subdomgen_][0]);
  1091.     }
  1092.  
  1093.     if (aq)
  1094.       fprintf(outf, "\n");
  1095.     else
  1096.       fprintf(outf, "<pre>");
  1097.   
  1098.     tempint = 10000;
  1099.     for (fieldwidth = 5; omaxreqs / tempint >= 10; fieldwidth++)
  1100.       tempint *= 10;
  1101.     if (repsepchar != '\0' && omaxreqs >= 10000)
  1102.       fieldwidth = fieldwidth + ((fieldwidth - 1) / 3);
  1103.  
  1104.     tempint = 10000;
  1105.     for (pfieldwidth = 5; omaxpages / tempint >= 10; pfieldwidth++)
  1106.       tempint *= 10;
  1107.     if (repsepchar != '\0' && omaxpages >= 10000)
  1108.       pfieldwidth = pfieldwidth + ((pfieldwidth - 1) / 3);
  1109.   
  1110.     if (byq) {
  1111.       bdivider = finddivider(omaxbytes, bprefix);
  1112.       if (rawbytes) {
  1113.     tempint = 100000;
  1114.     for (bfieldwidth = 6; omaxbytes / tempint >= 10; bfieldwidth++)
  1115.       tempint *= 10;
  1116.       }
  1117.       else
  1118.     bfieldwidth = 6;
  1119.       if (repsepchar != '\0' && omaxbytes / bdivider >= 99999.5)
  1120.     bfieldwidth = bfieldwidth + ((bfieldwidth - 1) / 3);
  1121.     }
  1122.   
  1123.     printcolheads(outf, ocols, fieldwidth, pfieldwidth, bfieldwidth, bprefix,
  1124.           lngstr[dom_], 0, (Onumber > 0)?'o':'\0', byq, ON, FALSE);
  1125.  
  1126.   }
  1127.  
  1128.   else /* aq == PREFORMATTED */
  1129.     ofloor = whatincludednop(osortby, ominreqstr, ominpagestr, ominbytestr);
  1130.  
  1131.   if (ofloor < 0)
  1132.     j = ofloor;    
  1133.   else j = 1;
  1134.  
  1135.   for (i = firstdom; i >= 0 && (j++) != 0; i = ohead[i] -> nexti) {
  1136.  
  1137.     if (!(i == DOMHASHSIZE - 2 && ohead[i] -> reqs == -1)) {
  1138.  
  1139.       if (aq == PREFORMATTED)
  1140.     precols(outf, ocols, 'o', byq, ON);
  1141.  
  1142.       printcols(outf, ocols, ohead[i] -> reqs, ohead[i] -> pages,
  1143.         ohead[i] -> bytes, fieldwidth, pfieldwidth, bfieldwidth,
  1144.         bdivider, total_succ_reqs, total_page_reqs, total_bytes,
  1145.         (Onumber > 0)?'o':'\0', byq, ON);
  1146.       
  1147.       if (ohead[i] -> id[0] == '*')
  1148.     /* flagged domains, not real domain names */
  1149.     fprintf(outf, "[%s]\n", ohead[i] -> name);
  1150.       else if (ohead[i] -> name[0] == '?')
  1151.     /* real domain, but don't print name */
  1152.     fprintf(outf, ".%s\n", ohead[i] -> id);
  1153.       else if (aq == PREFORMATTED)
  1154.     fprintf(outf, ".%s%s%s\n", ohead[i] -> id, presep, ohead[i] -> name);
  1155.       else if (aq == ASCII)
  1156.     fprintf(outf, ".%s (%s)\n", ohead[i] -> id, ohead[i] -> name);
  1157.       else {  /* aq == HTML */
  1158.     fprintf(outf, ".%s (", ohead[i] -> id);
  1159.     htmlfprintf(outf, ohead[i] -> name);
  1160.     fprintf(outf, ")\n");
  1161.       }
  1162.       
  1163.       /* Now print its subdomains too. */
  1164.       
  1165.       for (p = ohead[i] -> next; p -> name != NULL;
  1166.        p = p -> next) {
  1167.  
  1168.     if (aq == PREFORMATTED)
  1169.       precols(outf, ocols, 'O', byq, ON);
  1170.  
  1171.     printcols(outf, ocols, p -> reqs, p -> pages, p -> bytes, fieldwidth,
  1172.           pfieldwidth, bfieldwidth, bdivider, total_succ_reqs,
  1173.           total_page_reqs, total_bytes, 'O', byq, ON);
  1174.  
  1175.     if (aq != PREFORMATTED) {
  1176.       tempp = p -> id;
  1177.       while ((tempp = strchr(tempp, '.')) != NULL) {
  1178.         fprintf(outf, "  "); 
  1179.         /* print two spaces for each dot in name */
  1180.         tempp++;
  1181.       }
  1182.       if (i == DOMHASHSIZE - 1)
  1183.         fprintf(outf, "  ");  /* + 2 more for numerical domains */
  1184.     }
  1185.     
  1186.     fprintf(outf, "%s", p -> id);
  1187.     
  1188.     if (p -> name[0] != '?') {   /* print name */
  1189.       if (aq == PREFORMATTED)
  1190.         fprintf(outf,"%s%s", presep, p -> name);
  1191.       else if (aq == ASCII)
  1192.         fprintf(outf, " (%s)", p -> name);
  1193.       else {
  1194.         fprintf(outf, " (");
  1195.         htmlfprintf(outf, p -> name);
  1196.         fprintf(outf, ")");
  1197.       }
  1198.     }
  1199.     
  1200.     fprintf(outf, "\n");
  1201.     
  1202.       }    /* end for domp */
  1203.     
  1204.     }
  1205.  
  1206.   }   /* end for (i = running over domains) */
  1207.     
  1208.   if (aq == ASCII)
  1209.     asciiline(outf);
  1210.   else if (aq == HTML)
  1211.     fprintf(outf, "</pre>");
  1212.     
  1213. }
  1214.  
  1215. /*** The date reports aren't quite generic enough to combine completely,
  1216.      but we can go a long way towards it. ***/
  1217. /*** First a function for printing out the headers of a report and finding
  1218.      the fieldwidths etc.; then one for printing out each individual line. ***/
  1219.  
  1220. void datehead(FILE *outf, int maxreq, int maxpages, double maxbytes,
  1221.           char *wantcols, char *graphtype, char anchor[11],
  1222.           char title[31], char colhead[13], int colwidth,
  1223.           char codeletter, int *unit, int *fieldwidth, int *pfieldwidth,
  1224.           int *bfieldwidth, int *graphwidth, double *bdivider)
  1225.      /* assumes colwidth >= strlen(colhead) */
  1226.      /* The last 5 args are returned altered */
  1227. {
  1228.   extern int aq;
  1229.   extern flag byq, rawbytes, graphical;
  1230.   extern int pagewidth;
  1231.   extern char *imagedir;
  1232.   extern char markchar, sepchar, repsepchar;
  1233.  
  1234.   char *cols;
  1235.   char bprefix[2];
  1236.   int i, j, tempint;
  1237.   char *tempc;
  1238.  
  1239.   bprefix[0] = '\0';
  1240.   bprefix[1] = '\0';
  1241.  
  1242.   if (*graphtype == 'b')
  1243.     *graphtype = 'B';
  1244.   if (*graphtype == 'p')
  1245.     *graphtype = 'P';
  1246.  
  1247.   if (!aq) {
  1248.     fprintf(outf, "<hr>\n<h2><a NAME=\"%s\">%s</a></h2>\n", anchor, title);
  1249.       gotos(outf, codeletter);
  1250.   }
  1251.   else {
  1252.     fprintf(outf, "%s\n", title);
  1253.     for (tempc = title; *tempc != '\0'; tempc++)
  1254.       fprintf(outf, "-");
  1255.     fprintf(outf, "\n");
  1256.   }
  1257.     
  1258.   tempint = 10000;
  1259.   for (*fieldwidth = 5; maxreq / tempint >= 10; (*fieldwidth)++)
  1260.     tempint *= 10;   /* so fieldwidth is log_10(maxreq), but >= 5 */
  1261.   if (repsepchar != '\0' && maxreq >= 10000)
  1262.     *fieldwidth = *fieldwidth + ((*fieldwidth - 1) / 3);
  1263.  
  1264.   tempint = 10000;
  1265.   for (*pfieldwidth = 5; maxpages / tempint >= 10; (*pfieldwidth)++)
  1266.     tempint *= 10;
  1267.   if (repsepchar != '\0' && maxpages >= 10000)
  1268.     *pfieldwidth = *pfieldwidth + ((*pfieldwidth - 1) / 3);
  1269.     
  1270.   if (byq) {
  1271.     *bdivider = finddivider(maxbytes, bprefix);
  1272.     if (rawbytes || (*graphtype == 'B' && *unit > 0)) {
  1273.       tempint = 100000;
  1274.       for (*bfieldwidth = 6; maxbytes / tempint >= 10; (*bfieldwidth)++)
  1275.     tempint *= 10;
  1276.     }
  1277.     else
  1278.       *bfieldwidth = 6;
  1279.     if (repsepchar != '\0' && maxbytes / *bdivider >= 99999.5)
  1280.       *bfieldwidth = *bfieldwidth + ((*bfieldwidth - 1) / 3);
  1281.   }
  1282.  
  1283.   if (*unit <= 0) {   /* (o/wise just use the given amount) */
  1284.  
  1285.     /* Calculate the graphwidth */
  1286.     *graphwidth = pagewidth - colwidth - 2;
  1287.     for (cols = wantcols; *cols != '\0'; cols++) {
  1288.       switch(*cols) {
  1289.       case 'R':
  1290.     *graphwidth -= *fieldwidth + 2;
  1291.     break;
  1292.       case 'P':
  1293.     *graphwidth -= *pfieldwidth + 2;
  1294.     break;
  1295.       case 'B':
  1296.     *graphwidth -= *bfieldwidth + 2;
  1297.     break;
  1298.       case 'r':
  1299.       case 'p':
  1300.       case 'b':
  1301.     *graphwidth -= 8;
  1302.     break;
  1303.       }
  1304.     }
  1305.     *graphwidth = MAX(*graphwidth, MINGRAPHWIDTH);  /* must be >= MGW wide */
  1306.                                       
  1307.     if (*graphtype == 'B')
  1308.       *unit = (maxbytes - 1) / (*bdivider * *graphwidth);
  1309.     else if (*graphtype == 'P')
  1310.       *unit = (maxpages - 1) / *graphwidth;
  1311.     else   /* graphtype assumed to be 'R' */
  1312.       *unit = (maxreq - 1) / *graphwidth;
  1313.                                /* except we want a 'nice' amount, so ... */
  1314.                  /* (Nice amount is 1, 1.5, 2, 2.5, 3, 4, 5, 6, 8 * 10^n */
  1315.  
  1316.     j = 0;
  1317.     while (*unit > 24) {
  1318.       *unit /= 10;
  1319.       j++;
  1320.     }
  1321.     if (*unit == 6)
  1322.       *unit = 7;
  1323.     else if (*unit == 8)
  1324.       *unit = 9;
  1325.     else if (*unit >= 20)
  1326.       *unit = 24;
  1327.     else if (*unit >= 15)
  1328.       *unit = 19;
  1329.     else if (*unit >= 10)
  1330.       *unit = 14;
  1331.     (*unit)++;
  1332.     for (i = 0; i < j; i++) {
  1333.       *unit *= 10;
  1334.     }
  1335.  
  1336.   }     /* end if (*unit <= 0) */
  1337.  
  1338.   else if (*graphtype == 'B') {   /* o/wise unit doesn't make sense */
  1339.     *bdivider = 1;
  1340.     bprefix[0] = '\0';
  1341.   }
  1342.  
  1343.   if (!aq)
  1344.     fprintf(outf, "\n<p>");
  1345.   if (aq == HTML && graphical) {
  1346.     fprintf(outf, "%s (<tt><img src=\"", lngstr[eachunit_]);
  1347.     htmlfprintf(outf, imagedir);
  1348.     fprintf(outf, "bar1.gif\" alt=\"");
  1349.     htmlputc(markchar, outf);
  1350.     fprintf(outf, "\"></tt>) %s ", lngstr[represents_]);
  1351.     int3printf(outf, *unit, sepchar, 0);
  1352.     if (*graphtype == 'B')
  1353.       fprintf(outf, " %s%s, %s.\n\n", bprefix,
  1354.           (*unit == 1)?lngstr[byte_]:lngstr[bytes_], lngstr[partof_]);
  1355.     else if (*graphtype == 'P') {
  1356.       if (*unit == 1)
  1357.     fprintf(outf, " %s.\n\n", lngstr[pagereq_]);
  1358.       else
  1359.     fprintf(outf, " %s, %s.\n\n", lngstr[pagereqs_], lngstr[partof_]);
  1360.     }
  1361.     else {
  1362.       if (*unit == 1)
  1363.     fprintf(outf, " %s.\n\n", lngstr[request_]);
  1364.       else
  1365.     fprintf(outf, " %s, %s.\n\n", lngstr[requests_], lngstr[partof_]);
  1366.     }
  1367.   }
  1368.   else {
  1369.     fprintf(outf, "\n%s (%c) %s ", lngstr[eachunit_], markchar,
  1370.         lngstr[represents_]);
  1371.     int3printf(outf, *unit, sepchar, 0);
  1372.     if (*graphtype == 'B')
  1373.       fprintf(outf, " %s%s, %s.\n\n", bprefix,
  1374.           (*unit == 1)?lngstr[byte_]:lngstr[bytes_], lngstr[partof_]);
  1375.     else if (*graphtype == 'P') {
  1376.       if (*unit == 1)
  1377.     fprintf(outf, " %s.\n\n", lngstr[pagereq_]);
  1378.       else
  1379.     fprintf(outf, " %s, %s.\n\n", lngstr[pagereqs_], lngstr[partof_]);
  1380.     }
  1381.     else {
  1382.       if (*unit == 1)
  1383.     fprintf(outf, " %s.\n\n", lngstr[request_]);
  1384.       else
  1385.     fprintf(outf, " %s, %s.\n\n", lngstr[requests_], lngstr[partof_]);
  1386.     }
  1387.   }
  1388.   if (!aq)
  1389.     fprintf(outf, "<pre width=%d><tt>\n", pagewidth);
  1390.     
  1391.   printcolheads(outf, wantcols, *fieldwidth, *pfieldwidth, *bfieldwidth,
  1392.         bprefix, colhead, colwidth, codeletter, byq, ON, TRUE);
  1393.  
  1394. }
  1395.  
  1396. /* As promised, each separate line. We print name of date in output() though */
  1397.  
  1398. void dateline(FILE *outf, int reqs, int pages, double bytes, char *wantcols,
  1399.           char graphtype, int fieldwidth, int pfieldwidth, int bfieldwidth,
  1400.           int unit, double bdivider)
  1401. {
  1402.   extern double total_bytes;
  1403.   extern int total_succ_reqs, total_page_reqs;
  1404.   extern flag aq, byq;
  1405.  
  1406.   printcols(outf, wantcols, reqs, pages, bytes, fieldwidth, pfieldwidth,
  1407.         bfieldwidth, bdivider, total_succ_reqs, total_page_reqs,
  1408.         total_bytes, '\0', byq, ON);
  1409.  
  1410.   if (aq != PREFORMATTED) {
  1411.     if (graphtype == 'B')
  1412.       barplot(outf, (int)(ceil(bytes / (unit * bdivider))));
  1413.     else if (graphtype == 'P')
  1414.       barplot(outf, (pages == 0)?0:((pages - 1) / unit) + 1);
  1415.     else
  1416.       barplot(outf, (reqs == 0)?0:((reqs - 1) / unit) + 1);
  1417.     fprintf(outf, "\n");  /* PREFORMATTED has more before the \n */
  1418.   }
  1419. }
  1420.  
  1421. /*** The status code report (very simple) ***/
  1422.  
  1423. void statusout(FILE *outf)
  1424. {
  1425.   extern int status[], statusnos[];
  1426.   extern char statusstrs[NO_STATUS][MAXSTATUSLENGTH];
  1427.   extern char ccols[];
  1428.   extern int aq;
  1429.   extern char repsepchar;
  1430.  
  1431.   int fieldwidth;
  1432.   int maxreqs = 0;
  1433.   char tempstr[MAXSTRINGLENGTH];
  1434.   int i;
  1435.  
  1436.   if (aq != PREFORMATTED) {
  1437.     for (i = 0; i < NO_STATUS; i++)
  1438.       maxreqs = MAX(maxreqs, status[i]);
  1439.  
  1440.     if (aq == HTML) {
  1441.       fprintf(outf, "\n\n<hr>\n<h2><a NAME=\"Status\">%s</a></h2>\n\n",
  1442.           lngstr[statrep_]);
  1443.       gotos(outf, 'c');
  1444.       fprintf(outf, "<pre>");
  1445.     }
  1446.     else {
  1447.       fprintf(outf, "%s\n", lngstr[statrep_]);
  1448.       matchlength(outf, lngstr[statrep_], '-');
  1449.       fprintf(outf, "\n\n");
  1450.     }
  1451.     i = 10000;
  1452.     for (fieldwidth = 5; maxreqs / i >= 10; fieldwidth++)
  1453.       i *= 10;
  1454.     if (repsepchar != '\0' && maxreqs > 10000)
  1455.       fieldwidth = fieldwidth + ((fieldwidth - 1) / 3);
  1456.  
  1457.     sprintf(tempstr, "%s %s", lngstr[nr_], lngstr[description_]);
  1458.     printcolheads(outf, ccols, fieldwidth, 0, 0, "", tempstr, 0, 'c', FALSE,
  1459.           FALSE, FALSE);
  1460.   }
  1461.  
  1462.   for (i = 0; i < NO_STATUS; i++) {
  1463.     if (status[i] > 0) {
  1464.       if (aq == PREFORMATTED)
  1465.     precols(outf, ccols, 'c', OFF, OFF);
  1466.       printcols(outf, ccols, status[i], 0, 0.0, fieldwidth, 0, 0, 0.0, 1, 1,
  1467.         1.0, 'c', OFF, OFF);
  1468.       if (aq == PREFORMATTED)
  1469.     fprintf(outf, "%d\n", statusnos[i]);
  1470.       else if (statusstrs[i][0] == '[')
  1471.     fprintf(outf, "    %s\n", statusstrs[i]);
  1472.       else
  1473.     fprintf(outf, "%d %s\n", statusnos[i], statusstrs[i]);
  1474.     }
  1475.   }
  1476.  
  1477.   if (aq == ASCII)
  1478.     asciiline(outf);
  1479.   else if (aq == HTML)
  1480.     fprintf(outf, "</pre>");
  1481. }
  1482.  
  1483. /*** The error report ***/
  1484.  
  1485. void errout(FILE *outf, int errorder[NO_ERRS])
  1486. {
  1487.   extern int errors[NO_ERRS];
  1488.   extern char errs[NO_ERRS][MAXERRLENGTH];
  1489.   extern int eminreqs;
  1490.   extern char ecols[];
  1491.   extern int aq;
  1492.   extern char repsepchar;
  1493.  
  1494.   int fieldwidth;
  1495.   int i;
  1496.  
  1497.   if (aq != PREFORMATTED) {
  1498.     if (aq == HTML) {
  1499.       fprintf(outf, "\n\n<hr>\n<h2><a NAME=\"Error\">%s</a></h2>\n\n",
  1500.           lngstr[errrep_]);
  1501.       gotos(outf, 'e');
  1502.       fprintf(outf, "<p>");
  1503.     }
  1504.     else {
  1505.       fprintf(outf, "%s\n", lngstr[errrep_]);
  1506.       matchlength(outf, lngstr[errrep_], '-');
  1507.       fprintf(outf, "\n");
  1508.     }
  1509.  
  1510.     if (eminreqs == 0)
  1511.       fprintf(outf, "%s, ", lngstr[allerrs_]);
  1512.     else if (eminreqs == 1)
  1513.       fprintf(outf, "%s,\n  ", lngstr[allerrs1_]);
  1514.     else {
  1515.       fprintf(outf, lngstr[allerrsn_], eminreqs);
  1516.       fprintf(outf, "\n  ");
  1517.     }
  1518.     fprintf(outf, "%s.", lngstr[occsort_]);
  1519.   
  1520.     if (aq)
  1521.       fprintf(outf, "\n\n");
  1522.     else
  1523.       fprintf(outf, "<pre>");
  1524.  
  1525.     i = 10000;
  1526.     for (fieldwidth = 5; errors[errorder[0]] / i >= 10; fieldwidth++)
  1527.       i *= 10;
  1528.     if (repsepchar != '\0' && errors[errorder[0]] >= 10000)
  1529.       fieldwidth = fieldwidth + ((fieldwidth - 1) / 3);
  1530.  
  1531.     printcolheads(outf, ecols, fieldwidth, 0, 0, "", lngstr[errtype_], 0, 'e',
  1532.           FALSE, FALSE, FALSE);
  1533.   }
  1534.  
  1535.   for (i = 0; i < NO_ERRS && errors[errorder[i]] >= eminreqs; i++) {
  1536.     if (aq == PREFORMATTED)
  1537.       precols(outf, ecols, 'e', FALSE, FALSE);
  1538.     printcols(outf, ecols, errors[errorder[i]], 0, 0.0, fieldwidth, 0, 0, 0.0,
  1539.           1, 1, 1.0, 'e', OFF, OFF);
  1540.     fprintf(outf, "%s\n",
  1541.         (errs[errorder[i]][0] == '\0')?"[unknown]":errs[errorder[i]]);
  1542.   }
  1543.  
  1544.   if (aq == ASCII)
  1545.     asciiline(outf);
  1546.   else if (aq == HTML)
  1547.     fprintf(outf, "</pre>");
  1548. }
  1549.  
  1550. /*** And the general summary ***/
  1551.  
  1552. void gensum(FILE *outf)
  1553. {
  1554.   extern int corrupt_lines, other_lines;
  1555.   extern int no_urls, no_hosts, no_urls7, no_hosts7, no_new_hosts7;
  1556.   extern double total_bytes, total_bytes7;
  1557.   extern int total_succ_reqs, total_fail_reqs, total_other_reqs;
  1558.   extern int total_succ_reqs7, total_fail_reqs7, total_other_reqs7;
  1559.   extern int total_page_reqs, total_page_reqs7;
  1560.   extern flag mq, Wq, dq, Dq, hq, oq, Sq, iq, rq, q7, byq;
  1561.   extern int sq, aq;
  1562.   extern char sepchar, *presep;
  1563.   extern struct timestruct starttimec, totime, firsttime, lasttime, oldtime;
  1564.   extern char dayname[7][11];
  1565.   extern char monthname[12][12];
  1566.  
  1567.   int totalmins;    /* between first and last entries analysed */
  1568.   double bdivider;
  1569.   char bprefix[2];  /* kilo, Mega, etc. */
  1570.  
  1571.   bprefix[0] = '\0';
  1572.   bprefix[1] = '\0';
  1573.  
  1574.   if (aq == HTML)
  1575.     fprintf(outf, "<hr>");
  1576.  
  1577.   if (aq == PREFORMATTED)
  1578.     fprintf(outf, "\nx%sPS%s%d%s%d%s%d%s%d%s%d", presep,
  1579.         presep, starttimec.year, presep, starttimec.monthno + 1,
  1580.         presep, starttimec.date, presep, starttimec.hr, presep,
  1581.         starttimec.min);
  1582.   else {
  1583.     fprintf(outf, "\n%s ", lngstr[progstart_]);
  1584.     dateprintf(outf, lngstr[datefmt2_], starttimec.date, starttimec.monthno,
  1585.            starttimec.year, starttimec.hr, starttimec.min);
  1586.     fprintf(outf, " %s.\n", lngstr[localtime_]);
  1587.   }
  1588.  
  1589.   if (firsttime.code > oldtime.code)
  1590.     q7 = OFF;
  1591.  
  1592.   if (total_succ_reqs > 0) {
  1593.     totalmins = minsbetween(firsttime.date, firsttime.monthno,
  1594.                 firsttime.year, firsttime.hr, firsttime.min,
  1595.                 lasttime.date, lasttime.monthno, lasttime.year,
  1596.                 lasttime.hr, lasttime.min) + 1;
  1597.     if (aq == HTML)
  1598.       fprintf(outf, "<br>");
  1599.     if (aq == PREFORMATTED) {
  1600.       fprintf(outf, "\nx%sFR%s%d%s%d%s%d%s%d%s%d", presep, presep,
  1601.           firsttime.year, presep, firsttime.monthno + 1, presep,
  1602.           firsttime.date, presep, firsttime.hr, presep, firsttime.min);
  1603.       fprintf(outf, "\nx%sLR%s%d%s%d%s%d%s%d%s%d", presep, presep,
  1604.           lasttime.year, presep, lasttime.monthno + 1, presep,
  1605.           lasttime.date, presep, lasttime.hr, presep, lasttime.min);
  1606.       if (q7)
  1607.     fprintf(outf, "\nx%sL7%s%d%s%d%s%d%s%d%s%d", presep, presep,
  1608.         oldtime.year, presep, oldtime.monthno + 1, presep,
  1609.         oldtime.date, presep, oldtime.hr, presep, oldtime.min);
  1610.     }
  1611.     else {
  1612.       fprintf(outf, "%s ", lngstr[reqstart_]);
  1613.       dateprintf(outf, lngstr[datefmt2_], firsttime.date, firsttime.monthno,
  1614.          firsttime.year, firsttime.hr, firsttime.min);
  1615.       fprintf(outf, " %s\n  ", lngstr[to_]);
  1616.       dateprintf(outf, lngstr[datefmt2_], lasttime.date, lasttime.monthno,
  1617.          lasttime.year, lasttime.hr, lasttime.min);
  1618.       fprintf(outf, " (%.1f %s).\n\n", ((double)totalmins) / 1440.0,
  1619.           lngstr[days_]);
  1620.     }
  1621.   }
  1622.  
  1623.   if (aq == HTML)
  1624.     fprintf(outf, "<p><b>%s%s</b> ", lngstr[succreqs_], lngstr[colon_]);
  1625.   else if (aq == ASCII)
  1626.     fprintf(outf, "%s%s ", lngstr[succreqs_], lngstr[colon_]);
  1627.   else   /* aq == PREFORMATTED */
  1628.     fprintf(outf, "\nx%sSR%s", presep, presep);
  1629.   int3printf(outf, total_succ_reqs, sepchar, 0);
  1630.   if (q7) {
  1631.     if (aq == PREFORMATTED)
  1632.       fprintf(outf, "\nx%sS7%s%d", presep, presep, total_succ_reqs7);
  1633.     else {
  1634.       fprintf(outf, " (");
  1635.       int3printf(outf, total_succ_reqs7, sepchar, 0);
  1636.       fprintf(outf, ")");
  1637.     }
  1638.   }
  1639.   if (totalmins > 30 && aq != PREFORMATTED) {
  1640.     if (aq == HTML)
  1641.       fprintf(outf, "\n<br><b>%s%s</b> ", lngstr[avereqs_], lngstr[colon_]);
  1642.     else
  1643.       fprintf(outf, "\n%s%s ", lngstr[avereqs_], lngstr[colon_]);
  1644.       
  1645.     if (total_succ_reqs < 2)
  1646.       fprintf(outf, "0");
  1647.     else
  1648.       double3printf(outf, ROUND((double)(total_succ_reqs - 1)) * 1440.0 / (totalmins + 0.0), sepchar, 0);
  1649.     if (q7) {
  1650.       fprintf(outf, " (");
  1651.       int3printf(outf, total_succ_reqs7 / 7, sepchar, 0);
  1652.       fprintf(outf, ")");
  1653.     }
  1654.   }
  1655.   if (total_page_reqs > 0) {
  1656.     if (aq == HTML)
  1657.       fprintf(outf, "\n<br><b>%s%s</b> ", lngstr[totpages_], lngstr[colon_]);
  1658.     else if (aq == ASCII)
  1659.       fprintf(outf, "\n%s%s ", lngstr[totpages_], lngstr[colon_]);
  1660.     else   /* aq == PREFORMATTED */
  1661.       fprintf(outf, "\nx%sPR%s", presep, presep);
  1662.     int3printf(outf, total_page_reqs, sepchar, 0);
  1663.     if (q7) {
  1664.       if (aq == PREFORMATTED)
  1665.     fprintf(outf, "\nx%sP7%s%d", presep, presep, total_page_reqs7);
  1666.       else {
  1667.     fprintf(outf, " (");
  1668.     int3printf(outf, total_page_reqs7, sepchar, 0);
  1669.     fprintf(outf, ")");
  1670.       }
  1671.     }
  1672.     if (totalmins > 30 && aq != PREFORMATTED) {
  1673.       if (aq == HTML)
  1674.     fprintf(outf, "\n<br><b>%s%s</b> ", lngstr[avepages_], lngstr[colon_]);
  1675.       else
  1676.     fprintf(outf, "\n%s%s ", lngstr[avepages_], lngstr[colon_]);
  1677.       if (total_page_reqs < 2)
  1678.     fprintf(outf, "0");
  1679.       else
  1680.     double3printf(outf, ROUND((double)(total_page_reqs - 1)) * 1440.0 / (totalmins + 0.0), sepchar, 0);
  1681.       if (q7) {
  1682.     fprintf(outf, " (");
  1683.     int3printf(outf, total_page_reqs7 / 7, sepchar, 0);
  1684.     fprintf(outf, ")");
  1685.       }
  1686.     }
  1687.   }
  1688.   if (total_fail_reqs > 0) {
  1689.     if (aq == HTML)
  1690.       fprintf(outf, "\n<br><b>%s%s</b> ", lngstr[totfails_], lngstr[colon_]);
  1691.     else if (aq == ASCII)
  1692.       fprintf(outf, "\n%s%s ", lngstr[totfails_], lngstr[colon_]);
  1693.     else   /* aq == PREFORMATTED */
  1694.       fprintf(outf, "\nx%sFL%s", presep, presep);
  1695.     int3printf(outf, total_fail_reqs, sepchar, 0);
  1696.     if (q7) {
  1697.       if (aq == PREFORMATTED)
  1698.     fprintf(outf, "\nx%sF7%s%d", presep, presep, total_fail_reqs7);
  1699.       else {
  1700.     fprintf(outf, " (");
  1701.     int3printf(outf, total_fail_reqs7, sepchar, 0);
  1702.     fprintf(outf, ")");
  1703.       }
  1704.     }
  1705.   }
  1706.   if (total_other_reqs > 0) {
  1707.     if (aq == HTML)
  1708.       fprintf(outf, "\n<br><b>%s%s</b> ", lngstr[totredirs_], lngstr[colon_]);
  1709.     else if (aq == ASCII)
  1710.       fprintf(outf, "\n%s%s ", lngstr[totredirs_], lngstr[colon_]);
  1711.     else   /* aq == PREFORMATTED */
  1712.       fprintf(outf, "\nx%sRR%s", presep, presep);
  1713.     int3printf(outf, total_other_reqs, sepchar, 0);
  1714.     if (q7) {
  1715.       if (aq == PREFORMATTED)
  1716.     fprintf(outf, "\nx%sR7%s%d", presep, presep, total_other_reqs7);
  1717.       else {
  1718.     fprintf(outf, " (");
  1719.     int3printf(outf, total_other_reqs7, sepchar, 0);
  1720.     fprintf(outf, ")");
  1721.       }
  1722.     }
  1723.   }
  1724.   if (rq) {   /* These data are not collected o/wise */
  1725.     if (aq == HTML)
  1726.       fprintf(outf, "\n<br><b>%s%s</b> ", lngstr[distfiles_], lngstr[colon_]);
  1727.     else if (aq == ASCII)
  1728.       fprintf(outf, "\n%s%s ", lngstr[distfiles_], lngstr[colon_]);
  1729.     else   /* aq == PREFORMATTED */
  1730.       fprintf(outf, "\nx%sNF%s", presep, presep);
  1731.     int3printf(outf, no_urls, sepchar, 0);
  1732.     if (q7) {
  1733.       if (aq == PREFORMATTED)
  1734.     fprintf(outf, "\nx%sN7%s%d", presep, presep, no_urls7);
  1735.       else {
  1736.     fprintf(outf, " (");
  1737.     int3printf(outf, no_urls7, sepchar, 0);
  1738.     fprintf(outf, ")");
  1739.       }
  1740.     }
  1741.   }
  1742.   if ((sq == ON || sq == APPROX) && no_hosts > 0) {
  1743.     if (aq == HTML)
  1744.       fprintf(outf, "\n<br><b>%s%s</b> ",
  1745.           (sq == ON)?lngstr[disthosts_]:lngstr[approxhosts_],
  1746.           lngstr[colon_]);
  1747.     else if (aq == ASCII)
  1748.       fprintf(outf, "\n%s%s ",
  1749.           (sq == ON)?lngstr[disthosts_]:lngstr[approxhosts_],
  1750.           lngstr[colon_]);
  1751.     else   /* aq == PREFORMATTED */
  1752.       fprintf(outf, "\nx%s%cH%s", presep, (sq == ON)?'N':'A', presep);
  1753.     int3printf(outf, no_hosts, sepchar, 0);
  1754.     if (q7) {
  1755.       if (aq == PREFORMATTED)
  1756.     fprintf(outf, "\nx%s%c7%s%d", presep, (sq == ON)?'H':'A', presep,
  1757.         no_hosts7);
  1758.       else {
  1759.     fprintf(outf, " (");
  1760.     int3printf(outf, no_hosts7, sepchar, 0);
  1761.     fprintf(outf, ")");
  1762.       }
  1763.       if (aq == HTML)
  1764.     fprintf(outf, "\n<br><b>%s%s</b> ",
  1765.         (sq == ON)?lngstr[newhosts_]:lngstr[approxnewhosts_],
  1766.         lngstr[colon_]);
  1767.       else if (aq == ASCII)
  1768.     fprintf(outf, "\n%s%s ",
  1769.         (sq == ON)?lngstr[newhosts_]:lngstr[approxnewhosts_],
  1770.         lngstr[colon_]);
  1771.       else   /* aq == PREFORMATTED */
  1772.     fprintf(outf, "\nx%s%cV%s", presep, (sq == ON)?'N':'A', presep);
  1773.       int3printf(outf, no_new_hosts7, sepchar, 0);
  1774.     }
  1775.   }
  1776.   if (corrupt_lines > 0) {
  1777.     if (aq == HTML)
  1778.       fprintf(outf, "\n<br><b>%s%s</b> ", lngstr[corrupt_], lngstr[colon_]);
  1779.     else if (aq == ASCII)
  1780.       fprintf(outf, "\n%s%s ", lngstr[corrupt_], lngstr[colon_]);
  1781.     else   /* aq == PREFORMATTED */
  1782.       fprintf(outf, "\nx%sCL%s", presep, presep);
  1783.     int3printf(outf, corrupt_lines, sepchar, 0);
  1784.   }
  1785.   if (other_lines > 0) {
  1786.     if (aq == HTML)
  1787.       fprintf(outf, "\n<br><b>%s%s</b> ", lngstr[unwanted_], lngstr[colon_]);
  1788.     else if (aq == ASCII)
  1789.       fprintf(outf, "\n%s%s ", lngstr[unwanted_], lngstr[colon_]);
  1790.     else   /* aq == PREFORMATTED */
  1791.       fprintf(outf, "\nx%sUL%s", presep, presep);
  1792.     int3printf(outf, other_lines, sepchar, 0);
  1793.   }
  1794.   if (byq) {
  1795.     if (aq == HTML)
  1796.       fprintf(outf, "\n<br><b>%s%s</b> ", lngstr[totdata_], lngstr[colon_]);
  1797.     else if (aq == ASCII)
  1798.       fprintf(outf, "\n%s%s ", lngstr[totdata_], lngstr[colon_]);
  1799.     else   /* aq == PREFORMATTED */
  1800.       fprintf(outf, "\nx%sBT%s", presep, presep);
  1801.     bdivider = finddivider(total_bytes, bprefix);
  1802.     double3printf(outf, ROUND(total_bytes / bdivider), sepchar, 0);
  1803.     if (aq != PREFORMATTED)
  1804.       fprintf(outf, " %s%s", bprefix, lngstr[bytes_]);
  1805.     if (q7) {
  1806.       if (aq == PREFORMATTED)
  1807.     fprintf(outf, "\nx%sB7%s", presep, presep);
  1808.       else
  1809.     fprintf(outf, " (");
  1810.       bdivider = finddivider(total_bytes7, bprefix);
  1811.       double3printf(outf, ROUND(total_bytes7 / bdivider), sepchar, 0);
  1812.       if (aq != PREFORMATTED)
  1813.     fprintf(outf, " %s%s)", bprefix, lngstr[bytes_]);
  1814.     }
  1815.     if (totalmins > 30 && aq != PREFORMATTED) {
  1816.       if (aq == HTML)
  1817.     fprintf(outf, "\n<br><b>%s%s</b> ", lngstr[avedata_], lngstr[colon_]);
  1818.       else
  1819.     fprintf(outf, "\n%s%s ", lngstr[avedata_], lngstr[colon_]);
  1820.   
  1821.       bdivider = finddivider((total_bytes * 1440) / (totalmins + 0.0),
  1822.                  bprefix);
  1823.       double3printf(outf, ROUND((total_bytes * 1440) / (totalmins + 0.0) / bdivider), sepchar, 0);
  1824.       fprintf(outf, " %s%s", bprefix, lngstr[bytes_]);
  1825.       if (q7) {
  1826.     fprintf(outf, " (");
  1827.     bdivider = finddivider(total_bytes7 / 7.0, bprefix);
  1828.     double3printf(outf, ROUND(total_bytes7 / 7.0 / bdivider), sepchar, 0);
  1829.     fprintf(outf, " %s%s)", bprefix, lngstr[bytes_]);
  1830.       }
  1831.     }
  1832.   }
  1833.   if (q7 && aq != PREFORMATTED) {
  1834.     if (aq == HTML)
  1835.       fprintf(outf, "\n<br>");
  1836.     else
  1837.       fprintf(outf, "\n");
  1838.     fprintf(outf, "(%s ", lngstr[brackets_]);
  1839.       
  1840.     if (starttimec.code > totime.code) {
  1841.       fprintf(outf, "%s ", lngstr[sevendaysto_]);
  1842.       dateprintf(outf, lngstr[datefmt1_], totime.date, totime.monthno,
  1843.          totime.year, UNSET, UNSET);
  1844.       fprintf(outf, ").");
  1845.     }
  1846.     else
  1847.       fprintf(outf, "%s).", lngstr[lastsevendays_]);
  1848.   }
  1849.   
  1850.   if (aq == HTML && (mq || Wq || dq || Dq || hq || oq || Sq || iq || rq))
  1851.     gotos(outf, 'z');
  1852.   else if (aq == ASCII) {
  1853.     fprintf(outf, "\n");
  1854.     asciiline(outf);
  1855.   }
  1856.   else if (aq == PREFORMATTED)
  1857.     fprintf(outf, "\n");
  1858. }
  1859.