* New UI for mailing list setup
authorArt Cancro <ajc@citadel.org>
Tue, 24 Jul 2001 13:17:55 +0000 (13:17 +0000)
committerArt Cancro <ajc@citadel.org>
Tue, 24 Jul 2001 13:17:55 +0000 (13:17 +0000)
* rooms.c: code cleanup
* docs update

15 files changed:
citadel/ChangeLog
citadel/citadel.c
citadel/citadel.rc
citadel/commands.c
citadel/docs/inetmailsetup.txt
citadel/docs/inetmailsetupmx.txt
citadel/docs/network.txt
citadel/messages.h
citadel/rooms.c
citadel/routines2.c
citadel/routines2.h
citadel/serv_network.c
citadel/techdoc/delivery-list.txt
citadel/techdoc/netconfigs.txt
citadel/techdoc/session.txt

index 10a862f972946c9c052df16d9626c434f9e4baeb..83b12416394f8fcd7b41ee0805a9b206890d8edf 100644 (file)
@@ -1,4 +1,9 @@
  $Log$
+ Revision 580.6  2001/07/24 13:17:54  ajc
+ * New UI for mailing list setup
+ * rooms.c: code cleanup
+ * docs update
+
  Revision 580.5  2001/07/20 23:48:23  nbryant
  fix build on solaris, check default install location for db 3.2, and silence
  gcc 3.0
@@ -2578,4 +2583,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import 
-
index c25589047694e30ff86fb3b7730898034dc13339..2c89ac2f89a307604c533974fe5d456dc66fb1b1 100644 (file)
@@ -1383,6 +1383,10 @@ PWOK:
                                        }
                                }
 
+                       case 87:
+                               mailing_list_management();
+                               break;
+
                        case 6:
                                gotonext();
                                break;
index 654a1a14b08b5305170c9a17cced8dda5ab3f1b8..cefea1279ae93aef47ca23e22f07b009aaac2b19 100644 (file)
@@ -180,6 +180,7 @@ cmd=82,2,&.,&Aide,&System configuration,&Internet
 cmd=83,2,&.,&Aide,&System configuration,check &Message base
 cmd=85,2,&.,&Aide,&Terminate server,&Now
 cmd=86,2,&.,&Aide,&Terminate server,&Scheduled
+cmd=87,1,&.,&Aide,mailing &List management
 
 cmd=29,0,&.,&Terminate,and &Quit
 cmd=30,0,&.,&Terminate,and &Stay online
index f10b1aa213a4119b653503c1b509fbe93e1ecb33..75399ca1b59fc960442cabe831f620a26c5467f6 100644 (file)
@@ -1037,22 +1037,22 @@ int getcmd(char *argbuf)
                }
 
                if (ch == '?') {
-                       printf("\rOne of ...                         \n");
+                       pprintf("\rOne of ...                         \n");
                        for (cptr = cmdlist; cptr != NULL; cptr = cptr->next) {
                                if (cmdmatch(cmdbuf, cptr, cmdpos)) {
                                        for (a = 0; a < 5; ++a) {
-                                               printf("%s ", cmd_expand(cptr->c_keys[a], 1));
+                                               pprintf("%s ", cmd_expand(cptr->c_keys[a], 1));
                                        }
-                                       printf("\n");
+                                       pprintf("\n");
                                }
                        }
 
-                       printf("\n%s%c ", room_name, room_prompt(room_flags));
+                       pprintf("\n%s%c ", room_name, room_prompt(room_flags));
                        got = 0;
                        for (cptr = cmdlist; cptr != NULL; cptr = cptr->next) {
                                if ((got == 0) && (cmdmatch(cmdbuf, cptr, cmdpos))) {
                                        for (a = 0; a < cmdpos; ++a) {
-                                               printf("%s ",
+                                               pprintf("%s ",
                                                       cmd_expand(cptr->c_keys[a], 0));
                                        }
                                        got = 1;
index 612125da8ccef898ef3f6edf551fae4893a560f0..c93fb41f9fe16df90868ebed21273735c228d4a1 100644 (file)
@@ -5,7 +5,7 @@ capable system. Once you are through with this document you should be able to
 have your users send mail from, and receive mail to 
 systemname@system.citadel.org. For example to send e-mail to a user at
 Uncensored! BBS via e-mail you would do the following:
-mail Patriot@uncnsrd.citadel.org 
+mail patriot@uncensored.citadel.org 
 
 To set this up is almost insanely simple. 
 
@@ -29,12 +29,12 @@ bbs e-mail, which is described in inetmailsetupmx.txt.
      
 If you get a 'connection refused' message when you telnet to port 25 there's 
 nothing running and you should be able to continue. You might also want to
-turn off pop (try the above test substituting 110 for 25) and use
-citadel's pop server.
+turn off POP (try the above test substituting 110 for 25) and IMAP (port 143)
+and use Citadel's POP and IMAP services.
 
-This pop server will ONLY allow pop'ing of mail for your BBS users.
+The POP and IMAP services will ONLY allow retrieval of mail for Citadel users.
 For those of you who are running some kind of mail transport agent
-(as Pixel is, above) or  pop server, the following will show how to remove
+(as Pixel is, above) or POP server, the following will show how to remove
 it from a RedHat Linux system:
 
 
@@ -48,7 +48,7 @@ it from a RedHat Linux system:
           You can either reboot or /etc/rc.d/init.d/sendmail stop, OR do a
           ps and kill sendmail manually. Your method of choice is up to you.
 
-                             Removing Pop 
+                             Removing POP and IMAP
 
           cd /etc and edit inetd.conf. Look for a few lines similar to:
 
index e43a041883b1df101eaa07ef8f92bd442ce47740..19e5ab3f70670ab8ec393b440eaf6695d742eea9 100644 (file)
@@ -52,12 +52,12 @@ them to this document.
      bbs.pixel.citadel.org   preference = 10, mail exchanger = pixel.citadel.org
      citadel.org     nameserver = linux.compucomis.net
      citadel.org     nameserver = linux2.compucomis.net
-     citadel.org     nameserver = uncnsrd.mt-kisco.ny.us
+     citadel.org     nameserver = uncensored.citadel.org
      citadel.org     nameserver = mansrv.manhasset.techsoftwareinc.com
      pixel.citadel.org       internet address = 207.245.90.41
      linux.compucomis.net    internet address = 207.8.143.10
      linux2.compucomis.net   internet address = 207.8.143.13
-     uncnsrd.mt-kisco.ny.us  internet address = 168.100.205.221
+     uncensored.citadel.org  internet address = 66.9.37.38
      >
 
      As you can see pixel.citadel.org is listed as a mail exchanger for
index d8cca7bdf81fba54f2b8ce227e7e6b65b6aab4f9..d5732f5f280b6dd559609d71efcb72f88486742a 100644 (file)
@@ -102,25 +102,10 @@ handle incoming messages only.
    
   USING CITADEL/UX AS YOUR LOCAL E-MAIL SYSTEM
    
-   To use Citadel/UX as your local mail system, simply define the "citmail"
-program as your *local* mail delivery agent.  You can plug citmail into any
-popular mail routing system, including sendmail, smail, MMDF, etc.
-
-   Once you are using citmail as your local mail delivery agent, all users
-on your BBS may receive mail.  They can use addresses like
-"my_user_name@yoursite.com" (note the spaces in the user's name are replaced
-by underscores) or "cit1234@yoursite.com" (where 1234 is the user's user
-number).
-  
-   Messages may be posted by mail if you have this program installed.  Simply
-use the prefix "room_" -- for example, a message addressed to
-"room_hot_pink_amoebas@uncnsrd.mt-kisco.ny.us would be posted in the room "Hot
-Pink Amoebas" at the target system.
-   PLEASE NOTE that for your BBS users to be able to send mail, you should
-check the mailer command at the top of "netmailer.c" to be sure that it is
-the correct mailer command for your system.  You might need a command like
-"sendmail %s" or "smail %s" depending on what MTA you're using.
+ This has changed markedly in the last few versions.  Citadel used to require
+extensive patching into your system's MTA.  Now it is a fully functional
+standalone e-mail system, complete with its own SMTP, POP3, and IMAP4
+implementations.  Please refer to "inetmailsetup.txt" for more information.
    
      
   MAIL ALIASES
@@ -251,5 +236,5 @@ disabling all incoming messages.  Obviously you don't want to do this.
    That should cover everything you need to get running. By the way, gateway
 software for StoneHenge and NYTI FordBoard systems is available upon special
 request.  And, a Cit86Net gateway is now available.  For the latest version
-of this program, or to leave comments/suggestions, call my board  -  
-UNCENSORED! BBS at (914) 244-3252 (modem) or uncnsrd.mt-kisco.ny.us (Internet).
+of this program, or to leave comments/suggestions, visit UNCENSORED! BBS at
+uncensored.citadel.org.
index 095dc6f1dbdf84bdb871eec343308c68ee6a9ed0..2c4f47e4390eb3dc611ae1e6109c1a91107b2537 100644 (file)
@@ -12,3 +12,4 @@ int make_message(char *filename,      /* temporary file name */
                int format_type,
                int mode);
 void citedit(FILE *);
+int file_checksum(char *filename);
index 807a5bea858b1622fa9cac320f85acbbc329b8cc..0cf641886f0a8c2b5e8fa07acd42cca4546ef65a 100644 (file)
@@ -40,7 +40,8 @@ void dotgoto(char *towhere, int display_name);
 void serv_read(char *buf, int bytes);
 void formout(char *name);
 int inkey(void);
-int fmout(int width, FILE *fp, char pagin, int height, int starting_lp, char subst);
+int fmout(int width, FILE * fp, char pagin, int height, int starting_lp,
+         char subst);
 void progress(long int curr, long int cmax);
 int pattern(char *search, char *patn);
 int file_checksum(char *filename);
@@ -68,25 +69,28 @@ extern char ugname[];
 extern char floorlist[128][SIZ];
 
 
-void load_floorlist(void) {
+void load_floorlist(void)
+{
        int a;
        char buf[SIZ];
 
-       for (a=0; a<128; ++a) floorlist[a][0] = 0;
+       for (a = 0; a < 128; ++a)
+               floorlist[a][0] = 0;
 
        serv_puts("LFLR");
        serv_gets(buf);
-       if (buf[0]!='1') {
-               strcpy(floorlist[0],"Main Floor");
+       if (buf[0] != '1') {
+               strcpy(floorlist[0], "Main Floor");
                return;
-               }
-       while (serv_gets(buf), strcmp(buf,"000")) {
-               extract(floorlist[extract_int(buf,0)],buf,1);
-               }
        }
+       while (serv_gets(buf), strcmp(buf, "000")) {
+               extract(floorlist[extract_int(buf, 0)], buf, 1);
+       }
+}
 
 
-void room_tree_list(struct roomlisting *rp) {
+void room_tree_list(struct roomlisting *rp)
+{
        static int c = 0;
        char rmname[ROOMNAMELEN];
        int f;
@@ -94,11 +98,11 @@ void room_tree_list(struct roomlisting *rp) {
        if (rp == NULL) {
                c = 1;
                return;
-               }
+       }
 
        if (rp->lnext != NULL) {
                room_tree_list(rp->lnext);
-               }
+       }
 
        if (sigcaught == 0) {
                strcpy(rmname, rp->rlname);
@@ -108,30 +112,32 @@ void room_tree_list(struct roomlisting *rp) {
                        /* line break, check the paginator */
                        pprintf("\n");
                        c = 1;
-                       }
-                       if (f & QR_MAILBOX) {
-                       color(BRIGHT_YELLOW);
-                       }
-               else if (f & QR_PRIVATE) {
+               }
+               if (f & QR_MAILBOX) {
+                       color(BRIGHT_YELLOW);
+               } else if (f & QR_PRIVATE) {
                        color(BRIGHT_RED);
-                       }
-               else {
+               } else {
                        color(DIM_WHITE);
-                       }
-               pprintf("%s",rmname);
-               if ((f & QR_DIRECTORY) && (f & QR_NETWORK)) pprintf("}  ");
-               else if (f & QR_DIRECTORY) pprintf("]  ");
-               else if (f & QR_NETWORK) pprintf(")  ");
-               else pprintf(">  ");
-               c = c + strlen(rmname) + 3;
                }
+               pprintf("%s", rmname);
+               if ((f & QR_DIRECTORY) && (f & QR_NETWORK))
+                       pprintf("}  ");
+               else if (f & QR_DIRECTORY)
+                       pprintf("]  ");
+               else if (f & QR_NETWORK)
+                       pprintf(")  ");
+               else
+                       pprintf(">  ");
+               c = c + strlen(rmname) + 3;
+       }
 
        if (rp->rnext != NULL) {
                room_tree_list(rp->rnext);
-               }
+       }
 
        free(rp);
-       }
+}
 
 
 /* 
@@ -139,15 +145,22 @@ void room_tree_list(struct roomlisting *rp) {
  */
 int rordercmp(struct roomlisting *r1, struct roomlisting *r2)
 {
-       if ((r1==NULL)&&(r2==NULL)) return(0);
-       if (r1==NULL) return(-1);
-       if (r2==NULL) return(1);
-       if (r1->rlfloor < r2->rlfloor) return(-1);
-       if (r1->rlfloor > r2->rlfloor) return(1);
-       if (r1->rlorder < r2->rlorder) return(-1);
-       if (r1->rlorder > r2->rlorder) return(1);
-       return(0);
-       }
+       if ((r1 == NULL) && (r2 == NULL))
+               return (0);
+       if (r1 == NULL)
+               return (-1);
+       if (r2 == NULL)
+               return (1);
+       if (r1->rlfloor < r2->rlfloor)
+               return (-1);
+       if (r1->rlfloor > r2->rlfloor)
+               return (1);
+       if (r1->rlorder < r2->rlorder)
+               return (-1);
+       if (r1->rlorder > r2->rlorder)
+               return (1);
+       return (0);
+}
 
 
 /*
@@ -165,7 +178,9 @@ void listrms(char *variety)
        /* Ask the server for a room list */
        serv_puts(variety);
        serv_gets(buf);
-       if (buf[0]!='1') return;
+       if (buf[0] != '1') {
+               return;
+       }
        while (serv_gets(buf), strcmp(buf, "000")) {
                rp = malloc(sizeof(struct roomlisting));
                extract(rp->rlname, buf, 0);
@@ -178,28 +193,26 @@ void listrms(char *variety)
                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 {
-                               if (rs->rnext == NULL) {
-                                       rs->rnext = rp;
-                                       rp = NULL;
+               } 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->rnext;
+                               } else {
+                                       if (rs->rnext == NULL) {
+                                               rs->rnext = rp;
+                                               rp = NULL;
+                                       } else {
+                                               rs = rs->rnext;
                                        }
                                }
                        }
                }
