diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ustar.c | 103 |
1 files changed, 53 insertions, 50 deletions
diff --git a/src/ustar.c b/src/ustar.c index d8bd980..749af02 100644 --- a/src/ustar.c +++ b/src/ustar.c @@ -48,9 +48,10 @@ struct _opkg_opk_ustar_header { } __attribute__((__packed__)); struct opkg_opk_ustar { - struct opkg_opk_gzip *gzip; - uint64_t data_size_remaining; - char read_record[OPKG_OPK_USTAR_RECORD_SIZE]; + struct opkg_opk_gzip *gzip; + uint64_t data_size_remaining; + struct _opkg_opk_ustar_header header; + char read_record[OPKG_OPK_USTAR_RECORD_SIZE]; }; struct opkg_opk_ustar_seek_name { @@ -76,18 +77,16 @@ opkg_opk_ustar_init(struct opkg_opk_gzip *gzip) } static int -_opkg_opk_ustar_next(struct opkg_opk_ustar *ustar, - struct _opkg_opk_ustar_header *header) +_opkg_opk_ustar_next(struct opkg_opk_ustar *ustar) { - static char record[OPKG_OPK_USTAR_RECORD_SIZE]; - char *end; - uint32_t chksum_got; - uint32_t chksum_exp; - size_t i; - char *header_uc; + char *end; + uint32_t chksum_got; + uint32_t chksum_exp; + size_t i; + char *header_uc; /* Decompress next (hopefully valid header) record. */ - switch (opkg_opk_gzip_read(ustar->gzip, header)) { + switch (opkg_opk_gzip_read(ustar->gzip, &ustar->header)) { case OPKG_OPK_OK: break; case OPKG_OPK_END: @@ -97,27 +96,28 @@ _opkg_opk_ustar_next(struct opkg_opk_ustar *ustar, } /* Check for end of archive. */ - memset(record, 0, OPKG_OPK_USTAR_RECORD_SIZE); - if (memcmp(header, record, OPKG_OPK_USTAR_RECORD_SIZE) == 0) { + memset(ustar->read_record, 0, OPKG_OPK_USTAR_RECORD_SIZE); + if (memcmp(&ustar->header, ustar->read_record, + OPKG_OPK_USTAR_RECORD_SIZE) == 0) { return OPKG_OPK_END; } /* Verify magic. */ - if (memcmp(header->magic, "ustar", strlen("ustar")) != 0) { + if (memcmp(ustar->header.magic, "ustar", strlen("ustar")) != 0) { return OPKG_OPK_ERROR; } /* Verify checksum. */ - chksum_got = strtol(header->chksum, &end, + chksum_got = strtol(ustar->header.chksum, &end, OPKG_OPK_USTAR_NUM_BASE_); chksum_exp = 0; if (*end != '\0') { return OPKG_OPK_ERROR; } - for (i = 0; i < sizeof(header->chksum); ++i) { - header->chksum[i] = ' '; + for (i = 0; i < sizeof(ustar->header.chksum); ++i) { + ustar->header.chksum[i] = ' '; } - header_uc = (char *) header; + header_uc = (char *) &ustar->header; for (i = 0; i < OPKG_OPK_USTAR_RECORD_SIZE; ++i) { chksum_exp += header_uc[i]; } @@ -126,11 +126,11 @@ _opkg_opk_ustar_next(struct opkg_opk_ustar *ustar, } /* Depending on type, get size. */ - switch (*header->typeflag) { + switch (*ustar->header.typeflag) { case '0': /* Regular file */ case '7': /* High-performance or regular file */ ustar->data_size_remaining = strtol( - header->size, &end, + ustar->header.size, &end, OPKG_OPK_USTAR_NUM_BASE_); if (*end != '\0') { return OPKG_OPK_ERROR; @@ -155,12 +155,11 @@ int opkg_opk_ustar_list(struct opkg_opk_ustar *ustar, struct opkg_opk_ustar_member **member) { - static struct _opkg_opk_ustar_header header; - int ret; - char *end; + int ret; + char *end; /* Get next header record, if any. */ - if ((ret =_opkg_opk_ustar_next(ustar, &header)) != OPKG_OPK_OK) { + if ((ret =_opkg_opk_ustar_next(ustar)) != OPKG_OPK_OK) { return ret; /* Error or end of archive */ } @@ -171,35 +170,37 @@ opkg_opk_ustar_list(struct opkg_opk_ustar *ustar, } /* Set name, mode, size, mtime, type, linkname, uname, and gname. */ - if (header.prefix[0] != '\0') { - sprintf((*member)->name, "%s/%s", header.prefix, header.name); + if (ustar->header.prefix[0] != '\0') { + sprintf((*member)->name, "%s/%s", + ustar->header.prefix, ustar->header.name); } else { - /* Use memcpy() because header.name may not be NUL-terminated. - */ - memcpy((*member)->name, header.name, sizeof(header.name)); - (*member)->name[sizeof(header.name)] = '\0'; + /* Use memcpy() because ustar->header.name may not be + * NUL-terminated. */ + memcpy((*member)->name, ustar->header.name, + sizeof(ustar->header.name)); + (*member)->name[sizeof(ustar->header.name)] = '\0'; } - (*member)->mode = strtol(header.mode, &end, + (*member)->mode = strtol(ustar->header.mode, &end, OPKG_OPK_USTAR_NUM_BASE_); if (*end != '\0') { free(*member); return OPKG_OPK_ERROR; } (*member)->size = ustar->data_size_remaining; - (*member)->mtime = strtol(header.mtime, &end, + (*member)->mtime = strtol(ustar->header.mtime, &end, OPKG_OPK_USTAR_NUM_BASE_); if (*end != '\0') { free(*member); return OPKG_OPK_ERROR; } - switch (*header.typeflag) { + switch (*ustar->header.typeflag) { case '0': /* Regular file */ case '7': /* High-performance or regular file */ (*member)->type = '-'; break; case '2': /* Symbolic link */ (*member)->type = 'l'; - strncpy((*member)->linkname, header.linkname, + strncpy((*member)->linkname, ustar->header.linkname, sizeof((*member)->linkname)); break; case '3': /* Character special file */ @@ -219,8 +220,10 @@ opkg_opk_ustar_list(struct opkg_opk_ustar *ustar, free(*member); return OPKG_OPK_ERROR; /* Unsupported */ } - strncpy((*member)->uname, header.uname, sizeof((*member)->uname)); - strncpy((*member)->gname, header.gname, sizeof((*member)->gname)); + strncpy((*member)->uname, ustar->header.uname, + sizeof((*member)->uname)); + strncpy((*member)->gname, ustar->header.gname, + sizeof((*member)->gname)); /* Seek through data records until next header record. */ while (ustar->data_size_remaining > 0) { @@ -267,27 +270,27 @@ int opkg_opk_ustar_seek(struct opkg_opk_ustar *ustar, struct opkg_opk_ustar_seek_name *names) { - static struct _opkg_opk_ustar_header header; - static char name[OPKG_OPK_USTAR_NAME_SIZE]; - int found; - int found_all; - struct opkg_opk_ustar_seek_name *seek_name; + char name[OPKG_OPK_USTAR_NAME_SIZE]; + int found; + int found_all; + struct opkg_opk_ustar_seek_name *seek_name; for (;;) { /* Get next header record. */ - if (_opkg_opk_ustar_next(ustar, &header) != OPKG_OPK_OK) { + if (_opkg_opk_ustar_next(ustar) != OPKG_OPK_OK) { return OPKG_OPK_ERROR; /* Error or end (not found) */ } /* Prepare name (with prefix if any) for check. */ - if (header.prefix[0] != '\0') { - sprintf(name, "%s/%s", header.prefix, - header.name); + if (ustar->header.prefix[0] != '\0') { + sprintf(name, "%s/%s", ustar->header.prefix, + ustar->header.name); } else { - /* Use memcpy() because header.name may not be NUL- - * terminated. */ - memcpy(name, header.name, sizeof(header.name)); - name[sizeof(header.name)] = '\0'; + /* Use memcpy() because ustar->header.name may not be + * NUL-terminated. */ + memcpy(name, ustar->header.name, + sizeof(ustar->header.name)); + name[sizeof(ustar->header.name)] = '\0'; } /* Check each requested name. */ |