diff options
Diffstat (limited to 'abuild-tar.c')
-rw-r--r-- | abuild-tar.c | 58 |
1 files changed, 37 insertions, 21 deletions
diff --git a/abuild-tar.c b/abuild-tar.c index 29b904f..8e778c4 100644 --- a/abuild-tar.c +++ b/abuild-tar.c @@ -58,9 +58,9 @@ static inline int dx(int c) return -1; } -static int get_octal(char *s, size_t l) +static size_t get_octal(char *s, size_t l) { - unsigned int val; + size_t val; int ch; val = 0; @@ -104,9 +104,9 @@ static void tarhdr_checksum(struct tar_header *hdr) put_octal(hdr->chksum, sizeof(hdr->chksum)-1, chksum); } -static int usage(void) +static int usage(FILE *out) { - fprintf(stderr, + fprintf(out, "abuild-tar " VERSION "\n" "\n" "usage: abuild-tar [--hash[=<algorithm>]] [--cut]\n" @@ -116,20 +116,22 @@ static int usage(void) " regular entries and output tar archive on stdout\n" " --cut Remove the end of file tar record\n" "\n"); + return 1; } static ssize_t full_read(int fd, void *buf, size_t count) { ssize_t total, n; + char *p = buf; total = 0; do { - n = read(fd, buf, count); + n = read(fd, p, count); if (n < 0 && errno == EINTR) continue; if (n <= 0) break; - buf += n; + p += n; total += n; count -= n; } while (1); @@ -143,15 +145,16 @@ static ssize_t full_read(int fd, void *buf, size_t count) static ssize_t full_write(int fd, const void *buf, size_t count) { ssize_t total, n; + const char *p = buf; total = 0; do { - n = write(fd, buf, count); + n = write(fd, p, count); if (n < 0 && errno == EINTR) continue; if (n <= 0) break; - buf += n; + p += n; total += n; count -= n; } while (1); @@ -218,7 +221,8 @@ static int buf_padto(struct buf *b, size_t alignment) newsize = (oldsize + alignment - 1) & -alignment; if (buf_resize(b, newsize)) return -ENOMEM; b->size = newsize; - memset(b->ptr + oldsize, 0, newsize - oldsize); + if (b->ptr) + memset(b->ptr + oldsize, 0, newsize - oldsize); return 0; } @@ -248,9 +252,8 @@ static int buf_write_fd(struct buf *b, int fd) return -ENOSPC; } -static int buf_add_ext_header_hexdump(struct buf *b, const char *hdr, const char *value, int valuelen) +static int buf_add_ext_header_hexdump(struct buf *b, const char *hdr, const unsigned char *value, int valuelen) { - size_t oldsize = b->size; int i, len; /* "%u %s=%s\n" */ @@ -258,15 +261,17 @@ static int buf_add_ext_header_hexdump(struct buf *b, const char *hdr, const char for (i = len; i > 9; i /= 10) len++; if (buf_resize(b, b->size + len)) return -ENOMEM; + if (b->ptr == NULL) + return 0; b->size += snprintf(&b->ptr[b->size], len, "%u %s=", len, hdr); for (i = 0; i < valuelen; i++) - b->size += snprintf(&b->ptr[b->size], 3, "%02x", (int)(unsigned char)value[i]); + b->size += snprintf(&b->ptr[b->size], 3, "%02x", (int)value[i]); b->ptr[b->size++] = '\n'; return 0; } -static void add_legacy_checksum(struct tar_header *hdr, const EVP_MD *md, const char *digest) +static void add_legacy_checksum(struct tar_header *hdr, const EVP_MD *md, const unsigned char *digest) { struct { char id[4]; @@ -284,10 +289,11 @@ static void add_legacy_checksum(struct tar_header *hdr, const EVP_MD *md, const static int do_it(const EVP_MD *md, int cut) { - char checksumhdr[32], digest[EVP_MAX_MD_SIZE]; + char checksumhdr[32]; + unsigned char digest[EVP_MAX_MD_SIZE]; struct buf data = BUF_INITIALIZER, pax = BUF_INITIALIZER; struct tar_header hdr, paxhdr; - size_t size, aligned_size; + size_t name_len, size, aligned_size; int dohash = 0, r, ret = 1; memset(&paxhdr, 0, sizeof(paxhdr)); @@ -319,7 +325,8 @@ static int do_it(const EVP_MD *md, int cut) EVP_Digest(data.ptr, size, digest, NULL, md, NULL); add_legacy_checksum(&hdr, md, digest); } else { - EVP_Digest(hdr.linkname, strlen(hdr.linkname), digest, NULL, md, NULL); + name_len = strnlen(hdr.linkname, sizeof(hdr.linkname)); + EVP_Digest(hdr.linkname, name_len, digest, NULL, md, NULL); } buf_add_ext_header_hexdump(&pax, checksumhdr, digest, EVP_MD_size(md)); @@ -364,9 +371,10 @@ err: int main(int argc, char **argv) { - static int cut = 0; + static int cut = 0, help = 0; static const struct option options[] = { { "hash", optional_argument }, + { "help", no_argument, &help, 1 }, { "cut", no_argument, &cut, 1 }, { NULL } }; @@ -375,23 +383,31 @@ int main(int argc, char **argv) int ndx; OpenSSL_add_all_algorithms(); +#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR < 3 ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); +#endif - while (getopt_long(argc, argv, "", options, &ndx) != -1) { + int c; + while ((c = getopt_long(argc, argv, "", options, &ndx)) != -1) { + if (c == '?') + return usage(stderr); if (ndx == 0) digest = optarg ? optarg : "sha1"; } + if (help) + return usage(stdout) && 0; + if (digest == NULL && cut == 0) - return usage(); + return usage(stderr); if (isatty(STDIN_FILENO)) - return usage(); + return usage(stderr); if (digest != NULL) { md = EVP_get_digestbyname(digest); if (md == NULL) - return usage(); + return usage(stderr); } return do_it(md, cut); |