#include "include/defs.h"
#include "include/filelist.h"
+struct TopUserStatistics
+{
+ long long int ttnbytes;
+ long long int ttnacc;
+ long long int ttnelap;
+ long long int ttnincache;
+ long long int ttnoucache;
+ int totuser;
+};
+
+struct SortInfoStruct
+{
+ const char *sort_field;
+ const char *sort_order;
+};
+
extern struct globalstatstruct globstat;
extern bool smartfilter;
extern FileListObject UserAgentLog;
globstat.totuser=totuser;
}
-void topuser(void)
+/*!
+ * Generate a HTML report with the users downloading the most.
+ *
+ * \param ListFile Name of the file with the sorted list of users.
+ * \param Statis Statistics about the data collected from the log file.
+ * \param SortInfo Strings explaining how the list was sorted.
+ */
+static void TopUser_HtmlReport(const char *ListFile,struct TopUserStatistics *Statis,struct SortInfoStruct *SortInfo)
{
- FileObject *fp_in = NULL;
FileObject *fp_top1 = NULL;
- FILE *fp_top2 = NULL, *fp_top3 = NULL;
- long long int ttnbytes=0, ttnacc=0, tnacc=0;
- long long int tnbytes=0, ttnelap=0, tnelap=0;
- long long int tnincache=0, tnoucache=0, ttnincache=0, ttnoucache=0;
+ FILE *fp_top3 = NULL;
long long int nbytes;
long long int nacc;
long long int elap, incac, oucac;
double perc2=0.00;
double inperc=0.00, ouperc=0.00;
int posicao=0;
- char olduser[MAX_USER_LEN], csort[MAXLEN];
- char wger[MAXLEN], top1[MAXLEN], top2[MAXLEN], top3[MAXLEN];
+ char top3[MAXLEN];
char user[MAX_USER_LEN];
- const char *sfield="-n -k 2,2";
- const char *order;
- const char *sort_field;
- const char *sort_order;
char title[80];
char *warea;
- int totuser=0;
- int topcount=0;
- int cstatus;
+ bool ntopuser=false;
+ int topcount=0;
struct getwordstruct gwarea;
longline line;
- struct generalitemstruct item;
struct userinfostruct *uinfo;
- if (debugz>=LogLevel_Process)
- debuga(__FILE__,__LINE__,_("Creating top users report...\n"));
- ntopuser = 0;
- snprintf(wger,sizeof(wger),"%s/sarg-general",outdirname);
- if((fp_in=FileObject_Open(wger))==NULL) {
- debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),wger,FileObject_GetLastOpenError());
- exit(EXIT_FAILURE);
- }
-
- snprintf(top2,sizeof(top2),"%s/top.tmp",outdirname);
- if((fp_top2=fopen(top2,"w"))==NULL) {
- debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),top2,strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- olduser[0]='\0';
- totuser=0;
-
- if ((line=longline_create())==NULL) {
- debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\"\n"),wger);
- exit(EXIT_FAILURE);
- }
-
- while((warea=longline_read(fp_in,line))!=NULL) {
- ger_read(warea,&item,wger);
- if(item.total) continue;
- if(strcmp(olduser,item.user) != 0) {
- totuser++;
-
- if (olduser[0] != '\0') {
- /*
- This complicated printf is due to Microsoft's inability to comply with any standard. Msvcrt is unable
- to print a long long int unless it is exactly 64-bits long.
- */
- fprintf(fp_top2,"%s\t%"PRIu64"\t%"PRIu64"\t%"PRIu64"\t%"PRIu64"\t%"PRIu64"\n",olduser,(uint64_t)tnbytes,(uint64_t)tnacc,(uint64_t)tnelap,(uint64_t)tnincache,(uint64_t)tnoucache);
-
- ttnbytes+=tnbytes;
- ttnacc+=tnacc;
- ttnelap+=tnelap;
- ttnincache+=tnincache;
- ttnoucache+=tnoucache;
- }
- strcpy(olduser,item.user);
- tnbytes=0;
- tnacc=0;
- tnelap=0;
- tnincache=0;
- tnoucache=0;
- }
-
- tnbytes+=item.nbytes;
- tnacc+=item.nacc;
- tnelap+=item.nelap;
- tnincache+=item.incache;
- tnoucache+=item.oucache;
- }
- if (FileObject_Close(fp_in)) {
- debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wger,FileObject_GetLastCloseError());
- exit(EXIT_FAILURE);
- }
- longline_destroy(&line);
-
- if (olduser[0] != '\0') {
- /*
- This complicated printf is due to Microsoft's inability to comply with any standard. Msvcrt is unable
- to print a long long int unless it is exactly 64-bits long.
- */
- fprintf(fp_top2,"%s\t%"PRIu64"\t%"PRIu64"\t%"PRIu64"\t%"PRIu64"\t%"PRIu64"\n",olduser,(uint64_t)tnbytes,(uint64_t)tnacc,(uint64_t)tnelap,(uint64_t)tnincache,(uint64_t)tnoucache);
-
- ttnbytes+=tnbytes;
- ttnacc+=tnacc;
- ttnelap+=tnelap;
- ttnincache+=tnincache;
- ttnoucache+=tnoucache;
- }
- if (fclose(fp_top2)==EOF) {
- debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),top2,strerror(errno));
- exit(EXIT_FAILURE);
- }
-
-#ifdef ENABLE_DOUBLE_CHECK_DATA
- if (ttnacc!=globstat.nacc || ttnbytes!=globstat.nbytes || ttnelap!=globstat.elap ||
- ttnincache!=globstat.incache || ttnoucache!=globstat.oucache) {
- debuga(__FILE__,__LINE__,_("Total statistics mismatch when reading \"%s\" to produce the top users\n"),wger);
- exit(EXIT_FAILURE);
- }
-#endif
-
- set_total_users(totuser);
-
- if((TopuserSort & TOPUSER_SORT_USER) != 0) {
- sfield="-k 1,1";
- sort_field=_("user");
- } else if((TopuserSort & TOPUSER_SORT_CONNECT) != 0) {
- sfield="-n -k 3,3";
- sort_field=_("connect");
- } else if((TopuserSort & TOPUSER_SORT_TIME) != 0) {
- sfield="-n -k 4,4";
- sort_field=pgettext("duration","time");
- } else {
- sort_field=_("bytes");
- }
-
- if((TopuserSort & TOPUSER_SORT_REVERSE) == 0) {
- order="";
- sort_order=_("normal");
- } else {
- order="-r";
- sort_order=_("reverse");
- }
-
- snprintf(top1,sizeof(top1),"%s/top",outdirname);
- if (snprintf(csort,sizeof(csort),"sort -T \"%s\" -t \"\t\" %s %s -o \"%s\" \"%s\"", tmp, order, sfield, top1, top2)>=sizeof(csort)) {
- debuga(__FILE__,__LINE__,_("Sort command too long when sorting file \"%s\" to \"%s\"\n"),top2,top1);
- 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((fp_top1=FileObject_Open(top1))==NULL) {
- debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),top1,FileObject_GetLastOpenError());
- exit(EXIT_FAILURE);
- }
-
- if (!KeepTempLog && unlink(top2)) {
- debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),top2,strerror(errno));
+ if ((fp_top1=FileObject_Open(ListFile))==NULL) {
+ debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),ListFile,FileObject_GetLastOpenError());
exit(EXIT_FAILURE);
}
snprintf(top3,sizeof(top3),"%s/"INDEX_HTML_FILE,outdirname);
- if((fp_top3=fopen(top3,"w"))==NULL) {
+ if ((fp_top3=fopen(top3,"w"))==NULL) {
debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),top3,strerror(errno));
exit(EXIT_FAILURE);
}
fputs("</td></tr>\n",fp_top3);
if ((ReportType & REPORT_TYPE_TOPUSERS) != 0) {
fputs("<tr><td class=\"header_c\">",fp_top3);
- fprintf(fp_top3,_("Sort: %s, %s"),sort_field,sort_order);
+ fprintf(fp_top3,_("Sort: %s, %s"),SortInfo->sort_field,SortInfo->sort_order);
fputs("</td></tr>\n",fp_top3);
fprintf(fp_top3,"<tr><th class=\"header_c\">%s</th></tr>\n",_("Top users"));
} else {
greport_prepare();
- ntopuser = 0;
-
if ((line=longline_create())==NULL) {
- debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\"\n"),top1);
+ debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\"\n"),ListFile);
exit(EXIT_FAILURE);
}
- while((warea=longline_read(fp_top1,line))!=NULL) {
+ while ((warea=longline_read(fp_top1,line))!=NULL) {
getword_start(&gwarea,warea);
if (getword(user,sizeof(user),&gwarea,'\t')<0) {
- debuga(__FILE__,__LINE__,_("Invalid user in file \"%s\"\n"),top1);
+ debuga(__FILE__,__LINE__,_("Invalid user in file \"%s\"\n"),ListFile);
exit(EXIT_FAILURE);
}
if (getword_atoll(&nbytes,&gwarea,'\t')<0) {
- debuga(__FILE__,__LINE__,_("Invalid number of bytes in file \"%s\"\n"),top1);
+ debuga(__FILE__,__LINE__,_("Invalid number of bytes in file \"%s\"\n"),ListFile);
exit(EXIT_FAILURE);
}
if (getword_atoll(&nacc,&gwarea,'\t')<0) {
- debuga(__FILE__,__LINE__,_("Invalid number of accesses in file \"%s\"\n"),top1);
+ debuga(__FILE__,__LINE__,_("Invalid number of accesses in file \"%s\"\n"),ListFile);
exit(EXIT_FAILURE);
}
if (getword_atoll(&elap,&gwarea,'\t')<0) {
- debuga(__FILE__,__LINE__,_("Invalid elapsed time in file \"%s\"\n"),top1);
+ debuga(__FILE__,__LINE__,_("Invalid elapsed time in file \"%s\"\n"),ListFile);
exit(EXIT_FAILURE);
}
if (getword_atoll(&incac,&gwarea,'\t')<0) {
- debuga(__FILE__,__LINE__,_("Invalid in-cache size in file \"%s\"\n"),top1);
+ debuga(__FILE__,__LINE__,_("Invalid in-cache size in file \"%s\"\n"),ListFile);
exit(EXIT_FAILURE);
}
if (getword_atoll(&oucac,&gwarea,'\n')<0) {
- debuga(__FILE__,__LINE__,_("Invalid out-of-cache size in file \"%s\"\n"),top1);
+ debuga(__FILE__,__LINE__,_("Invalid out-of-cache size in file \"%s\"\n"),ListFile);
exit(EXIT_FAILURE);
}
- if(nacc < 1)
+ if (nacc < 1)
continue;
- ntopuser = 1;
- if(TopUsersNum > 0 && topcount >= TopUsersNum) break;
- tnbytes=nbytes;
- tnelap=elap;
+ ntopuser=true;
+ if (TopUsersNum>0 && topcount>=TopUsersNum) break;
uinfo=userinfo_find_from_id(user);
if (!uinfo) {
- debuga(__FILE__,__LINE__,_("Unknown user ID %s in file \"%s\"\n"),user,top1);
+ debuga(__FILE__,__LINE__,_("Unknown user ID %s in file \"%s\"\n"),user,ListFile);
exit(EXIT_FAILURE);
}
uinfo->topuser=1;
}
if((TopUserFields & TOPUSERFIELDS_BYTES) != 0) {
fputs("<td class=\"data\"",fp_top3);
- if (SortTableJs[0]) fprintf(fp_top3," sorttable_customkey=\"%"PRId64"\"",(int64_t)tnbytes);
- fprintf(fp_top3,">%s</td>",fixnum(tnbytes,1));
+ if (SortTableJs[0]) fprintf(fp_top3," sorttable_customkey=\"%"PRId64"\"",(int64_t)nbytes);
+ fprintf(fp_top3,">%s</td>",fixnum(nbytes,1));
}
if((TopUserFields & TOPUSERFIELDS_SETYB) != 0) {
- perc=(ttnbytes) ? tnbytes * 100. / ttnbytes : 0.;
+ perc=(Statis->ttnbytes) ? nbytes * 100. / Statis->ttnbytes : 0.;
fprintf(fp_top3,"<td class=\"data\">%3.2lf%%</td>",perc);
}
if((TopUserFields & TOPUSERFIELDS_IN_CACHE_OUT) != 0) {
- inperc=(tnbytes) ? incac * 100. / tnbytes : 0.;
- ouperc=(tnbytes) ? oucac * 100. / tnbytes : 0.;
+ inperc=(nbytes) ? incac * 100. / nbytes : 0.;
+ ouperc=(nbytes) ? oucac * 100. / nbytes : 0.;
fprintf(fp_top3,"<td class=\"data\">%3.2lf%%</td><td class=\"data\">%3.2lf%%</td>",inperc,ouperc);
#ifdef ENABLE_DOUBLE_CHECK_DATA
if ((inperc!=0. || ouperc!=0.) && fabs(inperc+ouperc-100.)>=0.01) {
}
if((TopUserFields & TOPUSERFIELDS_USED_TIME) != 0) {
fputs("<td class=\"data\"",fp_top3);
- if (SortTableJs[0]) fprintf(fp_top3," sorttable_customkey=\"%"PRId64"\"",(int64_t)tnelap);
- fprintf(fp_top3,">%s</td>",buildtime(tnelap));
+ if (SortTableJs[0]) fprintf(fp_top3," sorttable_customkey=\"%"PRId64"\"",(int64_t)elap);
+ fprintf(fp_top3,">%s</td>",buildtime(elap));
}
if((TopUserFields & TOPUSERFIELDS_MILISEC) != 0) {
fputs("<td class=\"data\"",fp_top3);
- if (SortTableJs[0]) fprintf(fp_top3," sorttable_customkey=\"%"PRId64"\"",(int64_t)tnelap);
- fprintf(fp_top3,">%s</td>",fixnum2(tnelap,1));
+ if (SortTableJs[0]) fprintf(fp_top3," sorttable_customkey=\"%"PRId64"\"",(int64_t)elap);
+ fprintf(fp_top3,">%s</td>",fixnum2(elap,1));
}
if((TopUserFields & TOPUSERFIELDS_PTIME) != 0) {
- perc2=(ttnelap) ? elap * 100. / ttnelap : 0.;
+ perc2=(Statis->ttnelap) ? elap * 100. / Statis->ttnelap : 0.;
fprintf(fp_top3,"<td class=\"data\">%3.2lf%%</td>",perc2);
}
topcount++;
}
if (FileObject_Close(fp_top1)) {
- debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),top1,FileObject_GetLastCloseError());
+ debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),ListFile,FileObject_GetLastCloseError());
exit(EXIT_FAILURE);
}
- if (!KeepTempLog && unlink(top1)) {
- debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),top1,strerror(errno));
+ if (!KeepTempLog && unlink(ListFile)) {
+ debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),ListFile,strerror(errno));
exit(EXIT_FAILURE);
}
longline_destroy(&line);
- if((TopUserFields & TOPUSERFIELDS_TOTAL) != 0) {
+ if ((TopUserFields & TOPUSERFIELDS_TOTAL) != 0) {
fputs("<tfoot><tr>",fp_top3);
if((TopUserFields & TOPUSERFIELDS_NUM) != 0)
fputs("<td></td>",fp_top3);
fprintf(fp_top3,"<th class=\"header_l\">%s</th>",_("TOTAL"));
if((TopUserFields & TOPUSERFIELDS_CONNECT) != 0)
- fprintf(fp_top3,"<th class=\"header_r\">%s</th>",fixnum(ttnacc,1));
+ fprintf(fp_top3,"<th class=\"header_r\">%s</th>",fixnum(Statis->ttnacc,1));
if((TopUserFields & TOPUSERFIELDS_BYTES) != 0)
- fprintf(fp_top3,"<th class=\"header_r\">%15s</th>",fixnum(ttnbytes,1));
+ fprintf(fp_top3,"<th class=\"header_r\">%15s</th>",fixnum(Statis->ttnbytes,1));
if((TopUserFields & TOPUSERFIELDS_SETYB) != 0)
fputs("<td></td>",fp_top3);
if((TopUserFields & TOPUSERFIELDS_IN_CACHE_OUT) != 0)
{
- inperc=(ttnbytes) ? ttnincache * 100. / ttnbytes : 0.;
- ouperc=(ttnbytes) ? ttnoucache *100. / ttnbytes : 0.;
+ inperc=(Statis->ttnbytes) ? Statis->ttnincache * 100. / Statis->ttnbytes : 0.;
+ ouperc=(Statis->ttnbytes) ? Statis->ttnoucache *100. / Statis->ttnbytes : 0.;
fprintf(fp_top3,"<th class=\"header_r\">%3.2lf%%</th><th class=\"header_r\">%3.2lf%%</th>",inperc,ouperc);
#ifdef ENABLE_DOUBLE_CHECK_DATA
if (fabs(inperc+ouperc-100.)>=0.01) {
#endif
}
if((TopUserFields & TOPUSERFIELDS_USED_TIME) != 0)
- fprintf(fp_top3,"<th class=\"header_r\">%s</th>",buildtime(ttnelap));
+ fprintf(fp_top3,"<th class=\"header_r\">%s</th>",buildtime(Statis->ttnelap));
if((TopUserFields & TOPUSERFIELDS_MILISEC) != 0)
- fprintf(fp_top3,"<th class=\"header_r\">%s</th>",fixnum2(ttnelap,1));
+ fprintf(fp_top3,"<th class=\"header_r\">%s</th>",fixnum2(Statis->ttnelap,1));
fputs("</tr>\n",fp_top3);
}
greport_cleanup();
- if(ntopuser && (TopUserFields & TOPUSERFIELDS_AVERAGE) != 0) {
+ if (ntopuser && (TopUserFields & TOPUSERFIELDS_AVERAGE) != 0) {
fputs("<tr>",fp_top3);
if((TopUserFields & TOPUSERFIELDS_NUM) != 0)
fputs("<td></td>",fp_top3);
fprintf(fp_top3,"<th class=\"header_l\">%s</th>",_("AVERAGE"));
if((TopUserFields & TOPUSERFIELDS_CONNECT) != 0)
- fprintf(fp_top3,"<th class=\"header_r\">%s</th>",fixnum(ttnacc/totuser,1));
+ fprintf(fp_top3,"<th class=\"header_r\">%s</th>",fixnum(Statis->ttnacc/Statis->totuser,1));
if((TopUserFields & TOPUSERFIELDS_BYTES) != 0) {
- tnbytes=(totuser) ? ttnbytes / totuser : 0;
- fprintf(fp_top3,"<th class=\"header_r\">%15s</th>",fixnum(tnbytes,1));
+ nbytes=(Statis->totuser) ? Statis->ttnbytes / Statis->totuser : 0;
+ fprintf(fp_top3,"<th class=\"header_r\">%15s</th>",fixnum(nbytes,1));
}
if((TopUserFields & TOPUSERFIELDS_SETYB) != 0)
fputs("<td></td>",fp_top3);
if((TopUserFields & TOPUSERFIELDS_IN_CACHE_OUT) != 0)
fputs("<td></td><td></td>",fp_top3);
if((TopUserFields & TOPUSERFIELDS_USED_TIME) != 0)
- fprintf(fp_top3,"<th class=\"header_r\">%s</th>",buildtime(ttnelap/totuser));
+ fprintf(fp_top3,"<th class=\"header_r\">%s</th>",buildtime(Statis->ttnelap/Statis->totuser));
if((TopUserFields & TOPUSERFIELDS_MILISEC) != 0)
- fprintf(fp_top3,"<th class=\"header_r\">%s</th>",fixnum2(ttnelap/totuser,1));
+ fprintf(fp_top3,"<th class=\"header_r\">%s</th>",fixnum2(Statis->ttnelap/Statis->totuser,1));
fputs("</tr></tfoot>\n",fp_top3);
}
debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),top3,strerror(errno));
exit(EXIT_FAILURE);
}
+}
+
+/*!
+ * Produce a report with the user downloading the most data.
+ */
+void topuser(void)
+{
+ FileObject *fp_in = NULL;
+ FILE *fp_top2;
+ char wger[MAXLEN];
+ char top1[MAXLEN];
+ char top2[MAXLEN];
+ longline line;
+ long long int tnacc=0;
+ long long int tnbytes=0, tnelap=0;
+ long long int tnincache=0, tnoucache=0;
+ char *warea;
+ struct generalitemstruct item;
+ char olduser[MAX_USER_LEN], csort[MAXLEN];
+ const char *sfield="-n -k 2,2";
+ const char *order;
+ int cstatus;
+ struct TopUserStatistics Statis;
+ struct SortInfoStruct SortInfo;
+
+ if (debugz>=LogLevel_Process)
+ debuga(__FILE__,__LINE__,_("Creating top users report...\n"));
+
+ memset(&Statis,0,sizeof(Statis));
+
+ snprintf(wger,sizeof(wger),"%s/sarg-general",outdirname);
+ if ((fp_in=FileObject_Open(wger))==NULL) {
+ debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),wger,FileObject_GetLastOpenError());
+ exit(EXIT_FAILURE);
+ }
+
+ snprintf(top2,sizeof(top2),"%s/top.tmp",outdirname);
+ if ((fp_top2=fopen(top2,"w"))==NULL) {
+ debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),top2,strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ olduser[0]='\0';
+
+ if ((line=longline_create())==NULL) {
+ debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\"\n"),wger);
+ exit(EXIT_FAILURE);
+ }
+
+ while ((warea=longline_read(fp_in,line))!=NULL) {
+ ger_read(warea,&item,wger);
+ if (item.total) continue;
+ if (strcmp(olduser,item.user) != 0) {
+ Statis.totuser++;
+
+ if (olduser[0] != '\0') {
+ /*
+ This complicated printf is due to Microsoft's inability to comply with any standard. Msvcrt is unable
+ to print a long long int unless it is exactly 64-bits long.
+ */
+ fprintf(fp_top2,"%s\t%"PRIu64"\t%"PRIu64"\t%"PRIu64"\t%"PRIu64"\t%"PRIu64"\n",olduser,(uint64_t)tnbytes,(uint64_t)tnacc,(uint64_t)tnelap,(uint64_t)tnincache,(uint64_t)tnoucache);
+
+ Statis.ttnbytes+=tnbytes;
+ Statis.ttnacc+=tnacc;
+ Statis.ttnelap+=tnelap;
+ Statis.ttnincache+=tnincache;
+ Statis.ttnoucache+=tnoucache;
+ }
+ safe_strcpy(olduser,item.user,sizeof(olduser));
+ tnbytes=0;
+ tnacc=0;
+ tnelap=0;
+ tnincache=0;
+ tnoucache=0;
+ }
+
+ tnbytes+=item.nbytes;
+ tnacc+=item.nacc;
+ tnelap+=item.nelap;
+ tnincache+=item.incache;
+ tnoucache+=item.oucache;
+ }
+ if (FileObject_Close(fp_in)) {
+ debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wger,FileObject_GetLastCloseError());
+ exit(EXIT_FAILURE);
+ }
+ longline_destroy(&line);
+
+ if (olduser[0] != '\0') {
+ /*
+ This complicated printf is due to Microsoft's inability to comply with any standard. Msvcrt is unable
+ to print a long long int unless it is exactly 64-bits long.
+ */
+ fprintf(fp_top2,"%s\t%"PRIu64"\t%"PRIu64"\t%"PRIu64"\t%"PRIu64"\t%"PRIu64"\n",olduser,(uint64_t)tnbytes,(uint64_t)tnacc,(uint64_t)tnelap,(uint64_t)tnincache,(uint64_t)tnoucache);
+
+ Statis.ttnbytes+=tnbytes;
+ Statis.ttnacc+=tnacc;
+ Statis.ttnelap+=tnelap;
+ Statis.ttnincache+=tnincache;
+ Statis.ttnoucache+=tnoucache;
+ }
+ if (fclose(fp_top2)==EOF) {
+ debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),top2,strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+#ifdef ENABLE_DOUBLE_CHECK_DATA
+ if (Statis.ttnacc!=globstat.nacc || Statis.ttnbytes!=globstat.nbytes || Statis.ttnelap!=globstat.elap ||
+ Statis.ttnincache!=globstat.incache || Statis.ttnoucache!=globstat.oucache) {
+ debuga(__FILE__,__LINE__,_("Total statistics mismatch when reading \"%s\" to produce the top users\n"),wger);
+ exit(EXIT_FAILURE);
+ }
+#endif
+
+ set_total_users(Statis.totuser);
+
+ if((TopuserSort & TOPUSER_SORT_USER) != 0) {
+ sfield="-k 1,1";
+ SortInfo.sort_field=_("user");
+ } else if((TopuserSort & TOPUSER_SORT_CONNECT) != 0) {
+ sfield="-n -k 3,3";
+ SortInfo.sort_field=_("connect");
+ } else if((TopuserSort & TOPUSER_SORT_TIME) != 0) {
+ sfield="-n -k 4,4";
+ SortInfo.sort_field=pgettext("duration","time");
+ } else {
+ SortInfo.sort_field=_("bytes");
+ }
+
+ if((TopuserSort & TOPUSER_SORT_REVERSE) == 0) {
+ order="";
+ SortInfo.sort_order=_("normal");
+ } else {
+ order="-r";
+ SortInfo.sort_order=_("reverse");
+ }
+
+ snprintf(top1,sizeof(top1),"%s/top",outdirname);
+ if (snprintf(csort,sizeof(csort),"sort -T \"%s\" -t \"\t\" %s %s -o \"%s\" \"%s\"", tmp, order, sfield, top1, top2)>=sizeof(csort)) {
+ debuga(__FILE__,__LINE__,_("Sort command too long when sorting file \"%s\" to \"%s\"\n"),top2,top1);
+ 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(top2)) {
+ debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),top2,strerror(errno));
+ exit(EXIT_FAILURE);
+ }
- return;
+ TopUser_HtmlReport(top1,&Statis,&SortInfo);
}