summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gzip.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/gzip.c b/src/gzip.c
new file mode 100644
index 0000000..11828db
--- /dev/null
+++ b/src/gzip.c
@@ -0,0 +1,125 @@
1// Standard C
2#include <errno.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6
7// System
8#include <unistd.h>
9
10// zlib
11#include <zlib.h>
12
13enum { BUFFER_SIZE = 8192 };
14
15static void
16usage(void)
17{
18 (void) fprintf(stderr, "stream [-d] infile outfile\n");
19}
20
21static void
22error(const char *msg)
23{
24 perror(msg);
25 exit(EXIT_FAILURE);
26}
27
28void
29do_compress(const char *in_name, const char *out_name, int compress_level)
30{
31 FILE *in_file = fopen(in_name, "rb");
32 if ( in_file == NULL ) {
33 error("fopen() on in_file failed");
34 }
35
36 char mode[10];
37 (void) snprintf(mode, sizeof mode, "wb%d", compress_level);
38
39 gzFile out_file = gzopen(out_name, mode);
40 if ( out_file == NULL ) {
41 (void) fclose(in_file);
42 error("gzopen() on out_file failed");
43 }
44
45 unsigned char buffer[BUFFER_SIZE];
46
47 size_t bytes_read = 0;
48 while ( (bytes_read = fread(buffer, 1, BUFFER_SIZE, in_file)) != 0 ) {
49 gzfwrite(buffer, 1, bytes_read, out_file);
50 }
51
52 (void) fclose(in_file);
53 gzclose(out_file);
54}
55
56void
57do_uncompress(const char *in_name, const char *out_name)
58{
59 gzFile in_file = gzopen(in_name, "rb");
60 if ( in_file == NULL ) {
61 error("gzopen() on in_file failed");
62 }
63
64 FILE *out_file = fopen(out_name, "wb");
65 if ( out_file == NULL ) {
66 (void) gzclose(in_file);
67 error("fopen() on out_file failed");
68 }
69
70 unsigned char buffer[BUFFER_SIZE];
71
72 size_t bytes_read = 0;
73 while ( (bytes_read = gzfread(buffer, 1, BUFFER_SIZE, in_file)) != 0 ) {
74 (void) fwrite(buffer, 1, bytes_read, out_file);
75 }
76
77 gzclose(in_file);
78 (void) fclose(out_file);
79}
80
81int
82main(int argc, char *argv[])
83{
84 enum {
85 COMPRESSION_STD = 5,
86 COMPRESSION_BEST = 9
87 };
88
89 int decompress = 0;
90 int compress_level = COMPRESSION_STD;
91
92 int opt = 0;
93 while ( (opt = getopt(argc, argv, "dl")) != -1 ) {
94 switch ( opt ) {
95 case 'd':
96 decompress = 1;
97 break;
98
99 case 'l':
100 compress_level = COMPRESSION_BEST;
101 break;
102
103 case '?':
104 default:
105 usage();
106 return EXIT_SUCCESS;
107 }
108 }
109 argc -= optind;
110 argv += optind;
111
112 if ( argc != 2 ) {
113 usage();
114 return EXIT_FAILURE;
115 }
116
117 if ( !decompress ) {
118 do_compress(argv[0], argv[1], compress_level);
119 }
120 else {
121 do_uncompress(argv[0], argv[1]);
122 }
123
124 return EXIT_SUCCESS;
125}