all repos — xrxs @ c8ba412121282b7e4d51126b5da615d75b7faf1a

experimental networked application/game server with 9p

use libString insead of static character arrays where useful, added some data structure stuff for realm master, random, and scope
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAmD3R0UACgkQO3+8IhRO
Y5iFiQ//TGkXRVpk0HCXXk4N7CGh8BbrjqHY6G4TUdby2rHmXz9TU/7WN1LTI5eS
bMIZKr7nV21elIaHkjN5PUe9v4NwMz62cyvCQDiVlDsKdNVR+cnJYnKUKNqIJTmJ
mL364zEaap1B8Aur522iwwH2GdxpICNJZuQc1vYTglHheLQGIqWtd7RpngbzpNhg
kN2kPxbfwgpYrEMq0yyQ0GZRM2wvHTROsVNsScKLRCjXW6Rhvqvs5+6bd3TfGqMP
hc5JHKMrOZhJixPg0naHCAFfG7JiUkDbhsQBCXdUG66ZLo+q+GHknMLCb3QPEHMF
sO83zWDF18p3s4wkt1SI7BijFuUErgbCmm+os8ugmQYJOS3s8Cif7x2WvTJoxH9X
kXiA4d370D29sYxQsunCGprgKAIu7u4TqeG67JWioY30D5d88xYb1mTOb70hS47X
9DVLfJHlmn02/M69x3rXrw6m0F4FXH2iB54aMGYvWSG2i7TEEjxhvnlR3dFnCh+L
KvgJwapZWgdCMeRot9i7pCP/VrIv1PFAAevDu75TAhWL9tNZKhB//AeSadlb20tC
h+rtsbXXzMAgaTAfGOhj+3PU4B/i03WnaBmAGF7DZW9mjroxTc90Gc3E/IJbAfgP
jKvSn5ub75vJcRAXxCb2PBHnkCA1AcU/KkHOFL3jDy9RIuZZ7eE=
=eirs
-----END PGP SIGNATURE-----
commit

c8ba412121282b7e4d51126b5da615d75b7faf1a

parent

4430d607d6be9d3423626f6eaef27621e2d418ea

6 files changed, 99 insertions(+), 23 deletions(-)

jump to
M README.mdREADME.md

@@ -13,7 +13,8 @@ * `login PW`: Authenticate with `xrxs` -- password is hashed against realm password hash

