]> git.ipfire.org Git - thirdparty/sarg.git/commitdiff
Protect the creation of the index against invalid directories.
authorFrédéric Marchal <fmarchal@users.sourceforge.net>
Sun, 27 Dec 2009 14:38:26 +0000 (14:38 +0000)
committerFrédéric Marchal <fmarchal@users.sourceforge.net>
Sun, 27 Dec 2009 14:38:26 +0000 (14:38 +0000)
Only copy the files when creating the directory with the images to link the reports to.

CMakeLists.txt
ChangeLog
documentation/index.txt [new file with mode: 0644]
documentation/util.txt
include/conf.h
include/info.h
index.c
log.c
useragent.c
util.c

index efb79a4b22a3da1f14bfd25780278177e3e790a3..7982770b38712c0c8417c1e2dfb327e4b0c76c3e 100755 (executable)
@@ -3,7 +3,7 @@ PROJECT(sarg C)
 SET(sarg_VERSION 2)
 SET(sarg_REVISION 2)
 SET(sarg_BUILD "7rc1")
-SET(sarg_BUILDDATE "Dec-23-2009")
+SET(sarg_BUILDDATE "Dec-27-2009")
 
 INCLUDE(AddFileDependencies)
 INCLUDE(CheckIncludeFile)
index 18fdf6a5f5a7d59069f65a515a763014055cf89d..7b064f653dd9d70b1c53084e3231918e521179da 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,6 @@
 SARG ChangeLog
 
-Dec-23-2009 Version 2.2.7
+Dec-27-2009 Version 2.2.7
                - Extra compile and run time protection (FORTIFY_SOURCE) fixed in configure.
                - Use tabulations as columns separator in intermediary files to avoid problems when a field of the log contains a space.
                - Input log file type detection partly rewritten to clearly distinguish which type is processed where.
@@ -13,6 +13,8 @@ Dec-23-2009 Version 2.2.7
                - Use boolean to enable the options instead of string compares.
                - Accept an absolute path for the language file in sarg.conf.
                - Experimental: Can show the backtrace of the program when a getword loop is detected to help in locating the origin of the error.
+               - Protect the creation of the index against invalid directories.
+               - Only copy the files when creating the directory with the images to link the reports to.
 
 Dec-17-2009 Version 2.2.6.1
                - Remove unecessary dependency on off_t.
diff --git a/documentation/index.txt b/documentation/index.txt
new file mode 100644 (file)
index 0000000..783b0c7
--- /dev/null
@@ -0,0 +1,38 @@
+/*!\file index.c
+\brief Create the HTML index of the reports
+*/
+
+
+
+
+/*! \fn void make_index(void)
+Create the main HTML index of the available reports.
+*/
+
+
+
+
+
+/*! \fn static void file_index_to_date_index(const char *entry)
+Convert a report from the file tree into a report for a date tree.
+
+This function is invoked for each directory entry when ::IndexTree request a date index.
+The function has to opportunity to convert a previous entry created when ::IndexTree was
+requesting a file index.
+
+\param entry The directory name that may require to be converted.
+*/
+
+
+
+
+
+/*! \fn static void date_index_to_file_index(const char *entry)
+Convert a report from the date tree into a report for a file tree.
+
+This function is invoked for each directory entry when ::IndexTree request a file index.
+The function has to opportunity to convert a previous entry created when ::IndexTree was
+requesting a date index.
+
+\param entry The directory name that may require to be converted.
+*/
index 7db97afb50f151d4b90a8a58fc5af84f835556df..4b032e990db12b14b350a42e14b5a46766aaf0c9 100644 (file)
@@ -422,6 +422,15 @@ in the connection directory.
 
 
 
