[ C ] help for Cabal???

Skilled Illusionist
Joined
Feb 6, 2009
Messages
327
Reaction score
56
Hey people!

Im looking for someone who is knowledgeable in C.
Basically I have this problem, im trying to make a Windows C app ( converted from linux ) but im having problems. Here is the code that I have it uses the ZLIB library:

Code:
/* zpipe.c: example of proper use of zlib's inflate() and deflate()
   Not copyrighted -- provided to the public domain
   Version 1.2  9 November 2004  Mark Adler */
/* Version history:
   1.0  30 Oct 2004  First version
   1.1   8 Nov 2004  Add void casting for unused return values
                     Use switch statement for inflate() return values
   1.2   9 Nov 2004  Add assertions to document zlib guarantees
   1.3   6 Apr 2005  Remove incorrect assertion in inf()
 */
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "zlib.h"
#include <sys/types.h>
#include <sys/stat.h>
#define CHUNK 16384
/* Compress from file source to file dest until EOF on source.
   def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
   allocated for processing, Z_STREAM_ERROR if an invalid compression
   level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
   version of the library linked do not match, or Z_ERRNO if there is
   an error reading or writing the files. */
int def(FILE *source, FILE *dest, int level)
{
    int ret, flush;
    unsigned have;
    z_stream strm;
    char in[CHUNK];
    char out[CHUNK];
    char *buf;
    unsigned long dest_size;
    unsigned long indx = 0;
    struct stat sb;
    have = fileno(source);
    if (fstat(have, &sb) < 0)
        return Z_ERRNO;
    if (!S_ISREG(sb.st_mode))
        return Z_ERRNO;
    if ((dest_size = (unsigned long)sb.st_size) <= 0)
        return Z_ERRNO;
    if (fwrite(&dest_size, 4, 1, dest) != 1 || ferror(dest))
        return Z_ERRNO;
    /* allocate deflate state */
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    ret = deflateInit2(&strm, level, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
    if (ret != Z_OK)
        return ret;
    /* compress until end of file */
    do {
        strm.avail_in = fread(in, 1, CHUNK, source);
        if (ferror(source)) {
            (void)deflateEnd(&strm);
            return Z_ERRNO;
        }
        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
        strm.next_in = in;
        /* run deflate() on input until output buffer not full, finish
           compression if all of source has been read in */
        do {
            strm.avail_out = CHUNK;
            strm.next_out = out;
            ret = deflate(&strm, flush);    /* no bad return value */
            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
            have = CHUNK - strm.avail_out;
            if (have > 0) {
                buf = out;
                do {
                    if (dest_size > indx++) {
                        switch (indx) {
                        case 1:
                            *buf ^= 0x10;
                            break;
                        case 2:
                            *buf ^= 0x20;
                            break;
                        case 3:
                            *buf ^= 0x30;
                            break;
                        case 4:
                            *buf ^= 0x40;
                           }
                    }
                } while (*buf++);
                if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
                    (void)deflateEnd(&strm);
                    return Z_ERRNO;
                }
            }
        } while (strm.avail_out == 0);
        assert(strm.avail_in == 0);     /* all input will be used */
        /* done when last data in file processed */
    } while (flush != Z_FINISH);
    assert(ret == Z_STREAM_END);        /* stream will be complete */
    /* clean up and return */
    (void)deflateEnd(&strm);
    return Z_OK;
}
/* Decompress from file source to file dest until stream ends or EOF.
   inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
   allocated for processing, Z_DATA_ERROR if the deflate data is
   invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
   the version of the library linked do not match, or Z_ERRNO if there
   is an error reading or writing the files. */
