#!/usr/bin/perl # $Source: /srv/cvs/asterisk/cgi-bin/snom,v $ # $Id: snom,v 1.9 2009-06-18 18:51:39 cnw Exp $ # Copyright 2008 Conrad Wood # script to provision SNOM phones # put this into apaches cgi-bin # configure DHCP like so: #option subnet-mask 255.255.255.0; #default-lease-time 3600; #max-lease-time 7200; #next-server 192.168.110.1; #option ntp-servers 192.168.110.1; #subnet 192.168.110.0 netmask 255.255.255.0 { # range 192.168.110.10 192.168.110.200; # option broadcast-address 192.168.110.255; # option routers 192.168.110.4; # next-server 192.168.110.1; # option tftp-server-name "http://192.168.110.1"; # filename "cgi-bin/snom?event=boot&mac={mac}"; # option bootfile-name "cgi-bin/snom?event=boot&mac={mac}"; #} # put your main cfg file in /etc/snom/default.cfg # and one file for each phone in /etc/snom/[mac] with the phone-specific parameters # point your browser at http://[server]/cgi-bin/snom # to edit the snom phone entries use strict; use CGI; my $DEFAULTFILE="/etc/snom/default.cfg"; my $form = new CGI(); my $mac = $form->param("mac"); my $event = $form->param("event"); unless(defined($event)) { $event="boot"; } print "Content-Type: text/html\n\n"; if ($event eq "boot") { doBoot(); } elsif ($event eq "edit") { doEdit(); } elsif ($event eq "registerfailure") { my $ip = $ENV{REMOTE_ADDR}; system("mail","-s","Register failure on $ip","cnw\@conradwood.net"); } exit 0; sub doEdit { if ( (!defined($mac) ) || (length($mac) == 0)) { print ""; askMac(); print "\n"; return; } my $cmac = cleanMac($mac); unless (defined($cmac)) { print "Invalid mac: $mac (12 characters, only a-f and 0-9 allowed)\n"; print ""; askMac(); print "\n"; return; } my $filename = "/etc/snom/$cmac.cfg"; my $edit_username=$form->param("edit_username"); my $edit_extension=$form->param("edit_extension"); if (defined($edit_username)) { my $fmac = findExtension($edit_extension); if ( (defined($fmac)) && ( $fmac ne $cmac) ) { print "Error. extension $edit_extension is already allocated to mac address $fmac
"; } else { # save... open FH,">$filename" or fatal_error("Cannot open $filename: $!"); print FH "user_realname1: $edit_username user_name1: $edit_extension user_pname1: $edit_extension user_mailbox1: $edit_extension user_idle_text1: $edit_username ($edit_extension) "; close(FH); print ""; print "Saved - Please reboot the phone now.
\n"; askMac(); print "\n"; return; } } # edit my $res = (); if ( -f $filename) { $res = readHash($filename); } my $editusername=$res->{"user_realname1"}; my $editextension=$res->{"user_pname1"}; print ""; print "
\n"; print "Username:
\n"; print "Extension:
\n"; print "\n"; print "\n"; print "
\n"; print "
\n"; print "\n"; } # give string, returns mac sub cleanMac() { my $xmac = shift; $xmac =~ s/^ *//g; $xmac =~ s/ *$//g; $xmac = uc($xmac); unless ( (length($xmac) == 12) && ($xmac =~ /^[0-9A-F]*$/) ){ return undef; } return $xmac; } # ask user to choose or enter a mac address sub askMac() { print "
\n"; print "Please enter Mac address: \n"; print "\n"; print "
\n"; print "
\n"; print "or choose from the list below:\n"; opendir DH,"/etc/snom" or fatal_error("Unable to open /etc/snom: $!"); print "\n"; print ""; my @files = readdir DH; foreach my $file (@files) { if ( ( "$file" eq ".") || ("$file" eq "..") ) { next ; } insertTableFile($file); } print "
MACextensionusername
"; closedir(DH); } sub insertTableFile { my $filename = shift; my $thismac = $filename; $thismac =~ s/.cfg$//; $filename = "/etc/snom/$filename"; my $settings = readHash($filename); print "" . editLink($thismac) . "" . "" . $settings->{"user_name1"} . "" . "" . $settings->{"user_realname1"} . "" . "\n"; } sub editLink { my $mac = shift; return "$mac"; } sub doBoot { print "\n
\n#comment\n";
  if ( (!defined($mac) ) || (length($mac) == 0)) {
    fatal_error("Mac undefined");
  }
  my $peer = mac_settings($mac);
  unless ( defined($peer) ) {
    fatal_error("no peer for mac $mac");
  }
  my $default = readHash($DEFAULTFILE);
  foreach my $name (keys(%{$peer})) {
    $default->{$name} = $peer->{$name};
  }
  foreach my $name (sort(keys(%{$default}))) {
    print "$name: " . $default->{$name} . "\n";
  }
  print "
\n\n"; } # given a mac will return the specific settings sub mac_settings { my $mac = shift; $mac = uc($mac); my $filename = "/etc/snom/$mac.cfg"; return readHash("$filename"); } sub readHash { my $filename = shift; open FH,"<$filename" or fatal_error("Missing file $filename: $!"); my @lines = ; close(FH); my %res = (); foreach my $line (@lines) { $line =~ s/\n//; $line =~ s/\r//; my @valx = split(":",$line); my $name = shift @valx; my $val = join(":",@valx); if ( defined($name) && defined($val) && (length($name)>0 ) && (length($val) > 0)) { $val =~ s/^ *//; $res{$name} = $val; } } return \%res; } # given a peer, returns mac or undef sub findExtension { my $peer = shift; opendir DH,"/etc/snom" or die("Unable to open dir /etc/snom: $!"); my @files = readdir(DH); closedir(DH); foreach my $file (@files) { if ( ($file eq ".") || ($file eq "..") ) { next; } my $p = readHash("/etc/snom/$file"); if ( $p->{"user_pname1"} eq $peer ) { my $mac = $file; $mac =~ s/.cfg$//; return $mac; } } return undef; } sub fatal_error { my $txt = shift; print STDOUT "$txt\n"; die("$txt"); }