home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 35 Internet
/
35-Internet.zip
/
ckurl162.zip
/
checkurl.cmd
< prev
next >
Wrap
OS/2 REXX Batch file
|
2000-04-25
|
33KB
|
1,160 lines
/*
CheckUrl, written by Francesco Cipriani
version 1.6.2 - April 25, 2000
Parses a HTML page and checks if the URLs it contains
are correct. More infos in the docs.
You need to have two dll installed: RxSock and RxFtp.
(see http://village.flashnet.it/~rm03703/programs if
you don't have them)
Syntax: CheckUrl <parameters>
parameters:
- "/html" : the page we are going to check is an html file
- "/mconn": we want to use multiple connections.
- "/source <html_page>": the page to analyze
- "/log <log_file_name>": overrides the log setting in the cfg
- "/report <report_file_name>": overrides the report setting in the cfg
*/
signal on SYNTAX name SYNTAX
signal on halt
call RxfuncAdd "SysLoadFuncs","RexxUtil","SysLoadFuncs"
call SysLoadFuncs
loadattempt='FTP'
call RxFuncAdd "FtpLoadFuncs","RxFtp","FtpLoadFuncs"
call FtpLoadFuncs "skip"
loadattempt='SOCK'
call RxFuncAdd "SockLoadFuncs", "RxSock", "SockLoadFuncs"
call SockLoadFuncs "skip"
loadattempt=''
vars.!debug=0
say 'CheckUrl 1.6.2'
say
parse arg parms
if parms='' then do
say "Syntax: CheckUrl <parameters>"
say
say "parameters:"
say "- /html : the page we are going to check contains html code"
say "- /mconn: we want to use multiple connections."
say "- /source <html_page>: the page to analyze (use \ instead of"
say " / when the page is and URL)"
say "- /log <log_file_name>: overrides the log setting in the cfg"
say "- /report <report_file_name>: overrides the HTML report setting in the cfg"
say "examples:"
say "checkurl /html /mconn /source http:\\www.netscape.com"
say "checkurl /html /log mylog.txt /mconn /source x:\mypath\my_file.html"
say "checkurl /mconn /source text_file.txt"
exit
end
call read_cfg 'checkurl.cfg'
vars.!opt.!ishtml=0;
vars.!opt.!testbug=0;
vars.!opt.!imchild=0;
vars.!opt.!imserver=0;
wordnum = words(parms); i=1;
do while (i <= wordnum)
thisword = word(parms, i);
thisUpperWord = translate(thisword);
select
when thisUpperWord = "/HTML" then
vars.!opt.!ishtml = 1
when thisUpperWord = "/TESTBUG" then
vars.!opt.!testbug = 1
when thisUpperWord = "/CHILD" then do
vars.!opt.!imchild = 1
vars.!conn.!name = word(parms, i + 1)
i = i + 1;
end
when thisUpperWord = "/SOURCE" then do
source = word(parms, i+1)
i = i + 1;
end
when thisUpperWord = "/LOG" then do
vars.!files.!log = word(parms, i+1)
i = i + 1;
end
when thisUpperWord = "/REPORT" then do
vars.!files.!htmllog = word(parms, i+1)
i = i + 1;
end
when thisUpperWord = "/MCONN" then do
vars.!opt.!imserver=1
end
otherwise nop
end
i = i + 1;
end
vars.!url.0=0
crlf='0d0a'x
if vars.!opt.!imchild = 1 then signal skip
if pos("HTTP:", translate(source))<>0 then do
mode = "fetch";
url = normalize(source);
res = "";
do while res <> "ok"
say "Fetching "url
res = checkHttp(url)
if res <> "ok" then do
if session.!errorCode = "301" | session.!errorCode = "302" then do
url = session.!redirect;
say "Page redirected to "session.!redirect" - Retrying"
end
else do
say "Error while retrieving source page ("res")"
exit 2
end
end
end
say "...done"
/* we have session.!content set with the content of the url passed */
call retrieve_html_urls session.!content, 'HREF=', url
end
else do
call apri_lettura source
if (vars.!opt.!ishtml) then do
text=charin(source,1,chars(source))
call retrieve_html_urls text, 'HREF=', ""
end
else do while lines(source)=1
line=linein(source)
if line<>"" & left(line,1)<>";" then call insert_url unescape(line)
end
call chiudi source
end
skip:
if vars.!opt.!imchild then call child_proc
else do
say "0d0a"x||"Checking urls..."
call apri_scrittura vars.!files.!log
/* if conn number > url to check then conn number=url to check */
if vars.!conn.!num>vars.!url.0 then vars.!conn.!num=vars.!url.0
call time('R')
call time('E')
if vars.!opt.!imserver then call server_proc
else
do i=1 to vars.!url.0
say 'Checking 'vars.!url.i" ("i" of "vars.!url.0")"
ret=checkurl(vars.!url.i);try=1
do while try<vars.!maxtries & left(ret,5)='Error'
ret=checkurl(vars.!url.i);try=try+1
end
say ret||crlf
call list_insert vars.!url.i' 'ret, '!result'
end
call makereport
call chiudi vars.!files.!log
end
/* uncomment if no other program uses rxsock or rxftp
* call SockDropFuncs
* call FtpDropFuncs
*/
exit
/*
* Given a url passed from command line with \ substituting /
* translate \ into / and return the correct url
*/
normalize:
procedure
parse arg cmdlineUrl
url = translate(cmdlineUrl, "/", "\");
return url
read_cfg:
procedure expose vars.
parse arg cfgfile
vars.!files.!badurl='' /* defaults */
vars.!maxtries=1
vars.!email=''
vars.!opt.!logwarnings=0
vars.!opt.!logerrors=0
vars.!files.!log='checkurl.log'
vars.!files.!htmllog='report.html'
vars.!internalport=1932
vars.!socket.!timeout=60
vars.!conn.!num=5
call apri_lettura cfgfile
do while lines(cfgfile)=1
line=linein(cfgfile)
if left(line,1)=';' | line='' then iterate
else do
parse var line keyword'='val
keyword=translate(keyword)
val=strip(val)
select
when keyword='EMAIL' then vars.!email=val
when keyword='LOGERRORS' then do
if val='yes' then vars.!opt.!logerrors=1
else vars.!opt.!logerrors=0
end
when keyword='LOGWARNINGS' then do
if val='yes' then vars.!opt.!logwarnings=1
else vars.!opt.!logwarnings=0
end
when keyword='LOGFILE' then vars.!files.!log=val
when keyword='HTMLLOGFILE' then vars.!files.!htmllog=val
when keyword='CONNECTIONS' then vars.!conn.!num=val
when keyword='TIMEOUT' then vars.!socket.!timeout=val
when keyword='INTERNALPORT' then vars.!internalport=val
when keyword='BADURLFILE' then vars.!files.!badurl=val
when keyword='MAXTRIES' then vars.!maxtries=val
otherwise nop
end
end
end
call chiudi cfgfile
return
makereport:
procedure expose vars.
/* do nothing if no result available */
if datatype(vars.!result.0)='NUM' then do
if vars.!result.0=0 then return
end
else return
crlf='0d0a'x
htmlfile=vars.!files.!htmllog
writebadurl=vars.!files.!badurl<>'' /* write bad urls? */
if writebadurl then do
call sysfiledelete vars.!files.!badurl
call apri_scrittura vars.!files.!badurl
end
call sysfiledelete htmlfile;call apri_scrittura htmlfile
call lineout htmlfile, '<HTML><BODY><TABLE>'
do i=1 to vars.!result.0
parse var vars.!result.i url status
/* logmessage=url' 'status||crlf */
select
when left(status, 7)='Warning' then do
if vars.!opt.!logwarnings=1 then do
parse var status . err
call lineout htmlfile, '<TR><TD WIDTH=3% BGCOLOR="Orange">Warning</TD><TD>'
call lineout htmlfile, '<A HREF='url'>'url'</A><BR>'err
call lineout htmlfile, '</TD></TR>'
/* call logga logmessage */
end
end
when left(status,5)='Error' then do
if writebadurl then call lineout vars.!files.!badurl, url
if vars.!opt.!logerrors=1 then do
parse var status . err
call lineout htmlfile, '<TR><TD WIDTH=3% BGCOLOR="Red">Error</TD><TD>'
call lineout htmlfile, '<A HREF='url'>'url'</A><BR>'err
call lineout htmlfile, '</TD></TR>'
/* call logga logmessage */
end
end
otherwise nop
end
end
if vars.!debug then
call logga 'Checked 'vars.!url.0 'urls in 'time('E') 'seconds'
call lineout htmlfile, '</TABLE></BODY></HTML>'
call chiudi htmlfile
if writebadurl then
call chiudi vars.!files.!badurl
return
/* Read urls from html file - called with HREF string to be looked for */
retrieve_html_urls:
procedure expose vars.
parse arg text, what, currentUrl
baseUrl = baseUrl(currentUrl)
if pos("http://", currentUrl) = 1 then do
x = lastpos("/", currentUrl);
if x > 7 then
currentLevel = left(currentUrl, x - 1);
else
currentLevel = currentUrl;
end
text=stripchar('0d'x,text)
text=stripchar('0a'x,text)
utext=translate(text)
spos=1;
do while pos(what,utext,spos)>0
str='';wtl=length(what)
x=pos(what,utext,spos)
if x>1 then prev=substr(text,x-1,1)
else prev=' '
if prev=' ' | prev='0a'x | prev='0d'x then do
nextch = substr(text, x+wtl, 1)
if nextch = '"' | nextch = "'" then x=x+1
fine = 0;
fine1 = pos('>', text, x+wtl);
if fine1 <> 0 then fine = fine1
fine2 = pos('"', text, x+wtl);
if fine2 <> 0 & fine2 < fine then fine = fine2
fine3 = pos("'", text, x+wtl);
if fine3 <> 0 & fine3 < fine then fine = fine3
if fine = 0 then str=substr(text, x+wtl)
else str = substr(text, x+wtl, fine-x-wtl)
str=strip(str,,'=')
str=strip(str,,')')
str=strip(str,,'(')
str=strip(str,,',')
str=strip(str,,'"')
str=strip(str,,' ')
str=strip(str,,"'")
str=strip(str,,'0a'x)
str=strip(str,,'0d'x)
/* Check url not empty and
* Support relative url only for online urls
*/
ustr=translate(str);
if str <> "" then do
okflag = 0;
if currentUrl = "" then do
if pos("HTTP://", ustr) = 1 then
okflag =1;
end
else do
okflag = 1
end
if okflag then do
upper_levels = count_occurrences('../', str)
if upper_levels > 0 then do
tstring = currentUrl
do i = 1 to upper_levels + 1
tstring = url_up(tstring)
end
/* Strip leading ../ */
found = false; i= 1; len = length(str)
do while found = false & i < len
c = substr(str, i, 1)
if c <> "." & c <> "/" then
found = true
else
i = i + 1;
end
str = tstring'/'||right(str, len - i + 1);
end
if pos('/', str) = 1 then
str = baseUrl||str
ustr=translate(str);
ok = 1;
if pos('JAVASCRIPT:', ustr) = 1,
| pos('GOPHER:',ustr) = 1,
| pos('MAILTO:',ustr) = 1,
| pos('NEWS:',ustr) = 1,
| pos('FTP:',ustr) = 1,
| pos('FILE://',ustr) = 1,
| pos('#',str)=1,
then ok=0;
if ok then do
if left(ustr, 4)='HTTP' then do
str=filter_url(str)
call insert_url unescape(str)
end
else do
str = currentLevel'/'str /* subdirectory */
str=filter_url(str)
call insert_url unescape(str)
end
end
spos = x + length(str)
end /* if okflag */
else do
spos = spos + length(str)
end
end /* if str <> "" */
else do
spos = spos + 1;
end
end /* if .. */
else spos = spos+1;
end /* do while */
return
insert_url:
procedure expose vars.
parse arg url
if list_isinlist(url, '!url')=0 then do
call list_insert url, '!url'
end
else do
str='! Dupe: 'url
say str
call logga str
end
return
/* ------- LIST ROUTINES ---------- */
list_insert:
procedure expose vars.
parse arg elem, stem
stem=value(stem)
if symbol('vars.'stem'.0')<>'VAR' then vars.stem.0=0
x=list_isinlist(elem,stem)
if x=0 then do
a=vars.stem.0+1
vars.stem.a=elem
vars.stem.0=a
end
return
/* 0 -> not in list
n -> elem position */
list_isinlist:
procedure expose vars.
parse arg elem, stem
stem = value(stem)
do i = 1 to vars.stem.0
if elem = vars.stem.i then return i
end
return 0
/* ------------ CHECK ROUTINES ----------------- */
/* Returns "ok" if all ok, or an error message ("Error:..")*/
checkurl:
procedure expose vars.
parse arg url
uurl=translate(url)
mode = "check" /* for checkhttp */
if pos('HTTP://',uurl)<>0 then do
err=checkhttp(url)
end
else if pos('FTP://',uurl)<>0 then err=checkftp(url)
else err='Bad Url - Only FTP and HTTP supported'
return err
/* Check an FTP url */
checkftp:
procedure expose vars.
parse arg url
uurl=translate(url);err=''
parse var url .'://'site'/'rest
x=lastpos('/',rest)
dir=left(rest,x)
file=right(rest,length(rest)-x)
rc = FtpSetUser(site, 'anonymous', vars.!email)
if rc=1 then do
rc = ftpchdir('/'dir)
err = 'Error: Url not found';
ufile = translate(file)
call FTPLs "-la "file, "files."
do i = 1 to files.0
if pos(ufile, translate(files.i))<>0 then do
err='Ok'
leave;
end
end
rc = ftpLogoff()
end
return err
baseUrl:
procedure
parse arg currentUrl
/* find the site domain */
x1 = pos("://", currentUrl);
if x1 <> 0 then x2 = pos("/", currentUrl, x1 + 3)
else x2 = 0;
if x2 <> 0 then do
baseUrl = left(currentUrl, x2)
end
else baseUrl = currentUrl
/* strip trailing / */
if right(baseUrl, 1) = "/" then
baseUrl = left(baseUrl, length(baseUrl) - 1)
return baseUrl
/*
* Check a HTTP url
*/
checkhttp:
procedure expose vars. mode session.
parse arg url
/*
* initialization for "fetch" mode
* In fetch mode this function fills the session. stem
* session.!content - the content of the url requested
* session.!errorCode - the error code returned by the http server
* session.!redirect - url we've been redirected to (available only
* if the server reported a redirection err code
*/
session.!content = ""
session.!errorCode = 0;
session.!redirect = ""
url=filter_url(url)
parse value url with type'://'server'/'suburl
suburl=transl(suburl)
baseUrl = "http://"server
host.!dotted=get_dotted(server)
if host.!dotted='' then return "Error: Domain doesn't exist"
sock = SockSocket('AF_INET', 'SOCK_STREAM', 'IPPROTO_TCP')
if (sock=-1) then do
return 'Error: cannot get a socket (fun SockSocket)'
end
addr.!family='AF_INET'
addr.!port = strip(host.!port) /* retrieved by get_dotted */
addr.!addr = host.!dotted
rc = _SockConnect(sock, vars.!socket.!timeout)
if rc<>'ok' then do
call SockSoClose sock
return rc
end
ret='';crlf='0d0a'x
message = 'GET /'suburl' HTTP/1.0'crlf,
|| 'User-Agent: CheckUrl/1.6.2'crlf,
|| 'Host: 'server':'host.!port||crlf,
|| 'Accept: */*'||crlf,
|| crlf
/* modes: fetch | check
* the mode variable is set from the calling function
* if mode = fetch session.!contente variable is filled with the
* html page
*/
if (mode = "check") then do
rc = SockSend(sock, message)
ret = sockin(sock, vars.!socket.!timeout, 1024, '##SockIn:')
if left(ret,9)='##SockIn:' then do
rc = SockSoClose(sock)
return 'Error: Timeout receiving data'
end
end
else do
rc = SockSend(sock, message)
ret = sockin(sock, vars.!socket.!timeout,, '##SockIn:')
session.!content = ret
if left(ret,9)='##SockIn:' then do
rc = SockSoClose(sock)
return 'Error: Timeout receiving data'
end
end
rc = SockSoClose(sock)
sock=""
ret=strip(ret)
servercode=word(ret,2)
parse var servercode servercode '0d'x . /* further parsing */
parse var servercode servercode '0a'x .
session.!errorCode = servercode
select
when ret='' then err='Error: Connection refused'
when translate(left(ret,6))='<HTML>' then err='ok' /* special handling for some bad site */
when servercode='200' then err='ok'
when servercode='400' then err='Error: Bad request'
when servercode='401' then err='Warning: Unuathorized'
when servercode='403' then err='Error: Forbidden'
when servercode='404' then err='Error: Url not found'
when servercode='301' | servercode='302' then do
if servercode='301' then err='Warning: Moved Permanently -> '
if servercode='302' then err='Warning: Moved Temporarily -> '
x=pos('Location: ', ret);loc=''
if x<>0 then do
parse value ret with .'Location: 'loc'0a'x
loc=strip(loc,'T','0d'x)
/* if loc=url'/' then return 'ok'*/ /* Just a slash to be added .. */
if pos("/", loc) = 1 then do
loc = baseurl||loc /* loc is /location */
end
err=err||loc
session.!redirect = loc
end
end
otherwise do
err='Error: Unknown server return code'
end
end
/*
* if there was an error, the page is not valid
* otherwise, clean it from the server information
*/
if mode = "fetch" & err = "ok" then do
session.!content = stripHeader(session.!content);
end
return err
/* Given a site name return its dotted rappresentation or the name itself
if it's already a dotted ip */
get_dotted:
procedure expose host. server.
parse arg servname
parse var servname hostname ':' host.!port
if host.!port='' then host.!port='80'
parse var hostname o1 '.' o2 '.' o3 '.' o4
if datatype(o1)='NUM' & datatype(o2)='NUM' & datatype(o3)='NUM' & datatype(o4)='NUM' then
if datatype(o1,'w')=1 & datatype(o2,'w')=1 & datatype(o3,'w')=1 & datatype(o4,'w')=1 then
if (o1>=0 & o1<=255) & (o2>=0 & o2<=255) & (o3>=0 & o3<=255) & (o4>=0 & o4<=255) then
return hostname
server.!family = 'AF_INET'
server.!port = host.!port
server.!addr = hostname
rc=sockgethostbyname(hostname,serv.!)
if rc=0 then return ''
return serv.!addr
/* "Clean" url */
filter_url:
procedure
parse arg url
if pos('#',url)<>0 then parse var url url'#'.
return url
transl:
procedure
parse arg s
result='';
unsafe=' "<>#%{}~|\^[]`'
do i=1 to length(s)
car=substr(s,i,1)
code=c2d(car)
select
when code>=127 | code<=31 then result=result||'%'d2x(code)
when pos(car, unsafe)<>0 then result=result||'%'d2x(code)
otherwise result=result||car
end
end
return result
/* ------------------------ */
logga:
procedure expose vars.
parse arg str
rc=lineout(vars.!files.!log,str)
return
child_proc:
procedure expose vars.
url=''; try=1;
do while url<>'FINE'
if url='' then url=child_talkserver('GETURL 'vars.!conn.!name)
if url<>'FINE' then do
result=checkurl(url);lasturl=url
stringa='RESULT 'vars.!conn.!name' 'try' 'url' 'result
url=child_talkserver(stringa)
select
when url=lasturl then try=try+1 /* times the url has been checked */
when url='OK' then do; try=1; url=''; end;
otherwise nop
end
end
end
return
/* send a string and get another */
child_talkserver:
procedure expose vars.
parse arg stringtosend
host.!dotted=get_dotted('localhost')
addr.!family='AF_INET'
addr.!port = vars.!internalport
addr.!addr = host.!dotted
sock = SockSocket('AF_INET','SOCK_STREAM',0)
if (sock=-1) then do
say 'Error on SockSocket'
signal halt
end
rc = SockConnect(sock, "addr.!")
if (rc=-1) then do
say 'Error on SockConnect'
signal halt
end
rc = SockSend(sock, stringtosend)
if (rc=-1) then do
say 'Error on SockSend' errno
signal halt
end
ret = sockin(sock, vars.!socket.!timeout, 1024, '##SockIn:')
if left(ret,9)='##SockIn:' then do
rc = SockSoClose(sock)
signal halt
end
rc = SockSoClose(sock)
sock=""
if (rc=-1) then do
say 'Error on SockClose' errno
signal halt
end
return ret
server_proc:
procedure expose vars.
s = SockSocket("AF_INET","SOCK_STREAM",0)
if s = -1 then do
say 'Error on SockSocket:' errno
signal halt
end
server.!family = "AF_INET"
server.!port = vars.!internalport
server.!addr = "INADDR_ANY"
if vars.!opt.!testbug=0 then
rc=SockSetSockOpt(s, "SOL_SOCKET", "SO_REUSEADDR", 1)
rc = SockBind(s,"server.!")
if (rc = -1) then do
say 'Error on SockBind' errno
signal halt
end
do i=1 to vars.!conn.!num
temp.!conn.!url.i = ''
temp.!conn.!try.i = 0
temp.!conn.!secs.i = 0
'@detach checkurl /child 'i
end
i=1;threadfinished=0;
temp.!checkedurl=0 /* analyzed urls */
do while threadfinished<vars.!conn.!num
rc = SockListen(s, vars.!conn.!num)
if (rc = -1) then do
say "Error on SockListen:" errno
signal halt
end
ns = SockAccept(s, "client.!")
if (ns = -1) then do
say "Error on SockAccept:" errno
signal halt
end
if vars.!debug then say "Accepted client:" client.!addr
data=''
rc = sockrecv(ns, 'data', 1024)
if rc=-1 then do
rc = SockSoClose(s)
rc = SockSoClose(ns)
iterate
end
select
when left(data,6)='RESULT' then do
parse var data . threadname try url res
if (left(res,5)='Error') & (try<vars.!maxtries) then do
call _socksend ns, url
try=try+1 /* child is tryingfor try+1 times now */
end
else do
call _socksend ns, 'OK'
call list_insert url' 'res, '!result'
call logga url' 'res
temp.!conn.!url.threadname=''
temp.!checkedurl=temp.!checkedurl+1
try=0
end
temp.!conn.!secs.threadname=trunc(time('E'))
temp.!conn.!try.threadname=try
call showthreads
end
when left(data,6)='GETURL' then do
parse var data . threadname
if i>vars.!url.0 then do
call _socksend ns, 'FINE'
threadfinished=threadfinished+1
temp.!conn.!url.threadname='FINE'
call showthreads
end
else do
newdata=vars.!url.i;i=i+1
call _socksend ns, newdata
temp.!conn.!url.threadname=newdata
temp.!conn.!secs.threadname=trunc(time('E'))
temp.!conn.!try.threadname=1
call showthreads
end
end
otherwise nop
end
rc = SockSoClose(ns)
ns=""
if (rc = -1) then do
say "Error on SockSoClose:" errno
signal halt
end
end /* do while */
rc = SockSoClose(s)
s=""
if (rc=-1) then do
say "Error on SockSoClose:" errno
signal halt
end
return
showthreads:
procedure expose temp. vars.
curtime=trunc(time('E'))
call syscls
do i=1 to vars.!conn.!num
call syscurpos 2+(i-1)*2, 0
if temp.!conn.!url.i='FINE' then say 'Conn 'right(i,2) ': Finished'
else say 'C'right(i,2) '['temp.!conn.!try.i']' '('right(curtime-temp.!conn.!secs.i,2)')' temp.!conn.!url.i
end
parse value systextscreensize() with row col
bar=copies('■',col)
percent=(temp.!checkedurl/vars.!url.0)*100
call syscurpos 0, 0;say left(bar,trunc( length(bar)*(percent/100) ))
call syscurpos 1, 0;say 'C # Try Secs Url'
mex=temp.!checkedurl 'of' vars.!url.0
call syscurpos 0, trunc((col/2)-length(mex)/2); say mex
return
_socksend:
procedure
parse arg socket, data
rc = SockSend(socket,data)
if (rc = -1) then do
say "Error on SockSend:" errno
signal halt
end
return
/* Extended SockConnect - timeout support */
_sockconnect:
procedure expose addr. vars. sock
parse arg socket, timeout
call SockIoctl sock, 'FIONBIO', 1 /* Non blocking mode */
c=0;rc=-1;rcode=''
do while c<=timeout & rc=-1 & rcode=''
rc=SockConnect(sock, "addr.!")
if rc=-1 then
select
when errno = 'EINPROGRESS' |,
errno = 'EALREADY' then do; call syssleep(1);c=c+1;iterate;end;
when errno = 'EADDRNOTAVAIL' then rcode='Error: No route to host'
when errno = 'EISCONN' then rcode='ok'
when errno = 'ENOTSOCK' then rcode='Error: Incorrect socket parameter'
when errno = 'ECONNREFUSED' then rcode='Error: Connection refused'
when errno = 'EINTR' then rcode='Error: Interrupted system call'
when errno = 'ENETUNREACH' then rcode='Error: Network unreachable'
when errno = 'ETIMEDOUT' then rcode='Error: Connection timed out'
when errno = 'ENOBUFS' then rcode='Error: No buffer space available'
otherwise rcode="Error: couldn't connect" /* ? */
end
end
if rcode='' then do
if c>timeout then rcode='Error: Timeout connecting'
else rcode='Error: 'errno
end
call SockIoctl sock, 'FIONBIO', 0
return rcode
apri_lettura:
procedure
parse arg file
rc=stream(file,'c','open read')
if rc<>'READY: ' then do
say 'Error opening file "'file'" for reading'
exit
end
return
apri_scrittura:
procedure
parse arg file
rc=stream(file,'c','open write')
if rc<>'READY: ' then do
say 'Error opening file "'file'" for writing'
exit
end
return
chiudi:
procedure
parse arg file
rc=stream(file,'c','close')
if rc<>'READY: ' then do
say 'Error closing file "'file'"'
exit
end
return
halt:
call makereport
rc=stream(vars.!files.!log,'c',close)
if datatype(sock,"W") then call SockSoClose(sock)
if datatype(socket,"W") then call SockSoClose(socket)
if datatype(ns,"W") then call SockSoClose(ns)
if datatype(s,"W") then call SockSoClose(s)
say 'Exiting'
exit
return
SYNTAX:
select
when loadattempt='FTP' then do
say ''
say 'RxFTP library not present.'
say 'See documentation for download instructions.'
exit
end
when loadattempt='SOCK' then do
say ''
say 'RxSock library not present.'
say 'See documentation for download instructions.'
exit
end
otherwise do
nop
exit
end
end
return
/**************************/
/* SOCKIN: a replacement for sockrecv.
call as
stuff=sockin(socket,timeout,maxlen,timeoutmess)
where:
socket == a socket that's been established using sockconnect
timeout == a timeout value in seconds
maxlen == maximum length of message to recieve
If not specified, then no maximum is imposed
timeoutmess == Prefix for "error" and "timeout" message.
If not specified, "#SOCKIN: " is used as a prefix
For example: #SOCKIN: timeout " will be returned if no response
was recieved in timeout seconds.
and
stuff = the contents returned from the server (up to maxlen characters)
or an error message (starting with the timeoutmess)
Note: timeout refers to maximum seconds between "sockrecv" requests.
It does NOT refer to total length of time required to recieve a message.
Thus, a number of medium length delays (say, a few seconds required
to complete each of several sockrecv requests) will NOT cause a timeout
(in other words, the timeout counter is reset upon each successful
completion of a 256 byte sockrecv request).
*/
/* Adpapted from Sockin by Daniel Hellerstein, danielh@econ.ag.gov */
sockin:
procedure
parse arg socket, timeout, maxlen, timeoutmess
if maxlen=0 | maxlen='' then maxlen=100000000
if timeoutmess='' then timeoutmess='#SOCKIN:'
if timeout='' then timeout=10
if sockioctl(socket, 'FIONBIO', 1)=-1 then
return timeoutmess||'crashed in ioctl 'errno
maxPkt = 10000;
if (maxlen < maxPkt) then maxPkt = maxlen;
ok=0; incoming=''
Do While TimeOut > 0
res = sockrecv(socket, 'data', maxPkt)
if res = -1 then do /* error condition ? */
/* severe error */
If errno <> 'EWOULDBLOCK' then
return timeoutmess||'crashed in sockrecv 'errno
/* not-fatal,no-data-available-condition:
* errno = EWOULDBLOCK & sockrecv returned -1
*/
/* if incoming<>'' then do; ok=1; leave; end*/
call syssleep(1) /* release cpu? */
TimeOut = TimeOut - 1; /* count down my timer */
Iterate;
end;
if res=0 then do
ok=1 ; leave /* got end of message, so exit this do loop*/
end
if res<0 & incoming='' then do
return timeoutmess||" Error in sockrecv " rc
end
incoming = incoming||data; data=''
call syssleep(0);
if length(incoming) > maxlen then do
ok=2
leave
end
end /* do while timeout > 0 */
/* here we are timed out, or got entire message */
if ok=1 then do
rc=sockioctl(socket,'FIONBIO',0) /* switch to blocking mode */
return incoming /* success! */
end
if ok=2 then do
rc=sockioctl(socket,'FIONBIO',0)
return left(incoming, maxlen)
end
return timeoutmess||' Timeout ';
/*
* Given a page with its header,
* strips the header and returns the content
*/
stripHeader:
procedure
parse arg page
parse var page . '0d0a0d0a'x page
return page
count_occurrences:
procedure
parse arg word, string
num = 0; start = 1; len = length(word)
do forever
x=pos(word, string, start)
if x = 0 then leave
num = num + 1
start = x + len
end
return num
stripchar:
procedure
parse arg char, text
fine=false; spos=1
do while fine=false
x = pos(char, text, spos)
if x = 0 then fine=true
else text = delstr(text, x, 1)
spos = x
end
return text
unescape:
procedure
parse arg string
do forever
x = pos('%',string)
if x = 0 then return string
es = substr(string, x + 1, 2)
string= left(String, x - 1),
||x2c(es),
||right(string, length(string) - (x + 2))
end
return string
url_up:
procedure
parse arg url
x = lastpos('/',url)
url = left(url, x-1)
return url