2 # Main G-RIN CGI script code. Must be invoked with --cgi if
3 # as a CGI script - see the example file cam-grin.
5 # Copyright (C) 1999 Ian Jackson <ijackson@chiark.greenend.org.uk>
7 # This is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as
9 # published by the Free Software Foundation; either version 2,
10 # or (at your option) any later version.
12 # This is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public
18 # License along with this file; if not, write to the Free Software
19 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 if ($ARGV[0] eq '--cgi') {
29 } elsif ($ARGV[0] eq '--expire-noconfirm') {
31 $invokestyle= 'maintain';
32 } elsif ($ARGV[0] eq '--expire-norenew') {
34 $invokestyle= 'maintain';
36 } elsif ($ARGV[0] =~ m/^--/) {
38 } elsif ($ENV{'SERVER_SOFTWARE'} =~ m/^Lynx/) {
39 $invokestyle= 'lynxcgi';
41 $invokestyle= 'manual';
44 if ($invokestyle eq 'manual') {
45 open DEBUG,">&STDERR" or die $!;
46 } elsif ($invokestyle eq 'lynxcgi') {
47 open DEBUG,">>debug.txt" or die $!;
48 } elsif ($invokestyle eq 'cgi' || $invokestyle eq 'maintain') {
49 open DEBUG,">/dev/null" or die $!;
52 if ($invokestyle eq 'cgi' || $invokestyle eq 'maintain') {
53 $scriptdir= shift @ARGV;
54 $datadir= shift @ARGV;
60 if (!($invokestyle eq 'manual' || $invokestyle eq 'maintain')) {
61 $ct= 'BCP5REGISTRY_CONTENTTYPEDONE';
64 print "Content-Type: text/html\n\n" or die $!;
71 chdir($datadir) or die $!;
74 require 'database.pl';
76 require 'networks.pl';
78 require 'passwords.pl';
80 if (!($invokestyle eq 'manual' || $invokestyle eq 'maintain')) {
84 foreach $k (keys %in) { print DEBUG "$k -> \"$in{$k}\"\n"; }
87 $x =~ m/^(\w+)\=/ or die "$x ?";
89 print DEBUG "$1 -> \"$'\"\n";
93 if ($invokestyle eq 'lynxcgi') {
94 defined($pwd= getcwd) or die $!;
96 $cgi= "lynxcgi:$pwd/$_";
99 @area_networks= qw(0a000000 ac100000 c0a80000);
100 @area_prefixes= qw(8 12 16);
103 $current_areai= $rec_areai;
116 $pick24check= 'checked';
117 $pickvarsubnetcheck= '';
118 $pickvarprefixcheck= '';
125 $listingviewoverlap= 0;
134 $emailhidechecked= '';
137 $listingarea= length $list_areai;
138 $listingoverlap= length $listoverlap;
140 defined($now= time) or die $!;
142 if ($invokestyle eq 'maintain') {
148 $threshold_recent= $now - $renew_interval;
149 $threshold_old= $threshold_recent - $expire_norenew;
151 $threshold= $now - $expire_noconfirm;
156 foreach $id (keys %db) {
159 next unless $ent->{'changed'};
160 next if $ent->{'changed'} >= $threshold_recent;
161 if ($ent->{'changed'} > $threshold_old) {
164 print "sent renewal for $id ($net)\n" or die $!;
168 printf("deleted stale %s (%s, %x %x %x)\n",
169 $id, $net, $threshold_recent, $threshold_old,
170 $ent->{'changed'}) or die $!;
172 next if $ent->{'changed'};
173 next if $ent->{'created'} >= $threshold;
175 printf("deleted new %s (%s, %x %x)\n",
176 $id, $net, $threshold, $ent->{'created'}) or die $!;
185 close STDOUT or die $!;
188 } elsif (length $in{'register'}) {
195 $ent->{'created'}= $now;
196 $ent->{'changed'}= 0;
197 $alwaysemail= $email= $in{'email'};
206 } elsif (length $in{'mailpasswd'}) {
217 } elsif (length $in{'view'}) {
227 } elsif (length $in{'update'}) {
234 $ent->{'changed'}= $now;
235 $email= length($in{'email'}) ? $in{'email'} : $db{$id}->{'email'};
242 } elsif (length $in{'delete'}) {
257 } elsif (length $in{'pick'}) {
267 } elsif (length $in{'list'}) {
270 $list_areai= $in{'listareai'};
271 list_database($in{'list'});
274 } elsif (length $in{'id'}) {
276 if (length $in{'pw'}) {
281 $ent->{'changed'}= $now;
310 sub find_areai ($$) {
311 my ($network,$prefix) = @_;
313 for ($i=0; $i<@area_networks; $i++) {
314 next unless net_subset($network,$prefix, $area_networks[$i],$area_prefixes[$i]);
321 length $in{'id'} or die;
323 exists $db{$id} or finish_error('notfound');
329 foreach $k (@db_fields) {
332 foreach $k (qw(created changed)) {
334 $$dk= gmtime($$k)." GMT";
336 $alwaysemail= $email;
337 if ($ent->{'hiddenemail'} && !$justcreated && \
338 !$fulldetails && !$justupdated && !$deleted) {
344 $net= display_net($network,$prefix);
345 $emailhidechecked= $ent->{'hiddenemail'} ? 'checked' : '';
346 list_database('viewoverlap');
350 my ($v, $b, @b, $val, $mask);
353 ($network,$prefix,$val,$mask) = parse_netrange($net);
354 print DEBUG "set_entry parsed netrange $network $prefix\n";
355 $current_areai= find_areai($network,$prefix);
356 print DEBUG "$current_areai\n";
357 $current_areai>=0 or finish_error("wrongnet");
360 foreach $v (qw(name contact email)) {
361 $$v= $in{$v} unless $v eq 'email';
362 length $$v or finish_error("no$v");
363 finish_error("badchar") unless $$v =~ m/^[ -\176\240\376]+$/; $$v= $&;
365 $hiddenemail= !!length $in{'hiddenemail'};
367 foreach $k (qw(network prefix name contact email hiddenemail)) {
375 my ($ai, $k, $vn, $rand, $mask, $fixmask, $value);
377 $ai= $in{'from'}; $ai =~ m/\d+/ or die "$ai ?"; $ai= $&;
378 ($ai>=0 && $ai<@area_networks) or die "$ai ?";
381 foreach $k (qw(24 28 prefix subnet)) { $vn= "pick${k}check"; $$vn= ''; }
382 foreach $k (qw(prefix subnet)) { $vn= "pickvar${k}"; $$vn= $in{$vn}; }
387 $vn= "pick${pick_prefix}check"; $$vn= 'checked';
388 } elsif (m/prefix|subnet/) {
390 $vn= "pickvar${which}check"; $$vn= 'checked';
391 $pick_prefix= $in{"pickvar${which}"};
392 $pick_prefix =~ m/\d+/ or finish_error('badsize');
394 ($pick_prefix >= 0 && $pick_prefix <= 32) or finish_error('badsize');
395 $pick_prefix= 32-$pick_prefix if $which eq 'subnet';
400 $network= $area_networks[$ai];
401 $prefix= $area_prefixes[$ai];
402 $net= display_net($network,$prefix);
403 ($pick_prefix >= $prefix) or finish_error('wrongsize');
405 $fixmask= get_mask($prefix);
406 $mask= get_mask($pick_prefix);
409 $value= hex($network) | ($rand & ($mask & ~$fixmask));
410 $pick_network= sprintf '%08x',$value;
412 $net= display_net($pick_network,$pick_prefix);
415 printf DEBUG "picking network=$network prefix=$prefix net=$net pick_prefix=$pick_prefix\n";
416 printf DEBUG "picking rnybs=%s fixmask=%08x mask=%08x rand=%08x ".
417 "value=%08x pick_network=%s net=%s\n",
418 $rnybs,$fixmask,$mask,$rand,$value,$pick_network,$net;
422 $ent->{'network'}= $pick_network;
423 $ent->{'prefix'}= $pick_prefix;
425 list_database('area');
428 sub finish_error ($) {
431 foreach $t (qw(noemail nonet noname nocontact badsize wrongsize badnet wrongnet
432 nopassword badpassword notfound badchar)) {
438 $esel= "error_$type";
445 process_file('template.html');
446 print $out or die $!;
447 close STDOUT or die $!;
451 sub foreach_start_area { $area_i=0; }
452 sub foreach_cond_area { return $area_i < @area_networks; }
453 sub foreach_incr_area { $area_i++; }
454 sub foreach_setvars_area {
455 $area_network= $area_networks[$area_i];
456 $area= display_net($area_network,$area_prefixes[$area_i]);
457 $area_recommended= $area_i==$rec_areai;
458 $area_pickchecked= $area_i==$current_areai ? 'checked' : '';
459 $area_listing= $area_i eq $list_areai;
460 # out("<!-- setvars_area @area_networks $area_i $area $list_areai -->");