From aa882cfe7c8bb66b9f31d7f6581a94bc9744c04b Mon Sep 17 00:00:00 2001 From: Nathan Wagner Date: Wed, 1 Mar 2017 06:38:23 -0600 Subject: [PATCH] add zpm-stat command for a portable stat interface --- .gitignore | 1 + Makefile | 4 +- zpm-stat.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 zpm-stat.c diff --git a/.gitignore b/.gitignore index 6d799aa..c38c26a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ zpm-extract zpm-init zpm-soneed zpm-hash +zpm-stat *.zpm *.db soname diff --git a/Makefile b/Makefile index 71c066b..d0f9fb7 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CFLAGS=-Wall -std=c99 -Ilib -Ielf -I. +CFLAGS=-Wall -std=c99 -Ilib -Ielf -I. -Ilzma/api LZMAFLAGS=-Ilzma/api -Ilzma/tuklib -Ilzma/lzma -Ilzma/common -Ilzma/check -Ilzma/lz -Ilzma/rangecoder -Ilzma/simple -Ilzma/delta -DHAVE_CHECK_CRC64 -DHAVE_CHECK_CRC32 -DHAVE_ENCODER_LZMA2 -DHAVE_DECODER_LZMA2 -DHAVE_MF_BT4 @@ -10,7 +10,7 @@ LZMAOBJ=$(filter-out lzma/common/stream_encoder_mt.o, $(LZMASRC:%.c=%.o)) curdir=$(shell pwd) -ZPKGBIN=zpm-addfile zpm-extract zpm-init zpm-vercmp +ZPKGBIN=zpm-addfile zpm-extract zpm-init zpm-vercmp zpm-stat def: programs d: printf '%s\n' $(LZMAOBJ) diff --git a/zpm-stat.c b/zpm-stat.c new file mode 100644 index 0000000..b85857a --- /dev/null +++ b/zpm-stat.c @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include +#include + +#include "zpm.h" + +/* + * a generic printf style format string parser + * takes a character pointer, returns pointer to next non + * parsed character, next token, optionally + * does a callback, fills in a format struct + */ + +#if 0 +char *fmt; +struct format f; + +while (*fmt) { + fmt = parse_format_str(fmt, &f); + if (!f.found) break; /* done */ + if (!f.flags) { + /* literal/noformat */ + putchar(f.found); /* or whatever */ + continue; + } + switch (f.found) { + case 'a': /* handle %a */ + break; + default: /* handle unknown formatting character */ + break; + } +} +#endif + +struct format_string { + int found; /* the 'd' in '%d' */ + unsigned flags; /* 1 = found, 0 = none found */ +}; + +char *format_string_parse(char *s, struct format_string *f) { + f->found = 0; + f->flags = 0; + + if (!*s) return s; /* done */ + + /* literal non-format specifier */ + if (*s != '%') { + f->found = *s++; + return s; + } + s++; + + f->flags = 1; + f->found = *s++; + return s; +} + +void stat_one(char *fmt, char *timefmt, char *filename) { + struct stat buf; + struct tm *tm; + char timestr[1024]; + struct format_string f; + struct passwd *pw; + struct group *gr; + + stat(filename, &buf); + + while (*fmt) { + fmt = format_string_parse(fmt, &f); + if (!f.found) break; /* done */ + if (!f.flags) { + /* literal/noformat */ + putchar(f.found); /* or whatever */ + continue; + } + switch (f.found) { + case 'y': /* handle mtime */ + tm = gmtime(&buf.st_mtime); + strftime(timestr, 1023, timefmt, tm); + timestr[1023] = 0; + printf("%s", timestr); + break; + case 'a': /* octal mode */ + printf("%o", (int)buf.st_mode & 07777); + break; + case 'u': /* handle uid */ + printf("%0d", buf.st_uid); + break; + case 'U': /* handle username */ + pw = getpwuid(buf.st_uid); + if (!pw) exit(1); + printf("%s", pw->pw_name); + break; + case 'g': /* handle gid */ + printf("%0d", buf.st_gid); + break; + case 'G': /* handle groupname */ + gr = getgrgid(buf.st_gid); + if (!gr) exit(1); + printf("%s", gr->gr_name); + break; + default: /* handle unknown formatting character */ + printf("%c", f.found); + break; + } + } + putchar('\n'); +} + +int main(int ac, char *av[]) { + char *fmt = "%y"; /* default stat is mtime */ + char *timefmt = "%s"; /* default time fmt is unix ts */ + int errflg = 0; + int c; + + while ((c = getopt(ac, av, "f:t:")) != -1) { + switch(c) { + case 'f': + fmt = optarg; + break; + case 't': + timefmt = optarg; + break; + case ':': /* -f or -t without operand */ + fprintf(stderr, + "Option -%c requires an operand\n", optopt); + errflg++; + break; + case '?': + fprintf(stderr, + "Unrecognized option: '-%c'\n", optopt); + errflg++; + } + } + if (errflg) { + fprintf(stderr, "zpm-stat [-f ] [-t ]"); + exit(2); + } + for ( ; optind < ac; optind++) { + stat_one(fmt, timefmt, av[optind]); + } + return 0; +} -- 2.40.0