int load_roominfo(Room *r, char *username) { Room *tmp; if (r == NULL) return -1; if (r->number == MAIL_ROOM) /* don't bother */ return 0; if (r->info != NULL) /* already resident */ return 0; tmp = new_Room(); if (r->number == MAIL_ROOM) tmp = load_Mail(username, LOAD_ROOM_INFO); else if (r->number == HOME_ROOM) tmp = load_Home(username, LOAD_ROOM_INFO); else tmp = load_Room(r->number, LOAD_ROOM_INFO); if (tmp == NULL) return -1; destroy_StringIO(r->info); r->info = tmp->info; tmp->info = NULL; destroy_Room(tmp); return 0; }
/* unload an 'on demand loaded' room Sometimes, the find_Room() functions load a room on demand This is cool, but there are cases in which the loaded room needs to be destroyed again -- this is done by unload_Room() */ void unload_Room(Room *r) { if (r == NULL) return; if (r->number == HOME_ROOM && count_Queue(r->inside) <= 0) { /* demand loaded Home room */ (void)remove_Room(&HomeRooms, r); if (save_Room(r)) log_err("unload_Room(): failed to save room #%u %s", r->number, r->name); destroy_Room(r); return; } if (r->number == MAIL_ROOM) { /* demand loaded Mail> room */ Room *h; /* Note: mail rooms are usually stored in the user as usr->mail However, if the user was not online, it was put on the HomeRooms list so if we can find it there, it should be unloaded if we can't find it there, the room should not be unloaded This procedure is more efficient than scanning all users for "(usr->mail == r)" because the HomeRooms list is usually very short or empty */ for(h = HomeRooms; h != NULL; h = h->next) { if (h == r) { (void)remove_Room(&HomeRooms, r); if (save_Room(r)) log_err("unload_Room(): failed to save HomeRoom #%u %s", r->number, r->name); destroy_Room(r); return; } /* do some house-cleaning Note: due the 'return' statement just above, we may not complete the house-cleaning work... */ if (count_Queue(h->inside) <= 0) { (void)remove_Room(&HomeRooms, r); if (save_Room(r)) log_err("unload_Room(): failed to save room #%u %s", r->number, r->name); destroy_Room(r); } } } }
Room *new_Room(void) { Room *r; if ((r = (Room *)Malloc(sizeof(Room), TYPE_ROOM)) == NULL) return NULL; if ((r->inside = new_PQueue()) == NULL) { destroy_Room(r); return NULL; } r->max_msgs = PARAM_MAX_MESSAGES; return r; }
void destroyRoomMeeting(struct Room* room) { clear_Room(room); destroy_Room(room); }
Room *load_RoomData(char *filename, unsigned int number, int flags) { Room *r; File *f; int (*load_func)(File *, Room *, int) = NULL; int version; if (filename == NULL || !*filename || (r = new_Room()) == NULL) return NULL; if ((f = Fopen(filename)) == NULL) { destroy_Room(r); return NULL; } r->number = number; version = fileformat_version(f); switch(version) { case -1: log_err("load_RoomData(): error trying to determine file format version of %s", filename); load_func = NULL; break; case 0: Frewind(f); load_func = load_RoomData_version0; break; case 1: load_func = load_RoomData_version1; break; default: log_err("load_RoomData(): don't know how to load version %d of %s", version, filename); } if (load_func != NULL && !load_func(f, r, flags)) { Fclose(f); r->flags &= ROOM_ALL; /* force the room name for Mail> and Home> so that find_abbrevRoom() won't act strangely when these names are different in the files for some strange reason */ if (r->number == MAIL_ROOM) { Free(r->name); r->name = cstrdup("Mail"); } if (r->number == HOME_ROOM) { Free(r->name); r->name = cstrdup("Home"); } if (r->number == MAIL_ROOM) r->max_msgs = PARAM_MAX_MAIL_MSGS; else if (r->max_msgs < 1) r->max_msgs = PARAM_MAX_MESSAGES; if (PARAM_HAVE_CHATROOMS && (r->flags & ROOM_CHATROOM) && r->chat_history == NULL) r->chat_history = new_StringQueue(); if (!PARAM_HAVE_CHATROOMS && (r->flags & ROOM_CHATROOM) && r->number != HOME_ROOM) { r->flags &= ~ROOM_CHATROOM; r->flags |= ROOM_DIRTY; } (void)sort_StringList(&r->room_aides, alphasort_StringList); (void)sort_StringList(&r->invited, alphasort_StringList); (void)sort_StringList(&r->kicked, alphasort_StringList); return r; } destroy_Room(r); Fclose(f); return NULL; }