1

I have a project for a class in which we're supposed to read each block into a buffer and compare the bytes to look for a mp3 file signature.

We are supposed to start with a zeroed out drive (I had an ext3 filesystem which I zeroed out using dd if=/dev/zero of=/dev/sdc1) and print out that there are no matching bytes to the file signature.

Currently, using the code shown below:

int main (int argc, char* argv[]) {
    printf("argc : %d \nargv %s \n", argc, argv[1]);
    ReadDataBlockTest(argv[1]);

    return 0;
}
void ReadDataBlockTest(char* arg) {
    int fd;
    int *pointList;
    int bytes;
    int buffer;
    if((fd = open(arg, O_RDONLY)) < 0){ //check if disk can be read
        perror(arg);
        exit(1);
    } 

    for (int i = 1; i < 5; i++)
    {
        lseek(fd, (i * 134217728), SEEK_SET);
        read(fd, &buffer, 1);
        printf("C: %02X\n", buffer);
    }
}

I am getting an output of

argc : 2 
argv /dev/sdc1 
C: 5500
C: 5500
C: 5500
C: 5500

but also sometimes the number is 5600.

My issue is that I am not sure that I am reading in the bytes correctly, or if I am, why does the output oscillate?

If I am wrong, what should I do in order to fix it? Any help is appreciated.

Sanika
  • 41
  • 4
  • `buffer` is not initialized and no error checking on the `lseek` or `read` calls... – John3136 Nov 03 '21 at 01:51
  • what should the error checking in lseek and read be? i thought those were similar to fread – Sanika Nov 03 '21 at 01:57
  • You want to read an `int`, do `read(fd, &buffer, sizeof(int));`. Besides, shouldn't the loop start at `0` (not 1)? Moreover, the `i*134217728` is suspicious... – Déjà vu Nov 03 '21 at 02:24
  • Also, I'm guessing the `lseek` should be done once, before the loop (doing `read` advances the data pointer, so the next read reads the next int, no need to lseek each time). Just lseek to 134217728. Thus starting ffrom `i=0` to have 5 ints, with only `read` and printf in the loop should work. – Déjà vu Nov 03 '21 at 02:31
  • @John3136 `buffer` does not need to be initialized, it's set by `read()`. – Déjà vu Nov 03 '21 at 02:33
  • @Breakingnotsobad i ended up changing buffer to a char array of 512 since thats how many bytes are in a block. The `i*134217728` was there because that's how many bytes in a block group (which i know now is not what i should be doing for the offset) im just not sure why the values keep changing every time i execute the program – Sanika Nov 03 '21 at 03:13
  • @Breakingnotsobad Even if read fails for some reason? The man page I'm looking at doesn't make that clear. At least if buffer was initialized you'd know if the read had changed it or not. – John3136 Nov 03 '21 at 04:42
  • do you have a prototype or definition of `ReadDataBlockTest` before `main`? – phuclv Nov 03 '21 at 07:18
  • @John3136 Checking the return value of read() is a good idea. As for "*At least if buffer was initialized you'd know if the read had changed it or not*": `buffer` is an int that has always some value, so if you initialize it to x, the next read() could set it to x with some luck, and you cannot determine if it was read or not. – Déjà vu Nov 03 '21 at 10:15
  • @Breakingnotsobad "buffer is an int that has always some value" not in OP's case. It explicitly has an unknown value. You're right in that if you set it buffer=x you can't tell if you just read x or it's x because that was the initial value. I guess we just need to agree "check the result of read()" :-) – John3136 Nov 03 '21 at 15:31
  • @John3136 *"buffer is an int that has always some value" not in OP's case* ... what?? It's C and it has a value! The value is not "unknown", it's random. That's the worst case as it would work most of the time, except when it does not. – Déjà vu Nov 04 '21 at 03:03
  • @Breakingnotsobad So we quibble over terms - if you have no way of knowing what the value is it may as well not have a value. Lets just leave it at check read() worked. – John3136 Nov 04 '21 at 03:23

0 Answers0