+/*! \fn static void copy_images(void)
+Copy the images (in fact all the files) from the directory ::IMAGEDIR into the output directory
+whose name is in ::outdir.
+*/
+
+
+
+
+
 /*! \fn void vrfydir(const char *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.
index 560c08b0f91a2375342f77c52baf6a83b10fbac1..9ec03fc3b87413b0a3a0c8f35a715e38894622ae 100755 (executable)
@@ -147,7 +147,6 @@ char per_hour[128];
 char code[MAXLEN];
 char code2[MAXLEN];
 char tmp[MAXLEN];
-char tmp2[MAXLEN];
 char tmp3[MAXLEN];
 char tmp4[MAXLEN];
 char tmp5[MAXLEN];
index 43d86d379f29be04e42091c84ac1791b76dcfaae..fe1969c5410b6242ad863b94105dd1cd90f5978c 100755 (executable)
@@ -1,3 +1,3 @@
-#define VERSION PACKAGE_VERSION" Dec-23-2009"
+#define VERSION PACKAGE_VERSION" Dec-27-2009"
 #define PGM PACKAGE_NAME
 #define URL "http://sarg.sourceforge.net"
diff --git a/index.c b/index.c
index f708770be16b171f0533011958b1b748bdd2ffd6..11f07ed6224986cfa15be7e810023401e7727ec6 100644 (file)
--- a/index.c
+++ b/index.c
 #include "include/conf.h"
 #include "include/defs.h"
 
+static void file_index_to_date_index(const char *entry);
+static void date_index_to_file_index(const char *entry);
+
 void make_index(void)
 {
-
    FILE *fp_ou, *fp_ou2, *fp_ou3, *fp_tmp, *fp_tmp2, *fp_tmp3;
    DIR *dirp, *dirp2, *dirp3;
    struct dirent *direntp;
@@ -49,11 +51,9 @@ void make_index(void)
    char ftime[128];
    char day[16], mon[16], year[40], hour[10];
    char *str;
+   char tmp2[MAXLEN];
    int cstatus;
    int iyear, imonth, iday, ihour, iminute, isecond, idst;
-   char y1[5], y2[5];
-   char d1[3], d2[3];
-   char m1[4], m2[4];
    struct getwordstruct gwarea;
 
    if(LastLog[0] != '\0') mklastlog(outdir);
@@ -70,124 +70,31 @@ void make_index(void)
 
    if(debug) debuga("%s",text[53]);
 
-   // Root dir
+   // convert any old report hierarchy
    dirp = opendir(outdir);
    while ((direntp = readdir( dirp )) != NULL) {
-      if(strcmp(IndexTree,"date") == 0) {
-         if(!isdigit(direntp->d_name[0]) && !isdigit(direntp->d_name[1])) continue;
-         if(strlen(direntp->d_name) > 4) {
-            bzero(y1,5);
-            bzero(y2,5);
-            bzero(m1,4);
-            bzero(m2,4);
-            bzero(d1,3);
-            bzero(d2,3);
-            if(strcmp(df,"u") == 0) {
-               strncpy(y1,direntp->d_name,4);
-               strncpy(m1,direntp->d_name+4,3);
-               strncpy(d1,direntp->d_name+7,2);
-               strncpy(y2,direntp->d_name+10,4);
-               strncpy(m2,direntp->d_name+14,3);
-               strncpy(d2,direntp->d_name+17,2);
-           } else if(strcmp(df,"e") == 0) {
-               strncpy(y1,direntp->d_name+5,4);
-               strncpy(m1,direntp->d_name+2,3);
-               strncpy(d1,direntp->d_name,2);
-               strncpy(y2,direntp->d_name+15,4);
-               strncpy(m2,direntp->d_name+12,3);
-               strncpy(d2,direntp->d_name+10,2);
-            }
-            conv_month(m1);
-            conv_month(m2);
-         }
-         sprintf(val1,"%s%s",outdir,y1);
-         if(access(val1, R_OK) != 0) mkdir(val1,0755);
-         if(strcmp(m1,m2) != 0) sprintf(val2,"%s/%s-%s",val1,m1,m2);
-         else sprintf(val2,"%s/%s",val1,m1);
-         if(access(val2, R_OK) != 0) mkdir(val2,0755);
-         if(strcmp(d1,d2) != 0) sprintf(val3,"%s/%s-%s",val2,d1,d2);
-         else sprintf(val3,"%s/%s",val2,d1);
-         sprintf(val4,"%s%s",outdir,direntp->d_name);
-         rename(val4,val3);
-         sprintf(val5,"%s/images",val2);
-         if(access(val5, R_OK) != 0) {
-            sprintf(val5,"ln -s \"%simages\" \"%s/images\"",outdir,val2);
-            cstatus=system(val5);
-            if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
-               fprintf(stderr, "SARG: command return status %d\n",WEXITSTATUS(cstatus));
-               fprintf(stderr, "SARG: command: %s\n",val5);
-               exit(1);
-            }
-         }
-      } else {
-         if(!isdigit(direntp->d_name[0]) && !isdigit(direntp->d_name[1])) continue;
-         if(strlen(direntp->d_name) == 4) {
-            strcpy(y1,direntp->d_name);
-            sprintf(val1,"%s%s",outdir,direntp->d_name);
-            dirp2 = opendir(val1);
-            while ((direntp2 = readdir( dirp2 )) != NULL) {
-               if(!isdigit(direntp2->d_name[0]) && !isdigit(direntp2->d_name[1])) continue;
-               sprintf(val2,"%s/%s",val1,direntp2->d_name);
-               dirp3 = opendir(val2);
-               while ((direntp3 = readdir( dirp3 )) != NULL) {
-                  if(!isdigit(direntp3->d_name[0]) && !isdigit(direntp3->d_name[1])) continue;
-                  bzero(newname,512);
-                  strcpy(warea,direntp2->d_name);
-                  if((str = strchr(warea,'-')) != 0) {
-                     *str++ = '\0';
-                     strcpy(m1,warea);
-                     strcpy(m2,str);
-                     conv_month_name(m1);
-                     conv_month_name(m2);
-                  } else {
-                     strcpy(m1,warea);
-                     conv_month_name(m1);
-                     strcpy(m2,m1);
-                  }
-                  strcpy(warea,direntp3->d_name);
-                  if((str = strchr(warea,'-')) != 0) {
-                     *str++ = '\0';
-                     strcpy(d1,warea);
-                     strcpy(d2,warea);
-                  } else {
-                     strcpy(d1,warea);
-                     strcpy(d2,warea);
-                  }
-                  if(strcmp(df,"u") == 0) sprintf(val4,"%s%s%s%s-%s%s%s",outdir,y1,m1,d1,y1,m2,d2);
-                  else if(strcmp(df,"e") == 0) sprintf(val4,"%s%s%s%s-%s%s%s",outdir,d1,m1,y1,d2,m2,y1);
-                  sprintf(val5,"%s%s/%s/%s",outdir,y1,direntp2->d_name,direntp3->d_name);
-                  if(rename(val5,val4)) {
-                     fprintf(stderr, "SARG: (index) rename error - %s\n",strerror(errno));
-                     exit(1);
-                  }
-               }
-               (void)rewinddir( dirp3 );
-               (void)closedir( dirp3 );
-            }
-            (void)rewinddir( dirp2 );
-            (void)closedir( dirp2 );
-         }
-//         sprintf(cmd,"rm -rf %s%s\n",outdir,direntp->d_name);
-//         system(cmd);
+      if(isdigit(direntp->d_name[0]) && isdigit(direntp->d_name[1])) {
+         if(strcmp(IndexTree,"date") == 0)
+            file_index_to_date_index(direntp->d_name);
+         else
+            date_index_to_file_index(direntp->d_name);
       }
    }
-   (void)rewinddir( dirp );
-   (void)closedir( dirp );
 
    if((fp_tmp=fopen(wdir_tmp,"w"))==NULL) {
       fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir_tmp);
       exit(1);
    }
 
-   dirp = opendir(outdir);
+   rewinddir(dirp);
    while ((direntp = readdir( dirp )) != NULL) {
       if(strcmp(IndexTree,"date") == 0) {
-         if(strlen(direntp->d_name) > 4 || (!isdigit(direntp->d_name[0]) && !isdigit(direntp->d_name[1]))) continue;
+         if(strlen(direntp->d_name) > 4 || !isdigit(direntp->d_name[0]) || !isdigit(direntp->d_name[1]) ||
+            !isdigit(direntp->d_name[2]) || !isdigit(direntp->d_name[3])) continue;
          fprintf(fp_tmp,"%s\t%s\n",direntp->d_name,get_size(outdir,direntp->d_name));
-         continue;
       } else {
-         if(strstr(direntp->d_name,"-") == 0) continue;
-         bzero(newname, 512);
+         if(strchr(direntp->d_name,'-') == 0) continue;
+         bzero(newname, sizeof(newname));
          if(strcmp(df,"u") == 0) {
             strncat(newname,direntp->d_name,4);
             strncpy(month,direntp->d_name+4,3);
@@ -241,15 +148,11 @@ void make_index(void)
             buildymd(day,mon,year,ftime);
             fprintf(fp_tmp,"%s%02d%02d%02d;%s;%s;%s;%s;%s;%s\n",ftime, ihour, iminute, isecond, direntp->d_name, data, tuser, tbytes, media,newname);
          }
-         continue;
       }
    }
 
-   if(fp_tmp) fclose(fp_tmp);
-   if(strcmp(IndexTree,"file") == 0) {
-      (void)rewinddir( dirp );
-      (void)closedir( dirp );
-   }
+   fclose(fp_tmp);
+   (void)closedir( dirp );
 
    if(strcmp(IndexTree,"date") == 0) {
       if(strcmp(IndexSortOrder,"A") == 0) sprintf(warea,"sort -k 1,1 \"%s\" -o \"%s\"", wdir_tmp, wdir_tmp2);
@@ -288,11 +191,10 @@ void make_index(void)
          }
          dirp2 = opendir(tmp2);
          while ((direntp2 = readdir( dirp2 )) != NULL) {
-            if(!isdigit(direntp2->d_name[0]) && !isdigit(direntp2->d_name[1])) continue;
+            if(!isdigit(direntp2->d_name[0]) || !isdigit(direntp2->d_name[1])) continue;
             fprintf(fp_ou2,"%s\n",direntp2->d_name);
          }
          if(fp_ou2) fclose(fp_ou2);
-         (void)rewinddir(dirp2);
          (void)closedir(dirp2);
          sprintf(wdir_tmp3,"%s%s/index.sort",outdir,tmp4);
          if(strcmp(IndexSortOrder,"A") == 0) sprintf(csort,"sort -n \"%s\" -o \"%s\"", tmp3, wdir_tmp3);
@@ -381,8 +283,6 @@ void make_index(void)
          write_html_trailer(fp_ou2);
          if(fp_ou2) fclose(fp_ou2);
       }
-      (void)rewinddir(dirp);
-      (void)closedir(dirp);
       if(fp_tmp) fclose(fp_tmp);
       unlink(tmp6);
       unlink(wdir_tmp2);
@@ -442,3 +342,174 @@ void make_index(void)
    write_html_trailer(fp_ou);
    if(fp_ou) fclose(fp_ou);
 }
+
+static void file_index_to_date_index(const char *entry)
+{
+   int y1, y2, d1, d2;
+   int i, j;
+   int ndirlen;
+   char m1[8], m2[8];
+   char olddir[MAXLEN], newdir[MAXLEN];
+
+   if(strlen(entry) < 19) return;
+
+   y1=0;
+   y2=0;
+   memset(m1,0,sizeof(m1));
+   memset(m2,0,sizeof(m2));
+   d1=0;
+   d2=0;
+   i=0;
+   if(strcmp(df,"u") == 0) {
+      for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
+         y1=y1*10+(entry[i++]-'0');
+      if (j!=4) return;
+      for (j=0 ; j<sizeof(m1)-1 && entry[i] && isalpha(entry[i]) ; j++)
+         m1[j]=entry[i++];
+      if (j!=3) return;
+      m1[j]='\0';
+      for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
+         d1=d1*10+(entry[i++]-'0');
+      if (j!=2) return;
+
+      if (entry[i++]!='-') return;
+
+      for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
+         y2=y2*10+(entry[i++]-'0');
+      if (j!=4) return;
+      for (j=0 ; j<sizeof(m2)-1 && entry[i] && isalpha(entry[i]) ; j++)
+         m2[j]=entry[i++];
+      if (j!=3) return;
+      m2[j]='\0';
+      for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
+         d2=d2*10+(entry[i++]-'0');
+      if (j!=2) return;
+   } else if(strcmp(df,"e") == 0) {
+      for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
+         d1=d1*10+(entry[i++]-'0');
+      if (j!=2) return;
+      for (j=0 ; j<sizeof(m1)-1 && entry[i] && isalpha(entry[i]) ; j++)
+         m1[j]=entry[i++];
+      if (j!=3) return;
+      m1[j]='\0';
+      for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
+         y1=y1*10+(entry[i++]-'0');
+      if (j!=4) return;
+
+      if (entry[i++]!='-') return;
+
+      for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
+         d2=d2*10+(entry[i++]-'0');
+      if (j!=2) return;
+      for (j=0 ; j<sizeof(m2)-1 && entry[i] && isalpha(entry[i]) ; j++)
+         m2[j]=entry[i++];
+      if (j!=3) return;
+      m2[j]='\0';
+      for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
+         y2=y2*10+(entry[i++]-'0');
+      if (j!=4) return;
+   } else
+      return;
+
+   conv_month(m1);
+   conv_month(m2);
+   ndirlen=sprintf(newdir,"%s%04d",outdir,y1);
+   if(access(newdir, R_OK) != 0) mkdir(newdir,0755);
+   if(strcmp(m1,m2) != 0) ndirlen+=sprintf(newdir+ndirlen,"/%s-%s",m1,m2);
+   else ndirlen+=sprintf(newdir+ndirlen,"/%s",m1);
+   if(access(newdir, R_OK) != 0) mkdir(newdir,0755);
+   if(d1!=d2) ndirlen+=sprintf(newdir+ndirlen,"/%02d-%02d",d1,d2);
+   else ndirlen+=sprintf(newdir+ndirlen,"/%02d",d1);
+
+   sprintf(olddir,"%s%s",outdir,entry);
+   if (rename(olddir,newdir)) {
+      fprintf(stderr, "SARG: (index) rename error from \"%s\" to \"%s\" - %s\n",olddir,newdir,strerror(errno));
+      exit(1);
+   }
+
+   /*! \bug The links to the images in the reports are broken after moving the directories
+   as the the HTML files are not at the right level for the images any more.
+   */
+}
+
+static void date_index_to_file_index(const char *entry)
+{
+   int y1, next;
+   int val1len;
+   int d1, d2;
+   int i, j;
+   char val1[MAXLEN];
+   char m1[8], m2[8];
+   char *str;
+   char newdir[MAXLEN], olddir[MAXLEN];
+   DIR *dirp2, *dirp3;
+   struct dirent *direntp2;
+   struct dirent *direntp3;
+
+   if(strlen(entry) != 4) return;
+
+   next=-1;
+   if (sscanf(entry,"%d%n",&y1,&next)!=1 || next<0 || entry[next]) return;
+
+   val1len=sprintf(val1,"%s%s",outdir,entry);
+   dirp2 = opendir(val1);
+   if (!dirp2) return;
+   while ((direntp2 = readdir( dirp2 )) != NULL) {
+      if(!isdigit(direntp2->d_name[0]) || !isdigit(direntp2->d_name[1])) continue;
+      i=0;
+      str=direntp2->d_name;
+      for (j=0 ; j<sizeof(m1) && str[i] && isdigit(str[i]) ; j++)
+         m1[j]=str[i++];
+      if (j>=sizeof(m1)) continue;
+      m1[j]='\0';
+      conv_month_name(m1);
+      if (str[i]=='-') {
+         i++;
+         for (j=0 ; j<sizeof(m2) && str[i] && isdigit(str[i]) ; j++)
+            m2[j]=str[i++];
+         if (j>=sizeof(m2)) continue;
+         m2[j]='\0';
+         conv_month_name(m2);
+      } else if (!str[i]) {
+         strcpy(m2,m1);
+      } else {
+         continue;
+      }
+
+      sprintf(val1+val1len,"/%s",direntp2->d_name);
+      dirp3 = opendir(val1);
+      if (!dirp3) continue;
+      while ((direntp3 = readdir( dirp3 )) != NULL) {
+         if(!isdigit(direntp3->d_name[0]) || !isdigit(direntp3->d_name[1])) continue;
+         i=0;
+         str=direntp3->d_name;
+         d1=0;
+         for (j=0 ; str[i] && isdigit(str[i]) ; j++)
+            d1=d1*10+(str[i++]-'0');
+         if (j!=2) continue;
+         if (str[i]=='-') {
+            i++;
+            d2=0;
+            for (j=0 ; str[i] && isdigit(str[i]) ; j++)
+               d2=d2*10+(str[i++]-'0');
+            if (j!=2) continue;
+         } else if (!str[i]) {
+            d2=d1;
+         } else {
+            continue;
+         }
+
+         if(strcmp(df,"u") == 0) sprintf(newdir,"%s%04d%s%02d-%04d%s%02d",outdir,y1,m1,d1,y1,m2,d2);
+         else if(strcmp(df,"e") == 0) sprintf(newdir,"%s%02d%s%04d-%02d%s%04d",outdir,d1,m1,y1,d2,m2,y1);
+         else continue;
+         sprintf(olddir,"%s%04d/%s/%s",outdir,y1,direntp2->d_name,direntp3->d_name);
+         if(rename(olddir,newdir)) {
+            fprintf(stderr, "SARG: (index) rename error from \"%s\" to \"%s\" - %s\n",olddir,newdir,strerror(errno));
+            exit(1);
+         }
+      }
+      (void)closedir( dirp3 );
+   }
+   (void)closedir( dirp2 );
+}
+
diff --git a/log.c b/log.c
index 62a853ba11d0d01fa35d91dcb5c84372c4092e8a..a159326ac7b1aa2a370206f70c0d2828caba806d 100644 (file)
--- a/log.c
+++ b/log.c
@@ -103,6 +103,7 @@ int main(int argc,char *argv[])
    char *str;
    char bufz[MAXLEN];
    char bufy[MAXLEN];
