home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / duucp-1.17 / AU-117b4-src.lha / src / uucico / sysdep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-28  |  15.8 KB  |  855 lines

  1. /*
  2.  *  SYSDEP.C
  3.  *
  4.  * (C) Copyright 1987 by John Gilmore
  5.  * Copying and use of this program are controlled by the terms of the Free
  6.  * Software Foundation's GNU Emacs General Public License.
  7.  *
  8.  *  Amiga Changes Copyright 1988 by William Loftus. All rights reserved.
  9.  *  Additional chgs Copyright 1989 by Matthew Dillon, All Rights Reserved.
  10.  *  Additional chgs Copyright 1993 by Michael B. Smith, All Rights Reserved.
  11.  */
  12.  
  13. #include "includes.h"
  14. #include <hardware/cia.h>
  15. #include <devices/timer.h>
  16. #include <devices/serial.h>
  17. #include <pwd.h>
  18. #include "uucp.h"
  19. #include "version.h"
  20. #include <OwnDevUnit.h>
  21.  
  22. #define Assert(x)   if (!(x)) _assert_failed(__LINE__);
  23.  
  24. Prototype int openout (char *, int);
  25. Prototype void sigint (int);
  26. Prototype void cleanup (void);
  27. Prototype int xdatardy (void);
  28. Prototype int xgetc (int,int);
  29. Prototype int xwrite (const void *, int);
  30. Prototype int xwritea (const void *, int);
  31. Prototype int xxwrite (const void *, int, int);
  32. Prototype void SendBreak (void);
  33. Prototype int CheckCarrier (void);
  34. Prototype void munge_filename (char *, char *);
  35. Prototype int hangup (void);
  36. Prototype void set_dir (const char *dirname);
  37. Prototype int work_scan (char *);
  38. Prototype char *work_next (void);
  39. Prototype void amiga_setup (void);
  40. Prototype void set_baud (int);
  41. Prototype void OpenSerial (int);
  42. Prototype void CloseSerial (int);
  43. Prototype void xexit (int);
  44. Prototype void printc (unsigned char);
  45. Prototype void NiceAbortIO (void *);
  46.  
  47. Prototype char *DeviceName;
  48. Prototype int DeviceUnit;
  49.  
  50. char
  51.     *DeviceName = "serial.device";
  52. int
  53.     DeviceUnit = 0;
  54. static void
  55.     _assert_failed (int);
  56.  
  57. IDENT (".03");
  58.  
  59. /*
  60.  *  Split out of uuslave.c by John Gilmore, 8 August 1987.
  61.  *  ported to the Amiga by William Loftus, 20 September 1987.
  62.  *  rewritten by Matthew Dillon, October 1989
  63.  */
  64.  
  65. struct IOExtSer
  66.     Iosr,
  67.     Iosw,
  68.     Ioss;
  69. struct timerequest
  70.     Iot0;
  71. char
  72.     *OldTaskName;
  73. unsigned char
  74.     XInBuf [512];        /*    for xgetc() */
  75. int
  76.     XInIdx = 0,
  77.     XInLen = 0,
  78.     IoswIP = 0,
  79.     IosrIP = 0,
  80.     IotIP = 0,
  81.     InExitRoutine = 0,
  82.     debugRead = 0;
  83.  
  84. int
  85. openout (char *acu, int baud)
  86. {
  87.     set_baud (baud);
  88.  
  89.     return SUCCESS;
  90. }
  91.  
  92. /*
  93.  * Basement level I/O routines
  94.  *
  95.  * xwrite () writes a character string to the serial port
  96.  * xgetc () returns a character from the serial port, or an EOF for timeout.
  97.  * sigint () restores the state of the serial port on exit.
  98.  */
  99.  
  100. void
  101. sigint (int sig)
  102. {
  103.     xexit (10);
  104.     return;
  105. }
  106.  
  107.  
  108. void
  109. cleanup (void)
  110. {
  111.  
  112.     signal (SIGINT, SIG_IGN);
  113.  
  114.     ++InExitRoutine;
  115.  
  116.     if (InExitRoutine == 1 && Iosr.IOSer.io_Device && CheckCarrier ())
  117.         reset_modem ();
  118.  
  119.     CloseSerial (1);
  120.  
  121.     if (OldTaskName) {
  122.         struct Task
  123.             *task = (struct Task *) FindTask (NULL);
  124.  
  125.         task->tc_Node.ln_Name = OldTaskName;
  126.     }
  127.  
  128.     if (Iot0.tr_node.io_Device) {
  129.         CloseDevice ((struct IORequest *) &Iot0);
  130.         Iot0.tr_node.io_Device = NULL;
  131.     }
  132.     if (Iot0.tr_node.io_Message.mn_ReplyPort) {
  133.         DeletePort (Iot0.tr_node.io_Message.mn_ReplyPort);
  134.         Iot0.tr_node.io_Message.mn_ReplyPort = NULL;
  135.     }
  136.  
  137.     mountrequest (1);
  138.  
  139.     UnLockFiles ();      /*  unlock any hanging locks */
  140.     return;
  141. }
  142.  
  143. int
  144. xdatardy (void)
  145. {
  146.     if (XInIdx != XInLen)
  147.         return 1;
  148.     CheckCarrier ();
  149.     return (Ioss.IOSer.io_Actual > 0);
  150. }
  151.  
  152. int
  153. xgetc (int byteto, int delay_flg)
  154. {
  155.     int
  156.         ch,
  157.         n,
  158.         smask,
  159.         tmask,
  160.         bytetimeout;
  161.  
  162. top:
  163.     if (XInIdx != XInLen) {
  164.         if (debug > 8) {
  165.             if (debugRead == 0)
  166.                 printf("\nREAD: ");
  167.             debugRead = 1;
  168.             printc (XInBuf [XInIdx]);
  169.         }
  170.         xfer.bytes_recv++;
  171.         return (int) XInBuf [XInIdx++];
  172.     }
  173.  
  174.     XInIdx = 0;
  175.     XInLen = 0;
  176.  
  177.     /* Mod by Steve Drew:
  178.      * at high speeds and fast machines we can end up going through all
  179.      * layers for only 1 byte. Delaying a small amount here give the serial
  180.      * device a chance to buffer a few chars and then we will grab them all
  181.      * saving many cpu cycles. On a 030 system with 14.4K modem have seen
  182.      * cpu load go from %70 down to %10 with this one line change.
  183.      */
  184.     if (byteto && delay_flg && NoDelay == 0) {
  185.         Delay (3L);  /* .06 sec */
  186.     }
  187.  
  188.     if (!CheckCarrier ())                 /*  carrier lost?       */
  189.         return EOF;
  190.  
  191.     Assert (Iosr.IOSer.io_Device);
  192.  
  193.     if ((n = Ioss.IOSer.io_Actual) > 0) {        /*    at least one..      */
  194.         Iosr.IOSer.io_Command = CMD_READ;
  195.         Iosr.IOSer.io_Data = (APTR) XInBuf;
  196.         if (n > sizeof (XInBuf))
  197.             n = sizeof (XInBuf);
  198.         Iosr.IOSer.io_Length = n;
  199.         DoIO ((struct IORequest *) &Iosr);
  200.         if (Iosr.IOSer.io_Actual > 0) {
  201.             if (debug > 8)
  202.                 printf ("(r%d/%d)\n", n, Iosr.IOSer.io_Actual);
  203.             XInIdx = 0;
  204.             XInLen = Iosr.IOSer.io_Actual;
  205.             goto top;
  206.         }
  207.     }
  208.  
  209.     /*
  210.      *  no bytes ready, byteto is 0 (no wait)
  211.      */
  212.  
  213.     if (byteto == 0)
  214.         return EOF;
  215.  
  216.     /*
  217.      *  no bytes ready, wait for one.
  218.      *
  219.      *  once every 3 seconds check carrier detect.
  220.      */
  221.  
  222.     bytetimeout = byteto;
  223.     Iot0.tr_time.tv_secs = 3;
  224.     Iot0.tr_time.tv_micro= 0;
  225.     SendIO ((struct IORequest *) &Iot0);
  226.     IotIP = 1;
  227.  
  228.     Iosr.IOSer.io_Command = CMD_READ;
  229.     Iosr.IOSer.io_Data = (APTR) XInBuf;
  230.     Iosr.IOSer.io_Length = 1;
  231.     Iosr.IOSer.io_Actual = 0;   /*    trying to find a bug... */
  232.     SendIO ((struct IORequest *) &Iosr);
  233.     IosrIP = 1;
  234.  
  235.     smask = 1L << Iosr.IOSer.io_Message.mn_ReplyPort->mp_SigBit;
  236.     tmask = 1L << Iot0.tr_node.io_Message.mn_ReplyPort->mp_SigBit;
  237.  
  238.     for (;;) {
  239.         long
  240.             mask = Wait (tmask | smask | SIGBREAKF_CTRL_C);
  241.  
  242.         if (debug > 8) {
  243.             printf ("** wakeup **");
  244.             if (mask & tmask)
  245.                 printf ("timeout ");
  246.             if (mask & smask)
  247.                 printf ("rcv ");
  248.             if (mask & SIGBREAKF_CTRL_C)
  249.                 printf ("^C");
  250.             printf ("\n");
  251.             fflush (stdout);
  252.         }
  253.  
  254.         if (mask & SIGBREAKF_CTRL_C) {
  255.             NiceAbortIO (&Iosr);
  256.             WaitIO ((struct IORequest *) &Iosr);
  257.             IosrIP = 0;
  258.             AbortIO ((struct IORequest *) &Iot0);
  259.             WaitIO ((struct IORequest *) &Iot0);
  260.             IotIP = 0;
  261.             xexit (10);
  262.         }
  263.  
  264.         if (CheckIO ((struct IORequest *) &Iosr)) {
  265.             WaitIO ((struct IORequest *) &Iosr);
  266.             IosrIP = 0;
  267.             AbortIO ((struct IORequest *) &Iot0);
  268.             WaitIO ((struct IORequest *) &Iot0);
  269.             IotIP = 0;
  270.  
  271.             ch = (int) XInBuf [0];
  272.  
  273.             if (debug > 8) {
  274.                 if (debugRead == 0)
  275.                     printf ("\nREAD ");
  276.                 debugRead = 1;
  277.                 if (debug > 9)
  278.                     printf ("(waitc%d)", Iosr.IOSer.io_Actual);
  279.                 printc ((unsigned char) ch);
  280.             }
  281.             xfer.bytes_recv++;
  282.             return ch;
  283.         }
  284.  
  285.         if (CheckIO ((struct IORequest *) &Iot0)) {
  286.             WaitIO ((struct IORequest *) &Iot0);
  287.             IotIP = 0;
  288.  
  289.             Iot0.tr_time.tv_secs = 3;
  290.             Iot0.tr_time.tv_micro= 0;
  291.  
  292.             bytetimeout -= Iot0.tr_time.tv_secs;
  293.             if (bytetimeout > 0) {
  294.                 if (CheckCarrier () == 0) {
  295.                     NiceAbortIO (&Iosr);
  296.                     WaitIO ((struct IORequest *) &Iosr);
  297.                     IosrIP = 0;
  298.                     break;
  299.                 }
  300.                 SendIO ((struct IORequest *) &Iot0);
  301.                 IotIP = 1;
  302.             }
  303.             else {
  304.                 NiceAbortIO (&Iosr);
  305.                 WaitIO ((struct IORequest *) &Iosr);
  306.                 IosrIP = 0;
  307.                 if (Iosr.IOSer.io_Actual == 1) {
  308.                     xfer.bytes_recv++;
  309.                     return (int) XInBuf [0];
  310.                 }
  311.                 break;
  312.             }
  313.         }
  314.     }
  315.  
  316.     if (debug > 8)
  317.         printf ("\nRecv-EOF\n");
  318.  
  319.     return EOF;
  320. }
  321.  
  322. int
  323. xwrite (const void *buf, int ctr)
  324. {
  325.     return xxwrite (buf, ctr, 0);
  326. }
  327.  
  328. int
  329. xwritea (const void *buf, int ctr)
  330. {
  331.     xxwrite (buf, ctr, 1);
  332.     return ctr;
  333. }
  334.  
  335. int
  336. xxwrite (const void *buf, int ctr, int async)
  337. {
  338.     Assert (Iosr.IOSer.io_Device);
  339.  
  340.     if (debug > 9) {
  341.         int
  342.             i;
  343.  
  344.         if (debugRead)
  345.             printf ("\nWRITE ");
  346.         debugRead = 0;
  347.         for (i = 0; i < ctr; ++i) {
  348.             printc (((unsigned char *) buf) [i]);
  349.         }
  350.         printf ("\n");
  351.     }
  352.  
  353.     if (IoswIP) {
  354.         WaitIO ((struct IORequest *) &Iosw);
  355.         IoswIP = 0;
  356.     }
  357.  
  358.     Iosw.IOSer.io_Command = CMD_WRITE;
  359.     Iosw.IOSer.io_Length = ctr;
  360.     Iosw.IOSer.io_Data = (APTR) buf;
  361.     if (async) {
  362.         SendIO ((struct IORequest *) &Iosw);
  363.         IoswIP = 1;
  364.     }
  365.     else {
  366.         DoIO ((struct IORequest *) &Iosw);
  367.     }
  368.     xfer.bytes_send += ctr;
  369.     return ctr;
  370. }
  371.  
  372. void
  373. SendBreak (void)
  374. {
  375.     Assert (Iosr.IOSer.io_Device);
  376.     Ioss.IOSer.io_Command = SDCMD_BREAK;
  377.     DoIO ((struct IORequest *) &Ioss);
  378.  
  379.     return;
  380. }
  381.  
  382. int
  383. CheckCarrier (void)
  384. {
  385.     Assert (Iosr.IOSer.io_Device);
  386.     Ioss.IOSer.io_Command = SDCMD_QUERY;
  387.     DoIO ((struct IORequest *) &Ioss);
  388.  
  389.     if (debug > 8 && Ioss.IOSer.io_Actual) {
  390.         printf ("*** carrier data len %ld\n", Ioss.IOSer.io_Actual);
  391.         fflush (stdout);
  392.     }
  393.  
  394.     if (IgnoreCD)
  395.         return 1;
  396.  
  397.     if (Ioss.io_Status & CIAF_COMCD)    /*    non-zero == no carrier */
  398.         return 0;
  399.  
  400.     return 1;
  401. }
  402.  
  403. /*
  404.  * Transform a filename from a uucp packet (in Unix format) into a local
  405.  * filename that will work in the local file system.
  406.  */
  407.  
  408. void
  409. munge_filename (char *s, char *d)
  410. {
  411.     if (*s != '~') {
  412.         if (s != d)
  413.             strcpy (d, s);
  414.         return;
  415.     }
  416.  
  417.     /*
  418.      *  ~/ ...  convert to UUPUB:
  419.      *  ~user/...    convert to <homedir>/...
  420.      */
  421.  
  422.     {
  423.         int
  424.             i,
  425.             c;
  426.         char
  427.             *t;
  428.         struct passwd
  429.             *pw;
  430.  
  431.         for (i = 1; s [i] && s [i] != '/'; ++i)
  432.             ;
  433.         c = s [i];
  434.  
  435.         s [i] = 0;
  436.         if (i == 1)
  437.             pw = NULL;
  438.         else
  439.             pw = getpwnam (s + 1);
  440.         s [i] = c;
  441.  
  442.         if (c == '/')
  443.             ++i;
  444.  
  445.         if (pw) {
  446.             t = malloc (strlen (pw->pw_dir) + strlen (s + i) + 1);
  447.             strcpy (t, pw->pw_dir);
  448.         }
  449.         else {
  450.             t = malloc (strlen (s + i) + 32);
  451.             strcpy (t, GetConfigDir (UUPUB));
  452.         }
  453.         strcat (t, s + i);
  454.         strcpy (d, t);
  455.         free (t);
  456.     }
  457.  
  458.     return;
  459. }
  460.  
  461. int
  462. hangup (void)
  463. {
  464.     char
  465.         buf [128];
  466.  
  467.     reset_modem ();
  468.  
  469.     sprintf (buf, "run >nil: <nil: %s", GetConfigProgram (UUXQT));
  470.  
  471.     if (PriMode)
  472.         SetTaskPri (FindTask (NULL), OldPri - 1);
  473.  
  474.     if (Execute (buf, 0, 0) == 0)
  475.         fprintf (stderr, "Unable to run UUXQT\n");
  476.  
  477.     if (PriMode)
  478.         SetTaskPri (FindTask (NULL), OldPri + 1);
  479.  
  480.     return SUCCESS;
  481. }
  482.  
  483. void
  484. set_dir (const char *dirname)
  485. {
  486.     /*
  487.     **  set_dir
  488.     **
  489.     **    Change our directory to the appropriate subdirectory
  490.     **    of UUSpool:, or to the UUSpool: main directory if
  491.     **    UseSubDirs is not set.
  492.     */
  493.  
  494.     static char
  495.         *p = NULL;
  496.     int
  497.         i;
  498.  
  499.     if (debug > 1) {
  500.         printf ("set_dir (%s)\n", dirname);
  501.     }
  502.  
  503.     if (!uuspool)
  504.         uuspool = "UUSpool:";
  505.  
  506.     if (UseSubDirs == 0) {
  507.         if (safe_chdir (uuspool)) {
  508.             ulog (-1, "safe_chdir (%s) failure %ld", uuspool, IoErr ());
  509.         }
  510.         return;
  511.     }
  512.  
  513.     if (!p) {
  514.  
  515.         i = strlen (uuspool) + 35;
  516.         p = malloc (i);
  517.         if (!p) {
  518.             ulog (-1, "No memory in set_dir()!");
  519.             exit (30);
  520.         }
  521.     }
  522.  
  523.     /* our own AddPart ... */
  524.     i = strlen (uuspool);
  525.     if (uuspool [i - 1] != ':' && uuspool [i - 1] != '/') {
  526.         sprintf (p, "%s/%s", uuspool, dirname);
  527.     }
  528.     else {
  529.         sprintf (p, "%s%s", uuspool, dirname);
  530.     }
  531.  
  532.     if (safe_chdir (p)) {
  533.         ulog (-1, "safe_chdir (%s) failure %ld", p, IoErr ());
  534.     }
  535.  
  536.     return;
  537. }
  538.  
  539. static char
  540.     names [MAXFILES * 16],
  541.     *pointers [MAXFILES];
  542. static int
  543.     file_pointer = 0;
  544.  
  545. int
  546. bp_strcmp (const void *s1, const void *s2)
  547. {
  548.     return strcmp (* ((char **) s1), * ((char **) s2));
  549. }
  550.  
  551. int
  552. search_dir (const char *system_name)
  553. {
  554.     static char
  555.         name [128];
  556.  
  557.     sprintf (name, "C.%.7s#?", system_name);
  558.     if (debug > 2)
  559.         printf ("Looking for %s\n", name);
  560.  
  561.     return getfnl (name, names, sizeof (names), 0);
  562. }
  563.  
  564. int
  565. work_scan (char *system_name)
  566. {
  567.     int
  568.         count;
  569.  
  570.     file_pointer = 0;
  571.  
  572.     set_dir (system_name);
  573.  
  574. #if 0
  575.     if (strlen (system_name) > 7)        /* FIXME - why? */
  576.         system_name [7] = '\0';
  577. #endif
  578.  
  579.     count = search_dir (system_name);
  580.     if (debug > 1) {
  581.         printf ("count from search_dir (%s) is %ld\n", system_name, count);
  582.     }
  583.  
  584.     if (count == 0 && UseSubDirs) {
  585.         /* try looking in UUSpool: main directory too */
  586.         safe_chdir (uuspool);
  587.         count = search_dir (system_name);
  588.         if (debug > 1) {
  589.             printf ("count from uuspool search_dir (%s) is %ld\n", system_name, count);
  590.         }
  591.     }
  592.  
  593.     if (count > 0) {
  594.         if (strbpl (pointers, MAXFILES, names) != count) {
  595.             ulog (-1, "Too many command files for %s.", system_name);
  596.             return 0;
  597.         }
  598.     }
  599.     else {
  600.         return 0;
  601.     }
  602.  
  603.     qsort (pointers, count, sizeof (char *), bp_strcmp);
  604.     if (debug > 2)
  605.         printf ("Found -> %s\n", pointers [file_pointer]);
  606.  
  607.     return 1;
  608. }
  609.  
  610. char *
  611. work_next (void)
  612. {
  613.     char
  614.         *ptr;
  615.  
  616.     if (ptr = pointers [file_pointer]) {
  617.         if (debug > 2)
  618.             printf ("Found -> %s\n", ptr);
  619.         ++file_pointer;
  620.     }
  621.  
  622.     return ptr;
  623. }
  624.  
  625. void
  626. amiga_setup (void)
  627. {
  628.     int
  629.         err;
  630.     struct Task
  631.         *task = (struct Task *) FindTask (NULL);
  632.  
  633.     mountrequest (0);     /*  disallow requesters */
  634.  
  635.     OpenSerial (1);
  636.  
  637.     if (err = OpenDevice (TIMERNAME, UNIT_VBLANK, (struct IORequest *) &Iot0, 0))  {
  638.         Iot0.tr_node.io_Device = NULL;
  639.         ulog (-1, "Can't open timer device (error %ld).", err);
  640.         xexit (10);
  641.     }
  642.  
  643.     Iot0.tr_node.io_Message.mn_ReplyPort = (struct MsgPort *) CreatePort ("UUCICO-Timer", 0L);
  644.     Iot0.tr_node.io_Command = TR_ADDREQUEST;
  645.     Iot0.tr_node.io_Error = 0;
  646.  
  647.     OldTaskName = task->tc_Node.ln_Name;
  648.     task->tc_Node.ln_Name = "uucico";
  649.  
  650.     return;
  651. }
  652.  
  653. void
  654. set_baud (int baud)
  655. {
  656.     Assert (Iosr.IOSer.io_Device);
  657.  
  658.     /*
  659.      *  only modify serial parameters if not run from a Getty.  This is
  660.      *  to get around a bug in the A2232 serial.device (possibly also
  661.      *  the normal serial.device) having to do with hanging semaphores.
  662.      *
  663.      *  it is also possible that this might be desirable for operation.
  664.      */
  665.  
  666.     if ((Getty == 0) && (Overide == 0)) {
  667.         Iosr.IOSer.io_Command = SDCMD_SETPARAMS;
  668.         Iosr.io_SerFlags =  SERF_SHARED | SERF_XDISABLED;
  669.         Iosr.io_Baud = baud;
  670.         Iosr.io_ReadLen = 8L;
  671.         Iosr.io_WriteLen = 8L;
  672.         Iosr.io_CtlChar = 0x11130000L;
  673.         Iosr.io_RBufLen = 4096;
  674.         Iosr.io_StopBits= 1;
  675.         Iosr.io_BrkTime = 500000;
  676.  
  677.         if (SevenWire)
  678.             Iosr.io_SerFlags |= SERF_7WIRE;
  679.  
  680.         DoIO ((struct IORequest *) &Iosr);
  681.     }
  682.  
  683.     return;
  684. }
  685.  
  686. void
  687. OpenSerial (int lock)
  688. {
  689.     unsigned char
  690.         *error;
  691.     int
  692.         err;
  693.  
  694.     if (Iosr.IOSer.io_Device) {
  695.         ulog (-1, "ERROR: softerror, OpenSerial: Serial Port already open!");
  696.         return;
  697.     }
  698.  
  699.     Iosr.io_SerFlags = SERF_SHARED | SERF_XDISABLED;
  700.     Iosr.IOSer.io_Message.mn_ReplyPort = (struct MsgPort *) CreatePort ("Read_RS", 0);
  701.  
  702.     if (SevenWire)
  703.         Iosr.io_SerFlags |= SERF_7WIRE;
  704.  
  705.     if (lock && Getty == 0) {
  706.         if (DoAttempt)
  707.             error = AttemptDevUnit (DeviceName, DeviceUnit, "UUcico", 0);
  708.         else
  709.             error = LockDevUnit (DeviceName, DeviceUnit, "UUcico", 0);
  710.  
  711.         if (error) {
  712.             if (error [0] == ODUERR_LEADCHAR [0])
  713.                 ulog (-1, "ERROR: Unable to lock serial port: %s", &error[1]);
  714.             else
  715.                 ulog (-1, "ERROR: %s unit %ld already owned by %s",
  716.                     DeviceName, DeviceUnit, error);
  717.  
  718.             xexit (10);
  719.         }
  720.     }
  721.  
  722.     if (err = OpenDevice (DeviceName, DeviceUnit, (struct IORequest *) &Iosr, 0)) {
  723.         Iosr.IOSer.io_Device = NULL;
  724.         DeletePort (Iosr.IOSer.io_Message.mn_ReplyPort);
  725.         Iosr.IOSer.io_Message.mn_ReplyPort = NULL;
  726.         ulog (-1, "ERROR: Cannot open serial port for read (error %ld, for '%s' unit %ld).",
  727.             err, DeviceName, DeviceUnit);
  728.         xexit (TRUE);
  729.     }
  730.  
  731.     Iosw = Iosr;
  732.     Iosw.IOSer.io_Message.mn_ReplyPort = (struct MsgPort *) CreatePort ("Write_RS", 0);
  733.     Ioss = Iosw;
  734.  
  735.     Iosr.IOSer.io_Command = SDCMD_QUERY;
  736.     DoIO ((struct IORequest *) &Iosr);
  737.  
  738.     set_baud (Iosr.io_Baud);
  739.  
  740.     return;
  741. }
  742.  
  743. void
  744. CloseSerial (int lock)
  745. {
  746.     if (IosrIP) {
  747.         /* I/O Serial Read In-Process */
  748.         NiceAbortIO (&Iosr);
  749.         WaitIO ((struct IORequest *) &Iosr);
  750.         IosrIP = 0;
  751.     }
  752.  
  753.     if (IotIP) {
  754.         /* I/O Timer In-Process */
  755.         AbortIO ((struct IORequest *) &Iot0);
  756.         WaitIO ((struct IORequest *) &Iot0);
  757.         IotIP = 0;
  758.     }
  759.  
  760.     if (IoswIP) {
  761.         /* I/O Serial Write In-Process */
  762.         WaitIO ((struct IORequest *) &Iosw);
  763.         IoswIP = 0;
  764.     }
  765.  
  766.     if (Iosr.IOSer.io_Device) {
  767.         CloseDevice ((struct IORequest *) &Iosr);
  768.         Iosr.IOSer.io_Device = NULL;
  769.         Iosw.IOSer.io_Device = NULL;
  770.         Ioss.IOSer.io_Device = NULL;
  771.     }
  772.     else {
  773.         fprintf (stderr, "softerr, CloseSerial: Serial Port already closed!\n");
  774.     }
  775.  
  776.     if (Iosr.IOSer.io_Message.mn_ReplyPort) {
  777.         DeletePort (Iosr.IOSer.io_Message.mn_ReplyPort);
  778.         Iosr.IOSer.io_Message.mn_ReplyPort = NULL;
  779.     }
  780.  
  781.     if (Iosw.IOSer.io_Message.mn_ReplyPort) {
  782.         DeletePort (Iosw.IOSer.io_Message.mn_ReplyPort);
  783.         Iosw.IOSer.io_Message.mn_ReplyPort = NULL;
  784.     }
  785.  
  786.     if (lock && Getty == 0)
  787.         FreeDevUnit (DeviceName, DeviceUnit);
  788.  
  789.     return;
  790. }
  791.  
  792. void
  793. xexit (int code)
  794. {
  795.     cleanup ();
  796.  
  797.     if (code)
  798.         ulog (-1, "Abnormal Termination, code %ld", code);
  799.  
  800.     exit (code);
  801. }
  802.  
  803. void
  804. printc (unsigned char c)
  805. {
  806.     c &= 0x7F;
  807.  
  808.     if (c == '\n')
  809.         printf ("\\n");
  810.     else
  811.     if (c == '\r')
  812.         printf ("\\r");
  813.     else
  814.     if (c < 32)
  815.         printf ("^%c", c | 0x40);
  816.     else
  817.     if (c == 32)
  818.         printf ("_");
  819.     else
  820.     if (c < 128)
  821.         printf ("%c", c);
  822.     else
  823.         printf ("(%02x)", c);
  824.  
  825.     return;
  826. }
  827.  
  828. void
  829. _assert_failed (int line)
  830. {
  831.     static int
  832.         reent = 0;
  833.  
  834.     if (reent == 0) {
  835.         ++reent;
  836.         ulog (-1, "Software Error line %d sysdep.c (uucico)", line);
  837.         xexit (20);
  838.     }
  839. }
  840.  
  841. /*
  842.  *  bug fix for older A2232 serial.device's
  843.  */
  844.  
  845. void
  846. NiceAbortIO (void *ior)
  847. {
  848.     Disable ();
  849.     if (((struct Message *) ior)->mn_Node.ln_Type != NT_REPLYMSG)
  850.         AbortIO ((struct IORequest *) ior);
  851.     Enable ();
  852.  
  853.     return;
  854. }
  855.