4 static char elem[NAMELEN];
6 static char conline[100];
22 for(i=0; s = command[i].string; i++) {
26 if(*c == '\0' || *c == ' ' || *c == '\t'){
43 for(s = cons.arg; *s; s++){
44 while(*s == ' ' || *s == '\t')
49 /* rebuild the free list */
50 case 'f': flags |= Cfree; break;
52 case 't': flags |= Ctag; break;
53 /* fix bad tags and clear the contents of the block */
54 case 'c': flags |= Cream; break;
55 /* delete all redundant references to a block */
56 case 'd': flags |= Cbad; break;
57 /* read and check tags on all blocks */
58 case 'r': flags |= Crdall; break;
59 /* write all of the blocks you touch */
60 case 'w': flags |= Ctouch; break;
61 /* print all directories as they are read */
62 case 'p': flags |= Cpdir; break;
63 /* print all files as they are read */
64 case 'P': flags |= Cpfile; break;
65 /* quiet, just report really nasty stuff */
66 case 'q': flags |= Cquiet; break;
80 cprint("work stats\n");
81 cprint(" work = %A rps\n", (Filta){&cons.work, 1});
82 cprint(" rate = %A tBps\n", (Filta){&cons.rate, 1000});
83 cprint(" hits = %A iops\n", (Filta){&cons.bhit, 1});
84 cprint(" read = %A iops\n", (Filta){&cons.bread, 1});
85 cprint(" init = %A iops\n", (Filta){&cons.binit, 1});
86 /* for(i = 0; i < MAXTAG; i++)
87 cprint(" tag %G = %A iops\n", i, (Filta){&cons.tags[i], 1});
104 superok(cur_fs->dev, superaddr(cur_fs->dev), 1);
105 print("kfs: file system halted\n");
111 superok(cur_fs->dev, superaddr(cur_fs->dev), 0);
113 print("kfs: file system started\n");
121 for(i=0; command[i].string; i++)
122 cprint(" %s %s\n", command[i].string, command[i].args);
123 cprint("check options:\n"
124 " r read all blocks\n"
125 " f rebuild the free list\n"
126 " t fix all bad tags\n"
127 " c fix bad tags and zero the blocks\n"
128 " d delete all redundant references to blocks\n"
129 " p print directories as they are checked\n"
130 " P print all files as they are checked\n"
131 " w write all blocks that are read\n");
142 if(err = con_clone(FID1, FID2)){
143 cprint("clone failed: %s\n", errstring[err]);
153 if(err = con_walk(FID2, oelem)){
154 cprint("walk failed: %s\n", errstring[err]);
157 memmove(oelem, elem, NAMELEN);
161 uid = strtouid(cname(name));
163 cprint("unknown user %s\n", name);
166 gid = strtouid(cname(name));
168 cprint("unknown group %s\n", name);
171 perm = number(0777, 8);
173 for(; *cons.arg; cons.arg++){
185 err = con_create(FID2, elem, uid, gid, perm, 0);
187 cprint("can't create %s: %s\n", elem, errstring[err]);
193 if(con_clone(FID1, FID2))
198 if(con_walk(FID2, elem)){
199 cprint("can't walk %s\n", elem);
211 char oelem[NAMELEN], noelem[NAMELEN], nxelem[NAMELEN];
214 if(con_clone(FID1, FID2))
221 if(con_walk(FID2, oelem)){
222 cprint("file does not exits");
225 memmove(oelem, elem, NAMELEN);
229 if(cons.arg[0]=='/'){
230 if(con_clone(FID1, FID3))
235 if(con_walk(FID3, noelem)){
236 cprint("target path %s does not exist", noelem);
239 memmove(noelem, elem, NAMELEN);
241 if(!con_walk(FID3, elem)){
242 cprint("target %s already exists\n", elem);
245 if(con_walk(FID2, oelem)){
246 cprint("src %s does not exist\n", oelem);
250 * we know the target does not exist,
251 * the source does exist.
252 * to do the rename, create the target and then
253 * copy the directory entry directly. then remove the source.
255 if(err = con_stat(FID2, stat)){
256 cprint("can't stat file: %s\n", errstring[err]);
259 convM2D9p1(stat, &d);
260 perm = (d.mode&0777)|((d.mode&0x7000)<<17);
261 if(err = con_create(FID3, elem, d.uid, d.gid, perm, (d.mode&DDIR)?OREAD:ORDWR)){
262 cprint("can't create %s: %s\n", elem, errstring[err]);
265 if(err = con_swap(FID2, FID3)){
266 cprint("can't swap data: %s\n", errstring[err]);
269 if(err = con_remove(FID2)){
270 cprint("can't remove file: %s\n", errstring[err]);
275 if(strchr(nxelem, '/')){
276 cprint("bad rename target: not full path, but contains slashes\n");
279 if(!con_walk(FID2, nxelem))
280 cprint("file %s already exists\n", nxelem);
281 else if(con_walk(FID2, oelem))
282 cprint("file does not already exist\n");
283 else if(err = con_stat(FID2, stat))
284 cprint("can't stat file: %s\n", errstring[err]);
286 convM2D9p1(stat, &d);
287 strncpy(d.name, nxelem, NAMELEN);
288 convD2M9p1(&d, stat);
289 if(err = con_wstat(FID2, stat))
290 cprint("can't move file: %s\n", errstring[err]);
298 if(con_clone(FID1, FID2))
303 if(con_walk(FID2, elem)){
304 cprint("can't walk %s\n", elem);
315 if(*cons.arg != ' ') {
316 fs = &filesys[0]; /* default */
323 fs = &filesys[0]; /* default */
328 cprint("unknown file system %s\n", elem);
331 if(con_attach(FID1, "adm", fs->name))
332 panic("FID1 attach to root");
337 * find out the length of a file
338 * given the mesg version of a stat buffer
339 * we call this because convM2D is different
340 * for the file system than in the os
350 ll = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
351 hl = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24);
352 return ll | ((uvlong) hl << 32);
356 adduser(char *user, int isgroup)
373 for(i=0, u=uid; i<conf.nuid; i++,u++) {
377 if(strcmp(uidspace+u->offset, user) == 0)
379 if(c >= 9000 && !isgroup)
387 cprint("out of group ids\n");
392 cprint("out of user ids\n");
398 * write onto adm/users
400 if(con_clone(FID1, FID2)
401 || con_path(FID2, "/adm/users")
402 || con_open(FID2, 1)) {
403 cprint("can't open /adm/users\n");
407 sprint(msg, "%d:%s:%s:\n", nu, user, user);
408 cprint("add user %s", msg);
410 i = con_stat(FID2, stat);
412 cprint("can't stat /adm/users: %s\n", errstring[i]);
415 i = con_write(FID2, msg, statlen(stat), c);
417 cprint("short write on /adm/users: %d %d\n", c, i);
426 char user[NAMELEN], param[NAMELEN], msg[100];
434 for(i=0; i<NAMELEN; i++) {
438 if(c >= '0' && c <= '9'
439 || c >= 'a' && c <= 'z'
440 || c >= 'A' && c <= 'Z')
442 cprint("bad character in name: 0x%x\n", c);
446 cprint("name too short: %s\n", user);
450 cprint("name too long: %s\n", user);
456 if(!adduser(user, 0))
474 sprint(msg, "create /usr/%s %s %s 775 d", user, user, user);
476 sprint(msg, "create /usr/%s/tmp %s %s 775 d", user, user, user);
478 sprint(msg, "create /usr/%s/lib %s %s 775 d", user, user, user);
480 sprint(msg, "create /usr/%s/bin %s %s 775 d", user, user, user);
482 sprint(msg, "create /usr/%s/bin/rc %s %s 775 d", user, user, user);
484 sprint(msg, "create /usr/%s/bin/mips %s %s 775 d", user, user, user);
486 sprint(msg, "create /usr/%s/bin/386 %s %s 775 d", user, user, user);
488 sprint(msg, "create /usr/%s/bin/power %s %s 775 d", user, user, user);
490 sprint(msg, "create /usr/%s/bin/alpha %s %s 775 d", user, user, user);
497 uchar buf[DIRREC], *p;
498 static char utime[4];
500 if(con_clone(FID1, FID2)
501 || con_path(FID2, "/adm/users")
503 || con_stat(FID2, (char*)buf))
505 p = buf + 3*NAMELEN + 4*4;
506 if(memcmp(utime, p, 4) == 0)
508 memmove(utime, p, 4);
535 cprint("atimes will not be updated\n");
537 cprint("atimes will be updated\n");
543 allownone = !allownone;
545 cprint("none can attach to new connections\n");
547 cprint("none can only attach on authenticated connections\n");
556 strcpy(addr, "tcp!*!564"); /* 9fs */
561 cprint("announce %s failed\n", addr);
563 cprint("announce %s\n", addr);
567 cmd_nowritegroup(void)
574 "allow", cmd_allow, "",
575 "allowoff", cmd_disallow, "",
576 "atime", cmd_atime, "",
577 "cfs", cmd_cfs, "[filesys]",
578 "chat", cmd_chat, "",
579 "check", cmd_check, "[cdfpPqrtw]",
580 "clri", cmd_clri, "filename",
581 "create", cmd_create, "filename user group perm [ald]",
582 "disallow", cmd_disallow, "",
583 "halt", cmd_halt, "",
584 "help", cmd_help, "",
585 "listen", cmd_listen, "[address]",
586 "newuser", cmd_newuser, "username",
587 "noneattach", cmd_noneattach, "",
588 "nowritegroup", cmd_nowritegroup, "",
589 "remove", cmd_remove, "filename",
590 "rename", cmd_rename, "file newname",
591 "start", cmd_start, "",
592 "stats", cmd_stats, "[fw]",
593 "sync", cmd_sync, "",
594 "user", cmd_user, "",
601 if(*cons.arg != ' ') {
603 cprint("syntax error\n");
606 while(*cons.arg == ' ')
616 memset(name, 0, NAMELEN);
646 while(*cons.arg == '/')
649 if(c == 0 || c == ' ')
651 for(i = 0; c = *cons.arg; i++) {
652 if(c == ' ' || c == '/')
655 cprint("path name component too long\n");
666 number(int d, int base)
685 while((c >= '0' && c <= '9') ||
686 (base == 16 && c >= 'a' && c <= 'f') ||
687 (base == 16 && c >= 'A' && c <= 'F')) {
689 if(c >= 'a' && c <= 'f')
692 if(c >= 'A' && c <= 'F')