]> git.ipfire.org Git - thirdparty/sarg.git/blobdiff - sort.c
Optimize away a useless strcpy.
[thirdparty/sarg.git] / sort.c
diff --git a/sort.c b/sort.c
index 3fad666a5a76006a2ac2ad32adcc2679457cf9cd..f2802d438191080e4fc3e14d4b6dcb4070ad05f4 100644 (file)
--- a/sort.c
+++ b/sort.c
@@ -1,6 +1,6 @@
 /*
  * SARG Squid Analysis Report Generator      http://sarg.sourceforge.net
- *                                                            1998, 2010
+ *                                                            1998, 2015
  *
  * SARG donations:
  *      please look at http://sarg.sourceforge.net/donations.php
 #include "include/conf.h"
 #include "include/defs.h"
 
-void tmpsort(void)
+/*!
+Sort all the \c utmp files form the temporary directory. The sort can be made according to the
+number of connections, the accessed sites or the time of the access depending on the value of
+::UserSortField. The sorting is either made in increasing or decreasing order as specified by
+the value of ::UserSortOrder.
+*/
+void tmpsort(const struct userinfostruct *uinfo)
 {
-       DIR *dirp;
-       struct dirent *direntp;
        int cstatus;
-       const char tmpext[]=".utmp";
-       int dlen;
        char csort[MAXLEN];
-       char arqou[MAXLEN], arqin[MAXLEN], wnome[MAXLEN];
+       char arqou[MAXLEN], arqin[MAXLEN];
        const char *field1="2,2";
        const char *field2="1,1";
        const char *field3="3,3";
        const char *order;
 
-       if(indexonly) return;
-       if((ReportType & REPORT_TYPE_USERS_SITES) == 0) return;
-
        if((UserSort & USER_SORT_CONNECT) != 0) {
                field1="1,1";
                field2="2,2";
@@ -63,113 +62,101 @@ void tmpsort(void)
        else
                order="-r";
 
-       if ((dirp = opendir(tmp)) == NULL) {
-               debuga(_("Failed to open directory %s - %s\n"),tmp,strerror(errno));
+       if (snprintf(arqin,sizeof(arqin),"%s/%s.utmp",tmp,uinfo->filename)>=sizeof(arqin)) {
+               debuga(__FILE__,__LINE__,_("Path too long: "));
+               debuga_more("%s/%s.utmp\n",tmp,uinfo->filename);
+               exit(EXIT_FAILURE);
+       }
+       if (snprintf(arqou,sizeof(arqou),"%s/htmlrel.txt",tmp)>=sizeof(arqou)) {
+               debuga(__FILE__,__LINE__,_("Path too long: "));
+               debuga_more("%s/htmlrel.txt\n",tmp);
                exit(EXIT_FAILURE);
        }
-       while ((direntp = readdir( dirp )) != NULL ){
-               dlen=strlen(direntp->d_name)-(sizeof(tmpext)-1);
-               if (dlen<0) continue;
-               if(strcmp(direntp->d_name+dlen,tmpext) != 0)
-                       continue;
-
-               if (dlen>0) {
-                       if (dlen>=sizeof(wnome)) continue;
-                       strncpy(wnome,direntp->d_name,dlen);
-                       wnome[dlen]='\0';
-               } else {
-                       wnome[0]='\0';
-               }
-
-               strcpy(arqou,tmp);
-               strcat(arqou,"/");
-               strcpy(arqin,arqou);
-               strcat(arqou,wnome);
-               strcat(arqin,direntp->d_name);
-
-               if(debug) {
-                       debuga(_("Sorting file: %s\n"),arqou);
-               }
-
-               strcat(arqou,".txt");
-               sprintf(csort,"sort -n -T \"%s\" %s -k %s -k %s -k %s -o \"%s\" \"%s\"",tmp,order,field1,field2,field3,arqou,arqin);
-               cstatus=system(csort);
-               if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
-                       debuga(_("sort command return status %d\n"),WEXITSTATUS(cstatus));
-                       debuga(_("sort command: %s\n"),csort);
-                       exit(EXIT_FAILURE);
-               }
-               unlink(arqin);
 
+       if(debug) {
+               debuga(__FILE__,__LINE__,_("Sorting file \"%s\"\n"),arqin);
+       }
+
+       if (snprintf(csort,sizeof(csort),"sort -n -T \"%s\" -t \"\t\" %s -k %s -k %s -k %s -o \"%s\" \"%s\"",tmp,order,field1,field2,field3,arqou,arqin)>=sizeof(csort)) {
+               debuga(__FILE__,__LINE__,_("Sort command too long when sorting file \"%s\" to \"%s\"\n"),arqin,arqou);
+               exit(EXIT_FAILURE);
+       }
+       cstatus=system(csort);
+       if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
+               debuga(__FILE__,__LINE__,_("sort command return status %d\n"),WEXITSTATUS(cstatus));
+               debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort);
+               exit(EXIT_FAILURE);
+       }
+       if (!KeepTempLog && unlink(arqin)) {
+               debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),arqin,strerror(errno));
+               exit(EXIT_FAILURE);
        }
 
-       (void)closedir( dirp );
        return;
 }
 
