"Fossies" - the Fresh Open Source Software Archive

Member "sarg-2.4.0/realtime.c" (24 Dec 2019, 8026 Bytes) of package /linux/privat/sarg-2.4.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "realtime.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.3.11_vs_2.4.0.

    1 /*
    2  * SARG Squid Analysis Report Generator      http://sarg.sourceforge.net
    3  *                                                            1998, 2015
    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 #include "include/filelist.h"
   30 #include "include/readlog.h"
   31 
   32 //! Maximum length of the scheme plus host name from the url.
   33 #define MAX_URL_HOST_LEN 260
   34 
   35 /*!
   36 \brief Data read from an input log file.
   37 */
   38 struct RealtimeReadLogStruct
   39 {
   40     //! The time corresponding to the entry.
   41     struct tm EntryTime;
   42     //! The IP address connecting to internet.
   43     char Ip[48];
   44     //! The user's name.
   45     char User[MAX_USER_LEN];
   46     /*!
   47     The URL of the visited site.
   48 
   49     The pointer may be NULL if the URL doesn't exists in the log file.
   50     */
   51     char Url[MAX_URL_HOST_LEN];
   52     //! HTTP method or NULL if the information is not stored in the log.
   53     char HttpMethod[32];
   54 };
   55 
   56 extern FileListObject AccessLog;
   57 
   58 static bool GetLatestModified(char *file_name,int file_name_size)
   59 {
   60     FileListIterator FIter;
   61     const char *file;
   62     bool found=false;
   63     struct stat st;
   64     time_t latest;
   65 
   66     FIter=FileListIter_Open(AccessLog);
   67     while ((file=FileListIter_Next(FIter))!=NULL)
   68     {
   69         if (stat(file,&st)==-1) {
   70             debuga(__FILE__,__LINE__,_("Cannot stat \"%s\": %s\n"),file,strerror(errno));
   71         }
   72         if (!found)
   73         {
   74             found=true;
   75             latest=st.st_mtime;
   76             safe_strcpy(file_name,file,file_name_size);
   77         }
   78         else if (st.st_mtime>latest)
   79         {
   80             latest=st.st_mtime;
   81             safe_strcpy(file_name,file,file_name_size);
   82         }
   83     }
   84     FileListIter_Close(FIter);
   85     return(found);
   86 }
   87 
   88 /*!
   89  * \brief Store a log entry.
   90  *
   91  * \param Dest A pointer to the list entry where to store the entry.
   92  * \param Entry The entry to store.
   93  */
   94 static void StoreLogEntry(struct RealtimeReadLogStruct *Dest,struct ReadLogStruct *Entry)
   95 {
   96     memcpy(&Dest->EntryTime,&Entry->EntryTime,sizeof(Dest->EntryTime));
   97     safe_strcpy(Dest->Ip,Entry->Ip,sizeof(Dest->Ip));
   98     if (Entry->Url)
   99     {
  100         int i;
  101         const char *url=Entry->Url;
  102 
  103         // skip the scheme
  104         for (i=0 ; i<8 && url[i] && (isalnum(url[i]) || url[i]=='+' || url[i]=='-' || url[i]=='.') ; i++);
  105         if (url[i]==':' && url[i+1]=='/' && url[i+2]=='/')
  106         {
  107             url+=i+3;
  108             for (i=0 ; url[i] && url[i]!='/' ; i++);
  109         }
  110         if (i>=sizeof(Dest->Url)) i=sizeof(Dest->Url)-1;
  111         strncpy(Dest->Url,url,i);
  112         Dest->Url[i]='\0';
  113     }
  114     safe_strcpy(Dest->User,Entry->User,sizeof(Dest->User));
  115     safe_strcpy(Dest->HttpMethod,Entry->HttpMethod,sizeof(Dest->HttpMethod));
  116 }
  117 
  118 static void header(void)
  119 {
  120     puts("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"");
  121     puts(" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
  122     puts("<html>\n");
  123     puts("<head>\n");
  124     if (realtime_refresh)
  125         printf("  <meta http-equiv=refresh content=\"%d\" url=\"sarg-php/sarg-realtime.php\"; charset=\"%s\">\n",realtime_refresh,CharSet);
  126     else
  127         printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">\n",CharSet);
  128     css(stdout);
  129     puts("</head>\n");
  130     printf("<body style=\"font-family:%s;font-size:%s;background-color:%s;background-image:url(%s)\">\n",FontFace,TitleFontSize,BgColor,BgImage);
  131     puts("<div align=\"center\"><table cellpadding=\"1\" cellspacing=\"1\">\n");
  132     printf("<tr><th class=\"title_l\" colspan=\"10\">SARG %s</th></tr>\n",_("Realtime"));
  133     printf("<tr><th class=\"text\" colspan=\"10\">%s: %d s</th></tr>\n",_("Auto refresh"),realtime_refresh);
  134     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"));
  135 }
  136 
  137 static void datashow(struct RealtimeReadLogStruct *List,int Index,int Size)
  138 {
  139     char tbuf[128];
  140     char user[MAX_USER_LEN];
  141     char name[MAX_USER_LEN];
  142     int i;
  143     struct RealtimeReadLogStruct *entry;
  144 
  145     header();
  146     for (i=0 ; i<realtime_access_log_lines ; i++)
  147     {
  148         entry=List+Index;
  149         Index--;
  150         if (Index<0) Index=Size-1;
  151 
  152         if (UserIp)
  153             strcpy(user,entry->Ip);
  154         else
  155             strcpy(user,entry->User);
  156         if (Ip2Name)
  157             ip2name(user,sizeof(user));
  158         user_find(name, sizeof(name), user);
  159 
  160         if (df=='u')
  161             strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M", &entry->EntryTime);
  162         else if (df=='e')
  163             strftime(tbuf, sizeof(tbuf), "%d-%m-%Y %H:%M", &entry->EntryTime);
  164 
  165         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",
  166                tbuf,entry->Ip,name,entry->HttpMethod,entry->Url,entry->Url);
  167     }
  168 
  169     puts("</table>\n</div>\n</body>\n</html>\n");
  170     fflush(NULL);
  171 }
  172 
  173 void realtime(void)
  174 {
  175     FileObject *fp;
  176     char file_name[2048];
  177     char *buf;
  178     longline line;
  179     struct ReadLogStruct log_entry;
  180     enum ReadLogReturnCodeEnum log_entry_status;
  181     struct LogLineStruct log_line;
  182     struct RealtimeReadLogStruct *StoredLogEntries;
  183     int StoreIndex=0;
  184     int StoreSize=0;
  185     int NextIndex=1;
  186 
  187     init_usertab(UserTabFile);
  188     LogLine_Init(&log_line);
  189 
  190     /*
  191      * Store one more entry to prepare the memory structure in place and reject it if
  192      * it is about the same user and url as the last stored one.
  193      */
  194     StoredLogEntries=calloc(realtime_access_log_lines+1,sizeof(struct RealtimeReadLogStruct));
  195     if (!StoredLogEntries)
  196     {
  197         debuga(__FILE__,__LINE__,_("Not enough memory to store %d records"),realtime_access_log_lines);
  198         exit(EXIT_FAILURE);
  199     }
  200     /*
  201      * Clear the url and user strings so that strcmp on the user and url are not
  202      * satisfied and the first entry can be stored.
  203      */
  204     memset(StoredLogEntries,0,sizeof(struct RealtimeReadLogStruct));
  205 
  206     if (!GetLatestModified(file_name,sizeof(file_name)))
  207     {
  208         debuga(__FILE__,__LINE__,_("No log file to read the last %d lines from\n"),realtime_access_log_lines);
  209         exit(EXIT_FAILURE);
  210     }
  211     fp = FileObject_Open(file_name);
  212     if (!fp) {
  213         debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),file_name,FileObject_GetLastOpenError());
  214         exit(EXIT_FAILURE);
  215     }
  216 
  217     if ((line=longline_create())==NULL) {
  218         debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\"\n"),file_name);
  219         exit(EXIT_FAILURE);
  220     }
  221 
  222     while((buf=longline_read(fp,line)) != NULL )
  223     {
  224         log_entry_status=LogLine_Parse(&log_line,&log_entry,buf);
  225         if (log_entry_status==RLRC_Unknown)
  226         {
  227             continue;
  228         }
  229         if (log_entry_status==RLRC_Ignore)
  230         {
  231             continue;
  232         }
  233         if (log_entry.HttpMethod && strstr(RealtimeTypes,log_entry.HttpMethod)==0)
  234             continue;
  235         if (RealtimeUnauthRec==REALTIME_UNAUTH_REC_IGNORE && log_entry.User[0]=='-' && log_entry.User[1]=='\0')
  236             continue;
  237         StoreLogEntry(StoredLogEntries+NextIndex,&log_entry);
  238         if (strcmp(StoredLogEntries[StoreIndex].User,StoredLogEntries[NextIndex].User)==0 && strcmp(StoredLogEntries[StoreIndex].Url,StoredLogEntries[NextIndex].Url)==0)
  239             continue;
  240 
  241         StoreIndex=NextIndex;
  242         NextIndex++;
  243         if (NextIndex>StoreSize) StoreSize=NextIndex;
  244         if (NextIndex>realtime_access_log_lines) NextIndex=0;
  245     }
  246     if (FileObject_Close(fp)) {
  247         debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),file_name,FileObject_GetLastCloseError());
  248         exit(EXIT_FAILURE);
  249     }
  250     longline_destroy(&line);
  251 
  252     datashow(StoredLogEntries,StoreIndex,StoreSize);
  253     free(StoredLogEntries);
  254 }