plan9fox/sys/src/cmd/hjfs/cons.c

270 lines
4.2 KiB
C
Raw Normal View History

2012-08-07 15:57:04 +00:00
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <bio.h>
#include "dat.h"
#include "fns.h"
enum { MAXARGS = 16 };
typedef struct Cmd Cmd;
static int echo;
extern Fs *fsmain;
struct Cmd {
char *name;
int args;
int (*f)(int, char **);
};
static int
walkpath(Chan *ch, char *path, char **cr)
{
char buf[NAMELEN], *p, *fp;
2012-08-07 22:52:37 +00:00
2012-08-07 15:57:04 +00:00
fp = path;
if(*path != '/'){
noent:
werrstr("%s: %s", fp, Enoent);
return -1;
}
path++;
for(;;){
p = strchr(path, '/');
if(p == nil){
if(cr != nil){
if(*path == 0){
werrstr("%s: trailing slash", fp);
return -1;
}
*cr = path;
break;
}
p = path + strlen(path);
}
if(*path == '/'){
path++;
continue;
}
if(*path == 0)
break;
if(p - path >= NAMELEN)
goto noent;
2012-08-07 22:52:37 +00:00
memset(buf, 0, sizeof buf);
2012-08-07 15:57:04 +00:00
memcpy(buf, path, p - path);
if(chanwalk(ch, buf) <= 0){
werrstr("%s: %r", fp);
return -1;
}
if(*p == 0)
break;
path = p + 1;
}
return 1;
}
int
cmdhalt(int, char **)
{
shutdown();
return 0;
}
int
cmddump(int, char **)
{
fsdump(fsmain);
dprint("hjfs: dumped\n");
return 0;
}
int
cmdallow(int, char **)
{
fsmain->flags |= FSNOPERM | FSCHOWN;
dprint("hjfs: allow\n");
return 0;
}
int
cmdchatty(int, char **)
{
extern int chatty9p;
chatty9p = !chatty9p;
return 0;
}
int
cmddisallow(int, char **)
{
fsmain->flags &= ~(FSNOPERM | FSCHOWN);
dprint("hjfs: disallow\n");
return 0;
}
int
cmdnoauth(int, char **)
{
fsmain->flags ^= FSNOAUTH;
2012-08-08 08:14:20 +00:00
if((fsmain->flags & FSNOAUTH) == 0)
2012-08-07 15:57:04 +00:00
dprint("hjfs: auth enabled\n");
else
dprint("hjfs: auth disabled\n");
return 1;
}
int
cmdcreate(int argc, char **argv)
{
Chan *ch;
char *n;
short uid, gid;
ulong perm;
Dir di;
if(argc != 5 && argc != 6)
return -9001;
perm = strtol(argv[4], &n, 8) & 0777;
if(*n != 0)
return -9001;
if(argc == 6)
for(n = argv[5]; *n != 0; n++)
switch(*n){
case 'l': perm |= DMEXCL; break;
case 'd': perm |= DMDIR; break;
case 'a': perm |= DMAPPEND; break;
default: return -9001;
}
if(name2uid(fsmain, argv[2], &uid) < 0)
return -1;
if(name2uid(fsmain, argv[3], &gid) < 0)
return -1;
ch = chanattach(fsmain, 0);
if(ch == nil)
return -1;
ch->uid = uid;
if(walkpath(ch, argv[1], &n) < 0){
chanclunk(ch);
return -1;
}
if(chancreat(ch, n, perm, OREAD) < 0){
chanclunk(ch);
return -1;
}
nulldir(&di);
di.gid = argv[3];
chanwstat(ch, &di);
chanclunk(ch);
return 1;
}
int
cmdecho(int, char **argv)
{
echo = strcmp(argv[1], "on") == 0;
return 1;
}
2012-09-27 13:06:42 +00:00
int
2012-09-27 14:26:28 +00:00
cmddf(int, char **)
2012-09-27 13:06:42 +00:00
{
uvlong n;
uvlong i;
int j;
Buf *b, *sb;
wlock(fsmain);
sb = getbuf(fsmain->d, SUPERBLK, TSUPERBLOCK, 0);
if(sb == nil){
wunlock(fsmain);
return -1;
}
n = 0;
for(i = sb->sb.fstart; i < sb->sb.fend; i++){
b = getbuf(fsmain->d, i, TREF, 0);
if(b == nil)
continue;
for(j = 0; j < REFPERBLK; j++)
if(b->refs[j] == 0)
n++;
putbuf(b);
}
2012-09-27 13:10:03 +00:00
dprint("hjfs: free %uld, used %uld, total %uld\n", n, sb->sb.size - n, sb->sb.size);
2012-09-27 13:06:42 +00:00
putbuf(sb);
wunlock(fsmain);
return 1;
}
2012-08-07 15:57:04 +00:00
extern int cmdnewuser(int, char **);
Cmd cmds[] = {
{"allow", 1, cmdallow},
{"noauth", 1, cmdnoauth},
{"chatty", 1, cmdchatty},
{"create", 0, cmdcreate},
{"disallow", 1, cmddisallow},
{"dump", 1, cmddump},
{"halt", 1, cmdhalt},
{"newuser", 0, cmdnewuser},
{"echo", 2, cmdecho},
2012-09-27 14:26:28 +00:00
{"df", 1, cmdstatw},
2012-08-07 15:57:04 +00:00
};
static void
consproc(void *v)
{
Biobuf *in;
Cmd *c;
char *s;
char *args[MAXARGS];
int rc;
in = (Biobuf *) v;
for(;;){
s = Brdstr(in, '\n', 1);
if(s == nil)
continue;
if(echo)
dprint("hjfs: >%s\n", s);
rc = tokenize(s, args, MAXARGS);
if(rc == 0)
goto syntax;
for(c = cmds; c < cmds + nelem(cmds); c++)
if(strcmp(c->name, args[0]) == 0){
if(c->args != 0 && c->args != rc)
goto syntax;
if(c->f != nil){
rc = c->f(rc, args);
if(rc == -9001)
goto syntax;
if(rc < 0)
dprint("hjfs: %r\n");
goto done;
}
}
syntax:
dprint("hjfs: syntax error\n");
done:
free(s);
}
}
void
initcons(char *service)
{
int fd, pfd[2];
static Biobuf bio;
char buf[512];
snprint(buf, sizeof(buf), "/srv/%s.cmd", service);
fd = create(buf, OWRITE|ORCLOSE, 0600);
if(fd < 0)
return;
pipe(pfd);
fprint(fd, "%d", pfd[1]);
Binit(&bio, pfd[0], OREAD);
proccreate(consproc, &bio, mainstacksize);
}