home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / BTMTSRC3.ZIP / RECVSYNC.C < prev    next >
C/C++ Source or Header  |  1991-08-14  |  23KB  |  581 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  (C) Copyright 1987-90, Bit Bucket Software Co., a Delaware Corporation. */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*               This module was written by Vince Perriello                 */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*          FidoNet(R) Mail Session Called System Synchronization           */
  17. /*                                                                          */
  18. /*                                                                          */
  19. /*    For complete  details  of the licensing restrictions, please refer    */
  20. /*    to the License  agreement,  which  is published in its entirety in    */
  21. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.240.    */
  22. /*                                                                          */
  23. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  24. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  25. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  26. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  27. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  28. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  29. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  30. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  31. /*                                                                          */
  32. /*                                                                          */
  33. /* You can contact Bit Bucket Software Co. at any one of the following      */
  34. /* addresses:                                                               */
  35. /*                                                                          */
  36. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:132/491, 1:141/491  */
  37. /* P.O. Box 460398                AlterNet 7:491/0                          */
  38. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  39. /*                                Internet f491.n132.z1.fidonet.org         */
  40. /*                                                                          */
  41. /* Please feel free to contact us at any time to share your comments about  */
  42. /* our software and/or licensing policies.                                  */
  43. /*                                                                          */
  44. /*                                                                          */
  45. /*--------------------------------------------------------------------------*/
  46.  
  47.  
  48.  
  49. extern void pascal com_direct(unsigned char c);        /* CML */
  50.  
  51.  
  52.  /*
  53.     Receiver Synchronization state table.
  54.    
  55.     This logic is used by the called system. It will determine the
  56.     type of mail transfer which can be used in communicating with
  57.     the calling system.
  58.    
  59.     This stuff was originally copied from a file sent to us by TJ.
  60.     (Of course, then we hacked the heck out of it!!!)
  61.   
  62.     Thanks, Tom.
  63.   
  64.  
  65.  .-----+----------+-------------------------+-------------------------+-----.
  66.  | RS0 | SyncInit |                         | Start 5 second idle tmr | RS1 |
  67.  |-----+----------+-------------------------+-------------------------+-----|
  68.  | RS1 | IdleWait | 1. 5 sec tmr expired    | Take the initiative     | RS2 |
  69.  |     |          +-------------------------+-------------------------+-----|
  70.  |     |          | 2. Carrier lost         | Session aborted         | exit|
  71.  |     |          +-------------------------+-------------------------+-----|
  72.  |     |          | 3. Peek = YOOHOO        | Looks like a live WaZOO | RS3 |
  73.  |     |          +-------------------------+-------------------------+-----|
  74.  |     |          | 4. Peek = TSYNC         | Live FSC001, we think   | RS3 |
  75.  |     |          +-------------------------+-------------------------+-----|
  76.  |     |          | 5. Peek = CR, LF, space | He looks alive          | RS2 |
  77.  |     |          +-------------------------+-------------------------+-----|
  78.  |     |          | 6. Other character      | Eat it                  | RS1 |
  79.  |-----+----------+-------------------------+-------------------------+-----|
  80.  | RS2 |SendBanner| 1. Error returned       | Session aborted         | exit|
  81.  |     |          +-------------------------+-------------------------+-----|
  82.  |     |          | 2. Banner sent OK       |                         | RS3 |
  83.  |-----+----------+-------------------------+-------------------------+-----|
  84.  | RS3 |RecvInit  |                         | Init ext-mail scan ptrs | RS4 |
  85.  |     |          |                         | Start 20 sec timer      |     |
  86.  |     |          |                         | Init 10 sec timer       |     |
  87.  |-----+----------+-------------------------+-------------------------+-----|
  88.  | RS4 |SendSync  | 1. Error returned       | Session aborted         | exit|
  89.  |     |(xmit sync+-------------------------+-------------------------+-----|
  90.  |     |string)   | 2. String sent OK       | Watch for sender sync   | RS5 |
  91.  |-----+----------+-------------------------+-------------------------+-----|
  92.  | RS5 | WaitSync | 1. Carrier lost         | Session aborted         | exit|
  93.  |     |          +-------------------------+-------------------------+-----|
  94.  |     |          | 2. YOOHOO received      | WaZOO session selected  | exit|
  95.  |     |          +-------------------------+-------------------------+-----|
  96.  |     |          | 3. TSYNC received       | probable FSC001         | RS6 |
  97.  |     |          +-------------------------+-------------------------+-----|
  98.  |     |          | 4. CR received          | Still sync'ing          | RS4 |
  99.  |     |          +-------------------------+-------------------------+-----|
  100.  |     |          | 5. ESC received         | BBS session             | exit|
  101.  |     |          +-------------------------+-------------------------+-----|
  102.  |     |          | 6. Other character rcvd | check ext-mail string   | RS7 |
  103.  |     |          +-------------------------+-------------------------+-----|
  104.  |     |          | 7. 10 sec timer elapsed | FSC001 protocol selected| exit|
  105.  |     |          +-------------------------+-------------------------+-----|
  106.  |     |          | 8. 20 sec timer elapsed | Not a mail session      | exit|
  107.  |-----+----------+-------------------------+-------------------------+-----|
  108.  | RS6 | TsyncTmr | 1. Timer not running    | Start 10 second timer   | RS5 |
  109.  |     |          |                         | Reset 20 sec timer      |     |
  110.  |     |          +-------------------------+-------------------------+-----|
  111.  |     |          | 2. Timer running        |                         | RS5 |
  112.  |-----+----------+-------------------------+-------------------------+-----|
  113.  | RS7 | ExtMail  | 1. String matched       | External mail selected  | exit|
  114.  |     |          +-------------------------+-------------------------+-----|
  115.  |     |          | 2. Checked all strings  | Get next input character| RS5 |
  116.  `-----+----------+-------------------------+-------------------------+-----'
  117.  
  118.  */
  119.  
  120.  
  121.  
  122. /* System include files */
  123.  
  124. #include <stdio.h>
  125. #include <string.h>
  126.  
  127. /* Local include files */
  128.  
  129. #include "defines.h"
  130. #include "com.h"
  131. #include "xfer.h"
  132. #include "zmodem.h"
  133. #include "keybd.h"
  134. #include "sbuf.h"
  135. #include "sched.h"
  136. #include "externs.h"
  137. #include "prototyp.h"
  138.  
  139. extern int SendBanner (char *);
  140.  
  141.  
  142. /*
  143.  * Data structure used by all RecvSync state machine functions.
  144.  * Contains all data which needs to be passed between various states.
  145.  *
  146.  */
  147.  
  148. typedef struct {
  149.    long Idle_Timer;                     /* 5 second initial idle timer      */
  150.    long BBS_Timer;                      /* 20 second Timer for BBS user     */
  151.    char *ExtMailScan[16];               /* Scan pointer for External Mail   */
  152.    long TSYNC_Timer;                    /* 10 second TSYNC timer            */
  153.    int  result;                         /* Result we want to send out       */
  154. } RSARGS, *RSARGSP;
  155.  
  156. static int RSSyncInit (RSARGSP, int);   /* Called by state machine at start */
  157. static int RSExit     (RSARGSP, int);   /* Called by state machine at end   */
  158. static int RSIdleWait (RSARGSP);        /* RS1 state processing function    */
  159. static int RSSendBannr(RSARGSP);        /* RS2 state processing function    */
  160. static int RSRecvInit (RSARGSP);        /* RS3 state processing function    */
  161. static int RSSendSync (RSARGSP);        /* RS4 state processing function    */
  162. static int RSWaitSync (RSARGSP);        /* RS5 state processing function    */
  163. static int RSTsyncTmr (RSARGSP);        /* RS6 state processing function    */
  164. static int RSExtMail  (RSARGSP);        /* RS7 state processing function    */
  165.  
  166.  
  167. #define RS0    0                        /* Reserved value of 0 for init     */
  168. #define RSexit 0                        /* Slot 1 is exit, but called by 0  */
  169. #define RS1    2                        /* First "user" slot is 2.          */
  170. #define RS2    3                        /* After that, it all maps n : n+1  */
  171. #define RS3    4
  172. #define RS4    5
  173. #define RS5    6
  174. #define RS6    7
  175. #define RS7    8
  176.  
  177.  
  178. static STATES Recv_Sync [] = {          /* Table used by state machine      */
  179.    { "RSSyncInit", RSSyncInit },        /* And referred to by 'SSn' defines */
  180.    { "RSExit",     RSExit },            /* listed above ...                 */
  181.    { "RSIdleWait", RSIdleWait },
  182.    { "RSSendBannr",RSSendBannr },
  183.    { "RSRecvInit", RSRecvInit },
  184.    { "RSSendSync", RSSendSync },
  185.    { "RSWaitSync", RSWaitSync },
  186.    { "RSTsyncTmr", RSTsyncTmr },
  187.    { "RSExtMail",  RSExtMail },
  188. };
  189.  
  190.  
  191. /*
  192.  * CalledRecvSync
  193.  * Determine whether the calling system is an FTS-0001 mailer, an FTS-0006
  194.  * mailer, an external mailer, or a human caller. Use the general state 
  195.  * machine driver.
  196.  *
  197.  * This is the only external entry point into this module.
  198.  *
  199.  */
  200.  
  201. int CalledRecvSync (void)
  202. {
  203.    RSARGS args;
  204.    int res;
  205.  
  206.    args.result = 0;
  207.  
  208.    res = state_machine (Recv_Sync, &args, 2);
  209.    return (res);
  210. }
  211.  
  212.  
  213.  
  214. /*
  215.  * This routine is called by the state machine when the 'RSexit'
  216.  * state is seen. Its return value is what the state machine
  217.  * will return to its caller as the result of the function.
  218.  *
  219.  */
  220.  
  221. static int RSExit (args, cur_state)
  222. RSARGSP args;
  223. int cur_state;
  224. {
  225.    cur_state = args->result;    /* Not meaningful. Makes compiler happy */
  226.    return (args->result);
  227. }
  228.  
  229.  /*
  230.  
  231.  .-----+----------+-------------------------+-------------------------+-----.
  232.  | RS0 | SyncInit |                         | Start 5 second idle tmr | RS1 |
  233.  `-----+----------+-------------------------+-------------------------+-----'
  234.  
  235.  */
  236.  
  237.  
  238. static int RSSyncInit (args, start_state)
  239. RSARGSP args;
  240. int start_state;
  241. {
  242. //   args->Idle_Timer = timerset (500);
  243.    args->Idle_Timer = timerset (1000);        /* CML - bend the rules a little under OS/2 */
  244.    start_state = RS1;           /* Not meaningful. Makes compiler happy */
  245.    return (RS1);
  246. }
  247.  
  248.  /*
  249.  
  250.  .-----+----------+-------------------------+-------------------------+-----.
  251.  | RS1 | IdleWait | 1. 5 sec tmr expired    | Take the initiative     | RS2 |
  252.  |     |          +-------------------------+-------------------------+-----|
  253.  |     |          | 2. Carrier lost         | Session aborted         | exit|
  254.  |     |          +-------------------------+-------------------------+-----|
  255.  |     |          | 3. Peek = YOOHOO        | Looks like a live WaZOO | RS3 |
  256.  |     |          +-------------------------+-------------------------+-----|
  257.  |     |          | 4. Peek = TSYNC         | Live FSC001, we think   | RS3 |
  258.  |     |          +-------------------------+-------------------------+-----|
  259.  |     |          | 5. Peek = CR, LF, space | He looks alive          | RS2 |
  260.  |     |          +-------------------------+-------------------------+-----|
  261.  |     |          | 6. Other character      | Eat it                  | RS1 |
  262.  `-----+----------+-------------------------+-------------------------+-----'
  263.  
  264.  */
  265.  
  266.  
  267. static int RSIdleWait (args)
  268. RSARGSP args;
  269. {
  270.    unsigned char i;
  271.  
  272.    while (!timeup (args->Idle_Timer)) {
  273.       
  274.       if (!CARRIER) {
  275.          args->result = 0;
  276.          return (RSexit);
  277. //    time_release();            /* CML -- stop hogging my CPU! */
  278.       }
  279.       
  280.       switch (i = (unsigned char) (PEEKBYTE () & 0xff)) {
  281.  
  282.          case 0xff:                              /* No char available    */
  283.             break;
  284.  
  285.          case TSYNC:
  286.          case YOOHOO:
  287.             return (RS3);                        /* Fast lane, no banner */
  288.             break;
  289.  
  290.          case CR:
  291.          case LV:
  292.          case ' ':
  293.          case ENQ:
  294.          case ESC:
  295.             return (RS2);                        /* He's alive, do banner*/
  296.             break;
  297.  
  298.          default:
  299.             (void) TIMED_READ (0);               /* eat it up            */
  300.             return (RS1);
  301.             break;
  302.       }
  303.  
  304.    }
  305.  
  306.    return (RS2);                                 /* Idle for 5 seconds   */
  307.  
  308. }
  309.  
  310.  /*
  311.  
  312.  .-----+----------+-------------------------+-------------------------+-----.
  313.  | RS2 |SendBanner| 1. Error returned       | Session aborted         | exit|
  314.  |     |          +-------------------------+-------------------------+-----|
  315.  |     |          | 2. Banner sent OK       |                         | RS3 |
  316.  `-----+----------+-------------------------+-------------------------+-----'
  317.  
  318.  */
  319.  
  320.  
  321. static int RSSendBannr (args)
  322. RSARGSP args;
  323. {
  324.    char buff[128];
  325.  
  326.    (void) sprintf (buff, msgtxt[M_ADDRESS], Full_Addr_Str (&my_addr), ANNOUNCE);
  327.  
  328.    if (!SendBanner (buff)) {
  329.       args->result = 0;
  330.       return (RSexit);
  331.    }
  332.  
  333.    if (strlen (BBSbanner) != 0) {                /* If BBS name spec'ed, */
  334.         com_direct ('\r');                           /* make sure user gets a full CR-LF */
  335.         com_direct ('\n');         /* com_direct is CML's */
  336.  
  337.       if (!SendBanner (BBSbanner)) {
  338.          args->result = 0;
  339.          return (RSexit);
  340.       }
  341.  
  342.     com_direct ('\r');                           /* make sure user gets a full CR-LF */
  343.     com_direct ('\n');         /* com_direct is CML's */
  344.    }
  345.  
  346.    if (!mail_only) {
  347.       if (!SendBanner (BBSwelcome)) {
  348.          args->result = 0;
  349.          return (RSexit);
  350.       }
  351.    }
  352.  
  353.    return (RS3);
  354. }
  355.  
  356.  /*
  357.  
  358.  .-----+----------+-------------------------+-------------------------+-----.
  359.  | RS3 |RecvInit  |                         | Init ext-mail scan ptrs | RS4 |
  360.  |     |          |                         | Start 20 sec timer      |     |
  361.  |     |          |                         | Init 10 sec timer       |     |
  362.  `-----+----------+-------------------------+-------------------------+-----'
  363.  
  364.  */
  365.  
  366.  
  367. static int RSRecvInit (args)
  368. RSARGSP args;
  369. {
  370.    register int k;
  371.  
  372.    for (k = 0; k < num_ext_mail; k++) {
  373.       args->ExtMailScan[k] = ext_mail_string[k]; /* UUCP handshake       */
  374.    }
  375.  
  376.    args->BBS_Timer = timerset (BBStimeout);      /* 20 second timeout    */
  377.    args->TSYNC_Timer = 0L;                       /* Initialize for test  */
  378.  
  379.    return (RS4);
  380. }
  381.  
  382.  /*
  383.  
  384.  .-----+----------+-------------------------+-------------------------+-----.
  385.  | RS4 |SendSync  | 1. Error returned       | Session aborted         | exit|
  386.  |     |(xmit sync+-------------------------+-------------------------+-----|
  387.  |     |string)   | 2. String sent OK       | Watch for sender sync   | RS5 |
  388.  `-----+----------+-------------------------+-------------------------+-----'
  389.  
  390.  */
  391.  
  392.  
  393. static int RSSendSync (args)
  394. RSARGSP args;
  395. {
  396.    char *c;
  397.  
  398.    if (mail_only) {                              /* If no BBS allowed,   */
  399.       c = noBBS;                                 /* tell human to git    */
  400.    } else {
  401.       c = BBSesc;                                /* or hit ESC for BBS   */
  402.    }
  403.  
  404.    if (!SendBanner (c)) {
  405.       args->result = 0;
  406.       return (RSexit);
  407.    }
  408.  
  409.    return (RS5);
  410. }
  411.  
  412.  /*
  413.  
  414.  .-----+----------+-------------------------+-------------------------+-----.
  415.  | RS5 | WaitSync | 1. Carrier lost         | Session aborted         | exit|
  416.  |     |          +-------------------------+-------------------------+-----|
  417.  |     |          | 2. YOOHOO received      | WaZOO session selected  | exit|
  418.  |     |          +-------------------------+-------------------------+-----|
  419.  |     |          | 3. TSYNC received       | probable FSC001         | RS6 |
  420.  |     |          +-------------------------+-------------------------+-----|
  421.  |     |          | 4. CR received          | Still sync'ing          | RS4 |
  422.  |     |          +-------------------------+-------------------------+-----|
  423.  |     |          | 5. ESC received         | BBS session             | exit|
  424.  |     |          +-------------------------+-------------------------+-----|
  425.  |     |          | 6. Other character rcvd | check ext-mail string   | RS7 |
  426.  |     |          +-------------------------+-------------------------+-----|
  427.  |     |          | 7. 10 sec timer elapsed | FSC001 protocol selected| exit|
  428.  |     |          +-------------------------+-------------------------+-----|
  429.  |     |          | 8. 20 sec timer elapsed | Not a mail session      | exit|
  430.  `-----+----------+-------------------------+-------------------------+-----'
  431.  
  432.  */
  433.  
  434.  
  435. static int RSWaitSync (args)
  436. RSARGSP args;
  437. {
  438.    int i;
  439.  
  440.    while (CARRIER) {
  441.  
  442.       if (got_ESC ()) {                          /* Manual abort?        */
  443.          DTR_OFF ();                             /* Yes, drop carrier    */
  444.          timer (10);
  445.          args->result = 0;
  446.          return (RSexit);
  447.       }
  448.  
  449.       /* Note: the following line is a NON-DESTRUCTIVE READ! */
  450.  
  451.       i = PEEKBYTE () & 0xff;                    /* Get the next char    */
  452.  
  453.       switch (i) {
  454.  
  455.          case 0xff:                              /* No character there   */
  456.  
  457.             break;
  458.  
  459.          case YOOHOO:                            /* Looks like a WaZOO   */
  460.  
  461.             if (no_WaZOO) {                      /* If we're not WaZOO,  */
  462.                (void) TIMED_READ (0);            /* Eat the YooHoo       */
  463.                continue;
  464.             }
  465.  
  466.             CLEAR_OUTBOUND ();                   /* End noisy banner now */
  467.             args->result = 3;                    /* WaZOO session        */
  468.             return (RSexit);
  469.             break;
  470.          
  471.          case TSYNC:                             /* Looks like an FTSC   */
  472.  
  473.             CLEAR_OUTBOUND ();                   /* End noisy banner now */
  474.             (void) TIMED_READ (0);               /* Eat the TSYNC        */
  475.  
  476.             if (!no_WaZOO) {                     /* If we support WaZOO, */
  477.                return (RS6);                     /* Go set up the timer  */
  478.             } else {
  479.             args->result = 2;                    /* FTS-0001 session     */
  480.             return (RSexit);
  481.             }
  482.  
  483.             break;
  484.  
  485.          case CR:                                /* Still sync'ing       */
  486.  
  487.             (void) TIMED_READ (0);               /* Eat the character    */
  488.             return (RS4);                        /* Back to that stuff   */
  489.  
  490.          case ESC:                               /* User wants the BBS   */
  491.  
  492.             (void) TIMED_READ (0);               /* Eat the character    */
  493.             if (!mail_only) {
  494.                args->result = 1;                 /* BBS session          */
  495.                return (RSexit);
  496.             }
  497.  
  498.             break;
  499.  
  500.          default:                                /* A less special char  */
  501.  
  502.             return (RS7);                        /* Check ext mailers    */
  503.             break;
  504.  
  505.       } /* End switch */
  506.  
  507.       if ((args->TSYNC_Timer != 0L) && (timeup (args->TSYNC_Timer))) {
  508.          args->result = 2;                       /* FTS-0001 session     */
  509.          return (RSexit);
  510.       }
  511.       
  512.       if (timeup (args->BBS_Timer)) {            /* The big timeout      */
  513.          args->result = 1;                       /* BBS session          */
  514.          return (RSexit);
  515.       }
  516.  
  517.    } /* End (while CARRIER) */
  518.  
  519.    args->result = 0;                             /* carrier loss = abort */
  520.    return (RSexit);
  521. }
  522.  
  523.  /*
  524.  
  525.  .-----+----------+-------------------------+-------------------------+-----.
  526.  | RS6 | TsyncTmr | 1. Timer not running    | Start 10 second timer   | RS5 |
  527.  |     |          |                         | Reset 20 sec timer      |     |
  528.  |     |          +-------------------------+-------------------------+-----|
  529.  |     |          | 2. Timer running        |                         | RS5 |
  530.  `-----+----------+-------------------------+-------------------------+-----'
  531.  
  532.  */
  533.  
  534.  
  535. static int RSTsyncTmr (args)
  536. RSARGSP args;
  537. {
  538.    if (args->TSYNC_Timer == 0L) {                /* If not already set,  */
  539. //      args->TSYNC_Timer = timerset (1000);       /* Then just set it     */
  540.       args->TSYNC_Timer = timerset (2000);       /* Then just set it. (CML - bend the rules a little under OS/2) */
  541.       args->BBS_Timer = timerset (BBStimeout);   /* Reset 20 sec timer   */
  542.    }
  543.    
  544.    return (RS5);
  545. }
  546.  
  547.  /*
  548.  
  549.  .-----+----------+-------------------------+-------------------------+-----.
  550.  | RS7 | ExtMail  | 1. String matched       | External mail selected  | exit|
  551.  |     |          +-------------------------+-------------------------+-----|
  552.  |     |          | 2. Checked all strings  | Get next input character| RS5 |
  553.  `-----+----------+-------------------------+-------------------------+-----'
  554.  
  555.  */
  556.  
  557.  
  558. static int RSExtMail (args)
  559. RSARGSP args;
  560. {
  561.    int i, k;
  562.  
  563.    /* Note: last character was read in RS5 using a NON-DESTRUCTIVE READ.
  564.       We now will get it out with a DESTRUCTIVE READ.                     */
  565.  
  566.    i = TIMED_READ (0) & 0xff;                    /* Eat the character     */
  567.  
  568.    for (k = 0; k < num_ext_mail; k++) {
  569.       if (i != *(args->ExtMailScan[k]++)) {      /* Does this match next? */
  570.          args->ExtMailScan[k] = ext_mail_string[k];  /* No, reset pointer */
  571.       } else {
  572.          if (!*args->ExtMailScan[k]) {           /* End of UUCP string?   */
  573.                 args->result = 5 + k;            /* 5 + n for external    */
  574.                 return (RSexit);
  575.          }
  576.       }
  577.    }
  578.  
  579.    return (RS5);
  580. }
  581.