"Fossies" - the Fresh Open Source Software Archive

Member "sarg-2.4.0/useragent.c" (24 Dec 2019, 14764 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 "useragent.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 
   31 FileListObject UserAgentLog=NULL;
   32 
   33 //! Log file where the user agent data are written.
   34 static char UserAgentTempLog[MAXLEN]="";
   35 
   36 static struct tm UserAgentStartDate;
   37 static struct tm UserAgentEndDate;
   38 
   39 /*!
   40  * Open the temporary file to store the useragent entries to be
   41  * reported.
   42  *
   43  * \return The file handle. It must be closed when the data have
   44  * been written.
   45  */
   46 FILE *UserAgent_Open(void)
   47 {
   48     FILE *fp_ou=NULL;
   49 
   50     if (UserAgentTempLog[0]) {
   51         debuga(__FILE__,__LINE__,_("Useragent log already opened\n"));
   52         exit(EXIT_FAILURE);
   53     }
   54     if ((ReportType & REPORT_TYPE_USERAGENT)!=0) {
   55         format_path(__FILE__, __LINE__, UserAgentTempLog, sizeof(UserAgentTempLog), "%s/squagent.int_unsort", tmp);
   56         if ((fp_ou=fopen(UserAgentTempLog,"w"))==NULL) {
   57             debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),UserAgentTempLog,strerror(errno));
   58             exit(EXIT_FAILURE);
   59         }
   60         memset(&UserAgentStartDate,0,sizeof(UserAgentStartDate));
   61         memset(&UserAgentEndDate,0,sizeof(UserAgentEndDate));
   62     }
   63     return(fp_ou);
   64 }
   65 
   66 /*!
   67  * Write a user agent entry into the temporary log.
   68  *
   69  * \param fp The file opened by UserAgent_Open().
   70  * \param Ip The IP address using this agent.
   71  * \param User The user name.
   72  * \param Agent The user agent string.
   73  */
   74 void UserAgent_Write(FILE *fp,const struct tm *Time,const char *Ip,const char *User,const char *Agent)
   75 {
   76     if (fp) {
   77         if (useragent_count==0 || compare_date(&UserAgentStartDate,Time)>0)
   78             memcpy(&UserAgentStartDate,Time,sizeof(UserAgentStartDate));
   79         if (useragent_count==0 || compare_date(&UserAgentEndDate,Time)<0)
   80             memcpy(&UserAgentEndDate,Time,sizeof(UserAgentEndDate));
   81         fprintf(fp,"%s\t%s\t%s\n",Ip,Agent,User);
   82         useragent_count++;
   83     }
   84 }
   85 
   86 /*!
   87  * Read the user provided useragent file and create
   88  * a temporary file with the data to report.
   89  */
   90 void UserAgent_Readlog(const struct ReadLogDataStruct *ReadFilter)
   91 {
   92     FileObject *fp_log;
   93     FILE *fp_ou = NULL;
   94     char *ptr;
   95     char ip[80], data[50], agent[MAXLEN], user[MAXLEN];
   96     int day,month,year;
   97     char monthname[5];
   98     int hour,min;
   99     const char *FileName;
  100     unsigned long totregsl=0;
  101     int ndate;
  102     struct getwordstruct gwarea, gwarea1;
  103     longline line;
  104     FileListIterator FIter;
  105     struct tm logtime;
  106     int dfrom;
  107     int duntil;
  108 
  109     fp_ou=UserAgent_Open();
  110 
  111     if ((line=longline_create())==NULL) {
  112         debuga(__FILE__,__LINE__,_("Not enough memory to read useragent log\n"));
  113         exit(EXIT_FAILURE);
  114     }
  115     memset(&logtime,0,sizeof(logtime));
  116     getperiod_torange(&period,&dfrom,&duntil);
  117 
  118     FIter=FileListIter_Open(UserAgentLog);
  119     while ((FileName=FileListIter_Next(FIter))!=NULL)
  120     {
  121         longline_reset(line);
  122         if ((fp_log=decomp(FileName))==NULL) {
  123             debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),FileName,FileObject_GetLastOpenError());
  124             exit(EXIT_FAILURE);
  125         }
  126 
  127         if (debug) {
  128             debuga(__FILE__,__LINE__,_("Reading useragent log \"%s\"\n"),FileName);
  129         }
  130 
  131         while ((ptr=longline_read(fp_log,line))!=NULL) {
  132             totregsl++;
  133             getword_start(&gwarea,ptr);
  134             if (getword(ip,sizeof(ip),&gwarea,' ')<0 || getword_skip(10,&gwarea,'[')<0 ||
  135                 getword(data,sizeof(data),&gwarea,' ')<0) {
  136                 debuga(__FILE__,__LINE__,_("Invalid record in file \"%s\"\n"),FileName);
  137                 exit(EXIT_FAILURE);
  138             }
  139             getword_start(&gwarea1,data);
  140             if (getword_atoi(&day,&gwarea1,'/')<0 || getword(monthname,sizeof(monthname),&gwarea1,'/')<0 ||
  141                 getword_atoi(&year,&gwarea1,':')<0) {
  142                 debuga(__FILE__,__LINE__,_("Invalid date in file \"%s\"\n"),FileName);
  143                 exit(EXIT_FAILURE);
  144             }
  145             month=month2num(monthname)+1;
  146             if (month>12) {
  147                 debuga(__FILE__,__LINE__,_("Invalid month name \"%s\" found in user agent file \"%s\""),monthname,FileName);
  148                 exit(EXIT_FAILURE);
  149             }
  150             if (dfrom!=0 || duntil!=0){
  151                 ndate=year*10000+month*100+day;
  152                 if (ndate<dfrom) continue;
  153                 if (ndate>duntil) break;
  154             }
  155             if (getword_atoi(&hour,&gwarea1,':')<0 || getword_atoi(&min,&gwarea1,':')<0) {
  156                 debuga(__FILE__,__LINE__,_("Invalid time in file \"%s\"\n"),FileName);
  157                 exit(EXIT_FAILURE);
  158             }
  159             if (ReadFilter->StartTime>=0 || ReadFilter->EndTime>=0)
  160             {
  161                 int hmr=hour*100+min;
  162                 if (hmr<ReadFilter->StartTime || hmr>=ReadFilter->EndTime)
  163                     continue;
  164             }
  165             logtime.tm_year=year-1900;
  166             logtime.tm_mon=month-1;
  167             logtime.tm_mday=day;
  168             if (getword_skip(MAXLEN,&gwarea,'"')<0 || getword(agent,sizeof(agent),&gwarea,'"')<0) {
  169                 debuga(__FILE__,__LINE__,_("Invalid useragent in file \"%s\"\n"),FileName);
  170                 exit(EXIT_FAILURE);
  171             }
  172 
  173             if (gwarea.current[0]!='\0') {
  174                 if (getword_skip(MAXLEN,&gwarea,' ')<0 || getword(user,sizeof(user),&gwarea,'\n')<0) {
  175                     debuga(__FILE__,__LINE__,_("Invalid record in file \"%s\"\n"),FileName);
  176                     exit(EXIT_FAILURE);
  177                 }
  178                 if (user[0] == '-')
  179                     strcpy(user,ip);
  180                 if (user[0] == '\0')
  181                     strcpy(user,ip);
  182             } else {
  183                 strcpy(user,ip);
  184             }
  185 
  186             UserAgent_Write(fp_ou,&logtime,ip,user,agent);
  187         }
  188 
  189         if (FileObject_Close(fp_log)==EOF) {
  190             debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),FileName,FileObject_GetLastCloseError());
  191             exit(EXIT_FAILURE);
  192         }
  193     }
  194     FileListIter_Close(FIter);
  195     longline_destroy(&line);
  196 
  197     if (debug) {
  198         debuga(__FILE__,__LINE__,_("   Records read: %ld\n"),totregsl);
  199     }
  200 
  201     if (fclose(fp_ou)==EOF) {
  202         debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),UserAgentTempLog,strerror(errno));
  203         exit(EXIT_FAILURE);
  204     }
  205 }
  206 
  207 void UserAgent(void)
  208 {
  209     FILE *fp_in = NULL, *fp_ou = NULL, *fp_ht = NULL;
  210     char buf[MAXLEN];
  211     char ip[80], agent[MAXLEN], user[MAXLEN];
  212     char ipbefore[MAXLEN]="";
  213     char namebefore[MAXLEN]="";
  214     char tagent[MAXLEN];
  215     char user_old[MAXLEN]="";
  216     char agent_old[MAXLEN]="";
  217     char hfile[MAXLEN];
  218     char idate[100], fdate[100];
  219     char tmp2[MAXLEN];
  220     char tmp3[MAXLEN];
  221     char csort[MAXLEN];
  222     int  agentot=0, agentot2=0, agentdif=0, cont=0, nagent;
  223     int cstatus;
  224     double perc;
  225     struct getwordstruct gwarea;
  226 
  227     if (!UserAgentTempLog[0] || useragent_count==0) return;
  228 
  229     format_path(__FILE__, __LINE__, tmp2, sizeof(tmp2), "%s/squagent.int_log", tmp);
  230     if (debug) {
  231         debuga(__FILE__,__LINE__,_("Sorting file \"%s\"\n"),tmp2);
  232     }
  233 
  234     if (snprintf(csort,sizeof(csort),"sort -n -t \"\t\" -k 3,3 -k 2,2 -k 1,1 -o \"%s\" \"%s\"",tmp2,UserAgentTempLog)>=sizeof(csort)) {
  235         debuga(__FILE__,__LINE__,_("Sort command too long when sorting file \"%s\" to \"%s\"\n"),tmp2,UserAgentTempLog);
  236         exit(EXIT_FAILURE);
  237     }
  238     cstatus=system(csort);
  239     if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
  240         debuga(__FILE__,__LINE__,_("sort command return status %d\n"),WEXITSTATUS(cstatus));
  241         debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort);
  242         exit(EXIT_FAILURE);
  243     }
  244     if ((fp_in=fopen(tmp2,"r"))==NULL) {
  245         debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),tmp2,strerror(errno));
  246         debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort);
  247         exit(EXIT_FAILURE);
  248     }
  249 
  250     if (!KeepTempLog && unlink(UserAgentTempLog)) {
  251         debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),UserAgentTempLog,strerror(errno));
  252         exit(EXIT_FAILURE);
  253     }
  254 
  255     format_path(__FILE__, __LINE__, hfile, sizeof(hfile), "%s/useragent.html", outdirname);
  256     if ((fp_ht=fopen(hfile,"w"))==NULL) {
  257         debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),hfile,strerror(errno));
  258         exit(EXIT_FAILURE);
  259     }
  260 
  261     if (debug)
  262         debuga(__FILE__,__LINE__,_("Making Useragent report\n"));
  263 
  264     write_html_header(fp_ht,(IndexTree == INDEX_TREE_DATE) ? 3 : 1,_("Squid Useragent's Report"),HTML_JS_NONE);
  265     fprintf(fp_ht,"<tr><th class=\"header_c\">%s</th></tr>\n",_("Squid Useragent's Report"));
  266     strftime(idate,sizeof(idate),"%x",&UserAgentStartDate);
  267     strftime(fdate,sizeof(fdate),"%x",&UserAgentEndDate);
  268     fprintf(fp_ht,"<tr><td class=\"header_c\">%s: %s - %s</td></tr>\n",_("Period"),idate,fdate);
  269     close_html_header(fp_ht);
  270 
  271     fputs("<br><br>\n",fp_ht);
  272 
  273     fputs("<div class=\"report\"><table cellpadding=\"0\" cellspacing=\"0\">\n",fp_ht);
  274     fputs("<tr><td>&nbsp;</td><td>&nbsp;</td></tr>",fp_ht);
  275 
  276     fprintf(fp_ht,"<tr><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th></tr>\n",_("USERID"),_("AGENT"));
  277 
  278     while (fgets(buf,sizeof(buf),fp_in)!=NULL) {
  279         getword_start(&gwarea,buf);
  280         if (getword(ip,sizeof(ip),&gwarea,'\t')<0) {
  281             debuga(__FILE__,__LINE__,_("Invalid IP address in file \"%s\"\n"),tmp2);
  282             exit(EXIT_FAILURE);
  283         }
  284 
  285         if (Ip2Name) {
  286             if (strcmp(ip,ipbefore) != 0) {
  287                 strcpy(ipbefore,ip);
  288                 ip2name(ip,sizeof(ip));
  289                 strcpy(namebefore,ip);
  290             } else strcpy(ip,namebefore);
  291         }
  292 
  293         if (getword(agent,sizeof(agent),&gwarea,'\t')<0) {
  294             debuga(__FILE__,__LINE__,_("Invalid useragent in file \"%s\"\n"),tmp2);
  295             exit(EXIT_FAILURE);
  296         }
  297         if (getword(user,sizeof(user),&gwarea,'\t')<0) {
  298             debuga(__FILE__,__LINE__,_("Invalid user ID in file \"%s\"\n"),tmp2);
  299             exit(EXIT_FAILURE);
  300         }
  301 
  302         if (strcmp(user,user_old) != 0) {
  303             fprintf(fp_ht,"<tr><td class=\"data2\">%s</td><td class=\"data2\">",user);
  304             output_html_string(fp_ht,agent,250);
  305             fputs("</td></tr>\n",fp_ht);
  306             strcpy(user_old,user);
  307             strcpy(agent_old,agent);
  308         } else if (strcmp(agent,agent_old) != 0) {
  309             fputs("<tr><td></td><td class=\"data2\">",fp_ht);
  310             output_html_string(fp_ht,agent,250);
  311             fputs("</td></tr>\n",fp_ht);
  312             strcpy(agent_old,agent);
  313         }
  314     }
  315 
  316     fputs("</table>\n",fp_ht);
  317     if (fclose(fp_in)==EOF) {
  318         debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),tmp2,strerror(errno));
  319         exit(EXIT_FAILURE);
  320     }
  321 
  322     format_path(__FILE__, __LINE__, tmp3, sizeof(tmp3), "%s/squagent2.int_log", tmp);
  323     if (snprintf(csort,sizeof(csort),"sort -t \"\t\" -k 2,2 -o \"%s\" \"%s\"",tmp3,tmp2)>=sizeof(csort)) {
  324         debuga(__FILE__,__LINE__,_("Sort command too long when sorting file \"%s\" to \"%s\"\n"),tmp2,tmp3);
  325         exit(EXIT_FAILURE);
  326     }
  327     cstatus=system(csort);
  328     if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
  329         debuga(__FILE__,__LINE__,_("sort command return status %d\n"),WEXITSTATUS(cstatus));
  330         debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort);
  331         exit(EXIT_FAILURE);
  332     }
  333     if ((fp_in=fopen(tmp3,"r"))==NULL) {
  334         debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),tmp3,strerror(errno));
  335         debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort);
  336         exit(EXIT_FAILURE);
  337     }
  338 
  339     if (!KeepTempLog && unlink(tmp2)) {
  340         debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),tmp2,strerror(errno));
  341         exit(EXIT_FAILURE);
  342     }
  343 
  344     if ((fp_ou=fopen(tmp2,"w"))==NULL) {
  345         debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),tmp2,strerror(errno));
  346         exit(EXIT_FAILURE);
  347     }
  348 
  349     agent_old[0]='\0';
  350     cont=0;
  351 
  352     while (fgets(buf,sizeof(buf),fp_in)!=NULL) {
  353         getword_start(&gwarea,buf);
  354         if (getword(ip,sizeof(ip),&gwarea,'\t')<0) {
  355             debuga(__FILE__,__LINE__,_("Invalid IP address in file \"%s\"\n"),tmp3);
  356             exit(EXIT_FAILURE);
  357         }
  358         if (getword(agent,sizeof(agent),&gwarea,'\t')<0) {
  359             debuga(__FILE__,__LINE__,_("Invalid useragent in file \"%s\"\n"),tmp3);
  360             exit(EXIT_FAILURE);
  361         }
  362 
  363         if (!cont) {
  364             cont++;
  365             strcpy(agent_old,agent);
  366         }
  367 
  368         if (strcmp(agent,agent_old) != 0) {
  369             agentdif++;
  370             fprintf(fp_ou,"%06d %s\n",agentot,agent_old);
  371             strcpy(agent_old,agent);
  372             agentot2+=agentot;
  373             agentot=0;
  374         }
  375         agentot++;
  376     }
  377     agentdif++;
  378     fprintf(fp_ou,"%06d %s\n",agentot,agent);
  379     agentot2+=agentot;
  380 
  381     if (fclose(fp_ou)==EOF) {
  382         debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),tmp2,strerror(errno));
  383         exit(EXIT_FAILURE);
  384     }
  385     if (fclose(fp_in)==EOF) {
  386         debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),tmp3,strerror(errno));
  387         exit(EXIT_FAILURE);
  388     }
  389 
  390     if (!KeepTempLog && unlink(tmp3)) {
  391         debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),tmp3,strerror(errno));
  392         exit(EXIT_FAILURE);
  393     }
  394 
  395     if (snprintf(csort,sizeof(csort),"sort -n -r -k 1,1 -o \"%s\" \"%s\"",tmp3,tmp2)>=sizeof(csort)) {
  396         debuga(__FILE__,__LINE__,_("Sort command too long when sorting file \"%s\" to \"%s\"\n"),tmp2,tmp3);
  397         exit(EXIT_FAILURE);
  398     }
  399     cstatus=system(csort);
  400     if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
  401         debuga(__FILE__,__LINE__,_("sort command return status %d\n"),WEXITSTATUS(cstatus));
  402         debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort);
  403         exit(EXIT_FAILURE);
  404     }
  405     if ((fp_in=fopen(tmp3,"r"))==NULL) {
  406         debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),tmp3,strerror(errno));
  407         debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort);
  408         exit(EXIT_FAILURE);
  409     }
  410 
  411     if (!KeepTempLog && unlink(tmp2)) {
  412         debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),tmp2,strerror(errno));
  413         exit(EXIT_FAILURE);
  414     }
  415 
  416     fputs("<br><br>\n",fp_ht);
  417 
  418     fputs("<table cellpadding=\"0\" cellspacing=\"0\">\n",fp_ht);
  419     fprintf(fp_ht,"<tr><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th><th class=\"header_c\">%%</th></tr>\n",_("AGENT"),_("TOTAL"));
  420 
  421     perc=0.;
  422     while(fgets(buf,sizeof(buf),fp_in)!=NULL) {
  423         fixendofline(buf);
  424         getword_start(&gwarea,buf);
  425         if (getword(tagent,sizeof(tagent),&gwarea,' ')<0) {
  426             debuga(__FILE__,__LINE__,_("Invalid useragent in file \"%s\"\n"),tmp3);
  427             exit(EXIT_FAILURE);
  428         }
  429         nagent=atoi(tagent);
  430         perc=(agentot2>0) ? nagent * 100. / agentot2 : 0.;
  431 
  432         fputs("<tr><td class=\"data2\">",fp_ht);
  433         output_html_string(fp_ht,gwarea.current,250);
  434         fprintf(fp_ht,"</td><td class=\"data\">%d</td><td class=\"data\">%3.2lf</td></tr>\n",nagent,perc);
  435     }
  436     if (fclose(fp_in)==EOF) {
  437         debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),tmp3,strerror(errno));
  438         exit(EXIT_FAILURE);
  439     }
  440 
  441     fputs("</table></div>\n",fp_ht);
  442     write_html_trailer(fp_ht);
  443     if (fclose(fp_ht)==EOF) {
  444         debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),hfile,strerror(errno));
  445         exit(EXIT_FAILURE);
  446     }
  447 
  448     if (!KeepTempLog && unlink(tmp3)) {
  449         debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),tmp3,strerror(errno));
  450         exit(EXIT_FAILURE);
  451     }
  452 
  453     return;
  454 }