diff options
author | Patrick McDermott <patrick.mcdermott@libiquity.com> | 2023-04-29 23:04:43 (EDT) |
---|---|---|
committer | Patrick McDermott <patrick.mcdermott@libiquity.com> | 2023-04-29 23:04:43 (EDT) |
commit | 4a9d3a83d5f62afaa841fd79a5b90089e4975475 (patch) | |
tree | c4559bf85bdb129a7d0cf43f3363fa09f5ebf509 /src | |
parent | 50f9ee989f89fd47a5f554d9967e8abedd6bd938 (diff) |
ustar: Add function to write header
Diffstat (limited to 'src')
-rw-r--r-- | src/ustar.c | 56 | ||||
-rw-r--r-- | src/ustar.h | 7 |
2 files changed, 63 insertions, 0 deletions
diff --git a/src/ustar.c b/src/ustar.c index 1a2858b..0eda87a 100644 --- a/src/ustar.c +++ b/src/ustar.c @@ -22,6 +22,7 @@ #include <stdlib.h> #include <string.h> #include "defs.h" +#include "dirent.h" #include "gzip.h" #include "ustar.h" @@ -264,6 +265,61 @@ opkg_opk_ustar_read(struct opkg_opk_ustar *ustar, char **buffer, size_t *size) return OPKG_OPK_OK; } +int +opkg_opk_ustar_write_header(struct opkg_opk_ustar *ustar, + struct opkg_opk_dirent *dirent, uint16_t mode, + uid_t uid, const char *uname, gid_t gid, const char *gname, + uint64_t size, char type, const char *linkname) +{ + size_t linkname_len; + + if (opkg_opk_dirent_name_prefix(dirent, + ustar->header.name, + sizeof(ustar->header.name), + ustar->header.prefix, + sizeof(ustar->header.prefix)) != OPKG_OPK_OK) { + return OPKG_OPK_ERROR; + } + sprintf(ustar->header.mode, "%o", mode); + sprintf(ustar->header.uid, "%o", uid); + sprintf(ustar->header.gid, "%o", gid); + strncpy(ustar->header.uname, uname, sizeof(ustar->header.uname)); + strncpy(ustar->header.gname, gname, sizeof(ustar->header.gname)); + sprintf(ustar->header.size, "%o", size); + switch (type) { + case '-': /* Regular file */ + *ustar->header.typeflag = '0'; + break; + case 'l': /* Symbolic link */ + *ustar->header.typeflag = '2'; + break; + case 'c': /* Character special file */ + *ustar->header.typeflag = '3'; + break; + case 'b': /* Block special file */ + *ustar->header.typeflag = '4'; + break; + case 'd': /* Directory */ + *ustar->header.typeflag = '5'; + break; + case 'p': /* FIFO special file */ + *ustar->header.typeflag = '6'; + break; + default: + return OPKG_OPK_ERROR; /* Unsupported */ + } + linkname_len = strlen(linkname); + memcpy(ustar->header.linkname, linkname, linkname_len); + ustar->header.linkname[linkname_len] = '\0'; + if (opkg_opk_gzip_write(ustar->gzip, &ustar->header, + OPKG_OPK_USTAR_RECORD_SIZE, 0) != OPKG_OPK_OK) { + return OPKG_OPK_ERROR; + } + + ustar->data_size_remaining = size; + return OPKG_OPK_OK; +} + void opkg_opk_ustar_free(struct opkg_opk_ustar *ustar) { diff --git a/src/ustar.h b/src/ustar.h index 802412a..1337f1a 100644 --- a/src/ustar.h +++ b/src/ustar.h @@ -21,6 +21,7 @@ #define OPKG_OPK_USTAR_H_ #include <stdint.h> +#include "dirent.h" #include "gzip.h" #define OPKG_OPK_USTAR_RECORD_SIZE 512 @@ -85,6 +86,12 @@ opkg_opk_ustar_list(struct opkg_opk_ustar *ustar, int opkg_opk_ustar_read(struct opkg_opk_ustar *ustar, char **buffer, size_t *size); +int +opkg_opk_ustar_write_header(struct opkg_opk_ustar *ustar, + struct opkg_opk_dirent *dirent, uint16_t mode, + uid_t uid, const char *uname, gid_t gid, const char *gname, + uint64_t size, char type, const char *linkname); + /* * Frees an archive structure. * Parameters: |