[comp.sources.bugs] Fix for MIT Athena delete/undelete programs

davison@drivax.UUCP (Wayne Davison) (04/05/89)

The following patch file fixes two bugs in the MIT Athena delete/undelete
posting in comp.sources.unix and makes one usability change to expunge.c.

The first bug is a problem in col.c when using an auto-wrap terminal.  If
the columns divide evenly into 80, the last one will be space-padded up to
the 80th character, causing a screen wrap and double-spaced output.  The
fix is to not space-pad the last column on a line.

The second bug is more serious.  When you specify a minimum time for expunge
and it skips a file because it is not old enough to expunge, it decreases
the number of found files.  This causes the loop to terminate before processing
all of the files, skipping the ones at the end of the list.  I fixed this by
adding a count of skipped files, and subtracting it off the found count for
the return value.

Finally, I changed the way purge is handled in expunge to enable the
processing of options such as `-t2' or a directory name.  The purge
functionality can now be accessed either with the `-p' option of expunge,
or through the `purge' file link created by the Makefile.

					..Wayne..
----------------------------------Cut Here----------------------------------
*** col.c.orig	Tue Apr  4 13:59:20 1989
--- col.c	Tue Apr  4 13:59:43 1989
***************
*** 64,81 ****
  	  height++;
       
       if (number_flag) for (updown = 0; updown < height; updown++) {
! 	  for (leftright = updown; leftright < num_to_print;
! 	       leftright += height) {
  	       (void) sprintf(buf, "%*d. %s", numwidth, leftright+1,
  			      strings[leftright]);
! 	       fprintf(outfile, "%*s", -column_width, buf);
  	  }
  	  fprintf(outfile, "\n");
       } else for (updown = 0; updown < height; updown++) {
! 	  for (leftright = updown; leftright < num_to_print;
! 	       leftright += height) {
  	       (void) sprintf(buf, "%s", strings[leftright]);
! 	       fprintf(outfile, "%*s", -column_width, buf);
  	  }
  	  fprintf(outfile, "\n");
       }
--- 64,85 ----
  	  height++;
       
       if (number_flag) for (updown = 0; updown < height; updown++) {
! 	  for (leftright = updown; leftright < num_to_print; ) {
  	       (void) sprintf(buf, "%*d. %s", numwidth, leftright+1,
  			      strings[leftright]);
! 	       if ((leftright += height) >= num_to_print)
! 		    fprintf(outfile, "%s", buf );
! 	       else
! 		    fprintf(outfile, "%*s", -column_width, buf);
  	  }
  	  fprintf(outfile, "\n");
       } else for (updown = 0; updown < height; updown++) {
! 	  for (leftright = updown; leftright < num_to_print; ) {
  	       (void) sprintf(buf, "%s", strings[leftright]);
! 	       if ((leftright += height) >= num_to_print)
! 		    fprintf(outfile, "%s", buf );
! 	       else
! 		    fprintf(outfile, "%*s", -column_width, buf);
  	  }
  	  fprintf(outfile, "\n");
       }
*** expunge.c.orig	Tue Apr  4 13:59:21 1989
--- expunge.c	Tue Apr  4 14:12:19 1989
***************
*** 47,53 ****
       verbose,		/* print a line as each file is deleted */
       force,		/* do not ask for any confirmation */
       listfiles,		/* list files at toplevel */
!      yield;		/* print yield of expunge at end */
  
  int blocks_removed = 0;
  
--- 47,54 ----
       verbose,		/* print a line as each file is deleted */
       force,		/* do not ask for any confirmation */
       listfiles,		/* list files at toplevel */
!      yield,		/* print yield of expunge at end */
!      purge;		/* alias for expunge -r -l -y $HOME */
  
  int blocks_removed = 0;
  
***************
*** 61,67 ****
       extern char *optarg;
       extern int optind;
       int arg;
!      int status = 0;
  
       whoami = lastpart(argv[0]);
       error_buf = malloc(strlen(whoami) + MAXPATHLEN + 3);
--- 62,68 ----
       extern char *optarg;
       extern int optind;
       int arg;
!      char *dir;
  
       whoami = lastpart(argv[0]);
       error_buf = malloc(strlen(whoami) + MAXPATHLEN + 3);
***************
*** 70,81 ****
  	  exit(1);
       }
       if (*whoami == 'p') { /* we're doing a purge */
! 	  exit (purge());
       }
       timev = 0;
       yield = interactive = recursive = noop = verbose = listfiles = force = 0;
!      while ((arg = getopt(argc, argv, "t:irfnvly")) != -1) {
  	  switch (arg) {
  	  case 't':
  	       timev = atoi(optarg);
  	       break;
--- 71,85 ----
  	  exit(1);
       }
       if (*whoami == 'p') { /* we're doing a purge */
! 	  purge++;
       }
       timev = 0;
       yield = interactive = recursive = noop = verbose = listfiles = force = 0;
!      while ((arg = getopt(argc, argv, "pt:irfnvly")) != -1) {
  	  switch (arg) {
+ 	  case 'p':
+ 	       purge++;
+ 	       break;
  	  case 't':
  	       timev = atoi(optarg);
  	       break;
***************
*** 105,144 ****
  	       exit(1);
  	  }
       }
!      if (optind == argc) {
! 	  char *dir;
! 	  dir = ".";
! 	  status = status | expunge(&dir, 1); /* current working directory */
       }
!      else
! 	  status = status | expunge(&argv[optind], argc - optind);
!      exit(status & ERROR_MASK);
! }
! 
! 
! 
! 
! 
! purge()
! {
!      char *home[1];
! 
!      home[0] = malloc(MAXPATHLEN);
!      if (! home[0]) {
! 	  perror(sprintf(error_buf, "%s: purge", whoami));
! 	  exit(1);
       }
!      timev = interactive = noop = verbose = force = 0;
!      yield = listfiles = recursive = 1;
!      get_home(home[0]);
!      if (! *home[0]) {
! 	  fprintf(stderr, "%s: purge: can't get home directory\n", whoami);
! 	  exit(1);
       }
! 
!      printf("Please be patient.... this may take a while.\n\n");
!      
!      return(expunge(home, 1));
  }
  
  
--- 109,139 ----
  	       exit(1);
  	  }
       }
!      if (purge) {
! 	  yield = listfiles = recursive = 1;
       }
!      if (optind == argc) {
! 	  if (purge) {
! 	       dir = malloc(MAXPATHLEN);
! 	       if (! dir) {
! 		  perror(whoami);
! 		  exit(1);
! 	       }
! 	       get_home(dir);
! 	       if (! *dir) {
! 		  fprintf(stderr, "%s: can't get home directory\n", whoami);
! 		  exit(1);
! 	       }
! 	  } else {
! 	       dir = ".";
! 	  }
! 	  argv[optind] = dir;
! 	  argc++;
       }
!      if (recursive) {
! 	  printf("Please be patient.... this may take a while.\n\n");
       }
!      exit(expunge(&argv[optind], argc - optind) & ERROR_MASK);
  }
  
  
***************
*** 270,276 ****
  char **files;
  int num;
  {
!      int i;
       filerec *leaf;
       
       for (i = 0; i < num; i++) {
--- 265,271 ----
  char **files;
  int num;
  {
!      int i, skipped = 0;
       filerec *leaf;
       
       for (i = 0; i < num; i++) {
***************
*** 283,293 ****
  	  free(files[i]);
  	  if (! timed_out(leaf, current_time, timev)) {
  	       free_leaf(leaf);
! 	       num--;
  	  }
       }
       free(files);
!      return(num);
  }
  
  
--- 278,288 ----
  	  free(files[i]);
  	  if (! timed_out(leaf, current_time, timev)) {
  	       free_leaf(leaf);
! 	       skipped++;
  	  }
       }
       free(files);
!      return(num-skipped);
  }
  
  
----------------------------------Cut Here----------------------------------
-- 
 Wayne Davison                                        ...amdahl!drivax!davison
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
   Lkung tku nrcd pdnm bknwrea xztmykazojb nrcd ypdbd?  Yzt "xztmyk", ypd
   xztmykazoj-nkwdz'b qzrdeg.  Oy o xkjm.bkuzxdb.aojdb ozxprwdz edoz tku.

jik@athena.mit.edu (Jonathan I. Kamens) (04/07/89)

In article <4479@drivax.UUCP> davison@drivax.UUCP (Wayne Davison) writes:
>   The following patch file fixes two bugs in the MIT Athena
>   delete/undelete posting in comp.sources.unix and makes one
>   usability change to expunge.c.

Thank you for the input and the fixes.  They are all valid.

>   The first bug is a problem in col.c when using an auto-wrap
>   terminal.  If the columns divide evenly into 80, the last one will
>   be space-padded up to the 80th character, causing a screen wrap and
>   double-spaced output.  The fix is to not space-pad the last column
>   on a line.

Accepted in full and will go out again in the next official
patch/release (if there is another one :-).

>   The second bug is more serious.  When you specify a minimum time
>   for expunge and it skips a file because it is not old enough to
>   expunge, it decreases the number of found files.  This causes the
>   loop to terminate before processing all of the files, skipping the
>   ones at the end of the list.  I fixed this by adding a count of
>   skipped files, and subtracting it off the found count for the
>   return value.

Ditto.

>   Finally, I changed the way purge is handled in expunge to enable
>   the processing of options such as `-t2' or a directory name.  The
>   purge functionality can now be accessed either with the `-p' option
>   of expunge, or through the `purge' file link created by the
>   Makefile.

I can't install this in our sources.  After a long and drawn-out
design process, it was decided here at Athena that purge should be
*only* a purge, and should not take command-line arguments.  The
purpose of the purge command is to give our users a very simple
command they can type that they can be sure will get rid of the
deleted files in their home directory if they are over quota and need
to do something about it.

You can leave your patch in your version of the sources, but I can't
put it into ours.  It's a valid patch if it's the functionality you
want, but it's not what we want here :-)

>					   ..Wayne..

Jonathan Kamens			              USnail:
MIT Project Athena				410 Memorial Drive, No. 223F
jik@Athena.MIT.EDU				Cambridge, MA 02139-4318
Office: 617-253-4261			      Home: 617-225-8218

P.S. Now, if you had submitted a man page patch for expunge and purge
as well, I might have thought about installing it :-)