xref: /plan9-contrib/sys/src/cmd/auth/secstore/dirls.c (revision be0c1e85af510c365eaea6b4e03fd8ff93b34ae0)
19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <mp.h>
49a747e4fSDavid du Colombier #include <libsec.h>
59a747e4fSDavid du Colombier #include "SConn.h"
69a747e4fSDavid du Colombier 
79a747e4fSDavid du Colombier static long
ls(char * p,Dir ** dirbuf)89a747e4fSDavid du Colombier ls(char *p, Dir **dirbuf)
99a747e4fSDavid du Colombier {
109a747e4fSDavid du Colombier 	int fd;
119a747e4fSDavid du Colombier 	long n;
129a747e4fSDavid du Colombier 	Dir *db;
139a747e4fSDavid du Colombier 
149a747e4fSDavid du Colombier 	if((db = dirstat(p)) == nil ||
159a747e4fSDavid du Colombier 		!(db->qid.type & QTDIR) ||
169a747e4fSDavid du Colombier 		(fd = open(p, OREAD)) < 0 )
179a747e4fSDavid du Colombier 		return -1;
189a747e4fSDavid du Colombier 	free(db);
199a747e4fSDavid du Colombier 	n = dirreadall(fd, dirbuf);
209a747e4fSDavid du Colombier 	close(fd);
219a747e4fSDavid du Colombier 	return n;
229a747e4fSDavid du Colombier }
239a747e4fSDavid du Colombier 
249a747e4fSDavid du Colombier static uchar*
sha1file(char * pfx,char * nm)259a747e4fSDavid du Colombier sha1file(char *pfx, char *nm)
269a747e4fSDavid du Colombier {
279a747e4fSDavid du Colombier 	int n, fd, len;
289a747e4fSDavid du Colombier 	char *tmp;
299a747e4fSDavid du Colombier 	uchar buf[8192];
309a747e4fSDavid du Colombier 	static uchar digest[SHA1dlen];
319a747e4fSDavid du Colombier 	DigestState *s;
329a747e4fSDavid du Colombier 
339a747e4fSDavid du Colombier 	len = strlen(pfx)+1+strlen(nm)+1;
349a747e4fSDavid du Colombier 	tmp = emalloc(len);
359a747e4fSDavid du Colombier 	snprint(tmp, len, "%s/%s", pfx, nm);
369a747e4fSDavid du Colombier 	if((fd = open(tmp, OREAD)) < 0){
379a747e4fSDavid du Colombier 		free(tmp);
389a747e4fSDavid du Colombier 		return nil;
399a747e4fSDavid du Colombier 	}
409a747e4fSDavid du Colombier 	free(tmp);
419a747e4fSDavid du Colombier 	s = nil;
429a747e4fSDavid du Colombier 	while((n = read(fd, buf, sizeof buf)) > 0)
439a747e4fSDavid du Colombier 		s = sha1(buf, n, nil, s);
449a747e4fSDavid du Colombier 	close(fd);
459a747e4fSDavid du Colombier 	sha1(nil, 0, digest, s);
469a747e4fSDavid du Colombier 	return digest;
479a747e4fSDavid du Colombier }
489a747e4fSDavid du Colombier 
499a747e4fSDavid du Colombier static int
compare(Dir * a,Dir * b)509a747e4fSDavid du Colombier compare(Dir *a, Dir *b)
519a747e4fSDavid du Colombier {
529a747e4fSDavid du Colombier 	return strcmp(a->name, b->name);
539a747e4fSDavid du Colombier }
549a747e4fSDavid du Colombier 
559a747e4fSDavid du Colombier /* list the (name mtime size sum) of regular, readable files in path */
569a747e4fSDavid du Colombier char *
dirls(char * path)579a747e4fSDavid du Colombier dirls(char *path)
589a747e4fSDavid du Colombier {
599a747e4fSDavid du Colombier 	char *list, *date, dig[30], buf[128];
609a747e4fSDavid du Colombier 	int m, nmwid, lenwid;
619a747e4fSDavid du Colombier 	long i, n, ndir, len;
629a747e4fSDavid du Colombier 	Dir *dirbuf;
639a747e4fSDavid du Colombier 
649a747e4fSDavid du Colombier 	if(path==nil || (ndir = ls(path, &dirbuf)) < 0)
659a747e4fSDavid du Colombier 		return nil;
669a747e4fSDavid du Colombier 
679a747e4fSDavid du Colombier 	qsort(dirbuf, ndir, sizeof dirbuf[0], (int (*)(void *, void *))compare);
689a747e4fSDavid du Colombier 	for(nmwid=lenwid=i=0; i<ndir; i++){
699a747e4fSDavid du Colombier 		if((m = strlen(dirbuf[i].name)) > nmwid)
709a747e4fSDavid du Colombier 			nmwid = m;
719a747e4fSDavid du Colombier 		snprint(buf, sizeof(buf), "%ulld", dirbuf[i].length);
729a747e4fSDavid du Colombier 		if((m = strlen(buf)) > lenwid)
739a747e4fSDavid du Colombier 			lenwid = m;
749a747e4fSDavid du Colombier 	}
759a747e4fSDavid du Colombier 	for(list=nil, len=0, i=0; i<ndir; i++){
769a747e4fSDavid du Colombier 		date = ctime(dirbuf[i].mtime);
779a747e4fSDavid du Colombier 		date[28] = 0;  // trim newline
789a747e4fSDavid du Colombier 		n = snprint(buf, sizeof buf, "%*ulld %s", lenwid, dirbuf[i].length, date+4);
799a747e4fSDavid du Colombier 		n += enc64(dig, sizeof dig, sha1file(path, dirbuf[i].name), SHA1dlen);
809a747e4fSDavid du Colombier 		n += nmwid+3+strlen(dirbuf[i].name);
819a747e4fSDavid du Colombier 		list = erealloc(list, len+n+1);
829a747e4fSDavid du Colombier 		len += snprint(list+len, n+1, "%-*s\t%s %s\n", nmwid, dirbuf[i].name, buf, dig);
839a747e4fSDavid du Colombier 	}
84*be0c1e85SDavid du Colombier 	free(dirbuf);
859a747e4fSDavid du Colombier 	return list;
869a747e4fSDavid du Colombier }
879a747e4fSDavid du Colombier 
88