* `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 - * `protect REALM PW`: Protect the realm with a password if not already. + * `protect PW`: Protect the curent realm with a password if you are the master. + * `transfer USER`: Transfer ownership of the realm to another user. * `enter REALM`: Join an existing realm * `leave`: Leave the current realm * `unload`: Unload the cartridge

@@ -40,7 +41,7 @@ ## realm format

Each realm directory on the server should have the following files: - * `realm`: Basic data for the realm, file should contain only the maximum number of members, and the password hash, if any, separated by a space - * `universe`: The actual game state in for the realm, key value pairs, one per line, as `KEY = VALUE`; limit 15 characters for keys, 63 for values. + * `realm`: Basic data for the realm, file should contain only the maximum number of members, the master's name, and the password hash, if any (otherwise 0), separated by spaces. + * `universe`: The actual game state for the realm as key value pairs, one per line, like `KEY = VALUE`; limit 15 characters for keys, 63 for values. The realm should be synchronized to disc when realm membership, limit, or password change. Fenagling some periodic autosave should be possible...
M command.hcommand.h

@@ -1,8 +1,10 @@

typedef enum { LOGIN = 208176873, LOAD = 5626172, + CHUNK = 190974201, CREATE = 7083959236, PROTECT = 295480618573, + TRANSFER = 11311529048177, ENTER = 195024746, LEAVE = 207662601, LOGOUT = 7702552890,
M realm.crealm.c

@@ -45,6 +45,7 @@ scpy(name, self->name, 32);

self->max = max; self->password = 0; self->universe = create_universe(); + scpy(uname, self->master, 32); save_realm(cart, self); fprintf(stderr, "created realm '%s'\n", name); return self;

@@ -68,7 +69,7 @@ f = fopen(file, "r");

if (f != nil) { if (fgets(buf, 256, f)) { self = malloc(sizeof(Realm)); - sscanf(buf, "%hu %llu", &(self->max), &(self->password)); + sscanf(buf, "%hu %32s %llu", &(self->max), self->master, &(self->password)); fclose(f); } else { return nil;

@@ -108,7 +109,7 @@

scat(file, "/realm"); f = fopen(file, "w"); if (f != nil) { - fprintf(f, "%hu %llu", self->max, self->password); + fprintf(f, "%hu %s, %llu", self->max, self->master, self->password); fclose(f); save_universe(cart, self->universe, self->name); fprintf(stderr, "saved realm data");
M realm.hrealm.h

@@ -3,12 +3,13 @@ typedef struct UserInfo UserInfo;

typedef struct Realm { char name[32]; + char master[32]; ushort max; uvlong password; Universe* universe; } Realm; -Realm* create_realm(UserInfo* table, char* cart, char* name); +Realm* create_realm(UserInfo* table, char* uname, char* name); Realm* parse_realm(char* cart, char* name); Realm* find_realm(UserInfo* table, char* name); void save_realm(char* cart, Realm* self);
M user.huser.h

@@ -5,6 +5,8 @@ char name[32];

uvlong password; Cart* cart; Realm* realm; + char* scope; + int random; } UserInfo; UserInfo* find_user(UserInfo* table, char* uname);
M xrxs.cxrxs.c

@@ -77,6 +77,11 @@ for (i = 0; i < 64; i++) {

if (scmp(uname, u->name)) { *(u->name) = 0; u->password = 0; + if (u->scope != nil) { + free(u->scope); + u->scope = nil; + } + u->random = 0; if (u->realm != nil) leave_realm(users_table, uname); if (u->cart != nil)

@@ -91,7 +96,7 @@

void protect(char* uname, char* password) { UserInfo* u = find_user(users_table, uname); - if (u != nil && u->realm != nil) { + if (u != nil && u->realm != nil && scmp(uname, u->realm->master)) { u->realm->password = hash(password, 0); } }

@@ -117,12 +122,17 @@ break;

case LOAD: load_cart(users_table, r->fid->uid, c); break; + case CHUNK: + // get_chunk(users_table, r->fid->uid, c); + break; case CREATE: create_realm(users_table, r->fid->uid, c); break; case PROTECT: protect(r->fid->uid, c); break; + case TRANSFER: + // transfer(r->fid->uid, c); case ENTER: enter_realm(users_table, r->fid->uid, c); break;

@@ -222,13 +232,18 @@ respond(r, nil);

} String** list_dir(char* path) { - String** self = malloc(128 * sizeof(String*)); + int size = 128; + String** self = malloc(size * sizeof(String*)); DIR* dir; struct dirent* ent; int i = 0; char* c; if ((dir = opendir(path)) != NULL) { while ((ent = readdir(dir)) != NULL) { + if (i = size) { + size *= 2; + self = reallloc(self, size * sizeof(String*)); + } c = ent->d_name; if (scmp(c, ".") || scmp(c, "..")) { continue;

@@ -246,17 +261,38 @@ self[i] = nil;

return self; } +void s_freemany(String** ss) { + int i; + String** s = ss; + for (i = 0; i < 128; i++) { + if (*s != nil) { + s_free(*s); + } + } + free(ss); +} + +String* s_putmanyc(String* s, char* c) { + String* tmp = s_copy(c); + s_append(s, tmp); + s_free(tmp); + return s; +} + void read_carts(Req* r) { String** carts = list_dir(CARTSPATH); String** c = carts; - char data[4096] = {0}; + string* data = s_new(); while (*c != nil) { - scat(data, (*c)->base); - ccat(data, '\n'); + s_append(data, *c); + s_putc(data, '\n'); c++; } - readstr(r, data); + s_terminate(data); + readstr(r, data->base); respond(r, nil); + s_free(data); + s_freemany(carts); } void read_slot(Req* r) {

@@ -299,7 +335,7 @@ char realm_path[128] = {0};

String** realms; String** rr; Realm* realm; - char data[4096] = {0}; + String* data = s_new(); int i, u, m, p; char ubuf[8] = {0}; char mbuf[8] = {0};

@@ -316,8 +352,8 @@ realms = list_dir(realm_path);

rr = realms; while (*rr != nil) { - scat(data, (*rr)->base); - ccat(data, ' '); + s_append(data, *rr); + s_putc(data, ' '); realm = parse_realm(user->cart->name, (*rr)->base); m = realm->max;

@@ -330,18 +366,51 @@ scmp(users_table[i].realm->name, realm->name))

u++; } itoa(u, ubuf, 10); - scat(data, ubuf); - ccat(data, ' '); + s_putmanyc(data, ubuf); + s_putc(data, ' '); itoa(m, mbuf, 10); - scat(data, mbuf); - ccat(data, ' '); + s_putmanyc(data, mbuf); + s_putc(data, ' '); itoa(p, pbuf, 10); - scat(data, pbuf); - ccat(data, '\n'); + s_putmanyc(data, pbuf); + s_putc(data, '\n'); rr++; } - readstr(r, data); + s_terminate(data); + readstr(r, data->base); + respond(r, nil); + s_free(data); + s_freemany(realms); +} + +void read_universe(Req* r) { + char* uname = r->fid->uid; + UserInfo* u = find_user(users_table, uname); + String* data = s_new(); + Universe* universe; + Atom* a; + int i; + + if (u == nil || u->realm == nil) { + respond(r, nil); + return; + } + + universe = u->realm->universe; + for (i = 0; i < 256; i++) { + a = universe[i]; + while (a != nil) { + s_putmanyc(data, a->name); + s_putmanyc(data, " = "); + s_putmanyc(data, a->value); + s_putc(data, '\n'); + a = a->next; + } + } + s_terminate(data); + readstr(r, data->base); respond(r, nil); + s_free(data); } void xrxs_read(Req* r) {

@@ -365,7 +434,7 @@ case REALMS:

read_realms(r); break; case UNIVERSE: - // read_universe(r); + read_universe(r); break; case SCOPE: // read_scope(r);