]> pd.if.org Git - zpackage/commitdiff
add zpm-stat command for a portable stat interface
authorNathan Wagner <nw@hydaspes.if.org>
Wed, 1 Mar 2017 12:38:23 +0000 (06:38 -0600)
committerNathan Wagner <nw@hydaspes.if.org>
Wed, 1 Mar 2017 12:56:47 +0000 (06:56 -0600)
.gitignore
Makefile
zpm-stat.c [new file with mode: 0644]

index 6d799aa67140a5adc77231bad3d4c9912abb154c..c38c26a4a868308ec5c4b5224df0a0fc528155cb 100644 (file)
@@ -8,6 +8,7 @@ zpm-extract
 zpm-init
 zpm-soneed
 zpm-hash
+zpm-stat
 *.zpm
 *.db
 soname
index 71c066b3430b4cc4de7db1b049777ad473f38d18..d0f9fb7cd82922284c584ebfbd731878e028611e 100644 (file)
--- 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 (file)
index 0000000..b85857a
--- /dev/null
@@ -0,0 +1,146 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#include <grp.h>
+
+#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 <format>] [-t <timefmt>]");
+               exit(2);
+       }
+       for ( ; optind < ac; optind++) {
+               stat_one(fmt, timefmt, av[optind]);
+       }
+       return 0;
+}