xref: /plan9/sys/src/cmd/disk/kfs/con.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include	"all.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier static	char	elem[NAMELEN];
43e12c5d1SDavid du Colombier static	Filsys*	cur_fs;
53e12c5d1SDavid du Colombier static	char	conline[100];
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier void
83e12c5d1SDavid du Colombier consserve(void)
93e12c5d1SDavid du Colombier {
103e12c5d1SDavid du Colombier 	strncpy(cons.chan->whoname, "console", sizeof(cons.chan->whoname));
113e12c5d1SDavid du Colombier 	con_session();
123e12c5d1SDavid du Colombier 	cmd_exec("cfs");
133e12c5d1SDavid du Colombier 	cmd_exec("user");
143e12c5d1SDavid du Colombier 	cmd_exec("auth");
153e12c5d1SDavid du Colombier }
163e12c5d1SDavid du Colombier 
173e12c5d1SDavid du Colombier int
183e12c5d1SDavid du Colombier cmd_exec(char *arg)
193e12c5d1SDavid du Colombier {
203e12c5d1SDavid du Colombier 	char *s, *c;
213e12c5d1SDavid du Colombier 	int i;
223e12c5d1SDavid du Colombier 
233e12c5d1SDavid du Colombier 	for(i=0; s = command[i].string; i++) {
243e12c5d1SDavid du Colombier 		for(c=arg; *s; c++)
253e12c5d1SDavid du Colombier 			if(*c != *s++)
263e12c5d1SDavid du Colombier 				goto brk;
273e12c5d1SDavid du Colombier 		if(*c == '\0' || *c == ' ' || *c == '\t'){
283e12c5d1SDavid du Colombier 			cons.arg = c;
293e12c5d1SDavid du Colombier 			(*command[i].func)();
303e12c5d1SDavid du Colombier 			return 1;
313e12c5d1SDavid du Colombier 		}
323e12c5d1SDavid du Colombier 	brk:;
333e12c5d1SDavid du Colombier 	}
343e12c5d1SDavid du Colombier 	return 0;
353e12c5d1SDavid du Colombier }
363e12c5d1SDavid du Colombier 
373e12c5d1SDavid du Colombier void
383e12c5d1SDavid du Colombier cmd_check(void)
393e12c5d1SDavid du Colombier {
403e12c5d1SDavid du Colombier 	char *s;
413e12c5d1SDavid du Colombier 	int flags;
423e12c5d1SDavid du Colombier 
433e12c5d1SDavid du Colombier 	flags = 0;
443e12c5d1SDavid du Colombier 	for(s = cons.arg; *s; s++){
453e12c5d1SDavid du Colombier 		while(*s == ' ' || *s == '\t')
463e12c5d1SDavid du Colombier 			s++;
473e12c5d1SDavid du Colombier 		if(*s == '\0')
483e12c5d1SDavid du Colombier 			break;
493e12c5d1SDavid du Colombier 		switch(*s){
503e12c5d1SDavid du Colombier 		/* rebuild the free list */
513e12c5d1SDavid du Colombier 		case 'f':	flags |= Cfree;			break;
523e12c5d1SDavid du Colombier 		/* fix bad tags */
533e12c5d1SDavid du Colombier 		case 't':	flags |= Ctag;			break;
543e12c5d1SDavid du Colombier 		/* fix bad tags and clear the contents of the block */
553e12c5d1SDavid du Colombier 		case 'c':	flags |= Cream;			break;
563e12c5d1SDavid du Colombier 		/* delete all redundant references to a block */
573e12c5d1SDavid du Colombier 		case 'd':	flags |= Cbad;			break;
583e12c5d1SDavid du Colombier 		/* read and check tags on all blocks */
593e12c5d1SDavid du Colombier 		case 'r':	flags |= Crdall;		break;
603e12c5d1SDavid du Colombier 		/* write all of the blocks you touch */
613e12c5d1SDavid du Colombier 		case 'w':	flags |= Ctouch;		break;
623e12c5d1SDavid du Colombier 		/* print all directories as they are read */
633e12c5d1SDavid du Colombier 		case 'p':	flags |= Cpdir;			break;
643e12c5d1SDavid du Colombier 		/* print all files as they are read */
653e12c5d1SDavid du Colombier 		case 'P':	flags |= Cpfile;		break;
663e12c5d1SDavid du Colombier 		/* quiet, just report really nasty stuff */
673e12c5d1SDavid du Colombier 		case 'q':	flags |= Cquiet;		break;
683e12c5d1SDavid du Colombier 		}
693e12c5d1SDavid du Colombier 	}
703e12c5d1SDavid du Colombier 	check(cur_fs, flags);
713e12c5d1SDavid du Colombier }
723e12c5d1SDavid du Colombier 
733e12c5d1SDavid du Colombier enum
743e12c5d1SDavid du Colombier {
753e12c5d1SDavid du Colombier 	Sset	= (1<<0),
763e12c5d1SDavid du Colombier 	Setc	= (1<<1),
773e12c5d1SDavid du Colombier };
783e12c5d1SDavid du Colombier void
793e12c5d1SDavid du Colombier cmd_stats(void)
803e12c5d1SDavid du Colombier {
813e12c5d1SDavid du Colombier 	cprint("work stats\n");
823e12c5d1SDavid du Colombier 	cprint("	work = %F rps\n", (Filta){&cons.work, 1});
833e12c5d1SDavid du Colombier 	cprint("	rate = %F tBps\n", (Filta){&cons.rate, 1000});
843e12c5d1SDavid du Colombier 	cprint("	hits = %F iops\n", (Filta){&cons.bhit, 1});
853e12c5d1SDavid du Colombier 	cprint("	read = %F iops\n", (Filta){&cons.bread, 1});
863e12c5d1SDavid du Colombier 	cprint("	init = %F iops\n", (Filta){&cons.binit, 1});
873e12c5d1SDavid du Colombier /*	for(i = 0; i < MAXTAG; i++)
883e12c5d1SDavid du Colombier 		cprint("	tag %G = %F iops\n", i, (Filta){&cons.tags[i], 1});
893e12c5d1SDavid du Colombier */
903e12c5d1SDavid du Colombier }
913e12c5d1SDavid du Colombier 
923e12c5d1SDavid du Colombier void
933e12c5d1SDavid du Colombier cmd_sync(void)
943e12c5d1SDavid du Colombier {
953e12c5d1SDavid du Colombier 	rlock(&mainlock);
963e12c5d1SDavid du Colombier 	syncall();
973e12c5d1SDavid du Colombier 	runlock(&mainlock);
983e12c5d1SDavid du Colombier }
993e12c5d1SDavid du Colombier 
1003e12c5d1SDavid du Colombier void
1013e12c5d1SDavid du Colombier cmd_halt(void)
1023e12c5d1SDavid du Colombier {
1033e12c5d1SDavid du Colombier 	wlock(&mainlock);
1043e12c5d1SDavid du Colombier 	syncall();
105*219b2ee8SDavid du Colombier 	superok(cur_fs->dev, superaddr(cur_fs->dev), 1);
1063e12c5d1SDavid du Colombier 	print("kfs: file system halted\n");
1073e12c5d1SDavid du Colombier }
1083e12c5d1SDavid du Colombier 
1093e12c5d1SDavid du Colombier void
1103e12c5d1SDavid du Colombier cmd_help(void)
1113e12c5d1SDavid du Colombier {
1123e12c5d1SDavid du Colombier 	int i;
1133e12c5d1SDavid du Colombier 
1143e12c5d1SDavid du Colombier 	for(i=0; command[i].string; i++)
1153e12c5d1SDavid du Colombier 		cprint("	%s %s\n", command[i].string, command[i].args);
1163e12c5d1SDavid du Colombier 	cprint("check options:\n"
1173e12c5d1SDavid du Colombier 		" r	read all blocks\n"
1183e12c5d1SDavid du Colombier 		" f	rebuild the free list\n"
1193e12c5d1SDavid du Colombier 		" t	fix all bad tags\n"
1203e12c5d1SDavid du Colombier 		" c	fix bad tags and zero the blocks\n"
1213e12c5d1SDavid du Colombier 		" d	delete all redundant references to blocks\n"
1223e12c5d1SDavid du Colombier 		" p	print directories as they are checked\n"
1233e12c5d1SDavid du Colombier 		" P	print all files as they are checked\n"
1243e12c5d1SDavid du Colombier 		" w	write all blocks that are read\n");
1253e12c5d1SDavid du Colombier }
1263e12c5d1SDavid du Colombier 
1273e12c5d1SDavid du Colombier void
1283e12c5d1SDavid du Colombier cmd_create(void)
1293e12c5d1SDavid du Colombier {
1303e12c5d1SDavid du Colombier 	int uid, gid, err;
1313e12c5d1SDavid du Colombier 	long perm;
1323e12c5d1SDavid du Colombier 	char oelem[NAMELEN];
1333e12c5d1SDavid du Colombier 	char name[NAMELEN];
1343e12c5d1SDavid du Colombier 
1353e12c5d1SDavid du Colombier 	if(con_clone(FID1, FID2))
1363e12c5d1SDavid du Colombier 		return;
1373e12c5d1SDavid du Colombier 	if(skipbl(1))
1383e12c5d1SDavid du Colombier 		return;
1393e12c5d1SDavid du Colombier 	oelem[0] = 0;
1403e12c5d1SDavid du Colombier 	while(nextelem()) {
1413e12c5d1SDavid du Colombier 		if(oelem[0])
1423e12c5d1SDavid du Colombier 			if(con_walk(FID2, oelem))
1433e12c5d1SDavid du Colombier 				return;
144bd389b36SDavid du Colombier 		memmove(oelem, elem, NAMELEN);
1453e12c5d1SDavid du Colombier 	}
1463e12c5d1SDavid du Colombier 	if(skipbl(1))
1473e12c5d1SDavid du Colombier 		return;
1483e12c5d1SDavid du Colombier 	uid = strtouid(cname(name));
1493e12c5d1SDavid du Colombier 	if(uid == 0){
1503e12c5d1SDavid du Colombier 		cprint("unknown user %s\n", name);
1513e12c5d1SDavid du Colombier 		return;
1523e12c5d1SDavid du Colombier 	}
1533e12c5d1SDavid du Colombier 	gid = strtouid(cname(name));
1543e12c5d1SDavid du Colombier 	if(gid == 0){
1553e12c5d1SDavid du Colombier 		cprint("unknown group %s\n", name);
1563e12c5d1SDavid du Colombier 		return;
1573e12c5d1SDavid du Colombier 	}
1583e12c5d1SDavid du Colombier 	perm = number(0777, 8);
1593e12c5d1SDavid du Colombier 	skipbl(0);
1603e12c5d1SDavid du Colombier 	for(; *cons.arg; cons.arg++){
1613e12c5d1SDavid du Colombier 		if(*cons.arg == 'l')
1623e12c5d1SDavid du Colombier 			perm |= PLOCK;
1633e12c5d1SDavid du Colombier 		else
1643e12c5d1SDavid du Colombier 		if(*cons.arg == 'a')
1653e12c5d1SDavid du Colombier 			perm |= PAPND;
1663e12c5d1SDavid du Colombier 		else
1673e12c5d1SDavid du Colombier 		if(*cons.arg == 'd')
1683e12c5d1SDavid du Colombier 			perm |= PDIR;
1693e12c5d1SDavid du Colombier 		else
1703e12c5d1SDavid du Colombier 			break;
1713e12c5d1SDavid du Colombier 	}
1723e12c5d1SDavid du Colombier 	err = con_create(FID2, elem, uid, gid, perm, 0);
1733e12c5d1SDavid du Colombier 	if(err)
1743e12c5d1SDavid du Colombier 		cprint("can't create %s: %s\n", elem, errstr[err]);
1753e12c5d1SDavid du Colombier }
1763e12c5d1SDavid du Colombier 
1773e12c5d1SDavid du Colombier void
1783e12c5d1SDavid du Colombier cmd_clri(void)
1793e12c5d1SDavid du Colombier {
1803e12c5d1SDavid du Colombier 	if(con_clone(FID1, FID2))
1813e12c5d1SDavid du Colombier 		return;
1823e12c5d1SDavid du Colombier 	if(skipbl(1))
1833e12c5d1SDavid du Colombier 		return;
1843e12c5d1SDavid du Colombier 	while(nextelem())
185bd389b36SDavid du Colombier 		if(con_walk(FID2, elem)){
186bd389b36SDavid du Colombier 			cprint("can't walk %s\n", elem);
1873e12c5d1SDavid du Colombier 			return;
188bd389b36SDavid du Colombier 		}
1893e12c5d1SDavid du Colombier 	con_clri(FID2);
1903e12c5d1SDavid du Colombier }
1913e12c5d1SDavid du Colombier 
1923e12c5d1SDavid du Colombier void
1933e12c5d1SDavid du Colombier cmd_rename(void)
1943e12c5d1SDavid du Colombier {
1953e12c5d1SDavid du Colombier 	Dentry d;
1963e12c5d1SDavid du Colombier 	char stat[DIRREC];
1973e12c5d1SDavid du Colombier 	char oelem[NAMELEN], nelem[NAMELEN];
1983e12c5d1SDavid du Colombier 	int err;
1993e12c5d1SDavid du Colombier 
2003e12c5d1SDavid du Colombier 	if(con_clone(FID1, FID2))
2013e12c5d1SDavid du Colombier 		return;
2023e12c5d1SDavid du Colombier 	if(skipbl(1))
2033e12c5d1SDavid du Colombier 		return;
2043e12c5d1SDavid du Colombier 	oelem[0] = 0;
2053e12c5d1SDavid du Colombier 	while(nextelem()) {
2063e12c5d1SDavid du Colombier 		if(oelem[0])
2073e12c5d1SDavid du Colombier 			if(con_walk(FID2, oelem)){
2083e12c5d1SDavid du Colombier 				cprint("file does not exits");
2093e12c5d1SDavid du Colombier 				return;
2103e12c5d1SDavid du Colombier 			}
211bd389b36SDavid du Colombier 		memmove(oelem, elem, NAMELEN);
2123e12c5d1SDavid du Colombier 	}
2133e12c5d1SDavid du Colombier 	cname(nelem);
2143e12c5d1SDavid du Colombier 	if(!con_walk(FID2, nelem))
2153e12c5d1SDavid du Colombier 		cprint("file %s already exists\n", nelem);
2163e12c5d1SDavid du Colombier 	else if(con_walk(FID2, oelem))
2173e12c5d1SDavid du Colombier 		cprint("file does not already exist\n");
2183e12c5d1SDavid du Colombier 	else if(err = con_stat(FID2, stat))
2193e12c5d1SDavid du Colombier 		cprint("can't stat file: %s\n", errstr[err]);
2203e12c5d1SDavid du Colombier 	else{
2213e12c5d1SDavid du Colombier 		convM2D(stat, &d);
2223e12c5d1SDavid du Colombier 		strncpy(d.name, nelem, NAMELEN);
2233e12c5d1SDavid du Colombier 		convD2M(&d, stat);
2243e12c5d1SDavid du Colombier 		if(err = con_wstat(FID2, stat))
2253e12c5d1SDavid du Colombier 			cprint("can't move file: %s\n", errstr[err]);
2263e12c5d1SDavid du Colombier 	}
2273e12c5d1SDavid du Colombier }
2283e12c5d1SDavid du Colombier 
2293e12c5d1SDavid du Colombier void
2303e12c5d1SDavid du Colombier cmd_remove(void)
2313e12c5d1SDavid du Colombier {
2323e12c5d1SDavid du Colombier 	if(con_clone(FID1, FID2))
2333e12c5d1SDavid du Colombier 		return;
2343e12c5d1SDavid du Colombier 	if(skipbl(1))
2353e12c5d1SDavid du Colombier 		return;
2363e12c5d1SDavid du Colombier 	while(nextelem())
237bd389b36SDavid du Colombier 		if(con_walk(FID2, elem)){
238bd389b36SDavid du Colombier 			cprint("can't walk %s\n", elem);
2393e12c5d1SDavid du Colombier 			return;
240bd389b36SDavid du Colombier 		}
2413e12c5d1SDavid du Colombier 	con_remove(FID2);
2423e12c5d1SDavid du Colombier }
2433e12c5d1SDavid du Colombier 
2443e12c5d1SDavid du Colombier void
2453e12c5d1SDavid du Colombier cmd_cfs(void)
2463e12c5d1SDavid du Colombier {
2473e12c5d1SDavid du Colombier 	Filsys *fs;
2483e12c5d1SDavid du Colombier 
2493e12c5d1SDavid du Colombier 	if(*cons.arg != ' ') {
2503e12c5d1SDavid du Colombier 		fs = &filsys[0];		/* default */
2513e12c5d1SDavid du Colombier 	} else {
2523e12c5d1SDavid du Colombier 		if(skipbl(1))
2533e12c5d1SDavid du Colombier 			return;
2543e12c5d1SDavid du Colombier 		if(!nextelem())
2553e12c5d1SDavid du Colombier 			fs = &filsys[0];	/* default */
2563e12c5d1SDavid du Colombier 		else
2573e12c5d1SDavid du Colombier 			fs = fsstr(elem);
2583e12c5d1SDavid du Colombier 	}
2593e12c5d1SDavid du Colombier 	if(fs == 0) {
2603e12c5d1SDavid du Colombier 		cprint("unknown file system %s\n", elem);
2613e12c5d1SDavid du Colombier 		return;
2623e12c5d1SDavid du Colombier 	}
2633e12c5d1SDavid du Colombier 	if(con_attach(FID1, "adm", fs->name))
2643e12c5d1SDavid du Colombier 		panic("FID1 attach to root");
2653e12c5d1SDavid du Colombier 	cur_fs = fs;
2663e12c5d1SDavid du Colombier }
2673e12c5d1SDavid du Colombier 
2683e12c5d1SDavid du Colombier int
2693e12c5d1SDavid du Colombier adduser(char *user)
2703e12c5d1SDavid du Colombier {
2713e12c5d1SDavid du Colombier 	char stat[DIRREC];
2723e12c5d1SDavid du Colombier 	char msg[100];
2733e12c5d1SDavid du Colombier 	Uid *u;
2743e12c5d1SDavid du Colombier 	int i, c, nu;
2753e12c5d1SDavid du Colombier 
2763e12c5d1SDavid du Colombier 	/*
2773e12c5d1SDavid du Colombier 	 * check uniq of name
2783e12c5d1SDavid du Colombier 	 * and get next uid
2793e12c5d1SDavid du Colombier 	 */
2803e12c5d1SDavid du Colombier 	cmd_exec("cfs");
2813e12c5d1SDavid du Colombier 	cmd_exec("user");
2823e12c5d1SDavid du Colombier 	nu = 0;
2833e12c5d1SDavid du Colombier 	for(i=0, u=uid; i<conf.nuid; i++,u++) {
2843e12c5d1SDavid du Colombier 		c = u->uid;
2853e12c5d1SDavid du Colombier 		if(c == 0)
2863e12c5d1SDavid du Colombier 			break;
2873e12c5d1SDavid du Colombier 		if(strcmp(uidspace+u->offset, user) == 0)
2883e12c5d1SDavid du Colombier 			return 1;
2893e12c5d1SDavid du Colombier 		if(c >= 10000)
2903e12c5d1SDavid du Colombier 			continue;
2913e12c5d1SDavid du Colombier 		if(c > nu)
2923e12c5d1SDavid du Colombier 			nu = c;
2933e12c5d1SDavid du Colombier 	}
2943e12c5d1SDavid du Colombier 	nu++;
2953e12c5d1SDavid du Colombier 
2963e12c5d1SDavid du Colombier 	/*
2973e12c5d1SDavid du Colombier 	 * write onto adm/users
2983e12c5d1SDavid du Colombier 	 */
2993e12c5d1SDavid du Colombier 	if(con_clone(FID1, FID2)
3003e12c5d1SDavid du Colombier 	|| con_path(FID2, "/adm/users")
3013e12c5d1SDavid du Colombier 	|| con_open(FID2, 1)) {
3023e12c5d1SDavid du Colombier 		cprint("can't open /adm/users\n");
3033e12c5d1SDavid du Colombier 		return 0;
3043e12c5d1SDavid du Colombier 	}
3053e12c5d1SDavid du Colombier 
3063e12c5d1SDavid du Colombier 	sprint(msg, "%d:%s:%s:\n", nu, user, user);
3073e12c5d1SDavid du Colombier 	cprint("add user '%s'", msg);
3083e12c5d1SDavid du Colombier 	c = strlen(msg);
3093e12c5d1SDavid du Colombier 	i = con_stat(FID2, stat);
3103e12c5d1SDavid du Colombier 	if(i){
3113e12c5d1SDavid du Colombier 		cprint("can't stat /adm/users: %s\n", errstr[i]);
3123e12c5d1SDavid du Colombier 		return 0;
3133e12c5d1SDavid du Colombier 	}
3143e12c5d1SDavid du Colombier 	i = con_write(FID2, msg, statlen(stat), c);
3153e12c5d1SDavid du Colombier 	if(i != c){
3163e12c5d1SDavid du Colombier 		cprint("short write on /adm/users: %d %d\n", c, i);
3173e12c5d1SDavid du Colombier 		return 0;
3183e12c5d1SDavid du Colombier 	}
3193e12c5d1SDavid du Colombier 	return 1;
3203e12c5d1SDavid du Colombier }
3213e12c5d1SDavid du Colombier 
3223e12c5d1SDavid du Colombier void
3233e12c5d1SDavid du Colombier cmd_newuser(void)
3243e12c5d1SDavid du Colombier {
3253e12c5d1SDavid du Colombier 	char user[NAMELEN], msg[100];
3263e12c5d1SDavid du Colombier 	int i, c;
3273e12c5d1SDavid du Colombier 
3283e12c5d1SDavid du Colombier 	/*
3293e12c5d1SDavid du Colombier 	 * get uid
3303e12c5d1SDavid du Colombier 	 */
3313e12c5d1SDavid du Colombier 	cname(user);
3323e12c5d1SDavid du Colombier 	for(i=0; i<NAMELEN; i++) {
3333e12c5d1SDavid du Colombier 		c = user[i];
3343e12c5d1SDavid du Colombier 		if(c == 0)
3353e12c5d1SDavid du Colombier 			break;
3363e12c5d1SDavid du Colombier 		if(c >= '0' && c <= '9'
3373e12c5d1SDavid du Colombier 		|| c >= 'a' && c <= 'z'
3383e12c5d1SDavid du Colombier 		|| c >= 'A' && c <= 'Z')
3393e12c5d1SDavid du Colombier 			continue;
3403e12c5d1SDavid du Colombier 		cprint("bad character in name: 0x%x\n", c);
3413e12c5d1SDavid du Colombier 		return;
3423e12c5d1SDavid du Colombier 	}
3433e12c5d1SDavid du Colombier 	if(i < 2) {
3443e12c5d1SDavid du Colombier 		cprint("name too short: %s\n", user);
3453e12c5d1SDavid du Colombier 		return;
3463e12c5d1SDavid du Colombier 	}
3473e12c5d1SDavid du Colombier 	if(i >= NAMELEN) {
3483e12c5d1SDavid du Colombier 		cprint("name too long: %s\n", user);
3493e12c5d1SDavid du Colombier 		return;
3503e12c5d1SDavid du Colombier 	}
3513e12c5d1SDavid du Colombier 
3523e12c5d1SDavid du Colombier 	/*
3533e12c5d1SDavid du Colombier 	 * install and create directory
3543e12c5d1SDavid du Colombier 	 */
3553e12c5d1SDavid du Colombier 	if(!adduser(user))
3563e12c5d1SDavid du Colombier 		return;
3573e12c5d1SDavid du Colombier 
3583e12c5d1SDavid du Colombier 	cmd_exec("user");
3593e12c5d1SDavid du Colombier 	sprint(msg, "create /usr/%s %s %s 775 d", user, user, user);
3603e12c5d1SDavid du Colombier 	cmd_exec(msg);
3613e12c5d1SDavid du Colombier 	sprint(msg, "create /usr/%s/tmp %s %s 775 d", user, user, user);
3623e12c5d1SDavid du Colombier 	cmd_exec(msg);
3633e12c5d1SDavid du Colombier 	sprint(msg, "create /usr/%s/lib %s %s 775 d", user, user, user);
3643e12c5d1SDavid du Colombier 	cmd_exec(msg);
3653e12c5d1SDavid du Colombier 	sprint(msg, "create /usr/%s/bin %s %s 775 d", user, user, user);
3663e12c5d1SDavid du Colombier 	cmd_exec(msg);
3673e12c5d1SDavid du Colombier 	sprint(msg, "create /usr/%s/bin/rc %s %s 775 d", user, user, user);
3683e12c5d1SDavid du Colombier 	cmd_exec(msg);
3693e12c5d1SDavid du Colombier 	sprint(msg, "create /usr/%s/bin/mips %s %s 775 d", user, user, user);
3703e12c5d1SDavid du Colombier 	cmd_exec(msg);
3713e12c5d1SDavid du Colombier 	sprint(msg, "create /usr/%s/bin/386 %s %s 775 d", user, user, user);
3723e12c5d1SDavid du Colombier 	cmd_exec(msg);
3733e12c5d1SDavid du Colombier 	sprint(msg, "create /usr/%s/bin/68020 %s %s 775 d", user, user, user);
3743e12c5d1SDavid du Colombier 	cmd_exec(msg);
3753e12c5d1SDavid du Colombier 	sprint(msg, "create /usr/%s/bin/sparc %s %s 775 d", user, user, user);
3763e12c5d1SDavid du Colombier 	cmd_exec(msg);
3773e12c5d1SDavid du Colombier }
3783e12c5d1SDavid du Colombier 
3793e12c5d1SDavid du Colombier void
3803e12c5d1SDavid du Colombier cmd_checkuser(void)
3813e12c5d1SDavid du Colombier {
3823e12c5d1SDavid du Colombier 	uchar buf[DIRREC], *p;
3833e12c5d1SDavid du Colombier 	static char utime[4];
3843e12c5d1SDavid du Colombier 
3853e12c5d1SDavid du Colombier 	if(con_clone(FID1, FID2)
3863e12c5d1SDavid du Colombier 	|| con_path(FID2, "/adm/users")
3873e12c5d1SDavid du Colombier 	|| con_open(FID2, 0)
3883e12c5d1SDavid du Colombier 	|| con_stat(FID2, (char*)buf))
3893e12c5d1SDavid du Colombier 		return;
3903e12c5d1SDavid du Colombier 	p = buf + 3*NAMELEN + 4*4;
3913e12c5d1SDavid du Colombier 	if(memcmp(utime, p, 4) == 0)
3923e12c5d1SDavid du Colombier 		return;
393bd389b36SDavid du Colombier 	memmove(utime, p, 4);
3943e12c5d1SDavid du Colombier 	cmd_user();
3953e12c5d1SDavid du Colombier }
3963e12c5d1SDavid du Colombier 
3973e12c5d1SDavid du Colombier void
3983e12c5d1SDavid du Colombier cmd_allow(void)
3993e12c5d1SDavid du Colombier {
400bd389b36SDavid du Colombier 	wstatallow = 1;
4013e12c5d1SDavid du Colombier }
4023e12c5d1SDavid du Colombier 
4033e12c5d1SDavid du Colombier void
4043e12c5d1SDavid du Colombier cmd_disallow(void)
4053e12c5d1SDavid du Colombier {
406bd389b36SDavid du Colombier 	wstatallow = 0;
4073e12c5d1SDavid du Colombier }
4083e12c5d1SDavid du Colombier 
4093e12c5d1SDavid du Colombier Command	command[] =
4103e12c5d1SDavid du Colombier {
4113e12c5d1SDavid du Colombier 	"allow",	cmd_allow,	"",
4123e12c5d1SDavid du Colombier 	"allowoff",	cmd_disallow,	"",
4133e12c5d1SDavid du Colombier 	"cfs",		cmd_cfs,	"[filsys]",
4143e12c5d1SDavid du Colombier 	"check",	cmd_check,	"[rftRdPpw]",
415bd389b36SDavid du Colombier 	"clri",		cmd_clri,	"filename",
4163e12c5d1SDavid du Colombier 	"create",	cmd_create,	"filename user group perm [ald]",
4173e12c5d1SDavid du Colombier 	"disallow",	cmd_disallow,	"",
4183e12c5d1SDavid du Colombier 	"halt",		cmd_halt,	"",
4193e12c5d1SDavid du Colombier 	"help",		cmd_help,	"",
4203e12c5d1SDavid du Colombier 	"newuser",	cmd_newuser,	"username",
4213e12c5d1SDavid du Colombier 	"remove",	cmd_remove,	"filename",
4223e12c5d1SDavid du Colombier 	"rename",	cmd_rename,	"file newname",
4233e12c5d1SDavid du Colombier 	"stats",	cmd_stats,	"[fw]",
4243e12c5d1SDavid du Colombier 	"sync",		cmd_sync,	"",
4253e12c5d1SDavid du Colombier 	"user",		cmd_user,	"",
4263e12c5d1SDavid du Colombier 	0
4273e12c5d1SDavid du Colombier };
4283e12c5d1SDavid du Colombier 
4293e12c5d1SDavid du Colombier int
4303e12c5d1SDavid du Colombier skipbl(int err)
4313e12c5d1SDavid du Colombier {
4323e12c5d1SDavid du Colombier 	if(*cons.arg != ' ') {
4333e12c5d1SDavid du Colombier 		if(err)
4343e12c5d1SDavid du Colombier 			cprint("syntax error\n");
4353e12c5d1SDavid du Colombier 		return 1;
4363e12c5d1SDavid du Colombier 	}
4373e12c5d1SDavid du Colombier 	while(*cons.arg == ' ')
4383e12c5d1SDavid du Colombier 		cons.arg++;
4393e12c5d1SDavid du Colombier 	return 0;
4403e12c5d1SDavid du Colombier }
4413e12c5d1SDavid du Colombier 
4423e12c5d1SDavid du Colombier char*
4433e12c5d1SDavid du Colombier cname(char *name)
4443e12c5d1SDavid du Colombier {
4453e12c5d1SDavid du Colombier 	int i, c;
4463e12c5d1SDavid du Colombier 
4473e12c5d1SDavid du Colombier 	skipbl(0);
4483e12c5d1SDavid du Colombier 	memset(name, 0, NAMELEN);
4493e12c5d1SDavid du Colombier 	for(i=0;; i++) {
4503e12c5d1SDavid du Colombier 		c = *cons.arg;
4513e12c5d1SDavid du Colombier 		switch(c) {
4523e12c5d1SDavid du Colombier 		case ' ':
4533e12c5d1SDavid du Colombier 		case '\t':
4543e12c5d1SDavid du Colombier 		case '\n':
4553e12c5d1SDavid du Colombier 		case '\0':
4563e12c5d1SDavid du Colombier 			return name;
4573e12c5d1SDavid du Colombier 		}
4583e12c5d1SDavid du Colombier 		if(i < NAMELEN-1)
4593e12c5d1SDavid du Colombier 			name[i] = c;
4603e12c5d1SDavid du Colombier 		cons.arg++;
4613e12c5d1SDavid du Colombier 	}
4623e12c5d1SDavid du Colombier 	return 0;
4633e12c5d1SDavid du Colombier }
4643e12c5d1SDavid du Colombier 
4653e12c5d1SDavid du Colombier int
4663e12c5d1SDavid du Colombier nextelem(void)
4673e12c5d1SDavid du Colombier {
4683e12c5d1SDavid du Colombier 	char *e;
4693e12c5d1SDavid du Colombier 	int i, c;
4703e12c5d1SDavid du Colombier 
4713e12c5d1SDavid du Colombier 	e = elem;
4723e12c5d1SDavid du Colombier 	while(*cons.arg == '/')
4733e12c5d1SDavid du Colombier 		cons.arg++;
4743e12c5d1SDavid du Colombier 	c = *cons.arg;
4753e12c5d1SDavid du Colombier 	if(c == 0 || c == ' ')
4763e12c5d1SDavid du Colombier 		return 0;
4773e12c5d1SDavid du Colombier 	for(i = 0; c = *cons.arg; i++) {
4783e12c5d1SDavid du Colombier 		if(c == ' ' || c == '/')
4793e12c5d1SDavid du Colombier 			break;
4803e12c5d1SDavid du Colombier 		if(i == NAMELEN) {
4813e12c5d1SDavid du Colombier 			cprint("path name component too long\n");
4823e12c5d1SDavid du Colombier 			return 0;
4833e12c5d1SDavid du Colombier 		}
4843e12c5d1SDavid du Colombier 		*e++ = c;
4853e12c5d1SDavid du Colombier 		cons.arg++;
4863e12c5d1SDavid du Colombier 	}
4873e12c5d1SDavid du Colombier 	*e = 0;
4883e12c5d1SDavid du Colombier 	return 1;
4893e12c5d1SDavid du Colombier }
4903e12c5d1SDavid du Colombier 
4913e12c5d1SDavid du Colombier long
4923e12c5d1SDavid du Colombier number(int d, int base)
4933e12c5d1SDavid du Colombier {
4943e12c5d1SDavid du Colombier 	int c, sign, any;
4953e12c5d1SDavid du Colombier 	long n;
4963e12c5d1SDavid du Colombier 
4973e12c5d1SDavid du Colombier 	sign = 0;
4983e12c5d1SDavid du Colombier 	any = 0;
4993e12c5d1SDavid du Colombier 	n = 0;
5003e12c5d1SDavid du Colombier 
5013e12c5d1SDavid du Colombier 	c = *cons.arg;
5023e12c5d1SDavid du Colombier 	while(c == ' ') {
5033e12c5d1SDavid du Colombier 		cons.arg++;
5043e12c5d1SDavid du Colombier 		c = *cons.arg;
5053e12c5d1SDavid du Colombier 	}
5063e12c5d1SDavid du Colombier 	if(c == '-') {
5073e12c5d1SDavid du Colombier 		sign = 1;
5083e12c5d1SDavid du Colombier 		cons.arg++;
5093e12c5d1SDavid du Colombier 		c = *cons.arg;
5103e12c5d1SDavid du Colombier 	}
5113e12c5d1SDavid du Colombier 	while((c >= '0' && c <= '9') ||
5123e12c5d1SDavid du Colombier 	      (base == 16 && c >= 'a' && c <= 'f') ||
5133e12c5d1SDavid du Colombier 	      (base == 16 && c >= 'A' && c <= 'F')) {
5143e12c5d1SDavid du Colombier 		n *= base;
5153e12c5d1SDavid du Colombier 		if(c >= 'a' && c <= 'f')
5163e12c5d1SDavid du Colombier 			n += c - 'a' + 10;
5173e12c5d1SDavid du Colombier 		else
5183e12c5d1SDavid du Colombier 		if(c >= 'A' && c <= 'F')
5193e12c5d1SDavid du Colombier 			n += c - 'A' + 10;
5203e12c5d1SDavid du Colombier 		else
5213e12c5d1SDavid du Colombier 			n += c - '0';
5223e12c5d1SDavid du Colombier 		cons.arg++;
5233e12c5d1SDavid du Colombier 		c = *cons.arg;
5243e12c5d1SDavid du Colombier 		any = 1;
5253e12c5d1SDavid du Colombier 	}
5263e12c5d1SDavid du Colombier 	if(!any)
5273e12c5d1SDavid du Colombier 		return d;
5283e12c5d1SDavid du Colombier 	if(sign)
5293e12c5d1SDavid du Colombier 		n = -n;
5303e12c5d1SDavid du Colombier 	return n;
5313e12c5d1SDavid du Colombier }
532