home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol150 / 211roomb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1984-04-29  |  18.1 KB  |  684 lines

  1. /************************************************************************/
  2. /*                roomb.c                 */
  3. /*        room code for Citadel bulletin board system        */
  4. /************************************************************************/
  5.  
  6. /************************************************************************/
  7. /*                History                 */
  8. /*                                    */
  9. /* 83Feb26 CrT    bug in makeRoom when out of rooms fixed.        */
  10. /* 83Feb26 CrT    matchString made caseless, normalizeString()        */
  11. /* 83Feb26 CrT    "]" directory prompt, user name before prompts        */
  12. /* 82Dec06 CrT    2.00 release.                        */
  13. /* 82Nov02 CrT    Cleanup prior to V1.2 mods.                */
  14. /* 82Nov01 CrT    Proofread for CUG distribution.             */
  15. /* 82Mar27 dvm    conversion to v. 1.4 begun                */
  16. /* 82Mar25 dvm    conversion for TRS-80/Omikron test started        */
  17. /* 81Dec21 CrT    Log file...                        */
  18. /* 81Dec20 CrT    Messages...                        */
  19. /* 81Dec19 CrT    Rooms seem to be working...                */
  20. /* 81Dec12 CrT    Started.                        */
  21. /************************************************************************/
  22.  
  23. #include "b:210ctdl.h"
  24.  
  25. /************************************************************************/
  26. /*                Contents                */
  27. /*                                    */
  28. /*    editText()        handles the end-of-message-entry menu    */
  29. /*    findRoom()        find a free room            */
  30. /*    getNumber()        prompt user for a number, limited range */
  31. /*    getRoom()        load given room into RAM        */
  32. /*    getString()        read a string in from user        */
  33. /*    getText()        reads a message in from user        */
  34. /*    getYesNo()        prompts for a yes/no response        */
  35. /*    givePrompt()        gives usual "THISROOM>" prompt        */
  36. /*    indexRooms()        build RAM index to ctdlroom.sys     */
  37. /*    makeRoom()        make new room via user dialogue     */
  38. /*    matchString()        search for given string         */
  39. /*    noteRoom()        enter room into RAM index        */
  40. /*    putRoom()        store room to given disk slot        */
  41. /*    renameRoom()        sysop special to rename rooms        */
  42. /*    replaceString()     string-substitute for message entry    */
  43. /*    zapRoomFile()        erase & re-initialize ctdlroom.sys    */
  44. /************************************************************************/
  45.  
  46. /************************************************************************/
  47. /*    editText() handles the end-of-message-entry menu.        */
  48. /*    return TRUE  to save message to disk,                */
  49. /*           FALSE to abort message, and                */
  50. /*           ERROR if user decides to continue            */
  51. /************************************************************************/
  52. int editText(buf, lim)
  53. char *buf;
  54. int lim;
  55. {
  56.     char iChar(), toUpper();
  57.     char c;
  58.     int  i;
  59.  
  60.     do {
  61.     outFlag = OUTOK;
  62.     mprintf("\n entry cmd: ");
  63.     switch (c=toUpper(iChar())) {
  64.     case 'A':
  65.         mprintf("bort\n ");
  66.         if (getYesNo(" confirm")) return FALSE;
  67.         break;
  68.     case 'C':
  69.         mprintf("ontinue\n ");
  70.         return ERROR;
  71.     case 'P':
  72.         mprintf("rint formatted\n ");
  73.         doCR();
  74.         mPrintf(   "   ");
  75.         printDate(
  76.         interpret(pGetYear ),
  77.         interpret(pGetMonth),
  78.         interpret(pGetDay  )
  79.         );
  80.         if (loggedIn)   mprintf(" from %s", msgBuf.mbauth);
  81.         doCR();
  82.         mformat(buf);
  83.         break;
  84.     case 'R':
  85.         mprintf("eplace string\n ");
  86.         replaceString(buf, lim);
  87.         break;
  88.     case 'S':
  89.         mprintf("ave buffer\n ");
  90.         return TRUE;
  91.     default:
  92.         tutorial("edit.mnu");
  93.         break;
  94.     }
  95.     } while (haveCarrier  ||  onConsole);
  96.     return FALSE;
  97. }
  98.  
  99. /************************************************************************/
  100. /*    findRoom() returns # of free room if possible, else ERROR    */
  101. /************************************************************************/
  102. int findRoom() {
  103.     int roomRover;
  104.  
  105.     for (roomRover=0;  roomRover<MAXROOMS;  roomRover++) {
  106.     if (!(roomTab[roomRover].rtflags & INUSE)) return roomRover;
  107.     }
  108.     return ERROR;
  109. }
  110.  
  111. /************************************************************************/
  112. /*    getNumber() prompts for a number in (bottom, top) range.    */
  113. /************************************************************************/
  114. int getNumber(prompt, bottom, top)
  115. char   *prompt;
  116. unsigned bottom;
  117. unsigned top;
  118. {
  119.     unsigned try;
  120.     char numstring[NAMESIZE];
  121.  
  122.     do {
  123.     outFlag = OUTOK;
  124.     getstring(prompt, numstring, NAMESIZE);
  125.     try    = atoi(numstring);
  126.     if (try < bottom)  mprintf("Sorry, must be at least %d\n", bottom);
  127.     if (try > top    )  mprintf("Sorry, must be no more than %d\n", top);
  128.     } while ((try < bottom ||  try > top)
  129.       && (haveCarrier  ||  onConsole)
  130.     );
  131.     return  try;
  132. }
  133.  
  134. /************************************************************************/
  135. /*    getRoom()                            */
  136. /************************************************************************/
  137. getRoom(rm, buf)
  138. int rm;
  139. int *buf;
  140. {
  141.     int      rread();
  142.     unsigned val;
  143.  
  144.     /* load room #rm into memory starting at buf */
  145.     thisRoom    = rm;
  146.     rseek(roomfl, rm*SECSPERROOM, 0);
  147.     if ((val = rread(roomfl, &roomBuf, SECSPERROOM)) >= 1000)    {
  148.     printf(" ?getRoom(): rread failed, val=%d\n", val);
  149.     }
  150.     crypte(&roomBuf, (SECSPERROOM * SECTSIZE), rm);
  151. }
  152.  
  153. /************************************************************************/
  154. /*    getString() gets a string from the user.            */
  155. /************************************************************************/
  156. getString(prompt, buf, lim)
  157. char *prompt;
  158. char *buf;
  159. int  lim;    /* max # chars to read */
  160. {
  161.     char iChar();
  162.     char c;
  163.     int  i;
  164.  
  165.     outFlag = OUTOK;
  166.  
  167.     if(strLen(prompt) > 0) {
  168.     doCR();
  169.     mprintf("Enter %s\n : ", prompt, lim);
  170.     }
  171.  
  172.     i    = 0;
  173.     while (
  174.      c = iChar(),
  175.  
  176.      c      != NEWLINE
  177.      && i      <  lim
  178.      && (haveCarrier || onConsole)
  179.     ) {
  180.     outFlag = OUTOK;
  181.  
  182.     /* handle delete chars: */
  183.     if (c == BACKSPACE) {
  184.         oChar(' ');
  185.         oChar(BACKSPACE);
  186.         if (i > 0) i--;
  187.         else  {
  188.         oChar(' ');
  189.         oChar(BELL);
  190.         }
  191.     } else     buf[i++] = c;
  192.  
  193.     if (i >= lim) {
  194.         oChar(BELL);
  195.         oChar(BACKSPACE); i--;
  196.     }
  197.  
  198.     /* kludge to return immediately on single '?': */
  199.     if (*buf == '?')   {
  200.         doCR();
  201.         break;
  202.     }
  203.     }
  204.     buf[i]  = '\0';
  205. }
  206.  
  207. /************************************************************************/
  208. /*    getText() reads a message from the user             */
  209. /*    Returns TRUE if user decides to save it, else FALSE        */
  210. /************************************************************************/
  211. char getText(prompt, buf, lim)
  212. char *prompt;
  213. char *buf;
  214. int  lim;    /* max # chars to read */
  215. {
  216.     char iChar(), visible();
  217.     char c, sysopAbort;
  218.     int  i, toReturn;
  219.  
  220.     outFlag = OUTOK;
  221.     if (!expert)    tutorial("entry.blb");
  222.  
  223.     outFlag = OUTOK;
  224.     if (!expert)    mprintf(   "Enter %s (end with empty line)", prompt);
  225.  
  226.     outFlag = OUTOK;
  227.     doCR();
  228.     mPrintf(   "   ");
  229.     printDate(
  230.     interpret(pGetYear ),
  231.     interpret(pGetMonth),
  232.     interpret(pGetDay  )
  233.     );
  234.  
  235.     if (loggedIn)  mprintf("from %s", msgBuf.mbauth);
  236.     doCR();
  237.  
  238.     lim--;
  239.     i  = 0;
  240.     toReturn    = TRUE;
  241.     sysopAbort    = FALSE;
  242.     do {
  243.     if (whichIO == MODEM)    {
  244.         fastIn(toReturn == ERROR);
  245.         if (whichIO != MODEM)   sysopAbort    = TRUE;
  246.     } else {
  247.        /* this code would handle the modem as well...    */
  248.        /* fastIn() is a later addition to handle people    */
  249.        /* who like to upload fast without handshaking    */
  250.        while (
  251.         !(  (c=iChar()) == NEWLINE   &&   buf[i-1] == NEWLINE )
  252.         && i < lim
  253.         && (haveCarrier || onConsole)
  254.        ) {
  255.            if (debug) putCh(visible(c));
  256.  
  257.            if (c != BACKSPACE)  buf[i++]   = c;
  258.            else {
  259.            /* handle delete chars: */
  260.            oChar(' ');
  261.            oChar(BACKSPACE);
  262.            if (i>0  &&    buf[i-1] != NEWLINE)   i--;
  263.            else                    oChar(BELL);
  264.            }
  265.        }
  266.  
  267.        buf[i] = 0x00;           /* null to terminate message    */
  268.  
  269.        if (i == lim)   mprintf(" buffer overflow\n ");
  270.     }
  271.     toReturn    =    sysopAbort  ?  FALSE  :  editText(buf, lim);
  272.     } while ((toReturn == ERROR)  &&  (haveCarrier || onConsole));
  273.     return  toReturn;
  274. }
  275.  
  276. /************************************************************************/
  277. /*    getYesNo() prompts for a yes/no response            */
  278. /************************************************************************/
  279. char getYesNo(prompt)
  280. char *prompt;
  281. {
  282.     char iChar(), toUpper();
  283.     int  toReturn;
  284.  
  285.     for (
  286.     doCR(),
  287.     toReturn = ERROR;
  288.  
  289.     toReturn == ERROR   &&     (haveCarrier || onConsole);
  290.     ) {
  291.     outFlag = OUTOK;
  292.     mprintf("%s? (Y/N): ", prompt);
  293.  
  294.     switch (toUpper(iChar())) {
  295.     case 'Y': toReturn    = TRUE ;        break;
  296.     case 'N': toReturn    = FALSE;        break;
  297.     }
  298.     doCR();
  299.     }
  300.     return   toReturn;
  301. }
  302.  
  303. /************************************************************************/
  304. /*    givePrompt() prints the usual "CURRENTROOM>" prompt.        */
  305. /************************************************************************/
  306. givePrompt() {
  307.     doCR();
  308.  
  309.     if (loggedIn)   printf("(%s)\n", logBuf.lbname);
  310.  
  311.     if (roomBuf.rbflags & CPMDIR)    mprintf("%s] ", roomBuf.rbname);
  312.     else                mprintf("%s> ", roomBuf.rbname);
  313. }
  314.  
  315. /************************************************************************/
  316. /*    indexRooms() -- build RAM index to room.buf            */
  317. /************************************************************************/
  318. indexRooms() {
  319.     int goodRoom, m, roomCount, slot;
  320.  
  321.     roomCount    = 0;
  322.     for (slot=0;  slot<MAXROOMS;  slot++) {
  323.     getRoom(slot, &roomBuf);
  324.     if (roomBuf.rbflags & INUSE) {
  325.         roomBuf.rbflags ^=    INUSE;        /* clear "inUse" flag */
  326.         for (m=0, goodRoom=FALSE;
  327.  
  328.         m<MSGSPERRM && !goodRoom;
  329.  
  330.         m++
  331.         ) {
  332.         /* comparison done with 64K wraparound in mind: */
  333.         if (roomBuf.vp.msg[m].rbmsgNo - oldestLo < 0x800) {
  334.             goodRoom    = TRUE;
  335.         }
  336.         }
  337.         if (goodRoom   ||    (roomBuf.rbflags & PERMROOM))    {
  338.         roomBuf.rbflags |= INUSE;
  339.         }
  340.  
  341.         if (roomBuf.rbflags & INUSE) roomCount++;
  342.         else {
  343.         roomBuf.rbflags = 0;
  344.         putRoom(slot, &roomBuf);
  345.         }
  346.     }
  347.     noteRoom();
  348.     }
  349. #ifdef XYZZY
  350.     printf(" %d of %d rooms in use\n", roomCount, MAXROOMS);
  351. #endif
  352. }
  353.  
  354. /************************************************************************/
  355. /*    makeRoom() constructs a new room via dialogue with user.    */
  356. /************************************************************************/
  357. makeRoom() {
  358.     char getYesNo();
  359.     char *nm[NAMESIZE];
  360.     char *oldName[NAMESIZE];
  361.     int  i;
  362.  
  363.     /* update lastMessage for current room: */
  364.     logBuf.lbgen[thisRoom]    = roomBuf.rbgen << GENSHIFT;
  365.  
  366.     strcpy(oldName, roomBuf.rbname);
  367.     if ((thisRoom=findRoom()) == ERROR) {
  368.     indexRooms();    /* try and reclaim an empty room    */
  369.     if ((thisRoom=findRoom()) == ERROR) {
  370.         mprintf(" ?no room");
  371.         /* may have reclaimed old room, so: */
  372.         if (roomExists(oldName) == ERROR)    strcpy(oldName, "Lobby");
  373.         getRoom(roomExists(oldName), &roomBuf);
  374.         return;
  375.     }
  376.     }
  377.  
  378.     getString("name for new room", nm, NAMESIZE);
  379.     normalizeString(nm);
  380.     if (roomExists(nm) >= 0) {
  381.     mprintf(" A '%s' already exists.\n", nm);
  382.     /* may have reclaimed old room, so: */
  383.     if (roomExists(oldName) == ERROR)   strcpy(oldName, "Lobby");
  384.     getRoom(roomExists(oldName), &roomBuf);
  385.     return;
  386.     }
  387.     if (!expert)   tutorial("newroom.blb");
  388.  
  389.     roomBuf.rbflags = INUSE;
  390.     if (getYesNo(" Make room public"))     roomBuf.rbflags |= PUBLIC;
  391.  
  392.     mprintf("'%s', a %s room",
  393.     nm,
  394.     roomBuf.rbflags & PUBLIC  ?  "public"  :  "private"
  395.     );
  396.  
  397.     if(!getYesNo("Install it")) {
  398.     /* may have reclaimed old room, so: */
  399.     if (roomExists(oldName) == ERROR)   strcpy(oldName, "Lobby");
  400.     getRoom(roomExists(oldName), &roomBuf);
  401.     return;
  402.     }
  403.  
  404.     strcpy(roomBuf.rbname, nm);
  405.     for (i=0;  i<MSGSPERRM;  i++) {
  406.     roomBuf.vp.msg[i].rbmsgNo   = 0;    /* mark all slots empty */
  407.     roomBuf.vp.msg[i].rbmsgLoc  = ERROR;
  408.     }
  409.     roomBuf.rbgen    = (roomBuf.rbgen +1) % MAXGEN;
  410.  
  411.     noteRoom();             /* index new room    */
  412.     putRoom(thisRoom, &roomBuf);
  413.  
  414.     /* update logBuf: */
  415.     logBuf.lbgen[thisRoom]    = roomBuf.rbgen << GENSHIFT;
  416. }
  417.  
  418. /************************************************************************/
  419. /*    matchString() searches for match to given string.  Runs backward*/
  420. /*    through buffer so we get most recent error first.        */
  421. /*    Returns loc of match, else ERROR                */
  422. /************************************************************************/
  423. char *matchString(buf, pattern, bufEnd)
  424. char *buf, *pattern, *bufEnd;
  425. {
  426.     char *loc, *pc1, *pc2;
  427.     char foundIt;
  428.  
  429.     for (loc=bufEnd, foundIt=FALSE;  !foundIt && --loc>=buf;) {
  430.     for (pc1=pattern, pc2=loc,  foundIt=TRUE ;  *pc1 && foundIt;) {
  431.         if (! (toLower(*pc1++) == toLower(*pc2++)))   foundIt=FALSE;
  432.     }
  433.     }
  434.  
  435.     return   foundIt  ?  loc  :  ERROR;
  436. }
  437.  
  438. /************************************************************************/
  439. /*    normalizeString() deletes leading & trailing blanks etc.    */
  440. /************************************************************************/
  441. normalizeString(s)
  442. char *s;
  443. {
  444.     char *pc, *s2;
  445.  
  446.     pc = s;
  447.  
  448.     /* find end of string   */
  449.     while (*pc)   {
  450.     if (*pc < ' ')     *pc = ' ';   /* zap tabs etc... */
  451.     pc++;
  452.     }
  453.  
  454.     /* no trailing spaces: */
  455.     while (pc>s  &&  isSpace(*(pc-1))) pc--;
  456.     *pc = '\0';
  457.  
  458.     /* no leading spaces: */
  459.     while (*s == ' ') {
  460.     for (pc=s;  *pc;  pc++)    *pc = *(pc+1);
  461.     }
  462.  
  463.     /* no double blanks */
  464.     for (;  *s;  s++)    {
  465.     if (*s == ' '    &&   *(s+1) == ' ')   {
  466.         for (pc=s;    *pc;  pc++)    *pc = *(pc+1);
  467.     }
  468.     }
  469. }
  470.  
  471. /************************************************************************/
  472. /*    noteRoom() -- enter room into RAM index array.            */
  473. /************************************************************************/
  474. noteRoom()
  475. {
  476.     int i, last;
  477.  
  478.     last = 0;
  479.     for (i=0;  i<MSGSPERROOM;  i++)  {
  480.     if (roomBuf.vp.msg[i].rbmsgNo > last) {
  481.         last = roomBuf.vp.msg[i].rbmsgNo;
  482.     }
  483.     }
  484.     roomTab[thisRoom].rtlastMessage = last         ;
  485.     strcpy(roomTab[thisRoom].rtname, roomBuf.rbname) ;
  486.     roomTab[thisRoom].rtgen        = roomBuf.rbgen  ;
  487.     roomTab[thisRoom].rtflags        = roomBuf.rbflags;
  488. }
  489.  
  490. /************************************************************************/
  491. /*    putRoom() stores room in buf into slot rm in room.buf        */
  492. /************************************************************************/
  493. putRoom(rm, buf)
  494. int rm;
  495. int *buf;
  496. {
  497.     int      rwrite();
  498.     unsigned val;
  499.  
  500.     crypte(&roomBuf, (SECSPERROMM * SECTSIZE), rm);
  501.  
  502.     rseek(roomfl, rm*SECSPERROOM, 0);
  503.     if ((val = rwrite(roomfl, &roomBuf, SECSPERROOM)) != SECSPERROOM) {
  504.     printf("?putRoom()%d", val);
  505.     }
  506.  
  507.     crypte(&roomBuf, (SECSPERROMM * SECTSIZE), rm);
  508. }
  509.  
  510. /************************************************************************/
  511. /*    renameRoom() is sysop special fn                */
  512. /*    Returns:    TRUE on success else FALSE            */
  513. /************************************************************************/
  514. renameRoom() {
  515.     char getYesNo(), toUpper();
  516.     char nm[NAMESIZE];
  517.     char c, goodOne, wasDirectory;
  518.     int  r;
  519.  
  520.     if (                /* clearer than "thisRoom <= AIDEROOM"*/
  521.     thisRoom == LOBBY
  522.     ||
  523.     thisRoom == MAILROOM
  524.     ||
  525.     thisRoom == AIDEROOM
  526.     ) {
  527.     mPrintf("? -- may not edit this room.\n ");
  528.     return FALSE;
  529.     }
  530.  
  531.     if (!getYesNo("confirm"))    return FALSE;
  532.  
  533.     if (getYesNo("Change name"))   {
  534.     getString("new room name", nm, NAMESIZE);
  535.     normalizeString(nm);
  536.     r = roomExists(nm);
  537.     if (r>=0  &&  r!=thisRoom) {
  538.          mprintf("A %s exists already!\n", nm);
  539.     } else {
  540.         strcpy(roomBuf.rbname,         nm);   /* also in room itself  */
  541.     }
  542.     }
  543.     mprintf("%s, ", roomBuf.rbflags & PUBLIC ? "public" : "private");
  544.     mprintf(
  545.     "%s, ",
  546.     (
  547.         (roomBuf.rbflags & PERMROOM)
  548.         ?
  549.         " permanent"
  550.         :
  551.         " temporary"
  552.     )
  553.     );
  554.     wasDirectory = roomBuf.rbflags & CPMDIR;
  555.     mprintf("%sdirectory room\n ", wasDirectory  ?  "" : "non");
  556.  
  557.     roomBuf.rbflags = INUSE;
  558.  
  559.     if (getYesNo("Public room"))    {
  560.     roomBuf.rbflags |= PUBLIC;
  561.     } else {
  562.     roomBuf.rbgen     = (roomBuf.rbgen +1) % MAXGEN;
  563.     }
  564.  
  565.     if (!onConsole)   roomBuf.rbflags |= wasDirectory;
  566.     else if (getYesNo("Directory room")) {
  567.     roomBuf.rbflags    |= CPMDIR;
  568.  
  569.     printf(" now space %c%c\n", 'A'+roomBuf.rbdisk, '0'+roomBuf.rbuser);
  570.  
  571.     for (goodOne=FALSE;  !goodOne;    )   {
  572.         getString("disk", nm, NAMESIZE);
  573.         c        = toUpper(nm[0]);
  574.         if (c>='A'    && c<='P') {
  575.         roomBuf.rbdisk        = c - 'A';
  576.         goodOne         = TRUE;
  577.         } else mprintf("?");
  578.     }
  579.  
  580.     roomBuf.rbuser = getNumber("user", 0, 31);
  581.     printf(" space %c%c\n", 'A'+roomBuf.rbdisk, '0'+roomBuf.rbuser);
  582.     }
  583.  
  584.  
  585.     if (
  586.     roomBuf.rbflags & CPMDIR
  587.     ||
  588.     getYesNo("permanent")
  589.     ) {
  590.     roomBuf.rbflags    |= PERMROOM;
  591.     }
  592.  
  593.     noteRoom();
  594.     putRoom(thisRoom, &roomBuf);
  595.  
  596.     return TRUE;
  597. }
  598.  
  599. /************************************************************************/
  600. /*    replaceString() corrects typos in message entry         */
  601. /************************************************************************/
  602. replaceString(buf, lim)
  603. char *buf;
  604. int  lim;
  605. {
  606.     char oldString[2*SECTSIZE];
  607.     char newString[2*SECTSIZE];
  608.     char *loc, *textEnd;
  609.     char *pc;
  610.     int  incr;
  611.  
  612.     for (textEnd=buf;  *textEnd;  textEnd++);    /* find terminal null    */
  613.  
  614.     getString("string",      oldString, (2*SECTSIZE));
  615.     if ((loc=matchString(buf, oldString, textEnd)) == ERROR) {
  616.     mprintf("?not found.\n ");
  617.     return;
  618.     }
  619.  
  620.     getString("replacement", newString, (2*SECTSIZE));
  621.     if ( (strLen(newString)-strLen(oldString))    >=  (&buf[lim]-textEnd) ) {
  622.     mprintf("?Overflow!\n ");
  623.     return;
  624.     }
  625.  
  626.     /* delete old string: */
  627.     for (pc=loc, incr=strLen(oldString);  *pc=*(pc+incr);  pc++);
  628.     textEnd -= incr;
  629.  
  630.     /* make room for new string: */
  631.     for (pc=textEnd, incr=strLen(newString);  pc>=loc;    pc--) {
  632.     *(pc+incr) = *pc;
  633.     }
  634.  
  635.     /* insert new string: */
  636.     for (pc=newString;    *pc;  *loc++ = *pc++);
  637. }
  638.  
  639. /************************************************************************/
  640. /*    zapRoomFile() erases and re-initilizes room.buf         */
  641. /************************************************************************/
  642. zapRoomFile()
  643. {
  644.     char getCh(), toUpper();
  645.     int i;
  646.  
  647.     printf("\nWipe room file? ");
  648.     if (toUpper(getCh()) != 'Y') return;
  649.  
  650.     roomBuf.rbflags    = 0;
  651.     roomBuf.rbgen    = 0;
  652.     roomBuf.rbdisk    = 0;
  653.     roomBuf.rbuser    = 0;
  654.     roomBuf.rbname[0]    = 0;    /* unnecessary -- but I like it...    */
  655.     for (i=0;  i<MSGSPERRM;  i++) {
  656.     roomBuf.vp.msg[i].rbmsgNo = roomBuf.vp.msg[i].rbmsgLoc = 0;
  657.     }
  658.  
  659.     printf("maxrooms=%d\n", MAXROOMS);
  660.  
  661.     for (i=0;  i<MAXROOMS;  i++) {
  662.     printf("clearing room %d\n", i);
  663.     putRoom(i, &roomBuf);
  664.     }
  665.  
  666.     /* Lobby> always exists -- guarantees us a place to stand! */
  667.     thisRoom        = 0        ;
  668.     strcpy(roomBuf.rbname, "Lobby")    ;
  669.     roomBuf.rbflags    = (PERMROOM | PUBLIC | INUSE);
  670.     putRoom(LOBBY, &roomBuf);
  671.  
  672.     /* Mail> is also permanent...    */
  673.     thisRoom        = MAILROOM    ;
  674.     strcpy(roomBuf.rbname, "Mail")    ;
  675.     roomBuf.rbflags    = (PERMROOM | PUBLIC | INUSE);
  676.     putRoom(MAILROOM, &roomBuf);
  677.  
  678.     /* Aide> also...            */
  679.     thisRoom        = AIDEROOM    ;
  680.     strcpy(roomBuf.rbname, "Aide")    ;
  681.     roomBuf.rbflags    = (PERMROOM | INUSE);
  682.     putRoom(AIDEROOM, &roomBuf);
  683. }
  684.