uncgi.pp 9.3 KB

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