/*
- * AUTHOR: Pedro Lineu Orso pedro.orso@gmail.com
- * 1998, 2008
* SARG Squid Analysis Report Generator http://sarg.sourceforge.net
+ * 1998, 2015
*
* SARG donations:
* please look at http://sarg.sourceforge.net/donations.php
+ * Support:
+ * http://sourceforge.net/projects/sarg/forums/forum/363374
* ---------------------------------------------------------------------
*
* This program is free software; you can redistribute it and/or modify
#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)
{
+ int cstatus;
+ char csort[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((UserSort & USER_SORT_CONNECT) != 0) {
+ field1="1,1";
+ field2="2,2";
+ field3="3,3";
+ } else if((UserSort & USER_SORT_SITE) != 0) {
+ field1="3,3";
+ field2="2,2";
+ field3="1,1";
+ } else if((UserSort & USER_SORT_TIME) != 0) {
+ field1="5,5";
+ field2="2,2";
+ field3="1,1";
+ }
+
+ if((UserSort & USER_SORT_REVERSE) == 0)
+ order="";
+ else
+ order="-r";
+
+ 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);
+ }
+
+ 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);
+ }
+
+ return;
+}
+
+/*!
+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.
- DIR *dirp;
- struct dirent *direntp;
- int cstatus;
- const char tmpext[]=".utmp";
- int dlen;
-
- char csort[MAXLEN];
- char arqou[MAXLEN], arqin[MAXLEN], wnome[MAXLEN];
- char field1[10]="2,2";
- char field2[10]="1,1";
- char field3[10]="3,3";
- char order[4]="-r";
-
- if(indexonly) return;
- if(strstr(ReportType,"users_sites") == 0) return;
-
- strup(UserSortField);
- if(strcmp(UserSortField,"CONNECT") == 0) {
- strcpy(field1,"1,1");
- strcpy(field2,"2,2");
- strcpy(field3,"3,3");
- } else if(strcmp(UserSortField,"SITE") == 0) {
- strcpy(field1,"3,3");
- strcpy(field2,"2,2");
- strcpy(field3,"1,1");
- } else if(strcmp(UserSortField,"TIME") == 0) {
- strcpy(field1,"5,5");
- strcpy(field2,"2,2");
- strcpy(field3,"1,1");
- }
-
- strlow(UserSortOrder);
- if(strcmp(UserSortOrder,"normal") == 0)
- order[0]='\0';
-
- dirp = opendir(tmp);
- 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) {
- sprintf(msg,"%s: %s",text[54],arqou);
- debuga(msg);
- }
-
- strcat(arqou,".txt");
- sprintf(csort,"sort -n -T %s %s -k %s -k %s -k %s -o '%s' '%s'",TempDir,order,field1,field2,field3,arqou,arqin);
- 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);
- }
- unlink(arqin);
-
- }
-
- (void)closedir( dirp );
- return;
+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)
+{
+ char csort[MAXLEN];
+ const char *user;
+ int cstatus;
+ int clen;
+
+ if(debug) {
+ snprintf(csort,sizeof(csort),"%s/%s.user_unsort",tmp,uinfo->filename);
+ debuga(__FILE__,__LINE__,_("Sorting file \"%s\"\n"),csort);
+ }
+
+ 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);
+ }
+ 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);
+ }
+
+ return;
}
-void sort_users_log(const char *tmp, int debug)
+/*!
+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)
{
- DIR *dirp;
- struct dirent *direntp;
- char csort[MAXLEN];
- char wtmp[MAXLEN];
- char user[MAXLEN];
- char wdname[MAXLEN];
- int cstatus;
- const char unsortext[]=".unsort";
- int dlen;
-
- if(debug) {
- sprintf(msg,"%s",text[138]);
- debuga(msg);
- }
-
- sprintf(wtmp,"%s/sarg",tmp);
-
- dirp = opendir(wtmp);
- 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 {
- bzero(user, MAXLEN);
- }
-
- if(strcmp(direntp->d_name,"download.unsort") == 0)
- sprintf(csort,"sort -T %s -k 3,3 -k 1,1 -k 2,2 -k 5,5 -o '%s/%s.log' '%s/%s.unsort'",
- tmp, wtmp, user, wtmp, user);
- else
- sprintf(csort,"sort -T %s -k 5,5 -k 1,1 -k 2,2 -o '%s/%s.log' '%s/%s.unsort'",
- tmp, wtmp, user, wtmp, user);
- 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 (snprintf(wdname,sizeof(wdname),"%s/%s.unsort",wtmp,user)>=sizeof(wdname)) {
- fprintf(stderr, "SARG: user name too long for: %s/%s.unsort\n",wtmp,user);
- exit(1);
- }
- unlink(wdname);
- bzero(user, MAXLEN);
-
- }
- (void)closedir( dirp );
-
- return;
+ if((UserSort & USER_SORT_CONNECT) != 0) {
+ *label=_("connect");
+ } else if((UserSort & USER_SORT_SITE) != 0) {
+ *label=_("site");
+ } else if((UserSort & USER_SORT_TIME) != 0) {
+ *label=pgettext("duration","time");
+ } else {
+ *label=_("bytes");
+ }
+
+ if((UserSort & USER_SORT_REVERSE) == 0)
+ *order=_("normal");
+ else
+ *order=_("reverse");
}