--- /dev/null
+#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;
+}