write.c

mail@pastecode.io avatar
unknown
plain_text
2 months ago
3.7 kB
1
Indexable
Never
#include "write.h"

/*this function writes a header to a tar file*/
void write_header(int tar_fd, header *curr_header) {
    int name_len, prefix_len, uname_len, gname_len;

    verify_header(curr_header);

    name_len = 0;
    prefix_len = 0;

    /* Get length of names */
    if(curr_header->name != NULL){
        name_len = strlen(curr_header->name);
    }

    if(curr_header->prefix != NULL){
        prefix_len = strlen(curr_header->prefix);
    }
    uname_len = strlen(curr_header->uname);
    gname_len = strlen(curr_header->gname);

    /* Write every header field to tar file */
    write_field(tar_fd, curr_header->name, name_len);
    write_field(tar_fd, NULL, NAME_SIZE - name_len);
    write_field(tar_fd, curr_header->mode, MODE_SIZE);
    write_field(tar_fd, curr_header->uid, UID_SIZE);
    write_field(tar_fd, curr_header->gid, GID_SIZE);
    write_field(tar_fd, curr_header->size, FILESIZE_SIZE);
    write_field(tar_fd, curr_header->mtime, MTIME_SIZE);
    write_field(tar_fd, curr_header->chksum, CHKSUM_SIZE);
    write_field(tar_fd, &curr_header->typeflag, TYPEFLAG_SIZE);
    write_field(tar_fd, curr_header->linkname, LINKNAME_SIZE);
    write_field(tar_fd, curr_header->magic, MAGIC_SIZE);
    write_field(tar_fd, curr_header->version, VERSION_SIZE);
    write_field(tar_fd, curr_header->uname, uname_len);
    write_field(tar_fd, NULL, UNAME_SIZE - uname_len);
    write_field(tar_fd, curr_header->gname, gname_len);
    write_field(tar_fd, NULL, GNAME_SIZE - gname_len);
    write_field(tar_fd, curr_header->devmajor, DEVMAJOR_SIZE);
    write_field(tar_fd, curr_header->devminor, DEVMINOR_SIZE);
    write_field(tar_fd, curr_header->prefix, prefix_len);
    write_field(tar_fd, NULL, PREFIX_SIZE - prefix_len);
    write_field(tar_fd, NULL, HEADER_PAD_SIZE);
}

/* Function writes a single field of a header to a tar file and frees it */
void write_contents(int tar_fd, int file_fd, struct stat sb){
    int byte_count, i;
    char block_buff[BLOCK_SIZE];

    byte_count = sb.st_size;

    while(byte_count >= BLOCK_SIZE){
        /* Read a content block */
        if(read(file_fd, block_buff, BLOCK_SIZE) == -1){
            perror("read");
            exit(EXIT_FAILURE);
        }

        /* Write content block */
        if (write(tar_fd, block_buff, BLOCK_SIZE) == -1) {
            perror("write");
            exit(EXIT_FAILURE);
        }

        byte_count -= BLOCK_SIZE;
    }

    if(byte_count > 0){

        /* Read a content block */
        if(read(file_fd, block_buff, byte_count) == -1){
            perror("read");
            exit(EXIT_FAILURE);
        }

        if(write(tar_fd, block_buff, byte_count) == -1){
            perror("write");
            exit(EXIT_FAILURE);
        }

        /* Write null at EOF */
        for(i = 0; i < BLOCK_SIZE - byte_count; i++){
            block_buff[i] = '\0';
        }

        if(write(tar_fd, block_buff, BLOCK_SIZE - byte_count) == -1){
            perror("write");
            exit(EXIT_FAILURE);
        }
    }

    return;
}

/* Function writes a single field of a header to a tar file and frees it */
void write_field(int fd, char *field, unsigned field_size){
    char buffer[field_size];
    int i;

    /* If field is NULL write \0 for the field size */
    if (field == NULL) {
        for (i = 0; i < field_size; i++) {
            buffer[i] = '\0';
        }
        if (write(fd, buffer, field_size) == -1) {
            perror("Buffer Write Failure");
            exit(EXIT_FAILURE);
        }
        return;
    }

    /* Write and free field */
    if (write(fd, field, field_size) == -1) {
        perror("write");
        exit(EXIT_FAILURE);
    }

    if(field_size > 1){
        free(field);
    }
}
Leave a Comment