/* * 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"#include "9p1.h" static char elem[NAMELEN];static Filsys* cur_fs;static char conline[100]; voidconsserve(void){ con_session(); cmd_exec("cfs"); cmd_exec("user");} intcmd_exec(char *arg){ char *s, *c; int i; for(i=0; s = command[i].string; i++) { for(c=arg; *s; c++) if(*c != *s++) goto brk; if(*c == '\0' || *c == ' ' || *c == '\t'){ cons.arg = c; (*command[i].func)(); return 1; } brk:; } return 0;} voidcmd_check(void){ char *s; int flags; flags = 0; for(s = cons.arg; *s; s++){ while(*s == ' ' || *s == '\t') s++; if(*s == '\0') break; switch(*s){ /* rebuild the free list */ case 'f': flags |= Cfree; break; /* fix bad tags */ case 't': flags |= Ctag; break; /* fix bad tags and clear the contents of the block */ case 'c': flags |= Cream; break; /* delete all redundant references to a block */ case 'd': flags |= Cbad; break; /* read and check tags on all blocks */ case 'r': flags |= Crdall; break; /* write all of the blocks you touch */ case 'w': flags |= Ctouch; break; /* print all directories as they are read */ case 'p': flags |= Cpdir; break; /* print all files as they are read */ case 'P': flags |= Cpfile; break; /* quiet, just report really nasty stuff */ case 'q': flags |= Cquiet; break; } } check(cur_fs, flags);} enum{ Sset = (1<<0), Setc = (1<<1),};voidcmd_stats(void){ cprint("work stats\n"); cprint(" work = %A rps\n", (Filta){&cons.work, 1}); cprint(" rate = %A tBps\n", (Filta){&cons.rate, 1000}); cprint(" hits = %A iops\n", (Filta){&cons.bhit, 1}); cprint(" read = %A iops\n", (Filta){&cons.bread, 1}); cprint(" init = %A iops\n", (Filta){&cons.binit, 1});/* for(i = 0; i < MAXTAG; i++) cprint(" tag %G = %A iops\n", i, (Filta){&cons.tags[i], 1});*/} voidcmd_sync(void){ rlock(&mainlock); syncall(); runlock(&mainlock);} voidcmd_halt(void){ wlock(&mainlock); syncall(); superok(cur_fs->dev, superaddr(cur_fs->dev), 1); print("kfs: file system halted\n");} voidcmd_start(void){ superok(cur_fs->dev, superaddr(cur_fs->dev), 0); wunlock(&mainlock); print("kfs: file system started\n");} voidcmd_help(void){ int i; for(i=0; command[i].string; i++) cprint(" %s %s\n", command[i].string, command[i].args); cprint("check options:\n" " r read all blocks\n" " f rebuild the free list\n" " t fix all bad tags\n" " c fix bad tags and zero the blocks\n" " d delete all redundant references to blocks\n" " p print directories as they are checked\n" " P print all files as they are checked\n" " w write all blocks that are read\n");} voidcmd_create(void){ int uid, gid, err; long perm; char oelem[NAMELEN]; char name[NAMELEN]; if(err = con_clone(FID1, FID2)){ cprint("clone failed: %s\n", errstring[err]); return; } if(skipbl(1)){ cprint("skipbl\n"); return; } oelem[0] = 0; while(nextelem()) { if(oelem[0]) if(err = con_walk(FID2, oelem)){ cprint("walk failed: %s\n", errstring[err]); return; } memmove(oelem, elem, NAMELEN); } if(skipbl(1)) return; uid = strtouid(cname(name)); if(uid == 0){ cprint("unknown user %s\n", name); return; } gid = strtouid(cname(name)); if(gid == 0){ cprint("unknown group %s\n", name); return; } perm = number(0777, 8); skipbl(0); for(; *cons.arg; cons.arg++){ if(*cons.arg == 'l') perm |= PLOCK; else if(*cons.arg == 'a') perm |= PAPND; else if(*cons.arg == 'd') perm |= PDIR; else break; } err = con_create(FID2, elem, uid, gid, perm, 0); if(err) cprint("can't create %s: %s\n", elem, errstring[err]);} voidcmd_clri(void){ if(con_clone(FID1, FID2)) return; if(skipbl(1)) return; while(nextelem()) if(con_walk(FID2, elem)){ cprint("can't walk %s\n", elem); return; } con_clri(FID2);} voidcmd_rename(void){ ulong perm; Dentry d; char stat[DIRREC]; char oelem[NAMELEN], noelem[NAMELEN], nxelem[NAMELEN]; int err; if(con_clone(FID1, FID2)) return; if(skipbl(1)) return; oelem[0] = 0; while(nextelem()) { if(oelem[0]) if(con_walk(FID2, oelem)){ cprint("file does not exits"); return; } memmove(oelem, elem, NAMELEN); } if(skipbl(1)) return; if(cons.arg[0]=='/'){ if(con_clone(FID1, FID3)) return; noelem[0] = 0; while(nextelem()){ if(noelem[0]) if(con_walk(FID3, noelem)){ cprint("target path %s does not exist", noelem); return; } memmove(noelem, elem, NAMELEN); } if(!con_walk(FID3, elem)){ cprint("target %s already exists\n", elem); return; } if(con_walk(FID2, oelem)){ cprint("src %s does not exist\n", oelem); return; } /* * we know the target does not exist, * the source does exist. * to do the rename, create the target and then * copy the directory entry directly. then remove the source. */ if(err = con_stat(FID2, stat)){ cprint("can't stat file: %s\n", errstring[err]); return; } convM2D9p1(stat, &d); perm = (d.mode&0777)|((d.mode&0x7000)<<17); if(err = con_create(FID3, elem, d.uid, d.gid, perm, (d.mode&DDIR)?OREAD:ORDWR)){ cprint("can't create %s: %s\n", elem, errstring[err]); return; } if(err = con_swap(FID2, FID3)){ cprint("can't swap data: %s\n", errstring[err]); return; } if(err = con_remove(FID2)){ cprint("can't remove file: %s\n", errstring[err]); return; } }else{ cname(nxelem); if(strchr(nxelem, '/')){ cprint("bad rename target: not full path, but contains slashes\n"); return; } if(!con_walk(FID2, nxelem)) cprint("file %s already exists\n", nxelem); else if(con_walk(FID2, oelem)) cprint("file does not already exist\n"); else if(err = con_stat(FID2, stat)) cprint("can't stat file: %s\n", errstring[err]); else{ convM2D9p1(stat, &d); strncpy(d.name, nxelem, NAMELEN); convD2M9p1(&d, stat); if(err = con_wstat(FID2, stat)) cprint("can't move file: %s\n", errstring[err]); } } } voidcmd_remove(void){ if(con_clone(FID1, FID2)) return; if(skipbl(1)) return; while(nextelem()) if(con_walk(FID2, elem)){ cprint("can't walk %s\n", elem); return; } con_remove(FID2);} voidcmd_cfs(void){ Filsys *fs; if(*cons.arg != ' ') { fs = &filesys[0]; /* default */ } else { if(skipbl(1)){ cprint("skipbl\n"); return; } if(!nextelem()) fs = &filesys[0]; /* default */ else fs = fsstr(elem); } if(fs == 0) { cprint("unknown file system %s\n", elem); return; } if(con_attach(FID1, "adm", fs->name)) panic("FID1 attach to root"); cur_fs = fs;} /* * find out the length of a file * given the mesg version of a stat buffer * we call this because convM2D is different * for the file system than in the os */static uvlongstatlen(char *ap){ uchar *p; ulong ll, hl; p = (uchar*)ap; p += 3*28+5*4; ll = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); hl = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24); return ll | ((uvlong) hl << 32);} intadduser(char *user, int isgroup){ char stat[DIRREC]; char msg[100]; Uid *u; int i, c, nu; /* * check uniq of name * and get next uid */ cmd_exec("cfs"); cmd_exec("user"); if(isgroup) nu = 9000; else nu = 0; for(i=0, u=uid; i<conf.nuid; i++,u++) { c = u->uid; if(c == 0) break; if(strcmp(uidspace+u->offset, user) == 0) return 1; if(c >= 9000 && !isgroup) continue; if(c > nu) nu = c; } nu++; if(isgroup){ if(nu >= 0x10000) { cprint("out of group ids\n"); return 0; } } else { if(nu >= 9000) { cprint("out of user ids\n"); return 0; } } /* * write onto adm/users */ if(con_clone(FID1, FID2) || con_path(FID2, "/adm/users") || con_open(FID2, 1)) { cprint("can't open /adm/users\n"); return 0; } sprint(msg, "%d:%s:%s:\n", nu, user, user); cprint("add user %s", msg); c = strlen(msg); i = con_stat(FID2, stat); if(i){ cprint("can't stat /adm/users: %s\n", errstring[i]); return 0; } i = con_write(FID2, msg, statlen(stat), c); if(i != c){ cprint("short write on /adm/users: %d %d\n", c, i); return 0; } return 1;} voidcmd_newuser(void){ char user[NAMELEN], param[NAMELEN], msg[100]; int i, c; /* * get uid */ cname(user); cname(param); for(i=0; i<NAMELEN; i++) { c = user[i]; if(c == 0) break; if(c >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') continue; cprint("bad character in name: 0x%x\n", c); return; } if(i < 2) { cprint("name too short: %s\n", user); return; } if(i >= NAMELEN) { cprint("name too long: %s\n", user); return; } switch(param[0]){ case 0: if(!adduser(user, 0)) return; cmd_exec("user"); break; case ':': adduser(user, 1); cmd_exec("user"); return; case '#': adduser(user, 0); cmd_exec("user"); return; } /* * create directories */ cmd_exec("user"); sprint(msg, "create /usr/%s %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/tmp %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/lib %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/bin %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/bin/rc %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/bin/mips %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/bin/386 %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/bin/power %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/bin/alpha %s %s 775 d", user, user, user); cmd_exec(msg);Lines 1–500 of 714. Load more
/* * 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" #include "9p1.h" static char elem[NAMELEN]; static Filsys* cur_fs; static char conline[100]; void consserve(void) { con_session(); cmd_exec("cfs"); cmd_exec("user"); } int cmd_exec(char *arg) { char *s, *c; int i; for(i=0; s = command[i].string; i++) { for(c=arg; *s; c++) if(*c != *s++) goto brk; if(*c == '\0' || *c == ' ' || *c == '\t'){ cons.arg = c; (*command[i].func)(); return 1; } brk:; } return 0; } void cmd_check(void) { char *s; int flags; flags = 0; for(s = cons.arg; *s; s++){ while(*s == ' ' || *s == '\t') s++; if(*s == '\0') break; switch(*s){ /* rebuild the free list */ case 'f': flags |= Cfree; break; /* fix bad tags */ case 't': flags |= Ctag; break; /* fix bad tags and clear the contents of the block */ case 'c': flags |= Cream; break; /* delete all redundant references to a block */ case 'd': flags |= Cbad; break; /* read and check tags on all blocks */ case 'r': flags |= Crdall; break; /* write all of the blocks you touch */ case 'w': flags |= Ctouch; break; /* print all directories as they are read */ case 'p': flags |= Cpdir; break; /* print all files as they are read */ case 'P': flags |= Cpfile; break; /* quiet, just report really nasty stuff */ case 'q': flags |= Cquiet; break; } } check(cur_fs, flags); } enum { Sset = (1<<0), Setc = (1<<1), }; void cmd_stats(void) { cprint("work stats\n"); cprint(" work = %A rps\n", (Filta){&cons.work, 1}); cprint(" rate = %A tBps\n", (Filta){&cons.rate, 1000}); cprint(" hits = %A iops\n", (Filta){&cons.bhit, 1}); cprint(" read = %A iops\n", (Filta){&cons.bread, 1}); cprint(" init = %A iops\n", (Filta){&cons.binit, 1}); /* for(i = 0; i < MAXTAG; i++) cprint(" tag %G = %A iops\n", i, (Filta){&cons.tags[i], 1}); */ } void cmd_sync(void) { rlock(&mainlock); syncall(); runlock(&mainlock); } void cmd_halt(void) { wlock(&mainlock); syncall(); superok(cur_fs->dev, superaddr(cur_fs->dev), 1); print("kfs: file system halted\n"); } void cmd_start(void) { superok(cur_fs->dev, superaddr(cur_fs->dev), 0); wunlock(&mainlock); print("kfs: file system started\n"); } void cmd_help(void) { int i; for(i=0; command[i].string; i++) cprint(" %s %s\n", command[i].string, command[i].args); cprint("check options:\n" " r read all blocks\n" " f rebuild the free list\n" " t fix all bad tags\n" " c fix bad tags and zero the blocks\n" " d delete all redundant references to blocks\n" " p print directories as they are checked\n" " P print all files as they are checked\n" " w write all blocks that are read\n"); } void cmd_create(void) { int uid, gid, err; long perm; char oelem[NAMELEN]; char name[NAMELEN]; if(err = con_clone(FID1, FID2)){ cprint("clone failed: %s\n", errstring[err]); return; } if(skipbl(1)){ cprint("skipbl\n"); return; } oelem[0] = 0; while(nextelem()) { if(oelem[0]) if(err = con_walk(FID2, oelem)){ cprint("walk failed: %s\n", errstring[err]); return; } memmove(oelem, elem, NAMELEN); } if(skipbl(1)) return; uid = strtouid(cname(name)); if(uid == 0){ cprint("unknown user %s\n", name); return; } gid = strtouid(cname(name)); if(gid == 0){ cprint("unknown group %s\n", name); return; } perm = number(0777, 8); skipbl(0); for(; *cons.arg; cons.arg++){ if(*cons.arg == 'l') perm |= PLOCK; else if(*cons.arg == 'a') perm |= PAPND; else if(*cons.arg == 'd') perm |= PDIR; else break; } err = con_create(FID2, elem, uid, gid, perm, 0); if(err) cprint("can't create %s: %s\n", elem, errstring[err]); } void cmd_clri(void) { if(con_clone(FID1, FID2)) return; if(skipbl(1)) return; while(nextelem()) if(con_walk(FID2, elem)){ cprint("can't walk %s\n", elem); return; } con_clri(FID2); } void cmd_rename(void) { ulong perm; Dentry d; char stat[DIRREC]; char oelem[NAMELEN], noelem[NAMELEN], nxelem[NAMELEN]; int err; if(con_clone(FID1, FID2)) return; if(skipbl(1)) return; oelem[0] = 0; while(nextelem()) { if(oelem[0]) if(con_walk(FID2, oelem)){ cprint("file does not exits"); return; } memmove(oelem, elem, NAMELEN); } if(skipbl(1)) return; if(cons.arg[0]=='/'){ if(con_clone(FID1, FID3)) return; noelem[0] = 0; while(nextelem()){ if(noelem[0]) if(con_walk(FID3, noelem)){ cprint("target path %s does not exist", noelem); return; } memmove(noelem, elem, NAMELEN); } if(!con_walk(FID3, elem)){ cprint("target %s already exists\n", elem); return; } if(con_walk(FID2, oelem)){ cprint("src %s does not exist\n", oelem); return; } /* * we know the target does not exist, * the source does exist. * to do the rename, create the target and then * copy the directory entry directly. then remove the source. */ if(err = con_stat(FID2, stat)){ cprint("can't stat file: %s\n", errstring[err]); return; } convM2D9p1(stat, &d); perm = (d.mode&0777)|((d.mode&0x7000)<<17); if(err = con_create(FID3, elem, d.uid, d.gid, perm, (d.mode&DDIR)?OREAD:ORDWR)){ cprint("can't create %s: %s\n", elem, errstring[err]); return; } if(err = con_swap(FID2, FID3)){ cprint("can't swap data: %s\n", errstring[err]); return; } if(err = con_remove(FID2)){ cprint("can't remove file: %s\n", errstring[err]); return; } }else{ cname(nxelem); if(strchr(nxelem, '/')){ cprint("bad rename target: not full path, but contains slashes\n"); return; } if(!con_walk(FID2, nxelem)) cprint("file %s already exists\n", nxelem); else if(con_walk(FID2, oelem)) cprint("file does not already exist\n"); else if(err = con_stat(FID2, stat)) cprint("can't stat file: %s\n", errstring[err]); else{ convM2D9p1(stat, &d); strncpy(d.name, nxelem, NAMELEN); convD2M9p1(&d, stat); if(err = con_wstat(FID2, stat)) cprint("can't move file: %s\n", errstring[err]); } } } void cmd_remove(void) { if(con_clone(FID1, FID2)) return; if(skipbl(1)) return; while(nextelem()) if(con_walk(FID2, elem)){ cprint("can't walk %s\n", elem); return; } con_remove(FID2); } void cmd_cfs(void) { Filsys *fs; if(*cons.arg != ' ') { fs = &filesys[0]; /* default */ } else { if(skipbl(1)){ cprint("skipbl\n"); return; } if(!nextelem()) fs = &filesys[0]; /* default */ else fs = fsstr(elem); } if(fs == 0) { cprint("unknown file system %s\n", elem); return; } if(con_attach(FID1, "adm", fs->name)) panic("FID1 attach to root"); cur_fs = fs; } /* * find out the length of a file * given the mesg version of a stat buffer * we call this because convM2D is different * for the file system than in the os */ static uvlong statlen(char *ap) { uchar *p; ulong ll, hl; p = (uchar*)ap; p += 3*28+5*4; ll = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); hl = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24); return ll | ((uvlong) hl << 32); } int adduser(char *user, int isgroup) { char stat[DIRREC]; char msg[100]; Uid *u; int i, c, nu; /* * check uniq of name * and get next uid */ cmd_exec("cfs"); cmd_exec("user"); if(isgroup) nu = 9000; else nu = 0; for(i=0, u=uid; i<conf.nuid; i++,u++) { c = u->uid; if(c == 0) break; if(strcmp(uidspace+u->offset, user) == 0) return 1; if(c >= 9000 && !isgroup) continue; if(c > nu) nu = c; } nu++; if(isgroup){ if(nu >= 0x10000) { cprint("out of group ids\n"); return 0; } } else { if(nu >= 9000) { cprint("out of user ids\n"); return 0; } } /* * write onto adm/users */ if(con_clone(FID1, FID2) || con_path(FID2, "/adm/users") || con_open(FID2, 1)) { cprint("can't open /adm/users\n"); return 0; } sprint(msg, "%d:%s:%s:\n", nu, user, user); cprint("add user %s", msg); c = strlen(msg); i = con_stat(FID2, stat); if(i){ cprint("can't stat /adm/users: %s\n", errstring[i]); return 0; } i = con_write(FID2, msg, statlen(stat), c); if(i != c){ cprint("short write on /adm/users: %d %d\n", c, i); return 0; } return 1; } void cmd_newuser(void) { char user[NAMELEN], param[NAMELEN], msg[100]; int i, c; /* * get uid */ cname(user); cname(param); for(i=0; i<NAMELEN; i++) { c = user[i]; if(c == 0) break; if(c >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') continue; cprint("bad character in name: 0x%x\n", c); return; } if(i < 2) { cprint("name too short: %s\n", user); return; } if(i >= NAMELEN) { cprint("name too long: %s\n", user); return; } switch(param[0]){ case 0: if(!adduser(user, 0)) return; cmd_exec("user"); break; case ':': adduser(user, 1); cmd_exec("user"); return; case '#': adduser(user, 0); cmd_exec("user"); return; } /* * create directories */ cmd_exec("user"); sprint(msg, "create /usr/%s %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/tmp %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/lib %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/bin %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/bin/rc %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/bin/mips %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/bin/386 %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/bin/power %s %s 775 d", user, user, user); cmd_exec(msg); sprint(msg, "create /usr/%s/bin/alpha %s %s 775 d", user, user, user); cmd_exec(msg);