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