From 069e0b79e3768fd5af8b070254a5bddeec8d7e73 Mon Sep 17 00:00:00 2001 From: Bas Lijnse Date: Mon, 17 Mar 2008 15:04:31 +0000 Subject: [PATCH] Added a subserver wrapper option to the http library. It should however only be used in experimental environments, because it is based on the undocumented CleanServer API, instead of stable pure Clean libraries. Also moved the makeResponse function in the HttpServer, HttpCGI and HttpSubServer modules to a unified http_makeResponse function in HttpUtil git-svn-id: https://svn.cs.ru.nl/repos/iTask-system/trunk@129 63da3aa8-80fd-4f01-9db8-e6ea747a3da2 --- Http/Examples/example.icl | 12 +- Http/HttpCGI.icl | 11 +- Http/HttpServer.icl | 11 +- Http/HttpUtil.dcl | 1 + Http/HttpUtil.icl | 10 + .../SubServer/Clean System Files/CFUNCLIB.OBJ | Bin 0 -> 1110 bytes .../SubServer/Clean System Files/KERNEL32.TXT | 6 + .../SubServer/Clean System Files/REGERROR.OBJ | Bin 0 -> 432 bytes Http/SubServer/Clean System Files/REGEXP.OBJ | Bin 0 -> 7076 bytes Http/SubServer/Clean System Files/REGSUB.OBJ | Bin 0 -> 908 bytes .../Clean System Files/SUBSERVER.OBJ | Bin 0 -> 5114 bytes Http/SubServer/Clean System Files/USER32.TXT | 2 + Http/SubServer/Clean System Files/WSOCK32.TXT | 8 + Http/SubServer/HttpSubServer.dcl | 45 ++ Http/SubServer/HttpSubServer.icl | 364 +++++++++++++ Http/SubServer/Semaphore.dcl | 6 + Http/SubServer/Semaphore.icl | 46 ++ Http/SubServer/SubServerUtil.dcl | 130 +++++ Http/SubServer/SubServerUtil.icl | 475 +++++++++++++++++ Http/SubServer/bin/mainserver_eventlog.exe | Bin 0 -> 65536 bytes .../bin/remove_subservers_in_registry.exe | Bin 0 -> 57856 bytes Http/SubServer/bin/removesubserver.exe | Bin 0 -> 36864 bytes Http/SubServer/bin/subservers_in_registry.exe | Bin 0 -> 59392 bytes .../src/subservers_in_registry/registry.dcl | 47 ++ .../src/subservers_in_registry/registry.icl | 126 +++++ .../remove_subservers_in_registry.icl | 30 ++ .../remove_subservers_in_registry.prj | 473 +++++++++++++++++ .../subservers_in_registry.icl | 43 ++ .../subservers_in_registry.prj | 497 ++++++++++++++++++ 29 files changed, 2318 insertions(+), 25 deletions(-) create mode 100644 Http/SubServer/Clean System Files/CFUNCLIB.OBJ create mode 100644 Http/SubServer/Clean System Files/KERNEL32.TXT create mode 100644 Http/SubServer/Clean System Files/REGERROR.OBJ create mode 100644 Http/SubServer/Clean System Files/REGEXP.OBJ create mode 100644 Http/SubServer/Clean System Files/REGSUB.OBJ create mode 100644 Http/SubServer/Clean System Files/SUBSERVER.OBJ create mode 100644 Http/SubServer/Clean System Files/USER32.TXT create mode 100644 Http/SubServer/Clean System Files/WSOCK32.TXT create mode 100644 Http/SubServer/HttpSubServer.dcl create mode 100644 Http/SubServer/HttpSubServer.icl create mode 100644 Http/SubServer/Semaphore.dcl create mode 100644 Http/SubServer/Semaphore.icl create mode 100644 Http/SubServer/SubServerUtil.dcl create mode 100644 Http/SubServer/SubServerUtil.icl create mode 100644 Http/SubServer/bin/mainserver_eventlog.exe create mode 100644 Http/SubServer/bin/remove_subservers_in_registry.exe create mode 100644 Http/SubServer/bin/removesubserver.exe create mode 100644 Http/SubServer/bin/subservers_in_registry.exe create mode 100644 Http/SubServer/src/subservers_in_registry/registry.dcl create mode 100644 Http/SubServer/src/subservers_in_registry/registry.icl create mode 100644 Http/SubServer/src/subservers_in_registry/remove_subservers_in_registry.icl create mode 100644 Http/SubServer/src/subservers_in_registry/remove_subservers_in_registry.prj create mode 100644 Http/SubServer/src/subservers_in_registry/subservers_in_registry.icl create mode 100644 Http/SubServer/src/subservers_in_registry/subservers_in_registry.prj diff --git a/Http/Examples/example.icl b/Http/Examples/example.icl index 540c91540..7a21749b3 100644 --- a/Http/Examples/example.icl +++ b/Http/Examples/example.icl @@ -1,10 +1,12 @@ module example -import Http, HttpServer, HttpCGI, HttpUtil +import Http, HttpServer, HttpCGI, HttpUtil, HttpSubServer import StdString, StdList, StdArray, StdInt -//serverFunction = http_startServer -//serverOptions = [HTTPServerOptPort 80, HTTPServerOptStaticFallback True, HTTPServerOptParseArguments True] -serverFunction = http_startCGI -serverOptions = [HTTPCGIOptParseArguments True] +serverFunction = http_startServer +serverOptions = [HTTPServerOptPort 80, HTTPServerOptStaticFallback True, HTTPServerOptParseArguments True] +//serverFunction = http_startCGI +//serverOptions = [HTTPCGIOptParseArguments True] +//serverFunction = http_startSubServer +//serverOptions = [HTTPSubServerOptPort 80, HTTPSubServerOptStaticFallback True, HTTPSubServerOptParseArguments True] Start :: *World -> *World Start world = serverFunction serverOptions [ ((==) "/debug",debug) , ((==) "/upload", upload) diff --git a/Http/HttpCGI.icl b/Http/HttpCGI.icl index 0485a5008..d18f7067d 100644 --- a/Http/HttpCGI.icl +++ b/Http/HttpCGI.icl @@ -32,7 +32,7 @@ http_startCGI options handlers world client_name = getClientName} # request = if (getParseOption options) (http_parseArguments request) request - # (response,world) = makeResponse options request handlers world + # (response,world) = http_makeResponse request handlers (getStaticOption options) world # (response,world) = http_encodeResponse response False world # (ok,console) = freopen console FWriteData # console = fwrites response console @@ -67,15 +67,6 @@ makeHeaders [(name,envname):xs] = case value of EnvironmentVariableUndefined = makeHeaders xs (EnvironmentVariable v) = [(name,v): makeHeaders xs] -// Calls the request handler for a request and returns the generated response -makeResponse :: [HTTPCGIOption] HTTPRequest [((String -> Bool),(HTTPRequest *World -> (HTTPResponse, *World)))] *World -> (HTTPResponse, *World) -makeResponse options request [] world //None of the request handlers matched - = if (getStaticOption options) - (http_staticResponse request world) (http_notfoundResponse request world) -makeResponse options request [(pred,handler):rest] world - | (pred request.req_path) = handler request world //Apply handler function - = makeResponse options request rest world //Search the rest of the list - getStaticOption :: [HTTPCGIOption] -> Bool getStaticOption [] = False getStaticOption [x:xs] = case x of (HTTPCGIOptStaticFallback b) = b diff --git a/Http/HttpServer.icl b/Http/HttpServer.icl index 91ee74fad..db7f84c53 100644 --- a/Http/HttpServer.icl +++ b/Http/HttpServer.icl @@ -70,7 +70,7 @@ loop options handlers listener rchannels schannels requests world | method_done && headers_done && data_done # request = if (getParseOption options) (http_parseArguments request) request // Create a response - # (response,world) = makeResponse options request handlers world + # (response,world) = http_makeResponse request handlers (getStaticOption options)world // Encode the response to the HTTP protocol format # (reply, world) = http_encodeResponse response True world // Send the encoded response to the client @@ -124,15 +124,6 @@ addRequestData req requestline_done headers_done data_done data = (req,True,True,True,False) //We have all data and are done //Data is added while we were already done = (req,True,True,True,False) - -// Calls the request handler for a request and returns the generated response -makeResponse :: [HTTPServerOption] HTTPRequest [((String -> Bool),(HTTPRequest *World -> (HTTPResponse, *World)))] *World -> (HTTPResponse, *World) -makeResponse options request [] world //None of the request handlers matched - = if (getStaticOption options) - (http_staticResponse request world) (http_notfoundResponse request world) -makeResponse options request [(pred,handler):rest] world - | (pred request.req_path) = handler request world //Apply virtual page function - = makeResponse options request rest world //Search the rest of the list getPortOption :: [HTTPServerOption] -> Int diff --git a/Http/HttpUtil.dcl b/Http/HttpUtil.dcl index c30da05ed..17f2d44a5 100644 --- a/Http/HttpUtil.dcl +++ b/Http/HttpUtil.dcl @@ -19,6 +19,7 @@ http_parseUrlEncodedArguments :: !String -> [HTTPArgument] http_parseMultiPartPostArguments :: !HTTPRequest -> ([HTTPArgument],[HTTPUpload]) //Construction of HTTP Response messages +http_makeResponse :: !HTTPRequest [((String -> Bool),(HTTPRequest *World -> (HTTPResponse, *World)))] !Bool !*World -> (!HTTPResponse,!*World) http_encodeResponse :: !HTTPResponse !Bool !*World -> (!String,!*World) //Error responses diff --git a/Http/HttpUtil.icl b/Http/HttpUtil.icl index d8c92b7cd..7d7d404bd 100644 --- a/Http/HttpUtil.icl +++ b/Http/HttpUtil.icl @@ -148,6 +148,16 @@ where = s % (start, end) //Construction of HTTP Response messages +http_makeResponse :: !HTTPRequest [((String -> Bool),(HTTPRequest *World -> (HTTPResponse, *World)))] !Bool !*World -> (!HTTPResponse,!*World) +http_makeResponse request [] fallback world //None of the request handlers matched + = if fallback + (http_staticResponse request world) //Use the static response handler + (http_notfoundResponse request world) //Raise an error +http_makeResponse request [(pred,handler):rest] fallback world + | (pred request.req_path) = handler request world //Apply handler function + = http_makeResponse request rest fallback world //Search the rest of the list + + http_encodeResponse :: !HTTPResponse !Bool !*World -> (!String, !*World) http_encodeResponse {rsp_headers = headers, rsp_data = data} withreply world //When used directly the 'Status' header should be converted to # (date,world) = getCurrentDate world diff --git a/Http/SubServer/Clean System Files/CFUNCLIB.OBJ b/Http/SubServer/Clean System Files/CFUNCLIB.OBJ new file mode 100644 index 0000000000000000000000000000000000000000..914c54526344d84c7275a7f43b9e84731eaa658b GIT binary patch literal 1110 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 literal 0 HcmV?d00001 diff --git a/Http/SubServer/Clean System Files/SUBSERVER.OBJ b/Http/SubServer/Clean System Files/SUBSERVER.OBJ new file mode 100644 index 0000000000000000000000000000000000000000..565c8abf890bdd124830832634a2cd2456090fe2 GIT binary patch literal 5114 zcma)AYiv{J8U9Q{>IKu7HjIpRC6rJ~Sxq36ODS3|90CY~b20pwm@)QAZ15$rk0ETM zTV$ePPSZ_O*^gH6wf8_dVy> zULvh0vd?p#@4dh8_c`_fSG_v2WLUf7QEHcx%NNb)5#y9@J*oh}PwfZ$-sn}nH}!~zvO{^-90r@hYsvM*yYy-TIX=}B=m5qbs%>8MW~9-oe4Z zvq?Rh4G*I_BEy`e6*TXfn%DGu^OLTE-#cD3o-l)MQ}bMKpKk=pUvm}sIbU=YG|$wZ zOuzfOOC5a+ieq59LczyI0X!`HR)>e6DOj{Sq^U^)Nq z)lK6UKunCk@L+B(5OX18P6Ktd(r<^!(qhamUok2IOQ2!}?S|=ZF_-n5T1&oIA29tl z`m8mN8NAVN%W)W{cEc&PMDYSFmKNJ1-BFzU9lW1VF>gC3UXSGGtSrad5nle+^sbCg z2$-`A^)l3KB^6txnv^*~l6|)Fc2=f$m0Mw6q_uuolMegI03~LQvuM#9u`s!&aYbqLT>Tfueble3;s7q1z+=FwTW#qH6j*g}wE* zh_}$~#+-8Ho4N8F-`G_zlBjAyi@69*X~|!$?-SLrYu;9+?8bN`)_}?74VX(Qen?W# zR)J~)muZZVlxU6@UtBabS(^{WMSb49!yAs1J9^Elu=y^Lnq7gVZai4!WXb$4o-ktt z`4CZaDN&YC3|m8)ym9*_3_F6{>4m~Neu?I4Cr^8>+mhhXsCF%b8T7D2(_Ls35BY2L zIAaPpW!xp&5o)R@zl-cWl5^XGF;%dlv4`B$+$D(6Nb?PEIHgLYE*pmPJmG?z>;qVr zR!ITwdU1#$27j5_zMR}Kv6H)UYMHnz1k1$w%LTU(8-nG6oM)N`lTgs6^JmMd>0AN& z5(!1XJ)T1pu)HBS z!|_blX)|yxve1q^rrG;Z>%O5rIX936aO$xZO=W`o!@}47%zop>Y$Zm9fh7PuG!k4<=Ld)M@3WD|_oZiuwDE zO|KNEJY1ux#e8!L?Ear4dKTR@-RLVm8p+43eF|fWX8US~*j+$06$x@h!}N;XKA7Sy zbM!3@h1h^sgYr9Q0O%RKn$>l@ug9xF{T}b1Ve}WgKh3BPO~nc`Uyt+fj-UXB+%oGz6|sjqnDi3?*Of2?lquKG5U=ocf*lutFz{Tv-%zo{$oYoe&V3ZKpT1WI?!{B{s6Rv(T70GSmPeh!;C(1kOxP#aLXO! z0}_pGKr$tr4%Z8`oh`?KwlVr5PzR&$I_O;>v2qJYeEiKp_Z)QJL5mt}IS-KNE(ekb zo^ZIeKoWrlBoPb)iH~nNa<4k*2S8%wb%%QsNUYoj5-U%mv`=y#yMbgM^#Ms2jsWfC z)gho(Mq@zY*EbYT=-}vjfY0h-SJwVV-xm>Dbw<+35nnvou%=Pbzq)m*`fCujpQ>{O zELrXH?Y9M1e+9xuf(+WXz-6;61Iv{!L>Ogg?YDIP?AG5G7&78XJ)JY?iDXDqc5lU2 zD5DP>8C|bplG)*SwDMIF? zyjrS}p@-Y^nE%XU9-;Q~WykYO4HFtdk!=xhdEhMvrX1*fxwRtj|ckI~4ong69*2pCE6fj+OJm0U;qLm_;AHpnkhpa39 z)VXXi(!tx1xmCkV&$IJj9`mRu!=mkd+dO6v%&!o1Wj2!YWWF?yIS=MNM+?1(oa)>} z<67nG;ykTa!Tb^@TE*9oz&wsA7KVDNkLr0?8OY|te(KHDk{Xk8u;~OWaNwr_3Oj&tf6P{!$TmG zjtr&;5P8WZ;%eL2X~Ov)$I&6Hi5t;FUhz z)w$g!gQ;YAew#hyeutM3h`qSYGy8bg~M zzdcCZU^9>yLBYB@H^a@5fvy1~oH24Em1yi*NSIFEPEcY>R<+Tt&Mi(Jwq{QvoXujv zj+82rP9_oRfp`izAgbNDWb(|BRFq1@CEbIqJ;1#~PY_r*ZtO{CEbkmBHw=L~IccMD zyTlb={_L==i=U?ABMJS`@e^oxwzEx=OzwMdMk_ObQCUnQ%lO$|ZU* zMO5i*I&xAs$Wb5#-y=hY1s*MSM7C%@K-(WSA~BRk8y&$!4p1$4C=bZQ F{ukRhM@9eu literal 0 HcmV?d00001 diff --git a/Http/SubServer/Clean System Files/USER32.TXT b/Http/SubServer/Clean System Files/USER32.TXT new file mode 100644 index 000000000..323c8d70d --- /dev/null +++ b/Http/SubServer/Clean System Files/USER32.TXT @@ -0,0 +1,2 @@ +USER32.DLL +FindWindowA@8 \ No newline at end of file diff --git a/Http/SubServer/Clean System Files/WSOCK32.TXT b/Http/SubServer/Clean System Files/WSOCK32.TXT new file mode 100644 index 000000000..7cd1915bd --- /dev/null +++ b/Http/SubServer/Clean System Files/WSOCK32.TXT @@ -0,0 +1,8 @@ +WSOCK32.DLL +WSACleanup@0 +WSAStartup@8 +send@16 +recv@16 +closesocket@4 +select@20 +shutdown@8 \ No newline at end of file diff --git a/Http/SubServer/HttpSubServer.dcl b/Http/SubServer/HttpSubServer.dcl new file mode 100644 index 000000000..29e9afb3d --- /dev/null +++ b/Http/SubServer/HttpSubServer.dcl @@ -0,0 +1,45 @@ +definition module HttpSubServer + +import Http, SubServerUtil + +// (c) 2006 Erwin Lips and Jacco van Drunen +// HIO - Breda +// Radboud University Nijmegen + +// This is an Http 1.1 SubServer written in Clean +// The SubServer can be linked with a Clean function generating Html code +// It creates a subserver application which can be attached to a Http 1.1 compliant main server. +// This can e.g. be an Apache server, a Microsoft IIS server, or the Clean Http 1.1 server. +// Several SubServers can be attached, and Strings and Files can be communicated + + +:: HTTPSubServerOption = HTTPSubServerOptPort Int // The port on which the server listens (default is 80) + | HTTPSubServerOptStaticFallback Bool // If all request handlers fail, should the static file handler be tried (default False) + | HTTPSubServerOptParseArguments Bool // Should the query and body of the request be parsed (default True) + | HTTPSubServerOptMaxServers Int // The maximum number of subserver processes to be started (default is 100) + + +//Wrapper function similar to http_startServer and http_startCGI +http_startSubServer :: [HTTPSubServerOption] [((String -> Bool),(HTTPRequest *World-> (HTTPResponse,*World)))] *World -> *World + +//The following types and functions can be used to implement a more advanced streaming subserver. +//For simple applications, it is advisable to just use the http_startSubServer wrapper + +:: Socket :== Int; + +//required functions +RegisterSubProcToServer :: !Int !Int !Int !String !String -> Int // priority minimum maximum number of subservers +WaitForMessageLoop :: ([String] Int Socket *World -> (Socket,*World)) Socket !*World -> *World + +//helper-functions for sending (suggested to use one of these) +SendString :: !String !String ![String] !Socket !*World -> (Socket,*World) +SendFile :: String ![String] !Socket !*World -> (Socket,*World) + +//helper-functions for receiving (optional to use one of these) +ReceiveString :: !Int !Int !Socket !*World -> (Int,String,Socket,*World) +ReceiveFile :: !Int !Socket !*File !*World -> (Bool,*File,*World) + +//extra functions (do not use these unless you know what you are doing, read the RFC first) +SendDataToClient :: !Socket !{#Char} !*env -> (!Socket,*env); +HTTPdisconnectGracefulC :: !Socket !*env -> *env; +DetectHttpVersionAndClose :: !String !String !Socket !*World -> (Socket,*World) \ No newline at end of file diff --git a/Http/SubServer/HttpSubServer.icl b/Http/SubServer/HttpSubServer.icl new file mode 100644 index 000000000..b38d8fab5 --- /dev/null +++ b/Http/SubServer/HttpSubServer.icl @@ -0,0 +1,364 @@ +implementation module HttpSubServer + +import StdEnv, Directory +import Http, HttpUtil, SubServerUtil, Semaphore +import code from "REGEXP.OBJ" +import code from "REGSUB.OBJ" +import code from "REGERROR.OBJ" +import code from "CFUNCLIB.OBJ" +import code from "SUBSERVER.OBJ", library "KERNEL32.TXT", library "USER32.TXT", library "WSOCK32.TXT" + +// Create subserver talking to an http 1.1 server. +// One needs to create several copies of the same subserver to handle parallel request issues by an http 1.1 server. +// To prevent race conditions, calls to such a subserver copy is serialized using a semaphore. + +// This wrapper function works like the http_startServer and http_startCGI functions +http_startSubServer :: [HTTPSubServerOption] [((String -> Bool),(HTTPRequest *World-> (HTTPResponse,*World)))] *World -> *World +http_startSubServer options handlers world + # result = RegisterSubProcToServer 1 0 (getMaxServersOption options) ".*" ".*" //Handle all requests + | result == 1 + # (console,world) = stdio world + # (_,world) = fclose (fwrites ("Error: SubServer could *NOT* be registered to an HTTP 1.1 main server\n") console) world + = world + | result == 2 + # (console,world) = stdio world + # (_,world) = fclose (fwrites ("SubServer successfully registered to an HTTP 1.1 main server\n") console) world + = world + # (semaphore,world) = CreateSemaphore 0 1 1 "HttpSubServer" world + | semaphore == 0 = abort "CreateSemaphore failed" + # world = WaitForMessageLoop (callback semaphore handlers) (getPortOption options) world + # (ok,world) = CloseHandle semaphore world + | ok==0 = abort "CloseHandle failed" + = world +where + callback :: !Int [((String -> Bool),(HTTPRequest *World-> (HTTPResponse,*World)))] [String] Int Socket *World -> (Socket, *World) + callback semaphore handlers header contentlength socket world + # (alldatareceived,datafromclient,socket,world) = ReceiveString 0 contentlength socket world + # (method,path,query,version, ok) = http_parseRequestLine (hd header) + # headers = [hdr \\ (hdr, error) <- map http_parseHeader (tl header) | not error] + # request = {http_emptyRequest & req_method = method + , req_path = path + , req_query = query + , req_version = version + , req_headers = headers + , req_data = datafromclient + } + # request = if (getParseOption options) (http_parseArguments request) request + | socket==0 = (0,world) //socket closed or timed out + | alldatareceived == -1 + # (response,world) = indivisable options request handlers world + # (response,world) = http_encodeResponse response True world + = SendDataToClient socket response world + | alldatareceived <> 0 + = SendString "Unexpected request" "text/plain" header socket world + # (response,world) = indivisable options request handlers world + # (response,world) = http_encodeResponse response True world + = SendDataToClient socket response world + where + indivisable options request handlers world + # (_,world) = WaitForSingleObject semaphore -1 world + # (response,world) = http_makeResponse request handlers (getStaticOption options) world + # (_,world) = ReleaseSemaphore semaphore 1 0 world + = (response,world) + +getPortOption :: [HTTPSubServerOption] -> Int +getPortOption [] = 80 +getPortOption [x:xs] = case x of (HTTPSubServerOptPort port) = port + _ = getPortOption xs + +getStaticOption :: [HTTPSubServerOption] -> Bool +getStaticOption [] = False +getStaticOption [x:xs] = case x of (HTTPSubServerOptStaticFallback b) = b + _ = getStaticOption xs + +getParseOption :: [HTTPSubServerOption] -> Bool +getParseOption [] = True +getParseOption [x:xs] = case x of (HTTPSubServerOptParseArguments b) = b + _ = getParseOption xs + +getMaxServersOption :: [HTTPSubServerOption] -> Int +getMaxServersOption [] = 100 +getMaxServersOption [x:xs] = case x of (HTTPSubServerOptMaxServers num) = num + _ = getMaxServersOption xs + + +RegisterSubProcToServer :: !Int !Int !Int !String !String -> Int; +RegisterSubProcToServer _ _ _ _ _ = code{ + ccall RegisterSubProcToServer "IIISS:I" +} + +WaitForMessage :: (!Bool,!Socket,!String); +WaitForMessage = code{ + ccall WaitForMessage ":VIIS" +} + +RecvContent :: !Socket !String -> Bool; +RecvContent _ _ = code{ + ccall RecvContent "IS:I" +} + +HTTPrecvC :: !Socket !String -> Int; +HTTPrecvC _ _ = code{ + ccall HTTPrecvC "IS:I" +} + +MatchRegExpr :: !String -> Bool; +MatchRegExpr _ = code{ + ccall MatchRegExpr "S:I" +} + +FreeSharedMem :: !Int !*env -> *env; +FreeSharedMem _ _ = code{ + ccall FreeSharedMem "I:V:A" +} + +SetContentLength :: !Int !*env -> *env; +SetContentLength _ _ = code{ + ccall SetContentLength "I:V:A" +} + +SendDataToClient :: !Socket !{#Char} !*env -> (!Socket,*env); +SendDataToClient 0 _ world = (0,world) +SendDataToClient socket data world + # (_,world) = sendAPI socket data (size data) 0 world + = (socket,world) +where + sendAPI :: !Socket !{#Char} !Int !Int !*env -> (!Int,*env); + sendAPI _ _ _ _ _ = code{ + ccall send@16 "PIsII:I:A" + } + +HTTPdisconnectGracefulC :: !Socket !*env -> *env; +HTTPdisconnectGracefulC _ _ = code{ + ccall HTTPdisconnectGracefulC "I:V:A" +} + +makeNewString :: !Int -> {#.Char}//function to allocate memory for a new string +makeNewString _ = code inline{ + create_array_ CHAR 0 1 +} + +ReadTotalHeaderFromSocket :: Int [String] Socket !*World -> ([String],Socket,*World) +ReadTotalHeaderFromSocket 0 header socket world//first line (example: GET / HTTP/1.0) + # (newheaderline,socket,world) = ReadHeaderFromSocket socket world + | socket==0 = ([],0,world) + # (newheaderline,socket,world) = case newheaderline of//empty line is allowed at the beginning of a request -> RFC2616 section 4.1 + "\r\n" -> ReadHeaderFromSocket socket world + _ -> (newheaderline,socket,world) + | socket==0 = ([],0,world) + # newheaderline = newheaderline % (0,size newheaderline - 3)//remove '\r\n' at the end of the line + # (method,location,getDataArray,version) = GetFirstLine newheaderline + | method=="" || location=="" || version=="" || version % (0,4)<>"HTTP/"//check correctness of the first line + # (socket,world) = SendDataToClient socket "HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n" world + # world = HTTPdisconnectGracefulC socket world + = ([],0,world) + | MatchRegExpr location//match the new location against the regular expression, no match means sending back to mainserver + # (headerlist,socket,world) = ReadTotalHeaderFromSocket 1 (header++[newheaderline]) socket world + | socket==0 = ([],0,world) + # hostname = (GetHeaderData headerlist "HOST:") + | hostname=="" + # (socket,world) = SendDataToClient socket "HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n" world + # world = HTTPdisconnectGracefulC socket world + = ([],0,world) + # (socket,world) = SendDataToClient socket "HTTP/1.1 302 Found\r\nConnection: close\r\nLocation: http://" world + # (socket,world) = SendDataToClient socket hostname world + # (socket,world) = SendDataToClient socket location world + # (socket,world) = SendDataToClient socket "\r\nContent-Type: text/plain\r\nContent-Length: 18\r\n\r\nSubserver Redirect" world//a little text is required when using a redirect -> RFC2616 section 10.3.2 + # world = HTTPdisconnectGracefulC socket world + = ([],0,world) + = ReadTotalHeaderFromSocket 1 (header++[newheaderline]) socket world +ReadTotalHeaderFromSocket 99 header socket world//reached maximum lines, must be an evil request + = ([],0,HTTPdisconnectGracefulC socket world) +ReadTotalHeaderFromSocket linenumber header socket world + # (newheaderline,socket,world) = ReadHeaderFromSocket socket world + | newheaderline=="\r\n" || socket==0 = (header,socket,world)//stop reading header + # newheaderline = newheaderline % (0,size newheaderline - 3)//remove '\r\n' at the end of the line + = ReadTotalHeaderFromSocket (linenumber+1) (header++[newheaderline]) socket world + +ReadHeaderFromSocket :: Socket !*World -> (String,Socket,*World) +ReadHeaderFromSocket socket world + # (success,world) = ReadHeaderFromSocket` world + | success = (data,socket,world)//reading header succeeded + | otherwise = ("",0,HTTPdisconnectGracefulC socket world)//reading header failed +where + data = makeNewString 4092//4092 = sizeof(a page in Windows) - sizeof(int), hope to increase some allocation speed this way + ReadHeaderFromSocket` :: !*World -> (Bool,*World) + ReadHeaderFromSocket` world + # eorl = HTTPrecvC socket data//eorl = short for End Of Read Line + | eorl==2 = (False,world)//line too long, or timeout + | eorl==1 = (True,world)//reached the '\n' + = ReadHeaderFromSocket` world//eorl=0, keep reading the line + +WaitForMessageLoop :: ([String] Int Socket *World -> (Socket,*World)) Socket !*World -> *World +WaitForMessageLoop handlefunction 0 world + #! (success,socket,header) = WaitForMessage + | success + #! headerlist = SplitToStringArray header "\r\n" + #! world = FreeSharedMem 0 world//from this point, the same code as below, TODO: replace same code + #! cl = toInt(GetHeaderData headerlist "CONTENT-LENGTH:") + #! encoding = GetHeaderData headerlist "TRANSFER-ENCODING:" + | cl==0 && encoding <> "" && encoding <> "chunked"//only chunked is required, otherwise send 501 Unimplemented -> RFC2616 section 3.6 + #! (socket,world) = SendDataToClient socket "HTTP/1.1 501 Unimplemented\r\nConnection: close\r\nContent-Type: text/plain\r\nContent-Length: 27\r\n\r\nOnly Chunked Is Implemented" world//a little text is required when using a 5xx error -> RFC2616 section 10.5 + = WaitForMessageLoop handlefunction 0 (HTTPdisconnectGracefulC socket world) + #! cl = case encoding of + "chunked" = -1//-1 represents the chunked mode in both the ReceiveString and the functions in C + _ = cl + #! world = SetContentLength cl world//remember the contentlength in C, so later we check on it to know if there is data on the socket + #! (socket,world) = case (GetHeaderData headerlist "EXPECT:") of + "100-continue" -> SendDataToClient socket "HTTP/1.1 100 Continue\r\n\r\n" world//a client could expect a 100 reply before sending the data -> RFC2616 section 8.2.3 + _ -> (socket,world) + #! (socket,world) = handlefunction headerlist cl socket world + = WaitForMessageLoop handlefunction socket world + = world +WaitForMessageLoop handlefunction socket world + #! (headerlist,socket,world) = ReadTotalHeaderFromSocket 0 [] socket world + | socket==0 = WaitForMessageLoop handlefunction 0 world + #! cl = toInt(GetHeaderData headerlist "CONTENT-LENGTH:") + #! encoding = GetHeaderData headerlist "TRANSFER-ENCODING:" + | cl==0 && encoding <> "" && encoding <> "chunked"//only chunked is required, otherwise send 501 Unimplemented -> RFC2616 section 3.6 + #! (socket,world) = SendDataToClient socket "HTTP/1.1 501 Unimplemented\r\nConnection: close\r\nContent-Type: text/plain\r\nContent-Length: 27\r\n\r\nOnly Chunked Is Implemented" world//a little text is required when using a 5xx error -> RFC2616 section 10.5 + = WaitForMessageLoop handlefunction 0 (HTTPdisconnectGracefulC socket world) + #! cl = case encoding of + "chunked" = -1 + _ = cl + #! world = SetContentLength cl world//remember the contentlength in C, so later we check on it to know if there is data on the socket + #! (socket,world) = case (GetHeaderData headerlist "EXPECT:") of + "100-continue" -> SendDataToClient socket "HTTP/1.1 100 Continue\r\n\r\n" world//a client could expect a 100 reply before sending the data -> RFC2616 section 8.2.3 + _ -> (socket,world) + #! (socket,world) = handlefunction headerlist cl socket world + = WaitForMessageLoop handlefunction socket world + +//gebruikers afhandelfunctie voor het verzenden van een bestand +SendFile :: String ![String] !Socket !*World -> (Socket,*World) +SendFile directory header sock world + # (method,location,getDataArray,version) = GetFirstLine (hd header) + # location = directory +++ CheckLocation location + | location=="" + # (sock,world) = SendDataToClient sock (version +++" 404 Not Found\r\nContent-Length: 0\r\n\r\n") world + = DetectHttpVersionAndClose version (GetHeaderData header "Connection:") sock world + # (ok,file,world) = fopen location FReadData world//probeer bestand te openen + | not ok + # (sock,world) = SendDataToClient sock (version +++" 404 Not Found\r\nContent-Length: 0\r\n\r\n") world + = DetectHttpVersionAndClose version (GetHeaderData header "Connection:") sock world + # ((_,path),world)= pd_StringToPath location world + # ((error,info),world)= getFileInfo path world + # {pi_fileInfo=piinfo}=info + # {fileSize=sizeFile}=piinfo + # string = GetHeaderData header "Content-Range:" + | string<>"" + # first = FindIndexInString string "-" 0 + # firstPoint = toInt(string % (6,first-1)) + # tmp = string % (first+1,size string) + # second = FindIndexInString tmp "/" 0 + # secondPoint = toInt(tmp % (0,second-1)) + # thirdPoint = toInt(tmp % (second+1,size tmp)) + | first==(-1) || second ==(-1) || firstPoint >= secondPoint || secondPoint > thirdPoint || secondPoint > (fst sizeFile) + # (sock,world) = SendDataToClient sock "HTTP/1.0 400 Bad Request\r\nContent-Length: 0\r\n\r\n" world + = DetectHttpVersionAndClose version (GetHeaderData header "Connection:") sock world + # (ok,file) = fseek file firstPoint FSeekSet + | not ok + # (sock,world) = SendDataToClient sock (version+++" 501 Internal Server Error\r\nContent-Length: 0\r\n\r\n") world + # (_,world) = fclose file world + = DetectHttpVersionAndClose version (GetHeaderData header "Connection:") sock world + # (sock,world) = SendDataToClient sock (version+++" 206 Partial content\r\n") world + # (sock,world) = SendDataToClient sock ("Content-Range: "+++string+++"\r\n") world + # contentType= getContentTypeGF (location % ((FindIndexInString location "." 0),size location)) + # (sock,world) = SendDataToClient sock ("Content-Length: "+++toString(secondPoint-firstPoint)) world + # (sock,world) = SendDataToClient sock ("\r\nAccept-Ranges: bytes\r\n\r\n") world + | method<>"HEAD" + # (sock,file,world) = SendFile` (secondPoint-firstPoint) sock file world + # (_,world) = fclose file world + = DetectHttpVersionAndClose version (GetHeaderData header "Connection:") sock world + # (_,world) = fclose file world + = DetectHttpVersionAndClose version (GetHeaderData header "Connection:") sock world + # contentType= getContentTypeGF (location % ((FindIndexInString location "." 0),size location)) + # (sock,world) = SendDataToClient sock (version+++" 200 OK\r\n") world + # (sock,world) = SendDataToClient sock ("Content-Type: "+++contentType+++"\r\n") world + # (sock,world) = SendDataToClient sock ("Content-Length: "+++(toString (fst sizeFile))+++"\r\n\r\n") world + | method<>"HEAD" + # (sock,file,world) = SendFile` (fst sizeFile) sock file world + # (_,world) = fclose file world + = DetectHttpVersionAndClose version (GetHeaderData header "Connection:") sock world + # (_,world) = fclose file world + = DetectHttpVersionAndClose version (GetHeaderData header "Connection:") sock world + +SendFile` :: !Int !Socket !*File !*World-> (Socket,*File,*World)//functie die alle gegevens uit een bestand leest +SendFile` bytes sock file world + # read = case (bytes>4096) of + True = 4096 + _ = bytes + # (data,file) = freads file read + # (sock,world)= SendDataToClient sock data world + | (bytes-read)==0 = (sock,file,world) + = SendFile` (bytes-read) sock file world + +DetectHttpVersionAndClose :: !String !String !Socket !*World -> (Socket,*World) +DetectHttpVersionAndClose version connection sock world + | version=="HTTP/1.0" = (0,HTTPdisconnectGracefulC sock world) + | connection == "close" = (0,HTTPdisconnectGracefulC sock world) + = (sock,world) + +SendString :: !String !String ![String] !Socket !*World -> (Socket,*World) +SendString _ _ _ 0 world = (0,world)//called function with a closed socket +SendString str contenttype requestheader sock world + # (method,location,getDataArray,version) = GetFirstLine (hd requestheader) + # (sock,world) = case version of//does not exist in the other SendString function + "HTTP/1.0" -> SendDataToClient sock "HTTP/1.0" world//does not exist in the other SendString function + _ -> SendDataToClient sock "HTTP/1.1" world//does not exist in the other SendString function + | method<>"GET" && method<>"HEAD" && method<>"POST" + # (sock,world) = SendDataToClient sock " 405 Method Not Allowed\r\nAllow: GET, HEAD, POST\r\nConnection: close\r\n\r\n" world//an Allow-field must be present with a 405 error -> RFC2616 section 14.7 + = (0,HTTPdisconnectGracefulC sock world)//does not exist in the other SendString function + # (sock,world) = SendDataToClient sock " 200 OK\r\nContent-Type: " world + # (sock,world) = SendDataToClient sock contenttype world + # (sock,world) = SendDataToClient sock "\r\nContent-Length: " world + # strsize = (toString (size str)) + # (sock,world) = SendDataToClient sock strsize world + # (sock,world) = SendDataToClient sock "\r\n\r\n" world + # (sock,world) = case method of + "HEAD" -> (sock,world) + _ -> SendDataToClient sock str world + = DetectHttpVersionAndClose version (GetHeaderData requestheader "CONNECTION:") sock world + +ReadChunkSize :: !Socket !*World -> (Int,Socket,*World) +ReadChunkSize sock world + # (data,sock,world) = ReadHeaderFromSocket sock world + = (HexLineToInt (fromString (data % (0,size data - 3))),sock,world) + +ReadChunkData :: !Int !Socket !*World -> (String,Socket,*World) +ReadChunkData 0 sock world = ("",sock,world)//reached the end of the chunked data +ReadChunkData _ 0 world = ("",0,world)//function called with a closed socket +ReadChunkData chunksize sock world + # world = SetContentLength chunksize world//set to the actuall size, so RecvContent (in C) won't get stuck on it + # (_,chunkdata,sock,world) = ReceiveString chunksize 1 sock world + # world = SetContentLength 0 world//set to 0, so ReadHeaderFromSocket won't get stuck on it + # (_,sock,world) = ReadHeaderFromSocket sock world//read an empty line + # (chunksize,sock,world) = ReadChunkSize sock world + # (newchunkdata,sock,world) = ReadChunkData chunksize sock world + = (chunkdata+++newchunkdata,sock,world)//WARNING: possibly creating giga-strings here + +ReceiveString :: !Int !Int !Socket !*World -> (Int,String,Socket,*World) +ReceiveString _ _ 0 world = (-1,"",0,world)//function called with a closed socket +ReceiveString _ 0 sock world = (-1,"",sock,world)//contentlength was zero no data downloaded +ReceiveString _ -1 sock world//-1 means that 'Transfer-Encoding: chunked' is used, chunked is required for all 1.1 apps -> RFC2616 section 3.6.1 + # world = SetContentLength 0 world//set to 0, so ReceiveString won't get stuck on it + # (chunksize,sock,world) = ReadChunkSize sock world + # (allchunkdata,sock,world) = ReadChunkData chunksize sock world + | sock==0 = (0,"",0,HTTPdisconnectGracefulC sock world)//stop reading content + # world = SetContentLength -1 world//the ReceiveString messes up the contentlength in C, so set it back + = (0,allchunkdata,sock,world) +ReceiveString expectedlength contentlength sock world + # expectedlength = case expectedlength of + 0 -> contentlength//autodetect expected length + _ -> expectedlength + # data = makeNewString expectedlength + | RecvContent sock data = (0,"",0,world)//timed-out or disconnected, close was already done in the RecvContent-function + | expectedlength < contentlength = (contentlength-expectedlength,data,sock,world) + = (0,data,sock,world) + +ReceiveFile :: !Int !Socket !*File !*World -> (Bool,*File,*World) +ReceiveFile _ 0 file world = (False,file,world)//called with closed socket +ReceiveFile 0 _ file world = (True,file,world)//called with a contentlength of zero or reached the end of the data +ReceiveFile contentlength socket file world + # (alldatareceived,data,socket,world) = ReceiveString 4096 contentlength socket world + # file = fwrites data file + = ReceiveFile alldatareceived socket file world \ No newline at end of file diff --git a/Http/SubServer/Semaphore.dcl b/Http/SubServer/Semaphore.dcl new file mode 100644 index 000000000..c3da7d8a7 --- /dev/null +++ b/Http/SubServer/Semaphore.dcl @@ -0,0 +1,6 @@ +definition module Semaphore + +CreateSemaphore :: !Int !Int !Int !{#Char} !*World -> (!Int,!*World); +WaitForSingleObject :: !Int !Int !*World -> (!Int,!*World); +ReleaseSemaphore :: !Int !Int !Int !*World -> (!Int,!*World); +CloseHandle :: !Int !*World -> (!Int,!*World); diff --git a/Http/SubServer/Semaphore.icl b/Http/SubServer/Semaphore.icl new file mode 100644 index 000000000..b41955b61 --- /dev/null +++ b/Http/SubServer/Semaphore.icl @@ -0,0 +1,46 @@ +implementation module Semaphore; + +import StdEnv; + +INFINITE :== -1; + +// add CreateSemaphoreA@16 and ReleaseSemaphore@12 to kernel_library for Clean 2.2 and older + +CreateSemaphore :: !Int !Int !Int !{#Char} !*World -> (!Int,!*World); +CreateSemaphore semaphoreAttributes initialCount maximumCount name world = code { + ccall CreateSemaphoreA@16 "PIIIs:I:A" +} + +WaitForSingleObject :: !Int !Int !*World -> (!Int,!*World); +WaitForSingleObject handle milliseconds world = code { + ccall WaitForSingleObject@8 "PII:I:A" +} + +ReleaseSemaphore :: !Int !Int !Int !*World -> (!Int,!*World); +ReleaseSemaphore semaphore releaseCount previousCount_p world = code { + ccall ReleaseSemaphore@12 "PIII:I:A" +} + +CloseHandle :: !Int !*World -> (!Int,!*World); +CloseHandle handle world = code { + ccall CloseHandle@4 "PI:I:A" +} + +Start w + # semaphore_name = "MySemaphoreName"; + + # (semaphore,world) = CreateSemaphore 0 1 1 semaphore_name w; + | semaphore==0 + = abort "CreateSemaphore failed"; + + # (r,world) = WaitForSingleObject semaphore INFINITE world; + + # (stdout,world) = stdio world; + # (ok,c,stdout) = freadc stdout; + # (ok,world) = fclose stdout world; + + # (ok,world) = ReleaseSemaphore semaphore 1 0 world; + + # (ok,world) = CloseHandle semaphore world; + | ok==0 + = abort "CloseHandle failed"; diff --git a/Http/SubServer/SubServerUtil.dcl b/Http/SubServer/SubServerUtil.dcl new file mode 100644 index 000000000..3d020377f --- /dev/null +++ b/Http/SubServer/SubServerUtil.dcl @@ -0,0 +1,130 @@ +definition module SubServerUtil + +// (c) 2005 Paul de Mast +// (c) 2006 Erwin Lips and Jacco van Drunen +// HIO - Breda +// Radboud University Nijmegen + +// a collection of utility functions used by the http server / http subserver + +import StdEnv, StdMaybe, StdLibMisc + +/**************************************************************************** + Set of handy http related functions for the end user +****************************************************************************/ + +GetHeaderData :: [String] *String -> String // Returns method, location, GET data, http version*/ +GetFirstLine :: String -> (String,String,[String],String) +HexLineToInt :: [Char] -> Int +URLDecode :: [Char] -> String +CheckLocation :: String -> String +getContentTypeGF :: String -> String + +/**************************************************************************** + String handling utility functions +****************************************************************************/ + +CountStringInString :: String String -> Int + +StringToUppercase :: Int *String ->*String // Converting a string to a uppercase string, int for begin place in string +TrimString :: String -> String // Removes spaces at beginning and end of a string +FindIndexInString :: String String Int -> Int // Find the index place in the string, based on the second string, int for begin place in first string +ToUniqueString :: String -> *String // Convert a string to a unique string +SplitToStringArray :: String String -> [String] // Split a string in a list of stringd, using on the second string as delimiter + // Example: SplitToStringArray "This:is:a:string" ":" = ["This","is","a","string"] +StringArrayToTupple :: [String] String -> [(String,String)] // Example: StringArrayToTupple ["Name:data","Name1: data1"] ":" = [("Name","data"),("Name1","data1")] +StringArrayCount :: [String] -> Int +CountStringInArray :: [String] String Int -> Int +StringArrayToString :: [String] String -> String + +/**************************************************************************** + as -- bs removes all elements in bs from as +****************************************************************************/ +(--) infixl 5 :: [a] [a] -> [a] | Eq a + +/********************************************************************** + General sorting and ordening of a list of elements +***********************************************************************/ +sortOn :: [(t t -> Bool)] [t] -> [t] +groupOn :: [t -> a] [t] -> [[t]] | ==, < a +splitWith :: (a -> Bool) [a] -> ([a], [a]) + +/********************************************************************** + Some String utilities: +***********************************************************************/ +/* words string = list of words in the string */ +words :: !a -> [String] | toString a + +wordsWith :: !.Char !String -> [String] + +/* a String is split in a part until the seperator and the rest */ +splitAfter :: !.Char !String -> (!String,!String) +cSplit :: !.Char !String -> (!String,!String) +sSplit :: !String !String -> (!String,!String) + +/* flatWith listOfStrings seperator stringlist = concatenates strings with seperator */ +flatWith :: !a ![b] -> String | toString a & toString b + +/* endWith listOfStrings suffix stringlist = concatenates strings with suffix after each string*/ +endWith :: !a ![b] -> String | toString a & toString b + +/* unwords = flatWith ' ' */ +unwords :: ![a] -> String | toString a + +/* unlines = flatWith '\n' */ +unlines :: ![a] -> String | toString a + +trim :: String -> String // remove whitespace at start and end of a String +trimQuotes :: String -> String // ""text"" -> "text" + +substring :: String String -> Bool +match :: String String -> Bool + +stringToUpper :: String -> String +stringToLower :: String -> String + +/********************************************************************** + Instances on Maybe: +***********************************************************************/ + +instance < (Maybe a) | < a +instance toString (Maybe a) | toString a + +/********************************************************************** + To read all the characters from one File in one readacces + returns: a String containing all characters in a file +***********************************************************************/ + +readFile :: *File -> (String, *File) + +/********************************************************************** + To read all the lines from one File + returns: a list of lines without the "\n" +***********************************************************************/ + +readStrings :: *File -> ([String], *File) + + +/********************************************************************** + To save a list of files: [(fileName,fileContents)] +***********************************************************************/ + +exportFiles :: [(String,String)] *Files -> ([String],*Files) + +/********************************************************************** + Some funtion from the Haskell prelude: +***********************************************************************/ +// from the Haskell prelude: + +(hseq) infixr 0 :: !.a .b -> .b + +($) infixr 0 +($) f x :== f x + +instance == (Either a b) | == a & == b + +lookup :: a [(a,.b)] -> Maybe .b | == a; +foldr1 :: (.a -> .(.a -> .a)) ![.a] -> .a; +concatMap :: (.a -> [w:b]) -> u:([.a] -> v:[w:b]), [u <= v, u <= w] +fromMaybe :: a (Maybe a) -> a + diff --git a/Http/SubServer/SubServerUtil.icl b/Http/SubServer/SubServerUtil.icl new file mode 100644 index 000000000..153d37699 --- /dev/null +++ b/Http/SubServer/SubServerUtil.icl @@ -0,0 +1,475 @@ +implementation module SubServerUtil +import StdEnv, StdLib, StdMaybe + +/**************************************************************************** + Set of handy http related functions for the end user +****************************************************************************/ + +/*1e method, 2e location, 3e get data, 4e http version*/ +GetFirstLine :: String -> (String,String,[String],String) +GetFirstLine firstLine +| length data <>3 = ("","",[],"") +| otherwise + # location=data!!1 + # location = case location % (0,6) == "http://" of + True=location % ((FindIndexInString (location % (7,size location)) "/" 0)+7,size location) + _=location + # location = case location == "" of + True="/" + _=URLDecode (fromString location) + # nr = FindIndexInString location "?" 0 + | nr==(-1) = (data!!0,location,[],data!!2) + = (data!!0,location % (0,nr-1),(SplitToStringArray (location %(nr+1,size (location)))) "&",data!!2) +where + data = SplitToStringArray firstLine " " + +HexLineToInt :: [Char] -> Int +HexLineToInt [a] = toInt(hexToChar a) +HexLineToInt [a,b] = (16 * toInt(hexToChar a)) + HexLineToInt [b] +HexLineToInt [a,b,c] = (256 * toInt(hexToChar a)) + HexLineToInt [b,c] +HexLineToInt [a,b,c,d] = (4096 * toInt(hexToChar a)) + HexLineToInt [b,c,d] +HexLineToInt _ = 0 + +URLDecode :: [Char] -> String//URLDecode-functie (zet %?? om naar juiste characters, %20 naar spatie bijv.) +URLDecode [] = "" +URLDecode ['%',a,b:tail] = toString ((toChar (16 * toInt (hexToChar a))) + hexToChar b)+++ URLDecode tail +URLDecode ['+':tail]= " "+++URLDecode tail +URLDecode [head:tail] = toString head +++URLDecode tail + +hexToChar :: Char -> Char//functie is onderdeel van removeEscapes +hexToChar a + | a >= '0' && a <= '9' = a - '0' + | a >= 'A' && a <= 'F' = a - 'A' + (toChar 10) + | a >= 'a' && a <= 'f' = a - 'a' + (toChar 10) + = toChar 0 + +GetHeaderData :: [String] *String -> String//ook een hulpfunctie, tevens interne functie +GetHeaderData [as:bs] header + #string1 = ToUniqueString(as % (0,(size header)-1)) + # string = StringToUppercase 0 string1 + # header = StringToUppercase 0 header + | string==header = TrimString (as % ((size header),size as)) + = GetHeaderData bs header +GetHeaderData _ _ = "" + +getContentTypeGF :: String -> String//functie die Content-Type genereert aan de hand van de extensie +getContentTypeGF ".jpg" = "image/jpeg" +getContentTypeGF ".gif" = "image/gif" +getContentTypeGF ".bmp" = "image/x-ms-bmp" +getContentTypeGF ".htm" = "text/html" +getContentTypeGF ".txt" = "text/plain" +getContentTypeGF "" = "application/octet-stream\r\nContent-Disposition: attachment;"//forceer download (bij video's bijv., zodat deze niet meteen worden afgespeeld) +getContentTypeGF str = getContentTypeGF (str % (1,size str)) + +CheckLocation ::String -> String +CheckLocation location +# array = SplitToStringArray (location % (1,size location)) "/" +| hd array ==".." = "" +# array = FlattenLocation array +| hd array ==".." = "" +| (hd array) % (0,0)=="%" = "" +# countBack = CountStringInArray array ".." 0 +# bool = StringArrayCount array - countBack > countBack +| not bool = "" += StringArrayToString array "\\" + +FlattenLocation :: [String] -> [String] +FlattenLocation array +# array1 = FlattenLocation1 array +| array == array1 = array1 += FlattenLocation array1 +where + FlattenLocation1 [as,bs:cs] + | as==".." && bs==".." && cs<>[]= [as]++ FlattenLocation1 ([bs]++cs) + | as==".." && bs<>".."&& cs<>[]= FlattenLocation1 cs + | bs==".." && cs<>[] = FlattenLocation1 cs + | cs<>[] = [as]++ FlattenLocation1 ([bs]++cs) + FlattenLocation1 [as,bs] = [as,bs] + FlattenLocation1 [as] = [as] + +/**************************************************************************** + String handling utility functions +****************************************************************************/ + +CountStringInString :: String String -> Int +CountStringInString string token +# index = FindIndexInString string token 0 +| index > -1 = 1 + CountStringInString (string % (index+size token,size string)) token += 0 + +StringToUppercase :: Int *String ->*String +StringToUppercase nr string +| nr < 0 = string +| size string > nr + #! char = CharToUppercase string.[nr] + # string = update string nr char + = StringToUppercase (nr+1) string +| otherwise = string + +CharToUppercase :: Char -> Char +CharToUppercase char +| int > 96 && int < 123 = toChar (int bitand (0xdf)) +| otherwise = char +where + int = toInt char + +TrimString::String -> String +TrimString string +| (FindIndexInString string "\t" 0)==0 = TrimString (string % (1,size string)) +| string %(size string-1,size string)=="\t"= TrimString (string % (0,size string-2)) +| (FindIndexInString string " " 0)==0 = TrimString (string % (1,size string)) +| string %(size string-1,size string)==" "= TrimString (string % (0,size string-2)) +| otherwise = string + +SplitToStringArray :: String String -> [String] +SplitToStringArray string token +| string==""=[] +| nr <> -1 = [string % (0,(nr-1))]++SplitToStringArray (string % ((nr+(size token)),size string)) token +| otherwise = [string] +where + nr = FindIndexInString string token 0 + +FindIndexInString ::String String Int -> Int +FindIndexInString string token nr +| nr>size string || token==""= -1 +| string %(nr,nr+(size token)-1)==token = nr +| ((size string) - 1)== nr = -1 +| otherwise = FindIndexInString string token (nr+1) + +StringArrayToTupple::[String] String -> [(String,String)] +StringArrayToTupple [as:bs] token +# index = FindIndexInString as token 0 +| index== -1 = StringArrayToTupple bs token +| otherwise = [(as % (0,(index-1)),as%((index+size token),size as))]++ StringArrayToTupple bs token +StringArrayToTupple _ _ = [] + +ToUniqueString :: String -> *String +ToUniqueString c = {c.[i] \\ i <- [0..(size c-1)]} + +CountStringInArray :: [String] String Int -> Int +CountStringInArray [as:bs] token nr +| as==token = CountStringInArray bs token nr+1 +| otherwise = CountStringInArray bs token nr +CountStringInArray _ _ nr = nr + +StringArrayCount :: [String] -> Int +StringArrayCount [as:bs] = 1 + StringArrayCount bs +StringArrayCount _ = 0 + +StringArrayToString :: [String] String-> String +StringArrayToString [as:bs] token= token+++as +++ StringArrayToString bs token +StringArrayToString _ _= "" + +/**************************************************************************** + as -- bs removes all elements in bs from as +****************************************************************************/ +(--) infixl 5 :: [a] [a] -> [a] | Eq a +(--) as bs = removeMembers as bs + +/********************************************************************** + General sorting and ordening of a list of elements +***********************************************************************/ +sortOn :: [(t t -> Bool)] [t] -> [t] +sortOn ps items += sortBy (combined ps) items +where + combined :: [ (t t -> Bool) ] t t -> Bool + combined [] x y = True + combined [p:ps] x y = (p x y == p y x && combined ps x y) || p x y + +groupOn :: [t -> a] [t] -> [[t]] | ==, < a +groupOn fs xs = (groupBy eqf o sortOn (map smf fs)) xs +where + eqf a b = [f a \\ f <- fs] == [f b \\ f <- fs] + smf f a b = f a < f b + +splitWith :: (a -> Bool) [a] -> ([a], [a]) +splitWith _ [] = ([],[]) +splitWith p [x:xs] + | p x = ([x:as],bs) + | otherwise = (as,[x:bs]) + where + (as,bs) = splitWith p xs + + + +/********************************************************************** + Some String utilities: +***********************************************************************/ +words :: !a -> [String] | toString a +words a + | size s == 0 = [] + | otherwise = [s%(b,e-1) \\ (b,e) <- bes2] +where + s = toString a + bes1 = [i \\ i <- [1..(size s - 1)] | (isSpace s.[i]) <> (isSpace s.[i-1])] + // alleen nog de vraag of je zo niet het laatste woord mist? + // zo ja moeten we nog (size s - 1) aan de staart van bes1 toevoegen... + // waarschijnlijk handigst in zip` met + // zip` [b] = [(b,size s - 1)] + bes2 + | isSpace s.[0] + = zip` bes1 + = zip` [0:bes1] + + zip` [b] = [(b,size s)] + zip` [b,e:r] = [(b,e):zip` r] + zip` _ = [] + +wordsWith :: !.Char !String -> [String] +wordsWith c s + | s=="" && r=="" = [] + | r=="" = [s] + | otherwise = [f : wordsWith c r] +where + (f,r) = cSplit c s + +splitAfter :: !.Char !String -> (!String,!String) +splitAfter c s = (s%(b1,e1),s%(b2,e2)) +where + sp = findPos c s 0 e2 + b1 = 0 + e1 = sp + b2 = sp + 1 + e2 = size s + + findPos :: Char String Int Int -> Int + findPos c s i end + | i >= end = end + | s.[i] == c = i + | otherwise = findPos c s (inc i) end + +cSplit :: !.Char !String -> (!String,!String) +cSplit c s = (s%(b1,e1),s%(b2,e2)) +where + sp = findPos c s 0 e2 + b1 = 0 + e1 = sp - 1 + b2 = sp + 1 + e2 = size s + + findPos :: Char String Int Int -> Int + findPos c s i end + | i >= end = end + | s.[i] == c = i + | otherwise = findPos c s (inc i) end + +sSplit :: !String !String -> (!String,!String) +sSplit sep s = (s%(b1,e1),s%(b2,e2)) +where + sp = findPos sep s 0 e2 + b1 = 0 + e1 = sp - 1 + b2 = sp + ic + 1 + e2 = size s + ic = size sep-1 + + findPos :: String String Int Int -> Int + findPos c s i end + | i >= end = end + | s%(i,i+ic) == c = i + | otherwise = findPos c s (inc i) end + +unwords :: ![a] -> String | toString a +unwords ss = flatWith " " ss + +unlines :: ![a] -> String | toString a +unlines ss = flatWith "\n" ss + +/*flatWith :: !a ![b] -> String | toString a & toString b +flatWith s [] = "" +flatWith s [h] = toString h +flatWith s [h:t] = toString h +++ toString s +++ flatWith s t +*/ + +flatWith :: !a ![b] -> String | toString a & toString b +flatWith sep items += copyLines (createArray (sum (map size lines) + nrOfSep * (size ssep)) ' ') 0 lines +where + nrOfSep + | isEmpty items = 0 + | otherwise = length items - 1 + + lines = map toString items + ssep = toString sep + + copyLines result n [] = result + copyLines result n [l] + # (_,result) = sup (size l) n 0 result l + = result + + copyLines result n [l:ls] + # (n,result) = sup (size l) n 0 result l + # (n,result) = sup (size ssep) n 0 result ssep + = copyLines result n ls + + +endWith :: !a ![b] -> String | toString a & toString b +endWith suffix items += copyLines (createArray (sum (map size lines) + nrOfSep * (size ssuffix)) ' ') 0 lines +where + nrOfSep = length items + + lines = map toString items + ssuffix = toString suffix + + copyLines result n [] = result + + copyLines result n [l:ls] + # (n,result) = sup (size l) n 0 result l + # (n,result) = sup (size ssuffix) n 0 result ssuffix + = copyLines result n ls + +sup :: !.Int Int !Int *String String -> (Int,.String) +sup l i j s h + | j >= l = (i,s) + #! s = {s & [i] = h.[j]} + = sup l (inc i) (inc j) s h + +substring :: String String -> Bool +substring s1 s2 = ss (fromString s1) (fromString s2) +where + ss :: [Char] [Char] -> Bool + ss p [] = p ==[] + ss p xs = take (length p) xs == p || ss p (tl xs) + +match :: String String -> Bool +match p s = match` (fromString p) (fromString s) +where + match` :: [Char] [Char] -> Bool + match` p [] = all ((==) '*') p + match` [] ss = ss == [] + match` ['*':ps] ss = match` ps ss + || match` ['*' : ps] (tl ss) + match` ['?':ps] [s:ss] = match` ps ss + match` [p :ps] [s:ss] = p==s + && match` ps ss + + + +trim :: String -> String +trim s + | s == "" = "" + | otherwise = s % ((start 0),(end sizeS)) +where end n + | not (isSpace s.[n]) || n <= 0 = n + | otherwise = end (n-1) + + start n + | not (isSpace s.[n]) || n >= sizeS = n + | otherwise = start (n+1) + + sizeS = size s - 1 + +trimQuotes :: String -> String +trimQuotes s + | s == "" = "" + | otherwise = s % ((start 0),(end sizeS)) +where end n + | (s.[n] <> '\'' && s.[n] <> '\"') || n <= 0 = n + | otherwise = end (n-1) + + start n + | (s.[n] <> '\'' && s.[n] <> '\"') || n >= sizeS = n + | otherwise = start (n+1) + + sizeS = size s - 1 + +stringToUpper :: String -> String +stringToUpper cs += {toUpper c \\ c <-: cs} + +stringToLower :: String -> String +stringToLower cs += {toLower c \\ c <-: cs} + +/********************************************************************** + Instances on Maybe: +***********************************************************************/ +instance < (Maybe a) | < a +where (<) (Just a) (Just b) = a < b + (<) Nothing _ = True + (<) _ Nothing = False + +instance toString (Maybe a) | toString a +where toString (Just a) = toString a + toString Nothing = "" + + + +/********************************************************************** + To read all the characters from one File in one readacces + returns: a String containing all characters in a file +***********************************************************************/ +readFile :: *File -> (String, *File) +readFile file + # (ok,file) = fseek file 0 FSeekEnd + | not ok = abort "seek to end of file does not succeed\n" + # (pos,file) = fposition file + # (ok,file) = fseek file (~pos) FSeekCur + | not ok = abort "seek to begin of file does not succeed\n" + # (s, file) = freads file pos + = (s, file) + +/********************************************************************** + To read all the lines from one File + returns: a list of lines without the "\n" +***********************************************************************/ +readStrings :: *File -> ([String], *File) +readStrings file + # (eof, file) = fend file + | eof = ([], file) + # (s, file) = freadline file + # s` = s%(0,size s - 2) + # (ss, file) = readStrings file + | otherwise = ([s` : ss], file) + +/********************************************************************** + To save a list of files: [(fileName,fileContents)] + returns: a list of errors and a new fileenvironment +***********************************************************************/ +exportFiles :: [(String,String)] *Files -> ([String],*Files) +exportFiles [] files + = ([],files) +exportFiles [(fn,fc):htmls] files + # (errors,files) = exportFiles htmls files + # (open,htmlfile,files) = fopen fn FWriteText files + | not open = (["could not open: "+++fn+++"\n" : errors],files) + # (close,files) = (fclose (htmlfile <<< fc)) files + | not close = (["could not close: "+++fn+++"\n" : errors],files) + | otherwise = (errors,files) + +/********************************************************************** + Some funtion from the Haskell prelude: +***********************************************************************/ +// from the Haskell prelude: +(hseq) infixr 0 :: !.a .b -> .b +(hseq) a b = b + +($) infixr 0 +($) f x :== f x + +instance == (Either a b) | == a & == b + where + (==) (Left x) (Left y) = y==x + (==) (Right x) (Right y) = y==x + (==) _ _ = False + +lookup :: a [(a,.b)] -> Maybe .b | == a; +lookup k [] = Nothing +lookup k [(x,y):xys] + | k==x = Just y + | otherwise = lookup k xys + +foldr1 :: (.a -> .(.a -> .a)) ![.a] -> .a; +foldr1 f [x] = x +foldr1 f [x:xs] = f x (foldr1 f xs) + +concatMap :: (.a -> [w:b]) -> u:([.a] -> v:[w:b]), [u <= v, u <= w] +concatMap f = flatten o map f + +fromMaybe :: a (Maybe a) -> a +fromMaybe d Nothing = d +fromMaybe d (Just a) = a + + diff --git a/Http/SubServer/bin/mainserver_eventlog.exe b/Http/SubServer/bin/mainserver_eventlog.exe new file mode 100644 index 0000000000000000000000000000000000000000..d5f4041b28e99f5a7332d227526e8f099f1e4477 GIT binary patch literal 65536 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

