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