From 6274fb230a7d4ee8ccd893b306541c2b13658bcc Mon Sep 17 00:00:00 2001 From: Nathan Wagner Date: Fri, 3 Mar 2017 07:28:30 -0600 Subject: [PATCH] add switch to zpm-stat to use lstat --- t/stat.t | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ zpm-stat.c | 50 ++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 87 insertions(+), 12 deletions(-) create mode 100755 t/stat.t diff --git a/t/stat.t b/t/stat.t new file mode 100755 index 0000000..ead3bc6 --- /dev/null +++ b/t/stat.t @@ -0,0 +1,49 @@ +#!/bin/sh + +# test addfile + +. tap.sh + +fn=$(echo $$ $(date) | zpm hash -) + +typetest() { + res=$(zpm-stat -f '%t' "$1") + okstreq "$res" "$2" "$1 is a $2" +} + +ltypetest() { + res=$(zpm-stat -l -f '%t' "$1") + okstreq "$res" "$2" "$1 is a $2" +} + +plan 16 + +file="/tmp/$fn" + +# directory +tryrun mkdir $file +typetest $file directory +ltypetest $file directory +tryrun rmdir $file + +#regular file +tryrun touch $file +typetest $file regular +ltypetest $file regular + +# symlink +require ln -s $file $file.symlink +typetest $file.symlink regular +ltypetest $file.symlink symlink +require rm $file.symlink +require rm $file + +# fifo +require mkfifo $file +typetest $file fifo +require rm $file + +# block and char specials probably require root to create +typetest /dev/null character + +finish diff --git a/zpm-stat.c b/zpm-stat.c index b85857a..4c95aa5 100644 --- a/zpm-stat.c +++ b/zpm-stat.c @@ -58,16 +58,13 @@ char *format_string_parse(char *s, struct format_string *f) { return s; } -void stat_one(char *fmt, char *timefmt, char *filename) { - struct stat buf; +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 */ @@ -78,27 +75,46 @@ void stat_one(char *fmt, char *timefmt, char *filename) { } switch (f.found) { case 'y': /* handle mtime */ - tm = gmtime(&buf.st_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); + printf("%o", (int)buf->st_mode & 07777); + break; + case 't': + if (S_ISBLK(buf->st_mode)) { + printf("block"); + } else if (S_ISCHR(buf->st_mode)) { + printf("character"); + } else if (S_ISDIR(buf->st_mode)) { + printf("directory"); + } else if (S_ISFIFO(buf->st_mode)) { + printf("fifo"); + } else if (S_ISREG(buf->st_mode)) { + printf("regular"); + } else if (S_ISLNK(buf->st_mode)) { + printf("symlink"); + } else if (S_ISSOCK(buf->st_mode)) { + printf("socket"); + } else { + printf("unknown"); + } break; case 'u': /* handle uid */ - printf("%0d", buf.st_uid); + printf("%0d", buf->st_uid); break; case 'U': /* handle username */ - pw = getpwuid(buf.st_uid); + pw = getpwuid(buf->st_uid); if (!pw) exit(1); printf("%s", pw->pw_name); break; case 'g': /* handle gid */ - printf("%0d", buf.st_gid); + printf("%0d", buf->st_gid); break; case 'G': /* handle groupname */ - gr = getgrgid(buf.st_gid); + gr = getgrgid(buf->st_gid); if (!gr) exit(1); printf("%s", gr->gr_name); break; @@ -115,8 +131,9 @@ int main(int ac, char *av[]) { char *timefmt = "%s"; /* default time fmt is unix ts */ int errflg = 0; int c; + int uselstat = 0; - while ((c = getopt(ac, av, "f:t:")) != -1) { + while ((c = getopt(ac, av, "lf:t:")) != -1) { switch(c) { case 'f': fmt = optarg; @@ -129,6 +146,9 @@ int main(int ac, char *av[]) { "Option -%c requires an operand\n", optopt); errflg++; break; + case 'l': + uselstat = 1; + break; case '?': fprintf(stderr, "Unrecognized option: '-%c'\n", optopt); @@ -140,7 +160,13 @@ int main(int ac, char *av[]) { exit(2); } for ( ; optind < ac; optind++) { - stat_one(fmt, timefmt, av[optind]); + struct stat buf; + if (uselstat) { + lstat(av[optind], &buf); + } else { + stat(av[optind], &buf); + } + stat_one(fmt, timefmt, av[optind], &buf); } return 0; } -- 2.40.0