xrxs/xrxs.c

176 lines
4.4 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>
/* 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-16 05:46:47 +00:00
static char Ebad[] = "something bad happened";
static char Enomem[] = "no memory";
typedef struct Ramfile Ramfile;
struct Ramfile {
char* data;
int ndata;
};
2021-06-13 17:22:58 +00:00
void fsread(Req* r) {
2021-06-16 05:46:47 +00:00
Ramfile* rf;
vlong offset;
long count;
rf = r->fid->file->aux;
offset = r->ifcall.offset;
count = r->ifcall.count;
/*print("read %ld %lld\n", *count, offset); */
if (offset >= rf->ndata) {
r->ofcall.count = 0;
respond(r, nil);
return;
}
if (offset + count >= rf->ndata)
count = rf->ndata - offset;
memmove(r->ofcall.data, rf->data + offset, count);
r->ofcall.count = count;
respond(r, nil);
}
void fswrite(Req* r) {
void* v;
Ramfile* rf;
vlong offset;
long count;
rf = r->fid->file->aux;
offset = r->ifcall.offset;
count = r->ifcall.count;
if (offset + count >= rf->ndata) {
v = realloc(rf->data, offset + count);
if (v == nil) {
respond(r, Enomem);
return;
}
rf->data = v;
rf->ndata = offset + count;
r->fid->file->dir.length = rf->ndata;
}
memmove(rf->data + offset, r->ifcall.data, count);
r->ofcall.count = count;
2021-06-13 17:22:58 +00:00
respond(r, nil);
}
2021-06-16 05:46:47 +00:00
void fscreate(Req* r) {
Ramfile* rf;
File* f;
if (
f = createfile(
r->fid->file,
r->ifcall.name,
nil,
r->ifcall.perm,
nil)) {
rf = emalloc9p(sizeof *rf);
f->aux = rf;
r->fid->file = f;
r->ofcall.qid = f->dir.qid;
respond(r, nil);
return;
}
respond(r, Ebad);
}
void fsopen(Req* r) {
Ramfile* rf;
rf = r->fid->file->aux;
if (rf && (r->ifcall.mode & OTRUNC)) {
rf->ndata = 0;
r->fid->file->dir.length = 0;
}
respond(r, nil);
}
void fsdestroyfile(File* f) {
Ramfile* rf;
/*fprint(2, "clunk\n"); */
rf = f->aux;
if (rf) {
free(rf->data);
free(rf);
}
}
2021-06-13 17:22:58 +00:00
Srv fs = {
2021-06-16 05:46:47 +00:00
.open = fsopen,
2021-06-13 17:22:58 +00:00
.read = fsread,
2021-06-16 05:46:47 +00:00
.write = fswrite,
.create = fscreate,
2021-06-13 17:22:58 +00:00
};
2021-06-16 05:46:47 +00:00
int threadmaybackground(void) {
return 1;
}
void threadmain(int argc, char* argv[]) {
2021-06-13 17:22:58 +00:00
Tree* tree;
char* mtpt = nil;
char* usocket = nil;
int i;
/* 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);
}
}
}
/* create a single file called 'hello'. reading it calls fsread() */
2021-06-13 17:22:58 +00:00
2021-06-16 05:46:47 +00:00
fs.tree = alloctree(nil, nil, DMDIR|0777, fsdestroyfile);
fs.foreground = 1;
2021-06-13 17:22:58 +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
threadpostmountsrv(&fs, usocket, mtpt, MREPL | MCREATE);
threadexits(0);
} else {
srv(&fs);
}
}