From afc83af9b5e7ad6b288cf6d93b8da5c6a8628e95 Mon Sep 17 00:00:00 2001 From: Lassi Marttala Date: Tue, 13 Mar 2012 15:54:36 +0100 Subject: GDLT-2 zlib based compression. Signed-off-by: Christian Muck --- src/system/dlt-system-log.c | 106 ++++++++++++++++++++++++++++++++++++++++++++ src/system/dlt-system.c | 12 +++++ src/system/dlt-system.conf | 4 ++ src/system/dlt-system.h | 2 + 4 files changed, 124 insertions(+) diff --git a/src/system/dlt-system-log.c b/src/system/dlt-system-log.c index c9dada4..781171e 100644 --- a/src/system/dlt-system-log.c +++ b/src/system/dlt-system-log.c @@ -62,6 +62,7 @@ #include #include #include +#include #include "dlt_common.h" #include "dlt_user.h" @@ -71,6 +72,102 @@ #include "dlt-system_cfg.h" #include "dlt-system-log.h" +/* Size of the zlib deflate buffer */ +#define Z_CHUNK_SZ 1024*128 + +/* File compression routine. + * Side effects: + * - modifies src to point to the compressed file. + * - removes the original file + */ +int dlt_system_compress_file(char *src, int level) +{ + /* Local variables */ + unsigned char buf_in[Z_CHUNK_SZ]; + unsigned char buf_out[Z_CHUNK_SZ]; + int start_flush; + z_stream strm; + int comp_count; + + /* Prepare file names */ + char *dst = malloc(strlen(src)+3); + sprintf(dst, "%s.z", src); + + /* Prepare zlib */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + int err = deflateInit(&strm, level); + if(err != Z_OK) + { + fprintf(stderr, "dlt_system_compress_file: deflateInit failed with error %d.\n", err); + return err; + } + + /* Open input and output */ + FILE *f_in = fopen(src, "r"); + FILE *f_out = fopen(dst, "w"); + + while(start_flush != Z_FINISH) + { + /* read data to buffer */ + strm.avail_in = fread(buf_in, 1, Z_CHUNK_SZ, f_in); + strm.next_in = buf_in; + + /* Check if we have read everything */ + start_flush = feof(f_in) ? Z_FINISH : Z_NO_FLUSH; + + if (ferror(f_in)) + { + fprintf(stderr, "dlt_system_compress_file: Error while reading file."); + fclose(f_in); + fclose(f_out); + deflateEnd(&strm); + return Z_ERRNO; + } + + while(strm.avail_out == 0) + { + /* Prepare stream for compression */ + strm.avail_out = Z_CHUNK_SZ; + strm.next_out = buf_out; + + /* Compress a chunk of data */ + if(deflate(&strm, start_flush) == Z_STREAM_ERROR) + { + fclose(f_in); + fclose(f_out); + deflateEnd(&strm); + return Z_STREAM_ERROR; + } + + /* Write to the output file */ + comp_count = Z_CHUNK_SZ - strm.avail_out; + if (fwrite(buf_out, 1, comp_count, f_out) != comp_count || + ferror(dest)) + { + fprintf(stderr, "dlt_system_compress_file: Error while writing file."); + fclose(f_in); + fclose(f_out); + deflateEnd(&strm); + return Z_ERRNO; + } + } + } + + /* Close streams and clean the zlib state machine */ + fclose(f_in); + fclose(f_out); + deflateEnd(&strm); + + /* Remove the source file */ + unlink(src); + + /* Modify the parameter file name to point to the new file */ + strcpy(src, dst); + return 0; +} + void dlt_system_filetransfer_init(DltSystemOptions *options,DltSystemRuntime *runtime) { runtime->filetransferFile[0] = 0; @@ -144,6 +241,15 @@ void dlt_system_filetransfer_run(DltSystemOptions *options,DltSystemRuntime *run /* start filetransfer if file exists */ if(runtime->filetransferFile[0]) { + /* Compress the file if required */ + if(options->FiletransferCompression > 0) + { + printf("Start compression: %s\n",runtime->filetransferFile); + if(dlt_system_compress_file(runtime->filetransferFile, options->FiletransferCompressionLevel) < 0) + { + return; + } + } printf("Start Filetransfer: %s\n",runtime->filetransferFile); runtime->filetransferCountPackages = dlt_user_log_file_packagesCount(context,runtime->filetransferFile); if(runtime->filetransferCountPackages < 0 ) diff --git a/src/system/dlt-system.c b/src/system/dlt-system.c index e8dd7c5..1d68ecd 100755 --- a/src/system/dlt-system.c +++ b/src/system/dlt-system.c @@ -108,6 +108,8 @@ void dlt_system_init_options(DltSystemOptions *options) /* Filetransfer */ options->FiletransferEnable = 0; + options->FiletransferCompression = 0; + options->FiletransferCompressionLevel = 5; strncpy(options->FiletransferContextId,DEFAULT_FILETRANSFER_CONTEXT_ID,sizeof(options->FiletransferContextId)); strncpy(options->FiletransferDirectory1,DEFAULT_FILETRANSFER_DIRECTORY,sizeof(options->FiletransferDirectory1)); options->FiletransferDirectory2[0]=0; @@ -253,6 +255,16 @@ int dlt_system_parse_configuration(DltSystemOptions *options) options->FiletransferEnable = atoi(value); printf("Option: %s=%s\n",token,value); } + else if(strcmp(token,"FiletransferCompression")==0) + { + options->FiletransferCompression = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"FiletransferCompressionLevel")==0) + { + options->FiletransferCompression = atoi(value); + printf("Option: %s=%s\n",token,value); + } else if(strcmp(token,"FiletransferDirectory1")==0) { strncpy(options->FiletransferDirectory1,value,sizeof(options->FiletransferDirectory1)); diff --git a/src/system/dlt-system.conf b/src/system/dlt-system.conf index 426d3ef..779894d 100644 --- a/src/system/dlt-system.conf +++ b/src/system/dlt-system.conf @@ -28,6 +28,10 @@ SyslogPort = 47111 # Enable the Filetransfer (Default: 0) FiletransferEnable = 0 +# Enable the file transfer compression with zlib +FiletransferCompression = 0 +FiletransferCompressionLevel = 5 + # Directory which contains files to be transfered over DLT (Default: /tmp/filetransfer) # Files are deleted after Filetransfer is finished and after TimeDelay expired FiletransferDirectory1 = /tmp/filetransfer diff --git a/src/system/dlt-system.h b/src/system/dlt-system.h index 2c5825a..a49ce5a 100644 --- a/src/system/dlt-system.h +++ b/src/system/dlt-system.h @@ -74,6 +74,8 @@ typedef struct { int SyslogPort; /*# The UDP port opened by DLT system mamager to receive system logs (Default: 47111)*/ int FiletransferEnable; /*# Enable the Filetransfer (Default: 0)*/ + int FiletransferCompression; /*# Enable the Filetransfer compression (Default: 0)*/ + int FiletransferCompressionLevel; /*# Set the compression level between 0-9 (Default: 5)*/ char FiletransferDirectory1[256]; /*# Directory which contains files to be transfered over DLT (Default: /tmp/filetransfer)# Files are deleted after Filetransfer is finished and after TimeDelay expired*/ char FiletransferDirectory2[256]; char FiletransferContextId[256]; /*# The Context Id of the filetransfer (Default: FILE)*/ -- cgit v1.2.1