Search code examples
cfile-iobinaryfiles

C File Input/Output for Unknown File Types: File Copying


having some issues with a networking assignment. End goal is to have a C program that grabs a file from a given URL via HTTP and writes it to a given filename. I've got it working fine for most text files, but I'm running into some issues, which I suspect all come from the same root cause.

Here's a quick version of the code I'm using to transfer the data from the network file descriptor to the output file descriptor:

unsigned long content_length; // extracted from HTTP header
unsigned long successfully_read = 0;
while(successfully_read != content_length)
{
  char buffer[2048];
  int extracted = read(connection,buffer,2048);
  fprintf(output_file,buffer);
  successfully_read += extracted;
}

As I said, this works fine for most text files (though the % symbol confuses fprintf, so it would be nice to have a way to deal with that). The problem is that it just hangs forever when I try to get non-text files (a .png is the basic test file I'm working with, but the program needs to be able to handle anything).

I've done some debugging and I know I'm not going over content_length, getting errors during read, or hitting some network bottleneck. I looked around online but all the C file i/o code I can find for binary files seems to be based on the idea that you know how the data inside the file is structured. I don't know how it's structured, and I don't really care; I just want to copy the contents of one file descriptor into another.

Can anyone point me towards some built-in file i/o functions that I can bludgeon into use for that purpose?

Edit: Alternately, is there a standard field in the HTTP header that would tell me how to handle whatever file I'm working with?


Solution

  • You are using the wrong tool for the job. fprintf takes a format string and extra arguments, like this:

    fprintf(output_file, "hello %s, today is the %d", cstring, dayoftheweek);
    

    If you pass the second argument from an unknown source (like the web, which you are doing) you can accidentally have %s or %d or other format specifiers in the string. Then fprintf will try to read more arguments than it was passed, and cause undefined behaviour.

    Use fwrite for this:

    fwrite(buffer, 1, extracted, output_file);