// Standard C #include #include #include #include // System #include // zlib #include enum { BUFFER_SIZE = 8192 }; static void usage(void) { (void) fprintf(stderr, "stream [-d] infile outfile\n"); } static void error(const char *msg) { perror(msg); exit(EXIT_FAILURE); } void do_compress(const char *in_name, const char *out_name, int compress_level) { FILE *in_file = fopen(in_name, "rb"); if ( in_file == NULL ) { error("fopen() on in_file failed"); } char mode[10]; (void) snprintf(mode, sizeof mode, "wb%d", compress_level); gzFile out_file = gzopen(out_name, mode); if ( out_file == NULL ) { (void) fclose(in_file); error("gzopen() on out_file failed"); } unsigned char buffer[BUFFER_SIZE]; size_t bytes_read = 0; while ( (bytes_read = fread(buffer, 1, BUFFER_SIZE, in_file)) != 0 ) { gzfwrite(buffer, 1, bytes_read, out_file); } (void) fclose(in_file); gzclose(out_file); } void do_uncompress(const char *in_name, const char *out_name) { gzFile in_file = gzopen(in_name, "rb"); if ( in_file == NULL ) { error("gzopen() on in_file failed"); } FILE *out_file = fopen(out_name, "wb"); if ( out_file == NULL ) { (void) gzclose(in_file); error("fopen() on out_file failed"); } unsigned char buffer[BUFFER_SIZE]; size_t bytes_read = 0; while ( (bytes_read = gzfread(buffer, 1, BUFFER_SIZE, in_file)) != 0 ) { (void) fwrite(buffer, 1, bytes_read, out_file); } gzclose(in_file); (void) fclose(out_file); } int main(int argc, char *argv[]) { enum { COMPRESSION_STD = 5, COMPRESSION_BEST = 9 }; int decompress = 0; int compress_level = COMPRESSION_STD; int opt = 0; while ( (opt = getopt(argc, argv, "dl")) != -1 ) { switch ( opt ) { case 'd': decompress = 1; break; case 'l': compress_level = COMPRESSION_BEST; break; case '?': default: usage(); return EXIT_SUCCESS; } } argc -= optind; argv += optind; if ( argc != 2 ) { usage(); return EXIT_FAILURE; } if ( !decompress ) { do_compress(argv[0], argv[1], compress_level); } else { do_uncompress(argv[0], argv[1]); } return EXIT_SUCCESS; }