compress.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 996 行 · 第 1/3 页
C
996 行
/* Unsuccessful return -- one of the tests failed */
if( unlink( ofname ) )
perror( ofname );
}
static void compress_file( char **fileptr )
/*****************************************/
{
char tempname[MAXPATHLEN];
#ifdef SHORTNAMES
char *cp;
#endif
strcpy( tempname, *fileptr );
errno = 0;
if( stat( tempname, &insbuf ) == -1 ) {
if( do_decomp ) {
switch( errno ) {
case ENOENT: /* file doesn't exist */
/*
** if the given name doesn't end with .Z, try appending one
** This is obviously the wrong thing to do if it's a
** directory, but it shouldn't do any harm.
*/
if( stricmp( tempname + strlen( tempname ) - 2, ".Z" ) != 0 ) {
#ifdef SHORTNAMES
if( (cp = strrchr( tempname, DIR_SEP_CHAR ) ) != NULL )
cp++;
else
cp = tempname;
if( strlen( cp ) > 12 ) {
fprintf( stderr, "%s.Z: No such file or directory\n", tempname );
return;
}
#endif /* SHORTNAMES */
strcat( tempname, ".Z" );
errno = 0;
if( stat( tempname, &insbuf ) == -1 ) {
perror( tempname );
return;
}
} else {
perror( tempname );
return;
}
break;
default:
perror( tempname );
return;
}
} else {
/* we can't stat the file, ignore it */
perror( tempname );
return;
}
}
switch( insbuf.st_mode & S_IFMT ) {
case S_IFDIR: /* directory */
if( !quiet )
fprintf( stderr, "%s is a directory -- ignored\n", tempname );
break;
case S_IFREG: /* regular file */
exit_stat = 0;
if( do_decomp != 0 ) {
/* DECOMPRESSION */
if( !zcat_flg ) {
if( stricmp( tempname + strlen( tempname ) - 2, ".Z" ) != 0 ) {
if( !quiet ) {
fprintf( stderr, "%s - no .Z suffix\n", tempname );
}
return;
}
}
/* Open input file */
if( freopen( tempname, "rb", stdin ) == NULL ) {
perror( tempname );
return;
}
setvbuf( stdin, NULL, _IOFBF, IO_BUF_SIZE );
/* Check the magic number */
if( nomagic == 0 ) {
if ((getchar() != (magic_header[0] & 0xFF))
|| (getchar() != (magic_header[1] & 0xFF))) {
fprintf( stderr, "%s: not in compressed format\n", tempname );
return;
}
maxbits = getchar(); /* set -b from file */
block_compress = maxbits & BLOCK_MASK;
maxbits &= BIT_MASK;
maxmaxcode = 1 << maxbits;
if( maxbits > BITS ) {
fprintf( stderr,
"%s: compressed with %d bits, can only handle %d bits\n",
tempname, maxbits, BITS );
return;
}
}
/* we have to ignore SIGINT for a while, otherwise
* a ^C can nuke an existing file with ofname
*/
signal( SIGINT, SIG_IGN );
/* Generate output filename */
strcpy( ofname, tempname );
/* Check for .Z suffix */
if( stricmp( tempname + strlen( tempname ) - 2, ".Z" ) == 0 ) {
ofname[strlen( tempname ) - 2] = '\0'; /* Strip off .Z */
}
} else {
/* COMPRESSION */
if( stricmp( tempname + strlen( tempname ) - 2, ".Z" ) == 0 ) {
fprintf( stderr, "%s: already has .Z suffix -- no change\n",
tempname);
return;
}
if( insbuf.st_nlink > 1 && (!force) ) {
fprintf( stderr, "%s has %d other links: unchanged\n",
tempname, insbuf.st_nlink - 1 );
return;
}
/* Open input file */
if( freopen( tempname, "rb", stdin ) == NULL ) {
perror( tempname );
return;
}
fsize = (long)insbuf.st_size;
/*
* tune hash table size for small files -- ad hoc,
* but the sizes match earlier #defines, which
* serve as upper bounds on the number of output codes.
*/
hsize = HSIZE;
if( fsize < (1 << 12) )
hsize = min( 5003, HSIZE );
else if( fsize < (1 << 13) )
hsize = min( 9001, HSIZE );
else if( fsize < (1 << 14) )
hsize = min( 18013, HSIZE );
else if( fsize < (1 << 15) )
hsize = min( 35023, HSIZE );
else if( fsize < 47000 )
hsize = min( 50021, HSIZE );
/* we have to ignore SIGINT for a while, otherwise
* a ^C can nuke an existing file with ofname
*/
signal( SIGINT, SIG_IGN );
/* Generate output filename */
strcpy( ofname, tempname );
#ifdef SHORTNAMES /* Short filenames */
if( (cp = strrchr( ofname, DIR_SEP_CHAR ) ) != NULL )
cp++;
else
cp = ofname;
if( strlen( cp ) > 12 ) {
fprintf( stderr, "%s: filename too long to tack on .Z\n", ofname );
signal( SIGINT, onintr );
return;
}
#endif /* SHORTNAMES */
strcat( ofname, ".Z" );
}
/* Check for overwrite of existing file */
if( overwrite == 0 && zcat_flg == 0 ) {
if( stat( ofname, &statbuf ) == 0 ) {
char response[2];
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' ) {
if( read( 2, response + 1, 1 ) < 0 ) { /* Ack! */
perror( "stderr" );
break;
}
}
}
if( response[0] != 'y' ) {
fprintf( stderr, "\tnot overwritten\n" );
signal( SIGINT, onintr );
return;
}
}
}
signal( SIGINT, onintr );
if( zcat_flg == 0 ) { /* Open output file */
valid = 1;
if( freopen( ofname, "wb", stdout ) == NULL ) {
perror( ofname );
return;
}
if( !quiet )
fprintf( stderr, "%s: ", tempname );
} else {
setmode( fileno( stdout ), O_BINARY );
}
setvbuf( stdout, NULL, _IOFBF, IO_BUF_SIZE );
/* Actually do the compression/decompression */
if( do_decomp == 0 )
compress();
else
decompress();
if( zcat_flg == 0 ) {
copystat( tempname, ofname ); /* Copy stats */
if( (exit_stat == 1) || (!quiet) )
putc( '\n', stderr );
}
break;
default:
fprintf( stderr,"%s is not a directory or a regular file - ignored\n",
tempname );
break;
}
}
static int is_this( char *pathname, const char *name )
/****************************************************/
{
const char *base = basename( pathname );
#ifdef __UNIX__
return( !strcmp( base, name ) );
#else
return( !strnicmp( base, name, strlen( name ) ) );
#endif
}
int main( int argc, char **argv )
/*******************************/
{
int ch;
if( (bgnd_flag = signal( SIGINT, SIG_IGN )) != SIG_IGN ) {
signal( SIGINT, onintr );
}
signal( SIGSEGV, oops );
if( is_this( argv[0], "uncompress" ) ) {
do_decomp = 1;
} else if( is_this( argv[0], "zcat" ) ) {
do_decomp = 1;
zcat_flg = 1;
}
while( (ch = getopt( argc, argv, ":b:cdfv" )) != -1 ) {
switch( ch ) {
case 'b':
maxbits = atoi( optarg );
break;
case 'c':
zcat_flg = 1;
break;
case 'C':
block_compress = 0;
break;
case 'd':
do_decomp = 1;
break;
case 'f':
overwrite = 1;
force = 1;
break;
case 'n':
nomagic = 1;
break;
case 'v':
quiet = 0;
break;
case 'q':
quiet = 1;
break;
case ':':
util_quit( usage_text, "missing maxbits\n" );
case '?':
util_quit( usage_text, NULL );
}
}
/* Skip option arguments and argv[0] */
argc = argc - optind;
argv += optind;
if( maxbits < INIT_BITS )
maxbits = INIT_BITS;
if( maxbits > BITS )
maxbits = BITS;
maxmaxcode = 1 << maxbits;
if( *argv != NULL ) {
for( ; *argv; ++argv ) {
compress_file( argv );
}
} else { /* Standard input */
setmode( fileno( stdin ), O_BINARY );
setmode( fileno( stdout ), O_BINARY );
setvbuf( stdin, NULL, _IOFBF, IO_BUF_SIZE );
setvbuf( stdout, NULL, _IOFBF, IO_BUF_SIZE );
if( do_decomp == 0 ) {
compress();
if( !quiet )
putc( '\n', stderr );
} else {
/* Check the magic number */
if( nomagic == 0 ) {
if( (getchar() != (magic_header[0] & 0xFF))
|| (getchar() != (magic_header[1] & 0xFF)) ) {
fprintf( stderr, "stdin: not in compressed format\n" );
return( 1 );
}
maxbits = getchar(); /* set -b from file */
block_compress = maxbits & BLOCK_MASK;
maxbits &= BIT_MASK;
maxmaxcode = 1 << maxbits;
fsize = 100000; /* assume stdin large for USERMEM */
if( maxbits > BITS ) {
fprintf( stderr,
"stdin: compressed with %d bits, can only handle %d bits\n",
maxbits, BITS );
return( 1 );
}
}
decompress();
}
}
return( exit_stat );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?