-void sort_users_log(const char *tmp, int debug)
+/*!
+The function sorts the \c unsort file in the temporary directory. These files correspond
+to the format described in \ref UserUnsortLog.
+
+\param tmp The temorary directory of the sarg files.
+\param debug \c True to output debug information.
+\param uinfo The user whose log must be sorted.
+
+The user's files are sorted by columns 5, 1 and 2 that are the columns of the number of bytes transfered,
+the date of the access and the time of the access.
+
+The sorted files are written in files with the extension \c log and the name of the unsorted
+file without the \c unsort extension. The unsorted file is deleted just after the sorting.
+*/
+void sort_users_log(const char *tmp, int debug,struct userinfostruct *uinfo)
 {
-       DIR *dirp;
-       struct dirent *direntp;
        char csort[MAXLEN];
-       char user[MAXLEN];
-       char wdname[MAXLEN];
+       const char *user;
        int cstatus;
-       int dlen;
        int clen;
-       const char unsortext[]=".unsort";
 
        if(debug) {
-               debuga(_("pre-sorting files\n"));
+               snprintf(csort,sizeof(csort),"%s/%s.user_unsort",tmp,uinfo->filename);
+               debuga(__FILE__,__LINE__,_("Sorting file \"%s\"\n"),csort);
        }
 
-       if ((dirp = opendir(tmp)) == NULL) {
-               debuga(_("Failed to open directory %s - %s\n"),tmp,strerror(errno));
+       user=uinfo->filename;
+       clen=snprintf(csort,sizeof(csort),"sort -T \"%s\" -t \"\t\" -k 4,4 -k 1,1 -k 2,2 -o \"%s/%s.user_log\" \"%s/%s.user_unsort\"",
+                       tmp, tmp, user, tmp, user);
+       if (clen>=sizeof(csort)) {
+               /* TRANSLATORS: The message is followed by the command that is too long. */
+               debuga(__FILE__,__LINE__,_("User name too long to sort with command "));
+               debuga_more("sort -T \"%s\" -t \"\t\" -k 4,4 -k 1,1 -k 2,2 -o \"%s/%s.user_log\" \"%s/%s.user_unsort\"",
+                                       tmp, tmp, user, tmp, user);
+               exit(EXIT_FAILURE);
+       }
+       cstatus=system(csort);
+       if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
+               debuga(__FILE__,__LINE__,_("sort command return status %d\n"),WEXITSTATUS(cstatus));
+               debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort);
                exit(EXIT_FAILURE);
        }
-       while ( (direntp = readdir( dirp )) != NULL ){
-               dlen=strlen(direntp->d_name)-(sizeof(unsortext)-1);
-               if (dlen<0) continue;
-               if(strcmp(direntp->d_name+dlen,unsortext) != 0)
-                       continue;
-               if(strcmp(direntp->d_name,"authfail.log.unsort") == 0)
-                       continue;
-
-               if (dlen>0) {
-                       if (dlen>=sizeof(user)) continue;
-                       strncpy(user,direntp->d_name,dlen);
-                       user[dlen]=0;
-               } else {
-                       user[0]='\0';
-               }
-
-               if(strcmp(direntp->d_name,"download.unsort") == 0)
-                       clen=snprintf(csort,sizeof(csort),"sort -T \"%s\" -k 3,3 -k 1,1 -k 2,2 -k 5,5 -o \"%s/%s.log\" \"%s/%s.unsort\"",
-                           tmp, tmp, user, tmp, user);
-               else
-                       clen=snprintf(csort,sizeof(csort),"sort -T \"%s\" -k 4,4 -k 1,1 -k 2,2 -o \"%s/%s.log\" \"%s/%s.unsort\"",
-                           tmp, tmp, user, tmp, user);
-               if (clen>=sizeof(csort)) {
-                       debuga(_("user name too long to sort %s\n"),csort);
-                       exit(EXIT_FAILURE);
-               }
-               cstatus=system(csort);
-               if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
-                       debuga(_("sort command return status %d\n"),WEXITSTATUS(cstatus));
-                       debuga(_("sort command: %s\n"),csort);
-                       exit(EXIT_FAILURE);
-               }
-               if (snprintf(wdname,sizeof(wdname),"%s/%s.unsort",tmp,user)>=sizeof(wdname)) {
-                       debuga(_("user name too long for %s/%s.unsort\n"),tmp,user);
-                       exit(EXIT_FAILURE);
-               }
-               unlink(wdname);
+       if (snprintf(csort,sizeof(csort),"%s/%s.user_unsort",tmp,user)>=sizeof(csort)) {
+               debuga(__FILE__,__LINE__,_("User name too long to manufacture file name "));
+               debuga_more("%s/%s.user_unsort\n",tmp,user);
+               exit(EXIT_FAILURE);
+       }
+       if (!KeepTempLog && unlink(csort)) {
+               debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),csort,strerror(errno));
+               exit(EXIT_FAILURE);
        }
-       (void)closedir( dirp );
 
        return;
 }
 
+/*!
+Get the internationalized text to display when reporting the sort criterion and order
+of a user list.
+
+\param label A pointer to set to the string of the sort criterion name.
+\param order A pointer to set to the string of the sort order name
+*/
 void sort_labels(const char **label,const char **order)
 {
        if((UserSort & USER_SORT_CONNECT) != 0) {
@@ -177,7 +164,7 @@ void sort_labels(const char **label,const char **order)
        } else if((UserSort & USER_SORT_SITE) != 0) {
                *label=_("site");
        } else if((UserSort & USER_SORT_TIME) != 0) {
-               *label=_("time");
+               *label=pgettext("duration","time");
        } else {
                *label=_("bytes");
        }