]>
git.ipfire.org Git - thirdparty/sarg.git/blob - grepday.c
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
6 * please look at http://sarg.sourceforge.net/donations.php
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
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.
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.
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.
27 #include "include/conf.h"
28 #include "include/defs.h"
32 #if defined(HAVE_ICONV_H) && defined(gdFTEX_Unicode)
37 struct GraphDataStruct
47 //! The color of the top side of a graph bar.
49 //! The color of the right side of a graph bar.
51 //! The color of the front side of a graph bar.
53 //! The libgd image we are drawing on.
55 //! An allocated buffer to convert the string into UTF-8.
57 //! The number of bytes allocated for the string buffer.
59 //! The bottom border of the graph.
61 //! The top border of the graph.
63 //! The left border of the graph.
65 //! The right border of the graph.
67 //! The height at which the bottom depth border of the graph extends.
69 //! The distance between two ticks on the horizontal axis.
71 //! The distance between two ticks on the vertical axis.
73 //! The exterior length of a tick on the scales.
75 //! The distance, in pixels, between two ticks along the Y axis.
88 //! The data points to plot.
89 long long int *datapoints
;
90 //! The number of points to plot.
92 //! The minimum data to plot along the Y axis.
94 //! The maximum data to plot along the Y axis.
96 //! The type of Y axis to draw.
98 //! The label to write on the X axis.
100 //! The label to write on the Y axis.
102 //! The name of the output PNG file.
120 //! The iconv object to convert the text from the locale character set to UTF-8.
121 iconv_t localtoutf
=(iconv_t
)-1;
124 static void Sarg_gdImageStringFT (struct GraphDataStruct
*gdata
, int fg
, char *fontlist
,
125 double ptsize
, double angle
, int x
, int y
, const char *string
,enum TextRefPos RefPos
)
130 int minx
,miny
,maxx
,maxy
;
134 if (localtoutf
!=(iconv_t
)-1) {
139 slen
= strlen(string
) + 1; // We must include string termination character
140 sslen
= slen
* 3; // We assume that the UTF8 string will not be bigger than 3 times the original size.
141 if (sslen
>gdata
->string_size
) {
142 sstring
= (char *)realloc(gdata
->string
,sslen
);
144 debuga(_("realloc error (%"PRIu64
" bytes required)\n"),(uint64_t)sslen
);
147 gdata
->string
=(char *)sstring
;
148 gdata
->string_size
=sslen
;
150 sstring
=gdata
->string
;
151 sslen
=gdata
->string_size
;
156 if (iconv (localtoutf
, (ICONV_CONST
char **)&str
, &slen
, &sstr
, &sslen
)==-1) {
157 debuga(_("(grepday) iconv failed to convert string \"%s\" from %s to UTF-8 - %s\n"),string
,CharSet
,strerror(errno
));
158 sstring
=(char *)string
; //show something sensible on the graph
161 sstring
=(char *)string
; //show something sensible on the graph
164 sstring
=(char *)string
;
167 if (RefPos
!=TRP_BottomLeft
) {
168 retval
= gdImageStringFTEx (NULL
, brect
, fg
, fontlist
, ptsize
, angle
, 0, 0, sstring
, gdFTEX_Unicode
);
170 debuga(_("libgd failed to calculate the bounding box of the text \"%s\": %s\n"),sstring
,retval
);
174 From libgd documentation, brect contains this without taking into account the angle:
175 0 lower left corner, X position
176 1 lower left corner, Y position
177 2 lower right corner, X position
178 3 lower right corner, Y position
179 4 upper right corner, X position
180 5 upper right corner, Y position
181 6 upper left corner, X position
182 7 upper left corner, Y position
186 for (i
=2 ; i
<7 ; i
+=2) {
187 if (minx
>brect
[i
]) minx
=brect
[i
];
188 if (maxx
<brect
[i
]) maxx
=brect
[i
];
189 if (miny
>brect
[i
+1]) miny
=brect
[i
+1];
190 if (maxy
<brect
[i
+1]) maxy
=brect
[i
+1];
213 case TRP_BottomCenter
:
217 case TRP_BottomRight
:
230 case TRP_CenterRight
:
235 retval
= gdImageStringFTEx (gdata
->im
, brect
, fg
, fontlist
, ptsize
, angle
, x
, y
, sstring
, gdFTEX_Unicode
);
237 debuga(_("libgd failed to render the text \"%s\": %s\n"),sstring
,retval
);
242 static void bar(struct GraphDataStruct
*gdata
,int x1
,double y
,const char *label
)
248 val
=gdata
->BottomGraph
+5-(int)(y
*gdata
->YScale
+0.5);
249 width2
=(int)(gdata
->XScale
/4.);
251 // front side of the bar
252 if (val
<gdata
->BottomDepth
)
253 gdImageFilledRectangle(gdata
->im
, x1
-width2
, val
, x1
+width2
, gdata
->BottomDepth
, gdata
->color3
);
255 // top side of the bar
256 points
[0].x
= x1
-width2
+5;
258 points
[1].x
= x1
-width2
;
260 points
[2].x
= x1
+width2
;
262 points
[3].x
= x1
+width2
+5;
264 gdImageFilledPolygon(gdata
->im
, points
, 4, gdata
->color1
);
266 gdImageLine(gdata
->im
, x1
+2, val
-2, x1
+2, val
-10, gdata
->dimgray
);
267 gdImageFilledRectangle(gdata
->im
, x1
-8, val
-20, x1
+12, val
-10, gdata
->goldenrod
);
268 gdImageRectangle(gdata
->im
, x1
-8, val
-20, x1
+12, val
-10, gdata
->goldenrod2
);
270 Sarg_gdImageStringFT(gdata
,gdata
->black
,GraphFont
,6,0.0,x1
+2,val
-12,label
,TRP_BottomCenter
);
272 // lateral side of the bar
273 if (val
<gdata
->BottomDepth
) {
274 points
[0].x
= x1
+width2
+5;
276 points
[1].x
= x1
+width2
;
278 points
[2].x
= x1
+width2
;
279 points
[2].y
= gdata
->BottomDepth
;
280 points
[3].x
= x1
+width2
+5;
281 points
[3].y
= gdata
->BottomGraph
;
282 gdImageFilledPolygon(gdata
->im
, points
, 4, gdata
->color2
);
288 static int greport_compute_yaxis(struct PlotStruct
*pdata
,struct GraphDataStruct
*gdata
)
295 if (pdata
->ymin
<0.) {
296 debuga(_("Minimum for Y scale of the graph is out of range: %"PRId64
"\n"),(int64_t)pdata
->ymin
);
299 if (pdata
->ymax
<=0.) {
300 debuga(_("Maximum for Y scale of the graph is out of range: %"PRId64
"\n"),(int64_t)pdata
->ymax
);
307 symin
=(double)pdata
->ymin
;
308 symax
=(double)pdata
->ymax
;
314 symin
=log(pdata
->ymin
);
317 symax
=log(pdata
->ymax
);
322 symin
=(double)pdata
->ymin
;
323 symax
=(double)pdata
->ymax
;
328 debuga(_("Unknown type %d for Y axis scale\n"),pdata
->ytype
);
331 gdata
->YTickSpace
=10;
334 yscale
=(double)(gdata
->BottomGraph
-gdata
->TopGraph
)/range
;
335 gdata
->YScale
=yscale
;
339 static void greport_formatbin(double yval
,int maxdigits
,char *string
,int slen
)
342 char schar
[]={'\0','k','M','G','T','P'};
347 for (scount
=0 ; scount
<sizeof(schar
)/sizeof(*schar
) && yval
>=1000. ; scount
++)
355 if (ndigits
>maxdigits
) ndigits
=maxdigits
;
356 len
=snprintf(string
,slen
,"%.*f",ndigits
,(float)yval
);
358 for (i
=0 ; i
<len
; i
++)
359 if (string
[i
]=='.') string
[i
]=',';
360 if (schar
[scount
] && len
<slen
) {
361 string
[len
++]=schar
[scount
];
366 static void greport_draw_yaxis(struct PlotStruct
*pdata
,struct GraphDataStruct
*gdata
)
377 y0
=gdata
->BottomGraph
;
378 yt
=gdata
->BottomDepth
-gdata
->BottomGraph
;
379 xexterior
=gdata
->LeftGraph
-10;
380 xinterior
=gdata
->LeftGraph
;
381 xtick
=gdata
->LeftGraph
-10-gdata
->TickLength
;
382 for(y
=y0
-gdata
->YTickSpace
; y
>=gdata
->TopGraph
; y
-=gdata
->YTickSpace
) {
383 gdImageLine(gdata
->im
, xtick
, y
+yt
, xexterior
, y
+yt
, gdata
->dimgray
);
384 gdImageLine(gdata
->im
, xexterior
, y
+yt
, xinterior
, y
, gdata
->dimgray
);
385 gdImageLine(gdata
->im
, xinterior
, y
, gdata
->RightGraph
, y
, gdata
->dimgray
);
386 switch (pdata
->ytype
)
389 yval
=(double)(y0
-y
)/gdata
->YScale
+(double)pdata
->ymin
;
390 greport_formatbin(yval
,2,YLabel
,sizeof(YLabel
));
394 yval
=exp((double)(y0
-y
)/gdata
->YScale
+log(pdata
->ymin
));
395 greport_formatbin(yval
,2,YLabel
,sizeof(YLabel
));
402 yval
=(double)(y0
-y
)/gdata
->YScale
+(double)pdata
->ymin
;
403 t
=(int)(yval
/60000.+0.5);
404 snprintf(YLabel
,sizeof(YLabel
),"%02d:%02d",t
/60,t
%60);
408 Sarg_gdImageStringFT(gdata
,gdata
->dimgray
,GraphFont
,7,0.0,xtick
,y
+yt
,YLabel
,TRP_CenterRight
);
412 static void greport_plot(const struct userinfostruct
*uinfo
,struct PlotStruct
*pdata
)
424 struct GraphDataStruct gdata
;
425 const int ImgXSize
=720;
426 const int ImgYSize
=480;
427 const int LeftMargin
=60;
428 const int RightMargin
=20;
429 const int TopMargin
=60;
430 const int BottomMargin
=60;
431 const int TickLength
=3;
432 const int ZTickLength
=5;
437 memset(&gdata
,0,sizeof(gdata
));
439 gdata
.im
= gdImageCreate(ImgXSize
, ImgYSize
);
440 gdata
.BottomGraph
=ImgYSize
-BottomMargin
;
441 gdata
.LeftGraph
=LeftMargin
;
442 gdata
.RightGraph
=ImgXSize
-RightMargin
;
443 gdata
.TopGraph
=TopMargin
;
444 gdata
.BottomDepth
=gdata
.BottomGraph
+5;
445 gdata
.XScale
=(double)(gdata
.RightGraph
-gdata
.LeftGraph
)/(pdata
->npoints
+1);
446 if (greport_compute_yaxis(pdata
,&gdata
)<0) return;
447 gdata
.TickLength
=TickLength
;
449 // first allocated color is the background
450 gdata
.lavender
= gdImageColorAllocate(gdata
.im
, 230, 230, 250);
451 gdata
.gray
= gdImageColorAllocate(gdata
.im
, 192, 192, 192);
452 gdata
.silver
= gdImageColorAllocate(gdata
.im
, 211, 211, 211);
453 gdata
.black
= gdImageColorAllocate(gdata
.im
, 0, 0, 0);
454 gdata
.dimgray
= gdImageColorAllocate(gdata
.im
, 105, 105, 105);
455 gdata
.darkblue
= gdImageColorAllocate(gdata
.im
, 0, 0, 139);
456 gdata
.goldenrod
= gdImageColorAllocate(gdata
.im
, 234, 234, 174);
457 gdata
.goldenrod2
= gdImageColorAllocate(gdata
.im
, 207, 181, 59);
459 if(strcmp(GraphDaysBytesBarColor
,"orange") == 0) {
460 gdata
.color1
= gdImageColorAllocate(gdata
.im
, 255, 233, 142);
461 gdata
.color2
= gdImageColorAllocate(gdata
.im
, 220, 163, 72);
462 gdata
.color3
= gdImageColorAllocate(gdata
.im
, 255, 198, 107);
464 else if(strcmp(GraphDaysBytesBarColor
,"blue") == 0) {
465 gdata
.color1
= gdImageColorAllocate(gdata
.im
, 62, 80, 167);
466 gdata
.color2
= gdImageColorAllocate(gdata
.im
, 40, 51, 101);
467 gdata
.color3
= gdImageColorAllocate(gdata
.im
, 57, 73, 150);
469 else if(strcmp(GraphDaysBytesBarColor
,"green") == 0) {
470 gdata
.color1
= gdImageColorAllocate(gdata
.im
,120,166,129);
471 gdata
.color2
= gdImageColorAllocate(gdata
.im
,84,113,82);
472 gdata
.color3
= gdImageColorAllocate(gdata
.im
,158,223,167);
474 else if(strcmp(GraphDaysBytesBarColor
,"yellow") == 0) {
475 gdata
.color1
= gdImageColorAllocate(gdata
.im
,185,185,10);
476 gdata
.color2
= gdImageColorAllocate(gdata
.im
,111,111,10);
477 gdata
.color3
= gdImageColorAllocate(gdata
.im
,166,166,10);
479 else if(strcmp(GraphDaysBytesBarColor
,"brown") == 0) {
480 gdata
.color1
= gdImageColorAllocate(gdata
.im
,97,45,27);
481 gdata
.color2
= gdImageColorAllocate(gdata
.im
,60,30,20);
482 gdata
.color3
= gdImageColorAllocate(gdata
.im
,88,41,26);
484 else if(strcmp(GraphDaysBytesBarColor
,"red") == 0){
485 gdata
.color1
= gdImageColorAllocate(gdata
.im
,185,10,10);
486 gdata
.color2
= gdImageColorAllocate(gdata
.im
,111,10,10);
487 gdata
.color3
= gdImageColorAllocate(gdata
.im
,166,10,10);
489 debuga(_("Unknown color \"%s\" requested for the graph. Using orange instead\n"),GraphDaysBytesBarColor
);
490 gdata
.color1
= gdImageColorAllocate(gdata
.im
, 255, 233, 142);
491 gdata
.color2
= gdImageColorAllocate(gdata
.im
, 220, 163, 72);
492 gdata
.color3
= gdImageColorAllocate(gdata
.im
, 255, 198, 107);
495 // rectangle around the image
496 gdImageRectangle(gdata
.im
, 0, 0, ImgXSize
-1, ImgYSize
-1, gdata
.dimgray
);
497 // backtround of the graph
498 gdImageFilledRectangle(gdata
.im
, LeftMargin
, gdata
.TopGraph
, gdata
.RightGraph
, gdata
.BottomGraph
, gdata
.silver
);
500 // depth of the left Y axis
501 points
[0].x
= gdata
.LeftGraph
-10;
502 points
[0].y
= gdata
.TopGraph
+5;
503 points
[1].x
= gdata
.LeftGraph
-10;
504 points
[1].y
= gdata
.BottomDepth
;
505 points
[2].x
= gdata
.LeftGraph
;
506 points
[2].y
= gdata
.BottomGraph
;
507 points
[3].x
= gdata
.LeftGraph
;
508 points
[3].y
= gdata
.TopGraph
;
509 gdImageFilledPolygon(gdata
.im
, points
, 4, gdata
.gray
);
511 // depth of the bottom X axis
512 points
[0].x
= gdata
.LeftGraph
;
513 points
[0].y
= gdata
.BottomGraph
;
514 points
[1].x
= gdata
.LeftGraph
-10;
515 points
[1].y
= gdata
.BottomDepth
;
516 points
[2].x
= gdata
.RightGraph
-10;
517 points
[2].y
= gdata
.BottomDepth
;
518 points
[3].x
= gdata
.RightGraph
;
519 points
[3].y
= gdata
.BottomGraph
;
520 gdImageFilledPolygon(gdata
.im
, points
, 4, gdata
.gray
);
522 // vertical exterior line of the depth
523 gdImageLine(gdata
.im
, LeftMargin
-10, TopMargin
+5, LeftMargin
-10, gdata
.BottomDepth
+ZTickLength
, gdata
.black
);
524 // horizontal exterior line of the depth
525 gdImageLine(gdata
.im
, LeftMargin
-10-ZTickLength
, gdata
.BottomDepth
, gdata
.RightGraph
-10, gdata
.BottomDepth
, gdata
.black
);
526 // diagonal line between the two depths
527 gdImageLine(gdata
.im
, LeftMargin
-10, gdata
.BottomDepth
, LeftMargin
, gdata
.BottomGraph
, gdata
.black
);
528 // vertical left line of the graph
529 gdImageLine(gdata
.im
, LeftMargin
, gdata
.BottomGraph
, LeftMargin
, gdata
.TopGraph
, gdata
.black
);
530 // horizontal bottom line of the graph
531 gdImageLine(gdata
.im
, LeftMargin
, gdata
.BottomGraph
, gdata
.RightGraph
, gdata
.BottomGraph
, gdata
.black
);
532 // vertical right line of the graph
533 gdImageLine(gdata
.im
, gdata
.RightGraph
, gdata
.TopGraph
, gdata
.RightGraph
, gdata
.BottomGraph
, gdata
.black
);
534 // diagonal line to close the right of the bottom depth
535 gdImageLine(gdata
.im
, gdata
.RightGraph
-10, gdata
.BottomDepth
, gdata
.RightGraph
, gdata
.BottomGraph
, gdata
.black
);
538 greport_draw_yaxis(pdata
,&gdata
);
540 // X axis ticks and labels
541 for(y
=1; y
<=pdata
->npoints
; y
++) {
542 x
=gdata
.LeftGraph
-10+(int)((double)y
*gdata
.XScale
+0.5);
543 gdImageLine(gdata
.im
, x
, gdata
.BottomDepth
, x
, gdata
.BottomDepth
+TickLength
, gdata
.dimgray
);
545 Sarg_gdImageStringFT(&gdata
,gdata
.dimgray
,GraphFont
,7,0.0,x
,gdata
.BottomDepth
+TickLength
+1,s
,TRP_TopCenter
);
549 local
= localtime(&t
);
550 if(DateFormat
[0]=='u')
551 strftime(ftime
, sizeof(ftime
), "%b/%d/%Y %H:%M", local
);
552 if(DateFormat
[0]=='e')
553 strftime(ftime
, sizeof(ftime
), "%d/%b/%Y-%H:%M", local
);
556 Sarg_gdImageStringFT(&gdata
,gdata
.darkblue
,GraphFont
,7,0.0,ImgXSize
-10,ImgYSize
-10,ftime
,TRP_BottomRight
);
557 if(ShowSargInfo
) Sarg_gdImageStringFT(&gdata
,gdata
.darkblue
,GraphFont
,10,0.0,x
,15,_("SARG, "),TRP_BottomRight
);
558 Sarg_gdImageStringFT(&gdata
,gdata
.darkblue
,GraphFont
,10,0.0,x
,15,Title
,TRP_BottomLeft
);
559 sprintf(warea
,_("Period: %s"),period
.text
);
560 Sarg_gdImageStringFT(&gdata
,gdata
.darkblue
,GraphFont
,9,0.0,x
,27,warea
,TRP_BottomLeft
);
561 sprintf(warea
,_("User: %s"),uinfo
->label
);
562 Sarg_gdImageStringFT(&gdata
,gdata
.darkblue
,GraphFont
,9,0.0,x
,38,warea
,TRP_BottomLeft
);
564 Sarg_gdImageStringFT(&gdata
,gdata
.black
,GraphFont
,10,3.141592/2,15,ImgYSize
/2,pdata
->YLabel
,TRP_CenterLeft
);
565 Sarg_gdImageStringFT(&gdata
,gdata
.black
,GraphFont
,10,0.0,ImgXSize
/2,ImgYSize
-20,pdata
->XLabel
,TRP_BottomCenter
);
567 logpmin
=(pdata
->ytype
==PTG_LogBin
&& pdata
->ymin
>0.) ? log(pdata
->ymin
) : 0.;
568 for (day
=0 ; day
<pdata
->npoints
; day
++) {
569 if (pdata
->datapoints
[day
]>0) {
570 x1
=gdata
.LeftGraph
-10+(int)((double)(day
+1)*gdata
.XScale
+0.5);
571 switch (pdata
->ytype
)
574 yval
=(double)pdata
->datapoints
[day
];
575 if (yval
<pdata
->ymin
)
577 else if (yval
>pdata
->ymax
)
581 greport_formatbin(pdata
->datapoints
[day
],1,blabel
,sizeof(blabel
));
584 yval
=(double)pdata
->datapoints
[day
];
585 if (yval
<=pdata
->ymin
)
587 else if (yval
>pdata
->ymax
)
588 yval
=log(pdata
->ymax
)-logpmin
;
590 yval
=log(yval
)-logpmin
;
591 greport_formatbin(pdata
->datapoints
[day
],1,blabel
,sizeof(blabel
));
597 yval
=(double)pdata
->datapoints
[day
];
598 if (yval
<pdata
->ymin
)
600 else if (yval
>pdata
->ymax
)
604 t
=(int)(pdata
->datapoints
[day
]/60000.);
605 snprintf(blabel
,sizeof(blabel
),"%d:%02d",t
/60,t
%60);
612 if (yval
>=0.) bar(&gdata
,x1
,yval
,blabel
);
616 if (snprintf(graph
,sizeof(graph
),"%s/%s/%s",outdirname
,uinfo
->filename
,pdata
->pngfile
)>=sizeof(graph
)) {
617 debuga(_("user name too long for %s/%s/%s\n"),outdirname
,uinfo
->filename
,pdata
->pngfile
);
620 if((pngout
=fopen(graph
,"wb"))==NULL
) {
621 debuga(_("(grepday) Cannot open log file %s\n"),graph
);
624 gdImagePng(gdata
.im
, pngout
);
626 gdImageDestroy(gdata
.im
);
628 if (gdata
.string
) free(gdata
.string
);
633 void greport_prepare(void)
638 debugaz(_("Graphs disabled as requested in %s\n"),ConfigFile
);
641 if (GraphFont
[0]=='\0') {
643 debugaz(_("Graphs disabled as no font names were provided in %s\n"),ConfigFile
);
647 if(access(GraphFont
, R_OK
) != 0) {
648 debuga(_("(grepday) Fontname %s not found\n"),GraphFont
);
653 localtoutf
= iconv_open ("UTF-8", CharSet
);
654 if (localtoutf
==(iconv_t
)-1) {
655 debuga(_("(grepday) iconv cannot convert from %s to UTF-8 - %s\n"),CharSet
,strerror(errno
));
662 void greport_day(const struct userinfostruct
*uinfo
)
666 char wdirname
[MAXLEN
];
673 long long int bytespoints
[31];
674 long long int elappoints
[31];
675 struct getwordstruct gwarea
;
676 struct PlotStruct pdata
;
678 if (snprintf(wdirname
,sizeof(wdirname
),"%s/%s.day",tmp
,uinfo
->filename
)>=sizeof(wdirname
)) {
679 debuga(_("user name too long for %s/%s.day\n"),tmp
,uinfo
->filename
);
682 if(access(wdirname
, R_OK
) != 0) {
685 if(!Graphs
|| GraphFont
[0]=='\0') {
690 if((fp_in
=fopen(wdirname
,"r"))==NULL
) {
691 debuga(_("(grepday) Cannot open log file %s\n"),wdirname
);
695 memset(bytespoints
,0,sizeof(bytespoints
));
696 memset(elappoints
,0,sizeof(elappoints
));
697 while(fgets(buf
,sizeof(buf
),fp_in
)!=NULL
) {
699 getword_start(&gwarea
,buf
);
700 if (getword_atoll(&llday
,&gwarea
,'/')<0) {
701 debuga(_("Invalid date in file %s\n"),wdirname
);
705 if (day
<1 || day
>31) continue;
706 if (getword_skip(20,&gwarea
,'\t')<0 || getword_skip(20,&gwarea
,'\t')<0) {
707 debuga(_("Invalid entry in file %s\n"),wdirname
);
710 if ((datetimeby
& DATETIME_BYTE
)!=0) {
711 colsep
=((datetimeby
& DATETIME_ELAP
)!=0) ? '\t' : '\0';
712 if (getword_atoll(&bytes
,&gwarea
,'\t')<0) {
713 debuga(_("Invalid number of bytes in file %s\n"),wdirname
);
716 bytespoints
[day
-1]+=bytes
;
718 if ((datetimeby
& DATETIME_ELAP
)!=0) {
719 if (getword_atoll(&elap
,&gwarea
,'\0')<0) {
720 debuga(_("Invalid elapsed time in file %s\n"),wdirname
);
723 elappoints
[day
-1]+=elap
;
727 if (unlink(wdirname
)) {
728 debuga(_("Cannot delete %s - %s\n"),wdirname
,strerror(errno
));
732 if (snprintf(wdirname
,sizeof(wdirname
),"%s/%s/graph.html",outdirname
,uinfo
->filename
)>=sizeof(wdirname
)) {
733 debuga(_("user name too long for %s/%s/%s\n"),outdirname
,uinfo
->filename
,"graph.html");
736 if ((fp_ou
=fopen(wdirname
,"wt"))==NULL
) {
737 debuga(_("(grepday) Cannot open output file %s\n"),wdirname
);
740 write_html_head(fp_ou
,(IndexTree
== INDEX_TREE_DATE
) ? 4 : 2,_("Graph report"),HTML_JS_NONE
);
742 fputs("<table class=\"report\" cellpadding=\"0\" cellspacing=\"2\">\n", fp_ou
);
743 if((datetimeby
& DATETIME_BYTE
)!=0) {
744 memset(&pdata
,0,sizeof(pdata
));
745 pdata
.datapoints
=bytespoints
;
747 pdata
.XLabel
=_("DAYS");
748 pdata
.ymin
=50LL*1000LL;
749 pdata
.ymax
=5LL*1000LL*1000LL*1000LL;
750 pdata
.ytype
=PTG_LogBin
;
751 pdata
.YLabel
=_("BYTES");
752 pdata
.pngfile
="graph_day_byte.png";
753 greport_plot(uinfo
,&pdata
);
754 fprintf(fp_ou
,"<tr><td><img src=\"%s\" alt=\"B\"></td></tr>\n",pdata
.pngfile
);
756 if((datetimeby
& DATETIME_ELAP
)!=0) {
757 memset(&pdata
,0,sizeof(pdata
));
758 pdata
.datapoints
=elappoints
;
760 pdata
.XLabel
=_("DAYS");
763 pdata
.ytype
=PTG_Time
;
764 pdata
.YLabel
=_("ELAPSED TIME");
765 pdata
.pngfile
="graph_day_elap.png";
766 greport_plot(uinfo
,&pdata
);
767 fprintf(fp_ou
,"<tr><td><img src=\"%s\" alt=\"E\"></td></tr>\n",pdata
.pngfile
);
769 fputs("</table>\n",fp_ou
);
771 if (write_html_trailer(fp_ou
)<0)
772 debuga(_("Write error in file %s\n"),wdirname
);
773 if (fclose(fp_ou
)==EOF
)
774 debuga(_("Failed to close file %s - %s\n"),wdirname
,strerror(errno
));
780 void greport_cleanup(void)
783 gdFontCacheShutdown();
786 if (localtoutf
!=(iconv_t
)-1)
787 iconv_close (localtoutf
);