rateup.c
上传用户:shbosideng
上传日期:2013-05-04
资源大小:1555k
文件大小:59k
- /*
- MRTG 2.13.2 -- Rateup
- *********************
- Rateup is a fast add-on to the great MRTG Traffic monitor. It makes
- the database file updates much faster, and creates the graphic image
- files, ready for processing by PPMTOGIF. It also reduces memory
- requirements by a factor of 10, and increases the speed of updates
- by a factor of at least 10. This makes it feasible to run mrtg
- every 5 minutes.
- rateup attempts to compensate for missed updates by repeating the last
- sample, and also tries to catch bad update times. The .log file stores
- real history every five minutes for 31 hours, then 'compresses' the
- history into 30 minute samples for a week, then 2-hour samples for
- 31 days, then daily samples for two years. This ensures that the
- log files don't grow in size.
- The log files are a slightly different format, but convert.perl
- will fix that for you.
- Enjoy!
- Dave Rand
- dlr@bungi.com
- 04/26/99 - There was some compilation bug under Watcom 10.6
- which was fixed when recompiled with VC++ 6.0
- Alexandre Steinberg
- steinberg@base.com.br
- */
- #include <stdlib.h>
- #include <string.h>
- /* VC++ does not have unistd.h */
- #ifndef WIN32
- #ifndef NETWARE
- #include "../config.h"
- #endif
- #include <unistd.h>
- #endif
- #include <limits.h>
- #include <stdio.h>
- #include <time.h>
- #include <math.h>
- #include <ctype.h>
- #ifndef GFORM_GD
- #define GFORM_GD gdImagePng
- #endif
- /* BSD* does not have/need malloc.h */
- #if !defined(bsdi) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__APPLE__)
- #include <malloc.h>
- #endif
- /* MSVCRT.DLL does not know %ll in printf */
- #ifdef __MINGW32_VERSION
- #define LLD "%I64d"
- #define LLD_FORMAT "I64d"
- #endif
- #ifdef __EMX__ /* OS/2 */
- #define strtoll _strtoll
- #define LLD "%Ld" /* EMX lib use %Ld for long long */
- #define LLD_FORMAT "Ld"
- #endif
- #ifndef LLD
- #define LLD "%lld"
- #define LLD_FORMAT "lld"
- #endif
- /* WATCOM C/C++ 10.6 under Win95/NT */
- /* VC++ 6.0 under Win95/NT */
- #if defined(__WATCOMC__) || defined(WIN32)
- #include <string.h>
- #include <sys/types.h>
- #include <direct.h>
- #include <io.h>
- #endif
- #include <gd.h>
- #include <gdfonts.h>
- char *VERSION = "2.13.2";
- char *program, *router, *routerpath;
- int histvalid;
- /* Options */
- short options = 0;
- #define OPTION_WITHZEROES 0x0001 /* withzeros */
- #define OPTION_UNKNASZERO 0x0002 /* unknaszero */
- #define OPTION_TRANSPARENT 0x0004 /* transparent */
- #define OPTION_DORELPERCENT 0x0008 /* dorelpercent */
- #define OPTION_NOBORDER 0x0010 /* noborder */
- #define OPTION_NOARROW 0x0020 /* noarrow */
- #define OPTION_NO_I 0x0040 /* ignore 'I' (first) variable */
- #define OPTION_NO_O 0x0080 /* ignore 'O' (second) variable */
- #define OPTION_PNGDATE 0x0100 /* show date & time in graph */
- #define OPTION_PRINTROUTER 0x0200 /* show title in graph */
- #define OPTION_LOGGRAPH 0x0400 /* Use a logarithmic Y axis */
- #define OPTION_MEANOVER 0x0800 /* max Y = mean-above-the-mean */
- time_t NOW;
- char *short_si[] = { "", "k", "M", "G", "T" };
- char *longup = NULL;
- char *shortup = NULL;
- char *pngtitle = NULL;
- char *pngdate = NULL;
- char *rtimezone = NULL;
- char weekformat = 'V'; /* strftime() fmt char for week # */
- #define DAY_COUNT (600) /* 400 samples is 33.33 hours */
- #define DAY_SAMPLE (5*60) /* Sample every 5 minutes */
- #define WEEK_COUNT (600) /* 400 samples is 8.33 days */
- #define WEEK_SAMPLE (30*60) /* Sample every 30 minutes */
- #define MONTH_COUNT (600) /* 400 samples is 33.33 days */
- #define MONTH_SAMPLE (2*60*60) /* Sample every 2 hours */
- #define YEAR_COUNT (2 * 366) /* 1 sample / day, 366 days, 2 years */
- #define YEAR_SAMPLE (24*60*60) /* Sample every 24 hours */
- /* One 'rounding error' per sample period, so add 4 to total and for
- good mesure we take 10 :-) */
- #define MAX_HISTORY (DAY_COUNT+WEEK_COUNT+MONTH_COUNT+YEAR_COUNT+10)
- /* These are the colors used for the variouse parts of the graph */
- /* the format is Red,Green,Blue */
- #define c_blank 245,245,245
- #define c_light 194,194,194
- #define c_dark 100,100,100
- #define c_major 255,0,0
- #define c_in 0,235,12
- #define c_out 0,94,255
- #define c_grid 0,0,0
- #define c_inm 0,166,33
- #define c_outm 255,0,255
- #define c_outp 239,159,79
- int col_in[3];
- int col_out[3];
- int col_inm[3];
- int col_outm[3];
- int col_outp[3];
- long long kilo = (long long) 1000;
- char *kMG = (char *) NULL;
- char *kMGcopy = (char *) NULL; /* JML bugfix */
- int kMGnumber = 0;
- #define MAXL 200 /* Maximum length of last in & out fields */
- struct HISTORY
- {
- time_t time;
- double in, out, percent, inmax, outmax;
- }
- *history;
- int Mh;
- struct LAST
- {
- time_t time;
- char in[MAXL], out[MAXL];
- }
- last;
- #ifndef max
- #define max(a,b) ((a) > (b) ? (a) : (b))
- #endif
- #ifndef min
- #define min(a,b) ((a) < (b) ? (a) : (b))
- #endif
- /*
- notes about the NEXT macro ....
- * position n to the entry in the history array so that NOW is between
- history[n] and history[n+1]
- * calculate the interval according to steptime and position of
- now within the history array.
- for debuging
- fprintf (stderr,"NOW: %8lu ST: %4lu N: %4u HTN: %8lu HTN+1: %8lu IV: %6.0fn",
- now,steptime,n,history[n].time, history[n+1].time, interval);
- */
- #define NEXT(steptime)
- inmax = outmax = avc = 0;
- inr = outr = 0.0;
- nextnow = now - steptime;
- if (now == history[n].time &&
- n<histvalid &&
- nextnow == history[n+1].time) {
- inr = (double) history[n].in;
- outr = (double) history[n].out;
- inmax = history[n].inmax;
- outmax = history[n].outmax;
- n++;
- } else {
- if (now > history[n].time) {
- fprintf(stderr,"ERROR: Rateup is trying to read ahead of the available datan");
- } else {
- while (now <= history[n+1].time && n < histvalid){n++;}
- do {
- if (now >= history[n].time) {
- if (nextnow <= history[n+1].time) {
- interval = history[n].time - history[n+1].time;
- } else {
- interval = history[n].time - nextnow;
- }
- } else {
- if (nextnow > history[n+1].time) {
- interval = steptime;
- } else {
- interval = now - history[n+1].time;
- }
- }
- inr += (double) history[n].in * interval;
- outr += (double) history[n].out * interval;
- avc += interval;
- inmax = (long long) max(inmax, history[n].inmax);
- outmax = (long long) max(outmax,history[n].outmax);
- if (nextnow <= history[n+1].time) n++; else break;
- } while (n < histvalid && nextnow < history[n].time);
- if (avc != steptime) {
- fprintf(stderr,"ERROR: StepTime does not match Avc %8" LLD_FORMAT ". Please Report this.n", avc);
- }
- inr /= avc; outr /= avc;
- }
- }
- static void
- image (file, maxvi, maxvo, maxx, maxy, xscale, yscale, growright, step, bits,
- ytics, yticsf, peak, currdatetimeformat, currdatetimepos)
- char *file;
- long long maxvi, maxvo;
- long maxx;
- long maxy, growright, step, bits;
- double xscale, yscale;
- int ytics; /* number of tics on the y axis */
- double yticsf; /* scale everything on the y axis with this factor */
- int peak;
- char *currdatetimeformat;
- int currdatetimepos;
- {
- FILE *fo;
- int i, x, n, type;
- long long maxv;
- double origmaxvi, origmaxvo;
- long long maxs, avc, inmax, outmax;
- long long ytrmax;
- double y, lmx1, lmx2, mea1, mea2, temp;
- double inr, outr, muli = 1, interval;
- time_t now, onow, nextnow;
- struct tm tm2, *tm = &tm2;
- struct tm tm3, *tmtz = &tm3;
- char **graph_label;
- char ylab[30];
- /* scaling helpers */
- long long maxv_q;
- long long valsamp, maxin, maxout, digits, maxpercent = 0;
- long long sca_ten, sca_hun;
- double nmax_q;
- double avmxin, avmxout, avin, avout, latestout = 0, latestin =
- 0, nmax, avpercent = 0, latestpercent = 0;
- double nex_ten, nex_hun, nex_rnd;
- double sca_max_q, dummy;
- double percent;
- char *short_si_out;
- char currdatetimestr[256];
- time_t currdatetime;
- int currdatetimepos_x, currdatetimepos_y;
- #define NO_TIMESTAMPSTR (0)
- #define LU_CORNER (1)
- #define RU_CORNER (2)
- #define LL_CORNER (3)
- #define RL_CORNER (4)
- struct HISTORY *lhist;
- /* ################################################# */
- /* Some general definitions for the graph generation */
- #define XSIZE (long)((maxx*xscale)+100+((options & OPTION_DORELPERCENT) ? 1 : 0)*30)
- #define YSIZE (long)((maxy*yscale)+35)
- /* position the graph */
- #define ytr(y) (long)(maxy*yscale+14-((y)*yscale))
- /* translate x/y coord into graph coord */
- #define xtr(x) (long)((growright) ? (maxx*xscale+81-((x)*xscale)) : (81+((x)*xscale)))
- /* ################################################# */
- /* GD LIB declarations */
- /* Declare the image */
- gdImagePtr graph, brush_out, brush_outm, brush_outp;
- /* Declare color indexes */
- int i_light, i_dark, i_blank, i_major, i_in, i_out, i_grid, i_inm, i_outm;
- int i_outp, i_outpg;
- /* Dotted style */
- int styleDotted[3];
- if ((graph_label = (char **) calloc (1, sizeof (char *) * maxx)) == NULL)
- {
- fprintf (stderr, "Rateup ERROR: Out of memory in graph creationn");
- exit (1);
- }
- /* multiplicator for bits/bytes */
- if (bits) {
- muli = 8;
- }
-
- maxv = (long long) max (maxvi, maxvo);
- maxv *= (long long) muli;
-
- origmaxvi = maxvi < (long long) 0 ? -maxvi : maxvi;
- origmaxvo = maxvo < (long long) 0 ? -maxvo : maxvo;
- if (step > MONTH_SAMPLE)
- {
- type = 4;
- now = (long) (NOW / YEAR_SAMPLE) * YEAR_SAMPLE;
- }
- else if (step > WEEK_SAMPLE)
- {
- type = 3;
- now = (long) (NOW / MONTH_SAMPLE) * MONTH_SAMPLE;
- }
- else if (step > DAY_SAMPLE)
- {
- type = 2;
- now = (long) (NOW / WEEK_SAMPLE) * WEEK_SAMPLE;
- }
- else
- {
- type = 1;
- now = (long) (NOW / DAY_SAMPLE) * DAY_SAMPLE;
- }
- if ((lhist = calloc (1, sizeof (struct HISTORY) * maxx)) == NULL)
- {
- fprintf (stderr, "Rateup ERROR: Out of memory in graph creationn");
- exit (1);
- }
- onow = now;
- avin = avout = avmxin = avmxout = 0.0;
- inmax = outmax = maxin = maxout = 0;
- valsamp = 0;
- for (maxs = 0, n = 0, x = 0; x < maxx; x++)
- {
- NEXT (step);
- /*scale with muli */
- inr *= muli;
- outr *= muli;
- inmax *= muli;
- outmax *= muli;
- /* ignore times when we have not sampled */
- if (inmax > 0 || outmax > 0 || inr > 0 || outr > 0
- || (options & OPTION_WITHZEROES)) valsamp++;
- if (x == 0)
- {
- latestin = inr;
- latestout = outr;
- if (outr)
- {
- latestpercent = inr * (double) 100. / outr;
- }
- }
- avin += inr;
- avout += outr;
- avmxin += inmax;
- avmxout += outmax;
- if (peak)
- {
- maxin = (long long) max (maxin, inmax);
- maxout = (long long) max (maxout, outmax);
- maxs = (long long) max (maxs, inmax);
- maxs = (long long) max (maxs, outmax);
- }
- else
- {
- maxin = (long long) max (maxin, inr);
- maxout = (long long) max (maxout, outr);
- maxs = (long long) max (maxs, inr);
- maxs = (long long) max (maxs, outr);
- }
- if ((options & OPTION_DORELPERCENT) && outr)
- {
- dummy = (double) 100. *inr / outr;
- maxpercent = max (dummy, maxpercent);
- }
- now -= step;
- }
- if (options & OPTION_DORELPERCENT)
- {
- if (avout && valsamp)
- {
- avpercent = (double) 100. *avin / avout;
- }
- else
- {
- avpercent = 0;
- }
- }
- if (valsamp)
- {
- avin /= valsamp;
- avout /= valsamp;
- avmxin /= valsamp;
- avmxout /= valsamp;
- }
- printf ("" LLD "n", (long long) (maxin / (long long) muli + .5));
- printf ("" LLD "n", (long long) (maxout / (long long) muli + .5));
- if (options & OPTION_DORELPERCENT)
- {
- printf ("" LLD "n", (long long) (maxpercent + .5));
- }
- printf ("" LLD "n", (long long) (avin / (long long) muli + .5));
- printf ("" LLD "n", (long long) (avout / (long long) muli + .5));
- if (options & OPTION_DORELPERCENT)
- {
- printf ("" LLD "n", (long long) (avpercent + .5));
- }
- printf ("" LLD "n", (long long) (latestin / (long long) muli + .5));
- printf ("" LLD "n", (long long) (latestout / (long long) muli + .5));
- if (options & OPTION_DORELPERCENT)
- {
- printf ("" LLD "n", (long long) (latestpercent + .5));
- }
- printf ("" LLD "n", (long long) (avmxin / (long long) muli + .5));
- printf ("" LLD "n", (long long) (avmxout / (long long) muli + .5));
- if (maxv < 0 || maxv < maxs)
- {
- maxv = maxs;
- }
- now = onow;
- if (maxv <= 0)
- maxv = 1;
- if (kMG)
- {
- char *string = kMG;
- kMGnumber = 0;
- while (strchr (string, ','))
- {
- string = strchr (string, ',') + 1;
- kMGnumber++;
- }
- }
- else
- {
- kMGnumber = 4;
- }
- /* mangle the 0.25*maxv value so, that we get a number with either */
- /* one or two digits != 0 and these digits should be at the */
- /* start of the number ... */
- /* the ceil compensates for rounding with small numbers */
- maxv_q = ceil ((double) maxv / (double) ytics); /* int */
- digits = 0;
- {
- double number = (double) maxv_q;
- number *= yticsf; /* we just want to scale the lables nothing else */
- /*
- while (number/(double) kilo >= (double)kilo && digits<kMGnumber*3) {
- */
- /* yes this should be kilo, but then the log and pow bits below
- should be base 'kilo' as well and not base 10 */
- while (number >= (double) 1000 && digits < (long long) kMGnumber * 3)
- {
- number /= (double) 1000;
- digits += 3;
- }
- sca_max_q = (double) ((int) (((double) 100. * (double) number) /
- (pow
- ((double) 10.,
- (double) (int) (log10 ((double) number))))
- +
- (double) 9.999) / (int) 10) / (double) 10 *
- (pow ((double) 10., (double) (int) (log10 ((double) number))));
- }
- if (kMG)
- {
- int count = (int) digits;
- short_si_out = kMGcopy; /* JML bugfix */
- strcpy (kMGcopy, kMG); /* JML bugfix */
- while (count >= 3)
- {
- count -= 3;
- short_si_out = strchr (short_si_out, ',') + 1;
- }
- if (strchr (short_si_out, ','))
- {
- *((char *) strchr (short_si_out, ',')) = ' ';
- }
- }
- else
- {
- short_si_out = short_si[min ((signed) (digits / 3), kMGnumber)];
- }
- if (maxv_q * yticsf >= 1)
- {
- /* digits = log10((double)maxv_q); */
- digits = log10 ((double) maxv_q * yticsf);
- }
- else
- {
- digits = 0;
- }
- /* sca_ten = maxv_q / pow(10.0,(double)digits); */
- /* sca_hun = maxv_q / pow(10.0,(double)digits-1); */
- sca_ten = (double) maxv_q *yticsf / pow (10.0, (double) digits);
- sca_hun = (double) maxv_q *yticsf / pow (10.0, (double) digits - 1);
- nex_rnd = (sca_hun) * pow (10.0, (double) digits - 1);
- nex_ten = (sca_ten + 1) * pow (10.0, (double) digits);
- nex_hun = (sca_hun + 1) * pow (10.0, (double) digits - 1);
- /* if (nex_ten <= (1.1 * maxv_q)) { */
- if (nex_ten <= (1.1 * maxv_q * yticsf))
- {
- nmax_q = nex_ten;
- /* } else if (maxv_q == nex_rnd) { */
- }
- else if ((maxv_q * yticsf) == nex_rnd)
- {
- nmax_q = nex_rnd;
- }
- else
- {
- nmax_q = nex_hun;
- }
- sca_max_q = nmax_q / (pow (10.0, (double) ((int) (digits / 3)) * 3));
- /* nmax=sca_max_q*ytics*(pow((double)kilo,(double)((int)(digits/3)))); */
- nmax =
- (sca_max_q / yticsf) * ytics *
- (pow ((double) kilo, (double) ((int) (digits / 3))));
- if (nmax < 1.)
- {
- nmax = 1.;
- }
- for (n = 0, x = 0; x < maxx; x++)
- {
- lhist[x].time = 0;
- graph_label[x] = NULL;
- /* this seesm to be necessary to work a round a bug in solaris
- where tm for complex TZ settings gets modified after the
- fact ... so we whisk the stuff away into our own memspace
- just in time */
- memcpy (tm, localtime (&history[n].time), sizeof (struct tm));
- switch (type)
- {
- default:
- case 1:
- if (tm->tm_min < 5)
- {
- lhist[x].time |= 1;
- if (tm->tm_hour == 0)
- lhist[x].time |= 2;
- }
- if ((tm->tm_min < 5) && (tm->tm_hour % 2 == 0))
- {
- if ((graph_label[x] = calloc (1, sizeof (char) * 4)) == NULL)
- {
- fprintf (stderr,
- "Rateup ERROR: Out of memory in graph labelingn");
- exit (0);
- }
- else
- {
- sprintf (graph_label[x], "%i", tm->tm_hour);
- }
- }
- break;
- case 2:
- if (tm->tm_min < 30 && tm->tm_hour == 0)
- {
- lhist[x].time |= 1;
- if (tm->tm_wday == 1)
- lhist[x].time |= 2;
- }
- /* fprintf(stderr,"x: %i, min:%i, hour:%i day: %in",
- x,tm->tm_min,tm->tm_hour,tm->tm_wday); */
- if ((tm->tm_min < 30) && (tm->tm_hour == 12))
- {
- if ((graph_label[x] = calloc (1, sizeof (char) * 5)) == NULL)
- {
- fprintf (stderr,
- "Rateup ERROR: Out of memory in graph labelingn");
- exit (0);
- }
- else
- {
- strftime (graph_label[x], 4, "%a", tm);
- }
- }
- break;
- case 3:
- if (tm->tm_hour < 2)
- {
- if (tm->tm_wday == 1)
- lhist[x].time |= 1;
- if (tm->tm_mday == 1)
- lhist[x].time |= 2;
- }
- /* label goes to thursday noon */
- if ((tm->tm_hour > 10) && (tm->tm_hour <= 12) && (tm->tm_wday == 4))
- {
- if ((graph_label[x] = calloc (1, sizeof (char) * 16)) == NULL)
- {
- fprintf (stderr,
- "Rateup ERROR: Out of memory in graph labelingn");
- exit (0);
- }
- else
- {
- char fmtbuf[10];
- sprintf (fmtbuf, "Week %%%c", weekformat);
- strftime (graph_label[x], 8, fmtbuf, tm);
- }
- }
- break;
- case 4:
- if (tm->tm_mday == 1)
- lhist[x].time |= 1;
- if (tm->tm_yday == 0)
- lhist[x].time |= 2;
- if (tm->tm_mday == 15)
- {
- if ((graph_label[x] = calloc (1, sizeof (char) * 5)) == NULL)
- {
- fprintf (stderr,
- "Rateup Error: Out of memory in graph labelingn");
- exit (0);
- }
- else
- {
- strftime (graph_label[x], 4, "%b", tm);
- }
- }
- break;
- }
- NEXT (step);
- /*scale with muli */
- inr *= muli;
- outr *= muli;
- inmax *= muli;
- outmax *= muli;
- y = ((double) inr / nmax) * maxy;
- if (y >= maxy)
- y = maxy;
- lhist[x].in = y;
- y = ((double) outr / nmax) * maxy;
- if (y >= maxy)
- y = maxy;
- lhist[x].out = y;
- y = ((double) inmax / nmax) * maxy;
- if (y >= maxy)
- y = maxy;
- lhist[x].inmax = y;
- y = ((double) outmax / nmax) * maxy;
- if (y >= maxy)
- y = maxy;
- lhist[x].outmax = y;
- if (options & OPTION_DORELPERCENT)
- {
- if (outr != (long long) 0)
- {
- percent = (double) inr / (double) outr;
- }
- else
- {
- percent = (double) 0.;
- }
- if (percent > (double) 1)
- percent = (double) 1.;
- percent *= maxy;
- lhist[x].percent = (long long) percent;
- }
- else
- {
- lhist[x].percent = (long long) 0;
- }
- now -= step;
- }
- origmaxvi = (origmaxvi * muli / nmax ) * maxy;
- origmaxvo = (origmaxvo * muli / nmax ) * maxy;
- /* Log and second-mean scaling added by Benjamin Despres, 2004-10-13 */
- if ((options & OPTION_LOGGRAPH) || (options & OPTION_MEANOVER))
- {
- lmx1 = lmx2 = mea1 = mea2 = temp = 0.0;
- for (x = 0; x < maxx; x++)
- {
- if (lhist[x].in < 1.0)
- lhist[x].in = 1.0;
- if (lhist[x].out < 1.0)
- lhist[x].out = 1.0;
- if (lhist[x].inmax < 1.0)
- lhist[x].inmax = 1.0;
- if (lhist[x].outmax < 1.0)
- lhist[x].outmax = 1.0;
- if (lhist[x].in > lmx1)
- lmx1 = lhist[x].in;
- if (lhist[x].out > lmx1)
- lmx1 = lhist[x].out;
- if (lhist[x].inmax > lmx1)
- lmx1 = lhist[x].inmax;
- if (lhist[x].outmax > lmx1)
- lmx1 = lhist[x].outmax;
- mea1 +=
- (lhist[x].in + lhist[x].out + lhist[x].inmax +
- lhist[x].outmax) / 4.0;
- }
- if (origmaxvi < 1.0)
- origmaxvi = 1.0;
- if (origmaxvo < 1.0)
- origmaxvo = 1.0;
- mea1 /= (double) maxx;
- if (options & OPTION_MEANOVER)
- {
- for (x = 0; x < maxx; x++)
- {
- y =
- (lhist[x].in + lhist[x].out + lhist[x].inmax +
- lhist[x].outmax) / 4.0;
- if (y > mea1)
- {
- mea2 += y;
- temp += 1.0;
- }
- }
- mea2 /= temp;
- for (x = 0; x < maxx; x++)
- {
- if (lhist[x].in > mea2)
- lhist[x].in = mea2;
- if (lhist[x].out > mea2)
- lhist[x].out = mea2;
- if (lhist[x].inmax > mea2)
- lhist[x].inmax = mea2;
- if (lhist[x].outmax > mea2)
- lhist[x].outmax = mea2;
- }
- }
- if (options & OPTION_LOGGRAPH)
- {
- for (x = 0; x < maxx; x++)
- {
- lhist[x].in = log (lhist[x].in);
- lhist[x].out = log (lhist[x].out);
- lhist[x].inmax = log (lhist[x].inmax);
- lhist[x].outmax = log (lhist[x].outmax);
- }
- origmaxvi = log (origmaxvi);
- origmaxvo = log (origmaxvo);
- }
- for (x = 0; x < maxx; x++)
- {
- if (lhist[x].in > lmx2)
- lmx2 = lhist[x].in;
- if (lhist[x].out > lmx2)
- lmx2 = lhist[x].out;
- if (lhist[x].inmax > lmx2)
- lmx2 = lhist[x].inmax;
- if (lhist[x].outmax > lmx2)
- lmx2 = lhist[x].outmax;
- }
- if (lmx2 > 0.0)
- lmx2 = (lmx1 / lmx2);
- for (x = 0; x < maxx; x++)
- {
- lhist[x].in *= lmx2;
- lhist[x].out *= lmx2;
- lhist[x].inmax *= lmx2;
- lhist[x].outmax *= lmx2;
- }
- origmaxvi *= lmx2;
- origmaxvo *= lmx2;
- if (options & OPTION_MEANOVER)
- sca_max_q *= ((float) mea2 / (float) maxy);
- } /* end of primary log and second-mean scaling code (more below) */
- /* the graph is made ten pixels higher to acomodate the x labels */
- graph = gdImageCreate (XSIZE, YSIZE);
- brush_out = gdImageCreate (1, 2);
- brush_outm = gdImageCreate (1, 2);
- brush_outp = gdImageCreate (1, 2);
- /* the first color allocated will be the background color. */
- i_blank = gdImageColorAllocate (graph, c_blank);
- i_light = gdImageColorAllocate (graph, c_light);
- i_dark = gdImageColorAllocate (graph, c_dark);
- if (options & OPTION_TRANSPARENT)
- {
- gdImageColorTransparent (graph, i_blank);
- }
- gdImageInterlace (graph, 1);
- /* do NOT delete the out variables. they are dummies, but the actual color
- allocation for the brush is essential */
- i_major = gdImageColorAllocate (graph, c_major);
- i_in = gdImageColorAllocate (graph, col_in[0], col_in[1], col_in[2]);
- i_out =
- gdImageColorAllocate (brush_out, col_out[0], col_out[1], col_out[2]);
- i_grid = gdImageColorAllocate (graph, c_grid);
- i_inm = gdImageColorAllocate (graph, col_inm[0], col_inm[1], col_inm[2]);
- i_outm =
- gdImageColorAllocate (brush_outm, col_outm[0], col_outm[1], col_outm[2]);
- i_outp =
- gdImageColorAllocate (brush_outp, col_outp[0], col_outp[1], col_outp[2]);
- i_outpg =
- gdImageColorAllocate (graph, col_outp[0], col_outp[1], col_outp[2]);
- /* draw the image border */
- if (!(options & OPTION_NOBORDER))
- {
- gdImageLine (graph, 0, 0, XSIZE - 1, 0, i_light);
- gdImageLine (graph, 1, 1, XSIZE - 2, 1, i_light);
- gdImageLine (graph, 0, 0, 0, YSIZE - 1, i_light);
- gdImageLine (graph, 1, 1, 1, YSIZE - 2, i_light);
- gdImageLine (graph, XSIZE - 1, 0, XSIZE - 1, YSIZE - 1, i_dark);
- gdImageLine (graph, 0, YSIZE - 1, XSIZE - 1, YSIZE - 1, i_dark);
- gdImageLine (graph, XSIZE - 2, 1, XSIZE - 2, YSIZE - 2, i_dark);
- gdImageLine (graph, 1, YSIZE - 2, XSIZE - 2, YSIZE - 2, i_dark);
- }
- /* draw the incoming traffic */
- if (!(options & OPTION_NO_I))
- {
- for (x = 0; x < maxx; x++)
- {
- /* peak is always above average, we therefore only draw the upper part */
- if (peak)
- gdImageLine (graph, xtr (x), ytr (lhist[x].in),
- xtr (x), ytr (lhist[x].inmax), i_inm);
- #ifdef INCOMING_UNFILLED
- gdImageLine (graph, xtr (x), ytr (lhist[x].in), xtr (x),
- ytr (lhist[x + 1].in), i_in);
- #else
- gdImageLine (graph, xtr (x), ytr (0), xtr (x), ytr (lhist[x].in),
- i_in);
- /* draw the line a second time offset slightly. makes the graph
- * look better if xscale is fractional */
- gdImageLine (graph, xtr (x + 0.5), ytr (0), xtr (x + 0.5),
- ytr (lhist[x].in), i_in);
- #endif
- }
- }
- /* draw the percentage */
- if (options & OPTION_DORELPERCENT)
- {
- gdImageSetBrush (graph, brush_outp);
- for (x = 0; x < maxx - 1; x++)
- gdImageLine (graph, xtr (x), ytr (lhist[x].percent),
- xtr (x + 1), ytr (lhist[x + 1].percent), gdBrushed);
- }
- /* draw the outgoing traffic */
- if (!(options & OPTION_NO_O))
- {
- gdImageSetBrush (graph, brush_outm);
- if (peak)
- for (x = 0; x < maxx - 1; x++)
- gdImageLine (graph, xtr (x), ytr (lhist[x].outmax),
- xtr (x + 1), ytr (lhist[x + 1].outmax), gdBrushed);
- gdImageSetBrush (graph, brush_out);
- for (x = 0; x < maxx - 1; x++)
- gdImageLine (graph, xtr (x), ytr (lhist[x].out),
- xtr (x + 1), ytr (lhist[x + 1].out), gdBrushed);
- }
- /* print the graph title */
- if (pngtitle != NULL)
- {
- gdImageString (graph, gdFontSmall, 81, 1,
- (unsigned char *) pngtitle, i_grid);
- }
- else
- {
- if (options & OPTION_PRINTROUTER)
- {
- gdImageString (graph, gdFontSmall, 81, 1,
- (unsigned char *) router, i_grid);
- }
- }
- /* print the date & time */
- if (options & OPTION_PNGDATE)
- {
- pngdate = (char *) calloc (1, 100);
- tmtz = localtime (&NOW);
- if (rtimezone == NULL)
- {
- strftime (pngdate, 18, "%b %d %Y %H:%M", tmtz);
- }
- else
- {
- strftime (pngdate, 19, "%b %d %Y %H:%M ", tmtz);
- if (((size_t) strlen (pngdate) + strlen (rtimezone)) < 100)
- {
- strcat (pngdate, rtimezone);
- }
- else
- {
- fprintf (stderr,
- "Rateup ERROR: date + timezone string too longn");
- exit (1);
- }
- }
- gdImageString (graph, gdFontSmall,
- (81 + maxx * xscale) - gdFontSmall->w * strlen (pngdate),
- 1, (unsigned char *) pngdate, i_grid);
- }
- /* draw the graph border */
- gdImageRectangle (graph, xtr (0), ytr (0), xtr (maxx), ytr (maxy), i_grid);
- /*create a dotted style for the grid lines */
- styleDotted[0] = i_grid;
- styleDotted[1] = gdTransparent;
- styleDotted[2] = gdTransparent;
- gdImageSetStyle (graph, styleDotted, 3);
- /* draw the horizontal grid */
- if ((longup == NULL) || (shortup == NULL))
- {
- if (!bits)
- {
- longup = "Bytes per Second";
- shortup = "Bytes/s";
- }
- else
- {
- longup = "Bits per Second";
- shortup = "Bits/s";
- }
- }
- if (maxy < gdFontSmall->w * 16)
- {
- gdImageStringUp (graph, gdFontSmall, 8,
- ytr ((maxy - gdFontSmall->w * strlen (shortup)) / 2),
- (unsigned char *) shortup, i_grid);
- }
- else
- {
- gdImageStringUp (graph, gdFontSmall, 8,
- ytr ((maxy - gdFontSmall->w * strlen (longup)) / 2),
- (unsigned char *) longup, i_grid);
- }
- /* secondary log and second-mean scale code block follows */
- if (options & OPTION_LOGGRAPH)
- {
- for (i = 0; i <= ytics; i++)
- {
- gdImageLine (graph, xtr (-2), ytr (i * maxy / ytics), xtr (1),
- ytr (i * maxy / ytics), i_grid);
- gdImageLine (graph, xtr (maxx + 2), ytr (i * maxy / ytics),
- xtr (maxx - 1), ytr (i * maxy / ytics), i_grid);
- gdImageLine (graph, xtr (0), ytr (i * maxy / ytics), xtr (maxx),
- ytr (i * maxy / ytics), gdStyled);
- temp = exp ((log ((float) maxy) / (float) ytics) * (float) i) - 1.0;
- temp *= ((float) sca_max_q * (float) ytics) / (float) maxy;
- sprintf (ylab, "%6.1f %s", temp, short_si_out);
- gdImageString (graph, gdFontSmall, 23,
- ytr (i * maxy / ytics + gdFontSmall->h / 2),
- (unsigned char *) ylab, i_grid);
- if (options & OPTION_DORELPERCENT)
- {
- sprintf (ylab, "% 6.1f%%", (float) 100 / ytics * i);
- gdImageString (graph, gdFontSmall, 77 + ((maxx) * xscale) + 1,
- ytr (i * maxy / ytics + gdFontSmall->h / 2),
- (unsigned char *) ylab, i_outpg);
- }
- }
- }
- else /* end of secondary log and second-mean scaling code */
- {
- for (i = 0; i <= ytics; i++)
- {
- gdImageLine (graph, xtr (-2), ytr (i * maxy / ytics),
- xtr (1), ytr (i * maxy / ytics), i_grid);
- gdImageLine (graph, xtr (maxx + 2), ytr (i * maxy / ytics),
- xtr (maxx - 1), ytr (i * maxy / ytics), i_grid);
- gdImageLine (graph, xtr (0), ytr (i * maxy / ytics),
- xtr (maxx), ytr (i * maxy / ytics), gdStyled);
- /*
- sprintf(ylab,"%6.1f %s",sca_max_q*i,short_si[digits/3]);
- */
- /* sprintf(ylab,"%6.1f %s",sca_max_q*i*yticsf,short_si_out); */
- sprintf (ylab, "%6.1f %s", sca_max_q * i, short_si_out);
- /* sprintf(ylab,"%6.1f %s",sca_max_q*i,short_si_out); */
- gdImageString (graph, gdFontSmall, 23,
- ytr (i * maxy / ytics + gdFontSmall->h / 2),
- (unsigned char *) ylab, i_grid);
- if (options & OPTION_DORELPERCENT)
- {
- /* sprintf(ylab,"% 6.1f%%",(float)25.*i); */
- sprintf (ylab, "% 6.1f%%", (float) 100 / ytics * i);
- gdImageString (graph, gdFontSmall, 77 + ((maxx) * xscale) + 1,
- ytr (i * maxy / ytics + gdFontSmall->h / 2),
- (unsigned char *) ylab, i_outpg);
- }
- }
- }
- /* draw vertical grid and horizontal labels */
- for (x = 0; x < maxx; x++)
- {
- if (lhist[x].time)
- {
- gdImageLine (graph, xtr (x), ytr (-2), xtr (x), ytr (1), i_grid);
- gdImageLine (graph, xtr (x), ytr (0), xtr (x), ytr (maxy),
- gdStyled);
- }
- if (graph_label[x] != NULL)
- {
- gdImageString (graph, gdFontSmall,
- (xtr (x) - (strlen (graph_label[x]) *
- gdFontSmall->w / 2)),
- ytr (-4), (unsigned char *) graph_label[x], i_grid);
- free (graph_label[x]);
- }
- if (lhist[x].time & 2)
- gdImageLine (graph, xtr (x), ytr (0), xtr (x), ytr (maxy), i_major);
- }
- ytrmax = ytr (origmaxvi);
- /* draw line at peak In value in i_major color */
- /* only draw the line if it's within the graph ... */
- if (ytr (maxy) < ytrmax)
- {
- styleDotted[0] = i_major;
- gdImageSetStyle (graph, styleDotted, 3);
- gdImageLine (graph, xtr (0), ytrmax, xtr (maxx), ytrmax, gdStyled);
- }
- /* draw line at peak Out value in i_major color */
- /* only draw the line if it's within the graph ... */
- ytrmax = ytr (origmaxvo);
- if (ytr (maxy) < ytrmax)
- {
- styleDotted[0] = i_major;
- gdImageSetStyle (graph, styleDotted, 3);
- gdImageLine (graph, xtr (0), ytrmax, xtr (maxx), ytrmax, gdStyled);
- }
- /* draw a red arrow a 0,0 */
- if (!(options & OPTION_NOARROW))
- {
- gdImageLine (graph, xtr (2), ytr (3), xtr (2), ytr (-3), i_major);
- gdImageLine (graph, xtr (1), ytr (3), xtr (1), ytr (-3), i_major);
- gdImageLine (graph, xtr (0), ytr (2), xtr (0), ytr (-2), i_major);
- gdImageLine (graph, xtr (-1), ytr (1), xtr (-1), ytr (-1), i_major);
- gdImageLine (graph, xtr (-2), ytr (1), xtr (-2), ytr (-1), i_major);
- gdImageLine (graph, xtr (-3), ytr (0), xtr (-3), ytr (0), i_major);
- }
- if (currdatetimepos > NO_TIMESTAMPSTR)
- {
- currdatetime = time (NULL);
- strftime (currdatetimestr, 250, currdatetimeformat,
- localtime (&currdatetime));
- switch (currdatetimepos)
- {
- case LL_CORNER:
- currdatetimepos_x = 3;
- currdatetimepos_y = YSIZE - gdFontSmall->h - 3;
- break;
- case RL_CORNER:
- currdatetimepos_x =
- XSIZE - strlen (currdatetimestr) * gdFontSmall->w - 3;
- currdatetimepos_y = YSIZE - gdFontSmall->h - 3;
- break;
- case LU_CORNER:
- currdatetimepos_x = 3;
- currdatetimepos_y = 1;
- break;
- case RU_CORNER:
- default:
- currdatetimepos_x =
- XSIZE - strlen (currdatetimestr) * gdFontSmall->w - 3;
- currdatetimepos_y = 1;
- };
- gdImageString (graph, gdFontSmall,
- currdatetimepos_x, currdatetimepos_y,
- currdatetimestr, i_grid);
- }
- if ((fo = fopen (file, "wb")) == NULL)
- {
- perror (program);
- fprintf (stderr, "Rateup Error: Can't open %s for writen", file);
- exit (1);
- }
- GFORM_GD (graph, fo);
- fclose (fo);
- gdImageDestroy (graph);
- gdImageDestroy (brush_out);
- gdImageDestroy (brush_outm);
- gdImageDestroy (brush_outp);
- free (lhist);
- free (graph_label);
- }
- static double
- diff (a, b)
- char *a, *b;
- {
- char res[MAXL], *a1, *b1, *r1;
- int c, x, m;
- if (*a == '-' && *b == '-')
- {
- b1 = b + 1;
- b = a + 1;
- a = b1;
- }
- while (!isdigit ((int) *a))
- a++;
- while (!isdigit ((int) *b))
- b++;
- a1 = &a[strlen (a) - 1];
- m = max (strlen (a), strlen (b));
- r1 = &res[m + 1];
- for (b1 = res; b1 <= r1; b1++)
- *b1 = ' ';
- b1 = &b[strlen (b) - 1];
- r1[1] = 0; /* Null terminate result */
- c = 0;
- for (x = 0; x < m; x++)
- {
- /* we want to avoid reading off the edge of the string */
- char save_a, save_b;
- save_a = (a1 >= a) ? *a1 : '0';
- save_b = (b1 >= b) ? *b1 : '0';
- *r1 = save_a - save_b - c + '0';
- if (*r1 < '0')
- {
- *r1 += 10;
- c = 1;
- }
- else if (*r1 > '9')
- { /* 0 - 10 */
- *r1 -= 10;
- c = 1;
- }
- else
- {
- c = 0;
- }
- a1--;
- b1--;
- r1--;
- }
- if (c)
- {
- r1 = &res[m + 1];
- for (x = 0; isdigit ((int) *r1) && x < m; x++, r1--)
- {
- *r1 = ('9' - *r1 + c) + '0';
- if (*r1 > '9')
- {
- *r1 -= 10;
- c = 1;
- }
- else
- {
- c = 0;
- }
- }
- return (-atof (res));
- }
- else
- return (atof (res));
- }
- static int
- readhist (file)
- char *file;
- {
- FILE *fi;
- int x, retcode = 0;
- char buf[256], tempform[50];
- struct HISTORY *hist;
- long long rd[5];
- time_t cur;
- long lasttime;
- sprintf (tempform, "%%ld %%%ds %%%dsn", MAXL - 1, MAXL - 1);
- if ((fi = fopen (file, "r")) != NULL)
- {
- if (fscanf (fi, tempform, &lasttime, &last.in[0], &last.out[0]) != 3)
- {
- fprintf (stderr, "Read Error: File %s lin 1n", file);
- retcode = 1;
- }
- last.time = lasttime;
- cur = last.time;
- x = histvalid = 0;
- hist = history;
- while (!feof (fi))
- {
- fgets (buf, 256, fi);
- if (sscanf (buf, "" LLD " " LLD " " LLD " " LLD " " LLD "",
- &rd[0], &rd[1], &rd[2], &rd[3], &rd[4]) < 5)
- {
- rd[3] = rd[1];
- rd[4] = rd[2];
- }
- /* we are long long now, so don't cut bit 8
- for (i=0;i<=4;i++){
- if (rd[i] & 0x80000000)
- rd[i] = 0;
- }
- */
- hist->time = rd[0];
- hist->in = rd[1];
- hist->out = rd[2];
- hist->inmax = rd[3];
- hist->outmax = rd[4];
- if (hist->inmax < hist->in)
- hist->inmax = hist->in;
- if (hist->outmax < hist->out)
- hist->outmax = hist->out;
- if (hist->time > cur)
- {
- fprintf (stderr,
- "Rateup ERROR: %s found %s's log file was corruptn or not in sorted order:ntime: %lu.",
- program, router, (unsigned long) hist->time);
- retcode = 2;
- break;
- }
- cur = hist->time;
- if (++x >= Mh)
- {
- struct HISTORY *lh;
- Mh += MAX_HISTORY;
- lh = realloc (history, (Mh + 1) * sizeof (struct HISTORY));
- if (lh == NULL)
- {
- fprintf (stderr,
- "Rateup WARNING: (pay attention to this)nWARNING: %s found %s's log file had too many entries, data discardedn",
- program, router);
- break;
- }
- hist = lh + (hist - history);
- history = lh;
- }
- hist++;
- }
- histvalid = x;
- fclose (fi);
- }
- else
- {
- retcode = 1;
- }
- return (retcode);
- }
- static void
- readfile ()
- {
- char buf[128];
- int err, x;
- time_t now;
- struct HISTORY *hist;
- sprintf (buf, "%s.log", router);
- if ((err = readhist (buf)) != 0)
- { /* Read of log file failed. Try backup */
- fprintf (stderr,
- "Rateup WARNING: %s could not read the primary log file for %sn",
- program, router);
- sprintf (buf, "%s.old", router);
- if ((err = readhist (buf)) != 0)
- { /* Backup failed too. New file? */
- fprintf (stderr,
- "Rateup WARNING: %s The backup log file for %s was invalid as welln",
- program, router);
- if (err == 2)
- exit (1);
- /* File does not exist - it must be created */
- now = NOW - DAY_SAMPLE;
- hist = history;
- histvalid = DAY_COUNT + WEEK_COUNT + MONTH_COUNT + YEAR_COUNT - 1;
- last.time = now;
- /* calculating a diff does not make sense */
- last.in[0] = 'x';
- now /= DAY_SAMPLE;
- now *= DAY_SAMPLE;
- for (x = 0; x < DAY_COUNT; x++, hist++)
- {
- hist->time = now;
- hist->in = hist->inmax = hist->out = hist->outmax = 0;
- now -= DAY_SAMPLE;
- }
- now /= WEEK_SAMPLE;
- now *= WEEK_SAMPLE;
- for (x = 0; x < WEEK_COUNT; x++, hist++)
- {
- hist->time = now;
- hist->in = hist->inmax = hist->out = hist->outmax = 0;
- now -= WEEK_SAMPLE;
- }
- now /= MONTH_SAMPLE;
- now *= MONTH_SAMPLE;
- for (x = 0; x < MONTH_COUNT; x++, hist++)
- {
- hist->time = now;
- hist->in = hist->inmax = hist->out = hist->outmax = 0;
- now -= MONTH_SAMPLE;
- }
- now /= YEAR_SAMPLE;
- now *= YEAR_SAMPLE;
- for (x = 0; x < YEAR_COUNT; x++, hist++)
- {
- hist->time = now;
- hist->in = hist->inmax = hist->out = hist->outmax = 0;
- now -= YEAR_SAMPLE;
- }
- }
- }
- }
- static void
- update (in, out, abs_max, absupdate)
- char *in, *out;
- long long abs_max;
- int absupdate;
- {
- FILE *fo;
- char buf[128], buf1[128], buf2[128];
- time_t now, nextnow, plannow;
- long long inrate, outrate;
- long long avc, inmax, outmax;
- double period, interval;
- int x, n, nout;
- struct HISTORY *lhist, *hist;
- double inr, outr;
- now = NOW;
- if (now < last.time)
- {
- fprintf (stderr,
- "Rateup ERROR: %s found that %s's log file time of %lu was greater than now (%lu)nERROR: Let's not do the time warp, again. Logfile unchanged.n",
- program, router, (unsigned long) last.time,
- (unsigned long) now);
- return;
- }
- sprintf (buf, "%s.tmp", router);
- sprintf (buf1, "%s.log", router);
- sprintf (buf2, "%s.old", router);
- if ((lhist = calloc (1, sizeof (struct HISTORY) * (MAX_HISTORY + 1))) ==
- NULL)
- {
- fprintf (stderr, "Rateup ERROR: Out of memory in updaten");
- exit (1);
- }
- hist = lhist;
- period = (now - last.time);
- if (period <= 0 || period > (60 * 60) || last.in[0] == 'x')
- { /* if last update is strange */
- if (options & OPTION_UNKNASZERO)
- {
- inrate = 0; /* sync unknown to zero */
- outrate = 0;
- }
- else
- {
- inrate = history[0].in; /* Sync by using last value */
- outrate = history[0].out;
- }
- }
- else
- {
- /* gauge and absolute */
- if (strcmp (in, "-1") == 0 || /* if current count missing */
- strcmp (last.in, "-1") == 0)
- { /* or previous count missing */
- if (options & OPTION_UNKNASZERO)
- { /* then use 0 or last value */
- inrate = 0;
- }
- else
- {
- inrate = history[0].in;
- }
- }
- else
- {
- if ((absupdate != 0) && (absupdate != 3) && (absupdate != 4))
- {
- inr = diff (in, "0");
- }
- else
- {
- inr = diff (in, last.in);
- if (inr < 0) /* wrapped 32-bit counter? */
- inr += (long long) 1 << 32;
- }
- if (absupdate == 2)
- {
- inrate = inr + .5;
- }
- else if (absupdate == 3)
- {
- inrate = inr * (3600.0 / (period * 1.0)) + .5;
- }
- else if (absupdate == 4)
- {
- inrate = inr * (60.0 / (period * 1.0)) + .5;
- }
- else
- {
- inrate = inr / period + .5;
- }
- }
- if (strcmp (out, "-1") == 0 || /* if current count missing */
- strcmp (last.out, "-1") == 0)
- { /* or previous count missing */
- if (options & OPTION_UNKNASZERO)
- { /* then use 0 or last value */
- outrate = 0;
- }
- else
- {
- outrate = history[0].out;
- }
- }
- else
- {
- if ((absupdate != 0) && (absupdate != 3) && (absupdate != 4))
- {
- outr = diff (out, "0");
- }
- else
- {
- outr = diff (out, last.out);
- if (outr < 0) /* wrapped 32-bit counter? */
- outr += (long long) 1 << 32;
- }
- if (absupdate == 2)
- {
- outrate = outr + .5;
- }
- else if (absupdate == 3)
- {
- outrate = outr * (3600.0 / (period * 1.0)) + .5;
- }
- else if (absupdate == 4)
- {
- outrate = outr * (60.0 / (period * 1.0)) + .5;
- }
- else
- {
- outrate = outr / period + .5;
- }
- }
- }
- if (inrate < 0 || (unsigned) inrate > abs_max)
- {
- if (options & OPTION_UNKNASZERO)
- {
- inrate = 0; /* sync unknown to zero */
- }
- else
- {
- inrate = history[0].in; /* Sync by using last value */
- }
- }
- if (outrate < 0 || (unsigned) outrate > abs_max)
- {
- if (options & OPTION_UNKNASZERO)
- {
- outrate = 0; /* sync unknown to zero */
- }
- else
- {
- outrate = history[0].out; /* Sync by using last value */
- }
- }
- if ((fo = fopen (buf, "w")) != NULL)
- {
- fprintf (fo, "%lu %s %sn", (unsigned long) now, in, out);
- last.time = now;
- /* what is this good for? */
- /* gauge und absolute */
- if ((absupdate != 0) && (absupdate != 3) && (absupdate != 4))
- {
- strcpy (last.in, "0");
- strcpy (last.out, "0");
- }
- else
- {
- strcpy (last.in, in);
- strcpy (last.out, out);
- }
- fprintf (fo, "%lu " LLD " " LLD " " LLD " " LLD "n",
- (unsigned long) now, inrate, outrate, inrate, outrate);
- nout = 1;
- hist->time = now;
- hist->in = inrate;
- hist->out = outrate;
- hist->inmax = inrate;
- hist->outmax = outrate;
- hist++;
- /* just in case we were dead for a long time, don't try to gather
- data from non existing log entries */
- now = plannow = history[0].time;
- plannow /= DAY_SAMPLE;
- plannow *= DAY_SAMPLE;
- n = 0;
- /* gobble up every shred of data we can get ... */
- if (plannow < now)
- {
- NEXT ((unsigned long) (now - plannow));
- fprintf (fo, "%lu " LLD " " LLD " " LLD " " LLD "n",
- (unsigned long) now, (long long) inr, (long long) outr,
- (long long) inmax, (long long) outmax);
- hist->time = now;
- hist->in = inr;
- hist->out = outr;
- hist->inmax = inmax;
- hist->outmax = outmax;
- nout++;
- hist++;
- now = plannow;
- }
- for (x = 1; x < DAY_COUNT; x++)
- {
- NEXT (DAY_SAMPLE);
- fprintf (fo, "%lu " LLD " " LLD " " LLD " " LLD "n",
- (unsigned long) now, (long long) inr, (long long) outr,
- (long long) inmax, (long long) outmax);
- hist->time = now;
- hist->in = inr;
- hist->out = outr;
- hist->inmax = inmax;
- hist->outmax = outmax;
- nout++;
- hist++;
- now -= DAY_SAMPLE;
- }
- plannow = now;
- plannow /= WEEK_SAMPLE;
- plannow *= WEEK_SAMPLE;
- if (plannow < now)
- {
- NEXT ((unsigned long) (now - plannow));
- fprintf (fo, "%lu " LLD " " LLD " " LLD " " LLD "n",
- (unsigned long) now, (long long) inr, (long long) outr,
- inmax, outmax);
- hist->time = now;
- hist->in = inr;
- hist->out = outr;
- hist->inmax = inmax;
- hist->outmax = outmax;
- nout++;
- hist++;
- now = plannow;
- }
- for (x = 0; x < WEEK_COUNT; x++)
- {
- NEXT (WEEK_SAMPLE);
- fprintf (fo, "%lu " LLD " " LLD " " LLD " " LLD "n",
- (unsigned long) now, (long long) inr, (long long) outr,
- inmax, outmax);
- hist->time = now;
- hist->in = inr;
- hist->out = outr;
- hist->inmax = inmax;
- hist->outmax = outmax;
- nout++;
- hist++;
- now -= WEEK_SAMPLE;
- }
- plannow = now;
- plannow /= MONTH_SAMPLE;
- plannow *= MONTH_SAMPLE;
- if (plannow < now)
- {
- NEXT ((unsigned long) (now - plannow));
- fprintf (fo, "%lu " LLD " " LLD " " LLD " " LLD "n",
- (unsigned long) now, (long long) inr, (long long) outr,
- inmax, outmax);
- hist->time = now;
- hist->in = inr;
- hist->out = outr;
- hist->inmax = inmax;
- hist->outmax = outmax;
- nout++;
- hist++;
- now = plannow;
- }
- for (x = 0; x < MONTH_COUNT; x++)
- {
- NEXT (MONTH_SAMPLE);
- fprintf (fo, "%lu " LLD " " LLD " " LLD " " LLD "n",
- (unsigned long) now, (long long) inr, (long long) outr,
- inmax, outmax);
- hist->time = now;
- hist->in = inr;
- hist->out = outr;
- hist->inmax = inmax;
- hist->outmax = outmax;
- nout++;
- hist++;
- now -= MONTH_SAMPLE;
- }
- plannow = now;
- plannow /= YEAR_SAMPLE;
- plannow *= YEAR_SAMPLE;
- if (plannow < now)
- {
- NEXT ((unsigned long) (now - plannow));
- fprintf (fo, "%lu " LLD " " LLD " " LLD " " LLD "n",
- (unsigned long) now, (long long) inr, (long long) outr,
- inmax, outmax);
- hist->time = now;
- hist->in = inr;
- hist->out = outr;
- hist->inmax = inmax;
- hist->outmax = outmax;
- nout++;
- hist++;
- now = plannow;
- }
- for (x = 0; x < YEAR_COUNT; x++)
- {
- NEXT (YEAR_SAMPLE);
- fprintf (fo, "%lu " LLD " " LLD " " LLD " " LLD "n",
- (unsigned long) now, (long long) inr, (long long) outr,
- inmax, outmax);
- hist->time = now;
- hist->in = inr;
- hist->out = outr;
- hist->inmax = inmax;
- hist->outmax = outmax;
- nout++;
- hist++;
- now -= YEAR_SAMPLE;
- }
- if (ferror (fo) || fclose (fo))
- {
- perror (program);
- fprintf (stderr, "Rateup ERROR: Can't write new log filen");
- exit (1);
- }
- /* another fix to get things working under NT */
- if (unlink (buf2))
- {
- fprintf (stderr,
- "Rateup WARNING: %s Can't remove %s updating log filen",
- program, buf2);
- }
- if (rename (buf1, buf2))
- {
- fprintf (stderr,
- "Rateup WARNING: %s Can't rename %s to %s updating log filen",
- program, buf1, buf2);
- }
- if (rename (buf, buf1))
- {
- fprintf (stderr,
- "Rateup WARNING: %s Can't rename %s to %s updating log filen",
- program, buf, buf1);
- }
- for (n = 0; n < nout && n < MAX_HISTORY; n++)
- {
- history[n] = lhist[n];
- }
- }
- else
- {
- perror (program);
- fprintf (stderr, "Rateup ERROR: Can't open %s for writen", buf);
- exit (1);
- }
- free (lhist);
- }
- static void
- init_colour (int *colmap, int c0, int c1, int c2)
- {
- *colmap++ = c0;
- *colmap++ = c1;
- *colmap = c2;
- }
- /* Constants for readparm option */
- #define LENGTH_OF_BUFF (2048)
- #define NUMBER_OF_PARM (100)
- char buff[LENGTH_OF_BUFF + 1];
- char *program;
- static int
- readparam (char const *file)
- {
- FILE *fp = NULL;
- int cbuf;
- /* Open the file */
- if ((fp = fopen (file, "r")) == NULL)
- {
- fprintf (stderr, "%s ERROR: Can't open parameters file: %sn", program,
- file);
- return (1);
- }
- /* Check we actually got something */
- if (!(cbuf = fread (buff, 1, LENGTH_OF_BUFF, fp)))
- {
- fprintf (stderr, "%s ERROR: Parameters file emptyn", program);
- return (1);
- }
- fclose (fp);
- buff[cbuf] = ' ';
- /* #define READPARAM_INFO */
- #ifdef READPARAM_INFO
- fprintf (stderr, "%s INFO: Read: %d bytes from File: '%s'n", program, cbuf,
- file);
- #endif
- return (0);
- }
- int
- main (argc, argv)
- int argc;
- char **argv;
- {
- int x, argi, used, initarg;
- program = argv[0];
- /* Is Argv[1] a path/file to passed parameters? */
- if ((argc > 1) && (strncasecmp (argv[1], "-F", 2) == 0))
- {
- char *b, *c, *l;
- if (readparam (argv[2]))
- {
- return (1);
- }
- /* Parse buffer into argv[] */
- argv = calloc (NUMBER_OF_PARM + 1, sizeof (char *));
- argc = 0;
- b = buff;
- l = b + strlen (b);
- while (b < l)
- {
- if (b[0] == '"')
- {
- b++;
- c = strstr (b, """);
- if (c != NULL)
- {
- *c = ' ';
- argv[argc] = b;
- argc++;
- b = c + 2;
- }
- else
- {
- fprintf (stderr,
- "Rateup ERROR: Parameter %d [%s] missing quoten",
- argc, b);
- break;
- }
- }
- else
- {
- c = strstr (b, " ");
- if (c != NULL)
- {
- *c = ' ';
- argv[argc] = b;
- argc++;
- b = c + 1;
- }
- else
- {
- argv[argc] = b;
- argc++;
- b = l;
- }
- }
- if (argc == NUMBER_OF_PARM)
- {
- break;
- }
- }
- /* Check we didn't fill argv[] */
- if (argc == NUMBER_OF_PARM)
- {
- fprintf (stderr, "Rateup ERROR: Too many parameters read: %dn",
- argc);
- return (1);
- }
- /* Check we didn't end early */
- if (b < l)
- {
- return (1);
- }
- /* Mark End of argv[] */
- argv[argc] = NULL;
- #ifdef READPARAM_DEBUG
- for (i = 0; i < argc; i++)
- {
- printf ("ParameterX %2d : '%s'n", i, argv[i] ? argv[i] : "<null>");
- }
- #endif
- }
- if (argc < 3)
- {
- fprintf (stderr, "%s for MRTG %sn"
- "Usage: %s -f <parameter file>n"
- " %s directory basename [sampletime] [t sampletime] "
- "[-(t)ransparent] [-(b)order]"
- "[u|a|g|h|m in out abs_max] "
- "[i/p file maxvi maxvo maxx maxy growright step bits]n",
- program, VERSION, program, program);
- return (1);
- }
- routerpath = argv[1];
- /* this is for NT compatibility, because it does not seem to like
- rename across directories */
- if (chdir (routerpath))
- {
- fprintf (stderr, "Rateup ERROR: Chdir to %s failed ...n", routerpath);
- return (1);
- }
- /* Initialiase the colour variables - should be overwritten */
- init_colour (&col_in[0], c_in);
- init_colour (&col_out[0], c_out);
- init_colour (&col_inm[0], c_inm);
- init_colour (&col_outm[0], c_outm);
- init_colour (&col_outp[0], c_outp);
- if ((history = calloc (1, sizeof (struct HISTORY) * (MAX_HISTORY + 1))) ==
- NULL)
- {
- fprintf (stderr, "Rateup ERROR: Out of memory in mainn");
- exit (1);
- }
- #if defined(__WATCOMC__) || defined(NETWARE)
- memset (history, 0, sizeof (struct HISTORY) * (MAX_HISTORY + 1));
- #endif
- Mh = MAX_HISTORY;
- router = argv[2];
- /* from mrtg-2.x with x>5 rateup calling syntax changed to
- to support time properly ... this is for backward compat
- we check if now is remotely reasonable ...
- */
- if (argc > 3)
- {
- NOW = atol (argv[3]);
- if (NOW > 10 * 365 * 24 * 60 * 60)
- {
- initarg = 4;
- }
- else
- {
- initarg = 3;
- time (&NOW);
- }
- }
- else
- {
- initarg = 3;
- time (&NOW);
- }
- readfile ();
- used = 1;
- for (argi = initarg; argi < argc; argi += used)
- {
- switch (argv[argi][0])
- {
- case '-': /* -options */
- switch (argv[argi][1])
- {
- case 'a': /* Turn off the direction arrow */
- options |= OPTION_NOARROW;
- used = 1;
- break;
- case 'A': /* Turn on the direction arrow */
- options &= ~OPTION_NOARROW;
- used = 1;
- break;
- case 'b': /* Turn off the shaded border */
- options |= OPTION_NOBORDER;
- used = 1;
- break;
- case 'B': /* Turn on the shaded border */
- options &= ~OPTION_NOBORDER;
- used = 1;
- break;
- case 'd': /* Print date in image */
- options |= OPTION_PNGDATE;
- used = 1;
- break;
- case 'i': /* Do not graph the I variable */
- options |= OPTION_NO_I;
- used = 1;
- break;
- case 'I': /* Graph the I variable */
- options &= ~OPTION_NO_I;
- used = 1;
- break;
- case 'o': /* Do not graph the O variable */
- options |= OPTION_NO_O;
- used = 1;
- break;
- case 'O': /* Graph the O variable */
- options &= ~OPTION_NO_O;
- used = 1;
- break;
- case 'l': /* logarithmic scaling */
- options |= OPTION_LOGGRAPH;
- options &= ~OPTION_MEANOVER;
- used = 1;
- break;
- case 'm': /* second-mean scaling */
- options |= OPTION_MEANOVER;
- options &= ~OPTION_LOGGRAPH;
- used = 1;
- break;
- case 'p': /* print router name in image */
- options |= OPTION_PRINTROUTER;
- used = 1;
- break;
- case 't': /* Transparent Image */
- options |= OPTION_TRANSPARENT;
- used = 1;
- break;
- case 'T': /* non-Transparent Image */
- options &= ~OPTION_TRANSPARENT;
- used = 1;
- break;
- case 'z': /* unknown as zero */
- options |= OPTION_UNKNASZERO;
- used = 1;
- break;
- case 'Z': /* repeat last */
- options &= ~OPTION_UNKNASZERO;
- used = 1;
- break;
- case '0': /* assume zeroes */
- options |= OPTION_WITHZEROES;
- used = 1;
- break;
- default:
- fprintf (stderr, "Rateup ERROR: Unknown option: %s, sorry!n",
- argv[argi]);
- return (1);
- }
- break;
- case 'i': /* Create PPM Image record */
- image (argv[argi + 1], /* Image */
- strtoll (argv[argi + 2], NULL, 10), /* Max Value In */
- strtoll (argv[argi + 3], NULL, 10), /* Max Value Out */
- atol (argv[argi + 4]), /* xsize maxx */
- atol (argv[argi + 5]), /* ysize maxy */
- atof (argv[argi + 6]), /* xscale */
- atof (argv[argi + 7]), /* yscale */
- atol (argv[argi + 8]), /* growright */
- atol (argv[argi + 9]), /* step */
- atol (argv[argi + 10]), /* bits */
- atol (argv[argi + 11]), /* ytics */
- atof (argv[argi + 12]), /* yticsfactor */
- 0, argv[argi + 13], atol (argv[argi + 14]));
- used = 15;
- break;
- case 'p': /* Create PPM Image record with Peak values */
- image (argv[argi + 1], strtoll (argv[argi + 2], NULL, 10), /* Max Value In */
- strtoll (argv[argi + 3], NULL, 10), /* Max Value Out */
- atol (argv[argi + 4]), /* xsize maxx */
- atol (argv[argi + 5]), /* ysize maxy */
- atof (argv[argi + 6]), /* xscale */
- atof (argv[argi + 7]), /* yscale */
- atol (argv[argi + 8]), /* growright */
- atol (argv[argi + 9]), /* step */
- atol (argv[argi + 10]), /* bits */
- atol (argv[argi + 11]), /* ytics */
- atof (argv[argi + 12]), /* yticsfactor */
- 1, argv[argi + 13], atol (argv[argi + 14]));
- used = 15;
- break;
- case 'r': /* Create random records, then update */
- for (x = 0; x < histvalid; x++)
- {
- history[x].in = rand () % atoi (argv[argi + 1]);
- history[x].out = rand () % atoi (argv[argi + 2]);
- }
- case 'u': /* Update file */
- if (argv[argi][1] == 'p')
- {
- options |= OPTION_DORELPERCENT;
- }
- update (argv[argi + 1], argv[argi + 2],
- strtoll (argv[argi + 3], NULL, 10), 0);
- used = 4;
- break;
- case 'a': /* Absolute Update file */
- if (argv[argi][1] == 'p')
- {
- options |= OPTION_DORELPERCENT;
- }
- update (argv[argi + 1], argv[argi + 2],
- strtoll (argv[argi + 3], NULL, 10), 1);
- used = 4;
- break;
- case 'g': /* Gauge Update file */
- if (argv[argi][1] == 'p')
- {
- options |= OPTION_DORELPERCENT;
- }
- update (argv[argi + 1], argv[argi + 2],
- strtoll (argv[argi + 3], NULL, 10), 2);
- used = 4;
- break;
- case 'h':
- if (argv[argi][1] == 'p')
- {
- options |= OPTION_DORELPERCENT;
- }
- update (argv[argi + 1], argv[argi + 2],
- strtoll (argv[argi + 3], NULL, 10), 3);
- used = 4;
- break;
- case 'm':
- if (argv[argi][1] == 'p')
- {
- options |= OPTION_DORELPERCENT;
- }
- update (argv[argi + 1], argv[argi + 2],
- strtoll (argv[argi + 3], NULL, 10), 4);
- used = 4;
- break;
- case 'W': /* Week format */
- weekformat = argv[argi + 1][0];
- used = 2;
- break;
- case 'c': /* Colour Map */
- sscanf (argv[argi + 1], "#%2x%2x%2x", &col_in[0], &col_in[1],
- &col_in[2]);
- sscanf (argv[argi + 2], "#%2x%2x%2x", &col_out[0], &col_out[1],
- &col_out[2]);
- sscanf (argv[argi + 3], "#%2x%2x%2x", &col_inm[0], &col_inm[1],
- &col_inm[2]);
- sscanf (argv[argi + 4], "#%2x%2x%2x", &col_outm[0], &col_outm[1],
- &col_outm[2]);
- used = 5;
- break;
- case 'C': /* Extented Colour Map */
- sscanf (argv[argi + 1], "#%2x%2x%2x", &col_in[0], &col_in[1],
- &col_in[2]);
- sscanf (argv[argi + 2], "#%2x%2x%2x", &col_out[0], &col_out[1],
- &col_out[2]);
- sscanf (argv[argi + 3], "#%2x%2x%2x", &col_inm[0], &col_inm[1],
- &col_inm[2]);
- sscanf (argv[argi + 4], "#%2x%2x%2x", &col_outm[0], &col_outm[1],
- &col_outm[2]);
- sscanf (argv[argi + 5], "#%2x%2x%2x", &col_outp[0], &col_outp[1],
- &col_outp[2]);
- used = 6;
- break;
- case 't':
- NOW = atol (argv[argi + 1]);
- used = 2;
- break;
- case 'k':
- kilo = atol (argv[argi + 1]);
- used = 2;
- break;
- case 'K':
- kMG = calloc (strlen (argv[argi + 1]) + 1, sizeof (char));
- strcpy (kMG, argv[argi + 1]);
- kMGcopy = calloc (strlen (argv[argi + 1]) + 1, sizeof (char));
- used = 2;
- break;
- case 'Z': /* Timezone name */
- rtimezone = argv[argi + 1];
- used = 2;
- break;
- case 'l': /* YLegend - rewritten by Oliver Haidi, re-rewritten by Jon Barber */
- {
- int i, j, k, loop = 1;
- int start = 1, got_esc = 0, append_ok;
- char *qstr;
- longup = (char *) calloc (1, 100);
- *longup = 0;
- /* this rather twisty argument scanning is necesary
- because NT command.coms rather dumb argument
- passing .... or because we don't know
- better. Under Unix we just would say. if
- ((sscanf(argv[argi+1],"[%[^]]]", longup); */
- /* at start, check 1st char must be [ */
- if (argv[argi + 1][0] != '[')
- {
- fprintf (stderr,
- "Rateup ERROR: YLegend: Option must be passed with '[' at start and ']' at end (these will not be printed).n");
- return (1);
- }
- for (i = 1; (i < argc) && loop; i++)
- { /* check all args until unescaped ']' */
- qstr = argv[argi + i];
- for (j = start; ((size_t) j < strlen (qstr)) && loop; j++)
- {
- start = 0; /* 1st char in 1st arg already checked */
- append_ok = 1; /* OK to append unless we find otherwise */
- if (qstr[j] == '\')
- {
- if (++got_esc == 1)
- {
- append_ok = 0; /* don't append 1st '/' */
- }
- else
- {
- got_esc = 0; /* 2nd '/' in a row, i.e. '//' */
- }
- }
- if (qstr[j] == ']')
- { /* is this the end? */
- if (got_esc == 1)
- {
- if (strlen (qstr + j) >= 2)
- {
- append_ok = 1;
- got_esc = 0;
- }
- else
- {
- fprintf (stderr,
- "1: rateup ERROR: YLegend: use "\]" for "]" or "\\" for "\".n");
- return (1);
- }
- }
- else
- {
- if (strlen (qstr + j) >= 2)
- {
- fprintf (stderr,
- "2: rateup ERROR: YLegend: use "\]" for "]" or "\\" for "\".n");
- return (1);
- }
- loop = 0;
- append_ok = 0;
- }
- }
- if (append_ok == 1)
- {
- k = strlen (longup);
- if ((size_t) (k + 1) > 99)
- {
- fprintf (stderr,
- "3: rateup ERROR: YLegend too longn");
- return (1);
- }
- longup[k] = qstr[j];
- longup[k + 1] = 0;
- }
- } /* for (j=start...) */
- /* append space */
- k = strlen (longup);
- if ((size_t) (k + 1) > 99)
- {
- fprintf (stderr, "4: rateup ERROR: YLegend too longn");
- return (1);
- }
- longup[k] = ' ';
- longup[k + 1] = 0;
- } /* for (i =1 ... */
- used = i;
- }
- /* remove trailing space */
- longup[max (0, (signed) strlen (longup) - 1)] = 0;
- shortup = longup;
- /* fprintf(stderr, "YLegend = "%s"n", longup); */
- break;
- case 'T': /* pngTitle - based on YLegend */
- {
- int i, j, k, loop = 1;
- int start = 1, got_esc = 0, append_ok;
- char *qstr;
- pngtitle = (char *) calloc (1, 100);
- *pngtitle = 0;
- /* this rather twisty argument scanning is necesary
- because NT command.coms rather dumb argument
- passing .... or because we don't know
- better. Under Unix we just would say. if
- ((sscanf(argv[argi+1],"[%[^]]]", pngtitle); */
- /* at start, check 1st char must be [ */
- if (argv[argi + 1][0] != '[')
- {
- fprintf (stderr,
- "Rateup ERROR: YLegend: Option must be passed with '[' at start and ']' at end (these will not be printed).n");
- return (1);
- }
- for (i = 1; (i < argc) && loop; i++)
- { /* check all args until unescaped ']' */
- qstr = argv[argi + i];
- for (j = start; ((size_t) j < strlen (qstr)) && loop; j++)
- {
- start = 0; /* 1st char in 1st arg already checked */
- append_ok = 1; /* OK to append unless we find otherwise */
- if (qstr[j] == '\')
- {
- if (++got_esc == 1)
- {
- append_ok = 0; /* don't append 1st '/' */
- }
- else
- {
- got_esc = 0; /* 2nd '/' in a row, i.e. '//' */
- }
- }
- if (qstr[j] == ']')
- { /* is this the end? */
- if (got_esc == 1)
- {
- if (strlen (qstr + j) >= 2)
- {
- append_ok = 1;
- got_esc = 0;
- }
- else
- {
- fprintf (stderr,
- "1: rateup ERROR: YLegend: use "\]" for "]" or "\\" for "\".n");
- return (1);
- }
- }
- else
- {
- if (strlen (qstr + j) >= 2)
- {
- fprintf (stderr,
- "2: rateup ERROR: YLegend: use "\]" for "]" or "\\" for "\".n");
- return (1);
- }
- loop = 0;
- append_ok = 0;
- }
- }
- if (append_ok == 1)
- {
- k = strlen (pngtitle);
- if ((size_t) (k + 1) > 99)
- {
- fprintf (stderr,
- "3: rateup ERROR: YLegend too longn");
- return (1);
- }
- pngtitle[k] = qstr[j];
- pngtitle[k + 1] = 0;
- }
- } /* for (j=start...) */
- /* append space */
- k = strlen (pngtitle);
- if ((size_t) (k + 1) > 99)
- {
- fprintf (stderr, "4: rateup ERROR: YLegend too longn");
- return (1);
- }
- pngtitle[k] = ' ';
- pngtitle[k + 1] = 0;
- } /* for (i =1 ... */
- used = i;
- }
- /* remove trailing space */
- pngtitle[max (0, (signed) strlen (pngtitle) - 1)] = 0;
- /* fprintf(stderr, "YLegend = "%s"n", pngtitle); */
- break;
- default:
- fprintf (stderr, "Rateup ERROR: Can't cope with %s, sorry!n",
- argv[argi]);
- return (1);
- }
- }
- return (0);
- }