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"
30 #ifdef ENABLE_DOUBLE_CHECK_DATA
31 extern struct globalstatstruct globstat
;
34 int geramail(const char *dirname
, int debug
, const char *outdir
, const char *email
, const char *TempDir
)
36 FILE *fp_in
, *fp_top1
, *fp_top2
, *fp_top3
;
37 long long int ttnbytes
=0, ttnacc
=0, tnacc
=0;
38 long long int tnbytes
=0, ttnelap
=0, tnelap
=0;
39 long long int nacc
, nbytes
, elap
;
40 long long int avgacc
, avgelap
;
44 char olduser
[MAX_USER_LEN
], csort
[MAXLEN
];
45 char wger
[MAXLEN
], top1
[MAXLEN
], top2
[MAXLEN
], top3
[MAXLEN
], user
[MAX_USER_LEN
];
46 char strip1
[MAXLEN
], strip2
[MAXLEN
], strip3
[MAXLEN
], strip4
[MAXLEN
], strip5
[MAXLEN
], strip6
[MAXLEN
], strip7
[MAXLEN
];
54 struct getwordstruct gwarea
;
55 struct generalitemstruct item
;
57 const struct userinfostruct
*uinfo
;
59 snprintf(wger
,sizeof(wger
),"%s/sarg-general",dirname
);
60 if((fp_in
=fopen(wger
,"r"))==NULL
) {
61 debuga(_("(email) Cannot open file %s: %s\n"),wger
,strerror(errno
));
65 snprintf(top1
,sizeof(top1
),"%s/top",dirname
);
66 if((fp_top1
=fopen(top1
,"w"))==NULL
) {
67 debuga(_("(email) Cannot open file %s: %s\n"),top1
,strerror(errno
));
71 snprintf(top2
,sizeof(top2
),"%s/top.tmp",dirname
);
72 if((fp_top2
=fopen(top2
,"w"))==NULL
) {
73 debuga(_("(email) Cannot open file %s: %s\n"),top2
,strerror(errno
));
80 if ((line
=longline_create())==NULL
) {
81 debuga(_("Not enough memory to read file %s\n"),wger
);
85 while((buf
=longline_read(fp_in
,line
))!=NULL
) {
86 ger_read(buf
,&item
,wger
);
87 if(item
.total
) continue;
88 if(strcmp(olduser
,item
.user
) != 0) {
91 if (olduser
[0] != '\0') {
92 #if defined(__FreeBSD__)
93 fprintf(fp_top2
,"%s\t%qu\t%qu\t%qu\n",olduser
,tnbytes
,tnacc
,tnelap
);
95 fprintf(fp_top2
,"%s\t%"PRIu64
"\t%"PRIu64
"\t%"PRIu64
"\n",olduser
,(uint64_t)tnbytes
,(uint64_t)tnacc
,(uint64_t)tnelap
);
101 strcpy(olduser
,item
.user
);
107 tnbytes
+=item
.nbytes
;
112 longline_destroy(&line
);
114 if (olduser
[0] != '\0') {
115 #if defined(__FreeBSD__)
116 fprintf(fp_top2
,"%s\t%qu\t%qu\t%qu\n",olduser
,tnbytes
,tnacc
,tnelap
);
118 fprintf(fp_top2
,"%s\t%"PRIu64
"\t%"PRIu64
"\t%"PRIu64
"\n",olduser
,(uint64_t)tnbytes
,(uint64_t)tnacc
,(uint64_t)tnelap
);
125 if (fclose(fp_top2
)==EOF
) {
126 debuga(_("Write error in %s: %s\n"),top2
,strerror(errno
));
130 #ifdef ENABLE_DOUBLE_CHECK_DATA
131 if (ttnacc
!=globstat
.nacc
|| ttnbytes
!=globstat
.nbytes
|| ttnelap
!=globstat
.elap
) {
132 debuga(_("Total statistics mismatch when reading %s to produce the email report\n"),wger
);
137 if (snprintf(csort
,sizeof(csort
),"sort -n -T \"%s\" -t \"\t\" -r -k 2,2 -o \"%s\" \"%s\"", TempDir
, top1
, top2
)>=sizeof(csort
)) {
138 debuga(_("Sort command too long when sorting file \"%s\" to \"%s\"\n"),top2
,top1
);
141 cstatus
=system(csort
);
142 if (!WIFEXITED(cstatus
) || WEXITSTATUS(cstatus
)) {
143 debuga(_("sort command return status %d\n"),WEXITSTATUS(cstatus
));
144 debuga(_("sort command: %s\n"),csort
);
148 if (!KeepTempLog
&& unlink(top2
)) {
149 debuga(_("Cannot delete \"%s\": %s\n"),top2
,strerror(errno
));
153 if((fp_top1
=fopen(top1
,"r"))==NULL
) {
154 debuga(_("(email) Cannot open file %s: %s\n"),top1
,strerror(errno
));
158 snprintf(top3
,sizeof(top3
),"%s/report",dirname
);
159 if((fp_top3
=fopen(top3
,"w"))==NULL
) {
160 debuga(_("(email) Cannot open file %s: %s\n"),top3
,strerror(errno
));
164 safe_strcpy(strip1
,_("Squid User Access Report"),sizeof(strip1
));
166 fprintf(fp_top3
,"%s\n",strip1
);
168 safe_strcpy(strip1
,_("Decreasing Access (bytes)"),sizeof(strip1
));
170 fprintf(fp_top3
,"%s\n",strip1
);
172 safe_strcpy(strip1
,_("Period"),sizeof(strip1
));
174 fprintf(fp_top3
,"%s %s\n\n",strip1
,period
.text
);
176 safe_strcpy(strip1
,_("NUM"),sizeof(strip1
));
178 safe_strcpy(strip2
,_("USERID"),sizeof(strip2
));
180 safe_strcpy(strip3
,_("CONNECT"),sizeof(strip3
));
182 safe_strcpy(strip4
,_("BYTES"),sizeof(strip4
));
184 safe_strcpy(strip5
,_("ELAPSED TIME"),sizeof(strip5
));
186 safe_strcpy(strip6
,_("MILLISEC"),sizeof(strip6
));
188 safe_strcpy(strip7
,_("TIME"),sizeof(strip7
));
191 fprintf(fp_top3
,"%-7s %-20s %-8s %-15s %%%-6s %-10s %-10s %%%-7s\n------- -------------------- -------- --------------- ------- ---------- ---------- -------\n",strip1
,strip2
,strip3
,strip4
,strip4
,strip5
,strip6
,strip7
);
193 while(fgets(warea
,sizeof(warea
),fp_top1
)) {
195 getword_start(&gwarea
,warea
);
196 if (getword(user
,sizeof(user
),&gwarea
,'\t')<0) {
197 debuga(_("There is an invalid user ID in file %s\n"),top1
);
200 if (getword_atoll(&nbytes
,&gwarea
,'\t')<0) {
201 debuga(_("There is an invalid number of bytes in file %s\n"),top1
);
204 if (getword_atoll(&nacc
,&gwarea
,'\t')<0) {
205 debuga(_("There is an invalid number of access in file %s\n"),top1
);
208 if (getword_atoll(&elap
,&gwarea
,'\0')<0) {
209 debuga(_("There is an invalid elapsed time in file %s\n"),top1
);
213 uinfo
=userinfo_find_from_id(user
);
215 debuga(_("Unknown user ID %s in file %s\n"),user
,top1
);
219 perc
=(ttnbytes
) ? nbytes
* 100. / ttnbytes
: 0;
220 perc2
=(ttnelap
) ? elap
* 100. / ttnelap
: 0;
224 #if defined(__FreeBSD__)
225 fprintf(fp_top3
,"%7d %20s %8lld %15s %3.2lf%% %10s %10qu %3.2lf%%\n",posicao
,uinfo
->label
,nacc
,fixnum(nbytes
,1),perc
,buildtime(elap
),elap
,perc2
);
227 fprintf(fp_top3
,"%7d %20s %8"PRIu64
" %15s %3.2lf%% %10s %10"PRIu64
" %3.2lf%%\n",posicao
,uinfo
->label
,(uint64_t)nacc
,fixnum(nbytes
,1),perc
,buildtime(elap
),(uint64_t)elap
,perc2
);
232 fputs("------- -------------------- -------- --------------- ------- ---------- ---------- -------\n",fp_top3
);
233 #if defined(__FreeBSD__)
234 fprintf(fp_top3
,"%-7s %20s %8qu %15s %8s %9s %10qu\n",_("TOTAL")," ",ttnacc
,fixnum(ttnbytes
,1)," ",buildtime(ttnelap
),ttnelap
);
236 fprintf(fp_top3
,"%-7s %20s %8"PRIu64
" %15s %8s %9s %10"PRIu64
"\n",_("TOTAL")," ",(uint64_t)ttnacc
,fixnum(ttnbytes
,1)," ",buildtime(ttnelap
),(uint64_t)ttnelap
);
239 // compute and write average
241 tnbytes
=(totuser
) ? ttnbytes
/ totuser
: 0;
242 avgacc
=ttnacc
/totuser
;
243 avgelap
=ttnelap
/totuser
;
250 safe_strcpy(strip1
,_("AVERAGE"),sizeof(strip1
));
252 #if defined(__FreeBSD__)
253 fprintf(fp_top3
,"%-7s %20s %8qu %15s %8s %9s %10qu\n",strip1
," ",avgacc
,fixnum(tnbytes
,1)," ",buildtime(avgelap
),avgelap
);
255 fprintf(fp_top3
,"%-7s %20s %8"PRIu64
" %15s %8s %9s %10"PRIu64
"\n",strip1
," ",(uint64_t)avgacc
,fixnum(tnbytes
,1)," ",buildtime(avgelap
),(uint64_t)avgelap
);
259 if (!KeepTempLog
&& unlink(top1
)) {
260 debuga(_("Cannot delete \"%s\": %s\n"),top1
,strerror(errno
));
265 local
= localtime(&t
);
266 fprintf(fp_top3
, "\n%s\n", asctime(local
));
268 if (fclose(fp_top3
)==EOF
) {
269 debuga(_("Write error in %s: %s\n"),top3
,strerror(errno
));
273 if(strcmp(email
,"stdout") == 0) {
274 if((fp_top3
=fopen(top3
,"r"))==NULL
) {
275 debuga(_("(email) Cannot open file %s: %s\n"),top3
,strerror(errno
));
279 while(fgets(warea
,sizeof(warea
),fp_top3
)!=NULL
)
282 /* TRANSLATORS: The string is formatted using strftime. You can use
283 any string formatting marker allowed by strftime. */
284 strftime(Subject
,sizeof(Subject
),_("SARG report, %c"),local
);
285 snprintf(warea
,sizeof(warea
),"%s -s \"%s\" \"%s\" <\"%s\"",MailUtility
,Subject
,email
,top3
);
287 debuga(_("Sending mail with command: %s\n"),warea
);
288 cstatus
=system(warea
);
289 if (!WIFEXITED(cstatus
) || WEXITSTATUS(cstatus
)) {
290 debuga(_("command return status %d\n"),WEXITSTATUS(cstatus
));
291 debuga(_("command: %s\n"),warea
);
296 //unlinkdir(TempDir,0);