forked from len0rd/rockbox
microtar: Update to latest upstream commit
This is a major overhaul of the library with some API changes and ease of use improvements, particularly for creating new archives. The updated functionality is intended to support a new X1000 installer framework. Change-Id: Icf192bb546831231d49303fbf529ef1c1ce8905c
This commit is contained in:
parent
4052a9ddcf
commit
c1709e3194
12 changed files with 1468 additions and 611 deletions
|
@ -1,65 +1,88 @@
|
|||
/**
|
||||
/*
|
||||
* Copyright (c) 2017 rxi
|
||||
* Copyright (c) 2021 Aidan MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the MIT license. See `microtar.c` for details.
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "microtar-stdio.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "microtar.h"
|
||||
static int file_read(void* stream, void* data, unsigned size)
|
||||
{
|
||||
unsigned res = fread(data, 1, size, (FILE*)stream);
|
||||
if(res != size && ferror((FILE*)stream))
|
||||
return MTAR_EREADFAIL;
|
||||
|
||||
static int file_write(mtar_t *tar, const void *data, unsigned size) {
|
||||
unsigned res = fwrite(data, 1, size, tar->stream);
|
||||
return (res == size) ? MTAR_ESUCCESS : MTAR_EWRITEFAIL;
|
||||
return res;
|
||||
}
|
||||
|
||||
static int file_read(mtar_t *tar, void *data, unsigned size) {
|
||||
unsigned res = fread(data, 1, size, tar->stream);
|
||||
return (res == size) ? MTAR_ESUCCESS : MTAR_EREADFAIL;
|
||||
static int file_write(void* stream, const void* data, unsigned size)
|
||||
{
|
||||
unsigned res = fwrite(data, 1, size, (FILE*)stream);
|
||||
if(res != size && ferror((FILE*)stream))
|
||||
return MTAR_EWRITEFAIL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int file_seek(mtar_t *tar, unsigned offset) {
|
||||
int res = fseek(tar->stream, offset, SEEK_SET);
|
||||
return (res == 0) ? MTAR_ESUCCESS : MTAR_ESEEKFAIL;
|
||||
static int file_seek(void* stream, unsigned offset)
|
||||
{
|
||||
int res = fseek((FILE*)stream, offset, SEEK_SET);
|
||||
return (res == 0) ? MTAR_ESUCCESS : MTAR_ESEEKFAIL;
|
||||
}
|
||||
|
||||
static int file_close(mtar_t *tar) {
|
||||
fclose(tar->stream);
|
||||
return MTAR_ESUCCESS;
|
||||
static int file_close(void* stream)
|
||||
{
|
||||
int err = fclose((FILE*)stream);
|
||||
return (err == 0 ? MTAR_ESUCCESS : MTAR_EFAILURE);
|
||||
}
|
||||
|
||||
static const mtar_ops_t file_ops = {
|
||||
.read = file_read,
|
||||
.write = file_write,
|
||||
.seek = file_seek,
|
||||
.close = file_close,
|
||||
};
|
||||
|
||||
int mtar_open(mtar_t *tar, const char *filename, const char *mode) {
|
||||
int err;
|
||||
mtar_header_t h;
|
||||
|
||||
/* Init tar struct and functions */
|
||||
memset(tar, 0, sizeof(*tar));
|
||||
tar->write = file_write;
|
||||
tar->read = file_read;
|
||||
tar->seek = file_seek;
|
||||
tar->close = file_close;
|
||||
|
||||
/* Assure mode is always binary */
|
||||
if ( strchr(mode, 'r') ) mode = "rb";
|
||||
if ( strchr(mode, 'w') ) mode = "wb";
|
||||
if ( strchr(mode, 'a') ) mode = "ab";
|
||||
/* Open file */
|
||||
tar->stream = fopen(filename, mode);
|
||||
if (!tar->stream) {
|
||||
return MTAR_EOPENFAIL;
|
||||
}
|
||||
/* Read first header to check it is valid if mode is `r` */
|
||||
if (*mode == 'r') {
|
||||
err = mtar_read_header(tar, &h);
|
||||
if (err != MTAR_ESUCCESS) {
|
||||
mtar_close(tar);
|
||||
return err;
|
||||
int mtar_open(mtar_t* tar, const char* filename, const char* mode)
|
||||
{
|
||||
/* Determine access mode */
|
||||
int access;
|
||||
char* read = strchr(mode, 'r');
|
||||
char* write = strchr(mode, 'w');
|
||||
if(read) {
|
||||
if(write)
|
||||
return MTAR_EAPI;
|
||||
access = MTAR_READ;
|
||||
} else if(write) {
|
||||
access = MTAR_WRITE;
|
||||
} else {
|
||||
return MTAR_EAPI;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return ok */
|
||||
return MTAR_ESUCCESS;
|
||||
/* Open file */
|
||||
FILE* file = fopen(filename, mode);
|
||||
if(!file)
|
||||
return MTAR_EOPENFAIL;
|
||||
|
||||
mtar_init(tar, access, &file_ops, file);
|
||||
return MTAR_ESUCCESS;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue