0

for recover my code returns 51 jpegs, was wondering where i went wrong? none of the jpegs seem viewable from vscode as well.

int main (int argc, char *argv[])

{

 if (argc < 2|| argc <= 1)
{
    printf("Usage: ./recover filename\n");
    return 1;
}

char *name = argv[1];
FILE *input = fopen(name, "r");
if (input == NULL)
{
    printf("File input null\n");
    return 1;
}



fseek(input, 0 , SEEK_END);
long totalbyte = ftell(input); //size = total no. of byte
fseek(input, 0, SEEK_SET);
// calc no. of blocks
// read each 512 byte block into an array of bytes
// check if it is start of jpeg, if not write into previous jpeg
long totalblocks = (totalbyte/512);
long count = 1; //counter for jpeg file no. and space for counter name
char *jpegname = malloc(50);
if (jpegname == NULL)
{
    printf("memory not allocated\n");
    return 1;
}
//create memory for current block

uint8_t *cblock = malloc(sizeof(uint8_t) *512);
if (cblock == NULL)
{
    printf("memory not allocated\n");
    return 1;
}
for (int i = 0; i < totalblocks; i++)
{
    FILE *output;
    //read each block into cblock
fread(cblock, sizeof(uint8_t), 512, input);
    if (cblock[0] == 0xff && cblock[1] == 0xd8 && cblock[2]== 0xff
    && cblock[3] >= 0xe0 && cblock[3] <= 0xef )
    {//if start of jpeg found

        if (count ==1) //if first file
        {
            sprintf(jpegname, "%03li.jpeg",count);
            //open output file
            output = fopen(jpegname , "w");
            fwrite(cblock, sizeof(uint8_t), 512, output);
            count++;
        }
        if (count >1)
        {
            // close previous file
            fclose(output);
            sprintf(jpegname, "%03li.jpeg",count);
            output = fopen(jpegname, "w");
            fwrite(cblock, sizeof(uint8_t),512,output);
            count++;
        }
    }
    //if first jpeg not found yet do nothing
    if (count > 1)     //if first jpeg found
    {

         fwrite(cblock, sizeof(uint8_t), 512, output); //keep writing to 1st jpeg

    }


}





free(jpegname);
free(cblock);

return 0;
}

1 Answer 1

1

There are a few problems going on here. Let's start with the easy ones. The files are incorrectly named. There's not supposed to be an "e' in jpg. Second, the file numbering starts at 0, not 1.

Now, let's move on to the logic problems. What happens when the first file is created? The code logic handles the creation of the first file ok. BUT, there's a problem. That logic increments count (which it should.) The problem is that now, count is > 1. The next if statement looks at this and decides that it needs to close the file that was just opened and create a new file. That means that for the first actual file to be recovered, two files are created. Instead of an if statement, the second if should be either an else or an else if statement.

Finally, every file will have the first data block written twice. Ignoring the problem above, each signature block is written out to the output file when the file is opened. Then, in the last if code block, the current data block, which is still the signature block, is written out again.

There may be other issues, but these are the major problems that I spotted. After reworking the code a bit, you should be well on your way. ;-)

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

2
  • thanks so much, have managed to fix my code. I thought it was jpeg my whole life lol
    – duckpro
    Commented Jan 9, 2023 at 7:53
  • actually, both are correct, but the spec calls for "jpg", so the code has to match the spec.
    – Cliff B
    Commented Jan 9, 2023 at 10:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .