home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / EXTRAS / UUCODE / UUPC / TEST / UPC12ES2.ZIP / UUCICO / dcp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-28  |  27.5 KB  |  832 lines

  1. /*--------------------------------------------------------------------*/
  2. /*          d c p . c                                                 */
  3. /*                                                                    */
  4. /*          Main routines for UUCICO                                  */
  5. /*--------------------------------------------------------------------*/
  6.  
  7. /*--------------------------------------------------------------------*/
  8. /*    Changes Copyright (c) 1989-1993 by Kendra Electronic            */
  9. /*    Wonderworks.                                                    */
  10. /*                                                                    */
  11. /*    All rights reserved except those explicitly granted by the      */
  12. /*    UUPC/extended license agreement.                                */
  13. /*--------------------------------------------------------------------*/
  14.  
  15. /*--------------------------------------------------------------------*/
  16. /*    Copyright (c) Richard H. Lamb 1985, 1986, 1987                  */
  17. /*    Changes Copyright (c) Stuart Lynne 1987                         */
  18. /*--------------------------------------------------------------------*/
  19.  
  20. /*
  21.  *    $Id: dcp.c 1.23 1993/10/28 12:19:01 ahd Exp $
  22.  *
  23.  *    $Log: dcp.c $
  24.  * Revision 1.23  1993/10/28  12:19:01  ahd
  25.  * Cosmetic time formatting twiddles and clean ups
  26.  *
  27.  * Revision 1.22  1993/10/25  01:21:22  ahd
  28.  * Restructure to suppress silly unable to perform global optimizations
  29.  * message under MS C 6.0.
  30.  * Trap and report invalid system names when dialing out.
  31.  *
  32.  * Revision 1.21  1993/10/12  01:32:46  ahd
  33.  * Normalize comments to PL/I style
  34.  *
  35.  * Revision 1.20  1993/10/03  20:37:34  ahd
  36.  * Don't attempt to suspend port if using network protocol suite
  37.  *
  38.  * Revision 1.19  1993/09/30  03:06:28  ahd
  39.  * Move suspend signal handler into suspend2
  40.  *
  41.  * Revision 1.18  1993/09/29  13:18:06  ahd
  42.  * Don't call suspend handler under DOS Turbo C++ (not impletemented, anyway)
  43.  *
  44.  * Revision 1.17  1993/09/29  04:52:03  ahd
  45.  * Suspend port by port name, not modem file name
  46.  *
  47.  * Revision 1.16  1993/09/27  00:48:43  ahd
  48.  * Control UUCICO in passive mode by K. Rommel
  49.  *
  50.  * Revision 1.15  1993/09/20  04:46:34  ahd
  51.  * OS/2 2.x support (BC++ 1.0 support)
  52.  * TCP/IP support from Dave Watt
  53.  * 't' protocol support
  54.  *
  55.  * Revision 1.14  1993/08/02  03:24:59  ahd
  56.  * Further changes in support of Robert Denny's Windows 3.x support
  57.  *
  58.  * Revision 1.13  1993/07/31  16:26:01  ahd
  59.  * Changes in support of Robert Denny's Windows support
  60.  *
  61.  * Revision 1.12  1993/07/22  23:22:27  ahd
  62.  * First pass at changes for Robert Denny's Windows 3.1 support
  63.  *
  64.  * Revision 1.11  1993/05/30  00:01:47  ahd
  65.  * Allow tracing connection via UUCICO -t flag
  66.  *
  67.  * Revision 1.10  1993/04/11  00:35:46  ahd
  68.  * Global edits for year, TEXT, etc.
  69.  *
  70.  * Revision 1.9  1993/04/05  04:32:19  ahd
  71.  * Allow unique send and receive packet sizes
  72.  *
  73.  * Revision 1.8  1993/01/23  19:08:09  ahd
  74.  * Don't update host status at sysend() if hostp is not initialized
  75.  *
  76.  * Revision 1.7  1992/12/18  12:05:57  ahd
  77.  * Suppress duplicate machine state messages to improve OS/2 scrolling
  78.  *
  79.  * Revision 1.6  1992/12/01  04:37:03  ahd
  80.  * Add standard comment block for header
  81.  *
  82.  * Revision 1.5  1992/11/28  19:51:16  ahd
  83.  * If in multitask mode, only open syslog on demand basis
  84.  *
  85.  * Revision 1.4  1992/11/22  21:30:55  ahd
  86.  * Do not bother to strdup() string arguments
  87.  *
  88.  * 25Aug87 - Added a version number - Jal
  89.  * 25Aug87 - Return 0 if contact made with host, or 5 otherwise.
  90.  * 04Sep87 - Bug causing premature sysend() fixed. - Randall Jessup
  91.  * 13May89 - Add date to version message  - Drew Derbyshire
  92.  * 17May89 - Add '-u' (until) option for login processing
  93.  * 01 Oct 89      Add missing function prototypes
  94.  * 28 Nov 89      Add parse of incoming user id for From record
  95.  * 18 Mar 90      Change checktime() calls to Microsoft C 5.1
  96.  */
  97.  
  98. /*--------------------------------------------------------------------*/
  99. /* This program implements a uucico type file transfer and remote     */
  100. /* execution protocol.                                                */
  101. /*                                                                    */
  102. /* Usage:   UUCICO [-s sys]                                           */
  103. /*                 [-r 0|1]                                           */
  104. /*                 [-x debug]                                         */
  105. /*                 [-d hhmm]                                          */
  106. /*                 [-m modem]                                         */
  107. /*                 [-l logfile]                                       */
  108. /*                 [-x debuglevel]                                    */
  109. /*                 [-w userid]                                        */
  110. /*                 [-z bps]                                           */
  111. /*                 [-t]                                               */
  112. /*                                                                    */
  113. /* e.g.                                                               */
  114. /*                                                                    */
  115. /* UUCICO [-x n] -r 0 [-d hhmm]    client mode, wait for an incoming  */
  116. /*                                 call for 'hhmm'.                   */
  117. /* UUCICO [-x n] -s HOST     call the host "HOST".                    */
  118. /* UUCICO [-x n] -s all      call all known hosts in the systems      */
  119. /*                           file.                                    */
  120. /* UUCICO [-x n] -s any      call any host we have work queued for.   */
  121. /* UUCICO [-x n]             same as the above.                       */
  122. /*--------------------------------------------------------------------*/
  123.  
  124. /*--------------------------------------------------------------------*/
  125. /*                        System include files                        */
  126. /*--------------------------------------------------------------------*/
  127.  
  128. #include <stdio.h>
  129. #include <stdlib.h>
  130. #include <string.h>
  131. #include <sys/types.h>
  132. #include <limits.h>
  133. #include <time.h>
  134.  
  135. #ifdef _Windows
  136. #include <Windows.h>
  137. #endif
  138.  
  139. /*--------------------------------------------------------------------*/
  140. /*                      UUPC/extended prototypes                      */
  141. /*--------------------------------------------------------------------*/
  142.  
  143. #include "lib.h"
  144. #include "catcher.h"
  145. #include "checktim.h"
  146. #include "dcp.h"
  147. #include "dcplib.h"
  148. #include "dcpstats.h"
  149. #include "dcpsys.h"
  150. #include "dcpxfer.h"
  151. #include "expath.h"
  152. #include "getopt.h"
  153. #include "hlib.h"
  154. #include "hostable.h"
  155. #include "hostatus.h"
  156. #include "lock.h"
  157. #include "logger.h"
  158. #include "modem.h"
  159. #include "security.h"
  160. #include "ssleep.h"
  161. #include "suspend.h"
  162. #include "commlib.h"
  163.  
  164. #if defined(_Windows)
  165. #include "winutil.h"
  166. #endif
  167.  
  168. /*--------------------------------------------------------------------*/
  169. /*    Define passive and active polling modes; passive is             */
  170. /*    sometimes refered to as "slave", "active" as master.  Since     */
  171. /*    the roles can actually switch during processing, we avoid       */
  172. /*    the terms here                                                  */
  173. /*--------------------------------------------------------------------*/
  174.  
  175. typedef enum {
  176.       POLL_PASSIVE = 0,       /* We answer the telephone          */
  177.       POLL_ACTIVE  = 1        /* We call out to another host      */
  178.       } POLL_MODE ;
  179.  
  180. /*--------------------------------------------------------------------*/
  181. /*                          Global variables                          */
  182. /*--------------------------------------------------------------------*/
  183.  
  184. size_t s_pktsize;             /* send packet size for protocol       */
  185. size_t r_pktsize;             /* receive packet size for protocol    */
  186.  
  187. FILE *xfer_stream = NULL;        /* stream for file being handled    */
  188. boolean callnow = FALSE;           /* TRUE = ignore time in L.SYS     */
  189. FILE *fwork = NULL, *fsys= NULL ;
  190. FILE *syslog = NULL;
  191. char workfile[FILENAME_MAX];  /* name of current workfile         */
  192. char *Rmtname = "any";        /* system we want to call           */
  193. char rmtname[20];             /* system we end up talking to      */
  194. struct HostTable *hostp;
  195. struct HostStats remote_stats; /* host status, as defined by hostatus */
  196.  
  197. static boolean dialed = FALSE;/* True = We attempted a phone call */
  198.  
  199. currentfile();
  200.  
  201. /*--------------------------------------------------------------------*/
  202. /*                     Local function prototypes                      */
  203. /*--------------------------------------------------------------------*/
  204.  
  205. static CONN_STATE process( const POLL_MODE poll_mode, const char callgrade );
  206.  
  207. static boolean master( const char recvgrade,
  208.                        const boolean overrideGrade);
  209.  
  210. static boolean client( const time_t exit_time,
  211.                        const char *hotuser,
  212.                        const BPS hotbaud );
  213.  
  214. /*--------------------------------------------------------------------*/
  215. /*    d c p m a i n                                                   */
  216. /*                                                                    */
  217. /*    main program for DCP, called by uuhost                          */
  218. /*--------------------------------------------------------------------*/
  219.  
  220. int dcpmain(int argc, char *argv[])
  221. {
  222.  
  223.    char *logfile_name = NULL;
  224.    boolean  contacted = FALSE;
  225.  
  226.    int option;
  227.    int poll_mode = POLL_ACTIVE;   /* Default = dial out to system     */
  228.    time_t exit_time = LONG_MAX;
  229.  
  230.    char recvgrade = ALL_GRADES;
  231.    boolean overrideGrade = FALSE;
  232.  
  233.    char *hotuser = NULL;
  234.    BPS  hotbaud = 0;
  235.  
  236.    fwork = nil(FILE);
  237.  
  238. /*--------------------------------------------------------------------*/
  239. /*                        Process our options                         */
  240. /*--------------------------------------------------------------------*/
  241.  
  242.    while ((option = getopt(argc, argv, "d:g:m:l:r:s:tw:x:z:n?")) != EOF)
  243.       switch (option)
  244.       {
  245.  
  246.       case 'd':
  247.          exit_time = atoi( optarg );
  248.          exit_time = time(NULL) + hhmm2sec(exit_time);
  249.          poll_mode = POLL_PASSIVE;  /* Implies passive polling       */
  250.          break;
  251.  
  252.       case 'g':
  253.          if (strlen(optarg) == 1 )
  254.             recvgrade = *optarg;
  255.          else {
  256.             recvgrade = checktime( optarg );
  257.                                  /* Get restriction for this hour */
  258.             if ( ! recvgrade )   /* If no class, use the default  */
  259.                recvgrade = ALL_GRADES;
  260.          }
  261.          overrideGrade = TRUE;
  262.          break;
  263.  
  264.       case 'm':                     /* Override in modem name     */
  265.          E_inmodem = optarg;
  266.          poll_mode = POLL_PASSIVE;  /* Implies passive polling       */
  267.          break;
  268.  
  269.       case 'l':                     /* Log file name              */
  270.          logfile_name = optarg;
  271.          break;
  272.  
  273.       case 'n':
  274.          callnow = TRUE;
  275.          break;
  276.  
  277.       case 'r':
  278.          poll_mode = atoi(optarg);
  279.          break;
  280.  
  281.       case 's':
  282.          Rmtname = optarg;
  283.          break;
  284.  
  285.       case 't':
  286.          traceEnabled = TRUE;
  287.          break;
  288.  
  289.       case 'x':
  290.          debuglevel = atoi(optarg);
  291.          break;
  292.  
  293.       case 'z':
  294.          hotbaud = atoi(optarg);
  295.          break;
  296.  
  297.       case 'w':
  298.          poll_mode = POLL_PASSIVE;  /* Implies passive polling       */
  299.          hotuser = optarg;
  300.          break;
  301.  
  302.       case '?':
  303.          puts("\nUsage:\tuucico\t"
  304.          "[-s [all | any | sys]] [-r 1|0] [-x debug] [-d hhmm]\n"
  305.          "\t\t[-n] [-t] [-w user] [-l logfile] [-m modem] [-z bps]");
  306.          return 4;
  307.       }
  308.  
  309. /*--------------------------------------------------------------------*/
  310. /*                Abort if any options were left over                 */
  311. /*--------------------------------------------------------------------*/
  312.  
  313.    if (optind != argc) {
  314.       puts("Extra parameter(s) at end.");
  315.       return 4;
  316.    }
  317.  
  318. /*--------------------------------------------------------------------*/
  319. /*        Initialize logging and the name of the systems file         */
  320. /*--------------------------------------------------------------------*/
  321.  
  322.    openlog( logfile_name );
  323.  
  324.    if (bflag[F_SYSLOG] && ! bflag[F_MULTITASK])
  325.    {
  326.       syslog = FOPEN(SYSLOG, "a",TEXT_MODE);
  327.       if ((syslog == nil(FILE)) || setvbuf( syslog, NULL, _IONBF, 0))
  328.       {
  329.          printerr( SYSLOG );
  330.          panic();
  331.       }
  332.    }
  333.  
  334.    if ( terminate_processing )
  335.       return 100;
  336.  
  337. /*--------------------------------------------------------------------*/
  338. /*                        Initialize security                         */
  339. /*--------------------------------------------------------------------*/
  340.  
  341.    if ( !LoadSecurity())
  342.    {
  343.       printmsg(0,"Unable to initialize security, see previous message");
  344.       panic();
  345.    }
  346.  
  347.    if ( terminate_processing )
  348.       return 100;
  349.  
  350. #if defined(_Windows)
  351.    atexit(CloseEasyWin);       /* Auto-close EasyWin window on exit   */
  352. #endif
  353.  
  354.    atexit( shutDown );        /* Insure port is closed by panic()    */
  355.    remote_stats.save_hstatus = nocall;
  356.                               /* Known state for automatic status
  357.                                  update                              */
  358.  
  359. /*--------------------------------------------------------------------*/
  360. /*                     Begin main processing loop                     */
  361. /*--------------------------------------------------------------------*/
  362.  
  363.    if (poll_mode == POLL_ACTIVE)
  364.       contacted = master(recvgrade, overrideGrade);
  365.    else if (poll_mode == POLL_PASSIVE)
  366.       contacted = client(exit_time, hotuser, hotbaud);
  367.    else {
  368.       printmsg(0,"Invalid -r flag, must be 0 or 1");
  369.       panic();
  370.    }
  371.  
  372. /*--------------------------------------------------------------------*/
  373. /*                         Report our results                         */
  374. /*--------------------------------------------------------------------*/
  375.  
  376.    if (!contacted && (poll_mode == POLL_ACTIVE))
  377.    {
  378.       if (dialed)
  379.          printmsg(0, "Could not connect to remote system.");
  380.       else
  381.          printmsg(0,
  382.                "No work for requested system or wrong time to call.");
  383.    }
  384.  
  385.    dcupdate();
  386.  
  387.    if (bflag[F_SYSLOG] && ! bflag[F_MULTITASK])
  388.       fclose(syslog);
  389.  
  390.    return terminate_processing ? 100 : (contacted ? 0 : 5);
  391.  
  392. } /*dcpmain*/
  393.  
  394. /*--------------------------------------------------------------------*/
  395. /*       m a s t e r                                                  */
  396. /*                                                                    */
  397. /*       Call out to other sites                                      */
  398. /*--------------------------------------------------------------------*/
  399.  
  400. static boolean master( const char recvgrade,
  401.                        const boolean overrideGrade)
  402. {
  403.  
  404.    CONN_STATE m_state = CONN_INITSTAT;
  405.    CONN_STATE old_state = CONN_EXIT;
  406.  
  407.    char sendgrade = ALL_GRADES;
  408.  
  409.    boolean contacted = FALSE;
  410.  
  411. /*--------------------------------------------------------------------*/
  412. /*                    Validate the system to call                     */
  413. /*--------------------------------------------------------------------*/
  414.  
  415.    if ( !equal( Rmtname, "any" ) && !equal( Rmtname, "all" ))
  416.    {
  417.       if ( checkreal( Rmtname ) == NULL )
  418.       {
  419.          printmsg(0,"%s is not \"any\", \"all\", or a valid system to call",
  420.                      Rmtname);
  421.          printmsg(0,"Run UUNAME for a list of callable systems");
  422.          panic();
  423.       }
  424.  
  425.    }
  426.  
  427.    if ((fsys = FOPEN(E_systems, "r",TEXT_MODE)) == nil(FILE))
  428.    {
  429.       printerr(E_systems);
  430.       panic();
  431.    }
  432.  
  433.    setvbuf( fsys, NULL, _IONBF, 0);
  434.  
  435.    while (m_state != CONN_EXIT )
  436.    {
  437.       printmsg(old_state == m_state ? 10 : 4 ,
  438.                "M state = %c", m_state);
  439.       old_state = m_state;
  440.  
  441.       if (bflag[F_MULTITASK] &&
  442.            (hostp != NULL ) &&
  443.            (remote_stats.save_hstatus != hostp->hstatus ))
  444.       {
  445.          dcupdate();
  446.          remote_stats.save_hstatus = hostp->hstatus;
  447.       }
  448.  
  449.       switch (m_state)
  450.       {
  451.          case CONN_INITSTAT:
  452.             HostStatus();
  453.             m_state = CONN_INITIALIZE;
  454.             break;
  455.  
  456.          case CONN_INITIALIZE:
  457.             hostp = NULL;
  458.  
  459.             if ( locked )
  460.                UnlockSystem();
  461.  
  462.             m_state = getsystem(recvgrade);
  463.             if ( hostp != NULL )
  464.                remote_stats.save_hstatus = hostp->hstatus;
  465.             break;
  466.  
  467.          case CONN_CHECKTIME:
  468.             sendgrade = checktime(flds[FLD_CCTIME]);
  469.  
  470.             if ( (overrideGrade && sendgrade) || callnow )
  471.                sendgrade = recvgrade;
  472.  
  473.             if ( !CallWindow( sendgrade ))
  474.                m_state = CONN_INITIALIZE;
  475.             else if ( LockSystem( hostp->hostname , B_UUCICO))
  476.             {
  477.                dialed = TRUE;
  478.                time(&hostp->hstats->ltime);
  479.                               /* Save time of last attempt to call  */
  480.                hostp->hstatus = autodial;
  481.                m_state = CONN_MODEM;
  482.             }
  483.             else
  484.                m_state = CONN_INITIALIZE;
  485.  
  486.             break;
  487.  
  488.          case CONN_MODEM:
  489.             if (getmodem(flds[FLD_TYPE]))
  490.                m_state = CONN_DIALOUT;
  491.             else {
  492.                hostp->hstatus = invalid_device;
  493.                m_state = CONN_INITIALIZE;
  494.             }
  495.             break;
  496.  
  497.          case CONN_DIALOUT:
  498.  
  499.             if ( !IsNetwork() && suspend_other(TRUE, M_device ) < 0 )
  500.             {
  501.                hostp->hstatus =  nodevice;
  502.                m_state = CONN_INITIALIZE;    /* Try next system     */
  503.             }
  504.             else
  505.                m_state = callup( );
  506.             break;
  507.  
  508.          case CONN_PROTOCOL:
  509.             m_state = startup_server( (char)
  510.                                        (bflag[F_SYMMETRICGRADES] ?
  511.                                        sendgrade  : recvgrade) );
  512.             break;
  513.  
  514.          case CONN_SERVER:
  515.             m_state = process( POLL_ACTIVE, recvgrade );
  516.             contacted = TRUE;
  517.             break;
  518.  
  519.          case CONN_TERMINATE:
  520.             m_state = sysend();
  521.             if ( hostp != NULL )
  522.             {
  523.                if (hostp->hstatus == inprogress)
  524.                   hostp->hstatus = call_failed;
  525.                dcstats();
  526.             }
  527.             break;
  528.  
  529.          case CONN_DROPLINE:
  530.             shutDown();
  531.             UnlockSystem();
  532.             suspend_other(FALSE, M_device);
  533.             m_state = CONN_INITIALIZE;
  534.             break;
  535.  
  536.          case CONN_EXIT:
  537.             break;
  538.  
  539.          default:
  540.             printmsg(0,"dcpmain: Unknown master state = %c",m_state );
  541.             panic();
  542.             break;
  543.       } /* switch */
  544.  
  545.       if ( terminate_processing )
  546.          m_state = CONN_EXIT;
  547.  
  548.    } /* while */
  549.  
  550.    fclose(fsys);
  551.  
  552.    return contacted;
  553.  
  554. } /* master */
  555.  
  556. /*--------------------------------------------------------------------*/
  557. /*       c l i e n t                                                  */
  558. /*                                                                    */
  559. /*       Allow other systems to call us                               */
  560. /*--------------------------------------------------------------------*/
  561.  
  562. static boolean client( const time_t exit_time,
  563.                        const char *hotuser,
  564.                        const BPS hotbaud )
  565. {
  566.  
  567.    CONN_STATE s_state = CONN_INITIALIZE;
  568.    CONN_STATE old_state = CONN_EXIT;
  569.  
  570.    boolean contacted = FALSE;
  571.  
  572.    char sendgrade = ALL_GRADES;
  573.  
  574.    if (!getmodem(E_inmodem))  /* Initialize modem configuration     */
  575.       panic();                /* Avoid loop if bad modem name       */
  576.  
  577.    if ( ! IsNetwork() )
  578.       suspend_init(M_device);
  579.  
  580.    while (s_state != CONN_EXIT )
  581.    {
  582.       printmsg(s_state == old_state ? 10 : 4 ,
  583.                "S state = %c", s_state);
  584.       old_state = s_state;
  585.  
  586.       if (bflag[F_MULTITASK] &&
  587.            (hostp != NULL ) &&
  588.            (remote_stats.save_hstatus != hostp->hstatus ))
  589.       {
  590.          printmsg(2, "Updating status for host %s, status %d",
  591.                      hostp->hostname ,
  592.                      (int) hostp->hstatus );
  593.          dcupdate();
  594.          remote_stats.save_hstatus = hostp->hstatus;
  595.       }
  596.  
  597.       switch (s_state) {
  598.          case CONN_INITIALIZE:
  599.             if ( hotuser == NULL )
  600.                s_state = CONN_ANSWER;
  601.             else
  602.                s_state = CONN_HOTMODEM;
  603.             break;
  604.  
  605.          case CONN_WAIT:
  606. #if !defined(__TURBOC__) || defined(BIT32ENV)
  607.            s_state = suspend_wait();
  608. #else
  609.            panic();                 /* Why are we here?!           */
  610. #endif
  611.            break;
  612.  
  613.          case CONN_ANSWER:
  614.             s_state = callin( exit_time );
  615.             break;
  616.  
  617.          case CONN_HOTMODEM:
  618.             s_state = callhot( hotbaud );
  619.             break;
  620.  
  621.          case CONN_HOTLOGIN:
  622.             if ( loginbypass( hotuser ) )
  623.                s_state = CONN_INITSTAT;
  624.             else
  625.                s_state = CONN_DROPLINE;
  626.             break;
  627.  
  628.          case CONN_LOGIN:
  629.             if ( login( ) )
  630.                s_state = CONN_INITSTAT;
  631.             else
  632.                s_state = CONN_DROPLINE;
  633.             break;
  634.  
  635.          case CONN_INITSTAT:
  636.             HostStatus();
  637.             s_state = CONN_PROTOCOL;
  638.             break;
  639.  
  640.          case CONN_PROTOCOL:
  641.             s_state = startup_client(&sendgrade);
  642.             break;
  643.  
  644.          case CONN_CLIENT:
  645.             contacted = TRUE;
  646.             s_state = process( POLL_PASSIVE, sendgrade );
  647.             break;
  648.  
  649.          case CONN_TERMINATE:
  650.             s_state = sysend();
  651.             if ( hostp != NULL )
  652.                dcstats();
  653.             break;
  654.  
  655.          case CONN_DROPLINE:
  656.             shutDown();
  657.             if ( locked )     /* Cause could get here w/o
  658.                                  locking                    */
  659.                UnlockSystem();
  660.             s_state = CONN_EXIT;
  661.             break;
  662.  
  663.          case CONN_EXIT:
  664.             break;
  665.  
  666.          default:
  667.             printmsg(0,"dcpmain: Unknown slave state = %c",s_state );
  668.             panic();
  669.             break;
  670.       } /* switch */
  671.  
  672.       if ( terminate_processing )
  673.          s_state = CONN_EXIT;
  674.  
  675.    } /* while */
  676.  
  677.    return contacted;
  678.  
  679. } /* client */
  680.  
  681. /*--------------------------------------------------------------------*/
  682. /*    p r o c e s s                                                   */
  683. /*                                                                    */
  684. /*    The procotol state machine                                      */
  685. /*--------------------------------------------------------------------*/
  686.  
  687. static CONN_STATE process( const POLL_MODE poll_mode, const char callgrade )
  688. {
  689.    boolean master  = ( poll_mode == POLL_ACTIVE );
  690.    boolean aborted = FALSE;
  691.    XFER_STATE state =  master ? XFER_SENDINIT : XFER_RECVINIT;
  692.    XFER_STATE old_state = XFER_EXIT;
  693.                               /* Initialized to any state but the
  694.                                  original value of "state"           */
  695.    XFER_STATE save_state = XFER_EXIT;
  696.  
  697. /*--------------------------------------------------------------------*/
  698. /*  Yea old state machine for the high level file transfer procotol   */
  699. /*--------------------------------------------------------------------*/
  700.  
  701.    while( state != XFER_EXIT )
  702.    {
  703.       printmsg(state == old_state ? 14 : 4 ,
  704.                "process: Machine state is = %c", state );
  705.       old_state = state;
  706.  
  707.       if ( terminate_processing != aborted )
  708.       {
  709.          aborted = terminate_processing;
  710.          state = XFER_ABORT;
  711.       }
  712.  
  713.       switch( state )
  714.       {
  715.  
  716.          case XFER_SENDINIT:  /* Initialize outgoing protocol        */
  717.             state = sinit();
  718.             break;
  719.  
  720.          case XFER_RECVINIT:  /* Initialize Receive protocol         */
  721.             state = rinit();
  722.             break;
  723.  
  724.          case XFER_MASTER:    /* Begin master mode                   */
  725.             master = TRUE;
  726.             state = XFER_NEXTJOB;
  727.             break;
  728.  
  729.          case XFER_SLAVE:     /* Begin slave mode                    */
  730.             master = FALSE;
  731.             state = XFER_RECVHDR;
  732.             break;
  733.  
  734.          case XFER_NEXTJOB:   /* Look for work in local queue        */
  735.             state = scandir( rmtname, callgrade );
  736.             break;
  737.  
  738.          case XFER_REQUEST:   /* Process next file in current job
  739.                                  in queue                            */
  740.             state = newrequest();
  741.             break;
  742.  
  743.          case XFER_PUTFILE:   /* Got local tranmit request           */
  744.             state = ssfile();
  745.             break;
  746.  
  747.          case XFER_GETFILE:   /* Got local tranmit request           */
  748.             state = srfile();
  749.             break;
  750.  
  751.          case XFER_SENDDATA:  /* Remote accepted our work, send data */
  752.             state = sdata();
  753.             break;
  754.  
  755.          case XFER_SENDEOF:   /* File xfer complete, send EOF        */
  756.             state = seof( master );
  757.             break;
  758.  
  759.          case XFER_FILEDONE:  /* Receive or transmit is complete     */
  760.             state = master ? XFER_REQUEST : XFER_RECVHDR;
  761.             break;
  762.  
  763.          case XFER_NOLOCAL:   /* No local work, remote have any?     */
  764.             state = sbreak();
  765.             break;
  766.  
  767.          case XFER_NOREMOTE:  /* No remote work, local have any?     */
  768.             state = schkdir( poll_mode == POLL_ACTIVE, callgrade );
  769.             break;
  770.  
  771.          case XFER_RECVHDR:   /* Receive header from other host      */
  772.             state = rheader();
  773.             break;
  774.  
  775.          case XFER_TAKEFILE:  /* Set up to receive remote requested
  776.                                  file transfer                       */
  777.             state = rrfile();
  778.             break;
  779.  
  780.          case XFER_GIVEFILE:  /* Set up to transmit remote
  781.                                  requuest file transfer              */
  782.             state = rsfile();
  783.             break;
  784.  
  785.          case XFER_RECVDATA:  /* Receive file data from other host   */
  786.             state = rdata();
  787.             break;
  788.  
  789.          case XFER_RECVEOF:
  790.             state = reof();
  791.             break;
  792.  
  793.          case XFER_LOST:      /* Lost the other host, flame out      */
  794.             printmsg(0,"process: Connection lost to %s, "
  795.                        "previous system state = %c",
  796.                        rmtname, save_state );
  797.             hostp->hstatus = call_failed;
  798.             state = XFER_EXIT;
  799.             break;
  800.  
  801.          case XFER_ABORT:     /* Internal error, flame out           */
  802.             printmsg(0,"process: Aborting connection to %s, "
  803.                        "previous system state = %c",
  804.                        rmtname, save_state );
  805.             hostp->hstatus = call_failed;
  806.             state = XFER_ENDP;
  807.             break;
  808.  
  809.          case XFER_ENDP:      /* Terminate the protocol              */
  810.             state = endp();
  811.             break;
  812.  
  813.          default:
  814.             printmsg(0,"process: Unknown state = %c, "
  815.                        "previous system state = %c",
  816.                        state, save_state );
  817.             state = XFER_ABORT;
  818.             break;
  819.       } /* switch */
  820.  
  821.       save_state = old_state; /* Used only if we abort               */
  822.  
  823.    } /* while( state != XFER_EXIT ) */
  824.  
  825. /*--------------------------------------------------------------------*/
  826. /*           Protocol is complete, terminate the connection           */
  827. /*--------------------------------------------------------------------*/
  828.  
  829.    return CONN_TERMINATE;
  830.  
  831. } /* process */
  832.