]> code.citadel.org Git - citadel.git/blobdiff - webcit/roomops.c
* Brought over the newer string tokenizer from Citadel
[citadel.git] / webcit / roomops.c
index f2f2057058c846a61010ac400e17c24732925902..1a3c2960c9d42f403e1d1a0d0d45b7b3d72d2689 100644 (file)
@@ -1,48 +1,35 @@
 /* $Id$ */
 
+
+#include <ctype.h>
 #include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 #include <stdio.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <string.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
 
-/*
- * This struct holds a list of rooms for <G>oto operations.
- */
-struct march {
-       struct march *next;
-       char march_name[32];
-       int march_floor;
-       int march_order;
-};
 
-/* 
- * This struct holds a list of rooms for client display.
- * (oooh, a tree!)
- */
-struct roomlisting {
-       struct roomlisting *lnext;
-       struct roomlisting *rnext;
-       char rlname[64];
-       unsigned rlflags;
-       int rlfloor;
-       int rlorder;
-};
 
 
-char floorlist[128][256];
-char ugname[128];
-long uglsn = (-1L);
-unsigned room_flags;
-int is_aide = 0;
-int is_room_aide = 0;
 
-struct march *march = NULL;
+
+
+char floorlist[128][SIZ];
+
 
 /*
  * load the list of floors
@@ -50,7 +37,7 @@ struct march *march = NULL;
 void load_floorlist(void)
 {
        int a;
-       char buf[256];
+       char buf[SIZ];
 
        for (a = 0; a < 128; ++a)
                floorlist[a][0] = 0;
@@ -74,17 +61,17 @@ void remove_march(char *aaa)
 {
        struct march *mptr, *mptr2;
 
-       if (march == NULL)
+       if (WC->march == NULL)
                return;
 
-       if (!strcasecmp(march->march_name, aaa)) {
-               mptr = march->next;
-               free(march);
-               march = mptr;
+       if (!strcasecmp(WC->march->march_name, aaa)) {
+               mptr = WC->march->next;
+               free(WC->march);
+               WC->march = mptr;
                return;
        }
-       mptr2 = march;
-       for (mptr = march; mptr != NULL; mptr = mptr->next) {
+       mptr2 = WC->march;
+       for (mptr = WC->march; mptr != NULL; mptr = mptr->next) {
                if (!strcasecmp(mptr->march_name, aaa)) {
                        mptr2->next = mptr->next;
                        free(mptr);
@@ -115,7 +102,8 @@ void room_tree_list(struct roomlisting *rp)
 
        wprintf("<A HREF=\"/dotgoto&room=");
        urlescputs(rmname);
-       wprintf("\">");
+       wprintf("\"");
+       wprintf(">");
        escputs1(rmname, 1);
        if ((f & QR_DIRECTORY) && (f & QR_NETWORK))
                wprintf("}");
@@ -162,7 +150,8 @@ int rordercmp(struct roomlisting *r1, struct roomlisting *r2)
  */
 void listrms(char *variety)
 {
-       char buf[256];
+       char buf[SIZ];
+       int num_rooms = 0;
 
        struct roomlisting *rl = NULL;
        struct roomlisting *rp;
@@ -172,9 +161,12 @@ void listrms(char *variety)
        /* Ask the server for a room list */
        serv_puts(variety);
        serv_gets(buf);
-       if (buf[0] != '1')
+       if (buf[0] != '1') {
+               wprintf("&nbsp;");
                return;
+       }
        while (serv_gets(buf), strcmp(buf, "000")) {
+               ++num_rooms;
                rp = malloc(sizeof(struct roomlisting));
                extract(rp->rlname, buf, 0);
                rp->rlflags = extract_int(buf, 1);
@@ -207,6 +199,11 @@ void listrms(char *variety)
        }
 
        room_tree_list(rl);
+
+       /* If no rooms were listed, print an nbsp to make the cell
+        * borders show up anyway.
+        */
+       if (num_rooms == 0) wprintf("&nbsp;");
 }
 
 
