⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ls.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <fcall.h>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	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);char*	xcleanname(char*);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;voidmain(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 'T':	Tflag++; break;	case 'u':	uflag++; break;	default:	fprint(2, "usage: ls [-dlmnpqrstuFQT] [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; i<argc; i++)		errs |= ls(argv[i], 1);	output();	exits(errs? "errors" : 0);}intls(char *s, int multi){	int fd;	long i, n;	char *p;	Dir *db;	db = dirstat(s);	if(db == nil){    error:		fprint(2, "ls: %s: %r\n", s);		return 1;	}	if((db->qid.type&QTDIR) && dflag==0){		free(db);		output();		fd = open(s, OREAD);		if(fd == -1)			goto error;		n = dirreadall(fd, &db);		if(n < 0)			goto error;		xcleanname(s);		growto(ndir+n);		for(i=0; i<n; i++){			dirbuf[ndir+i].d = db+i;			dirbuf[ndir+i].prefix = multi? s : 0;		}		ndir += n;		close(fd);		output();	}else{		growto(ndir+1);		dirbuf[ndir].d = db;		dirbuf[ndir].prefix = 0;		xcleanname(s);		p = utfrrune(s, '/');		if(p){			dirbuf[ndir].prefix = s;			*p = 0;		}		ndir++;	}	return 0;}voidoutput(void){	int i;	char buf[4096];	char *s;	if(!nflag)		qsort(dirbuf, ndir, sizeof dirbuf[0], (int (*)(void*, void*))compar);	for(i=0; i<ndir; i++)		dowidths(dirbuf[i].d);	for(i=0; i<ndir; i++) {		if(!pflag && (s = dirbuf[i].prefix)) {			if(strcmp(s, "/") ==0)	/* / is a special case */				s = "";			sprint(buf, "%s/%s", s, dirbuf[i].d->name);			format(dirbuf[i].d, buf);		} else			format(dirbuf[i].d, dirbuf[i].d->name);	}	ndir = 0;	Bflush(&bin);}voiddowidths(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 "";}voidformat(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); i<mwidth; i++)			Bprint(&bin, " ");	}	if(qflag)		Bprint(&bin, "(%.16llux %*lud %.2ux) ",			db->qid.path,			qwidth, db->qid.vers,			db->qid.type);	if(Tflag)		Bprint(&bin, "%c ", (db->mode&DMTMP) ? 't' : '-');	if(lflag)		Bprint(&bin,			Qflag? "%M %C %*ud %*s %s %*llud %s %s\n" : "%M %C %*ud %*s %s %*llud %s %q\n",			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), name);	else		Bprint(&bin,			Qflag? "%s%s\n" : "%q%s\n",			name, fileflag(db));}voidgrowto(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");	}		}intcompar(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 = (a<b? -1 : 1);	if(rflag)		i = -i;	return i;}char*asciitime(long l){	static char buf[32];	char *t;	t = ctime(l);	/* 6 months in the past or a day in the future */	if(l<clk-180L*24*60*60 || clk+24L*60*60<l){		memmove(buf, t+4, 7);		/* month and day */		memmove(buf+7, t+23, 5);		/* year */	}else		memmove(buf, t+4, 12);		/* skip day of week */	buf[12] = 0;	return buf;}/* * Compress slashes, remove trailing slash.  Don't worry about . and .. */char*xcleanname(char *name){	char *r, *w;		for(r=w=name; *r; r++){		if(*r=='/' && r>name && *(r-1)=='/')			continue;		*w++ = *r;	}	*w = 0;	while(w-1>name && *(w-1)=='/')		*--w = 0;	return name;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -