home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / auucp+-1.02 / fuucp_plus_src.lzh / uucico / sysdep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-21  |  11.8 KB  |  634 lines

  1.  
  2. /*
  3.  *  SYSDEP.C
  4.  *
  5.  *  $Header: Beta:src/uucp/src/uucico/RCS/sysdep.c,v 1.1 90/02/02 11:56:16 dillon Exp Locker: dillon $
  6.  *
  7.  * (C) Copyright 1987 by John Gilmore
  8.  * Copying and use of this program are controlled by the terms of the Free
  9.  * Software Foundation's GNU Emacs General Public License.
  10.  *
  11.  *  Amiga Changes Copyright 1988 by William Loftus. All rights reserved.
  12.  *  Additional chgs Copyright 1989 by Matthew Dillon, All Rights Reserved.
  13.  */
  14.  
  15. #include "includes.h"
  16. #include <hardware/cia.h>
  17. #include <libraries/dos.h>
  18. #include <pwd.h>
  19. #include "uucp.h"
  20. #include "version.h"
  21.  
  22. Prototype int openout(char *, int);
  23. Prototype int sigint(void);
  24. Prototype void cleanup(void);
  25. Prototype int xdatardy(void);
  26. Prototype int xgetc(int);
  27. Prototype int xwrite(const void *, int);
  28. Prototype int xwritea(const void *, int);
  29. Prototype int xxwrite(const void *, int, int);
  30. Prototype void SendBreak(void);
  31. Prototype int CheckCarrier(void);
  32. Prototype void *bzero(void *, long);
  33. Prototype void *bcopy(const void *, void *, long);
  34. Prototype void munge_filename(char *, char *);
  35. Prototype int hangup(void);
  36. Prototype char *work_scan(char *);
  37. Prototype char *work_next(void);
  38. Prototype void amiga_closeopen(char *);
  39. Prototype void amiga_setup(void);
  40. Prototype void set_baud(int);
  41. Prototype void OpenSerial(void);
  42. Prototype void CloseSerial(void);
  43. Prototype void xexit(int);
  44. Prototype void printc(unsigned char);
  45.  
  46. /*
  47.  *  Split out of uuslave.c by John Gilmore, 8 August 1987.
  48.  *  ported to the Amiga by William Loftus, 20 September 1987.
  49.  *  rewritten by Matthew Dillon, October 1989
  50.  */
  51.  
  52. /* FIXME -- System dependent defines (not really -- should be in a .h) */
  53. /*
  54.  * Timeout for raw characters -- if we don't hear a char within BYTE_TIMEOUT
  55.  * seconds, we assume the other side has gone away.  Has nothing to do with
  56.  * retransmission timeouts (if any!).
  57.  */
  58.  
  59. extern int debug;
  60. extern int SevenWire;
  61.  
  62. #define FAILURE  1
  63.  
  64. struct IOExtSer Iosr;
  65. struct IOExtSer Iosw;
  66. struct IOExtSer Ioss;
  67. struct timerequest Iot0;
  68. char   *OldTaskName;
  69.  
  70. char    *DeviceName = "serial.device";
  71. long    DeviceUnit = 0;
  72.  
  73. unsigned char    XInBuf[256];       /*  for xgetc() */
  74. short    XInIdx = 0;
  75. short    XInLen = 0;
  76. short    IoswIP = 0;
  77.  
  78. short    InExitRoutine = 0;
  79. short    debugRead = 0;
  80.  
  81. extern char path[];
  82. extern int Getty;
  83. extern int IgnoreCD;
  84.  
  85. int
  86. openout(acu, baud)
  87. char *acu;
  88. int  baud;
  89. {
  90.     set_baud(baud);
  91.  
  92.     return SUCCESS;
  93. }
  94.  
  95. /*
  96.  * Basement level I/O routines
  97.  *
  98.  * xwrite() writes a character string to the serial port
  99.  * xgetc() returns a character from the serial port, or an EOF for timeout.
  100.  * sigint() restores the state of the serial port on exit.
  101.  */
  102.  
  103. int
  104. sigint()
  105. {
  106.     xexit(1);
  107.     return(0);
  108. }
  109.  
  110.  
  111. void
  112. cleanup()
  113. {
  114.     xexit(0);
  115. }
  116.  
  117. int
  118. xdatardy()
  119. {
  120.     if (XInIdx != XInLen)
  121.     return(1);
  122.     CheckCarrier();
  123.     return (Ioss.IOSer.io_Actual > 0);
  124. }
  125.  
  126. int
  127. xgetc(byteto)
  128. int byteto;
  129. {
  130.     int ch, n;
  131.     long smask;
  132.     long tmask;
  133.     short bytetimeout;
  134.  
  135. top:
  136.     if (XInIdx != XInLen) {
  137.     if (debug > 8) {
  138.         if (debugRead == 0)
  139.         printf("\nREAD: ");
  140.         debugRead = 1;
  141.         printc(XInBuf[XInIdx]);
  142.     }
  143.     return((int)XInBuf[XInIdx++]);
  144.     }
  145.     XInIdx = 0;
  146.     XInLen = 0;
  147.  
  148.     if (!CheckCarrier())                        /*  carrier lost?     */
  149.     return(EOF);
  150.  
  151.     if ((n = Ioss.IOSer.io_Actual) > 0) {       /*  at least one..    */
  152.     Iosr.IOSer.io_Command = CMD_READ;
  153.     Iosr.IOSer.io_Data = (APTR)XInBuf;
  154.     if (n > sizeof(XInBuf))
  155.         n = sizeof(XInBuf);
  156.     Iosr.IOSer.io_Length = n;
  157.     DoIO(&Iosr);
  158.     if (Iosr.IOSer.io_Actual > 0) {
  159.         if (debug > 8)
  160.         printf("(r%d/%d)", n, Iosr.IOSer.io_Actual);
  161.         XInIdx = 0;
  162.         XInLen = Iosr.IOSer.io_Actual;
  163.         goto top;
  164.     }
  165.     }
  166.  
  167.     /*
  168.      *    no bytes ready, byteto is 0 (no wait)
  169.      */
  170.  
  171.     if (byteto == 0)
  172.     return(EOF);
  173.  
  174.     /*
  175.      *    no bytes ready, wait for one.
  176.      *
  177.      *    once every 3 seconds check carrier detect.
  178.      */
  179.  
  180.     bytetimeout = byteto;
  181.     Iot0.tr_time.tv_secs = 3;
  182.     Iot0.tr_time.tv_micro= 0;
  183.     SendIO(&Iot0);
  184.  
  185.     Iosr.IOSer.io_Command = CMD_READ;
  186.     Iosr.IOSer.io_Data = (APTR)XInBuf;
  187.     Iosr.IOSer.io_Length = 1;
  188.     Iosr.IOSer.io_Actual = 0;    /*  trying to find a bug... */
  189.     SendIO(&Iosr);
  190.  
  191.     smask = 1L << Iosr.IOSer.io_Message.mn_ReplyPort->mp_SigBit;
  192.     tmask = 1L << Iot0.tr_node.io_Message.mn_ReplyPort->mp_SigBit;
  193.  
  194.     for (;;) {
  195.     long mask = Wait(tmask | smask | SIGBREAKF_CTRL_C);
  196.  
  197.     if (mask & SIGBREAKF_CTRL_C) {
  198.         AbortIO(&Iosr);
  199.         WaitIO(&Iosr);
  200.         AbortIO(&Iot0);
  201.         WaitIO(&Iot0);
  202.         xexit(1);
  203.     }
  204.     if (CheckIO(&Iosr)) {
  205.         WaitIO(&Iosr);
  206.         AbortIO(&Iot0);
  207.         WaitIO(&Iot0);
  208.  
  209.         ch = (int)XInBuf[0];
  210.  
  211.         if (debug > 8) {
  212.         if (debugRead == 0)
  213.             printf("\nREAD ");
  214.         debugRead = 1;
  215.         printf("(waitc%d)", Iosr.IOSer.io_Actual);
  216.         printc((unsigned char)ch);
  217.         }
  218.         return(ch);
  219.     }
  220.     if (CheckIO(&Iot0)) {
  221.         WaitIO(&Iot0);
  222.  
  223.         Iot0.tr_time.tv_secs = 3;
  224.         Iot0.tr_time.tv_micro= 0;
  225.  
  226.         bytetimeout -= Iot0.tr_time.tv_secs;
  227.         if (bytetimeout > 0) {
  228.         if (CheckCarrier() == 0) {
  229.             AbortIO(&Iosr);
  230.             WaitIO(&Iosr);
  231.             break;
  232.         }
  233.         SendIO(&Iot0);
  234.         } else {
  235.         AbortIO(&Iosr);
  236.         WaitIO(&Iosr);
  237.         if (Iosr.IOSer.io_Actual == 1)
  238.             return((int)XInBuf[0]);
  239.         break;
  240.         }
  241.     }
  242.     }
  243.     if (debug > 8)
  244.     printf("\nRecv-EOF\n");
  245.     return(EOF);
  246. }
  247.  
  248. int
  249. xwrite(buf, ctr)
  250. const void *buf;
  251. int ctr;
  252. {
  253.     return(xxwrite(buf, ctr, 0));
  254. }
  255.  
  256. int
  257. xwritea(buf, ctr)
  258. const void *buf;
  259. int ctr;
  260. {
  261.     xxwrite(buf, ctr, 1);
  262.     return(ctr);
  263. }
  264.  
  265. int
  266. xxwrite(buf, ctr, async)
  267. const void *buf;
  268. int ctr;
  269. int async;
  270. {
  271.     if (debug > 8) {
  272.     short i;
  273.     if (debugRead)
  274.         printf("\nWRITE ");
  275.     debugRead = 0;
  276.     for (i = 0; i < ctr; ++i) {
  277.         printc(((unsigned char *)buf)[i]);
  278.     }
  279.     printf("\n");
  280.     }
  281.     if (IoswIP) {
  282.     WaitIO(&Iosw);
  283.     IoswIP = 0;
  284.     }
  285.  
  286.     Iosw.IOSer.io_Command = CMD_WRITE;
  287.     Iosw.IOSer.io_Length = ctr;
  288.     Iosw.IOSer.io_Data = (APTR)buf;
  289.     if (async) {
  290.     SendIO(&Iosw);
  291.     IoswIP = 1;
  292.     } else {
  293.     DoIO(&Iosw);
  294.     }
  295.     return ctr;
  296. }
  297.  
  298. void
  299. SendBreak()
  300. {
  301.     Ioss.IOSer.io_Command = SDCMD_BREAK;
  302.     DoIO(&Ioss);
  303. }
  304.  
  305. int
  306. CheckCarrier()
  307. {
  308.     Ioss.IOSer.io_Command = SDCMD_QUERY;
  309.     DoIO(&Ioss);
  310.     if (IgnoreCD)
  311.     return(1);
  312.     if (Ioss.io_Status & CIAF_COMCD)    /*  non-zero == no carrier */
  313.     return(0);
  314.     return(1);
  315. }
  316.  
  317. void *
  318. bzero(s, cnt)
  319. void   *s;
  320. long   cnt;
  321. {
  322.     setmem(s, cnt, 0);
  323.     return(s);
  324. }
  325.  
  326. void *
  327. bcopy(from, to, cnt)
  328. const void   *from;
  329. void   *to;
  330. long   cnt;
  331. {
  332.     movmem(from, to, cnt);
  333.     return(to);
  334. }
  335.  
  336. /*
  337.  * Transform a filename from a uucp packet (in Unix format) into a local
  338.  * filename that will work in the local file system.
  339.  */
  340.  
  341. void
  342. munge_filename(s, d)
  343. char *s, *d;
  344. {
  345.     if (*s != '~') {
  346.     if (s != d)
  347.         strcpy(d, s);
  348.     return;
  349.     }
  350.  
  351.     /*
  352.      *    ~/ ...    convert to UUPUB:
  353.      *    ~user/...   convert to <homedir>/...
  354.      */
  355.  
  356.     {
  357.     short i;
  358.     short c;
  359.     char *t;
  360.     struct passwd *pw;
  361.  
  362.     for (i = 1; s[i] && s[i] != '/'; ++i);
  363.     c = s[i];
  364.  
  365.     s[i] = 0;
  366.     if (i == 1)
  367.         pw = NULL;
  368.     else
  369.         pw = getpwnam(s + 1);
  370.     s[i] = c;
  371.  
  372.     if (c == '/')
  373.         ++i;
  374.  
  375.     if (pw) {
  376.         t = malloc(strlen(pw->pw_dir) + strlen(s + i) + 1);
  377.         strcpy(t, pw->pw_dir);
  378.     } else {
  379.         t = malloc(strlen(s + i) + 32);
  380.         strcpy(t, GetConfigDir(UUPUB));
  381.     }
  382.     strcat(t, s + i);
  383.     strcpy(d, t);
  384.     free(t);
  385.     }
  386. }
  387.  
  388. int
  389. hangup()
  390. {
  391.     static char buf[128];
  392.  
  393.     reset_modem();
  394.  
  395.     sprintf(buf, "run >nil: <nil: %s", GetConfigProgram(UUXQT));
  396.  
  397.     if (Execute(buf, NULL, NULL) == 0)
  398.     puts("Unable to run UUXQT");
  399.     return SUCCESS;
  400. }
  401.  
  402. static char names[MAXFILES*16];
  403. static char *pointers[MAXFILES];
  404. static int file_pointer;
  405.  
  406. char *
  407. work_scan(system_name)
  408. char *system_name;
  409. {
  410.     static char name[128];
  411.     int count;
  412.  
  413.     file_pointer = 0;
  414.  
  415. /* -IF-
  416.     if (strlen(system_name) > 7) {
  417.     system_name[7] = '\0';
  418.     }
  419. */
  420.  
  421.     sprintf(name, "%sC.%.6s#?", MakeConfigPath(UUSPOOL, ""), system_name);
  422.  
  423.     if (debug > 2)
  424.     printf("Looking for %s\n",name);
  425.  
  426.     count = getfnl(name,names,sizeof(names),0);
  427.  
  428.     if (count > 0)
  429.     {
  430.     if (strbpl(pointers,MAXFILES,names) != count)
  431.         {
  432.         printf("Too many command files for %s.\n",system_name);
  433.         return (char *)NULL;
  434.     }
  435.         else
  436.         {
  437.             tqsort(pointers, count); /* Let's sort the X.* files -IF- */
  438.         }
  439.     }
  440.     else
  441.     {
  442.     return (char *)NULL;
  443.     }
  444.     if (debug > 2)
  445.     printf("Found -> %s\n", pointers[file_pointer]);
  446.     return (char *)1;
  447. }
  448.  
  449. char *
  450. work_next()
  451. {
  452.     if (debug > 2)
  453.     printf("Found -> %s\n", pointers[file_pointer]);
  454.     return pointers[file_pointer++];
  455. }
  456.  
  457. /*
  458.  *  Closing and openning the serial device drops DTR
  459.  */
  460.  
  461. void
  462. amiga_closeopen(str)
  463. char *str;
  464. {
  465.     CloseSerial();
  466.     Delay(60);
  467.     OpenSerial();
  468. }
  469.  
  470. void
  471. amiga_setup()
  472. {
  473.     mountrequest(0);        /*  disallow requesters */
  474.  
  475.     OpenSerial();
  476.  
  477.     if (OpenDevice(TIMERNAME, UNIT_VBLANK, &Iot0, 0))  {
  478.     Iot0.tr_node.io_Device = NULL;
  479.     printf("Can't open timer device.");
  480.     xexit(1);
  481.     }
  482.  
  483.     Iot0.tr_node.io_Message.mn_ReplyPort = (struct MsgPort *)CreatePort("UUCICO-Timer", 0L);
  484.     Iot0.tr_node.io_Command = TR_ADDREQUEST;
  485.     Iot0.tr_node.io_Error = 0;
  486.  
  487.     {
  488.     struct Task *task = (struct Task *)FindTask(NULL);
  489.     OldTaskName = task->tc_Node.ln_Name;
  490.     task->tc_Node.ln_Name = "uucico";
  491.     }
  492. }
  493.  
  494. void
  495. set_baud(baud)
  496. int baud;
  497. {
  498.     Iosr.IOSer.io_Command = SDCMD_SETPARAMS;
  499.     Iosr.io_SerFlags =    SERF_SHARED | SERF_XDISABLED;
  500.     Iosr.io_Baud = baud;
  501.     Iosr.io_ReadLen = 8L;
  502.     Iosr.io_WriteLen = 8L;
  503.     Iosr.io_CtlChar = 0x11130000L;
  504.     Iosr.io_RBufLen = 4096;
  505.  
  506.     if (SevenWire)
  507.     Iosr.io_SerFlags |= SERF_7WIRE;
  508.  
  509.     DoIO(&Iosr);
  510. }
  511.  
  512. void
  513. OpenSerial()
  514. {
  515.     Iosr.io_SerFlags = SERF_SHARED | SERF_XDISABLED;
  516.     Iosr.IOSer.io_Message.mn_ReplyPort = (struct MsgPort *)CreatePort("Read_RS",0);
  517.  
  518.     if (SevenWire)
  519.     Iosr.io_SerFlags |= SERF_7WIRE;
  520.  
  521.     if (OpenDevice(DeviceName, DeviceUnit, &Iosr, NULL)) {
  522.     Iosr.IOSer.io_Device = NULL;
  523.     printf("Can not open serial port for read.\n");
  524.     xexit(TRUE);
  525.     }
  526.  
  527.     /*
  528.      *    Assume a Getty is running, if the opencount is > 2 then
  529.      *    assume collision and disallow
  530.      */
  531.  
  532.     if (Iosr.IOSer.io_Device->dd_Library.lib_OpenCnt > 2) {
  533.     CloseDevice(&Iosr);
  534.     Iosr.IOSer.io_Device = NULL;
  535.     printf("Collision, serial port in use!\n");
  536.     xexit(TRUE);
  537.     }
  538.  
  539.     /*
  540.      *    The public port 'Lock-<spname>-<unit>' is used to lock the
  541.      *    serial port (Getty will lock it this way while it is
  542.      *    receiving an incomming call so if we are Getty assume it
  543.      *    is already locked)
  544.      */
  545.  
  546.     if (Getty == 0)
  547.     LockSerialPort(DeviceName, DeviceUnit);
  548.  
  549.     Iosw = Iosr;
  550.     Iosw.IOSer.io_Message.mn_ReplyPort = (struct MsgPort *)CreatePort("Write_RS", 0);
  551.     Ioss = Iosw;
  552.  
  553.     Iosr.IOSer.io_Command = SDCMD_QUERY;
  554.     DoIO(&Iosr);
  555.  
  556.     set_baud(Iosr.io_Baud);
  557. }
  558.  
  559. void
  560. CloseSerial()
  561. {
  562.     if (IoswIP) {
  563.     WaitIO(&Iosw);
  564.     IoswIP = 0;
  565.     }
  566.     if (Iosr.IOSer.io_Device) {
  567.     CloseDevice(&Iosr);
  568.     Iosr.IOSer.io_Device = NULL;
  569.     if (Getty == 0)
  570.         UnLockSerialPort(DeviceName, DeviceUnit);
  571.     }
  572.     if (Iosr.IOSer.io_Message.mn_ReplyPort) {
  573.     DeletePort(Iosr.IOSer.io_Message.mn_ReplyPort);
  574.     Iosr.IOSer.io_Message.mn_ReplyPort = NULL;
  575.     }
  576.     if (Iosw.IOSer.io_Message.mn_ReplyPort) {
  577.     DeletePort(Iosw.IOSer.io_Message.mn_ReplyPort);
  578.     Iosw.IOSer.io_Message.mn_ReplyPort = NULL;
  579.     }
  580. }
  581.  
  582. void
  583. xexit(code)
  584. int code;
  585. {
  586.     ++InExitRoutine;
  587.  
  588.     if (InExitRoutine == 1 && code && Iosr.IOSer.io_Device && CheckCarrier())
  589.     reset_modem();
  590.  
  591.     CloseSerial();
  592.  
  593.     {
  594.     struct Task *task = (struct Task *)FindTask(NULL);
  595.     if (OldTaskName)
  596.         task->tc_Node.ln_Name = OldTaskName;
  597.     }
  598.  
  599.     if (Iot0.tr_node.io_Device) {
  600.     CloseDevice(&Iot0);
  601.     Iot0.tr_node.io_Device = NULL;
  602.     }
  603.     if (Iot0.tr_node.io_Message.mn_ReplyPort) {
  604.     DeletePort(Iot0.tr_node.io_Message.mn_ReplyPort);
  605.     Iot0.tr_node.io_Message.mn_ReplyPort = NULL;
  606.     }
  607.     chdir(path);
  608.     if (code)
  609.     printf("\nAbnormal Termination.\n");
  610.  
  611.     mountrequest(1);
  612.  
  613.     UnLockFiles();      /*  unlock any hanging locks */
  614.  
  615.     exit(code);
  616. }
  617.  
  618. void
  619. printc(c)
  620. unsigned char c;
  621. {
  622.     c &= 0x7F;
  623.  
  624.     if (c < 32)
  625.     printf("^%c", c | 0x40);
  626.     else if (c == 32)
  627.     printf("_");
  628.     else if (c < 128)
  629.     printf("%c", c);
  630.     else
  631.     printf("(%02x)", c);
  632. }
  633.  
  634.