/* */ parse arg configFile . /***************************************************************************/ /* socket is number 0 */ sock=0 /***************************************************************************/ call readConfig(configFile) call Pragma("D",global.RootDir) /***************************************************************************/ /* who is it? */ if ~GetPeerName(0,"NAME")<0 then do call ErrLog("hserv Can't get peer info (" || errno() || ")") exit end peer = name.addrAddr if global.HostnameLookups=="ON" then if GetHostByAddr("HOST",name.addrAddr) then peer = host.hostName /***************************************************************************/ /* auth */ if global.Auth=="ON" then do auth=AuthFun(name.addrAddr,80,name.addrPort) if left(auth,4)=="-ERR" then do parse var auth"-ERR "code call sen "HTTP/1.0 400 Forbidden" call sen "Content-Type: text/html" call sen "" call sen "

ERROR

ARexxRXSWebServer error:
sorry" peer ", you don't have the ident service running,
or an error stopped your lookup.
" call ErrLog("hserv Can't get auth info for <" || peer || ">") exit end else do parse var auth"+OK" rp "," lp ": USERID : " sis " : " user "D"x"A"x . userat = "<" || user || "@" || peer || ">" end end else do user = "unknown" userat = "<" || peer || ">" end /***************************************************************************/ /* the service itself most the following code is from arexxwebserver.rexx by Casey Halverson, courtesy of the author. */ len = recv(sock,"A",256) if len<0 then do call ErrLog("hserv Error reading (" || errno() || ")") exit end file=subword(a,2,1) if file="/" then file = "/"global.DocumentIndex if index(file,"//")~=0 then signal error if index(file,":")~=0 then signal error file = right(file,length(file)-1) complete = AddPart(global.DocumentDir,file) if global.TransferLog~="OFF" then call TransferLog("hserv Connection from" userat "- Request:" file) if exists(complete)=0 then bad=1 if lastpos(".",file)~= 0 then ext=upper(substr(file,lastpos(".",file),length(file))) else ext = "" mime="text/html" if ext=".HTML"|ext=".HTM"|ext=".HML" then mime="text/html" if ext=".DOC"|ext=".TXT" then mime="text/plain" if ext=".GUIDE" then mime="text/aguide" if ext=".GIF" then mime="image/gif" if ext=".JPG"|ext=".JPEG" then mime="image/jpeg" if ext=".WAV"|ext=".AU"|ext=".8SVX" then mime="audio/*" if ext=".MID"|ext=".MIDI" then mime="audio/x-midi" if ext=".LHA"|ext=".LZH"|ext=".LZX" then mime="application/octet-stream" if ext=".MOCHA" then mime="language/mocha" if ext=".GSM"|ext=".GSD" then mime="audio/x-gsm" if ext=".PS" then mime="application/postscript" call sen "HTTP/1.0 200 OK" call sen "Server: RexxWebServer/1.0" call sen "Date: "||date()||" "||time() call sen "Accept-ranges: bytes" /*call sen "Content-length: "||subword(statef(complete),2,1)*/ call sen "Content-type: "||mime if bad=1 then signal bad call sen "" if ~open("IN",complete,"R") then do call ErrLog("hserv Unable to open" complete) exit end do until eof("IN") a = readln("IN") stop=0 do while a~="" & ~stop select when index(a,"" b INTERPRET "res = "fun a = a || res || b end when index(a,"")~=0 then do parse var a a "" b a = a || peer || b end when index(a,"")~=0 then do parse var a a "" b a = a || user || b end when index(a,"")~=0 then do parse var a a "" b a = a || "Powered up with rxsocket.library" || b end otherwise stop = 1 end end call sen a end call close("IN") exit /***************************************************************************/ bad: call sen "HTTP/1.0 404 Not Found" call sen "Content-Type: text/html" call sen "" call sen "

ERROR

ARexxRXSWebServer error 404:
Page does not exist
FILENAME: "||file||"" exit /***************************************************************************/ error: call sen "HTTP/1.0 400 Forbidden" call sen "Content-Type: text/html" call sen "" call sen "

ERROR

ARexxRXSWebServer error 400:
You may not place : or double //'s in a URL
FILENAME: "||file||"" call ErrLog("hserv <" || peer || "> Request" file) exit /***************************************************************************/ sen: parse arg string string = string || d2c(10) res = send(sock,string) if res~=length(string) then do call ErrLog("hserv Error seanding (" || errno() || ")") exit end return /***************************************************************************/ readConfig: PROCEDURE EXPOSE global. parse arg file if ~Open("CONF",file,"R") then do call EasyRequest("Config file" file "not found.","Http Server") exit end global.RootDir = "miami:www" global.DocumentDir = "miami:www" global.DocumentIndex = "index.html" global.HostnameLookups = "OFF" global.ErrorLog = "SYS" global.ErrorFile = "" global.TransferLog = "SYS" global.TransferFile = "" global.Auth = "OFF" global.Timeout = 100 err = 0 do i = 1 while ~eof("CONF") & (err==0) line = ReadLn("CONF") if line~="" & left(line,1)~="#" then do line = translate(line,' ','9'x) opt = SubWord(line,1,1) arg = SubWord(line,2,1) select when opt=="RootDir" then global.RootDir = arg when opt=="DocumentDir" then global.DocumentDir = arg when opt=="DocumentIndex" then global.DocumentIndex = arg when opt=="HostnameLookups" then if arg~="ON" & arg~= "OFF" then err = 1 else global.HostnameLookups = arg when opt=="ErrorLog" then if arg~="ON" & arg~= "OFF" & arg~="SYS" then err = 1 else global.ErrorLog = arg when opt=="ErrorFile" then global.ErrorFile = arg when opt=="TransferLog" then if arg~="ON" & arg~= "OFF" & arg~="SYS" then err = 1 else global.TransferLog = arg when opt=="TransferFile" then global.TransferFile = arg when opt=="Auth" then if arg~="ON" & arg~= "OFF" then err = 1 else global.Auth = arg when opt=="Timeout" then if ~DataType(arg,"N") then err = 2 else global.Timeout = arg otherwise err = 3 end end end i = i-1 select when err==1 then do call EasyRequest("bad option in line" i,"ARexxRXSWebServer") exit end when err==2 then do call EasyRequest("bad number in line" i,"ARexxRXSWebServer") exit end when err==3 then do call EasyRequest("Unknown option in line" i,"ARexxRXSWebServer") exit end otherwise nop end if global.ErrorFile=="" & global.ErrorLog~="SYS" then global.ErrorLog="OFF" if global.TransferFile=="" & global.TransferLog~="SYS" then global.TransferLog="OFF" call close("IN") return /***************************************************************************/ errLog: parse arg msg select when global.ErrorLog=="OFF" then return when global.ErrorLog=="ON" then do if ~open("LOG",AddPart(global.RootDir,global.ErrorFile),"A") then if ~open("LOG",AddPart(global.RootDir,global.ErrorFile),"W") then exit call WriteLN("LOG",msg) call close("LOG") end when global.ErrorLog=="SYS" then call SysLog(msg) otherwise nop end return /***************************************************************************/ transferLog: parse arg msg select when global.TransferLog=="OFF" then return when global.TransferLog=="ON" then do if ~open("LOG",AddPart(global.RootDir,global.TransferFile),"A") then if ~open("LOG",AddPart(global.RootDir,global.TransferFile),"W") then exit call WriteLN("LOG",msg) call close("LOG") end when global.TransferLog=="SYS" then call SysLog(msg) otherwise nop end return /***************************************************************************/