853 lines · 15.7 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include "all.h" static	Command	command[100];static	Flag	flag[35];static	char	statsdef[20];	/* default stats list */static	int	whoflag; static	void	consserve1(void *);static	void	installcmds(void); voidconsserve(void){	int i; 	strncpy(cons.chan->whochan, "console", sizeof(cons.chan->whochan));	installcmds();	con_session();	cmd_exec("cfs");	cmd_exec("users");	cmd_exec("version"); 	for(i = 0; command[i].arg0; i++)		if(strcmp("cwcmd", command[i].arg0) == 0){			cmd_exec("cwcmd touchsb");			break;		} 	newproc(consserve1, 0, "con");} /* console commands process */static voidconsserve1(void *){	char *conline; 	for (;;) {		/* conslock(); */		do {			print("%s: ", service);			if ((conline = Brdline(&bin, '\n')) == nil)				print("\n");			else {				conline[Blinelen(&bin)-1] = '\0';				cmd_exec(conline);			}		} while (conline != nil);	}} static intcmdcmp(void *va, void *vb){	Command *a, *b; 	a = va;	b = vb;	return strcmp(a->arg0, b->arg0);} voidcmd_install(char *arg0, char *help, void (*func)(int, char*[])){	int i; 	qlock(&cons);	for(i=0; command[i].arg0; i++)		;	if(i >= nelem(command)-2) {		qunlock(&cons);		print("cmd_install: too many commands\n");		return;	}	command[i+1].arg0 = 0;	command[i].help = help;	command[i].func = func;	command[i].arg0 = arg0;	qsort(command, i+1, sizeof(Command), cmdcmp);	qunlock(&cons);} voidcmd_exec(char *arg){	char line[2*Maxword], *s;	char *argv[10];	int argc, i, c; 	if(strlen(arg) >= nelem(line)-2) {		print("cmd_exec: line too long\n");		return;	}	strcpy(line, arg); 	argc = 0;	s = line;	c = *s++;	for(;;) {		while(isascii(c) && isspace(c))			c = *s++;		if(c == 0)			break;		if(argc >= nelem(argv)-2) {			print("cmd_exec: too many args\n");			return;		}		argv[argc++] = s-1;		while((!isascii(c) || !isspace(c)) && c != '\0')			c = *s++;		s[-1] = 0;	}	if(argc <= 0)		return;	for(i=0; s=command[i].arg0; i++)		if(strcmp(argv[0], s) == 0) {			(*command[i].func)(argc, argv);			prflush();			return;		}	print("cmd_exec: unknown command: %s\n", argv[0]);} static voidcmd_halt(int, char *[]){	wlock(&mainlock);	/* halt */	sync("halt");	exit();} static voidcmd_duallow(int argc, char *argv[]){	int uid; 	if(argc <= 1) {		duallow = 0;		return;	} 	uid = strtouid(argv[1]);	if(uid < 0)		uid = number(argv[1], -2, 10);	if(uid < 0) {		print("bad uid %s\n", argv[1]);		return;	}	duallow = uid;} static voidcmd_stats(int argc, char *argv[]){	int i, c;	char buf[30], *s, *p, *q; 	if(argc <= 1) {		if(statsdef[0] == 0)			strcpy(statsdef, "a");		sprint(buf, "stats s%s", statsdef);		cmd_exec(buf);		return;	} 	strcpy(buf, "stat");	p = strchr(buf, 0);	p[1] = 0; 	q = 0;	for(i = 1; i < argc; i++)		for(s = argv[i]; c = *s; s++) {			if(c == 's')				continue;			if(c == '-') {				q = statsdef;				continue;			}			if(q) {				*q++ = c;				*q = 0;			}			*p = c;			cmd_exec(buf);		}} static voidcmd_stata(int, char *[]){	int i; 	print("cons stats\n");//	print("\twork =%7W%7W%7W rps\n", cons.work+0, cons.work+1, cons.work+2);//	print("\trate =%7W%7W%7W tBps\n", cons.rate+0, cons.rate+1, cons.rate+2);//	print("\thits =%7W%7W%7W iops\n", cons.bhit+0, cons.bhit+1, cons.bhit+2);//	print("\tread =%7W%7W%7W iops\n", cons.bread+0, cons.bread+1, cons.bread+2);//	print("\trah  =%7W%7W%7W iops\n", cons.brahead+0, cons.brahead+1, cons.brahead+2);//	print("\tinit =%7W%7W%7W iops\n", cons.binit+0, cons.binit+1, cons.binit+2);	print("\tbufs =    %3ld sm %3ld lg %ld res\n",		cons.nsmall, cons.nlarge, cons.nreseq); 	for(i=0; i<nelem(mballocs); i++)		if(mballocs[i])			print("\t[%d]=%d\n", i, mballocs[i]); 	print("\tioerr=    %3ld wr %3ld ww %3ld dr %3ld dw\n",		cons.nwormre, cons.nwormwe, cons.nwrenre, cons.nwrenwe);	print("\tcache=     %9ld hit %9ld miss\n",		cons.nwormhit, cons.nwormmiss);} static intflagcmp(void *va, void *vb){	Flag *a, *b; 	a = va;	b = vb;	return strcmp(a->arg0, b->arg0);} ulongflag_install(char *arg, char *help){	int i; 	qlock(&cons);	for(i=0; flag[i].arg0; i++)		;	if(i >= 32) {		qunlock(&cons);		print("flag_install: too many flags\n");		return 0;	}	flag[i+1].arg0 = 0;	flag[i].arg0 = arg;	flag[i].help = help;	flag[i].flag = 1<<i;	qsort(flag, i+1, sizeof(Flag), flagcmp);	qunlock(&cons);	return 1<<i;} voidcmd_flag(int argc, char *argv[]){	int f, n, i, j;	char *s;	Chan *cp; 	if(argc <= 1) {		for(i=0; flag[i].arg0; i++)			print("%.4lux %s %s\n",				flag[i].flag, flag[i].arg0, flag[i].help);		if(cons.flags)			print("flag[*]   = %.4lux\n", cons.flags);		for(cp = chans; cp; cp = cp->next)			if(cp->flags)				print("flag[%3d] = %.4lux\n", cp->chan, cp->flags);		return;	} 	f = 0;	n = -1;	for(i=1; i<argc; i++) {		for(j=0; s=flag[j].arg0; j++)			if(strcmp(s, argv[i]) == 0)				goto found;		j = number(argv[i], -1, 10);		if(j < 0) {			print("bad flag argument: %s\n", argv[i]);			continue;		}		n = j;		continue;	found:		f |= flag[j].flag;	} 	if(n < 0) {		cons.flags ^= f;		if(f == 0)			cons.flags = 0;		print("flag      = %.8lux\n", cons.flags);		return;	}	for(cp = chans; cp; cp = cp->next)		if(cp->chan == n) {			cp->flags ^= f;			if(f == 0)				cp->flags = 0;			print("flag[%3d] = %.8lux\n", cp->chan, cp->flags);			return;		}	print("no such channel\n");} static voidcmd_who(int argc, char *argv[]){	Chan *cp;	int i, c; 	c = 0;	for(cp = chans; cp; cp = cp->next) {		if(cp->whotime == 0 && !(cons.flags & whoflag)) {			c++;			continue;		}		if(argc > 1) {			for(i=1; i<argc; i++)				if(strcmp(argv[i], cp->whoname) == 0)					break;			if(i >= argc) {				c++;				continue;			}		}		print("%3d: %10s %24s", cp->chan,			cp->whoname? cp->whoname: "<nowhoname>", cp->whochan);		if(cp->whoprint)			cp->whoprint(cp);		print("\n");		prflush();	}	if(c > 0)		print("%d chans not listed\n", c);} static voidcmd_hangup(int argc, char *argv[]){	Chan *cp;	int n; 	if(argc < 2) {		print("usage: hangup chan-number\n");		return;	}	n = number(argv[1], -1, 10);	for(cp = chans; cp; cp = cp->next) {		if(cp->whotime == 0) {			if(cp->chan == n)				print("that chan is hung up\n");			continue;		}		if(cp->chan == n) {			/* need more than just fileinit with tcp */			chanhangup(cp, "console command", 1);			fileinit(cp);		}	}} static voidcmd_sync(int, char *[]){	wlock(&mainlock);	/* sync */	sync("command");	wunlock(&mainlock);	print("\n");} static voidcmd_help(int argc, char *argv[]){	char *arg;	int i, j; 	for(i=0; arg=command[i].arg0; i++) {		if(argc > 1) {			for(j=1; j<argc; j++)				if(strcmp(argv[j], arg) == 0)					goto found;			continue;		}	found:		print("\t%s %s\n", arg, command[i].help);		prflush();	}} voidcmd_fstat(int argc, char *argv[]){	int i; 	for(i=1; i<argc; i++) {		if(walkto(argv[i])) {			print("cant stat %s\n", argv[i]);			continue;		}		con_fstat(FID2);	}} voidcmd_create(int argc, char *argv[]){	int uid, gid;	long perm;	char elem[NAMELEN], *p; 	if(argc < 5) {		print("usage: create path uid gid mode [lad]\n");		return;	} 	p = utfrrune(argv[1], '/');	if(p) {		*p++ = 0;		if(walkto(argv[1])) {			print("create failed in walkto: %s\n", p);			return;		}	} else {		if(walkto("/"))			return;		p = argv[1];	}	if(strlen(p) >= NAMELEN) {		print("name too long %s\n", p);		return;	} 	memset(elem, 0, sizeof(elem));	strcpy(elem, p); 	uid = strtouid(argv[2]);	if(uid < -1)		uid = number(argv[2], -2, 10);	if(uid < -1) {		print("bad uid %s\n", argv[2]);		return;	} 	gid = strtouid(argv[3]);	if(gid < -1)		gid = number(argv[3], -2, 10);	if(gid < -1) {		print("bad gid %s\n", argv[3]);		return;	} 	perm = number(argv[4], 0777, 8) & 0777; 	if(argc > 5) {		if(strchr(argv[5], 'l'))			perm |= PLOCK;		if(strchr(argv[5], 'a'))			perm |= PAPND;		if(strchr(argv[5], 'd'))			perm |= PDIR;	} 	if(con_create(FID2, elem, uid, gid, perm, 0))		print("create failed: %s/%s\n", argv[1], p);} static voidcmd_clri(int argc, char *argv[]){	int i; 	for(i=1; i<argc; i++) {		if(walkto(argv[i])) {			print("cant remove %s\n", argv[i]);			continue;		}		con_clri(FID2);	}} static voidcmd_allow(int, char**){	wstatallow = writeallow = 1;} static voidcmd_disallow(int, char**){	wstatallow = writeallow = 0;} voidckblock(Device *d, Off a, int typ, Off qpath){	Iobuf *p; 

Lines 1–500 of 853.