URI:
       tdirls.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tdirls.c (1856B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <mp.h>
            4 #include <libsec.h>
            5 #include "SConn.h"
            6 
            7 static long
            8 ls(char *p, Dir **dirbuf)
            9 {
           10         int fd;
           11         long n;
           12         Dir *db;
           13 
           14         if((db = dirstat(p)) == nil ||
           15                 !(db->qid.type & QTDIR) ||
           16                 (fd = open(p, OREAD)) < 0 )
           17                 return -1;
           18         free(db);
           19         n = dirreadall(fd, dirbuf);
           20         close(fd);
           21         return n;
           22 }
           23 
           24 static uchar*
           25 sha1file(char *pfx, char *nm)
           26 {
           27         int n, fd, len;
           28         char *tmp;
           29         uchar buf[8192];
           30         static uchar digest[SHA1dlen];
           31         DigestState *s;
           32 
           33         len = strlen(pfx)+1+strlen(nm)+1;
           34         tmp = emalloc(len);
           35         snprint(tmp, len, "%s/%s", pfx, nm);
           36         if((fd = open(tmp, OREAD)) < 0){
           37                 free(tmp);
           38                 return nil;
           39         }
           40         free(tmp);
           41         s = nil;
           42         while((n = read(fd, buf, sizeof buf)) > 0)
           43                 s = sha1(buf, n, nil, s);
           44         close(fd);
           45         sha1(nil, 0, digest, s);
           46         return digest;
           47 }
           48 
           49 static int
           50 compare(Dir *a, Dir *b)
           51 {
           52         return strcmp(a->name, b->name);
           53 }
           54 
           55 /* list the (name mtime size sum) of regular, readable files in path */
           56 char *
           57 dirls(char *path)
           58 {
           59         char *list, *date, dig[30], buf[128];
           60         int m, nmwid, lenwid;
           61         long i, n, ndir, len;
           62         Dir *dirbuf;
           63 
           64         if(path==nil || (ndir = ls(path, &dirbuf)) < 0)
           65                 return nil;
           66 
           67         qsort(dirbuf, ndir, sizeof dirbuf[0], (int (*)(const void *, const void *))compare);
           68         for(nmwid=lenwid=i=0; i<ndir; i++){
           69                 if((m = strlen(dirbuf[i].name)) > nmwid)
           70                         nmwid = m;
           71                 snprint(buf, sizeof(buf), "%ulld", dirbuf[i].length);
           72                 if((m = strlen(buf)) > lenwid)
           73                         lenwid = m;
           74         }
           75         for(list=nil, len=0, i=0; i<ndir; i++){
           76                 date = ctime(dirbuf[i].mtime);
           77                 date[28] = 0;  /* trim newline */
           78                 n = snprint(buf, sizeof buf, "%*ulld %s", lenwid, dirbuf[i].length, date+4);
           79                 n += enc64(dig, sizeof dig, sha1file(path, dirbuf[i].name), SHA1dlen);
           80                 n += nmwid+3+strlen(dirbuf[i].name);
           81                 list = erealloc(list, len+n+1);
           82                 len += snprint(list+len, n+1, "%-*s\t%s %s\n", nmwid, dirbuf[i].name, buf, dig);
           83         }
           84         free(dirbuf);
           85         return list;
           86 }