]> git.ipfire.org Git - thirdparty/sarg.git/blob - totday.c
Add support to decompress xz files
[thirdparty/sarg.git] / totday.c
1 /*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
3 * 1998, 2015
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
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"
28 #include "include/defs.h"
29
30 //! The daily statistics for one user.
31 struct DayStruct
32 {
33 int ndaylist;
34 int maxindex;
35 int daylist[MAX_DATETIME_DAYS];
36 long long int bytes[MAX_DATETIME_DAYS*24];
37 long long int elap[MAX_DATETIME_DAYS*24];
38 };
39
40 /*!
41 Prepare the object to store the daily statistics of one user.
42
43 \return The object to pass to other functions in this module.
44 The object must be freed with a call to day_cleanup().
45 */
46 DayObject day_prepare(void)
47 {
48 DayObject ddata;
49
50 ddata=(DayObject)malloc(sizeof(*ddata));
51 if (!ddata)
52 {
53 debuga(__FILE__,__LINE__,_("Not enough memory to store the daily statistics\n"));
54 exit(EXIT_FAILURE);
55 }
56
57 return(ddata);
58 }
59
60 /*!
61 Free the memory allocated by day_prepare().
62
63 \param ddata The object returned by day_prepare().
64 */
65 void day_cleanup(DayObject ddata)
66 {
67 if (ddata) free(ddata);
68 }
69
70 /*!
71 Prepare the object for a new user.
72
73 \param ddata The object created by day_prepare().
74 */
75 void day_newuser(DayObject ddata)
76 {
77 if (ddata)
78 {
79 ddata->ndaylist=0;
80 ddata->maxindex=0;
81 memset(ddata->bytes,0,sizeof(ddata->bytes));
82 memset(ddata->elap,0,sizeof(ddata->elap));
83 }
84 }
85
86 /*!
87 Store one data point in the statistics.
88
89 \param ddata The object to store the statistics.
90 \param date The date of the data point formated as day/month/year.
91 \param time The time of the data point.
92 \param elap The time spent processing the user's request on the proxy.
93 \param bytes The number of bytes transfered by the user.
94 */
95 void day_addpoint(DayObject ddata,const char *date, const char *time, long long int elap, long long int bytes)
96 {
97 int hour;
98 int day,month,year;
99 int daynum;
100 int dayidx;
101 int i;
102
103 if (!ddata) return;
104 if (sscanf(date,"%d/%d/%d",&day,&month,&year)!=3) {
105 debuga(__FILE__,__LINE__,_("Invalid date \"%s\" for the hourly statistics\n"),date);
106 exit(EXIT_FAILURE);
107 }
108 if (day<1 || day>31 || month<1 || month>12 || year>9999) {
109 debuga(__FILE__,__LINE__,_("Invalid date component in \"%s\" for the hourly statistics\n"),date);
110 exit(EXIT_FAILURE);
111 }
112 hour=atoi(time);
113 if (hour<0 || hour>=24) {
114 debuga(__FILE__,__LINE__,_("Invalid hour %d for the hourly statistics\n"),hour);
115 exit(EXIT_FAILURE);
116 }
117 daynum=(year*10000)+(month*100)+day;
118 for (dayidx=ddata->ndaylist-1 ; dayidx>=0 && daynum!=ddata->daylist[dayidx] ; dayidx--);
119 if (dayidx<0) {
120 dayidx=ddata->ndaylist++;
121 if (dayidx>=sizeof(ddata->daylist)/sizeof(*ddata->daylist)) {
122 debuga(__FILE__,__LINE__,_("Too many different dates for the hourly statistics\n"));
123 exit(EXIT_FAILURE);
124 }
125 ddata->daylist[dayidx]=daynum;
126 }
127 i=dayidx*24+hour;
128 if (i>=ddata->maxindex) ddata->maxindex=i+1;
129 ddata->bytes[i]+=bytes;
130 ddata->elap[i]+=elap;
131 }
132
133 /*!
134 Store the dayly statistics in the file.
135
136 \param ddata The object containing the statistics.
137 \param tmp The temporary directory to store the file into.
138 \param uinfo The user's data.
139 */
140 void day_totalize(DayObject ddata,const char *tmp, const struct userinfostruct *uinfo)
141 {
142 FILE *fp_ou;
143 int hour;
144 int day,month,year;
145 int i;
146 int daynum;
147 int dayidx;
148 char arqout[2048];
149
150 if (datetimeby==0) return;
151 if (!ddata) return;
152
153 if (snprintf(arqout,sizeof(arqout),"%s/%s.day",tmp,uinfo->filename)>=sizeof(arqout)) {
154 debuga(__FILE__,__LINE__,_("Path too long: "));
155 debuga_more("%s/%s%s\n",tmp,uinfo->filename,".day");
156 exit(EXIT_FAILURE);
157 }
158
159 if((fp_ou=fopen(arqout,"w"))==NULL) {
160 debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),arqout,strerror(errno));
161 exit(EXIT_FAILURE);
162 }
163
164 for (i=0 ; i<ddata->maxindex ; i++) {
165 if (ddata->bytes[i]==0 && ddata->elap[i]==0) continue;
166 dayidx=i/24;
167 if (dayidx>=sizeof(ddata->daylist)/sizeof(*ddata->daylist)) {
168 debuga(__FILE__,__LINE__,_("Invalid day index found in the hourly statistics\n"));
169 exit(EXIT_FAILURE);
170 }
171 hour=i%24;
172 daynum=ddata->daylist[dayidx];
173 day=daynum%100;
174 month=(daynum/100)%100;
175 year=daynum/10000;
176 fprintf(fp_ou,"%d/%d/%d\t%d",day,month,year,hour);
177 if ((datetimeby & DATETIME_BYTE)!=0) fprintf(fp_ou,"\t%"PRIu64"",(uint64_t)ddata->bytes[i]);
178 if ((datetimeby & DATETIME_ELAP)!=0) fprintf(fp_ou,"\t%"PRIu64"",(uint64_t)ddata->elap[i]);
179 fputs("\n",fp_ou);
180 }
181
182 if (fclose(fp_ou)==EOF) {
183 debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),arqout,strerror(errno));
184 exit(EXIT_FAILURE);
185 }
186 return;
187 }
188
189 /*!
190 Delete the temporary file generated by day_totalize().
191
192 \param uinfo The user whose daily statistics are to be deleted.
193 */
194 void day_deletefile(const struct userinfostruct *uinfo)
195 {
196 char arqout[2048];
197
198 if (KeepTempLog) return;
199
200 if (snprintf(arqout,sizeof(arqout),"%s/%s.day",tmp,uinfo->filename)>=sizeof(arqout)) {
201 debuga(__FILE__,__LINE__,_("Path too long: "));
202 debuga_more("%s/%s%s\n",tmp,uinfo->filename,".day");
203 exit(EXIT_FAILURE);
204 }
205
206 if (unlink(arqout))
207 debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),arqout,strerror(errno));
208 }
209