home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / UUCPbb_2_1_src.lzh / UUCPBB21 / connect.c < prev    next >
Text File  |  1994-09-25  |  14KB  |  506 lines

  1. /*  connect.c   Run the dial and login scripts when calling a remote.
  2.     Copyright (C) 1990, 1993  Rick Adams and Bob Billson
  3.  
  4.     This file is part of the OS-9 UUCP package, UUCPbb.
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20.     The author of UUCPbb, Bob Billson, can be contacted at:
  21.     bob@kc2wz.bubble.org  or  uunet!kc2wz!bob  or  by snail mail:
  22.     21 Bates Way, Westfield, NJ 07090
  23. */
  24.  
  25. #include "uucp.h"
  26. #include "uucico.h"
  27. #include <ctype.h>
  28. #include <sgstat.h>
  29.  
  30. #define WORDSIZE    30
  31. #define SS_BREAK    0x1d                     /* send break signal out acia */
  32.  
  33. static char *nothing = "<NOTHING>";
  34.  
  35.  
  36. /* connect()  --negotiate the dialscript to dial the remote system, then
  37.                 negotiate the chatscript to log into the remote system */
  38.  
  39. int connect (index)
  40. int index;
  41. {
  42.      register flag status;
  43.  
  44.      fprintf (log, "%s %s %s Calling system %s (port %s)",
  45.               sender, sysname, gtime(), sysname,
  46.               *device != '\0' ? device : "unknown");
  47.  
  48.      if (index > 1)
  49.           fprintf (log, " (line %d)", index);
  50.  
  51.      putc ('\n', log);
  52.  
  53.      /* do dialscript */
  54.      if ((status = doscript (TRUE)) == OK)
  55.        {
  56.           /* do chatscript */
  57.           if ((status = doscript (FALSE)) != OK)
  58.                return (ABORT);                    /* failed script */
  59.        }
  60.  
  61.      return ((int) status);
  62. }
  63.  
  64.  
  65.  
  66. /* doscript --do a chat script to dial and log in to the remote */
  67.  
  68. int doscript (dialing) 
  69. flag dialing;
  70. {
  71.      char *words[WORDSIZE];
  72.      register int i;
  73.      flag status;
  74.      int n;
  75.  
  76.      /* parse chat script into expect/send pairs. */
  77.      n = getargs (words, (dialing ? dialscript : chatscript), WORDSIZE);
  78.  
  79.      /* cycle through expect/send pairs */
  80.      for (i = 0; i < n; i++)
  81.           if ((i & 1) == 0)
  82.             {
  83.                status = waitfor (*(words + i), dialing);
  84.                switch (status)
  85.                  {
  86.                     case OK:
  87.                          break;
  88.  
  89.                     case ABORT:
  90.                          return ((int)status);
  91.  
  92.                     default:
  93.                          if (!dialing)
  94.                            {
  95.                               logerror ("chat script failed");
  96.                               return (CHATERROR);
  97.                            }
  98.                          else
  99.                               return ((int)status); 
  100.                  }
  101.              }
  102.           else
  103.                send (*(words + i));
  104.  
  105.      return (OK);           /* status okay */
  106. }
  107.  
  108.  
  109.  
  110. int send (msg)
  111. char *msg;
  112. {
  113.      register short i;
  114.      flag crneeded;
  115.      char c;
  116.      int msglen = strlen (msg);
  117.  
  118.      if (debuglvl > 1)
  119.           fputs ("sendthem: ", log);
  120.  
  121.      /* send nothing? */
  122.      if (*msg == '|')
  123.        {
  124.           if (debuglvl > 1)
  125.                fprintf (log, "%s\n", nothing);
  126.  
  127.           return (OK);
  128.        }
  129.  
  130.      /* send line break? */
  131.      if (*msg == 'B'  &&  strcmp (msg, "BREAK") == 0)
  132.        {
  133.           sendbreak();
  134.           return (OK);
  135.        }
  136.  
  137.      /* send end-of-transmission character? */
  138.      if (*msg == 'E'  &&  strcmp (msg, "EOT") == 0)
  139.        {
  140.           if (debuglvl > 1)
  141.                 fputs ("<EOT>", log);
  142.  
  143.           write (port, '\x04', 1);
  144.           return (OK);
  145.        }
  146.  
  147.      for (tsleep (MODEMDELAY), crneeded = TRUE, i = 0; i < msglen; i++)
  148.        {
  149.           c = *(msg + i);
  150.  
  151.           if (c != '\\')
  152.             {
  153.                if (debuglvl > 1)
  154.                     putc (c, log);
  155.  
  156.                write (port, &c, 1);
  157.             }
  158.           else
  159.             {
  160.                switch (msg[i + 1])
  161.                  {
  162.                     case 'T':
  163.                          if (debuglvl > 1)
  164.                               fprintf (log, "%s", phone);
  165.                          write (port, phone, strlen (phone));
  166.                          break;
  167.  
  168.                     case 's':
  169.                          if (debuglvl > 1)
  170.                               fputs ("<SPACE>", log);
  171.                          write (port, " ", 1);
  172.                          break;
  173.  
  174.                     case 'r':
  175.                          if (debuglvl > 1)
  176.                               fputs ("<CR>", log);
  177.                          write (port, "\x0D", 1);
  178.                          break;
  179.  
  180.                     case 'n':
  181.                          if (debuglvl > 1)
  182.                               fputs ("<LF>", log);
  183.                          write (port, "\x0A", 1);
  184.                          break;
  185.  
  186.                     case '\\':
  187.                          if (debuglvl > 1)
  188.                               putc ('\\', log);
  189.                          write (port, "\\", 1);
  190.                          break;
  191.  
  192.                     case 'd':                        /* 1 second delay */
  193.                          if (debuglvl > 1)
  194.                               fputs ("<DELAY>", log);
  195.                          sleep (1);
  196.                          break;
  197.  
  198.                     case 'N':
  199.                          if (debuglvl > 1)
  200.                               fputs ("<NUL>", log);
  201.                          write (port, "\0", 1);
  202.                          break;
  203.  
  204.                     case 't':
  205.                          if (debuglvl > 1)
  206.                               fputs ("<TAB>", log);
  207.                          write (port, "\t", 1);
  208.                          break;
  209.  
  210.                     case 'b':                                /* back space */
  211.                          if (debuglvl > 1)
  212.                               fputs ("<BS>", log);
  213.                          write (port, "\b", 1);
  214.                          break;
  215.  
  216.                     case 'c':                              /* don't send CR */
  217.                          if (debuglvl > 1)
  218.                               fputs ("<NO CR>", log);
  219.                          crneeded = FALSE;
  220.                          break;
  221.  
  222.                     case '^':
  223.                          c = toupper (msg[i + 2]) & 0x3f;
  224.                          if (debuglvl > 1)
  225.                               fprintf (log, "<CNTRL>-%c\n",
  226.                                             toupper (msg[i + 2]));
  227.                          write (port, &c, 1);
  228.                          i += 2;
  229.                          break;
  230.  
  231.                     case 'K':                          /* send a line break */
  232.                          sendbreak();
  233.                          break;
  234.  
  235.                     case 'p':                 /* fraction of a second pause */
  236.                          if (debuglvl > 1)
  237.                               fputs ("<PAUSE>", log);
  238.  
  239.                          tsleep (PORTSLEEP);
  240.                          break;
  241.  
  242.                     case '[':                                /* send ESCAPE */
  243.                          if (debuglvl > 1)
  244.                               fputs ("<ESC>", log);
  245.  
  246.                          write (port, "\x1b", 1);
  247.                          break;
  248.  
  249.                     case '0':
  250.                     case '1':
  251.                     case '2':
  252.                     case '3':
  253.                     case '4':
  254.                     case '5':
  255.                     case '6':
  256.                     case '7':
  257.                          if (debuglvl > 1)
  258.                               fprintf (log, "<%.4s>", &msg[i]);
  259.  
  260.                          c = (msg[i + 1] - '0') & 0x07;
  261.                          c <<= 3;
  262.                          c |= (msg[i + 2] - '0') & 0x07;
  263.                          c <<= 3;
  264.                          c |= (msg[i + 3] - '0') & 0x07;
  265.                          write (port, &c, 1);
  266.                          i += 2;
  267.                          break;
  268.  
  269.                     default:
  270.                          break;
  271.                  }
  272.                ++i;
  273.             }
  274.        }
  275.  
  276.      if (crneeded)
  277.           write (port, "\n", 1);
  278.  
  279.      if (debuglvl > 1)
  280.           putc ('\n', log);
  281.  
  282.      return (OK);
  283. }
  284.  
  285.  
  286.  
  287. int waitfor (msg, dialing)
  288. char *msg;
  289. flag dialing;
  290. {
  291.      register char *p;
  292.      flag result;
  293.      char c, *p1, *p2, *p3, *p4, *p5;
  294.      char *nocarrier = "NO CARRIER",
  295.           *busy = "BUSY",
  296.           *noanswer = "NO ANSWER",
  297.           *nodialtone = "NO DIALTONE",      /* for real Hayes compatable */
  298.           *notone2 = "NO DIAL TONE";        /* and not so compatible modems */
  299.  
  300.      p = msg;
  301.      p1 = busy;
  302.      p2 = nocarrier;
  303.      p3 = noanswer;
  304.      p4 = nodialtone;
  305.      p5 = notone2;
  306.  
  307.      if (debuglvl > 1)
  308.           fprintf (log, "expect: %s\n", *msg != '|' ? msg : nothing);
  309.  
  310.      /* expect nothing? */
  311.      if (*msg == '|')
  312.           return (OK);
  313.  
  314.      while (*p && *p1 && *p2 && *p3 && *p4 && *p5)
  315.        {
  316.           if (readport (&c, dialing  ? CNCTIME : LOGTIME,
  317.                             dialing  ? 1 : MAXLOGTRY) == TIMEDOUT)
  318.             {
  319.                return (ABORT);
  320.             }
  321.  
  322.           c &= 0x7F;                                 /* strip parity */
  323.                                                      /* check for...       */
  324.           p  = (c == *p)  ? ++p  : msg;              /*    expected string */
  325.           p1 = (c == *p1) ? ++p1 : busy;             /*    BUSY            */
  326.           p2 = (c == *p2) ? ++p2 : nocarrier;        /*    NO CARRIER      */
  327.           p3 = (c == *p3) ? ++p3 : noanswer;         /*    NO ANSWER       */
  328.           p4 = (c == *p4) ? ++p4 : nodialtone;       /*    NO DIALTONE     */
  329.           p5 = (c == *p5) ? ++p5 : notone2;          /*    NO DIAL TONE    */
  330.        }
  331.  
  332.      if (debuglvl > 1)
  333.           fputs ("got: ", log);
  334.  
  335.      if (*p1 == '\0')                        /* BUSY */
  336.        {
  337.           if (debuglvl > 1)
  338.                fputs (busy, log);
  339.           else
  340.                logerror ("line is BUSY");
  341.  
  342.           result = BUSY; 
  343.        }
  344.      else if (*p2 == '\0')                   /* NO CARRIER */
  345.        {
  346.           if (debuglvl > 1)
  347.                fputs (nocarrier, log);
  348.           else
  349.                logerror (nocarrier);
  350.  
  351.           result = NOCARRIER;
  352.        }
  353.      else if (*p3 == '\0')                   /* NO ANSWER */
  354.        {
  355.           if (debuglvl > 1)
  356.                fputs (noanswer, log);
  357.           else
  358.                logerror ("Remote not answering");
  359.  
  360.           result = NOANSWER;
  361.        }
  362.      else if (*p4 == '\0' || *p5 == '\0')    /* NO DIALTONE */
  363.        {
  364.           if (debuglvl > 1)
  365.                fputs (nodialtone, log);
  366.           else
  367.                logerror (nodialtone);
  368.  
  369.           result = NODIALTONE;
  370.        }
  371.      else
  372.        {
  373.           if (debuglvl > 1)
  374.                fputs (msg, log);
  375.  
  376.           result = OK;                       /* status okay */
  377.        }
  378.  
  379.      if (debuglvl > 1)
  380.           putc ('\n', log);
  381.  
  382.      return ((int) result);
  383. }
  384.  
  385.  
  386.  
  387. /* Send a line break.  First try using a system call to send a true line
  388.    break.  If that fails, fake it by setting the port to its lowest baud
  389.    rate, send a NUL character and return the port to its original baud rate.
  390.    This will cause a framing error on the receiving end which will act the
  391.    same as a line break.  This method will work on many but not all systems.
  392. */
  393.  
  394. int sendbreak()
  395. {
  396.      struct sgbuf options;
  397.      int oldbaud;
  398.      
  399.      /* try sending break via setstat */
  400.      if (_ss_sbreak (port) < 0)
  401.        {
  402.           /* could not do it, so fake one */
  403.           _gs_opt (port, &options);
  404.           oldbaud = options.sg_baud;
  405.           options.sg_baud = 0;
  406.           _ss_opt (port, &options);
  407.  
  408.           /* send a nul */
  409.           write (port, "\0", 1);
  410.  
  411.           /* put port back the way we found it */
  412.           options.sg_baud = oldbaud;
  413.           _ss_opt (port, &options);
  414.        }
  415. }
  416.  
  417.  
  418.  
  419. /* Try sending a true line break */
  420.  
  421. int _ss_sbreak (path)
  422. int path;
  423. {
  424.      return (setstat (SS_BREAK, path));
  425. }
  426.  
  427.  
  428.  
  429. /* Read one byte from the port.  Returns TRUE if successful, TIMEDOUT if we
  430.    timed out. */
  431.  
  432. int readport (c, seconds, retries)
  433. char *c;
  434. unsigned seconds;                /* timeout in seconds */
  435. int retries;
  436. {
  437.      register int i;
  438.  
  439.      /* wait for data available */
  440.      for (i = 0;  i < retries;  ++i)
  441.           if ( !timeout (seconds) )             /* something is waiting */
  442.             {
  443.                read (port, c, 1);
  444.                return (TRUE);
  445.             }
  446.  
  447.      /* we timed out, tell the caller */
  448.      logerror ("readport: timed out");
  449.      return (TIMEDOUT);
  450. }
  451.  
  452.  
  453.  
  454. /* Read 'count' characters into buffer 'p'.  Return # chars read (less than
  455.    'count' only if timeout). */
  456.  
  457. int readfill (p, count)
  458. register char *p;
  459. int  count;
  460. {
  461.      int rdy, byte_count = 0;
  462.  
  463.      while (byte_count < count  &&  timeout (1) != TIMEDOUT)
  464.        {
  465.           if ((rdy = min (_gs_rdy (port), count-byte_count)) < 1)
  466.                continue;
  467.  
  468.           /* Handle I/O Error! */
  469.           if ((rdy = read (port, p, rdy)) == ERROR)
  470.                continue;
  471.  
  472.           p += rdy;
  473.           byte_count += rdy;
  474.        }
  475.      return (byte_count);
  476. }
  477.  
  478.  
  479.  
  480. /* Timeout will sleep for 'secs' seconds or until there's input ready
  481.    Return:  TIMEDOUT  - if we timed out
  482.             FALSE - if data is waiting */
  483.  
  484. int timeout (secs)
  485. int secs;
  486. {
  487.      register int i;
  488.      int count;
  489.  
  490.      /* if input waiting, return */
  491.      if (_gs_rdy (port) > 0)
  492.           return (FALSE);
  493.  
  494.      /* count *= 4 because we wake up 4 times / second */
  495.      for (count = secs << 2, i = 0; i < count; i++)
  496.           if (_gs_rdy (port) > 0)
  497.                return (FALSE);
  498.           else
  499.             {
  500.                _ss_ssig (port, SIGWAKE);
  501.                tsleep (PORTSLEEP);
  502.                _ss_rel (port);
  503.             }
  504.      return (TIMEDOUT);
  505. }
  506.