aboutsummaryrefslogtreecommitdiff
path: root/lib/tar/write_header.c
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-01-31 11:21:30 +0100
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-01-31 13:51:49 +0100
commitcdccc69c62579b0c13b35fad0728079652b8f3c9 (patch)
tree9fa54c710f73c5e08a9c8466e7a712eb63ee07ac /lib/tar/write_header.c
parent2182129c8f359c4fa1390eaba7a65b595ccd4182 (diff)
Move library source into src sub-directory
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/tar/write_header.c')
-rw-r--r--lib/tar/write_header.c282
1 files changed, 0 insertions, 282 deletions
diff --git a/lib/tar/write_header.c b/lib/tar/write_header.c
deleted file mode 100644
index b0711b3..0000000
--- a/lib/tar/write_header.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * write_header.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "config.h"
-
-#include "internal.h"
-#include <string.h>
-
-static void write_binary(char *dst, sqfs_u64 value, int digits)
-{
- memset(dst, 0, digits);
-
- while (digits > 0) {
- ((unsigned char *)dst)[digits - 1] = value & 0xFF;
- --digits;
- value >>= 8;
- }
-
- ((unsigned char *)dst)[0] |= 0x80;
-}
-
-static void write_number(char *dst, sqfs_u64 value, int digits)
-{
- sqfs_u64 mask = 0;
- char buffer[64];
- int i;
-
- for (i = 0; i < (digits - 1); ++i)
- mask = (mask << 3) | 7;
-
- if (value <= mask) {
- sprintf(buffer, "%0*lo ", digits - 1, (unsigned long)value);
- memcpy(dst, buffer, digits);
- } else if (value <= ((mask << 3) | 7)) {
- sprintf(buffer, "%0*lo", digits, (unsigned long)value);
- memcpy(dst, buffer, digits);
- } else {
- write_binary(dst, value, digits);
- }
-}
-
-static void write_number_signed(char *dst, sqfs_s64 value, int digits)
-{
- sqfs_u64 neg;
-
- if (value < 0) {
- neg = -value;
- write_binary(dst, ~neg + 1, digits);
- } else {
- write_number(dst, value, digits);
- }
-}
-
-static int write_header(ostream_t *fp, const struct stat *sb, const char *name,
- const char *slink_target, int type)
-{
- int maj = 0, min = 0;
- sqfs_u64 size = 0;
- tar_header_t hdr;
-
- if (S_ISCHR(sb->st_mode) || S_ISBLK(sb->st_mode)) {
- maj = major(sb->st_rdev);
- min = minor(sb->st_rdev);
- }
-
- if (S_ISREG(sb->st_mode))
- size = sb->st_size;
-
- memset(&hdr, 0, sizeof(hdr));
-
- strncpy(hdr.name, name, sizeof(hdr.name) - 1);
- write_number(hdr.mode, sb->st_mode & ~S_IFMT, sizeof(hdr.mode));
- write_number(hdr.uid, sb->st_uid, sizeof(hdr.uid));
- write_number(hdr.gid, sb->st_gid, sizeof(hdr.gid));
- write_number(hdr.size, size, sizeof(hdr.size));
- write_number_signed(hdr.mtime, sb->st_mtime, sizeof(hdr.mtime));
- hdr.typeflag = type;
- if (slink_target != NULL)
- memcpy(hdr.linkname, slink_target, sb->st_size);
- memcpy(hdr.magic, TAR_MAGIC_OLD, sizeof(hdr.magic));
- memcpy(hdr.version, TAR_VERSION_OLD, sizeof(hdr.version));
- sprintf(hdr.uname, "%u", sb->st_uid);
- sprintf(hdr.gname, "%u", sb->st_gid);
- write_number(hdr.devmajor, maj, sizeof(hdr.devmajor));
- write_number(hdr.devminor, min, sizeof(hdr.devminor));
-
- update_checksum(&hdr);
-
- return ostream_append(fp, &hdr, sizeof(hdr));
-}
-
-static int write_gnu_header(ostream_t *fp, const struct stat *orig,
- const char *payload, size_t payload_len,
- int type, const char *name)
-{
- struct stat sb;
-
- sb = *orig;
- sb.st_mode = S_IFREG | 0644;
- sb.st_size = payload_len;
-
- if (write_header(fp, &sb, name, NULL, type))
- return -1;
-
- if (ostream_append(fp, payload, payload_len))
- return -1;
-
- return padd_file(fp, payload_len);
-}
-
-static size_t num_digits(size_t num)
-{
- size_t i = 1;
-
- while (num >= 10) {
- num /= 10;
- ++i;
- }
-
- return i;
-}
-
-static size_t prefix_digit_len(size_t len)
-{
- size_t old_ndigit, ndigit = 0;
-
- do {
- old_ndigit = ndigit;
- ndigit = num_digits(len + ndigit);
- } while (old_ndigit != ndigit);
-
- return ndigit;
-}
-
-static int write_schily_xattr(ostream_t *fp, const struct stat *orig,
- const char *name, const tar_xattr_t *xattr)
-{
- static const char *prefix = "SCHILY.xattr.";
- size_t len, total_size = 0;
- const tar_xattr_t *it;
- struct stat sb;
-
- for (it = xattr; it != NULL; it = it->next) {
- len = strlen(prefix) + strlen(it->key) + it->value_len + 3;
-
- total_size += len + prefix_digit_len(len);
- }
-
- sb = *orig;
- sb.st_mode = S_IFREG | 0644;
- sb.st_size = total_size;
-
- if (write_header(fp, &sb, name, NULL, TAR_TYPE_PAX))
- return -1;
-
- for (it = xattr; it != NULL; it = it->next) {
- len = strlen(prefix) + strlen(it->key) + it->value_len + 3;
- len += prefix_digit_len(len);
-
- if (ostream_printf(fp, PRI_SZ " %s%s=",
- len, prefix, it->key) < 0) {
- return -1;
- }
- if (ostream_append(fp, it->value, it->value_len))
- return -1;
- if (ostream_append(fp, "\n", 1))
- return -1;
- }
-
- return padd_file(fp, total_size);
-}
-
-int write_tar_header(ostream_t *fp, const struct stat *sb, const char *name,
- const char *slink_target, const tar_xattr_t *xattr,
- unsigned int counter)
-{
- const char *reason;
- char buffer[64];
- int type;
-
- if (xattr != NULL) {
- sprintf(buffer, "pax/xattr%u", counter);
-
- if (write_schily_xattr(fp, sb, buffer, xattr))
- return -1;
- }
-
- if (!S_ISLNK(sb->st_mode))
- slink_target = NULL;
-
- if (S_ISLNK(sb->st_mode) && sb->st_size >= 100) {
- sprintf(buffer, "gnu/target%u", counter);
- if (write_gnu_header(fp, sb, slink_target, sb->st_size,
- TAR_TYPE_GNU_SLINK, buffer))
- return -1;
- slink_target = NULL;
- }
-
- if (strlen(name) >= 100) {
- sprintf(buffer, "gnu/name%u", counter);
-
- if (write_gnu_header(fp, sb, name, strlen(name),
- TAR_TYPE_GNU_PATH, buffer)) {
- return -1;
- }
-
- sprintf(buffer, "gnu/data%u", counter);
- name = buffer;
- }
-
- switch (sb->st_mode & S_IFMT) {
- case S_IFCHR: type = TAR_TYPE_CHARDEV; break;
- case S_IFBLK: type = TAR_TYPE_BLOCKDEV; break;
- case S_IFLNK: type = TAR_TYPE_SLINK; break;
- case S_IFREG: type = TAR_TYPE_FILE; break;
- case S_IFDIR: type = TAR_TYPE_DIR; break;
- case S_IFIFO: type = TAR_TYPE_FIFO; break;
- case S_IFSOCK:
- reason = "cannot pack socket";
- goto out_skip;
- default:
- reason = "unknown type";
- goto out_skip;
- }
-
- return write_header(fp, sb, name, slink_target, type);
-out_skip:
- fprintf(stderr, "WARNING: %s: %s\n", name, reason);
- return 1;
-}
-
-int write_hard_link(ostream_t *fp, const struct stat *sb, const char *name,
- const char *target, unsigned int counter)
-{
- tar_header_t hdr;
- char buffer[64];
- size_t len;
-
- memset(&hdr, 0, sizeof(hdr));
-
- len = strlen(target);
- if (len >= 100) {
- sprintf(buffer, "gnu/target%u", counter);
- if (write_gnu_header(fp, sb, target, len,
- TAR_TYPE_GNU_SLINK, buffer))
- return -1;
- sprintf(hdr.linkname, "hardlink_%u", counter);
- } else {
- memcpy(hdr.linkname, target, len);
- }
-
- len = strlen(name);
- if (len >= 100) {
- sprintf(buffer, "gnu/name%u", counter);
- if (write_gnu_header(fp, sb, name, len,
- TAR_TYPE_GNU_PATH, buffer)) {
- return -1;
- }
- sprintf(hdr.name, "gnu/data%u", counter);
- } else {
- memcpy(hdr.name, name, len);
- }
-
- write_number(hdr.mode, sb->st_mode & ~S_IFMT, sizeof(hdr.mode));
- write_number(hdr.uid, sb->st_uid, sizeof(hdr.uid));
- write_number(hdr.gid, sb->st_gid, sizeof(hdr.gid));
- write_number(hdr.size, 0, sizeof(hdr.size));
- write_number_signed(hdr.mtime, sb->st_mtime, sizeof(hdr.mtime));
- hdr.typeflag = TAR_TYPE_LINK;
- memcpy(hdr.magic, TAR_MAGIC_OLD, sizeof(hdr.magic));
- memcpy(hdr.version, TAR_VERSION_OLD, sizeof(hdr.version));
- sprintf(hdr.uname, "%u", sb->st_uid);
- sprintf(hdr.gname, "%u", sb->st_gid);
- write_number(hdr.devmajor, 0, sizeof(hdr.devmajor));
- write_number(hdr.devminor, 0, sizeof(hdr.devminor));
-
- update_checksum(&hdr);
- return ostream_append(fp, &hdr, sizeof(hdr));
-}