+       }
 
        room_tree_list(NULL);
        room_tree_list(rl);
@@ -207,19 +220,22 @@ void listrms(char *variety)
 }
 
 
-void list_other_floors(void) {
-       int a,c;
+void list_other_floors(void)
+{
+       int a, c;
 
        c = 1;
-       for (a=0; a<128; ++a) if ((strlen(floorlist[a])>0)&&(a!=curr_floor)) {
-               if ((c + strlen(floorlist[a]) + 4) > screenwidth) {
-                       pprintf("\n");
-                       c = 1;
+       for (a = 0; a < 128; ++a) {
+               if ((strlen(floorlist[a]) > 0) && (a != curr_floor)) {
+                       if ((c + strlen(floorlist[a]) + 4) > screenwidth) {
+                               pprintf("\n");
+                               c = 1;
                        }
-               pprintf("%s:  ",floorlist[a]);
-               c = c + strlen(floorlist[a]) + 3;
+                       pprintf("%s:  ", floorlist[a]);
+                       c = c + strlen(floorlist[a]) + 3;
                }
        }
+}
 
 
 /*
@@ -241,59 +257,65 @@ void knrooms(int kn_floor_mode)
                pprintf("\n\n   No unseen messages in:\n");
                listrms("LKRO");
                pprintf("\n");
-               }
+       }
 
        if (kn_floor_mode == 1) {
                color(BRIGHT_CYAN);
                pprintf("\n   Rooms with unread messages on %s:\n",
-                       floorlist[(int)curr_floor]);
-               sprintf(buf,"LKRN %d", curr_floor);
+                       floorlist[(int) curr_floor]);
+               sprintf(buf, "LKRN %d", curr_floor);
                listrms(buf);
                color(BRIGHT_CYAN);
                pprintf("\n\n   Rooms with no new messages on %s:\n",
-                       floorlist[(int)curr_floor]);
-               sprintf(buf,"LKRO %d",curr_floor);
+                       floorlist[(int) curr_floor]);
+               sprintf(buf, "LKRO %d", curr_floor);
                listrms(buf);
                color(BRIGHT_CYAN);
                pprintf("\n\n   Other floors:\n");
                list_other_floors();
                pprintf("\n");
-               }
+       }
 
        if (kn_floor_mode == 2) {
-               for (a=0; a<128; ++a) if (floorlist[a][0]!=0) {
-                       color(BRIGHT_CYAN);
-                       pprintf("\n   Rooms on %s:\n",floorlist[a]);
-                       sprintf(buf,"LKRA %d",a);
-                       listrms(buf);
-                       pprintf("\n");
+               for (a = 0; a < 128; ++a) {
+                       if (floorlist[a][0] != 0) {
+                               color(BRIGHT_CYAN);
+                               pprintf("\n   Rooms on %s:\n",
+                                       floorlist[a]);
+                               sprintf(buf, "LKRA %d", a);
+                               listrms(buf);
+                               pprintf("\n");
                        }
                }
-       
+       }
+
        color(DIM_WHITE);
        IFNEXPERT hit_any_key();
-       }
+}
 
 
-void listzrooms(void) {                /* list public forgotten rooms */
+void listzrooms(void)
+{                              /* list public forgotten rooms */
        color(BRIGHT_CYAN);
        pprintf("\n   Forgotten public rooms:\n");
        listrms("LZRM");
        pprintf("\n");
        color(DIM_WHITE);
        IFNEXPERT hit_any_key();
-       }
+}
 
 
 int set_room_attr(int ibuf, char *prompt, unsigned int sbit)
 {
        int a;
 
-       a = boolprompt(prompt, (ibuf&sbit));
-       ibuf=(ibuf|sbit);
-       if (!a) ibuf=(ibuf^sbit);
-       return(ibuf);
+       a = boolprompt(prompt, (ibuf & sbit));
+       ibuf = (ibuf | sbit);
+       if (!a) {
+               ibuf = (ibuf ^ sbit);
        }
+       return (ibuf);
+}
 
 
 
@@ -308,33 +330,44 @@ int select_floor(int rfloor)
        char floorstr[SIZ];
 
        if (floor_mode == 1) {
-               if (floorlist[(int)curr_floor][0]==0) load_floorlist();
+               if (floorlist[(int) curr_floor][0] == 0) {
+                       load_floorlist();
+               }
 
                do {
                        newfloor = (-1);
-                       safestrncpy(floorstr,floorlist[rfloor],sizeof floorstr);
-                       strprompt("Which floor",floorstr,SIZ);
-                       for (a=0; a<128; ++a) {
-                               if (!strcasecmp(floorstr,&floorlist[a][0]))
+                       safestrncpy(floorstr, floorlist[rfloor],
+                                   sizeof floorstr);
+                       strprompt("Which floor", floorstr, SIZ);
+                       for (a = 0; a < 128; ++a) {
+                               if (!strcasecmp
+                                   (floorstr, &floorlist[a][0]))
                                        newfloor = a;
-                               if ((newfloor<0)&&(!strncasecmp(floorstr,
-                                       &floorlist[a][0],strlen(floorstr))))
-                                               newfloor = a;
-                               if ((newfloor<0)&&(pattern(&floorlist[a][0],
-                                       floorstr)>=0)) newfloor = a;
-                               }
-                       if (newfloor<0) {
+                               if ((newfloor < 0)
+                                   &&
+                                   (!strncasecmp
+                                    (floorstr, &floorlist[a][0],
+                                     strlen(floorstr))))
+                                       newfloor = a;
+                               if ((newfloor < 0)
+                                   && (pattern(&floorlist[a][0], floorstr)
+                                       >= 0))
+                                       newfloor = a;
+                       }
+                       if (newfloor < 0) {
                                printf("\n One of:\n");
-                               for (a=0; a<128; ++a)
-                                       if (floorlist[a][0]!=0)
+                               for (a = 0; a < 128; ++a) {
+                                       if (floorlist[a][0] != 0) {
                                                printf("%s\n",
-                                                       &floorlist[a][0]);
+                                                      &floorlist[a][0]);
+                                       }
                                }
-                       } while(newfloor < 0);
-               return(newfloor);
-               }
-       return(rfloor);
+                       }
+               } while (newfloor < 0);
+               return (newfloor);
        }
