logins:  logtab[].name	- who you are
		 .ptr	- where you are in vm
		 .size	- size of record
		 .flags - stuff of interest for searching
#define LOG_SYSTEM	0x01			// a systems record
#define	LOG_USER	0x02			// a user record
#define LOG_INUSE	(LOG_SYSTEM|LOG_USER)	// record is being used
#define	LOG_ACTIVE	0x04			// session established

(200 people; 200*(8+4+2+2 == 16 bytes) == 3200 bytes)

rooms:   roomtab[].name	- what it is
		  .ptr	- where it is
		  .size	- size of record
		  .flags - stuff of interest for searching
#define	ROOM_INUSE	0x01			// room is active
(200 rooms; 200*(40+4+2+2 == 48 bytes) == 9600 bytes)

superblock() - vaddr 4:
userptr: 4
usersize: 2
roomptr: 4
roomsize: 2
modified: 8

synchtab()
{
    vread(0x04, &superblock, sizeof superblock);

    if (superblock.modified != lastmodtime) {
	free(rooms);
	free(users);
	rooms = xmalloc(sizeof rooms[0] * superblock.roomsize);
	users = xmalloc(sizeof users[0] * superblock.usersize);

	vread(superblock.roomptr, rooms, sizeof rooms[0] * superblock.roomsize);
	vread(superblock.userptr, users, sizeof users[0] * superblock.usersize);

	lastmodtime = superblock.modified;
    }
}


/* do an operation on a user, or just acknowledge her existance
 */
withuser(name, flags, op)
char *name;
int (*op)();
{
    register i, st;

    if (op)
	lock();
    synchtab();
    for (i=0; i<superblock.usersize; i++)
	if ((users[i].flags & flags) && strcmp(users[i].name, name)
	    break;

    if (op && i < superblock.usersize) {
	st = (*op)(&users[i]);
	unlock();
    }
    else st=0;

    return st ? i : (-1);
}


logout(p)
struct logins *p;
{
    p->flags &= ~LOG_ACTIVE;
    return 1;
}

login(p)
struct logins *p;
{
    if (p->flags & LOG_ACTIVE) {
	msg("You're already logged in\n");
	return 0;
    }
    p->flags |= LOG_ACTIVE;
    return 1;
}


i = withuser(name, LOG_INUSE, login);
if (i 
