uncgi.pp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. unit uncgi;
  2. {
  3. $Id$
  4. UNCGI UNIT 2.0.11
  5. ----------------
  6. }
  7. interface
  8. uses
  9. strings
  10. {$ifdef linux}
  11. ,linux
  12. {$endif}
  13. {$IFDEF OS2}
  14. , DosCalls
  15. {$ENDIF OS2}
  16. ;
  17. {***********************************************************************}
  18. const
  19. maxquery = 100;
  20. hextable : array[0..15] of char=('0','1','2','3','4','5','6','7',
  21. '8','9','A','B','C','D','E','F');
  22. uncgi_version = 'UNCGI 2.0.11';
  23. uncgi_year = '1999';
  24. maintainer_name = 'Your Name Here';
  25. maintainer_email= '[email protected]';
  26. Type cgi_error_proc = procedure (Const Proc,Err : String);
  27. var
  28. get_nodata : boolean;
  29. query_read : word;
  30. query_array : array[1..2,1..maxquery] of pchar;
  31. uncgi_error : cgi_error_proc;
  32. {***********************************************************************}
  33. { FUNCTION
  34. This function returns the REQUEST METHOD of the CGI-BIN script
  35. Input - Nothing
  36. Output - [GET|POST]
  37. }
  38. function http_request_method: pchar;
  39. { FUNCTION
  40. This function returns the "referring" page. i.e. the page you followed
  41. the link to this CGI-BIN from
  42. Input - Nothing
  43. Output - [http://somewhere.a.tld]
  44. }
  45. function http_referer: pchar;
  46. { FUNCTION
  47. This function returns the users's USER AGENT, the browser name etc.
  48. Input - Nothing
  49. Output - user agent string
  50. }
  51. function http_useragent: pchar;
  52. { FUNCTION
  53. This function returns a value from an id=value pair
  54. Input - The identifier you want the value from
  55. Output - If the identifier was found, the resulting value is
  56. the output, otherwise the output is NIL
  57. }
  58. function get_value(id: pchar): pchar;
  59. { PROCEDURE
  60. This procedure writes the content-type to the screen
  61. Input - The content type in MIME format
  62. Output - Nothing
  63. Example - set_content('text/plain');
  64. set_content('text/html');
  65. }
  66. procedure set_content(ctype: string);
  67. procedure cgi_init;
  68. procedure cgi_deinit;
  69. implementation
  70. {$IFDEF OS2}
  71. function GetEnv (EnvVar: string): PChar;
  72. var RC: longint;
  73. P, Q: PChar;
  74. begin
  75. GetMem (Q, Succ (Length (EnvVar)));
  76. RC := DosScanEnv (Q, P);
  77. FreeMem (Q, Succ (Length (EnvVar)));
  78. GetEnv := P;
  79. end;
  80. {$ENDIF OS2}
  81. {$ifdef win32}
  82. Var EnvP : PChar;
  83. EnvLen : Longint;
  84. OldExitProc : Pointer;
  85. function GetEnvironmentStrings : pchar; external 'kernel32' name 'GetEnvironmentStringsA';
  86. function FreeEnvironmentStrings(p : pchar) : longbool; external 'kernel32' name 'FreeEnvironmentStringsA';
  87. Procedure FInitWin32CGI;
  88. begin
  89. { Free memory }
  90. FreeMem (EnvP,EnvLen);
  91. ExitProc:=OldExitProc;
  92. end;
  93. Procedure InitWin32CGI;
  94. var s : String;
  95. i,len : longint;
  96. hp,p : pchar;
  97. begin
  98. { Make a local copy of environment}
  99. p:=GetEnvironmentStrings;
  100. hp:=p;
  101. envp:=Nil;
  102. envlen:=0;
  103. while hp[0]<>#0 do
  104. begin
  105. len:=strlen(hp);
  106. hp:=hp+len+1;
  107. EnvLen:=Envlen+len+1;
  108. end;
  109. GetMem(EnvP,Envlen);
  110. Move(P^,EnvP^,EnvLen);
  111. FreeEnvironmentStrings(p);
  112. OldExitProc:=ExitProc;
  113. ExitProc:=@FinitWin32CGI;
  114. end;
  115. Function GetEnv(envvar: string): pchar;
  116. { Getenv that can return environment vars of length>255 }
  117. var s : String;
  118. i,len : longint;
  119. hp : pchar;
  120. begin
  121. s:=Envvar+#0;
  122. getenv:=Nil;
  123. hp:=envp;
  124. while hp[0]<>#0 do
  125. begin
  126. len:=strlen(hp);
  127. i:=Longint(strscan(hp,'='))-longint(hp);
  128. if StrLIComp(@s[1],HP,i-1)=0 then
  129. begin
  130. Len:=Len-i;
  131. getmem (getenv,len);
  132. Move(HP[I+1],getenv^,len+1);
  133. break;
  134. end;
  135. { next string entry}
  136. hp:=hp+len+1;
  137. end;
  138. end;
  139. {$endif}
  140. {$ifdef GO32V2}
  141. Function GetEnv(envvar: string): pchar;
  142. var
  143. hp : ppchar;
  144. p : pchar;
  145. hs : string;
  146. eqpos : longint;
  147. begin
  148. envvar:=upcase(envvar);
  149. hp:=envp;
  150. getenv:=nil;
  151. while assigned(hp^) do
  152. begin
  153. hs:=strpas(hp^);
  154. eqpos:=pos('=',hs);
  155. if copy(hs,1,eqpos-1)=envvar then
  156. begin
  157. getenv:=hp^+eqpos;
  158. exit;
  159. end;
  160. inc(hp);
  161. end;
  162. end;
  163. {$endif}
  164. var
  165. done_init : boolean;
  166. procedure set_content(ctype: string);
  167. begin
  168. writeln('Content-Type: ',ctype);
  169. writeln;
  170. end;
  171. function http_request_method: pchar;
  172. begin
  173. http_request_method :=getenv('REQUEST_METHOD');
  174. end;
  175. function http_referer: pchar;
  176. begin
  177. http_referer :=getenv('HTTP_REFERER');
  178. end;
  179. function http_useragent: pchar;
  180. begin
  181. http_useragent :=getenv('HTTP_USER_AGENT');
  182. end;
  183. function hexconv(h1,h2: char): char;
  184. var
  185. cnt : byte;
  186. thex : byte;
  187. begin
  188. for cnt :=0 to 15 do if upcase(h1)=hextable[cnt] then thex := cnt * 16;
  189. for cnt :=0 to 15 do if upcase(h2)=hextable[cnt] then thex := thex + cnt;
  190. hexconv := chr(thex);
  191. end;
  192. procedure def_uncgi_error(const pname,perr: string);
  193. begin
  194. set_content('text/html');
  195. writeln('<html><head><title>UNCGI ERROR</title></head>');
  196. writeln('<body>');
  197. writeln('<center><hr><h1>UNCGI ERROR</h1><hr></center><br><br>');
  198. writeln('UnCgi encountered the following error: <br>');
  199. writeln('<ul><br>');
  200. writeln('<li> procedure: ',pname,'<br>');
  201. writeln('<li> error: ',perr,'<br><hr>');
  202. writeln(
  203. '<h5><p><i>uncgi (c) ',uncgi_year,' ',maintainer_name,
  204. { skelet fix }
  205. '<a href="mailto:',maintainer_email,'">',
  206. maintainer_email,'</a></i></p></h5>');
  207. writeln('</body></html>');
  208. halt;
  209. end;
  210. function get_value(id: pchar): pchar;
  211. var
  212. cnt : word;
  213. begin
  214. get_value:=Nil;
  215. if done_init then
  216. for cnt :=1 to query_read do
  217. if strcomp(strupper(id),strupper(query_array[1,cnt]))=0 then
  218. begin
  219. get_value := query_array[2,cnt];
  220. exit;
  221. end;
  222. end;
  223. Function UnEscape(QueryString: PChar): PChar;
  224. var
  225. qunescaped : pchar;
  226. sptr : longint;
  227. cnt : word;
  228. qslen : longint;
  229. begin
  230. qslen:=strlen(QueryString);
  231. if qslen=0 then
  232. begin
  233. Unescape:=#0;
  234. get_nodata:=true;
  235. exit;
  236. end
  237. else
  238. get_nodata :=false;
  239. { skelet fix }
  240. getmem(qunescaped,qslen+1);
  241. if qunescaped=nil then
  242. begin
  243. writeln ('Oh-oh');
  244. halt;
  245. end;
  246. sptr :=0;
  247. for cnt := 0 to qslen do
  248. begin
  249. case querystring[cnt] of
  250. '+': qunescaped[sptr] := ' ';
  251. '%': begin
  252. qunescaped[sptr] :=
  253. hexconv(querystring[cnt+1], querystring[cnt+2]);
  254. inc(cnt,2);
  255. end;
  256. else
  257. qunescaped[sptr] := querystring[cnt];
  258. end;
  259. inc(sptr);
  260. { skelet fix }
  261. qunescaped[sptr]:=#0;
  262. end;
  263. UnEscape:=qunescaped;
  264. end;
  265. Function Chop(QunEscaped : PChar) : Longint;
  266. var
  267. qptr : word;
  268. cnt : word;
  269. qslen : longint;
  270. begin
  271. qptr := 1;
  272. qslen:=strlen(QUnescaped);
  273. query_array[1,qptr] := qunescaped;
  274. for cnt := 0 to qslen-1 do
  275. case qunescaped[cnt] of
  276. '=': begin
  277. qunescaped[cnt] := #0;
  278. { save address }
  279. query_array[2,qptr] := @qunescaped[cnt+1];
  280. end;
  281. '&': begin
  282. qunescaped[cnt] := #0;
  283. { Unescape previous one. }
  284. query_array[2,qptr]:=unescape(query_array[2,qptr]);
  285. inc(qptr);
  286. query_array[1,qptr] := @qunescaped[cnt+1];
  287. end;
  288. end; { Case }
  289. { Unescape last one. }
  290. query_array[2,qptr]:=unescape(query_array[2,qptr]);
  291. Chop :=qptr;
  292. end;
  293. procedure cgi_read_get_query;
  294. var
  295. querystring : pchar;
  296. qslen : longint;
  297. begin
  298. querystring :=strnew(getenv('QUERY_STRING'));
  299. if querystring<>NIL then
  300. begin
  301. qslen :=strlen(querystring);
  302. if qslen=0 then
  303. begin
  304. get_nodata :=true;
  305. exit;
  306. end
  307. else
  308. get_nodata :=false;
  309. query_read:=Chop(QueryString);
  310. end;
  311. done_init :=true;
  312. end;
  313. procedure cgi_read_post_query;
  314. var
  315. querystring : pchar;
  316. qslen : longint;
  317. sptr : longint;
  318. clen : string;
  319. ch : char;
  320. begin
  321. if getenv('CONTENT_LENGTH')<>Nil then
  322. begin
  323. clen:=strpas (getenv('CONTENT_LENGTH'));
  324. val(clen,qslen);
  325. if upcase(strpas(getenv('CONTENT_TYPE')))='APPLICATION/X-WWW-FORM-URLENCODED'
  326. then
  327. begin
  328. getmem(querystring,qslen+1);
  329. sptr :=0;
  330. while sptr<>qslen do
  331. begin
  332. read(ch);
  333. pchar(longint(querystring)+sptr)^ :=ch;
  334. inc(sptr);
  335. end;
  336. { !!! force null-termination }
  337. pchar(longint(querystring)+sptr)^ :=#0;
  338. query_read:=Chop(QueryString);
  339. end;
  340. end;
  341. done_init :=true;
  342. end;
  343. procedure cgi_init;
  344. var
  345. rmeth : pchar;
  346. begin
  347. query_read:=0;
  348. rmeth :=http_request_method;
  349. if rmeth=nil then
  350. begin
  351. uncgi_error('cgi_init()','No REQUEST_METHOD passed from server!');
  352. exit;
  353. end;
  354. if strcomp('POST',rmeth)=0 then cgi_read_post_query else
  355. if strcomp('GET',rmeth)=0 then cgi_read_get_query else
  356. uncgi_error('cgi_init()','No REQUEST_METHOD passed from server!');
  357. end;
  358. procedure cgi_deinit;
  359. begin
  360. done_init :=false;
  361. query_read :=0;
  362. fillchar(query_array,sizeof(query_array),0);
  363. end;
  364. begin
  365. {$ifdef win32}
  366. InitWin32CGI;
  367. {$endif}
  368. uncgi_error:=@def_uncgi_error;
  369. done_init :=false;
  370. fillchar(query_array,sizeof(query_array),0);
  371. end.
  372. {
  373. HISTORY
  374. $Log$
  375. Revision 1.3 2000-12-19 00:47:11 hajny
  376. + OS/2 support added
  377. Revision 1.2 2000/07/13 11:33:32 michael
  378. + removed logs
  379. }