summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--configure.ac2
-rw-r--r--src/main.c51
3 files changed, 48 insertions, 7 deletions
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 <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;