Blame src/rateup.c

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