diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 51 |
1 files changed, 46 insertions, 5 deletions
@@ -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; |