+   char tmp2[MAXLEN];
    enum InputLogFormat ilf;
    int ilf_count[ILF_Last];
    int  ch;
@@ -1102,6 +1103,7 @@ int main(int argc,char *argv[])
          if(testvaliduserchar(user))
             continue;
 
+#if 0
          if((str = strstr(user,"%20")) != NULL) {
             /*
             Why is it necessary to truncate the user name at the first space ?
@@ -1123,6 +1125,7 @@ int main(int argc,char *argv[])
             *str='.';
             for (x=3 ; str[x] ; x++) str[x-2]=str[x];
          }
+#endif
 
          for(str=user; *str; str++) {
             if(*str=='.') dotinuser++;
index c98d1fcef204344ad8697937af4142301b7669d1..7ce163480bed346baa839a97a88ae09bcc7e3a21 100644 (file)
@@ -37,6 +37,7 @@ void useragent(void)
    char agent_old[MAXLEN]="$#%0a3bc6";
    char hfile[MAXLEN];
    char idate[MAXLEN], fdate[MAXLEN];
+   char tmp2[MAXLEN];
    int  agentot=0, agentot2=0, agentdif=0, cont=0, nagent;
    unsigned long totregsl=0;
    int cstatus;
diff --git a/util.c b/util.c
index 13bb78b0be8d7d176c0bca77dab50010da07a8ad..aa393d9b5437925b43a5aea80c425cc6c5f7784a 100644 (file)
--- a/util.c
+++ b/util.c
@@ -351,7 +351,6 @@ void conv_month(char *month)
 
    for(x=0; x<12 && strcmp(mtab1[x],month)!=0; x++);
    sprintf(month,"%02d",x+1);
-
 }
 
 
@@ -794,18 +793,70 @@ void gperiod(const char *dirname, const char *period)
 
 }
 
-void vrfydir(const char *per1, const char *addr, const char *site, const char *us, const char *form)
+static void copy_images(void)
 {
    FILE *img_in, *img_ou;
+   char images[512];
+   char imgdir[MAXLEN];
+   char srcfile[MAXLEN];
+   char dstfile[MAXLEN];
+   DIR *dirp;
+   struct dirent *direntp;
+   char buffer[MAXLEN];
+   size_t nread;
+   struct stat info;
+
+   if (snprintf(images,sizeof(images),"%simages",outdir)>=sizeof(images)) {
+      fprintf(stderr,"SARG: Cannot copy images to target directory %simages\n",outdir);
+      exit(1);
+   }
+   if (access(images,R_OK)!=0) {
+      mkdir(images,0755);
+   }
+
+   strcpy(imgdir,IMAGEDIR);
+   dirp = opendir(imgdir);
+   if(dirp==NULL) {
+      fprintf(stderr, "SARG: (util) %s %s: %s\n","Can't open directory", imgdir,strerror(errno));
+      return;
+   }
+   while ((direntp = readdir( dirp )) != NULL ){
+      if(direntp->d_name[0]=='.')
+         continue;
+      sprintf(srcfile,"%s/%s",imgdir,direntp->d_name);
+      if (stat(srcfile,&info)) {
+         fprintf(stderr,"SARG: Cannot stat \"%s\" - %s\n",srcfile,strerror(errno));
+         continue;
+      }
+      if (S_ISREG(info.st_mode)) {
+         sprintf(dstfile,"%s/%s",images,direntp->d_name);
+         img_in = fopen(srcfile, "rb");
+         if(img_in!=NULL) {
+            img_ou = fopen(dstfile, "wb");
+            if(img_ou!=NULL) {
+               while ((nread = fread(buffer,1,sizeof(buffer),img_in))>0) {
+                  fwrite(buffer,1,nread,img_ou);
+               }
+               fclose(img_ou);
+            } else
+               fprintf(stderr,"SARG: (util): %s %s: %s\n", text[45]?text[45]:"Can't open/create file", dstfile, strerror(errno));
+            fclose(img_in);
+         } else
+            fprintf(stderr,"SARG: (util): %s %s: %s\n", text[45]?text[45]:"Can't open file", srcfile, strerror(errno));
+      }
+   }
+   (void) closedir(dirp);
+
+   return;
+}
+
+void vrfydir(const char *per1, const char *addr, const char *site, const char *us, const char *form)
+{
    FILE *fp_ou;
    int  num=1, count=0;
-   int  c;
    char wdir[MAXLEN];
    char per2[MAXLEN];
    char dirname2[MAXLEN];
-   char images[512];
-   DIR *dirp;
-   struct dirent *direntp;
    char y1[5], y2[5];
    char d1[3], d2[3];
    char m1[8], m2[8];
@@ -946,8 +997,6 @@ void vrfydir(const char *per1, const char *addr, const char *site, const char *u
    }
 
    strcpy(dirname2,wdir);
-   sprintf(images,"%simages",outdir);
-   mkdir(images,0755);
 
    sprintf(wdir,"%s/sarg-date",dirname);
    if ((fp_ou = fopen(wdir, "wt")) == 0) {
@@ -962,41 +1011,9 @@ void vrfydir(const char *per1, const char *addr, const char *site, const char *u
    fprintf(fp_ou,"%s %d\n",wdir,loctm->tm_isdst);
    fclose(fp_ou);
 
-   strcpy(per2,IMAGEDIR);
-
-   dirp = opendir(per2);
-   if(dirp==NULL) {
-      fprintf(stderr, "SARG: (util) %s %s: %s\n","Can't open directory", per2,strerror(errno));
-      return;
-   }
-   while ((direntp = readdir( dirp )) != NULL ){
-      if(strncmp(direntp->d_name,".",1) == 0)
-         continue;
-      sprintf(val10,"%s/%s",per2,direntp->d_name);
-      sprintf(val11,"%s/%s",images,direntp->d_name);
-      img_in = fopen(val10, "rb");
-      if(img_in!=NULL) {
-         img_ou = fopen(val11, "wb");
-         if(img_ou!=NULL) {
-            while ((c = fgetc(img_in))!=EOF) {
-               fputc(c,img_ou);
-            }
-            fclose(img_ou);
-         } else
-            fprintf(stderr,"SARG: (util): %s %s: %s\n", text[45]?text[45]:"Can't open/create file", val11, strerror(errno));
-         fclose(img_in);
-      } else
-         fprintf(stderr,"SARG: (util): %s %s: %s\n", text[45]?text[45]:"Can't open file", val10, strerror(errno));
-   }
-   (void) rewinddir(dirp);
-   (void) closedir(dirp);
-
-   return;
-
-
+   copy_images();
 }
 
-
 void strip_latin(char *line)
 {
    int i,j;