xrxs/xrxs.c

324 lines
7.3 KiB
C
Raw Normal View History

2021-06-13 17:22:58 +00:00
#include <u.h>
#include <libc.h>
#include <fcall.h>
#include <thread.h>
#include <9p.h>
#include <stdio.h>
2021-06-24 07:17:34 +00:00
#include <dirent.h>
#include <libString.h>
2021-06-28 21:37:59 +00:00
#include <mp.h>
#include <libsec.h>
2021-06-24 07:17:34 +00:00
#define CARTSLOC "./carts/"
2021-06-28 21:37:59 +00:00
#define CTL_HASHV 139931
#define SHUTDOWN_HASHV 11192337284248
2021-06-13 17:22:58 +00:00
/* clang-format off */
char clca(char c) { return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c; } /* char to lowercase */
char cuca(char c) { return c >= 'a' && c <= 'z' ? c - ('a' - 'A') : c; } /* char to uppercase */
int slen(char *s) { int i = 0; while(s[i] && s[++i]) { ; } return i; } /* string length */
char *st__(char *s, char (*fn)(char)) { int i = 0; char c; while((c = s[i])) s[i++] = fn(c); return s; }
char *stuc(char *s) { return st__(s, cuca); } /* string to uppercase */
char *stlc(char *s) { return st__(s, clca); } /* string to lowercase */
char *scpy(char *src, char *dst, int len) { int i = 0; while((dst[i] = src[i]) && i < len - 2) i++; dst[i + 1] = '\0'; return dst; } /* string copy */
int scmp(char *a, char *b) { int i = 0; while(a[i] == b[i]) if(!a[i++]) return 1; return 0; } /* string compare */
char *scsw(char *s, char a, char b) { int i = 0; char c; while((c = s[i])) s[i++] = c == a ? b : c; return s; } /* string char swap */
char *scat(char *dst, const char *src) { char *ptr = dst + slen(dst); while(*src) *ptr++ = *src++; *ptr = '\0'; return dst; } /* string cat */
int ssin(char *s, char *ss) { int a = 0, b = 0; while(s[a]) { if(s[a] == ss[b]) { if(!ss[b + 1]) return a - b; b++; } else b = 0; a++; } return -1; } /* string substring index */
char *ccat(char *dst, char c) { int len = slen(dst); dst[len] = c; dst[len + 1] = '\0'; return dst; }
/* clang-format on */
2021-06-28 21:37:59 +00:00
int chatty9p = 1;
2021-06-13 17:22:58 +00:00
2021-06-16 05:46:47 +00:00
static char Ebad[] = "something bad happened";
static char Enomem[] = "no memory";
2021-07-01 07:45:48 +00:00
static char Euname[] = "username is already taken";
2021-06-16 05:46:47 +00:00
typedef enum { CTL = 1, USERS, CARTS, SLOT, DATA, REALMS, UNIVERSE } FileType;
2021-06-29 18:56:21 +00:00
typedef struct Aux Aux;
struct Aux {
FileType type;
2021-06-16 05:46:47 +00:00
char* data;
2021-06-29 18:56:21 +00:00
int count;
2021-06-16 05:46:47 +00:00
};
Aux* create_aux(FileType t) {
Aux* self = (Aux*)malloc(sizeof(Aux));
2021-07-01 07:45:48 +00:00
self->type = t;
self->data = nil;
self->count = 0;
return self;
}
2021-07-01 07:45:48 +00:00
typedef struct UserInfo UserInfo;
struct UserInfo {
char name[32];
ushort id;
};
static UserInfo users_table[64];
void xrxs_attach(Req* r) {
static ushort id = 1;
int i = 0;
int l = 0;
char* usr;
char* username = r->ifcall.uname;
usr = username;
while (*usr) {
l++;
usr++;
}
for (i = 0; i < 64; i++) {
usr = users_table[i].name;
if (scmp(usr, username))
respond(r, Euname);
return;
if (*usr == 0) {
scpy(username, usr, l+1);
users_table[i].id = id++;
break;
}
}
respond(r, nil);
}
2021-06-13 17:22:58 +00:00
void fsread(Req* r) {
2021-06-29 18:56:21 +00:00
Aux* a;
2021-06-16 05:46:47 +00:00
vlong offset;
long count;
2021-06-29 18:56:21 +00:00
a = r->fid->file->aux;
2021-06-16 05:46:47 +00:00
offset = r->ifcall.offset;
count = r->ifcall.count;
/*print("read %ld %lld\n", *count, offset); */
2021-06-29 18:56:21 +00:00
if (offset >= a->count) {
2021-06-16 05:46:47 +00:00
r->ofcall.count = 0;
respond(r, nil);
return;
}
2021-06-29 18:56:21 +00:00
if (offset + count >= a->count)
count = a->count - offset;
2021-06-16 05:46:47 +00:00
2021-06-29 18:56:21 +00:00
memmove(r->ofcall.data, a->data + offset, count);
2021-06-16 05:46:47 +00:00
r->ofcall.count = count;
respond(r, nil);
}
2021-06-28 21:37:59 +00:00
unsigned long long hash(char* str) {
unsigned long long h;
unsigned char* p;
h = 0;
for (p = (unsigned char*)str; *p != '\0'; p++)
h = 37 * h + *p;
return h; // or, h % ARRAY_SIZE;
}
2021-06-16 05:46:47 +00:00
void fswrite(Req* r) {
void* v;
2021-06-29 18:56:21 +00:00
Aux* a;
2021-06-16 05:46:47 +00:00
vlong offset;
long count;
2021-06-29 18:56:21 +00:00
a = r->fid->file->aux;
2021-06-16 05:46:47 +00:00
offset = r->ifcall.offset;
count = r->ifcall.count;
2021-06-29 18:56:21 +00:00
if (offset + count >= a->count) {
v = realloc(a->data, offset + count);
2021-06-16 05:46:47 +00:00
if (v == nil) {
respond(r, Enomem);
return;
}
2021-06-29 18:56:21 +00:00
a->data = v;
a->count = offset + count;
r->fid->file->dir.length = a->count;
2021-06-16 05:46:47 +00:00
}
2021-06-29 18:56:21 +00:00
memmove(a->data + offset, r->ifcall.data, count);
2021-06-16 05:46:47 +00:00
r->ofcall.count = count;
2021-06-13 17:22:58 +00:00
respond(r, nil);
}
void write_ctl(Req* r) {
2021-06-28 21:37:59 +00:00
char cmd[16];
char* c = r->ifcall.data;
2021-06-29 18:56:21 +00:00
int i;
2021-06-28 21:37:59 +00:00
2021-06-29 18:56:21 +00:00
for (i = 0; i < r->ifcall.count; i++) {
ccat(cmd, *c++);
2021-06-28 21:37:59 +00:00
}
unsigned long long const cmd_hashv = hash(cmd);
switch (cmd_hashv) {
default:
break;
}
2021-06-29 18:56:21 +00:00
r->ofcall.count = r->ifcall.count;
r->fid->file->dir.length = r->ifcall.count;
respond(r, nil);
2021-06-28 21:37:59 +00:00
}
void xrxs_write(Req* r) {
2021-06-29 18:56:21 +00:00
Aux* a = r->fid->file->aux;
switch (a->type) {
case CTL:
write_ctl(r);
break;
case UNIVERSE:
2021-07-01 07:45:48 +00:00
// write_universe(r);
2021-06-28 21:37:59 +00:00
break;
default:
respond(r, nil);
break;
}
}
2021-07-01 07:45:48 +00:00
void read_users(Req* r) {
char buf[2112] = {0};
int i;
for (i = 0; i < 64; i++) {
if (scmp(users_table[i].name, "\0")) {
break;
}
scat(buf, users_table[i].name);
if (i == 63) {
ccat(buf, 0);
} else {
ccat(buf, '\n');
}
}
readstr(r, buf);
respond(r, nil);
}
void xrxs_read(Req* r) {
Aux* a = r->fid->file->aux;
switch (a->type) {
case USERS:
2021-07-01 07:45:48 +00:00
read_users(r);
break;
case CARTS:
2021-07-01 07:45:48 +00:00
// read_carts(r);
break;
case SLOT:
2021-07-01 07:45:48 +00:00
// read_slot(r);
break;
case DATA:
2021-07-01 07:45:48 +00:00
// read_data(r);
break;
case REALMS:
2021-07-01 07:45:48 +00:00
// read_realms(r);
break;
case UNIVERSE:
2021-07-01 07:45:48 +00:00
// read_universe(r);
break;
default:
respond(r, nil);
2021-06-28 21:37:59 +00:00
break;
}
}
2021-06-29 18:56:21 +00:00
void fsopen(Req* r) { respond(r, nil); }
2021-06-16 05:46:47 +00:00
2021-06-29 18:56:21 +00:00
void wstat(Req* r) { respond(r, nil); }
2021-06-16 05:46:47 +00:00
void fs_destroy_file(File* f) {
2021-06-29 18:56:21 +00:00
Aux* a = f->aux;
if (a && a->data) {
free(a->data);
free(a);
} else if (a) {
free(a);
2021-06-16 05:46:47 +00:00
}
}
2021-06-24 07:17:34 +00:00
String** listdir(char* path) {
String** self = malloc(128 * sizeof(String*));
DIR* dir;
struct dirent* ent;
int i = 0;
char* c;
if ((dir = opendir(path)) != NULL) {
while ((ent = readdir(dir)) != NULL) {
c = ent->d_name;
if (scmp(c, ".") || scmp(c, "..")) {
continue;
}
self[i] = s_new();
while (*c) {
s_putc(self[i], *c++);
}
s_terminate(self[i++]);
}
closedir(dir);
}
self[i] = nil;
return self;
}
2021-06-13 17:22:58 +00:00
Srv fs = {
2021-07-01 07:45:48 +00:00
.attach = xrxs_attach,
2021-06-16 05:46:47 +00:00
.open = fsopen,
2021-06-30 06:55:56 +00:00
.read = xrxs_read,
.write = xrxs_write,
2021-06-29 18:56:21 +00:00
.create = fsopen,
.wstat = wstat};
2021-06-13 17:22:58 +00:00
int threadmaybackground(void) { return 1; }
2021-06-16 05:46:47 +00:00
void threadmain(int argc, char* argv[]) {
2021-06-13 17:22:58 +00:00
Tree* tree;
char* mtpt = nil;
char* usocket = nil;
int i;
2021-06-24 07:17:34 +00:00
String** cart;
/* if -m PATH is supplied, mount on PATH */
/* if -s NAME is supplied, create a socket for the namespace */
/* otherwise, just use srv() (for wrapping with socat or inetd) */
2021-06-13 17:22:58 +00:00
if (argc >= 3) {
for (i = 0; i < argc; i++) {
if (scmp(argv[i], "-m")) {
mtpt = argv[++i];
printf("serving on %s", mtpt);
} else if (scmp(argv[i], "-s")) {
usocket = argv[++i];
printf("serving socket namespace %s", usocket);
}
}
}
2021-06-29 18:56:21 +00:00
fs.foreground = 1;
fs.tree = alloctree(nil, nil, DMDIR | 0777, fs_destroy_file);
tree = fs.tree;
closefile(createfile(tree->root, "carts", nil, 0444, create_aux(CARTS)));
2021-07-01 07:45:48 +00:00
closefile(
createfile(tree->root, "ctl", nil, DMAPPEND | 0300, create_aux(CTL)));
closefile(createfile(tree->root, "users", nil, 0444, create_aux(USERS)));
/*String** carts = listdir("carts/");
2021-06-24 07:17:34 +00:00
cart = carts;
2021-06-13 17:22:58 +00:00
2021-07-01 07:45:48 +00:00
while (*cart) {
// just concatenate the carts into a multiline string, and put it in
CARTS.data
}*/
2021-07-01 07:45:48 +00:00
if (argc >= 3) {
if (mtpt != nil && access(mtpt, AEXIST) < 0 && access(mtpt, AEXIST) < 0)
sysfatal("mountpoint %s does not exist", mtpt);
2021-06-13 17:22:58 +00:00
2021-07-01 07:45:48 +00:00
threadpostmountsrv(&fs, usocket, mtpt, MREPL | MCREATE);
threadexits(0);
} else {
srv(&fs);
}
}