+       return (rfloor);
+}
 
 
 
@@ -342,7 +375,8 @@ int select_floor(int rfloor)
 /*
  * .<A>ide <E>dit room
  */
-void editthisroom(void) {
+void editthisroom(void)
+{
        char rname[ROOMNAMELEN];
        char rpass[10];
        char rdir[15];
@@ -358,103 +392,124 @@ void editthisroom(void) {
        /* Fetch the existing room config */
        serv_puts("GETR");
        serv_gets(buf);
-       if (buf[0]!='2') {
-               printf("%s\n",&buf[4]);
+       if (buf[0] != '2') {
+               printf("%s\n", &buf[4]);
                return;
-               }
+       }
 
-       extract(rname,&buf[4],0);
-       extract(rpass,&buf[4],1);
-       extract(rdir, &buf[4],2);
-       rflags = extract_int(&buf[4],3);
-       rfloor = extract_int(&buf[4],4);
-       rorder = extract_int(&buf[4],5);
+       extract(rname, &buf[4], 0);
+       extract(rpass, &buf[4], 1);
+       extract(rdir, &buf[4], 2);
+       rflags = extract_int(&buf[4], 3);
+       rfloor = extract_int(&buf[4], 4);
+       rorder = extract_int(&buf[4], 5);
        rbump = 0;
 
        /* Fetch the name of the current room aide */
        serv_puts("GETA");
        serv_gets(buf);
-       if (buf[0]=='2') safestrncpy(raide,&buf[4],sizeof raide);
-       else strcpy(raide,"");
-       if (strlen(raide)==0) strcpy(raide,"none");
+       if (buf[0] == '2') {
+               safestrncpy(raide, &buf[4], sizeof raide);
+       }
+       else {
+               strcpy(raide, "");
+       }
+       if (strlen(raide) == 0) {
+               strcpy(raide, "none");
+       }
 
        /* Fetch the expire policy (this will silently fail on old servers,
         * resulting in "default" policy)
         */
        serv_puts("GPEX room");
        serv_gets(buf);
-       if (buf[0]=='2') {
+       if (buf[0] == '2') {
                expire_mode = extract_int(&buf[4], 0);
                expire_value = extract_int(&buf[4], 1);
-               }
+       }
 
        /* Now interact with the user. */
-       strprompt("Room name",rname,ROOMNAMELEN-1);
+       strprompt("Room name", rname, ROOMNAMELEN - 1);
 
        rfloor = select_floor(rfloor);
-       rflags = set_room_attr(rflags,"Private room",QR_PRIVATE);
-       if (rflags & QR_PRIVATE)
+       rflags = set_room_attr(rflags, "Private room", QR_PRIVATE);
+       if (rflags & QR_PRIVATE) {
                rflags = set_room_attr(rflags,
-                       "Accessible by guessing room name",QR_GUESSNAME);
+                                      "Accessible by guessing room name",
+                                      QR_GUESSNAME);
+       }
 
        /* if it's public, clear the privacy classes */
-       if ((rflags & QR_PRIVATE)==0) {
-               if (rflags & QR_GUESSNAME)  rflags = rflags - QR_GUESSNAME;
-               if (rflags & QR_PASSWORDED) rflags = rflags - QR_PASSWORDED;
+       if ((rflags & QR_PRIVATE) == 0) {
+               if (rflags & QR_GUESSNAME) {
+                       rflags = rflags - QR_GUESSNAME;
+               }
+               if (rflags & QR_PASSWORDED) {
+                       rflags = rflags - QR_PASSWORDED;
                }
+       }
 
        /* if it's private, choose the privacy classes */
-       if ( (rflags & QR_PRIVATE)
-          && ( (rflags & QR_GUESSNAME) == 0) ) {
+       if ((rflags & QR_PRIVATE)
+           && ((rflags & QR_GUESSNAME) == 0)) {
                rflags = set_room_attr(rflags,
-                       "Accessible by entering a password",QR_PASSWORDED);
-               }
-       if ( (rflags & QR_PRIVATE)
-          && ((rflags&QR_PASSWORDED)==QR_PASSWORDED) ) {
-               strprompt("Room password",rpass,9);
-               }
+                                      "Accessible by entering a password",
+                                      QR_PASSWORDED);
+       }
+       if ((rflags & QR_PRIVATE)
+           && ((rflags & QR_PASSWORDED) == QR_PASSWORDED)) {
+               strprompt("Room password", rpass, 9);
+       }
 
-       if ((rflags&QR_PRIVATE)==QR_PRIVATE) {
-               rbump = boolprompt("Cause current users to forget room", 0);
-               }
+       if ((rflags & QR_PRIVATE) == QR_PRIVATE) {
+               rbump =
+                   boolprompt("Cause current users to forget room", 0);
+       }
 
-       rflags = set_room_attr(rflags,"Preferred users only",QR_PREFONLY);
-       rflags = set_room_attr(rflags,"Read-only room",QR_READONLY);
-       rflags = set_room_attr(rflags,"Directory room",QR_DIRECTORY);
-       rflags = set_room_attr(rflags,"Permanent room",QR_PERMANENT);
+       rflags =
+           set_room_attr(rflags, "Preferred users only", QR_PREFONLY);
+       rflags = set_room_attr(rflags, "Read-only room", QR_READONLY);
+       rflags = set_room_attr(rflags, "Directory room", QR_DIRECTORY);
+       rflags = set_room_attr(rflags, "Permanent room", QR_PERMANENT);
        if (rflags & QR_DIRECTORY) {
-               strprompt("Directory name",rdir,14);
-               rflags = set_room_attr(rflags,"Uploading allowed",QR_UPLOAD);
-               rflags = set_room_attr(rflags,"Downloading allowed",
-                                                               QR_DOWNLOAD);
-               rflags = set_room_attr(rflags,"Visible directory",QR_VISDIR);
-               }
-       rflags = set_room_attr(rflags,"Network shared room",QR_NETWORK);
+               strprompt("Directory name", rdir, 14);
+               rflags =
+                   set_room_attr(rflags, "Uploading allowed", QR_UPLOAD);
+               rflags =
+                   set_room_attr(rflags, "Downloading allowed",
+                                 QR_DOWNLOAD);
+               rflags =
+                   set_room_attr(rflags, "Visible directory", QR_VISDIR);
+       }
+       rflags = set_room_attr(rflags, "Network shared room", QR_NETWORK);
        rflags = set_room_attr(rflags,
-               "Automatically make all messages anonymous",QR_ANONONLY);
-       if ( (rflags & QR_ANONONLY) == 0) {
+                              "Automatically make all messages anonymous",
+                              QR_ANONONLY);
+       if ((rflags & QR_ANONONLY) == 0) {
                rflags = set_room_attr(rflags,
-                       "Ask users whether to make messages anonymous",
-                       QR_ANONOPT);
-               }
+                                      "Ask users whether to make messages anonymous",
+                                      QR_ANONOPT);
+       }
        rorder = intprompt("Listing order", rorder, 1, 127);
 
        /* Ask about the room aide */
        do {
-               strprompt("Room aide (or 'none')",raide,29);
-               if (!strcasecmp(raide,"none")) {
-                       strcpy(raide,"");
-                       strcpy(buf,"200");
-                       }
-               else {
-                       snprintf(buf,sizeof buf,"QUSR %s",raide);
+               strprompt("Room aide (or 'none')", raide, 29);
+               if (!strcasecmp(raide, "none")) {
+                       strcpy(raide, "");
+                       strcpy(buf, "200");
+               } else {
+                       snprintf(buf, sizeof buf, "QUSR %s", raide);
                        serv_puts(buf);
                        serv_gets(buf);
-                       if (buf[0]!='2') printf("%s\n",&buf[4]);
-                       }
-               } while(buf[0]!='2');
+                       if (buf[0] != '2')
+                               printf("%s\n", &buf[4]);
+               }
+       } while (buf[0] != '2');
 
