]> git.ipfire.org Git - thirdparty/sarg.git/blobdiff - util.c
Add support to decompress xz files
[thirdparty/sarg.git] / util.c
diff --git a/util.c b/util.c
index d350c342c325938b27f7e5d943516f06ddc45196..aba23b191b769db4af96cb708361bda67c3d6bdb 100644 (file)
--- a/util.c
+++ b/util.c
@@ -507,7 +507,7 @@ Compare two dates.
 \retval 0 If date1==date2.
 \retval 1 if date1>date2.
 */
-int compare_date(struct tm *date1,struct tm *date2)
+int compare_date(const struct tm *date1,const struct tm *date2)
 {
        if (date1->tm_year<date2->tm_year) return(-1);
        if (date1->tm_year>date2->tm_year) return(1);
@@ -898,7 +898,7 @@ int obtuser(const char *dirname, const char *name)
 
 void obttotal(const char *dirname, const char *name, int nuser, long long int *tbytes, long long int *media)
 {
-       FILE *fp_in;
+       FileObject *fp_in;
        char *buf;
        char wdir[MAXLEN];
        char user[MAX_USER_LEN];
@@ -914,13 +914,13 @@ void obttotal(const char *dirname, const char *name, int nuser, long long int *t
                debuga_more("%s%s/sarg-general",dirname,name);
                exit(EXIT_FAILURE);
        }
-       if ((fp_in = fopen(wdir, "r")) == 0) {
+       if ((fp_in = FileObject_Open(wdir)) == NULL) {
                if (snprintf(wdir,sizeof(wdir),"%s%s/general",dirname,name)>=sizeof(wdir)) {
                        debuga(__FILE__,__LINE__,_("Buffer too small to store "));
                        debuga_more("%s%s/general",dirname,name);
                        exit(EXIT_FAILURE);
                }
-               if ((fp_in = fopen(wdir, "r")) == 0) {
+               if ((fp_in = FileObject_Open(wdir)) == NULL) {
                        return;
                }
        }
@@ -954,8 +954,8 @@ void obttotal(const char *dirname, const char *name, int nuser, long long int *t
                }
                break;
        }
-       if (fclose(fp_in)==EOF) {
-               debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wdir,strerror(errno));
+       if (FileObject_Close(fp_in)) {
+               debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wdir,FileObject_GetLastCloseError());
                exit(EXIT_FAILURE);
        }
        longline_destroy(&line);
@@ -988,7 +988,7 @@ int getperiod_fromsarglog(const char *arqtt,struct periodstruct *period)
                str+=2;
                year0=0;
                for (i=0 ; isdigit(str[i]) && i<4 ; i++) year0=year0*10+(str[i]-'0');
-               if (i!=4) continue;
+               if (i!=4 || year0<1900) continue;
                str+=4;
                if (str[0]!='_') continue;
                str++;
@@ -1012,7 +1012,7 @@ int getperiod_fromsarglog(const char *arqtt,struct periodstruct *period)
                str+=2;
                year1=0;
                for (i=0 ; isdigit(str[i]) && i<4 ; i++) year1=year1*10+(str[i]-'0');
-               if (i!=4) continue;
+               if (i!=4 || year1<1900) continue;
                str+=4;
 
                if (str[0]!='_') continue;
@@ -1040,6 +1040,13 @@ int getperiod_fromsarglog(const char *arqtt,struct periodstruct *period)
        return(-1);
 }
 
+/*!
+Fill the period with the specified range.
+
+\param period The period to change.
+\param dfrom The start date in the form year*10000+month*100+day.
+\param duntil The end date in the form year*10000+month*100+day.
+*/
 void getperiod_fromrange(struct periodstruct *period,int dfrom,int duntil)
 {
        memset(&period->start,0,sizeof(period->start));
@@ -1053,6 +1060,21 @@ void getperiod_fromrange(struct periodstruct *period,int dfrom,int duntil)
        period->end.tm_year=(duntil/10000)-1900;
 }
 
+/*!
+Get the range from a period.
+
+\param period The period to convert to a range.
+\param dfrom The variable to store the range beginning. It can be NULL.
+\param duntil The variable to store the range end. It can be NULL.
+*/
+void getperiod_torange(const struct periodstruct *period,int *dfrom,int *duntil)
+{
+       if (dfrom)
+               *dfrom=(period->start.tm_year+1900)*10000+(period->start.tm_mon+1)*100+period->start.tm_mday;
+       if (duntil)
+               *duntil=(period->end.tm_year+1900)*10000+(period->end.tm_mon+1)*100+period->end.tm_mday;
+}
+
 /*!
 Update the \a main period to encompass the period in \a candidate.
 */
@@ -1063,7 +1085,7 @@ void getperiod_merge(struct periodstruct *main,struct periodstruct *candidate)
 
        mdate=(main->start.tm_year)*10000+(main->start.tm_mon)*100+main->start.tm_mday;
        cdate=(candidate->start.tm_year)*10000+(candidate->start.tm_mon)*100+candidate->start.tm_mday;
-       if (cdate<mdate) memcpy(&main->start,&candidate->start,sizeof(struct tm));
+       if (mdate==0 || cdate<mdate) memcpy(&main->start,&candidate->start,sizeof(struct tm));
 
        mdate=(main->end.tm_year)*10000+(main->end.tm_mon)*100+main->end.tm_mday;
        cdate=(candidate->end.tm_year)*10000+(candidate->end.tm_mon)*100+candidate->end.tm_mday;
@@ -1347,12 +1369,24 @@ bool IsTreeDayFileName(const char *Name)
        return(true);
 }
 
