/*@H************************ < COMPRESS utility> **************************** * * * compress : compusi.uni * * * * port by : Donald J. Gloistein * * * * Source, Documentation, Object Code: * * released to Public Domain. This code is ported from compress v4.0 * * release joe. * * * *--------------------------- Module Description --------------------------* * Unix system dependent routines. These are specific to either the * * unix file structure or some unix only functions. * * * * Separated out for ease of writing the main module. * * * *--------------------------- Implementation Notes --------------------------* * * * compiled with : compress.h compress.fns * * linked with : compress.o compapi.o * * * * To use, copy or rename this file to compusi.c and recompile. * * Set the defines in compress.h to reflect the status of your compiler's * * runtime library, allocation type for malloc()'s, and memory models if * * applicable, and your library function call for malloc() and free(). * * * * problems: header has some hardcoded defines you may need to change * * for your compiler. Please read the header thoroughly. * * * * * * Revision ++jrb * * - replaced all '/' with separator[0] * * - name mapping when MSDOS is defined * * (ie filesystems with no multiple extensions) * * On compression * * foo --> foo.Z * * foo.c --> foo.cZ * * foo.cc --> foo.ccZ * * foo.ccc --> foo.ccZ notice the ambiguity * * On Uncompression * * foo.Z --> foo * * foo.cZ --> foo.c * * foo.ccZ --> foo.cc * * uncompress foo.cc with uncompress foo.ccZ * * * *--------------------------- Author(s) -------------------------* * Initials ---- Name --------------------------------- * * DjG Donald J. Gloistein * * Plus many others, see rev.hst file for full list * * LvR Lyle V. Rains, thanks for the improved implementation * * of the compression and decompression routines. * *************************************************************************@H*/ #include #include "compress.h" /* contains the rest of the include file declarations */ /* For those who don't have it in libc.a */ #ifdef NO_STRRCHR char *strrchr(s,c) char *s; int c; { register int count; while (*s){ s++; count++; } s--; while (count--) if (*s == (char)c) return(s); else s--; return(NULL); } #endif char *get_program_name(ptr) char *ptr; { char *cp; if ((cp = strrchr(ptr, separator[0])) != NULL) cp++; else cp = ptr; #ifdef MSDOS if(strcmp(cp,"uncompre") == 0) { #else if(strcmp(cp,"uncompress") == 0) { #endif do_decomp = 1; } else if(strcmp(cp, "zcat") == 0) { keep = TRUE; zcat_flg = do_decomp = 1; } return (cp); } char *name_index(ptr) char *ptr; { char *p; p = strrchr(ptr,separator[0]); return ((p)? ++p: ptr); } int is_z_name(ptr) /* checks if it is already a z name */ char *ptr; { #ifndef MSDOS return (!(strcmp(ptr + strlen(ptr) -2,".Z"))); #else extern char *rindex(); register int n; register char *ext = rindex(ptr, '.'); if(ext == NULL) return 0; n = strlen(ext) - 2; return ((ext[n] == 'Z') || (ext[n] == 'z')); #endif } int make_z_name(ptr) char *ptr; { #ifndef BSD4_2 #ifndef MSDOS if (strlen(name_index(ptr)) > 12 ) { fprintf(stderr,"%s: filename too long to add .Z\n",name_index(ptr)); return FALSE; } #else extern char *rindex(); register int n; register char *ext = rindex(ptr, '.'); if(ext == NULL) { strcat(ptr, ".Z"); return TRUE; } if((n = strlen(ext)) < 4) { ext[n] = 'Z'; ext[n+1] = '\0'; } else ext[n-1] = 'Z'; return TRUE; #endif #endif strcat(ptr,".Z"); return TRUE; } void unmake_z_name(ptr) char *ptr; { #ifdef MSDOS extern char *rindex(); register char *ext = rindex(ptr, 'Z'); if(ext == NULL) ext = rindex(ptr, 'z'); if(ext[-1] == '.') { ext[-1] = '\0'; return; } *ext = '\0'; return; #else register int len = strlen(ptr)-2; ptr[len] = '\0'; #endif } #ifndef NOSIGNAL SIGTYPE onintr ( ) { if (!zcat_flg && !keep_error){ fclose(stdout); unlink ( ofname ); } exit ( ERROR ); } SIGTYPE oops ( ) /* wild pointer -- assume bad input */ { if ( do_decomp == 1 ) fprintf ( stderr, "%s: corrupt input: %s\n",prog_name,ifname); if (!zcat_flg && !keep_error){ fclose(stdout); unlink ( ofname ); } exit ( ERROR ); } #endif void copystat(ifname, ofname) char *ifname, *ofname; { struct stat statbuf; int mode; time_t timep[2]; fclose(stdout); if (stat(ifname, &statbuf)) { /* Get stat on input file */ perror(ifname); return; } if ((statbuf.st_mode & S_IFMT/*0170000*/) != S_IFREG/*0100000*/) { if(quiet) fprintf(stderr, "%s: ", ifname); fprintf(stderr, " -- not a regular file: unchanged"); exit_stat = 1; } else if (statbuf.st_nlink > 1) { if(quiet) fprintf(stderr, "%s: ", ifname); fprintf(stderr, " -- has %d other links: unchanged", statbuf.st_nlink - 1); exit_stat = ERROR; } else if (exit_stat == NOSAVING && (!force)) { /* No compression: remove file.Z */ if(!quiet) fprintf(stderr, " -- no savings -- file unchanged"); } else if (exit_stat == NOMEM){ if (!quiet) fprintf(stderr, " -- file unchanged"); if (!do_decomp) exit(ERROR); else return; /* otherwise will unlink outfile */ } else if (exit_stat == OK) { /* ***** Successful Compression ***** */ mode = statbuf.st_mode & 07777; if (chmod(ofname, mode)) /* Copy modes */ perror(ofname); chown(ofname,statbuf.st_uid,statbuf.st_gid); /* Copy Ownership */ timep[0] = statbuf.st_atime; timep[1] = statbuf.st_mtime; utime(ofname,timep); /* Update last accessed and modified times */ if (!keep){ fclose(stdin); if (unlink(ifname)) /* Remove input file */ perror(ifname); if(!quiet) fprintf(stderr, " -- replaced with %s", ofname); } else{ if(!quiet) fprintf(stderr, " -- compressed to %s", ofname); } return; /* Successful return */ } /* Unsuccessful return -- one of the tests failed */ fclose(stdout); if (unlink(ofname)) perror(ofname); } void version() { #ifdef XENIX #ifndef NDEBUG fprintf(stderr, "%s\nOptions: Xenix %s MAXBITS = %d\n", rcs_ident, "DEBUG",MAXBITS); #else fprintf(stderr, "%s\nOptions: Xenix MAXBITS = %d\n", rcs_ident,MAXBITS); #endif #else #ifndef NDEBUG fprintf(stderr, "%s\nOptions: Unix %s MAXBITS = %d\n", rcs_ident, "DEBUG",MAXBITS); #else fprintf(stderr, "%s\nOptions: Unix MAXBITS = %d\n", rcs_ident,MAXBITS); #endif #endif } ALLOCTYPE FAR *emalloc(x,y) unsigned int x; int y; { ALLOCTYPE FAR *p; p = (ALLOCTYPE FAR *)ALLOCATE(x,y); return(p); } void efree(ptr) ALLOCTYPE FAR *ptr; { FREEIT(ptr); }