New improvements

"Pablo G.F." <[email protected]>
Newsgroups gmane.comp.gnu.fileutils.bugs
Message-ID <[email protected]>
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
> 
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.