mirror of
https://hacklab.nilfm.cc/kuro
synced 2024-10-22 15:11:49 +00:00
123 lines
2.4 KiB
C
123 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);
|
||
|
}
|
||
|
}
|