home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / httpget.zip / httpget.cmd next >
OS/2 REXX Batch file  |  1998-02-18  |  9KB  |  299 lines

  1. /* Fetch documents via HTTP */
  2. call RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
  3. call SysLoadFuncs
  4. call RxFuncAdd 'SockLoadFuncs','RxSock','SockLoadFuncs'
  5. call SockLoadFuncs 'q'
  6.  
  7. parse arg parm
  8. if parm~strip~left(1)='@' then do
  9.     parse var parm '@' urllist ' ' .
  10.     ulist=.stream~new(urllist)
  11.     if ulist~query('exists')='' then do
  12.         say ''
  13.         say 'URL list file not found!'
  14.         exit
  15.     end
  16.     else host='fromfile'
  17. end
  18. else if parm~translate~left(7)='HTTP://' then host='fromparm'
  19. else do
  20.     call usage
  21.     exit
  22. end
  23. urls=.queue~new
  24.  
  25. if host='fromfile' then do while ulist~lines>0
  26.     urls~queue(ulist~linein)
  27. end
  28. else urls~queue(parm)
  29. urls=urls~makearray
  30.     
  31. currdrive=directory()~left(2)
  32. fatcheck=SysFileSystemType(currdrive)
  33.  
  34. crlf='0d0a'x
  35. headend=crlf||crlf
  36. blocksize=10240
  37. call SysCurState 'off'
  38. con=.stream~new('stdout')
  39.  
  40. do i=1 to urls~items
  41.     newname=0
  42.     parse value urls[i] with '://' host '/' path ';' lfile
  43.     host=host~strip
  44.     if host='' then
  45.         if urls~items>1 then iterate
  46.         else do
  47.             call usage
  48.             exit
  49.         end
  50.     parse var host host ':' port
  51.     if port~strip='' then port=80
  52.     rpath=path~reverse
  53.     parse var rpath file '/' .
  54.     file=file~reverse~strip
  55.     if file~pos(' ')>0 then
  56.         if urls~items>1 then iterate
  57.         else do
  58.             call usage
  59.             exit
  60.         end
  61.     lfile=lfile~strip
  62.     rfile=file~reverse
  63.     parse var rpath (rfile) '/' dirpath
  64.     dirpath=dirpath~reverse
  65.     if file='' then 
  66.         if urls~items>1 then iterate
  67.         else do
  68.             call usage
  69.             exit
  70.         end
  71.     if lfile='' then lfile=file
  72.     if fatcheck='FAT' then do
  73.         parse var lfile basename '.' ext
  74.         parse value lfile~reverse with ext2 '.' basename2
  75.         select 
  76.             when ext\=ext2~reverse then newname=1
  77.             when basename\=basename2~reverse then newname=1
  78.             when basename~length>8 then newname=1
  79.             when ext~length>3 then newname=1
  80.             when basename~pos(' ')>0 then newname=1
  81.             when ext~pos(' ')>0 then newname=1
  82.             otherwise newname=0
  83.         end
  84.         if newname=1 then do
  85.             if ext~length<=3 then shext='.'||ext
  86.             else shext='.HTF'
  87.         end
  88.         done=0
  89.         longea=0
  90.         if newname=1 then do until done=1
  91.             p1=right(d2x(random(65535)),4,'0')
  92.             p2=right(d2x(random(65535)),4,'0')
  93.             outfile=.stream~new(p1||p2||shext)
  94.             if outfile~query('exists')='' then do
  95.                 done=1
  96.                 longea=1
  97.                 longval='FDFF'x||d2c(lfile~length)||'00'x||lfile
  98.                 lfile=filespec('name',outfile~qualify)
  99.             end
  100.         end
  101.         else outfile=.stream~new(lfile)
  102.     end
  103.     else outfile=.stream~new(lfile)
  104.     call SysFileDelete outfile~qualify
  105.  
  106.     servport=host||':'||port
  107.  
  108.     sendstring='GET /'||dirpath'/'file||' HTTP/1.0'||crlf||crlf
  109.  
  110.     csock=.socket~new
  111.  
  112.     say ''
  113.  
  114.     say 'Connecting to host '||host||' on port '||port||'...'
  115.     check=csock~connect(servport)
  116.     if check=-1 then do
  117.         say 'Connection to host '||host||' on port '||port||' failed!'
  118.         csock~shutdown
  119.         csock~close
  120.         exit
  121.     end
  122.     say ''
  123.  
  124.     say 'Requesting file '||file||'...'
  125.     check=csock~send(sendstring)
  126.     if check=-1 then do
  127.         say 'Failed to send file request!'
  128.         csock~shutdown
  129.         csock~close
  130.         exit
  131.     end
  132.     say ''
  133.  
  134.     say 'Receiving file '||file||'...'
  135.     say 'Stored locally as '||lfile||'...'
  136.     say ''
  137.     parse value SysCurPos() with row col
  138.     headgone=0
  139.     total=0
  140.     calc=0
  141.     next=0
  142.     freq=10240
  143.     freq2=1024
  144.     call time 'r'
  145.     do until rvar<=0
  146.         check=csock~receive(blocksize)
  147.         call SysCurPos row,0
  148.         con~charout('Bytes received: ')
  149.         call SysCurPos row,32
  150.         con~charout('Bytes/second: ')
  151.         rvar=check[2]
  152.         data=check[1]
  153.         if headgone=0 then do
  154.             if data~pos(headend)>0 then do
  155.                 headgone=1
  156.                 parse var data . (headend) data
  157.                 outfile~charout(data)
  158.                 total=total+data~length
  159.                 if total>=next | rvar<=0 then do
  160.                     ct=time('e')
  161.                     next=total+freq2
  162.                     call SysCurPos row,16
  163.                     con~charout(codel(total)~left(12))
  164.                 end
  165.                 if total>=calc | rvar<=0 then do
  166.                     rate=total%ct
  167.                     calc=total+freq
  168.                     call SysCurPos row,46
  169.                     con~charout(rate~left(12))
  170.                 end
  171.             end
  172.         end
  173.         else do
  174.             outfile~charout(data)
  175.             total=total+data~length
  176.             if total>=next | rvar<=0 then do
  177.                 ct=time('e')
  178.                 next=total+freq2
  179.                 call SysCurPos row,16
  180.                 con~charout(codel(total)~left(12))
  181.                 if total>50000 then freq2=rate/2
  182.             end
  183.             if total>=calc | rvar<=0 then do
  184.                 rate=total%ct
  185.                 calc=total+freq
  186.                 if total>50000 then freq=rate/2
  187.                 call SysCurPos row,46
  188.                 con~charout(codel(rate)~left(12))
  189.             end
  190.         end
  191.     end
  192.     outfile~close 
  193.     if longea=1 then call SysPutEA outfile~qualify,'.LONGNAME',longval
  194.     say ''
  195.     say ''
  196.     
  197.     say 'Shutting down socket...'
  198.     csock~shutdown('both')
  199.     say 'Closing socket...'
  200.     csock~close
  201.     say 'Done!'
  202. end
  203.  
  204. /* Socket class - work in progress **********************************/
  205. /*                                                                  */
  206. ::class 'socket'
  207.  
  208. ::method init
  209. expose portnum
  210. portnum=SockSocket('AF_INET','SOCK_STREAM',0)
  211. return
  212.  
  213. ::method sock
  214. expose portnum
  215. return portnum
  216.  
  217. ::method connect
  218. use arg servname
  219. parse var servname hostname ':' host.!port
  220. parse var hostname o1 '.' o2 '.' o3 '.' o4
  221. if o1~datatype='NUM' & o2~datatype='NUM' & o3~datatype='NUM' &,
  222.    o4~datatype='NUM' then do
  223.     if o1~datatype('w')=1 & o2~datatype('w')=1 & o3~datatype('w')=1 &,
  224.        o4~datatype('w')=1 then do
  225.         if (o1>=0 & o1<=255) & (o2>=0 & o2<=255) & (o3>=0 & o3<=255) &,
  226.            (o4>=0 & o4<=255) then do
  227.             stype='IP'
  228.             host.!addr=hostname
  229.         end
  230.     end
  231. end
  232. else stype='NAME'            
  233. if stype='NAME' then call SockGetHostByName hostname,'host.!'
  234. host.!family='AF_INET'
  235. rc=SockConnect(self~sock,'host.!')
  236. return rc
  237.  
  238. ::method send
  239. use arg sendstring
  240. rc=SockSend(self~sock,sendstring)
  241. return rc
  242.  
  243. ::method receive
  244. use arg length
  245. if length='LENGTH' then length=1024
  246. check=SockRecv(self~sock,'sockdata',length)
  247. return .array~new~~put(sockdata,1)~~put(check,2)
  248.  
  249. ::method shutdown
  250. use arg how
  251. select
  252.     when how~translate='FROM' then how=0
  253.     when how~translate='TO' then how=1
  254.     otherwise how=2
  255. end
  256. call SockShutDown self~sock,how
  257. return
  258.  
  259. ::method close
  260. call SockClose self~sock
  261. return
  262. /*                                                                  */
  263. /********************************************************************/
  264.  
  265. /* Comma deliminator routine ****************************************/
  266. /*                                                                  */
  267. ::routine codel
  268. use arg RNum
  269. if RNum~length<3 then return RNum
  270. RNum=RNum~reverse
  271. FNum=''
  272. do while RNum~length>3
  273.     parse var RNum TriDig +3 RNum
  274.     FNum=FNum||TriDig||','
  275. end
  276. FNum=FNum||RNum
  277. return FNum~reverse
  278. /*                                                                  */
  279. /********************************************************************/
  280.  
  281. /* Display usage information ****************************************/
  282. /*                                                                  */
  283. ::routine usage
  284. say ''
  285. say 'Usage:'
  286. say ''
  287. say 'httpget.cmd <URL name ;[local name] | @[filename]>'
  288. say ''
  289. say '<URL name> - URL (only HTTP) of file to get'
  290. say ''
  291. say '[local name] - local name to store file as'
  292. say ''
  293. say "@[filename] - text file with multiple URL's, one on a line"
  294. say ''
  295. say 'e.g. httpget http://www.somewhere.com/index.html'
  296. return
  297. /*                                                                  */
  298. /********************************************************************/
  299.