I've been quite frustrated by trying to make progress in Recover. When I run my code, I am unable to make even the first JPEG file as the program continues running until the file size is exceeded. I can't find where the bug(s) are, but my poor understanding of file reading/writing doesn't help.
I have some questions:
When we call fread, does the function just read off from where the so-called file position indicator last left off?
In the walkthrough, Brian suggested that we use
FILE *image = fopen(filename, "w");
. However, I understand that writing to a file erases the data that was there prior while appending just adds on to the file's existing data. Thus, when we write buffer data that isn't headed by the JPEG signature (i.e. the last "else" in my code) into our outgoing JPEG file, why aren't we somehow using "a" instead of the default "w"? Wouldn't this overwrite the data that is already written to our opened JPEG file?Finally, what is causing my first JPEG file to keep on getting written (presumably) indefinitely? As you can see from my commented-out code, I've tried various things - using malloc and free, changing the size of my buffer variable (called "copy"), and changing my arguments to fwrite, but all these haven't worked.
The following is my code. I know there's lots to be improved about it, but I'd really appreciate any input. Thank you.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
// argument entry check
if (argc != 2)
{
printf("usage: ./recover image\n");
return 1;
}
// open file
FILE *raw = fopen(argv[1], "r");
if (raw == NULL)
{
printf("unable to open file for reading\n");
fclose(raw);
return 1;
}
int count = 0;
int flag = 0; // indicates if JPEG-copying has started
char filename[8];
sprintf(filename, "%03i.jpg", count);
FILE *img = fopen(filename, "w"); // declare outside while loop to prevent undeclared identifier error. A OR W???
while (feof(raw) == 0)
{
// allocate buffer space
//BYTE *copy = malloc(512 * sizeof(BYTE));
//BYTE copy[512 * sizeof(BYTE)];
BYTE copy[512];
// read a block to the buffer
fread(©, sizeof(copy), 1, raw);
// check if start of JPEG
if (copy[0] == 0xff && copy[1] == 0xd8 && copy[2] == 0xff && (copy[3] >= 0xe0 && copy[3] <= 0xef))
{
if (count == 0) // if first JPEG
{
fwrite(©, sizeof(copy), 1, img); //or fwrite(©, sizeof(BYTE), 512, img);?
flag = 1;
}
else // if not first JPEG
{
count += 1;
// close the current image
fclose(img);
// create a new image
sprintf(filename, "%03i.jpg", count);
img = fopen(filename, "w");
fwrite(©, sizeof(copy), 1, img);
}
}
// if not start of JPEG
else
{
if (flag == 0)
{
continue;
}
fwrite(©, sizeof(copy), 1, img);
}
//free (copy);
}
fclose(img);
fclose(raw);
}