gdipcgi_cmn.pm 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. ########################################################################
  2. # gdipcgi_cmn.pm
  3. #
  4. # These routines are common to the GnuDIP web interface and update
  5. # server CGI-s.
  6. #
  7. # See COPYING for licensing information.
  8. #
  9. ########################################################################
  10. # Perl modules
  11. use strict;
  12. # global variables
  13. use vars qw($reqparm $thishost $bad_config $logger $remote_ip $cgi_exit);
  14. # GnuDIP common subroutines
  15. use gdiplib;
  16. # override "exit"
  17. use subs qw(exit);
  18. ########################################################################
  19. # override for "exit"
  20. ########################################################################
  21. sub exit {
  22. # call handler?
  23. &$cgi_exit(@_) if defined $cgi_exit;
  24. # under mod_perl?
  25. Apache::exit(@_) if defined &Apache::exit;
  26. # normal exit
  27. CORE::exit(@_);
  28. }
  29. ########################################################################
  30. # called for database error
  31. ########################################################################
  32. sub dberror {
  33. bad_config();
  34. }
  35. ########################################################################
  36. # write to the log and catch errors
  37. ########################################################################
  38. sub writelog {
  39. my @text;
  40. my $msgprfx = '';
  41. $msgprfx = "$remote_ip - " if defined $remote_ip;
  42. while (my $line = shift @_) {
  43. if ($line =~ /\n/) {
  44. # split on new line
  45. push @text, (split(/\n/, $msgprfx . $line));
  46. } else {
  47. push @text, ($msgprfx . $line);
  48. }
  49. }
  50. if (! calllogger($logger, @text)) {
  51. print STDERR "GnuDIP CGI has exited - calllogger failed\n";
  52. bad_config();
  53. }
  54. }
  55. ########################################################################
  56. # call nsupdate and catch errors
  57. ########################################################################
  58. sub donsupdate {
  59. if (! callnsupdate(@_)) {
  60. writelog("GnuDIP CGI has exited - callnsupdate failed");
  61. bad_config();
  62. }
  63. }
  64. ########################################################################
  65. # display the CGI data in the HTTP server log
  66. ########################################################################
  67. sub logreq {
  68. my $var;
  69. my $val;
  70. print STDERR "ENV:\n";
  71. foreach $var (sort(keys(%ENV))) {
  72. $val = $ENV{$var};
  73. $val =~ s|\n|\\n|g;
  74. $val =~ s|"|\\"|g;
  75. print STDERR " ${var}=\"${val}\"\n";
  76. }
  77. print STDERR "reqparm:\n";
  78. foreach $var (sort(keys(%$reqparm))) {
  79. $val = $$reqparm{$var};
  80. $val =~ s|\n|\\n|g;
  81. $val =~ s|"|\\"|g;
  82. print STDERR " ${var}=\"${val}\"\n";
  83. }
  84. }
  85. ########################################################################
  86. # configuration error handler
  87. ########################################################################
  88. sub bad_config {
  89. # call handler
  90. &$bad_config() if defined $bad_config;
  91. # no handler set - default action
  92. tpr(qq*
  93. Content-Type: text/html; charset=iso-8859-1
  94. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  95. "http://www.w3.org/TR/html4/loose.dtd\">
  96. <html>
  97. <head>
  98. <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  99. <title>
  100. GnuDIP Common CGI Code Error Handler
  101. </title>
  102. </head>
  103. <body>
  104. <center>
  105. <h2>
  106. Error: GnuDIP Configuration or Interface Problem Caught In Common CGI Code
  107. </h2>
  108. An internal GnuDIP operation has failed, due to a configuration error, or
  109. the failure of a system service required by GnuDIP.
  110. <p>
  111. Please report this problem to your administrator if it persists.
  112. </center>
  113. </body>
  114. </html>
  115. *);
  116. exit;
  117. }
  118. ########################################################################
  119. # read POST data from input
  120. ########################################################################
  121. sub read_post_data {
  122. my $str = '';
  123. my $str_len = 0;
  124. my $toread = $ENV{'CONTENT_LENGTH'};
  125. $toread = 0 if ! defined $toread;
  126. my $eof = '';
  127. while (!$eof and $toread > 0) {
  128. my $len = read(STDIN, $str, $toread, $str_len);
  129. if (!defined($len) || $len eq 0) {
  130. $eof = 1;
  131. } else {
  132. $str_len = $str_len + $len;
  133. $toread = $toread - $len;
  134. }
  135. }
  136. # for debugging
  137. #print STDERR "POST data = $str\n";
  138. return $str;
  139. }
  140. ########################################################################
  141. # parse query string or post data
  142. ########################################################################
  143. sub parse_query {
  144. my $str = shift;
  145. $str = '' if ! defined $str;
  146. my %parm;
  147. my @pairs = split(/\&/, $str);
  148. foreach my $pair (@pairs) {
  149. my $name;
  150. my $value;
  151. if ($pair =~ /^(.*?)=(.*)$/) {
  152. $name = $1;
  153. $value = $2;
  154. } else {
  155. $name = $pair;
  156. $value = '';
  157. }
  158. if (! defined $parm{$name}) {
  159. $parm{$name} = uri_unescape($value);
  160. } else {
  161. $parm{$name} = $parm{$name} . "\0" . uri_unescape($value);
  162. }
  163. }
  164. return \%parm;
  165. }
  166. ########################################################################
  167. # parse cookie string
  168. ########################################################################
  169. sub parse_cookies {
  170. my $str = shift;
  171. $str = '' if ! defined $str;
  172. my %cookie;
  173. my @pairs = split(/\;/, $str);
  174. foreach my $pair (@pairs) {
  175. # trim leading or trailing white space
  176. $pair =~ s/\s*(.*?)\s*/$1/;
  177. my $name;
  178. my $value;
  179. if ($pair =~ /^(.*?)=(.*)$/) {
  180. $name = $1;
  181. $value = $2;
  182. } else {
  183. $name = $pair;
  184. $value = '';
  185. }
  186. if (! defined $cookie{$name}) {
  187. $cookie{$name} = uri_unescape($value);
  188. }
  189. }
  190. return \%cookie;
  191. }
  192. ########################################################################
  193. # URI escape a string
  194. ########################################################################
  195. sub uri_escape
  196. {
  197. my $text = shift;
  198. $text = '' if !defined($text);
  199. # map unsafe characters (RFC 2732)
  200. $text =~ s/([\;\/\?\:\@\=\&\<\>\"\#\%\{\}\|\\\^\~\[\]\`\+])/sprintf("%%%02X", ord($1))/eg;
  201. return $text;
  202. }
  203. ########################################################################
  204. # unescape URI escaped string
  205. ########################################################################
  206. sub uri_unescape {
  207. my $text = shift;
  208. $text = '' if !defined($text);
  209. $text =~ tr/+/ /;
  210. $text =~ s/%([0-9a-fA-F]{2})/chr(hex($1))/eg;
  211. return $text;
  212. }
  213. ########################################################################
  214. # generate a "Set-Cookie" header
  215. ########################################################################
  216. sub printcookie {
  217. my $name = shift;
  218. my $value = shift;
  219. my $expires = shift;
  220. print
  221. "Set-Cookie: $name=" . uri_escape($value) .
  222. "; domain=$thishost; path=/; expires=" . expires($expires) . "\n";
  223. }
  224. #######################################################################
  225. # taken from CGI::Util
  226. # - default for format changed to "cookie"
  227. #######################################################################
  228. # This internal routine creates date strings suitable for use in
  229. # cookies and HTTP headers. (They differ, unfortunately.)
  230. # Thanks to Mark Fisher for this.
  231. sub expires {
  232. my($time,$format) = @_;
  233. $format ||= 'cookie';
  234. my(@MON)=qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/;
  235. my(@WDAY) = qw/Sun Mon Tue Wed Thu Fri Sat/;
  236. # pass through preformatted dates for the sake of expire_calc()
  237. $time = expire_calc($time);
  238. return $time unless $time =~ /^\d+$/;
  239. # make HTTP/cookie date string from GMT'ed time
  240. # (cookies use '-' as date separator, HTTP uses ' ')
  241. my($sc) = ' ';
  242. $sc = '-' if $format eq "cookie";
  243. my($sec,$min,$hour,$mday,$mon,$year,$wday) = gmtime($time);
  244. $year += 1900;
  245. return sprintf("%s, %02d$sc%s$sc%04d %02d:%02d:%02d GMT",
  246. $WDAY[$wday],$mday,$MON[$mon],$year,$hour,$min,$sec);
  247. }
  248. # This internal routine creates an expires time exactly some number of
  249. # hours from the current time. It incorporates modifications from
  250. # Mark Fisher.
  251. sub expire_calc {
  252. my($time) = @_;
  253. my(%mult) = ('s'=>1,
  254. 'm'=>60,
  255. 'h'=>60*60,
  256. 'd'=>60*60*24,
  257. 'M'=>60*60*24*30,
  258. 'y'=>60*60*24*365);
  259. # format for time can be in any of the forms...
  260. # "now" -- expire immediately
  261. # "+180s" -- in 180 seconds
  262. # "+2m" -- in 2 minutes
  263. # "+12h" -- in 12 hours
  264. # "+1d" -- in 1 day
  265. # "+3M" -- in 3 months
  266. # "+2y" -- in 2 years
  267. # "-3m" -- 3 minutes ago(!)
  268. # If you don't supply one of these forms, we assume you are
  269. # specifying the date yourself
  270. my($offset);
  271. if (!$time || (lc($time) eq 'now')) {
  272. $offset = 0;
  273. } elsif ($time=~/^\d+/) {
  274. return $time;
  275. } elsif ($time=~/^([+-]?(?:\d+|\d*\.\d*))([mhdMy]?)/) {
  276. $offset = ($mult{$2} || 1)*$1;
  277. } else {
  278. return $time;
  279. }
  280. return (time+$offset);
  281. }
  282. #####################################################
  283. # must return 1
  284. #####################################################
  285. 1;