home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR3 / KA9Q212.ZIP / RLOGIN.C < prev    next >
C/C++ Source or Header  |  1993-07-16  |  11KB  |  496 lines

  1. /****************************************************************************
  2. *    $Id: rlogin.c 1.8 93/07/16 11:49:47 ROOT_DOS Exp $
  3. *    24 Oct 92    1.1        GT    Add ZMODEM.                                        *
  4. *    17 Jan 93    1.2        GT    Don't delete first 4 characters from remote.    *
  5. *                            Fix XMODEM download prompt.                        *
  6. *    30 Jan 93    1.3        GT    Fix background file transfers.                    *
  7. *    07 Feb 93    1.4        GT    Re-enable ZMODEM upload.                        *
  8. *    20 Feb 93    1.5        GT    Debugging Tx again.                                *
  9. *    21 Feb 93    1.6        GT    And again.                                        *
  10. *    22 Feb 93    1.7        GT    Only allow one file transfer at a time.            *
  11. *    08 May 93    1.8        GT    Fix warnings.                                    *
  12. ****************************************************************************/
  13.  
  14. #include <stdio.h>
  15. #include    <ctype.h>
  16. #include "global.h"
  17. #include "mbuf.h"
  18. #include "socket.h"
  19. #include "session.h"
  20. #include "proc.h"
  21. #include "tty.h"
  22. #include "commands.h"
  23. #include "netuser.h"
  24. #include    "sz.h"
  25.  
  26. #if    0
  27. static char *username = "guest";
  28. #endif
  29. static char terminal[] = "vt102";
  30. static char *termspeed = "/38400";
  31. static char logname[16];
  32.  
  33. extern FILE *Rawterm;
  34. int rlo_connect __ARGS ((struct session * sp, char *fsocket, int len));
  35. void rlo_output __ARGS ((int unused, void *p1, void *p2));
  36. void rlrecv __ARGS ((struct session * sp));
  37. static int dorwhatever __ARGS ((int argc, char *argv[], void *p));
  38. static void file_xfer __ARGS ((int s, int direction, struct session * sp));
  39. #if    0
  40. static void reporter __ARGS ((int type, void *data));
  41. #endif
  42.  
  43. #if    0
  44. static char recv_ok;         /* nz - ok to run receive                 */
  45. #endif
  46.  
  47. /* Execute user rsh command */
  48. int dorsh (argc, argv, p)
  49. int argc;
  50. char *argv[];
  51. void *p;
  52.  
  53.     {
  54.     return 0;
  55.     }
  56.  
  57. /* Execute user rlogin command */
  58. int dorlogin (argc, argv, p)
  59. int argc;
  60. char *argv[];
  61. void *p;
  62.  
  63.     {
  64.     return dorwhatever (argc, argv, p);
  65.     }
  66.  
  67. /* Execute some sort of r command */
  68. static int dorwhatever (argc, argv, p)
  69. int argc;
  70. char *argv[];
  71. void *p;
  72.  
  73.     {
  74.     struct session *sp;
  75.     struct sockaddr_in fsocket;
  76.     struct sockaddr_in lsocket;
  77.  
  78.     /* Make sure this comes from console - WG7J */
  79.  
  80.     if (Curproc->input != Command->input)
  81.         return 0;
  82.  
  83.     /* Allocate a session descriptor */
  84.  
  85.     if ((sp = newsession (argv[1], RLOGIN)) == NULLSESSION)
  86.         {
  87.         tputs ("Too many sessions");
  88.         return 1;
  89.         }
  90.  
  91.     fsocket.sin_family = AF_INET;
  92.     if (argc < 3)
  93.         fsocket.sin_port = IPPORT_RLOGIN;
  94.     else
  95.         fsocket.sin_port = atoi (argv[2]);
  96.  
  97.     tprintf ("Resolving %s... ", sp->name);
  98.     if ((fsocket.sin_addr.s_addr = resolve (sp->name)) == 0L)
  99.         {
  100.         tprintf (Badhost, sp->name);
  101.         keywait (NULLCHAR, 1);
  102.         freesession (sp);
  103.         return 1;
  104.         }
  105.  
  106.     if ((sp->s = socket (AF_INET, SOCK_STREAM, 0)) == -1)
  107.         {
  108.         tputs ("No Socket");
  109.         keywait (NULLCHAR, 1);
  110.         freesession (sp);
  111.         return 1;
  112.         }
  113.  
  114.     lsocket.sin_family = AF_INET;
  115.     lsocket.sin_addr.s_addr = INADDR_ANY;
  116.     lsocket.sin_port = IPPORT_RLOGIN;
  117.     bind (sp->s, (char *) &lsocket, sizeof (lsocket));
  118.     return rlo_connect (sp, (char *) &fsocket, SOCKSIZE);
  119.     }
  120.  
  121. /* Generic interactive connect routine */
  122.  
  123. int rlo_connect (sp, fsocket, len)
  124. struct session *sp;
  125. char *fsocket;
  126. int len;
  127.     {
  128.     unsigned int index;
  129.  
  130.     index = (unsigned int) (sp - Sessions);
  131.  
  132.     sockmode (sp->s, SOCK_ASCII);
  133.     tprintf ("Trying %s...\n", psocket ((struct sockaddr *) fsocket));
  134.     if (connect (sp->s, fsocket, len) == -1)
  135.         {
  136.         tprintf ("%s session %u failed: %s errno %d\n",
  137.                  Sestypes[sp->type], index, sockerr (sp->s), errno);
  138.         keywait (NULLCHAR, 1);
  139.         freesession (sp);
  140.         return 1;
  141.         }
  142.  
  143.     tprintf ("%s session ", Sestypes[sp->type]);
  144.     tprintf ("%u connected to %s\n", index, sp->name);
  145.     rlrecv (sp);
  146.     return 0;
  147.     }
  148.  
  149. /* Rlogin input routine, common to both rlogin and ttylink */
  150.  
  151. void rlrecv (sp)
  152. struct session *sp;
  153.     {
  154.     int c, s, index;
  155.     char *cp;
  156.  
  157.     s = sp->s;
  158.  
  159.     /* Get the login name. */
  160.  
  161.     tprintf ("login: ");
  162.     recvline (sp->input, logname, sizeof (logname));
  163.     *(logname + strlen (logname) - 1) = '\0';     /* delete \n                 */
  164.  
  165.     /* We run both the network and local sockets in transparent mode
  166.      * because we have to do our own eol mapping */
  167.  
  168.     seteol (s, "");
  169.     seteol (Curproc->input, "");
  170.     seteol (Curproc->output, "");
  171.  
  172.     /* Read real keystrokes from the keyboard */
  173.  
  174.     sp->ttystate.crnl = 0;
  175.  
  176.     /* Put tty into raw mode */
  177.  
  178.     sp->ttystate.echo = 0;
  179.     sp->ttystate.edit = 0;
  180.  
  181.     setflush (s, '\n');
  182.  
  183.     index = (int) (sp - Sessions);
  184.  
  185.     /* Fork off the transmit process */
  186.  
  187. #if    0
  188.     recv_ok = 1;
  189. #endif
  190.     sp->proc1 = newproc ("rlo_out", 2048, rlo_output, 0, sp, NULL, 0);
  191.  
  192. #if    0
  193.     for (c = 0; c < 4; c++)
  194.         (void) recvchar (s);                     /* get response                     */
  195. #endif
  196.  
  197.     /* Process input on the connection */
  198.  
  199.     while ((c = recvchar (s)) != -1)
  200.         {
  201.         if (c == '\r' || c == '\n')
  202.             {
  203.             seteol (Curproc->output, "\r\n");
  204.             tputc ((char) c);
  205.             seteol (Curproc->output, "");
  206.             }
  207.         else
  208.             {
  209.             tputc ((char) c);
  210.             }
  211.  
  212.         }
  213.  
  214. #if    0
  215.     for (;;)
  216.         {
  217.         if (recv_ok == 0)
  218.             pwait (&recv_ok);            /* suspended                        */
  219.  
  220.         if (socklen (s, 0) == 0)
  221.             {
  222.             pwait (NULL);                /* nothing to do                    */
  223.             continue;
  224.             }
  225.  
  226.         if ((c = recvchar (s)) == -1)
  227.             break;                        /* socket failed                    */
  228.  
  229.         if (c == '\r' || c == '\n')
  230.             {
  231.             seteol (Curproc->output, "\r\n");
  232.             tputc ((char) c);
  233.             seteol (Curproc->output, "");
  234.             }
  235.         else
  236.             {
  237.             tputc ((char) c);
  238.             }
  239.  
  240.         }    /* for (;;) */
  241. #endif    
  242.  
  243. quit:                                             /* A close was received from
  244.                                                   * the remote host. Notify
  245.                                                   * the user, kill the output
  246.                                                   * task and wait for a
  247.                                                   * response from the user
  248.                                                   * before freeing the
  249.                                                   * session. */
  250.  
  251.     cp = sockerr (s);
  252.     seteol (s, "\r\n");
  253.     seteol (Curproc->input, "\r\n");
  254.     seteol (Curproc->output, "\r\n");
  255.  
  256.     tprintf ("%s session %u", Sestypes[sp->type], index);
  257.     tprintf (" closed: %s\n", cp != NULLCHAR ? cp : "EOF");
  258.     killproc (sp->proc1);
  259.     sp->proc1 = NULLPROC;
  260.     close_s (sp->s);
  261.     sp->s = -1;
  262.     keywait (NULLCHAR, 1);
  263.     freesession (sp);
  264.     }
  265.  
  266.     
  267. /* User rlogin output task, started by user rlogin command */
  268. void rlo_output (unused, sp1, p)
  269. int unused;
  270. void *sp1;
  271. void *p;
  272.     {
  273.     struct session *sp;
  274.     struct mbuf *bp;
  275.     char *cp;
  276.     int c;
  277.  
  278.     sp = (struct session *) sp1;
  279.  
  280. #if    0
  281.     logname = getenv ("USER");
  282.     if (logname == NULLCHAR)
  283.         logname = username;
  284. #endif
  285.     bp = ambufw (1 + strlen (logname) + 1 + strlen (logname) + 1 +
  286.                  strlen (terminal) + strlen (termspeed) + 1);
  287.  
  288.     cp = bp->data;
  289.     *cp++ = '\0';
  290.     strcpy (cp, logname);
  291.     cp += strlen (logname) + 1;
  292.     strcpy (cp, logname);
  293.     cp += strlen (logname) + 1;
  294.     strcpy (cp, terminal);
  295.     cp += strlen (terminal);
  296.     strcpy (cp, termspeed);
  297.     cp += strlen (termspeed) + 1;
  298.     bp->cnt = cp - bp->data;
  299.     if (send_mbuf (sp->s, bp, 0, NULLCHAR, 0) != -1)
  300.         {
  301.         /* Send whatever's typed on the terminal */
  302.  
  303. #if    0
  304.         while (recv_mbuf (sp->input, &bp, 0, NULLCHAR, 0) > 0)
  305.             {
  306.             if (send_mbuf (sp->s, bp, 0, NULLCHAR, 0) == -1)
  307.                 break;
  308.  
  309.             }
  310. #endif
  311.  
  312.         while ((c = recvchar (sp->input)) != EOF)
  313.             {
  314.             /* Check for escape. */
  315.  
  316.             if (c == '~')
  317.                 {
  318.                 c = recvchar (sp->input);
  319.                 if (c == EOF)
  320.                     break;
  321.  
  322.                 switch (c)
  323.                     {
  324.                     case 'u':
  325.                     case 'd':
  326.                         file_xfer (sp->s, c, sp);     /* do [XYZ]MODEM        */
  327.                         continue;
  328.  
  329.                     }
  330.  
  331.                 }                                 /* if (c == '~') */
  332.  
  333.             /* Send the data. */
  334.  
  335.             usputc (sp->s, (char) c);
  336.             usflush (sp->s);
  337.             }    /* while ((c = recvchar (sp->input)) != EOF) */
  338.  
  339.         }
  340.  
  341.     /* Make sure our parent doesn't try to kill us after we exit */
  342.  
  343.     sp->proc1 = NULLPROC;
  344.     }
  345.  
  346.     
  347. /****************************************************************************
  348. *    file_xfer                                                                *
  349. *    Do an [XYZ]MODEM file transfer.                                            *
  350. ****************************************************************************/
  351.  
  352. static void file_xfer (s, direction, sp)
  353. int s;
  354. int direction;
  355. struct session *sp;
  356.     {
  357.     char buf[65];                        /* input buffer                        */
  358.     int protocol;                         /* protocol (X, Y, Z)                */
  359.     char *filenames[2];                     /* list of file names                */
  360. #if    0
  361.     int oldmode;                         /* old socket mode                    */
  362.     int oldflush;                         /* old flush character                */
  363. #endif
  364.     char *rcv_opts = "bvv";                /* file transfer options            */
  365.     char *send_opts = "bvv";
  366.     static int xferring = 0;            /* nz - transfer running            */
  367.     
  368.     /* Suspend the receive process. */
  369.  
  370.     sp->ttystate.crnl = 1;
  371.     sp->ttystate.echo = 1;
  372.     sp->ttystate.edit = 1;
  373.     seteol (Curproc->input, "\r\n");
  374.     seteol (Curproc->output, "\r\n");
  375.  
  376.     /* See if we are already doing a file transfer. */
  377.  
  378.     if (xferring != 0)
  379.         {
  380.         tprintf ("Sorry - only one file transfer at a time\n");
  381.         sp->ttystate.crnl = 0;
  382.         sp->ttystate.echo = 0;
  383.         sp->ttystate.edit = 0;
  384.         seteol (Curproc->input, "");
  385.         seteol (Curproc->output, "");
  386.         return;
  387.         }
  388.  
  389.     xferring = 1;
  390.     suspend (sp->proc);
  391.  
  392.     /* Get the protocol type. */
  393.  
  394.     do
  395.         {
  396.         tprintf ("\nProtocol (XYZ): ");
  397.         recvline (sp->input, buf, sizeof (buf));
  398.         protocol = tolower (*buf);
  399.         } while (protocol != 'x' && protocol != 'y' && protocol != 'z');
  400.  
  401.     /* Get the file path if required. */
  402.  
  403.     if (protocol == 'x' || direction == 'u')
  404.         {
  405.         tprintf ("File path: ");
  406.         recvline (sp->input, buf, sizeof (buf));
  407.         *(buf + strlen (buf) - 1) = '\0';
  408.         }
  409.  
  410.     /* Do the transfer. */
  411.  
  412.     filenames[0] = buf;
  413.     filenames[1] = "";
  414.     if (direction == 'u')
  415.         (void) _sendfile (s, protocol, send_opts, filenames, NULL);
  416.     else
  417.         {
  418.         if (protocol == 'x')
  419.             (void) _getfile (s, protocol, rcv_opts, filenames[0], NULL);
  420.         else
  421.             (void) _getfile (s, protocol, rcv_opts, NULL, NULL);
  422.  
  423.         }
  424.  
  425.     /* Restart the receive process. */
  426.  
  427.     usflush (s);
  428.  
  429.     /* Reset raw mode. */
  430.  
  431.     sp->ttystate.crnl = 0;
  432.     sp->ttystate.echo = 0;
  433.     sp->ttystate.edit = 0;
  434.     seteol (Curproc->input, "");
  435.     seteol (Curproc->output, "");
  436.     xferring = 0;
  437.     resume (sp->proc);
  438.     pwait (NULL);
  439.     }
  440.  
  441. #if    0    
  442. /****************************************************************************
  443. *    reporter                                                                *
  444. *    Do report functions for ZMODEM.                                            *
  445. ****************************************************************************/
  446.  
  447. static void reporter (type, data)
  448. int type;
  449. void *data;
  450.     {
  451. #if    0
  452. #if    0
  453.     Current->ttystate.echo = 1;
  454.     Current->ttystate.crnl = 1;
  455.     Current->ttystate.edit = 1;
  456. #endif
  457.  
  458.     switch (type)
  459.         {
  460.         case 0:                                 /* filename                             */
  461.             tprintf ("FILE: %s", (char *) data);
  462.             break;
  463.  
  464.         case 1:                                 /* transfer count                     */
  465.             tprintf ("\r%7ld", *((long *) data));
  466.             break;
  467.  
  468.         case 2:                                 /* other text                         */
  469.             seteol (Curproc->output, "\r\n");
  470.             tprintf ("\n%s", (char *) data);
  471.             seteol (Curproc->output, "");
  472.             break;
  473.  
  474.         case 3:                                 /* end of transfer                     */
  475.             seteol (Curproc->output, "\r\n");
  476.             tprintf ("\n%7d files transferred.\n", *((int *) data));
  477.             seteol (Curproc->output, "");
  478.             break;
  479.  
  480.         default:
  481.             seteol (Curproc->output, "\r\n");
  482.             tprintf ("\nreporter: unknown type %d\n", type);
  483.             seteol (Curproc->output, "");
  484.             break;
  485.         }                                         /* switch (type) */
  486.  
  487.     usflush (Curproc->output);
  488. #if    0
  489.     Current->ttystate.echo = 0;
  490.     Current->ttystate.crnl = 0;
  491.     Current->ttystate.edit = 0;
  492. #endif
  493. #endif
  494.     }     /* static void reporter (int type, void *data) */
  495. #endif
  496.