@@ -223,14 +220,13 @@ void listrms(char *variety)
 void list_all_rooms_by_floor(void)
 {
        int a;
-       char buf[256];
+       char buf[SIZ];
 
        load_floorlist();
 
-       printf("HTTP/1.0 200 OK\n");
-       output_headers(1, "bottom");
+       output_headers(1);
 
-       wprintf("<TABLE width=100% border><TR><TH>Floor</TH>");
+       wprintf("<TABLE width=100%% border><TR><TH>Floor</TH>");
        wprintf("<TH>Rooms with new messages</TH>");
        wprintf("<TH>Rooms with no new messages</TH></TR>\n");
 
@@ -257,7 +253,7 @@ void list_all_rooms_by_floor(void)
                        wprintf("<TD>");
                        sprintf(buf, "LKRN %d", a);
                        listrms(buf);
-                       wprintf("</TD><TD>\n");
+                       wprintf("</TD>\n<TD>");
 
                        /* Rooms with old messages column */
                        sprintf(buf, "LKRO %d", a);
@@ -274,12 +270,11 @@ void list_all_rooms_by_floor(void)
  */
 void zapped_list(void)
 {
-       printf("HTTP/1.0 200 OK\n");
-       output_headers(1, "bottom");
-       wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
+       output_headers(1);
+       wprintf("<TABLE WIDTH=100%% BORDER=0 BGCOLOR=770000><TR><TD>");
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
        wprintf("<B>Zapped (forgotten) rooms</B>\n");
-       wprintf("</FONT></TD></TR></TABLE><BR>\n");
+       wprintf("</TD></TR></TABLE><BR>\n");
        listrms("LZRM -1");
        wprintf("<BR><BR>\n");
        wprintf("Click on any room to un-zap it and goto that room.\n");
@@ -290,21 +285,89 @@ void zapped_list(void)
 /*
  * read this room's info file (set v to 1 for verbose mode)
  */
-void readinfo(int v)
+void readinfo(void)
 {
-       char buf[256];
+       char buf[SIZ];
 
        serv_puts("RINF");
        serv_gets(buf);
-       if (buf[0] == '1')
+       if (buf[0] == '1') {
+               wprintf("<FONT SIZE=-1>");
                fmout(NULL);
-       else {
-               if (v == 1)
-                       wprintf("<EM>%s</EM><BR>\n", &buf[4]);
+               wprintf("</FONT>");
        }
 }
 
 
+
+
+/* Display room graphic.  The server doesn't actually
+ * need the room name, but we supply it in order to
+ * keep the browser from using a cached graphic from 
+ * another room.
+ */
+void embed_room_graphic(void) {
+       char buf[SIZ];
+
+       serv_puts("OIMG _roompic_");
+       serv_gets(buf);
+       if (buf[0] == '2') {
+               wprintf("<TD>");
+               wprintf("<IMG SRC=\"/image&name=_roompic_&room=");
+               urlescputs(WC->wc_roomname);
+               wprintf("\"></TD>");
+               serv_puts("CLOS");
+               serv_gets(buf);
+       }
+
+}
+
+
+/* Let the user know if new mail has arrived 
+ */
+void embed_newmail_button(void) {
+       if ( (WC->new_mail > WC->remember_new_mail) && (WC->new_mail>0) ) {
+               wprintf("<TD VALIGN=TOP>"
+                       "<IMG SRC=\"/static/mail.gif\" border=0 "
+                       "ALT=\"You have new mail\">"
+                       "<BR><BLINK>%d</BLINK>", WC->new_mail);
+               wprintf("<FONT SIZE=-2> new mail messages</FONT></TD>");
+               WC->remember_new_mail = WC->new_mail;
+       }
+}
+
+
+
+void embed_room_banner(char *got) {
+       char fakegot[SIZ];
+
+       /* We need to have the information returned by a GOTO server command.
+        * If it isn't supplied, we fake it by issuing our own GOTO.
+        */
+       if (got == NULL) {
+               serv_printf("GOTO %s", WC->wc_roomname);
+               serv_gets(fakegot);
+               got = fakegot;
+       }
+
+       /* Check for new mail. */
+       WC->new_mail = extract_int(&got[4], 9);
+
+       svprintf("ROOMNAME", WCS_STRING, "%s", WC->wc_roomname);
+       svprintf("NEWMSGS", WCS_STRING, "%d", extract_int(&got[4], 1));
+       svprintf("TOTALMSGS", WCS_STRING, "%d", extract_int(&got[4], 2));
+       svcallback("ROOMPIC", embed_room_graphic);
+       svcallback("ROOMINFO", readinfo);
+       svcallback("YOUHAVEMAIL", embed_newmail_button);
+
+       do_template("roombanner.html");
+       clear_local_substs();
+}
+
+
+
+
+
 /*
  * generic routine to take the session to a new room
  *
@@ -314,25 +377,27 @@ void readinfo(int v)
  */
 void gotoroom(char *gname, int display_name)
 {
-       char buf[256];
+       char buf[SIZ];
        static long ls = (-1L);
 
 
        if (display_name) {
-               printf("HTTP/1.0 200 OK\n");
-               output_headers(0, "top");
-               wprintf("<HTML><HEAD></HEAD>\n<BODY ");
-
-               /* automatically fire up a read-new-msgs in the bottom frame */
-               if (!noframes)
-                       wprintf("onload=location=\"/readnew\" ");
-
-               wprintf("BACKGROUND=\"/image&name=background\" TEXT=\"#000000\" LINK=\"#004400\">\n");
+               output_headers(0);
+                wprintf("Pragma: no-cache\n");
+                wprintf("Cache-Control: no-store\n");
+
+               wprintf("<HTML><HEAD>\n"
+                       "<META HTTP-EQUIV=\"refresh\" CONTENT=\"500363689;\">\n"
+                       "<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">\n"
+                       "<META HTTP-EQUIV=\"expired\" CONTENT=\"28-May-1971 18:10:00 GMT\">\n"
+                       "<meta name=\"MSSmartTagsPreventParsing\" content=\"TRUE\">\n"
+                       "</HEAD>\n");
+               do_template("background.html");
        }
        if (display_name != 2) {
                /* store ungoto information */
-               strcpy(ugname, wc_roomname);
-               uglsn = ls;
+               strcpy(WC->ugname, WC->wc_roomname);
+               WC->uglsn = ls;
        }
        /* move to the new room */
        serv_printf("GOTO %s", gname);
@@ -348,61 +413,28 @@ void gotoroom(char *gname, int display_name)
                }
                return;
        }
-       extract(wc_roomname, &buf[4], 0);
-       room_flags = extract_int(&buf[4], 4);
+       extract(WC->wc_roomname, &buf[4], 0);
+       WC->room_flags = extract_int(&buf[4], 4);
        /* highest_msg_read = extract_int(&buf[4],6);
           maxmsgnum = extract_int(&buf[4],5);
           is_mail = (char) extract_int(&buf[4],7); */
        ls = extract_long(&buf[4], 6);
 
-       if (is_aide)
-               is_room_aide = is_aide;
+       if (WC->is_aide)
+               WC->is_room_aide = WC->is_aide;
        else
-               is_room_aide = (char) extract_int(&buf[4], 8);
+               WC->is_room_aide = (char) extract_int(&buf[4], 8);
 
-       remove_march(wc_roomname);
+       remove_march(WC->wc_roomname);
        if (!strcasecmp(gname, "_BASEROOM_"))
                remove_march(gname);
 
        /* Display the room banner */
        if (display_name) {
-               wprintf("<CENTER><TABLE border=0><TR>");
-
-               if ((strlen(ugname) > 0) && (strcasecmp(ugname, wc_roomname))) {
-                       wprintf("<TD VALIGN=TOP><A HREF=\"/ungoto\">");
-                       wprintf("<IMG SRC=\"/static/back.gif\" BORDER=0></A></TD>");
-               }
-               wprintf("<TD VALIGN=TOP><FONT FACE=\"Arial,Helvetica,sans-serif\"><H1>%s</H1>", wc_roomname);
-               wprintf("%d new of %d messages</FONT></TD>\n",
-                       extract_int(&buf[4], 1),
-                       extract_int(&buf[4], 2));
-
-               /* Display room graphic.  The server doesn't actually
-                * need the room name, but we supply it in order to
-                * keep the browser from using a cached graphic from 
-                * another room.
-                */
-               serv_puts("OIMG _roompic_");
-               serv_gets(buf);
-               if (buf[0] == '2') {
-                       wprintf("<TD><FONT FACE=\"Arial,Helvetica,sans-serif\">");
-                       wprintf("<IMG SRC=\"/image&name=_roompic_&room=");
-                       escputs(wc_roomname);
-                       wprintf("\"></FONT></TD>");
-                       serv_puts("CLOS");
-                       serv_gets(buf);
-               }
-               wprintf("<TD VALIGN=TOP><FONT FACE=\"Arial,Helvetica,sans-serif\">");
-               readinfo(0);
-               wprintf("</FONT></TD>");
-
-               wprintf("<TD VALIGN=TOP><A HREF=\"/gotonext\">");
-               wprintf("<IMG SRC=\"/static/forward.gif\" border=0></A></TD>");
-               wprintf("</TR></TABLE></CENTER>\n");
-
+               embed_room_banner(buf);
                wDumpContent(1);
        }
-       strcpy(wc_roomname, wc_roomname);
+       strcpy(WC->wc_roomname, WC->wc_roomname);
 }
 
 
@@ -420,10 +452,10 @@ char *pop_march(int desired_floor)
        struct march *mptr = NULL;
 
        strcpy(TheRoom, "_BASEROOM_");
-       if (march == NULL)
+       if (WC->march == NULL)
                return (TheRoom);
 
-       for (mptr = march; mptr != NULL; mptr = mptr->next) {
+       for (mptr = WC->march; mptr != NULL; mptr = mptr->next) {
                weight = 0;
                if ((strcasecmp(mptr->march_name, "_BASEROOM_")))
                        weight = weight + 10000;
@@ -454,7 +486,7 @@ char *pop_march(int desired_floor)
  */
 void gotonext(void)
 {
-       char buf[256];
+       char buf[SIZ];
        struct march *mptr, *mptr2;
        char next_room[32];
 
@@ -462,7 +494,7 @@ void gotonext(void)
         * If it is, pop the first room off the list and go there.
         */
 
-       if (march == NULL) {
+       if (WC->march == NULL) {
                serv_puts("LKRN");
                serv_gets(buf);
                if (buf[0] == '1')
@@ -472,10 +504,10 @@ void gotonext(void)
                                extract(mptr->march_name, buf, 0);
                                mptr->march_floor = extract_int(buf, 2);
                                mptr->march_order = extract_int(buf, 3);
-                               if (march == NULL) {
-                                       march = mptr;
+                               if (WC->march == NULL) {
+                                       WC->march = mptr;
                                } else {
-                                       mptr2 = march;
+                                       mptr2 = WC->march;
                                        while (mptr2->next != NULL)
                                                mptr2 = mptr2->next;
                                        mptr2->next = mptr;
@@ -487,10 +519,10 @@ void gotonext(void)
                mptr = (struct march *) malloc(sizeof(struct march));
                mptr->next = NULL;
                strcpy(mptr->march_name, "_BASEROOM_");
-               if (march == NULL) {
-                       march = mptr;
+               if (WC->march == NULL) {
+                       WC->march = mptr;
                } else {
-                       mptr2 = march;
+                       mptr2 = WC->march;
                        while (mptr2->next != NULL)
                                mptr2 = mptr2->next;
                        mptr2->next = mptr;
@@ -499,14 +531,22 @@ void gotonext(void)
  * ...and remove the room we're currently in, so a <G>oto doesn't make us
  * walk around in circles
  */
-               remove_march(wc_roomname);
+               remove_march(WC->wc_roomname);
        }
-       if (march != NULL) {
+       if (WC->march != NULL) {
                strcpy(next_room, pop_march(-1));
        } else {
                strcpy(next_room, "_BASEROOM_");
        }
-       gotoroom(next_room, 1);
+
+
+       smart_goto(next_room);
+}
+
+
+void smart_goto(char *next_room) {
+       gotoroom(next_room, 0);
+       readloop("readnew");
 }
 
 
@@ -516,7 +556,7 @@ void gotonext(void)
  */
 void slrp_highest(void)
 {
-       char buf[256];
+       char buf[SIZ];
 
        /* set pointer */
        serv_puts("SLRP HIGHEST");
@@ -533,25 +573,25 @@ void slrp_highest(void)
  */
 void ungoto(void)
 {
-       char buf[256];
+       char buf[SIZ];
 
-       if (!strcmp(ugname, "")) {
-               gotoroom(wc_roomname, 1);
+       if (!strcmp(WC->ugname, "")) {
+               smart_goto(WC->wc_roomname);
                return;
        }
-       serv_printf("GOTO %s", ugname);
+       serv_printf("GOTO %s", WC->ugname);
        serv_gets(buf);
        if (buf[0] != '2') {
-               gotoroom(wc_roomname, 1);
+               smart_goto(WC->wc_roomname);
                return;
        }
-       if (uglsn >= 0L) {
-               serv_printf("SLRP %ld", uglsn);
+       if (WC->uglsn >= 0L) {
+               serv_printf("SLRP %ld", WC->uglsn);
                serv_gets(buf);
        }
-       strcpy(buf, ugname);
-       strcpy(ugname, "");
-       gotoroom(buf, 1);
+       strcpy(buf, WC->ugname);
+       strcpy(WC->ugname, "");
+       smart_goto(buf);
 }
 
 /*
@@ -559,7 +599,7 @@ void ungoto(void)
  */
 void display_editroom(void)
 {
-       char buf[256];
+       char buf[SIZ];
        char er_name[20];
        char er_password[10];
        char er_dirname[15];
@@ -582,12 +622,25 @@ void display_editroom(void)
        er_floor = extract_int(&buf[4], 4);
 
 
-       printf("HTTP/1.0 200 OK\n");
-       output_headers(1, "bottom");
+       output_headers(1);
+
+       wprintf("<TABLE WIDTH=100%% BORDER=0 BGCOLOR=000077><TR><TD>");
+       wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
+       wprintf("<B>Room administration</B>\n");
+       wprintf("</FONT></TD></TR></TABLE>\n");
+
+       wprintf("<UL>"
+               "<LI><A HREF=\"/confirm_delete_room\">\n"
+               "Delete this room</A>\n"
+               "<LI><A HREF=\"/display_editroompic\">\n"
+               "Set or change the graphic for this room's banner</A>\n"
+               "<LI><A HREF=\"/display_editinfo\">\n"
+               "Edit this room's Info file</A>\n"
+               "</UL>");
 
-       wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=000077><TR><TD>");
+       wprintf("<TABLE WIDTH=100%% BORDER=0 BGCOLOR=000077><TR><TD>");
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
-       wprintf("<B>Edit this room</B>\n");
+       wprintf("<B>Room editing</B>\n");
        wprintf("</FONT></TD></TR></TABLE>\n");
 
        wprintf("<FORM METHOD=\"POST\" ACTION=\"/editroom\">\n");
@@ -728,7 +781,7 @@ void display_editroom(void)
  */
 void editroom(void)
 {
-       char buf[256];
+       char buf[SIZ];
        char er_name[20];
        char er_password[10];
        char er_dirname[15];
@@ -866,7 +919,80 @@ void editroom(void)
                        return;
                }
        }
-       gotoroom(er_name, 1);
+       smart_goto(er_name);
+}
+
+/*
+ * Invite, Kick, and show Who Knows a room
+ */
+void display_whok(void)
+{
+        char buf[SIZ], room[SIZ], username[SIZ];
+
+        serv_puts("GETR");
+        serv_gets(buf);
+
+        if (buf[0] != '2') {
+                display_error(&buf[4]);
+                return;
+        }
+        extract(room, &buf[4], 0);
+
+        strcpy(username, bstr("username"));
+
+        output_headers(1);
+
+        if(!strcmp(bstr("sc"), "Kick")) {
+                sprintf(buf, "KICK %s", username);
+                serv_puts(buf);
+                serv_gets(buf);
+
+                if (buf[0] != '2') {
+                        display_error(&buf[4]);
+                        return;
+                } else {
+                        wprintf("User %s kicked out of room %s.\n", 
+                                username, room);
+                }
+        } else if(!strcmp(bstr("sc"), "Invite")) {
+                sprintf(buf, "INVT %s", username);
+                serv_puts(buf);
+                serv_gets(buf);
+
+                if (buf[0] != '2') {
+                        display_error(&buf[4]);
+                        return;
+                } else {
+                        wprintf("User %s invited to room %s.\n", 
+                                username, room);
+                }
+        }
+        
+
+        wprintf("<FORM METHOD=\"POST\" ACTION=\"/display_whok\">\n");
+        wprintf("<SELECT NAME=\"username\" SIZE=10>\n");
+        serv_puts("WHOK");
+        serv_gets(buf);
+        if (buf[0] == '1') {
+                while (serv_gets(buf), strcmp(buf, "000")) {
+                        extract(username, buf, 0);
+                        wprintf("<OPTION>");
+                        escputs(username);
+                        wprintf("\n");
+                }
+        }
+        wprintf("</SELECT>\n");
+
+        wprintf("<CENTER>\n");
+        wprintf("<input type=submit name=sc value=\"Kick\">");
+        wprintf("</CENTER>\n");
+        wprintf("</FORM>\n");
+        wprintf("<FORM METHOD=\"POST\" ACTION=\"/display_whok\">\n");
+        wprintf("Invite: ");
+        wprintf("<input type=text name=username>\n");
+        wprintf("<input type=hidden name=sc value=\"Invite\">");
+        wprintf("<input type=submit value=\"Invite\">");
+        wDumpContent(1);
 }
 
 
@@ -876,7 +1002,8 @@ void editroom(void)
  */
 void display_entroom(void)
 {
-       char buf[256];
+       int i;
+       char buf[SIZ];
 
        serv_puts("CRE8 0");
        serv_gets(buf);
@@ -885,10 +1012,9 @@ void display_entroom(void)
                display_error(&buf[4]);
                return;
        }
-       printf("HTTP/1.0 200 OK\n");
-       output_headers(1, "bottom");
+       output_headers(1);
 
-       wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=000077><TR><TD>");
+       wprintf("<TABLE WIDTH=100%% BORDER=0 BGCOLOR=000077><TR><TD>");
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
        wprintf("<B>Enter (create) a new room</B>\n");
        wprintf("</FONT></TD></TR></TABLE>\n");
@@ -912,12 +1038,32 @@ void display_entroom(void)
 
        wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"invonly\" ");
        wprintf("> Private - invitation only\n");
+       wprintf("</UL>\n");
+
+        wprintf("<LI>Resides on floor: ");
+        load_floorlist(); 
+        wprintf("<SELECT NAME=\"er_floor\" SIZE=\"1\">\n");
+        for (i = 0; i < 128; ++i)
+                if (strlen(floorlist[i]) > 0) {
+                        wprintf("<OPTION ");
+                        wprintf("VALUE=\"%d\">", i);
+                        escputs(floorlist[i]);
+                        wprintf("</OPTION>\n");
+                }
+        wprintf("</SELECT>\n");                
+       wprintf("</UL>\n");
+
 
        wprintf("<CENTER>\n");
        wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"OK\">");
        wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
        wprintf("</CENTER>\n");
-       wprintf("</FORM>\n");
+       wprintf("</FORM>\n<HR>");
+       serv_printf("MESG roomaccess");
+       serv_gets(buf);
+       if (buf[0] == '1') {
+               fmout(NULL);
+       }
        wDumpContent(1);
 }
 
@@ -928,10 +1074,11 @@ void display_entroom(void)
  */
 void entroom(void)
 {
-       char buf[256];
+       char buf[SIZ];
        char er_name[20];
        char er_type[20];
        char er_password[10];
+       int er_floor;
        int er_num_type;
 
        if (strcmp(bstr("sc"), "OK")) {
@@ -941,6 +1088,7 @@ void entroom(void)
        strcpy(er_name, bstr("er_name"));
        strcpy(er_type, bstr("type"));
        strcpy(er_password, bstr("er_password"));
+       er_floor = atoi(bstr("er_floor"));
 
        er_num_type = 0;
        if (!strcmp(er_type, "guessname"))
@@ -950,14 +1098,15 @@ void entroom(void)
        if (!strcmp(er_type, "invonly"))
                er_num_type = 3;
 
-       sprintf(buf, "CRE8 1|%s|%d|%s", er_name, er_num_type, er_password);
+       sprintf(buf, "CRE8 1|%s|%d|%s|%d", 
+               er_name, er_num_type, er_password, er_floor);
        serv_puts(buf);
        serv_gets(buf);
        if (buf[0] != '2') {
                display_error(&buf[4]);
                return;
        }
-       gotoroom(er_name, 1);
+       smart_goto(er_name);
 }
 
 
@@ -967,10 +1116,9 @@ void entroom(void)
 void display_private(char *rname, int req_pass)
 {
 
-       printf("HTTP/1.0 200 OK\n");
-       output_headers(1, "bottom");
+       output_headers(1);
 
-       wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
+       wprintf("<TABLE WIDTH=100%% BORDER=0 BGCOLOR=770000><TR><TD>");
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
        wprintf("<B>Goto a private room</B>\n");
        wprintf("</FONT></TD></TR></TABLE>\n");
@@ -1008,13 +1156,13 @@ void display_private(char *rname, int req_pass)
 void goto_private(void)
 {
        char hold_rm[32];
-       char buf[256];
+       char buf[SIZ];
 
        if (strcasecmp(bstr("sc"), "OK")) {
                display_main_menu();
                return;
        }
-       strcpy(hold_rm, wc_roomname);
+       strcpy(hold_rm, WC->wc_roomname);
        strcpy(buf, "GOTO ");
        strcat(buf, bstr("gr_name"));
        strcat(buf, "|");
@@ -1023,15 +1171,14 @@ void goto_private(void)
        serv_gets(buf);
 
        if (buf[0] == '2') {
-               gotoroom(bstr("gr_name"), 1);
+               smart_goto(bstr("gr_name"));
                return;
        }
        if (!strncmp(buf, "540", 3)) {
                display_private(bstr("gr_name"), 1);
                return;
        }
-       printf("HTTP/1.0 200 OK\n");
-       output_headers(1, "bottom");
+       output_headers(1);
        wprintf("%s\n", &buf[4]);
        wDumpContent(1);
        return;
@@ -1043,15 +1190,14 @@ void goto_private(void)
  */
 void display_zap(void)
 {
-       printf("HTTP/1.0 200 OK\n");
-       output_headers(1, "bottom");
+       output_headers(1);
 
-       wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
+       wprintf("<TABLE WIDTH=100%% BORDER=0 BGCOLOR=770000><TR><TD>");
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
        wprintf("<B>Zap (forget) the current room</B>\n");
        wprintf("</FONT></TD></TR></TABLE>\n");
 
-       wprintf("If you select this option, <em>%s</em> will ", wc_roomname);
+       wprintf("If you select this option, <em>%s</em> will ", WC->wc_roomname);
        wprintf("disappear from your room list.  Is this what you wish ");
        wprintf("to do?<BR>\n");
 
@@ -1068,25 +1214,30 @@ void display_zap(void)
  */
 void zap(void)
 {
-       char buf[256];
+       char buf[SIZ];
+       char final_destination[SIZ];
 
-       if (strcmp(bstr("sc"), "OK")) {
-               display_main_menu();
-               return;
-       }
-       serv_printf("GOTO %s", wc_roomname);
-       serv_gets(buf);
-       if (buf[0] != '2') {
-               display_error(&buf[4]);
-               return;
-       }
-       serv_puts("FORG");
-       serv_gets(buf);
-       if (buf[0] != '2') {
-               display_error(&buf[4]);
-               return;
+       /* If the forget-room routine fails for any reason, we fall back
+        * to the current room; otherwise, we go to the Lobby
+        */
+       strcpy(final_destination, WC->wc_roomname);
+
+       if (!strcasecmp(bstr("sc"), "OK")) {
+               serv_printf("GOTO %s", WC->wc_roomname);
+               serv_gets(buf);
+               if (buf[0] != '2') {
+                       /* ExpressMessageCat(&buf[4]);   FIXME    */
+               } else {
+                       serv_puts("FORG");
+                       serv_gets(buf);
+                       if (buf[0] != '2') {
+                               /* ExpressMessageCat(&buf[4]);  FIXME   */
+                       } else {
+                               strcpy(final_destination, "_BASEROOM_");
+                       }
+               }
        }
-       gotoroom(bstr("_BASEROOM_"), 1);
+       smart_goto(final_destination);
 }
 
 
@@ -1097,7 +1248,7 @@ void zap(void)
  */
 void confirm_delete_room(void)
 {
-       char buf[256];
+       char buf[SIZ];
 
        serv_puts("KILL 0");
        serv_gets(buf);
@@ -1105,9 +1256,8 @@ void confirm_delete_room(void)
                display_error(&buf[4]);
                return;
        }
-       printf("HTTP/1.0 200 OK\n");
-       output_headers(1, "bottom");
-       wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
+       output_headers(1);
+       wprintf("<TABLE WIDTH=100%% BORDER=0 BGCOLOR=770000><TR><TD>");
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
        wprintf("<B>Confirm deletion of room</B>\n");
        wprintf("</FONT></TD></TR></TABLE>\n");
@@ -1116,7 +1266,7 @@ void confirm_delete_room(void)
        wprintf("<FORM METHOD=\"POST\" ACTION=\"/delete_room\">\n");
 
        wprintf("Are you sure you want to delete <FONT SIZE=+1>");
-       escputs(wc_roomname);
+       escputs(WC->wc_roomname);
        wprintf("</FONT>?<BR>\n");
 
        wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Delete\">");
@@ -1132,8 +1282,8 @@ void confirm_delete_room(void)
  */
 void delete_room(void)
 {
-       char buf[256];
-       char sc[256];
+       char buf[SIZ];
+       char sc[SIZ];
 
        strcpy(sc, bstr("sc"));
 
@@ -1146,6 +1296,6 @@ void delete_room(void)
        if (buf[0] != '2') {
                display_error(&buf[4]);
        } else {
-               gotoroom("_BASEROOM_", 1);
+               smart_goto("_BASEROOM_");
        }
 }