lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (01/07/89)
System: cdiff version 1.1 Patch #: 4 Priority: LOW Subject: now passes diff switches through Subject: handles directories better Subject: now quotes filenames passed to subshell From: Amos Shapir and Francois Pinard Description: cdiff didn't pass diff switches through. Now it does. Now one or the other of the filenames can be a directory holding a different version by the same name. The filenames passed to diff are now quoted to prevent interpretation of shell metacharacters (in particular, #). Fix: From rn, say "| patch -p -N -d DIR", where DIR is your cdiff source directory. Outside of rn, say "cd DIR; patch -p -N <thisarticle". If you don't have the patch program, apply the following by hand, or get patch (version 2.0, latest patchlevel). If patch indicates that patchlevel is the wrong version, you may need to apply one or more previous patches, or the patch may already have been applied. See the patchlevel.h file to find out what has or has not been applied. In any event, don't continue with the patch. If you are missing previous patches they can be obtained from me: Larry Wall lwall@jpl-devvax.jpl.nasa.gov If you send a mail message of the following form it will greatly speed processing: Subject: Command @SH mailpatch PATH cdiff 1.1 LIST ^ note the c where PATH is a return path FROM ME TO YOU either in Internet notation, or in bang notation from some well-known host, and LIST is the number of one or more patches you need, separated by spaces, commas, and/or hyphens. Saying 35- says everything from 35 to the end. You can also get the patches via anonymous FTP from jpl-devvax.jpl.nasa.gov. Index: patchlevel.h Prereq: 3 1c1 < #define PATCHLEVEL 3 --- > #define PATCHLEVEL 4 Index: cdiff.c Prereq: 1.1.1.3 *** cdiff.c.old Fri Jan 6 12:31:52 1989 --- cdiff.c Fri Jan 6 12:31:53 1989 *************** *** 1,10 **** ! static char rcsid[] = "$Header: cdiff.c,v 1.1.1.3 88/08/04 16:08:18 lwall Exp $"; /* cdiff - turns a regular diff into a new-style context diff * * Usage: cdiff file1 file2 * * $Log: cdiff.c,v $ * Revision 1.1.1.3 88/08/04 16:08:18 lwall * patch3: include <stat.h> => <sys/stat.h> * --- 1,15 ---- ! static char rcsid[] = "$Header: cdiff.c,v 1.1.1.4 89/01/06 12:31:41 lwall Locked $"; /* cdiff - turns a regular diff into a new-style context diff * * Usage: cdiff file1 file2 * * $Log: cdiff.c,v $ + * Revision 1.1.1.4 89/01/06 12:31:41 lwall + * patch4: now passes diff switches through + * patch4: handles directories better + * patch4: now quotes filenames passed to subshell + * * Revision 1.1.1.3 88/08/04 16:08:18 lwall * patch3: include <stat.h> => <sys/stat.h> * *************** *** 25,31 **** #include <sys/stat.h> #include <ctype.h> ! char buf[512]; FILE *inputfp, *oldfp, *newfp; --- 30,36 ---- #include <sys/stat.h> #include <ctype.h> ! char buf[512] = "diff "; FILE *inputfp, *oldfp, *newfp; *************** *** 77,82 **** --- 82,89 ---- } if (argv[0][1] == 'c') context = atoi(argv[0]+2); + else + sprintf(buf+strlen(buf), "%s ", argv[0]); } if (argc != 2) { *************** *** 87,113 **** old = argv[0]; new = argv[1]; ! sprintf(buf,"diff %s %s", old, new); inputfp = popen(buf, "r"); if (!inputfp) { ! fprintf(stderr, "Can't execute diff %s %s\n", old, new); exit(1); } oldfp = fopen(old,"r"); if (!oldfp) { fprintf(stderr, "Can't open %s\n", old); exit(1); } newfp = fopen(new,"r"); if (!newfp) { fprintf(stderr, "Can't open %s\n", new); exit(1); } - - fstat(fileno(oldfp),&statbuf); - printf("*** %s\t%s", old, ctime(&statbuf.st_mtime)); - fstat(fileno(newfp),&statbuf); printf("--- %s\t%s", new, ctime(&statbuf.st_mtime)); preoldend = -1000; --- 94,130 ---- old = argv[0]; new = argv[1]; ! sprintf(buf+strlen(buf), "'%s' '%s'", old, new); inputfp = popen(buf, "r"); if (!inputfp) { ! fprintf(stderr, "Can't execute %s\n", buf); exit(1); } + stat(old,&statbuf); + if((statbuf.st_mode&S_IFMT) == S_IFDIR) { + sprintf(buf, "%s/%s", old, new); + old = buf; + stat(old,&statbuf); + } oldfp = fopen(old,"r"); if (!oldfp) { fprintf(stderr, "Can't open %s\n", old); exit(1); } + printf("*** %s\t%s", old, ctime(&statbuf.st_mtime)); + + stat(new,&statbuf); + if((statbuf.st_mode&S_IFMT) == S_IFDIR) { + sprintf(buf, "%s/%s", new, old); + new = buf; + stat(new,&statbuf); + } newfp = fopen(new,"r"); if (!newfp) { fprintf(stderr, "Can't open %s\n", new); exit(1); } printf("--- %s\t%s", new, ctime(&statbuf.st_mtime)); preoldend = -1000;
wietse@wzv.UUCP (Wietse Z. Venema) (01/07/89)
In article <3843@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes: > > Now one or the other of the filenames can be a directory > holding a different version by the same name. The algorithm for filename construction is a bit naive: $ cp /etc/passwd /tmp $ ./cdiff /etc/passwd /tmp Can't open /tmp//etc/passwd The fix (see below) is relatively simple. I also found that cdiff does not check whether both file arguments are directories: $ ./cdiff /etc /tmp Can't open /etc//tmp Since the bare diff(1) command suffers from the same problem (on S5R2 systems at least) no attempt was made to remove this feature from the cdiff source. In the following fix you may want to substitute rindex() for the strrchr() call. Wietse Venema *** cdiff.c.bug Sat Jan 7 12:31:23 1989 --- cdiff.c Sat Jan 7 12:31:23 1989 *************** *** 103,109 **** stat(old,&statbuf); if((statbuf.st_mode&S_IFMT) == S_IFDIR) { ! sprintf(buf, "%s/%s", old, new); old = buf; stat(old,&statbuf); } --- 103,110 ---- stat(old,&statbuf); if((statbuf.st_mode&S_IFMT) == S_IFDIR) { ! char *strrchr(), *kludge = strrchr(new,'/'); ! sprintf(buf, "%s/%s", old, kludge ? kludge+1 : new); old = buf; stat(old,&statbuf); } *************** *** 116,122 **** stat(new,&statbuf); if((statbuf.st_mode&S_IFMT) == S_IFDIR) { ! sprintf(buf, "%s/%s", new, old); new = buf; stat(new,&statbuf); } --- 117,124 ---- stat(new,&statbuf); if((statbuf.st_mode&S_IFMT) == S_IFDIR) { ! char *strrchr(), *kludge = strrchr(old,'/'); ! sprintf(buf, "%s/%s", new, kludge ? kludge+1 : old); new = buf; stat(new,&statbuf); } -- work: wswietse@eutrc3.uucp | Eindhoven University of Technology work: wswietse@heitue5.bitnet | Mathematics and Computing Science home: wietse@wzv.uucp | 5600 MB Eindhoven, The Netherlands
amos@taux02.UUCP (Amos Shapir) (01/08/89)
Thanks for the fix; I just noticed that the version I sent for distribution by Larry was not the Latest & Greatest. Here is a fix for people who can't stand the word 'kludge' in their code... :-) *** cdiff.c Sun Jan 8 08:36:47 1989 --- cdiff.c.loc Sun Jan 8 09:54:43 1989 *************** *** 5,10 * Usage: cdiff file1 file2 * * $Log: cdiff.c,v $ * Revision 1.1.1.4 89/01/06 12:31:41 lwall * patch4: now passes diff switches through * patch4: handles directories better --- 5,13 ----- * Usage: cdiff file1 file2 * * $Log: cdiff.c,v $ + * Local revision 2 88/10/26 11:57:36 amos@kleo1 + * fix bug in dir code - append last component only + * * Revision 1.1.1.4 89/01/06 12:31:41 lwall * patch4: now passes diff switches through * patch4: handles directories better *************** *** 49,54 char *malloc(); char *realloc(); char *fgets(); FILE *popen(); #define Nullfp (FILE*)0 --- 52,58 ----- char *malloc(); char *realloc(); char *fgets(); + char *strrchr(); FILE *popen(); #define Nullfp (FILE*)0 *************** *** 103,109 stat(old,&statbuf); if((statbuf.st_mode&S_IFMT) == S_IFDIR) { ! sprintf(buf, "%s/%s", old, new); old = buf; stat(old,&statbuf); } --- 107,113 ----- stat(old,&statbuf); if((statbuf.st_mode&S_IFMT) == S_IFDIR) { ! sprintf(buf, "%s/%s", old, (s = strrchr(new, '/')) == NULL ? new : s+1); old = buf; stat(old,&statbuf); } *************** *** 116,122 stat(new,&statbuf); if((statbuf.st_mode&S_IFMT) == S_IFDIR) { ! sprintf(buf, "%s/%s", new, old); new = buf; stat(new,&statbuf); } --- 120,126 ----- stat(new,&statbuf); if((statbuf.st_mode&S_IFMT) == S_IFDIR) { ! sprintf(buf, "%s/%s", new, (s = strrchr(old, '/')) == NULL ? old : s+1); new = buf; stat(new,&statbuf); } -- Amos Shapir amos@nsc.com National Semiconductor (Israel) P.O.B. 3007, Herzlia 46104, Israel Tel. +972 52 522261 TWX: 33691, fax: +972-52-558322 34 48 E / 32 10 N (My other cpu is a NS32532)