📄 newls.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)newls.c 1.1 92/07/30 SMI"; #endif/** list file or directory;*/#include <sys/param.h>#include <sys/types.h>#include <sys/sysmacros.h>#include <sys/stat.h>#include <sys/dir.h>#include <stdio.h>#include <ctype.h>#include <locale.h>#define ISARG 0100000 /* this bit equals 1 in lflags of structure lbuf * if name is an argument to ls; */#define DIRECT 10 /* Number of direct blocks */struct lbuf { char ltype; /* file type, e.g. 'd', 'c', 'f' */ ino_t lnum; /* inode number of file */ short lflags; /* 0777 bits used as r,w,x permissions */ short lnl; /* number of links to file */ unsigned short luid; /* owner id */ unsigned short lgid; /* group id */ long lsize; /* file size or major/minor dev numbers */ long lblks; /* number of blocks used */ long lmtime; /* time (modify or access or create) */ char *lname; /* for filename in directory or name in ls-command */ char *llinkto; /* symbolic link value */};struct dchain { char *dc_name; /* path name */ struct dchain *dc_next; /* next directory in the chain */};struct dchain *dfirst; /* start of the dir chain */struct dchain *cdfirst; /* start of the durrent dir chain */struct dchain *dtemp; /* temporary - used for linking */char *curdir; /* the current directory */int nfiles = 0; /* number of flist entries in current use */int nargs = 0; /* number of flist entries used for arguments */int maxfils = 0; /* number of flist/lbuf entries allocated */int maxn = 0; /* number of flist entries with lbufs assigned */int quantn = 1024; /* allocation growth quantum */struct lbuf *nxtlbf; /* pointer to next lbuf to be assigned */struct lbuf **flist; /* pointer to list of lbuf pointers */struct lbuf *gstat();FILE *pwdfu, *pwdfg;int aflg, gflg, lflg;int nflg, oflg;int flags;int err = 0; /* Contains return code */char *dmark; /* Used if -p option active. Contains "/" or NULL. */unsigned lastuid = -1, lastgid = -1;int statreq; /* is > 0 if any of sflg, (n)lflg, tflg are on */static int nomocore = 0;char *dotp = ".";char *makename();char *getname(), *getgroup();char *ctime(), *strcpy();long tblocks; /* total number of blocks of files in a directory */long year;int num_cols = 80;int colwidth;int filewidth;int fixedwidth;int curcol;int compar();main(argc, argv)int argc;char *argv[];{ extern char *optarg; extern int optind; int amino, opterr=0; int c; register struct lbuf *ep; struct lbuf lb; int i, width; long time(); char *malloc(); void qsort(), exit(); setlocale(LC_ALL, ""); /* get local environment */ lb.lmtime = time((long *) NULL); year = lb.lmtime - 6L*30L*24L*60L*60L; /* 6 months ago */ while ((c=getopt(argc, argv, "RadCxmnlogrtucpFbqisfL")) != EOF) switch(c) { case 'a': aflg++; continue; case 'n': nflg++; continue; case 'l': lflg++; statreq++; continue; case '?': opterr++; continue; } if(opterr) { fprintf(stderr,"usage: newls -anl [files]\n"); exit(2); } fixedwidth = 2; if (lflg) gflg = oflg = 1; /* allocate space for flist and the associated */ /* data structures (lbufs) */ maxfils = quantn; if((flist=(struct lbuf **)malloc((unsigned)(maxfils * sizeof(struct lbuf *)))) == NULL || (nxtlbf = (struct lbuf *)malloc((unsigned)(quantn * sizeof(struct lbuf)))) == NULL) { fprintf(stderr, "ls: out of memory\n"); exit(2); } if ((amino=(argc-optind))==0) { /* case when no names are given * in ls-command and current * directory is to be used */ argv[optind] = dotp; } for (i=0; i < (amino ? amino : 1); i++) { if ((ep = gstat((*argv[optind] ? argv[optind] : dotp), 1))==NULL) { err = 2; optind++; continue; } ep->lname = (*argv[optind] ? argv[optind] : dotp); ep->lflags |= ISARG; optind++; nargs++; /* count good arguments stored in flist */ } colwidth = fixedwidth + filewidth; qsort(flist, (unsigned)nargs, sizeof(struct lbuf *), compar); for (i=0; i<nargs; i++) if (flist[i]->ltype=='d') break; pem(&flist[0],&flist[i], 0); for (; i<nargs; i++) { pdirectory(flist[i]->lname, (amino>1), nargs); /* -R: print subdirectories found */ while (dfirst || cdfirst) { /* Place direct subdirs on front in right order */ while (cdfirst) { /* reverse cdfirst onto front of dfirst */ dtemp = cdfirst; cdfirst = cdfirst -> dc_next; dtemp -> dc_next = dfirst; dfirst = dtemp; } /* take off first dir on dfirst & print it */ dtemp = dfirst; dfirst = dfirst->dc_next; pdirectory (dtemp->dc_name, 1, nargs); free (dtemp->dc_name); free ((char *)dtemp); } } exit(err); /*NOTREACHED*/}/* * pdirectory: print the directory name, labelling it if title is * nonzero, using lp as the place to start reading in the dir. */pdirectory (name, title, lp)char *name;int title;int lp;{ register struct dchain *dp; register struct lbuf *ap; register char *pname; register int j; filewidth = 0; curdir = name; if (title) { putc('\n', stdout); pprintf(name); putc(':', stdout); curcol++; new_line(); } nfiles = lp; rddir(name); qsort(&flist[lp],(unsigned)(nfiles - lp),sizeof(struct lbuf *),compar); curcol += printf("total %ld", tblocks); pem(&flist[lp],&flist[nfiles],lflg);}/* * pem: print 'em. Print a list of files (e.g. a directory) bounded * by slp and lp. */pem(slp, lp, tot_flag) register struct lbuf **slp, **lp; int tot_flag;{ int ncols, nrows, row, col; register struct lbuf **ep; for (ep = slp; ep < lp; ep++) pentry(*ep); new_line(); return;}pentry(ap) /* print one output entry; * if uid/gid is not found in the appropriate * file (passwd/group), then print uid/gid instead of * user/group name; */struct lbuf *ap;{ struct { char dminor, dmajor; }; register struct lbuf *p; register char *cp; p = ap; column(); if (lflg) { putchar(p->ltype); curcol++; pmode(p->lflags); curcol += printf("%4d ", p->lnl); curcol += printf("%-9u", p->luid); curcol += printf("%-9u", p->lgid); if (p->ltype=='b' || p->ltype=='c') curcol += printf("%3d,%3d", major((int)p->lsize), minor((int)p->lsize)); else curcol += printf("%7ld", p->lsize); cp = ctime(&p->lmtime); curcol += printf(" %-7.7s %-4.4s ", cp+4, cp+20); } curcol += printf("%s",p->lname); if (p->llinkto) { curcol += printf(" -> "); curcol += printf("%s", p->llinkto); } }/* print various r,w,x permissions */pmode(aflag){ /* these arrays are declared static to allow initializations */ static int m0[] = { 1, S_IREAD>>0, 'r', '-' }; static int m1[] = { 1, S_IWRITE>>0, 'w', '-' }; static int m2[] = { 3, S_ISUID|S_IEXEC, 's', S_IEXEC, 'x', S_ISUID, 'S', '-' }; static int m3[] = { 1, S_IREAD>>3, 'r', '-' }; static int m4[] = { 1, S_IWRITE>>3, 'w', '-' }; static int m5[] = { 3, S_ISGID|(S_IEXEC>>3),'s', S_IEXEC>>3,'x', S_ISGID,'S', '-'}; static int m6[] = { 1, S_IREAD>>6, 'r', '-' }; static int m7[] = { 1, S_IWRITE>>6, 'w', '-' }; static int m8[] = { 3, S_ISVTX|(S_IEXEC>>6),'t', S_IEXEC>>6,'x', S_ISVTX,'T', '-'}; static int *m[] = { m0, m1, m2, m3, m4, m5, m6, m7, m8}; register int **mp; flags = aflag; for (mp = &m[0]; mp < &m[sizeof(m)/sizeof(m[0])];) selectbits(*mp++);}selectbits(pairp)register int *pairp;{ register int n; n = *pairp++; while (n-->0) { if((flags & *pairp) == *pairp) { pairp++; break; }else { pairp += 2; } } putchar(*pairp); curcol++;}/* * column: get to the beginning of the next column. */column(){ if (curcol == 0) return; putc('\n', stdout); curcol = 0; return;}new_line(){ if (curcol) { putc('\n',stdout); curcol = 0; }}/* read each filename in directory dir and store its * status in flist[nfiles] * use makename() to form pathname dir/filename; */rddir(dir)char *dir;{ struct direct *dentry; DIR *dirf; extern char *malloc();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -