]> pd.if.org Git - zpackage/commitdiff
add switch to zpm-stat to use lstat
authorNathan Wagner <nw@hydaspes.if.org>
Fri, 3 Mar 2017 13:28:30 +0000 (07:28 -0600)
committerNathan Wagner <nw@hydaspes.if.org>
Sun, 5 Mar 2017 15:05:14 +0000 (09:05 -0600)
t/stat.t [new file with mode: 0755]
zpm-stat.c

diff --git a/t/stat.t b/t/stat.t
new file mode 100755 (executable)
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
index b85857a0b59eb0f54419cf1af1445c9f16d9ee96..4c95aa5e888c5b4aad22e22066864d59f611af63 100644 (file)
@@ -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;
 }