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-**