int inf(FILE *source, FILE *dest)
{
    int ret;
    unsigned have;
    z_stream strm;
    char in[CHUNK];
    char out[CHUNK];
    char *buf;
    unsigned long dest_size;
    unsigned long indx = 0;
    have = fread(in, 1, 4, source);
    if (have != 4 || ferror(source)) {
        return Z_ERRNO;
    }
    dest_size = ((unsigned long)in[0]) |
                ((unsigned long)in[1] << 8) |
                ((unsigned long)in[2] << 16) |
                ((unsigned long)in[3] << 24);
    /* allocate inflate state */
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    strm.avail_in = 0;
    strm.next_in = Z_NULL;
    ret = inflateInit2(&strm, -MAX_WBITS);
    if (ret != Z_OK)
        return ret;
    /* decompress until deflate stream ends or end of file */
    do {
        strm.avail_in = fread(in, 1, CHUNK, source);
        if (ferror(source)) {
            (void)inflateEnd(&strm);
            return Z_ERRNO;
        }
        if (strm.avail_in == 0)
            break;
        buf = in;
        do {
            if (dest_size > indx++) {
                switch (indx) {
                case 1:
                            *buf ^= 0x10;
                            break;
                        case 2:
                            *buf ^= 0x20;
                            break;
                        case 3:
                            *buf ^= 0x30;
                            break;
                        case 4:
                            *buf ^= 0x40;
                }
            }
        } while (*buf++);
        strm.next_in = in;
        /* run inflate() on input until output buffer not full */
        do {
            strm.avail_out = CHUNK;
            strm.next_out = out;
            ret = inflate(&strm, Z_NO_FLUSH);
            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
            switch (ret) {
            case Z_NEED_DICT:
                ret = Z_DATA_ERROR;     /* and fall through */
            case Z_DATA_ERROR:
            case Z_MEM_ERROR:
                (void)inflateEnd(&strm);
                return ret;
            }
            have = CHUNK - strm.avail_out;
            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
                (void)inflateEnd(&strm);
                return Z_ERRNO;
            }
        } while (strm.avail_out == 0);
        /* done when inflate() says it's done */
    } while (ret != Z_STREAM_END);
    /* clean up and return */
    (void)inflateEnd(&strm);
    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
/* report a zlib or i/o error */
void zerr(int ret)
{
    fputs("zpipe: ", stderr);
    switch (ret) {
    case Z_ERRNO:
        if (ferror(stdin))
            fputs("error reading stdin\n", stderr);
        if (ferror(stdout))
            fputs("error writing stdout\n", stderr);
        break;
    case Z_STREAM_ERROR:
        fputs("invalid compression level\n", stderr);
        break;
    case Z_DATA_ERROR:
        fputs("invalid or incomplete deflate data\n", stderr);
        break;
    case Z_MEM_ERROR:
        fputs("out of memory\n", stderr);
        break;
    case Z_VERSION_ERROR:
        fputs("zlib version mismatch!\n", stderr);
    }
}
/* compress or decompress from stdin to stdout */
int main(int argc, char **argv)
{
    int ret;
    /* do compression if -c specified */
    if (argc == 2 && strcmp(argv[1], "-c") == 0) {
        ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
        if (ret != Z_OK)
            zerr(ret);
        return ret;
    }
    /* do decompression if -d specified */
    else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
        ret = inf(stdin, stdout);
        if (ret != Z_OK)
            zerr(ret);
        return ret;
    }
    /* otherwise, report usage */
    else {
        fputs("encpack usage: encpack [-c|-d] < source > dest\n", stderr);
        fputs("E.g: encpack -c < cabal.txt > cabal.enc\n\n", stderr);
        return 1;
    }
}

Now this code is working and compiles but output files are created at 1kb only. So therefore the files are not being outputed correctly. I have been told that this is due to file sizes in Linux and Windows that are different.
I only use BASIC programming language so my C is no good ( to a point ). I understand the structure and format of C but not to much in depth.

Does anyone know how to edit this code that would be suitable for Windows environment??

P.S I am Cabal devving at the moment! Thanks in advance!
 
Last edited by a moderator:
Skilled Illusionist
Joined
Apr 6, 2007
Messages
384
Reaction score
2
Re: C code help for Cabal???

ignore all that.



Have you tried stepping through with a debugger? Does it give any errors back from the functions? and are you sure the zlib.h and lib are the latest version?
 
Last edited:
Skilled Illusionist
Joined
Feb 6, 2009
Messages
327
Reaction score
56
Re: C code help for Cabal???

Yeah, all latest available updates for the complier. And as I said, complier finishes with no errors.

