1
votes

Right now, I'm working on an example code that I wish to integrate into my program later. What essentially I'm trying to do is read a .dat file byte by byte and interpret the data (ie. interpret boot sector to output the sector size, reserved sectors etc.)

To do this, I am reading the data byte by byte and, using the descriptions in fat12 of https://www.win.tue.nl/~aeb/linux/fs/fat/fat-1.html#ss1.3 , I translate the data into the information that I want. Right now, I can pull individual bytes from the file (Is it right to assume that the data pulled is in hex?). However, I need two bytes to have something meaningful. So, I need to combine two bytes into one, convert the hex data into decimal and output the information. Unfortunately, right now, I'm getting a seg fault and for the life of me, I can't figure out what's wrong. Thanks in advance!

int main (int argc, char **argv){

FILE *fp ,*fptest;
long lSize;
char *buffer;

//Open file
fptest= open("fat_volume.dat", "rb");

//Read file into buffer
fread(buffer,1,512,fptest);

//Parse the boot sector
char tmpA, tmpB;
tmpA = buffer[10]; //First byte
tmpB = buffer[11]; //Second byte

//Combine the two bytes into one
char combinedBytes[3];
strcpy (combinedBytes, tmpA);
strcat (combinedBytes, tmpB);

//Hex to decimal converter
long int li1;
li1 = strtol (combinedBytes,NULL,16);
printf ("The sector size is: %ld.\n", li1);

return 0;

}

2
You never malloc an array for buffer. Somewhere along the way, you need to say something like buffer = malloc(512);cHao
Can you please explain? My C is incredibly rusty. An example would be greatly appreciated!user2989964
You define yourself a char*, but you never point it at anything. It's probably pointing to some unknown location that could open a wormhole if you try to access it. You need to set it to point to some memory you own.cHao

2 Answers

1
votes

You must allocate buffer; e.g.

char buffer[512];

or

char *buffer = malloc(512);

EDIT:

The string operations

strcpy (combinedBytes, tmpA);
strcat (combinedBytes, tmpB);

do not make sense either and access/copy too much data (the compiler will warn you about this!).

I suggest do read values as

unsigned char tmpA = buffer[10];
unsigned char tmpB = buffer[11];

unsigned int tmp = (tmpA << 8) | (tmpB << 0);  /* or revert in in case of
                                                  little-endian */

To make things more efficient, I would write it as

struct fat_header {
    uint8_t pad0[10];
    uint16_t my_val;
    uint8_t pad1[500];
} __attribute__((__packed__));      /* this is not portable and for gcc! */

...

struct fat_header  hdr;

fread(&hdr, 1, sizeof hdr, f);
uint16_t val = be16toh(hdr.my_val); /* or le16toh() in case of le */
0
votes

You are reading into a buffer you never allocated memory for.

What you're trying now is to read from some junk value in memory, who knows, which almost always leads to a segmentation fault.

Use:

char *buffer = malloc(512 * sizeof(char)); // this allocates 512 times the size of a single char of memory

If you don't specify the number inside malloc to be of a specific size (e.g. malloc(512) the number is in bytes, though I think it's better to always include it.

This specific error is called dereferencing a null pointer

EDIT:

I've managed to run this code:

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

int main (int argc, char **argv)
{  
    FILE *fp ,*fptest;
    long lSize;
    char *buffer;

    //Open file
    fptest = fopen("input.txt", "rb");

    if (fptest == NULL)
    {
        printf("Error occurred when opening file");
        return 1;
    }

    buffer = malloc(sizeof(char) * 512);
    //Read file into buffer
    fread(buffer,1,512,fptest);

    //Parse the boot sector
    char tmpA, tmpB;
    tmpA = buffer[10]; //First byte
    tmpB = buffer[11]; //Second byte

    //Combine the two bytes into one
    char combinedBytes[3];
    strcpy (combinedBytes, &tmpA);
    strcat (combinedBytes, &tmpB);

    //Hex to decimal converter
    long int li1;
    li1 = strtol (combinedBytes,NULL,16);
    printf ("The sector size is: %ld.\n", li1);

    return 0;
}

You also used a function open() which must be fopen(), and you need to pass the address of tmpA and tmpB to strcpy and strcat.

This is why I don't understand why your compiler doesn't give any errors or warnings..