add config.h, ctl status codes, and delete realm command
This commit is contained in:
parent
e9839b1663
commit
4fab56e77f
12 changed files with 220 additions and 66 deletions
23
README.md
23
README.md
|
@ -8,16 +8,18 @@ The client is intended to be a specialized [uxn](https://wiki.xxiivv.com/site/ux
|
||||||
|
|
||||||
This is the working structure of the 9p filesystem:
|
This is the working structure of the 9p filesystem:
|
||||||
|
|
||||||
* `/ctl`: Write-only control file for inputing system commands
|
* `/ctl`: Read/write control file for inputing system commands. Reading the file shows the status of the last input command: 1 for success, 0 for failure; `logout` is a special case, and the status code will be -1 if it was succesful. the following are valid command syntax:
|
||||||
* `login PW`: Authenticate with `xrxs` -- password is hashed against realm password hash
|
* `login PW`: Authenticate with `xrxs` -- password is hashed against realm password hash.
|
||||||
* `load CART`: Load a cartridge
|
* `logout`: Gracefully remove yourself from the users table.
|
||||||
* `chunk TYPE N`: Load data of type TYPE and chunk number N
|
* `load CART`: Load a cartridge.
|
||||||
|
* `chunk TYPE N`: Load data of type TYPE and chunk number N.
|
||||||
* `create REALM`: Create a new realm (start a new game) -- must have a cartridge loaded
|
* `create REALM`: Create a new realm (start a new game) -- must have a cartridge loaded
|
||||||
* `protect PW`: Protect the curent realm with a password if you are the master.
|
* `protect PW`: Protect the curent realm with a password if you are the master.
|
||||||
* `transfer USER`: Transfer ownership of the realm to another user.
|
* `transfer USER`: Transfer ownership of the realm to another user.
|
||||||
* `enter REALM`: Join an existing realm
|
* `delete REALM`: Delete the realm off the server if you are the master and it is empty.
|
||||||
* `leave`: Leave the current realm
|
* `enter REALM`: Join an existing realm.
|
||||||
* `unload`: Unload the cartridge
|
* `leave`: Leave the current realm.
|
||||||
|
* `unload`: Unload the cartridge.
|
||||||
|
|
||||||
* `/users`: Read-only; Self and others in the realm are readable from here, one per line. It contains only yourself before joining a realm. Your username on your machine is used as your username in `xrxs` -- if your name is taken, you will get an error on attaching.
|
* `/users`: Read-only; Self and others in the realm are readable from here, one per line. It contains only yourself before joining a realm. Your username on your machine is used as your username in `xrxs` -- if your name is taken, you will get an error on attaching.
|
||||||
|
|
||||||
|
@ -37,6 +39,13 @@ This is the working structure of the 9p filesystem:
|
||||||
|
|
||||||
* `/grandom`: Read-only, get a random number from 0 to 99 -- These are doled out on a per-realm basis, and the number stays the same until everyone in the realm has had a chance to read it. If you've already read it this round or aren't in a realm, it will be empty.
|
* `/grandom`: Read-only, get a random number from 0 to 99 -- These are doled out on a per-realm basis, and the number stays the same until everyone in the realm has had a chance to read it. If you've already read it this round or aren't in a realm, it will be empty.
|
||||||
|
|
||||||
|
## configuration
|
||||||
|
|
||||||
|
`config.h` in the source contains the following configuration macros:
|
||||||
|
|
||||||
|
* `MAX_USERS`: the maximum number of simultaneous users able to attach to the `xrxs` service
|
||||||
|
* `DATA_DIR`: the path to the root of the cartridge and realm storage; can be absolute or relative to the `xrxs` executable, but must have the trailing `/`
|
||||||
|
|
||||||
## realm format
|
## realm format
|
||||||
|
|
||||||
Each realm directory on the server should have the following files:
|
Each realm directory on the server should have the following files:
|
||||||
|
|
9
cart.c
9
cart.c
|
@ -1,18 +1,19 @@
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
|
#include "config.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "cart.h"
|
#include "cart.h"
|
||||||
|
|
||||||
Cart* create_cart(char* name) {
|
Cart* create_cart(char* name) {
|
||||||
char path[64] = {0};
|
char path[256] = {0};
|
||||||
char file[64] = {0};
|
char file[256] = {0};
|
||||||
Cart* cart;
|
Cart* cart;
|
||||||
Blob* cart_data;
|
Blob* cart_data;
|
||||||
|
|
||||||
scat(path, "carts/");
|
scat(path, DATA_DIR);
|
||||||
scat(path, name);
|
scat(path, name);
|
||||||
scpy(path, file, 64);
|
scpy(path, file, 256);
|
||||||
ccat(file, '/');
|
ccat(file, '/');
|
||||||
scat(file, name);
|
scat(file, name);
|
||||||
scat(file, ".rom");
|
scat(file, ".rom");
|
||||||
|
|
|
@ -5,6 +5,7 @@ typedef enum {
|
||||||
CREATE = 7083959236,
|
CREATE = 7083959236,
|
||||||
PROTECT = 295480618573,
|
PROTECT = 295480618573,
|
||||||
TRANSFER = 11311529048177,
|
TRANSFER = 11311529048177,
|
||||||
|
DELETE = 7129299147,
|
||||||
ENTER = 195024746,
|
ENTER = 195024746,
|
||||||
LEAVE = 207662601,
|
LEAVE = 207662601,
|
||||||
LOGOUT = 7702552890,
|
LOGOUT = 7702552890,
|
||||||
|
|
5
config.h
Normal file
5
config.h
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
/* Maximum number of users on the server */
|
||||||
|
#define MAX_USERS 64
|
||||||
|
|
||||||
|
/* Path to cart/realm storage (must include trailing slash) */
|
||||||
|
#define DATA_DIR "/home/nilix/src/xrxs/carts/"
|
25
realm.c
25
realm.c
|
@ -1,6 +1,7 @@
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "config.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "cart.h"
|
#include "cart.h"
|
||||||
|
@ -13,7 +14,7 @@ Realm* create_realm(UserInfo* table, char* uname, char* name) {
|
||||||
char cart[32];
|
char cart[32];
|
||||||
int max = 4;
|
int max = 4;
|
||||||
char* n = name;
|
char* n = name;
|
||||||
char path[128] = {0};
|
char path[256] = {0};
|
||||||
|
|
||||||
if (u == nil || u->cart == nil)
|
if (u == nil || u->cart == nil)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -28,7 +29,7 @@ Realm* create_realm(UserInfo* table, char* uname, char* name) {
|
||||||
max = atoi(n);
|
max = atoi(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
scat(path, "carts/");
|
scat(path, DATA_DIR);
|
||||||
scat(path, cart);
|
scat(path, cart);
|
||||||
scat(path, "/realms/");
|
scat(path, "/realms/");
|
||||||
if (open(path, OREAD) < 0)
|
if (open(path, OREAD) < 0)
|
||||||
|
@ -55,14 +56,14 @@ Realm* create_realm(UserInfo* table, char* uname, char* name) {
|
||||||
Realm* parse_realm(char* cart, char* name) {
|
Realm* parse_realm(char* cart, char* name) {
|
||||||
Realm* self;
|
Realm* self;
|
||||||
FILE* f;
|
FILE* f;
|
||||||
char path[128] = {0};
|
char path[256] = {0};
|
||||||
char file[128] = {0};
|
char file[256] = {0};
|
||||||
char buf[256] = {0};
|
char buf[256] = {0};
|
||||||
scat(path, "carts/");
|
scat(path, DATA_DIR);
|
||||||
scat(path, cart);
|
scat(path, cart);
|
||||||
scat(path, "/realms/");
|
scat(path, "/realms/");
|
||||||
scat(path, name);
|
scat(path, name);
|
||||||
scpy(path, file, 128);
|
scpy(path, file, 256);
|
||||||
|
|
||||||
scat(file, "/realm");
|
scat(file, "/realm");
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ Realm* parse_realm(char* cart, char* name) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
scpy(path, file, 128);
|
scpy(path, file, 256);
|
||||||
scat(file, "/universe");
|
scat(file, "/universe");
|
||||||
self->universe = parse_universe(cart, name);
|
self->universe = parse_universe(cart, name);
|
||||||
return self;
|
return self;
|
||||||
|
@ -95,7 +96,7 @@ Realm* find_realm(UserInfo* table, char* name) {
|
||||||
UserInfo* u = table;
|
UserInfo* u = table;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < MAX_USERS; i++) {
|
||||||
if (slen(u->name) > 0 && u->realm != nil && scmp(u->realm->name, name))
|
if (slen(u->name) > 0 && u->realm != nil && scmp(u->realm->name, name))
|
||||||
return u->realm;
|
return u->realm;
|
||||||
u++;
|
u++;
|
||||||
|
@ -105,13 +106,13 @@ Realm* find_realm(UserInfo* table, char* name) {
|
||||||
|
|
||||||
void save_realm(char* cart, Realm* self) {
|
void save_realm(char* cart, Realm* self) {
|
||||||
FILE* f;
|
FILE* f;
|
||||||
char path[128] = {0};
|
char path[256] = {0};
|
||||||
char file[128] = {0};
|
char file[256] = {0};
|
||||||
scat(path, "carts/");
|
scat(path, DATA_DIR);
|
||||||
scat(path, cart);
|
scat(path, cart);
|
||||||
scat(path, "/realms/");
|
scat(path, "/realms/");
|
||||||
scat(path, self->name);
|
scat(path, self->name);
|
||||||
scpy(path, file, 128);
|
scpy(path, file, 256);
|
||||||
|
|
||||||
scat(file, "/realm");
|
scat(file, "/realm");
|
||||||
f = fopen(file, "w");
|
f = fopen(file, "w");
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "config.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "universe.h"
|
#include "universe.h"
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ Universe* create_universe() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Universe* parse_universe(char* cart, char* realm_name) {
|
Universe* parse_universe(char* cart, char* realm_name) {
|
||||||
char path[64] = {0};
|
char path[256] = {0};
|
||||||
char buf[256] = {0};
|
char buf[256] = {0};
|
||||||
char name[16] = {0};
|
char name[16] = {0};
|
||||||
char value[64] = {0};
|
char value[64] = {0};
|
||||||
|
@ -22,7 +23,7 @@ Universe* parse_universe(char* cart, char* realm_name) {
|
||||||
Atom* a;
|
Atom* a;
|
||||||
Universe* self;
|
Universe* self;
|
||||||
|
|
||||||
scat(path, "carts/");
|
scat(path, DATA_DIR);
|
||||||
scat(path, cart);
|
scat(path, cart);
|
||||||
scat(path, "/realms/");
|
scat(path, "/realms/");
|
||||||
scat(path, realm_name);
|
scat(path, realm_name);
|
||||||
|
@ -52,12 +53,12 @@ Universe* parse_universe(char* cart, char* realm_name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_universe(char* cart, Universe* self, char* realm_name) {
|
void save_universe(char* cart, Universe* self, char* realm_name) {
|
||||||
char path[64] = {0};
|
char path[256] = {0};
|
||||||
FILE* f;
|
FILE* f;
|
||||||
Atom* a;
|
Atom* a;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
scat(path, "carts/");
|
scat(path, DATA_DIR);
|
||||||
scat(path, cart);
|
scat(path, cart);
|
||||||
scat(path, "/realms/");
|
scat(path, "/realms/");
|
||||||
scat(path, realm_name);
|
scat(path, realm_name);
|
||||||
|
|
|
@ -4,7 +4,7 @@ typedef struct Atom Atom;
|
||||||
|
|
||||||
struct Atom {
|
struct Atom {
|
||||||
char name[16];
|
char name[16];
|
||||||
char value[64];
|
char value[MAX_USERS];
|
||||||
Atom* next;
|
Atom* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
61
user.c
61
user.c
|
@ -1,6 +1,8 @@
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "config.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "cart.h"
|
#include "cart.h"
|
||||||
#include "realm.h"
|
#include "realm.h"
|
||||||
|
@ -11,7 +13,7 @@ extern UserInfo users_table[64];
|
||||||
UserInfo* find_user(UserInfo* table, char* uname) {
|
UserInfo* find_user(UserInfo* table, char* uname) {
|
||||||
UserInfo* u = table;
|
UserInfo* u = table;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < MAX_USERS; i++) {
|
||||||
if (scmp(uname, u->name))
|
if (scmp(uname, u->name))
|
||||||
return u;
|
return u;
|
||||||
u++;
|
u++;
|
||||||
|
@ -19,6 +21,13 @@ UserInfo* find_user(UserInfo* table, char* uname) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int* ctl_code_handle(UserInfo* table, char* uname) {
|
||||||
|
UserInfo* u = find_user(table, uname);
|
||||||
|
if (u != nil)
|
||||||
|
return &(u->ctl_code);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
int login(UserInfo* table, char* uname, char* password) {
|
int login(UserInfo* table, char* uname, char* password) {
|
||||||
UserInfo* u = find_user(table, uname);
|
UserInfo* u = find_user(table, uname);
|
||||||
|
|
||||||
|
@ -43,7 +52,7 @@ int logout(UserInfo* table, char* uname) {
|
||||||
u->scope = nil;
|
u->scope = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
u->random = 0;
|
u->random = -1;
|
||||||
|
|
||||||
if (u->realm != nil)
|
if (u->realm != nil)
|
||||||
leave_realm(table, uname);
|
leave_realm(table, uname);
|
||||||
|
@ -104,8 +113,7 @@ int enter_realm(UserInfo* table, char* uname, char* realm_name) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < MAX_USERS; i++) {
|
||||||
fprintf(stderr, "iterating through users table: slot %d\n", i);
|
|
||||||
if (table[i].realm != nil && scmp(table[i].realm->name, realm_name))
|
if (table[i].realm != nil && scmp(table[i].realm->name, realm_name))
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
@ -163,3 +171,48 @@ int unload_cart(UserInfo* table, char* uname) {
|
||||||
u->cart = nil;
|
u->cart = nil;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int delete_realm(UserInfo* table, char* uname, char* realm) {
|
||||||
|
UserInfo* u = find_user(table, uname);
|
||||||
|
char path[256] = {0};
|
||||||
|
char file[256] = {0};
|
||||||
|
Blob* realm_data;
|
||||||
|
char garbage[32] = {0};
|
||||||
|
char master[32] = {0};
|
||||||
|
int i;
|
||||||
|
if (u == nil || u->cart == nil) {
|
||||||
|
fprintf(stderr, "no user/cart\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_USERS; i++) {
|
||||||
|
if (table[i].realm != nil && scmp(table[i].realm->name, realm)) {
|
||||||
|
fprintf(stderr, "realm not empty\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scat(path, DATA_DIR);
|
||||||
|
scat(path, u->cart->name);
|
||||||
|
scat(path, "/realms/");
|
||||||
|
scat(path, realm);
|
||||||
|
scpy(path, file, 256);
|
||||||
|
ccat(file, '/');
|
||||||
|
scat(file, "realm");
|
||||||
|
|
||||||
|
fprintf(stderr, "%s\n", file);
|
||||||
|
realm_data = read_chars(file);
|
||||||
|
if (realm_data == nil)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
sscanf(
|
||||||
|
realm_data->data,
|
||||||
|
"%u %32s %llu",
|
||||||
|
(uint*)garbage,
|
||||||
|
master,
|
||||||
|
(uvlong*)garbage);
|
||||||
|
if (scmp(master, uname) && rm_dir(path))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
3
user.h
3
user.h
|
@ -7,9 +7,11 @@ typedef struct UserInfo {
|
||||||
Realm* realm;
|
Realm* realm;
|
||||||
char* scope;
|
char* scope;
|
||||||
int random;
|
int random;
|
||||||
|
int ctl_code;
|
||||||
} UserInfo;
|
} UserInfo;
|
||||||
|
|
||||||
UserInfo* find_user(UserInfo* table, char* uname);
|
UserInfo* find_user(UserInfo* table, char* uname);
|
||||||
|
int* ctl_code_handle(UserInfo* table, char* uname);
|
||||||
int login(UserInfo* table, char* uname, char* password);
|
int login(UserInfo* table, char* uname, char* password);
|
||||||
int logout(UserInfo* table, char* uname);
|
int logout(UserInfo* table, char* uname);
|
||||||
int protect_realm(UserInfo* table, char* uname, char* password);
|
int protect_realm(UserInfo* table, char* uname, char* password);
|
||||||
|
@ -18,3 +20,4 @@ int load_cart(UserInfo* table, char* uname, char* cart_name);
|
||||||
int enter_realm(UserInfo* table, char* uname, char* realm_name);
|
int enter_realm(UserInfo* table, char* uname, char* realm_name);
|
||||||
int leave_realm(UserInfo* table, char* uname);
|
int leave_realm(UserInfo* table, char* uname);
|
||||||
int unload_cart(UserInfo* table, char* uname);
|
int unload_cart(UserInfo* table, char* uname);
|
||||||
|
int delete_realm(UserInfo* table, char* uname, char* realm);
|
54
util.c
54
util.c
|
@ -1,4 +1,5 @@
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "cart.h"
|
#include "cart.h"
|
||||||
|
@ -149,6 +150,59 @@ Blob* read_chars(char* path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int issymlink(char* name) {
|
||||||
|
struct stat s;
|
||||||
|
return lstat(name, &s) >= 0 && S_ISLNK(s.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rm_dir(char* f) {
|
||||||
|
char* name;
|
||||||
|
int fd, i, j, n, ndir, nname;
|
||||||
|
Dir* dirbuf;
|
||||||
|
int fail = 0;
|
||||||
|
|
||||||
|
fd = open(f, OREAD);
|
||||||
|
if (fd < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
n = dirreadall(fd, &dirbuf);
|
||||||
|
close(fd);
|
||||||
|
if (n < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nname = strlen(f) + 1 + STATMAX + 1; /* plenty! */
|
||||||
|
name = malloc(nname);
|
||||||
|
if (name == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ndir = 0;
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
snprint(name, nname, "%s/%s", f, dirbuf[i].name);
|
||||||
|
if (remove(name) != -1 || issymlink(name))
|
||||||
|
dirbuf[i].qid.type = QTFILE; /* so we won't recurse */
|
||||||
|
else {
|
||||||
|
if (dirbuf[i].qid.type & QTDIR)
|
||||||
|
ndir++;
|
||||||
|
else
|
||||||
|
fail = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ndir)
|
||||||
|
for (j = 0; j < n; j++)
|
||||||
|
if (dirbuf[j].qid.type & QTDIR) {
|
||||||
|
snprint(name, nname, "%s/%s", f, dirbuf[j].name);
|
||||||
|
rmdir(name);
|
||||||
|
}
|
||||||
|
if (remove(f) == -1)
|
||||||
|
fail = 1;
|
||||||
|
|
||||||
|
free(name);
|
||||||
|
free(dirbuf);
|
||||||
|
return fail ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
void strreverse(char* begin, char* end) {
|
void strreverse(char* begin, char* end) {
|
||||||
|
|
||||||
char aux;
|
char aux;
|
||||||
|
|
1
util.h
1
util.h
|
@ -17,3 +17,4 @@ char* ccat(char* dst, char c);
|
||||||
Blob* read_bytes(char* path);
|
Blob* read_bytes(char* path);
|
||||||
Blob* read_chars(char* path);
|
Blob* read_chars(char* path);
|
||||||
void itoa(int, char*, int);
|
void itoa(int, char*, int);
|
||||||
|
int rm_dir(char* path);
|
91
xrxs.c
91
xrxs.c
|
@ -7,6 +7,7 @@
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <libString.h>
|
#include <libString.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "config.h"
|
||||||
#include "err.h"
|
#include "err.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -16,14 +17,11 @@
|
||||||
#include "realm.h"
|
#include "realm.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
||||||
#define CARTSPATH "./carts"
|
|
||||||
#define REALMSPATH "./realms"
|
|
||||||
|
|
||||||
int chatty9p = 1;
|
int chatty9p = 1;
|
||||||
|
|
||||||
static Tree* tree;
|
static Tree* tree;
|
||||||
|
|
||||||
static UserInfo users_table[64];
|
static UserInfo users_table[MAX_USERS];
|
||||||
|
|
||||||
void xrxs_attach(Req* r) {
|
void xrxs_attach(Req* r) {
|
||||||
/* As it is, once the user detaches, they will stay in the table
|
/* As it is, once the user detaches, they will stay in the table
|
||||||
|
@ -36,7 +34,7 @@ void xrxs_attach(Req* r) {
|
||||||
char* usr;
|
char* usr;
|
||||||
char* username = r->ifcall.uname;
|
char* username = r->ifcall.uname;
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < MAX_USERS; i++) {
|
||||||
usr = users_table[i].name;
|
usr = users_table[i].name;
|
||||||
if (scmp(usr, username)) {
|
if (scmp(usr, username)) {
|
||||||
respond(r, EUNAME);
|
respond(r, EUNAME);
|
||||||
|
@ -44,6 +42,7 @@ void xrxs_attach(Req* r) {
|
||||||
}
|
}
|
||||||
if (*usr == 0) {
|
if (*usr == 0) {
|
||||||
scpy(username, usr, 32);
|
scpy(username, usr, 32);
|
||||||
|
users_table[i].random = -1;
|
||||||
vacancy = 1;
|
vacancy = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -59,6 +58,7 @@ void write_ctl(Req* r) {
|
||||||
char cmd[16] = {0};
|
char cmd[16] = {0};
|
||||||
char* c = r->ifcall.data;
|
char* c = r->ifcall.data;
|
||||||
int i;
|
int i;
|
||||||
|
int* code = ctl_code_handle(users_table, r->fid->uid);
|
||||||
|
|
||||||
for (i = 0; i < r->ifcall.count && *c != ' ' && *c != '\n'; i++) {
|
for (i = 0; i < r->ifcall.count && *c != ' ' && *c != '\n'; i++) {
|
||||||
ccat(cmd, *c++);
|
ccat(cmd, *c++);
|
||||||
|
@ -71,28 +71,31 @@ void write_ctl(Req* r) {
|
||||||
uvlong const cmd_hashv = hash(cmd, 0);
|
uvlong const cmd_hashv = hash(cmd, 0);
|
||||||
switch (cmd_hashv) {
|
switch (cmd_hashv) {
|
||||||
case LOGIN:
|
case LOGIN:
|
||||||
login(users_table, r->fid->uid, c);
|
*code = login(users_table, r->fid->uid, c);
|
||||||
break;
|
break;
|
||||||
case LOAD:
|
case LOAD:
|
||||||
load_cart(users_table, r->fid->uid, c);
|
*code = load_cart(users_table, r->fid->uid, c);
|
||||||
break;
|
break;
|
||||||
case CHUNK:
|
case CHUNK:
|
||||||
get_chunk(users_table, r->fid->uid, c);
|
*code = get_chunk(users_table, r->fid->uid, c);
|
||||||
break;
|
break;
|
||||||
case CREATE:
|
case CREATE:
|
||||||
create_realm(users_table, r->fid->uid, c);
|
*code = create_realm(users_table, r->fid->uid, c) != nil ? 1 : 0;
|
||||||
break;
|
break;
|
||||||
case PROTECT:
|
case PROTECT:
|
||||||
protect_realm(users_table, r->fid->uid, c);
|
*code = protect_realm(users_table, r->fid->uid, c);
|
||||||
break;
|
break;
|
||||||
case TRANSFER:
|
case TRANSFER:
|
||||||
transfer_realm(users_table, r->fid->uid, c);
|
*code = transfer_realm(users_table, r->fid->uid, c);
|
||||||
|
break;
|
||||||
|
case DELETE:
|
||||||
|
*code = delete_realm(users_table, r->fid->uid, c);
|
||||||
break;
|
break;
|
||||||
case ENTER:
|
case ENTER:
|
||||||
enter_realm(users_table, r->fid->uid, c);
|
*code = enter_realm(users_table, r->fid->uid, c);
|
||||||
break;
|
break;
|
||||||
case LEAVE:
|
case LEAVE:
|
||||||
leave_realm(users_table, r->fid->uid);
|
*code = leave_realm(users_table, r->fid->uid);
|
||||||
break;
|
break;
|
||||||
case LOGOUT:
|
case LOGOUT:
|
||||||
logout(users_table, r->fid->uid);
|
logout(users_table, r->fid->uid);
|
||||||
|
@ -104,7 +107,7 @@ void write_ctl(Req* r) {
|
||||||
// reset(r->fid->uid);
|
// reset(r->fid->uid);
|
||||||
break;
|
break;
|
||||||
case UNLOAD:
|
case UNLOAD:
|
||||||
unload_cart(users_table, r->fid->uid);
|
*code = unload_cart(users_table, r->fid->uid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
r->ofcall.count = r->ifcall.count;
|
r->ofcall.count = r->ifcall.count;
|
||||||
|
@ -189,26 +192,27 @@ void xrxs_write(Req* r) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_users(Req* r) {
|
void read_users(Req* r) {
|
||||||
char buf[2113] = {0};
|
String* data = s_new();
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < MAX_USERS; i++) {
|
||||||
if (scmp(users_table[i].name, r->fid->uid)) {
|
if (scmp(users_table[i].name, r->fid->uid)) {
|
||||||
scat(buf, users_table[i].name);
|
s_append(data, users_table[i].name);
|
||||||
ccat(buf, '\n');
|
s_putc(data, '\n');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < MAX_USERS; i++) {
|
||||||
if (
|
if (
|
||||||
scmp(users_table[i].name, "\0") ||
|
scmp(users_table[i].name, "\0") ||
|
||||||
scmp(users_table[i].name, r->fid->uid)) {
|
scmp(users_table[i].name, r->fid->uid)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
scat(buf, users_table[i].name);
|
s_append(data, users_table[i].name);
|
||||||
ccat(buf, '\n');
|
s_putc(data, '\n');
|
||||||
}
|
}
|
||||||
ccat(buf, 0);
|
s_terminate(data);
|
||||||
readstr(r, buf);
|
readstr(r, data->base);
|
||||||
|
s_free(data);
|
||||||
respond(r, nil);
|
respond(r, nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,8 +254,24 @@ void s_freemany(String** ss) {
|
||||||
free(ss);
|
free(ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void read_ctl(Req* r) {
|
||||||
|
int* code = ctl_code_handle(users_table, r->fid->uid);
|
||||||
|
char buf[8] = {0};
|
||||||
|
if (code != nil) {
|
||||||
|
if (*code) {
|
||||||
|
strcat(buf, "1\n");
|
||||||
|
} else {
|
||||||
|
strcat(buf, "0\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
strcat(buf, "-1\n");
|
||||||
|
}
|
||||||
|
readstr(r, buf);
|
||||||
|
respond(r, nil);
|
||||||
|
}
|
||||||
|
|
||||||
void read_carts(Req* r) {
|
void read_carts(Req* r) {
|
||||||
String** carts = list_dir(CARTSPATH);
|
String** carts = list_dir(DATA_DIR);
|
||||||
String** c = carts;
|
String** c = carts;
|
||||||
String* data = s_new();
|
String* data = s_new();
|
||||||
while (*c != nil) {
|
while (*c != nil) {
|
||||||
|
@ -318,7 +338,7 @@ end:
|
||||||
|
|
||||||
void read_realms(Req* r) {
|
void read_realms(Req* r) {
|
||||||
UserInfo* user = find_user(users_table, r->fid->uid);
|
UserInfo* user = find_user(users_table, r->fid->uid);
|
||||||
char realm_path[128] = {0};
|
char realm_path[256] = {0};
|
||||||
String** realms;
|
String** realms;
|
||||||
String** rr;
|
String** rr;
|
||||||
Realm* realm;
|
Realm* realm;
|
||||||
|
@ -346,7 +366,7 @@ void read_realms(Req* r) {
|
||||||
m = realm->max;
|
m = realm->max;
|
||||||
p = realm->password ? 1 : 0;
|
p = realm->password ? 1 : 0;
|
||||||
|
|
||||||
for (i = u = 0; i < 64; i++) {
|
for (i = u = 0; i < MAX_USERS; i++) {
|
||||||
if (
|
if (
|
||||||
users_table[i].realm != nil &&
|
users_table[i].realm != nil &&
|
||||||
scmp(users_table[i].realm->name, realm->name))
|
scmp(users_table[i].realm->name, realm->name))
|
||||||
|
@ -463,22 +483,24 @@ void read_grandom(Req* r) {
|
||||||
int reset = 1;
|
int reset = 1;
|
||||||
int random;
|
int random;
|
||||||
UserInfo* u = find_user(users_table, r->fid->uid);
|
UserInfo* u = find_user(users_table, r->fid->uid);
|
||||||
UserInfo** usrs = malloc(64 * sizeof(UserInfo*));
|
UserInfo** usrs = malloc(MAX_USERS * sizeof(UserInfo*));
|
||||||
UserInfo* p = users_table;
|
UserInfo* p = users_table;
|
||||||
UserInfo** uu = usrs;
|
UserInfo** uu = usrs;
|
||||||
|
|
||||||
if (u->realm == nil)
|
if (u->realm == nil) {
|
||||||
|
respond(r, nil);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < MAX_USERS; i++) {
|
||||||
if (scmp(p->realm->name, u->realm->name)) {
|
if (scmp(p->realm->name, u->realm->name)) {
|
||||||
*uu++ = p;
|
*uu++ = p;
|
||||||
if (i < 64)
|
if (i < MAX_USERS - 1)
|
||||||
*uu = nil;
|
*uu = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uu = usrs;
|
uu = usrs;
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < MAX_USERS; i++) {
|
||||||
if ((*uu) != nil && (*uu)->random >= 0) {
|
if ((*uu) != nil && (*uu)->random >= 0) {
|
||||||
reset = 0;
|
reset = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -489,7 +511,7 @@ void read_grandom(Req* r) {
|
||||||
srand(rand());
|
srand(rand());
|
||||||
random = rand() % 100;
|
random = rand() % 100;
|
||||||
uu = usrs;
|
uu = usrs;
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < MAX_USERS; i++) {
|
||||||
if ((*uu) != nil) {
|
if ((*uu) != nil) {
|
||||||
(*uu)->random = random;
|
(*uu)->random = random;
|
||||||
}
|
}
|
||||||
|
@ -505,6 +527,9 @@ void read_grandom(Req* r) {
|
||||||
void xrxs_read(Req* r) {
|
void xrxs_read(Req* r) {
|
||||||
Aux* a = r->fid->file->aux;
|
Aux* a = r->fid->file->aux;
|
||||||
switch (a->type) {
|
switch (a->type) {
|
||||||
|
case CTL:
|
||||||
|
read_ctl(r);
|
||||||
|
break;
|
||||||
case USERS:
|
case USERS:
|
||||||
read_users(r);
|
read_users(r);
|
||||||
break;
|
break;
|
||||||
|
@ -586,7 +611,7 @@ void threadmain(int argc, char* argv[]) {
|
||||||
tree = fs.tree;
|
tree = fs.tree;
|
||||||
|
|
||||||
closefile(
|
closefile(
|
||||||
createfile(tree->root, "ctl", nil, DMAPPEND | 0300, create_aux(CTL)));
|
createfile(tree->root, "ctl", nil, DMAPPEND | 0600, create_aux(CTL)));
|
||||||
closefile(createfile(tree->root, "carts", nil, 0400, create_aux(CARTS)));
|
closefile(createfile(tree->root, "carts", nil, 0400, create_aux(CARTS)));
|
||||||
closefile(createfile(tree->root, "users", nil, 0400, create_aux(USERS)));
|
closefile(createfile(tree->root, "users", nil, 0400, create_aux(USERS)));
|
||||||
closefile(createfile(tree->root, "slot", nil, 0400, create_aux(SLOT)));
|
closefile(createfile(tree->root, "slot", nil, 0400, create_aux(SLOT)));
|
||||||
|
|
Loading…
Reference in a new issue