summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPatrick 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)
commit4a9d3a83d5f62afaa841fd79a5b90089e4975475 (patch)
treec4559bf85bdb129a7d0cf43f3363fa09f5ebf509 /src
parent50f9ee989f89fd47a5f554d9967e8abedd6bd938 (diff)
ustar: Add function to write header
Diffstat (limited to 'src')
-rw-r--r--src/ustar.c56
-rw-r--r--src/ustar.h7
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: