"Fossies" - the Fresh Open Source Software Archive

Member "sarg-2.4.0/lastlog.c" (24 Dec 2019, 8509 Bytes) of package /linux/privat/sarg-2.4.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "lastlog.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.3.11_vs_2.4.0.

    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 struct DirEntry
   31 {
   32     struct DirEntry *Next;
   33     time_t Time;
   34     char *Name;
   35 };
   36 
   37 static void DeleteDirList(struct DirEntry *List)
   38 {
   39     struct DirEntry *Next;
   40 
   41     while (List)
   42     {
   43         Next=List->Next;
   44         if (List->Name) free(List->Name);
   45         free(List);
   46         List=Next;
   47     }
   48 }
   49 
   50 static struct DirEntry *AppendDirEntry(struct DirEntry *List,time_t CreationTime,const char *Name,int NameLen)
   51 {
   52     struct DirEntry *entry;
   53     struct DirEntry *prev;
   54     struct DirEntry *ptr;
   55 
   56     entry=malloc(sizeof(*entry));
   57     if (!entry) {
   58         debuga(__FILE__,__LINE__,_("Not enough memory to store a report to purge\n"));
   59         DeleteDirList(List);
   60         return(NULL);
   61     }
   62     entry->Name=malloc((NameLen+1)*sizeof(char));
   63     if (!entry->Name) {
   64         free(entry);
   65         debuga(__FILE__,__LINE__,_("Not enough memory to store a report to purge\n"));
   66         DeleteDirList(List);
   67         return(NULL);
   68     }
   69     entry->Time=CreationTime;
   70     strcpy(entry->Name,Name);
   71 
   72     // store most recent file first
   73     prev=NULL;
   74     for (ptr=List ; ptr ; ptr=ptr->Next)
   75     {
   76         if (ptr->Time>CreationTime) break;
   77         prev=ptr;
   78     }
   79     entry->Next=ptr;
   80     if (prev)
   81         prev->Next=entry;
   82     else
   83         List=entry;
   84 
   85     return(List);
   86 }
   87 
   88 static struct DirEntry *BuildDirDateList(struct DirEntry *List,char *Path,int PathSize,int RootPos,int Length,int Level)
   89 {
   90     DIR *dirp;
   91     struct dirent *direntp;
   92     struct stat statb;
   93     int name_len;
   94 
   95     if ((dirp = opendir(Path)) == NULL) {
   96         debuga(__FILE__,__LINE__,_("Cannot open directory \"%s\": %s\n"),Path,strerror(errno));
   97         exit(EXIT_FAILURE);
   98     }
   99     while ((direntp = readdir( dirp )) != NULL )
  100     {
  101         name_len=strlen(direntp->d_name);
  102         if (RootPos+name_len+1>=PathSize) {
  103             debuga(__FILE__,__LINE__,_("Directory entry \"%s%s\" too long to purge the old reports\n"),Path,direntp->d_name);
  104             exit(EXIT_FAILURE);
  105         }
  106         strcpy(Path+Length,direntp->d_name);
  107         if (stat(Path,&statb) == -1) {
  108             debuga(__FILE__,__LINE__,_("Failed to get the statistics of file \"%s\": %s\n"),Path,strerror(errno));
  109             continue;
  110         }
  111         if (!S_ISDIR(statb.st_mode)) continue;
  112         if (Level==0)
  113         {
  114             if (IsTreeMonthFileName(direntp->d_name))
  115             {
  116                 Path[Length+name_len]='/';
  117                 Path[Length+name_len+1]='\0';
  118                 List=BuildDirDateList(List,Path,PathSize,RootPos,Length+name_len+1,1);
  119                 if (!List)
  120                 {
  121                     debuga(__FILE__,__LINE__,_("Old reports deletion not undertaken due to previous error\n"));
  122                     break;
  123                 }
  124             }
  125         }
  126         else if (Level==1)
  127         {
  128             if (IsTreeDayFileName(direntp->d_name))
  129             {
  130                 List=AppendDirEntry(List,statb.st_mtime,Path+RootPos,Length-RootPos+name_len);
  131                 if (!List)
  132                 {
  133                     debuga(__FILE__,__LINE__,_("Old reports deletion not undertaken due to previous error\n"));
  134                     break;
  135                 }
  136             }
  137         }
  138     }
  139 
  140     closedir(dirp);
  141     return(List);
  142 }
  143 
  144 static struct DirEntry *BuildDirList(const char *Path)
  145 {
  146     DIR *dirp;
  147     struct dirent *direntp;
  148     struct stat statb;
  149     char warea[MAXLEN];
  150     int name_pos;
  151     int name_len;
  152     struct DirEntry *List=NULL;
  153 
  154     name_pos=strlen(Path);
  155     if (name_pos>=sizeof(warea)) {
  156         debuga(__FILE__,__LINE__,_("The directory name \"%s\" containing the old reports to purge is too long\n"),Path);
  157         exit(EXIT_FAILURE);
  158     }
  159     strcpy(warea,Path);
  160     if ((dirp = opendir(outdir)) == NULL) {
  161         debuga(__FILE__,__LINE__,_("Cannot open directory \"%s\": %s\n"),outdir,strerror(errno));
  162         exit(EXIT_FAILURE);
  163     }
  164     while ((direntp = readdir( dirp )) != NULL )
  165     {
  166         name_len=strlen(direntp->d_name);
  167         if (name_pos+name_len+1>=sizeof(warea)) {
  168             debuga(__FILE__,__LINE__,_("Directory entry \"%s%s\" too long to purge the old reports\n"),Path,direntp->d_name);
  169             exit(EXIT_FAILURE);
  170         }
  171         strcpy(warea+name_pos,direntp->d_name);
  172         if (stat(warea,&statb) == -1) {
  173             debuga(__FILE__,__LINE__,_("Failed to get the statistics of file \"%s\": %s\n"),warea,strerror(errno));
  174             continue;
  175         }
  176         if (!S_ISDIR(statb.st_mode)) continue;
  177         if (IsTreeFileDirName(direntp->d_name))
  178         {
  179             List=AppendDirEntry(List,statb.st_mtime,direntp->d_name,name_len);
  180             if (!List)
  181             {
  182                 debuga(__FILE__,__LINE__,_("Old reports deletion not undertaken due to previous error\n"));
  183                 break;
  184             }
  185         }
  186         else if (IsTreeYearFileName(direntp->d_name))
  187         {
  188             warea[name_pos+name_len]='/';
  189             warea[name_pos+name_len+1]='\0';
  190             List=BuildDirDateList(List,warea,sizeof(warea),name_pos,name_pos+name_len+1,0);
  191             if (!List)
  192             {
  193                 debuga(__FILE__,__LINE__,_("Old reports deletion not undertaken due to previous error\n"));
  194                 break;
  195             }
  196         }
  197     }
  198 
  199     closedir(dirp);
  200     return(List);
  201 }
  202 
  203 static void DeleteEmptyDirs(char *Path,int PathSize,int BasePos)
  204 {
  205     char *Dir;
  206     DIR *dirp;
  207     struct dirent *direntp;
  208     bool index;
  209 
  210     while ((Dir=strrchr(Path,'/'))!=NULL)
  211     {
  212         if (Dir-Path<=BasePos) break;
  213         *Dir='\0';
  214         if ((dirp = opendir(Path)) == NULL) {
  215             debuga(__FILE__,__LINE__,_("Cannot open directory \"%s\": %s\n"),Path,strerror(errno));
  216             return;
  217         }
  218         index=false;
  219         while ((direntp = readdir( dirp )) != NULL )
  220         {
  221             if (direntp->d_name[0]=='.' && (direntp->d_name[1]=='\0' || (direntp->d_name[1]=='.' && direntp->d_name[2]=='\0'))) continue;
  222             if (!strcmp(direntp->d_name,INDEX_HTML_FILE))
  223             {
  224                 index=true;
  225                 continue;
  226             }
  227             break;
  228         }
  229         closedir(dirp);
  230         if (direntp!=NULL) {
  231             // at least one file exists in the directory, don't delete the directory
  232             break;
  233         }
  234         if (debug)
  235             debuga(__FILE__,__LINE__,_("Deleting empty directory \"%s\"\n"),Path);
  236         if (index) {
  237             if (strlen(Path)+strlen(INDEX_HTML_FILE)+2>=PathSize) {
  238                 debuga(__FILE__,__LINE__,_("Buffer too small to delete index file \"%s/%s\""),Path,INDEX_HTML_FILE);
  239                 exit(EXIT_FAILURE);
  240             }
  241             strcat(Path,"/"INDEX_HTML_FILE);
  242             if (unlink(Path)==-1) {
  243                 debuga(__FILE__,__LINE__,_("Failed to delete \"%s\": %s\n"),Path,strerror(errno));
  244                 exit(EXIT_FAILURE);
  245             }
  246             *Dir='\0';
  247         }
  248         if (rmdir(Path)) {
  249             debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),Path,strerror(errno));
  250             exit(EXIT_FAILURE);
  251         }
  252     }
  253     //! \todo Rebuild the surviving index file
  254 }
  255 
  256 void mklastlog(const char *outdir)
  257 {
  258     char warea[MAXLEN];
  259     int name_pos;
  260     int  ftot=0;
  261     struct DirEntry *List;
  262     struct DirEntry *ptr;
  263 
  264     if (LastLog <= 0)
  265         return;
  266 
  267     List=BuildDirList(outdir);
  268     if (!List) return;
  269 
  270     for (ptr=List ; ptr ; ptr=ptr->Next) ftot++;
  271     if (debug)
  272         debuga(__FILE__,__LINE__,ngettext("%d report directory found\n","%d report directories found\n",ftot),ftot);
  273 
  274     if (ftot<=LastLog) {
  275         DeleteDirList(List);
  276         if (debug) {
  277             debuga(__FILE__,__LINE__,ngettext("No old reports to delete as only %d report currently exists\n",
  278                         "No old reports to delete as only %d reports currently exist\n",ftot),ftot);
  279         }
  280         return;
  281     }
  282 
  283     ftot-=LastLog;
  284     if (debug)
  285         debuga(__FILE__,__LINE__,ngettext("%d old report to delete\n","%d old reports to delete\n",ftot),ftot);
  286 
  287     name_pos=strlen(outdir);
  288     if (name_pos>=sizeof(warea)) {
  289         DeleteDirList(List);
  290         debuga(__FILE__,__LINE__,_("The directory name \"%s\" containing the old reports to purge is too long\n"),outdir);
  291         exit(EXIT_FAILURE);
  292     }
  293     strcpy(warea,outdir);
  294     for (ptr=List ; ptr && ftot>0 ; ptr=ptr->Next)
  295     {
  296         if (debug)
  297             debuga(__FILE__,__LINE__,_("Removing old report file %s\n"),ptr->Name);
  298         if (name_pos+strlen(ptr->Name)+1>=sizeof(warea)) {
  299             DeleteDirList(List);
  300             debuga(__FILE__,__LINE__,_("Path too long: "));
  301             debuga_more("%s%s\n",outdir,ptr->Name);
  302             exit(EXIT_FAILURE);
  303         }
  304         strcpy(warea+name_pos,ptr->Name);
  305         unlinkdir(warea,0);
  306         DeleteEmptyDirs(warea,sizeof(warea),name_pos);
  307         ftot--;
  308     }
  309 
  310     DeleteDirList(List);
  311     return;
  312 }