]> git.ipfire.org Git - thirdparty/sarg.git/commitdiff
Index created using an internal sort algorithm instead of a system call
authorFrédéric Marchal <fmarchal@users.sourceforge.net>
Sun, 3 Jan 2010 18:27:14 +0000 (18:27 +0000)
committerFrédéric Marchal <fmarchal@users.sourceforge.net>
Sun, 3 Jan 2010 18:27:14 +0000 (18:27 +0000)
CMakeLists.txt
ChangeLog
documentation/index.txt
include/conf.h
include/info.h
index.c
log.c
util.c

index ada1bbd501a2361781637d3db912f1b13f51b32c..afac3fc37f0265c253a8ef7550436edb1a43510d 100755 (executable)
@@ -3,7 +3,7 @@ PROJECT(sarg C)
 SET(sarg_VERSION 2)
 SET(sarg_REVISION 2)
 SET(sarg_BUILD "7rc1")
-SET(sarg_BUILDDATE "Dec-27-2009")
+SET(sarg_BUILDDATE "Jan-03-2010")
 
 INCLUDE(AddFileDependencies)
 INCLUDE(CheckIncludeFile)
index 1cc87aab1e975bf144284ae9b115ed9ab30829f5..0ad3ad4ea50e2169e17f779424a0f898ca49fd01 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,6 @@
 SARG ChangeLog
 
-Dec-31-2009 Version 2.2.7
+Jan-01-2010 Version 2.2.7
                - Extra compile and run time protection (FORTIFY_SOURCE) fixed in configure.
                - Use tabulations as columns separator in intermediary files to avoid problems when a field of the log contains a space.
                - Input log file type detection partly rewritten to clearly distinguish which type is processed where.
@@ -16,6 +16,7 @@ Dec-31-2009 Version 2.2.7
                - Protect the creation of the index against invalid directories.
                - Only copy the files when creating the directory with the images to link the reports to.
                - Directories deleted without using the rm system command.
+               - Index created using an internal sort algorithm instead of a system call.
 
 Dec-31-2009 Version 2.2.6.1
                - Remove unnecessary dependency on off_t.
index 783b0c778b4433e43042be8632989610d0017740..176b3a337a14d20fb27152fbc7c5eee7651ac688 100644 (file)
@@ -13,6 +13,25 @@ Create the main HTML index of the available reports.
 
 
 
