--- generator.c 2011-02-21 19:26:36.690428002 -0800 +++ generator.c 2011-02-21 18:27:54.554427999 -0800 @@ -142,6 +142,8 @@ enum logcode code, int f_out); #endif +int merge_partial( enum logcode, char *, char *); /*SMITH*/ + static int is_backup_file(char *fn) { int k = strlen(fn) - backup_suffix_len; @@ -1830,6 +1832,16 @@ prepare_to_open: if (partialptr) { + + /* SMITH - merge partial with main file, then use merge as basis */ + if ( ! merge_partial(FLOG,fname,partialptr)) + { + rprintf(FERROR, "Merge Failed: destFile(%s) partialFile(%s)\n", fname, partialptr); + exit_cleanup(RERR_FILEIO); + } + + link_stat(partialptr, &partial_st, 0); /* get stat again */ + sx.st = partial_st; fnamecmp = partialptr; fnamecmp_type = FNAMECMP_PARTIAL_DIR; @@ -2227,7 +2239,6 @@ wait_for_receiver(); } #endif - if (inc_recurse && cur_flist->parent_ndx >= 0) { struct file_struct *fp = dir_flist->files[cur_flist->parent_ndx]; if (solo_file) @@ -2353,3 +2364,122 @@ if (verbose > 2) rprintf(FINFO, "generate_files finished\n"); } + + +/* SMITH */ +int merge_partial( enum logcode FLOG, char * fname, char *partial ) +{ + struct stat st_fname; + struct stat st_partial; + struct stat st_merge; + int BUFFER_SIZE=10000; + unsigned char buffer[BUFFER_SIZE]; + char fmerge[1000]; + FILE *fp_merge; + FILE *fp_fname; + FILE *fp_partial; + off_t byteCount=0; + off_t byteTotal=0; + + rprintf(FLOG, "SMITH: Enter merge_partial\n"); + + /************************************/ + /* is it a merge partial situation? */ + /************************************/ + + if( access( partial, F_OK ) != -1 ) { + stat(partial, &st_partial); + } else { + rprintf(FLOG,"MP: partial file does not exist, merge not possible"); + return 1; + } + + if( access( fname, F_OK ) != -1 ) { + stat(fname, &st_fname); + } else { + rprintf(FLOG,"MP: destination file does not exist, merge not possible"); + return 1; + } + + if ( st_partial.st_size >= st_fname.st_size ) + { + rprintf(FLOG,"MP: partial file (%s) at (%.0f) bytes is >= than destination file (%s) at (%.0f), use partial",partial,(double)st_partial.st_size,fname,(double)st_fname.st_size); + return 1; + } + + rprintf(FLOG, "MP: attempting merge partial: destination file %s is %.0f bytes, partial file %s is %.0f bytes\n", + fname,(double)st_fname.st_size,partial,(double)st_partial.st_size); + + /******************************/ + /* copy partial to merge file */ + /******************************/ + + sprintf(fmerge,"%s.mp",partial); + + fp_partial = fopen(partial,"rb"); /* read only, binary mode */ + + if ( ! fp_partial ) + { + rprintf(FERROR,"Error in merge_partial, cannot open (%s) for reading in binary modei (%s)\n",partial,strerror(errno)); + return 0; + } + + fp_merge = fopen(fmerge,"wb"); + + if ( ! fp_merge ) + { + rprintf(FERROR,"Error in merge_partial, cannot open (%s) for writing in binary mode (%s)\n",fmerge,strerror(errno)); + return 0; + } + + while (!feof(fp_partial)) + { + byteCount = fread(buffer, 1, BUFFER_SIZE, fp_partial); + byteTotal += byteCount; + fwrite(buffer, 1, byteCount, fp_merge); + } + fclose(fp_partial); + + rprintf(FLOG, "MP: %.0f bytes from partial file written to merge file\n", (double)byteTotal); + + fp_fname = fopen(fname,"rb"); /* read only, binary mode */ + + if ( ! fp_partial ) + { + rprintf(FERROR,"Error in merge_partial, cannot open (%s) for reading in binary modei (%s)\n",fname,strerror(errno)); + return 0; + } + + /***********************************************************/ + /* copy from main file from the point the partial finished */ + /***********************************************************/ + + fseek( fp_fname, byteTotal, SEEK_SET ); + + byteCount=0; + byteTotal=0; + + while (!feof(fp_fname)) + { + byteCount = fread(buffer, 1, BUFFER_SIZE, fp_fname); + byteTotal += byteCount; + fwrite(buffer, 1, byteCount, fp_merge); + } + fclose(fp_fname); + rprintf(FLOG, "MP: %.0f bytes from main file written to merge file\n", (double)byteTotal); + + fclose(fp_merge); + + stat(fmerge, &st_merge); + rprintf(FLOG, "MP: final size of merge file (%s) is (%.0f) bytes\n",fmerge,(double)st_merge.st_size); + + if ( -1 == rename( fmerge, partial ) ) + { + rprintf(FERROR,"Error in merge_partial, cannot rename (%s) to (%s) - (%s)\n",fmerge,partial,strerror(errno)); + return 0; + } + + rprintf(FLOG, "SMITH: Exit merge_partial\n"); + return 1; +} +