You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

170 lines
4.0 KiB

/*
* GZIP Compression functions for kernel crash dumps.
*
* Created by: Matt Robinson (yakker@sourceforge.net)
* Copyright 2001 Matt D. Robinson. All rights reserved.
*
* This code is released under version 2 of the GNU GPL.
*/
#include <stdio.h>
#include <linux/zlib.h>
typedef unsigned int u32;
typedef unsigned char u8;
#define ENOMEM 12 /* Out of memory */
static void *deflate_workspace;
static void *inflate_workspace;
char *new;
int newsize;
static u32
compress_gzip(const u8 *old, u32 oldsize)
{
/* error code and dump stream */
int err;
char *buf;
int bufsize;
z_stream dump_stream;
buf=new=malloc(oldsize);
bufsize=oldsize;
dump_stream.workspace = deflate_workspace;
if ((err = zlib_deflateInit(&dump_stream,Z_BEST_COMPRESSION)) != Z_OK) {
printf("compress_gzip(): zlib_deflateInit() " "failed (%d)!\n", err);
return 0;
}
dump_stream.next_in = (u8 *) old;
dump_stream.avail_in = oldsize;
while(1)
{
dump_stream.next_out = buf;
dump_stream.avail_out = oldsize;
/* deflate the page -- check for error */
err = zlib_deflate(&dump_stream, Z_FINISH);
if(err==Z_STREAM_END)break;
if(err<0 && (err!=Z_BUF_ERROR)){
/* zero is return code here */
printf("compress_gzip(): zlib_deflate() failed (%d),total_out=%x,next_out=%x!\n",
err,dump_stream.total_out,dump_stream.next_out);
(void)zlib_deflateEnd(&dump_stream);
return 0;
}
new=realloc(new,bufsize+oldsize);
buf=new+dump_stream.total_out;
bufsize+=oldsize;
}
/* let's end the deflated compression stream */
if ((err = zlib_deflateEnd(&dump_stream)) != Z_OK) {
printf("compress_gzip(): zlib_deflateEnd() "
"failed (%d)!\n", err);
}
newsize=dump_stream.total_out;
return dump_stream.total_out;
}
#define MYDBG printf("debug:%s,%d\n",__FUNCTION__,__LINE__);
static u32
compress_gunzip(const u8 *old, u32 oldsize)
{
/* error code and dump stream */
int err;
char *buf;
int bufsize;
z_stream dump_stream;
buf=new=malloc(oldsize);
bufsize=oldsize;
dump_stream.workspace = inflate_workspace;
if ((err = zlib_inflateInit(&dump_stream)) != Z_OK) {
/* fall back to RLE compression */
printf("compress_gunzip(): zlib_inflateInit() "
"failed (%d)!\n", err);
return 0;
}
dump_stream.next_in = (u8 *) old;
dump_stream.avail_in = oldsize;
while(1){
dump_stream.next_out = buf;
dump_stream.avail_out = oldsize;
err = zlib_inflate(&dump_stream, Z_FINISH);
if(err==Z_STREAM_END)break;
else if(err<0 && (err!=Z_BUF_ERROR))
{
/* zero is return code here */
(void)zlib_inflateEnd(&dump_stream);
printf("compress_gunzip(): zlib_inflate() failed (%d)!\n",
err);
return 0;
}
new=realloc(new,bufsize+oldsize);
buf=new+dump_stream.total_out;
bufsize+=oldsize;
}
/* let's end the deflated compression stream */
if ((err = zlib_inflateEnd(&dump_stream)) != Z_OK) {
printf("compress_gunzip(): zlib_inflateEnd() "
"failed (%d)!\n", err);
}
newsize=dump_stream.total_out;
/* return the compressed byte total (if it's smaller) */
return dump_stream.total_out;
}
/* setup the gzip compression functionality */
int main(int argc,char **argv)
{
u32 fsize;
char *buf;
FILE *fin;
FILE *fout;
if(argc<3){printf("usage:gzip filein fileout [-d]\n");return -1;}
deflate_workspace = malloc(zlib_deflate_workspacesize());
if (!deflate_workspace) {
printf("compress_gzip_init(): Failed to "
"alloc %d bytes for deflate workspace\n",
zlib_deflate_workspacesize());
goto out;
}
inflate_workspace = malloc(zlib_inflate_workspacesize());
if (!inflate_workspace) {
printf("compress_gunzip_init(): Failed to "
"alloc %d bytes for deflate workspace\n",
zlib_inflate_workspacesize());
goto out;
}
fin=fopen(argv[1],"rb");
fseek(fin,0,SEEK_END);
fsize=ftell(fin);
fseek(fin,0,SEEK_SET);
buf=malloc(fsize);
fread(buf,fsize,1,fin);
fclose(fin);
if(argc>3)
compress_gunzip(buf,fsize);
else
compress_gzip(buf,fsize);
fout=fopen(argv[2],"wb");
fwrite(new,newsize,1,fout);
fclose(fout);
free(new);
free(buf);
out:
if(deflate_workspace)free(deflate_workspace);
if(inflate_workspace)free(inflate_workspace);
return 0;
}