home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / lib / dial / d_connect.c.sa < prev    next >
Encoding:
Text File  |  1986-06-04  |  18.3 KB  |  810 lines

  1. # include  "util.h"
  2. # include <signal.h>
  3. # include  "d_syscodes.h"
  4. # include  "d_clogcodes.h"
  5. # include  "d_proto.h"
  6. # include  "d_returns.h"
  7. # include  "d_structs.h"
  8. #ifdef SYS5
  9. # include <termio.h>
  10. #else
  11. # include  <sgtty.h>
  12. #endif SYS5
  13. # include  <sys/stat.h>
  14. #ifdef V4_2BSD
  15. # include  <sys/file.h>
  16. #endif V4_2BSD
  17.  
  18. /*  Jun 81  Dave Crocker    fixed some text, referring to errno
  19.  *  Aug 81  Dave Crocker    added sleep before kill & alarm around
  20.  *                          parent waiting for acu
  21.  *  Sep 81  Dean Krafft     put signal (ALRM,d_catch) before ACUWAIT
  22.  *  Apr 82  Dave Crocker    modify dial timings & lock-file handling
  23.  *  Jun 82  Dave Crocker    do_dial use of kill() moved around
  24.  *                          d_drop() timeouts around modem line fclose()
  25.  *  Jan 84  Dennis Rockwell converted to do sane things with 4.2 select(2)
  26.  *                          by setting non-blocking open option
  27.  *  Feb 84  Dan Long        moved d_cstart to start of phone conversation
  28.  *  Feb 84  Dan Long        added support for line-type selection
  29.  *  Mar 84  Dennis Rockwell converted from select to s_io library
  30.  */
  31.  
  32. extern int errno;
  33. extern int d_errno;
  34. extern struct directlines  *d_lines;
  35. extern struct directlines  *d_ptline;
  36. extern struct dialports *d_prtpt;
  37. extern struct dialports *d_prts;
  38. extern char d_uname[];
  39. extern int  d_didial;
  40. extern int  d_baudrate;
  41. extern  FILE * d_prtfp;
  42. extern struct speedtab d_spdtab[];
  43. extern char **d_typelist();
  44. extern char *strdup();
  45. extern char *multcat();
  46. extern int  d_lckfd;
  47.  
  48.  
  49. /*
  50.  *     D_CONNECT
  51.  *    
  52.  *     this routine is called to make a connection to the remote system.  it
  53.  *     is capable of using direct lines or dial-up connections, as specified
  54.  *     in the connection path table ('numtab').
  55.  *    
  56.  *     numtab -- array of structure whch contain speed indicies and associated
  57.  *               phone numbers or direct connect line names.
  58.  *    
  59.  *     nnumbs -- number of entries in numtab
  60.  *    
  61.  *     ntries -- number of time to retry a connection.
  62.  *    
  63.  *     interval -- number of seconds between connection retries.
  64.  */
  65.  
  66. d_connect (numtab, nnumb, ntries, interval)
  67. struct telspeed numtab[];
  68. int     nnumb,
  69.         ntries,
  70.         interval;
  71. {
  72.     register int    num,
  73.                     try,
  74.                     result;
  75.  
  76. #ifdef D_DBGLOG
  77.     d_dbglog ("d_connect", "nnumb %d, ntries %d, interval %d",
  78.         nnumb, ntries, interval);
  79. #endif
  80.  
  81. /*  make sure we were given some numbers to dial  */
  82.  
  83.     if (nnumb <= 0)
  84.     {
  85. #ifdef D_LOG
  86.     d_log ("d_connect", "no connection paths given!");
  87. #endif D_LOG
  88.     d_errno = D_NONUMBS;
  89.     return (D_FATAL);
  90.     }
  91.  
  92. /*  for each attempt, try each of the paths given  */
  93.  
  94.     for (try = 1; try <= ntries; try++)
  95.     {
  96.     for (num = 0; num < nnumb; num++)
  97.     {
  98. #ifdef D_DBGLOG
  99.         d_dbglog ("d_connect", "%d: (speed %d) num '%s'",
  100.             num, numtab[num].t_speed, numtab[num].t_number);
  101. #endif D_DBGLOG
  102.         if (numtab[num].t_speed == 0)
  103.         result = d_direct (numtab[num].t_number);
  104.  
  105.         else
  106.         result = d_dial (numtab[num].t_number, numtab[num].t_speed);
  107.  
  108.         if (result != D_NONFATAL)
  109.         return (result);
  110.     }
  111.  
  112. /*  if we're going to try again, and we're supposed to wait awhile, sleep  */
  113.  
  114.     if ((try < ntries) && (interval > 0))
  115.     {
  116. #ifdef D_DBGLOG
  117.         d_dbglog ("d_connect", "sleeping for %d seconds", interval);
  118. #endif D_DBGLOG
  119.         sleep ((unsigned) interval);
  120.     }
  121.     }
  122.  
  123. #ifdef D_LOG
  124.     d_log ("d_connect", "couldn't make connection.");
  125. #endif D_LOG
  126.     return (D_FATAL);
  127. }
  128.  
  129. /*
  130.  *     D_DIRECT
  131.  *
  132.  *     routine called to try to make a direct connection using the line
  133.  *     given as the argument.
  134.  *
  135.  *     linename -- name of direct connect line
  136.  */
  137.  
  138. d_direct (linename)
  139. register char  *linename;
  140. {
  141.     int     fd;
  142.     register int    result;
  143. #ifdef D_LOG
  144.     register int    i;
  145. #endif D_LOG
  146. #ifdef SYS5
  147.     struct termio hupbuf;
  148. #endif SYS5
  149.  
  150. /*  see if a direct line with the given name is available  */
  151.  
  152.     if ((result = d_avline (linename)) < 0)
  153.     return (result);
  154.  
  155.     d_baudrate = d_ptline -> l_speed;
  156.  
  157. #ifdef D_LOG
  158.     for (i=0; d_spdtab[i].s_speed != 0; i++) {
  159.         if (d_spdtab[i].s_index == d_baudrate) {
  160.        d_log ("d_direct", "Trying direct connection on %s at %s.",
  161.         d_ptline -> l_tty, d_spdtab[i].s_speed);
  162.        break;
  163.     }
  164.     }
  165. #endif D_LOG
  166.  
  167. /*  found a line.  set an alarm in case the open hangs  */
  168.  
  169.     if (setjmp (timerest)) {
  170. #ifdef D_LOG
  171.         d_log ("d_direct", "direct line open timeout for %s",
  172.             d_ptline -> l_tty);
  173. #endif D_LOG
  174.     d_errno = D_PORTOPEN;
  175.     return (D_FATAL);
  176.     }
  177.     s_alarm (CONNWAIT);
  178. #ifndef V4_2BSD
  179.     if ((fd = open (d_ptline -> l_tty, 2)) >= 0) {
  180. #else V4_2BSD
  181.     if ((fd = open (d_ptline -> l_tty, O_RDWR | O_NDELAY)) >= 0) {
  182. #endif V4_2BSD
  183.  
  184. #ifdef SYS5
  185.     ioctl (fd, TCGETA, &hupbuf);
  186.     hupbuf.c_cflag |= HUPCL;
  187.     if (ioctl (fd, TCSETA, &hupbuf) < OK) {
  188. #else
  189.     if (ioctl (fd, TIOCHPCL, 0) < OK) {
  190. #endif SYS5
  191. #ifdef D_LOG
  192.         d_log ("d_direct", "problem setting close-on-hangup; errno = %d", errno);
  193. #endif D_LOG
  194.     }
  195. #ifdef    TIOCEXCL
  196.     if (ioctl (fd, TIOCEXCL, 0) < OK) { /* gain exclusive access [mtr] */
  197. #ifdef D_LOG
  198.         d_log ("d_direct",
  199.             "problem gaining exclusive access; errno = %d", errno);
  200. #endif D_LOG
  201.     }
  202. #endif    TIOCEXCL
  203.     }
  204.     s_alarm (0);
  205.  
  206.     if (fd < 0)
  207.     {
  208. #ifndef V4_2BSD
  209.     if (errno == EINTR) {
  210. #ifdef D_LOG
  211.         d_log ("d_direct", "direct line open timeout for %s",
  212.             d_ptline -> l_tty);
  213. #endif D_LOG
  214.     } else
  215. #endif V4_2BSD
  216. #ifdef D_LOG
  217.         d_log ("d_direct", "direct line open errno %d for %s",
  218.             errno, d_ptline -> l_tty);
  219. #endif D_LOG
  220.  
  221.     d_errno = D_PORTOPEN;
  222.     return (D_FATAL);
  223.     }
  224.  
  225. /* stdio for input and straight write() for output */
  226.     d_prtfp = fdopen (fd, "r");
  227.     if (d_ttsave (d_prtfp, d_ptline -> l_tty) < 0 ||
  228.         d_ttscript (d_baudrate) < 0)
  229.     {
  230. #ifdef D_LOG
  231.     d_log ("d_direct",
  232.             "can't set direct-line parameters; errno = %d", errno);
  233. #endif D_LOG
  234.     (void) close (fd);
  235.     fd = NOTOK;     /* make sure it hangs up, later       */
  236.     d_errno = D_PORTOPEN;
  237.     return (D_FATAL);
  238.     }
  239.  
  240. #ifdef D_LOG
  241.     d_log ("d_direct", "Open");
  242. #endif D_LOG
  243.     return (D_OK);
  244. }
  245.  
  246. /*
  247.  *     D_DIAL
  248.  *
  249.  *     routine called to make dial-up connection to remote system
  250.  *
  251.  *     number -- number to be called
  252.  *
  253.  *     speed -- speed index
  254.  */
  255.  
  256. d_dial (number, speed)
  257. char   *number;
  258. int     speed;
  259. {
  260.     register int    result;
  261.     char **tlist;
  262.  
  263.     /* get ordered list of acceptable linetypes for this phone number */
  264.     tlist = d_typelist(&number);
  265.  
  266.  
  267.     /* try to find an available dial-out port for the given speed and types */
  268.     result = d_avport (speed, tlist);
  269.  
  270.     if (result < 0)
  271.     return (result);
  272.  
  273.     d_baudrate = speed;
  274.  
  275. #ifdef D_LOG
  276.     d_log ("d_dial", "port %s at %d", d_prtpt -> p_port, d_baudrate);
  277. #endif D_LOG
  278.  
  279.     /*  do the dialing  */
  280.     if ((result = d_dodial (number)) < 0)
  281.     d_drop ();
  282.  
  283.     return (result);
  284. }
  285.  
  286.  
  287. /*
  288.  *     D_AVPORT
  289.  *
  290.  *     routine which finds an available dial-out port with the given speed.
  291.  *     an ordered list of acceptable types is given--the first type is best.
  292.  *     exclusive open of lock files is employed to check for other
  293.  *     users.  if the open succeeds, a global pointer 'd_prtpt' is set
  294.  *     to the entry in the available port structure.
  295.  *
  296.  *     speed -- the speed index of the port be sought
  297.  *
  298.  *     typelist -- a list of acceptable line types for the port
  299.  */
  300.  
  301. d_avport (speed, typelist)
  302. int     speed;
  303. char **typelist;
  304. {
  305.     register struct dialports  *dpt;
  306.     register int    result;
  307. #ifdef D_LOG
  308.     register int    i;
  309. #endif D_LOG
  310.     char **tpt;
  311.  
  312. #ifdef D_DBGLOG
  313.     d_dbglog ("d_avport", "looking for port with speed %d", speed);
  314. #endif D_DBGLOG
  315.  
  316. /* for each type in the typelist, look at each of the known dial-out    */
  317. /* ports.  if the type and speed match, check the access list (if there */
  318. /* is one).  they try to lock the port.                                 */
  319.  
  320.  
  321.  
  322.     for (tpt = typelist; *tpt; tpt++)
  323.     {
  324. #ifdef D_DBGLOG
  325.     d_dbglog("d_avport", "checking for type: %s", *tpt);
  326. #endif D_DBGLOG
  327.  
  328.     for (dpt = d_prts; dpt -> p_port; dpt++)
  329.     {
  330.         if ( ((dpt -> p_speed & (1 << (speed - 1))) == 0) ||
  331.               !lexequ(dpt -> p_ltype, *tpt) )
  332.             continue;
  333.  
  334. /*  check the access list for this port, if there is one  */
  335.  
  336.         if (dpt -> p_access)
  337.         {
  338.             if ((result = d_chkaccess (d_uname, dpt -> p_access)) < 0)
  339.             return (result);
  340.  
  341.             if (result == D_NO)
  342.             continue;
  343.         }
  344.  
  345. /*  try to lock the port.  if we can, we're in business.  */
  346.  
  347.         if ((result = d_lock (dpt -> p_lock)) < 0)
  348.             return (result);
  349.  
  350.  
  351.         if (result == D_OK)
  352.         {
  353.             d_prtpt = dpt;
  354.             d_didial = 1;
  355.             return (D_OK);
  356.         }
  357.         }
  358.  
  359.     }
  360.  
  361.  
  362. /*  if we get here, then we've looked at all the ports and found none  */
  363. /*  that are available.                                                */
  364.  
  365. #ifdef D_LOG
  366.     for (i=0; d_spdtab[i].s_speed != 0; i++) {
  367.         if (d_spdtab[i].s_index == speed) {
  368.        d_log ("d_avport", "No %s baud dial-out ports available",
  369.           d_spdtab[i].s_speed);
  370.        break;
  371.     }
  372.     }
  373. #endif D_LOG
  374.     if (typelist[1] != 0) {
  375. #ifdef D_LOG
  376.         d_log ("d_avport", "of type: %s", typelist[0]);
  377. #endif D_LOG
  378.     } else {
  379.     char *cp, *textlist;
  380.     textlist = strdup(typelist[0]);
  381.     for (tpt = &typelist[1]; *tpt != 0; tpt++)
  382.     {
  383.         cp = multcat(textlist, ",", *tpt, (char *)0);
  384.         free(textlist);
  385.         textlist = cp;
  386.     }
  387. #ifdef D_LOG
  388.         d_log("d_avport", "of types: %s", textlist);
  389. #endif D_LOG
  390.     }
  391.  
  392.     d_errno = D_NOPORT;
  393.     return (D_NONFATAL);
  394. }
  395.  
  396.  
  397. /*
  398.  *     D_AVLINE
  399.  *
  400.  *     routine to search for a direct connect line of the given name, and to
  401.  *     secure its use exclusively.
  402.  *
  403.  *     linename -- direct connect line name
  404.  */
  405.  
  406. d_avline (linename)
  407. register char  *linename;
  408. {
  409.     register struct directlines *lpt;
  410.     register int    result;
  411. #ifdef D_LOG
  412.     int foundone = 0;      /* any lines exist at all? */
  413. #endif D_LOG
  414.  
  415. /*  cycle through the available direct lines  */
  416.  
  417.     for (lpt = d_lines; lpt -> l_name != (char *) 0; lpt++)
  418.     {
  419.     if (strcmp (linename, lpt -> l_name) != 0)
  420.         continue;
  421.  
  422. #ifdef D_LOG
  423.     foundone = 1;
  424. #endif D_LOG
  425.  
  426. /*  check the access (if there is one)  */
  427.  
  428.     if (lpt -> l_access != (char *) 0)
  429.     {
  430.         if ((result = d_chkaccess (d_uname, lpt -> l_access)) < 0)
  431.         return (result);
  432.  
  433.         if (result == D_NO)
  434.         continue;
  435.     }
  436.  
  437. /*  try to lock it.  */
  438.  
  439.     if ((result = d_lock (lpt -> l_lock)) < 0)
  440.         return (result);
  441.  
  442.     if (result == D_OK)
  443.     {
  444.         d_ptline = lpt;
  445.         d_didial = 0;
  446.         return (D_OK);
  447.     }
  448.     }
  449.  
  450. /*  if we get here, there is no available direct line  */
  451.  
  452. #ifdef D_LOG
  453.     if (foundone)
  454.     d_log ("d_avline", "No %s direct lines available", linename);
  455.     else
  456.     d_log ("d_avline", "No direct lines named '%s' are known", linename);
  457. #endif D_LOG
  458.     d_errno = D_NOPORT;
  459.     return (D_NONFATAL);
  460. }
  461.  
  462.  
  463. /*
  464.  *     D_DODIAL
  465.  *
  466.  *     this routine trys to make the connection to the remote system.
  467.  *     it forks, the parent opens the port and the child drives the acu
  468.  *
  469.  *     number -- pointer to the phone number string to be passed to the
  470.  *               dialer
  471.  */
  472.  
  473. d_dodial (number)
  474. char   *number;
  475. {
  476.     register int    parentpid,
  477.                     childpid;
  478.     int     fd;
  479.     int     errcode;
  480. #ifdef SYS5
  481.     struct termio hupbuf;
  482. #endif SYS5
  483.  
  484. #ifdef D_DBGLOG
  485.     d_dbglog ("d_dodial", "about to attempt to call '%s'", number);
  486. #endif D_DBGLOG
  487.     parentpid = getpid ();
  488.     if ((childpid = d_tryfork ()) == -1)
  489.     {
  490. #ifdef D_LOG
  491.     d_log ("d_dodial", "couldn't fork to dial");
  492. #endif D_LOG
  493.     d_errno = D_FORKERR;
  494.     return (D_FATAL);
  495.     }
  496.  
  497.     /*  the parent tries to open the port  */
  498.     if (childpid)
  499.     {
  500. #ifdef D_DBGLOG
  501.     d_dbglog ("d_dodial", "dialing parent opening '%s'",
  502.         d_prtpt -> p_port);
  503. #endif D_DBGLOG
  504.  
  505.         if (setjmp (timerest)) {
  506.         d_ttrestore ();
  507.         return (D_NONFATAL);
  508.         }
  509.     s_alarm (ACUWAIT);
  510.     fd = open (d_prtpt -> p_port, 2);
  511.     s_alarm (0);
  512.     d_errno = errno;      /* save, so kill does not overwrite   */
  513. #ifdef D_DBGLOG
  514.     d_dbglog ("d_dodial", "parent open return (errno=%d)", d_errno);
  515. #endif D_DBGLOG
  516.  
  517.     d_cstart (number,d_prtpt -> p_ltype); /* carrier: start call timer */
  518.  
  519.     kill (childpid, SIGKILL);  /* so it doesn't waste it time */
  520.     errcode = pgmwait (childpid);
  521.                   /* gather up the dialing child        */
  522. #ifdef D_DBGLOG
  523.     d_dbglog ("d_dodial", "acu child exit error code %d", errcode);
  524. #endif D_DBGLOG
  525.  
  526.     if (fd < 0)
  527.     {
  528.         if (errno != EINTR)   /* not timeout or child kill          */
  529.         {                     /* so must terminate                  */
  530. #ifdef D_LOG
  531.         d_log ("d_dodial", "can't open port '%s', errno #%d",
  532.             d_prtpt -> p_port, d_errno);
  533. #endif D_LOG
  534.         d_errno = D_PORTOPEN;
  535.         return (D_FATAL);
  536.         }
  537.     }
  538.     else
  539.     {
  540. #ifdef SYS5
  541.         ioctl(fd, TCGETA, &hupbuf);
  542.         hupbuf.c_cflag |= HUPCL;
  543.         if (ioctl (fd, TCSETA, &hupbuf) < OK)
  544. #else
  545.         if (ioctl (fd, TIOCHPCL, 0) < OK)
  546. #endif SYS5
  547.         {
  548. #ifdef D_LOG
  549.         d_log ("d_dodial",
  550.                 "problem setting hangup on close; errno = %d", errno);
  551. #endif D_LOG
  552.         (void) close (fd);
  553.         fd = NOTOK;     /* make sure it hangs up, later       */
  554.         d_errno = D_PORTOPEN;
  555.         return (D_FATAL);
  556.         }
  557.         else
  558.         {
  559.         d_prtfp = fdopen (fd, "r");
  560.         if (d_ttsave (d_prtfp, d_prtpt -> p_port) < 0 ||
  561.             d_ttscript (d_baudrate) < 0)
  562.         {
  563. #ifdef D_LOG
  564.             d_log ("d_dodial",
  565.                 "can't set dial-port parameters; errno = %d", errno);
  566. #endif D_LOG
  567.             (void) close (fd);
  568.             fd = NOTOK;     /* make sure it hangs up, later       */
  569.             d_errno = D_PORTOPEN;
  570.             d_ttrestore ();
  571.             return (D_FATAL);
  572.         }
  573.         }                     /* stdio for input and straight       */
  574.                   /*   write() for output               */
  575.     }
  576.  
  577.     switch (d_errno = errcode)
  578.     {
  579.         case 0:
  580.         if (fd < 0)
  581.             return (D_NONFATAL);
  582.         return (D_OK);
  583.  
  584.         case D_BUSY:
  585.         case D_ABAN:
  586.         d_ttrestore ();
  587.         return (D_NONFATAL);
  588.  
  589.         default:
  590.         d_ttrestore ();
  591.         return (D_FATAL);
  592.     }
  593.     }
  594.  
  595.     /*  the child drives the acu.  if there's an error, then a
  596.      *  signal is sent to the parent to interrupt his open call.
  597.      *  The error code is returned to the parent through his
  598.      *  exit status.
  599.      */
  600.     d_errno = 0;
  601.  
  602.     sleep ((unsigned) 5);       /* give parent time to get into open()  */
  603.     d_drvacu (number);
  604.  
  605.     sleep ((unsigned) CONNWAIT); /* wait for open to complete    */
  606.     kill (parentpid, SIGALRM);   /* kick parent out of open call     */
  607.  
  608.     exit (d_errno);
  609. #ifdef lint
  610.     return D_FATAL;
  611. #endif lint
  612. }
  613.  
  614. /*
  615.  *     D_DRVACU
  616.  *
  617.  *     this routine opens the appropriate acu and feeds the phone number to
  618.  *     it.  it's possible that it's in use, so we'll wait up to a minute,
  619.  *     trying every couple of seconds.  D_FATAL and D_NONFATAL errors are
  620.  *     possible here.
  621.  *
  622.  *     number -- phone number string to be passed to the dialer
  623.  */
  624.  
  625. d_drvacu (number)
  626. char   *number;
  627. {
  628.     int len;
  629.     char linebuf[100];
  630.     register int    acufd,
  631.                     warning;
  632.  
  633.     warning = 0;
  634.     if (d_prtpt -> p_acupref != (char *) 0)
  635.     (void) strcpy (linebuf, d_prtpt -> p_acupref);
  636.     else
  637.     linebuf[0] = '\0';
  638.  
  639.     strcat (linebuf, number);
  640.     if (d_prtpt -> p_acupost != (char *) 0)
  641.     strcat (linebuf, d_prtpt -> p_acupost);
  642.  
  643.     len = strlen (linebuf);
  644. #ifdef D_DBGLOG
  645.     d_dbglog ("d_drvacu", "about to write '%s' on acu", linebuf);
  646. #endif D_DBGLOG
  647.  
  648.     while (1)
  649.     {                             /* make sure open & write don't hang  */
  650.                 /* this doesn't really work under 4.2 */
  651. #ifdef D_DBGLOG
  652.     d_dbglog ("d_drvacu", "opening dialer");
  653. #endif D_DBGLOG
  654.         if (setjmp (timerest)) {
  655.             break;
  656.         }
  657.     s_alarm (DIALWAIT);
  658.     acufd = open (d_prtpt -> p_acu, 2);
  659. #ifdef D_DBGLOG
  660.     d_dbglog ("d_drvacu", "dialer open (errno=%d)", errno);
  661. #endif D_DBGLOG
  662.  
  663. /*  if we get it, then try to dial the number.  if that goes alright,  */
  664. /*  return                                                             */
  665.  
  666.     if (acufd >= 0)
  667.     {
  668.         sleep ((unsigned) 1);  /* let things settle down           */
  669. #ifdef D_LOG
  670.         d_log ("d_drvacu", "Dialing...");
  671. #endif D_LOG
  672.         if (write (acufd, linebuf, len) != len)
  673.         break;
  674.  
  675.         (void) close (acufd);      /* free the dialer */
  676. #ifdef D_DBGLOG
  677.         d_dbglog ("d_drvacu", "acu successful write");
  678. #endif D_DBGLOG
  679.         s_alarm (0);
  680.         return (D_OK);
  681.     }
  682.  
  683. /*  we get here from a failure of the acu open.  if it's worse than just  */
  684. /*  being busy, break out to the common error decoder                     */
  685.  
  686.     s_alarm(0);
  687. #ifdef D_DBGLOG
  688.     d_dbglog ("d_drvacu", "acu open (errno=%d)", errno);
  689. #endif D_DBGLOG
  690.  
  691.     if (errno != EBUSY)
  692.         break;
  693.  
  694. /*  print the warning message once, and then sleep before trying again  */
  695.  
  696.     if (!warning)
  697.     {
  698. #ifdef D_LOG
  699.         d_log ("d_drvacu", "waiting for dialer.");
  700. #endif D_LOG
  701.         warning = 1;
  702.     }
  703.     sleep ((unsigned) 5);
  704.     }
  705.  
  706. /*  this stuff prints error messages for failures of both the open and  */
  707. /*  write calls                                                         */
  708.  
  709.     s_alarm (0);
  710.     switch (errno)
  711.     {
  712.     case EBUSY: 
  713.  
  714. #ifdef D_LOG
  715.         d_log ("d_drvacu", "That number is busy.");
  716. #endif D_LOG
  717.         d_errno = D_BUSY;
  718.         return (D_NONFATAL);
  719.  
  720.     case EDNPWR: 
  721.  
  722. #ifdef D_LOG
  723.         d_log ("d_drvacu", "dialer power off");
  724. #endif D_LOG
  725.         d_errno = D_NOPWR;
  726.         return (D_FATAL);
  727.  
  728.     case EDNABAN: 
  729.  
  730. #ifdef D_LOG
  731.         d_log ("d_drvacu", "call abandoned");
  732. #endif D_LOG
  733.         d_clog (LOG_ABAN);
  734.         d_errno = D_ABAN;
  735.         return (D_NONFATAL);
  736.  
  737.     case EDNDIG: 
  738.  
  739. #ifdef D_LOG
  740.         d_log ("d_drvacu", "internal error: bad digit to dialer");
  741. #endif D_LOG
  742.         d_errno = D_SYSERR;
  743.         return (D_FATAL);
  744.  
  745.     default: 
  746.  
  747. #ifdef D_LOG
  748.         d_log ("d_drvacu", "system errno #%d", errno);
  749. #endif D_LOG
  750.         d_errno = D_INTERR;
  751.         return (D_FATAL);
  752.     }
  753. }
  754.  
  755.  
  756. /*
  757.  *     D_DROP
  758.  *
  759.  *     routine which is called to drop the connection to the remote system.
  760.  *     if closes the port and lock file, and logs the call, of this was a
  761.  *     dial-up.
  762.  */
  763.  
  764. d_drop ()
  765. {
  766. #ifdef SYS5
  767.     struct termio hupbuf;
  768. #endif SYS5
  769.  
  770. #ifdef D_DBGLOG
  771.     d_dbglog ("d_drop", "dropping connection.");
  772. #endif D_DBGLOG
  773.  
  774.     /*  restore the line to its old state  */
  775.     d_ttrestore ();
  776.  
  777.     /*  close port  */
  778.     if (d_prtfp != (FILE *) EOF && d_prtfp != NULL)
  779.     {
  780.         if (setjmp (timerest)) {
  781.         return;
  782.         }
  783.     s_alarm (CONNWAIT);
  784.  
  785. #ifdef SYS5
  786.     ioctl (fileno(d_prtfp), TCGETA, &hupbuf);
  787.     hupbuf.c_cflag &= ~CBAUD;    /* set 0 baud -- hangup */
  788.     ioctl (fileno(d_prtfp), TCSETA, &hupbuf);
  789. #endif SYS5
  790.  
  791.     fclose (d_prtfp);
  792.     s_alarm (0);
  793. /* XXX Why commented out? */    /* d_prtfp = (FILE *) EOF; */
  794.  
  795.     if ((FILE *) EOF == d_prtfp)
  796.     {
  797. #ifdef D_LOG
  798.         d_log ("d_drop", "problem closing connection line.");
  799. #endif D_LOG
  800.         return;     /* leave the line locked, in case of major problem */
  801.     }
  802.  
  803.     if (d_didial)
  804.         d_clog (LOG_COMP);
  805.     }
  806.  
  807.     /*  release the port to others by closing lock file  */
  808.     d_unlock (d_ptline -> l_lock);
  809. }
  810.