"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "realtime.c" between
sarg-2.3.11.tar.gz and sarg-2.4.0.tar.gz

About: SARG ia a Squid Analysis Report Generator.

realtime.c  (sarg-2.3.11):realtime.c  (sarg-2.4.0)
/* /*
* SARG Squid Analysis Report Generator http://sarg.sourceforge.net * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
* 1998, 2013 * 1998, 2015
* *
* SARG donations: * SARG donations:
* please look at http://sarg.sourceforge.net/donations.php * please look at http://sarg.sourceforge.net/donations.php
* Support: * Support:
* http://sourceforge.net/projects/sarg/forums/forum/363374 * http://sourceforge.net/projects/sarg/forums/forum/363374
* --------------------------------------------------------------------- * ---------------------------------------------------------------------
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
skipping to change at line 29 skipping to change at line 29
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
* *
*/ */
#include "include/conf.h" #include "include/conf.h"
#include "include/defs.h" #include "include/defs.h"
#include "include/filelist.h"
#include "include/readlog.h"
static int getdata(char*, FILE*); //! Maximum length of the scheme plus host name from the url.
static void datashow(const char *); #define MAX_URL_HOST_LEN 260
static void getlog(void);
static void header(void);
void realtime(void) /*!
{ \brief Data read from an input log file.
getlog(); */
} struct RealtimeReadLogStruct
static void getlog(void)
{ {
FILE *tmp, *fp; //! The time corresponding to the entry.
char template1[255]="/var/tmp/sargtpl1.XXXXXX"; struct tm EntryTime;
char template2[255]="/var/tmp/sargtpl2.XXXXXX"; //! The IP address connecting to internet.
char cmd[512]; char Ip[48];
char *buf; //! The user's name.
int fd1,fd2; char User[MAX_USER_LEN];
int cstatus; /*!
longline line; The URL of the visited site.
init_usertab(UserTabFile); The pointer may be NULL if the URL doesn't exists in the log file.
*/
char Url[MAX_URL_HOST_LEN];
//! HTTP method or NULL if the information is not stored in the log.
char HttpMethod[32];
};
#ifdef HAVE_MKSTEMP extern FileListObject AccessLog;
fd2 = mkstemp(template2);
if (fd2 == -1) {
debuga(_("Cannot create a temporary file name to produce the repo
rt: %s\n"),strerror(errno));
exit(EXIT_FAILURE);
}
fd1 = mkstemp(template1);
#else
buf = mktemp(template2);
if (buf[0]=='\0') {
debuga(_("Cannot create a temporary file name to produce the repo
rt: %s\n"),strerror(errno));
exit(EXIT_FAILURE);
}
fd2 = -1;
fd1 = open(mktemp(template1),O_RDWR);
#endif
if((fd1 == -1 ) || ((tmp = fdopen (fd1, "w+" )) == NULL) ) { /* failu
re, bail out */
debugapos("realtime",_("mkstemp error: %s\n"),strerror(errno));
exit(EXIT_FAILURE);
}
if ((line=longline_create())==NULL) { static bool GetLatestModified(char *file_name,int file_name_size)
debuga(_("Not enough memory to read the log file\n")); {
exit(EXIT_FAILURE); FileListIterator FIter;
const char *file;
bool found=false;
struct stat st;
time_t latest;
FIter=FileListIter_Open(AccessLog);
while ((file=FileListIter_Next(FIter))!=NULL)
{
if (stat(file,&st)==-1) {
debuga(__FILE__,__LINE__,_("Cannot stat \"%s\": %s\n"),fi
le,strerror(errno));
}
if (!found)
{
found=true;
latest=st.st_mtime;
safe_strcpy(file_name,file,file_name_size);
}
else if (st.st_mtime>latest)
{
latest=st.st_mtime;
safe_strcpy(file_name,file,file_name_size);
}
} }
FileListIter_Close(FIter);
return(found);
}
sprintf(cmd,"tail -%d \"%s\"",realtime_access_log_lines,AccessLog[0]); /*!
fp = popen(cmd, "r"); * \brief Store a log entry.
if (!fp) { *
debuga(_("Failed to get the %d trailing lines of \"%s\": %s\n"),r * \param Dest A pointer to the list entry where to store the entry.
ealtime_access_log_lines,AccessLog[0],strerror(errno)); * \param Entry The entry to store.
debuga(_("Failed \"tail\" command: %s\n"),cmd); */
exit(EXIT_FAILURE); static void StoreLogEntry(struct RealtimeReadLogStruct *Dest,struct ReadLogStruc
t *Entry)
{
memcpy(&Dest->EntryTime,&Entry->EntryTime,sizeof(Dest->EntryTime));
safe_strcpy(Dest->Ip,Entry->Ip,sizeof(Dest->Ip));
if (Entry->Url)
{
int i;
const char *url=Entry->Url;
// skip the scheme
for (i=0 ; i<8 && url[i] && (isalnum(url[i]) || url[i]=='+' || ur
l[i]=='-' || url[i]=='.') ; i++);
if (url[i]==':' && url[i+1]=='/' && url[i+2]=='/')
{
url+=i+3;
for (i=0 ; url[i] && url[i]!='/' ; i++);
}
if (i>=sizeof(Dest->Url)) i=sizeof(Dest->Url)-1;
strncpy(Dest->Url,url,i);
Dest->Url[i]='\0';
} }
while((buf=longline_read(fp,line)) != NULL ) safe_strcpy(Dest->User,Entry->User,sizeof(Dest->User));
if (getdata(buf,tmp)<0) { safe_strcpy(Dest->HttpMethod,Entry->HttpMethod,sizeof(Dest->HttpMethod));
/* TRANSLATORS: The %s is the command returning the inval }
id data. */
debuga(_("Invalid data returned by %s\n"),cmd);
exit(EXIT_FAILURE);
}
pclose(fp);
fclose(tmp);
longline_destroy(&line);
if (fd2!=-1) close(fd2);//not safe at all but good enough for now. static void header(void)
if (snprintf(cmd,sizeof(cmd),"sort -t \"\t\" -r -n -k 1,1 -o \"%s\" \"%s\ {
"",template2,template1)>=sizeof(cmd)) { puts("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"");
debuga(_("Command too long: ")); puts(" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
debuga_more("sort -t \"\t\" -r -n -k 1,1 -o \"%s\" \"%s\"",templa puts("<html>\n");
te2,template1); puts("<head>\n");
exit(EXIT_FAILURE); if (realtime_refresh)
} printf(" <meta http-equiv=refresh content=\"%d\" url=\"sarg-php/
cstatus=system(cmd); sarg-realtime.php\"; charset=\"%s\">\n",realtime_refresh,CharSet);
if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) { else
debuga(_("sort command return status %d\n"),WEXITSTATUS(cstatus)) printf(" <meta http-equiv=\"Content-Type\" content=\"text/html;
; charset=%s\">\n",CharSet);
debuga(_("sort command: %s\n"),cmd); css(stdout);
exit(EXIT_FAILURE); puts("</head>\n");
} printf("<body style=\"font-family:%s;font-size:%s;background-color:%s;bac
if (!KeepTempLog && unlink(template1)) { kground-image:url(%s)\">\n",FontFace,TitleFontSize,BgColor,BgImage);
debuga(_("Cannot delete \"%s\": %s\n"),template1,strerror(errno)) puts("<div align=\"center\"><table cellpadding=\"1\" cellspacing=\"1\">\n
; ");
exit(EXIT_FAILURE); printf("<tr><th class=\"title_l\" colspan=\"10\">SARG %s</th></tr>\n",_("
} Realtime"));
datashow(template2); printf("<tr><th class=\"text\" colspan=\"10\">%s: %d s</th></tr>\n",_("Au
to refresh"),realtime_refresh);
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"));
} }
static int getdata(char *rec, FILE *ftmp) static void datashow(struct RealtimeReadLogStruct *List,int Index,int Size)
{ {
int dat; char tbuf[128];
char typ[128];
char warea[MAXLEN];
char user[MAX_USER_LEN]; char user[MAX_USER_LEN];
char ip[45]; char name[MAX_USER_LEN];
char *url; int i;
struct getwordstruct gwarea; struct RealtimeReadLogStruct *entry;
getword_start(&gwarea,rec);
if (getword_atoi(&dat,&gwarea,'.')<0) {
debuga(_("The time stamp at column 1 is too long\n"));
return(-1);
}
if (getword_skip(10,&gwarea,' ')<0) {
debuga(_("The time stamp decimal part at column 1 is too long\n")
);
return(-1);
}
if (getword(warea,sizeof(warea),&gwarea,' ')<0) {
debuga(_("The connection duration at column 2 is too long\n"));
return(-1);
}
while(strcmp(warea,"") == 0 && gwarea.current[0] != '\0')
if (getword(warea,sizeof(warea),&gwarea,' ')<0) {
return(-1);
}
if (getword(ip,sizeof(ip),&gwarea,' ')<0) {
debuga(_("The IP address at column 3 is too long\n"));
return(-1);
}
if (getword_skip(MAXLEN,&gwarea,' ')<0) {
debuga(_("The status at column 4 is too long\n"));
return(-1);
}
if (getword_skip(MAXLEN,&gwarea,' ')<0) {
debuga(_("The size at column 5 is too long\n"));
return(-1);
}
if (getword(typ,sizeof(typ),&gwarea,' ')<0) {
debuga(_("The action at column 6 is too long\n"));
return(-1);
}
if(strncmp(typ,"CONNECT",7) == 0) {
if (getword_ptr(rec,&url,&gwarea,' ')<0) {
debuga(_("The URL at column 7 is too long\n"));
return(-1);
}
if (getword(user,sizeof(user),&gwarea,' ')<0) {
debuga(_("The user ID at column 8 is too long\n"));
return(-1);
}
}else {
if (getword_skip(MAXLEN,&gwarea,'/')<0) {
debuga(_("The URL at column 7 is too long\n"));
return(-1);
}
if (getword_skip(MAXLEN,&gwarea,'/')<0) {
debuga(_("The URL at column 7 is too long\n"));
return(-1);
}
if (getword_ptr(rec,&url,&gwarea,'/')<0) {
debuga(_("The URL at column 7 is too long\n"));
return(-1);
}
if (getword_skip(MAXLEN,&gwarea,' ')<0) {
debuga(_("The data at column 8 is too long\n"));
return(-1);
}
if (getword(user,sizeof(user),&gwarea,' ')<0) {
debuga(_("The user at column 9 is too long\n"));
return(-1);
}
}
if(strncmp(user,"-",1) == 0 && RealtimeUnauthRec==REALTIME_UNAUTH_REC_IGN header();
ORE) for (i=0 ; i<realtime_access_log_lines ; i++)
return(0); {
entry=List+Index;
Index--;
if (Index<0) Index=Size-1;
if (UserIp)
strcpy(user,entry->Ip);
else
strcpy(user,entry->User);
if (Ip2Name)
ip2name(user,sizeof(user));
user_find(name, sizeof(name), user);
if (df=='u')
strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M", &entry->En
tryTime);
else if (df=='e')
strftime(tbuf, sizeof(tbuf), "%d-%m-%Y %H:%M", &entry->En
tryTime);
fprintf(ftmp,"%d\t%s\t%s\t%s\t%s\n",dat,ip,user,url,typ); printf("<tr><td class=\"data\">%s</td><td class=\"data3\">%s</td>
return(0); <td class=\"data3\">%s</td><td class=\"data3\">%s</td><td class=\"data2\"><a hre
f=\"http://%s\">%s</td></tr>\n",
tbuf,entry->Ip,name,entry->HttpMethod,entry->Url,entry
->Url);
}
puts("</table>\n</div>\n</body>\n</html>\n");
fflush(NULL);
} }
static void datashow(const char *tmp) void realtime(void)
{ {
FILE *fin; FileObject *fp;
time_t tt; char file_name[2048];
struct tm *t;
char tbuf[128];
int dat;
char *buf; char *buf;
char *url;
char *ourl=NULL;
char ouser[MAX_USER_LEN]="";
char typ[128];
char user[MAX_USER_LEN];
char u2[MAX_USER_LEN];
char ip[45];
int url_len;
int ourl_size=0;
struct getwordstruct gwarea;
longline line; longline line;
struct ReadLogStruct log_entry;
enum ReadLogReturnCodeEnum log_entry_status;
struct LogLineStruct log_line;
struct RealtimeReadLogStruct *StoredLogEntries;
int StoreIndex=0;
int StoreSize=0;
int NextIndex=1;
if((fin=fopen(tmp,"r"))==NULL) { init_usertab(UserTabFile);
debugapos("realtime",_("Cannot open file \"%s\": %s\n"),tmp,strer LogLine_Init(&log_line);
ror(errno));
/*
* Store one more entry to prepare the memory structure in place and reje
ct it if
* it is about the same user and url as the last stored one.
*/
StoredLogEntries=calloc(realtime_access_log_lines+1,sizeof(struct Realtim
eReadLogStruct));
if (!StoredLogEntries)
{
debuga(__FILE__,__LINE__,_("Not enough memory to store %d records
"),realtime_access_log_lines);
exit(EXIT_FAILURE);
}
/*
* Clear the url and user strings so that strcmp on the user and url are
not
* satisfied and the first entry can be stored.
*/
memset(StoredLogEntries,0,sizeof(struct RealtimeReadLogStruct));
if (!GetLatestModified(file_name,sizeof(file_name)))
{
debuga(__FILE__,__LINE__,_("No log file to read the last %d lines
from\n"),realtime_access_log_lines);
exit(EXIT_FAILURE);
}
fp = FileObject_Open(file_name);
if (!fp) {
debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),file_
name,FileObject_GetLastOpenError());
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
header();
if ((line=longline_create())==NULL) { if ((line=longline_create())==NULL) {
debuga(_("Not enough memory to read the log file\n")); debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\" \n"),file_name);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
while((buf=longline_read(fin,line))!=NULL) { while((buf=longline_read(fp,line)) != NULL )
fixendofline(buf); {
getword_start(&gwarea,buf); log_entry_status=LogLine_Parse(&log_line,&log_entry,buf);
if (getword_atoi(&dat,&gwarea,'\t')<0) { if (log_entry_status==RLRC_Unknown)
debuga(_("Invalid time column in file %s\n"),tmp); {
exit(EXIT_FAILURE); continue;
}
if (getword(ip,sizeof(ip),&gwarea,'\t')<0) {
debuga(_("Invalid IP address in file \"%s\"\n"),tmp);
exit(EXIT_FAILURE);
}
if (getword(user,sizeof(user),&gwarea,'\t')<0) {
debuga(_("Invalid user in file \"%s\"\n"),tmp);
exit(EXIT_FAILURE);
}
if (strlen(user) < 1) continue;
if (getword_ptr(buf,&url,&gwarea,'\t')<0) {
debuga(_("Invalid url in file \"%s\"\n"),tmp);
exit(EXIT_FAILURE);
} }
if (getword(typ,sizeof(typ),&gwarea,'\t')<0) { if (log_entry_status==RLRC_Ignore)
debuga(_("Invalid access type in file \"%s\"\n"),tmp); {
exit(EXIT_FAILURE); continue;
} }
if(strstr(RealtimeTypes,typ) == 0) if (log_entry.HttpMethod && strstr(RealtimeTypes,log_entry.HttpMe thod)==0)
continue; continue;
if (RealtimeUnauthRec==REALTIME_UNAUTH_REC_IGNORE && log_entry.Us
if(strcmp(ouser,user) == 0 && ourl && strcmp(ourl,url) == 0) er[0]=='-' && log_entry.User[1]=='\0')
continue;
StoreLogEntry(StoredLogEntries+NextIndex,&log_entry);
if (strcmp(StoredLogEntries[StoreIndex].User,StoredLogEntries[Nex
tIndex].User)==0 && strcmp(StoredLogEntries[StoreIndex].Url,StoredLogEntries[Nex
tIndex].Url)==0)
continue; continue;
if(UserIp) StoreIndex=NextIndex;
strcpy(user,ip); NextIndex++;
strcpy(u2,user); if (NextIndex>StoreSize) StoreSize=NextIndex;
if(Ip2Name) if (NextIndex>realtime_access_log_lines) NextIndex=0;
ip2name(u2,sizeof(u2));
user_find(name, sizeof(name), u2);
tt=(time_t)dat;
t=localtime(&tt);
if(DateFormat[0]=='u')
strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M", t);
else if(DateFormat[0]=='e')
strftime(tbuf, sizeof(tbuf), "%d-%m-%Y %H:%M", t);
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 hre
f=\"http://%s\">%s</td></tr>\n",tbuf,ip,name,typ,url,url);
strcpy(ouser,user);
url_len=strlen(url);
if (!ourl || url_len>=ourl_size) {
ourl_size=url_len+1;
ourl=realloc(ourl,ourl_size);
if (!ourl) {
debuga(_("Not enough memory to store the url\n"))
;
exit(EXIT_FAILURE);
}
}
strcpy(ourl,url);
} }
longline_destroy(&line); if (FileObject_Close(fp)) {
if (ourl) free(ourl); debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),file_nam
e,FileObject_GetLastCloseError());
puts("</table>\n</div>\n</body>\n</html>\n");
fclose(fin);
if (!KeepTempLog && unlink(tmp)) {
debuga(_("Cannot delete \"%s\": %s\n"),tmp,strerror(errno));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
fflush(NULL); longline_destroy(&line);
}
static void header(void) datashow(StoredLogEntries,StoreIndex,StoreSize);
{ free(StoredLogEntries);
puts("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"");
puts(" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
puts("<html>\n");
puts("<head>\n");
if(realtime_refresh)
printf(" <meta http-equiv=refresh content=\"%d\" url=\"sarg-php/
sarg-realtime.php\"; charset=\"%s\">\n",realtime_refresh,CharSet);
else
printf(" <meta http-equiv=\"Content-Type\" content=\"text/html;
charset=%s\">\n",CharSet);
css(stdout);
puts("</head>\n");
printf("<body style=\"font-family:%s;font-size:%s;background-color:%s;bac
kground-image:url(%s)\">\n",FontFace,TitleFontSize,BgColor,BgImage);
puts("<div align=\"center\"><table cellpadding=\"1\" cellspacing=\"1\">\n
");
printf("<tr><th class=\"title_l\" colspan=\"10\">SARG %s</th></tr>\n",_("
Realtime"));
printf("<tr><th class=\"text\" colspan=\"10\">%s: %d s</th></tr>\n",_("Au
to refresh"),realtime_refresh);
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"));
} }
 End of changes. 31 change blocks. 
276 lines changed or deleted 216 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)