[comp.os.minix] Fixed commands/mv.c, lib/scanf.c

housel@ea.ecn.purdue.edu (Peter S. Housel) (07/19/88)

	Here are the fixed mv and scanf. When installing mv, be sure to
"chmem =3072 mv; chown root mv; chmod 4755 mv".

	The scanf patch is relative to the 1.3 version.

Peter S. Housel		housel@ei.ecn.purdue.edu	...!pur-ee!housel

#!/bin/sh
# This is a shell archive - unpack with sh
echo 'x - mv.c'
sed 's/^X//' <<'**-mv.c-EOF-**' >mv.c
X/* mv - move files		Author: Adri Koppes 
X *
X * 4/25/87 - J. Paradis		Bug fixes for directory handling
X * 3/15/88 - P. Housel		More directory bug fixes
X */
X
X#include <signal.h>
X#include <sys/stat.h>
X
Xextern char *rindex();
X
Xstruct stat st, st1;
X
Xmain (argc, argv)
Xint     argc;
Xchar  **argv;
X{
X    char   *destdir;
X
X    if (argc < 3) {
X	std_err ("Usage: mv file1 file2 or mv dir1 dir2 or mv file1 file2 ... dir\n");
X	exit (1);
X    }
X    if (argc == 3) {
X	if (stat (argv[1], &st)) {
X	    std_err ("mv: ");
X	    std_err (argv[1]);
X	    std_err (" doesn't exist\n");
X	    exit (1);
X	}
X
X	move (argv[1], argv[2]);
X    }
X    else {
X	destdir = argv[--argc];
X	if (stat (destdir, &st)) {
X	    std_err ("mv: target directory ");
X	    std_err (destdir);
X	    std_err (" doesn't exist\n");
X	    exit(1);
X	}
X	if ((st.st_mode & S_IFMT) != S_IFDIR) {
X	    std_err ("mv: target ");
X	    std_err (destdir);
X	    std_err (" not a directory\n");
X	    exit (1);
X	}
X	while (--argc)
X	    move (*++argv, destdir);
X    }
X    exit(0);
X}
X
Xmove (old, new)
Xchar   *old,
X       *new;
X{
X    int     retval;
X    char    name[64];
X    char    parent[64];
X    char    *oldbase;
X    int     i;
X
X    if((oldbase = rindex(old, '/')) == 0)
X	oldbase = old;
X    else
X	++oldbase;
X
X    /* It's too dangerous to fool with "." or ".." ! */
X    if((strcmp(oldbase, ".") == 0) || (strcmp(oldbase, "..") == 0)) {
X	cant(old);
X    }
X
X    /* Don't move a file to itself. */
X    if (stat(old, &st)==0 && stat(new, &st1)==0 && st.st_dev == st1.st_dev &&
X        st.st_ino == st1.st_ino)
X	cant(old);
X
X    if (stat (new, &st1) == 0)
X	if((st1.st_mode & S_IFMT) != S_IFDIR)
X	    unlink (new);
X	else {
X	    if ((strlen(oldbase) + strlen(new) + 2) > 64) {
X		cant(old);
X	    }
X	    strcpy(name, new);
X	    strcat(name, "/");
X	    strcat(name, oldbase);
X	    new = name;
X
X	    /* do the 'move-to-itself' check again for the new name */
X	    if (stat(new, &st1)==0 && st.st_dev == st1.st_dev
X		&& st.st_ino == st1.st_ino)
X	        cant(old);
X	}
X
X    strcpy(parent, new);
X
X    for(i = (strlen(parent) - 1); i > 0; i--) {
X	if(parent[i] == '/') break;
X    }
X
X    if(i == 0) {
X	strcpy(parent, ".");
X    }
X    else {
X	/* null-terminate name at last slash */
X	parent[i] = '\0';
X    }
X
X    /* prevent moving a directory into its own subdirectory */
X    if((st.st_mode & S_IFMT) == S_IFDIR) {
X	char lower[128];
X        short int prevdev = -1;
X	unsigned short previno;
X
X	strcpy(lower, parent);
X	while(1) {
X	    if(stat(lower, &st1) || (st1.st_dev == st.st_dev
X				     && st1.st_ino == st.st_ino))
X		cant(old);
X
X	    /* stop at root */
X	    if(st1.st_dev == prevdev && st1.st_ino == previno)
X		break;
X	    prevdev = st1.st_dev;
X	    previno = st1.st_ino;
X	    strcat(lower, "/..");
X	}
X    }
X
X    if (link (old, new))
X	if ((st.st_mode & S_IFMT) != S_IFDIR) {
X	    switch (fork ()) {
X		case 0: 
X		    setgid (getgid ());
X		    setuid (getuid ());
X		    execl ("/bin/cp", "cp", old, new, (char *) 0);
X		    cant(old);
X		case -1: 
X		    std_err ("mv: can't fork\n");
X		    exit (1);
X		default:
X		    wait (&retval);
X		    if (retval)
X			cant(old);
X	    }
X	} else
X	    cant(old);
X
X    /* If this was a directory that we moved, then we have
X    ** to update its ".." entry (in case it was moved some-
X    ** where else in the tree...)
X    */
X    if ((st.st_mode & S_IFMT) == S_IFDIR) {
X	char	dotdot[64];
X
X	/* Unlink the ".." entry */
X	strcpy(dotdot, new);
X	strcat(dotdot, "/..");
X	unlink(dotdot);
X
X	/* Now link it to its parent */
X	link(parent, dotdot);
X    }
X
X    utime (new, &st.st_atime);
X    unlink(old);
X}
X
Xcant(name)
Xchar *name;
X{
X	std_err("mv: can't move ");
X	std_err (name);
X	std_err ("\n");
X	exit (1);
X}
X
X
**-mv.c-EOF-**
echo 'x - scanf.cdif'
sed 's/^X//' <<'**-scanf.cdif-EOF-**' >scanf.cdif
X*** scanf.5	Mon Jul 18 19:56:00 1988
X--- scanf.c	Mon Jul 18 19:50:59 1988
X***************
X*** 162,168 ****
X  				goto all_done;
X  			++format;
X  			rnc ();
X- 			++done;
X  			continue;
X  		}
X  		++format;
X--- 162,167 ----
X***************
X*** 234,241 ****
X  				else
X  					*(argp++)->uint_p = (unsigned) val;
X  			}
X! 			if (done_some)
X! 				++done;
X  			else
X  				goto all_done;
X  			break;
X--- 233,241 ----
X  				else
X  					*(argp++)->uint_p = (unsigned) val;
X  			}
X! 			if (done_some) {
X! 				if(do_assign) ++done;
X! 			}
X  			else
X  				goto all_done;
X  			break;
X***************
X*** 250,256 ****
X  			}
X  			if (do_assign)
X  				argp++;	/* done with this one */
X! 			if (done_some)
X  				++done;
X  			break;
X  		case 's':
X--- 250,256 ----
X  			}
X  			if (do_assign)
X  				argp++;	/* done with this one */
X! 			if (done_some && do_assign)
X  				++done;
X  			break;
X  		case 's':
X***************
X*** 264,272 ****
X  			}
X  			if (do_assign)		/* terminate the string */
X  				*(argp++)->chr_p = '\0';	
X! 			if (done_some)
X! 				++done;
X! 			else
X  				goto all_done;
X  			break;
X  		case '[':
X--- 264,272 ----
X  			}
X  			if (do_assign)		/* terminate the string */
X  				*(argp++)->chr_p = '\0';	
X! 			if (done_some) {
X! 				if(do_assign) ++done;
X! 			} else
X  				goto all_done;
X  			break;
X  		case '[':
X***************
X*** 299,307 ****
X  			*format = ']';		/* put it back */
X  			if (do_assign)		/* terminate the string */
X  				*(argp++)->chr_p = '\0';	
X! 			if (done_some)
X! 				++done;
X! 			else
X  				goto all_done;
X  			break;
X  		}		/* end switch */
X--- 299,307 ----
X  			*format = ']';		/* put it back */
X  			if (do_assign)		/* terminate the string */
X  				*(argp++)->chr_p = '\0';	
X! 			if (done_some) {
X! 				if(do_assign) ++done;
X! 			} else
X  				goto all_done;
X  			break;
X  		}		/* end switch */
**-scanf.cdif-EOF-**