summaryrefslogtreecommitdiffstats
path: root/libssh/gzip.c
diff options
context:
space:
mode:
Diffstat (limited to 'libssh/gzip.c')
-rw-r--r--libssh/gzip.c250
1 files changed, 162 insertions, 88 deletions
diff --git a/libssh/gzip.c b/libssh/gzip.c
index a5edb44..7394012 100644
--- a/libssh/gzip.c
+++ b/libssh/gzip.c
@@ -4,6 +4,7 @@
* This file is part of the SSH Library
*
* Copyright (c) 2003 by Aris Adamantiadis
+ * Copyright (c) 2009 by Andreas Schneider <mail@cynapses.org>
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -34,110 +35,183 @@
#define BLOCKSIZE 4092
-static z_stream *initcompress(SSH_SESSION *session,int level){
- z_stream *stream=malloc(sizeof(z_stream));
- int status;
- memset(stream,0,sizeof(z_stream));
- status=deflateInit(stream,level);
- if (status!=0)
- ssh_set_error(session,SSH_FATAL,"status %d inititalising zlib deflate",status);
- return stream;
+static z_stream *initcompress(SSH_SESSION *session, int level) {
+ z_stream *stream = NULL;
+ int status;
+
+ stream = malloc(sizeof(z_stream));
+ if (stream == NULL) {
+ return NULL;
+ }
+ memset(stream, 0, sizeof(z_stream));
+
+ status = deflateInit(stream, level);
+ if (status != Z_OK) {
+ SAFE_FREE(stream);
+ ssh_set_error(session, SSH_FATAL,
+ "status %d inititalising zlib deflate", status);
+ return NULL;
+ }
+
+ return stream;
}
static BUFFER *gzip_compress(SSH_SESSION *session,BUFFER *source,int level){
- BUFFER *dest;
- static unsigned char out_buf[BLOCKSIZE];
- void *in_ptr=buffer_get(source);
- unsigned long in_size=buffer_get_len(source);
- unsigned long len;
- int status;
- z_stream *zout=session->current_crypto->compress_out_ctx;
- if(!zout)
- zout=session->current_crypto->compress_out_ctx=initcompress(session,level);
- dest=buffer_new();
- zout->next_out=out_buf;
- zout->next_in=in_ptr;
- zout->avail_in=in_size;
- do {
- zout->avail_out=BLOCKSIZE;
- status=deflate(zout,Z_PARTIAL_FLUSH);
- if(status !=0){
- ssh_set_error(session,SSH_FATAL,"status %d deflating zlib packet",status);
- return NULL;
- }
- len=BLOCKSIZE-zout->avail_out;
- buffer_add_data(dest,out_buf,len);
- zout->next_out=out_buf;
- } while (zout->avail_out == 0);
-
- return dest;
+ z_stream *zout = session->current_crypto->compress_out_ctx;
+ void *in_ptr = buffer_get(source);
+ unsigned long in_size = buffer_get_len(source);
+ BUFFER *dest = NULL;
+ static unsigned char out_buf[BLOCKSIZE] = {0};
+ unsigned long len;
+ int status;
+
+ if(zout == NULL) {
+ zout = session->current_crypto->compress_out_ctx = initcompress(session, level);
+ if (zout == NULL) {
+ return NULL;
+ }
+ }
+
+ dest = buffer_new();
+ if (dest == NULL) {
+ return NULL;
+ }
+
+ zout->next_out = out_buf;
+ zout->next_in = in_ptr;
+ zout->avail_in = in_size;
+ do {
+ zout->avail_out = BLOCKSIZE;
+ status = deflate(zout, Z_PARTIAL_FLUSH);
+ if (status != Z_OK) {
+ buffer_free(dest);
+ ssh_set_error(session, SSH_FATAL,
+ "status %d deflating zlib packet", status);
+ return NULL;
+ }
+ len = BLOCKSIZE - zout->avail_out;
+ if (buffer_add_data(dest, out_buf, len) < 0) {
+ buffer_free(dest);
+ return NULL;
+ }
+ zout->next_out = out_buf;
+ } while (zout->avail_out == 0);
+
+ return dest;
}
-int compress_buffer(SSH_SESSION *session,BUFFER *buf){
- BUFFER *dest=gzip_compress(session,buf,9);
- if(!dest)
- return -1;
- buffer_reinit(buf);
- buffer_add_data(buf,buffer_get(dest),buffer_get_len(dest));
+int compress_buffer(SSH_SESSION *session, BUFFER *buf) {
+ BUFFER *dest = NULL;
+
+ dest = gzip_compress(session, buf, 9);
+ if (dest == NULL) {
+ return -1;
+ }
+
+ if (buffer_reinit(buf) < 0) {
+ buffer_free(dest);
+ return -1;
+ }
+
+ if (buffer_add_data(buf, buffer_get(dest), buffer_get_len(dest)) < 0) {
buffer_free(dest);
- return 0;
+ return -1;
+ }
+
+ buffer_free(dest);
+ return 0;
}
/* decompression */
-static z_stream *initdecompress(SSH_SESSION *session){
- z_stream *stream=malloc(sizeof(z_stream));
- int status;
- memset(stream,0,sizeof(z_stream));
- status=inflateInit(stream);
- if (status!=0){
- ssh_set_error(session,SSH_FATAL,"Status = %d initiating inflate context !",status);
- free(stream);
- stream=NULL;
- }
- return stream;
+static z_stream *initdecompress(SSH_SESSION *session) {
+ z_stream *stream = NULL;
+ int status;
+
+ stream = malloc(sizeof(z_stream));
+ if (stream == NULL) {
+ return NULL;
+ }
+ memset(stream,0,sizeof(z_stream));
+
+ status = inflateInit(stream);
+ if (status != Z_OK) {
+ SAFE_FREE(stream);
+ ssh_set_error(session, SSH_FATAL,
+ "Status = %d initiating inflate context!", status);
+ return NULL;
+ }
+
+ return stream;
}
-static BUFFER *gzip_decompress(SSH_SESSION *session,BUFFER *source){
- BUFFER *dest;
- static unsigned char out_buf[BLOCKSIZE];
- void *in_ptr=buffer_get_rest(source);
- unsigned long in_size=buffer_get_rest_len(source);
- unsigned long len;
- int status;
- z_stream *zin=session->current_crypto->compress_in_ctx;
- if(!zin)
- zin=session->current_crypto->compress_in_ctx=initdecompress(session);
- dest=buffer_new();
- zin->next_out=out_buf;
- zin->next_in=in_ptr;
- zin->avail_in=in_size;
- do {
- zin->avail_out=BLOCKSIZE;
- status=inflate(zin,Z_PARTIAL_FLUSH);
- if(status !=Z_OK){
- ssh_set_error(session,SSH_FATAL,"status %d inflating zlib packet",status);
- buffer_free(dest);
- return NULL;
- }
- len=BLOCKSIZE-zin->avail_out;
- buffer_add_data(dest,out_buf,len);
- zin->next_out=out_buf;
- } while (zin->avail_out == 0);
-
- return dest;
+static BUFFER *gzip_decompress(SSH_SESSION *session, BUFFER *source) {
+ z_stream *zin = session->current_crypto->compress_in_ctx;
+ void *in_ptr = buffer_get_rest(source);
+ unsigned long in_size = buffer_get_rest_len(source);
+ static unsigned char out_buf[BLOCKSIZE] = {0};
+ BUFFER *dest = NULL;
+ unsigned long len;
+ int status;
+
+ if (zin == NULL) {
+ zin = session->current_crypto->compress_in_ctx = initdecompress(session);
+ if (zin == NULL) {
+ return NULL;
+ }
+ }
+
+ dest = buffer_new();
+ if (dest == NULL) {
+ return NULL;
+ }
+
+ zin->next_out = out_buf;
+ zin->next_in = in_ptr;
+ zin->avail_in = in_size;
+
+ do {
+ zin->avail_out = BLOCKSIZE;
+ status = inflate(zin, Z_PARTIAL_FLUSH);
+ if (status != Z_OK) {
+ ssh_set_error(session, SSH_FATAL,
+ "status %d inflating zlib packet", status);
+ buffer_free(dest);
+ return NULL;
+ }
+
+ len = BLOCKSIZE - zin->avail_out;
+ if (buffer_add_data(dest,out_buf,len) < 0) {
+ buffer_free(dest);
+ return NULL;
+ }
+
+ zin->next_out = out_buf;
+ } while (zin->avail_out == 0);
+
+ return dest;
}
int decompress_buffer(SSH_SESSION *session,BUFFER *buf){
- BUFFER *dest=gzip_decompress(session,buf);
- buffer_reinit(buf);
- if(!dest){
- return -1; /* failed */
- }
- buffer_reinit(buf);
- buffer_add_data(buf,buffer_get(dest),buffer_get_len(dest));
+ BUFFER *dest = NULL;
+
+ dest = gzip_decompress(session,buf);
+ if (dest == NULL) {
+ return -1;
+ }
+
+ if (buffer_reinit(buf) < 0) {
+ buffer_free(dest);
+ return -1;
+ }
+
+ if (buffer_add_data(buf, buffer_get(dest), buffer_get_len(dest)) < 0) {
buffer_free(dest);
- return 0;
+ return -1;
+ }
+
+ buffer_free(dest);
+ return 0;
}
#endif /* HAVE_LIBZ && WITH_LIBZ */