home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 341b.lha / uucp1_v1.03d / src / uucico / sysdep.c < prev    next >
C/C++ Source or Header  |  1990-01-28  |  11KB  |  608 lines

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