-       if (!strcasecmp(raide,"none")) strcpy(raide,"");
+       if (!strcasecmp(raide, "none")) {
+               strcpy(raide, "");
+       }
 
 
        /* Angels and demons dancing in my head... */
@@ -467,8 +522,8 @@ void editthisroom(void) {
                        printf("1. Never automatically expire messages\n");
                        printf("2. Expire by message count\n");
                        printf("3. Expire by message age\n");
-                       }
-               } while((buf[0]<48)||(buf[0]>51));
+               }
+       } while ((buf[0] < 48) || (buf[0] > 51));
        expire_mode = buf[0] - 48;
 
        /* ...lunatics and monsters underneath my bed */
@@ -476,60 +531,68 @@ void editthisroom(void) {
                sprintf(buf, "%d", expire_value);
                strprompt("Keep how many messages online?", buf, 10);
                expire_value = atol(buf);
-               }
+       }
 
        if (expire_mode == 3) {
                sprintf(buf, "%d", expire_value);
                strprompt("Keep messages for how many days?", buf, 10);
                expire_value = atol(buf);
-               }
+       }
 
        /* Give 'em a chance to change their minds */
        printf("Save changes (y/n)? ");
 
-       if (yesno()==1) {
-               snprintf(buf,sizeof buf,"SETA %s",raide);
+       if (yesno() == 1) {
+               snprintf(buf, sizeof buf, "SETA %s", raide);
                serv_puts(buf);
                serv_gets(buf);
-               if (buf[0]!='2') printf("%s\n",&buf[4]);
+               if (buf[0] != '2') {
+                       printf("%s\n", &buf[4]);
+               }
 
                snprintf(buf, sizeof buf, "SPEX room|%d|%d",
-                       expire_mode, expire_value);
+                        expire_mode, expire_value);
                serv_puts(buf);
                serv_gets(buf);
 
-               snprintf(buf,sizeof buf,"SETR %s|%s|%s|%d|%d|%d|%d",
-                       rname,rpass,rdir,rflags,rbump,rfloor,rorder);
+               snprintf(buf, sizeof buf, "SETR %s|%s|%s|%d|%d|%d|%d",
+                        rname, rpass, rdir, rflags, rbump, rfloor,
+                        rorder);
                serv_puts(buf);
                serv_gets(buf);
-               printf("%s\n",&buf[4]);
-               if (buf[0]=='2') dotgoto(rname,2);
-               }
+               printf("%s\n", &buf[4]);
+               if (buf[0] == '2')
+                       dotgoto(rname, 2);
        }
+}
 
 
 /*
  * un-goto the previous room
  */
-void ungoto(void) { 
+void ungoto(void)
+{
        char buf[SIZ];
-       
-       if (!strcmp(ugname,"")) return;
-       snprintf(buf,sizeof buf,"GOTO %s",ugname);
+
+       if (!strcmp(ugname, ""))
+               return;
+       snprintf(buf, sizeof buf, "GOTO %s", ugname);
        serv_puts(buf);
        serv_gets(buf);
-       if (buf[0]!='2') {
-               printf("%s\n",&buf[4]);
+       if (buf[0] != '2') {
+               printf("%s\n", &buf[4]);
                return;
-               }
-       sprintf(buf,"SLRP %ld",uglsn);
+       }
+       sprintf(buf, "SLRP %ld", uglsn);
        serv_puts(buf);
        serv_gets(buf);
-       if (buf[0]!='2') printf("%s\n",&buf[4]);
-       safestrncpy(buf,ugname,sizeof buf);
-       strcpy(ugname,"");
-       dotgoto(buf,0);
+       if (buf[0] != '2') {
+               printf("%s\n", &buf[4]);
        }
+       safestrncpy(buf, ugname, sizeof buf);
+       strcpy(ugname, "");
+       dotgoto(buf, 0);
+}
 
 
 /* Here's the code for simply transferring the file to the client,
@@ -542,62 +605,63 @@ void download_to_local_disk(char *supplied_filename, long total_bytes)
        char buf[SIZ];
        char dbuf[4096];
        long transmitted_bytes = 0L;
-       long aa,bb;
+       long aa, bb;
        FILE *savefp;
        int broken = 0;
        int packet;
        char filename[SIZ];
 
        strcpy(filename, supplied_filename);
-       if (strlen(filename)==0) {
+       if (strlen(filename) == 0) {
                newprompt("Filename: ", filename, 250);
-               }
+       }
 
-       printf("Enter the name of the directory to save '%s'\n",
-               filename);
+       printf("Enter the name of the directory to save '%s'\n", filename);
        printf("to, or press return for the current directory.\n");
        newprompt("Directory: ", dbuf, sizeof dbuf);
-       if (strlen(dbuf)==0) strcpy(dbuf,".");
-       strcat(dbuf,"/");
-       strcat(dbuf,filename);
-       
-       savefp = fopen(dbuf,"w");
+       if (strlen(dbuf) == 0)
+               strcpy(dbuf, ".");
+       strcat(dbuf, "/");
+       strcat(dbuf, filename);
+
+       savefp = fopen(dbuf, "w");
        if (savefp == NULL) {
-               printf("Cannot open '%s': %s\n",dbuf,strerror(errno));
+               printf("Cannot open '%s': %s\n", dbuf, strerror(errno));
                /* close the download file at the server */
                serv_puts("CLOS");
                serv_gets(buf);
-               if (buf[0]!='2') {
-                       printf("%s\n",&buf[4]);
-                       }
-               return;
+               if (buf[0] != '2') {
+                       printf("%s\n", &buf[4]);
                }
-       progress(0,total_bytes);
-       while ( (transmitted_bytes < total_bytes) && (broken == 0) ) {
+               return;
+       }
+       progress(0, total_bytes);
+       while ((transmitted_bytes < total_bytes) && (broken == 0)) {
                bb = total_bytes - transmitted_bytes;
                aa = ((bb < 4096) ? bb : 4096);
-               sprintf(buf,"READ %ld|%ld",transmitted_bytes,aa);
+               sprintf(buf, "READ %ld|%ld", transmitted_bytes, aa);
                serv_puts(buf);
                serv_gets(buf);
-               if (buf[0]!='6') {
-                       printf("%s\n",&buf[4]);
+               if (buf[0] != '6') {
+                       printf("%s\n", &buf[4]);
                        return;
-                       }
-               packet = extract_int(&buf[4],0);
-               serv_read(dbuf,packet);
-               if (fwrite(dbuf,packet,1,savefp) < 1) broken = 1;
-               transmitted_bytes = transmitted_bytes + (long)packet;
-               progress(transmitted_bytes,total_bytes);
                }
+               packet = extract_int(&buf[4], 0);
+               serv_read(dbuf, packet);
+               if (fwrite(dbuf, packet, 1, savefp) < 1)
+                       broken = 1;
+               transmitted_bytes = transmitted_bytes + (long) packet;
+               progress(transmitted_bytes, total_bytes);
+       }
        fclose(savefp);
        /* close the download file at the server */
        serv_puts("CLOS");
        serv_gets(buf);
-       if (buf[0]!='2') {
-               printf("%s\n",&buf[4]);
-               }
-       return;
+       if (buf[0] != '2') {
+               printf("%s\n", &buf[4]);
        }
+       return;
+}
 
 
 /*
@@ -614,7 +678,7 @@ void download(int proto)
        long total_bytes = 0L;
        char dbuf[4096];
        long transmitted_bytes = 0L;
-       long aa,bb;
+       long aa, bb;
        int packet;
        FILE *tpipe = NULL;
        int broken = 0;
@@ -622,44 +686,46 @@ void download(int proto)
        if ((room_flags & QR_DOWNLOAD) == 0) {
                printf("*** You cannot download from this room.\n");
                return;
-               }
-       
-       newprompt("Enter filename: ",filename,255);
+       }
 
-       snprintf(buf,sizeof buf,"OPEN %s",filename);
+       newprompt("Enter filename: ", filename, 255);
+
+       snprintf(buf, sizeof buf, "OPEN %s", filename);
        serv_puts(buf);
        serv_gets(buf);
-       if (buf[0]!='2') {
-               printf("%s\n",&buf[4]);
+       if (buf[0] != '2') {
+               printf("%s\n", &buf[4]);
                return;
-               }
-       total_bytes = extract_long(&buf[4],0);
+       }
+       total_bytes = extract_long(&buf[4], 0);
 
        /* Save to local disk, for folks with their own copy of the client */
        if (proto == 5) {
                download_to_local_disk(filename, total_bytes);
                return;
-               }
+       }
 
        /* Meta-download for public clients */
        printf("Fetching file from Citadel server...\n");
        mkdir(tempdir, 0700);
        snprintf(tempname, sizeof tempname, "%s/%s", tempdir, filename);
        tpipe = fopen(tempname, "wb");
