X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=client-src%2Fcalcsize.c;h=5ca13fac43c094136d0aefc89eb24813bfbf43ed;hb=bde83ad58d800ae004caccab6531234272181da2;hp=97a032adc3125d6a5ccb643957742fe0e314e539;hpb=3ab887b9bc819a846c75dd7f2ee5d41fac22b19f;p=debian%2Famanda diff --git a/client-src/calcsize.c b/client-src/calcsize.c index 97a032a..5ca13fa 100644 --- a/client-src/calcsize.c +++ b/client-src/calcsize.c @@ -24,12 +24,13 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: calcsize.c,v 1.24.2.3.6.1 2002/03/31 21:01:32 jrjackson Exp $ + * $Id: calcsize.c,v 1.24.2.3.6.1.2.5 2005/09/20 21:31:52 jrjackson Exp $ * * traverse directory tree to get backup size estimates */ #include "amanda.h" #include "statfs.h" +#include "sl.h" #define ROUND(n,x) ((x) + (n) - 1 - (((x) + (n) - 1) % (n))) @@ -44,7 +45,7 @@ unsigned long n, x; } */ -# define ST_BLOCKS(s) ((s).st_size / 512 + (((s).st_size % 512) ? 1 : 0)) +#define ST_BLOCKS(s) ((((s).st_blocks * 512) <= (s).st_size) ? (s).st_blocks+1 : ((s).st_size / 512 + (((s).st_size % 512) ? 1 : 0))) #define FILETYPES (S_IFREG|S_IFLNK|S_IFDIR) @@ -62,34 +63,39 @@ struct { int total_dirs; int total_files; long total_size; + long total_size_name; } dumpstats[MAXDUMPS]; time_t dumpdate[MAXDUMPS]; int dumplevel[MAXDUMPS]; int ndumps; +void (*add_file_name) P((int, char *)); void (*add_file) P((int, struct stat *)); long (*final_size) P((int, char *)); int main P((int, char **)); -void traverse_dirs P((char *)); +void traverse_dirs P((char *, char *)); +void add_file_name_dump P((int, char *)); void add_file_dump P((int, struct stat *)); long final_size_dump P((int, char *)); +void add_file_name_gnutar P((int, char *)); void add_file_gnutar P((int, struct stat *)); long final_size_gnutar P((int, char *)); +void add_file_name_unknown P((int, char *)); void add_file_unknown P((int, struct stat *)); long final_size_unknown P((int, char *)); -#ifdef BUILTIN_EXCLUDE_SUPPORT +sl_t *calc_load_file P((char *filename)); +int calc_check_exclude P((char *filename)); + int use_gtar_excl = 0; -char exclude_string[] = "--exclude="; -char exclude_list_string[] = "--exclude-list="; -#endif +sl_t *include_sl=NULL, *exclude_sl=NULL; int main(argc, argv) int argc; @@ -102,17 +108,8 @@ char **argv; unsigned long dump_total=0, gtar_total=0; char *d; int l, w; - int fd; - - for(fd = 3; fd < FD_SETSIZE; fd++) { - /* - * Make sure nobody spoofs us with a lot of extra open files - * that would cause an open we do to get a very high file - * descriptor, which in turn might be used as an index into - * an array (e.g. an fd_set). - */ - close(fd); - } + + safe_fd(-1, 0); set_pname("calcsize"); @@ -135,25 +132,15 @@ char **argv; return 0; #else int i; - char *dirname=NULL, *amname=NULL; - int fd; + char *dirname=NULL, *amname=NULL, *filename=NULL; unsigned long malloc_hist_1, malloc_size_1; unsigned long malloc_hist_2, malloc_size_2; - for(fd = 3; fd < FD_SETSIZE; fd++) { - /* - * Make sure nobody spoofs us with a lot of extra open files - * that would cause an open we do to get a very high file - * descriptor, which in turn might be used as an index into - * an array (e.g. an fd_set). - */ - close(fd); - } + safe_fd(-1, 0); + safe_cd(); set_pname("calcsize"); - safe_cd(); - malloc_size_1 = malloc_inuse(&malloc_hist_1); #if 0 @@ -165,17 +152,8 @@ char **argv; /* need at least program, amname, and directory name */ if(argc < 3) { -#ifdef BUILTIN_EXCLUDE_SUPPORT - usage: -#endif - error("Usage: %s [DUMP|GNUTAR%s] name dir [level date] ...", - get_pname(), -#ifdef BUILTIN_EXCLUDE_SUPPORT - " [-X --exclude[-list]=regexp]" -#else - "" -#endif - ); + error("Usage: %s [DUMP|GNUTAR] name dir [-X exclude-file] [-I include-file] [level date]*", + get_pname()); return 1; } @@ -186,6 +164,7 @@ char **argv; error("dump not available on this system"); return 1; #else + add_file_name = add_file_name_dump; add_file = add_file_dump; final_size = final_size_dump; #endif @@ -195,53 +174,18 @@ char **argv; error("gnutar not available on this system"); return 1; #else + add_file_name = add_file_name_gnutar; add_file = add_file_gnutar; final_size = final_size_gnutar; -#ifdef BUILTIN_EXCLUDE_SUPPORT use_gtar_excl++; -#endif #endif } else { + add_file_name = add_file_name_unknown; add_file = add_file_unknown; final_size = final_size_unknown; } argc--, argv++; -#ifdef BUILTIN_EXCLUDE_SUPPORT - if ((argc > 1) && strcmp(*argv,"-X") == 0) { - char *result = NULL; - char *cp = NULL; - argv++; - - if (!use_gtar_excl) { - error("exclusion specification not supported"); - return 1; - } - - result = stralloc(*argv); - if (*result && (cp = strrchr(result,';'))) - /* delete trailing ; */ - *cp = 0; - if (strncmp(result, exclude_string, sizeof(exclude_string)-1) == 0) - add_exclude(result+sizeof(exclude_string)-1); - else if (strncmp(result, exclude_list_string, - sizeof(exclude_list_string)-1) == 0) { - if (access(result + sizeof(exclude_list_string)-1, R_OK) != 0) { - fprintf(stderr,"Cannot open exclude file %s\n",cp+1); - use_gtar_excl = 0; - } else { - add_exclude_file(result + sizeof(exclude_list_string)-1); - } - } else { - amfree(result); - goto usage; - } - amfree(result); - argc -= 2; - argv++; - } else - use_gtar_excl = 0; -#endif /* the amanda name can be different from the directory name */ @@ -258,6 +202,42 @@ char **argv; } else error("missing "); + if ((argc > 1) && strcmp(*argv,"-X") == 0) { + argv++; + + if (!use_gtar_excl) { + error("exclusion specification not supported"); + return 1; + } + + filename = stralloc(*argv); + if (access(filename, R_OK) != 0) { + fprintf(stderr,"Cannot open exclude file %s\n",filename); + use_gtar_excl = 0; + } else { + exclude_sl = calc_load_file(filename); + } + amfree(filename); + argc -= 2; + argv++; + } else + use_gtar_excl = 0; + + if ((argc > 1) && strcmp(*argv,"-I") == 0) { + argv++; + + filename = stralloc(*argv); + if (access(filename, R_OK) != 0) { + fprintf(stderr,"Cannot open include file %s\n",filename); + use_gtar_excl = 0; + } else { + include_sl = calc_load_file(filename); + } + amfree(filename); + argc -= 2; + argv++; + } + /* the dump levels to calculate sizes for */ ndumps = 0; @@ -273,14 +253,28 @@ char **argv; if(argc) error("leftover arg \"%s\", expected and ", *argv); - traverse_dirs(dirname); + if(is_empty_sl(include_sl)) { + traverse_dirs(dirname,"."); + } + else { + sle_t *an_include = include_sl->first; + while(an_include != NULL) { +/* + char *adirname = stralloc2(dirname, an_include->name+1); + traverse_dirs(adirname); + amfree(adirname); +*/ + traverse_dirs(dirname, an_include->name); + an_include = an_include->next; + } + } for(i = 0; i < ndumps; i++) { amflock(1, "size"); lseek(1, (off_t)0, SEEK_END); - printf("%s %d SIZE %ld\n", + fprintf(stderr, "%s %d SIZE %ld\n", amname, dumplevel[i], final_size(i, dirname)); fflush(stdout); @@ -316,8 +310,9 @@ char *file; void push_name P((char *str)); char *pop_name P((void)); -void traverse_dirs(parent_dir) +void traverse_dirs(parent_dir, include) char *parent_dir; +char *include; { DIR *d; struct dirent *f; @@ -327,22 +322,22 @@ char *parent_dir; dev_t parent_dev = 0; int i; int l; + int parent_len; + int has_exclude = !is_empty_sl(exclude_sl) && use_gtar_excl; + + char *aparent = vstralloc(parent_dir, "/", include, NULL); if(parent_dir && stat(parent_dir, &finfo) != -1) parent_dev = finfo.st_dev; - push_name(parent_dir); + parent_len = strlen(parent_dir); - for(dirname = pop_name(); dirname; free(dirname), dirname = pop_name()) { + push_name(aparent); -#ifdef BUILTIN_EXCLUDE_SUPPORT - if(use_gtar_excl && - (check_exclude(basename(dirname)) || - check_exclude(dirname))) - /* will not be added by gnutar */ + for(dirname = pop_name(); dirname; free(dirname), dirname = pop_name()) { + if(has_exclude && calc_check_exclude(dirname+parent_len+1)) { continue; -#endif - + } if((d = opendir(dirname)) == NULL) { perror(dirname); continue; @@ -356,6 +351,9 @@ char *parent_dir; } while((f = readdir(d)) != NULL) { + int is_symlink = 0; + int is_dir; + int is_file; if(is_dot_or_dotdot(f->d_name)) { continue; } @@ -371,31 +369,39 @@ char *parent_dir; continue; } - if((finfo.st_mode & S_IFMT) == S_IFDIR) { - push_name(newname); - } - - for(i = 0; i < ndumps; i++) { - if(finfo.st_ctime >= dumpdate[i]) { - int exclude = 0; - int is_symlink = 0; - -#ifdef BUILTIN_EXCLUDE_SUPPORT - exclude = check_exclude(f->d_name); -#endif #ifdef S_IFLNK - is_symlink = ((finfo.st_mode & S_IFMT) == S_IFLNK); + is_symlink = ((finfo.st_mode & S_IFMT) == S_IFLNK); #endif - if (! exclude && - /* regular files */ - ((finfo.st_mode & S_IFMT) == S_IFREG - /* directories */ - || (finfo.st_mode & S_IFMT) == S_IFDIR - /* symbolic links */ - || is_symlink)) { + is_dir = ((finfo.st_mode & S_IFMT) == S_IFDIR); + is_file = ((finfo.st_mode & S_IFMT) == S_IFREG); + + if (!(is_file || is_dir || is_symlink)) { + continue; + } + + { + int is_excluded = -1; + for(i = 0; i < ndumps; i++) { + add_file_name(i, newname); + if(is_file && finfo.st_ctime >= dumpdate[i]) { + + if(has_exclude) { + if(is_excluded == -1) + is_excluded = + calc_check_exclude(newname+parent_len+1); + if(is_excluded == 1) { + i = ndumps; + continue; + } + } add_file(i, &finfo); } } + if(is_dir) { + if(has_exclude && calc_check_exclude(newname+parent_len+1)) + continue; + push_name(newname); + } } } @@ -408,6 +414,7 @@ char *parent_dir; } amfree(newbase); amfree(newname); + amfree(aparent); } void push_name(str) @@ -452,6 +459,13 @@ char *pop_name() * requirements for files with holes, nor the dumping of directories that * are not themselves modified. */ +void add_file_name_dump(level, name) +int level; +char *name; +{ + return; +} + void add_file_dump(level, sp) int level; struct stat *sp; @@ -496,12 +510,20 @@ char *topdir; * * As with DUMP, we only need a reasonable estimate, not an exact figure. */ +void add_file_name_gnutar(level, name) +int level; +char *name; +{ +/* dumpstats[level].total_size_name += strlen(name) + 64;*/ + dumpstats[level].total_size += 1; +} + void add_file_gnutar(level, sp) int level; struct stat *sp; { /* the header takes one additional block */ - dumpstats[level].total_size += ROUND(4,(ST_BLOCKS(*sp) + 1)); + dumpstats[level].total_size += ST_BLOCKS(*sp); } long final_size_gnutar(level, topdir) @@ -510,7 +532,7 @@ char *topdir; { /* divide by two to get kbytes, rounded up */ /* + 4 blocks for security */ - return (dumpstats[level].total_size + 5) / 2; + return (dumpstats[level].total_size + 5 + (dumpstats[level].total_size_name/512)) / 2; } /* @@ -520,6 +542,13 @@ char *topdir; * Here we'll just add up the file sizes and output that. */ +void add_file_name_unknown(level, name) +int level; +char *name; +{ + return; +} + void add_file_unknown(level, sp) int level; struct stat *sp; @@ -536,3 +565,41 @@ char *topdir; /* divide by two to get kbytes, rounded up */ return (dumpstats[level].total_size + 1) / 2; } + +/* + * ========================================================================= + */ +sl_t *calc_load_file(filename) +char *filename; +{ + char pattern[1025]; + + sl_t *sl_list = new_sl(); + + FILE *file = fopen(filename, "r"); + + while(fgets(pattern, 1025, file)) { + if(strlen(pattern)>0 && pattern[strlen(pattern)-1] == '\n') + pattern[strlen(pattern)-1] = '\0'; + sl_list = append_sl(sl_list, pattern); + } + fclose(file); + + return sl_list; +} + +int calc_check_exclude(filename) +char *filename; +{ + sle_t *an_exclude; + if(is_empty_sl(exclude_sl)) return 0; + + an_exclude=exclude_sl->first; + while(an_exclude != NULL) { + if(match_tar(an_exclude->name, filename)) { + return 1; + } + an_exclude=an_exclude->next; + } + return 0; +}