home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff319.lzh / CNewsSrc / uupc.lzh / uupc / dcp.c < prev    next >
C/C++ Source or Header  |  1990-01-16  |  9KB  |  462 lines

  1. /*    dcp.c
  2.  *
  3.  *    Revised edition of dcp
  4.  *
  5.  *    Stuart Lynne May/87
  6.  *
  7.  *    Copyright (c) Richard H. Lamb 1985, 1986, 1987
  8.  *    Changes Copyright (c) Stuart Lynne 1987
  9.  *
  10.  *    $Id: dcp.c,v 1.2 90/01/16 10:25:00 crash Exp Locker: crash $
  11.  */
  12.  
  13. #ifndef lint
  14. static char RCSid[] = "$Id: dcp.c,v 1.2 90/01/16 10:25:00 crash Exp Locker: crash $";
  15. #endif /* lint */
  16.  
  17. /*
  18.  *    "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987
  19.  *    This program implements a uucico type file transfer and remote
  20.  *    execution type protocol.
  21.  */
  22.  
  23. #include "dcp.h"
  24.  
  25. int        pktsize;                /* packet size for pro */
  26. FILE    *logfile;                /* system log file */
  27. FILE    *syslog;                /* transmission log file */
  28. FILE    *fw;                     /* cmdfile pointer */
  29. char    state;                    /* system state */
  30. char    cfile[80];              /* work file pointer */
  31. int        remote;                 /* -1 means we're remote ..7 */
  32. int        msgtime;                /* timout setting */
  33. char    fromfile[132];
  34. char    hostfile[132];            /* host version of fromfile */
  35. char    tofile[132];
  36. int        fp;                     /* current disk file ptr */
  37. int        size;                   /* nbytes in buff */
  38. FILE    *fsys;
  39. char    Rmtname[20];
  40. char    rmtname[20];
  41. char    *cctime;
  42. char    proto[5];
  43. /* char    loginseq[256]; */
  44. char     sysline[BUFSIZ];
  45. char    s_systems[64];
  46. char    s_logfile[64];
  47. char    s_syslog[64];
  48. char     *flds[60];
  49. int     kflds;
  50.  
  51. extern    int        debuglevel;                /* debugging flag */
  52.  
  53. unsigned int    checksum();
  54.  
  55.  
  56.  
  57. /*
  58.  *    new usage
  59.  *
  60.  *    dcp    [-xn] -r0        slave mode
  61.  *    dcp    [-xn] -shost    call host
  62.  *    dcp    [-xn] -sall        call all hosts
  63.  *    dcp    [-xn]             call any hosts as required by C. files
  64.  */
  65.  
  66. complain(s)
  67. char *s;
  68. {
  69.     fprintf(stderr, "Please set your %s environment variable.", s);
  70. }
  71.  
  72. static void cant(file)
  73. char *file;
  74. {
  75.     fprintf(stderr, "Can't open: \"%s\"\n", file);
  76.     exit( NULL );
  77. }
  78.  
  79. dcpmain( argc, argv )
  80. int    argc;
  81. char *argv[];
  82. {
  83.     FILE    *ftmp;
  84.     char    line[132];
  85. #ifdef FJE
  86.     short    inhibit_xqt = FALSE;
  87.     short    goto_xqt = FALSE;
  88. #endif /* FJE */
  89.  
  90.     if (!name || !*name) {
  91.         complain(NAME);
  92.         exit( -1 );
  93.     }
  94.     if (!nodename || !*nodename) {
  95.         complain(NODENAME);
  96.         exit( -1 );
  97.     }
  98.     mkfilename(s_logfile, logdir,  LOGFILE);
  99.     mkfilename(s_syslog,  logdir,  SYSLOG);
  100.     mkfilename(s_systems, confdir, SYSTEMS);
  101.  
  102.     if ((logfile = FOPEN(s_logfile, "a", 't')) == NULL)
  103.        cant(s_logfile);
  104.     if ((syslog  = FOPEN(s_syslog,  "a", 't')) == NULL)
  105.        cant(s_syslog);
  106.  
  107.     remote = MASTER;
  108.     debuglevel = 1;
  109.     fp = -1;
  110.     fw = (FILE *) NULL;
  111.     strcpy(Rmtname, "any");
  112.  
  113.     while (--argc) {
  114.         if (**++argv == '-') {
  115.             switch(argv[0][1]) {
  116. #ifdef FJE
  117.             case 'i':                /* "-i" to disable DCXQT() */
  118.                 inhibit_xqt = TRUE;
  119.                 break;
  120.             case 'c':                /* "-c" to jump down to DCXQT() */
  121.                 goto_xqt = TRUE;
  122.                 break;
  123. #endif /* FJE */
  124.             case 'x':
  125.                 debuglevel = atoi(argv[0]+2);
  126.                 break;
  127.             case 's':
  128.                 sprintf(Rmtname, "%.7s", argv[0]+2);
  129.                 break;
  130.             case 'r':
  131.                 remote = atoi(argv[0]+2);
  132.                 break;
  133.             default:
  134.                 break;
  135.             }
  136.         }
  137.     }
  138.     printmsg( 0, "remote = %d", remote);
  139.     printmsg( 0, "debuglevel = %d", debuglevel);
  140.     printmsg( 0, "Rmtname = %s", Rmtname);
  141.     if (goto_xqt)
  142.         goto try_dcxqt;
  143.  
  144.     if (remote == MASTER) {
  145.          printmsg( 0, "Calling %s", Rmtname );
  146.         if (( fsys = FOPEN( s_systems, "r", 't' )) == (char *)NULL )
  147.             exit( FAILED );
  148.         state = 'I';
  149.  
  150.         while (TRUE) {
  151.             printmsg( 4, "Mstate = %c", state );
  152.             switch (state) {
  153.             case 'I':
  154.                 state = getsystem();
  155.                 break;
  156.             case 'S':
  157.                 state = callup();
  158.                 break;
  159.             case 'P':
  160.                 state = startup();
  161.                 break;
  162.             case 'D':
  163.                 state = master();
  164.                 break;
  165.             case 'Y':
  166.                 state = sysend();
  167.                 break;
  168.             case 'G':
  169.                 if ( strcmp( Rmtname, "any" ) != SAME )
  170.                     state = 'Y';
  171.                 else
  172.                     state = 'I';
  173.                 break;
  174.             }
  175.             if (state == 'A')
  176.                 break;
  177.         }
  178.         fclose( fsys );
  179.     } else {
  180.          printmsg( 0, "Answering %s, speed %d", device, speed );
  181.         if (openline( device, speed ) == -1)
  182.             return(FALSE);
  183.         state = 'L';
  184.         while (TRUE) {
  185.             printmsg( 4, "Sstate = %c", state );
  186.             switch (state) {
  187.             case 'L':
  188.                 state = login();
  189.                 break;
  190.             case 'I':
  191.                 state = startup();
  192.                 break;
  193.             case 'R':
  194.                 state = slave();
  195.                 break;
  196.             case 'Y':
  197.                 state = sysend();
  198.                 break;
  199.             }
  200.             if (state == 'A')
  201.                 break;
  202.         }
  203.         closeline();
  204.     }
  205.     /* scan and process any received files */
  206.  
  207. try_dcxqt:
  208.     if (!inhibit_xqt && dcxqt())
  209.         printmsg( 0, "ERROR in DCXQT" );
  210.  
  211.     fclose( syslog );
  212.     fclose( logfile );
  213.     /*
  214.      *    If we initiated a call (remote == MASTER) and the
  215.      *    system responded without errors [or at least, without
  216.      *    an ABORT code 'A'], return 1 to the shell.
  217.      *
  218.      *    [The function sysend() returns 'I' if successful in
  219.      *    terminating the connection.  This allows the state
  220.      *    machine to start over again with the next machine
  221.      *    to call, although this isn't implemented :-]
  222.      */
  223.     return( (remote == MASTER) && (state != 'A') );
  224. }
  225.  
  226. /*
  227.  *    master
  228.  */
  229.  
  230. master()
  231. {
  232.     state = 'I';
  233.     while (TRUE) {
  234.         printmsg( 4, "Top level state (master mode) %c", state );
  235.         switch (state) {
  236.         case 'I':
  237.             state = sinit();
  238.             break;
  239.         case 'B':
  240.             state = scandir();
  241.             break;
  242.         case 'S':
  243.             state = send();
  244.             break;
  245.         case 'Q':
  246.             state = sbreak();
  247.             break;
  248.         case 'G':
  249.             state = receive();
  250.             break;
  251.         case 'C':
  252.             state = 'Y';
  253.             break;
  254.         case 'Y':
  255.             state = endp();
  256.             break;
  257.         case 'P':
  258.             return('Y');
  259.         case 'A':
  260.             return('A');
  261.         default:
  262.             return('A');
  263.         }
  264.     }
  265. }
  266.  
  267. /*
  268.  *    slave
  269.  */
  270.  
  271. slave()
  272. {
  273.     state = 'I';
  274.     while (TRUE) {
  275.         printmsg( 4, "Top level state (slave mode) %c", state );
  276.         switch (state) {
  277.         case 'I':
  278.             state = rinit();
  279.             break;
  280.         case 'F':
  281.             state = receive();
  282.             break;
  283.         case 'C':
  284.             state = schkdir();
  285.             break;
  286.         case 'T':
  287.             state = 'B';
  288.             break;
  289.         case 'B':
  290.             state = scandir();
  291.             break;
  292.         case 'S':
  293.             state = send();
  294.             break;
  295.         case 'Q':
  296.             state = sbreak();
  297.             break;
  298.         case 'G':
  299.             return('Y');
  300.         case 'Y':
  301.             state = endp();
  302.             break;
  303.         case 'P':
  304.             return('Y');
  305.         case 'A':
  306.             return('A');
  307.         default:
  308.             return('A');
  309.         }
  310.     }
  311. }
  312.  
  313.  
  314. /*
  315.  *    receive
  316.  *
  317.  *    This is the state table switcher for receiving files.
  318.  */
  319.  
  320. receive()
  321. {
  322.     state = 'F';            /* Receive-Init is the start state */
  323.  
  324.     while (TRUE) {
  325.         printmsg( 4, " receive state: %c", state );
  326.         switch (state) {                    /* Do until done */
  327.         case 'F':
  328.             state = rfile();
  329.             break;                            /* Receive-File */
  330.         case 'D':
  331.             state = rdata();
  332.             break;                            /* Receive-Data */
  333.         case 'C':
  334.             return('C');                    /* Complete state */
  335.         case 'A':
  336.             return('Y');                    /* "Abort" state */
  337.         default:
  338.             return('Y');
  339.         }
  340.     }
  341. }
  342.  
  343.  
  344. /*
  345.  *  send
  346.  *
  347.  *  Send is the state table switcher for sending files.  It loops until
  348.  *  either it finishes or an error is encountered.  The routines called
  349.  *  by send are responsible for changing the state.
  350.  */
  351.  
  352. send()
  353. {
  354.     fp = -1;                        /* reset file getter/opener */
  355.     state = 'F';                    /* Send initiate is the start state */
  356.     while (TRUE) {                    /* Do this as long as necessary */
  357.         printmsg( 4, "send state: %c", state );
  358.         switch (state) {
  359.         case 'F':
  360.             state = sfile();
  361.             break;                    /* Send-File */
  362.         case 'D':
  363.             state = sdata();
  364.             break;                    /* Send-Data */
  365.         case 'Z':
  366.             state = seof();
  367.             break;                    /* Send-End-of-File */
  368.         case 'B':
  369.             return ('B');            /* Complete */
  370.         case 'A':
  371.             return ('Y');            /* "Abort" */
  372.         default:
  373.             return ('Y');            /* Unknown, fail */
  374.         }
  375.     }
  376. }
  377.  
  378. /*
  379.  *    A command formatter for DCP. RH Lamb
  380.  *
  381.  *    sets up stdin and stdout on various machines
  382.  *    There is NO command checking so watch what you send and who you
  383.  *    let accsess your machine.  "C rm /usr/*.*" could be executed.
  384.  */
  385. dcxqt()
  386. {
  387.     int    i;
  388.     char    command[60], input[60], output[60], line[BUFSIZ];
  389.     char    *cp;
  390.  
  391.     printmsg( 2, "\n\nStarting XQT phase..." );
  392.     while (dscandir()) {
  393.         strcpy( line, cfile );
  394.         fw = FOPEN( line, "r", 'b' );        /* imported X file */
  395. #if 0 /* Why? */
  396.         strcpy(cfile, line);
  397. #endif
  398.         printmsg( 2, "dcxqt:%s %ld", cfile, fw );
  399.         input[0]   = '\0';
  400.         output[0]  = '\0';
  401.         command[0] = '\0';
  402.         while ( fgets( line, BUFSIZ, fw ) != (char *)NULL ) {
  403.             cp = index( line, '\n' );
  404.             if ( cp != (char *)NULL )
  405.                 *cp = '\0';
  406.  
  407.             printmsg( 8, "dcxqt: %s", line );
  408.             switch (line[0]) {
  409.             case 'U':    /* User information */
  410.                 break;
  411.             case 'I':    /* File to use as stdin */
  412.                 strcpy( input,   &line[2] );
  413.                 break;
  414.             case 'O':    /* File to use as stdout */
  415.                 strcpy( output,  &line[2] );
  416.                 break;
  417.             case 'C':    /* Command to execute */
  418.                 strcpy( command, &line[2] );
  419.                 break;
  420.             case 'R':    /* Hmmm, I don't remember this one */
  421.                 break;    /* Maybe error response file? with '!' notation? */
  422.             default :
  423.                 break;
  424.             }
  425.         }
  426.         fclose( fw );
  427.         printmsg( 0, "xqt: %s\n", command );
  428.         shell( command, input, output, (char *)NULL );
  429.  
  430.         unlink(cfile);
  431.          importpath( hostfile, input );
  432.          unlink(hostfile);
  433.         importpath( hostfile, output );
  434.          unlink(hostfile);
  435.     }
  436.     return(0);
  437. }
  438.  
  439. /*
  440.  *  printmsg
  441.  *
  442.  *  Print error message on standard output if not remote.
  443.  */
  444.  
  445. /* VARARGS2 */
  446. printmsg(level, fmt, args)
  447. int     level;
  448. char    *fmt;
  449. long    args;
  450. {
  451.     if ( debuglevel > level ) {
  452.         if ( remote == MASTER ) {
  453.             vprintf( fmt, &args );
  454.             fputc( '\n', stdout );
  455.             fflush(stdout);
  456.         }
  457.         vfprintf( logfile, fmt, &args );
  458.         fputc( '\n', logfile );
  459.         fflush(logfile);
  460.     }
  461. }
  462.