?? vmail.cgi
字號:
#!/usr/bin/perl## Web based Voicemail for Asterisk## Copyright (C) 2002, Linux Support Services, Inc.## Distributed under the terms of the GNU General Public License## Written by Mark Spencer <markster@linux-support.net>## (icky, I know.... if you know better perl please help!)### Synchronization added by GDS Partners (www.gdspartners.com)# Stojan Sljivic (stojan.sljivic@gdspartners.com)#use CGI qw/:standard/;use Carp::Heavy;use CGI::Carp qw(fatalsToBrowser);use DBI;use Fcntl qw ( O_WRONLY O_CREAT O_EXCL );use Time::HiRes qw ( usleep );$context=""; # Define here your by default context (so you dont need to put voicemail@context in the login)@validfolders = ( "INBOX", "Old", "Work", "Family", "Friends", "Cust1", "Cust2", "Cust3", "Cust4", "Cust5" );%formats = ( "wav" => { name => "Uncompressed WAV", mime => "audio/x-wav", pref => 1 }, "WAV" => { name => "GSM Compressed WAV", mime => "audio/x-wav", pref => 2 }, "gsm" => { name => "Raw GSM Audio", mime => "audio/x-gsm", pref => 3 });$astpath = "/_asterisk";$stdcontainerstart = "<table align=center width=600><tr><td>\n";$footer = "<hr><font size=-1><a href=\"http://www.asterisk.org\">The Asterisk Open Source PBX</a> Copyright 2004-2008, <a href=\"http://www.digium.com\">Digium, Inc.</a></a>";$stdcontainerend = "</td></tr><tr><td align=right>$footer</td></tr></table>\n";sub lock_path($) { my($path) = @_; my $rand; my $rfile; my $start; my $res; $rand = rand 99999999; $rfile = "$path/.lock-$rand"; sysopen(RFILE, $rfile, O_WRONLY | O_CREAT | O_EXCL, 0666) or return -1; close(RFILE); $res = link($rfile, "$path/.lock"); $start = time; if ($res == 0) { while (($res == 0) && (time - $start <= 5)) { $res = link($rfile, "$path/.lock"); usleep(1); } } unlink($rfile); if ($res == 0) { return -1; } else { return 0; }}sub unlock_path($) { my($path) = @_; unlink("$path/.lock");}sub untaint($) { my($data) = @_; if ($data =~ /^([-\@\w.]+)$/) { $data = $1; } else { die "Security violation."; } return $data;}sub login_screen($) { print header; my ($message) = @_; print <<_EOH;<TITLE>Asterisk Web-Voicemail</TITLE><BODY BGCOLOR="white">$stdcontainerstart<FORM METHOD="post"><input type=hidden name="action" value="login"><table align=center><tr><td valign=top align=center rowspan=6><img align=center src="$astpath/animlogo.gif"></td></tr><tr><td align=center colspan=2><font size=+2>Comedian Mail Login</font></td></tr><tr><td align=center colspan=2><font size=+1>$message</font></td></tr><tr><td>Mailbox:</td><td><input type=text name="mailbox"></td></tr><tr><td>Password:</td><td><input type=password name="password"></td></tr><tr><td align=right colspan=2><input value="Login" type=submit></td></tr><input type=hidden name="context" value="$context"></table></FORM>$stdcontainerend</BODY>\n_EOH}sub check_login($$){ local ($filename, $startcat) = @_; local ($mbox, $context) = split(/\@/, param('mailbox')); local $pass = param('password'); local $category = $startcat; local @fields; local $tmp; local (*VMAIL); if (!$category) { $category = "general"; } if (!$context) { $context = param('context'); } if (!$context) { $context = "default"; } if (!$filename) { $filename = "/etc/asterisk/voicemail.conf"; }# print header;# print "Including <h2>$filename</h2> while in <h2>$category</h2>...\n"; open(VMAIL, "<$filename") || die("Bleh, no $filename"); while(<VMAIL>) { chomp; if (/include\s\"([^\"]+)\"$/) { ($tmp, $category) = &check_login("/etc/asterisk/$1", $category); if (length($tmp)) {# print "Got '$tmp'\n"; return ($tmp, $category); } } elsif (/\[(.*)\]/) { $category = $1; } elsif ($category eq "general") { if (/([^\s]+)\s*\=\s*(.*)/) { if ($1 eq "dbname") { $dbname = $2; } elsif ($1 eq "dbpass") { $dbpass = $2; } elsif ($1 eq "dbhost") { $dbhost = $2; } elsif ($1 eq "dbuser") { $dbuser = $2; } } if ($dbname and $dbpass and $dbhost and $dbuser) { # db variables are present. Use db for authentication. my $dbh = DBI->connect("DBI:mysql:$dbname:$dbhost",$dbuser,$dbpass); my $sth = $dbh->prepare(qq{select fullname,context from voicemail where mailbox='$mbox' and password='$pass' and context='$context'}); $sth->execute(); if (($fullname, $category) = $sth->fetchrow_array()) { return ($fullname ? $fullname : "Extension $mbox in $context",$category); } } } elsif (($category ne "general") && ($category ne "zonemessages")) { if (/([^\s]+)\s*\=\>?\s*(.*)/) { @fields = split(/\,\s*/, $2);# print "<p>Mailbox is $1\n"; if (($mbox eq $1) && (($pass eq $fields[0]) || ("-${pass}" eq $fields[0])) && ($context eq $category)) { return ($fields[1] ? $fields[1] : "Extension $mbox in $context", $category); } } } } close(VMAIL); return check_login_users();}sub check_login_users { my ($mbox, $context) = split(/\@/, param('mailbox')); my $pass = param('password'); my ($found, $fullname) = (0, ""); open VMAIL, "</etc/asterisk/users.conf"; while (<VMAIL>) { chomp; if (m/\[(.*)\]/) { if ($1 eq $mbox) { $found = 1; } elsif ($found == 2) { close VMAIL; return (($fullname ? $fullname : "Extension $mbox in $context"), $context); } else { $found = 0; } } elsif ($found) { my ($var, $value) = split /\s*=\s*/, $_, 2; if ($var eq 'vmsecret' and $value eq $pass) { $found = 2; } elsif ($var eq 'fullname') { $fullname = $value; if ($found == 2) { close VMAIL; return ($fullname, $context); } } } } close VMAIL; return ("", "");}sub validmailbox($$$$){ local ($context, $mbox, $filename, $startcat) = @_; local $category = $startcat; local @fields; local (*VMAIL); if (!$context) { $context = param('context'); } if (!$context) { $context = "default"; } if (!$filename) { $filename = "/etc/asterisk/voicemail.conf"; } if (!$category) { $category = "general"; } open(VMAIL, "<$filename") || die("Bleh, no $filename"); while (<VMAIL>) { chomp; if (/include\s\"([^\"]+)\"$/) { ($tmp, $category) = &validmailbox($mbox, $context, "/etc/asterisk/$1"); if ($tmp) { return ($tmp, $category); } } elsif (/\[(.*)\]/) { $category = $1; } elsif ($category eq "general") { if (/([^\s]+)\s*\=\s*(.*)/) { if ($1 eq "dbname") { $dbname = $2; } elsif ($1 eq "dbpass") { $dbpass = $2; } elsif ($1 eq "dbhost") { $dbhost = $2; } elsif ($1 eq "dbuser") { $dbuser = $2; } } if ($dbname and $dbpass and $dbhost and $dbuser) { # db variables are present. Use db for authentication. my $dbh = DBI->connect("DBI:mysql:$dbname:$dbhost",$dbuser,$dbpass); my $sth = $dbh->prepare(qq{select fullname,context from voicemail where mailbox='$mbox' and password='$pass' and context='$context'}); $sth->execute(); if (($fullname, $context) = $sth->fetchrow_array()) { return ($fullname ? $fullname : "unknown", $category); } } } elsif (($category ne "general") && ($category ne "zonemessages") && ($category eq $context)) { if (/([^\s]+)\s*\=\>?\s*(.*)/) { @fields = split(/\,\s*/, $2); if (($mbox eq $1) && ($context eq $category)) { return ($fields[2] ? $fields[2] : "unknown", $category); } } } } return ("", $category);}sub mailbox_options(){ local($context, $current, $filename, $category) = @_; local (*VMAIL); local $tmp2; local $tmp; if (!$filename) { $filename = "/etc/asterisk/voicemail.conf"; } if (!$category) { $category = "general"; }# print header;# print "Including <h2>$filename</h2> while in <h2>$category</h2>...\n"; open(VMAIL, "<$filename") || die("Bleh, no voicemail.conf"); while(<VMAIL>) { chomp; s/\;.*$//; if (/include\s\"([^\"]+)\"$/) { ($tmp2, $category) = &mailbox_options($context, $current, "/etc/asterisk/$1", $category);# print "Got '$tmp2'...\n"; $tmp .= $tmp2; } elsif (/\[(.*)\]/) { $category = $1; } elsif ($category eq "general") { if (/([^\s]+)\s*\=\s*(.*)/) { if ($1 eq "dbname") { $dbname = $2; } elsif ($1 eq "dbpass") { $dbpass = $2; } elsif ($1 eq "dbhost") { $dbhost = $2; } elsif ($1 eq "dbuser") { $dbuser = $2; } } if ($dbname and $dbpass and $dbhost and $dbuser) { # db variables are present. Use db for authentication. my $dbh = DBI->connect("DBI:mysql:$dbname:$dbhost",$dbuser,$dbpass); my $sth = $dbh->prepare(qq{select mailbox,fullname,context from voicemail where context='$context' order by mailbox}); $sth->execute(); while (($mailbox, $fullname, $category) = $sth->fetchrow_array()) { $text = $mailbox; if ($fullname) { $text .= " (".$fullname.")"; } if ($mailbox eq $current) { $tmp .= "<OPTION SELECTED>$text</OPTION>\n"; } else { $tmp .= "<OPTION>$text</OPTION>\n"; } } return ($tmp, $category); } } elsif (($category ne "general") && ($category ne "zonemessages")) { if (/([^\s]+)\s*\=\>?\s*(.*)/) { @fields = split(/\,\s*/, $2); $text = "$1"; if ($fields[1]) { $text .= " ($fields[1])"; } if ($1 eq $current) { $tmp .= "<OPTION SELECTED>$text</OPTION>\n"; } else { $tmp .= "<OPTION>$text</OPTION>\n"; } } } } close(VMAIL); return ($tmp, $category);}sub mailbox_list(){ local ($name, $context, $current) = @_; local $tmp; local $text; local $tmp; local $opts; if (!$context) { $context = "default"; } $tmp = "<SELECT name=\"$name\">\n"; ($opts) = &mailbox_options($context, $current); $tmp .= $opts; $tmp .= "</SELECT>\n"; }sub msgcount() { my ($context, $mailbox, $folder) = @_; my $path = "/var/spool/asterisk/voicemail/$context/$mailbox/$folder"; if (opendir(DIR, $path)) { my @msgs = grep(/^msg....\.txt$/, readdir(DIR)); closedir(DIR); return sprintf "%d", $#msgs + 1; } return "0";}sub msgcountstr(){ my ($context, $mailbox, $folder) = @_; my $count = &msgcount($context, $mailbox, $folder); if ($count > 1) { "$count messages"; } elsif ($count > 0) { "$count message"; } else { "no messages"; }}sub messages(){ my ($context, $mailbox, $folder) = @_; my $path = "/var/spool/asterisk/voicemail/$context/$mailbox/$folder"; if (opendir(DIR, $path)) { my @msgs = sort grep(/^msg....\.txt$/, readdir(DIR)); closedir(DIR); return map { s/^msg(....)\.txt$/$1/; $_ } @msgs; } return ();}sub getcookie(){ my ($var) = @_; return cookie($var);}sub makecookie(){ my ($format) = @_; cookie(-name => "format", -value =>["$format"], -expires=>"+1y");}sub getfields(){ my ($context, $mailbox, $folder, $msg) = @_; my $fields; if (open(MSG, "</var/spool/asterisk/voicemail/$context/$mailbox/$folder/msg${msg}.txt")) { while(<MSG>) { s/\#.*$//g; if (/^(\w+)\s*\=\s*(.*)$/) { $fields->{$1} = $2; } } close(MSG); $fields->{'msgid'} = $msg; } else { print "<BR>Unable to open '$msg' in '$mailbox', '$folder'\n<B>"; } $fields;}sub message_prefs(){ my ($nextaction, $msgid) = @_; my $folder = param('folder'); my $mbox = param('mailbox'); my $context = param('context'); my $passwd = param('password'); my $format = param('format'); if (!$format) { $format = &getcookie('format'); } print header; print <<_EOH;<TITLE>Asterisk Web-Voicemail: Preferences</TITLE><BODY BGCOLOR="white">$stdcontainerstart<FORM METHOD="post"><table width=100% align=center><tr><td align=right colspan=3><font size=+2>Web Voicemail Preferences</font></td></tr><tr><td align=left><font size=+1>Preferred Audio Format:</font></td><td colspan=2></td></tr>_EOHforeach $fmt (sort { $formats{$a}->{'pref'} <=> $formats{$b}->{'pref'} } keys %formats) { my $clicked = "checked" if $fmt eq $format; print "<tr><td></td><td align=left><input type=radio name=\"format\" $clicked value=\"$fmt\"></td><td width=100%> $formats{$fmt}->{name}</td></tr>\n";}print <<_EOH;<tr><td align=right colspan=3><input type=submit value="save settings..."></td></tr></table><input type=hidden name="action" value="$nextaction"><input type=hidden name="folder" value="$folder"><input type=hidden name="mailbox" value="$mbox"><input type=hidden name="context" value="$context"><input type=hidden name="password" value="$passwd"><input type=hidden name="msgid" value="$msgid">$stdcontainerend</BODY>\n_EOH}sub message_play(){ my ($message, $msgid) = @_; my $folder = param('folder'); my ($mbox, $context) = split(/\@/, param('mailbox')); my $passwd = param('password'); my $format = param('format'); my $fields; if (!$context) { $context = param('context'); } if (!$context) { $context = "default"; } my $folders = &folder_list('newfolder', $context, $mbox, $folder); my $mailboxes = &mailbox_list('forwardto', $context, $mbox); if (!$format) { $format = &getcookie('format'); } if (!$format) { &message_prefs("play", $msgid); } else { print header(-cookie => &makecookie($format)); $fields = &getfields($context, $mbox, $folder, $msgid); if (!$fields) { print "<BR>Bah!\n"; return; } my $duration = $fields->{'duration'}; if ($duration) { $duration = sprintf "%d:%02d", $duration/60, $duration % 60; } else { $duration = "<i>Unknown</i>"; } print <<_EOH; <TITLE>Asterisk Web-Voicemail: $folder Message $msgid</TITLE><BODY BGCOLOR="white">$stdcontainerstart<FORM METHOD="post"><table width=100% align=center><tr><td align=right colspan=3><font size=+1>$folder Message $msgid</font></td></tr>_EOH print <<_EOH;<tr><td align=center colspan=3><table> <tr><td colspan=2 align=center><font size=+1>$folder <b>$msgid</b></font></td></tr> <tr><td><b>Message:</b></td><td>$msgid</td></tr>\n <tr><td><b>Mailbox:</b></td><td>$mbox\@$context</td></tr>\n <tr><td><b>Folder:</b></td><td>$folder</td></tr>\n <tr><td><b>From:</b></td><td>$fields->{callerid}</td></tr>\n <tr><td><b>Duration:</b></td><td>$duration</td></tr>\n <tr><td><b>Original Date:</b></td><td>$fields->{origdate}</td></tr>\n <tr><td><b>Original Mailbox:</b></td><td>$fields->{origmailbox}</td></tr>\n <tr><td><b>Caller Channel:</b></td><td>$fields->{callerchan}</td></tr>\n <tr><td align=center colspan=2> <input name="action" type=submit value="index"> <input name="action" type=submit value="delete "> <input name="action" type=submit value="forward to -> "> $mailboxes <input name="action" type=submit value="save to ->"> $folders <input name="action" type=submit value="play "> <input name="action" type=submit value="download"></td></tr><tr><td colspan=2 align=center><embed width=400 height=40 src="vmail.cgi?action=audio&folder=$folder&mailbox=$mbox&context=$context&password=$passwd&msgid=$msgid&format=$format&dontcasheme=$$.$format" autostart=yes loop=false></embed></td></tr></table></td></tr></table><input type=hidden name="folder" value="$folder"><input type=hidden name="mailbox" value="$mbox"><input type=hidden name="context" value="$context"><input type=hidden name="password" value="$passwd"><input type=hidden name="msgid" value="$msgid">
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -