From ba357e342af00a06fbce682e866232390780bbc5 Mon Sep 17 00:00:00 2001
From: Patrick McDermott <patrick.mcdermott@libiquity.com>
Date: Fri, 12 May 2023 13:02:53 -0400
Subject: opk/read: List device major and minor numbers

---
(limited to 'src')

diff --git a/src/opk/read.c b/src/opk/read.c
index e0f3af4..5341a96 100644
--- a/src/opk/read.c
+++ b/src/opk/read.c
@@ -289,12 +289,19 @@ _opkg_opk_opk_read_data(struct opkg_opk_opk *opk)
 	size_t                        gname_len;
 	size_t                        gname_len_max;
 	uint64_t                      size_max;
+	uint32_t                      devmajor_max;
+	uint32_t                      devminor_max;
 	int                           ret_read;
 	char                         *buffer;
 	size_t                        size;
 	long int                      size_len_max;
+	long int                      devmajor_len_max;
+	long int                      devminor_len_max;
+	long int                      dev_len_max;
 	char                          fmt[26];
-	                              /* "%c%s %-32s/%-32s %11d %s " */
+	                              /* "%c%s %-32s/%-32s %16d %s " */
+	char                          fmt_dev[30];
+	                              /* "%c%s %-32s/%-32s %9d, %7d %s " */
 	int                           len;
 	char                          mode[10];
 	char                          mtime[20];
@@ -314,6 +321,8 @@ _opkg_opk_opk_read_data(struct opkg_opk_opk *opk)
 	uname_len_max = 0;
 	gname_len_max = 0;
 	size_max      = 0;
+	devmajor_max  = 0;
+	devminor_max  = 0;
 	while ((ret = opkg_opk_ustar_list(opk->inner_ustar, &member)) ==
 			OPKG_OPK_OK) {
 		/* If listing, link members and update max column widths. */
@@ -335,6 +344,12 @@ _opkg_opk_opk_read_data(struct opkg_opk_opk *opk)
 			if (member->size > size_max) {
 				size_max = member->size;
 			}
+			if (member->devmajor > devmajor_max) {
+				devmajor_max = member->devmajor;
+			}
+			if (member->devminor > devminor_max) {
+				devminor_max = member->devminor;
+			}
 		}
 
 		if (opk->print_data_head == NULL) {
@@ -396,9 +411,19 @@ _opkg_opk_opk_read_data(struct opkg_opk_opk *opk)
 		puts("");
 	}
 	ret = OPKG_OPK_OK;
-	size_len_max = lrint(ceil(log10(size_max)));
-	snprintf(fmt, sizeof(fmt), "%%c%%s %%-%zus/%%-%zus %%%lid %%s ",
+	size_len_max     = lrint(ceil(log10(    size_max)));
+	devmajor_len_max = lrint(ceil(log10(devmajor_max)));
+	devminor_len_max = lrint(ceil(log10(devminor_max)));
+	dev_len_max = devmajor_len_max + 2 /* ", " */ + devminor_len_max;
+	if (dev_len_max > size_len_max) {
+		size_len_max = dev_len_max;
+	}
+	snprintf(fmt    , sizeof(fmt    ), "%%c%%s %%-%zus/%%-%zus %%%lid %%s ",
 			uname_len_max, gname_len_max, size_len_max);
+	snprintf(fmt_dev, sizeof(fmt_dev), "%%c%%s %%-%zus/%%-%zus "
+			"%%%lid, %%%lid %%s ",
+			uname_len_max, gname_len_max,
+			size_len_max - devminor_len_max - 2, devminor_len_max);
 	len = 34 + uname_len_max + gname_len_max + size_len_max;
 	for (member = head; member != NULL;) {
 		if (member->mode & 00400) mode[0] = 'r'; else mode[0] = '-';
@@ -418,10 +443,19 @@ _opkg_opk_opk_read_data(struct opkg_opk_opk *opk)
 				localtime((const time_t *) &member->mtime));
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
-		if (printf(fmt, member->type, mode,
-				member->uname, member->gname,
-				member->size, mtime) != len) {
-			ret = OPKG_OPK_ERROR;
+		if (member->type != 'b' && member->type != 'c') {
+			if (printf(fmt, member->type, mode,
+					member->uname, member->gname,
+					member->size, mtime) != len) {
+				ret = OPKG_OPK_ERROR;
+			}
+		} else {
+			if (printf(fmt_dev, member->type, mode,
+					member->uname, member->gname,
+					member->devmajor, member->devminor,
+					mtime) != len) {
+				ret = OPKG_OPK_ERROR;
+			}
 		}
 #pragma GCC diagnostic pop
 		/* Print name, ensuring it begins with "/". */
--
cgit v0.9.1