nkiss

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/nkiss
Log | Files | Refs

commit d4e4f3d2ba15cf8c2f225aefb9cc165d406e0b3e
parent 7a88f218494b5a414030c408dcfc30225c2a395e
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Fri, 19 Feb 2021 17:00:40 -0600

tar.c: replace fd parameter with gzFile

tar_remove requires ftruncate, but I think don't think we need to use
it. A solution should be found to truncate with libz regardless.

read_size and write_size are replaced with gzread_size and gzwrite_size.
read_size is still needed in one case, so it is kept

Diffstat:
Mtar.c | 111++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mtar.h | 16++++++++--------
2 files changed, 67 insertions(+), 60 deletions(-)

diff --git a/tar.c b/tar.c @@ -23,6 +23,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE */ +#include "zlib.h" #include "tar.h" #define MIN(x, y) (((x) < (y)) ? (x) : (y)) @@ -36,11 +37,14 @@ THE SOFTWARE #define WRITE_ERROR(fmt, ...) { ERROR(fmt, ##__VA_ARGS__); tar_free(*archive); *archive = NULL; return -1; } #define EXIST_ERROR(fmt, ...) const int rc = errno; if (rc != EEXIST) { ERROR(fmt, ##__VA_ARGS__); return -1; } +// force gzread() to complete +static int gzread_size(gzFile gzf, char *buf, int size); + // force read() to complete static int read_size(int fd, char *buf, int size); -// force write() to complete -static int write_size(int fd, char *buf, int size); +// force gzwrite() to complete +static int gzwrite_size(gzFile gzf, char *buf, int size); // convert octal string to unsigned integer static unsigned int oct2uint(char *oct, unsigned int size); @@ -51,8 +55,8 @@ static int iszeroed(char *buf, size_t size); // make directory recursively static int recursive_mkdir(const char *dir, const unsigned int mode, const char verbosity); -int tar_read(const int fd, struct tar_t **archive, const char verbosity) { - if (fd < 0) { +int tar_read(const gzFile gzf, struct tar_t **archive, const char verbosity) { + if (gzf == NULL) { ERROR("Bad file descriptor"); } @@ -68,7 +72,7 @@ int tar_read(const int fd, struct tar_t **archive, const char verbosity) { for(count = 0; ; count++) { *tar = malloc(sizeof(struct tar_t)); - if (update && (read_size(fd, (*tar)->block, 512) != 512)) { + if (update && (gzread_size(gzf, (*tar)->block, 512) != 512)) { V_PRINT(stderr, "Error: Bad read. Stopping"); tar_free(*tar); *tar = NULL; @@ -78,7 +82,7 @@ int tar_read(const int fd, struct tar_t **archive, const char verbosity) { update = 1; // if current block is all zeros if (iszeroed((*tar)->block, 512)) { - if (read_size(fd, (*tar)->block, 512) != 512) { + if (gzread_size(gzf, (*tar)->block, 512) != 512) { V_PRINT(stderr, "Error: Bad read. Stopping"); tar_free(*tar); *tar = NULL; @@ -91,7 +95,7 @@ int tar_read(const int fd, struct tar_t **archive, const char verbosity) { *tar = NULL; // skip to end of record - if (lseek(fd, RECORDSIZE - (offset % RECORDSIZE), SEEK_CUR) == (off_t) (-1)) { + if (gzseek(gzf, RECORDSIZE - (offset % RECORDSIZE), SEEK_CUR) == (off_t) (-1)) { RC_ERROR("Unable to seek file: %s", strerror(rc)); } @@ -112,7 +116,7 @@ int tar_read(const int fd, struct tar_t **archive, const char verbosity) { // move file descriptor offset += 512 + jump; - if (lseek(fd, jump, SEEK_CUR) == (off_t) (-1)) { + if (gzseek(gzf, jump, SEEK_CUR) == (off_t) (-1)) { RC_ERROR("Unable to seek file: %s", strerror(rc)); } @@ -123,8 +127,8 @@ int tar_read(const int fd, struct tar_t **archive, const char verbosity) { return count; } -int tar_write(const int fd, struct tar_t **archive, const size_t filecount, const char *files[], const char verbosity) { - if (fd < 0) { +int tar_write(const gzFile gzf, struct tar_t **archive, const size_t filecount, const char *files[], const char verbosity) { + if (gzf == NULL) { ERROR("Bad file descriptor"); } @@ -151,19 +155,19 @@ int tar_write(const int fd, struct tar_t **archive, const size_t filecount, cons // move file descriptor offset = (*tar)->begin + jump; - if (lseek(fd, offset, SEEK_SET) == (off_t) (-1)) { + if (gzseek(gzf, offset, SEEK_SET) == (off_t) (-1)) { RC_ERROR("Unable to seek file: %s", strerror(rc)); } tar = &((*tar)->next); } // write entries first - if (write_entries(fd, tar, archive, filecount, files, &offset, verbosity) < 0) { + if (write_entries(gzf, tar, archive, filecount, files, &offset, verbosity) < 0) { WRITE_ERROR("Failed to write entries"); } // write ending data - if (write_end_data(fd, offset, verbosity) < 0) { + if (write_end_data(gzf, offset, verbosity) < 0) { ERROR("Failed to write end data"); } @@ -203,7 +207,7 @@ int tar_ls(FILE *f, struct tar_t *archive, const size_t filecount, const char *f return 0; } -int tar_extract(const int fd, struct tar_t *archive, const size_t filecount, const char *files[], const char verbosity) { +int tar_extract(const gzFile gzf, struct tar_t *archive, const size_t filecount, const char *files[], const char verbosity) { int ret = 0; // extract entries with given names @@ -215,11 +219,11 @@ int tar_extract(const int fd, struct tar_t *archive, const size_t filecount, con while (archive) { for(size_t i = 0; i < filecount; i++) { if (!strncmp(archive->name, files[i], MAX(strlen(archive->name), strlen(files[i])))) { - if (lseek(fd, archive->begin, SEEK_SET) == (off_t) (-1)) { + if (gzseek(gzf, archive->begin, SEEK_SET) == (off_t) (-1)) { RC_ERROR("Unable to seek file: %s", strerror(rc)); } - if (extract_entry(fd, archive, verbosity) < 0) { + if (extract_entry(gzf, archive, verbosity) < 0) { ret = -1; } break; @@ -231,13 +235,13 @@ int tar_extract(const int fd, struct tar_t *archive, const size_t filecount, con // extract all else{ // move offset to beginning - if (lseek(fd, 0, SEEK_SET) == (off_t) (-1)) { + if (gzseek(gzf, 0, SEEK_SET) == (off_t) (-1)) { RC_ERROR("Unable to seek file: %s", strerror(rc)); } // extract each entry while (archive) { - if (extract_entry(fd, archive, verbosity) < 0) { + if (extract_entry(gzf, archive, verbosity) < 0) { ret = -1; } archive = archive->next; @@ -247,7 +251,7 @@ int tar_extract(const int fd, struct tar_t *archive, const size_t filecount, con return ret; } -int tar_update(const int fd, struct tar_t **archive, const size_t filecount, const char *files[], const char verbosity) { +int tar_update(const gzFile gzf, struct tar_t **archive, const size_t filecount, const char *files[], const char verbosity) { if (!filecount) { return 0; } @@ -291,7 +295,7 @@ int tar_update(const int fd, struct tar_t **archive, const size_t filecount, con } // update listed files only - if (tar_write(fd, archive, count, (const char **) newer, verbosity) < 0) { + if (tar_write(gzf, archive, count, (const char **) newer, verbosity) < 0) { ERROR("Unable to update archive"); } @@ -304,8 +308,8 @@ int tar_update(const int fd, struct tar_t **archive, const size_t filecount, con return all ? 0 : -1; } -int tar_remove(const int fd, struct tar_t **archive, const size_t filecount, const char *files[], const char verbosity) { - if (fd < 0) { +int tar_remove(const gzFile gzf, struct tar_t **archive, const size_t filecount, const char *files[], const char verbosity) { + if (gzf == NULL) { return -1; } @@ -323,14 +327,8 @@ int tar_remove(const int fd, struct tar_t **archive, const size_t filecount, con return 0; } - // get file permissions - struct stat st; - if (fstat(fd, &st)) { - RC_ERROR("Unable to stat archive: %s", strerror(rc)); - } - // reset offset of original file - if (lseek(fd, 0, SEEK_SET) == (off_t) (-1)) { + if (gzseek(gzf, 0, SEEK_SET) == (off_t) (-1)) { RC_ERROR("Unable to seek file: %s", strerror(rc)); } @@ -368,24 +366,24 @@ int tar_remove(const int fd, struct tar_t **archive, const size_t filecount, con int got = 0; while (got < total) { // go to old data - if (lseek(fd, read_offset, SEEK_SET) == (off_t) (-1)) { + if (gzseek(gzf, read_offset, SEEK_SET) == (off_t) (-1)) { RC_ERROR("Cannot seek: %s", strerror(rc)); } char buf[512]; // copy chunk out - if (read_size(fd, buf, 512) != 512) {// guarenteed 512 octets + if (gzread_size(gzf, buf, 512) != 512) {// guarenteed 512 octets ERROR("Read error"); } // go to new position - if (lseek(fd, write_offset, SEEK_SET) == (off_t) (-1)) { + if (gzseek(gzf, write_offset, SEEK_SET) == (off_t) (-1)) { RC_ERROR("Cannot seek: %s", strerror(rc)); } // write data in - if (write_size(fd, buf, 512) != 512) { + if (gzwrite_size(gzf, buf, 512) != 512) { RC_ERROR("Write error: %s", strerror(rc)); } @@ -400,7 +398,7 @@ int tar_remove(const int fd, struct tar_t **archive, const size_t filecount, con write_offset += total; // skip past data - if (lseek(fd, read_offset, SEEK_SET) == (off_t) (-1)) { + if (gzseek(gzf, read_offset, SEEK_SET) == (off_t) (-1)) { RC_ERROR("Cannot seek: %s", strerror(rc)); } } @@ -430,13 +428,14 @@ int tar_remove(const int fd, struct tar_t **archive, const size_t filecount, con } } + /* TODO we don't use tar_remove, but a solution should be found for this // resize file if (ftruncate(fd, write_offset) < 0) { RC_ERROR("Could not truncate file: %s", strerror(rc)); } - + */ // add end data - if (write_end_data(fd, write_offset, verbosity) < 0) { + if (write_end_data(gzf, write_offset, verbosity) < 0) { V_PRINT(stderr, "Error: Could not close file"); } @@ -753,7 +752,7 @@ int ls_entry(FILE *f, struct tar_t *entry, const size_t filecount, const char *f return 0; } -int extract_entry(const int fd, struct tar_t *entry, const char verbosity) { +int extract_entry(const gzFile gzf, struct tar_t *entry, const char verbosity) { V_PRINT(stdout, "%s", entry->name); if ((entry->type == REGULAR) || (entry->type == NORMAL) || (entry->type == CONTIGUOUS)) { @@ -787,7 +786,7 @@ int extract_entry(const int fd, struct tar_t *entry, const char verbosity) { } // move archive pointer to data location - if (lseek(fd, 512 + entry->begin, SEEK_SET) == (off_t) (-1)) { + if (gzseek(gzf, 512 + entry->begin, SEEK_SET) == (off_t) (-1)) { RC_ERROR("Bad index: %s", strerror(rc)); } @@ -796,7 +795,7 @@ int extract_entry(const int fd, struct tar_t *entry, const char verbosity) { int got = 0; while (got < size) { int r; - if ((r = read_size(fd, buf, MIN(size - got, 512))) < 0) { + if ((r = gzread_size(gzf, buf, MIN(size - got, 512))) < 0) { EXIST_ERROR("Unable to read from archive: %s", strerror(rc)); } @@ -848,8 +847,8 @@ int extract_entry(const int fd, struct tar_t *entry, const char verbosity) { return 0; } -int write_entries(const int fd, struct tar_t **archive, struct tar_t **head, const size_t filecount, const char *files[], int *offset, const char verbosity) { - if (fd < 0) { +int write_entries(const gzFile gzf, struct tar_t **archive, struct tar_t **head, const size_t filecount, const char *files[], int *offset, const char verbosity) { + if (gzf == NULL) { ERROR("Bad file descriptor"); } @@ -890,7 +889,7 @@ int write_entries(const int fd, struct tar_t **archive, struct tar_t **head, con V_PRINT(stdout, "Writing %s", (*tar)->name); // write metadata to (*tar) file - if (write_size(fd, (*tar)->block, 512) != 512) { + if (gzwrite_size(gzf, (*tar)->block, 512) != 512) { WRITE_ERROR("Failed to write metadata to archive"); } @@ -909,7 +908,7 @@ int write_entries(const int fd, struct tar_t **archive, struct tar_t **head, con sprintf(path, "%s/%s", parent, dir->d_name); // recursively write each subdirectory - if (write_entries(fd, &((*tar)->next), head, 1, (const char **) &path, offset, verbosity) < 0) { + if (write_entries(gzf, &((*tar)->next), head, 1, (const char **) &path, offset, verbosity) < 0) { WRITE_ERROR("Recurse error"); } @@ -952,7 +951,7 @@ int write_entries(const int fd, struct tar_t **archive, struct tar_t **head, con } // write metadata to (*tar) file - if (write_size(fd, (*tar)->block, 512) != 512) { + if (gzwrite_size(gzf, (*tar)->block, 512) != 512) { WRITE_ERROR("Failed to write metadata to archive"); } @@ -967,7 +966,7 @@ int write_entries(const int fd, struct tar_t **archive, struct tar_t **head, con int r = 0; char buf[512]; while ((r = read_size(f, buf, 512)) > 0) { - if (write_size(fd, buf, r) != r) { + if (gzwrite_size(gzf, buf, r) != r) { RC_ERROR("Could not write to archive: %s", strerror(rc)); } } @@ -981,7 +980,7 @@ int write_entries(const int fd, struct tar_t **archive, struct tar_t **head, con const unsigned int pad = 512 - size % 512; if (pad != 512) { for(unsigned int j = 0; j < pad; j++) { - if (write_size(fd, "\0", 1) != 1) { + if (gzwrite_size(gzf, "\0", 1) != 1) { WRITE_ERROR("Could not write padding data"); } } @@ -998,15 +997,15 @@ int write_entries(const int fd, struct tar_t **archive, struct tar_t **head, con return 0; } -int write_end_data(const int fd, int size, const char verbosity) { - if (fd < 0) { +int write_end_data(const gzFile gzf, int size, const char verbosity) { + if (gzf == NULL) { return -1; } // complete current record const int pad = RECORDSIZE - (size % RECORDSIZE); for(int i = 0; i < pad; i++) { - if (write(fd, "\0", 1) != 1) { + if (gzwrite(gzf, "\0", 1) != 1) { V_PRINT(stderr, "Error: Unable to close tar file"); return -1; } @@ -1015,7 +1014,7 @@ int write_end_data(const int fd, int size, const char verbosity) { // if the current record does not have 2 blocks of zeros, add a whole other record if (pad < (2 *BLOCKSIZE)) { for(int i = 0; i < RECORDSIZE; i++) { - if (write(fd, "\0", 1) != 1) { + if (gzwrite(gzf, "\0", 1) != 1) { V_PRINT(stderr, "Error: Unable to close tar file"); return -1; } @@ -1056,9 +1055,17 @@ int read_size(int fd, char *buf, int size) { return got; } -int write_size(int fd, char *buf, int size) { +int gzread_size(gzFile gzf, char *buf, int size) { + int got = 0, rc; + while ((got < size) && ((rc = gzread(gzf, buf + got, size - got)) > 0)) { + got += rc; + } + return got; +} + +int gzwrite_size(gzFile gzf, char *buf, int size) { int wrote = 0, rc; - while ((wrote < size) && ((rc = write(fd, buf + wrote, size - wrote)) > 0)) { + while ((wrote < size) && ((rc = gzwrite(gzf, buf + wrote, size - wrote)) > 0)) { wrote += rc; } return wrote; diff --git a/tar.h b/tar.h @@ -109,11 +109,11 @@ struct tar_t { // core functions ////////////////////////////////////////////////////////////// // read a tar file // archive should be address to null pointer -int tar_read(const int fd, struct tar_t ** archive, const char verbosity); +int tar_read(const gzFile gzf, struct tar_t ** archive, const char verbosity); // write to a tar file // if archive contains data, the new data will be appended to the back of the file (terminating blocks will be rewritten) -int tar_write(const int fd, struct tar_t ** archive, const size_t filecount, const char * files[], const char verbosity); +int tar_write(const gzFile gzf, struct tar_t ** archive, const size_t filecount, const char * files[], const char verbosity); // recursive freeing of entries void tar_free(struct tar_t * archive); @@ -125,13 +125,13 @@ void tar_free(struct tar_t * archive); int tar_ls(FILE * f, struct tar_t * archive, const size_t filecount, const char * files[], const char verbosity); // extracts files from an archive -int tar_extract(const int fd, struct tar_t * archive, const size_t filecount, const char * files[], const char verbosity); +int tar_extract(const gzFile gzf, struct tar_t * archive, const size_t filecount, const char * files[], const char verbosity); // update files in tar with provided list -int tar_update(const int fd, struct tar_t ** archive, const size_t filecount, const char * files[], const char verbosity); +int tar_update(const gzFile gzf, struct tar_t ** archive, const size_t filecount, const char * files[], const char verbosity); // remove entries from tar -int tar_remove(const int fd, struct tar_t ** archive, const size_t filecount, const char * files[], const char verbosity); +int tar_remove(const gzFile gzf, struct tar_t ** archive, const size_t filecount, const char * files[], const char verbosity); // show files that are missing from the current directory int tar_diff(FILE * f, struct tar_t * archive, const char verbosity); @@ -159,13 +159,13 @@ int ls_entry(FILE * f, struct tar_t * archive, const size_t filecount, const cha // extracts a single entry // expects file descriptor offset to already be set to correct location -int extract_entry(const int fd, struct tar_t * entry, const char verbosity); +int extract_entry(const gzFile gzf, struct tar_t * entry, const char verbosity); // write entries to a tar file -int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, const size_t filecount, const char * files[], int * offset, const char verbosity); +int write_entries(const gzFile gzf, struct tar_t ** archive, struct tar_t ** head, const size_t filecount, const char * files[], int * offset, const char verbosity); // add ending data -int write_end_data(const int fd, int size, const char verbosity); +int write_end_data(const gzFile gzf, int size, const char verbosity); // check if entry is a match for any of the given file names // returns index + 1 if match is found