home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Workbench / Dvices / TELSER1.LHA / src / tstelnet.c next >
Encoding:
C/C++ Source or Header  |  1994-12-28  |  11.2 KB  |  371 lines

  1. /*****************************************************************************\
  2. *                                                                             *
  3. * tstelnet.c -- telnet program for telser.device                              *
  4. *                                                                             *
  5. * Copyright (c) 1994 by Sam Yee.                                              *
  6. * Source freely distributable in unmodified form.                             *
  7. *                                                                             *
  8. * $ Author:       Sam Yee (samy@sfu.ca) $                                     *
  9. * $ Project:      telser $                                                    *
  10. * $ Date Started: October 30, 1994 $                                          *
  11. * $ Version:      1.0 (30.10.94) $                                            *
  12. *                                                                             *
  13. * History:                                                                    *
  14. * YY/MM/DD Who                Modifications                                   *
  15. * --------------------------------------------------------------------------- *
  16. *                                                                             *
  17. \*****************************************************************************/
  18.  
  19. #include <clib/dos_protos.h>
  20. #include <clib/exec_protos.h>
  21. #include <devices/serial.h>
  22. #include <pragmas/dos_pragmas.h>
  23. #include <pragmas/exec_pragmas.h>
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27.  
  28. #define RAWIN_RUNTIME
  29. #include "RawIN.h"
  30.  
  31. /********************************************************************/
  32. /* imports */
  33. extern struct DOSBase *DOSBase;
  34. extern struct SysBase *SysBase;
  35.  
  36. /********************************************************************/
  37. /* prototypes */
  38. ULONG ScanSerial(struct IOExtSer *ser_rreq, struct IOExtSer  *ser_oreq,
  39.                  char *buf, ULONG buf_len);
  40. void SendSerReadRequest(struct IOExtSer *req, char *c);
  41. void SendSerWriteRequest(struct IOExtSer *req, char *buf, ULONG buf_len);
  42. void AbortReq(struct IORequest *req);
  43.  
  44. /********************************************************************/
  45. void __regargs __chkabort(void);    /* disable SAS/C ^C checking */
  46. void __regargs __chkabort(){}
  47. void __regargs _CXBRK(void);
  48. void __regargs _CXBRK(){}
  49.  
  50. const char version[] = "\0$VER: tstelnet 1.00 (28.12.94)";
  51.  
  52. /********************************************************************/
  53. /* where the action starts */
  54. int
  55. main(int  argc,
  56.      char *argv[])
  57. {
  58.     struct Library  *RawINBase = NULL;  /* std i/o handling library */
  59.     struct Line     *line = NULL;       /* line buffer */
  60.     struct IOExtSer *ser_rreq = NULL,   /* serial stuff */
  61.                     *ser_wreq = NULL,
  62.                     *ser_oreq = NULL;
  63.     struct MsgPort  *ser_rport = NULL,
  64.                     *ser_wport = NULL,
  65.                     *ser_oport = NULL;
  66.     char            device[64] = "telser.device",
  67.                     *s,
  68.                     *prog_name,
  69.                     buf[256],       /* these three buffers must be the same size! */
  70.                     ser_wbuf[256],
  71.                     raw_buf[256],
  72.                     *host,
  73.                     ser_char;           /* for serial reads */
  74.     ULONG           wait_mask;
  75.     int             unit = 0,
  76.                     host_arg_num = 1,
  77.                     port = 0,
  78.                     i,
  79.                     read_len,
  80.                     error_code = 0;
  81.     BOOL            show_usage = FALSE,
  82.                     got_stuff,
  83.                     typed,
  84.                     ser_wrote = FALSE,
  85.                     device_specified = FALSE;
  86.  
  87.     prog_name = FilePart(argv[0]);
  88.  
  89.     if (argc == 1)  /* no arguments specified? */
  90.         show_usage = TRUE;
  91.     else if (!strnicmp(argv[host_arg_num],"-d",2))
  92.     {
  93.         device_specified = TRUE;
  94.         s = argv[host_arg_num] + 2;
  95.         i = 0;
  96.  
  97.         while (*s && (i < sizeof(device)-1) && (*s != ','))
  98.             device[i++] = *s++;
  99.  
  100.         device[i] = '\0';
  101.  
  102.         if (*s)
  103.             unit = atol(++s);
  104.  
  105.         host_arg_num++;
  106.     }
  107.  
  108.     /* host not specified */
  109.     if (host_arg_num == argc)
  110.         show_usage = TRUE;
  111.     else
  112.     {
  113.         host = argv[host_arg_num];
  114.  
  115.         if (host_arg_num < (argc-1))
  116.             port = atol(argv[host_arg_num+1]);
  117.     }
  118.  
  119.     if (show_usage)
  120.     {
  121.         Printf("Usage: %s [-ddevice,unit] host-name [port]\n",prog_name);
  122.         error_code = 1;
  123.     }
  124.     else if (!(ser_rport = CreateMsgPort()) ||
  125.              !(ser_wport = CreateMsgPort()) ||
  126.              !(ser_oport = CreateMsgPort()))
  127.     {
  128.         Printf("%s: no memory for message ports\n",prog_name);
  129.         error_code = 10;
  130.     }
  131.     else if (!(ser_rreq = CreateIORequest(ser_rport,sizeof(struct IOExtSer))) ||
  132.              !(ser_wreq = CreateIORequest(ser_wport,sizeof(struct IOExtSer))) ||
  133.              !(ser_oreq = CreateIORequest(ser_oport,sizeof(struct IOExtSer))))
  134.     {
  135.         Printf("%s: no memory for io requests\n",prog_name);
  136.         error_code = 10;
  137.     }
  138.     else
  139.     {
  140.         if (device_specified)
  141.         {
  142.             if (OpenDevice(device,unit,(struct IORequest *)ser_rreq,0L))
  143.                 error_code = 10;
  144.         }
  145.         else
  146.         {
  147.             ser_rreq->io_SerFlags = 0;
  148.  
  149.             for (i = unit; i < (unit+20);i++)
  150.             {
  151.                 if (!OpenDevice(device,i,(struct IORequest *)ser_rreq,0L))
  152.                     break;
  153.             }
  154.  
  155.             if (i == (unit+20))
  156.                 error_code = 10;
  157.  
  158.             unit = i;
  159.         }
  160.  
  161.         if (error_code)
  162.             Printf("%s: cannot open device %s, unit %ld\n",prog_name,device,unit);
  163.     }
  164.  
  165.     if (!error_code)
  166.     {
  167.         if (!(RawINBase = OpenLibrary(RAWIN_NAME,0)))
  168.         {
  169.             Printf("%s: " RAWIN_NAME " not found\n",prog_name);
  170.             error_code = 10;
  171.         }
  172.     }
  173.  
  174.     if (!RawINBase)
  175.     {
  176.         /* do nothing */
  177.     }
  178.     else if (!(line = RI_AllocLine(2,2)))
  179.     {
  180.         Printf("%s: no memory for line buffer\n",prog_name);
  181.         error_code = 10;
  182.     }
  183.     else
  184.     {
  185.         CopyMem(ser_rreq,ser_wreq,sizeof(struct IOExtSer));
  186.         CopyMem(ser_rreq,ser_oreq,sizeof(struct IOExtSer));
  187.  
  188.         ser_wreq->IOSer.io_Message.mn_ReplyPort = ser_rport;
  189.         ser_oreq->IOSer.io_Message.mn_ReplyPort = ser_oport;
  190.  
  191.         ser_oreq->io_Baud = 19200;  /* set the baud rate */
  192.         ser_oreq->io_RBufLen = 4096L;
  193.         ser_oreq->IOSer.io_Command = SDCMD_SETPARAMS;
  194.         DoIO((struct IORequest *)ser_oreq);
  195.         SendSerReadRequest(ser_rreq,&ser_char);
  196.  
  197.         sprintf(ser_wbuf,"ATDT %s",host);
  198.  
  199.         if (port)
  200.             sprintf(ser_wbuf+strlen(ser_wbuf),",%d",port);
  201.  
  202.         strcat(ser_wbuf,"\r");
  203.         SendSerWriteRequest(ser_wreq,ser_wbuf,strlen(ser_wbuf));
  204.         ser_wrote = TRUE;
  205.  
  206.         typed = TRUE;
  207.         RI_SendReadRequest(line);
  208.         wait_mask = SIGBREAKF_CTRL_C |
  209.                     (1L << ser_rport->mp_SigBit) |
  210.                     (1L << ser_wport->mp_SigBit) |
  211.                     (1L << line->ReadReplyPort->mp_SigBit);
  212.  
  213.         while (!(line->flags & (LNF_EOF|LNF_BREAKC|LNF_READERROR|LNF_WRITEERROR)))
  214.         {
  215.             got_stuff = FALSE;
  216.  
  217.             /* get user input */
  218.             if ((read_len = RI_GetBlock(line,FALSE,FALSE,buf,sizeof(buf))) > 0L)
  219.             {
  220.                 got_stuff = TRUE;
  221.                 typed = TRUE;
  222.  
  223.                 if (ser_wrote)  /* already wrote something? if so, wait! */
  224.                     WaitIO((struct IORequest *)ser_wreq);
  225.  
  226.                 memcpy(ser_wbuf,buf,read_len);
  227.                 SendSerWriteRequest(ser_wreq,ser_wbuf,read_len);
  228.                 ser_wrote = TRUE;
  229.                 RI_SendReadRequest(line);
  230.             }
  231.  
  232.             if (GetMsg(ser_wport))  /* a write reply? */
  233.                 ser_wrote = FALSE;
  234.  
  235.             /* read from serial port as much as possible */
  236.             if (read_len = ScanSerial(ser_rreq,ser_oreq,buf,sizeof(buf)))
  237.             {
  238.                 got_stuff = TRUE;
  239.                 RI_WaitWrite(line); /* wait for a write to finish if needed */
  240.                 memcpy(raw_buf,buf,read_len);
  241.                 RI_SendWriteRequest(line,raw_buf,read_len);
  242.             }
  243.  
  244.             /* if user typed key(s), send next read request */
  245.             if (typed)
  246.             {
  247.                 RI_SendReadRequest(line);
  248.                 typed = FALSE;
  249.             }
  250.  
  251.             if (got_stuff)
  252.                 continue;
  253.  
  254.             if (Wait(wait_mask) & SIGBREAKF_CTRL_C)
  255.                 break;
  256.         }
  257.  
  258.         AbortReq((struct IORequest *)ser_rreq);
  259.         CloseDevice((struct IORequest *)ser_rreq);
  260.     }
  261.  
  262.     /* cleanup */
  263.     if (ser_rreq)
  264.         DeleteIORequest((struct IORequest *)ser_rreq);
  265.  
  266.     if (ser_wreq)
  267.         DeleteIORequest((struct IORequest *)ser_wreq);
  268.  
  269.     if (ser_oreq)
  270.         DeleteIORequest((struct IORequest *)ser_oreq);
  271.  
  272.     if (ser_rport)
  273.         DeleteMsgPort(ser_rport);
  274.  
  275.     if (ser_wport)
  276.         DeleteMsgPort(ser_wport);
  277.  
  278.     if (ser_oport)
  279.         DeleteMsgPort(ser_oport);
  280.  
  281.     if (line)
  282.         RI_FreeLine(line);
  283.  
  284.     if (RawINBase)
  285.         CloseLibrary(RawINBase);
  286.  
  287.     return(error_code);
  288. }
  289.  
  290. /****************************************************************************/
  291. /* grab bytes from serial port if any */
  292. ULONG
  293. ScanSerial(struct IOExtSer  *ser_rreq,
  294.            struct IOExtSer  *ser_oreq,
  295.            char             *buf,
  296.            ULONG            buf_len)
  297. {
  298.     char    *s;
  299.     ULONG   bytesRead = 0L,
  300.             bytesInQ = 0L;
  301.  
  302.     if (!buf_len)
  303.         return(0L);
  304.  
  305.     if (CheckIO((struct IORequest *)ser_rreq))
  306.     {
  307.         WaitIO((struct IORequest *)ser_rreq);
  308.         s = (char *)ser_rreq->IOSer.io_Data;
  309.         buf[0] = *s;
  310.         bytesRead = 1L;
  311.         ser_oreq->IOSer.io_Command = SDCMD_QUERY;
  312.  
  313.         if (!DoIO((struct IORequest *)ser_oreq))
  314.         {
  315.             if (bytesInQ = ser_oreq->IOSer.io_Actual)
  316.             {
  317.                 if (bytesInQ >= buf_len)
  318.                     bytesInQ = buf_len - 1L;
  319.  
  320.                 ser_rreq->IOSer.io_Data = buf+1;
  321.                 ser_rreq->IOSer.io_Length = bytesInQ;
  322.                 ser_rreq->IOSer.io_Command = CMD_READ;
  323.                 DoIO((struct IORequest *)ser_rreq);
  324.                 bytesRead += bytesInQ;
  325.             }
  326.         }
  327.  
  328.         SendSerReadRequest(ser_rreq,s);
  329.     }
  330.  
  331.     return(bytesRead);
  332. }
  333.  
  334. /****************************************************************************/
  335. /* send an asynchronous serial read */
  336. void
  337. SendSerReadRequest(struct IOExtSer  *req,
  338.                    char             *c)
  339. {
  340.     req->IOSer.io_Command = CMD_READ;
  341.     req->IOSer.io_Data    = c;
  342.     req->IOSer.io_Length  = 1L;
  343.     SendIO((struct IORequest *)req);
  344. }
  345.  
  346. /****************************************************************************/
  347. /* send an asynchronous serial write */
  348. void
  349. SendSerWriteRequest(struct IOExtSer *req,
  350.                     char            *buf,
  351.                     ULONG           buf_len)
  352. {
  353.     req->IOSer.io_Command = CMD_WRITE;
  354.     req->IOSer.io_Data    = buf;
  355.     req->IOSer.io_Length  = buf_len;
  356.     SendIO((struct IORequest *)req);
  357. }
  358.  
  359. /****************************************************************************/
  360. void
  361. AbortReq(struct IORequest   *req)
  362. {
  363.     if (!CheckIO(req))
  364.         AbortIO(req);
  365.  
  366.     WaitIO(req);
  367. }
  368.  
  369. /****************************************************************************/
  370. /* END */
  371.