home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Rice_CMS / gopher24 / gopclisx.rexx < prev    next >
Encoding:
OS/2 REXX Batch file  |  1993-01-24  |  8.1 KB  |  291 lines

  1. /*
  2.  *        Name: GOPCLISX REXX
  3.  *              CMS Gopher client TCP/IP (sockets; "sox") function
  4.  *      Author: Rick Troth, Rice University, Information Systems
  5.  *        Date: 1992-Dec-23
  6.  *
  7.  *       Input: one or more gopher menu lines
  8.  *    Output 0: zero or more blocks of raw (may be ASCII) data
  9.  *    Output 1: status messages and/or error messages
  10.  *
  11.  *        Note: input is "plain text" (EBCDIC),  while output
  12.  *              may be anything.   If output is "plain text" (ASCII),
  13.  *              the following stage must handle translation.
  14.  */
  15.  
  16. /*
  17.  *      Copyright 1992 Richard M. Troth.   This software was developed
  18.  *      with resources provided by Rice University and is intended
  19.  *      to serve Rice's user community.   Rice has benefitted greatly
  20.  *      from the free distribution of software,  therefore distribution
  21.  *      of unmodified copies of this material is not restricted.
  22.  *      You may change your own copy as needed.   Neither Rice
  23.  *      University nor any of its employees or students shall be held
  24.  *      liable for damages resulting from the use of this software.
  25.  */
  26.  
  27. Trace "OFF"
  28.  
  29. /*  sync with input so that 'CALLPIPE COMMAND' will work  */
  30. 'PEEKTO'
  31.  
  32. 'CALLPIPE COMMAND GLOBALV SELECT GOPHER GET GOPHER'
  33. If gopher = "" Then gopher = "Gopher"
  34. quit = 0
  35.  
  36. Parse Arg . '(' opts ')' .
  37.  
  38. trans = 0
  39. Do While opts ^= ""
  40.     Parse Var opts op opts
  41.     Upper op
  42.     Select  /*  op  */
  43.         When Abbrev("TRANSLATE",op,4) Then trans = 1
  44.         When Abbrev("NOTRANSLATE",op,6) Then trans = 0
  45.         Otherwise Address "COMMAND" 'XMITMSG 3 OP (ERRMSG'
  46.         End  /*  Select  op  */
  47.     End  /*  Do  While  */
  48.  
  49. If trans Then crlf = '0D25'x
  50.          Else crlf = '0D0A'x
  51.  
  52. /*
  53.  *   Initialize RXSOCKET
  54.  */
  55. maxdesc = Socket('Initialize', gopher)
  56. If maxdesc = "-1" Then Do
  57.     If errno ^= "ESUBTASKALREADYACTIVE" Then Do
  58.     /*  Call STATUS tcperror()  */
  59.         Exit -1
  60.         End  /*  If  ..  Do  */
  61.     rc = Socket('Terminate')
  62.     maxdesc = Socket('Initialize', gopher)
  63.     If maxdesc = "-1" Then Do
  64.         Call STATUS tcperror()
  65.         Exit -1
  66.         End  /*  If  ..  Do  */
  67.     End  /*  If  ..  Do  */
  68.  
  69. /*  L O O P  */
  70.  
  71. Do Forever
  72.  
  73.     'PEEKTO ITEM'
  74.     If rc ^= 0 Then Leave
  75.  
  76.     Parse Var item 1 type 2 name '05'x path '05'x host ,
  77.                                  '05'x port '05'x xtra
  78.     port = Strip(port)              /*  for robustness  */
  79.     If type = '7' Then path = path || '05'x || xtra
  80.  
  81.     /*  Call STATUS "Connecting ... press ENTER twice to abort"  */
  82.     /*  Call STATUS "Connecting to" host "port" port  */
  83.     Call STATUS 22 '"' || host || '"' '"' || port || '"'
  84.  
  85.     /*
  86.      *   Request a new socket descriptor (TCP protocol)
  87.      */
  88.     socket = Socket('Socket', 'AF_INET', 'Sock_Stream')
  89.     If socket = "-1" Then Do
  90.         Call STATUS tcperror()
  91.         Exit -1
  92.         End  /*  If  ..  Do  */
  93.  
  94.     If trans Then Do
  95.         /*
  96.          *   Enable ASCII<->EBCDIC Translation Option
  97.          */
  98.         rc = Socket('SetSockOpt', socket, 'SOL_SOCKET', 'SO_EBCDIC', 1)
  99.         If rc = "-1" Then Do
  100.             Call STATUS tcperror()
  101.             Exit -1
  102.             End  /*  If  ..  Do  */
  103.         End  /*  If  ..  Do  */
  104.  
  105.     /*
  106.      *   Connect to the server
  107.      */
  108.     Parse Var host h1 '.' h2 '.' h3 '.' h4 '.' .
  109.     If  Datatype(h1,'N') &,
  110.         Datatype(h2,'N') &,
  111.         Datatype(h3,'N') &,
  112.         Datatype(h4,'N')    Then
  113.         hisaddr = d2c(h1) || d2c(h2) || d2c(h3) || d2c(h4)
  114.     Else Do
  115.         hisaddr = Socket('GetHostByName', host)
  116.         If hisaddr = "-1" Then Do
  117.         Call STATUS tcperror()
  118.             Exit -1
  119.             End  /*  If  ..  Do  */
  120.         End  /*  Else  Do  */
  121.  
  122.     /*  Parse Var hisaddr h1 +1 h2 +1 h3 +1 h4 +1 .  */
  123.  
  124.     name = AF_INET || Htons(port) || hisaddr
  125.  
  126.     /*
  127.      *   Set this socket to non-blocking mode
  128.      */
  129.     rc = Socket('Ioctl', socket, 'FIONBIO', 1)
  130.     If rc="-1" Then Do
  131.         Call STATUS tcperror()
  132.         Exit -1
  133.         End  /*  If  ..  Do  */
  134.  
  135.     /*
  136.      *   Connect to the host
  137.      */
  138.     rc = Socket('Connect', socket, name)
  139.     If rc = "-1" Then ,
  140.         If errno ^= "EINPROGRESS" Then Do
  141.             Call STATUS tcperror()
  142.             If errno = "ECONNREFUSED" Then ,
  143.                 Call STATUS 23 '"' || host || '"' '"' || port || '"'
  144.         Exit -1
  145.         End  /*  If  ..  Do  */
  146.  
  147.     rc = FD_ZERO('readmask')
  148.     rc = FD_ZERO('writemask')
  149.     rc = FD_SET(socket,'writemask')
  150.     rc = FD_SET('0', 'readmask')
  151.  
  152.     rc = Socket('Select', socket+1, 'readmask', 'writemask', 0, 20)
  153.     If rc="-1" Then Do
  154.         Call STATUS tcperror()
  155.         Exit -1
  156.         End  /*  If  ..  Do  */
  157.  
  158.     If FD_ISSET('0', 'readmask')<>0 Then Do
  159.         rc = Socket('Close', socket)
  160.         /*  Call STATUS "Connection canceled by user request"  */
  161.         Call STATUS 28
  162.         Exit -1
  163.         End
  164.  
  165.     If FD_ISSET(socket, 'writemask')=0 Then Do
  166.         rc = Socket('Close', socket)
  167.         /*  Call STATUS "Connection canceled by TIMEOUT"  */
  168.         Call STATUS 29
  169.         Exit -1
  170.         end
  171.  
  172.     /* Return to standard mode
  173.     rc = Socket('Ioctl', socket, 'FIONBIO', 0)
  174.      */
  175.  
  176.     /*  TRANSlate option will affect both writing to,  as well as     *
  177.      *  reading from,  the socket.   So if the socket is set for      *
  178.      *  TRANSLATE,  then we need not translate the path from EBCDIC   *
  179.      *  to ASCII.   But if not,  then we must do so as follows:       */
  180.     If ^trans Then
  181.     'CALLPIPE VAR PATH | TCPE2A' gopher '| VAR PATH'
  182.  
  183.     /*
  184.      *   Send the "query" to the server
  185.      */
  186.     bytes_out = Socket('Write', socket, path || crlf)
  187.     If bytes_out = "-1" Then Do
  188.         If errno = 'EPIPE' Then ,
  189.             'OUTPUT' "ECONNREFUSED"
  190.         If errno = 'EPIPE' Then ,
  191.             Call STATUS 23 '"' || host || '"' '"' || port || '"'
  192.         Else Call STATUS tcperror()
  193.         Exit -1
  194.         End  /*  If  ..  Do  */
  195.  
  196.     /*  Call STATUS "Reading ... press ENTER twice to abort"  */
  197.     /*  Call STATUS "Reading ... "  */
  198.     /*  Call STATUS 24  */
  199.  
  200.     totbytes = 0
  201. prevtot = 0
  202.     /*
  203.      *   Loop, reading response and sending to the next pipeline stage
  204.      */
  205.     Do Forever
  206.         /* Set up to trap console ENTER key */
  207.         rc = FD_ZERO('readmask')
  208.         rc = FD_SET('0','readmask')
  209.         rc = FD_SET(socket,'readmask')
  210.  
  211.         /* Wait for something to happen */
  212.         rc = Socket('Select',socket+1,'readmask',0,0)
  213.         /* If console input, clear 'socket' and return */
  214.         If FD_ISSET('0','readmask')<>0 Then Do
  215.             /*  Call STATUS "Request ABORTED"  */
  216.             Call STATUS 27
  217.             rc = Socket('Close', socket)
  218.             Leave
  219.             End
  220.  
  221.         bytes_in = Socket('Read', socket, 'pack')
  222.         If bytes_in = "-1" Then
  223.             Call STATUS tcperror()
  224.         If bytes_in < 1 Then Leave
  225.  
  226.         totbytes = totbytes + bytes_in
  227. If prevtot/totbytes < 0.9 Then  /* adjust the 0.9 factor to taste */
  228. Do
  229.         Call STATUS 26 '"' || totbytes || '"'
  230. prevtot = totbytes
  231. End
  232.         'OUTPUT' pack
  233.         If rc ^= 0 Then Leave
  234.  
  235.         End  /*  Do  Forever  */
  236.  
  237.     If rc ^= 0 Then Leave
  238.  
  239.     /*
  240.      *   All done, relinquish our socket descriptor
  241.      */
  242.     rc = Socket('Close', socket)
  243.     If rc = "-1" Then Do
  244.         Call STATUS tcperror()
  245.         Leave
  246.         End  /*  If  ..  Do  */
  247.  
  248.     'READTO'
  249.  
  250.     End  /*  Do  Forever  */
  251.  
  252. /*
  253.  *   Tell RXSOCKET that we are done with this IUCV path
  254.  */
  255. rc = Socket('Terminate')
  256. If rc = "-1" Then Do
  257.     Call STATUS tcperror()
  258.     Exit -1
  259.     End
  260.  
  261. /*  an empty line as last in status stream indicates success  */
  262. /*  Call STATUS " "  */
  263.  
  264. Exit
  265.  
  266.  
  267.  
  268. /* -------------------------------------------------------------- STATUS
  269.  * Write  "status messages"  to the secondary stream,  if connected.
  270.  * This routine saves & restores the current stream selection.
  271.  * (though there are presently no other streams used besides 1 and 0)
  272.  */
  273. STATUS:   Procedure
  274. Parse Arg string
  275.  
  276. /* note the current stream (should be zero) */
  277. 'STREAMNO OUTPUT'
  278. If rc < 0 Then Return
  279. stream = rc
  280.  
  281. /* select secondary stream and output the string */
  282. 'SELECT OUTPUT 1'
  283. If rc ^= 0 Then Return
  284. If Datatype(Word(string,1),'N') Then
  285. 'CALLPIPE COMMAND XMITMSG' string '(APPLID GOP CALLER TCP ERRMSG | *:'
  286. Else 'OUTPUT' string
  287. 'SELECT OUTPUT' stream
  288.  
  289. Return
  290.  
  291.