So I have a fully compiled windows console exe ( cos its command line ) and using ZLIB.DLL which came with the complier itself ( so using the same library ).
But every file I compress, I get a 1kb result. So I try to compress a 40Mb file and outputs as 1kb file. So on and so on.
 
Newbie Spellweaver
Joined
Nov 22, 2004
Messages
16
Reaction score
0
Re: C code help for Cabal???

So you did not run step-by-step debugging looking for some run-time problems?
 
Skilled Illusionist
Joined
Feb 6, 2009
Messages
327
Reaction score
56
Re: C code help for Cabal???

No runtime problems occured.

BUT a new development. I found out that you can use setmode ( stdin, O_BINARY ) for converting from Linux to Binary using this command from the fcntl.h library! I have the compression working but not decompressing. PLEASE HELP this is just a file in and file out problem surely.

I guess im not adding the command to the right 'output' varible???
Have a lookey>>

Code:
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <fcntl.h>
setmode ( 0, O_BINARY )
setmode ( 1, O_BINARY )
#include "zlib.h"

#include <sys/types.h>
#include <sys/stat.h>

#define CHUNK 16384

int def(FILE *source, FILE *dest, int level)
{
    setmode ( fileno ( source ), O_BINARY ); //ADDED HERE<<<<<<
    int ret, flush;
    unsigned have;
    z_stream strm;
    char in[CHUNK];
    char out[CHUNK];
    char *buf;
    unsigned long dest_size;
    unsigned long indx = 0;
    struct stat sb;

    have = fileno(source);

    if (fstat(have, &sb) < 0)
        return Z_ERRNO;

    if (!S_ISREG(sb.st_mode))
        return Z_ERRNO;

    if ((dest_size = (unsigned long)sb.st_size) <= 0)
        return Z_ERRNO;

    if (fwrite(&dest_size, 4, 1, dest) != 1 || ferror(dest))
        return Z_ERRNO;

    /* allocate deflate state */
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    ret = deflateInit2(&strm, level, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
    if (ret != Z_OK)
        return ret;

    do {
        strm.avail_in = fread(in, 1, CHUNK, source);
        if (ferror(source)) {
            (void)deflateEnd(&strm);
            return Z_ERRNO;
        }
        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
        strm.next_in = in;

        do {
            strm.avail_out = CHUNK;
            strm.next_out = out;
            ret = deflate(&strm, flush);
            assert(ret != Z_STREAM_ERROR);
            have = CHUNK - strm.avail_out;
            if (have > 0) {
                buf = out;

                do {
                    if (dest_size > indx++) {
                        switch (indx) {
                        case 1:
                            *buf ^= 0x92;
                            break;
                        case 2:
                            *buf ^= 0x65;
                            break;
                        case 3:
                            *buf ^= 0x67;
                            break;
                        case 4:
                            *buf ^= 0x57;
                        }
                    }
                } while (*buf++);

                if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
                    (void)deflateEnd(&strm);
                    return Z_ERRNO;
                }
            }
        } while (strm.avail_out == 0);
        assert(strm.avail_in == 0);

    } while (flush != Z_FINISH);
    assert(ret == Z_STREAM_END);

    (void)deflateEnd(&strm);
    return Z_OK;
}

