#!/usr/bin/perl

$etcdir= '/etc/userv/ipif';
chdir($etcdir) or die "$0: chdir $etcdir: $!\n";

$descallowd= '-][()+_\'":=;,./|';

sub usage () {
    die <<END;
Allocates an RFC1918 address and records it
usage: userv ipif-alloc <group|gid> [<prefix>]/<size> <description>
<description> may contain alphanums, spaces and $descallowed
END
}

@ARGV==3 or usage();
($group, $pfxsize, $desc) = @ARGV;

$super= 0;

open X, "config" or die "$0: open config: $!\n";
while (<X>) {
    next if m/^\#/;
    next if !m/\S/;
    chomp; s/\s+$//;
    if (m/^supergroup\s+(\w+)$/) {
	$super= am_gid($1);
    } elsif (m/^maxpergid\s+(\d+)$/) {
	$maxpergid= $1;
    } elsif (m,^range\s+([.0-9]+)/(\d+)$,) {
	($allow_p, $allow_m, $allow_l) = parse_range($1,$2);
    } else {
	die "$0: config:$.: unknown directive: $_\n";
    }
}
close X or die "$0: read config: $!\n";

if ($pfxsize =~ m,^([.0-9]+)/(\d+)$,) {
    ($want_p, $want_m, $want_l) = parse_range($1,$2);
    if (!$super && !overlap($want_p,$want_m, $allow_p,$allow_m)) {
	die "$0: permission denied (out of required range)\n";
    }
} elsif ($pfxsize =~ m,^/(\d+)$,) {
    undef $want_p;
    undef $want_m;
    $want_l= $1;
} else {
    die "$0: bad request: $pfxsize\n";
}

$gid= get_gid($group);
if (!am_gid($gid)) {
    die "$0: you are not gid $gid\n";
}

$op.= '';
$max_p= 0; $max_m= 0;

open Y, "auto-nets" or die "$0: open auto-nets: $!\n";
for (;;) {
    $!= 0; chomp($_= <Y>);
    length or die "$0: read auto-nets: $!\n";
    last if m/^\#end/;
    next if m/^\#/;
    $op.= $_."\n";
    m:^(\d+),([.0-9]+)/(\d+),.*: or die "$0: auto-nets:$.: syntax error: $_\n";
    $this_gid= $1;
    ($this_p, $this_m, $this_l) = parse_range($2,$3);
    if (defined($want_p)) {
	if (overlap($want_p,$want_m, $this_p,$this_m)) {
	    die "$0: overlaps with existing allocation (auto-nets:$.)\n";
	}
    } else {
	if ($this_p > $max_p) {
	    ($this_p,$this_m) = ($max_p,$max_m);
	}
    }
    
    
    next if $1 ne $gid;
    
