I have developed some improvements for shred 4.0.35 like recursive mode,interactive mode and dereference links.
Bye, Pablo. 5,6d4 < - Add -r/-R/--recursive < - Add -i/--interactive 8d5 < - Add -L 111c108 < # include <string.h> /* For memcpy, strerror */ --- > # include <string.h> /* For memcpy, strerror, strcmp */ 118a116,117 > # include <dirent.h> /* For {open,read,close}dir, DIR and struct dirent */ > # include <errno.h> /* For errno */ 437a437,439 > int interactive; /* -i flag: Interactive mode */ > int recursive; /* -r flag: Be recursive */ > int dereference; /* -L flag: Follow symbolic links */ 448a451,454 > {"interactive", no_argument, NULL, 'i'}, > {"recursive", no_argument, NULL,'r'}, > {"recursive", no_argument, NULL, 'R'}, > {"dereference", no_argument, NULL, 'L'}, 470,479c476,488 < -f, --force change permissions to allow writing if necessary\n\ < -n, --iterations=N Overwrite N times instead of the default (%d)\n\ < -s, --size=N shred this many bytes (suffixes like k, M, G accepted)\n\ < -u, --remove truncate and remove file after overwriting\n\ < -v, --verbose show progress\n\ < -x, --exact do not round file sizes up to the next full block\n\ < -z, --zero add a final overwrite with zeros to hide shredding\n\ < - shred standard output\n\ < --help display this help and exit\n\ < --version print version information and exit\n\ --- > -f, --force change permissions to allow writing if necessary\n\ > -n, --iterations=N Overwrite N times instead of the default (%d)\n\ > -s, --size=N shred this many bytes (suffixes like k, M, G accepted)\n\ > -u, --remove truncate and remove file after overwriting\n\ > -v, --verbose show progress\n\ > -x, --exact do not round file sizes up to the next full block\n\ > -z, --zero add a final overwrite with zeros to hide shredding\n\ > -i, --interactive prompt before any wipe\n\ > -r, -R, --recursive surf through directories and wipe its files\n\ > -L, --dereference always follow symbolic links\n\ > - shred standard output\n\ > --help display this help and exit\n\ > --version print version information and exit\n\ 1663a1673,1725 > > /* > * Ask for a confirmation before any wipe > */ > static int > do_interactive (char *name, struct Options const *flags, > int descend, struct stat *dp) > { > char c, word[17], k; > > if (flags->interactive) > { > bzero(word,17); > /*This values were taken from 'man 2 lstat',*/ > /*there they are in octal, remember it!*/ > switch((dp->st_mode & 0x0000f000)>>12) { > case 0x01: > strcat(word,"FIFO"); > break; > case 0x02: > strcat(word,"character device"); > break; > case 0x04: > strcat(word,"directory"); > break; > case 0x06: > strcat(word,"block device"); > break; > case 0x08: > strcat(word,"regular file"); > break; > case 0x0A: > strcat(word,"symbolic link"); > break; > case 0x0C: > strcat(word,"socket"); > break; > default: /*Is this possible?*/ > strcat(word,"file"); > } > if(descend) { > fprintf(stderr,"%s: Descend into the %s called '%s'?", > program_name,word,name); > } else { > fprintf(stderr,"%s: Wipe the %s called '%s'?", > program_name,word,name); > } > bzero(word,17); > return yesno(); > } > return 1; > } > 1665c1727 < * Finally, the function that actually takes a filename and grinds --- > * Finally, the function that actually takes a file and grinds 1677,1678c1739,1740 < wipefile (char *name, char const *qname, < struct isaac_state *s, struct Options const *flags) --- > do_wipefile (char *name, char const *qname, > struct isaac_state *s, struct Options const *flags) 1685,1688c1747,1757 < if (errno == EACCES && flags->force) < { < if (chmod (name, S_IWUSR) >= 0) /* 0200, user-write-only */ < fd = open (name, O_WRONLY | O_NOCTTY); --- > if (errno == EACCES) > { > if (flags->force) { > if (chmod (name, S_IWUSR) < 0) {/* 0200, user-write-only */ > error(0,errno,"error with chmod() on '%s'", name); > } else { > fd = open (name, O_WRONLY | O_NOCTTY); > } > } else { > error(0,0, > "cannot wipe file '%s': bad permissions, try with --force",name); 1689a1759 > } 1727a1798,1928 > > } > > > /* > * Take a filename and surf into the directories > * until find a file, then wipe it and go on > * with another file. > */ > static int > wipefile (char *name, char const *qname, > struct isaac_state *s, struct Options const *flags) > { > struct stat dir_param; > DIR *anydir; > struct dirent *dir_ent; > char *new_name; > size_t thisisalen; > int stat_result, ret_val=0; > > if (flags->dereference) > { > stat_result=stat(name, &dir_param); /*Go for the file*/ > } else > { > stat_result=lstat(name, &dir_param); /*Go for the sym. link*/ > } > if (stat_result<0) > { > if (errno==ENOENT) > { > error(0,0, > "cannot descend into %s: no such file or directory",name); > } else > { > error(0,errno,"error on [l]stat()"); > } > return -1; > } > > if (S_ISDIR(dir_param.st_mode)) /*What kind of file do we have?*/ > { > /*Ok, we've got a directory*/ > if (!flags->recursive) > { > error (0, 0, "'%s' is a directory, try --recursive.", name); > return -1; > } > > /*Ask for descend into it*/ > if (!do_interactive (name,flags,1,&dir_param)) > return ret_val; > > if (flags->verbose) > error (0, 0, _("wiping all entries of directory `%s'"), name); > > anydir=opendir(name); > /*Read each directory item*/ > while((dir_ent=readdir(anydir))!=NULL) > { > /*If it's not '.' or '..'*/ > if((strcmp(dir_ent->d_name,".")!=0) && > (strcmp(dir_ent->d_name,"..")!=0)) > { > /*Length of the new path*/ > thisisalen=strlen(name)+strlen(dir_ent->d_name)+1; > if ((new_name=malloc(thisisalen))==NULL) > { > error (0,errno,"error with malloc()"); > return -1; > } > bzero(new_name,thisisalen); > strncat(new_name,name,strlen(name)); > /*Copy all but the ending slash, if there's any*/ > if (name[(int)strlen(name)-1]!='/') > { > strncat(new_name,"/",1); > } > strncat(new_name,dir_ent->d_name, strlen(dir_ent->d_name)); > /*Wipe the file*/ > ret_val=wipefile(new_name,new_name,s,flags); > bzero(new_name,thisisalen); > free(new_name); > } > } > closedir(anydir); > > /*Remove the directory itself*/ > /*FIXME: Wipe the name of the directory*/ > if(flags->remove_file) > { > if(do_interactive(name, flags,0,&dir_param)) > { > if (flags->verbose) > error (0, 0, _("removing the directory itself: `%s'"), name); > while(rmdir(name)<0) > { > if(errno==EACCES) /*There's a problem w/ permissions*/ > { > if (flags->force) > { /*chmod() if we have to*/ > if(chmod (name, S_IWUSR)<0) > { > error(0,errno,"error with chmod() on '%s", > name); > return -1; > } > /*now we have to try rmdir() again*/ > } else > { > error(0,0, > "cannot remove directory '%s': bad permissions," > " try with --force",name); > return -1; > } /*End of 'if (flags...'*/ > } else /*There's another kinda of problem*/ > { > error(0,errno,"error with rmdir() on %s",name); > return -1; > } /*End of 'if (errno==...'*/ > } /*End of 'while (rmdir...'*/ > } /*End of 'if (do_interact...'*/ > } /*End of 'if (flags...'*/ > } else > { > /*Lets go w/ a file*/ > if (do_interactive (name,flags,0,&dir_param)) > ret_val=do_wipefile (name, qname, s, flags); /*Really wipe it*/ > } /*End of 'if (S_ISDIR...'*/ > > return ret_val; 1755c1956 < while ((c = getopt_long (argc, argv, "fn:s:uvxz", long_opts, NULL)) != -1) --- > while ((c = getopt_long (argc, argv, "fn:s:uvxzirRL", long_opts, NULL)) != -1) 1808a2010,2022 > case 'i': > flags.interactive = 1; > break; > > case 'R': > case 'r': > flags.recursive = 1; > break; > > case 'L': > flags.dereference = 1; > break; > 1829a2044 > 1831a2047 > /*FIXME: Should a 'do_interactive()' be here?*/ 1850a2067,2068 > > _______________________________________________ Bug-fileutils mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-fileutils