From 60f7c693d50898cd7c60d0ff607715945d5ab0b3 Mon Sep 17 00:00:00 2001 From: Patrick McDermott Date: Tue, 18 Apr 2023 07:40:16 -0400 Subject: main: Set max column widths and free members --- diff --git a/TODO b/TODO index 31e6a3c..50f4036 100644 --- a/TODO +++ b/TODO @@ -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]) diff --git a/src/main.c b/src/main.c index c3ab9f7..8e7437a 100644 --- a/src/main.c +++ b/src/main.c @@ -17,8 +17,10 @@ * along with opkg-opk. If not, see . */ +#include #include #include +#include #include #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; -- cgit v0.9.1