+/*! \fn static void make_date_index(void)
+Create an index with the reports sorted hierarchicaly by date. A first level lists
+the year. The second level lists the months (possibly a range) and the third level
+lists the days or day ranges.
+*/
+
+
+
+
+
+/*! \fn static void make_file_index(void)
+Create an index with the reports sorted by directory name. There is only one level
+which is the name of the directory containing the report.
+*/
+
+
+
+
+
 /*! \fn static void file_index_to_date_index(const char *entry)
 Convert a report from the file tree into a report for a date tree.
 
index 9ec03fc3b87413b0a3a0c8f35a715e38894622ae..416a77e2bd353659bbb0af512c70dad0cbe9aa7b 100755 (executable)
@@ -162,7 +162,6 @@ char href2[MAXLEN];
 char href3[MAXLEN];
 char df[20];
 char day[3], month[4], year[5];
-char nmonth[30];
 char ltext110[50];
 char cdfrom[30];
 char cduntil[30];
index fe1969c5410b6242ad863b94105dd1cd90f5978c..e894c49fc93c7da3755c5a2e9046ec327373ae5e 100755 (executable)
@@ -1,3 +1,3 @@
-#define VERSION PACKAGE_VERSION" Dec-27-2009"
+#define VERSION PACKAGE_VERSION" Jan-03-2010"
 #define PGM PACKAGE_NAME
 #define URL "http://sarg.sourceforge.net"
diff --git a/index.c b/index.c
index 6b5d34f88fb3ce9d6a18967e8152759605202c57..ffd57c595a2d7a68d160bd805cf13c7e52954ce5 100644 (file)
--- a/index.c
+++ b/index.c
@@ -1,6 +1,6 @@
 /*
  * AUTHOR: Pedro Lineu Orso                         pedro.orso@gmail.com
- *                                                            1998, 2008
+ *                                                            1998, 2010
  * SARG Squid Analysis Report Generator      http://sarg.sourceforge.net
  *
  * SARG donations:
 #include "include/conf.h"
 #include "include/defs.h"
 
+static void make_date_index(void);
+static void make_file_index(void);
 static void file_index_to_date_index(const char *entry);
 static void date_index_to_file_index(const char *entry);
 
 void make_index(void)
 {
-   FILE *fp_ou, *fp_ou2, *fp_ou3, *fp_tmp, *fp_tmp2, *fp_tmp3;
-   DIR *dirp, *dirp2, *dirp3;
+   DIR *dirp;
    struct dirent *direntp;
-   struct dirent *direntp2;
-   struct dirent *direntp3;
-   char html[MAXLEN];
    char wdir[MAXLEN];
-   char wdir_tmp[MAXLEN];
-   char wdir_tmp2[MAXLEN];
-   char wdir_tmp3[MAXLEN];
-   char newname[512];
-   char month[4];
-   char period[80];
-   char data[80];
-   char tuser[20];
-   char tbytes[20];
-   char media[20];
-   char ftime[128];
-   char day[16], mon[16], year[40], hour[10];
-   char *str;
-   char tmp2[MAXLEN];
-   int cstatus;
-   int iyear, imonth, iday, ihour, iminute, isecond, idst;
-   struct getwordstruct gwarea;
 
    if(LastLog[0] != '\0') mklastlog(outdir);
 
-   sprintf(wdir,"%sindex.html",outdir);
-   sprintf(wdir_tmp,"%sindex.unsort",outdir);
-   sprintf(wdir_tmp2,"%sindex.sort",outdir);
-   strcpy(hbc1,"class=\"header\"");
-
    if(strcmp(Index,"no") == 0) {
+      sprintf(wdir,"%sindex.html",outdir);
       if(access(wdir, R_OK) == 0) unlink(wdir);
       return;
    }
@@ -81,266 +58,349 @@ void make_index(void)
       }
    }
 
-   if((fp_tmp=fopen(wdir_tmp,"w"))==NULL) {
-      fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir_tmp);
-      exit(1);
+   if(strcmp(IndexTree,"date") == 0) {
+      make_date_index();
+   } else {
+      make_file_index();
    }
+}
 
-   rewinddir(dirp);
+static void make_date_index(void)
+{
+   FILE *fp_ou, *fp_ou2, *fp_ou3;
+   DIR *dirp, *dirp2, *dirp3;
+   struct dirent *direntp;
+   struct dirent *direntp2;
+   struct dirent *direntp3;
+   char hbc1[30];
+   char yearindex[MAXLEN];
+   char yeardir[MAXLEN];
+   char yearnum[10];
+   char monthindex[MAXLEN];
+   char monthdir[MAXLEN];
+   char monthname1[9], monthname2[9];
+   char nmonth[30];
+   char monthnum[10];
+   char dayindex[MAXLEN];
+   char daynum[10];
+   int yearsort[150];
+   int nyears;
+   int year;
+   int monthsort[144];
+   int nmonths;
+   int m1, m2, month;
+   int daysort[31*31];
+   int ndays;
+   int d1, d2, day;
+   int i, y, m, d;
+   int order;
+
+   sprintf(yearindex,"%sindex.html",outdir);
+   strcpy(hbc1,"class=\"header\"");
+
+   nyears=0;
+   dirp = opendir(outdir);
    while ((direntp = readdir( dirp )) != NULL) {
-      if(strcmp(IndexTree,"date") == 0) {
-         if(strlen(direntp->d_name) > 4 || !isdigit(direntp->d_name[0]) || !isdigit(direntp->d_name[1]) ||
-            !isdigit(direntp->d_name[2]) || !isdigit(direntp->d_name[3])) continue;
-         fprintf(fp_tmp,"%s\t%s\n",direntp->d_name,get_size(outdir,direntp->d_name));
-      } else {
-         if(strchr(direntp->d_name,'-') == 0) continue;
-         bzero(newname, sizeof(newname));
-         if(strcmp(df,"u") == 0) {
-            strncat(newname,direntp->d_name,4);
-            strncpy(month,direntp->d_name+4,3);
-         } else {
-            strncat(newname,direntp->d_name+5,4);
-            strncpy(month,direntp->d_name+2,3);
+      if(strlen(direntp->d_name) > 4 || !isdigit(direntp->d_name[0]) || !isdigit(direntp->d_name[1]) ||
+         !isdigit(direntp->d_name[2]) || !isdigit(direntp->d_name[3])) continue;
+      year=atoi(direntp->d_name);
+      if (nyears>=sizeof(yearsort)/sizeof(yearsort[0])) {
+         /*
+         If too many years are listed in the directory, we ignore the earliest years. The yearsort array
+         is big enough to accomodate the most ambitious use of sarg but this safety is added to prevent
+         a crash should the directory be polluted by other entries.
+         */
+         if (year>yearsort[0]) {
+            for (i=1 ; i<nyears && year>yearsort[i] ; i++)
+               yearsort[i-1]=yearsort[i];
+            yearsort[i-1]=year;
          }
