diff options
Diffstat (limited to 'unpack')
| -rw-r--r-- | unpack/list_files.c | 75 | 
1 files changed, 69 insertions, 6 deletions
| diff --git a/unpack/list_files.c b/unpack/list_files.c index aaf0652..86bc185 100644 --- a/unpack/list_files.c +++ b/unpack/list_files.c @@ -1,6 +1,8 @@  /* SPDX-License-Identifier: GPL-3.0-or-later */  #include "unsquashfs.h" +#include <sys/sysmacros.h> +  static void mode_to_str(uint16_t mode, char *p)  {  	switch (mode & S_IFMT) { @@ -59,10 +61,51 @@ static int count_int_chars(unsigned int i)  	return count;  } +static void print_size(uint64_t size, char *buffer) +{ +	static const char *suffices = "kMGTPEZY"; +	int suffix = -1; + +	while (size > 1024) { +		++suffix; +		size /= 1024; +	} + +	if (suffix >= 0) { +		sprintf(buffer, "%u%c", (unsigned int)size, suffices[suffix]); +	} else { +		sprintf(buffer, "%u", (unsigned int)size); +	} +} + +static void print_node_size(tree_node_t *n, char *buffer) +{ +	switch (n->mode & S_IFMT) { +	case S_IFLNK: +		print_size(strlen(n->data.slink_target), buffer); +		break; +	case S_IFREG: +		print_size(n->data.file->size, buffer); +		break; +	case S_IFDIR: +		print_size(n->data.dir->size, buffer); +		break; +	case S_IFBLK: +	case S_IFCHR: +		sprintf(buffer, "%u:%u", major(n->data.devno), +			minor(n->data.devno)); +		break; +	default: +		buffer[0] = '0'; +		buffer[1] = '\0'; +		break; +	} +} +  void list_files(tree_node_t *node)  { -	int i, max_uid_chars = 0, max_gid_chars = 0; -	char modestr[12]; +	int i, max_uid_chars = 0, max_gid_chars = 0, max_sz_chars = 0; +	char modestr[12], sizestr[32];  	tree_node_t *n;  	if (S_ISDIR(node->mode)) { @@ -72,19 +115,39 @@ void list_files(tree_node_t *node)  			i = count_int_chars(n->gid);  			max_gid_chars = i > max_gid_chars ? i : max_gid_chars; + +			print_node_size(n, sizestr); +			i = strlen(sizestr); +			max_sz_chars = i > max_sz_chars ? i : max_sz_chars;  		}  		for (n = node->data.dir->children; n != NULL; n = n->next) {  			mode_to_str(n->mode, modestr); +			print_node_size(n, sizestr); -			printf("%s %*u/%-*u %s\n", modestr, +			printf("%s %*u/%-*u %*s %s", modestr,  			       max_uid_chars, n->uid, -			       max_gid_chars, n->gid, n->name); +			       max_gid_chars, n->gid, +			       max_sz_chars, sizestr, +			       n->name); + +			if (S_ISLNK(n->mode)) { +				printf(" -> %s\n", n->data.slink_target); +			} else { +				fputc('\n', stdout); +			}  		}  	} else {  		mode_to_str(node->mode, modestr); +		print_node_size(node, sizestr); -		printf("%s %u/%u %s\n", modestr, -		       node->uid, node->gid, node->name); +		printf("%s %u/%u %s %s", modestr, +		       node->uid, node->gid, sizestr, node->name); + +		if (S_ISLNK(node->mode)) { +			printf(" -> %s\n", node->data.slink_target); +		} else { +			fputc('\n', stdout); +		}  	}  } | 
