implemented some more functions and started putting it all together... realms aren't being saved on leaving; something's up

This commit is contained in:
Iris Lightshard 2021-07-13 01:34:34 -06:00
parent 92bbf397ac
commit c524a9b65b
Signed by: Iris Lightshard
GPG key ID: 3B7FBC22144E6398
8 changed files with 411 additions and 147 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
*.o
xrxs
realms/

12
aux.h
View file

@ -1,4 +1,14 @@
typedef enum { CTL = 1, USERS, CARTS, SLOT, DATA, REALMS, UNIVERSE } FileType;
typedef enum {
CTL = 1,
USERS,
CARTS,
SLOT,
SPRITE_DATA,
AUDIO_DATA,
TEXT_DATA,
REALMS,
UNIVERSE
} FileType;
typedef struct Aux {
FileType type;

40
realm.c
View file

@ -35,10 +35,14 @@ Realm* parse_realm(char* name) {
scat(file, "/realm");
f = fopen(file, "r");
if (fgets(buf, 256, f)) {
self = malloc(sizeof(Realm));
sscanf(buf, "%hu %llu", &(self->max), &(self->password));
fclose(f);
if (f != nil) {
if (fgets(buf, 256, f)) {
self = malloc(sizeof(Realm));
sscanf(buf, "%hu %llu", &(self->max), &(self->password));
fclose(f);
} else {
return nil;
}
} else {
return nil;
}
@ -58,6 +62,32 @@ Realm* find_realm(UserInfo* table, char* name) {
return u->realm;
u++;
}
return nil;
}
void save_realm(Realm* self) {}
void save_realm(Realm* self) {
FILE* f;
char path[64];
char file[64];
scat(path, "realms/");
scat(path, self->name);
scpy(path, file, 64);
scat(file, "/realm");
f = fopen(file, "w");
if (f != nil) {
fprintf(f, "%hu %llu", self->max, self->password);
fclose(f);
save_universe(self->universe, self->name);
}
}
void destroy_realm(Realm* self) {
if (self != nil) {
if (self->universe != nil) {
destroy_universe(self->universe);
}
free(self);
self = nil;
}
}

100
user.c
View file

@ -0,0 +1,100 @@
#include <u.h>
#include <libc.h>
#include "util.h"
#include "cart.h"
#include "realm.h"
#include "user.h"
extern UserInfo users_table[64];
UserInfo* find_user(UserInfo* table, char* uname) {
UserInfo* u = table;
int i;
for (i = 0; i < 64; i++) {
if (scmp(uname, u->name))
return u;
u++;
}
return nil;
}
int load_cart(UserInfo* table, char* uname, char* cart_name) {
Cart* c = find_cart(table, cart_name);
UserInfo* u = find_user(table, uname);
if (u == nil)
return 0;
if (c != nil) {
u->cart = c;
return 1;
} else {
u->cart = create_cart(cart_name);
if (u->cart == nil)
return 0;
else
return 1;
}
}
int enter_realm(UserInfo* table, char* uname, char* realm_name) {
Realm* r = find_realm(table, realm_name);
UserInfo* u = find_user(table, uname);
int i, j;
if (u == nil || u->cart == nil)
return 0;
for (i = j = 0; i < 64; i++) {
if (table[i].realm != nil && scmp(table[i].realm->name, realm_name))
j++;
}
if (j >= r->max)
return 0;
if (r != nil) {
u->realm = r;
return 1;
} else {
u->realm = parse_realm(realm_name);
if (u->realm == nil)
return 0;
else
return 1;
}
}
int leave_realm(UserInfo* table, char* uname) {
UserInfo* u = find_user(table, uname);
Realm* r;
if (u == nil)
return 0;
r = u->realm;
if (r == nil)
return 0;
save_realm(r);
u->realm = nil;
if (find_realm(table, r->name) == nil)
destroy_realm(r);
return 1;
}
int unload_cart(UserInfo* table, char* uname) {
UserInfo* u = find_user(table, uname);
Cart* c;
if (u == nil)
return 0;
c = u->cart;
if (c == nil)
return 0;
u->cart = nil;
if (find_cart(table, c->name) == nil)
destroy_cart(c);
return 1;
}

9
user.h
View file

@ -7,7 +7,8 @@ typedef struct UserInfo {
Realm* realm;
} UserInfo;
int load_cart(char* uname, char* cart_name);
int enter_realm(char* uname, char* realm_name);
int leave_realm(char* uname, Realm* realm);
int unload_cart(char* uname, Cart* cart);
UserInfo* find_user(UserInfo* table, char* uname);
int load_cart(UserInfo* table, char* uname, char* cart_name);
int enter_realm(UserInfo* table, char* uname, char* realm_name);
int leave_realm(UserInfo* table, char* uname);
int unload_cart(UserInfo* table, char* uname);

45
util.c
View file

@ -138,4 +138,49 @@ char* read_chars(char* path) {
fclose(f);
return buf;
}
}
void strreverse(char* begin, char* end) {
char aux;
while (end > begin)
aux = *end, *end-- = *begin, *begin++ = aux;
}
void itoa(int value, char* str, int base) {
static char num[] = "0123456789abcdefghijklmnopqrstuvwxyz";
char* wstr = str;
int sign;
// Validate base
if (base < 2 || base > 35) {
*wstr = '\0';
return;
}
// Take care of sign
if ((sign = value) < 0)
value = -value;
// Conversion. Number is reversed.
do
*wstr++ = num[value % base];
while (value /= base);
if (sign < 0)
*wstr++ = '-';
*wstr = '\0';
// Reverse string
strreverse(str, wstr - 1);
}

3
util.h
View file

@ -14,4 +14,5 @@ char* scat(char* dst, const char* src);
int ssin(char* str, char* substr);
char* ccat(char* dst, char c);
char* read_bytes(char* path);
char* read_chars(char* path);
char* read_chars(char* path);
void itoa(int, char*, int);

348
xrxs.c
View file

@ -6,6 +6,7 @@
#include <stdio.h>
#include <dirent.h>
#include <libString.h>
#include <string.h>
#include "err.h"
#include "command.h"
#include "util.h"
@ -15,6 +16,9 @@
#include "realm.h"
#include "user.h"
#define CARTSPATH "./carts"
#define REALMSPATH "./realms"
int chatty9p = 1;
static Tree* tree;
@ -67,95 +71,29 @@ void login(char* uname, char* password) {
int logout(char* uname) {
int i;
fprintf(stderr, uname);
UserInfo* u = users_table;
for (i = 0; i < 64; i++) {
if (scmp(uname, users_table[i].name)) {
*(users_table[i].name) = 0;
users_table[i].password = 0;
/* free cart */
/* free realm */
if (scmp(uname, u->name)) {
*(u->name) = 0;
u->password = 0;
if (u->realm != nil)
leave_realm(users_table, uname);
if (u->cart != nil)
unload_cart(users_table, uname);
return 1;
}
u++;
}
return 0;
}
int load(char* uname, char* cart) {
/* 1. get file handle to cartridge file
* 2. make cartridge file available in CART.data for this user
* 3. add cartridge name to user's UserInfo
* 4. if cartridge data dir is not empty, walk it
* 5. for each file in data dir, create corresponding
* data file in DATA/ for this user, grab a file handle, and make
* the data available in DATA.data
*/
return 1;
}
void protect(char* uname, char* password) {
UserInfo* u = find_user(users_table, uname);
int rcreate(char* realm) { // create is taken in the libc header!
/* 1. split input by space -- if 2+ elements, second element
* is the max number of members (default 4)
* 2. check if realm exists; return 0 if it does
* 3. create real files in the realms directory and fill as
* appropriate
*/
return 1;
}
int protect(char* password) {
/* 1. if current realm has a password already, return 0;
* 2. otherwise, hash the password and put it after the
* member limit in the realm file
*/
return 1;
}
int enter(char* uname, char* realm) {
/* 1. get password for realm; if none, skip to 3
* 2. check password for current user against it;
* return 0 if different
* 3. if member limit already met, return 0
* 4. otherwise, insert username in the realm
* and the realm name in the user's UserInfo
*/
return 1;
}
int leave(char* uname) {
/* 1. if not in a realm, return 0;
* 2. else remove self from realm file
* and remove realm from user's UserInfo
*/
return 1;
}
int save(char* uname) {
/* 1. flush this user's universe to the realm;
* maybe this is not needed
*/
return 1;
}
int reset(char* uname) {
/* 1. save
* 2. leave
* 3. clear this user's password
* 4. the client should now be able to restart execution
* of the cartridge safely
*/
return 1;
}
int unload(char* uname) {
/* 1. reset
* 2. clear cartridge data from CART->data for this user
* 3. destroy all files in DATA/ for this user
* 4. remove cartridge from UserInfo for thi user
* 5. the client should now be able to unload
* the cartridge from memory safely and restart
* the 'firmware' ROM execution
*/
return 1;
if (u != nil && u->realm != nil) {
u->realm->password = hash(password, 0);
}
}
void write_ctl(Req* r) {
@ -166,6 +104,9 @@ void write_ctl(Req* r) {
for (i = 0; i < r->ifcall.count && *c != ' ' && *c != '\n'; i++) {
ccat(cmd, *c++);
}
if (*c == ' ')
c++;
fprintf(stderr, cmd);
uvlong const cmd_hashv = hash(cmd, 0);
switch (cmd_hashv) {
@ -173,19 +114,19 @@ void write_ctl(Req* r) {
login(r->fid->uid, c);
break;
case LOAD:
// load(r->fid->uid, c);
load_cart(users_table, r->fid->uid, c);
break;
case CREATE:
// rcreate(c);
create_realm(c);
break;
case PROTECT:
// protect(c);
protect(r->fid->uid, c);
break;
case ENTER:
// enter(r->fid->uid, c);
enter_realm(users_table, r->fid->uid, c);
break;
case LEAVE:
// leave(r->fid->uid);
leave_realm(users_table, r->fid->uid);
break;
case LOGOUT:
logout(r->fid->uid);
@ -197,7 +138,7 @@ void write_ctl(Req* r) {
// reset(r->fid->uid);
break;
case UNLOAD:
// unload(r->fid->uid);
unload_cart(users_table, r->fid->uid);
break;
}
r->ofcall.count = r->ifcall.count;
@ -205,6 +146,39 @@ void write_ctl(Req* r) {
respond(r, nil);
}
void write_universe(Req* r) {
char key[16] = {0};
char value[64] = {0};
char* c = r->ifcall.data;
UserInfo* u = find_user(users_table, r->fid->uid);
Atom* a;
int i;
for (i = 0; i < 15 && i < r->ifcall.count && *c != ' ' && *c != '\n'; i++) {
ccat(key, *c++);
}
c++;
for (i = 0; i < 63 && i < r->ifcall.count && *c != ' ' && *c != '\n'; i++) {
ccat(value, *c++);
}
if (u != nil && u->realm != nil && u->realm->universe != nil) {
a = get_atom(u->realm->universe, key);
if (a != nil) {
scpy(value, a->value, 64);
} else {
a = malloc(sizeof(Atom));
scpy(key, a->name, 16);
scpy(value, a->value, 64);
a->next = nil;
set_atom(u->realm->universe, a);
}
}
r->ofcall.count = r->ifcall.count;
r->fid->file->dir.length = r->ifcall.count;
respond(r, nil);
}
void xrxs_write(Req* r) {
Aux* a = r->fid->file->aux;
switch (a->type) {
@ -212,7 +186,7 @@ void xrxs_write(Req* r) {
write_ctl(r);
break;
case UNIVERSE:
// write_universe(r);
write_universe(r);
break;
default:
respond(r, nil);
@ -244,44 +218,7 @@ void read_users(Req* r) {
respond(r, nil);
}
void xrxs_read(Req* r) {
Aux* a = r->fid->file->aux;
switch (a->type) {
case USERS:
read_users(r);
break;
case CARTS:
// read_carts(r);
break;
case SLOT:
// read_slot(r);
break;
case DATA:
// read_data(r);
break;
case REALMS:
// read_realms(r);
break;
case UNIVERSE:
// read_universe(r);
break;
default:
respond(r, nil);
break;
}
}
void fs_destroy_file(File* f) {
Aux* a = f->aux;
if (a && a->data) {
free(a->data);
free(a);
} else if (a) {
free(a);
}
}
String** listdir(char* path) {
String** list_dir(char* path) {
String** self = malloc(128 * sizeof(String*));
DIR* dir;
struct dirent* ent;
@ -306,6 +243,131 @@ String** listdir(char* path) {
return self;
}
void read_carts(Req* r) {
String** carts = list_dir(CARTSPATH);
String** c = carts;
char data[4096] = {0};
while (*c != nil) {
scat(data, (*c)->base);
ccat(data, '\n');
c++;
}
readstr(r, data);
respond(r, nil);
}
void read_slot(Req* r) {
UserInfo* u = find_user(users_table, r->fid->uid);
if (u == nil)
goto end;
if (u->cart == nil)
goto end;
readstr(r, u->cart->rom);
end:
respond(r, nil);
}
void read_data(Req* r, FileType t) {
UserInfo* u = find_user(users_table, r->fid->uid);
if (u->cart == nil)
goto end;
switch (t) {
case SPRITE_DATA:
readstr(r, u->cart->sprite_data);
break;
case AUDIO_DATA:
readstr(r, u->cart->audio_data);
break;
case TEXT_DATA:
readstr(r, u->cart->txt_data);
break;
}
end:
respond(r, nil);
}
void read_realms(Req* r) {
String** realms = list_dir(REALMSPATH);
String** rr = realms;
Realm* realm;
char data[4096] = {0};
int i, u, m, p;
char ubuf[8] = {0};
char mbuf[8] = {0};
char pbuf[2] = {0};
while (*rr != nil) {
scat(data, (*rr)->base);
ccat(data, ' ');
realm = parse_realm((*rr)->base);
m = realm->max;
p = realm->password ? 1 : 0;
for (i = u = 0; i < 64; i++) {
if (
users_table[i].realm != nil &&
scmp(users_table[i].realm->name, realm->name))
u++;
}
itoa(u, ubuf, 10);
scat(data, ubuf);
ccat(data, ' ');
itoa(m, mbuf, 10);
scat(data, mbuf);
ccat(data, ' ');
itoa(p, pbuf, 10);
scat(data, pbuf);
ccat(data, '\n');
rr++;
}
readstr(r, data);
respond(r, nil);
}
void xrxs_read(Req* r) {
Aux* a = r->fid->file->aux;
switch (a->type) {
case USERS:
read_users(r);
break;
case CARTS:
read_carts(r);
break;
case SLOT:
read_slot(r);
break;
case SPRITE_DATA:
case AUDIO_DATA:
case TEXT_DATA:
read_data(r, a->type);
break;
case REALMS:
read_realms(r);
break;
case UNIVERSE:
// read_universe(r);
break;
default:
respond(r, nil);
break;
}
}
void fs_destroy_file(File* f) {
Aux* a = f->aux;
if (a && a->data) {
free(a->data);
free(a);
} else if (a) {
free(a);
}
}
Srv fs = {.attach = xrxs_attach, .read = xrxs_read, .write = xrxs_write};
int threadmaybackground(void) { return 1; }
@ -314,7 +376,6 @@ void threadmain(int argc, char* argv[]) {
char* mtpt = nil;
char* usocket = nil;
int i;
String** cart;
/* if -h CMD is given, print the hash value of CMD */
if (argc == 3 && scmp(argv[1], "-h")) {
@ -348,16 +409,31 @@ void threadmain(int argc, char* argv[]) {
closefile(createfile(tree->root, "users", nil, 0400, create_aux(USERS)));
closefile(createfile(tree->root, "slot", nil, 0400, create_aux(SLOT)));
closefile(createfile(tree->root, "data", nil, DMDIR | 0500, nil));
closefile(createfile(
walkfile(tree->root, "data"),
"sprite",
nil,
0400,
create_aux(SPRITE_DATA)));
closefile(createfile(
walkfile(tree->root, "data"),
"audio",
nil,
0400,
create_aux(AUDIO_DATA)));
closefile(createfile(
walkfile(tree->root, "data"),
"text",
nil,
0400,
create_aux(TEXT_DATA)));
closefile(createfile(tree->root, "realms", nil, 0400, create_aux(REALMS)));
closefile(
createfile(tree->root, "universe", nil, 0600, create_aux(UNIVERSE)));
/*String** carts = listdir("carts/");
cart = carts;
while (*cart) {
// just concatenate the carts into a multiline string, and put it in
CARTS.data
}*/
closefile(createfile(
tree->root,
"universe",
nil,
DMAPPEND | 0600,
create_aux(UNIVERSE)));
if (argc >= 3) {
if (mtpt != nil && access(mtpt, AEXIST) < 0 && access(mtpt, AEXIST) < 0)