239 lines
3.7 KiB
C
239 lines
3.7 KiB
C
#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;
|
|
|
|
buf[NAMELEN - 1] = 0;
|
|
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;
|
|
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;
|
|
if((fsmain->flags & FSNOAUTH) != 0)
|
|
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;
|
|
}
|
|
|
|
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},
|
|
};
|
|
|
|
|
|
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);
|
|
}
|