[net.unix-wizards] Warning about rm

tupper@wanginst.UUCP (07/15/86)

Today I ran the following command:

	rm -r /student/tupper/.dead/.*

I was trying to remove alot of files with names like .signature, .login, .etc.
The shell expanded my wild card to include /student/tupper/.dead/. and
(this is the important part -->) /student/tupper/.dead/.. (that's "dot-dot")!

Now rm cleverly makes sure you don't remove "..", but it does not check for
".." at the end of a path name (it does strcmp of filename against "..").

Thus rm, recursivly removed /student/tupper/.dead/.. , which happens to
be my home directory (/student/tupper).

While I wait for the operator to restore my most of my account, I thought I
would pass my experience on for the benefit of others (I've already read
news).

mouse@mcgill-vision.UUCP (der Mouse) (07/27/86)

In article <79@wanginst.UUCP>, tupper@wanginst.UUCP (John Tupper) writes:
> Today I ran the following command:
> 	rm -r /student/tupper/.dead/.*
> The shell expanded my wild card to include /student/tupper/.dead/.
> and (this is the important part -->) /student/tupper/.dead/.. (that's
> "dot-dot")!

     If you are using the c-shell and have source access, I have a
change for you.  The user's view of it is two new shell variables,
"dotglob" and "dotdotdotglob".  If dotglob is not set, wildcard
expansion works as before (no dot filenames unless the dot is given,
.* matches . and .., etc).  If dotglob but not dotdotdotglob is set,
then dots are not special at the beginning of filenames, EXCEPT that .
and .. will never result from wildcard expansion.  If dotdotdotglob is
also set, . and .. are no longer special.  The changes are minor and
entirely in sh.glob.c; a diff follows.

     This diff also contains "nullnomatch", a change I started and
never finished (you can ignore it if you like, since it does nothing at
present).  It would be fairly easy to modify this so that the normal
behavior (. at the beginning of a filename must be explicitly
specified) is available with the exception that . and .. cannot result
from globbing, which is more likely what you want.

     I daren't post anything more extensive for the usual reasons....

*** /usr/src/bin/csh/sh.glob.c	Thu Apr 11 19:00:04 1985
--- /u1/mouse/shell/sh.glob.c	Fri Oct 18 02:54:51 1985
***************
*** 15,20
  int	globbed;
  bool	noglob;
  bool	nonomatch;
  char	*entp;
  char	**sortbas;
  

--- 15,23 -----
  int	globbed;
  bool	noglob;
  bool	nonomatch;
+ char nullnomatch;
+ char dotglob;
+ char dotdotdotglob;
  char	*entp;
  char	**sortbas;
  
***************
*** 33,38
  #endif
  	noglob = adrof("noglob") != 0;
  	nonomatch = adrof("nonomatch") != 0;
  	globcnt = noglob | nonomatch;
  	while (*v)
  		collect(*v++);

--- 36,44 -----
  #endif
  	noglob = adrof("noglob") != 0;
  	nonomatch = adrof("nonomatch") != 0;
+ 	nullnomatch = adrof("nullnomatch") != 0;
+ 	dotglob = adrof("dotglob") != 0;
+ 	dotdotdotglob = adrof("dotdotdotglob") != 0;
  	globcnt = noglob | nonomatch;
  	while (*v)
  		collect(*v++);
***************
*** 284,291
  	return (0);
  }
  
! match(s, p)
! 	char *s, *p;
  {
  	register int c;
  	register char *sentp;

--- 290,298 -----
  	return (0);
  }
  
! match(s,p)
! char *s;
! char *p;
  {
   register int c;
   register char *sentp;
***************
*** 287,295
  match(s, p)
  	char *s, *p;
  {
! 	register int c;
! 	register char *sentp;
! 	char sglobbed = globbed;
  
  	if (*s == '.' && *p != '.')
  		return (0);

--- 294,302 -----
  char *s;
  char *p;
  {
!  register int c;
!  register char *sentp;
!  char sglobbed = globbed;
  
   if (*s == '.')
    { if (dotglob)
***************
*** 291,304
  	register char *sentp;
  	char sglobbed = globbed;
  
! 	if (*s == '.' && *p != '.')
! 		return (0);
! 	sentp = entp;
! 	entp = s;
! 	c = amatch(s, p);
! 	entp = sentp;
! 	globbed = sglobbed;
! 	return (c);
  }
  
  amatch(s, p)

--- 298,321 -----
   register char *sentp;
   char sglobbed = globbed;
  
!  if (*s == '.')
!   { if (dotglob)
!      { if (!dotdotdotglob && (eq(s,".") || eq(s,"..")))
! 	{ return(eq(s,p));
! 	}
!      }
!     else
!      { if (*p != '.')
! 	{ return(0);
! 	}
!      }
!   }
!  sentp = entp;
!  entp = s;
!  c = amatch(s, p);
!  entp = sentp;
!  globbed = sglobbed;
!  return(c);
  }
  
  amatch(s, p)
-- 
					der Mouse

USA: {ihnp4,decvax,akgua,utzoo,etc}!utcsri!mcgill-vision!mouse
     think!mosart!mcgill-vision!mouse
Europe: mcvax!decvax!utcsri!mcgill-vision!mouse
ARPAnet: utcsri!mcgill-vision!mouse@uw-beaver.arpa

"Come with me a few minutes, mortal, and we shall talk."