From ed0f307c89ce6e9c766a9405cee19f0cc60f1ce0 Mon Sep 17 00:00:00 2001 From: Patrick McDermott Date: Mon, 17 Apr 2023 19:25:05 -0400 Subject: ustar, main: Dynamically allocate member structs TODO: Save max strlen()s in first loop and printf() and free() in second loop. --- diff --git a/src/main.c b/src/main.c index 84ff164..c3ab9f7 100644 --- a/src/main.c +++ b/src/main.c @@ -149,30 +149,31 @@ _opkg_opk_main_read_control(struct opkg_opk_ustar *ustar) static int _opkg_opk_main_list_members(struct opkg_opk_ustar *ustar) { - struct opkg_opk_ustar_member member; + struct opkg_opk_ustar_member *member; int ret; char mode[10]; char mtime[20]; while ((ret = opkg_opk_ustar_list(ustar, &member)) == OPKG_OPK_OK) { - if (member.mode & 00400) mode[0] = 'r'; else mode[0] = '-'; - if (member.mode & 00200) mode[1] = 'w'; else mode[1] = '-'; - if (member.mode & 00100) mode[2] = 'x'; else mode[2] = '-'; - if (member.mode & 04000) mode[2] = 's'; - if (member.mode & 00040) mode[3] = 'r'; else mode[3] = '-'; - if (member.mode & 00020) mode[4] = 'w'; else mode[4] = '-'; - if (member.mode & 00010) mode[5] = 'x'; else mode[5] = '-'; - if (member.mode & 02000) mode[5] = 's'; - if (member.mode & 00004) mode[6] = 'r'; else mode[6] = '-'; - if (member.mode & 00002) mode[7] = 'w'; else mode[7] = '-'; - if (member.mode & 00001) mode[8] = 'x'; else mode[8] = '-'; - if (member.mode & 01000) mode[8] = 't'; + if (member->mode & 00400) mode[0] = 'r'; else mode[0] = '-'; + if (member->mode & 00200) mode[1] = 'w'; else mode[1] = '-'; + if (member->mode & 00100) mode[2] = 'x'; else mode[2] = '-'; + if (member->mode & 04000) mode[2] = 's'; + if (member->mode & 00040) mode[3] = 'r'; else mode[3] = '-'; + if (member->mode & 00020) mode[4] = 'w'; else mode[4] = '-'; + if (member->mode & 00010) mode[5] = 'x'; else mode[5] = '-'; + if (member->mode & 02000) mode[5] = 's'; + if (member->mode & 00004) mode[6] = 'r'; else mode[6] = '-'; + if (member->mode & 00002) mode[7] = 'w'; else mode[7] = '-'; + if (member->mode & 00001) mode[8] = 'x'; else mode[8] = '-'; + if (member->mode & 01000) mode[8] = 't'; mode[9] = '\0'; strftime(mtime, sizeof(mtime), "%Y-%m-%d %H:%M:%S", - localtime(&member.mtime)); + localtime(&member->mtime)); printf("%c%s %32s/%-32s %11d %s %s\n", - member.type, mode, member.uname, member.gname, - member.size, mtime, member.name); + member->type, mode, + member->uname, member->gname, + member->size, mtime, member->name); } if (ret == OPKG_OPK_ERROR) { fputs("Error: Failed to list data files\n", stderr); diff --git a/src/ustar.c b/src/ustar.c index a277f15..7df8c43 100644 --- a/src/ustar.c +++ b/src/ustar.c @@ -141,7 +141,7 @@ _opkg_opk_ustar_next(struct opkg_opk_ustar *ustar, int opkg_opk_ustar_list(struct opkg_opk_ustar *ustar, - struct opkg_opk_ustar_member *member) + struct opkg_opk_ustar_member **member) { static struct _opkg_opk_ustar_header header; int ret; @@ -151,54 +151,63 @@ opkg_opk_ustar_list(struct opkg_opk_ustar *ustar, return ret; /* Error or end of archive */ } + *member = malloc(sizeof(**member)); + if (*member == NULL) { + return OPKG_OPK_ERROR; + } + if (header.prefix[0] != '\0') { - sprintf(member->name, "%s/%s", header.prefix, header.name); + sprintf((*member)->name, "%s/%s", header.prefix, header.name); } else { - memcpy(member->name, header.name, sizeof(header.name)); - member->name[sizeof(header.name)] = '\0'; + memcpy((*member)->name, header.name, sizeof(header.name)); + (*member)->name[sizeof(header.name)] = '\0'; } - member->mode = strtol((char *) header.mode, &end, + (*member)->mode = strtol((char *) 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((char *) header.mtime, &end, + (*member)->size = ustar->data_size_remaining; + (*member)->mtime = strtol((char *) header.mtime, &end, OPKG_OPK_USTAR_NUM_BASE_); if (*end != '\0') { + free(*member); return OPKG_OPK_ERROR; } switch (*header.typeflag) { case '0': /* Regular file */ case '7': /* High-performance or regular file */ - member->type = '-'; + (*member)->type = '-'; break; case '2': /* Symbolic link */ - member->type = 'l'; - strncpy(member->linkname, header.linkname, - sizeof(member->linkname)); + (*member)->type = 'l'; + strncpy((*member)->linkname, header.linkname, + sizeof((*member)->linkname)); break; case '3': /* Character special file */ - member->type = 'c'; + (*member)->type = 'c'; break; case '4': /* Block special file */ - member->type = 'b'; + (*member)->type = 'b'; break; case '5': /* Directory */ - member->type = 'd'; + (*member)->type = 'd'; break; case '6': /* FIFO special file */ - member->type = 'p'; + (*member)->type = 'p'; break; case '1': /* Link */ default: /* Reserved */ + 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, header.uname, sizeof((*member)->uname)); + strncpy((*member)->gname, header.gname, sizeof((*member)->gname)); while (ustar->data_size_remaining > 0) { if (opkg_opk_ustar_read(ustar, NULL, NULL) == OPKG_OPK_ERROR) { + free(*member); return OPKG_OPK_ERROR; } } diff --git a/src/ustar.h b/src/ustar.h index 7c4c089..d526239 100644 --- a/src/ustar.h +++ b/src/ustar.h @@ -29,14 +29,15 @@ struct opkg_opk_ustar; struct opkg_opk_ustar_member { - char name[OPKG_OPK_USTAR_NAME_MAX_LEN]; - uint16_t mode; - int64_t size; - int64_t mtime; - char type; - char linkname[100]; - char uname [32]; - char gname [32]; + char name[OPKG_OPK_USTAR_NAME_MAX_LEN]; + uint16_t mode; + int64_t size; + int64_t mtime; + char type; + char linkname[100]; + char uname [32]; + char gname [32]; + struct opkg_opk_ustar_member *next; }; struct opkg_opk_ustar * @@ -44,7 +45,7 @@ opkg_opk_ustar_init(struct opkg_opk_gzip *gzip); int opkg_opk_ustar_list(struct opkg_opk_ustar *ustar, - struct opkg_opk_ustar_member *member); + struct opkg_opk_ustar_member **member); int opkg_opk_ustar_seek(struct opkg_opk_ustar *ustar, int num_keys, ...); -- cgit v0.9.1