GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/swissknife_zpipe.cc Lines: 0 84 0.0 %
Date: 2019-02-03 02:48:13 Branches: 0 61 0.0 %

Line Branch Exec Source
1
/**
2
 * This file is part of the CernVM File System.
3
 *
4
 * Slightly adapted zpipe.c for the use within the CernVM File System
5
 */
6
7
/* zpipe.c: example of proper use of zlib's inflate() and deflate()
8
   Not copyrighted -- provided to the public domain
9
   Version 1.4  11 December 2005  Mark Adler */
10
11
/* Version history:
12
   1.0  30 Oct 2004  First version
13
   1.1   8 Nov 2004  Add void casting for unused return values
14
                     Use switch statement for inflate() return values
15
   1.2   9 Nov 2004  Add assertions to document zlib guarantees
16
   1.3   6 Apr 2005  Remove incorrect assertion in inf()
17
   1.4  11 Dec 2005  Add hack to avoid MSDOS end-of-line conversions
18
                     Avoid some compiler warnings for input and output buffers
19
 */
20
21
#include <stdio.h>
22
23
#include <cassert>
24
#include <cstring>
25
26
#include "duplex_zlib.h"
27
#include "swissknife_zpipe.h"
28
29
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
30
#  include <fcntl.h>
31
#  include <io.h>
32
#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
33
#else
34
#  define SET_BINARY_MODE(file)
35
#endif
36
37
#define CHUNK 16384
38
39
/* Compress from file source to file dest until EOF on source.
40
   def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
41
   allocated for processing, Z_STREAM_ERROR if an invalid compression
42
   level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
43
   version of the library linked do not match, or Z_ERRNO if there is
44
   an error reading or writing the files. */
45
int def(FILE *source, FILE *dest, int level)
46
{
47
    int ret, flush;
48
    unsigned have;
49
    z_stream strm;
50
    unsigned char in[CHUNK];
51
    unsigned char out[CHUNK];
52
53
    /* allocate deflate state */
54
    strm.zalloc = Z_NULL;
55
    strm.zfree = Z_NULL;
56
    strm.opaque = Z_NULL;
57
    ret = deflateInit(&strm, level);
58
    if (ret != Z_OK)
59
        return ret;
60
61
    /* compress until end of file */
62
    do {
63
        strm.avail_in = fread(in, 1, CHUNK, source);
64
        if (ferror(source)) {
65
            (void)deflateEnd(&strm);
66
            return Z_ERRNO;
67
        }
68
        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
69
        strm.next_in = in;
70
71
        /* run deflate() on input until output buffer not full, finish
72
           compression if all of source has been read in */
73
        do {
74
            strm.avail_out = CHUNK;
75
            strm.next_out = out;
76
            ret = deflate(&strm, flush);    /* no bad return value */
77
            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
78
            have = CHUNK - strm.avail_out;
79
            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
80
                (void)deflateEnd(&strm);
81
                return Z_ERRNO;
82
            }
83
        } while (strm.avail_out == 0);
84
        assert(strm.avail_in == 0);     /* all input will be used */
85
86
        /* done when last data in file processed */
87
    } while (flush != Z_FINISH);
88
    assert(ret == Z_STREAM_END);        /* stream will be complete */
89
90
    /* clean up and return */
91
    (void)deflateEnd(&strm);
92
    return Z_OK;
93
}
94
95
/* Decompress from file source to file dest until stream ends or EOF.
96
   inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
97
   allocated for processing, Z_DATA_ERROR if the deflate data is
98
   invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
99
   the version of the library linked do not match, or Z_ERRNO if there
100
   is an error reading or writing the files. */
101
int inf(FILE *source, FILE *dest)
102
{
103
    int ret;
104
    unsigned have;
105
    z_stream strm;
106
    unsigned char in[CHUNK];
107
    unsigned char out[CHUNK];
108
109
    /* allocate inflate state */
110
    strm.zalloc = Z_NULL;
111
    strm.zfree = Z_NULL;
112
    strm.opaque = Z_NULL;
113
    strm.avail_in = 0;
114
    strm.next_in = Z_NULL;
115
    ret = inflateInit(&strm);
116
    if (ret != Z_OK)
117
        return ret;
118
119
    /* decompress until deflate stream ends or end of file */
120
    do {
121
        strm.avail_in = fread(in, 1, CHUNK, source);
122
        if (ferror(source)) {
123
            (void)inflateEnd(&strm);
124
            return Z_ERRNO;
125
        }
126
        if (strm.avail_in == 0)
127
            break;
128
        strm.next_in = in;
129
130
        /* run inflate() on input until output buffer not full */
131
        do {
132
            strm.avail_out = CHUNK;
133
            strm.next_out = out;
134
            ret = inflate(&strm, Z_NO_FLUSH);
135
            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
136
            switch (ret) {
137
            case Z_NEED_DICT:
138
                ret = Z_DATA_ERROR;     /* and fall through */
139
            case Z_DATA_ERROR:
140
            case Z_MEM_ERROR:
141
                (void)inflateEnd(&strm);
142
                return ret;
143
            }
144
            have = CHUNK - strm.avail_out;
145
            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
146
                (void)inflateEnd(&strm);
147
                return Z_ERRNO;
148
            }
149
        } while (strm.avail_out == 0);
150
151
        /* done when inflate() says it's done */
152
    } while (ret != Z_STREAM_END);
153
154
    /* clean up and return */
155
    (void)inflateEnd(&strm);
156
    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
157
}
158
159
/* report a zlib or i/o error */
160
void zerr(int ret)
161
{
162
    fputs("zpipe: ", stderr);
163
    switch (ret) {
164
    case Z_ERRNO:
165
        if (ferror(stdin))
166
            fputs("error reading stdin\n", stderr);
167
        if (ferror(stdout))
168
            fputs("error writing stdout\n", stderr);
169
        break;
170
    case Z_STREAM_ERROR:
171
        fputs("invalid compression level\n", stderr);
172
        break;
173
    case Z_DATA_ERROR:
174
        fputs("invalid or incomplete deflate data\n", stderr);
175
        break;
176
    case Z_MEM_ERROR:
177
        fputs("out of memory\n", stderr);
178
        break;
179
    case Z_VERSION_ERROR:
180
        fputs("zlib version mismatch!\n", stderr);
181
    }
182
}
183
184
/* compress or decompress from stdin to stdout */
185
int swissknife::CommandZpipe::Main(const swissknife::ArgumentList &args) {
186
    int ret;
187
188
    /* avoid end-of-line conversions */
189
    SET_BINARY_MODE(stdin);
190
    SET_BINARY_MODE(stdout);
191
192
    /* do compression if no arguments */
193
    if (args.find('d') == args.end()) {
194
        ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
195
        if (ret != Z_OK)
196
            zerr(ret);
197
        return ret;
198
    } else {
199
      /* do decompression if -d specified */
200
      ret = inf(stdin, stdout);
201
      if (ret != Z_OK)
202
        zerr(ret);
203
      return ret;
204
    }
205
}