int inf(FILE *source, FILE *dest)
{
    int ret;
    unsigned have;
    z_stream strm;
    char in[CHUNK];
    char out[CHUNK];
    char *buf;
    unsigned long dest_size;
    unsigned long indx = 0;

    have = fread(in, 1, 4, source);

    if (have != 4 || ferror(source)) {
        return Z_ERRNO;
    }

    dest_size = ((unsigned long)in[0]) |
                ((unsigned long)in[1] << 8) |
                ((unsigned long)in[2] << 16) |
                ((unsigned long)in[3] << 24);

    /* allocate inflate state */
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    strm.avail_in = 0;
    strm.next_in = Z_NULL;
    ret = inflateInit2(&strm, -MAX_WBITS);
    if (ret != Z_OK)
        return ret;

    do {
        strm.avail_in = fread(in, 1, CHUNK, source);
        if (ferror(source)) {
            (void)inflateEnd(&strm);
            return Z_ERRNO;
        }
        if (strm.avail_in == 0)
            break;

        buf = in;

        do {
            if (dest_size > indx++) {
                switch (indx) {
                case 1:
                    *buf ^= 0x92;
                    break;
                case 2:
                    *buf ^= 0x65;
                    break;
                case 3:
                    *buf ^= 0x67;
                    break;
                case 4:
                    *buf ^= 0x57;
                }
            }
        } while (*buf++);

        strm.next_in = in;

        do {
            strm.avail_out = CHUNK;
            strm.next_out = out;
            ret = inflate(&strm, Z_NO_FLUSH);
            assert(ret != Z_STREAM_ERROR);
            switch (ret) {
            case Z_NEED_DICT:
                ret = Z_DATA_ERROR;
            case Z_DATA_ERROR:
            case Z_MEM_ERROR:
                (void)inflateEnd(&strm);
                return ret;
            }
            have = CHUNK - strm.avail_out;
            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
                (void)inflateEnd(&strm);
                return Z_ERRNO;
            }
        } while (strm.avail_out == 0);

    } while (ret != Z_STREAM_END);

    (void)inflateEnd(&strm);
    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}

void zerr(int ret)
{
    fputs("zpipe: ", stderr);
    switch (ret) {
    case Z_ERRNO:
        if (ferror(stdin))
            fputs("error reading stdin\n", stderr);
        if (ferror(stdout))
            fputs("error writing stdout\n", stderr);
        break;
    case Z_STREAM_ERROR:
        fputs("invalid compression level\n", stderr);
        break;
    case Z_DATA_ERROR:
        fputs("invalid or incomplete deflate data\n", stderr);
        break;
    case Z_MEM_ERROR:
        fputs("out of memory\n", stderr);
        break;
    case Z_VERSION_ERROR:
        fputs("zlib version mismatch!\n", stderr);
    }
}

int main(int argc, char **argv)
{
    int ret;

    if (argc == 1) {
        ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
        if (ret != Z_OK)
            zerr(ret);
        return ret;
    }

    else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
        ret = inf(stdin, stdout);
        if (ret != Z_OK)
            zerr(ret);
        return ret;
    }

    else {
        fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
        return 1;
    }
}

Again thankyou!
 
Skilled Illusionist
Joined
Apr 6, 2007
Messages
384
Reaction score
2
Re: C code help for Cabal???

No runtime problems occured.

BUT a new development. I found out that you can use setmode ( stdin, O_BINARY ) for converting from Linux to Binary using this command from the fcntl.h library! I have the compression working but not decompressing. PLEASE HELP this is just a file in and file out problem surely.

I guess im not adding the command to the right 'output' varible???
Have a lookey>>


Again thankyou!

As tedious as it is, it generally can find most if not all problems you're looking for. Debug step by step through the entire process and manually verify that it's working. If the problem is with zlib then the error function will catch.

To make it super easy, put a breakpoint on

ret = inf(stdin, stdout);

and when it hits, continue over that code 1 line, and see what "ret" equals. That will give you the reason.
 
Skilled Illusionist
Joined
Feb 6, 2009
Messages
327
Reaction score
56
Re: C code help for Cabal???

Ok, here are the results from that breakpoint ( bearing in mind this is a console command line app so no file was used )!

ret = -1 before and ret = -370086 after breakpoint.

How would I run this with arguments and debug it??
 
Skilled Illusionist
Joined
Apr 6, 2007
Messages
384
Reaction score
2
Re: C code help for Cabal???

If you didn't pass the debug with arguments of course it won't work. What compiler are you using? I know in VC++ you can just go to project properties, go to Debugging, and put command arguments right there.
 
Skilled Illusionist
Joined
Feb 6, 2009
Messages
327
Reaction score
56
Hmm I think I get RET = 0.

I did what you said above, set breakpoint and stuff. So what this means is that when the code creates the output file, its not creating it properly?? Because previous to this breakpoint, ret = -370086.

More confused now lol! :)
 
Last edited:
Back
Top