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

📄 ls.c

📁 minix软件源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			if (field & F_ATIME) {				CMP= atimecmp;			} else {				CMP= mtimecmp;			}			if (present('r')) { rCMP= CMP; CMP= revcmp; }			mergesort(al);		}		/* Separate by file type if so desired. */		if (field & F_TYPE) {			CMP= typecmp;			mergesort(al);		}	}}struct file *newfile(char *name)/* Create file structure for given name. */{	struct file *new;	new= (struct file *) allocate(sizeof(*new));	new->name= strcpy((char *) allocate(strlen(name)+1), name);	return new;}void pushfile(struct file **flist, struct file *new)/* Add file to the head of a list. */{	new->next= *flist;	*flist= new;}void delfile(struct file *old)/* Release old file structure. */{	free((void *) old->name);	free((void *) old);}struct file *popfile(struct file **flist)/* Pop file off top of file list. */{	struct file *f;	f= *flist;	*flist= f->next;	return f;}int dotflag(char *name)/* Return flag that would make ls list this name: -a or -A. */{	if (*name++ != '.') return 0;	switch (*name++) {	case 0:		return 'a';			/* "." */	case '.':	if (*name == 0) return 'a';	/* ".." */	default:	return 'A';			/* ".*" */	}}int adddir(struct file **aflist, char *name)/* Add directory entries of directory name to a file list. */{	DIR *d;	struct dirent *e;	if (access(name, 0) < 0) {		report(name);		return 0;	}	if ((d= opendir(name)) == nil) {		report(name);		return 0;	}	while ((e= readdir(d)) != nil) {		if (e->d_ino != 0 && present(dotflag(e->d_name))) {			pushfile(aflist, newfile(e->d_name));			aflist= &(*aflist)->next;		}	}	closedir(d);	return 1;}off_t countblocks(struct file *flist)/* Compute total block count for a list of files. */{	off_t cb = 0;	while (flist != nil) {		switch (flist->mode & S_IFMT) {		case S_IFDIR:		case S_IFREG:#ifdef S_IFLNK		case S_IFLNK:#endif			cb += nblocks(flist);		}		flist= flist->next;	}	return cb;}void printname(char *name)/* Print a name with control characters as '?' (unless -q).  The terminal is * assumed to be eight bit clean. */{	int c, q= present('q');	while ((c= (unsigned char) *name++) != 0) {		if (q && (c <= ' ' || c == 0177)) c= '?';		putchar(c);	}}int mark(struct file *f, int doit){	int c;	if (!(field & F_MARK)) return 0;	switch (f->mode & S_IFMT) {	case S_IFDIR:	c= '/'; break;#ifdef S_IFIFO	case S_IFIFO:	c= '|'; break;#endif#ifdef S_IFLNK	case S_IFLNK:	c= '@'; break;#endif#ifdef S_IFSOCK	case S_IFSOCK:	c= '='; break;#endif	case S_IFREG:		if (f->mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {			c= '*';			break;		}	default:		c= 0;	}	if (doit && c != 0) putchar(c);	return c;}int colwidth[MAXCOLS];	/* Need colwidth[i] spaces to print column i. */int sizwidth[MAXCOLS];	/* Spaces for the size field in a -X print. */int namwidth[MAXCOLS];	/* Name field. */int maxise(int *aw, int w)/* Set *aw to the larger of it and w.  Then return it. */{	if (w > *aw) *aw= w;	return *aw;}static int nsp= 0;	/* This many spaces have not been printed yet. */#define spaces(n)	(nsp= (n))#define terpri()	(nsp= 0, putchar('\n'))		/* No trailing spaces */void print1(struct file *f, int col, int doit)/* Either compute the number of spaces needed to print file f (doit == 0) or * really print it (doit == 1). */{	int width= 0, n;	char *p;	while (nsp>0) { putchar(' '); nsp--; }/* Fill gap between two columns */	if (field & F_INODE) {		if (doit) printf("%5d ", f->ino); else width+= 6;	}	if (field & F_BLOCKS) {		if (doit) printf("%4ld ", nblk2k(nblocks(f))); else width+= 5;	}	if (field & F_MODE) {		if (doit) {			printf("%s ", permissions(f));		} else {			width+= (field & F_EXTRA) ? 5 : 11;		}	}	if (field & F_EXTRA) {		p= cxsize(f);		n= strlen(p)+1;		if (doit) {			n= sizwidth[col] - n;			while (n > 0) { putchar(' '); --n; }			printf("%s ", p);		} else {			width+= maxise(&sizwidth[col], n);		}	}	if (field & F_LONG) {		if (doit) {			printf("%2u ", (unsigned) f->nlink);			if (!(field & F_GROUP)) {				printf("%-8s ", uidname(f->uid));			}			printf("%-8s ", gidname(f->gid));			switch (f->mode & S_IFMT) {			case S_IFBLK:			case S_IFCHR:#ifdef S_IFMPB			case S_IFMPB:#endif#ifdef S_IFMPC			case S_IFMPC:#endif				printf("%3d, %3d ",					major(f->rdev), minor(f->rdev));				break;			default:				printf("%8ld ", (long) f->size);			}			printf("%s ", timestamp(f));		} else {			width += (field & F_GROUP) ? 34 : 43;		}	}	n= strlen(f->name);	if (doit) {		printname(f->name);		if (mark(f, 1) != 0) n++;#ifdef S_IFLNK		if ((field & F_LONG) && (f->mode & S_IFMT) == S_IFLNK) {			char *buf;			int r, didx;			buf= (char *) allocate(((size_t) f->size + 1)							* sizeof(buf[0]));			addpath(&didx, f->name);			r= readlink(path, buf, (int) f->size);			delpath(didx);			if (r > 0) buf[r] = 0; else r=1, strcpy(buf, "?");			printf(" -> ");			printname(buf);			free((void *) buf);			n+= 4 + r;		}#endif		spaces(namwidth[col] - n);	} else {		if (mark(f, 0) != 0) n++;#ifdef S_IFLNK		if ((field & F_LONG) && (f->mode & S_IFMT) == S_IFLNK) {			n+= 4 + (int) f->size;		}#endif		width+= maxise(&namwidth[col], n + NSEP);		maxise(&colwidth[col], width);	}}int countfiles(struct file *flist)/* Return number of files in the list. */{	int n= 0;	while (flist != nil) { n++; flist= flist->next; }	return n;}struct file *filecol[MAXCOLS];	/* filecol[i] is list of files for column i. */int nfiles, nlines;	/* # files to print, # of lines needed. */int columnise(struct file *flist, int nplin)/* Chop list of files up in columns.  Note that 3 columns are used for 5 files * even though nplin may be 4, filecol[3] will simply be nil. */{	int i, j;	nlines= (nfiles + nplin - 1) / nplin;	/* nlines needed for nfiles */	filecol[0]= flist;	for (i=1; i<nplin; i++) {	/* Give nlines files to each column. */		for (j=0; j<nlines && flist != nil; j++) flist= flist->next;		filecol[i]= flist;	}}int print(struct file *flist, int nplin, int doit)/* Try (doit == 0), or really print the list of files over nplin columns. * Return true if it can be done in nplin columns or if nplin == 1. */{	register struct file *f;	register int i, totlen;	columnise(flist, nplin);	if (!doit) {		if (nplin==1 && !(field & F_EXTRA))			return 1;	/* No need to try 1 column. */		for (i=0; i<nplin; i++) {			colwidth[i]= sizwidth[i]= namwidth[i]= 0;		}	}	while (--nlines >= 0) {		totlen=0;		for (i=0; i<nplin; i++) {			if ((f= filecol[i]) != nil) {				filecol[i]= f->next;				print1(f, i, doit);			}			if (!doit && nplin>1) {				/* See if this line is not too long. */				totlen+= colwidth[i];				if (totlen > ncols+NSEP) return 0;			}		}		if (doit) terpri();	}	return 1;}enum depth { SURFACE, SURFACE1, SUBMERGED };enum state { BOTTOM, SINKING, FLOATING };void listfiles(struct file *flist, enum depth depth, enum state state)/* Main workhorse of ls, it sorts and prints the list of files.  Flags: * depth: working with the command line / just one file / listing dir. * state: How "recursive" do we have to be. */{	struct file *dlist= nil, **afl= &flist, **adl= &dlist;	int nplin;	static int white = 1;	/* Nothing printed yet. */	/* Flush everything previously printed, so new error output will	 * not intermix with files listed earlier.	 */	fflush(stdout);	if (field != 0 || state != BOTTOM) {	/* Need stat(2) info. */		while (*afl != nil) {			static struct stat st;			int r, didx;			addpath(&didx, (*afl)->name);			if ((r= status(path, &st)) < 0#ifdef S_IFLNK				&& (status == lstat || lstat(path, &st) < 0)#endif			) {				if (depth != SUBMERGED || errno != ENOENT)					report((*afl)->name);				delfile(popfile(afl));			} else {				setstat(*afl, &st);				afl= &(*afl)->next;			}			delpath(didx);		}	}	sort(&flist);	if (depth == SUBMERGED && (field & (F_BLOCKS | F_LONG))) {		printf("total %ld\n", nblk2k(countblocks(flist)));	}	if (state == SINKING || depth == SURFACE1) {	/* Don't list directories themselves, list their contents later. */		afl= &flist;		while (*afl != nil) {			if (((*afl)->mode & S_IFMT) == S_IFDIR) {				pushfile(adl, popfile(afl));				adl= &(*adl)->next;			} else {				afl= &(*afl)->next;			}		}	}	if ((nfiles= countfiles(flist)) > 0) {		/* Print files in how many columns? */		nplin= !present('C') ? 1 : nfiles < MAXCOLS ? nfiles : MAXCOLS;		while (!print(flist, nplin, 0)) nplin--;	/* Try first */		print(flist, nplin, 1);		/* Then do it! */		white = 0;	}	while (flist != nil) {	/* Destroy file list */		if (state == FLOATING && (flist->mode & S_IFMT) == S_IFDIR) {			/* But keep these directories for ls -R. */			pushfile(adl, popfile(&flist));			adl= &(*adl)->next;		} else {			delfile(popfile(&flist));		}	}	while (dlist != nil) {	/* List directories */		if (dotflag(dlist->name) != 'a' || depth != SUBMERGED) {			int didx;			addpath(&didx, dlist->name);			flist= nil;			if (adddir(&flist, path)) {				if (depth != SURFACE1) {					if (!white) putchar('\n');					printf("%s:\n", path);					white = 0;				}				listfiles(flist, SUBMERGED,					state == FLOATING ? FLOATING : BOTTOM);			}			delpath(didx);		}		delfile(popfile(&dlist));	}}int main(int argc, char **argv){	struct file *flist= nil, **aflist= &flist;	enum depth depth;	char *lsflags;	struct winsize ws;	uid= geteuid();	gid= getegid();	if ((arg0= strrchr(argv[0], '/')) == nil) arg0= argv[0]; else arg0++;	argv++;	if (strcmp(arg0, "ls") != 0) {		char *p= arg0+1;		while (*p != 0) {			if (strchr(arg0flag, *p) != nil) *p += 'A' - 'a';			p++;		}		setflags(arg0+1);	}	while (*argv != nil && (*argv)[0] == '-') {		if ((*argv)[1] == '-' && (*argv)[2] == 0) {			argv++;			break;		}		setflags(*argv++ + 1);	}	istty= isatty(1);	if (istty && (lsflags= getenv("LSOPTS")) != nil) {		if (*lsflags == '-') lsflags++;		setflags(lsflags);	}	if (!present('1') && !present('C') && !present('l')		&& (istty || present('M') || present('X') || present('F'))	) setflags("C");	if (istty) setflags("q");	if (SUPER_ID == 0 || present('a')) setflags("A");	if (present('i')) field|= F_INODE;	if (present('s')) field|= F_BLOCKS;	if (present('M')) field|= F_MODE;	if (present('X')) field|= F_EXTRA|F_MODE;	if (present('t')) field|= F_BYTIME;	if (present('u')) field|= F_ATIME;	if (present('c')) field|= F_CTIME;	if (present('l')) field= (field | F_MODE | F_LONG) & ~F_EXTRA;	if (present('g')) field= (field | F_MODE | F_LONG | F_GROUP) & ~F_EXTRA;	if (present('F')) field|= F_MARK;	if (present('T')) field|= F_TYPE;	if (present('d')) field|= F_DIR;#ifdef S_IFLNK	status= present('L') ? stat : lstat;#endif	if (present('C')) {		int t= istty ? 1 : open("/dev/tty", O_WRONLY);		if (t >= 0 && ioctl(t, TIOCGWINSZ, &ws) == 0 && ws.ws_col > 0)			ncols= ws.ws_col - 1;		if (t != 1 && t != -1) close(t);	}	depth= SURFACE;	if (*argv == nil) {		if (!(field & F_DIR)) depth= SURFACE1;		pushfile(aflist, newfile("."));	} else {		if (argv[1] == nil && !(field & F_DIR)) depth= SURFACE1;		do {			pushfile(aflist, newfile(*argv++));			aflist= &(*aflist)->next;		} while (*argv!=nil);	}	listfiles(flist, depth,		(field & F_DIR) ? BOTTOM : present('R') ? FLOATING : SINKING);	exit(ex);}

⌨️ 快捷键说明

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