rsalz@uunet.uu.net (Rich Salz) (06/08/90)
Submitted-by: Vladimir Lanin <lanin@csd4.cs.nyu.edu> Posting-number: Volume 22, Issue 103 Archive-name: mmv.pch Patch-To: volume21/mmv The following patch fixes a number of bugs in mmv 1.0 (as distributed on comp.sources.unix) and provides V7 compatibility. The new version is known as mmv 1.01b. Since one of the bugs can result in the unintended DELETION of the source file(s), it is imperative that the old version be replaced with the new one. The two major bugs fixed are: 1) in its BSD reincarnation, whenever a file had to be moved between devices (by copying, then deleting), mmv 1.0 made a symbolic link to "/" instead of copying the file. It still deleted the original, though. Oops! 2) the uppercase/lowercase conversion feature did not work. Vladimir Lanin ---cut here--- *************** *** 1,5 **** /* ! mmv 1.0 Copyright (c) 1990 Vladimir Lanin. This program may be freely used and copied on a non-commercial basis. The author assumes no responsibility for any damage or data loss that may --- 1,5 ---- /* ! mmv 1.01b Copyright (c) 1990 Vladimir Lanin. This program may be freely used and copied on a non-commercial basis. The author assumes no responsibility for any damage or data loss that may *************** *** 7,21 **** Author may be reached at: ! lanin@csd4.nyu.edu Vladimir Lanin 330 Wadsworth Ave, Apt 6F, New York, NY 10040 */ /* Define SYSV to compile under System V. If your System V has a rename() call, define RENAME. Otherwise, mmv will only be able to rename directories (via option -r) when running as the super-user. --- 7,36 ---- Author may be reached at: ! lanin@csd4.cs.nyu.edu Vladimir Lanin 330 Wadsworth Ave, Apt 6F, New York, NY 10040 + + Many thanks to those who have to contributed to the design + and/or coding of this program: + + Tom Albrecht: initial Sys V adaptation, consultation, and testing + Carl Mascott: V7 adaptation + Mark Lewis: -n flag idea, consultation. + Dave Bernhold: upper/lowercase conversion idea. + Paul Stodghill: copy option, argv[0] checking. + Frank Fiamingo: consultation and testing. + Tom Jordahl: bug reports and testing. + John Lukas, Hugh Redelmeyer, Barry Nelson, John Sauter, + Phil Dench, John Nelson: + bug reports. */ /* Define SYSV to compile under System V. + Define both SYSV and V7 to compile under V7. If your System V has a rename() call, define RENAME. Otherwise, mmv will only be able to rename directories (via option -r) when running as the super-user. *************** *** 74,84 **** #include <stdio.h> #include <ctype.h> - #include <string.h> #ifdef MSDOS /* for MS-DOS (under Turbo C 1.5)*/ #include <stdlib.h> #include <sys/stat.h> #include <dos.h> --- 89,99 ---- #include <stdio.h> #include <ctype.h> #ifdef MSDOS /* for MS-DOS (under Turbo C 1.5)*/ + #include <string.h> #include <stdlib.h> #include <sys/stat.h> #include <dos.h> *************** *** 109,116 **** #include <sys/types.h> #include <sys/stat.h> #include <sys/file.h> ! #include <sys/signal.h> ! #include <fcntl.h> extern char *getenv(); extern long lseek(); extern char *malloc(); --- 124,130 ---- #include <sys/types.h> #include <sys/stat.h> #include <sys/file.h> ! extern char *getenv(); extern long lseek(); extern char *malloc(); *************** *** 149,176 **** static char TTY[] = "/dev/tty"; ! #ifdef SYSV ! /* for System V */ struct utimbuf { time_t actime; time_t modtime; }; ! #define utimes(f, t) utime((f), (t)) - #else /* for BSD */ - #define RENAME - #include <sys/time.h> #endif - #endif - #define mylower(c) (isupper(c) ? (c)-'A'+'a' : (c)) #define myupper(c) (islower(c) ? (c)-'a'+'A' : (c)) #define STRLEN(s) (sizeof(s) - 1) --- 163,202 ---- static char TTY[] = "/dev/tty"; ! #ifdef V7 ! /* for Version 7 */ ! #include <errno.h> ! extern int errno; ! #define strchr index ! extern char *strcpy(), *strchr(); ! #include <signal.h> ! #define O_RDONLY 0 ! #define O_WRONLY 1 ! #define O_RDWR 2 + #else + /* for System V and BSD */ + #include <string.h> + #include <sys/signal.h> + #include <fcntl.h> + #endif + + #ifdef SYSV + /* for System V and Version 7*/ struct utimbuf { time_t actime; time_t modtime; }; ! #define utimes(f, t) utime((f), &(t)) #else /* for BSD */ #define RENAME #include <sys/time.h> #endif #endif #define mylower(c) (isupper(c) ? (c)-'A'+'a' : (c)) #define myupper(c) (islower(c) ? (c)-'a'+'A' : (c)) #define STRLEN(s) (sizeof(s) - 1) *************** *** 298,304 **** static void init(/* */); static void procargs(/* int argc, char **argv, char **pfrompat, char **ptopat */); ! static void matchpats(/* char *cfrom, char *cto */); static int getpat(/* */); static int getword(/* char *buf */); static void matchpat(/* */); --- 324,330 ---- static void init(/* */); static void procargs(/* int argc, char **argv, char **pfrompat, char **ptopat */); ! static void domatch(/* char *cfrom, char *cto */); static int getpat(/* */); static int getword(/* char *buf */); static void matchpat(/* */); *************** *** 355,360 **** --- 381,387 ---- static void *challoc(/* int k, int which */); static void chgive(/* void *p, unsigned k */); static int mygetc(/* */); + static char *mygets(/* char *s, int l */); #ifdef MSDOS static int leave(/* */); static void cleanup(/* */); *************** *** 394,406 **** static char PATLONG[] = "%.40s... : pattern too long.\n"; ! static char from[MAXPATLEN], to[MAXPATLEN]; static int fromlen, tolen; static char *(stagel[MAXWILD]), *(firstwild[MAXWILD]), *(stager[MAXWILD]); static int nwilds[MAXWILD]; static int nstages; ! static char pathbuf[MAXPATH]; ! static char fullrep[MAXPATH + 1]; static char *(start[MAXWILD]); static int len[MAXWILD]; static char hasdot[MAXWILD]; --- 421,433 ---- static char PATLONG[] = "%.40s... : pattern too long.\n"; ! char from[MAXPATLEN], to[MAXPATLEN]; static int fromlen, tolen; static char *(stagel[MAXWILD]), *(firstwild[MAXWILD]), *(stager[MAXWILD]); static int nwilds[MAXWILD]; static int nstages; ! char pathbuf[MAXPATH]; ! char fullrep[MAXPATH + 1]; static char *(start[MAXWILD]); static int len[MAXWILD]; static char hasdot[MAXWILD]; *************** *** 446,452 **** init(); procargs(argc, argv, &frompat, &topat); ! matchpats(frompat, topat); if (!(op & APPEND)) checkcollisions(); findorder(); --- 473,479 ---- init(); procargs(argc, argv, &frompat, &topat); ! domatch(frompat, topat); if (!(op & APPEND)) checkcollisions(); findorder(); *************** *** 616,622 **** } ! static void matchpats(cfrom, cto) char *cfrom, *cto; { if (cfrom == NULL) --- 643,649 ---- } ! static void domatch(cfrom, cto) char *cfrom, *cto; { if (cfrom == NULL) *************** *** 1381,1392 **** flags |= FI_STTAKEN; #ifdef SYSV if (stat(ffull, &fstat)) { ! fprintf("Strange, couldn't stat %s.\n", ffull); quit(); } #else if (lstat(ffull, &fstat)) { ! fprintf("Strange, couldn't lstat %s.\n", ffull); quit(); } if ((flags & FI_INSTICKY) && fstat.st_uid != uid && uid != 0) --- 1408,1419 ---- flags |= FI_STTAKEN; #ifdef SYSV if (stat(ffull, &fstat)) { ! fprintf(stderr, "Strange, couldn't stat %s.\n", ffull); quit(); } #else if (lstat(ffull, &fstat)) { ! fprintf(stderr, "Strange, couldn't lstat %s.\n", ffull); quit(); } if ((flags & FI_INSTICKY) && fstat.st_uid != uid && uid != 0) *************** *** 1967,1973 **** cnv = LOWER; c = *(++pat); } ! if (c == 'u') { cnv = UPPER; c = *(++pat); } --- 1994,2000 ---- cnv = LOWER; c = *(++pat); } ! else if (c == 'u') { cnv = UPPER; c = *(++pat); } *************** *** 2358,2364 **** if ( (op & (COPY | APPEND)) ? copy(p->r_ffrom, ! p->r_flags & R_ISALIASED ? aliaslen : -1) : #ifndef MSDOS (op & HARDLINK) ? link(pathbuf, fullrep) : --- 2385,2391 ---- if ( (op & (COPY | APPEND)) ? copy(p->r_ffrom, ! p->r_flags & R_ISALIASED ? aliaslen : -1L) : #ifndef MSDOS (op & HARDLINK) ? link(pathbuf, fullrep) : *************** *** 2484,2490 **** #endif while ( fprintf(stderr, "File name> "), ! (outfile = fopen(gets(fname), "w")) == NULL ) fprintf(stderr, "Can't open %s.\n", fname); } --- 2511,2517 ---- #endif while ( fprintf(stderr, "File name> "), ! (outfile = fopen(mygets(fname, 80), "w")) == NULL ) fprintf(stderr, "Can't open %s.\n", fname); } *************** *** 2552,2558 **** int llen; char linkbuf[MAXPATH]; ! if ((llen = readlink(pathbuf, linkbuf, MAXPATH - 1)) != 1) { linkbuf[llen] = '\0'; return(symlink(linkbuf, fullrep) || myunlink(pathbuf, p->r_ffrom)); } --- 2579,2585 ---- int llen; char linkbuf[MAXPATH]; ! if ((llen = readlink(pathbuf, linkbuf, MAXPATH - 1)) >= 0) { linkbuf[llen] = '\0'; return(symlink(linkbuf, fullrep) || myunlink(pathbuf, p->r_ffrom)); } *************** *** 2559,2565 **** } #endif #endif ! return(copy(p->r_ffrom, -1) || myunlink(pathbuf, p->r_ffrom)); } --- 2586,2592 ---- } #endif #endif ! return(copy(p->r_ffrom, -1L) || myunlink(pathbuf, p->r_ffrom)); } *************** *** 2595,2601 **** ff->fi_mode #endif ; ! mode = O_CREAT | #ifdef MSDOS O_BINARY | (op & ZAPPEND ? O_RDWR : O_WRONLY) #else --- 2622,2636 ---- ff->fi_mode #endif ; ! ! #ifdef V7 ! if ( ! !(op & APPEND) || ! (((t = open(fullrep, O_RDWR)) < 0 && errno == ENOENT) ! ) ! t = creat(fullrep, perm); ! #else ! mode = O_CREAT | (op & APPEND ? 0 : O_TRUNC) | #ifdef MSDOS O_BINARY | (op & ZAPPEND ? O_RDWR : O_WRONLY) #else *************** *** 2602,2624 **** O_WRONLY #endif ; ! if (!(op & APPEND)) ! mode |= O_TRUNC; ! if ((t = open(fullrep, mode, perm)) < 0) { close(f); return(-1); } if (op & APPEND) ! lseek(t, 0, 2); #ifdef MSDOS if (op & ZAPPEND && filelength(t) != 0) { ! if (lseek(t, -1, 1) == -1L || read(t, &c, 1) != 1) { close(f); close(t); return(-1); } if (c == 26) ! lseek(t, -1, 1); } #endif if ((op & APPEND) && len != -1L) { --- 2637,2659 ---- O_WRONLY #endif ; ! t = open(fullrep, mode, perm); ! #endif ! if (t < 0) { close(f); return(-1); } if (op & APPEND) ! lseek(t, 0L, 2); #ifdef MSDOS if (op & ZAPPEND && filelength(t) != 0) { ! if (lseek(t, -1L, 1) == -1L || read(t, &c, 1) != 1) { close(f); close(t); return(-1); } if (c == 26) ! lseek(t, -1L, 1); } #endif if ((op & APPEND) && len != -1L) { *************** *** 2822,2827 **** --- 2857,2880 ---- if (lastc == EOF) return(EOF); return(lastc = getchar()); + } + + + static char *mygets(s, l) + char *s; + int l; + { + char *nl; + + for (;;) { + if (fgets(s, l, stdin) == NULL) + return(NULL); + if ((nl = strchr(s, '\n')) != NULL) + break; + fprintf(stderr, "Input string too long. Try again> "); + } + *nl = '\0'; + return(s); } exit 0 # Just in case... -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.