-       while ( (transmitted_bytes < total_bytes) && (broken == 0) ) {
+       while ((transmitted_bytes < total_bytes) && (broken == 0)) {
                progress(transmitted_bytes, total_bytes);
                bb = total_bytes - transmitted_bytes;
                aa = ((bb < 4096) ? bb : 4096);
-               sprintf(buf,"READ %ld|%ld",transmitted_bytes,aa);
+               sprintf(buf, "READ %ld|%ld", transmitted_bytes, aa);
                serv_puts(buf);
                serv_gets(buf);
-               if (buf[0]!='6') {
-                       printf("%s\n",&buf[4]);
+               if (buf[0] != '6') {
+                       printf("%s\n", &buf[4]);
                }
-               packet = extract_int(&buf[4],0);
-               serv_read(dbuf,packet);
-               if (fwrite(dbuf,packet,1,tpipe) < 1) broken = 1;
-               transmitted_bytes = transmitted_bytes + (long)packet;
+               packet = extract_int(&buf[4], 0);
+               serv_read(dbuf, packet);
+               if (fwrite(dbuf, packet, 1, tpipe) < 1) {
+                       broken = 1;
+               }
+               transmitted_bytes = transmitted_bytes + (long) packet;
        }
        fclose(tpipe);
        progress(transmitted_bytes, total_bytes);
@@ -667,30 +733,39 @@ void download(int proto)
        /* close the download file at the server */
        serv_puts("CLOS");
        serv_gets(buf);
-       if (buf[0]!='2') {
-               printf("%s\n",&buf[4]);
+       if (buf[0] != '2') {
+               printf("%s\n", &buf[4]);
        }
 
-       if (proto==0)           sprintf(transmit_cmd, "SHELL=/dev/null; export SHELL; TERM=dumb; export TERM; exec more -d <%s",tempname);
-       else if (proto==1)      sprintf(transmit_cmd, "exec sx %s", tempname);
-       else if (proto==3)      sprintf(transmit_cmd, "exec sb %s", tempname);
-       else if (proto==4)      sprintf(transmit_cmd, "exec sz %s", tempname);
-       else                    sprintf(transmit_cmd, "exec cat %s", tempname);
+       if (proto == 0) {
+               sprintf(transmit_cmd,
+                       "SHELL=/dev/null; export SHELL; TERM=dumb; export TERM; exec more -d <%s",
+                       tempname);
+       }
+       else if (proto == 1)
+               sprintf(transmit_cmd, "exec sx %s", tempname);
+       else if (proto == 3)
+               sprintf(transmit_cmd, "exec sb %s", tempname);
+       else if (proto == 4)
+               sprintf(transmit_cmd, "exec sz %s", tempname);
+       else
+               sprintf(transmit_cmd, "exec cat %s", tempname);
 
        sttybbs(SB_RESTORE);
        system(transmit_cmd);
        sttybbs(SB_NO_INTR);
-       
+
        /* clean up the temporary directory */
        nukedir(tempdir);
-       putc(7,stdout);
+       putc(7, stdout);
 }
 
 
 /*
  * read directory of this room
  */
-void roomdir(void) {
+void roomdir(void)
+{
        char flnm[SIZ];
        char flsz[32];
        char comment[SIZ];
@@ -698,216 +773,245 @@ void roomdir(void) {
 
        serv_puts("RDIR");
        serv_gets(buf);
-       if (buf[0]!='1') {
-               pprintf("%s\n",&buf[4]);
+       if (buf[0] != '1') {
+               pprintf("%s\n", &buf[4]);
                return;
-               }
+       }
 
-       extract(comment,&buf[4],0);
-       extract(flnm,&buf[4],1);
-       pprintf("\nDirectory of %s on %s\n",flnm,comment);
+       extract(comment, &buf[4], 0);
+       extract(flnm, &buf[4], 1);
+       pprintf("\nDirectory of %s on %s\n", flnm, comment);
        pprintf("-----------------------\n");
-       while (serv_gets(buf), strcmp(buf,"000")) {
-               extract(flnm,buf,0);
-               extract(flsz,buf,1);
-               extract(comment,buf,2);
-               if (strlen(flnm)<=14)
-                       pprintf("%-14s %8s %s\n",flnm,flsz,comment);
+       while (serv_gets(buf), strcmp(buf, "000")) {
+               extract(flnm, buf, 0);
+               extract(flsz, buf, 1);
+               extract(comment, buf, 2);
+               if (strlen(flnm) <= 14)
+                       pprintf("%-14s %8s %s\n", flnm, flsz, comment);
                else
-                       pprintf("%s\n%14s %8s %s\n",flnm,"",flsz,comment);
-               }
+                       pprintf("%s\n%14s %8s %s\n", flnm, "", flsz,
+                               comment);
        }
+}
 
 
 /*
  * add a user to a private room
  */
-void invite(void) {
-       char aaa[31],bbb[SIZ];
-
-     /* Because kicking people out of public rooms now sets a LOCKOUT
-      * flag, we need to be able to invite people into public rooms
-      * in order to let them back in again.
-      *        - cough
-      */
-
-     /*
-      * if ((room_flags & QR_PRIVATE)==0) {
-      *        printf("This is not a private room.\n");
-      *        return;
-      *        }
-      */
-
-       newprompt("Name of user? ",aaa,30);
-       if (aaa[0]==0) return;
-
-       snprintf(bbb,sizeof bbb,"INVT %s",aaa);
+void invite(void)
+{
+       char aaa[31], bbb[SIZ];
+
+       /* Because kicking people out of public rooms now sets a LOCKOUT
+        * flag, we need to be able to invite people into public rooms
+        * in order to let them back in again.
+        *        - cough
+        */
+
+       /*
+        * if ((room_flags & QR_PRIVATE)==0) {
+        *         printf("This is not a private room.\n");
+        *         return;
+        * }
+        */
+
+       newprompt("Name of user? ", aaa, 30);
+       if (aaa[0] == 0)
+               return;
+
+       snprintf(bbb, sizeof bbb, "INVT %s", aaa);
        serv_puts(bbb);
        serv_gets(bbb);
-       printf("%s\n",&bbb[4]);
-       }
+       printf("%s\n", &bbb[4]);
+}
 
 
 /*
  * kick a user out of a room
  */
-void kickout(void) {
-       char aaa[31],bbb[SIZ];
-
-       newprompt("Name of user? ",aaa,30);
-       if (aaa[0]==0) return;
+void kickout(void)
+{
+       char username[31], cmd[SIZ];
 
-       snprintf(bbb,sizeof bbb,"KICK %s",aaa);
-       serv_puts(bbb);
-       serv_gets(bbb);
-       printf("%s\n",&bbb[4]);
+       newprompt("Name of user? ", username, 30);
+       if (strlen(username) == 0) {
+               return;
        }
 
+       snprintf(cmd, sizeof cmd, "KICK %s", username);
+       serv_puts(cmd);
+       serv_gets(cmd);
+       printf("%s\n", &cmd[4]);
+}
+
 
 /*
  * aide command: kill the current room
  */
-void killroom(void) {
+void killroom(void)
+{
        char aaa[100];
 
        serv_puts("KILL 0");
        serv_gets(aaa);
-       if (aaa[0]!='2') {
-               printf("%s\n",&aaa[4]);
+       if (aaa[0] != '2') {
+               printf("%s\n", &aaa[4]);
                return;
-               }
+       }
 
        printf("Are you sure you want to kill this room? ");
-       if (yesno()==0) return;
+       if (yesno() == 0)
+               return;
 
        serv_puts("KILL 1");
        serv_gets(aaa);
-       printf("%s\n",&aaa[4]);
-       if (aaa[0]!='2') return;
-       dotgoto("_BASEROOM_",0);
-       }
+       printf("%s\n", &aaa[4]);
+       if (aaa[0] != '2')
+               return;
+       dotgoto("_BASEROOM_", 0);
+}
 
-void forget(void) {    /* forget the current room */
+void forget(void)
+{                              /* forget the current room */
        char cmd[SIZ];
 
        printf("Are you sure you want to forget this room? ");
-       if (yesno()==0) return;
+       if (yesno() == 0)
+               return;
 
        serv_puts("FORG");
        serv_gets(cmd);
-       if (cmd[0]!='2') {
-               printf("%s\n",&cmd[4]);
+       if (cmd[0] != '2') {
+               printf("%s\n", &cmd[4]);
                return;
-               }
+       }
 
        /* now return to the lobby */
-       dotgoto("_BASEROOM_",0);
-       }
+       dotgoto("_BASEROOM_", 0);
+}
 
 
 /*
  * create a new room
  */
-void entroom(void) {
+void entroom(void)
+{
        char cmd[SIZ];
        char new_room_name[ROOMNAMELEN];
        int new_room_type;
        char new_room_pass[10];
        int new_room_floor;
-       int a,b;
+       int a, b;
 
        serv_puts("CRE8 0");
        serv_gets(cmd);
-       
-       if (cmd[0]!='2') {
-               printf("%s\n",&cmd[4]);
+
+       if (cmd[0] != '2') {
+               printf("%s\n", &cmd[4]);
+               return;
+       }
+
+       newprompt("Name for new room? ", new_room_name, ROOMNAMELEN - 1);
+       if (strlen(new_room_name) == 0) {
                return;
+       }
+       for (a = 0; a < strlen(new_room_name); ++a) {
+               if (new_room_name[a] == '|') {
+                       new_room_name[a] = '_';
                }
-       
-       newprompt("Name for new room? ",new_room_name,ROOMNAMELEN-1);
-       if (strlen(new_room_name)==0) return;
-       for (a=0; a<strlen(new_room_name); ++a)
-               if (new_room_name[a] == '|') new_room_name[a]='_';
+       }
 
-       new_room_floor = select_floor((int)curr_floor);
+       new_room_floor = select_floor((int) curr_floor);
 
        IFNEXPERT formout("roomaccess");
        do {
-               printf( "<?>Help\n<1>Public room\n<2>Guess-name room\n"
-                       "<3>Passworded room\n<4>Invitation-only room\n"
-                       "<5>Personal room\n");
+               printf("<?>Help\n<1>Public room\n<2>Guess-name room\n"
+                      "<3>Passworded room\n<4>Invitation-only room\n"
+                      "<5>Personal room\n");
                printf("Enter room type: ");
                do {
-                       b=inkey();
-                       } while (((b<'1')||(b>'5')) && (b!='?'));
-               if (b=='?') {
+                       b = inkey();
+               } while (((b < '1') || (b > '5')) && (b != '?'));
+               if (b == '?') {
                        printf("?\n");
                        formout("roomaccess");
-                       }
-               } while ((b<'1')||(b>'5'));
-       b=b-48;
-       printf("%d\n",b);
-       new_room_type = b - 1;
-       if (new_room_type==2) {
-               newprompt("Enter a room password: ",new_room_pass,9);
-               for (a=0; a<strlen(new_room_pass); ++a)
-                       if (new_room_pass[a] == '|') new_room_pass[a]='_';
                }
-       else strcpy(new_room_pass,"");
-
-       printf("\042%s\042, a",new_room_name);
-       if (b==1) printf(" public room.");
-       if (b==2) printf(" guess-name room.");
-       if (b==3) printf(" passworded room, password: %s",new_room_pass);
-       if (b==4) printf("n invitation-only room.");
-       if (b==5) printf(" personal room.");
+       } while ((b < '1') || (b > '5'));
+       b = b - 48;
+       printf("%d\n", b);
+       new_room_type = b - 1;
+       if (new_room_type == 2) {
+               newprompt("Enter a room password: ", new_room_pass, 9);
+               for (a = 0; a < strlen(new_room_pass); ++a)
+                       if (new_room_pass[a] == '|')
+                               new_room_pass[a] = '_';
+       } else {
+               strcpy(new_room_pass, "");
+       }
+
+       printf("\042%s\042, a", new_room_name);
+       if (b == 1)
+               printf(" public room.");
+       if (b == 2)
+               printf(" guess-name room.");
+       if (b == 3)
+               printf(" passworded room, password: %s", new_room_pass);
+       if (b == 4)
+               printf("n invitation-only room.");
+       if (b == 5)
+               printf(" personal room.");
        printf("\nInstall it? (y/n) : ");
-       a=yesno();
-       if (a==0) return;
+       if (yesno() == 0) {
+               return;
+       }
 
        snprintf(cmd, sizeof cmd, "CRE8 1|%s|%d|%s|%d", new_room_name,
-               new_room_type, new_room_pass, new_room_floor);
+                new_room_type, new_room_pass, new_room_floor);
        serv_puts(cmd);
        serv_gets(cmd);
-       if (cmd[0]!='2') {
-               printf("%s\n",&cmd[4]);
+       if (cmd[0] != '2') {
+               printf("%s\n", &cmd[4]);
                return;
-               }
+       }
 
        /* command succeeded... now GO to the new room! */
-       dotgoto(new_room_name,0);
-       }
+       dotgoto(new_room_name, 0);
+}
 
 
 
-void readinfo(void) {  /* read info file for current room */
+void readinfo(void)
+{                              /* read info file for current room */
        char cmd[SIZ];
-       
-       sprintf(cmd,"RINF");
+
+       sprintf(cmd, "RINF");
        serv_puts(cmd);
        serv_gets(cmd);
 
-       if (cmd[0]!='1') return;
-
-       fmout(screenwidth,NULL,
-               ((userflags & US_PAGINATOR) ? 1 : 0),
-               screenheight,0,1);
+       if (cmd[0] != '1') {
+               return;
        }
 
+       fmout(screenwidth, NULL,
+             ((userflags & US_PAGINATOR) ? 1 : 0), screenheight, 0, 1);
+}
+
 
 /*
  * <W>ho knows room...
  */
-void whoknows(void) {
+void whoknows(void)
+{
        char buf[SIZ];
        serv_puts("WHOK");
        serv_gets(buf);
-       if (buf[0]!='1') {
-               pprintf("%s\n",&buf[5]);
+       if (buf[0] != '1') {
+               pprintf("%s\n", &buf[5]);
                return;
        }
-       while (serv_gets(buf), strncmp(buf,"000",3)) {
-               if (sigcaught==0) pprintf("%s\n",buf);
+       while (serv_gets(buf), strncmp(buf, "000", 3)) {
+               if (sigcaught == 0)
+                       pprintf("%s\n", buf);
        }
 }
 
@@ -916,159 +1020,165 @@ void do_edit(char *desc, char *read_cmd, char *check_cmd, char *write_cmd)
 {
        FILE *fp;
        char cmd[SIZ];
-       int b,cksum,editor_exit;
+       int b, cksum, editor_exit;
 
 
-       if (strlen(editor_path)==0) {
-               printf("Do you wish to re-enter %s? ",desc);
-               if (yesno()==0) return;
-               }
+       if (strlen(editor_path) == 0) {
+               printf("Do you wish to re-enter %s? ", desc);
+               if (yesno() == 0)
+                       return;
+       }
 
-       fp = fopen(temp,"w");
+       fp = fopen(temp, "w");
        fclose(fp);
 
        serv_puts(check_cmd);
        serv_gets(cmd);
-       if (cmd[0]!='2') {
-               printf("%s\n",&cmd[4]);
+       if (cmd[0] != '2') {
+               printf("%s\n", &cmd[4]);
                return;
-               }
+       }
 
-       if (strlen(editor_path)>0) {
+       if (strlen(editor_path) > 0) {
                serv_puts(read_cmd);
                serv_gets(cmd);
-               if (cmd[0]=='1') {
-                       fp = fopen(temp,"w");
-                       while (serv_gets(cmd), strcmp(cmd,"000")) {
-                               fprintf(fp,"%s\n",cmd);
-                               }
-                       fclose(fp);
+               if (cmd[0] == '1') {
+                       fp = fopen(temp, "w");
+                       while (serv_gets(cmd), strcmp(cmd, "000")) {
+                               fprintf(fp, "%s\n", cmd);
                        }
+                       fclose(fp);
                }
+       }
 
        cksum = file_checksum(temp);
 
-       if (strlen(editor_path)>0) {
-               editor_pid=fork();
-               if (editor_pid==0) {
-                        chmod(temp,0600);
+       if (strlen(editor_path) > 0) {
+               editor_pid = fork();
+               if (editor_pid == 0) {
+                       chmod(temp, 0600);
                        sttybbs(SB_RESTORE);
-                       execlp(editor_path,editor_path,temp,NULL);
+                       execlp(editor_path, editor_path, temp, NULL);
                        exit(1);
-                       }
-               if (editor_pid>0) do {
-                       editor_exit = 0;
-                       b=wait(&editor_exit);
-                       } while((b!=editor_pid)&&(b>=0));
+               }
+               if (editor_pid > 0)
+                       do {
+                               editor_exit = 0;
+                               b = wait(&editor_exit);
+                       } while ((b != editor_pid) && (b >= 0));
                editor_pid = (-1);
                printf("Executed %s\n", editor_path);
                sttybbs(0);
-               }
-       else {
-               printf("Entering %s.  ",desc);
+       } else {
+               printf("Entering %s.  ", desc);
                printf("Press return twice when finished.\n");
-               fp=fopen(temp,"r+");
+               fp = fopen(temp, "r+");
                citedit(fp);
                fclose(fp);
-               }
+       }
 
        if (file_checksum(temp) == cksum) {
                printf("*** Aborted.\n");
-               }
+       }
 
        else {
                serv_puts(write_cmd);
                serv_gets(cmd);
-               if (cmd[0]!='4') {
-                       printf("%s\n",&cmd[4]);
+               if (cmd[0] != '4') {
+                       printf("%s\n", &cmd[4]);
                        return;
-                       }
+               }
 
-               fp=fopen(temp,"r");
-               while (fgets(cmd,SIZ-1,fp)!=NULL) {
-                       cmd[strlen(cmd)-1] = 0;
+               fp = fopen(temp, "r");
+               while (fgets(cmd, SIZ - 1, fp) != NULL) {
+                       cmd[strlen(cmd) - 1] = 0;
                        serv_puts(cmd);
-                       }
+               }
                fclose(fp);
                serv_puts("000");
-               }
+       }
 
        unlink(temp);
-       }
+}
 
 
-void enterinfo(void) {         /* edit info file for current room */
-       do_edit("the Info file for this room","RINF","EINF 0","EINF 1");
-       }
+void enterinfo(void)
+{                              /* edit info file for current room */
+       do_edit("the Info file for this room", "RINF", "EINF 0", "EINF 1");
+}
 
-void enter_bio(void) {
+void enter_bio(void)
+{
        char cmd[SIZ];
-       snprintf(cmd,sizeof cmd,"RBIO %s",fullname);
-       do_edit("your Bio",cmd,"NOOP","EBIO");
-       }
+       snprintf(cmd, sizeof cmd, "RBIO %s", fullname);
+       do_edit("your Bio", cmd, "NOOP", "EBIO");
+}
 
 /*
  * create a new floor
  */
-void create_floor(void) {
+void create_floor(void)
+{
        char buf[SIZ];
        char newfloorname[SIZ];
 
        serv_puts("CFLR xx|0");
        serv_gets(buf);
-       if (buf[0]!='2') {
-               printf("%s\n",&buf[4]);
+       if (buf[0] != '2') {
+               printf("%s\n", &buf[4]);
                return;
-               }
+       }
 
-       newprompt("Name for new floor: ",newfloorname,255);
-       snprintf(buf,sizeof buf,"CFLR %s|1",newfloorname);
+       newprompt("Name for new floor: ", newfloorname, 255);
+       snprintf(buf, sizeof buf, "CFLR %s|1", newfloorname);
        serv_puts(buf);
        serv_gets(buf);
-       if (buf[0]=='2') {
+       if (buf[0] == '2') {
                printf("Floor has been created.\n");
-               }
-       else {
-               printf("%s\n",&buf[4]);
-               }
+       } else {
+               printf("%s\n", &buf[4]);
        }
+}
 
 /*
  * edit the current floor
  */
-void edit_floor(void) {
+void edit_floor(void)
+{
        char buf[SIZ];
        int expire_mode = 0;
        int expire_value = 0;
 
-       if (floorlist[(int)curr_floor][0]==0) load_floorlist();
+       if (floorlist[(int) curr_floor][0] == 0)
+               load_floorlist();
 
        /* Fetch the expire policy (this will silently fail on old servers,
         * resulting in "default" policy)
         */
        serv_puts("GPEX floor");
        serv_gets(buf);
-       if (buf[0]=='2') {
+       if (buf[0] == '2') {
                expire_mode = extract_int(&buf[4], 0);
                expire_value = extract_int(&buf[4], 1);
-               }
+       }
 
        /* Interact with the user */
-       strprompt("Floor name",&floorlist[(int)curr_floor][0],255);
+       strprompt("Floor name", &floorlist[(int) curr_floor][0], 255);
 
        /* Angels and demons dancing in my head... */
        do {
                sprintf(buf, "%d", expire_mode);
-               strprompt("Floor default essage expire policy (? for list)",
-                       buf, 1);
+               strprompt
+                   ("Floor default essage expire policy (? for list)",
+                    buf, 1);
                if (buf[0] == '?') {
                        printf("\n");
                        printf("0. Use the system default\n");
                        printf("1. Never automatically expire messages\n");
                        printf("2. Expire by message count\n");
                        printf("3. Expire by message age\n");
-                       }
-               } while((buf[0]<48)||(buf[0]>51));
+               }
+       } while ((buf[0] < 48) || (buf[0] > 51));
        expire_mode = buf[0] - 48;
 
        /* ...lunatics and monsters underneath my bed */
@@ -1076,27 +1186,27 @@ void edit_floor(void) {
                sprintf(buf, "%d", expire_value);
                strprompt("Keep how many messages online?", buf, 10);
                expire_value = atol(buf);
-               }
+       }
 
        if (expire_mode == 3) {
                sprintf(buf, "%d", expire_value);
                strprompt("Keep messages for how many days?", buf, 10);
                expire_value = atol(buf);
-               }
+       }
 
        /* Save it */
        snprintf(buf, sizeof buf, "SPEX floor|%d|%d",
-               expire_mode, expire_value);
+                expire_mode, expire_value);
        serv_puts(buf);
        serv_gets(buf);
 
-       snprintf(buf,sizeof buf,"EFLR %d|%s",curr_floor,
-                &floorlist[(int)curr_floor][0]);
+       snprintf(buf, sizeof buf, "EFLR %d|%s", curr_floor,
+                &floorlist[(int) curr_floor][0]);
        serv_puts(buf);
        serv_gets(buf);
-       printf("%s\n",&buf[4]);
+       printf("%s\n", &buf[4]);
        load_floorlist();
-       }
+}
 
 
 
@@ -1104,28 +1214,31 @@ void edit_floor(void) {
 /*
  * kill the current floor 
  */
-void kill_floor(void) {
-       int floornum_to_delete,a;
+void kill_floor(void)
+{
+       int floornum_to_delete, a;
        char buf[SIZ];
 
-       if (floorlist[(int)curr_floor][0]==0) load_floorlist();
+       if (floorlist[(int) curr_floor][0] == 0)
+               load_floorlist();
        do {
                floornum_to_delete = (-1);
                printf("(Press return to abort)\n");
-               newprompt("Delete which floor? ",buf,255);
-               if (strlen(buf)==0) return;
-               for (a=0; a<128; ++a)
-                       if (!strcasecmp(&floorlist[a][0],buf))
+               newprompt("Delete which floor? ", buf, 255);
+               if (strlen(buf) == 0)
+                       return;
+               for (a = 0; a < 128; ++a)
+                       if (!strcasecmp(&floorlist[a][0], buf))
                                floornum_to_delete = a;
                if (floornum_to_delete < 0) {
                        printf("No such floor.  Select one of:\n");
-                       for (a=0; a<128; ++a)
-                               if (floorlist[a][0]!=0)
-                                       printf("%s\n",&floorlist[a][0]);
-                       }
-               } while (floornum_to_delete < 0);
-       sprintf(buf,"KFLR %d|1",floornum_to_delete);
+                       for (a = 0; a < 128; ++a)
+                               if (floorlist[a][0] != 0)
+                                       printf("%s\n", &floorlist[a][0]);
+               }
+       } while (floornum_to_delete < 0);
+       sprintf(buf, "KFLR %d|1", floornum_to_delete);
        serv_puts(buf);
        serv_gets(buf);
-       printf("%s\n",&buf[4]);
-       }
+       printf("%s\n", &buf[4]);
+}
index 0211449415c69fe7105cf24943222a57a219c678..e6deb9e4c811a60d7fb2275073d63aaa484bdbb9 100644 (file)
@@ -14,6 +14,7 @@
 #include <stdio.h>
 #include <ctype.h>
 #include <string.h>
+#include <limits.h>
 
 #if TIME_WITH_SYS_TIME
 # include <sys/time.h>
@@ -32,6 +33,7 @@
 #include <errno.h>
 #include <stdarg.h>
 #include "citadel.h"
+#include "citadel_decls.h"
 #include "routines2.h"
 #include "routines.h"
 #include "commands.h"
@@ -899,3 +901,122 @@ void do_internet_configuration(void) {
                free(recs);
        }
 }
+
+
+
+/*
+ * Edit mailing list configuration
+ */
+void mailing_list_management(void) {
+       char filename[PATH_MAX];
+       char changefile[PATH_MAX];
+       int e_ex_code;
+       pid_t editor_pid;
+       int cksum;
+       int b, i;
+       char buf[SIZ];
+       char instr[SIZ];
+       char addr[SIZ];
+       FILE *tempfp;
+       FILE *changefp;
+
+       if (strlen(editor_path) == 0) {
+               printf("You must have an external editor configured in order"
+                       " to use this function.\n");
+               return;
+       }
+
+       snprintf(filename, sizeof filename, "%s.listedit", tmpnam(NULL));
+       snprintf(changefile, sizeof changefile, "%s.listedit", tmpnam(NULL));
+
+       tempfp = fopen(filename, "w");
+       if (tempfp == NULL) {
+               printf("Cannot open %s: %s\n", filename, strerror(errno));
+               return;
+       }
+
+       fprintf(tempfp, "# Mailing list recipients for: %s\n", room_name);
+       fprintf(tempfp, "# Specify recipients one per line.\n"
+                       "\n\n");
+
+       serv_puts("GNET");
+       serv_gets(buf);
+       if (buf[0] == '1') {
+               while(serv_gets(buf), strcmp(buf, "000")) {
+                       extract(instr, buf, 0);
+                       if (!strcasecmp(instr, "listrecp")) {
+                               extract(addr, buf, 1);
+                               fprintf(tempfp, "%s\n", addr);
+                       }
+               }
+       }
+       fclose(tempfp);
+
+       e_ex_code = 1;  /* start with a failed exit code */
+       editor_pid = fork();
+       cksum = file_checksum(filename);
+       if (editor_pid == 0) {
+               chmod(filename, 0600);
+               sttybbs(SB_RESTORE);
+               execlp(editor_path, editor_path, filename, NULL);
+               exit(1);
+       }
+       if (editor_pid > 0) {
+               do {
+                       e_ex_code = 0;
+                       b = ka_wait(&e_ex_code);
+               } while ((b != editor_pid) && (b >= 0));
+       editor_pid = (-1);
+       sttybbs(0);
+       }
+
+       if (file_checksum(filename) == cksum) {
+               printf("*** Not saving changes.\n");
+               e_ex_code = 1;
+       }
+
+       if (e_ex_code == 0) {           /* Save changes */
+               changefp = fopen(changefile, "w");
+               serv_puts("GNET");
+               serv_gets(buf);
+               if (buf[0] == '1') {
+                       while(serv_gets(buf), strcmp(buf, "000")) {
+                               extract(instr, buf, 0);
+                               if (strcasecmp(instr, "listrecp")) {
+                                       fprintf(changefp, "%s\n", buf);
+                               }
+                       }
+               }
+               tempfp = fopen(filename, "r");
+               while (fgets(buf, sizeof buf, tempfp) != NULL) {
+                       for (i=0; i<strlen(buf); ++i) {
+                               if (buf[i] == '#') buf[i] = 0;
+                       }
+                       striplt(buf);
+                       if (strlen(buf) > 0) {
+                               fprintf(changefp, "listrecp|%s\n", buf);
+                       }
+               }
+               fclose(tempfp);
+               fclose(changefp);
+
+               /* now write it to the server... */
+               serv_puts("SNET");
+               serv_gets(buf);
+               if (buf[0] == '4') {
+                       changefp = fopen(changefile, "r");
+                       if (changefp != NULL) {
+                               while (fgets(buf, sizeof buf,
+                                      changefp) != NULL) {
+                                       buf[strlen(buf) - 1] = 0;
+                                       serv_puts(buf);
+                               }
+                               fclose(changefp);
+                       }
+                       serv_puts("000");
+               }
+       }
+
+       unlink(filename);               /* Delete the temporary files */
+       unlink(changefile);
+}
index 6f1ced38caccaab0250ab6ff38e06f9a557bdce7..1374c5eedd0d9eaf2b3372b9841d488077ef670e 100644 (file)
@@ -13,3 +13,4 @@ void read_bio(void);
 void cli_image_upload(char *keyname);
 int room_prompt(int qrflags);
 void do_internet_configuration(void);
+void mailing_list_management(void);
index 980160f32bdae55f623c8c61ad02dde3bb194d61..aedb73ecea3d8d979405f3edfb6677f20f8a78e2 100644 (file)
@@ -1,8 +1,10 @@
 /*
  * $Id$ 
  *
- * This module will eventually replace netproc and some of its utilities.
- * Copyright (C) 2000 by Art Cancro and others.
+ * This module will eventually replace netproc and some of its utilities.  In
+ * the meantime, it serves as a mailing list manager.
+ *
+ * Copyright (C) 2000-2001 by Art Cancro and others.
  * This code is released under the terms of the GNU General Public License.
  *
  */
@@ -115,7 +117,7 @@ void network_spool_msg(long msgnum, void *userdata) {
        struct namelist *nptr;
        int err;
        char *instr = NULL;
-       int instr_len = 0;
+       size_t instr_len = SIZ;
        struct CtdlMessage *imsg;
 
        sc = (struct SpoolControl *)userdata;
@@ -129,14 +131,37 @@ void network_spool_msg(long msgnum, void *userdata) {
        err = CtdlSaveMsgPointerInRoom(SMTP_SPOOLOUT_ROOM, msgnum, 0);
        if (err != 0) return;
 
+       /* 
+        * Figure out how big a buffer we need to allocate
+        */
+       for (nptr = sc->listrecps; nptr != NULL; nptr = nptr->next) {
+               instr_len = instr_len + strlen(nptr->name);
+       }
+
+       /*
+        * allocate...
+        */
        lprintf(9, "Generating delivery instructions\n");
-       instr_len = 4096;
        instr = mallok(instr_len);
+       if (instr == NULL) {
+               lprintf(1, "Cannot allocate %d bytes for instr...\n",
+                       instr_len);
+               abort();
+       }
        sprintf(instr,
                "Content-type: %s\n\nmsgid|%ld\nsubmitted|%ld\n"
                "bounceto|postmaster@%s\n" ,
                SPOOLMIME, msgnum, time(NULL), config.c_fqdn );
 
+       /* Generate delivery instructions for each recipient */
+       for (nptr = sc->listrecps; nptr != NULL; nptr = nptr->next) {
+               sprintf(&instr[strlen(instr)], "remote|%s|0||\n",
+                       nptr->name);
+       }
+
+       /*
+        * Generate a message from the instructions
+        */
                imsg = mallok(sizeof(struct CtdlMessage));
        memset(imsg, 0, sizeof(struct CtdlMessage));
        imsg->cm_magic = CTDLMESSAGE_MAGIC;
@@ -145,16 +170,6 @@ void network_spool_msg(long msgnum, void *userdata) {
        imsg->cm_fields['A'] = strdoop("Citadel");
        imsg->cm_fields['M'] = instr;
 
-       /* Generate delivery instructions for each recipient */
-       for (nptr = sc->listrecps; nptr != NULL; nptr = nptr->next) {
-               if (instr_len - strlen(instr) < SIZ) {
-                       instr_len = instr_len * 2;
-                       instr = reallok(instr, instr_len);
-               }
-               sprintf(&instr[strlen(instr)], "remote|%s|0||\n",
-                       nptr->name);
-       }
-
        /* Save delivery instructions in spoolout room */
        CtdlSaveMsg(imsg, "", SMTP_SPOOLOUT_ROOM, MES_LOCAL);
        CtdlFreeMessage(imsg);
@@ -169,7 +184,7 @@ void network_spool_msg(long msgnum, void *userdata) {
 /*
  * Batch up and send all outbound traffic from the current room
  */
-void network_spoolout_current_room(void) {
+void network_spoolout_room(struct quickroom *qrbuf, void *data) {
        char filename[SIZ];
        char buf[SIZ];
        char instr[SIZ];
@@ -178,6 +193,8 @@ void network_spoolout_current_room(void) {
        /* struct namelist *digestrecps = NULL; */
        struct namelist *nptr;
 
+       memcpy(&CC->quickroom, qrbuf, sizeof(struct quickroom));
+
        memset(&sc, 0, sizeof(struct SpoolControl));
        assoc_file_name(filename, &CC->quickroom, "netconfigs");
 
@@ -243,27 +260,45 @@ void network_spoolout_current_room(void) {
 }
 
 
+/*
+ * network_do_queue()
+ * 
+ * Run through the rooms doing various types of network stuff.
+ */
+void network_do_queue(void) {
+       static int doing_queue = 0;
+       static time_t last_run = 0L;
 
-/* FIXME temporary server command for batch send */
-void cmd_batc(char *argbuf) {
-       if (CtdlAccessCheck(ac_aide)) return;
+#define NETWORK_QUEUE_FREQUENCY 3600   /* one hour ... FIXME put in config */
+       /*
+        * Run no more frequently than once every n seconds
+        */
+       if ( (time(NULL) - last_run) < NETWORK_QUEUE_FREQUENCY ) return;
 
-       network_spoolout_current_room();
+       /*
+        * This is a simple concurrency check to make sure only one queue run
+        * is done at a time.  We could do this with a mutex, but since we
+        * don't really require extremely fine granularity here, we'll do it
+        * with a static variable instead.
+        */
+       if (doing_queue) return;
+       doing_queue = 1;
+       last_run = time(NULL);
 
-       cprintf("%d FIXME cmd_batc() ok\n", OK);
+       /* 
+        * Go ahead and run the queue
+        */
+       lprintf(7, "network: processing outbound queue\n");
+       ForEachRoom(network_spoolout_room, NULL);
+       lprintf(7, "network: queue run completed\n");
+       doing_queue = 0;
 }
 
 
-
 char *Dynamic_Module_Init(void)
 {
        CtdlRegisterProtoHook(cmd_gnet, "GNET", "Get network config");
        CtdlRegisterProtoHook(cmd_snet, "SNET", "Get network config");
-
-       /* FIXME
-          temporary server command for batch send
-        */
-       CtdlRegisterProtoHook(cmd_batc, "BATC", "send out batch (temp)");
-
+       CtdlRegisterSessionHook(network_do_queue, EVT_TIMER);
        return "$Id$";
 }
index ce90e765839fba870bb86b62f3f560da99f780fc..da66a322eebc9dec0b2136d4ff44b9ab1fbf840e 100644 (file)
@@ -82,7 +82,7 @@ fails).
  
  
  INSTRUCTION:  remote
- SYNTAX:       remote|billg@microsoft.com|0|delivery status message
+ SYNTAX:       remote|friko@mumjiboolean.com|0|delivery status message
  DESCRIPTION:
     Names a recipient on a remote system to which the message should be
     delivered.  The third parameter may contain any of the following values:
index 2b80eb23d6f68e832895c5db56cdd8b82333b7c4..9b611aca55df5003842dca3804c5bff9e2425cf9 100644 (file)
@@ -1,5 +1,3 @@
-(NOTE: the new networker is not finished yet, and as such, has been disabled
-in the current release.)
  
            Description of the files in the "netconfigs" directory
 
index 4007dc176b4f0107a84b3bd84ba12838a41f9c3f..3a93e745efc74d11c1d52d40f8850e0002ac3415 100644 (file)
@@ -36,8 +36,8 @@ document, but we will briefly cover the methodology employed by Citadel/UX.
  Citadel/UX offers Citadel BBS service using TCP/IP.  It does so via a
 multithreaded server listening on a TCP port.  Older (4.xx) versions employed
 an inetd-based server.
- The port number officially assigned to Citadel by the IANA is TCP/504.  Since
+  
+ The port number officially assigned to Citadel by the IANA is 504/tcp.  Since
 our session layer assumes a clean, reliable, sequenced connection, the use
 of UDP would render the server unstable and unusable, so we stick with TCP.
    
@@ -58,9 +58,9 @@ session.
  Unlike protocols such as FTP, all data transfers occur in-band.  This means
 that the same connection that is used for exchange of client/server
 messages, will also be used to transfer data back and forth.  (FTP opens a
-separate connection for data transfers.)  We do this to allow the server to
-function over transports which can only handle one session at a time (such
-as a dialup connection).
+separate connection for data transfers.)  This keeps protocol administration
+straightforward, as it can traverse firewalls without any special protocol
+support on the firewall except for opening the port number.
  
    
  RESULT CODES
@@ -1572,8 +1572,8 @@ UCLS command.
 
  HCHG is a command, usable by any user, that allows a user to change their RWHO
 host value.  This will mask a client's originating hostname from normal
-users; access level 6 and higher see an entry right underneath the spoofed
-entry listing the actual hostname the user originates from.
+users; access level 6 and higher can see, in an extended wholist, the actual
+hostname the user originates from.
 
  The format of an HCHG command is:
 
@@ -1586,8 +1586,8 @@ entry listing the actual hostname the user originates from.
 
  RCHG is a command, usable by any user, that allows a user to change their RWHO
 room value.  This will mask a client's roomname from normal users; access
-level 6 and higher see an entry right underneath the spoofed entry listing
-the actual room the user is in.
+level 6 and higher can see, in an extended wholist, the actual room the user
+is in.
 
  The format of an RCHG command is:
 
@@ -1663,7 +1663,7 @@ purging (expiration) of messages.  The following policies are available:
 
 
 
- SPEX   (Set Polict for message EXpiration)
+ SPEX   (Set Policy for message EXpiration)
  
  Sets the policy of the current room, floor, or site regarding the automatic
 purging (expiration) of messages.  See the writeup for the GPEX command for