From c9ed52730b352448c7c644f6942d310dd3509bf6 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 17 Nov 2014 11:21:06 -0500 Subject: cmd: rename *.C to *.c These were *.C back in 2003, before the 9 script, to avoid conflicts with the system utilities. A later change renamed them, but that change seems to have been lost during the hg->git conversion because I ran the conversion on a case-insensitive file system. Change-Id: Id32c99cb9571ef0e185c3cc9e8c8d6d5b48ca195 --- src/cmd/ls.c | 308 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 src/cmd/ls.c (limited to 'src/cmd/ls.c') diff --git a/src/cmd/ls.c b/src/cmd/ls.c new file mode 100644 index 00000000..60615059 --- /dev/null +++ b/src/cmd/ls.c @@ -0,0 +1,308 @@ +#include +#include +#include + +#define dirbuf p9dirbuf /* avoid conflict on sun */ + +typedef struct NDir NDir; +struct NDir +{ + Dir *d; + char *prefix; +}; + +int errs = 0; +int dflag; +int lflag; +int mflag; +int nflag; +int pflag; +int qflag; +int Qflag; +int rflag; +int sflag; +int tflag; +int uflag; +int Fflag; +int ndirbuf; +int ndir; +NDir* dirbuf; +int ls(char*, int); +int compar(NDir*, NDir*); +char* asciitime(long); +char* darwx(long); +void rwx(long, char*); +void growto(long); +void dowidths(Dir*); +void format(Dir*, char*); +void output(void); +ulong clk; +int swidth; /* max width of -s size */ +int qwidth; /* max width of -q version */ +int vwidth; /* max width of dev */ +int uwidth; /* max width of userid */ +int mwidth; /* max width of muid */ +int glwidth; /* max width of groupid and length */ +Biobuf bin; + +void +main(int argc, char *argv[]) +{ + int i; + + Binit(&bin, 1, OWRITE); + ARGBEGIN{ + case 'F': Fflag++; break; + case 'd': dflag++; break; + case 'l': lflag++; break; + case 'm': mflag++; break; + case 'n': nflag++; break; + case 'p': pflag++; break; + case 'q': qflag++; break; + case 'Q': Qflag++; break; + case 'r': rflag++; break; + case 's': sflag++; break; + case 't': tflag++; break; + case 'u': uflag++; break; + default: fprint(2, "usage: ls [-dlmnpqrstuFQ] [file ...]\n"); + exits("usage"); + }ARGEND + + doquote = needsrcquote; + quotefmtinstall(); + fmtinstall('M', dirmodefmt); + + if(lflag) + clk = time(0); + if(argc == 0) + errs = ls(".", 0); + else for(i=0; iqid.type&QTDIR && dflag==0){ + free(db); + db = nil; + output(); + fd = open(s, OREAD); + if(fd == -1) + goto error; + n = dirreadall(fd, &db); + if(n < 0) + goto error; + growto(ndir+n); + for(i=0; iname = strdup(p+1); + } + ndir++; + } + return 0; +} + +void +output(void) +{ + int i; + char buf[4096]; + char *s; + + if(!nflag) + qsort(dirbuf, ndir, sizeof dirbuf[0], (int (*)(const void*, const void*))compar); + for(i=0; iname); + format(dirbuf[i].d, buf); + } else + format(dirbuf[i].d, dirbuf[i].d->name); + } + ndir = 0; + Bflush(&bin); +} + +void +dowidths(Dir *db) +{ + char buf[256]; + int n; + + if(sflag) { + n = sprint(buf, "%llud", (db->length+1023)/1024); + if(n > swidth) + swidth = n; + } + if(qflag) { + n = sprint(buf, "%lud", db->qid.vers); + if(n > qwidth) + qwidth = n; + } + if(mflag) { + n = snprint(buf, sizeof buf, "[%s]", db->muid); + if(n > mwidth) + mwidth = n; + } + if(lflag) { + n = sprint(buf, "%ud", db->dev); + if(n > vwidth) + vwidth = n; + n = strlen(db->uid); + if(n > uwidth) + uwidth = n; + n = sprint(buf, "%llud", db->length); + n += strlen(db->gid); + if(n > glwidth) + glwidth = n; + } +} + +char* +fileflag(Dir *db) +{ + if(Fflag == 0) + return ""; + if(QTDIR & db->qid.type) + return "/"; + if(0111 & db->mode) + return "*"; + return ""; +} + +void +format(Dir *db, char *name) +{ + int i; + + if(sflag) + Bprint(&bin, "%*llud ", + swidth, (db->length+1023)/1024); + if(mflag){ + Bprint(&bin, "[%s] ", db->muid); + for(i=2+strlen(db->muid); iqid.path, + qwidth, db->qid.vers, + db->qid.type); + if(lflag) + Bprint(&bin, + "%M %C %*ud %*s %s %*llud %s ", + db->mode, db->type, + vwidth, db->dev, + -uwidth, db->uid, + db->gid, + (int)(glwidth-strlen(db->gid)), db->length, + asciitime(uflag? db->atime : db->mtime)); + Bprint(&bin, + Qflag? "%s%s\n" : "%q%s\n", + name, fileflag(db)); +} + +void +growto(long n) +{ + if(n <= ndirbuf) + return; + ndirbuf = n; + dirbuf=(NDir *)realloc(dirbuf, ndirbuf*sizeof(NDir)); + if(dirbuf == 0){ + fprint(2, "ls: malloc fail\n"); + exits("malloc fail"); + } +} + +int +compar(NDir *a, NDir *b) +{ + long i; + Dir *ad, *bd; + + ad = a->d; + bd = b->d; + + if(tflag){ + if(uflag) + i = bd->atime-ad->atime; + else + i = bd->mtime-ad->mtime; + }else{ + if(a->prefix && b->prefix){ + i = strcmp(a->prefix, b->prefix); + if(i == 0) + i = strcmp(ad->name, bd->name); + }else if(a->prefix){ + i = strcmp(a->prefix, bd->name); + if(i == 0) + i = 1; /* a is longer than b */ + }else if(b->prefix){ + i = strcmp(ad->name, b->prefix); + if(i == 0) + i = -1; /* b is longer than a */ + }else + i = strcmp(ad->name, bd->name); + } + if(i == 0) + i = (ad