/*** analog 4.13 http://www.analog.cx/ ***/ /*** This program is copyright (c) Stephen R. E. Turner 1995 - 2000 except as *** stated otherwise. Distribution, usage and modification of this program is *** subject to the conditions of the Licence which you should have received *** with it. This program comes with no warranty, expressed or implied. ***/ /*** output.c; controls the output, mostly calling fns from output2.c ***/ #include "anlghea3.h" #define GENSUM_RATE(x, m) (((m) < 30 || (x) <= 1)?((unsigned long)UNSET):\ ((unsigned long)(((double)((x) - 1) * 1440.0) / (double)(m)))) void gensum(FILE *outf, choice outstyle, logical last7, unsigned long *data, double bys, double bys7, Hashindex **gooditems, Hashindex **baditems, Dateman *dman, logical rawbytes, char sepchar, char decpt, char *compsep, char **monthname, char **dayname, unsigned int monthlen, unsigned int daylen, char **lngstr) { timecode_t totmins, totmins7; logical q7 = (last7 && dman->firsttime < dman->last7from && dman->last7from < dman->lasttime); unsigned long tot, tot7; totmins = dman->lasttime - dman->firsttime; totmins7 = q7?MINS_IN_WEEK:0; if (q7) lastseven(outf, outstyle, dman->last7to, compsep, monthname, dayname, monthlen, daylen, lngstr); gensumline(outf, outstyle, succreqs_, data[LOGDATA_SUCC], q7?data[LOGDATA_SUCC7]:(unsigned long)UNSET, sepchar, compsep, (logical)(!q7), lngstr); if (outstyle != COMPUTER) { gensumline(outf, outstyle, avereqs_, GENSUM_RATE(data[LOGDATA_SUCC], totmins), GENSUM_RATE(data[LOGDATA_SUCC7], totmins7), sepchar, compsep, FALSE, lngstr); } gensumline(outf, outstyle, totunknown_, data[LOGDATA_UNKNOWN], q7?data[LOGDATA_UNKNOWN7]:(unsigned long)UNSET, sepchar, compsep, FALSE, lngstr); gensumline(outf, outstyle, totpages_, data[LOGDATA_PAGES], q7?data[LOGDATA_PAGES7]:(unsigned long)UNSET, sepchar, compsep, FALSE, lngstr); if (outstyle != COMPUTER) { gensumline(outf, outstyle, avepages_, GENSUM_RATE(data[LOGDATA_PAGES], totmins), GENSUM_RATE(data[LOGDATA_PAGES7], totmins7), sepchar, compsep, FALSE, lngstr); } gensumline(outf, outstyle, totfails_, data[LOGDATA_FAIL], q7?data[LOGDATA_FAIL7]:(unsigned long)UNSET, sepchar, compsep, FALSE, lngstr); gensumline(outf, outstyle, totredirs_, data[LOGDATA_REDIR], q7?data[LOGDATA_REDIR7]:(unsigned long)UNSET, sepchar, compsep, FALSE, lngstr); gensumline(outf, outstyle, inforeqs_, data[LOGDATA_INFO], q7?data[LOGDATA_INFO7]:(unsigned long)UNSET, sepchar, compsep, FALSE, lngstr); distcount(gooditems[ITEM_FILE], baditems[ITEM_FILE], &tot, &tot7); gensumline(outf, outstyle, distfiles_, tot, q7?tot7:(unsigned long)UNSET, sepchar, compsep, FALSE, lngstr); distcount(gooditems[ITEM_HOST], baditems[ITEM_HOST], &tot, &tot7); gensumline(outf, outstyle, disthosts_, tot, q7?tot7:(unsigned long)UNSET, sepchar, compsep, FALSE, lngstr); gensumline(outf, outstyle, corrupt_, data[LOGDATA_CORRUPT], (unsigned long)UNSET, sepchar, compsep, FALSE, lngstr); gensumline(outf, outstyle, unwanted_, data[LOGDATA_UNWANTED], (unsigned long)UNSET, sepchar, compsep, FALSE, lngstr); gensumlineb(outf, outstyle, totdata_, bys, q7?bys7:UNSET, rawbytes, sepchar, decpt, compsep, lngstr); if (outstyle != COMPUTER) { gensumlineb(outf, outstyle, avedata_, (totmins < 30)?UNSET:((bys * 1440.0) / (double)totmins), (q7 && totmins7 >= 30)?\ ((bys7 * 1440.0) / (double)totmins7):UNSET, rawbytes, sepchar, decpt, compsep, lngstr); } } void genrep(FILE *outf, choice rep, choice outstyle, logical multibyte, Hashindex **gooditems, Hashindex **baditems, Alias *aliashead, Include *wanthead, choice requests, choice date, Floor *floor, choice sortby, logical alphaback, unsigned int pagewidth, char sepchar, char repsepchar, char decpt, char *compsep, logical rawbytes, choice *cols, char *colhead, char *colheadp, char *gens, char *genp, char gender, logical *html, timecode_t firsttime, char **monthname, char **dayname, unsigned int monthlen, unsigned int daylen, unsigned int plainmonthlen, unsigned int plaindaylen, char **lngstr) { Hashindex *ip; Hashentry *badp; unsigned long totr = 0, totp = 0, maxr = 0, maxp = 0, badn = 0, goodn = 0; double totb = 0.0, maxb = 0.0, unit = 1.0; unsigned int width[COL_NUMBER], bmult, tw = 0; char *notlistedstr; /* run through all items finding totals and maxima for floors */ for (ip = *gooditems; ip != NULL; TO_NEXT(ip)) { if (ip->own != NULL) { totr += ip->own->data[requests]; totp += ip->own->data[PAGES]; totb += ip->own->bytes; maxr = MAX(maxr, ip->own->data[requests]); maxp = MAX(maxp, ip->own->data[PAGES]); maxb = MAX(maxb, ip->own->bytes); } } for (ip = *baditems; ip != NULL; TO_NEXT(ip)) { if (ip->own != NULL) { totr += ip->own->data[requests]; totp += ip->own->data[PAGES]; totb += ip->own->bytes; maxr = MAX(maxr, ip->own->data[requests]); maxp = MAX(maxp, ip->own->data[PAGES]); maxb = MAX(maxb, ip->own->bytes); } } if (rep != REP_SIZE && rep != REP_PROCTIME) /* so as not to get rid of 0's and to preserve order */ my_sort(gooditems, baditems, NULL, NULL, NULL, 0, -1, floor, sortby, alphaback, wanthead, requests, date, totr, totp, totb, maxr, maxp, maxb); /* accumulate all unwanted items into a single entry */ badp = newhashentry(FALSE); for (ip = *baditems; ip != NULL; TO_NEXT(ip)) { if (ip->own != NULL && ip->own->data[requests] > 0) { badp->data[requests] += ip->own->data[requests]; badp->data[PAGES] += ip->own->data[PAGES]; badp->bytes += ip->own->bytes; badp->data[date] = MAX(badp->data[date], ip->own->data[date]); badn++; } } /* now run through all good items, finding maxima of those for report */ maxr = badp->data[requests]; maxp = badp->data[PAGES]; maxb = badp->bytes; for (ip = *gooditems; ip != NULL; TO_NEXT(ip)) { if (ip->own != NULL) { /* should obey this already, but for safety... */ maxr = MAX(maxr, ip->own->data[requests]); maxp = MAX(maxp, ip->own->data[PAGES]); maxb = MAX(maxb, ip->own->bytes); goodn++; } } if (rep == REP_SIZE || rep == REP_PROCTIME) { width[COL_TITLE] = htmlstrlen(colhead, outstyle); for (ip = *gooditems; ip != NULL; TO_NEXT(ip)) width[COL_TITLE] = MAX(strlen(ip->name), /* no HTML codes used */ width[COL_TITLE]); } else width[COL_TITLE] = 0; calcsizes(outstyle, width, &bmult, &unit, maxr, maxp, maxb, goodn, pagewidth, 0, '\0', repsepchar, rawbytes, cols, monthlen, daylen, lngstr); if (alphaback && sortby == ALPHABETICAL) { for (ip = *gooditems; ip != NULL; TO_NEXT(ip)) tw = MAX(tw, htmlstrlen(ip->name, outstyle)); tw = MIN(tw, width[COL_TITLE]); } else if (rep != REP_SIZE && rep != REP_PROCTIME) width[COL_TITLE] = 0; if (rep != REP_SIZE && rep != REP_PROCTIME) whatincluded(outf, rep, outstyle, goodn, pagewidth, floor, sortby, decpt, compsep, gens, genp, gender, requests, date, firsttime, monthname, dayname, plainmonthlen, plaindaylen, lngstr); PRESTART(); colheads(outf, cols, outstyle, width, bmult, colhead, (logical)(rep == REP_SIZE || rep == REP_PROCTIME), lngstr); /* run through all items printing them. Reuse goodn here. */ for (goodn = 0, ip = *gooditems; ip != NULL; TO_NEXT(ip)) { if (tw > 0) width[COL_TITLE] = (ISDIGIT(ip->name[0]) && ISDIGIT(ip->name[strlen(ip->name) - 1]))?0:tw; printcols(outf, rep, cols, outstyle, multibyte, ip->own->data[requests], ip->own->data[PAGES], ip->own->bytes, (long)(++goodn), 0, totr, totp, totb, width, bmult, '\0', unit, '\0', '\0', repsepchar, decpt, compsep, (logical)(rep == REP_SIZE || rep == REP_PROCTIME), FALSE, NULL, html, ip->name, ip->own->ispage, 0, aliashead, NULL, NULL, lngstr[genrepdate_], lngstr[genreptime_], ip->own->data[date] / 1440, (ip->own->data[date] % 1440) / 60, ip->own->data[date] % 60, 0, 0, monthname, dayname, monthlen, daylen, plainmonthlen, plaindaylen); } if (badn > 0) { printcols(outf, rep, cols, outstyle, multibyte, badp->data[requests], badp->data[PAGES], badp->bytes, -1, 0, totr, totp, totb, width, bmult, '\0', unit, '\0', '\0', repsepchar, decpt, compsep, (logical)(rep == REP_SIZE || rep == REP_PROCTIME), FALSE, NULL, html, NULL, FALSE, 0, NULL, NULL, NULL, lngstr[genrepdate_], lngstr[genreptime_], badp->data[date] / 1440, (badp->data[date] % 1440) / 60, badp->data[date] % 60, 0, 0, monthname, dayname, monthlen, daylen, plainmonthlen, plaindaylen); if (gender == 'm') notlistedstr = lngstr[notlistedm_]; else if (gender == 'f') notlistedstr = lngstr[notlistedf_]; else notlistedstr = lngstr[notlistedn_]; fprintf(outf, "[%s: ", notlistedstr); f3printf(outf, outstyle, (double)badn, 0, sepchar); if (outstyle == COMPUTER) fprintf(outf, "]\n"); else fprintf(outf, " %s]\n", (badn == 1)?colhead:colheadp); } PREEND(); } void subdayrep(FILE *outf, choice rep, Daysdata *firstdp, Daysdata *lastdp, datecode_t firstdate, datecode_t lastdate, choice outstyle, unsigned int granularity, unsigned int repgran, unsigned int pagewidth, unsigned int mingraphwidth, logical back, logical rawbytes, choice *cols, unsigned int rows, char graphby, char barstyle, char markchar, char sepchar, char repsepchar, char decpt, char *compsep, choice weekbeginson, char *imagedir, logical *html, char **monthname, char **dayname, unsigned int monthlen, unsigned int daylen, unsigned int plainmonthlen, unsigned int plaindaylen, char **lngstr, char *datefmt, char *colhead, char *busystr) { Daysdata *dp; Timerep *trhead, *trp, *oldtrp; int hr, min = 0, newmin = 0, busyhr = 0, busymin = 0; datecode_t busydate = 0, i; int j, firsttime, lasttime; unsigned int k; unsigned int relgran = granularity / repgran; /* guaranteed to be integer */ unsigned long reqs, pages, totr = 0, totp = 0; unsigned long maxr = 0, maxp = 0, busyr = 0, busyp = 0; double bys, totb = 0.0, maxb = 0.0, busyb = 0.0, unit = 0.0; unsigned int width[COL_NUMBER], bmult, rowsdone = 0; logical first = TRUE; dp = lastdp; trhead = (Timerep *)xmalloc(sizeof(Timerep)); trp = trhead; if (rows == 0) rows = INT_MAX; for (firsttime = 0; firsttime < (int)granularity && firstdp->reqs[firsttime] == 0; firsttime++) ; /* run to first time */ for (lasttime = granularity - 1; lasttime >= 0 && lastdp->reqs[lasttime] == 0; lasttime--) ; for (i = lastdate; i >= firstdate; i--) { for (j = (int)(granularity - relgran); j >= 0; j -= relgran) { reqs = 0; pages = 0; bys = 0.0; for (k = 0; k < relgran; k++) { reqs += dp->reqs[j + k]; pages += dp->pages[j + k]; bys += dp->bytes[j + k]; } if ((dp != lastdp || j <= lasttime) && (dp != firstdp || j + (int)relgran > firsttime)) { totr += reqs; totp += pages; totb += bys; if (((graphby == 'R' || graphby == 'r') && reqs >= busyr) || ((graphby == 'P' || graphby == 'p') && pages >= busyp) || ((graphby == 'B' || graphby == 'b') && bys >= busyb)) { busyr = reqs; busyp = pages; busyb = bys; busydate = i; busymin = (1440 * j) / granularity; } if (rowsdone < rows) { maxr = MAX(maxr, reqs); maxp = MAX(maxp, pages); maxb = MAX(maxb, bys); trp->prev = (Timerep *)xmalloc(sizeof(Timerep)); trp->prev->next = trp; trp = trp->prev; trp->reqs = reqs; trp->pages = pages; trp->bytes = bys; trp->date = i; trp->prev = NULL; rowsdone++; if (rowsdone == rows) /* set now because j will be destroyed */ min = (1440 * j) / granularity; } } } dp = dp->prev; } width[COL_TITLE] = MAX(datefmtlen(datefmt, monthlen, daylen, compsep, (logical)(outstyle == COMPUTER)), htmlstrlen(colhead, outstyle)); calcsizes(outstyle, width, &bmult, &unit, maxr, maxp, maxb, 0, pagewidth, mingraphwidth, graphby, repsepchar, rawbytes, cols, 0, 0, lngstr); declareunit(outf, outstyle, pagewidth, graphby, unit, bmult, barstyle, markchar, sepchar, decpt, imagedir, lngstr); if (back || rowsdone != rows) /* o/wise set above */ min = (int)((1440 * ((back?lasttime:firsttime) / relgran)) / repgran); hr = min / 60; min %= 60; PRESTART(); colheads(outf, cols, outstyle, width, bmult, colhead, TRUE, lngstr); for (trp = back?(trhead->prev):trp; trp != (back?NULL:trhead); ) { if (outstyle != COMPUTER && !first && ((rep == REP_HOURREP && hr == (back?23:0)) || (rep == REP_QUARTER && min == (back?45:0) && (hr % 4) == (back?3:0)) || (rep == REP_FIVE && min == (back?55:0)) || (rep == REP_DAYREP && DAYOFWEEK(trp->date) == (back?((weekbeginson + 6) % 7):weekbeginson)))) fputc('\n', outf); if (rep == REP_QUARTER) newmin = (min + 15) % 60; else if (rep == REP_FIVE) newmin = (min + 5) % 60; printcols(outf, rep, cols, outstyle, FALSE, trp->reqs, trp->pages, trp->bytes, -1, -1, totr, totp, totb, width, bmult, graphby, unit, barstyle, markchar, repsepchar, decpt, compsep, TRUE, TRUE, imagedir, html, "", FALSE, 0, NULL, NULL, NULL, datefmt, NULL, trp->date, (unsigned int)hr, (unsigned int)min, (unsigned int)((newmin == 0)?(hr + 1):(hr)), (unsigned int)newmin, monthname, dayname, monthlen, daylen, plainmonthlen, plaindaylen); first = FALSE; if (rep == REP_HOURREP) hr += back?(-1):(+1); else if (rep == REP_QUARTER) min += back?(-15):(+15); else if (rep == REP_FIVE) min += back?(-5):(+5); if (min >= 60) { min -= 60; hr++; } else if (min < 0) { min += 60; hr--; } if (hr >= 24) hr -= 24; else if (hr < 0) hr += 24; oldtrp = trp; trp = back?(trp->prev):(trp->next); free((void *)oldtrp); } PREEND(); busyhr = busymin / 60; busymin %= 60; if (rep == REP_QUARTER) newmin = (busymin + 15) % 60; else if (rep == REP_FIVE) newmin = (busymin + 5) % 60; busyprintf(outf, outstyle, datefmt, busyr, busyp, busyb, busydate, (unsigned int)busyhr, (unsigned int)busymin, (unsigned int)((newmin == 0)?(busyhr + 1):(busyhr)), (unsigned int)newmin, graphby, sepchar, decpt, rawbytes, lngstr, monthname, dayname, plainmonthlen, plaindaylen, busystr); } void superdayrep(FILE *outf, choice rep, Daysdata *firstdp, Daysdata *lastdp, datecode_t firstdate, datecode_t lastdate, choice outstyle, unsigned int granularity, unsigned int pagewidth, unsigned int mingraphwidth, logical back, logical rawbytes, choice *cols, unsigned int rows, char graphby, char barstyle, char markchar, char sepchar, char repsepchar, char decpt, char *compsep, choice weekbeginson, char *imagedir, logical *html, char **monthname, unsigned int monthlen, unsigned int plainmonthlen, char **lngstr, char *datefmt, char *colhead, char *busystr) { Daysdata *dp; Timerep *trhead, *trp, *oldtrp; unsigned long reqs = 0, pages = 0, totr = 0, totp = 0; unsigned long maxr = 0, maxp = 0, busyr = 0, busyp = 0; double bys = 0.0, totb = 0.0, maxb = 0.0, busyb = 0.0, unit = 0.0; unsigned int width[COL_NUMBER], bmult, date, dummy1, dummy2; logical save, first = TRUE; datecode_t busydate = 0, i; unsigned long rowsdone = 0; unsigned int j; dp = lastdp; trhead = (Timerep *)xmalloc(sizeof(Timerep)); trp = trhead; if (rows == 0) rows = INT_MAX; for (i = lastdate; i >= firstdate; i--) { for (j = 0; j < granularity; j++) { reqs += dp->reqs[j]; pages += dp->pages[j]; bys += dp->bytes[j]; } if (rep == REP_MONTH) { code2date(i, &date, &dummy1, &dummy2); save = (date == 1) || (i == firstdate); } else save = (DAYOFWEEK(i) == weekbeginson) || (i == firstdate); if (save) { totr += reqs; totp += pages; totb += bys; if (((graphby == 'R' || graphby == 'r') && reqs >= busyr) || ((graphby == 'P' || graphby == 'p') && pages >= busyp) || ((graphby == 'B' || graphby == 'b') && bys >= busyb)) { busyr = reqs; busyp = pages; busyb = bys; busydate = i; /* busydate always set coz busyr is initialised to 0 */ } if (rowsdone < rows) { maxr = MAX(maxr, reqs); maxp = MAX(maxp, pages); maxb = MAX(maxb, bys); trp->prev = (Timerep *)xmalloc(sizeof(Timerep)); trp->prev->next = trp; trp = trp->prev; trp->reqs = reqs; trp->pages = pages; trp->bytes = bys; while (rep == REP_WEEK && DAYOFWEEK(i) != weekbeginson) i--; /* destroys i, but in this case we've finished with it */ trp->date = i; trp->prev = NULL; rowsdone++; } reqs = 0; pages = 0; bys = 0.0; } dp = dp->prev; } width[COL_TITLE] = MAX(datefmtlen(datefmt, monthlen, 0, compsep, (logical)(outstyle == COMPUTER)), htmlstrlen(colhead, outstyle)); calcsizes(outstyle, width, &bmult, &unit, maxr, maxp, maxb, 0, pagewidth, mingraphwidth, graphby, repsepchar, rawbytes, cols, 0, 0, lngstr); declareunit(outf, outstyle, pagewidth, graphby, unit, bmult, barstyle, markchar, sepchar, decpt, imagedir, lngstr); PRESTART(); colheads(outf, cols, outstyle, width, bmult, colhead, TRUE, lngstr); for (trp = back?(trhead->prev):trp; trp != (back?NULL:trhead); ) { if (rep == REP_MONTH) { code2date(trp->date, &dummy1, &date, &dummy2); if (date == (unsigned int)(back?11:0) && outstyle != COMPUTER && !first) fputc('\n', outf); first = FALSE; } printcols(outf, rep, cols, outstyle, FALSE, trp->reqs, trp->pages, trp->bytes, -1, -1, totr, totp, totb, width, bmult, graphby, unit, barstyle, markchar, repsepchar, decpt, compsep, TRUE, TRUE, imagedir, html, "", FALSE, 0, NULL, NULL, NULL, datefmt, NULL, trp->date, 0, 0, 0, 0, monthname, NULL, monthlen, 0, plainmonthlen, 0); oldtrp = trp; trp = back?(trp->prev):(trp->next); free((void *)oldtrp); } PREEND(); while (rep == REP_WEEK && DAYOFWEEK(busydate) != weekbeginson) busydate--; /* if first week is busiest */ busyprintf(outf, outstyle, datefmt, busyr, busyp, busyb, busydate, 0, 0, 0, 0, graphby, sepchar, decpt, rawbytes, lngstr, monthname, NULL, plainmonthlen, 0, busystr); } void daysum(FILE *outf, Daysdata *firstdp, datecode_t firstdate, datecode_t lastdate, choice outstyle, unsigned int granularity, choice weekbeginson, unsigned int pagewidth, unsigned int mingraphwidth, logical rawbytes, choice *cols, char graphby, char barstyle, char markchar, char sepchar, char repsepchar, char decpt, char *compsep, char *imagedir, logical *html, char *colhead, char **dayname, unsigned int daylen, char **lngstr) { Daysdata *dp; unsigned long reqs[7], pages[7], totr = 0, totp = 0; double bys[7], totb = 0.0, unit = 0.0; unsigned int width[COL_NUMBER], bmult; choice weekday; datecode_t date; unsigned int i; for (i = 0; i < 7; i++) { reqs[i] = 0; pages[i] = 0; bys[i] = 0.0; } dp = firstdp; for (date = firstdate; date <= lastdate; date++) { weekday = DAYOFWEEK(date); for (i = 0; i < granularity; i++) { reqs[weekday] += dp->reqs[i]; totr += dp->reqs[i]; pages[weekday] += dp->pages[i]; totp += dp->pages[i]; bys[weekday] += dp->bytes[i]; totb += dp->bytes[i]; } dp = dp->next; } width[COL_TITLE] = MAX(daylen, htmlstrlen(lngstr[day_], outstyle)); calcsizes(outstyle, width, &bmult, &unit, arraymaxl(reqs, 7), arraymaxl(pages, 7), arraymaxd(bys, 7), 0, pagewidth, mingraphwidth, graphby, repsepchar, rawbytes, cols, 0, 0, lngstr); declareunit(outf, outstyle, pagewidth, graphby, unit, bmult, barstyle, markchar, sepchar, decpt, imagedir, lngstr); PRESTART(); colheads(outf, cols, outstyle, width, bmult, colhead, TRUE, lngstr); for (i = 0; i < 7; i++) { weekday = (weekbeginson + i) % 7; printcols(outf, REP_DAYSUM, cols, outstyle, FALSE, reqs[weekday], pages[weekday], bys[weekday], -1, -1, totr, totp, totb, width, bmult, graphby, unit, barstyle, markchar, repsepchar, decpt, compsep, TRUE, TRUE, imagedir, html, dayname[weekday], FALSE, 0, NULL, NULL, NULL, "", "", 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0); } PREEND(); } void hoursum(FILE *outf, Daysdata *firstdp, Daysdata *lastdp, choice outstyle, unsigned int granularity, unsigned int pagewidth, unsigned int mingraphwidth, logical rawbytes, choice *cols, char graphby, char barstyle, char markchar, char sepchar, char repsepchar, char decpt, char *compsep, char *imagedir, logical *html, char *colhead, char **lngstr) { Daysdata *dp; unsigned long reqs[24], pages[24], totr = 0, totp = 0; double bys[24], totb = 0.0, unit = 0.0; unsigned int width[COL_NUMBER], bmult; logical finished = FALSE; char temps[3]; unsigned int i; for (i = 0; i < 24; i++) { reqs[i] = 0; pages[i] = 0; bys[i] = 0.0; } for (dp = firstdp; !finished; TO_NEXT(dp)) { for (i = 0; i < granularity; i++) { reqs[(i * 24) / granularity] += dp->reqs[i]; totr += dp->reqs[i]; pages[(i * 24) / granularity] += dp->pages[i]; totp += dp->pages[i]; bys[(i * 24) / granularity] += dp->bytes[i]; totb += dp->bytes[i]; } if (dp == lastdp) finished = TRUE; } width[COL_TITLE] = MAX(2, htmlstrlen(lngstr[hr_], outstyle)); calcsizes(outstyle, width, &bmult, &unit, arraymaxl(reqs, 24), arraymaxl(pages, 24), arraymaxd(bys, 24), 0, pagewidth, mingraphwidth, graphby, repsepchar, rawbytes, cols, 0, 0, lngstr); declareunit(outf, outstyle, pagewidth, graphby, unit, bmult, barstyle, markchar, sepchar, decpt, imagedir, lngstr); PRESTART(); colheads(outf, cols, outstyle, width, bmult, colhead, TRUE, lngstr); for (i = 0; i < 24; i++) { sprintf(temps, "%d", i); printcols(outf, REP_HOURSUM, cols, outstyle, FALSE, reqs[i], pages[i], bys[i], -1, -1, totr, totp, totb, width, bmult, graphby, unit, barstyle, markchar, repsepchar, decpt, compsep, TRUE, TRUE, imagedir, html, temps, FALSE, 0, NULL, NULL, NULL, "", "", 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0); } PREEND(); } void printtree(FILE *outf, choice rep, choice outstyle, logical multibyte, Hashtable *tree, choice requests, choice date, Hashentry *badp, unsigned long badn, unsigned int level, Strlist *partname, Alias *aliashead, Include *linkhead, char *baseurl, unsigned long totr, unsigned long totp, double totb, unsigned int width[], unsigned int bmult, double unit, char sepchar, char repsepchar, char decpt, char *compsep, logical rawbytes, choice *cols, char *colhead, char *colheadp, char gender, logical *html, char **monthname, char **dayname, unsigned int monthlen, unsigned int daylen, unsigned int plainmonthlen, unsigned int plaindaylen, char **lngstr) { char *name; size_t need = (size_t)level + 3; Hashindex *p; Strlist *pn, s; char *notlistedstr; unsigned long goodn = 0; unsigned int tmpw = 0; if (tree != NULL) { for (pn = partname; pn != NULL; TO_NEXT(pn)) need += strlen(pn->name); for (p = tree->head[0]; p != NULL; TO_NEXT(p)) { name = maketreename(partname, p, &pn, &s, need, rep, TRUE); if (name[0] == '\0' || name[1] == '\0') { /* if REP_ORG, an alias */ tmpw = width[COL_TITLE]; width[COL_TITLE] = 0; } printcols(outf, rep, cols, outstyle, multibyte, p->own->data[requests], p->own->data[PAGES], p->own->bytes, (level == 0)?((long)(++goodn)):(-1), (int)level + 1, totr, totp, totb, width, bmult, '\0', unit, '\0', '\0', repsepchar, decpt, compsep, FALSE, FALSE, NULL, html, name, (logical)(p->own->ispage % 16), 2 * level, aliashead, linkhead, baseurl, lngstr[genrepdate_], lngstr[genreptime_], p->own->data[date] / 1440, (p->own->data[date] % 1440) / 60, p->own->data[date] % 60, 0, 0, monthname, dayname, monthlen, daylen, plainmonthlen, plaindaylen); if (name[0] == '\0' || name[1] == '\0') width[COL_TITLE] = tmpw; printtree(outf, rep, outstyle, multibyte, (Hashtable *)(p->other), requests, date, NULL, 0, level + 1, pn, aliashead, linkhead, baseurl, totr, totp, totb, width, bmult, unit, sepchar, repsepchar, decpt, compsep, rawbytes, cols, NULL, NULL, gender, html, monthname, dayname, monthlen, daylen, plainmonthlen, plaindaylen, lngstr); } } if (badn > 0 && level == 0) { printcols(outf, rep, cols, outstyle, multibyte, badp->data[requests], badp->data[PAGES], badp->bytes, -1, 1, totr, totp, totb, width, bmult, '\0', unit, '\0', '\0', repsepchar, decpt, compsep, FALSE, FALSE, NULL, html, NULL, FALSE, 0, NULL, NULL, NULL, lngstr[genrepdate_], lngstr[genreptime_], badp->data[date] / 1440, (badp->data[date] % 1440) / 60, badp->data[date] % 60, 0, 0, monthname, dayname, monthlen, daylen, plainmonthlen, plaindaylen); if (gender == 'm') notlistedstr = lngstr[notlistedm_]; else if (gender == 'f') notlistedstr = lngstr[notlistedf_]; else notlistedstr = lngstr[notlistedn_]; fprintf(outf, "[%s: ", notlistedstr); f3printf(outf, outstyle, (double)badn, 0, sepchar); if (outstyle == COMPUTER) fprintf(outf, "]\n"); else fprintf(outf, " %s]\n", (badn == 1)?colhead:colheadp); } } void treerep(FILE *outf, choice rep, choice outstyle, logical multibyte, Tree *treex, Hashindex *gooditems, Hashindex *baditems, Alias *aliashead, Include *wanthead, Include *linkhead, char *baseurl, choice *alltrees, choice requests, choice date, Floor *floor, choice sortby, Floor *subfloor, choice subsortby, logical alphaback, unsigned int pagewidth, char sepchar, char repsepchar, char decpt, char *compsep, logical rawbytes, choice *cols, char *colhead, char *colheadp, char *gens, char *genp, char gender, logical *html, timecode_t firsttime, char **monthname, char **dayname, unsigned int monthlen, unsigned int daylen, unsigned int plainmonthlen, unsigned int plaindaylen, char **lngstr) { /* alphaback only really makes sense if no hierarchy: kludge to allow REP_ORG to be implemented as treerep() instead of dervrep() for simplicity */ Hashtable *tree; Hashindex *p; Hashentry *badp; unsigned long totr = 0, totp = 0, maxr = 0, maxp = 0, goodn = 0, badn, i; double totb = 0.0, maxb = 0.0, unit = 1.0; unsigned int width[COL_NUMBER], bmult, tw; logical templ = FALSE; for (i = 0; alltrees[i] != REP_NUMBER; i++) if (rep == alltrees[i]) templ = TRUE; /* tree already constructed */ if (!templ) maketree(treex, gooditems, baditems); tree = treex->tree; for (i = 0; i < tree->size; i++) { for (p = tree->head[i]; p != NULL; TO_NEXT(p)) { totr += p->own->data[requests]; /* tot of top level = overall tot */ totp += p->own->data[PAGES]; /* also max's all on top level */ totb += p->own->bytes; maxr = MAX(maxr, p->own->data[requests]); maxp = MAX(maxp, p->own->data[PAGES]); maxb = MAX(maxb, p->own->bytes); } } tree->head[0] = sorttree(tree, rep, floor, sortby, subfloor, subsortby, alphaback, 0, NULL, wanthead, (rep == REP_DOM)?aliashead:NULL, requests, date, totr, totp, totb, maxr, maxp, maxb, &badp, &badn, treex->space); maxr = badp->data[requests]; maxp = badp->data[PAGES]; maxb = badp->bytes; for (p = tree->head[0]; p != NULL; TO_NEXT(p)) { maxr = MAX(maxr, p->own->data[requests]); maxp = MAX(maxp, p->own->data[PAGES]); maxb = MAX(maxb, p->own->bytes); goodn++; } width[COL_TITLE] = 0; calcsizes(outstyle, width, &bmult, &unit, maxr, maxp, maxb, goodn, pagewidth, 0, '\0', repsepchar, rawbytes, cols, monthlen, daylen, lngstr); if (alphaback && sortby == ALPHABETICAL) { tw = alphatreewidth(tree, outstyle); width[COL_TITLE] = MIN(tw, width[COL_TITLE]); } else width[COL_TITLE] = 0; whatincluded(outf, rep, outstyle, goodn, pagewidth, floor, sortby, decpt, compsep, gens, genp, gender, requests, date, firsttime, monthname, dayname, plainmonthlen, plaindaylen, lngstr); PRESTART(); colheads(outf, cols, outstyle, width, bmult, colhead, FALSE, lngstr); printtree(outf, rep, outstyle, multibyte, tree, requests, date, badp, badn, 0, NULL, aliashead, linkhead, baseurl, totr, totp, totb, width, bmult, unit, sepchar, repsepchar, decpt, compsep, rawbytes, cols, colhead, colheadp, gender, html, monthname, dayname, monthlen, daylen, plainmonthlen, plaindaylen, lngstr); PREEND(); freemm(treex->space); } void dervrep(FILE *outf, choice rep, choice outstyle, logical multibyte, Derv *derv, Hashindex *gooditems, Hashindex *baditems, Include *wanthead, choice *alldervs, Floor *floor, choice sortby, unsigned int pagewidth, char sepchar, char repsepchar, char decpt, char *compsep, logical rawbytes, unsigned char convfloor, choice *cols, char *colhead, char *colheadp, char *gens, char *genp, char gender, logical *html, timecode_t firsttime, char **monthname, char **dayname, unsigned int monthlen, unsigned int daylen, unsigned int plainmonthlen, unsigned int plaindaylen, char **lngstr) { Hashindex *good = NULL, *bad = NULL; choice i; logical templ = FALSE; /* strategy: build list of items then hand off to genrep() */ for(i = 0; alldervs[i] != REP_NUMBER; i++) if (rep == alldervs[i]) templ = TRUE; if (!templ) makederived(derv, gooditems, baditems, convfloor, rep); unhash(derv->table, &good, &bad); genrep(outf, rep, outstyle, multibyte, &good, &bad, NULL, wanthead, REQUESTS, SUCCDATE, floor, sortby, FALSE, pagewidth, sepchar, repsepchar, decpt, compsep, rawbytes, cols, colhead, colheadp, gens, genp, gender, html, firsttime, monthname, dayname, monthlen, daylen, plainmonthlen, plaindaylen, lngstr); } void dervtreerep(FILE *outf, choice rep, choice outstyle, logical multibyte, Derv *derv, Tree *treex, Hashindex *gooditems, Hashindex *baditems, Alias *aliashead, Include *wanthead, choice *alltrees, choice *alldervs, Floor *floor, choice sortby, Floor *subfloor, choice subsortby, unsigned int pagewidth, char sepchar, char repsepchar, char decpt, char *compsep, logical rawbytes, unsigned char convfloor, choice *cols, char *colhead, char *colheadp, char *gens, char *genp, char gender, logical *html, timecode_t firsttime, char **monthname, char **dayname, unsigned int monthlen, unsigned int daylen, unsigned int plainmonthlen, unsigned int plaindaylen, char **lngstr) { /* same as dervrep() except hand off to treerep() at the end */ Hashindex *good = NULL, *bad = NULL; choice i; logical templ = FALSE; for(i = 0; alldervs[i] != REP_NUMBER; i++) if (rep == alldervs[i]) templ = TRUE; if (!templ) makederived(derv, gooditems, baditems, convfloor, rep); unhash(derv->table, &good, &bad); treerep(outf, rep, outstyle, multibyte, treex, good, bad, aliashead, wanthead, NULL, NULL, alltrees, REQUESTS, SUCCDATE, floor, sortby, subfloor, subsortby, FALSE, pagewidth, sepchar, repsepchar, decpt, compsep, rawbytes, cols, colhead, colheadp, gens, genp, gender, html, firsttime, monthname, dayname, monthlen, daylen, plainmonthlen, plaindaylen, lngstr); } /* names for each bucket in arrayrep: see thresholds at top of defaults()... in globals.c. (Names for code buckets are in the language files). */ char *sizenames[] = {"0", "1b- 10b", "11b- 100b", "101b- 1kb", "1kb- 10kb", "10kb-100kb", "100kb- 1Mb", "1Mb- 10Mb", "10Mb-100Mb", "100Mb- 1Gb", "> 1Gb"}; char *ptnames1[] = {"0", "<= 0.01", "0.01-0.02", "0.02-0.05", "0.05-0.1 ", "0.1 -0.2 ", "0.2 -0.5 ", "0.5 -1 ", "1- 2 ", "2- 5 ", "5- 10 ", "10- 20 ", "20- 60 ", "60-120 ", "120-300 ", "> 300 "}; char *ptnames2[] = {"0", "", "", "", "", "", "", "1", "2", "3- 5", "5- 10", "10- 20", "20- 60", "60-120", "120-300", "> 300"}; /* empty string signifies don't use */ void arrayrep(FILE *outf, choice rep, choice outstyle, logical multibyte, Arraydata *array, Floor *floor, choice sortby, unsigned int pagewidth, char sepchar, char repsepchar, char decpt, char *compsep, logical rawbytes, choice *cols, char *colhead, char *colheadp, char *gens, char *genp, char gender, logical *html, timecode_t firsttime, char **monthname, char **dayname, unsigned int monthlen, unsigned int daylen, unsigned int plainmonthlen, unsigned int plaindaylen, char **lngstr) { extern Memman *xmemman; Hashindex *good = NULL, *bad = NULL, *gp = NULL; char **names; choice i, lasti; logical done; /* strategy: construct list of (Hashindex *), and pass to genrep() */ if (rep == REP_CODE) names = &(lngstr[code100_]); else if (rep == REP_SIZE) names = sizenames; else if (array[1].reqs + array[2].reqs + array[3].reqs + array[4].reqs + array[5].reqs + array[6].reqs == 0) /* assume %t not %T */ names = ptnames2; else names = ptnames1; /* calculate lasti */ for (lasti = 0; array[lasti].threshold >= -0.5; lasti++) ; if (rep != REP_CODE) { for ( ; array[lasti].reqs == 0; lasti--) ; } for (i = 0, done = FALSE; !done; i++) { if (array[i].reqs > 0 || (rep != REP_CODE && !IS_EMPTY_STRING(names[i]))) { if (good == NULL) { gp = (Hashindex *)submalloc(xmemman, sizeof(Hashindex)); good = gp; } else { gp->next = (Hashindex *)submalloc(xmemman, sizeof(Hashindex)); TO_NEXT(gp); } gp->name = names[i]; gp->own = newhashentry(FALSE); gp->own->data[REQUESTS] = array[i].reqs; gp->own->data[PAGES] = array[i].pages; gp->own->data[SUCCDATE] = array[i].lastdate; gp->own->bytes = array[i].bytes; gp->next = NULL; } if (i == lasti) done = TRUE; } genrep(outf, rep, outstyle, (logical)((rep == REP_CODE)?multibyte:FALSE), &good, &bad, NULL, NULL, REQUESTS, SUCCDATE, floor, sortby, FALSE, pagewidth, sepchar, repsepchar, decpt, compsep, rawbytes, cols, colhead, colheadp, gens, genp, gender, html, firsttime, monthname, dayname, monthlen, daylen, plainmonthlen, plaindaylen, lngstr); } void output(Outchoices *od, Hashindex **gooditems, Hashindex **baditems, Dateman *dman, Arraydata **arraydata, unsigned long *sumdata, double totbytes, double totbytes7, unsigned int granularity) { extern choice *rep2type, *rep2reqs, *rep2date; extern unsigned int *rep2gran, *rep2lng, *rep2datefmt, *rep2colhead; extern unsigned int *rep2busystr; extern char *workspace; FILE *outf; Include *linkhead; char *baseurl; int ro; choice rep; /* first open output file */ if (strcaseeq(od->outfile, "stdout") || STREQ(od->outfile, "-")) { outf = stdout; debug('F', "Opening stdout as output file"); } else { (void)datesprintf(workspace, od->outfile, OUT_NONE, dman->last7to / 1440, (dman->last7to % 1440) / 60, dman->last7to % 60, 0, 0, od->monthname, od->dayname, 0, 0, NULL, TRUE); if ((outf = FOPENW(workspace)) == NULL) error("failed to open output file %s for writing", workspace); else debug('F', "Opening %s as output file", workspace); } /* remove any reports not wanted */ checkreps(od, od->repq, dman, od->alltrees, od->alldervs, gooditems, od->tree, od->derv, arraydata); /* page header */ pagetop(outf, od, dman); /* Now the main reports */ for (ro = 0; od->reporder[ro] != -1; ro++) { rep = od->reporder[ro]; if (od->repq[rep]) { report_title(outf, od->lngstr[rep2lng[rep]], rep, od->gotos, od->repq, od->lngstr, od->reporder, od->outstyle); switch(rep) { case (REP_GENSUM): gensum(outf, od->outstyle, od->last7, sumdata, totbytes, totbytes7, gooditems, baditems, dman, od->rawbytes, od->sepchar, od->decpt, od->compsep, od->monthname, od->dayname, od->plainmonthlen, od->plaindaylen, od->lngstr); break; case (REP_DAYREP): case (REP_HOURREP): case (REP_QUARTER): case (REP_FIVE): subdayrep(outf, rep, dman->firstdp, dman->lastdp, dman->firstdate, dman->lastdate, od->outstyle, granularity, rep2gran[rep], od->pagewidth, od->mingraphwidth, od->back[rep], od->rawbytes, od->cols[rep], od->rows[rep], od->graph[rep], od->barstyle, od->markchar, od->sepchar, od->repsepchar, od->decpt, od->compsep, od->weekbeginson, od->imagedir, &(od->html), od->monthname, od->dayname, od->monthlen, od->daylen, od->plainmonthlen, od->plaindaylen, od->lngstr, od->lngstr[rep2datefmt[rep]], od->lngstr[rep2colhead[rep]], od->lngstr[rep2busystr[rep]]); break; case (REP_WEEK): case (REP_MONTH): superdayrep(outf, rep, dman->firstdp, dman->lastdp, dman->firstdate, dman->lastdate, od->outstyle, granularity, od->pagewidth, od->mingraphwidth, od->back[rep], od->rawbytes, od->cols[rep], od->rows[rep], od->graph[rep], od->barstyle, od->markchar, od->sepchar, od->repsepchar, od->decpt, od->compsep, od->weekbeginson, od->imagedir, &(od->html), od->monthname, od->monthlen, od->plainmonthlen, od->lngstr, od->lngstr[rep2datefmt[rep]], od->lngstr[rep2colhead[rep]], od->lngstr[rep2busystr[rep]]); break; case (REP_DAYSUM): daysum(outf, dman->firstdp, dman->firstdate, dman->lastdate, od->outstyle, granularity, od->weekbeginson, od->pagewidth, od->mingraphwidth, od->rawbytes, od->cols[rep], od->graph[rep], od->barstyle, od->markchar, od->sepchar, od->repsepchar, od->decpt, od->compsep, od->imagedir, &(od->html), od->lngstr[rep2colhead[rep]], od->dayname, od->daylen, od->lngstr); break; case (REP_HOURSUM): hoursum(outf, dman->firstdp, dman->lastdp, od->outstyle, granularity, od->pagewidth, od->mingraphwidth, od->rawbytes, od->cols[rep], od->graph[rep], od->barstyle, od->markchar, od->sepchar, od->repsepchar, od->decpt, od->compsep, od->imagedir, &(od->html), od->lngstr[rep2colhead[rep]], od->lngstr); break; case (REP_HOST): case (REP_BROWREP): case (REP_VHOST): case (REP_USER): case (REP_FAILUSER): genrep(outf, rep, od->outstyle, od->multibyte, &(gooditems[rep2type[rep]]), &(baditems[rep2type[rep]]), od->aliashead[G(rep)], od->wanthead[G(rep)], rep2reqs[G(rep)], rep2date[G(rep)], &(od->floor[G(rep)]), od->sortby[G(rep)], (logical)(rep == REP_HOST || rep == REP_VHOST), od->pagewidth, od->sepchar, od->repsepchar, od->decpt, od->compsep, od->rawbytes, od->cols[rep], od->lngstr[rep2colhead[rep]], od->lngstr[rep2colhead[rep] + 1], od->lngstr[rep2lng[rep] + 1], od->lngstr[rep2lng[rep] + 2], od->lngstr[rep2lng[rep] + 3][0], &(od->html), dman->firsttime, od->monthname, od->dayname, od->monthlen, od->daylen, od->plainmonthlen, od->plaindaylen, od->lngstr); break; case (REP_REQ): case (REP_REDIR): case (REP_FAIL): case (REP_REF): case (REP_REDIRREF): case (REP_FAILREF): case (REP_TYPE): case (REP_DIR): case (REP_DOM): case (REP_ORG): case (REP_REFSITE): baseurl = NULL; if (rep == REP_REQ) { linkhead = od->link; baseurl = od->baseurl; } else if (rep == REP_REF || rep == REP_REDIRREF || rep == REP_FAILREF) linkhead = od->reflink; else linkhead = NULL; treerep(outf, rep, od->outstyle, od->multibyte, od->tree[G(rep)], gooditems[rep2type[rep]], baditems[rep2type[rep]], od->aliashead[G(rep)], od->wanthead[G(rep)], linkhead, baseurl, od->alltrees, rep2reqs[G(rep)], rep2date[G(rep)], &(od->floor[G(rep)]), od->sortby[G(rep)], &(od->subfloor[G(rep)]), od->subsortby[G(rep)], (logical)(rep == REP_ORG), od->pagewidth, od->sepchar, od->repsepchar, od->decpt, od->compsep, od->rawbytes, od->cols[rep], od->lngstr[rep2colhead[rep]], od->lngstr[rep2colhead[rep] + 1], od->lngstr[rep2lng[rep] + 1], od->lngstr[rep2lng[rep] + 2], od->lngstr[rep2lng[rep] + 3][0], &(od->html), dman->firsttime, od->monthname, od->dayname, od->monthlen, od->daylen, od->plainmonthlen, od->plaindaylen, od->lngstr); break; case (REP_SEARCHREP): case (REP_SEARCHSUM): dervrep(outf, rep, od->outstyle, od->multibyte, od->derv[rep - FIRST_DERVREP], gooditems[rep2type[rep]], baditems[rep2type[rep]], od->wanthead[G(rep)], od->alldervs, &(od->floor[G(rep)]), od->sortby[G(rep)], od->pagewidth, od->sepchar, od->repsepchar, od->decpt, od->compsep, od->rawbytes, od->convfloor, od->cols[rep], od->lngstr[rep2colhead[rep]], od->lngstr[rep2colhead[rep] + 1], od->lngstr[rep2lng[rep] + 1], od->lngstr[rep2lng[rep] + 2], od->lngstr[rep2lng[rep] + 3][0], &(od->html), dman->firsttime, od->monthname, od->dayname, od->monthlen, od->daylen, od->plainmonthlen, od->plaindaylen, od->lngstr); break; case (REP_BROWSUM): case (REP_OS): dervtreerep(outf, rep, od->outstyle, od->multibyte, od->derv[rep - FIRST_DERVREP], od->tree[G(rep)], gooditems[rep2type[rep]], baditems[rep2type[rep]], od->aliashead[G(rep)], od->wanthead[G(rep)], od->alltrees, od->alldervs, &(od->floor[G(rep)]), od->sortby[G(rep)], &(od->subfloor[G(rep)]), od->subsortby[G(rep)], od->pagewidth, od->sepchar, od->repsepchar, od->decpt, od->compsep, od->rawbytes, od->convfloor, od->cols[rep], od->lngstr[rep2colhead[rep]], od->lngstr[rep2colhead[rep] + 1], od->lngstr[rep2lng[rep] + 1], od->lngstr[rep2lng[rep] + 2], od->lngstr[rep2lng[rep] + 3][0], &(od->html), dman->firsttime, od->monthname, od->dayname, od->monthlen, od->daylen, od->plainmonthlen, od->plaindaylen, od->lngstr); break; case (REP_SIZE): case (REP_CODE): case (REP_PROCTIME): arrayrep(outf, rep, od->outstyle, od->multibyte, arraydata[rep - FIRST_ARRAYREP], &(od->floor[G(rep)]), od->sortby[G(rep)], od->pagewidth, od->sepchar, od->repsepchar, od->decpt, od->compsep, od->rawbytes, od->cols[rep], od->lngstr[rep2colhead[rep]], od->lngstr[rep2colhead[rep] + 1], od->lngstr[rep2lng[rep] + 1], od->lngstr[rep2lng[rep] + 2], od->lngstr[rep2lng[rep] + 3][0], &(od->html), dman->firsttime, od->monthname, od->dayname, od->monthlen, od->daylen, od->plainmonthlen, od->plaindaylen, od->lngstr); break; } /* end switch rep */ hrule(outf, od->outstyle, od->pagewidth); } /* end if rep wanted */ } /* end for ro */ /*** Bit at the bottom of the page ***/ pagebot(outf, od); if (!strcaseeq(od->outfile, "stdout") && !STREQ(od->outfile, "-")) { debug('F', "Closing %s", datesprintf(workspace, od->outfile, OUT_NONE, dman->last7to / 1440, (dman->last7to % 1440) / 60, dman->last7to % 60, 0, 0, od->monthname, od->dayname, 0, 0, NULL, TRUE)); fclose(outf); } }