0

Honestly, I have been struggling with Week 4, and I have been trying to complete this pset to the best of of my current understanding. I have researched multiple articles on this topic, but I have yet to find one that will help me with where I am stuck at. My code will compile and run, although once it iterates through all 50 files, it just hangs in the terminal and will not finish running until I enter Ctrl + C. I am stuck as to where to look next, as the assignment only says "Odds are, though, the JPEGs that the first draft of your code spits out won’t be correct. (If you open them up and don’t see anything, they’re probably not correct!)". Well, that is what is happening to me, but where do I start to fix my code? Is it all completely wrong and I need to start over? Any suggestions and help is greatly appreciated.

Here is my code:

''''

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef uint8_t BYTE;

int main(int argc, char *argv[])
{
    // define command line usage
    if (argc != 2)
    {
        printf("Usage: ./recover image\n");
        return 1;
    }

    // open forensic file
    FILE *forensic = fopen(argv[1], "r");

    // check if file successfully opened
    if (forensic == NULL)
    {
        printf("Error opening file. Please try again.\n");
        return 2;
    }

    BYTE buffer[512];
    int jpegcounter = 0;
    char filename[8];
    
    do
    {
        // check for jpeg header
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xe0) == 0xe0)
        {
            sprintf(filename, "%03i.jpg", jpegcounter);
            jpegcounter++;
            FILE *img = fopen(filename, "w");
            fwrite(buffer, 512, 1, img);
            fclose(img);
        }
        // if not header 
        else 
        {
            continue;
        }
    }
    while (fread(buffer, 512, 1, forensic) <= 1);
}

''''

check50 returns the following:

:) recover.c exists.

:) recover.c compiles.

:) handles lack of forensic image

:( recovers 000.jpg correctly
timed out while waiting for program to exit

:( recovers middle images correctly
timed out while waiting for program to exit

:( recovers 049.jpg correctly
timed out while waiting for program to exit

Here is my code after applying the help in the comments below:

    BYTE buffer[512];
    int jpegcounter = 0;
    char filename[8];
    int counter = 0; // 0 = file is closed, 1 = file is open
    FILE *img = NULL;
    
    // while reading a block of data:
    while (fread(buffer, 512, 1, forensic) == 1)
    {
        // if signature found
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            // if output file is open
            if (counter == 1)
            {
                // close it
                fclose(img);
                counter = 0;
            }
            else 
            {
                counter = 1;
            }
            sprintf(filename, "%03i.jpg", jpegcounter);
            img = fopen(filename, "w");
            jpegcounter++;
        }        
        // if output file is open
        if (counter == 1)
        {
            // write block to output file
            fwrite(buffer, 512, 1, img);
        }
    }
    fclose(img);
    fclose(forensic);

1 Answer 1

1

This code has an infinite loop. Look at the last while condition statement:

while (fread(buffer, 512, 1, forensic) <= 1);

What happens when the end of the input file is reached? fread will return 0, so the loop never ends! Instead, it should check for == 1.

Next, notice that every output file is 512 bytes. Remember, once the first signature is found, everything that follows is valid data and part of the image files. The data blocks that follow but don't have signatures have to be appended to the current output file. You'll need to recode for this.

That should get you going.

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

9
  • Thank you so much for your input! That makes sense about the infinite loop now that you explain it. For the next part, would this be fixed with a different loop than what I currently have? i.e. an if loop verses a do..while loop. I'm still trying to sort out the logic on this problem, and was not sure if this would be a good solution
    – Rachel D
    Commented May 29, 2021 at 0:17
  • Not really, because an IF statement is not a loop. Try a while loop (vs a do-while). In your case, I suggest that you first get a working program on your own (feel free to ask questions), and then go look at other code and compare it to your approaches.
    – Cliff B
    Commented May 29, 2021 at 1:15
  • So then I would think that my psuedocode would look something like...WHILE FREAD(ing) each block in the output file, FOPEN a new input file, then FWRITE to input file. IF block contains JPEG header, FCLOSE the current input file, and FOPEN a new input file. I updated my code to reflect this logic, and now I am getting a segmentation fault. I’m sorry to be so specific. I understand this weeks material in theory, but in practice it is much different, and I feel lost. So your help is greatly appreciated!!
    – Rachel D
    Commented May 29, 2021 at 1:32
  • No, it seems like you do understand it, but just lack a little confidence. Your pseudocode is almost right, except that you want to check for and handle a signature BEFORE writing the block out. ALSO, use a while, not a do-while. The do-while runs the loop before the first data read. That'll cause issues.
    – Cliff B
    Commented May 29, 2021 at 1:32
  • You are very kind to say that. It seems like checking for the existence of information has been my Achilles heel for this pset. I have updated my original post with to show how I have changed my code based on your suggestions as I understand them. I think what I am confused about now is when I would change the value of my block_check variable to a falsy value. Or perhaps I am not understanding the handling of signatures correctly?
    – Rachel D
    Commented May 29, 2021 at 1:49

You must log in to answer this question.

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