13e12c5d1SDavid du Colombier #include "all.h"
29a747e4fSDavid du Colombier #include "9p1.h"
33e12c5d1SDavid du Colombier
43e12c5d1SDavid du Colombier static char elem[NAMELEN];
53e12c5d1SDavid du Colombier static Filsys* cur_fs;
63e12c5d1SDavid du Colombier static char conline[100];
73e12c5d1SDavid du Colombier
83e12c5d1SDavid du Colombier void
consserve(void)93e12c5d1SDavid du Colombier consserve(void)
103e12c5d1SDavid du Colombier {
113e12c5d1SDavid du Colombier con_session();
123e12c5d1SDavid du Colombier cmd_exec("cfs");
133e12c5d1SDavid du Colombier cmd_exec("user");
143e12c5d1SDavid du Colombier }
153e12c5d1SDavid du Colombier
163e12c5d1SDavid du Colombier int
cmd_exec(char * arg)173e12c5d1SDavid du Colombier cmd_exec(char *arg)
183e12c5d1SDavid du Colombier {
193e12c5d1SDavid du Colombier char *s, *c;
203e12c5d1SDavid du Colombier int i;
213e12c5d1SDavid du Colombier
223e12c5d1SDavid du Colombier for(i=0; s = command[i].string; i++) {
233e12c5d1SDavid du Colombier for(c=arg; *s; c++)
243e12c5d1SDavid du Colombier if(*c != *s++)
253e12c5d1SDavid du Colombier goto brk;
263e12c5d1SDavid du Colombier if(*c == '\0' || *c == ' ' || *c == '\t'){
273e12c5d1SDavid du Colombier cons.arg = c;
283e12c5d1SDavid du Colombier (*command[i].func)();
293e12c5d1SDavid du Colombier return 1;
303e12c5d1SDavid du Colombier }
313e12c5d1SDavid du Colombier brk:;
323e12c5d1SDavid du Colombier }
333e12c5d1SDavid du Colombier return 0;
343e12c5d1SDavid du Colombier }
353e12c5d1SDavid du Colombier
363e12c5d1SDavid du Colombier void
cmd_check(void)373e12c5d1SDavid du Colombier cmd_check(void)
383e12c5d1SDavid du Colombier {
393e12c5d1SDavid du Colombier char *s;
403e12c5d1SDavid du Colombier int flags;
413e12c5d1SDavid du Colombier
423e12c5d1SDavid du Colombier flags = 0;
433e12c5d1SDavid du Colombier for(s = cons.arg; *s; s++){
443e12c5d1SDavid du Colombier while(*s == ' ' || *s == '\t')
453e12c5d1SDavid du Colombier s++;
463e12c5d1SDavid du Colombier if(*s == '\0')
473e12c5d1SDavid du Colombier break;
483e12c5d1SDavid du Colombier switch(*s){
493e12c5d1SDavid du Colombier /* rebuild the free list */
503e12c5d1SDavid du Colombier case 'f': flags |= Cfree; break;
513e12c5d1SDavid du Colombier /* fix bad tags */
523e12c5d1SDavid du Colombier case 't': flags |= Ctag; break;
533e12c5d1SDavid du Colombier /* fix bad tags and clear the contents of the block */
543e12c5d1SDavid du Colombier case 'c': flags |= Cream; break;
553e12c5d1SDavid du Colombier /* delete all redundant references to a block */
563e12c5d1SDavid du Colombier case 'd': flags |= Cbad; break;
573e12c5d1SDavid du Colombier /* read and check tags on all blocks */
583e12c5d1SDavid du Colombier case 'r': flags |= Crdall; break;
593e12c5d1SDavid du Colombier /* write all of the blocks you touch */
603e12c5d1SDavid du Colombier case 'w': flags |= Ctouch; break;
613e12c5d1SDavid du Colombier /* print all directories as they are read */
623e12c5d1SDavid du Colombier case 'p': flags |= Cpdir; break;
633e12c5d1SDavid du Colombier /* print all files as they are read */
643e12c5d1SDavid du Colombier case 'P': flags |= Cpfile; break;
653e12c5d1SDavid du Colombier /* quiet, just report really nasty stuff */
663e12c5d1SDavid du Colombier case 'q': flags |= Cquiet; break;
673e12c5d1SDavid du Colombier }
683e12c5d1SDavid du Colombier }
693e12c5d1SDavid du Colombier check(cur_fs, flags);
703e12c5d1SDavid du Colombier }
713e12c5d1SDavid du Colombier
723e12c5d1SDavid du Colombier enum
733e12c5d1SDavid du Colombier {
743e12c5d1SDavid du Colombier Sset = (1<<0),
753e12c5d1SDavid du Colombier Setc = (1<<1),
763e12c5d1SDavid du Colombier };
773e12c5d1SDavid du Colombier void
cmd_stats(void)783e12c5d1SDavid du Colombier cmd_stats(void)
793e12c5d1SDavid du Colombier {
803e12c5d1SDavid du Colombier cprint("work stats\n");
819a747e4fSDavid du Colombier cprint(" work = %A rps\n", (Filta){&cons.work, 1});
829a747e4fSDavid du Colombier cprint(" rate = %A tBps\n", (Filta){&cons.rate, 1000});
839a747e4fSDavid du Colombier cprint(" hits = %A iops\n", (Filta){&cons.bhit, 1});
849a747e4fSDavid du Colombier cprint(" read = %A iops\n", (Filta){&cons.bread, 1});
859a747e4fSDavid du Colombier cprint(" init = %A iops\n", (Filta){&cons.binit, 1});
863e12c5d1SDavid du Colombier /* for(i = 0; i < MAXTAG; i++)
879a747e4fSDavid du Colombier cprint(" tag %G = %A iops\n", i, (Filta){&cons.tags[i], 1});
883e12c5d1SDavid du Colombier */
893e12c5d1SDavid du Colombier }
903e12c5d1SDavid du Colombier
913e12c5d1SDavid du Colombier void
cmd_sync(void)923e12c5d1SDavid du Colombier cmd_sync(void)
933e12c5d1SDavid du Colombier {
943e12c5d1SDavid du Colombier rlock(&mainlock);
953e12c5d1SDavid du Colombier syncall();
963e12c5d1SDavid du Colombier runlock(&mainlock);
973e12c5d1SDavid du Colombier }
983e12c5d1SDavid du Colombier
993e12c5d1SDavid du Colombier void
cmd_halt(void)1003e12c5d1SDavid du Colombier cmd_halt(void)
1013e12c5d1SDavid du Colombier {
1023e12c5d1SDavid du Colombier wlock(&mainlock);
1033e12c5d1SDavid du Colombier syncall();
104219b2ee8SDavid du Colombier superok(cur_fs->dev, superaddr(cur_fs->dev), 1);
1053e12c5d1SDavid du Colombier print("kfs: file system halted\n");
1063e12c5d1SDavid du Colombier }
1073e12c5d1SDavid du Colombier
1083e12c5d1SDavid du Colombier void
cmd_start(void)10980ee5cbfSDavid du Colombier cmd_start(void)
11080ee5cbfSDavid du Colombier {
11180ee5cbfSDavid du Colombier superok(cur_fs->dev, superaddr(cur_fs->dev), 0);
11280ee5cbfSDavid du Colombier wunlock(&mainlock);
11380ee5cbfSDavid du Colombier print("kfs: file system started\n");
11480ee5cbfSDavid du Colombier }
11580ee5cbfSDavid du Colombier
11680ee5cbfSDavid du Colombier void
cmd_help(void)1173e12c5d1SDavid du Colombier cmd_help(void)
1183e12c5d1SDavid du Colombier {
1193e12c5d1SDavid du Colombier int i;
1203e12c5d1SDavid du Colombier
1213e12c5d1SDavid du Colombier for(i=0; command[i].string; i++)
1223e12c5d1SDavid du Colombier cprint(" %s %s\n", command[i].string, command[i].args);
1233e12c5d1SDavid du Colombier cprint("check options:\n"
1243e12c5d1SDavid du Colombier " r read all blocks\n"
1253e12c5d1SDavid du Colombier " f rebuild the free list\n"
1263e12c5d1SDavid du Colombier " t fix all bad tags\n"
1273e12c5d1SDavid du Colombier " c fix bad tags and zero the blocks\n"
1283e12c5d1SDavid du Colombier " d delete all redundant references to blocks\n"
1293e12c5d1SDavid du Colombier " p print directories as they are checked\n"
1303e12c5d1SDavid du Colombier " P print all files as they are checked\n"
1313e12c5d1SDavid du Colombier " w write all blocks that are read\n");
1323e12c5d1SDavid du Colombier }
1333e12c5d1SDavid du Colombier
1343e12c5d1SDavid du Colombier void
cmd_create(void)1353e12c5d1SDavid du Colombier cmd_create(void)
1363e12c5d1SDavid du Colombier {
1373e12c5d1SDavid du Colombier int uid, gid, err;
1383e12c5d1SDavid du Colombier long perm;
1393e12c5d1SDavid du Colombier char oelem[NAMELEN];
1403e12c5d1SDavid du Colombier char name[NAMELEN];
1413e12c5d1SDavid du Colombier
1429a747e4fSDavid du Colombier if(err = con_clone(FID1, FID2)){
1439a747e4fSDavid du Colombier cprint("clone failed: %s\n", errstring[err]);
1443e12c5d1SDavid du Colombier return;
1459a747e4fSDavid du Colombier }
1469a747e4fSDavid du Colombier if(skipbl(1)){
1479a747e4fSDavid du Colombier cprint("skipbl\n");
1483e12c5d1SDavid du Colombier return;
1499a747e4fSDavid du Colombier }
1503e12c5d1SDavid du Colombier oelem[0] = 0;
1513e12c5d1SDavid du Colombier while(nextelem()) {
1523e12c5d1SDavid du Colombier if(oelem[0])
1539a747e4fSDavid du Colombier if(err = con_walk(FID2, oelem)){
1549a747e4fSDavid du Colombier cprint("walk failed: %s\n", errstring[err]);
1553e12c5d1SDavid du Colombier return;
1569a747e4fSDavid du Colombier }
157bd389b36SDavid du Colombier memmove(oelem, elem, NAMELEN);
1583e12c5d1SDavid du Colombier }
1593e12c5d1SDavid du Colombier if(skipbl(1))
1603e12c5d1SDavid du Colombier return;
1613e12c5d1SDavid du Colombier uid = strtouid(cname(name));
1623e12c5d1SDavid du Colombier if(uid == 0){
1633e12c5d1SDavid du Colombier cprint("unknown user %s\n", name);
1643e12c5d1SDavid du Colombier return;
1653e12c5d1SDavid du Colombier }
1663e12c5d1SDavid du Colombier gid = strtouid(cname(name));
1673e12c5d1SDavid du Colombier if(gid == 0){
1683e12c5d1SDavid du Colombier cprint("unknown group %s\n", name);
1693e12c5d1SDavid du Colombier return;
1703e12c5d1SDavid du Colombier }
1713e12c5d1SDavid du Colombier perm = number(0777, 8);
1723e12c5d1SDavid du Colombier skipbl(0);
1733e12c5d1SDavid du Colombier for(; *cons.arg; cons.arg++){
1743e12c5d1SDavid du Colombier if(*cons.arg == 'l')
1753e12c5d1SDavid du Colombier perm |= PLOCK;
1763e12c5d1SDavid du Colombier else
1773e12c5d1SDavid du Colombier if(*cons.arg == 'a')
1783e12c5d1SDavid du Colombier perm |= PAPND;
1793e12c5d1SDavid du Colombier else
1803e12c5d1SDavid du Colombier if(*cons.arg == 'd')
1813e12c5d1SDavid du Colombier perm |= PDIR;
1823e12c5d1SDavid du Colombier else
1833e12c5d1SDavid du Colombier break;
1843e12c5d1SDavid du Colombier }
1853e12c5d1SDavid du Colombier err = con_create(FID2, elem, uid, gid, perm, 0);
1863e12c5d1SDavid du Colombier if(err)
1877dd7cddfSDavid du Colombier cprint("can't create %s: %s\n", elem, errstring[err]);
1883e12c5d1SDavid du Colombier }
1893e12c5d1SDavid du Colombier
1903e12c5d1SDavid du Colombier void
cmd_clri(void)1913e12c5d1SDavid du Colombier cmd_clri(void)
1923e12c5d1SDavid du Colombier {
1933e12c5d1SDavid du Colombier if(con_clone(FID1, FID2))
1943e12c5d1SDavid du Colombier return;
1953e12c5d1SDavid du Colombier if(skipbl(1))
1963e12c5d1SDavid du Colombier return;
1973e12c5d1SDavid du Colombier while(nextelem())
198bd389b36SDavid du Colombier if(con_walk(FID2, elem)){
199bd389b36SDavid du Colombier cprint("can't walk %s\n", elem);
2003e12c5d1SDavid du Colombier return;
201bd389b36SDavid du Colombier }
2023e12c5d1SDavid du Colombier con_clri(FID2);
2033e12c5d1SDavid du Colombier }
2043e12c5d1SDavid du Colombier
2053e12c5d1SDavid du Colombier void
cmd_rename(void)2063e12c5d1SDavid du Colombier cmd_rename(void)
2073e12c5d1SDavid du Colombier {
2089a747e4fSDavid du Colombier ulong perm;
2093e12c5d1SDavid du Colombier Dentry d;
2103e12c5d1SDavid du Colombier char stat[DIRREC];
2119a747e4fSDavid du Colombier char oelem[NAMELEN], noelem[NAMELEN], nxelem[NAMELEN];
2123e12c5d1SDavid du Colombier int err;
2133e12c5d1SDavid du Colombier
2143e12c5d1SDavid du Colombier if(con_clone(FID1, FID2))
2153e12c5d1SDavid du Colombier return;
2163e12c5d1SDavid du Colombier if(skipbl(1))
2173e12c5d1SDavid du Colombier return;
2183e12c5d1SDavid du Colombier oelem[0] = 0;
2193e12c5d1SDavid du Colombier while(nextelem()) {
2203e12c5d1SDavid du Colombier if(oelem[0])
2213e12c5d1SDavid du Colombier if(con_walk(FID2, oelem)){
2223e12c5d1SDavid du Colombier cprint("file does not exits");
2233e12c5d1SDavid du Colombier return;
2243e12c5d1SDavid du Colombier }
225bd389b36SDavid du Colombier memmove(oelem, elem, NAMELEN);
2263e12c5d1SDavid du Colombier }
2279a747e4fSDavid du Colombier if(skipbl(1))
2289a747e4fSDavid du Colombier return;
2299a747e4fSDavid du Colombier if(cons.arg[0]=='/'){
2309a747e4fSDavid du Colombier if(con_clone(FID1, FID3))
2319a747e4fSDavid du Colombier return;
2329a747e4fSDavid du Colombier noelem[0] = 0;
2339a747e4fSDavid du Colombier while(nextelem()){
2349a747e4fSDavid du Colombier if(noelem[0])
2359a747e4fSDavid du Colombier if(con_walk(FID3, noelem)){
2369a747e4fSDavid du Colombier cprint("target path %s does not exist", noelem);
2379a747e4fSDavid du Colombier return;
2389a747e4fSDavid du Colombier }
2399a747e4fSDavid du Colombier memmove(noelem, elem, NAMELEN);
2409a747e4fSDavid du Colombier }
2419a747e4fSDavid du Colombier if(!con_walk(FID3, elem)){
2429a747e4fSDavid du Colombier cprint("target %s already exists\n", elem);
2439a747e4fSDavid du Colombier return;
2449a747e4fSDavid du Colombier }
2459a747e4fSDavid du Colombier if(con_walk(FID2, oelem)){
2469a747e4fSDavid du Colombier cprint("src %s does not exist\n", oelem);
2479a747e4fSDavid du Colombier return;
2489a747e4fSDavid du Colombier }
2499a747e4fSDavid du Colombier /*
2509a747e4fSDavid du Colombier * we know the target does not exist,
2519a747e4fSDavid du Colombier * the source does exist.
2529a747e4fSDavid du Colombier * to do the rename, create the target and then
2539a747e4fSDavid du Colombier * copy the directory entry directly. then remove the source.
2549a747e4fSDavid du Colombier */
2559a747e4fSDavid du Colombier if(err = con_stat(FID2, stat)){
2569a747e4fSDavid du Colombier cprint("can't stat file: %s\n", errstring[err]);
2579a747e4fSDavid du Colombier return;
2589a747e4fSDavid du Colombier }
2599a747e4fSDavid du Colombier convM2D9p1(stat, &d);
2609a747e4fSDavid du Colombier perm = (d.mode&0777)|((d.mode&0x7000)<<17);
2619a747e4fSDavid du Colombier if(err = con_create(FID3, elem, d.uid, d.gid, perm, (d.mode&DDIR)?OREAD:ORDWR)){
2629a747e4fSDavid du Colombier cprint("can't create %s: %s\n", elem, errstring[err]);
2639a747e4fSDavid du Colombier return;
2649a747e4fSDavid du Colombier }
2659a747e4fSDavid du Colombier if(err = con_swap(FID2, FID3)){
2669a747e4fSDavid du Colombier cprint("can't swap data: %s\n", errstring[err]);
2679a747e4fSDavid du Colombier return;
2689a747e4fSDavid du Colombier }
2699a747e4fSDavid du Colombier if(err = con_remove(FID2)){
2709a747e4fSDavid du Colombier cprint("can't remove file: %s\n", errstring[err]);
2719a747e4fSDavid du Colombier return;
2729a747e4fSDavid du Colombier }
2739a747e4fSDavid du Colombier }else{
2747dd7cddfSDavid du Colombier cname(nxelem);
2759a747e4fSDavid du Colombier if(strchr(nxelem, '/')){
2769a747e4fSDavid du Colombier cprint("bad rename target: not full path, but contains slashes\n");
2779a747e4fSDavid du Colombier return;
2789a747e4fSDavid du Colombier }
2797dd7cddfSDavid du Colombier if(!con_walk(FID2, nxelem))
2807dd7cddfSDavid du Colombier cprint("file %s already exists\n", nxelem);
2813e12c5d1SDavid du Colombier else if(con_walk(FID2, oelem))
2823e12c5d1SDavid du Colombier cprint("file does not already exist\n");
2833e12c5d1SDavid du Colombier else if(err = con_stat(FID2, stat))
2847dd7cddfSDavid du Colombier cprint("can't stat file: %s\n", errstring[err]);
2853e12c5d1SDavid du Colombier else{
2869a747e4fSDavid du Colombier convM2D9p1(stat, &d);
2877dd7cddfSDavid du Colombier strncpy(d.name, nxelem, NAMELEN);
2889a747e4fSDavid du Colombier convD2M9p1(&d, stat);
2893e12c5d1SDavid du Colombier if(err = con_wstat(FID2, stat))
2907dd7cddfSDavid du Colombier cprint("can't move file: %s\n", errstring[err]);
2913e12c5d1SDavid du Colombier }
2923e12c5d1SDavid du Colombier }
2939a747e4fSDavid du Colombier }
2943e12c5d1SDavid du Colombier
2953e12c5d1SDavid du Colombier void
cmd_remove(void)2963e12c5d1SDavid du Colombier cmd_remove(void)
2973e12c5d1SDavid du Colombier {
2983e12c5d1SDavid du Colombier if(con_clone(FID1, FID2))
2993e12c5d1SDavid du Colombier return;
3003e12c5d1SDavid du Colombier if(skipbl(1))
3013e12c5d1SDavid du Colombier return;
3023e12c5d1SDavid du Colombier while(nextelem())
303bd389b36SDavid du Colombier if(con_walk(FID2, elem)){
304bd389b36SDavid du Colombier cprint("can't walk %s\n", elem);
3053e12c5d1SDavid du Colombier return;
306bd389b36SDavid du Colombier }
3073e12c5d1SDavid du Colombier con_remove(FID2);
3083e12c5d1SDavid du Colombier }
3093e12c5d1SDavid du Colombier
3103e12c5d1SDavid du Colombier void
cmd_cfs(void)3113e12c5d1SDavid du Colombier cmd_cfs(void)
3123e12c5d1SDavid du Colombier {
3133e12c5d1SDavid du Colombier Filsys *fs;
3143e12c5d1SDavid du Colombier
3153e12c5d1SDavid du Colombier if(*cons.arg != ' ') {
3167dd7cddfSDavid du Colombier fs = &filesys[0]; /* default */
3173e12c5d1SDavid du Colombier } else {
3189a747e4fSDavid du Colombier if(skipbl(1)){
3199a747e4fSDavid du Colombier cprint("skipbl\n");
3203e12c5d1SDavid du Colombier return;
3219a747e4fSDavid du Colombier }
3223e12c5d1SDavid du Colombier if(!nextelem())
3237dd7cddfSDavid du Colombier fs = &filesys[0]; /* default */
3243e12c5d1SDavid du Colombier else
3253e12c5d1SDavid du Colombier fs = fsstr(elem);
3263e12c5d1SDavid du Colombier }
3273e12c5d1SDavid du Colombier if(fs == 0) {
3283e12c5d1SDavid du Colombier cprint("unknown file system %s\n", elem);
3293e12c5d1SDavid du Colombier return;
3303e12c5d1SDavid du Colombier }
3313e12c5d1SDavid du Colombier if(con_attach(FID1, "adm", fs->name))
3323e12c5d1SDavid du Colombier panic("FID1 attach to root");
3333e12c5d1SDavid du Colombier cur_fs = fs;
3343e12c5d1SDavid du Colombier }
3353e12c5d1SDavid du Colombier
3369a747e4fSDavid du Colombier /*
3379a747e4fSDavid du Colombier * find out the length of a file
3389a747e4fSDavid du Colombier * given the mesg version of a stat buffer
3399a747e4fSDavid du Colombier * we call this because convM2D is different
3409a747e4fSDavid du Colombier * for the file system than in the os
3419a747e4fSDavid du Colombier */
3429a747e4fSDavid du Colombier static uvlong
statlen(char * ap)3439a747e4fSDavid du Colombier statlen(char *ap)
3449a747e4fSDavid du Colombier {
3459a747e4fSDavid du Colombier uchar *p;
3469a747e4fSDavid du Colombier ulong ll, hl;
3479a747e4fSDavid du Colombier
3489a747e4fSDavid du Colombier p = (uchar*)ap;
3499a747e4fSDavid du Colombier p += 3*28+5*4;
3509a747e4fSDavid du Colombier ll = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
3519a747e4fSDavid du Colombier hl = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24);
3529a747e4fSDavid du Colombier return ll | ((uvlong) hl << 32);
3539a747e4fSDavid du Colombier }
3549a747e4fSDavid du Colombier
3553e12c5d1SDavid du Colombier int
adduser(char * user,int isgroup)3565d459b5aSDavid du Colombier adduser(char *user, int isgroup)
3573e12c5d1SDavid du Colombier {
3583e12c5d1SDavid du Colombier char stat[DIRREC];
3593e12c5d1SDavid du Colombier char msg[100];
3603e12c5d1SDavid du Colombier Uid *u;
3613e12c5d1SDavid du Colombier int i, c, nu;
3623e12c5d1SDavid du Colombier
3633e12c5d1SDavid du Colombier /*
3643e12c5d1SDavid du Colombier * check uniq of name
3653e12c5d1SDavid du Colombier * and get next uid
3663e12c5d1SDavid du Colombier */
3673e12c5d1SDavid du Colombier cmd_exec("cfs");
3683e12c5d1SDavid du Colombier cmd_exec("user");
3695d459b5aSDavid du Colombier if(isgroup)
3705d459b5aSDavid du Colombier nu = 9000;
3715d459b5aSDavid du Colombier else
3723e12c5d1SDavid du Colombier nu = 0;
3733e12c5d1SDavid du Colombier for(i=0, u=uid; i<conf.nuid; i++,u++) {
3743e12c5d1SDavid du Colombier c = u->uid;
3753e12c5d1SDavid du Colombier if(c == 0)
3763e12c5d1SDavid du Colombier break;
3773e12c5d1SDavid du Colombier if(strcmp(uidspace+u->offset, user) == 0)
3783e12c5d1SDavid du Colombier return 1;
3795d459b5aSDavid du Colombier if(c >= 9000 && !isgroup)
3803e12c5d1SDavid du Colombier continue;
3813e12c5d1SDavid du Colombier if(c > nu)
3823e12c5d1SDavid du Colombier nu = c;
3833e12c5d1SDavid du Colombier }
3843e12c5d1SDavid du Colombier nu++;
3855d459b5aSDavid du Colombier if(isgroup){
3865d459b5aSDavid du Colombier if(nu >= 0x10000) {
3875d459b5aSDavid du Colombier cprint("out of group ids\n");
3885d459b5aSDavid du Colombier return 0;
3895d459b5aSDavid du Colombier }
3905d459b5aSDavid du Colombier } else {
3917dd7cddfSDavid du Colombier if(nu >= 9000) {
3927dd7cddfSDavid du Colombier cprint("out of user ids\n");
3937dd7cddfSDavid du Colombier return 0;
3947dd7cddfSDavid du Colombier }
3955d459b5aSDavid du Colombier }
3963e12c5d1SDavid du Colombier
3973e12c5d1SDavid du Colombier /*
3983e12c5d1SDavid du Colombier * write onto adm/users
3993e12c5d1SDavid du Colombier */
4003e12c5d1SDavid du Colombier if(con_clone(FID1, FID2)
4013e12c5d1SDavid du Colombier || con_path(FID2, "/adm/users")
4023e12c5d1SDavid du Colombier || con_open(FID2, 1)) {
4033e12c5d1SDavid du Colombier cprint("can't open /adm/users\n");
4043e12c5d1SDavid du Colombier return 0;
4053e12c5d1SDavid du Colombier }
4063e12c5d1SDavid du Colombier
4073e12c5d1SDavid du Colombier sprint(msg, "%d:%s:%s:\n", nu, user, user);
4085d459b5aSDavid du Colombier cprint("add user %s", msg);
4093e12c5d1SDavid du Colombier c = strlen(msg);
4103e12c5d1SDavid du Colombier i = con_stat(FID2, stat);
4113e12c5d1SDavid du Colombier if(i){
4127dd7cddfSDavid du Colombier cprint("can't stat /adm/users: %s\n", errstring[i]);
4133e12c5d1SDavid du Colombier return 0;
4143e12c5d1SDavid du Colombier }
4153e12c5d1SDavid du Colombier i = con_write(FID2, msg, statlen(stat), c);
4163e12c5d1SDavid du Colombier if(i != c){
4173e12c5d1SDavid du Colombier cprint("short write on /adm/users: %d %d\n", c, i);
4183e12c5d1SDavid du Colombier return 0;
4193e12c5d1SDavid du Colombier }
4203e12c5d1SDavid du Colombier return 1;
4213e12c5d1SDavid du Colombier }
4223e12c5d1SDavid du Colombier
4233e12c5d1SDavid du Colombier void
cmd_newuser(void)4243e12c5d1SDavid du Colombier cmd_newuser(void)
4253e12c5d1SDavid du Colombier {
4265d459b5aSDavid du Colombier char user[NAMELEN], param[NAMELEN], msg[100];
4273e12c5d1SDavid du Colombier int i, c;
4283e12c5d1SDavid du Colombier
4293e12c5d1SDavid du Colombier /*
4303e12c5d1SDavid du Colombier * get uid
4313e12c5d1SDavid du Colombier */
4323e12c5d1SDavid du Colombier cname(user);
4335d459b5aSDavid du Colombier cname(param);
4343e12c5d1SDavid du Colombier for(i=0; i<NAMELEN; i++) {
4353e12c5d1SDavid du Colombier c = user[i];
4363e12c5d1SDavid du Colombier if(c == 0)
4373e12c5d1SDavid du Colombier break;
4383e12c5d1SDavid du Colombier if(c >= '0' && c <= '9'
4393e12c5d1SDavid du Colombier || c >= 'a' && c <= 'z'
4403e12c5d1SDavid du Colombier || c >= 'A' && c <= 'Z')
4413e12c5d1SDavid du Colombier continue;
4423e12c5d1SDavid du Colombier cprint("bad character in name: 0x%x\n", c);
4433e12c5d1SDavid du Colombier return;
4443e12c5d1SDavid du Colombier }
4453e12c5d1SDavid du Colombier if(i < 2) {
4463e12c5d1SDavid du Colombier cprint("name too short: %s\n", user);
4473e12c5d1SDavid du Colombier return;
4483e12c5d1SDavid du Colombier }
4493e12c5d1SDavid du Colombier if(i >= NAMELEN) {
4503e12c5d1SDavid du Colombier cprint("name too long: %s\n", user);
4513e12c5d1SDavid du Colombier return;
4523e12c5d1SDavid du Colombier }
4533e12c5d1SDavid du Colombier
4545d459b5aSDavid du Colombier switch(param[0]){
4555d459b5aSDavid du Colombier case 0:
4565d459b5aSDavid du Colombier if(!adduser(user, 0))
4573e12c5d1SDavid du Colombier return;
4585d459b5aSDavid du Colombier cmd_exec("user");
4595d459b5aSDavid du Colombier break;
4605d459b5aSDavid du Colombier case ':':
4615d459b5aSDavid du Colombier adduser(user, 1);
4625d459b5aSDavid du Colombier cmd_exec("user");
4635d459b5aSDavid du Colombier return;
4645d459b5aSDavid du Colombier case '#':
4655d459b5aSDavid du Colombier adduser(user, 0);
4665d459b5aSDavid du Colombier cmd_exec("user");
4675d459b5aSDavid du Colombier return;
4685d459b5aSDavid du Colombier }
4693e12c5d1SDavid du Colombier
4705d459b5aSDavid du Colombier /*
4715d459b5aSDavid du Colombier * create directories
4725d459b5aSDavid du Colombier */
4733e12c5d1SDavid du Colombier cmd_exec("user");
4743e12c5d1SDavid du Colombier sprint(msg, "create /usr/%s %s %s 775 d", user, user, user);
4753e12c5d1SDavid du Colombier cmd_exec(msg);
4763e12c5d1SDavid du Colombier sprint(msg, "create /usr/%s/tmp %s %s 775 d", user, user, user);
4773e12c5d1SDavid du Colombier cmd_exec(msg);
4783e12c5d1SDavid du Colombier sprint(msg, "create /usr/%s/lib %s %s 775 d", user, user, user);
4793e12c5d1SDavid du Colombier cmd_exec(msg);
4803e12c5d1SDavid du Colombier sprint(msg, "create /usr/%s/bin %s %s 775 d", user, user, user);
4813e12c5d1SDavid du Colombier cmd_exec(msg);
4823e12c5d1SDavid du Colombier sprint(msg, "create /usr/%s/bin/rc %s %s 775 d", user, user, user);
4833e12c5d1SDavid du Colombier cmd_exec(msg);
4843e12c5d1SDavid du Colombier sprint(msg, "create /usr/%s/bin/mips %s %s 775 d", user, user, user);
4853e12c5d1SDavid du Colombier cmd_exec(msg);
4863e12c5d1SDavid du Colombier sprint(msg, "create /usr/%s/bin/386 %s %s 775 d", user, user, user);
4873e12c5d1SDavid du Colombier cmd_exec(msg);
4887dd7cddfSDavid du Colombier sprint(msg, "create /usr/%s/bin/power %s %s 775 d", user, user, user);
4893e12c5d1SDavid du Colombier cmd_exec(msg);
4907dd7cddfSDavid du Colombier sprint(msg, "create /usr/%s/bin/alpha %s %s 775 d", user, user, user);
4913e12c5d1SDavid du Colombier cmd_exec(msg);
4923e12c5d1SDavid du Colombier }
4933e12c5d1SDavid du Colombier
4943e12c5d1SDavid du Colombier void
cmd_checkuser(void)4953e12c5d1SDavid du Colombier cmd_checkuser(void)
4963e12c5d1SDavid du Colombier {
4973e12c5d1SDavid du Colombier uchar buf[DIRREC], *p;
4983e12c5d1SDavid du Colombier static char utime[4];
4993e12c5d1SDavid du Colombier
5003e12c5d1SDavid du Colombier if(con_clone(FID1, FID2)
5013e12c5d1SDavid du Colombier || con_path(FID2, "/adm/users")
5023e12c5d1SDavid du Colombier || con_open(FID2, 0)
5033e12c5d1SDavid du Colombier || con_stat(FID2, (char*)buf))
5043e12c5d1SDavid du Colombier return;
5053e12c5d1SDavid du Colombier p = buf + 3*NAMELEN + 4*4;
5063e12c5d1SDavid du Colombier if(memcmp(utime, p, 4) == 0)
5073e12c5d1SDavid du Colombier return;
508bd389b36SDavid du Colombier memmove(utime, p, 4);
5093e12c5d1SDavid du Colombier cmd_user();
5103e12c5d1SDavid du Colombier }
5113e12c5d1SDavid du Colombier
5123e12c5d1SDavid du Colombier void
cmd_allow(void)5133e12c5d1SDavid du Colombier cmd_allow(void)
5143e12c5d1SDavid du Colombier {
515bd389b36SDavid du Colombier wstatallow = 1;
5163e12c5d1SDavid du Colombier }
5173e12c5d1SDavid du Colombier
5183e12c5d1SDavid du Colombier void
cmd_disallow(void)5193e12c5d1SDavid du Colombier cmd_disallow(void)
5203e12c5d1SDavid du Colombier {
521bd389b36SDavid du Colombier wstatallow = 0;
5223e12c5d1SDavid du Colombier }
5233e12c5d1SDavid du Colombier
5247dd7cddfSDavid du Colombier void
cmd_chat(void)5257dd7cddfSDavid du Colombier cmd_chat(void)
5267dd7cddfSDavid du Colombier {
5277dd7cddfSDavid du Colombier chat = 1 - chat;
5287dd7cddfSDavid du Colombier }
5297dd7cddfSDavid du Colombier
53059cc4ca5SDavid du Colombier void
cmd_atime(void)5319a747e4fSDavid du Colombier cmd_atime(void)
53280ee5cbfSDavid du Colombier {
5339a747e4fSDavid du Colombier noatime = !noatime;
5349a747e4fSDavid du Colombier if(noatime)
5359a747e4fSDavid du Colombier cprint("atimes will not be updated\n");
53680ee5cbfSDavid du Colombier else
5379a747e4fSDavid du Colombier cprint("atimes will be updated\n");
53880ee5cbfSDavid du Colombier }
53980ee5cbfSDavid du Colombier
54080ee5cbfSDavid du Colombier void
cmd_noneattach(void)54159cc4ca5SDavid du Colombier cmd_noneattach(void)
54259cc4ca5SDavid du Colombier {
54359cc4ca5SDavid du Colombier allownone = !allownone;
54459cc4ca5SDavid du Colombier if(allownone)
54559cc4ca5SDavid du Colombier cprint("none can attach to new connections\n");
54659cc4ca5SDavid du Colombier else
54759cc4ca5SDavid du Colombier cprint("none can only attach on authenticated connections\n");
54859cc4ca5SDavid du Colombier }
54959cc4ca5SDavid du Colombier
55059cc4ca5SDavid du Colombier void
cmd_listen(void)55159cc4ca5SDavid du Colombier cmd_listen(void)
55259cc4ca5SDavid du Colombier {
55359cc4ca5SDavid du Colombier char addr[NAMELEN];
55459cc4ca5SDavid du Colombier
55559cc4ca5SDavid du Colombier if(skipbl(0))
556*8c41de82SDavid du Colombier strcpy(addr, "tcp!*!564"); /* 9fs */
55759cc4ca5SDavid du Colombier else
55859cc4ca5SDavid du Colombier cname(addr);
55959cc4ca5SDavid du Colombier
56059cc4ca5SDavid du Colombier if(netserve(addr))
56159cc4ca5SDavid du Colombier cprint("announce %s failed\n", addr);
56259cc4ca5SDavid du Colombier else
56359cc4ca5SDavid du Colombier cprint("announce %s\n", addr);
56459cc4ca5SDavid du Colombier }
56559cc4ca5SDavid du Colombier
5665d459b5aSDavid du Colombier void
cmd_nowritegroup(void)5675d459b5aSDavid du Colombier cmd_nowritegroup(void)
5685d459b5aSDavid du Colombier {
5695d459b5aSDavid du Colombier writegroup = 0;
5705d459b5aSDavid du Colombier }
5715d459b5aSDavid du Colombier
5723e12c5d1SDavid du Colombier Command command[] =
5733e12c5d1SDavid du Colombier {
5743e12c5d1SDavid du Colombier "allow", cmd_allow, "",
5753e12c5d1SDavid du Colombier "allowoff", cmd_disallow, "",
5769a747e4fSDavid du Colombier "atime", cmd_atime, "",
5777dd7cddfSDavid du Colombier "cfs", cmd_cfs, "[filesys]",
5787dd7cddfSDavid du Colombier "chat", cmd_chat, "",
5795d459b5aSDavid du Colombier "check", cmd_check, "[cdfpPqrtw]",
580bd389b36SDavid du Colombier "clri", cmd_clri, "filename",
5813e12c5d1SDavid du Colombier "create", cmd_create, "filename user group perm [ald]",
5823e12c5d1SDavid du Colombier "disallow", cmd_disallow, "",
5833e12c5d1SDavid du Colombier "halt", cmd_halt, "",
5843e12c5d1SDavid du Colombier "help", cmd_help, "",
58559cc4ca5SDavid du Colombier "listen", cmd_listen, "[address]",
5863e12c5d1SDavid du Colombier "newuser", cmd_newuser, "username",
58759cc4ca5SDavid du Colombier "noneattach", cmd_noneattach, "",
5885d459b5aSDavid du Colombier "nowritegroup", cmd_nowritegroup, "",
5893e12c5d1SDavid du Colombier "remove", cmd_remove, "filename",
5903e12c5d1SDavid du Colombier "rename", cmd_rename, "file newname",
59180ee5cbfSDavid du Colombier "start", cmd_start, "",
5923e12c5d1SDavid du Colombier "stats", cmd_stats, "[fw]",
5933e12c5d1SDavid du Colombier "sync", cmd_sync, "",
5943e12c5d1SDavid du Colombier "user", cmd_user, "",
5953e12c5d1SDavid du Colombier 0
5963e12c5d1SDavid du Colombier };
5973e12c5d1SDavid du Colombier
5983e12c5d1SDavid du Colombier int
skipbl(int err)5993e12c5d1SDavid du Colombier skipbl(int err)
6003e12c5d1SDavid du Colombier {
6013e12c5d1SDavid du Colombier if(*cons.arg != ' ') {
6023e12c5d1SDavid du Colombier if(err)
6033e12c5d1SDavid du Colombier cprint("syntax error\n");
6043e12c5d1SDavid du Colombier return 1;
6053e12c5d1SDavid du Colombier }
6063e12c5d1SDavid du Colombier while(*cons.arg == ' ')
6073e12c5d1SDavid du Colombier cons.arg++;
6083e12c5d1SDavid du Colombier return 0;
6093e12c5d1SDavid du Colombier }
6103e12c5d1SDavid du Colombier
6113e12c5d1SDavid du Colombier char*
_cname(char * name)6129a747e4fSDavid du Colombier _cname(char *name)
6133e12c5d1SDavid du Colombier {
6143e12c5d1SDavid du Colombier int i, c;
6153e12c5d1SDavid du Colombier
6163e12c5d1SDavid du Colombier memset(name, 0, NAMELEN);
6173e12c5d1SDavid du Colombier for(i=0;; i++) {
6183e12c5d1SDavid du Colombier c = *cons.arg;
6193e12c5d1SDavid du Colombier switch(c) {
6203e12c5d1SDavid du Colombier case ' ':
6213e12c5d1SDavid du Colombier case '\t':
6223e12c5d1SDavid du Colombier case '\n':
6233e12c5d1SDavid du Colombier case '\0':
6243e12c5d1SDavid du Colombier return name;
6253e12c5d1SDavid du Colombier }
6263e12c5d1SDavid du Colombier if(i < NAMELEN-1)
6273e12c5d1SDavid du Colombier name[i] = c;
6283e12c5d1SDavid du Colombier cons.arg++;
6293e12c5d1SDavid du Colombier }
6303e12c5d1SDavid du Colombier }
6313e12c5d1SDavid du Colombier
6329a747e4fSDavid du Colombier char*
cname(char * name)6339a747e4fSDavid du Colombier cname(char *name)
6349a747e4fSDavid du Colombier {
6359a747e4fSDavid du Colombier skipbl(0);
6369a747e4fSDavid du Colombier return _cname(name);
6379a747e4fSDavid du Colombier }
6389a747e4fSDavid du Colombier
6393e12c5d1SDavid du Colombier int
nextelem(void)6403e12c5d1SDavid du Colombier nextelem(void)
6413e12c5d1SDavid du Colombier {
6423e12c5d1SDavid du Colombier char *e;
6433e12c5d1SDavid du Colombier int i, c;
6443e12c5d1SDavid du Colombier
6453e12c5d1SDavid du Colombier e = elem;
6463e12c5d1SDavid du Colombier while(*cons.arg == '/')
6473e12c5d1SDavid du Colombier cons.arg++;
6483e12c5d1SDavid du Colombier c = *cons.arg;
6493e12c5d1SDavid du Colombier if(c == 0 || c == ' ')
6503e12c5d1SDavid du Colombier return 0;
6513e12c5d1SDavid du Colombier for(i = 0; c = *cons.arg; i++) {
6523e12c5d1SDavid du Colombier if(c == ' ' || c == '/')
6533e12c5d1SDavid du Colombier break;
6543e12c5d1SDavid du Colombier if(i == NAMELEN) {
6553e12c5d1SDavid du Colombier cprint("path name component too long\n");
6563e12c5d1SDavid du Colombier return 0;
6573e12c5d1SDavid du Colombier }
6583e12c5d1SDavid du Colombier *e++ = c;
6593e12c5d1SDavid du Colombier cons.arg++;
6603e12c5d1SDavid du Colombier }
6613e12c5d1SDavid du Colombier *e = 0;
6623e12c5d1SDavid du Colombier return 1;
6633e12c5d1SDavid du Colombier }
6643e12c5d1SDavid du Colombier
6653e12c5d1SDavid du Colombier long
number(int d,int base)6663e12c5d1SDavid du Colombier number(int d, int base)
6673e12c5d1SDavid du Colombier {
6683e12c5d1SDavid du Colombier int c, sign, any;
6693e12c5d1SDavid du Colombier long n;
6703e12c5d1SDavid du Colombier
6713e12c5d1SDavid du Colombier sign = 0;
6723e12c5d1SDavid du Colombier any = 0;
6733e12c5d1SDavid du Colombier n = 0;
6743e12c5d1SDavid du Colombier
6753e12c5d1SDavid du Colombier c = *cons.arg;
6763e12c5d1SDavid du Colombier while(c == ' ') {
6773e12c5d1SDavid du Colombier cons.arg++;
6783e12c5d1SDavid du Colombier c = *cons.arg;
6793e12c5d1SDavid du Colombier }
6803e12c5d1SDavid du Colombier if(c == '-') {
6813e12c5d1SDavid du Colombier sign = 1;
6823e12c5d1SDavid du Colombier cons.arg++;
6833e12c5d1SDavid du Colombier c = *cons.arg;
6843e12c5d1SDavid du Colombier }
6853e12c5d1SDavid du Colombier while((c >= '0' && c <= '9') ||
6863e12c5d1SDavid du Colombier (base == 16 && c >= 'a' && c <= 'f') ||
6873e12c5d1SDavid du Colombier (base == 16 && c >= 'A' && c <= 'F')) {
6883e12c5d1SDavid du Colombier n *= base;
6893e12c5d1SDavid du Colombier if(c >= 'a' && c <= 'f')
6903e12c5d1SDavid du Colombier n += c - 'a' + 10;
6913e12c5d1SDavid du Colombier else
6923e12c5d1SDavid du Colombier if(c >= 'A' && c <= 'F')
6933e12c5d1SDavid du Colombier n += c - 'A' + 10;
6943e12c5d1SDavid du Colombier else
6953e12c5d1SDavid du Colombier n += c - '0';
6963e12c5d1SDavid du Colombier cons.arg++;
6973e12c5d1SDavid du Colombier c = *cons.arg;
6983e12c5d1SDavid du Colombier any = 1;
6993e12c5d1SDavid du Colombier }
7003e12c5d1SDavid du Colombier if(!any)
7013e12c5d1SDavid du Colombier return d;
7023e12c5d1SDavid du Colombier if(sign)
7033e12c5d1SDavid du Colombier n = -n;
7043e12c5d1SDavid du Colombier return n;
7053e12c5d1SDavid du Colombier }
706