kuro/srv.c

122 lines
2.4 KiB
C

#include "dat.h"
#include "fns.h"
static NodeTable nodes;
static QLock id_lock;
static uvlong get_next_id(void) {
static uvlong id = 0;
uvlong next;
qlock(&id_lock);
next = ++id;
qunlock(&id_lock);
return next;
}
Aux* create_aux(FileType t) {
Aux* self = (Aux*)malloc(sizeof(Aux));
self->type = t;
self->data = nil;
self->count = 0;
return self;
}
void fs_destroy_file(File* f) {
Aux* a = (Aux*)f->aux;
if(a && a->data) {
free(a->data);
}
if (a) {
free (a);
}
}
void kuro_read(Req* r) {
Aux* a = (Aux*)r->fid->file->aux;
switch (a->type) {
case CTL:
default:
respond(r, nil);
break;
}
}
void new_window(char* filename, int new) {
int rw_fd[2];
char client_fd[32] = {0};
char client_id[32] = {0};
uvlong id;
NodeRef* noderef;
pipe(rw_fd);
id = get_next_id();
noderef = (NodeRef*)malloc(sizeof(NodeRef));
noderef->id = id;
noderef->fd[0] = rw_fd[0];
noderef->fd[1] = rw_fd[1];
nodetbl_add(&nodes, noderef);
sprintf(client_fd, "%d", rw_fd[1]);
sprintf(client_id, "%d", id);
rfork(RFNAMEG);
char* a[] = { "kuro", "-p", client_fd, "-i", client_id, new ? "-n" : filename, new ? filename : 0, 0 };
exec("./kuro", a);
}
void write_ctl(Req* r) {
char cmd[16] = {0};
char* c = r->ifcall.data;
int i;
for (i = 0; i < r->ifcall.count && *c != ' ' && *c != '\n'; i++) {
strncat(cmd, c, 1);
c++;
}
if (*c == ' ') {
c++;
}
/* maybe don't do this... */
strcsw(c, '\n', 0);
/* diagnostics for now */
print("cmd: %s\n", cmd);
print("arg: %s\n", c);
if (strequ(cmd, "new")) {
new_window(c, 1);
respond(r, nil);
} else {
print("unknown command...\n");
respond(r, nil);
}
}
void kuro_write(Req* r) {
Aux* a = (Aux*)r->fid->file->aux;
switch (a->type) {
case CTL:
write_ctl(r);
break;
default:
respond(r, nil);
break;
}
}
void start_9p(char* mtpt) {
if (mtpt) {
putenv("KURO_MTPT", mtpt);
Srv srv = { .read = kuro_read, .write = kuro_write };
Tree* tree = alloctree(nil, nil, DMDIR | 0777, fs_destroy_file);
srv.tree = tree;
closefile(createfile(tree->root, "ctl", nil, DMAPPEND | 0600, create_aux(CTL)));
closefile(createfile(tree->root, "nodes", nil, DMDIR | 0600, nil));
closefile(tree->root);
/* TODO: figure out how to kill the server cleanly so we don't need MREPL */
threadpostmountsrv(&srv, nil, mtpt, MREPL | MCREATE);
}
}