0

I just wrote a C function that compress a file using bzip2 library APIs. The compression is not working fine. When I decompress the output file using an archiving utility, I'm getting some garbage value along with the actual data. I have done everything as per the instructions in the bzip2 library manual. Can someone tell me what went wrong?

The code may not be well structured. This is just an attempt to understand the usage of libzip2 library.

#define BUFSIZE  512
int main(int argc, char *argv[])
{
    char file_name[64];
    if(argc != 2)
    {
         printf("usage: compr <file name>");
         return -1;
    }
    strncpy(file_name,argv[1],64);
    return file_compress(file_name);
}

int file_compress(char * arg)
{
    int input_fd, output_fd;            
    ssize_t ret_in ;                     
    char buffer[BUFSIZE];            
    char buffout[BUFSIZE];

    struct stat fileStat;
    int insize;

    int st;
    bz_stream strm;
    strm.bzalloc= NULL;
    strm.bzfree= NULL;
    strm.opaque= NULL;

    st = BZ2_bzCompressInit (&strm,1,0,30 );
    if(st != BZ_OK)
    {
        return 1;
    }
    else
    {

        input_fd = open (arg, O_RDONLY);             
        if (input_fd < 0) 
        {
            return 1;
        }

        if(fstat(input_fd,&fileStat) < 0)    
            return 1;
        insize = fileStat.st_size;
        printf("File Size: \t%d bytes\n",insize);

        strcat(arg,".bz2");     
        output_fd = open(arg, O_WRONLY | O_CREAT, 0644); 
        if(output_fd == -1)
        {
            return 1;
        }

        strm.avail_in = 0;
        while(1)
        {
            if(insize > 0  && strm.avail_in == 0)
                ret_in = read (input_fd, buffer, BUFSIZE);
            else
                ret_in = 0;



            strm.next_in=buffer;
            strm.avail_in=ret_in;
            strm.next_out=buffout;
            strm.avail_out=BUFSIZE;

            if(insize == 0)                     
            {
                st= BZ2_bzCompress ( &strm,BZ_FINISH);

            }   
            else if(insize <= BUFSIZE)          
            {   
                st= BZ2_bzCompress ( &strm,BZ_FINISH);

            }
            else                                
            {
                st=BZ2_bzCompress ( &strm,BZ_RUN);
            }

            insize -= ret_in;

            if(BUFSIZE - strm.avail_out > 0)     
            {
                int ret_out=write (output_fd, buffout, BUFSIZE - strm.avail_out);
                printf("retout%d \n",ret_out);
            }

            if(st == BZ_STREAM_END)
                break;

            if(st < 0 )    
            {   
                return 1;
            }

        }
        close (input_fd);
        close (output_fd);  

    } 

    st = BZ2_bzCompressEnd (&strm );
    if(st != BZ_OK)
    {
        //      perror("ERROR BZ2_bzCompressEnd\n");
        return 1;
    }

    return 0;
}
  • How do you call `file_compress()`? And how do you defines the variable holding the file name being pass in? – alk Oct 01 '15 at 12:11
  • The code you show looks good, so the issue mostly like is in the code you do not show. – alk Oct 01 '15 at 12:12
  • @alk I call the function like file_compress(myFile.txt), where myFile.txt is a file inside my present working directory. I am not holding the file name being passed in in separate variable. Function parameter arg holds the file name. I'm appending .bz2 to the file name to form the output file name. In this case the output file name will be myFile.txt.bz2 – Sreeyesh Sreedharan Oct 01 '15 at 12:20
  • @alk. There nothing important in the hidden code. I am calling this function from main() with an argument(file name). And the BUFFSIZE is defined as 512. – Sreeyesh Sreedharan Oct 01 '15 at 12:24
  • There definitely *is* some important stuff in the code you do not show, as the code you do show works perfectly fine. So please take my 1st comment serious and dare to show the relevant code I am asking for. – alk Oct 01 '15 at 12:28
  • What is BUFSIZ**E** and **s**size_t ? You should show as a minimal code that compiles. – Michi Oct 01 '15 at 12:54
  • @Michi "man 2 read" for ssize_t. I think it's "unsigned long" – Sreeyesh Sreedharan Oct 01 '15 at 12:57
  • @sreeyesh What do you mean with **"man 2 read"** ? – Michi Oct 01 '15 at 13:03
  • @Michi I am writing the code in linux. man 2 read is the linux command to see the manual page of read function. ssize_t read(int fd, void *buf, size_t count); – Sreeyesh Sreedharan Oct 01 '15 at 13:06
  • Yes, sorry i see now what you mean and ssize_t is in unistd.h. Anyway, is there any reason why you do not show us the whole code ? or at least something that we can compile it too ? – Michi Oct 01 '15 at 13:10
  • @Michi: I added a minimal `main()` and the code shown works fine. – alk Oct 01 '15 at 14:14
  • @michi: Also the C Standard defines `ssize_t` to (at least) come from `stddef.h` – alk Oct 03 '15 at 11:44

0 Answers0