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