-int vrfydir(const struct periodstruct *per1, const char *addr, const char *site, const char *us, const char *form)
+/*!
+ * Create a directory to generate a report for the specified connection data
+ * and populate it with the a <tt>sarg-date</tt> file containing the current
+ * date.
+ *
+ * The function also create an <tt>images</tt> directory in \a dir and copy all
+ * the files from the <tt>SYSCONFDIR/images</tt> into that directory.
+ *
+ * \param per1 The date range in the form: YYYYMMMDD-YYYYMMMDD or DDMMMYYYY-DDMMMYYYY depending on the value of
+ * ::DateFormat.
+ * \param addr The ip address or host name to which the report is limited. If the string is empty, all the addresses are accepted.
+ * \param site The destination site to which the report is limited. If the string is empty, all the sites are accepted.
+ * \param us The user to whom the report is limited. It is an empty string if all the users are accepted.
+ */
+int vrfydir(const struct periodstruct *per1, const char *addr, const char *site, const char *us)
 {
        FILE *fp_ou;
-       int  num=1, count=0;
        char wdir[MAXLEN];
-       char dirname2[MAXLEN];
        int y1, y2;
        int m1, m2;
        int d1, d2;
@@ -1413,58 +1447,28 @@ int vrfydir(const struct periodstruct *per1, const char *addr, const char *site,
 
        strcpy(outdirname,wdir);
 
-       if(IndexTree != INDEX_TREE_DATE) {
-               if(!OverwriteReport) {
-                       while(num) {
-                               if(access(wdir,R_OK) == 0) {
-                                       sprintf(wdir,"%s.%d",outdirname,num);
-                                       num++;
-                                       count++;
-                               } else
-                                       break;
-                       }
+       // manufacture a new unique name if configured to keep old reports or overwrite old report if configured to do so
+       if (!OverwriteReport) {
+               int num=1;
 
-                       if(count > 0) {
-                               if(debug)
-                                       debuga(__FILE__,__LINE__,_("File %s already exists, moved to %s\n"),outdirname,wdir);
-                               rename(outdirname,wdir);
-                       }
-               } else {
-                       if(access(outdirname,R_OK) == 0) {
-                               unlinkdir(outdirname,1);
-                       }
+               while (access(wdir,R_OK)==0 || errno==EACCES) //file exist or can't be read
+               {
+                       sprintf(wdir,"%s.%d",outdirname,num);
+                       num++;
+               }
+               if (num>1) {
+                       if(debug)
+                               debuga(__FILE__,__LINE__,_("File %s already exists, moved to %s\n"),outdirname,wdir);
+                       rename(outdirname,wdir);
                }
-               my_mkdir(outdirname);
        } else {
-               strcpy(dirname2,wdir);
-               if(!OverwriteReport) {
-                       while(num) {
-                               if(access(wdir,R_OK) == 0) {
-                                       sprintf(wdir,"%s.%d",dirname2,num);
-                                       num++;
-                                       count++;
-                               } else
-                                       break;
-                       }
-
-                       if(count > 0) {
-                               if(debug)
-                                       debuga(__FILE__,__LINE__,_("File %s already exists, moved to %s\n"),dirname2,wdir);
-                               rename(dirname2,wdir);
-                               strcpy(dirname2,wdir);
-                       }
-               } else {
-                       if(access(wdir,R_OK) == 0) {
-                               unlinkdir(wdir,1);
-                       }
+               if(access(outdirname,R_OK) == 0) {
+                       unlinkdir(outdirname,1);
                }
-
-               if(access(wdir, R_OK) != 0)
-                       my_mkdir(wdir);
        }
+       my_mkdir(outdirname);
 
-       strcpy(dirname2,wdir);
-
+       // create sarg-date to keep track of the report creation date
        if (snprintf(wdir,sizeof(wdir),"%s/sarg-date",outdirname)>=sizeof(wdir)) {
                debuga(__FILE__,__LINE__,_("Buffer too small to store "));
                debuga_more("%s/sarg-date",outdirname);
@@ -2167,7 +2171,7 @@ void version(void)
        printf(_("SARG Version: %s\n"),VERSION);
 #if defined(ENABLE_NLS) && defined(HAVE_LOCALE_H)
        if (debug) {
-               printf(_("\nFor the translation to work, a valid message file should be installed as "
+               printf(_("\nFor the translation to work, a valid message file should be copied to "
                                 "\"%s/<Locale>/LC_MESSAGES/%s.mo\" where <Locale> is derived from the effective locale.\n"),LOCALEDIR,PACKAGE_NAME);
                if (CurrentLocale) {
                        printf(_("Currently effective locale is \"%s\".\n"),CurrentLocale);
@@ -2178,6 +2182,13 @@ void version(void)
                printf(_("If this message is in English, then your language is not supported or not correctly installed.\n"));
        }
 #endif
+       if (debug) {
+#ifdef HAVE_GLOB_H
+               printf(_("File globbing compiled in.\n"));
+#else
+               printf(_("File globbing NOT compiled in.\n"));
+#endif
+       }
        exit(EXIT_SUCCESS);
 }
 
@@ -2277,7 +2288,8 @@ void emptytmpdir(const char *dir)
                ".utmp",
                ".ip",
                "lastlog1",
-               "lastlog"
+               "lastlog",
+               "emailrep"
        };
 
        dirp=opendir(dir);
@@ -2317,9 +2329,7 @@ void emptytmpdir(const char *dir)
                        debuga(__FILE__,__LINE__,_("Cannot stat \"%s\": %s\n"),dname,strerror(errno));
                        exit(EXIT_FAILURE);
                }
-               if (S_ISDIR(st.st_mode)) {
-                       unlinkdir(dname,0);
-               } else if (!S_ISREG(st.st_mode)) {
+               if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode)) {
                        debuga(__FILE__,__LINE__,_("Unknown path type for \"%s\". Check temporary directory\n"),dname);
                        exit(EXIT_FAILURE);
                }
@@ -2359,7 +2369,9 @@ void emptytmpdir(const char *dir)
                        debuga(__FILE__,__LINE__,_("Cannot stat \"%s\": %s\n"),dname,strerror(errno));
                        exit(EXIT_FAILURE);
                }
-               if (S_ISREG(st.st_mode)) {
+               if (S_ISDIR(st.st_mode)) {
+                       unlinkdir(dname,0);
+               } else if (S_ISREG(st.st_mode)) {
                        if (unlink(dname)) {
                                debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),dname,strerror(errno));
                                exit(EXIT_FAILURE);