diff --git a/tar.c b/tar.c index 71719b0..4a81f8f 100644 --- a/tar.c +++ b/tar.c @@ -29,6 +29,12 @@ enum Type { RESERVED = '7' }; +enum Error { + BADCHKSUM, + BADMAGIC, + BADPATH +}; + struct header { char name[100]; char mode[8]; @@ -71,6 +77,12 @@ static const char *filtertools[] = { ['z'] = "gzip", }; +static const char *errors[] = { + [BADCHKSUM] = "bad checksum", + [BADMAGIC] = "bad magic", + [BADPATH] = "empty filename" +}; + static void pushdirtime(char *name, time_t mtime) { @@ -407,27 +419,36 @@ chktar(struct header *h) char tmp[8], *err; char *p = (char *)h; long s1, s2, i; + int errnum; - if (h->prefix[0] == '\0' && h->name[0] == '\0') + if (h->prefix[0] == '\0' && h->name[0] == '\0') { + errnum = BADPATH; goto bad; - if (h->magic[0] && strncmp("ustar", h->magic, 5)) + } + if (h->magic[0] && strncmp("ustar", h->magic, 5)) { + errnum = BADMAGIC; goto bad; + } memcpy(tmp, h->chksum, sizeof(tmp)); for (i = 0; i < sizeof(tmp); i++) if (tmp[i] == ' ') tmp[i] = '\0'; s1 = strtol(tmp, &err, 8); - if (s1 < 0 || *err != '\0') + if (s1 < 0 || *err != '\0') { + errnum = BADCHKSUM; goto bad; + } memset(h->chksum, ' ', sizeof(h->chksum)); for (i = 0, s2 = 0; i < sizeof(*h); i++) s2 += (unsigned char)p[i]; - if (s1 != s2) + if (s1 != s2) { + errnum = BADCHKSUM; goto bad; + } memcpy(h->chksum, tmp, sizeof(h->chksum)); return; bad: - eprintf("malformed tar archive\n"); + eprintf("malformed tar archive: %s\n", errors[errnum]); } static void