📄 calcsize.c
字号:
/* * ========================================================================= */#if !defined(HAVE_BASENAME) && defined(BUILTIN_EXCLUDE_SUPPORT)static char *basename( char * file){ char *cp; if ( (cp = strrchr(file,'/')) ) return cp+1; return file;}#endifvoid push_name(char *str);char *pop_name(void);voidtraverse_dirs( char * parent_dir, char * include){ DIR *d; struct dirent *f; struct stat finfo; char *dirname, *newname = NULL; char *newbase = NULL; dev_t parent_dev = (dev_t)0; int i; size_t l; size_t parent_len; int has_exclude; char *aparent; if(parent_dir == NULL || include == NULL) return; has_exclude = !is_empty_sl(exclude_sl) && (use_gtar_excl || use_star_excl); aparent = vstralloc(parent_dir, "/", include, NULL); /* We (may) need root privs for the *stat() calls here. */ set_root_privs(1); if(stat(parent_dir, &finfo) != -1) parent_dev = finfo.st_dev; parent_len = strlen(parent_dir); push_name(aparent); for(; (dirname = pop_name()) != NULL; free(dirname)) { if(has_exclude && calc_check_exclude(dirname+parent_len+1)) { continue; } if((d = opendir(dirname)) == NULL) { perror(dirname); continue; } l = strlen(dirname); if(l > 0 && dirname[l - 1] != '/') { newbase = newstralloc2(newbase, dirname, "/"); } else { newbase = newstralloc(newbase, dirname); } while((f = readdir(d)) != NULL) { int is_symlink = 0; int is_dir; int is_file; if(is_dot_or_dotdot(f->d_name)) { continue; } newname = newstralloc2(newname, newbase, f->d_name); if(lstat(newname, &finfo) == -1) { g_fprintf(stderr, "%s/%s: %s\n", dirname, f->d_name, strerror(errno)); continue; } if(finfo.st_dev != parent_dev) continue;#ifdef S_IFLNK is_symlink = ((finfo.st_mode & S_IFMT) == S_IFLNK);#endif 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 && (time_t)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); } } }#ifdef CLOSEDIR_VOID closedir(d);#else if(closedir(d) == -1) perror(dirname);#endif } /* drop root privs -- we're done with the permission-sensitive calls */ set_root_privs(0); amfree(newbase); amfree(newname); amfree(aparent);}voidpush_name( char * str){ Name *newp; newp = alloc(SIZEOF(*newp)); newp->str = stralloc(str); newp->next = name_stack; name_stack = newp;}char *pop_name(void){ Name *newp = name_stack; char *str; if(!newp) return NULL; name_stack = newp->next; str = newp->str; amfree(newp); return str;}/* * ========================================================================= * Backup size calculations for DUMP program * * Given the system-dependent nature of dump, it's impossible to pin this * down accurately. Luckily, that's not necessary. * * Dump rounds each file up to TP_BSIZE bytes, which is 1k in the BSD dump, * others are unknown. In addition, dump stores three bitmaps at the * beginning of the dump: a used inode map, a dumped dir map, and a dumped * inode map. These are sized by the number of inodes in the filesystem. * * We don't take into account the complexities of BSD dump's indirect block * requirements for files with holes, nor the dumping of directories that * are not themselves modified. */voidadd_file_name_dump( int level, char * name){ (void)level; /* Quiet unused parameter warning */ (void)name; /* Quiet unused parameter warning */ return;}voidadd_file_dump( int level, struct stat * sp){ /* keep the size in kbytes, rounded up, plus a 1k header block */ if((sp->st_mode & S_IFMT) == S_IFREG || (sp->st_mode & S_IFMT) == S_IFDIR) dumpstats[level].total_size += (ST_BLOCKS(*sp) + (off_t)1) / (off_t)2 + (off_t)1;}off_tfinal_size_dump( int level, char * topdir){ struct fs_usage fsusage; off_t mapsize; char *s; /* calculate the map sizes */ s = stralloc2(topdir, "/."); if(get_fs_usage(s, NULL, &fsusage) == -1) { error("statfs %s: %s", s, strerror(errno)); /*NOTREACHED*/ } amfree(s); mapsize = (fsusage.fsu_files + (off_t)7) / (off_t)8; /* in bytes */ mapsize = (mapsize + (off_t)1023) / (off_t)1024; /* in kbytes */ /* the dump contains three maps plus the files */ return (mapsize * (off_t)3) + dumpstats[level].total_size;}/* * ========================================================================= * Backup size calculations for GNUTAR program * * Gnutar's basic blocksize is 512 bytes. Each file is rounded up to that * size, plus one header block. Gnutar stores directories' file lists in * incremental dumps - we'll pick up size of the modified dirs here. These * will be larger than a simple filelist of their contents, but that's ok. * * As with DUMP, we only need a reasonable estimate, not an exact figure. */voidadd_file_name_gnutar( int level, char * name){ (void)name; /* Quiet unused parameter warning *//* dumpstats[level].total_size_name += strlen(name) + 64;*/ dumpstats[level].total_size += (off_t)1;}voidadd_file_gnutar( int level, struct stat * sp){ /* the header takes one additional block */ dumpstats[level].total_size += ST_BLOCKS(*sp);}off_tfinal_size_gnutar( int level, char * topdir){ (void)topdir; /* Quiet unused parameter warning */ /* divide by two to get kbytes, rounded up */ /* + 4 blocks for security */ return (dumpstats[level].total_size + (off_t)5 + (dumpstats[level].total_size_name/(off_t)512)) / (off_t)2;}/* * ========================================================================= * Backup size calculations for unknown backup programs. * * Here we'll just add up the file sizes and output that. */voidadd_file_name_unknown( int level, char * name){ (void)level; /* Quiet unused parameter warning */ (void)name; /* Quiet unused parameter warning */ return;}voidadd_file_unknown( int level, struct stat * sp){ /* just add up the block counts */ if((sp->st_mode & S_IFMT) == S_IFREG || (sp->st_mode & S_IFMT) == S_IFDIR) dumpstats[level].total_size += ST_BLOCKS(*sp);}off_tfinal_size_unknown( int level, char * topdir){ (void)topdir; /* Quiet unused parameter warning */ /* divide by two to get kbytes, rounded up */ return (dumpstats[level].total_size + (off_t)1) / (off_t)2;}/* * ========================================================================= */sl_t *calc_load_file( char * filename){ char pattern[1025]; sl_t *sl_list; FILE *file = fopen(filename, "r"); if (!file) { return NULL; } sl_list = new_sl(); 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;}intcalc_check_exclude( 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -