home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / tcp / Networking / TCP / Server / telser / src / tstelnet.c next >
C/C++ Source or Header  |  1995-03-06  |  14KB  |  433 lines

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