diff options
author | Patrick McDermott <patrick.mcdermott@libiquity.com> | 2023-04-18 07:40:16 (EDT) |
---|---|---|
committer | Patrick McDermott <patrick.mcdermott@libiquity.com> | 2023-04-18 08:59:33 (EDT) |
commit | 60f7c693d50898cd7c60d0ff607715945d5ab0b3 (patch) | |
tree | c660954c0ef6ce3251698d86d8b66e2269c9146a | |
parent | ed0f307c89ce6e9c766a9405cee19f0cc60f1ce0 (diff) |
main: Set max column widths and free members
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/main.c | 51 |
3 files changed, 48 insertions, 7 deletions
@@ -1,4 +1,2 @@ -Align ustar member fields to max column widths - Linked list of members, save max strlen()s on first pass Add option handling I18n? diff --git a/configure.ac b/configure.ac index 3f2dde0..4c3588b 100644 --- a/configure.ac +++ b/configure.ac @@ -33,6 +33,8 @@ AC_PROG_CC() AM_PROG_CC_C_O() test -d "${srcdir}/.git" || CFLAGS="${save_CFLAGS}" +AC_CHECK_LIB([m], [log10]) + PKG_PROG_PKG_CONFIG() PKG_CHECK_MODULES([ZLIB], [zlib]) @@ -17,8 +17,10 @@ * along with opkg-opk. If not, see <http://www.gnu.org/licenses/>. */ +#include <math.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <time.h> #include "defs.h" #include "gzip.h" @@ -149,12 +151,52 @@ _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 *head; + struct opkg_opk_ustar_member *tail; struct opkg_opk_ustar_member *member; int ret; + size_t uname_len; + size_t uname_len_max; + size_t gname_len; + size_t gname_len_max; + uint64_t size_max; + char fmt[29]; + /* "%c%s %-32s/%-32s %11d %s %s\n" */ char mode[10]; char mtime[20]; + head = NULL; + uname_len_max = 0; + gname_len_max = 0; + size_max = 0; while ((ret = opkg_opk_ustar_list(ustar, &member)) == OPKG_OPK_OK) { + if (head == NULL) { + head = member; + } else { + tail->next = member; + } + tail = member; + uname_len = strlen(member->uname); + if (uname_len > uname_len_max) { + uname_len_max = uname_len; + } + gname_len = strlen(member->gname); + if (gname_len > gname_len_max) { + gname_len_max = gname_len; + } + if (member->size > size_max) { + size_max = member->size; + } + } + if (ret == OPKG_OPK_ERROR) { + fputs("Error: Failed to list data files\n", stderr); + return OPKG_OPK_ERROR; + } + tail->next = NULL; + + snprintf(fmt, sizeof(fmt), "%%c%%s %%-%zus/%%-%zus %%%lid %%s %%s\n", + uname_len, gname_len, lrint(ceil(log10(size_max)))); + for (member = head; member != NULL;) { 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] = '-'; @@ -170,14 +212,13 @@ _opkg_opk_main_list_members(struct opkg_opk_ustar *ustar) mode[9] = '\0'; strftime(mtime, sizeof(mtime), "%Y-%m-%d %H:%M:%S", localtime(&member->mtime)); - printf("%c%s %32s/%-32s %11d %s %s\n", + printf(fmt, 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); - return OPKG_OPK_ERROR; + head = member; + member = member->next; + free(head); } return OPKG_OPK_OK; |