]> git.ipfire.org Git - thirdparty/sarg.git/blame - grepday.c
Use a boolean instead of a string compare
[thirdparty/sarg.git] / grepday.c
CommitLineData
25697a35 1/*
94ff9470 2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
1164c474 3 * 1998, 2010
25697a35
GS
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
1164c474
FM
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
25697a35
GS
9 * ---------------------------------------------------------------------
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
24 *
25 */
26
27#include "include/conf.h"
5f3cfd1d 28#include "include/defs.h"
25697a35 29
a1de61fe 30#if defined(HAVE_GD)
17c89803 31
a1de61fe 32#if defined(HAVE_ICONV_H) && defined(gdFTEX_Unicode)
25697a35 33#include <iconv.h>
e43854ef
FM
34#define USE_ICONV 1
35#endif
25697a35 36
e43854ef 37struct GraphDataStruct
25697a35 38{
e43854ef
FM
39 int lavender;
40 int darkblue;
41 int dimgray;
42 int goldenrod;
43 int goldenrod2;
44 int gray;
45 int silver;
46 int black;
1f482a8d 47 //! The color of the top side of a graph bar.
e43854ef 48 int color1;
1f482a8d 49 //! The color of the right side of a graph bar.
e43854ef 50 int color2;
1f482a8d 51 //! The color of the front side of a graph bar.
e43854ef 52 int color3;
1f482a8d 53 //! The libgd image we are drawing on.
e43854ef 54 gdImage *im;
1f482a8d 55 //! An allocated buffer to convert the string into UTF-8.
e43854ef 56 char *string;
1f482a8d 57 //! The number of bytes allocated for the string buffer.
e43854ef 58 size_t string_size;
1f482a8d
FM
59 //! The bottom border of the graph.
60 int BottomGraph;
61 //! The top border of the graph.
62 int TopGraph;
63 //! The height at which the bottom depth border of the graph extends.
64 int BottomDepth;
65 //! The distance between two ticks on the horizontal axis.
66 double XScale;
67 //! The distance between two ticks on the vertical axis.
68 double YScale;
e43854ef
FM
69};
70
71enum TextRefPos
72{
73 TRP_TopLeft,
74 TRP_TopCenter,
75 TRP_TopRight,
76 TRP_BottomLeft,
77 TRP_BottomCenter,
78 TRP_BottomRight,
79 TRP_CenterLeft,
80 TRP_Center,
81 TRP_CenterRight,
82};
83
1f482a8d
FM
84#ifdef USE_ICONV
85//! The iconv object to convert the text from the locale character set to UTF-8.
86iconv_t localtoutf=(iconv_t)-1;
87#endif
88
89static void Sarg_gdImageStringFT (struct GraphDataStruct *gdata, int fg, char *fontlist,
90 double ptsize, double angle, int x, int y, const char *string,enum TextRefPos RefPos)
e43854ef 91{
1f482a8d
FM
92 char *sstring;
93 char *retval;
e43854ef
FM
94 int brect[8];
95 int minx,miny,maxx,maxy;
96 int i;
97
98#ifdef USE_ICONV
1f482a8d
FM
99 if (localtoutf!=(iconv_t)-1) {
100 const char *str;
e43854ef
FM
101 char *sstr;
102 size_t slen, sslen;
103
104 slen = strlen(string) + 1; // We must include string termination character
1f482a8d 105 sslen = slen * 3; // We assume that the UTF8 string will not be bigger than 3 times the original size.
e43854ef
FM
106 if (sslen>gdata->string_size) {
107 sstring = (char *)realloc(gdata->string,sslen);
108 if (!sstring) {
109 debuga(_("realloc error (%zu bytes required)\n"),sslen);
110 exit(EXIT_FAILURE);
111 }
1f482a8d 112 gdata->string=(char *)sstring;
e43854ef
FM
113 gdata->string_size=sslen;
114 } else {
115 sstring=gdata->string;
116 sslen=gdata->string_size;
117 }
25697a35 118
e43854ef
FM
119 str = string;
120 sstr = sstring;
1f482a8d 121 if (iconv (localtoutf, (ICONV_CONST char **)&str, &slen, &sstr, &sslen)==-1) {
9f70c14e 122 debuga(_("(grepday) iconv failed to convert string \"%s\" from %s to UTF-8 - %s\n"),string,CharSet,strerror(errno));
1f482a8d 123 sstring=(char *)string; //show something sensible on the graph
e43854ef
FM
124 }
125 } else {
1f482a8d 126 sstring=(char *)string; //show something sensible on the graph
e43854ef
FM
127 }
128#else
1f482a8d 129 sstring=(char *)string;
e43854ef
FM
130#endif
131
132 if (RefPos!=TRP_BottomLeft) {
133 retval = gdImageStringFTEx (NULL, brect, fg, fontlist, ptsize, angle, 0, 0, sstring, gdFTEX_Unicode);
134 if (retval) {
135 debuga(_("libgd failed to calculate the bounding box of the text \"%s\": %s\n"),sstring,retval);
136 exit(EXIT_FAILURE);
137 }
138 /*
139 From libgd documentation, brect contains this without taking into account the angle:
140 0 lower left corner, X position
141 1 lower left corner, Y position
142 2 lower right corner, X position
143 3 lower right corner, Y position
144 4 upper right corner, X position
145 5 upper right corner, Y position
146 6 upper left corner, X position
147 7 upper left corner, Y position
148 */
149 minx=maxx=brect[0];
150 miny=maxy=brect[1];
151 for (i=2 ; i<7 ; i+=2) {
152 if (minx>brect[i]) minx=brect[i];
153 if (maxx<brect[i]) maxx=brect[i];
154 if (miny>brect[i+1]) miny=brect[i+1];
155 if (maxy<brect[i+1]) maxy=brect[i+1];
07709548 156 }
07709548 157 }
25697a35 158
e43854ef
FM
159 switch (RefPos)
160 {
161 case TRP_TopLeft:
162 y-=miny;
163 break;
164
165 case TRP_TopCenter:
166 x-=(maxx-minx)/2;
167 y-=miny;
168 break;
169
170 case TRP_TopRight:
171 x-=maxx;
172 y-=miny;
173 break;
174
175 case TRP_BottomLeft:
176 break;
177
178 case TRP_BottomCenter:
179 x-=(maxx-minx)/2;
180 break;
181
182 case TRP_BottomRight:
183 x-=maxx;
184 break;
185
186 case TRP_Center:
187 x-=(maxx-minx)/2;
188 y+=(maxy-miny)/2;
189 break;
190
191 case TRP_CenterLeft:
192 y+=(maxy-miny)/2;
193 break;
194
195 case TRP_CenterRight:
196 x-=maxx;
197 y+=(maxy-miny)/2;
198 break;
199 }
200 retval = gdImageStringFTEx (gdata->im, brect, fg, fontlist, ptsize, angle, x, y, sstring, gdFTEX_Unicode);
201 if (retval) {
202 debuga(_("libgd failed to render the text \"%s\": %s\n"),sstring,retval);
203 exit(EXIT_FAILURE);
204 }
25697a35 205}
25697a35 206
e43854ef 207static void bar(struct GraphDataStruct *gdata,int x1,long long int n)
1dd9dcec 208{
25697a35 209 gdPoint points[4];
25697a35 210 int val=0, x;
32e71fa4 211 long long int num;
1f482a8d 212 int width2;
25697a35 213
32e71fa4
FM
214 static const long long int limits[400]={0,500,1000,2000,3000,4000,
215 5000,6000,7000,8000,9000,10000,
216 20000,30000,40000,50000,70000,90000,
217 110000,130000,150000,170000,190000,210000,
218 230000,250000,280000,310000,340000,370000,
219 400000,430000,450000,460000,490000,500000,
220 550000,600000,650000,700000,750000,800000,
221 850000,900000,950000,1000000,1100000,1200000,
222 1300000,1400000,1500000,1600000,1700000,1800000,
223 1900000,2000000,2100000,2200000,2300000,2400000,
224 2500000,2600000,2700000,2800000,2900000,3000000,
225 3100000,3200000,3300000,3400000,3500000,3600000,
226 3700000,3800000,3900000,4000000,4100000,4200000,
227 4300000,4400000,4500000,4600000,4700000,4800000,
228 4900000,5000000,5100000,5200000,5300000,5400000,
229 5500000,5600000,5700000,5800000,5900000,6000000,
230 6100000,6200000,6300000,6400000,6500000,6600000,
231 6700000,6800000,6900000,7000000,7100000,7200000,
232 7300000,7400000,7500000,7600000,7700000,7800000,
233 7900000,8000000,8100000,8200000,8300000,8400000,
234 8500000,8600000,8700000,8800000,8900000,9000000,
235 9100000,9200000,9300000,9400000,9500000,9600000,
236 9700000,9800000,9900000,10000000,10500000,11000000,
237 11500000,12000000,12500000,13000000,13500000,14000000,
238 14500000,15000000,15500000,16000000,16500000,17000000,
239 17500000,18000000,18500000,19000000,19500000,20000000,
240 21000000,22000000,23000000,24000000,25000000,26000000,
241 27000000,28000000,29000000,30000000,31000000,32000000,
242 33000000,34000000,35000000,36000000,37000000,38000000,
243 39000000,40000000,41000000,42000000,43000000,44000000,
244 45000000,46000000,47000000,48000000,49000000,50000000,
245 51000000,52000000,53000000,54000000,55000000,56000000,
246 57000000,58000000,59000000,60000000,61000000,62000000,
247 63000000,64000000,65000000,66000000,67000000,68000000,
248 69000000,70000000,71000000,72000000,73000000,74000000,
249 75000000,76000000,77000000,78000000,79000000,80000000,
250 81000000,82000000,83000000,84000000,85000000,86000000,
251 87000000,88000000,89000000,90000000,91000000,92000000,
252 93000000,94000000,95000000,96000000,97000000,98000000,
253 99000000,100000000,110000000,120000000,130000000,140000000,
254 150000000,160000000,170000000,180000000,190000000,200000000,
255 210000000,220000000,230000000,240000000,250000000,260000000,
256 270000000,280000000,290000000,300000000,310000000,320000000,
257 330000000,340000000,350000000,360000000,370000000,380000000,
258 390000000,400000000,410000000,420000000,430000000,440000000,
259 450000000,460000000,470000000,480000000,490000000,500000000,
260 510000000,520000000,530000000,540000000,550000000,560000000,
261 570000000,580000000,590000000,600000000,610000000,620000000,
262 630000000,640000000,650000000,660000000,670000000,680000000,
263 690000000,700000000,710000000,720000000,730000000,740000000,
264 750000000,760000000,770000000,780000000,790000000,800000000,
265 810000000,820000000,830000000,840000000,850000000,860000000,
266 870000000,880000000,890000000,900000000,910000000,920000000,
267 930000000,940000000,950000000,960000000,970000000,980000000,
268 990000000LL,1000000000LL,1100000000LL,1200000000LL,1300000000LL,1400000000LL,
269 1500000000LL,1600000000LL,1700000000LL,1800000000LL,1900000000LL,2000000000LL,
270 2100000000LL,2200000000LL,2300000000LL,2400000000LL,2500000000LL,2600000000LL,
271 2700000000LL,2800000000LL,2900000000LL,3000000000LL,3100000000LL,3200000000LL,
272 3300000000LL,3400000000LL,3500000000LL,3600000000LL,3700000000LL,3800000000LL,
273 3900000000LL,4000000000LL,4100000000LL,4200000000LL,4300000000LL,4400000000LL,
274 4500000000LL,4600000000LL,4700000000LL,4800000000LL,4900000000LL,5000000000LL};
25697a35 275
25697a35 276 num = n;
32e71fa4 277 val = 55;
1f482a8d 278 val=gdata->BottomGraph+5-(int)((double)37*gdata->YScale+0.5);
25697a35 279 for(x=0; x<=366; x++) {
32e71fa4 280 if(limits[x] >= num) {
25697a35 281 val = 425 - x;
1f482a8d 282 val=gdata->BottomGraph+5-(int)((double)x*gdata->YScale/10.+0.5);
25697a35
GS
283 break;
284 }
285 }
25697a35 286
1f482a8d
FM
287 width2=(int)(gdata->XScale/4.);
288 gdImageFilledRectangle(gdata->im, x1-width2, val, x1+width2, gdata->BottomDepth, gdata->color3);
25697a35 289
1f482a8d 290 points[0].x = x1-width2+5;
25697a35 291 points[0].y = val-5;
1f482a8d 292 points[1].x = x1-width2;
25697a35 293 points[1].y = val;
1f482a8d 294 points[2].x = x1+width2;
25697a35 295 points[2].y = val;
1f482a8d 296 points[3].x = x1+width2+5;
25697a35 297 points[3].y = val-5;
e43854ef 298 gdImageFilledPolygon(gdata->im, points, 4, gdata->color1);
25697a35 299
1f482a8d
FM
300 gdImageLine(gdata->im, x1+2, val-2, x1+2, val-10, gdata->dimgray);
301 gdImageFilledRectangle(gdata->im, x1-8, val-20, x1+12, val-10, gdata->goldenrod);
302 gdImageRectangle(gdata->im, x1-8, val-20, x1+12, val-10, gdata->goldenrod2);
25697a35 303
1f482a8d 304 Sarg_gdImageStringFT(gdata,gdata->black,GraphFont,6,0.0,x1+2,val-12,fixnum(num,0),TRP_BottomCenter);
1dd9dcec 305
1f482a8d 306 points[0].x = x1+width2+5;
25697a35 307 points[0].y = val-5;
1f482a8d 308 points[1].x = x1+width2;
25697a35 309 points[1].y = val;
1f482a8d
FM
310 points[2].x = x1+width2;
311 points[2].y = gdata->BottomDepth;
312 points[3].x = x1+width2+5;
313 points[3].y = gdata->BottomGraph;
e43854ef 314 gdImageFilledPolygon(gdata->im, points, 4, gdata->color2);
25697a35 315
25697a35
GS
316 return;
317}
318
1f482a8d 319static void greport_plot(const struct userinfostruct *uinfo,long long int *datapoints,int npoints)
25697a35 320{
1f482a8d 321 FILE *pngout;
d6e703cc 322 int x, y;
1f482a8d 323 int day;
c274f011 324 int x1;
25697a35 325 char graph[MAXLEN];
2240dcea 326 char s[15];
120d768c 327 char ftime[128];
25697a35
GS
328 time_t t;
329 struct tm *local;
e43854ef 330 gdPoint points[4];
e43854ef
FM
331 struct GraphDataStruct gdata;
332 const int ImgXSize=720;
333 const int ImgYSize=480;
334 const int LeftMargin=60;
335 const int RightMargin=20;
336 const int TopMargin=60;
337 const int BottomMargin=60;
338 const int TickLength=3;
339 const int ZTickLength=5;
1f482a8d 340 int LeftGraph;
e43854ef 341 int RightGraph;
1f482a8d
FM
342 const char *YLabels[]={"50K","250K","500K","1M","2M","3M","4M","5M","6M","7M","8M","9M","10M","15M",
343 "20M","30M","40M","50M","60M","70M","80M","90M","100M","200M","300M","400M",
344 "500M","600M","700M","800M","900M","1G","2G","3G","4G","5G"};
c274f011 345
e43854ef
FM
346 memset(&gdata,0,sizeof(gdata));
347
e43854ef 348 gdata.im = gdImageCreate(ImgXSize, ImgYSize);
1f482a8d
FM
349 gdata.BottomGraph=ImgYSize-BottomMargin;
350 LeftGraph=LeftMargin;
e43854ef 351 RightGraph=ImgXSize-RightMargin;
1f482a8d
FM
352 gdata.TopGraph=TopMargin;
353 gdata.BottomDepth=gdata.BottomGraph+5;
354 gdata.XScale=(double)(RightGraph-LeftGraph)/(31+1);
355 gdata.YScale=(double)(gdata.BottomGraph-TopMargin)/36.;
e43854ef
FM
356
357 // first allocated color is the background
358 gdata.lavender = gdImageColorAllocate(gdata.im, 230, 230, 250);
359 gdata.gray = gdImageColorAllocate(gdata.im, 192, 192, 192);
360 gdata.silver = gdImageColorAllocate(gdata.im, 211, 211, 211);
361 gdata.black = gdImageColorAllocate(gdata.im, 0, 0, 0);
362 gdata.dimgray = gdImageColorAllocate(gdata.im, 105, 105, 105);
363 gdata.darkblue = gdImageColorAllocate(gdata.im, 0, 0, 139);
364 gdata.goldenrod = gdImageColorAllocate(gdata.im, 234, 234, 174);
365 gdata.goldenrod2 = gdImageColorAllocate(gdata.im, 207, 181, 59);
366
367 if(strcmp(GraphDaysBytesBarColor,"orange") == 0) {
368 gdata.color1 = gdImageColorAllocate(gdata.im, 255, 233, 142);
369 gdata.color2 = gdImageColorAllocate(gdata.im, 220, 163, 72);
370 gdata.color3 = gdImageColorAllocate(gdata.im, 255, 198, 107);
371 }
372 else if(strcmp(GraphDaysBytesBarColor,"blue") == 0) {
373 gdata.color1 = gdImageColorAllocate(gdata.im, 62, 80, 167);
374 gdata.color2 = gdImageColorAllocate(gdata.im, 40, 51, 101);
375 gdata.color3 = gdImageColorAllocate(gdata.im, 57, 73, 150);
376 }
377 else if(strcmp(GraphDaysBytesBarColor,"green") == 0) {
378 gdata.color1 = gdImageColorAllocate(gdata.im,120,166,129);
379 gdata.color2 = gdImageColorAllocate(gdata.im,84,113,82);
380 gdata.color3 = gdImageColorAllocate(gdata.im,158,223,167);
381 }
382 else if(strcmp(GraphDaysBytesBarColor,"yellow") == 0) {
383 gdata.color1 = gdImageColorAllocate(gdata.im,185,185,10);
384 gdata.color2 = gdImageColorAllocate(gdata.im,111,111,10);
385 gdata.color3 = gdImageColorAllocate(gdata.im,166,166,10);
386 }
387 else if(strcmp(GraphDaysBytesBarColor,"brown") == 0) {
388 gdata.color1 = gdImageColorAllocate(gdata.im,97,45,27);
389 gdata.color2 = gdImageColorAllocate(gdata.im,60,30,20);
390 gdata.color3 = gdImageColorAllocate(gdata.im,88,41,26);
391 }
392 else if(strcmp(GraphDaysBytesBarColor,"red") == 0){
393 gdata.color1 = gdImageColorAllocate(gdata.im,185,10,10);
394 gdata.color2 = gdImageColorAllocate(gdata.im,111,10,10);
395 gdata.color3 = gdImageColorAllocate(gdata.im,166,10,10);
396 } else {
397 debuga(_("Unknown color \"%s\" requested for the graph. Using orange instead\n"),GraphDaysBytesBarColor);
398 gdata.color1 = gdImageColorAllocate(gdata.im, 255, 233, 142);
399 gdata.color2 = gdImageColorAllocate(gdata.im, 220, 163, 72);
400 gdata.color3 = gdImageColorAllocate(gdata.im, 255, 198, 107);
401 }
402
403 // rectangle around the image
404 gdImageRectangle(gdata.im, 0, 0, ImgXSize-1, ImgYSize-1, gdata.dimgray);
405 // backtround of the graph
1f482a8d 406 gdImageFilledRectangle(gdata.im, LeftMargin, gdata.TopGraph, RightGraph, gdata.BottomGraph, gdata.silver);
e43854ef
FM
407
408 // depth of the left Y axis
409 points[0].x = LeftMargin-10;
410 points[0].y = TopMargin+5;
411 points[1].x = LeftMargin-10;
1f482a8d 412 points[1].y = gdata.BottomDepth;
e43854ef 413 points[2].x = LeftMargin;
1f482a8d 414 points[2].y = gdata.BottomGraph;
e43854ef
FM
415 points[3].x = LeftMargin;
416 points[3].y = TopMargin;
417 gdImageFilledPolygon(gdata.im, points, 4, gdata.gray);
418
419 // depth of the bottom X axis
420 points[0].x = LeftMargin;
1f482a8d 421 points[0].y = gdata.BottomGraph;
e43854ef 422 points[1].x = LeftMargin-10;
1f482a8d 423 points[1].y = gdata.BottomDepth;
e43854ef 424 points[2].x = RightGraph-10;
1f482a8d 425 points[2].y = gdata.BottomDepth;
e43854ef 426 points[3].x = RightGraph;
1f482a8d 427 points[3].y = gdata.BottomGraph;
e43854ef
FM
428 gdImageFilledPolygon(gdata.im, points, 4, gdata.gray);
429
430 // vertical exterior line of the depth
1f482a8d 431 gdImageLine(gdata.im, LeftMargin-10, TopMargin+5, LeftMargin-10, gdata.BottomDepth+ZTickLength, gdata.black);
e43854ef 432 // horizontal exterior line of the depth
1f482a8d 433 gdImageLine(gdata.im, LeftMargin-10-ZTickLength, gdata.BottomDepth, RightGraph-10, gdata.BottomDepth, gdata.black);
e43854ef 434 // diagonal line between the two depths
1f482a8d 435 gdImageLine(gdata.im, LeftMargin-10, gdata.BottomDepth, LeftMargin, gdata.BottomGraph, gdata.black);
e43854ef 436 // vertical left line of the graph
1f482a8d 437 gdImageLine(gdata.im, LeftMargin, gdata.BottomGraph, LeftMargin, gdata.TopGraph, gdata.black);
e43854ef 438 // horizontal bottom line of the graph
1f482a8d 439 gdImageLine(gdata.im, LeftMargin, gdata.BottomGraph, RightGraph, gdata.BottomGraph, gdata.black);
e43854ef 440 // vertical right line of the graph
1f482a8d 441 gdImageLine(gdata.im, RightGraph, gdata.TopGraph, RightGraph, gdata.BottomGraph, gdata.black);
e43854ef 442 // diagonal line to close the right of the bottom depth
1f482a8d 443 gdImageLine(gdata.im, RightGraph-10, gdata.BottomDepth, RightGraph, gdata.BottomGraph, gdata.black);
e43854ef
FM
444
445 // Y axis ticks
1f482a8d
FM
446 for(x=0; x<36; x++) {
447 y=gdata.BottomGraph+5-(int)((double)(x+1)*gdata.YScale+0.5);
448 gdImageLine(gdata.im, LeftMargin-10, y, LeftMargin, y-5, gdata.dimgray);
449 gdImageLine(gdata.im, LeftMargin-10-TickLength, y, LeftMargin-10, y, gdata.dimgray);
450 gdImageLine(gdata.im, LeftMargin, y-5, RightGraph, y-5, gdata.dimgray);
451 Sarg_gdImageStringFT(&gdata,gdata.dimgray,GraphFont,7,0.0,LeftMargin-10-TickLength,y,YLabels[x],TRP_CenterRight);
e43854ef
FM
452 }
453
e43854ef 454 // X axis ticks and labels
e43854ef 455 for(y=1; y<=31; y++) {
1f482a8d
FM
456 x=LeftGraph-10+(int)((double)y*gdata.XScale+0.5);
457 gdImageLine(gdata.im, x, gdata.BottomDepth, x, gdata.BottomDepth+TickLength, gdata.dimgray);
e43854ef 458 sprintf(s,"%02d",y);
1f482a8d 459 Sarg_gdImageStringFT(&gdata,gdata.dimgray,GraphFont,7,0.0,x,gdata.BottomDepth+TickLength+1,s,TRP_TopCenter);
e43854ef
FM
460 }
461
462 t = time(NULL);
463 local = localtime(&t);
1f482a8d 464 if(DateFormat[0]=='u')
e43854ef 465 strftime(ftime, sizeof(ftime), "%b/%d/%Y %H:%M", local);
1f482a8d 466 if(DateFormat[0]=='e')
e43854ef
FM
467 strftime(ftime, sizeof(ftime), "%d/%b/%Y-%H:%M", local);
468
1f482a8d 469 x=ImgXSize*5/12;
e43854ef 470 Sarg_gdImageStringFT(&gdata,gdata.darkblue,GraphFont,7,0.0,ImgXSize-10,ImgYSize-10,ftime,TRP_BottomRight);
1f482a8d
FM
471 if(ShowSargInfo) Sarg_gdImageStringFT(&gdata,gdata.darkblue,GraphFont,10,0.0,x,15,_("SARG, "),TRP_BottomRight);
472 Sarg_gdImageStringFT(&gdata,gdata.darkblue,GraphFont,10,0.0,x,15,Title,TRP_BottomLeft);
e43854ef 473 sprintf(warea,_("Period: %s"),period.text);
1f482a8d 474 Sarg_gdImageStringFT(&gdata,gdata.darkblue,GraphFont,9,0.0,x,27,warea,TRP_BottomLeft);
e43854ef 475 sprintf(warea,_("User: %s"),uinfo->label);
1f482a8d
FM
476 Sarg_gdImageStringFT(&gdata,gdata.darkblue,GraphFont,9,0.0,x,38,warea,TRP_BottomLeft);
477
43cc1649 478 if(datetimeby==DATETIME_BYTE)
e43854ef
FM
479 Sarg_gdImageStringFT(&gdata,gdata.black,GraphFont,10,3.141592/2,20,ImgYSize/2,_("BYTES"),TRP_CenterLeft);
480 else
481 Sarg_gdImageStringFT(&gdata,gdata.black,GraphFont,10,3.141592/2,20,ImgYSize/2,_("ELAPSED TIME"),TRP_CenterLeft);
482 Sarg_gdImageStringFT(&gdata,gdata.black,GraphFont,10,0.0,ImgXSize/2,ImgYSize-20,_("DAYS"),TRP_BottomCenter);
25697a35 483
e43854ef
FM
484 for (day=0 ; day<31 ; day++) {
485 if (datapoints[day]>0) {
1f482a8d 486 x1=LeftGraph-10+(int)((double)(day+1)*gdata.XScale+0.5);
e43854ef
FM
487 bar(&gdata,x1,datapoints[day]);
488 }
25697a35
GS
489 }
490
e43854ef
FM
491 if (snprintf(graph,sizeof(graph),"%s/%s/graph_day.png",outdirname,uinfo->filename)>=sizeof(graph)) {
492 debuga(_("user name too long for %s/%s/graph_day.png\n"),outdirname,uinfo->filename);
493 exit(EXIT_FAILURE);
494 }
495 if((pngout=fopen(graph,"wb"))==NULL) {
496 debuga(_("(grepday) Cannot open log file %s\n"),graph);
497 exit(EXIT_FAILURE);
498 }
499 gdImagePng(gdata.im, pngout);
25697a35 500 fclose(pngout);
e43854ef 501 gdImageDestroy(gdata.im);
25697a35 502
e43854ef 503 if (gdata.string) free(gdata.string);
1f482a8d
FM
504}
505
506#endif //HAVE_GD
507
508void greport_prepare(void)
509{
510#ifdef HAVE_GD
511 if(access(GraphFont, R_OK) != 0) {
512 debuga(_("(grepday) Fontname %s not found\n"),GraphFont);
513 exit(EXIT_FAILURE);
514 }
515
e43854ef 516#ifdef USE_ICONV
1f482a8d
FM
517 localtoutf = iconv_open ("UTF-8", CharSet);
518 if (localtoutf==(iconv_t)-1) {
519 debuga(_("(grepday) iconv cannot convert from %s to UTF-8 - %s\n"),CharSet,strerror(errno));
520 }
e43854ef 521#endif
1dd9dcec 522
1f482a8d
FM
523#endif //HAVE_GD
524}
525
526void greport_day(const struct userinfostruct *uinfo)
527{
528#ifdef HAVE_GD
529 FILE *fp_in;
530 char wdirname[MAXLEN];
531 char buf[MAXLEN];
532 int day;
533 long long int llday;
534 long long int bytes;
535 long long int datapoints[31];
536 struct getwordstruct gwarea;
537
538 if (snprintf(wdirname,sizeof(wdirname),"%s/%s.day",tmp,uinfo->filename)>=sizeof(wdirname)) {
539 debuga(_("user name too long for %s/%s.day\n"),tmp,uinfo->filename);
540 exit(EXIT_FAILURE);
541 }
542 if(access(wdirname, R_OK) != 0) {
543 return;
544 }
545 if(!Graphs || GraphFont[0]=='\0') {
546 unlink(wdirname);
547 return;
548 }
549
550 if((fp_in=fopen(wdirname,"r"))==NULL) {
551 debuga(_("(grepday) Cannot open log file %s\n"),wdirname);
552 exit(EXIT_FAILURE);
553 }
554
555 memset(datapoints,0,sizeof(datapoints));
556 while(fgets(buf,sizeof(buf),fp_in)!=NULL) {
557 fixendofline(buf);
558 getword_start(&gwarea,buf);
559 if (getword_atoll(&llday,&gwarea,'/')<0) {
560 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),wdirname);
561 exit(EXIT_FAILURE);
562 }
563 if(DateFormat[0]=='u') {
564 if (getword_atoll(&llday,&gwarea,'/')<0) {
565 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),wdirname);
566 exit(EXIT_FAILURE);
567 }
568 }
569 day=(int)llday;
570 if (day<1 || day>31) continue;
571 if (getword_skip(20,&gwarea,'\t')<0 || getword_skip(20,&gwarea,'\t')<0 || getword_atoll(&bytes,&gwarea,'\t')<0) {
572 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),wdirname);
573 exit(EXIT_FAILURE);
574 }
575 datapoints[day-1]+=bytes;
576 }
577 fclose(fp_in);
578 unlink(wdirname);
579
580 greport_plot(uinfo,datapoints,31);
a1de61fe 581#endif //HAVE_GD
d6e703cc 582
25697a35
GS
583 return;
584}
c274f011
FM
585
586void greport_cleanup(void)
587{
588#ifdef HAVE_GD
589 gdFontCacheShutdown();
1f482a8d
FM
590
591#ifdef USE_ICONV
592 if (localtoutf!=(iconv_t)-1)
593 iconv_close (localtoutf);
c274f011 594#endif
1f482a8d 595#endif //HAVE_GD
c274f011 596}