From 506cb4954d2a800871db7ba55c779f4eaebcc665 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 7 Apr 2003 05:02:24 +0000 Subject: [PATCH] * Reworked all the "list rooms" operations so that they only require one pass through the database. * Repaired the "create floor" operation which was broken by the switch to the new IPC libray --- citadel/ChangeLog | 7 ++ citadel/citadel.h | 2 + citadel/citadel_ipc.c | 17 ++--- citadel/ipcdef.h | 5 ++ citadel/room_ops.c | 49 ++++++++----- citadel/room_ops.h | 2 +- citadel/rooms.c | 140 +++++++++++++++++++++++------------- citadel/rooms.h | 7 ++ citadel/server.h | 5 -- citadel/techdoc/session.txt | 15 +++- 10 files changed, 161 insertions(+), 88 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index bf96da32c..75d4488e6 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,10 @@ $Log$ + Revision 605.33 2003/04/07 05:02:23 ajc + * Reworked all the "list rooms" operations so that they only require one + pass through the database. + * Repaired the "create floor" operation which was broken by the switch + to the new IPC libray + Revision 605.32 2003/04/02 13:33:28 ajc * Fixed output of "-0500" vs. "+0500" type of timezone stamps in RFC822. (I think they were reversed.) @@ -4616,3 +4622,4 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import + diff --git a/citadel/citadel.h b/citadel/citadel.h index d883258fa..40df05138 100644 --- a/citadel/citadel.h +++ b/citadel/citadel.h @@ -137,6 +137,8 @@ struct march { unsigned int march_flags; char march_floor; char march_order; + unsigned int march_flags2; + int march_access; }; #define NODENAME config.c_nodename diff --git a/citadel/citadel_ipc.c b/citadel/citadel_ipc.c index 4f3b7c483..c4feabae6 100644 --- a/citadel/citadel_ipc.c +++ b/citadel/citadel_ipc.c @@ -303,6 +303,8 @@ int CtdlIPCKnownRooms(CtdlIPC *ipc, enum RoomList which, int floor, struct march mptr->march_flags = (unsigned int) extract_int(aaa, 1); mptr->march_floor = (char) extract_int(aaa, 2); mptr->march_order = (char) extract_int(aaa, 3); + mptr->march_flags2 = (unsigned int) extract_int(aaa, 4); + mptr->march_access = (char) extract_int(aaa, 5); if (march == NULL) march = mptr; else { @@ -1344,18 +1346,13 @@ int CtdlIPCFloorListing(CtdlIPC *ipc, char **listing, char *cret) int CtdlIPCCreateFloor(CtdlIPC *ipc, int for_real, const char *name, char *cret) { register int ret; - char *aaa; + char aaa[SIZ]; if (!cret) return -2; if (!name) return -2; - if (!*name) return -2; - - aaa = (char *)malloc(strlen(name) + 17); - if (!aaa) return -1; sprintf(aaa, "CFLR %s|%d", name, for_real); ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret); - free(aaa); return ret; } @@ -1363,7 +1360,7 @@ int CtdlIPCCreateFloor(CtdlIPC *ipc, int for_real, const char *name, char *cret) /* KFLR */ int CtdlIPCDeleteFloor(CtdlIPC *ipc, int for_real, int floornum, char *cret) { - char aaa[27]; + char aaa[SIZ]; if (!cret) return -1; if (floornum < 0) return -1; @@ -1377,18 +1374,14 @@ int CtdlIPCDeleteFloor(CtdlIPC *ipc, int for_real, int floornum, char *cret) int CtdlIPCEditFloor(CtdlIPC *ipc, int floornum, const char *floorname, char *cret) { register int ret; - char *aaa; + char aaa[SIZ]; if (!cret) return -2; if (!floorname) return -2; if (floornum < 0) return -2; - aaa = (char *)malloc(strlen(floorname) + 17); - if (!aaa) return -1; - sprintf(aaa, "EFLR %d|%s", floornum, floorname); ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret); - free(aaa); return ret; } diff --git a/citadel/ipcdef.h b/citadel/ipcdef.h index a538cbe3f..6f2e26b84 100644 --- a/citadel/ipcdef.h +++ b/citadel/ipcdef.h @@ -83,6 +83,11 @@ struct CtdlServInfo { US_NOPROMPT | US_DISAPPEAR | US_PAGINATOR | \ US_FLOORS | US_COLOR | US_PROMPTCTL ) +#define UA_KNOWN 2 +#define UA_GOTOALLOWED 4 +#define UA_HASNEWMSGS 8 +#define UA_ZAPPED 16 + #ifdef __cplusplus } #endif diff --git a/citadel/room_ops.c b/citadel/room_ops.c index b61aebf4f..28c6f4971 100644 --- a/citadel/room_ops.c +++ b/citadel/room_ops.c @@ -480,7 +480,7 @@ int is_noneditable(struct quickroom *qrbuf) /* * Back-back-end for all room listing commands */ -void list_roomname(struct quickroom *qrbuf) +void list_roomname(struct quickroom *qrbuf, int ra) { char truncated_roomname[ROOMNAMELEN]; @@ -497,11 +497,12 @@ void list_roomname(struct quickroom *qrbuf) } /* ...and now the other parameters */ - cprintf("|%u|%d|%d|%d\n", + cprintf("|%u|%d|%d|%d|%d|\n", qrbuf->QRflags, (int) qrbuf->QRfloor, (int) qrbuf->QRorder, - (int) qrbuf->QRflags2 + (int) qrbuf->QRflags2, + ra ); } @@ -512,13 +513,15 @@ void list_roomname(struct quickroom *qrbuf) void cmd_lrms_backend(struct quickroom *qrbuf, void *data) { int FloorBeingSearched = (-1); + int ra; + FloorBeingSearched = *(int *)data; + ra = CtdlRoomAccess(qrbuf, &CC->usersupp); - if (((CtdlRoomAccess(qrbuf, &CC->usersupp) - & (UA_KNOWN | UA_ZAPPED))) + if ((( ra & (UA_KNOWN | UA_ZAPPED))) && ((qrbuf->QRfloor == (FloorBeingSearched)) || ((FloorBeingSearched) < 0))) - list_roomname(qrbuf); + list_roomname(qrbuf, ra); } void cmd_lrms(char *argbuf) @@ -547,13 +550,15 @@ void cmd_lrms(char *argbuf) void cmd_lkra_backend(struct quickroom *qrbuf, void *data) { int FloorBeingSearched = (-1); + int ra; + FloorBeingSearched = *(int *)data; + ra = CtdlRoomAccess(qrbuf, &CC->usersupp); - if (((CtdlRoomAccess(qrbuf, &CC->usersupp) - & (UA_KNOWN))) + if ((( ra & (UA_KNOWN))) && ((qrbuf->QRfloor == (FloorBeingSearched)) || ((FloorBeingSearched) < 0))) - list_roomname(qrbuf); + list_roomname(qrbuf, ra); } void cmd_lkra(char *argbuf) @@ -579,13 +584,16 @@ void cmd_lkra(char *argbuf) void cmd_lprm_backend(struct quickroom *qrbuf, void *data) { int FloorBeingSearched = (-1); + int ra; + FloorBeingSearched = *(int *)data; + ra = CtdlRoomAccess(qrbuf, &CC->usersupp); if ( ((qrbuf->QRflags & QR_PRIVATE) == 0) && ((qrbuf->QRflags & QR_MAILBOX) == 0) && ((qrbuf->QRfloor == (FloorBeingSearched)) || ((FloorBeingSearched) < 0))) - list_roomname(qrbuf); + list_roomname(qrbuf, ra); } void cmd_lprm(char *argbuf) @@ -607,16 +615,17 @@ void cmd_lprm(char *argbuf) */ void cmd_lkrn_backend(struct quickroom *qrbuf, void *data) { - int ra; int FloorBeingSearched = (-1); - FloorBeingSearched = *(int *)data; + int ra; + FloorBeingSearched = *(int *)data; ra = CtdlRoomAccess(qrbuf, &CC->usersupp); + if ((ra & UA_KNOWN) && (ra & UA_HASNEWMSGS) && ((qrbuf->QRfloor == (FloorBeingSearched)) || ((FloorBeingSearched) < 0))) - list_roomname(qrbuf); + list_roomname(qrbuf, ra); } void cmd_lkrn(char *argbuf) @@ -644,16 +653,17 @@ void cmd_lkrn(char *argbuf) */ void cmd_lkro_backend(struct quickroom *qrbuf, void *data) { - int ra; int FloorBeingSearched = (-1); - FloorBeingSearched = *(int *)data; + int ra; + FloorBeingSearched = *(int *)data; ra = CtdlRoomAccess(qrbuf, &CC->usersupp); + if ((ra & UA_KNOWN) && ((ra & UA_HASNEWMSGS) == 0) && ((qrbuf->QRfloor == (FloorBeingSearched)) || ((FloorBeingSearched) < 0))) - list_roomname(qrbuf); + list_roomname(qrbuf, ra); } void cmd_lkro(char *argbuf) @@ -681,16 +691,17 @@ void cmd_lkro(char *argbuf) */ void cmd_lzrm_backend(struct quickroom *qrbuf, void *data) { - int ra; int FloorBeingSearched = (-1); - FloorBeingSearched = *(int *)data; + int ra; + FloorBeingSearched = *(int *)data; ra = CtdlRoomAccess(qrbuf, &CC->usersupp); + if ((ra & UA_GOTOALLOWED) && (ra & UA_ZAPPED) && ((qrbuf->QRfloor == (FloorBeingSearched)) || ((FloorBeingSearched) < 0))) - list_roomname(qrbuf); + list_roomname(qrbuf, ra); } void cmd_lzrm(char *argbuf) diff --git a/citadel/room_ops.h b/citadel/room_ops.h index ea065314b..a8ed3b790 100644 --- a/citadel/room_ops.h +++ b/citadel/room_ops.h @@ -51,7 +51,7 @@ void ForEachRoom(void (*CallBack)(struct quickroom *EachRoom, void *out_data), void assoc_file_name(char *buf, size_t n, struct quickroom *qrbuf, const char *prefix); void delete_room(struct quickroom *qrbuf); -void list_roomname(struct quickroom *qrbuf); +void list_roomname(struct quickroom *qrbuf, int ra); int is_noneditable(struct quickroom *qrbuf); int CtdlRoomAccess(struct quickroom *roombuf, struct usersupp *userbuf); int CtdlDoIHavePermissionToDeleteThisRoom(struct quickroom *qr); diff --git a/citadel/rooms.c b/citadel/rooms.c index d107eceb4..971ce88a4 100644 --- a/citadel/rooms.c +++ b/citadel/rooms.c @@ -165,52 +165,57 @@ int rordercmp(struct roomlisting *r1, struct roomlisting *r2) /* * Common code for all room listings */ -static void listrms(CtdlIPC *ipc, enum RoomList variety, int floor) +static void listrms(struct march *listing, int new_only, int floor_only) { - char buf[SIZ]; - struct march *listing = NULL; - struct march *tmp = NULL; + struct march *mptr; struct roomlisting *rl = NULL; struct roomlisting *rp; struct roomlisting *rs; - int r; /* IPC response code */ - - /* Ask the server for a room list */ - r = CtdlIPCKnownRooms(ipc, variety, floor, &listing, buf); - if (r / 100 != 1) { - return; - } - while (listing) { - rp = malloc(sizeof(struct roomlisting)); - strncpy(rp->rlname, listing->march_name, ROOMNAMELEN); - rp->rlflags = listing->march_flags; - rp->rlfloor = listing->march_floor; - rp->rlorder = listing->march_order; - rp->lnext = NULL; - rp->rnext = NULL; - - tmp = listing->next; - free(listing); - listing = tmp; - - rs = rl; - if (rl == NULL) { - rl = rp; - } else { - while (rp != NULL) { - if (rordercmp(rp, rs) < 0) { - if (rs->lnext == NULL) { - rs->lnext = rp; - rp = NULL; + int list_it; + + for (mptr = listing; mptr != NULL; mptr = mptr->next) { + list_it = 1; + + if ( (new_only == LISTRMS_NEW_ONLY) + && ((mptr->march_access & UA_HASNEWMSGS) == 0)) + list_it = 0; + + if ( (new_only == LISTRMS_OLD_ONLY) + && ((mptr->march_access & UA_HASNEWMSGS) != 0)) + list_it = 0; + + if ( (floor_only >= 0) + && (mptr->march_floor != floor_only)) + list_it = 0; + + if (list_it) { + rp = malloc(sizeof(struct roomlisting)); + strncpy(rp->rlname, mptr->march_name, ROOMNAMELEN); + rp->rlflags = mptr->march_flags; + rp->rlfloor = mptr->march_floor; + rp->rlorder = mptr->march_order; + rp->lnext = NULL; + rp->rnext = NULL; + + rs = rl; + if (rl == NULL) { + rl = rp; + } else { + while (rp != NULL) { + if (rordercmp(rp, rs) < 0) { + if (rs->lnext == NULL) { + rs->lnext = rp; + rp = NULL; + } else { + rs = rs->lnext; + } } else { - rs = rs->lnext; - } - } else { - if (rs->rnext == NULL) { - rs->rnext = rp; - rp = NULL; - } else { - rs = rs->rnext; + if (rs->rnext == NULL) { + rs->rnext = rp; + rp = NULL; + } else { + rs = rs->rnext; + } } } } @@ -248,16 +253,28 @@ void list_other_floors(void) void knrooms(CtdlIPC *ipc, int kn_floor_mode) { int a; + struct march *listing = NULL; + struct march *mptr; + int r; /* IPC response code */ + char buf[SIZ]; + + + /* Ask the server for a room list */ + r = CtdlIPCKnownRooms(ipc, SubscribedRooms, (-1), &listing, buf); + if (r / 100 != 1) { + listing = NULL; + } load_floorlist(ipc); + if (kn_floor_mode == 0) { color(BRIGHT_CYAN); pprintf("\n Rooms with unread messages:\n"); - listrms(ipc, SubscribedRoomsWithNewMessages, -1); + listrms(listing, LISTRMS_NEW_ONLY, -1); color(BRIGHT_CYAN); pprintf("\n\n No unseen messages in:\n"); - listrms(ipc, SubscribedRoomsWithNoNewMessages, -1); + listrms(listing, LISTRMS_OLD_ONLY, -1); pprintf("\n"); } @@ -265,11 +282,11 @@ void knrooms(CtdlIPC *ipc, int kn_floor_mode) color(BRIGHT_CYAN); pprintf("\n Rooms with unread messages on %s:\n", floorlist[(int) curr_floor]); - listrms(ipc, SubscribedRoomsWithNewMessages, curr_floor); + listrms(listing, LISTRMS_NEW_ONLY, curr_floor); color(BRIGHT_CYAN); pprintf("\n\n Rooms with no new messages on %s:\n", floorlist[(int) curr_floor]); - listrms(ipc, SubscribedRoomsWithNoNewMessages, curr_floor); + listrms(listing, LISTRMS_OLD_ONLY, curr_floor); color(BRIGHT_CYAN); pprintf("\n\n Other floors:\n"); list_other_floors(); @@ -282,12 +299,19 @@ void knrooms(CtdlIPC *ipc, int kn_floor_mode) color(BRIGHT_CYAN); pprintf("\n Rooms on %s:\n", floorlist[a]); - listrms(ipc, AllAccessibleRooms, a); + listrms(listing, LISTRMS_ALL, a); pprintf("\n"); } } } + /* Free the room list */ + while (listing) { + mptr = listing->next; + free(listing); + listing = mptr; + }; + color(DIM_WHITE); IFNEXPERT hit_any_key(); } @@ -295,10 +319,30 @@ void knrooms(CtdlIPC *ipc, int kn_floor_mode) void listzrooms(CtdlIPC *ipc) { /* list public forgotten rooms */ + struct march *listing = NULL; + struct march *mptr; + int r; /* IPC response code */ + char buf[SIZ]; + + + /* Ask the server for a room list */ + r = CtdlIPCKnownRooms(ipc, UnsubscribedRooms, 1, &listing, buf); + if (r / 100 != 1) { + listing = NULL; + } + color(BRIGHT_CYAN); pprintf("\n Forgotten public rooms:\n"); - listrms(ipc, UnsubscribedRooms, -1); + listrms(listing, LISTRMS_ALL, -1); pprintf("\n"); + + /* Free the room list */ + while (listing) { + mptr = listing->next; + free(listing); + listing = mptr; + }; + color(DIM_WHITE); IFNEXPERT hit_any_key(); } @@ -1145,7 +1189,7 @@ void create_floor(CtdlIPC *ipc) load_floorlist(ipc); r = CtdlIPCCreateFloor(ipc, 0, "", buf); - if (r / 100 != 2) { + if ( (r / 100 != 2) && (r != ERROR + ILLEGAL_VALUE) ) { scr_printf("%s\n", buf); return; } diff --git a/citadel/rooms.h b/citadel/rooms.h index d6ee18f32..fdfe71e2d 100644 --- a/citadel/rooms.h +++ b/citadel/rooms.h @@ -41,3 +41,10 @@ struct roomlisting { }; +enum { + LISTRMS_NEW_ONLY, + LISTRMS_OLD_ONLY, + LISTRMS_ALL +}; + + diff --git a/citadel/server.h b/citadel/server.h index d99be8ddf..51573ea2c 100644 --- a/citadel/server.h +++ b/citadel/server.h @@ -408,11 +408,6 @@ struct visit { #define V_LOCKOUT 2 /* User is locked out of this room */ #define V_ACCESS 4 /* Access is granted to this room */ -#define UA_KNOWN 2 -#define UA_GOTOALLOWED 4 -#define UA_HASNEWMSGS 8 -#define UA_ZAPPED 16 - /* Supplementary data for a message on disk * (These are kept separately from the message itself because they are diff --git a/citadel/techdoc/session.txt b/citadel/techdoc/session.txt index fab67e077..361d4b82d 100644 --- a/citadel/techdoc/session.txt +++ b/citadel/techdoc/session.txt @@ -259,9 +259,18 @@ floor names. The fourth field displayed on each line is a "room listing order." Unless there is a compelling reason not to, clients should sort any received room listings by this value. - - - + + The fifth field is a special bit bucket containing fields which pertain to +room access controls: + +#define UA_KNOWN 2 /* Known room */ +#define UA_GOTOALLOWED 4 /* Access will be granted to this room + * if the user calls it up by name */ +#define UA_HASNEWMSGS 8 /* Unread messages exist in room */ +#define UA_ZAPPED 16 /* Zapped from known rooms list */ + + + LKRO (List Known Rooms with Old [no new] messages) This follows the same usage and format as LKRN. -- 2.39.2