MZyLez!jn^wq=#^do)3nvX$JNH;f^szv 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 literal 0 HcmV?d00001 diff --git a/Http/SubServer/bin/remove_subservers_in_registry.exe b/Http/SubServer/bin/remove_subservers_in_registry.exe new file mode 100644 index 0000000000000000000000000000000000000000..a01c0bd3ab9f48ff432fbb120aa7f2b363f8901e GIT binary patch literal 57856 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 B5MTfR literal 0 HcmV?d00001 diff --git a/Http/SubServer/bin/subservers_in_registry.exe b/Http/SubServer/bin/subservers_in_registry.exe new file mode 100644 index 0000000000000000000000000000000000000000..f966b692462573c666ced881dabc4edb243ac67e GIT binary patch literal 59392 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 H*#G|r4VvR2 literal 0 HcmV?d00001 diff --git a/Http/SubServer/src/subservers_in_registry/registry.dcl b/Http/SubServer/src/subservers_in_registry/registry.dcl new file mode 100644 index 000000000..28b3a12e9 --- /dev/null +++ b/Http/SubServer/src/subservers_in_registry/registry.dcl @@ -0,0 +1,47 @@ +definition module registry; + +:: RegistryState :== Int; + +KEY_READ:==0x20019; +KEY_SET_VALUE:==2; +KEY_ALL_ACCESS:==0xF002f; + +REG_OPTION_NON_VOLATILE:==0; + +REG_SZ:==1; +REG_BINARY:==3; + +ERROR_SUCCESS:==0; + +HKEY_CURRENT_USER :== 0x80000001; +HKEY_LOCAL_MACHINE :== 0x80000002; + +RegOpenKeyEx :: !Int !{#Char} !Int !Int !RegistryState -> (!Int,!Int,!RegistryState); +RegDeleteKey :: !Int !{#Char} !RegistryState-> (!Int,!RegistryState); +RegCloseKey :: !Int !RegistryState -> (!Int,!RegistryState); +RegCreateKeyEx :: !Int !{#Char} !Int !{#Char} !Int !Int !Int !RegistryState -> (!Int,!Int,!Int,!RegistryState); +RegSetValueEx :: + !Int + !{#Char} + !Int + !Int + !{#Char} + !Int + !RegistryState -> (!Int,!RegistryState); +RegQueryValueEx :: + !Int + !{#Char} + !Int + !Int + !{#Char} + !{#Char} + !RegistryState -> (!Int,!RegistryState); +RegEnumValue :: !Int !Int !Int !Int !Int !RegistryState -> (!Int,!{#Char},!Int,!{#Char},!RegistryState); + +//==> the following don't really belong here... +GetFileAttributes :: !{#Char} -> Int; + +:: CStringP :== Int; + +GetCommandLine :: CStringP; +read_char :: !CStringP -> Char; diff --git a/Http/SubServer/src/subservers_in_registry/registry.icl b/Http/SubServer/src/subservers_in_registry/registry.icl new file mode 100644 index 000000000..8a33520ea --- /dev/null +++ b/Http/SubServer/src/subservers_in_registry/registry.icl @@ -0,0 +1,126 @@ +implementation module registry; + +import StdArray,StdInt,StdClass,StdString,StdBool,StdChar; + +import code from library "registry_advapi32_library"; + +:: RegistryState :== Int; + +KEY_READ:==0x20019; +KEY_SET_VALUE:==2; +KEY_ALL_ACCESS:==0xF002f; + +REG_OPTION_NON_VOLATILE:==0; + +REG_SZ:==1; +REG_BINARY:==3; + +ERROR_SUCCESS:==0; + +HKEY_LOCAL_MACHINE:==0x80000002; + +RegOpenKeyEx :: !Int !{#Char} !Int !Int !RegistryState -> (!Int,!Int,!RegistryState); +RegOpenKeyEx hkey path n f rs = code { + ccall RegOpenKeyExA@20 "PIsII:II" +}; + +RegDeleteKey :: !Int !{#Char} !RegistryState-> (!Int,!RegistryState); +RegDeleteKey hkey path rs = code { + ccall RegDeleteKeyA@8 "PIs:I" +}; + +RegCloseKey :: !Int !RegistryState -> (!Int,!RegistryState); +RegCloseKey hkey rs = code { + ccall RegCloseKey@4 "PI:I" +}; + +RegCreateKeyEx :: !Int !{#Char} !Int !{#Char} !Int !Int !Int !RegistryState -> (!Int,!Int,!Int,!RegistryState); +RegCreateKeyEx hkey path i s i1 i2 i3 rs = code { + ccall RegCreateKeyExA@36 "PIsIsIII:III" +}; + +RegSetValueEx :: !Int !{#Char} !Int !Int !{#Char} !Int !RegistryState -> (!Int,!RegistryState); +RegSetValueEx hkey s1 i1 i2 s2 i3 rs = code { + ccall RegSetValueExA@24 "PIsIIsI:I" +}; + +RegQueryValueEx :: !Int !{#Char} !Int !Int !{#Char} !{#Char} !RegistryState -> (!Int,!RegistryState); +RegQueryValueEx hkey s1 i1 i2 s2 i3 rs = code { + ccall RegQueryValueExA@24 "PIsIIss:I:I" +}; + +/* +RegEnumValue :: !Int !Int !Int !Int !Int !RegistryState -> (!Int,!{#Char},!Int,!{#Char},!RegistryState); +RegEnumValue key index max_value_name_size reserved max_data_size rs + # value_name = createArray max_value_name_size '0'; + # data = createArray max_data_size '0'; + # type_s = createArray 4 '\0'; + # value_name_size_s = { toChar max_value_name_size, + toChar (max_value_name_size>>8), + toChar (max_value_name_size>>16), + toChar (max_value_name_size>>24) }; + # data_size_s = { toChar max_data_size, + toChar (max_data_size>>8), + toChar (max_data_size>>16), + toChar (max_data_size>>24) }; + # (r,rs) = RegEnumValue_ key index value_name value_name_size_s reserved type_s data data_size_s rs; + | r<>0 + = (r,"",0,"",rs); + # data_size = string4_to_int data_size_s; + # value_name_size = string4_to_int value_name_size_s; + # type = string4_to_int type_s; + | type==REG_SZ && data_size<>0 + = (r,value_name % (0,value_name_size-1),type,data % (0,data_size-2),rs); + = (r,value_name % (0,value_name_size-1),type,data % (0,data_size-1),rs); + +string4_to_int :: !{#Char} -> Int; +string4_to_int s + = toInt s.[0] + (toInt s.[1]<<8) + (toInt s.[2]<<16) + (toInt s.[3]<<24); + +RegEnumValue_ :: !Int !Int !{#Char} !{#Char} !Int !{#Char} !{#Char} !{#Char} !RegistryState -> (!Int,!RegistryState); +RegEnumValue_ key index value_name value_name_size reserved type data data_size rs + = code { + ccall RegEnumValueA@32 "PIIssIsss:I:I" + } +*/ +RegEnumValue :: !Int !Int !Int !Int !Int !RegistryState -> (!Int,!{#Char},!Int,!{#Char},!RegistryState); +RegEnumValue key index max_value_name_size reserved max_data_size rs + # value_name = createArray max_value_name_size '0'; + # data = createArray max_data_size '0'; + # type_s = { 0 }; + # value_name_size_s = { max_value_name_size }; + # data_size_s = { max_data_size }; + # (r,rs) = RegEnumValue_ key index value_name value_name_size_s reserved type_s data data_size_s rs; + | r<>0 + = (r,"",0,"",rs); + # data_size = data_size_s.[0]; + # value_name_size = value_name_size_s.[0]; + # type = type_s.[0]; + | type==REG_SZ && data_size<>0 + = (r,value_name % (0,value_name_size-1),type,data % (0,data_size-2),rs); + = (r,value_name % (0,value_name_size-1),type,data % (0,data_size-1),rs); + +RegEnumValue_ :: !Int !Int !{#Char} !{#Int} !Int !{#Int} !{#Char} !{#Int} !RegistryState -> (!Int,!RegistryState); +RegEnumValue_ key index value_name value_name_size reserved type data data_size rs + = code { + ccall RegEnumValueA@32 "PIIsAIAsA:I:I" + } + +GetFileAttributes :: !{#Char} -> Int; +GetFileAttributes file_name = code { + ccall GetFileAttributesA@4 "Ps:I" +}; + +:: CStringP :== Int; + +GetCommandLine :: CStringP; +GetCommandLine = code { + ccall GetCommandLineA@0 "P:I" +}; + +read_char :: !CStringP -> Char; +read_char p = code { + instruction 15 + instruction 182 + instruction 0 | movzx eax,byte ptr [eax] +}; diff --git a/Http/SubServer/src/subservers_in_registry/remove_subservers_in_registry.icl b/Http/SubServer/src/subservers_in_registry/remove_subservers_in_registry.icl new file mode 100644 index 000000000..fb458eee4 --- /dev/null +++ b/Http/SubServer/src/subservers_in_registry/remove_subservers_in_registry.icl @@ -0,0 +1,30 @@ +module remove_subservers_in_registry; + +import StdEnv,registry; + +REGLOCATION :== "SOFTWARE\\Clean HTTP\0"; + +ERROR_FILE_NOT_FOUND:== 2; +ERROR_ACCESS_DENIED :== 5; + +Start w + # rs=0; + # (stdout,w) = stdio w; + # (r,key,rs) = RegOpenKeyEx HKEY_LOCAL_MACHINE REGLOCATION 0 KEY_ALL_ACCESS rs; + | r==ERROR_FILE_NOT_FOUND + # stdout = fwrites "No subservers are stored in the registry\n" stdout; + = snd (fclose stdout w); + + | r<>0 + | r==ERROR_ACCESS_DENIED + = abort ("RegOpenKeyEx failed with error code "+++toString r+++" (access denied)"); + = abort ("RegOpenKeyEx failed with error code "+++toString r); + # (r,rs) = RegCloseKey key rs; + | r<>0 + = abort ("RegCloseKey failed with error code "+++toString r); + # (r,rs) = RegDeleteKey HKEY_LOCAL_MACHINE REGLOCATION rs; + | r<>0 + = abort ("RegDeleteKey failed with error code "+++toString r); + + # stdout = fwrites "The subservers have been removed from the registry\n" stdout; + = snd (fclose stdout w); diff --git a/Http/SubServer/src/subservers_in_registry/remove_subservers_in_registry.prj b/Http/SubServer/src/subservers_in_registry/remove_subservers_in_registry.prj new file mode 100644 index 000000000..e51b119bc --- /dev/null +++ b/Http/SubServer/src/subservers_in_registry/remove_subservers_in_registry.prj @@ -0,0 +1,473 @@ +Version: 1.4 +Global + Built: True + Target: StdEnv + Exec: {Project}\remove_subservers_in_registry.exe + CodeGen + CheckStacks: False + CheckIndexes: True + Application + HeapSize: 409600 + StackSize: 102400 + ExtraMemory: 81920 + IntialHeapSize: 204800 + HeapSizeMultiplier: 4096 + ShowExecutionTime: False + ShowGC: False + ShowStackSize: False + MarkingCollector: False + StandardRuntimeEnv: True + Profile + Memory: False + MemoryMinimumHeapSize: 0 + Time: False + Stack: False + Output + Output: NoReturnType + Font: Courier + FontSize: 9 + WriteStdErr: False + Link + LinkMethod: Static + GenerateRelocations: False + GenerateLinkMap: False + LinkResources: False + ResourceSource: + GenerateDLL: False + ExportedNames: + Paths + Path: {Project} + Precompile: + Postlink: +MainModule + Name: remove_subservers_in_registry + Dir: {Project} + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + Icl + WindowPosition + X: 10 + Y: 10 + SizeX: 817 + SizeY: 640 + IclOpen: True + LastModified: No 0 0 0 0 0 0 +OtherModules + Module + Name: registry + Dir: {Project} + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + Dcl + WindowPosition + X: 10 + Y: 10 + SizeX: 800 + SizeY: 640 + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + NeededLibraries + Library: registry_advapi32_library + Module + Name: StdFunc + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdCharList + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdTuple + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdOrdList + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: _SystemEnum + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdEnum + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdList + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdFile + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdString + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdReal + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: _SystemArray + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdArray + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdClass + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdChar + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdMisc + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdInt + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdOverloaded + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdBool + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdEnv + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 +Static + Mods + Path: {Project}\remove_subservers_in_registry.icl + Path: {Project}\registry.icl + Path: {Application}\Libraries\StdEnv\StdFunc.icl + Path: {Application}\Libraries\StdEnv\StdCharList.icl + Path: {Application}\Libraries\StdEnv\StdTuple.icl + Path: {Application}\Libraries\StdEnv\StdOrdList.icl + Path: {Application}\Libraries\StdEnv\_SystemEnum.icl + Path: {Application}\Libraries\StdEnv\StdEnum.icl + Path: {Application}\Libraries\StdEnv\StdList.icl + Path: {Application}\Libraries\StdEnv\StdFile.icl + Path: {Application}\Libraries\StdEnv\StdString.icl + Path: {Application}\Libraries\StdEnv\StdReal.icl + Path: {Application}\Libraries\StdEnv\_SystemArray.icl + Path: {Application}\Libraries\StdEnv\StdArray.icl + Path: {Application}\Libraries\StdEnv\StdClass.icl + Path: {Application}\Libraries\StdEnv\StdChar.icl + Path: {Application}\Libraries\StdEnv\StdMisc.icl + Path: {Application}\Libraries\StdEnv\StdInt.icl + Path: {Application}\Libraries\StdEnv\StdOverloaded.icl + Path: {Application}\Libraries\StdEnv\StdBool.icl + Path: {Application}\Libraries\StdEnv\StdEnv.icl + Objs + Path: {Application}\Libraries\StdEnv\Clean System Files\_startup0.o + Path: {Application}\Libraries\StdEnv\Clean System Files\_startup1.o + Path: {Application}\Libraries\StdEnv\Clean System Files\_startup2.o + Path: {Application}\Libraries\StdEnv\Clean System Files\_system.o + Path: {Project}\Clean System Files\remove_subservers_in_registry.o + Path: {Project}\Clean System Files\registry.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdFunc.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdCharList.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdTuple.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdOrdList.o + Path: {Application}\Libraries\StdEnv\Clean System Files\_SystemEnum.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdEnum.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdList.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdFile.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdString.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdReal.o + Path: {Application}\Libraries\StdEnv\Clean System Files\_SystemArray.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdArray.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdClass.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdChar.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdMisc.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdInt.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdOverloaded.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdBool.o + Path: {Application}\Libraries\StdEnv\Clean System Files\StdEnv.o + Dlib + Path: {Application}\Libraries\StdEnv\Clean System Files\kernel_library + Path: {Application}\Libraries\StdEnv\Clean System Files\user_library + Path: {Application}\Libraries\StdEnv\Clean System Files\gdi_library + Path: {Application}\Libraries\StdEnv\Clean System Files\comdlg_library + Path: {Project}\Clean System Files\registry_advapi32_library + Pths + Path: {Project} + Path: {Application}\Libraries\StdEnv + AppP: D:\John\Clean 2.2 + PrjP: D:\John\c\CleanHttpServer\subservers_in_registry diff --git a/Http/SubServer/src/subservers_in_registry/subservers_in_registry.icl b/Http/SubServer/src/subservers_in_registry/subservers_in_registry.icl new file mode 100644 index 000000000..3c8e06f20 --- /dev/null +++ b/Http/SubServer/src/subservers_in_registry/subservers_in_registry.icl @@ -0,0 +1,43 @@ +module subservers_in_registry; + +import StdEnv,registry; + +REGLOCATION :== "SOFTWARE\\Clean HTTP\0"; + +ERROR_FILE_NOT_FOUND:== 2; +ERROR_ACCESS_DENIED :== 5; +ERROR_NO_MORE_ITEMS :== 259; + +Start w + # rs=0; + # (stdout,w) = stdio w; + # (r,key,rs) = RegOpenKeyEx HKEY_LOCAL_MACHINE REGLOCATION 0 KEY_ALL_ACCESS rs; + | r==ERROR_FILE_NOT_FOUND + # stdout = fwrites "No subservers are stored in the registry\n" stdout; + = snd (fclose stdout w); + | r<>0 + | r==ERROR_ACCESS_DENIED + = abort ("RegOpenKeyEx failed with error code "+++toString r+++" (access denied)"); + = abort ("RegOpenKeyEx failed with error code "+++toString r); + + # (data,rs) = read_key_data_strings key 0 rs; + # (r,rs) = RegCloseKey key rs; + | r<>0 + = abort ("RegCloseKey failed with error code "+++toString r); + | isEmpty data + # stdout = fwrites "No subservers are stored in the registry\n" stdout; + = snd (fclose stdout w); + # stdout = fwrites "The following subservers are stored in the registry:\n" stdout; + # stdout = foldl (\f s -> fwritec '\n' (fwrites s f)) stdout data; + = snd (fclose stdout w); + +read_key_data_strings key index rs + # (r,value_name,type,data,rs) = RegEnumValue key index 256 0 4096 rs; + | r==ERROR_NO_MORE_ITEMS + = ([],rs); + | r<>0 + = abort ("RegEnumValue failed with error code "+++toString r); + | type==REG_SZ + # (more_data,rs) = read_key_data_strings key (index+1) rs; + = ([data:more_data],rs); + = read_key_data_strings key (index+1) rs; diff --git a/Http/SubServer/src/subservers_in_registry/subservers_in_registry.prj b/Http/SubServer/src/subservers_in_registry/subservers_in_registry.prj new file mode 100644 index 000000000..0fa080c01 --- /dev/null +++ b/Http/SubServer/src/subservers_in_registry/subservers_in_registry.prj @@ -0,0 +1,497 @@ +Version: 1.4 +Global + Built: True + Target: StdEnv + Exec: {Project}\subservers_in_registry.exe + CodeGen + CheckStacks: False + CheckIndexes: True + Application + HeapSize: 409600 + StackSize: 102400 + ExtraMemory: 81920 + IntialHeapSize: 204800 + HeapSizeMultiplier: 4096 + ShowExecutionTime: False + ShowGC: False + ShowStackSize: False + MarkingCollector: False + StandardRuntimeEnv: True + Profile + Memory: False + MemoryMinimumHeapSize: 0 + Time: False + Stack: False + Output + Output: NoReturnType + Font: Courier + FontSize: 9 + WriteStdErr: False + Link + LinkMethod: Static + GenerateRelocations: False + GenerateLinkMap: False + LinkResources: False + ResourceSource: + GenerateDLL: False + ExportedNames: + Paths + Path: {Project} + Precompile: + Postlink: +MainModule + Name: subservers_in_registry + Dir: {Project} + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + Icl + WindowPosition + X: 141 + Y: 42 + SizeX: 837 + SizeY: 566 + IclOpen: True + LastModified: No 0 0 0 0 0 0 +OtherModules + Module + Name: StdEnv + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdBool + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdOverloaded + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdInt + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdMisc + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdChar + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdClass + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdArray + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: _SystemArray + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdReal + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdString + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdFile + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + Dcl + WindowPosition + X: 10 + Y: 10 + SizeX: 800 + SizeY: 640 + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdList + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + Dcl + WindowPosition + X: 10 + Y: 10 + SizeX: 800 + SizeY: 640 + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdEnum + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: _SystemEnum + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdOrdList + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdTuple + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + Dcl + WindowPosition + X: 10 + Y: 10 + SizeX: 800 + SizeY: 640 + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdCharList + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: StdFunc + Dir: {Application}\Libraries\StdEnv + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + DclOpen: False + IclOpen: False + LastModified: No 0 0 0 0 0 0 + Module + Name: registry + Dir: {Project} + Compiler + NeverMemoryProfile: False + NeverTimeProfile: False + StrictnessAnalysis: True + ListTypes: StrictExportTypes + ListAttributes: True + Warnings: True + Verbose: True + ReadableABC: False + ReuseUniqueNodes: True + Fusion: False + Dcl + WindowPosition + X: 10 + Y: 10 + SizeX: 800 + SizeY: 640 + DclOpen: False + Icl + WindowPosition + X: 141 + Y: 11 + SizeX: 837 + SizeY: 618 + IclOpen: False + LastModified: No 0 0 0 0 0 0 + NeededLibraries + Library: registry_advapi32_library +Static + Mods + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\CleanServer\subservers_in_registry\subservers_in_registry.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdEnv.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdBool.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdOverloaded.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdInt.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdMisc.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdChar.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdClass.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdArray.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\_SystemArray.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdReal.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdString.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdFile.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdList.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdEnum.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\_SystemEnum.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdOrdList.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdTuple.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdCharList.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\StdFunc.icl + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\CleanServer\subservers_in_registry\registry.icl + Objs + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\_startup0.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\_startup1.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\_startup2.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\_system.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\CleanServer\subservers_in_registry\Clean System Files\subservers_in_registry.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\CleanServer\subservers_in_registry\Clean System Files\registry.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdFunc.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdCharList.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdTuple.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdOrdList.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\_SystemEnum.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdEnum.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdList.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdFile.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdString.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdReal.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\_SystemArray.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdArray.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdClass.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdChar.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdMisc.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdInt.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdOverloaded.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdBool.o + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\StdEnv.o + Dlib + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\kernel_library + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\user_library + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\gdi_library + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv\Clean System Files\comdlg_library + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\CleanServer\subservers_in_registry\Clean System Files\registry_advapi32_library + Pths + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\CleanServer\subservers_in_registry + Path: C:\Documents and Settings\rinus\Desktop\Clean 2.1.1\Libraries\StdEnv + AppP: D:\John\Clean 2.2 + PrjP: D:\John\c\CleanHttpServer\subservers_in_registry -- GitLab