//! The latest date in time format.
static struct tm LatestDateTime;
+/*!
+ * Initialize the memory structure needed by LogLine_Parse() to parse
+ * a log line.
+ *
+ * \param log_line The structure to initialize.
+ */
+void LogLine_Init(struct LogLineStruct *log_line)
+{
+ log_line->current_format=NULL;
+ log_line->current_format_idx=-1;
+ log_line->file_name="";
+ log_line->successive_errors=0;
+ log_line->total_errors=0;
+}
+
+/*!
+ * Set the name of the log file being parsed.
+ *
+ * \param log_line Data structure to parse the log line.
+ * \param file_name The name of the log file being read.
+ */
+void LogLine_File(struct LogLineStruct *log_line,const char *file_name)
+{
+ log_line->file_name=file_name;
+}
+
+/*!
+ * Parse the next line from a log file.
+ *
+ * \param log_line A buffer to store the data about the current parsing.
+ * \param log_entry The variable to store the parsed data.
+ * \param linebuf The text line read from the log file.
+ *
+ * \return
+ */
+enum ReadLogReturnCodeEnum LogLine_Parse(struct LogLineStruct *log_line,struct ReadLogStruct *log_entry,char *linebuf)
+{
+ enum ReadLogReturnCodeEnum log_entry_status=RLRC_Unknown;
+ int x;
+
+ if (log_line->current_format)
+ {
+ memset(log_entry,0,sizeof(*log_entry));
+ log_entry_status=log_line->current_format->ReadEntry(linebuf,log_entry);
+ }
+
+ // find out what line format to use
+ if (log_entry_status==RLRC_Unknown)
+ {
+ for (x=0 ; x<(int)(sizeof(LogFormats)/sizeof(*LogFormats)) ; x++)
+ {
+ if (LogFormats[x]==log_line->current_format) continue;
+ memset(log_entry,0,sizeof(*log_entry));
+ log_entry_status=LogFormats[x]->ReadEntry(linebuf,log_entry);
+ if (log_entry_status!=RLRC_Unknown)
+ {
+ log_line->current_format=LogFormats[x];
+ log_line->current_format_idx=x;
+ if (debugz>=LogLevel_Process)
+ {
+ /* TRANSLATORS: The argument is the log format name as translated by you. */
+ debuga(_("Log format identified as \"%s\" for %s\n"),_(log_line->current_format->Name),log_line->file_name);
+ }
+ break;
+ }
+ }
+ if (x>=(int)(sizeof(LogFormats)/sizeof(*LogFormats)))
+ {
+ if (++log_line->successive_errors>NumLogSuccessiveErrors) {
+ debuga(ngettext("%d consecutive error found in the input log file %s\n",
+ "%d consecutive errors found in the input log file %s\n",log_line->successive_errors),log_line->successive_errors,log_line->file_name);
+ exit(EXIT_FAILURE);
+ }
+ if (NumLogTotalErrors>=0 && ++log_line->total_errors>NumLogTotalErrors) {
+ debuga(ngettext("%d error found in the input log file (last in %s)\n",
+ "%d errors found in the input log file (last in %s)\n",log_line->total_errors),log_line->total_errors,log_line->file_name);
+ exit(EXIT_FAILURE);
+ }
+ debuga(_("The following line read from %s could not be parsed and is ignored\n%s\n"),log_line->file_name,linebuf);
+ }
+ else
+ log_line->successive_errors=0;
+ }
+
+ if (log_line->current_format_idx<0 || log_line->current_format==NULL) {
+ debuga(_("Sarg failed to determine the format of the input log file %s\n"),log_line->file_name);
+ exit(EXIT_FAILURE);
+ }
+ if (log_entry_status==RLRC_InternalError) {
+ debuga(_("Internal error encountered while processing %s\nSee previous message to know the reason for that error.\n"),log_line->file_name);
+ exit(EXIT_FAILURE);
+ }
+ return(log_entry_status);
+}
+
/*!
Read a single log file.
char smartfilter[MAXLEN];
const char *url;
const char *user;
- int current_format_idx;
int OutputNonZero = REPORT_EVERY_X_LINES ;
int idata=0;
int x;
int hmr;
int nopen;
int maxopenfiles=MAX_OPEN_USER_FILES;
- int successive_errors=0;
- int total_errors=0;
unsigned long int recs1=0UL;
unsigned long int recs2=0UL;
FILE *fp_in=NULL;
struct userfilestruct *ufile;
struct userfilestruct *ufile1;
struct ReadLogStruct log_entry;
- const struct ReadLogProcessStruct *current_format=NULL;
+ struct LogLineStruct log_line;
- current_format=NULL;
- current_format_idx=-1;
+ LogLine_Init(&log_line);
+ LogLine_File(&log_line,arq);
for (x=0 ; x<sizeof(LogFormats)/sizeof(*LogFormats) ; x++)
if (LogFormats[x]->NewFile)
LogFormats[x]->NewFile(arq);
printf("BUF=%s\n",linebuf);
// process the line
- log_entry_status=RLRC_Unknown;
- memset(&log_entry,0,sizeof(log_entry));
- if (current_format) {
- log_entry_status=current_format->ReadEntry(linebuf,&log_entry);
- }
-
- // find out what line format to use
- if (log_entry_status==RLRC_Unknown) {
- for (x=0 ; x<(int)(sizeof(LogFormats)/sizeof(*LogFormats)) ; x++) {
- if (LogFormats[x]==current_format) continue;
- memset(&log_entry,0,sizeof(log_entry));
- log_entry_status=LogFormats[x]->ReadEntry(linebuf,&log_entry);
- if (log_entry_status!=RLRC_Unknown) break;
- }
- if (x>=(int)(sizeof(LogFormats)/sizeof(*LogFormats))) {
- if (++successive_errors>NumLogSuccessiveErrors) {
- debuga(ngettext("%d consecutive error found in the input log file %s\n",
- "%d consecutive errors found in the input log file %s\n",successive_errors),successive_errors,arq);
- exit(EXIT_FAILURE);
- }
- if (NumLogTotalErrors>=0 && ++total_errors>NumLogTotalErrors) {
- debuga(ngettext("%d error found in the input log file (last in %s)\n",
- "%d errors found in the input log file (last in %s)\n",total_errors),total_errors,arq);
- exit(EXIT_FAILURE);
- }
- debuga(_("The following line read from %s could not be parsed and is ignored\n%s\n"),arq,linebuf);
- excluded_count[ER_UnknownFormat]++;
- continue;
- }
- current_format=LogFormats[x];
- current_format_idx=x;
- if (debugz>=LogLevel_Process) {
- /* TRANSLATORS: The argument is the log format name as translated by you. */
- debuga(_("Log format identified as \"%s\" for %s\n"),_(current_format->Name),arq);
- }
- successive_errors=0;
+ log_entry_status=LogLine_Parse(&log_line,&log_entry,linebuf);
+ if (log_entry_status==RLRC_Unknown)
+ {
+ excluded_count[ER_UnknownFormat]++;
+ continue;
}
if (log_entry_status==RLRC_Ignore) {
excluded_count[ER_FormatData]++;
continue;
}
- if (current_format_idx<0 || current_format==NULL) {
- debuga(_("Sarg failed to determine the format of the input log file %s\n"),arq);
- exit(EXIT_FAILURE);
- }
- if (log_entry_status==RLRC_InternalError) {
- debuga(_("Internal error encountered while processing %s\nSee previous message to know the reason for that error.\n"),arq);
- exit(EXIT_FAILURE);
- }
- format_count[current_format_idx]++;
+ format_count[log_line.current_format_idx]++;
- if (!fp_log && ParsedOutputLog[0] && current_format!=&ReadSargLog) {
+ if (!fp_log && ParsedOutputLog[0] && log_line.current_format!=&ReadSargLog) {
if(access(ParsedOutputLog,R_OK) != 0) {
my_mkdir(ParsedOutputLog);
}
for (str=log_entry.HttpCode ; *str ; str++)
if (*str=='\t') *str=' ';
- if (current_format!=&ReadSargLog) {
+ if (log_line.current_format!=&ReadSargLog) {
/*
The full URL is not saved in sarg log. There is no point in testing the URL to detect
a downloaded file.
}
records_kept++;
- if (fp_log && current_format!=&ReadSargLog) {
+ if (fp_log && log_line.current_format!=&ReadSargLog) {
fprintf(fp_log, "%s\t%s\t%s\t%s\t%s\t%"PRIu64"\t%s\t%ld\t%s\n",dia,hora,
log_entry.User,log_entry.Ip,url,(uint64_t)log_entry.DataSize,
log_entry.HttpCode,log_entry.ElapsedTime,smartfilter);
authfail_write(&log_entry);
if (download_flag) download_write(&log_entry,download_url);
- if (current_format!=&ReadSargLog) {
+ if (log_line.current_format!=&ReadSargLog) {
if (period.start.tm_year==0 || idata<mindate || compare_date(&period.start,&log_entry.EntryTime)>0){
mindate=idata;
memcpy(&period.start,&log_entry.EntryTime,sizeof(log_entry.EntryTime));
#include "include/conf.h"
#include "include/defs.h"
#include "include/filelist.h"
+#include "include/readlog.h"
-extern FileListObject AccessLog;
-
-static int getdata(char*, FILE*);
-static void datashow(const char *);
-static void getlog(void);
-static void header(void);
+//! Maximum length of the scheme plus host name from the url.
+#define MAX_URL_HOST_LEN 260
-void realtime(void)
+/*!
+\brief Data read from an input log file.
+*/
+struct RealtimeReadLogStruct
{
- getlog();
-}
+ //! The time corresponding to the entry.
+ struct tm EntryTime;
+ //! The IP address connecting to internet.
+ char Ip[48];
+ //! The user's name.
+ char User[MAX_USER_LEN];
+ /*!
+ The URL of the visited site.
+
+ 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];
+};
+
+extern FileListObject AccessLog;
-static void getlog(void)
+static bool GetLatestModified(char *file_name,int file_name_size)
{
- FILE *tmp, *fp;
- char template1[255]="/var/tmp/sargtpl1.XXXXXX";
- char template2[255]="/var/tmp/sargtpl2.XXXXXX";
- char cmd[2048];
- char *buf;
- const char *file;
- int fd1,fd2;
- int cstatus;
- longline line;
FileListIterator FIter;
-
- init_usertab(UserTabFile);
-
-#ifdef HAVE_MKSTEMP
- fd2 = mkstemp(template2);
- if (fd2 == -1) {
- debuga(_("Cannot create a temporary file name to produce the report: %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 report: %s\n"),strerror(errno));
- exit(EXIT_FAILURE);
- }
- fd2 = -1;
- fd1 = open(mktemp(template1),O_RDWR);
-#endif
-
- if((fd1 == -1 ) || ((tmp = fdopen (fd1, "w+" )) == NULL) ) { /* failure, bail out */
- debuga(_("(realtime) mkstemp error - %s\n"),strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- if ((line=longline_create())==NULL) {
- debuga(_("Not enough memory to read the log file\n"));
- exit(EXIT_FAILURE);
- }
+ const char *file;
+ bool found=false;
+ struct stat st;
+ time_t latest;
FIter=FileListIter_Open(AccessLog);
- file=FileListIter_Next(FIter);
- if (file==NULL) {
- debuga(_("No log file to read the last %d lines from\n"),realtime_access_log_lines);
- exit(EXIT_FAILURE);
- }
- if (snprintf(cmd,sizeof(cmd),"tail -%d \"%s\"",realtime_access_log_lines,file)>=sizeof(cmd)) {
- debuga(_("Input log file name too long: %s\n"),file);
- exit(EXIT_FAILURE);
- }
- fp = popen(cmd, "r");
- if (!fp) {
- debuga(_("Failed to get %d trailing lines from %s: %s\n"),realtime_access_log_lines,file,strerror(errno));
- debuga(_("tail command: %s\n"),cmd);
- exit(EXIT_FAILURE);
+ while ((file=FileListIter_Next(FIter))!=NULL)
+ {
+ if (stat(file,&st)==-1) {
+ debuga(_("Cannot stat \"%s\": %s"),file,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);
- while((buf=longline_read(fp,line)) != NULL )
- if (getdata(buf,tmp)<0) {
- debuga(_("Maybe a broken record or garbage was returned by %s\n"),cmd);
- exit(EXIT_FAILURE);
- }
- pclose(fp);
- fclose(tmp);
- longline_destroy(&line);
+ return(found);
+}
- if (fd2!=-1) close(fd2);//not safe at all but good enough for now.
- if (snprintf(cmd,sizeof(cmd),"sort -t \"\t\" -r -n -k 1,1 -o \"%s\" \"%s\"",template2,template1)>=sizeof(cmd)) {
- debuga(_("Sort command too long when sorting file \"%s\" to \"%s\"\n"),template1,template2);
- exit(EXIT_FAILURE);
- }
- cstatus=system(cmd);
- if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
- debuga(_("sort command return status %d\n"),WEXITSTATUS(cstatus));
- debuga(_("sort command: %s\n"),cmd);
- exit(EXIT_FAILURE);
- }
- if (!KeepTempLog && unlink(template1)) {
- debuga(_("Cannot delete \"%s\": %s\n"),template1,strerror(errno));
- exit(EXIT_FAILURE);
+/*!
+ * \brief Store a log entry.
+ *
+ * \param Dest A pointer to the list entry where to store the entry.
+ * \param Entry The entry to store.
+ */
+static void StoreLogEntry(struct RealtimeReadLogStruct *Dest,struct ReadLogStruct *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]=='+' || url[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';
}
- datashow(template2);
+ safe_strcpy(Dest->User,Entry->User,sizeof(Dest->User));
+ safe_strcpy(Dest->HttpMethod,Entry->HttpMethod,sizeof(Dest->HttpMethod));
}
-static int getdata(char *rec, FILE *ftmp)
+static void header(void)
{
- int dat;
- char typ[128];
- char warea[MAXLEN];
+ 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;background-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",_("Auto 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 void datashow(struct RealtimeReadLogStruct *List,int Index,int Size)
+{
+ char tbuf[128];
char user[MAX_USER_LEN];
- char ip[45];
- char *url;
- struct getwordstruct gwarea;
+ char name[MAX_USER_LEN];
+ int i;
+ 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);
- }
- }
+ header();
+ for (i=0 ; i<realtime_access_log_lines ; i++)
+ {
+ 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(strncmp(user,"-",1) == 0 && RealtimeUnauthRec==REALTIME_UNAUTH_REC_IGNORE)
- return(0);
+ if (df=='u')
+ strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M", &entry->EntryTime);
+ else if (df=='e')
+ strftime(tbuf, sizeof(tbuf), "%d-%m-%Y %H:%M", &entry->EntryTime);
- fprintf(ftmp,"%d\t%s\t%s\t%s\t%s\n",dat,ip,user,url,typ);
- return(0);
+ 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,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;
- time_t tt;
- struct tm *t;
- char tbuf[128];
- int dat;
+ FILE *fp;
+ char file_name[2048];
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;
+ 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) {
- debuga(_("(realtime) open error %s - %s\n"),tmp,strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- header();
+ init_usertab(UserTabFile);
+ LogLine_Init(&log_line);
if ((line=longline_create())==NULL) {
debuga(_("Not enough memory to read the log file\n"));
exit(EXIT_FAILURE);
}
- while((buf=longline_read(fin,line))!=NULL) {
- fixendofline(buf);
- getword_start(&gwarea,buf);
- if (getword_atoi(&dat,&gwarea,'\t')<0) {
- debuga(_("Invalid time column in file %s\n"),tmp);
- exit(EXIT_FAILURE);
- }
- 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 name 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);
+ /*
+ * Store one more entry to prepare the memory structure in place and reject it if
+ * it is about the same user and url as the last stored one.
+ */
+ StoredLogEntries=calloc(realtime_access_log_lines+1,sizeof(struct RealtimeReadLogStruct));
+ if (!StoredLogEntries)
+ {
+ debuga(_("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(_("No log file to read the last %d lines from\n"),realtime_access_log_lines);
+ exit(EXIT_FAILURE);
+ }
+ fp = fopen(file_name, "r");
+ if (!fp) {
+ debuga(_("Failed to open the last modified log file \"%s\": %s\n"),file_name,strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ while((buf=longline_read(fp,line)) != NULL )
+ {
+ log_entry_status=LogLine_Parse(&log_line,&log_entry,buf);
+ if (log_entry_status==RLRC_Unknown)
+ {
+ continue;
}
- if (getword(typ,sizeof(typ),&gwarea,'\t')<0) {
- debuga(_("Invalid access type in file %s\n"),tmp);
- exit(EXIT_FAILURE);
+ if (log_entry_status==RLRC_Ignore)
+ {
+ continue;
}
- if(strstr(RealtimeTypes,typ) == 0)
+ if (log_entry.HttpMethod && strstr(RealtimeTypes,log_entry.HttpMethod)==0)
continue;
-
- if(strcmp(ouser,user) == 0 && ourl && strcmp(ourl,url) == 0)
+ if (RealtimeUnauthRec==REALTIME_UNAUTH_REC_IGNORE && log_entry.User[0]=='-' && log_entry.User[1]=='\0')
+ continue;
+ StoreLogEntry(StoredLogEntries+NextIndex,&log_entry);
+ if (strcmp(StoredLogEntries[StoreIndex].User,StoredLogEntries[NextIndex].User)==0 && strcmp(StoredLogEntries[StoreIndex].Url,StoredLogEntries[NextIndex].Url)==0)
continue;
- if(UserIp)
- strcpy(user,ip);
- strcpy(u2,user);
- if(Ip2Name)
- ip2name(u2,sizeof(u2));
- user_find(name, sizeof(name), u2);
-
- tt=(time_t)dat;
- t=localtime(&tt);
- if (df=='u')
- strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M", t);
- else if (df=='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 href=\"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);
+ StoreIndex=NextIndex;
+ NextIndex++;
+ if (NextIndex>StoreSize) StoreSize=NextIndex;
+ if (NextIndex>realtime_access_log_lines) NextIndex=0;
}
+ fclose(fp);
longline_destroy(&line);
- if (ourl) free(ourl);
-
- 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);
- }
- fflush(NULL);
-}
-static void header(void)
-{
- 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;background-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",_("Auto 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"));
+ datashow(StoredLogEntries,StoreIndex,StoreSize);
+ free(StoredLogEntries);
}