compress42.c (ncompress-4.2.4.4) | : | compress42.c (ncompress-4.2.4.5) | ||
---|---|---|---|---|
skipping to change at line 133 | skipping to change at line 133 | |||
* Clean up the code a little and lint it. (Lint complains about all | * Clean up the code a little and lint it. (Lint complains about all | |||
* the regs used in the asm, but I'm not going to "fix" this.) | * the regs used in the asm, but I'm not going to "fix" this.) | |||
* | * | |||
* Revision 1.3 84/07/05 02:06:54 thomas | * Revision 1.3 84/07/05 02:06:54 thomas | |||
* Minor fixes. | * Minor fixes. | |||
* | * | |||
* Revision 1.2 84/07/05 00:27:27 thomas | * Revision 1.2 84/07/05 00:27:27 thomas | |||
* Add variable bit length output. | * Add variable bit length output. | |||
* | * | |||
*/ | */ | |||
#include <stdint.h> | ||||
#include <stdio.h> | #include <stdio.h> | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <string.h> | #include <string.h> | |||
#include <unistd.h> | #include <unistd.h> | |||
#include <fcntl.h> | #include <fcntl.h> | |||
#include <ctype.h> | #include <ctype.h> | |||
#include <signal.h> | #include <signal.h> | |||
#include <sys/types.h> | #include <sys/types.h> | |||
#include <sys/stat.h> | #include <sys/stat.h> | |||
#include <errno.h> | #include <errno.h> | |||
skipping to change at line 216 | skipping to change at line 217 | |||
#undef min | #undef min | |||
#define min(a,b) ((a>b) ? b : a) | #define min(a,b) ((a>b) ? b : a) | |||
#ifndef IBUFSIZ | #ifndef IBUFSIZ | |||
# define IBUFSIZ BUFSIZ /* Defailt input buffer size */ | # define IBUFSIZ BUFSIZ /* Defailt input buffer size */ | |||
#endif | #endif | |||
#ifndef OBUFSIZ | #ifndef OBUFSIZ | |||
# define OBUFSIZ BUFSIZ /* Default output buffer size */ | # define OBUFSIZ BUFSIZ /* Default output buffer size */ | |||
#endif | #endif | |||
#define MAXPATHLEN 1024 /* MAXPATHLEN - maximum length of a pathn ame we allow */ | ||||
#define SIZE_INNER_LOOP 256 /* Size of the inter (fast) compr ess loop */ | #define SIZE_INNER_LOOP 256 /* Size of the inter (fast) compr ess loop */ | |||
/* Defines for third byte of header */ | /* Defines for third byte of header */ | |||
#define MAGIC_1 (char_type)'\037'/* First byte of compressed file */ | #define MAGIC_1 (char_type)'\037'/* First byte of compressed file */ | |||
#define MAGIC_2 (char_type)'\235'/* Second byte of compressed fil e */ | #define MAGIC_2 (char_type)'\235'/* Second byte of compressed fil e */ | |||
#define BIT_MASK 0x1f /* Mask for 'number of compresssi on bits' */ | #define BIT_MASK 0x1f /* Mask for 'number of compresssi on bits' */ | |||
/* Masks 0x20 and 0x40 are free. */ | /* Masks 0x20 and 0x40 are free. */ | |||
/* I thin k 0x20 should mean that there is */ | /* I thin k 0x20 should mean that there is */ | |||
/* a four th header byte (for expansion). */ | /* a four th header byte (for expansion). */ | |||
#define BLOCK_MODE 0x80 /* Block compresssion if table is full and */ | #define BLOCK_MODE 0x80 /* Block compresssion if table is full and */ | |||
skipping to change at line 288 | skipping to change at line 288 | |||
#ifdef DOS /* PC/XT/AT (8088) processor */ | #ifdef DOS /* PC/XT/AT (8088) processor */ | |||
# define BITS 16 /* 16-bits processor max 12 bits */ | # define BITS 16 /* 16-bits processor max 12 bits */ | |||
# if BITS == 16 | # if BITS == 16 | |||
# define MAXSEG_64K | # define MAXSEG_64K | |||
# endif | # endif | |||
# undef BYTEORDER | # undef BYTEORDER | |||
# define BYTEORDER 4321 | # define BYTEORDER 4321 | |||
# undef NOALLIGN | # undef NOALLIGN | |||
# define NOALLIGN 1 | # define NOALLIGN 1 | |||
# define COMPILE_DATE __DATE__ | ||||
#endif /* DOS */ | #endif /* DOS */ | |||
#ifndef O_BINARY | #ifndef O_BINARY | |||
# define O_BINARY 0 /* System has no binary mode */ | # define O_BINARY 0 /* System has no binary mode */ | |||
#endif | #endif | |||
#ifdef M_XENIX /* Stupid compiler can't handle arrays with */ | #ifdef M_XENIX /* Stupid compiler can't handle arrays with */ | |||
# if BITS == 16 /* more than 65535 bytes - so we fake it */ | # if BITS == 16 /* more than 65535 bytes - so we fake it */ | |||
# define MAXSEG_64K | # define MAXSEG_64K | |||
# else | # else | |||
skipping to change at line 537 | skipping to change at line 536 | |||
int zcat_flg = 0; /* Write output on stdout, suppre ss messages */ | int zcat_flg = 0; /* Write output on stdout, suppre ss messages */ | |||
int recursive = 0; /* compress directories */ | int recursive = 0; /* compress directories */ | |||
int exit_code = -1; /* Exitcode of compress ( -1 no file compressed) */ | int exit_code = -1; /* Exitcode of compress ( -1 no file compressed) */ | |||
char_type inbuf[IBUFSIZ+64]; /* Input buffer */ | char_type inbuf[IBUFSIZ+64]; /* Input buffer */ | |||
char_type outbuf[OBUFSIZ+2048];/* Output buffer */ | char_type outbuf[OBUFSIZ+2048];/* Output buffer */ | |||
struct stat infstat; /* Input file status */ | struct stat infstat; /* Input file status */ | |||
char *ifname; /* Input filename */ | char *ifname; /* Input filename */ | |||
int remove_ofname = 0; /* Remove output file on a error */ | int remove_ofname = 0; /* Remove output file on a error */ | |||
char ofname[MAXPATHLEN]; /* Output filename */ | char *ofname = NULL; /* Output filename */ | |||
int fgnd_flag = 0; /* Running in background (SIGINT=SIGIGN) */ | int fgnd_flag = 0; /* Running in background (SIGINT=SIGIGN) */ | |||
long bytes_in; /* Total number of byte f rom input */ | long bytes_in; /* Total number of byte f rom input */ | |||
long bytes_out; /* Total number of byte t o output */ | long bytes_out; /* Total number of byte t o output */ | |||
/* | /* | |||
* 8086 & 80286 Has a problem with array bigger than 64K so fake the array | * 8086 & 80286 Has a problem with array bigger than 64K so fake the array | |||
* For processors with a limited address space and segments. | * For processors with a limited address space and segments. | |||
*/ | */ | |||
/* | /* | |||
skipping to change at line 644 | skipping to change at line 643 | |||
15733,-15791,15881,-15937,16057,-16097,16189,-16267, | 15733,-15791,15881,-15937,16057,-16097,16189,-16267, | |||
16363,-16447,16529,-16619,16691,-16763,16879,-16937, | 16363,-16447,16529,-16619,16691,-16763,16879,-16937, | |||
17021,-17093,17183,-17257,17341,-17401,17477,-17551, | 17021,-17093,17183,-17257,17341,-17401,17477,-17551, | |||
17623,-17713,17791,-17891,17957,-18041,18097,-18169, | 17623,-17713,17791,-17891,17957,-18041,18097,-18169, | |||
18233,-18307,18379,-18451,18523,-18637,18731,-18803, | 18233,-18307,18379,-18451,18523,-18637,18731,-18803, | |||
18919,-19031,19121,-19211,19273,-19381,19429,-19477 | 18919,-19031,19121,-19211,19273,-19381,19429,-19477 | |||
} ; | } ; | |||
#endif | #endif | |||
int main ARGS((int,char **)); | int main ARGS((int,char **)); | |||
void Usage ARGS((void)); | void Usage ARGS((int)); | |||
void comprexx ARGS((char **)); | void comprexx ARGS((const char *)); | |||
void compdir ARGS((char *)); | void compdir ARGS((char *)); | |||
void compress ARGS((int,int)); | void compress ARGS((int,int)); | |||
void decompress ARGS((int,int)); | void decompress ARGS((int,int)); | |||
void read_error ARGS((void)); | void read_error ARGS((void)); | |||
void write_error ARGS((void)); | void write_error ARGS((void)); | |||
void abort_compress ARGS((void)); | void abort_compress ARGS((void)); | |||
void prratio ARGS((FILE *,long,long)); | void prratio ARGS((FILE *,long,long)); | |||
void about ARGS((void)); | void about ARGS((void)); | |||
/***************************************************************** | /***************************************************************** | |||
skipping to change at line 702 | skipping to change at line 701 | |||
* deterministic, and can be done on the fly. Thus, the decompression | * deterministic, and can be done on the fly. Thus, the decompression | |||
* procedure needs no input table, but tracks the way the table was built. | * procedure needs no input table, but tracks the way the table was built. | |||
*/ | */ | |||
int | int | |||
main(argc, argv) | main(argc, argv) | |||
REG1 int argc; | REG1 int argc; | |||
REG2 char *argv[]; | REG2 char *argv[]; | |||
{ | { | |||
REG3 char **filelist; | REG3 char **filelist; | |||
REG4 char **fileptr; | REG4 char **fileptr; | |||
int seen_double_dash = 0; | ||||
if (fgnd_flag = (signal(SIGINT, SIG_IGN) != SIG_IGN)) | #ifdef SIGINT | |||
if ((fgnd_flag = (signal(SIGINT, SIG_IGN)) != SIG_IGN)) | ||||
signal(SIGINT, (SIG_TYPE)abort_compress); | signal(SIGINT, (SIG_TYPE)abort_compress); | |||
#endif | ||||
#ifdef SIGTERM | ||||
signal(SIGTERM, (SIG_TYPE)abort_compress); | signal(SIGTERM, (SIG_TYPE)abort_compress); | |||
#ifndef DOS | #endif | |||
#ifdef SIGHUP | ||||
signal(SIGHUP, (SIG_TYPE)abort_compress); | signal(SIGHUP, (SIG_TYPE)abort_compress); | |||
#endif | #endif | |||
#ifdef COMPATIBLE | #ifdef COMPATIBLE | |||
nomagic = 1; /* Original didn't have a magic number */ | nomagic = 1; /* Original didn't have a magic number */ | |||
#endif | #endif | |||
filelist = (char **)malloc(argc*sizeof(char *)); | filelist = (char **)malloc(argc*sizeof(char *)); | |||
if (filelist == NULL) | if (filelist == NULL) | |||
{ | { | |||
skipping to change at line 751 | skipping to change at line 755 | |||
* -n => no header: useful to uncompress old files | * -n => no header: useful to uncompress old files | |||
* -b maxbits => maxbits. If -b is specified, then maxbits MUST be given also. | * -b maxbits => maxbits. If -b is specified, then maxbits MUST be given also. | |||
* -c => cat all output to stdout | * -c => cat all output to stdout | |||
* -C => generate output compatible with compress 2.0. | * -C => generate output compatible with compress 2.0. | |||
* -r => recursively compress directories | * -r => recursively compress directories | |||
* if a string is left, must be an input filename. | * if a string is left, must be an input filename. | |||
*/ | */ | |||
for (argc--, argv++; argc > 0; argc--, argv++) | for (argc--, argv++; argc > 0; argc--, argv++) | |||
{ | { | |||
if (**argv == '-') | if (strcmp(*argv, "--") == 0) | |||
{ | ||||
seen_double_dash = 1; | ||||
continue; | ||||
} | ||||
if (seen_double_dash == 0 && **argv == '-') | ||||
{/* A flag argument */ | {/* A flag argument */ | |||
while (*++(*argv)) | while (*++(*argv)) | |||
{/* Process all flags in this arg */ | {/* Process all flags in this arg */ | |||
switch (**argv) | switch (**argv) | |||
{ | { | |||
case 'V': | case 'V': | |||
about(); | about(); | |||
break; | break; | |||
case 's': | case 's': | |||
skipping to change at line 792 | skipping to change at line 802 | |||
break; | break; | |||
case 'C': | case 'C': | |||
block_mode = 0; | block_mode = 0; | |||
break; | break; | |||
case 'b': | case 'b': | |||
if (!ARGVAL()) | if (!ARGVAL()) | |||
{ | { | |||
fprintf(stderr, "Missing maxbits\ n"); | fprintf(stderr, "Missing maxbits\ n"); | |||
Usage(); | Usage(1); | |||
} | } | |||
maxbits = atoi(*argv); | maxbits = atoi(*argv); | |||
goto nextarg; | goto nextarg; | |||
case 'c': | case 'c': | |||
zcat_flg = 1; | zcat_flg = 1; | |||
break; | break; | |||
case 'q': | case 'q': | |||
skipping to change at line 814 | skipping to change at line 824 | |||
break; | break; | |||
case 'r': | case 'r': | |||
case 'R': | case 'R': | |||
#ifdef RECURSIVE | #ifdef RECURSIVE | |||
recursive = 1; | recursive = 1; | |||
#else | #else | |||
fprintf(stderr, "%s -r not availa ble (due to missing directory functions)\n", *argv); | fprintf(stderr, "%s -r not availa ble (due to missing directory functions)\n", *argv); | |||
#endif | #endif | |||
break; | break; | |||
case 'h': | ||||
Usage(0); | ||||
break; | ||||
default: | default: | |||
fprintf(stderr, "Unknown flag: '% c'; ", **argv); | fprintf(stderr, "Unknown flag: '% c'; ", **argv); | |||
Usage(); | Usage(1); | |||
} | } | |||
} | } | |||
} | } | |||
else | else | |||
{ | { | |||
*fileptr++ = *argv; /* Build input file list */ | *fileptr++ = *argv; /* Build input file list */ | |||
*fileptr = NULL; | *fileptr = NULL; | |||
} | } | |||
nextarg: continue; | nextarg: continue; | |||
} | } | |||
if (maxbits < INIT_BITS) maxbits = INIT_BITS; | if (maxbits < INIT_BITS) maxbits = INIT_BITS; | |||
if (maxbits > BITS) maxbits = BITS; | if (maxbits > BITS) maxbits = BITS; | |||
if (*filelist != NULL) | if (*filelist != NULL) | |||
{ | { | |||
for (fileptr = filelist; *fileptr; fileptr++) | for (fileptr = filelist; *fileptr; fileptr++) | |||
comprexx(fileptr); | comprexx(*fileptr); | |||
} | } | |||
else | else | |||
{/* Standard input */ | {/* Standard input */ | |||
ifname = ""; | ifname = ""; | |||
exit_code = 0; | exit_code = 0; | |||
remove_ofname = 0; | remove_ofname = 0; | |||
if (do_decomp == 0) | if (do_decomp == 0) | |||
{ | { | |||
compress(0, 1); | compress(0, 1); | |||
skipping to change at line 865 | skipping to change at line 879 | |||
exit_code = 2; | exit_code = 2; | |||
} | } | |||
else | else | |||
decompress(0, 1); | decompress(0, 1); | |||
} | } | |||
exit((exit_code== -1) ? 1:exit_code); | exit((exit_code== -1) ? 1:exit_code); | |||
} | } | |||
void | void | |||
Usage() | Usage(int status) | |||
{ | { | |||
fprintf(stderr, "\ | fprintf(status ? stderr : stdout, "\ | |||
Usage: %s [-dfvcVr] [-b maxbits] [file ...]\n\ | Usage: %s [-dfhvcVr] [-b maxbits] [--] [file ...]\n\ | |||
-d If given, decompression is done instead.\n\ | -d If given, decompression is done instead.\n\ | |||
-c Write output on stdout, don't remove original.\n\ | -c Write output on stdout, don't remove original.\n\ | |||
-b Parameter limits the max number of bits/code.\n", progname); | -b Parameter limits the max number of bits/code.\n", progname); | |||
fprintf(stderr, "\ | fprintf(status ? stderr : stdout, "\ | |||
-f Forces output file to be generated, even if one already.\n\ | -f Forces output file to be generated, even if one already.\n\ | |||
exists, and even if no space is saved by compressing.\n\ | exists, and even if no space is saved by compressing.\n\ | |||
If -f is not used, the user will be prompted if stdin is.\n\ | If -f is not used, the user will be prompted if stdin is.\n\ | |||
a tty, otherwise, the output file will not be overwritten.\n\ | a tty, otherwise, the output file will not be overwritten.\n\ | |||
-h This help output.\n\ | ||||
-v Write compression statistics.\n\ | -v Write compression statistics.\n\ | |||
-V Output vesion and compile options.\n\ | -V Output version and compile options.\n\ | |||
-r Recursive. If a filename is a directory, descend\n\ | -r Recursive. If a filename is a directory, descend\n\ | |||
into it and compress everything in it.\n"); | into it and compress everything in it.\n"); | |||
exit(1); | exit(status); | |||
} | } | |||
void | void | |||
comprexx(fileptr) | comprexx(fileptr) | |||
char **fileptr; | const char *fileptr; | |||
{ | { | |||
int fdin; | int fdin = -1; | |||
int fdout; | int fdout = -1; | |||
char tempname[MAXPATHLEN]; | int has_z_suffix; | |||
char *tempname; | ||||
if (strlen(*fileptr) > sizeof(tempname) - 3) { | unsigned long namesize = strlen(fileptr); | |||
fprintf(stderr, "Pathname too long: %s\n", *fileptr); | ||||
exit_code = 1; | /* Create a temp buffer to add/remove the .Z suffix. */ | |||
return; | tempname = malloc(namesize + 3); | |||
if (tempname == NULL) | ||||
{ | ||||
perror("malloc"); | ||||
goto error; | ||||
} | } | |||
strcpy(tempname,*fileptr); | strcpy(tempname,fileptr); | |||
has_z_suffix = (namesize >= 2 && strcmp(&tempname[namesize - 2], | ||||
".Z") == 0); | ||||
errno = 0; | errno = 0; | |||
#ifdef LSTAT | #ifdef LSTAT | |||
if (lstat(tempname,&infstat) == -1) | if (lstat(tempname,&infstat) == -1) | |||
#else | #else | |||
if (stat(tempname,&infstat) == -1) | if (stat(tempname,&infstat) == -1) | |||
#endif | #endif | |||
{ | { | |||
if (do_decomp) | if (do_decomp) | |||
{ | { | |||
switch (errno) | switch (errno) | |||
{ | { | |||
case ENOENT: /* file doesn't exist */ | case ENOENT: /* file doesn't exist */ | |||
/* | /* | |||
** if the given name doesn't end with .Z, try app ending one | ** if the given name doesn't end with .Z, try app ending one | |||
** This is obviously the wrong thing to do if it' s a | ** This is obviously the wrong thing to do if it' s a | |||
** directory, but it shouldn't do any harm. | ** directory, but it shouldn't do any harm. | |||
*/ | */ | |||
if (strcmp(tempname + strlen(tempname) - 2, ".Z") != 0) | if (!has_z_suffix) | |||
{ | { | |||
strcat(tempname,".Z"); | memcpy(&tempname[namesize], ".Z", | |||
3); | ||||
namesize += 2; | ||||
has_z_suffix = 1; | ||||
errno = 0; | errno = 0; | |||
#ifdef LSTAT | #ifdef LSTAT | |||
if (lstat(tempname,&infstat) == - 1) | if (lstat(tempname,&infstat) == - 1) | |||
#else | #else | |||
if (stat(tempname,&infstat) == -1 ) | if (stat(tempname,&infstat) == -1 ) | |||
#endif | #endif | |||
{ | { | |||
perror(tempname); | perror(tempname); | |||
exit_code = 1; | goto error; | |||
return; | ||||
} | } | |||
if ((infstat.st_mode & S_IFMT) != S_IFREG) | if ((infstat.st_mode & S_IFMT) != S_IFREG) | |||
{ | { | |||
fprintf(stderr, "%s: Not a regular file.\n", tempname); | fprintf(stderr, "%s: Not a regular file.\n", tempname); | |||
exit_code = 1; | goto error; | |||
return ; | ||||
} | } | |||
} | } | |||
else | else | |||
{ | { | |||
perror(tempname); | perror(tempname); | |||
exit_code = 1; | goto error; | |||
return; | ||||
} | } | |||
break; | break; | |||
default: | default: | |||
perror(tempname); | perror(tempname); | |||
exit_code = 1; | goto error; | |||
return; | ||||
} | } | |||
} | } | |||
else | else | |||
{ | { | |||
perror(tempname); | perror(tempname); | |||
exit_code = 1; | goto error; | |||
return; | ||||
} | } | |||
} | } | |||
switch (infstat.st_mode & S_IFMT) | switch (infstat.st_mode & S_IFMT) | |||
{ | { | |||
case S_IFDIR: /* directory */ | case S_IFDIR: /* directory */ | |||
#ifdef RECURSIVE | #ifdef RECURSIVE | |||
if (recursive) | if (recursive) | |||
compdir(tempname); | compdir(tempname); | |||
else | else | |||
#endif | #endif | |||
if (!quiet) | if (!quiet) | |||
fprintf(stderr,"%s is a directory -- ignored\n", tempname ); | fprintf(stderr,"%s is a directory -- ignored\n", tempname ); | |||
break; | break; | |||
case S_IFREG: /* regular file */ | case S_IFREG: /* regular file */ | |||
if (do_decomp != 0) | if (do_decomp != 0) | |||
{/* DECOMPRESSION */ | {/* DECOMPRESSION */ | |||
if (!zcat_flg) | if (!zcat_flg) | |||
{ | { | |||
if (strcmp(tempname + strlen(tempname) - 2, ".Z") != 0) | if (!has_z_suffix) | |||
{ | { | |||
if (!quiet) | if (!quiet) | |||
fprintf(stderr,"%s - no . Z suffix\n",tempname); | fprintf(stderr,"%s - no . Z suffix\n",tempname); | |||
return; | goto error; | |||
} | } | |||
} | } | |||
strcpy(ofname, tempname); | free(ofname); | |||
ofname = strdup(tempname); | ||||
if (ofname == NULL) | ||||
{ | ||||
perror("strdup"); | ||||
goto error; | ||||
} | ||||
/* Strip of .Z suffix */ | /* Strip of .Z suffix */ | |||
if (has_z_suffix) | ||||
if (strcmp(tempname + strlen(tempname) - 2, ".Z") | ofname[namesize - 2] = '\0'; | |||
== 0) | ||||
ofname[strlen(tempname) - 2] = '\0'; | ||||
} | } | |||
else | else | |||
{/* COMPRESSION */ | {/* COMPRESSION */ | |||
if (!zcat_flg) | if (!zcat_flg) | |||
{ | { | |||
if (strcmp(tempname + strlen(tempname) - 2, ".Z") == 0) | if (has_z_suffix) | |||
{ | { | |||
fprintf(stderr, "%s: already has .Z suffix -- no change\n", tempname); | fprintf(stderr, "%s: already has .Z suffix -- no change\n", tempname); | |||
return; | free(tempname); | |||
return; | ||||
} | } | |||
if (infstat.st_nlink > 1 && (!force)) | if (infstat.st_nlink > 1 && (!force)) | |||
{ | { | |||
fprintf(stderr, "%s has %d other | fprintf(stderr, "%s has %jd other | |||
links: unchanged\n", | links: unchanged\n", | |||
t | t | |||
empname, infstat.st_nlink - 1); | empname, (intmax_t)(infstat.st_nlink - 1)); | |||
exit_code = 1; | goto error; | |||
return; | ||||
} | } | |||
} | } | |||
strcpy(ofname, tempname); | ofname = malloc(namesize + 3); | |||
strcat(ofname, ".Z"); | if (ofname == NULL) | |||
{ | ||||
perror("malloc"); | ||||
goto error; | ||||
} | ||||
memcpy(ofname, tempname, namesize); | ||||
strcpy(&ofname[namesize], ".Z"); | ||||
} | } | |||
if ((fdin = open(ifname = tempname, O_RDONLY|O_BINARY)) == -1) | if ((fdin = open(ifname = tempname, O_RDONLY|O_BINARY)) == -1) | |||
{ | { | |||
perror(tempname); | perror(tempname); | |||
exit_code = 1; | goto error; | |||
return; | ||||
} | } | |||
if (zcat_flg == 0) | if (zcat_flg == 0) | |||
{ | { | |||
int c; | if (access(ofname, F_OK) == 0) | |||
int s; | { | |||
struct stat statbuf; | ||||
struct stat statbuf2; | ||||
if (stat(ofname, &statbuf) == 0) | ||||
{ | ||||
if ((s = strlen(ofname)) > 8) | ||||
{ | ||||
c = ofname[s-1]; | ||||
ofname[s-1] = '\0'; | ||||
statbuf2 = statbuf; | ||||
if (!stat(ofname, &statbuf2) && | ||||
statbuf.st_mode == statb | ||||
uf2.st_mode && | ||||
statbuf.st_ino == statb | ||||
uf2.st_ino && | ||||
statbuf.st_dev == statb | ||||
uf2.st_dev && | ||||
statbuf.st_uid == statb | ||||
uf2.st_uid && | ||||
statbuf.st_gid == statb | ||||
uf2.st_gid && | ||||
statbuf.st_size == statb | ||||
uf2.st_size && | ||||
statbuf.st_atime == statb | ||||
uf2.st_atime && | ||||
statbuf.st_mtime == statb | ||||
uf2.st_mtime && | ||||
statbuf.st_ctime == statb | ||||
uf2.st_ctime) | ||||
{ | ||||
fprintf(stderr, "%s: file | ||||
name too long to tack on .Z\n", tempname); | ||||
exit_code = 1; | ||||
return; | ||||
} | ||||
ofname[s-1] = (char)c; | ||||
} | ||||
if (!force) | if (!force) | |||
{ | { | |||
inbuf[0] = 'n'; | inbuf[0] = 'n'; | |||
fprintf(stderr, "%s already exists.\n", o fname); | fprintf(stderr, "%s already exists.\n", o fname); | |||
if (fgnd_flag && isatty(0)) | if (fgnd_flag && isatty(0)) | |||
{ | { | |||
fprintf(stderr, "Do you w ish to overwrite %s (y or n)? ", ofname); | fprintf(stderr, "Do you w ish to overwrite %s (y or n)? ", ofname); | |||
fflush(stderr); | fflush(stderr); | |||
skipping to change at line 1094 | skipping to change at line 1090 | |||
while (in buf[1] != '\n'); | while (in buf[1] != '\n'); | |||
} | } | |||
} | } | |||
else | else | |||
perror("stdin"); | perror("stdin"); | |||
} | } | |||
if (inbuf[0] != 'y') | if (inbuf[0] != 'y') | |||
{ | { | |||
fprintf(stderr, "%s not o verwritten\n", ofname); | fprintf(stderr, "%s not o verwritten\n", ofname); | |||
exit_code = 1; | goto error; | |||
return; | ||||
} | } | |||
} | } | |||
if (unlink(ofname)) | if (unlink(ofname)) | |||
{ | { | |||
fprintf(stderr, "Can't remove old output file\n"); | fprintf(stderr, "Can't remove old output file\n"); | |||
perror(ofname); | perror(ofname); | |||
exit_code = 1; | goto error; | |||
return ; | ||||
} | } | |||
} | } | |||
if ((fdout = open(ofname, O_WRONLY|O_CREAT|O_EXCL|O_BINAR Y,0600)) == -1) | if ((fdout = open(ofname, O_WRONLY|O_CREAT|O_EXCL|O_BINAR Y,0600)) == -1) | |||
{ | { | |||
perror(tempname); | perror(tempname); | |||
return; | goto error; | |||
} | } | |||
if ((s = strlen(ofname)) > 8) | ||||
{ | ||||
if (fstat(fdout, &statbuf)) | ||||
{ | ||||
fprintf(stderr, "Can't get status | ||||
op output file\n"); | ||||
perror(ofname); | ||||
exit_code = 1; | ||||
return ; | ||||
} | ||||
c = ofname[s-1]; | ||||
ofname[s-1] = '\0'; | ||||
statbuf2 = statbuf; | ||||
if (!stat(ofname, &statbuf2) && | ||||
statbuf.st_mode == statbuf2.st_m | ||||
ode && | ||||
statbuf.st_ino == statbuf2.st_i | ||||
no && | ||||
statbuf.st_dev == statbuf2.st_d | ||||
ev && | ||||
statbuf.st_uid == statbuf2.st_u | ||||
id && | ||||
statbuf.st_gid == statbuf2.st_g | ||||
id && | ||||
statbuf.st_size == statbuf2.st_s | ||||
ize && | ||||
statbuf.st_atime == statbuf2.st_a | ||||
time && | ||||
statbuf.st_mtime == statbuf2.st_m | ||||
time && | ||||
statbuf.st_ctime == statbuf2.st_c | ||||
time) | ||||
{ | ||||
fprintf(stderr, "%s: filename too | ||||
long to tack on .Z\n", tempname); | ||||
if (unlink(ofname)) | ||||
{ | ||||
fprintf(stderr, "can't re | ||||
move bad output file\n"); | ||||
perror(ofname); | ||||
} | ||||
exit_code = 1; | ||||
return; | ||||
} | ||||
ofname[s-1] = (char)c; | ||||
} | ||||
if(!quiet) | if(!quiet) | |||
fprintf(stderr, "%s: ", tempname); | fprintf(stderr, "%s: ", tempname); | |||
remove_ofname = 1; | remove_ofname = 1; | |||
} | } | |||
else | else | |||
{ | { | |||
fdout = 1; | fdout = 1; | |||
ofname[0] = '\0'; | ||||
remove_ofname = 0; | remove_ofname = 0; | |||
} | } | |||
if (do_decomp == 0) | if (do_decomp == 0) | |||
compress(fdin, fdout); | compress(fdin, fdout); | |||
else | else | |||
decompress(fdin, fdout); | decompress(fdin, fdout); | |||
close(fdin); | close(fdin); | |||
skipping to change at line 1273 | skipping to change at line 1227 | |||
if (exit_code == -1) | if (exit_code == -1) | |||
exit_code = 0; | exit_code = 0; | |||
break; | break; | |||
default: | default: | |||
fprintf(stderr,"%s is not a directory or a regular file - ignored\n", | fprintf(stderr,"%s is not a directory or a regular file - ignored\n", | |||
tempname); | tempname); | |||
break; | break; | |||
} | } | |||
free(tempname); | ||||
if (!remove_ofname) | ||||
{ | ||||
free(ofname); | ||||
ofname = NULL; | ||||
} | ||||
return; | ||||
error: | ||||
free(ofname); | ||||
ofname = NULL; | ||||
free(tempname); | ||||
exit_code = 1; | ||||
if (fdin != -1) | ||||
close(fdin); | ||||
if (fdout != -1) | ||||
close(fdout); | ||||
} | } | |||
#ifdef RECURSIVE | #ifdef RECURSIVE | |||
void | void | |||
compdir(dir) | compdir(dir) | |||
REG3 char *dir; | REG3 char *dir; | |||
{ | { | |||
#ifndef DIRENT | #ifndef DIRENT | |||
REG1 struct direct *dp; | REG1 struct direct *dp; | |||
#else | #else | |||
REG1 struct dirent *dp; | REG1 struct dirent *dp; | |||
#endif | #endif | |||
REG2 DIR *dirp; | REG2 DIR *dirp; | |||
char nbuf[MAXPATHLEN]; | char *nptr; | |||
char *nptr = nbuf; | char *fptr; | |||
unsigned long dir_size = strlen(dir); | ||||
/* The +256 is a lazy optimization. We'll resize on demand. */ | ||||
unsigned long size = dir_size + 256; | ||||
nptr = malloc(size); | ||||
if (nptr == NULL) | ||||
{ | ||||
perror("malloc"); | ||||
exit_code = 1; | ||||
return; | ||||
} | ||||
memcpy(nptr, dir, dir_size); | ||||
nptr[dir_size] = '/'; | ||||
fptr = &nptr[dir_size + 1]; | ||||
dirp = opendir(dir); | dirp = opendir(dir); | |||
if (dirp == NULL) | if (dirp == NULL) | |||
{ | { | |||
free(nptr); | ||||
printf("%s unreadable\n", dir); /* not stderr! */ | printf("%s unreadable\n", dir); /* not stderr! */ | |||
return ; | return ; | |||
} | } | |||
/* | /* | |||
** WARNING: the following algorithm will occasionally cause | ** WARNING: the following algorithm will occasionally cause | |||
** compress to produce error warnings of the form "<filename>.Z | ** compress to produce error warnings of the form "<filename>.Z | |||
** already has .Z suffix - ignored". This occurs when the | ** already has .Z suffix - ignored". This occurs when the | |||
** .Z output file is inserted into the directory below | ** .Z output file is inserted into the directory below | |||
** readdir's current pointer. | ** readdir's current pointer. | |||
** These warnings are harmless but annoying. The alternative | ** These warnings are harmless but annoying. The alternative | |||
** to allowing this would be to store the entire directory | ** to allowing this would be to store the entire directory | |||
** list in memory, then compress the entries in the stored | ** list in memory, then compress the entries in the stored | |||
** list. Given the depth-first recursive algorithm used here, | ** list. Given the depth-first recursive algorithm used here, | |||
** this could use up a tremendous amount of memory. I don't | ** this could use up a tremendous amount of memory. I don't | |||
** think it's worth it. -- Dave Mack | ** think it's worth it. -- Dave Mack | |||
*/ | */ | |||
while (dp = readdir(dirp)) | while ((dp = readdir(dirp)) != NULL) | |||
{ | { | |||
if (dp->d_ino == 0) | if (dp->d_ino == 0) | |||
continue; | continue; | |||
if (strcmp(dp->d_name,".") == 0 || strcmp(dp->d_name,".." ) == 0) | if (strcmp(dp->d_name,".") == 0 || strcmp(dp->d_name,".." ) == 0) | |||
continue; | continue; | |||
if ((strlen(dir)+strlen(dp->d_name)+1) < (MAXPATHLEN - 1) ) | if (size < dir_size + strlen(dp->d_name) + 2) | |||
{ | { | |||
strcpy(nbuf,dir); | size = dir_size + strlen(dp->d_name) + 2; | |||
strcat(nbuf,"/"); | nptr = realloc(nptr, size); | |||
strcat(nbuf,dp->d_name); | if (nptr == NULL) | |||
comprexx(&nptr); | { | |||
perror("realloc"); | ||||
exit_code = 1; | ||||
break; | ||||
} | ||||
fptr = &nptr[dir_size + 1]; | ||||
} | } | |||
else | ||||
fprintf(stderr,"Pathname too long: %s/%s\n", dir, | strcpy(fptr, dp->d_name); | |||
dp->d_name); | comprexx(nptr); | |||
} | } | |||
closedir(dirp); | closedir(dirp); | |||
return; | free(nptr); | |||
} | } | |||
#endif | #endif | |||
/* | /* | |||
* compress fdin to fdout | * compress fdin to fdout | |||
* | * | |||
* Algorithm: use open addressing double hashing (no chaining) on the | * Algorithm: use open addressing double hashing (no chaining) on the | |||
* prefix code / next character combination. We do a variant of Knuth's | * prefix code / next character combination. We do a variant of Knuth's | |||
* algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime | * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime | |||
* secondary probe. Here, the modular division first probe is gives way | * secondary probe. Here, the modular division first probe is gives way | |||
* to a faster exclusive-or manipulation. Also do block compression with | * to a faster exclusive-or manipulation. Also do block compression with | |||
skipping to change at line 1647 | skipping to change at line 1640 | |||
fprintf(stderr, "%s: not in compressed format\n", | fprintf(stderr, "%s: not in compressed format\n", | |||
(ifname[0 ] != '\0'? ifname : "stdin")); | (ifname[0 ] != '\0'? ifname : "stdin")); | |||
exit_code = 1; | exit_code = 1; | |||
} | } | |||
return ; | return ; | |||
} | } | |||
maxbits = inbuf[2] & BIT_MASK; | maxbits = inbuf[2] & BIT_MASK; | |||
block_mode = inbuf[2] & BLOCK_MODE; | block_mode = inbuf[2] & BLOCK_MODE; | |||
maxmaxcode = MAXCODE(maxbits); | ||||
if (maxbits > BITS) | if (maxbits > BITS) | |||
{ | { | |||
fprintf(stderr, | fprintf(stderr, | |||
"%s: compressed with %d bits, can only ha ndle %d bits\n", | "%s: compressed with %d bits, can only ha ndle %d bits\n", | |||
(*ifname != '\0' ? ifname : "stdin"), max bits, BITS); | (*ifname != '\0' ? ifname : "stdin"), max bits, BITS); | |||
exit_code = 4; | exit_code = 4; | |||
return; | return; | |||
} | } | |||
maxmaxcode = MAXCODE(maxbits); | ||||
bytes_in = insize; | bytes_in = insize; | |||
maxcode = MAXCODE(n_bits = INIT_BITS)-1; | maxcode = MAXCODE(n_bits = INIT_BITS)-1; | |||
bitmask = (1<<n_bits)-1; | bitmask = (1<<n_bits)-1; | |||
oldcode = -1; | oldcode = -1; | |||
finchar = 0; | finchar = 0; | |||
outpos = 0; | outpos = 0; | |||
posbits = 3<<3; | posbits = 3<<3; | |||
free_ent = ((block_mode) ? FIRST : 256); | free_ent = ((block_mode) ? FIRST : 256); | |||
skipping to change at line 1839 | skipping to change at line 1833 | |||
{ | { | |||
fprintf(stderr, "\nread error on"); | fprintf(stderr, "\nread error on"); | |||
perror((ifname[0] != '\0') ? ifname : "stdin"); | perror((ifname[0] != '\0') ? ifname : "stdin"); | |||
abort_compress(); | abort_compress(); | |||
} | } | |||
void | void | |||
write_error() | write_error() | |||
{ | { | |||
fprintf(stderr, "\nwrite error on"); | fprintf(stderr, "\nwrite error on"); | |||
perror((ofname[0] != '\0') ? ofname : "stdout"); | perror(ofname ? ofname : "stdout"); | |||
abort_compress(); | abort_compress(); | |||
} | } | |||
void | void | |||
abort_compress() | abort_compress() | |||
{ | { | |||
if (remove_ofname) | if (remove_ofname) | |||
unlink(ofname); | unlink(ofname); | |||
exit(1); | exit(1); | |||
skipping to change at line 1882 | skipping to change at line 1876 | |||
putc('-', stream); | putc('-', stream); | |||
q = -q; | q = -q; | |||
} | } | |||
fprintf(stream, "%d.%02d%%", q / 100, q % 100); | fprintf(stream, "%d.%02d%%", q / 100, q % 100); | |||
} | } | |||
void | void | |||
about() | about() | |||
{ | { | |||
fprintf(stderr, "Compress version: %s, compiled: %s\n", version_i | printf("Compress version: %s\n", version_id); | |||
d, COMPILE_DATE); | printf("Compile options:\n "); | |||
fprintf(stderr, "Compile options:\n "); | ||||
#if BYTEORDER == 4321 && NOALLIGN == 1 | #if BYTEORDER == 4321 && NOALLIGN == 1 | |||
fprintf(stderr, "USE_BYTEORDER, "); | printf("USE_BYTEORDER, "); | |||
#endif | #endif | |||
#ifdef FAST | #ifdef FAST | |||
fprintf(stderr, "FAST, "); | printf("FAST, "); | |||
#endif | #endif | |||
#ifdef vax | #ifdef vax | |||
fprintf(stderr, "vax, "); | printf("vax, "); | |||
#endif | #endif | |||
#ifdef DIRENT | #ifdef DIRENT | |||
fprintf(stderr,"DIRENT, "); | printf("DIRENT, "); | |||
#endif | #endif | |||
#ifdef SYSDIR | #ifdef SYSDIR | |||
fprintf(stderr,"SYSDIR, "); | printf("SYSDIR, "); | |||
#endif | #endif | |||
#ifdef NO_UCHAR | #ifdef NO_UCHAR | |||
fprintf(stderr, "NO_UCHAR, "); | printf("NO_UCHAR, "); | |||
#endif | #endif | |||
#ifdef SIGNED_COMPARE_SLOW | #ifdef SIGNED_COMPARE_SLOW | |||
fprintf(stderr, "SIGNED_COMPARE_SLOW, "); | printf("SIGNED_COMPARE_SLOW, "); | |||
#endif | #endif | |||
#ifdef MAXSEG_64K | #ifdef MAXSEG_64K | |||
fprintf(stderr, "MAXSEG_64K, "); | printf("MAXSEG_64K, "); | |||
#endif | #endif | |||
#ifdef DOS | #ifdef DOS | |||
fprintf(stderr, "DOS, "); | printf("DOS, "); | |||
#endif | #endif | |||
#ifdef DEBUG | #ifdef DEBUG | |||
fprintf(stderr, "DEBUG, "); | printf("DEBUG, "); | |||
#endif | #endif | |||
#ifdef LSTAT | #ifdef LSTAT | |||
fprintf(stderr, "LSTAT, "); | printf("LSTAT, "); | |||
#endif | #endif | |||
fprintf(stderr, "\n REGISTERS=%d IBUFSIZ=%d, OBUFSIZ=%d, B ITS=%d\n", | printf("\n REGISTERS=%d IBUFSIZ=%d, OBUFSIZ=%d, BITS=%d\n" , | |||
REGISTERS, IBUFSIZ, OBUFSIZ, BITS); | REGISTERS, IBUFSIZ, OBUFSIZ, BITS); | |||
fprintf(stderr, "\n\ | printf("\n\ | |||
Author version 4.2.4.x (Maintenance):\n\ | ||||
Mike Frysinger (vapier@gmail.com)\n\ | ||||
\n\ | ||||
Author version 4.2 (Speed improvement & source cleanup):\n\ | Author version 4.2 (Speed improvement & source cleanup):\n\ | |||
Peter Jannesen (peter@ncs.nl)\n\ | Peter Jannesen (peter@ncs.nl)\n\ | |||
\n\ | \n\ | |||
Author version 4.1 (Added recursive directory compress):\n\ | Author version 4.1 (Added recursive directory compress):\n\ | |||
Dave Mack (csu@alembic.acs.com)\n\ | Dave Mack (csu@alembic.acs.com)\n\ | |||
\n\ | \n\ | |||
Authors version 4.0 (World release in 1985):\n\ | Authors version 4.0 (World release in 1985):\n\ | |||
Spencer W. Thomas, Jim McKie, Steve Davies,\n\ | Spencer W. Thomas, Jim McKie, Steve Davies,\n\ | |||
Ken Turkowski, James A. Woods, Joe Orost\n"); | Ken Turkowski, James A. Woods, Joe Orost\n"); | |||
End of changes. 71 change blocks. | ||||
188 lines changed or deleted | 162 lines changed or added |