-         month[3]='\0';
-         conv_month(month);
-         strcat(newname,month);
-         if(strcmp(df,"u") == 0) strncat(newname,direntp->d_name+7,2);
-         else strncat(newname,direntp->d_name,2);
-         obtdate(outdir,direntp->d_name,data);
-         obtuser(outdir,direntp->d_name,tuser);
-         obttotal(outdir,direntp->d_name,tbytes,tuser,media);
-         if (sscanf(data,"%d-%d-%d %d:%d:%d %d",&iyear,&imonth,&iday,&ihour,&iminute,&isecond,&idst)==7) {
-            formatdate(data,sizeof(data),iyear,imonth,iday,ihour,iminute,isecond,idst);
-            fprintf(fp_tmp,"%04d%02d%02d%02d%02d%02d;%s;%s;%s;%s;%s;%s\n",iyear,imonth,iday,ihour,iminute,isecond, direntp->d_name, data, tuser, tbytes, media,newname);
-         } else {
-            /*
-            Old code to parse a date stored by sarg before 2.2.6.1 in the sarg-date file of each report directory.
-            */
-            getword_start(&gwarea,data);
-            if (getword_multisep(mon,sizeof(mon),&gwarea,' ')<0) {
-               printf("SARG: Maybe you have a broken week day in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
-               exit(1);
-            }
-            if (getword_multisep(mon,sizeof(mon),&gwarea,' ')<0) {
-               printf("SARG: Maybe you have a broken month in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
-               exit(1);
-            }
-            if (getword_multisep(day,sizeof(day),&gwarea,' ')<0) {
-               printf("SARG: Maybe you have a broken day in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
-               exit(1);
-            }
-            if (getword_multisep(hour,sizeof(hour),&gwarea,' ')<0) {
-               printf("SARG: Maybe you have a broken time in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
-               exit(1);
-            }
-            do {
-               if (getword_multisep(year,sizeof(year),&gwarea,' ')<0) {
-                  printf("SARG: Maybe you have a broken year in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
-                  exit(1);
-               }
-            } while (year[0] && !isdigit(year[0])); //skip time zone information with spaces until the year is found
-            strcpy(html,hour);
-            if (sscanf(hour,"%d:%d:%d",&ihour,&iminute,&isecond)!=3) {
-               printf("SARG: Maybe you have a broken time in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
-               exit(1);
-            }
-            buildymd(day,mon,year,ftime);
-            fprintf(fp_tmp,"%s%02d%02d%02d;%s;%s;%s;%s;%s;%s\n",ftime, ihour, iminute, isecond, direntp->d_name, data, tuser, tbytes, media,newname);
+      } else {
+         for (i=nyears ; i>0 &&  year<yearsort[i-1] ; i--) {
+            yearsort[i]=yearsort[i-1];
          }
+         yearsort[i]=year;
+         nyears++;
       }
    }
-
-   fclose(fp_tmp);
    (void)closedir( dirp );
 
-   if(strcmp(IndexTree,"date") == 0) {
-      if(strcmp(IndexSortOrder,"A") == 0) sprintf(warea,"sort -k 1,1 \"%s\" -o \"%s\"", wdir_tmp, wdir_tmp2);
-      else sprintf(warea,"sort -r -k 1,1 \"%s\" -o \"%s\"", wdir_tmp, wdir_tmp2);
-      cstatus=system(warea);
-      if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
-         fprintf(stderr, "SARG: sort command return status %d\n",WEXITSTATUS(cstatus));
-         fprintf(stderr, "SARG: sort command: %s\n",warea);
-         exit(1);
-      }
-      if((fp_tmp=fopen(wdir_tmp2,"r"))==NULL) {
-         fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir_tmp2);
-         fprintf(stderr, "SARG: sort command: %s\n",warea);
-         exit(1);
-      }
-      unlink(wdir_tmp);
-      if((fp_ou=fopen(wdir,"w"))==NULL) {
-         fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir);
-         exit(1);
-      }
-      write_html_header(fp_ou, ".");
-      fprintf(fp_ou,"<tr><th %s>%s</th><th %s>%s</th></tr>\n",hbc1,text[130],hbc1,text[132]);
-      while(fgets(wwork1,sizeof(wwork1),fp_tmp)!=NULL) {
-         getword_start(&gwarea,wwork1);
-         if (getword(tmp4,sizeof(tmp4),&gwarea,'\t')<0) {
-            printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir_tmp2);
-            exit(1);
-         }
-         fprintf(fp_ou,"<tr><td class=\"data2\"><a href=\"%s/index.html\">%s</a></td><td class=\"data2\">%s</td></tr>\n",tmp4,tmp4,gwarea.current);
-         sprintf(tmp2,"%s%s",outdir,tmp4);
-         sprintf(tmp3,"%s%s/index.unsort",outdir,tmp4);
-         // Year dir
-         if((fp_ou2=fopen(tmp3,"w"))==NULL) {
-            fprintf(stderr, "SARG: (index) %s: %s\n",text[45],tmp3);
-            exit(1);
-         }
-         dirp2 = opendir(tmp2);
-         while ((direntp2 = readdir( dirp2 )) != NULL) {
-            if(!isdigit(direntp2->d_name[0]) || !isdigit(direntp2->d_name[1])) continue;
-            fprintf(fp_ou2,"%s\n",direntp2->d_name);
+   order=(strcmp(IndexSortOrder,"A") == 0) ? 1 : -1;
+
+   if((fp_ou=fopen(yearindex,"w"))==NULL) {
+      fprintf(stderr, "SARG: (index) %s: %s - %s\n",text[45],yearindex,strerror(errno));
+      exit(1);
+   }
+   write_html_header(fp_ou, ".");
+   fprintf(fp_ou,"<tr><th %s>%s</th><th %s>%s</th></tr>\n",hbc1,text[130],hbc1,text[132]);
+   for (y=0 ; y<nyears ; y++) {
+      if (order>0)
+         year=yearsort[y];
+      else
+         year=yearsort[nyears-1-y];
+      sprintf(yearnum,"%04d",year);
+      fprintf(fp_ou,"<tr><td class=\"data2\"><a href=\"%s/index.html\">%s</a></td><td class=\"data2\">%s</td></tr>\n",yearnum,yearnum,get_size(outdir,yearnum));
+      sprintf(yeardir,"%s%s",outdir,yearnum);
+      // Year dir
+      nmonths=0;
+      dirp2 = opendir(yeardir);
+      while ((direntp2 = readdir( dirp2 )) != NULL) {
+         if(!isdigit(direntp2->d_name[0]) || !isdigit(direntp2->d_name[1])) continue;
+         i=-1;
+         if (sscanf(direntp2->d_name,"%d%n",&m1,&i)!=1 || m1<=0 || m1>12 || i<0) continue;
+         if (direntp2->d_name[i]=='-') {
+            if (sscanf(direntp2->d_name+i+1,"%d",&m2)!=1 || m2<m1 || m2>12) continue;
+         } else if (direntp2->d_name[i]!='\0') {
+            continue;
+         } else {
+            m2=0;
          }
-         if(fp_ou2) fclose(fp_ou2);
-         (void)closedir(dirp2);
-         sprintf(wdir_tmp3,"%s%s/index.sort",outdir,tmp4);
-         if(strcmp(IndexSortOrder,"A") == 0) sprintf(csort,"sort -n \"%s\" -o \"%s\"", tmp3, wdir_tmp3);
-         else sprintf(csort,"sort -n -r \"%s\" -o \"%s\"", tmp3, wdir_tmp3);
-         cstatus=system(csort);
-         if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
-            fprintf(stderr, "SARG: sort command return status %d\n",WEXITSTATUS(cstatus));
-            fprintf(stderr, "SARG: sort command: %s\n",csort);
-            exit(1);
+         if (nmonths>=sizeof(monthsort)/sizeof(monthsort[0])) {
+            fprintf(stderr,"SARG: Too many month directories in %s\nSupernumerary entries are ignored\n",yeardir);
+            break;
          }
-         unlink(tmp3);
-         if((fp_tmp2=fopen(wdir_tmp3,"r"))==NULL) {
-            fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir_tmp3);
-            exit(1);
+         month=m1*16+m2;
+         for (i=nmonths ; i>0 &&  month<monthsort[i-1] ; i--) {
+            monthsort[i]=monthsort[i-1];
          }
-         sprintf(tmp3,"%s%s/index.html",outdir,tmp4);
-         if((fp_ou2=fopen(tmp3,"w"))==NULL) {
-            fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir);
-            exit(1);
+         monthsort[i]=month;
+         nmonths++;
+      }
+      (void)closedir(dirp2);
+      sprintf(monthindex,"%s/index.html",yeardir);
+      if((fp_ou2=fopen(monthindex,"w"))==NULL) {
+         fprintf(stderr, "SARG: (index) %s: %s - %s\n",text[45],monthindex,strerror(errno));
+         exit(1);
+      }
+      write_html_header(fp_ou2,"..");
+      fprintf(fp_ou2,"<tr><th %s>%s/%s</th></tr>\n",hbc1,text[130],text[131]);
+      for (m=0 ; m<nmonths ; m++) {
+         if (order>0)
+            month=monthsort[m];
+         else
+            month=monthsort[nmonths-1-m];
+         m1=month / 16;
+         if(month % 16 != 0) {
+            m2=month % 16;
+            sprintf(monthnum,"%02d-%02d",m1,m2);
+            sprintf(monthname1,"%02d",m1);
+            sprintf(monthname2,"%02d",m2);
+            name_month(monthname1,sizeof(monthname1));
+            name_month(monthname2,sizeof(monthname2));
+            sprintf(nmonth,"%s-%s",monthname1,monthname2);
+         } else {
+            sprintf(nmonth,"%02d",m1);
+            sprintf(monthnum,"%02d",m1);
+            name_month(nmonth,sizeof(nmonth));
          }
-         write_html_header(fp_ou2,"..");
-         fprintf(fp_ou2,"<tr><th %s>%s/%s</th></tr>\n",hbc1,text[130],text[131]);
-         while(fgets(wwork1,sizeof(wwork1),fp_tmp2)!=NULL) {
-            fixendofline(wwork1);
-            strcpy(tmp5,wwork1);
-            if((str = strchr(tmp5,'-')) != 0) {
-               *str++ = '\0';
-               strcpy(tmp6,str);
-               name_month(tmp5,sizeof(tmp5));
-               name_month(tmp6,sizeof(tmp6));
-               sprintf(nmonth,"%s-%s",tmp5,tmp6);
+         fprintf(fp_ou2,"<tr><td class=\"data2\"><a href=\"%s/index.html\">%s %s</a></td></tr>\n",monthnum,yearnum,nmonth);
+
+         sprintf(monthdir,"%s/%s",yeardir,monthnum);
+         // month dir
+         ndays=0;
+         dirp3 = opendir(monthdir);
+         while ((direntp3 = readdir( dirp3 )) != NULL) {
+            if(!isdigit(direntp3->d_name[0]) && !isdigit(direntp3->d_name[1])) continue;
+            i=-1;
+            if (sscanf(direntp3->d_name,"%d%n",&d1,&i)!=1 || d1<=0 || d1>31 || i<0) continue;
+            if (direntp3->d_name[i]=='-') {
+               if (sscanf(direntp3->d_name+i+1,"%d",&d2)!=1 || d2<d1 || d2>31) continue;
+            } else if (direntp3->d_name[i]!='\0') {
+               continue;
             } else {
-               strcpy(nmonth,tmp5);
-               name_month(nmonth,sizeof(nmonth));
-            }
-            fprintf(fp_ou2,"<tr><td class=\"data2\"><a href=\"%s/index.html\">%s %s</a></td></tr>\n",wwork1,tmp4,nmonth);
-
-            sprintf(val1,"%s%s/%s",outdir,tmp4,wwork1);
-            sprintf(tmp5,"%s%s/%s/index.unsort",outdir,tmp4,wwork1);
-            if((fp_ou3=fopen(tmp5,"w"))==NULL) {
-               fprintf(stderr, "SARG: (index) %s: %s\n",text[45],tmp5);
-               exit(1);
-            }
-            // month dir
-            dirp3 = opendir(val1);
-            while ((direntp3 = readdir( dirp3 )) != NULL) {
-               if(!isdigit(direntp3->d_name[0]) && !isdigit(direntp3->d_name[1])) continue;
-               fprintf(fp_ou3,"%s\n",direntp3->d_name);
-            }
-            if(fp_ou3) fclose(fp_ou3);
-            (void)rewinddir(dirp3);
-            (void)closedir(dirp3);
-            unlink(wdir_tmp3);
-            sprintf(tmp6,"%s%s/%s/index.sort",outdir,tmp4,wwork1);
-            if(strcmp(IndexSortOrder,"A") == 0) sprintf(csort,"sort -n \"%s\" -o \"%s\"", tmp5, tmp6);
-            else sprintf(csort,"sort -n -r \"%s\" -o \"%s\"", tmp5, tmp6);
-            cstatus=system(csort);
-            if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
-               fprintf(stderr, "SARG: sort command return status %d\n",WEXITSTATUS(cstatus));
-               fprintf(stderr, "SARG: sort command: %s\n",csort);
-               exit(1);
+               d2=0;
             }
-            unlink(tmp5);
-            sprintf(val2,"%s%s/%s/index.html",outdir,tmp4,wwork1);
-            sprintf(val3,"%s/%s",tmp4,wwork1);
-            unlink(val2);
-            if((fp_ou3=fopen(val2,"w"))==NULL) {
-               fprintf(stderr, "SARG: (index) %s: %s\n",text[45],val2);
-               exit(1);
+            if (ndays>=sizeof(daysort)/sizeof(daysort[0])) {
+               fprintf(stderr,"SARG: Too many day directories in %s\nSupernumerary entries are ignored\n",monthdir);
+               break;
             }
-            if((fp_tmp3=fopen(tmp6,"r"))==NULL) {
-               fprintf(stderr, "SARG: (index) %s: %s\n",text[45],tmp6);
-               exit(1);
+            day=d1*32+d2;
+            for (i=ndays ; i>0 &&  day<daysort[i-1] ; i--) {
+               daysort[i]=daysort[i-1];
             }
-            write_html_header(fp_ou3,"../..");
-            fprintf(fp_ou3,"<tr><th %s>%s/%s/%s</th></tr>\n",hbc1,text[130],text[131],text[127]);
-            while(fgets(warea,sizeof(warea),fp_tmp3)!=NULL) {
-               warea[strlen(warea)-1]='\0';
-               fprintf(fp_ou3,"<tr><td class=\"data2\"><a href=\"%s/index.html\">%s %s %s</a></td></tr>\n",warea,tmp4,nmonth,warea);
+            daysort[i]=day;
+            ndays++;
+         }
+         (void)closedir(dirp3);
+         sprintf(dayindex,"%s/index.html",monthdir);
+         if((fp_ou3=fopen(dayindex,"w"))==NULL) {
+            fprintf(stderr, "SARG: (index) %s: %s - %s\n",text[45],dayindex,strerror(errno));
+            exit(1);
+         }
+         write_html_header(fp_ou3,"../..");
+         fprintf(fp_ou3,"<tr><th %s>%s/%s/%s</th></tr>\n",hbc1,text[130],text[131],text[127]);
+         for (d=0 ; d<ndays ; d++) {
+            if (order>0)
+               day=daysort[d];
+            else
+               day=daysort[ndays-1-d];
+            d1=day / 32;
+            if(day % 32 != 0) {
+               d2=day % 32;
+               sprintf(daynum,"%02d-%02d",d1,d2);
+            } else {
+               sprintf(daynum,"%02d",d1);
             }
-            if(fp_tmp3) fclose(fp_tmp3);
-            write_html_trailer(fp_ou3);
-            if(fp_ou3) fclose(fp_ou3);
-            unlink(tmp6);
+            fprintf(fp_ou3,"<tr><td class=\"data2\"><a href=\"%s/index.html\">%s %s %s</a></td></tr>\n",daynum,yearnum,nmonth,daynum);
          }
-         write_html_trailer(fp_ou2);
-         if(fp_ou2) fclose(fp_ou2);
-      }
-      if(fp_tmp) fclose(fp_tmp);
-      unlink(tmp6);
-      unlink(wdir_tmp2);
-   } else {
-      if(strcmp(IndexSortOrder,"A") == 0) sprintf(warea,"sort -t\";\" -k 7,7 -k 1,1 \"%s\" -o \"%s\"", wdir_tmp, wdir_tmp2);
-      else sprintf(warea,"sort -r -t\";\" -k 7,7 -k 1,1 \"%s\" -o \"%s\"", wdir_tmp, wdir_tmp2);
-      cstatus=system(warea);
-      if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
-         fprintf(stderr, "SARG: sort command return status %d\n",WEXITSTATUS(cstatus));
-         fprintf(stderr, "SARG: sort command: %s\n",warea);
-         exit(1);
+         write_html_trailer(fp_ou3);
+         fclose(fp_ou3);
       }
-      if((fp_tmp2=fopen(wdir_tmp2,"r"))==NULL) {
-         fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir_tmp2);
-         fprintf(stderr, "SARG: sort command: %s\n",warea);
+      write_html_trailer(fp_ou2);
+      fclose(fp_ou2);
+   }
+
+   write_html_trailer(fp_ou);
+   fclose(fp_ou);
+}
+
+static void make_file_index(void)
+{
+   #define MAX_CREATION_DATE 15
+   #define MAX_DIR_NAME 30
+   FILE *fp_ou;
+   DIR *dirp;
+   struct dirent *direntp;
+   char wdir[MAXLEN];
+   char month[4];
+   char data[80];
+   char tuser[20];
+   char tbytes[20];
+   char media[20];
+   char ftime[128];
+   char day[6], mon[8], year[40], hour[10];
+   int iyear, imonth, iday, ihour, iminute, isecond, idst;
+   int nsort;
+   int nallocated;
+   int order;
+   int i;
+   int cmp;
+   struct getwordstruct gwarea;
+   struct sortstruct
+   {
+      char sortname[9];
+      char creationdate[MAX_CREATION_DATE];
+      char dirname[MAX_DIR_NAME];
+      char date[60];
+   } **sortlist, *item, **tempsort;
+
+   sprintf(wdir,"%sindex.html",outdir);
+   strcpy(hbc1,"class=\"header\"");
+
+   order=(strcmp(IndexSortOrder,"A") == 0) ? 1 : -1;
+
+   dirp = opendir(outdir);
+
+   nsort=0;
+   nallocated=0;
+   sortlist=NULL;
+   while ((direntp = readdir( dirp )) != NULL) {
+      if (strchr(direntp->d_name,'-') == 0) continue;
+      if (strlen(direntp->d_name)>MAX_DIR_NAME) continue;
+      item=malloc(sizeof(*item));
+      if (!item) {
+         fprintf(stderr,"SARG: not enough memory to sort the index\n");
          exit(1);
       }
-      unlink(wdir_tmp);
-      if((fp_ou=fopen(wdir,"w"))==NULL) {
-         fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir);
-         exit(1);
+      if(strcmp(df,"u") == 0) {
+         strncpy(item->sortname,direntp->d_name,4);
+         strncpy(month,direntp->d_name+4,3);
+      } else {
+         strncpy(item->sortname,direntp->d_name+5,4);
+         strncpy(month,direntp->d_name+2,3);
       }
-      write_html_header(fp_ou,".");
-      fprintf(fp_ou,"<tr><th %s>%s</th><th %s>%s</th><th %s>%s</th><th %s>%s</th><th %s>%s</th></tr>\n",hbc1,text[101],hbc1,text[102],hbc1,text[103],hbc1,text[93],hbc1,text[96]);
-      while(fgets(buf,sizeof(buf),fp_tmp2)!=NULL) {
-         getword_start(&gwarea,buf);
-         if (getword_multisep(period,sizeof(period),&gwarea,';')<0) {
-            printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir_tmp2);
+      item->sortname[4]='\0';
+      month[3]='\0';
+      conv_month(month);
+      strcat(item->sortname,month);
+      if(strcmp(df,"u") == 0) strncat(item->sortname,direntp->d_name+7,2);
+      else strncat(item->sortname,direntp->d_name,2);
+      obtdate(outdir,direntp->d_name,data);
+      if (sscanf(data,"%d-%d-%d %d:%d:%d %d",&iyear,&imonth,&iday,&ihour,&iminute,&isecond,&idst)==7) {
+         formatdate(data,sizeof(data),iyear,imonth,iday,ihour,iminute,isecond,idst);
+         snprintf(item->creationdate,sizeof(item->creationdate),"%04d%02d%02d%02d%02d%02d",iyear,imonth,iday,ihour,iminute,isecond);
+      } else {
+         /*
+         Old code to parse a date stored by sarg before 2.2.6.1 in the sarg-date file of each report directory.
+         */
+         getword_start(&gwarea,data);
+         if (getword_skip(16,&gwarea,' ')<0) {
+            printf("SARG: Maybe you have a broken week day in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
             exit(1);
          }
-         if (getword_multisep(period,sizeof(period),&gwarea,';')<0) {
-            printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir_tmp2);
+         if (getword_multisep(mon,sizeof(mon),&gwarea,' ')<0) {
+            printf("SARG: Maybe you have a broken month in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
             exit(1);
          }
-         if (getword_multisep(data,sizeof(data),&gwarea,';')<0) {
-            printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir_tmp2);
+         if (getword_multisep(day,sizeof(day),&gwarea,' ')<0) {
+            printf("SARG: Maybe you have a broken day in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
             exit(1);
          }
-         if (getword_multisep(tuser,sizeof(tuser),&gwarea,';')<0) {
-            printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir_tmp2);
+         if (getword_multisep(hour,sizeof(hour),&gwarea,' ')<0) {
+            printf("SARG: Maybe you have a broken time in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
             exit(1);
          }
-         if (getword_multisep(tbytes,sizeof(tbytes),&gwarea,';')<0) {
-            printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir_tmp2);
+         do {
+            if (getword_multisep(year,sizeof(year),&gwarea,' ')<0) {
+               printf("SARG: Maybe you have a broken year in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
+               exit(1);
+            }
+         } while (year[0] && !isdigit(year[0])); //skip time zone information with spaces until the year is found
+         if (sscanf(hour,"%d:%d:%d",&ihour,&iminute,&isecond)!=3) {
+            printf("SARG: Maybe you have a broken time in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
             exit(1);
          }
-         if (getword_multisep(media,sizeof(media),&gwarea,';')<0) {
-            printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir_tmp2);
+         buildymd(day,mon,year,ftime);
+         snprintf(item->creationdate,sizeof(item->creationdate),"%s%02d%02d%02d",ftime, ihour, iminute, isecond);
+      }
+      strcpy(item->dirname,direntp->d_name);
+      strncpy(item->date,data,sizeof(item->date));
+      if (nsort+1>nallocated) {
+         nallocated+=10;
+         tempsort=realloc(sortlist,nallocated*sizeof(*item));
+         if (!tempsort) {
+            fprintf(stderr,"SARG: not enough memory to sort the index\n");
             exit(1);
          }
-         fprintf(fp_ou,"<tr><td class=\"data2\"><a href='%s/%s'>%s</a></td><td class=\"data2\">%s</td><td class=\"data\">%s</td><td class=\"data\">%s</td><td class=\"data\">%s</td></tr>\n",period,ReplaceIndex,period,data,tuser,tbytes,media);
+         sortlist=tempsort;
+      }
+      for (i=nsort ; i>0 ; i--) {
+         cmp=strcmp(item->sortname,sortlist[i-1]->sortname);
+         if (cmp==0) cmp=strcmp(item->creationdate,sortlist[i-1]->creationdate);
+         if (cmp>=0) {
+            break;
+         }
+         sortlist[i]=sortlist[i-1];
       }
-      if(fp_tmp2) fclose(fp_tmp2);
-      unlink(wdir_tmp2);
+      sortlist[i]=item;
+      nsort++;
    }
 
+   (void)closedir( dirp );
+
+   if((fp_ou=fopen(wdir,"w"))==NULL) {
+      fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir);
+      exit(1);
+   }
+   write_html_header(fp_ou,".");
+   fprintf(fp_ou,"<tr><th %s>%s</th><th %s>%s</th><th %s>%s</th><th %s>%s</th><th %s>%s</th></tr>\n",hbc1,text[101],hbc1,text[102],hbc1,text[103],hbc1,text[93],hbc1,text[96]);
+   for (i=0 ; i<nsort ; i++) {
+      if (order>0)
+         item=sortlist[i];
+      else
+         item=sortlist[nsort-i-1];
+      obtuser(outdir,item->dirname,tuser);
+      obttotal(outdir,item->dirname,tbytes,tuser,media);
+      fprintf(fp_ou,"<tr><td class=\"data2\"><a href='%s/%s'>%s</a></td><td class=\"data2\">%s</td><td class=\"data\">%s</td><td class=\"data\">%s</td><td class=\"data\">%s</td></tr>\n",item->dirname,ReplaceIndex,item->dirname,item->date,tuser,tbytes,media);
+   }
    write_html_trailer(fp_ou);
-   if(fp_ou) fclose(fp_ou);
+   fclose(fp_ou);
+
+   if (sortlist) {
+      for (i=0 ; i<nsort ; i++)
+         free(sortlist[i]);
+      free(sortlist);
+   }
 }
 
 static void file_index_to_date_index(const char *entry)
diff --git a/log.c b/log.c
index 72b02ec892acdde43fe613ee14d0db7bde4351f6..c3dff1305fb4102cbca41bdff8536471a729a224 100644 (file)
--- a/log.c
+++ b/log.c
@@ -1,6 +1,6 @@
 /*
  * AUTHOR: Pedro Lineu Orso                         pedro.orso@gmail.com
- *                                                            1998, 2009
+ *                                                            1998, 2010
  * SARG Squid Analysis Report Generator      http://sarg.sourceforge.net
  *
  * SARG donations:
diff --git a/util.c b/util.c
index 0d0f031237bb6afa2a3e1300349f0b15ebaed52e..571866a69911002c4f1c47092eaf54b02d58d3c3 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1,6 +1,6 @@
 /*
  * AUTHOR: Pedro Lineu Orso                         pedro.orso@gmail.com
- *                                                            1998, 2008
+ *                                                            1998, 2010
  * SARG Squid Analysis Report Generator      http://sarg.sourceforge.net
  *
  * SARG donations:
@@ -340,7 +340,7 @@ void buildymd(const char *dia, const char *mes, const char *ano, char *wdata)
          break;
    }
 
-   sprintf(wdata,"%s%02d%s",ano,nmes+1,dia);
+   sprintf(wdata,"%04d%02d%02d",atoi(ano),nmes+1,atoi(dia));
 
 }