]> andersk Git - openssh.git/blob - compress.c
- OpenBSD CVS updates:
[openssh.git] / compress.c
1 /*
2  * 
3  * compress.c
4  * 
5  * Author: Tatu Ylonen <ylo@cs.hut.fi>
6  * 
7  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8  *                    All rights reserved
9  * 
10  * Created: Wed Oct 25 22:12:46 1995 ylo
11  * 
12  * Interface to packet compression for ssh.
13  * 
14  */
15
16 #include "includes.h"
17 RCSID("$Id$");
18
19 #include "ssh.h"
20 #include "buffer.h"
21 #include "zlib.h"
22
23 static z_stream incoming_stream;
24 static z_stream outgoing_stream;
25
26 /*
27  * Initializes compression; level is compression level from 1 to 9
28  * (as in gzip).
29  */
30
31 void 
32 buffer_compress_init(int level)
33 {
34         debug("Enabling compression at level %d.", level);
35         if (level < 1 || level > 9)
36                 fatal("Bad compression level %d.", level);
37         inflateInit(&incoming_stream);
38         deflateInit(&outgoing_stream, level);
39 }
40
41 /* Frees any data structures allocated for compression. */
42
43 void 
44 buffer_compress_uninit()
45 {
46         debug("compress outgoing: raw data %lu, compressed %lu, factor %.2f",
47               outgoing_stream.total_in, outgoing_stream.total_out,
48               outgoing_stream.total_in == 0 ? 0.0 :
49               (double) outgoing_stream.total_out / outgoing_stream.total_in);
50         debug("compress incoming: raw data %lu, compressed %lu, factor %.2f",
51               incoming_stream.total_out, incoming_stream.total_in,
52               incoming_stream.total_out == 0 ? 0.0 :
53               (double) incoming_stream.total_in / incoming_stream.total_out);
54         inflateEnd(&incoming_stream);
55         deflateEnd(&outgoing_stream);
56 }
57
58 /*
59  * Compresses the contents of input_buffer into output_buffer.  All packets
60  * compressed using this function will form a single compressed data stream;
61  * however, data will be flushed at the end of every call so that each
62  * output_buffer can be decompressed independently (but in the appropriate
63  * order since they together form a single compression stream) by the
64  * receiver.  This appends the compressed data to the output buffer.
65  */
66
67 void 
68 buffer_compress(Buffer * input_buffer, Buffer * output_buffer)
69 {
70         char buf[4096];
71         int status;
72
73         /* This case is not handled below. */
74         if (buffer_len(input_buffer) == 0)
75                 return;
76
77         /* Input is the contents of the input buffer. */
78         outgoing_stream.next_in = (unsigned char *) buffer_ptr(input_buffer);
79         outgoing_stream.avail_in = buffer_len(input_buffer);
80
81         /* Loop compressing until deflate() returns with avail_out != 0. */
82         do {
83                 /* Set up fixed-size output buffer. */
84                 outgoing_stream.next_out = (unsigned char *)buf;
85                 outgoing_stream.avail_out = sizeof(buf);
86
87                 /* Compress as much data into the buffer as possible. */
88                 status = deflate(&outgoing_stream, Z_PARTIAL_FLUSH);
89                 switch (status) {
90                 case Z_OK:
91                         /* Append compressed data to output_buffer. */
92                         buffer_append(output_buffer, buf,
93                                       sizeof(buf) - outgoing_stream.avail_out);
94                         break;
95                 case Z_STREAM_END:
96                         fatal("buffer_compress: deflate returned Z_STREAM_END");
97                         /* NOTREACHED */
98                 case Z_STREAM_ERROR:
99                         fatal("buffer_compress: deflate returned Z_STREAM_ERROR");
100                         /* NOTREACHED */
101                 case Z_BUF_ERROR:
102                         fatal("buffer_compress: deflate returned Z_BUF_ERROR");
103                         /* NOTREACHED */
104                 default:
105                         fatal("buffer_compress: deflate returned %d", status);
106                         /* NOTREACHED */
107                 }
108         }
109         while (outgoing_stream.avail_out == 0);
110 }
111
112 /*
113  * Uncompresses the contents of input_buffer into output_buffer.  All packets
114  * uncompressed using this function will form a single compressed data
115  * stream; however, data will be flushed at the end of every call so that
116  * each output_buffer.  This must be called for the same size units that the
117  * buffer_compress was called, and in the same order that buffers compressed
118  * with that.  This appends the uncompressed data to the output buffer.
119  */
120
121 void 
122 buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer)
123 {
124         char buf[4096];
125         int status;
126
127         incoming_stream.next_in = (unsigned char *) buffer_ptr(input_buffer);
128         incoming_stream.avail_in = buffer_len(input_buffer);
129
130         incoming_stream.next_out = (unsigned char *) buf;
131         incoming_stream.avail_out = sizeof(buf);
132
133         for (;;) {
134                 status = inflate(&incoming_stream, Z_PARTIAL_FLUSH);
135                 switch (status) {
136                 case Z_OK:
137                         buffer_append(output_buffer, buf,
138                                       sizeof(buf) - incoming_stream.avail_out);
139                         incoming_stream.next_out = (unsigned char *) buf;
140                         incoming_stream.avail_out = sizeof(buf);
141                         break;
142                 case Z_STREAM_END:
143                         fatal("buffer_uncompress: inflate returned Z_STREAM_END");
144                         /* NOTREACHED */
145                 case Z_DATA_ERROR:
146                         fatal("buffer_uncompress: inflate returned Z_DATA_ERROR");
147                         /* NOTREACHED */
148                 case Z_STREAM_ERROR:
149                         fatal("buffer_uncompress: inflate returned Z_STREAM_ERROR");
150                         /* NOTREACHED */
151                 case Z_BUF_ERROR:
152                         /*
153                          * Comments in zlib.h say that we should keep calling
154                          * inflate() until we get an error.  This appears to
155                          * be the error that we get.
156                          */
157                         return;
158                 case Z_MEM_ERROR:
159                         fatal("buffer_uncompress: inflate returned Z_MEM_ERROR");
160                         /* NOTREACHED */
161                 default:
162                         fatal("buffer_uncompress: inflate returned %d", status);
163                 }
164         }
165 }
This page took 0.066625 seconds and 5 git commands to generate.