allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (03/21/89)
Posting-number: Volume 6, Issue 66 Submitted-by: res@cbnews.ATT.COM (Robert E. Stampfli) Archive-name: compress-patch [These are NOT official patches. Make sure you save your original compress 4.0 sources, so you have them if/when official patches come out. In the meantime, you're crazy if you don't apply them (or, alternatively, only use compress/uncompress as filters as I do). I've been bit by these a few times myself. ++bsa] I use compress 4.0 (and its variants uncompress and zcat) daily and have come to find them invaluable. One pesky problem, though, is that they occasionally go overboard while trying to cleanup after themselves and remove valuable files. In an effort to break them of these nasty habits, I sat down the other night and studied the code. I think I have isolated and resolved several problems: 1. I had just finished porting a file, gcc.33-34diffZ, or some such 14 character gobbledegook, from osu-cis and typed "zcat gcc.33-34diffZ". Not realizing it did not end in ".Z", everything appeared to be uncompressing fine. It was a large file, so I broke out of it, only to discover to my horror that the file was no longer among the living: zcat had dutifully removed it, thinking it was the object of the aborted uncompress. 2. Recently, I typed "compress xxx", to which the program responded with the fact that a file xxx.Z already existed and asked if I wanted to overwrite it. Thankful for this degree of error checking, I hit DELETE to abort the compress. In this case, DELETE was very aptly named, much to my chagrin. 3. I have found that there are small windows of vulnerability when (de)compressing a number of files, where an ill-timed DELETE will remove all references to a file which has just finished being successfully (de)compressed. Actually, the changes are fairly minimal. I inserted a few sanity checks and created a variable that indicates to the various interrupt handlers when it is proper to remove a object, and when it is not. The diffs against the official version 4.0 compress.c file are included below. Of course, no warrantee, expressed or implied. Happy compressing. Rob Stampfli att!cblpe!res (work) osu-cis!n8emr!kd8wk!rees (home) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ The original 4.0 compress.c, upon which this diff is based, sums to 47475 78 (2nd number may vary according to your blocksize) and wc stats it as 1486 6313 39614. It is 19141 bytes long, compressed of course. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *** ocompress.c Tue Mar 7 00:31:20 1989 --- compress.c Tue Mar 7 11:27:37 1989 *************** *** 356,361 #define CLEAR 256 /* table clear output code */ int force = 0; char ofname [100]; #ifdef DEBUG int verbose = 0; --- 356,362 ----- #define CLEAR 256 /* table clear output code */ int force = 0; + int valid = 0; /* set when signal can remove ofname -- added by res */ char ofname [100]; #ifdef DEBUG int verbose = 0; *************** *** 414,420 if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) { signal ( SIGINT, onintr ); - signal ( SIGSEGV, oops ); } #ifdef COMPATIBLE --- 415,420 ----- if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) { signal ( SIGINT, onintr ); } signal ( SIGSEGV, oops ); *************** *** 416,421 signal ( SIGINT, onintr ); signal ( SIGSEGV, oops ); } #ifdef COMPATIBLE nomagic = 1; /* Original didn't have a magic number */ --- 416,422 ----- if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) { signal ( SIGINT, onintr ); } + signal ( SIGSEGV, oops ); #ifdef COMPATIBLE nomagic = 1; /* Original didn't have a magic number */ *************** *** 529,534 /* Check for .Z suffix */ if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") != 0) { /* No .Z: tack one on */ strcpy(tempname, *fileptr); strcat(tempname, ".Z"); *fileptr = tempname; --- 530,543 ----- /* Check for .Z suffix */ if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") != 0) { /* No .Z: tack one on */ + #ifndef BSD4_2 /* Short filenames */ + if ((cp=rindex(*fileptr,'/')) != NULL) cp++; + else cp = *fileptr; + if (strlen(cp) > 12) { + fprintf(stderr,"%s.Z: No such file or directory\n",cp); + continue; + } + #endif /* BSD4_2 Long filenames allowed */ strcpy(tempname, *fileptr); strcat(tempname, ".Z"); *fileptr = tempname; *************** *** 607,614 response[0] = 'n'; fprintf(stderr, "%s already exists;", ofname); if (foreground()) { ! fprintf(stderr, " do you wish to overwrite %s (y or n)? ", ! ofname); fflush(stderr); read(2, response, 2); while (response[1] != '\n') { --- 616,622 ----- response[0] = 'n'; fprintf(stderr, "%s already exists;", ofname); if (foreground()) { ! fprintf(stderr," OK to overwrite (y or n)? "); fflush(stderr); read(2, response, 2); while (response[1] != '\n') { *************** *** 624,629 } } if(zcat_flg == 0) { /* Open output file */ if (freopen(ofname, "w", stdout) == NULL) { perror(ofname); continue; --- 632,638 ----- } } if(zcat_flg == 0) { /* Open output file */ + valid = 1; /* added by res */ if (freopen(ofname, "w", stdout) == NULL) { perror(ofname); continue; *************** *** 633,639 } /* Actually do the compression/decompression */ ! if (do_decomp == 0) compress(); #ifndef DEBUG else decompress(); #else --- 642,648 ----- } /* Actually do the compression/decompression */ ! if (do_decomp == 0) compress(); #ifndef DEBUG else decompress(); #else *************** *** 1264,1270 writeerr() { perror ( ofname ); ! unlink ( ofname ); exit ( 1 ); } --- 1273,1280 ----- writeerr() { perror ( ofname ); ! if( valid ) ! unlink ( ofname ); exit ( 1 ); } *************** *** 1303,1308 timep[0] = statbuf.st_atime; timep[1] = statbuf.st_mtime; utime(ofname, timep); /* Update last accessed and modified times */ if (unlink(ifname)) /* Remove input file */ perror(ifname); if(!quiet) --- 1313,1319 ----- timep[0] = statbuf.st_atime; timep[1] = statbuf.st_mtime; utime(ofname, timep); /* Update last accessed and modified times */ + valid = 0; /* added by res -- prevents latent ofname removal */ if (unlink(ifname)) /* Remove input file */ perror(ifname); if(!quiet) *************** *** 1333,1339 onintr ( ) { ! unlink ( ofname ); exit ( 1 ); } --- 1344,1351 ----- onintr ( ) { ! if( valid ) ! unlink ( ofname ); exit ( 1 ); } *************** *** 1341,1347 { if ( do_decomp == 1 ) fprintf ( stderr, "uncompress: corrupt input\n" ); ! unlink ( ofname ); exit ( 1 ); } --- 1353,1360 ----- { if ( do_decomp == 1 ) fprintf ( stderr, "uncompress: corrupt input\n" ); ! if( valid ) ! unlink ( ofname ); exit ( 1 ); }