#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); } }