read.c

mail@pastecode.io avatar
unknown
plain_text
2 months ago
5.6 kB
5
Indexable
Never
#include "read.h"

int read_file(int tar_fd){
    struct header *file_header;
    char block[BLOCK_SIZE], null_block[BLOCK_SIZE];
    long int file_size;
    int target_fd;

    if(read(tar_fd, &block, BLOCK_SIZE) == 0){
        return 0;
    }

    if(is_null(block)){
        if(read(tar_fd, &null_block, BLOCK_SIZE) == 0){
            return 0;
        }
        if(is_null(null_block)){
            return 0;
        }
        else{
            if(lseek(tar_fd, -BLOCK_SIZE, SEEK_CUR) == -1){
                perror("lseek");
                exit(EXIT_FAILURE);
            }
        }
    }

    file_header = populate_header(block);
    verify_header(file_header);

    target_fd = extract_header(file_header);

    if(list_option == 1){
        list_file(file_header);
    }

    file_size = strtol(file_header->size, NULL, 0);
    while(file_size > 0){
        if(read(tar_fd, &block, BLOCK_SIZE) == 0){
            return 0;
        }

        if(target_fd != -1){
            write_contents(target_fd, block, file_size);
        }

        file_size -= BLOCK_SIZE;
    }
}

header *populate_header(char block[]){
    struct header *file_header;
    char *size8_buff, *size12_buff, *name_buff, *prefix_buff;

    /* Initialize string buffers */
    size8_buff = malloc(sizeof(char) * (MODE_SIZE + 1));
    if(size8_buff == NULL){
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    size12_buff = malloc(sizeof(char) * (FILESIZE_SIZE + 1));
    if(size12_buff == NULL){
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    prefix_buff = malloc(sizeof(char) * (PREFIX_SIZE + 1));
    if(prefix_buff == NULL){
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    /* Initialize string buffers */
    name_buff = malloc(sizeof(char) * (NAME_SIZE + 1));
    if(name_buff == NULL){
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    file_header = malloc(sizeof(header));
    if(file_header == NULL){
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    /* Write mode as an octal num and store in header */
    if(strncpy(name_buff, block, NAME_SIZE - 1) < 0){
        perror("word overflow");
    }
    name_buff[NAME_SIZE] = '\0';
    file_header->name = strdup(name_buff);

    /* Write mode as an octal num and store in header */
    if(strncpy(size8_buff, &block[MODE_OFF], MODE_SIZE - 1) < 0){
        perror("word overflow");
    }
    size8_buff[MODE_SIZE] = '\0';
    file_header->mode = strdup(size8_buff);

    /* Write mode as an octal num and store in header */
    if(strncpy(size8_buff, &block[UID_OFF], UID_SIZE - 1) < 0){
        perror("word overflow");
    }
    size8_buff[UID_SIZE] = '\0';
    file_header->uid = strdup(size8_buff);

    /* Write mode as an octal num and store in header */
    if(strncpy(size8_buff, &block[GID_OFF], GID_SIZE - 1) < 0){
        perror("word overflow");
    }
    size8_buff[GID_SIZE] = '\0';
    file_header->gid = strdup(size8_buff);

    /* Write mode as an octal num and store in header */
    if(strncpy(size12_buff, &block[SIZE_OFF], FILESIZE_SIZE - 1) < 0){
        perror("word overflow");
    }
    size12_buff[FILESIZE_SIZE] = '\0';
    file_header->size = strdup(size12_buff);

    /* Strcpy mtime from block and store in header */
    if(strncpy(size12_buff, &block[MTIME_OFF], MTIME_SIZE - 1) < 0){
        perror("word overflow");
    }
    size12_buff[MTIME_SIZE] = '\0';
    file_header->mtime = strdup(size12_buff);

    /* Strcpy chksum from block and store in header */
    if(strncpy(size8_buff, &block[CHKSUM_OFF], CHKSUM_SIZE - 1) < 0){
        perror("word overflow");
    }
    size8_buff[CHKSUM_SIZE] = '\0';
    file_header->chksum = strdup(size8_buff);

    /* Add typeflag into header field */
    file_header->typeflag = block[TYPEFLAG_OFF];

    /* Strcpy linkname from block and store in header */
    if(strncpy(name_buff, &block[LINKNAME_OFF], LINKNAME_SIZE - 1) < 0){
        perror("word overflow");
    }
    name_buff[LINKNAME_SIZE] = '\0';
    file_header->linkname = strdup(name_buff);

    /* Strcpy magic from block and store in header */
    if(strncpy(size8_buff, &block[MAGIC_OFF], MAGIC_SIZE - 1) < 0){
        perror("word overflow");
    }
    size8_buff[MAGIC_SIZE] = '\0';
    file_header->magic = strdup(size8_buff);

    /* Strcpy version from block and store in header */
    if(strncpy(size8_buff, &block[VERSION_OFF], VERSION_SIZE - 1) < 0){
        perror("word overflow");
    }
    size8_buff[VERSION_SIZE] = '\0';
    file_header->version = strdup(size8_buff);

    /* Strcpy uname from block and store in header */
    if(strncpy(name_buff, &block[UNAME_OFF], UNAME_SIZE - 1) < 0){
        perror("word overflow");
    }
    name_buff[UNAME_SIZE] = '\0';
    file_header->uname = strdup(name_buff);

    /* Strcpy gname from block and store in header */
    if(strncpy(name_buff, &block[GNAME_OFF], GNAME_SIZE - 1) < 0){
        perror("word overflow");
    }
    name_buff[GNAME_SIZE] = '\0';
    file_header->gname = strdup(name_buff);

    /* Set dev major and dev minor to NULL */
    file_header->devmajor = NULL;
    file_header->devminor = NULL;

    /* Strcpy version from block and store in header */
    if(strncpy(prefix_buff, &block[PREFIX_OFF], PREFIX_SIZE - 1) < 0){
        perror("word overflow");
    }
    prefix_buff[PREFIX_SIZE] = '\0';
    file_header->prefix = strdup(prefix_buff);

    return file_header;
}

int is_null(char block[]){
    int i;

    for(i = 0; i < BLOCK_SIZE; i++){
        if(block[i] != '\0'){
            return 1;
        }
    }

    return 0;
}
Leave a Comment