]> git.ipfire.org Git - thirdparty/sarg.git/blob - sort.c
Add support to decompress xz files
[thirdparty/sarg.git] / sort.c
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
30 /*!
31 Sort all the \c utmp files form the temporary directory. The sort can be made according to the
32 number of connections, the accessed sites or the time of the access depending on the value of
33 ::UserSortField. The sorting is either made in increasing or decreasing order as specified by
34 the value of ::UserSortOrder.
35 */
36 void tmpsort(const struct userinfostruct *uinfo)
37 {
38 int cstatus;
39 char csort[MAXLEN];
40 char arqou[MAXLEN], arqin[MAXLEN];
41 const char *field1="2,2";
42 const char *field2="1,1";
43 const char *field3="3,3";
44 const char *order;
45
46 if((UserSort & USER_SORT_CONNECT) != 0) {
47 field1="1,1";
48 field2="2,2";
49 field3="3,3";
50 } else if((UserSort & USER_SORT_SITE) != 0) {
51 field1="3,3";
52 field2="2,2";
53 field3="1,1";
54 } else if((UserSort & USER_SORT_TIME) != 0) {
55 field1="5,5";
56 field2="2,2";
57 field3="1,1";
58 }
59
60 if((UserSort & USER_SORT_REVERSE) == 0)
61 order="";
62 else
63 order="-r";
64
65 if (snprintf(arqin,sizeof(arqin),"%s/%s.utmp",tmp,uinfo->filename)>=sizeof(arqin)) {
66 debuga(__FILE__,__LINE__,_("Path too long: "));
67 debuga_more("%s/%s.utmp\n",tmp,uinfo->filename);
68 exit(EXIT_FAILURE);
69 }
70 if (snprintf(arqou,sizeof(arqou),"%s/htmlrel.txt",tmp)>=sizeof(arqou)) {
71 debuga(__FILE__,__LINE__,_("Path too long: "));
72 debuga_more("%s/htmlrel.txt\n",tmp);
73 exit(EXIT_FAILURE);
74 }
75
76 if(debug) {
77 debuga(__FILE__,__LINE__,_("Sorting file \"%s\"\n"),arqin);
78 }
79
80 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)) {
81 debuga(__FILE__,__LINE__,_("Sort command too long when sorting file \"%s\" to \"%s\"\n"),arqin,arqou);
82 exit(EXIT_FAILURE);
83 }
84 cstatus=system(csort);
85 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
86 debuga(__FILE__,__LINE__,_("sort command return status %d\n"),WEXITSTATUS(cstatus));
87 debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort);
88 exit(EXIT_FAILURE);
89 }
90 if (!KeepTempLog && unlink(arqin)) {
91 debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),arqin,strerror(errno));
92 exit(EXIT_FAILURE);
93 }
94
95 return;
96 }
97
98 /*!
99 The function sorts the \c unsort file in the temporary directory. These files correspond
100 to the format described in \ref UserUnsortLog.
101
102 \param tmp The temorary directory of the sarg files.
103 \param debug \c True to output debug information.
104 \param uinfo The user whose log must be sorted.
105
106 The user's files are sorted by columns 5, 1 and 2 that are the columns of the number of bytes transfered,
107 the date of the access and the time of the access.
108
109 The sorted files are written in files with the extension \c log and the name of the unsorted
110 file without the \c unsort extension. The unsorted file is deleted just after the sorting.
111 */
112 void sort_users_log(const char *tmp, int debug,struct userinfostruct *uinfo)
113 {
114 char csort[MAXLEN];
115 const char *user;
116 int cstatus;
117 int clen;
118
119 if(debug) {
120 snprintf(csort,sizeof(csort),"%s/%s.user_unsort",tmp,uinfo->filename);
121 debuga(__FILE__,__LINE__,_("Sorting file \"%s\"\n"),csort);
122 }
123
124 user=uinfo->filename;
125 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\"",
126 tmp, tmp, user, tmp, user);
127 if (clen>=sizeof(csort)) {
128 /* TRANSLATORS: The message is followed by the command that is too long. */
129 debuga(__FILE__,__LINE__,_("User name too long to sort with command "));
130 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\"",
131 tmp, tmp, user, tmp, user);
132 exit(EXIT_FAILURE);
133 }
134 cstatus=system(csort);
135 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
136 debuga(__FILE__,__LINE__,_("sort command return status %d\n"),WEXITSTATUS(cstatus));
137 debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort);
138 exit(EXIT_FAILURE);
139 }
140 if (snprintf(csort,sizeof(csort),"%s/%s.user_unsort",tmp,user)>=sizeof(csort)) {
141 debuga(__FILE__,__LINE__,_("User name too long to manufacture file name "));
142 debuga_more("%s/%s.user_unsort\n",tmp,user);
143 exit(EXIT_FAILURE);
144 }
145 if (!KeepTempLog && unlink(csort)) {
146 debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),csort,strerror(errno));
147 exit(EXIT_FAILURE);
148 }
149
150 return;
151 }
152
153 /*!
154 Get the internationalized text to display when reporting the sort criterion and order
155 of a user list.
156
157 \param label A pointer to set to the string of the sort criterion name.
158 \param order A pointer to set to the string of the sort order name
159 */
160 void sort_labels(const char **label,const char **order)
161 {
162 if((UserSort & USER_SORT_CONNECT) != 0) {
163 *label=_("connect");
164 } else if((UserSort & USER_SORT_SITE) != 0) {
165 *label=_("site");
166 } else if((UserSort & USER_SORT_TIME) != 0) {
167 *label=pgettext("duration","time");
168 } else {
169 *label=_("bytes");
170 }
171
172 if((UserSort & USER_SORT_REVERSE) == 0)
173 *order=_("normal");
174 else
175 *order=_("reverse");
176 }