Small utility collection for dealing with file archives that have dependencies
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

204 lines
4.6 KiB

/* SPDX-License-Identifier: ISC */
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include "filelist/image_entry.h"
typedef int (*print_fun_t)(image_entry_t *ent, const char *root);
static int print_pretty(image_entry_t *ent, const char *root)
{
(void)root;
printf("%s\n", ent->name);
printf("\towner: %d/%d\n", ent->uid, ent->gid);
printf("\tpermissions: 0%04o\n", ent->mode & (~S_IFMT));
fputs("\ttype: ", stdout);
switch (ent->mode & S_IFMT) {
case S_IFLNK:
fputs("symlink\n", stdout);
printf("\ttarget: %s\n\n", ent->data.symlink.target);
break;
case S_IFREG:
fputs("file\n", stdout);
printf("\tsize: %lu\n", (unsigned long)ent->data.file.size);
printf("\tid: %u\n\n", (unsigned int)ent->data.file.id);
break;
case S_IFDIR:
fputs("directory\n\n", stdout);
break;
case S_IFCHR:
fputs("character device\n", stdout);
printf("\tmajor: %u\n\tminor: %u\n\n",
major(ent->data.device.devno),
minor(ent->data.device.devno));
break;
case S_IFBLK:
fputs("block device\n", stdout);
printf("\tmajor: %u\n\tminor: %u\n\n",
major(ent->data.device.devno),
minor(ent->data.device.devno));
break;
default:
fputs("unknown\n\n", stdout);
goto fail_type;
}
return 0;
fail_type:
fputs("unknown file type in table of contents\n", stderr);
return -1;
}
static int print_sqfs(image_entry_t *ent, const char *root)
{
mode_t mode = ent->mode & (~S_IFMT);
(void)root;
switch (ent->mode & S_IFMT) {
case S_IFCHR:
printf("%s c %o %u %u %u %u\n", ent->name, mode,
(unsigned int)ent->uid, (unsigned int)ent->gid,
major(ent->data.device.devno),
minor(ent->data.device.devno));
break;
case S_IFBLK:
printf("%s b %o %u %u %u %u\n", ent->name, mode,
(unsigned int)ent->uid, (unsigned int)ent->gid,
major(ent->data.device.devno),
minor(ent->data.device.devno));
break;
case S_IFLNK:
mode = 0777;
/* fall-through */
case S_IFDIR:
case S_IFREG:
printf("%s m %o %u %u\n", ent->name, mode,
(unsigned int)ent->uid, (unsigned int)ent->gid);
break;
default:
fputs("unknown file type in table of contents\n", stderr);
return -1;
}
return 0;
}
static int print_initrd(image_entry_t *ent, const char *root)
{
mode_t mode = ent->mode & (~S_IFMT);
switch (ent->mode & S_IFMT) {
case S_IFCHR:
printf("nod /%s 0%o %u %u c %u %u\n", ent->name, mode,
(unsigned int)ent->uid, (unsigned int)ent->gid,
major(ent->data.device.devno),
minor(ent->data.device.devno));
return 0;
case S_IFBLK:
printf("nod /%s 0%o %u %u b %u %u\n", ent->name, mode,
(unsigned int)ent->uid, (unsigned int)ent->gid,
major(ent->data.device.devno),
minor(ent->data.device.devno));
return 0;
case S_IFLNK:
printf("slink /%s %s", ent->name, ent->data.symlink.target);
mode = 0777;
break;
case S_IFREG:
printf("file /%s ", ent->name);
if (root == NULL) {
fputs(ent->name, stdout);
} else {
printf("%s/%s", root, ent->name);
}
break;
case S_IFDIR:
printf("dir /%s", ent->name);
break;
default:
fputs("unknown file type in table of contents\n", stderr);
return -1;
}
printf(" 0%o %u %u\n", mode,
(unsigned int)ent->uid, (unsigned int)ent->gid);
return 0;
}
static int print_pkg(image_entry_t *ent, const char *root)
{
mode_t mode = ent->mode & (~S_IFMT);
switch (ent->mode & S_IFMT) {
case S_IFLNK:
mode = 0777;
fputs("slink", stdout);
break;
case S_IFREG:
fputs("file", stdout);
break;
case S_IFDIR:
fputs("dir", stdout);
break;
case S_IFCHR:
case S_IFBLK:
fputs("nod", stdout);
break;
default:
fputs("unknown file type in table of contents\n", stderr);
return -1;
}
printf(" %s 0%o %u %u ", ent->name, mode,
(unsigned int)ent->uid, (unsigned int)ent->gid);
switch (ent->mode & S_IFMT) {
case S_IFCHR:
printf("c %u %u", major(ent->data.device.devno),
minor(ent->data.device.devno));
break;
case S_IFBLK:
printf("b %u %u", major(ent->data.device.devno),
minor(ent->data.device.devno));
break;
case S_IFLNK:
fputs(ent->data.symlink.target, stdout);
break;
case S_IFREG:
if (root == NULL) {
printf("%s", ent->name);
} else {
printf("%s/%s", root, ent->name);
}
break;
}
fputc('\n', stdout);
return 0;
}
static print_fun_t printers[] = {
[TOC_FORMAT_PRETTY] = print_pretty,
[TOC_FORMAT_SQFS] = print_sqfs,
[TOC_FORMAT_INITRD] = print_initrd,
[TOC_FORMAT_PKG] = print_pkg,
};
int dump_toc(image_entry_t *list, const char *root, TOC_FORMAT format)
{
while (list != NULL) {
if (printers[format](list, root))
return -1;
list = list->next;
}
return 0;
}