diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/local.mk | 4 | ||||
-rw-r--r-- | src/ustar.c | 109 | ||||
-rw-r--r-- | src/ustar.h | 30 |
3 files changed, 142 insertions, 1 deletions
diff --git a/src/local.mk b/src/local.mk index a3ebaf1..ec4b347 100644 --- a/src/local.mk +++ b/src/local.mk @@ -2,4 +2,6 @@ opkg_opk_SOURCES += \ %reldir%/defs.h \ %reldir%/gzip.c \ %reldir%/gzip.h \ - %reldir%/main.c + %reldir%/main.c \ + %reldir%/ustar.c \ + %reldir%/ustar.h diff --git a/src/ustar.c b/src/ustar.c new file mode 100644 index 0000000..6388d76 --- /dev/null +++ b/src/ustar.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2023 Patrick McDermott + * + * This file is part of opkg-opk. + * + * opkg-opk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * opkg-opk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with opkg-opk. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include "defs.h" +#include "gzip.h" +#include "ustar.h" + +struct _opkg_opk_ustar_header { + unsigned char name [100]; + unsigned char mode [8]; + unsigned char uid [8]; + unsigned char gid [8]; + unsigned char size [12]; + unsigned char mtime [12]; + unsigned char chksum [8]; + unsigned char typeflag [1]; + unsigned char linkname [100]; + unsigned char magic [6]; + unsigned char version [2]; + unsigned char uname [32]; + unsigned char gname [32]; + unsigned char devmajor [8]; + unsigned char devminor [8]; + unsigned char prefix [155]; + unsigned char padding [12]; +} __attribute__((__packed__)); + +static int +_opkg_opk_ustar_next(struct opkg_opk_gzip_state *gzip_state, const char *member, + struct _opkg_opk_ustar_header *header, unsigned char **contents) +{ + static unsigned char record[512]; + int ret; + char *size_end; + uint32_t size; + unsigned char *contents_cursor; + uint32_t i; + + switch ((ret = opkg_opk_gzip_next_record(gzip_state, header))) { + case OPKG_OPK_OK: + case OPKG_OPK_END: + break; + case OPKG_OPK_ERROR: + return OPKG_OPK_ERROR; + } + size = strtol(header->size, &size_end, 10); + if (*size_end != '\0') { + return OPKG_OPK_ERROR; + } + for (i = 0; i < (size + 511) / 512; ++i) { + switch ((ret = opkg_opk_gzip_next_record(gzip_state, record))) { + case OPKG_OPK_OK: + case OPKG_OPK_END: + break; + case OPKG_OPK_ERROR: + return OPKG_OPK_ERROR; + } + } + + return ret; +} + +unsigned char * +opkg_opk_ustar_read(struct opkg_opk_gzip_state *gzip_state, const char *member) +{ + struct _opkg_opk_ustar_header header; + int ret; + unsigned char *contents; + + while ((ret = _opkg_opk_ustar_next(gzip_state, member, + &header, &contents)) == OPKG_OPK_OK) { + /* TODO: End gzip stream */ + return contents; + } + return NULL; +} + +int +opkg_opk_ustar_list(struct opkg_opk_gzip_state *gzip_state, + void (*member)(const char *name)) +{ + struct _opkg_opk_ustar_header header; + int ret; + + while ((ret = _opkg_opk_ustar_next(gzip_state, NULL, &header, NULL)) == + OPKG_OPK_OK) { + printf("%s\n", header.name); + } + return ret; +} diff --git a/src/ustar.h b/src/ustar.h new file mode 100644 index 0000000..a6959c7 --- /dev/null +++ b/src/ustar.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 Patrick McDermott + * + * This file is part of opkg-opk. + * + * opkg-opk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * opkg-opk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with opkg-opk. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef OPKG_OPK_USTAR_H_ +#define OPKG_OPK_USTAR_H_ + +unsigned char * +opkg_opk_ustar_read(struct opkg_opk_gzip_state *gzip_state, const char *member); + +int +opkg_opk_ustar_list(struct opkg_opk_gzip_state *gzip_state, + void (*member)(const char *name)); + +#endif /* OPKG_OPK_USTAR_H_ */ |