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= '';
133 $emailhidechecked= '';
136 $listingarea= length $list_areai;
137 $listingoverlap= length $listoverlap;
139 defined($now= time) or die $!;
141 if ($invokestyle eq 'maintain') {
147 $threshold_recent= $now - $renew_interval;
148 $threshold_old= $threshold_recent - $expire_norenew;
150 $threshold= $now - $expire_noconfirm;
155 foreach $id (keys %db) {
158 next unless $ent->{'changed'};
159 next if $ent->{'changed'} >= $threshold_recent;
160 if ($ent->{'changed'} > $threshold_old) {
163 print "sent renewal for $id ($net)\n" or die $!;
167 printf("deleted stale %s (%s, %x %x %x)\n",
168 $id, $net, $threshold_recent, $threshold_old,
169 $ent->{'changed'}) or die $!;
171 next if $ent->{'changed'};
172 next if $ent->{'created'} >= $threshold;
174 printf("deleted new %s (%s, %x %x)\n",
175 $id, $net, $threshold, $ent->{'created'}) or die $!;
184 close STDOUT or die $!;
187 } elsif (length $in{'register'}) {
194 $ent->{'created'}= $now;
195 $ent->{'changed'}= 0;
196 $alwaysemail= $email= $in{'email'};
205 } elsif (length $in{'mailpasswd'}) {
216 } elsif (length $in{'view'}) {
226 } elsif (length $in{'update'}) {
233 $ent->{'changed'}= $now;
234 $email= length($in{'email'}) ? $in{'email'} : $db{$id}->{'email'};
241 } elsif (length $in{'delete'}) {
256 } elsif (length $in{'pick'}) {
266 } elsif (length $in{'list'}) {
269 $list_areai= $in{'listareai'};
270 list_database($in{'list'});
273 } elsif (length $in{'id'}) {
275 if (length $in{'pw'}) {
280 $ent->{'changed'}= $now;
308 sub find_areai ($$) {
309 my ($network,$prefix) = @_;
311 for ($i=0; $i<@area_networks; $i++) {
312 next unless net_subset($network,$prefix, $area_networks[$i],$area_prefixes[$i]);
319 length $in{'id'} or die;
321 exists $db{$id} or finish_error('notfound');
327 foreach $k (@db_fields) {
330 foreach $k (qw(created changed)) {
332 $$dk= gmtime($$k)." GMT";
334 $alwaysemail= $email;
335 if ($ent->{'hiddenemail'} && !$justcreated && \
336 !$fulldetails && !$justupdated && !$deleted) {
342 $net= display_net($network,$prefix);
343 $emailhidechecked= $ent->{'hiddenemail'} ? 'checked' : '';
348 my ($v, $b, @b, $val, $mask);
351 ($network,$prefix,$val,$mask) = parse_netrange($net);
352 print DEBUG "set_entry parsed netrange $network $prefix\n";
353 $current_areai= find_areai($network,$prefix);
354 print DEBUG "$current_areai\n";
355 $current_areai>=0 or finish_error("wrongnet");
358 foreach $v (qw(name contact email)) {
359 $$v= $in{$v} unless $v eq 'email';
360 length $$v or finish_error("no$v");
361 finish_error("badchar") unless $$v =~ m/^[ -\176\240\376]+$/; $$v= $&;
363 $hiddenemail= !!length $in{'hiddenemail'};
365 foreach $k (qw(network prefix name contact email hiddenemail)) {
373 my ($ai, $k, $vn, $rand, $mask, $fixmask, $value);
375 $ai= $in{'from'}; $ai =~ m/\d+/ or die "$ai ?"; $ai= $&;
376 ($ai>=0 && $ai<@area_networks) or die "$ai ?";
379 foreach $k (qw(24 28 prefix subnet)) { $vn= "pick${k}check"; $$vn= ''; }
380 foreach $k (qw(prefix subnet)) { $vn= "pickvar${k}"; $$vn= $in{$vn}; }
385 $vn= "pick${specsize}check"; $$vn= 'checked';
386 } elsif (m/prefix|subnet/) {
388 $vn= "pickvar${which}check"; $$vn= 'checked';
389 $specsize= $in{"pickvar${which}"};
390 $specsize =~ m/\d+/ or finish_error('badsize');
392 ($specsize >= 0 && $specsize <= 32) or finish_error('badsize');
393 $specsize= 32-$specsize if $which eq 'subnet';
398 $network= $area_networks[$ai];
399 $prefix= $area_prefixes[$ai];
400 $net= display_net($network,$prefix);
401 ($specsize >= $prefix) or finish_error('wrongsize');
403 $fixmask= get_mask($prefix);
404 $mask= get_mask($specsize);
407 $value= hex($network) | ($rand & ($mask & ~$fixmask));
408 $vhex= sprintf '%08x',$value;
410 $net= display_net($vhex,$specsize);
413 printf DEBUG "picking network=$network prefix=$prefix net=$net specsize=$specsize\n";
414 printf DEBUG "picking rnybs=%s fixmask=%08x mask=%08x rand=%08x ".
415 "value=%08x vhex=%s net=%s\n",
416 $rnybs,$fixmask,$mask,$rand,$value,$vhex,$net;
420 $ent->{'network'}= $vhex;
421 $ent->{'prefix'}= $specsize;
423 list_database('area');
426 sub finish_error ($) {
429 foreach $t (qw(noemail nonet noname nocontact badsize wrongsize badnet wrongnet
430 nopassword badpassword notfound badchar)) {
436 $esel= "error_$type";
443 process_file('template.html');
444 print $out or die $!;
445 close STDOUT or die $!;
449 sub foreach_start_area { $area_i=0; }
450 sub foreach_cond_area { return $area_i < @area_networks; }
451 sub foreach_incr_area { $area_i++; }
452 sub foreach_setvars_area {
453 $area_network= $area_networks[$area_i];
454 $area= display_net($area_network,$area_prefixes[$area_i]);
455 $area_recommended= $area_i==$rec_areai;
456 $area_pickchecked= $area_i==$current_areai ? 'checked' : '';
457 $area_listing= $area_i eq $list_areai;
458 # out("<!-- setvars_area @area_networks $area_i $area $list_areai -->");