aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/auth/secstore/dirls.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/auth/secstore/dirls.c')
-rw-r--r--src/cmd/auth/secstore/dirls.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/cmd/auth/secstore/dirls.c b/src/cmd/auth/secstore/dirls.c
new file mode 100644
index 00000000..b4479413
--- /dev/null
+++ b/src/cmd/auth/secstore/dirls.c
@@ -0,0 +1,87 @@
+#include <u.h>
+#include <libc.h>
+#include <mp.h>
+#include <libsec.h>
+#include "SConn.h"
+
+static long
+ls(char *p, Dir **dirbuf)
+{
+ int fd;
+ long n;
+ Dir *db;
+
+ if((db = dirstat(p)) == nil ||
+ !(db->qid.type & QTDIR) ||
+ (fd = open(p, OREAD)) < 0 )
+ return -1;
+ free(db);
+ n = dirreadall(fd, dirbuf);
+ close(fd);
+ return n;
+}
+
+static uchar*
+sha1file(char *pfx, char *nm)
+{
+ int n, fd, len;
+ char *tmp;
+ uchar buf[8192];
+ static uchar digest[SHA1dlen];
+ DigestState *s;
+
+ len = strlen(pfx)+1+strlen(nm)+1;
+ tmp = emalloc(len);
+ snprint(tmp, len, "%s/%s", pfx, nm);
+ if((fd = open(tmp, OREAD)) < 0){
+ free(tmp);
+ return nil;
+ }
+ free(tmp);
+ s = nil;
+ while((n = read(fd, buf, sizeof buf)) > 0)
+ s = sha1(buf, n, nil, s);
+ close(fd);
+ sha1(nil, 0, digest, s);
+ return digest;
+}
+
+static int
+compare(Dir *a, Dir *b)
+{
+ return strcmp(a->name, b->name);
+}
+
+/* list the (name mtime size sum) of regular, readable files in path */
+char *
+dirls(char *path)
+{
+ char *list, *date, dig[30], buf[128];
+ int m, nmwid, lenwid;
+ long i, n, ndir, len;
+ Dir *dirbuf;
+
+ if(path==nil || (ndir = ls(path, &dirbuf)) < 0)
+ return nil;
+
+ qsort(dirbuf, ndir, sizeof dirbuf[0], (int (*)(const void *, const void *))compare);
+ for(nmwid=lenwid=i=0; i<ndir; i++){
+ if((m = strlen(dirbuf[i].name)) > nmwid)
+ nmwid = m;
+ snprint(buf, sizeof(buf), "%ulld", dirbuf[i].length);
+ if((m = strlen(buf)) > lenwid)
+ lenwid = m;
+ }
+ for(list=nil, len=0, i=0; i<ndir; i++){
+ date = ctime(dirbuf[i].mtime);
+ date[28] = 0; // trim newline
+ n = snprint(buf, sizeof buf, "%*ulld %s", lenwid, dirbuf[i].length, date+4);
+ n += enc64(dig, sizeof dig, sha1file(path, dirbuf[i].name), SHA1dlen);
+ n += nmwid+3+strlen(dirbuf[i].name);
+ list = erealloc(list, len+n+1);
+ len += snprint(list+len, n+1, "%-*s\t%s %s\n", nmwid, dirbuf[i].name, buf, dig);
+ }
+ free(dirbuf);
+ return list;
+}
+