]> git.ipfire.org Git - thirdparty/sarg.git/blob - realtime.c
Update the Russian translation.
[thirdparty/sarg.git] / realtime.c
1 /*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
3 * 1998, 2013
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 static int getdata(char*, FILE*);
31 static void datashow(const char *);
32 static void getlog(void);
33 static void header(void);
34
35 void realtime(void)
36 {
37 getlog();
38 }
39
40 static void getlog(void)
41 {
42 FILE *tmp, *fp;
43 char template1[255]="/var/tmp/sargtpl1.XXXXXX";
44 char template2[255]="/var/tmp/sargtpl2.XXXXXX";
45 char cmd[512];
46 char *buf;
47 int fd1,fd2;
48 int cstatus;
49 longline line;
50
51 init_usertab(UserTabFile);
52
53 #ifdef HAVE_MKSTEMP
54 fd2 = mkstemp(template2);
55 if (fd2 == -1) {
56 debuga(_("Cannot create a temporary file name to produce the report: %s\n"),strerror(errno));
57 exit(EXIT_FAILURE);
58 }
59 fd1 = mkstemp(template1);
60 #else
61 buf = mktemp(template2);
62 if (buf[0]=='\0') {
63 debuga(_("Cannot create a temporary file name to produce the report: %s\n"),strerror(errno));
64 exit(EXIT_FAILURE);
65 }
66 fd2 = -1;
67 fd1 = open(mktemp(template1),O_RDWR);
68 #endif
69
70 if((fd1 == -1 ) || ((tmp = fdopen (fd1, "w+" )) == NULL) ) { /* failure, bail out */
71 debugapos("realtime",_("mkstemp error: %s\n"),strerror(errno));
72 exit(EXIT_FAILURE);
73 }
74
75 if ((line=longline_create())==NULL) {
76 debuga(_("Not enough memory to read the log file\n"));
77 exit(EXIT_FAILURE);
78 }
79
80 sprintf(cmd,"tail -%d \"%s\"",realtime_access_log_lines,AccessLog[0]);
81 fp = popen(cmd, "r");
82 if (!fp) {
83 debuga(_("Failed to get the %d trailing lines of \"%s\": %s\n"),realtime_access_log_lines,AccessLog[0],strerror(errno));
84 debuga(_("Failed \"tail\" command: %s\n"),cmd);
85 exit(EXIT_FAILURE);
86 }
87 while((buf=longline_read(fp,line)) != NULL )
88 if (getdata(buf,tmp)<0) {
89 /* TRANSLATORS: The %s is the command returning the invalid data. */
90 debuga(_("Invalid data returned by %s\n"),cmd);
91 exit(EXIT_FAILURE);
92 }
93 pclose(fp);
94 fclose(tmp);
95 longline_destroy(&line);
96
97 if (fd2!=-1) close(fd2);//not safe at all but good enough for now.
98 if (snprintf(cmd,sizeof(cmd),"sort -t \"\t\" -r -n -k 1,1 -o \"%s\" \"%s\"",template2,template1)>=sizeof(cmd)) {
99 debuga(_("Command too long: "));
100 debuga_more("sort -t \"\t\" -r -n -k 1,1 -o \"%s\" \"%s\"",template2,template1);
101 exit(EXIT_FAILURE);
102 }
103 cstatus=system(cmd);
104 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
105 debuga(_("sort command return status %d\n"),WEXITSTATUS(cstatus));
106 debuga(_("sort command: %s\n"),cmd);
107 exit(EXIT_FAILURE);
108 }
109 if (!KeepTempLog && unlink(template1)) {
110 debuga(_("Cannot delete \"%s\": %s\n"),template1,strerror(errno));
111 exit(EXIT_FAILURE);
112 }
113 datashow(template2);
114 }
115
116 static int getdata(char *rec, FILE *ftmp)
117 {
118 int dat;
119 char typ[128];
120 char warea[MAXLEN];
121 char user[MAX_USER_LEN];
122 char ip[45];
123 char *url;
124 struct getwordstruct gwarea;
125
126 getword_start(&gwarea,rec);
127 if (getword_atoi(&dat,&gwarea,'.')<0) {
128 debuga(_("The time stamp at column 1 is too long\n"));
129 return(-1);
130 }
131 if (getword_skip(10,&gwarea,' ')<0) {
132 debuga(_("The time stamp decimal part at column 1 is too long\n"));
133 return(-1);
134 }
135 if (getword(warea,sizeof(warea),&gwarea,' ')<0) {
136 debuga(_("The connection duration at column 2 is too long\n"));
137 return(-1);
138 }
139 while(strcmp(warea,"") == 0 && gwarea.current[0] != '\0')
140 if (getword(warea,sizeof(warea),&gwarea,' ')<0) {
141 return(-1);
142 }
143 if (getword(ip,sizeof(ip),&gwarea,' ')<0) {
144 debuga(_("The IP address at column 3 is too long\n"));
145 return(-1);
146 }
147 if (getword_skip(MAXLEN,&gwarea,' ')<0) {
148 debuga(_("The status at column 4 is too long\n"));
149 return(-1);
150 }
151 if (getword_skip(MAXLEN,&gwarea,' ')<0) {
152 debuga(_("The size at column 5 is too long\n"));
153 return(-1);
154 }
155 if (getword(typ,sizeof(typ),&gwarea,' ')<0) {
156 debuga(_("The action at column 6 is too long\n"));
157 return(-1);
158 }
159 if(strncmp(typ,"CONNECT",7) == 0) {
160 if (getword_ptr(rec,&url,&gwarea,' ')<0) {
161 debuga(_("The URL at column 7 is too long\n"));
162 return(-1);
163 }
164 if (getword(user,sizeof(user),&gwarea,' ')<0) {
165 debuga(_("The user ID at column 8 is too long\n"));
166 return(-1);
167 }
168 }else {
169 if (getword_skip(MAXLEN,&gwarea,'/')<0) {
170 debuga(_("The URL at column 7 is too long\n"));
171 return(-1);
172 }
173 if (getword_skip(MAXLEN,&gwarea,'/')<0) {
174 debuga(_("The URL at column 7 is too long\n"));
175 return(-1);
176 }
177 if (getword_ptr(rec,&url,&gwarea,'/')<0) {
178 debuga(_("The URL at column 7 is too long\n"));
179 return(-1);
180 }
181 if (getword_skip(MAXLEN,&gwarea,' ')<0) {
182 debuga(_("The data at column 8 is too long\n"));
183 return(-1);
184 }
185 if (getword(user,sizeof(user),&gwarea,' ')<0) {
186 debuga(_("The user at column 9 is too long\n"));
187 return(-1);
188 }
189 }
190
191 if(strncmp(user,"-",1) == 0 && RealtimeUnauthRec==REALTIME_UNAUTH_REC_IGNORE)
192 return(0);
193
194 fprintf(ftmp,"%d\t%s\t%s\t%s\t%s\n",dat,ip,user,url,typ);
195 return(0);
196 }
197
198 static void datashow(const char *tmp)
199 {
200 FILE *fin;
201 time_t tt;
202 struct tm *t;
203 char tbuf[128];
204 int dat;
205 char *buf;
206 char *url;
207 char *ourl=NULL;
208 char ouser[MAX_USER_LEN]="";
209 char typ[128];
210 char user[MAX_USER_LEN];
211 char u2[MAX_USER_LEN];
212 char ip[45];
213 int url_len;
214 int ourl_size=0;
215 struct getwordstruct gwarea;
216 longline line;
217
218 if((fin=fopen(tmp,"r"))==NULL) {
219 debugapos("realtime",_("Cannot open file \"%s\": %s\n"),tmp,strerror(errno));
220 exit(EXIT_FAILURE);
221 }
222
223 header();
224
225 if ((line=longline_create())==NULL) {
226 debuga(_("Not enough memory to read the log file\n"));
227 exit(EXIT_FAILURE);
228 }
229
230 while((buf=longline_read(fin,line))!=NULL) {
231 fixendofline(buf);
232 getword_start(&gwarea,buf);
233 if (getword_atoi(&dat,&gwarea,'\t')<0) {
234 debuga(_("Invalid time column in file %s\n"),tmp);
235 exit(EXIT_FAILURE);
236 }
237 if (getword(ip,sizeof(ip),&gwarea,'\t')<0) {
238 debuga(_("Invalid IP address in file \"%s\"\n"),tmp);
239 exit(EXIT_FAILURE);
240 }
241 if (getword(user,sizeof(user),&gwarea,'\t')<0) {
242 debuga(_("Invalid user in file \"%s\"\n"),tmp);
243 exit(EXIT_FAILURE);
244 }
245 if (strlen(user) < 1) continue;
246 if (getword_ptr(buf,&url,&gwarea,'\t')<0) {
247 debuga(_("Invalid url in file \"%s\"\n"),tmp);
248 exit(EXIT_FAILURE);
249 }
250 if (getword(typ,sizeof(typ),&gwarea,'\t')<0) {
251 debuga(_("Invalid access type in file \"%s\"\n"),tmp);
252 exit(EXIT_FAILURE);
253 }
254 if(strstr(RealtimeTypes,typ) == 0)
255 continue;
256
257 if(strcmp(ouser,user) == 0 && ourl && strcmp(ourl,url) == 0)
258 continue;
259
260 if(UserIp)
261 strcpy(user,ip);
262 strcpy(u2,user);
263 if(Ip2Name)
264 ip2name(u2,sizeof(u2));
265 user_find(name, sizeof(name), u2);
266
267 tt=(time_t)dat;
268 t=localtime(&tt);
269 if(DateFormat[0]=='u')
270 strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M", t);
271 else if(DateFormat[0]=='e')
272 strftime(tbuf, sizeof(tbuf), "%d-%m-%Y %H:%M", t);
273
274 printf("<tr><td class=\"data\">%s</td><td class=\"data3\">%s</td><td class=\"data3\">%s</td><td class=\"data3\">%s</td><td class=\"data2\"><a href=\"http://%s\">%s</td></tr>\n",tbuf,ip,name,typ,url,url);
275 strcpy(ouser,user);
276
277 url_len=strlen(url);
278 if (!ourl || url_len>=ourl_size) {
279 ourl_size=url_len+1;
280 ourl=realloc(ourl,ourl_size);
281 if (!ourl) {
282 debuga(_("Not enough memory to store the url\n"));
283 exit(EXIT_FAILURE);
284 }
285 }
286 strcpy(ourl,url);
287 }
288 longline_destroy(&line);
289 if (ourl) free(ourl);
290
291 puts("</table>\n</div>\n</body>\n</html>\n");
292 fclose(fin);
293 if (!KeepTempLog && unlink(tmp)) {
294 debuga(_("Cannot delete \"%s\": %s\n"),tmp,strerror(errno));
295 exit(EXIT_FAILURE);
296 }
297 fflush(NULL);
298 }
299
300 static void header(void)
301 {
302 puts("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"");
303 puts(" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
304 puts("<html>\n");
305 puts("<head>\n");
306 if(realtime_refresh)
307 printf(" <meta http-equiv=refresh content=\"%d\" url=\"sarg-php/sarg-realtime.php\"; charset=\"%s\">\n",realtime_refresh,CharSet);
308 else
309 printf(" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">\n",CharSet);
310 css(stdout);
311 puts("</head>\n");
312 printf("<body style=\"font-family:%s;font-size:%s;background-color:%s;background-image:url(%s)\">\n",FontFace,TitleFontSize,BgColor,BgImage);
313 puts("<div align=\"center\"><table cellpadding=\"1\" cellspacing=\"1\">\n");
314 printf("<tr><th class=\"title_l\" colspan=\"10\">SARG %s</th></tr>\n",_("Realtime"));
315 printf("<tr><th class=\"text\" colspan=\"10\">%s: %d s</th></tr>\n",_("Auto refresh"),realtime_refresh);
316 printf("<tr><th class=\"header_c\">%s</th><th class=\"header_c\">%s</th><th class=\"header_c\">%s</th><th class=\"header_c\">%s</th><th class=\"header_l\">%s</th></tr>\n",_("DATE/TIME"),_("IP/NAME"),_("USERID"),_("TYPE"),_("ACCESSED SITE"));
317 }