3 # Web based Voicemail for Asterisk
5 # Copyright (C) 2002, Linux Support Services, Inc.
7 # Distributed under the terms of the GNU General Public License
9 # Written by Mark Spencer <markster@linux-support.net>
11 # (icky, I know.... if you know better perl please help!)
14 # Synchronization added by GDS Partners (www.gdspartners.com)
15 # Stojan Sljivic (stojan.sljivic@gdspartners.com)
17 use CGI qw
/:standard/;
19 use CGI
::Carp
qw(fatalsToBrowser);
21 use Fcntl qw
( O_WRONLY O_CREAT O_EXCL
);
22 use Time
::HiRes qw
( usleep
);
24 $context=""; # Define here your by default context (so you dont need to put voicemail@context in the login)
26 @validfolders = ( "INBOX", "Old", "Work", "Family", "Friends", "Cust1", "Cust2", "Cust3", "Cust4", "Cust5" );
30 name
=> "Uncompressed WAV",
31 mime
=> "audio/x-wav",
35 name
=> "GSM Compressed WAV",
36 mime
=> "audio/x-wav",
40 name
=> "Raw GSM Audio",
41 mime
=> "audio/x-gsm",
46 $astpath = "/_asterisk";
48 $stdcontainerstart = "<table align=center width=600><tr><td>\n";
49 $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>";
50 $stdcontainerend = "</td></tr><tr><td align=right>$footer</td></tr></table>\n";
60 $rand = rand 99999999;
61 $rfile = "$path/.lock-$rand";
63 sysopen(RFILE
, $rfile, O_WRONLY
| O_CREAT
| O_EXCL
, 0666) or return -1;
66 $res = link($rfile, "$path/.lock");
69 while (($res == 0) && (time - $start <= 5)) {
70 $res = link($rfile, "$path/.lock");
87 unlink("$path/.lock");
94 if ($data =~ /^([-\@\w.]+)$/) {
97 die "Security violation.";
103 sub login_screen
($) {
108 <TITLE
>Asterisk Web
-Voicemail
</TITLE
>
109 <BODY BGCOLOR
="white">
112 <input type
=hidden name
="action" value
="login">
114 <tr
><td valign
=top align
=center rowspan
=6><img align
=center src
="$astpath/animlogo.gif"></td
></tr
>
115 <tr
><td align
=center colspan
=2><font size
=+2>Comedian Mail Login
</font></td
></tr
>
116 <tr
><td align
=center colspan
=2><font size
=+1>$message</font></td
></tr
>
117 <tr
><td
>Mailbox
:</td><td><input type=text name="mailbox"></td
></tr
>
118 <tr
><td
>Password
:</td><td><input type=password name="password"></td
></tr
>
119 <tr
><td align
=right colspan
=2><input value
="Login" type
=submit
></td></tr
>
120 <input type
=hidden name
="context" value
="$context">
131 local ($filename, $startcat) = @_;
132 local ($mbox, $context) = split(/\@/, param
('mailbox'));
133 local $pass = param
('password');
134 local $category = $startcat;
139 $category = "general";
142 $context = param
('context');
145 $context = "default";
148 $filename = "/etc/asterisk/voicemail.conf";
151 # print "Including <h2>$filename</h2> while in <h2>$category</h2>...\n";
152 open(VMAIL
, "<$filename") || die("Bleh, no $filename");
155 if (/include\s\"([^\"]+)\"$/) {
156 ($tmp, $category) = &check_login
("/etc/asterisk/$1", $category);
158 # print "Got '$tmp'\n";
159 return ($tmp, $category);
161 } elsif (/\[(.*)\]/) {
163 } elsif ($category eq "general") {
164 if (/([^\s]+)\s*\=\s*(.*)/) {
165 if ($1 eq "dbname") {
167 } elsif ($1 eq "dbpass") {
169 } elsif ($1 eq "dbhost") {
171 } elsif ($1 eq "dbuser") {
175 if ($dbname and $dbpass and $dbhost and $dbuser) {
177 # db variables are present. Use db for authentication.
178 my $dbh = DBI
->connect("DBI:mysql:$dbname:$dbhost",$dbuser,$dbpass);
179 my $sth = $dbh->prepare(qq{select fullname
,context from voicemail where mailbox
='$mbox' and password
='$pass' and context
='$context'});
181 if (($fullname, $category) = $sth->fetchrow_array()) {
182 return ($fullname ?
$fullname : "Extension $mbox in $context",$category);
185 } elsif (($category ne "general") && ($category ne "zonemessages")) {
186 if (/([^\s]+)\s*\=\>?\s*(.*)/) {
187 @fields = split(/\,\s*/, $2);
188 # print "<p>Mailbox is $1\n";
189 if (($mbox eq $1) && (($pass eq $fields[0]) || ("-${pass}" eq $fields[0])) && ($context eq $category)) {
190 return ($fields[1] ?
$fields[1] : "Extension $mbox in $context", $category);
196 return check_login_users
();
199 sub check_login_users
{
200 my ($mbox, $context) = split(/\@/, param
('mailbox'));
201 my $pass = param
('password');
202 my ($found, $fullname) = (0, "");
203 open VMAIL
, "</etc/asterisk/users.conf";
209 } elsif ($found == 2) {
211 return (($fullname ?
$fullname : "Extension $mbox in $context"), $context);
216 my ($var, $value) = split /\s*=\s*/, $_, 2;
217 if ($var eq 'vmsecret' and $value eq $pass) {
219 } elsif ($var eq 'fullname') {
223 return ($fullname, $context);
232 sub validmailbox
($$$$)
234 local ($context, $mbox, $filename, $startcat) = @_;
235 local $category = $startcat;
239 $context = param
('context');
242 $context = "default";
245 $filename = "/etc/asterisk/voicemail.conf";
248 $category = "general";
250 open(VMAIL
, "<$filename") || die("Bleh, no $filename");
253 if (/include\s\"([^\"]+)\"$/) {
254 ($tmp, $category) = &validmailbox
($mbox, $context, "/etc/asterisk/$1");
256 return ($tmp, $category);
258 } elsif (/\[(.*)\]/) {
260 } elsif ($category eq "general") {
261 if (/([^\s]+)\s*\=\s*(.*)/) {
262 if ($1 eq "dbname") {
264 } elsif ($1 eq "dbpass") {
266 } elsif ($1 eq "dbhost") {
268 } elsif ($1 eq "dbuser") {
272 if ($dbname and $dbpass and $dbhost and $dbuser) {
274 # db variables are present. Use db for authentication.
275 my $dbh = DBI
->connect("DBI:mysql:$dbname:$dbhost",$dbuser,$dbpass);
276 my $sth = $dbh->prepare(qq{select fullname
,context from voicemail where mailbox
='$mbox' and password
='$pass' and context
='$context'});
278 if (($fullname, $context) = $sth->fetchrow_array()) {
279 return ($fullname ?
$fullname : "unknown", $category);
282 } elsif (($category ne "general") && ($category ne "zonemessages") && ($category eq $context)) {
283 if (/([^\s]+)\s*\=\>?\s*(.*)/) {
284 @fields = split(/\,\s*/, $2);
285 if (($mbox eq $1) && ($context eq $category)) {
286 return ($fields[2] ?
$fields[2] : "unknown", $category);
291 return ("", $category);
294 sub mailbox_options
()
296 local($context, $current, $filename, $category) = @_;
301 $filename = "/etc/asterisk/voicemail.conf";
304 $category = "general";
307 # print "Including <h2>$filename</h2> while in <h2>$category</h2>...\n";
308 open(VMAIL
, "<$filename") || die("Bleh, no voicemail.conf");
312 if (/include\s\"([^\"]+)\"$/) {
313 ($tmp2, $category) = &mailbox_options
($context, $current, "/etc/asterisk/$1", $category);
314 # print "Got '$tmp2'...\n";
316 } elsif (/\[(.*)\]/) {
318 } elsif ($category eq "general") {
319 if (/([^\s]+)\s*\=\s*(.*)/) {
320 if ($1 eq "dbname") {
322 } elsif ($1 eq "dbpass") {
324 } elsif ($1 eq "dbhost") {
326 } elsif ($1 eq "dbuser") {
330 if ($dbname and $dbpass and $dbhost and $dbuser) {
332 # db variables are present. Use db for authentication.
333 my $dbh = DBI
->connect("DBI:mysql:$dbname:$dbhost",$dbuser,$dbpass);
334 my $sth = $dbh->prepare(qq{select mailbox
,fullname
,context from voicemail where context
='$context' order by mailbox
});
336 while (($mailbox, $fullname, $category) = $sth->fetchrow_array()) {
339 $text .= " (".$fullname.")";
341 if ($mailbox eq $current) {
342 $tmp .= "<OPTION SELECTED>$text</OPTION>\n";
344 $tmp .= "<OPTION>$text</OPTION>\n";
347 return ($tmp, $category);
349 } elsif (($category ne "general") && ($category ne "zonemessages")) {
350 if (/([^\s]+)\s*\=\>?\s*(.*)/) {
351 @fields = split(/\,\s*/, $2);
354 $text .= " ($fields[1])";
356 if ($1 eq $current) {
357 $tmp .= "<OPTION SELECTED>$text</OPTION>\n";
359 $tmp .= "<OPTION>$text</OPTION>\n";
366 return ($tmp, $category);
371 local ($name, $context, $current) = @_;
377 $context = "default";
379 $tmp = "<SELECT name=\"$name\">\n";
380 ($opts) = &mailbox_options
($context, $current);
382 $tmp .= "</SELECT>\n";
388 my ($context, $mailbox, $folder) = @_;
389 my $path = "/var/spool/asterisk/voicemail/$context/$mailbox/$folder";
390 if (opendir(DIR
, $path)) {
391 my @msgs = grep(/^msg....\.txt$/, readdir(DIR
));
393 return sprintf "%d", $#msgs + 1;
400 my ($context, $mailbox, $folder) = @_;
401 my $count = &msgcount
($context, $mailbox, $folder);
404 } elsif ($count > 0) {
412 my ($context, $mailbox, $folder) = @_;
413 my $path = "/var/spool/asterisk/voicemail/$context/$mailbox/$folder";
414 if (opendir(DIR
, $path)) {
415 my @msgs = sort grep(/^msg....\.txt$/, readdir(DIR
));
417 return map { s/^msg(....)\.txt$/$1/; $_ } @msgs;
431 cookie
(-name
=> "format", -value
=>["$format"], -expires
=>"+1y");
436 my ($context, $mailbox, $folder, $msg) = @_;
438 if (open(MSG
, "</var/spool/asterisk/voicemail/$context/$mailbox/$folder/msg${msg}.txt")) {
441 if (/^(\w+)\s*\=\s*(.*)$/) {
446 $fields->{'msgid'} = $msg;
447 } else { print "<BR>Unable to open '$msg' in '$mailbox', '$folder'\n<B>"; }
453 my ($nextaction, $msgid) = @_;
454 my $folder = param
('folder');
455 my $mbox = param
('mailbox');
456 my $context = param
('context');
457 my $passwd = param
('password');
458 my $format = param
('format');
460 $format = &getcookie
('format');
465 <TITLE
>Asterisk Web
-Voicemail
: Preferences
</TITLE
>
466 <BODY BGCOLOR
="white">
469 <table width
=100% align
=center
>
470 <tr
><td align
=right colspan
=3><font size
=+2>Web Voicemail Preferences
</font></td
></tr
>
471 <tr
><td align
=left
><font size
=+1>Preferred
 
;Audio
 
;Format
:</font></td
><td colspan
=2></td></tr
>
474 foreach $fmt (sort { $formats{$a}->{'pref'} <=> $formats{$b}->{'pref'} } keys %formats) {
475 my $clicked = "checked" if $fmt eq $format;
476 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";
480 <tr
><td align
=right colspan
=3><input type
=submit value
="save settings..."></td></tr
>
482 <input type
=hidden name
="action" value
="$nextaction">
483 <input type
=hidden name
="folder" value
="$folder">
484 <input type
=hidden name
="mailbox" value
="$mbox">
485 <input type
=hidden name
="context" value
="$context">
486 <input type
=hidden name
="password" value
="$passwd">
487 <input type
=hidden name
="msgid" value
="$msgid">
496 my ($message, $msgid) = @_;
497 my $folder = param
('folder');
498 my ($mbox, $context) = split(/\@/, param
('mailbox'));
499 my $passwd = param
('password');
500 my $format = param
('format');
504 $context = param
('context');
507 $context = "default";
510 my $folders = &folder_list
('newfolder', $context, $mbox, $folder);
511 my $mailboxes = &mailbox_list
('forwardto', $context, $mbox);
513 $format = &getcookie
('format');
516 &message_prefs
("play", $msgid);
518 print header
(-cookie
=> &makecookie
($format));
519 $fields = &getfields
($context, $mbox, $folder, $msgid);
524 my $duration = $fields->{'duration'};
526 $duration = sprintf "%d:%02d", $duration/60, $duration % 60;
528 $duration = "<i>Unknown</i>";
532 <TITLE
>Asterisk Web
-Voicemail
: $folder Message
$msgid</TITLE
>
533 <BODY BGCOLOR
="white">
536 <table width
=100% align
=center
>
537 <tr
><td align
=right colspan
=3><font size
=+1>$folder Message
$msgid</font></td
></tr
>
541 <tr
><td align
=center colspan
=3>
543 <tr
><td colspan
=2 align
=center
><font size
=+1>$folder <b
>$msgid</b></font
></td></tr
>
544 <tr
><td
><b
>Message
:</b></td
><td
>$msgid</td></tr
>\n
545 <tr
><td
><b
>Mailbox
:</b></td
><td
>$mbox\@
$context</td></tr
>\n
546 <tr
><td
><b
>Folder
:</b></td
><td
>$folder</td></tr
>\n
547 <tr
><td
><b
>From
:</b></td
><td
>$fields->{callerid
}</td></tr
>\n
548 <tr
><td
><b
>Duration
:</b></td
><td
>$duration</td></tr
>\n
549 <tr
><td
><b
>Original Date
:</b></td
><td
>$fields->{origdate
}</td></tr
>\n
550 <tr
><td
><b
>Original Mailbox
:</b></td
><td
>$fields->{origmailbox
}</td></tr
>\n
551 <tr
><td
><b
>Caller Channel
:</b></td
><td
>$fields->{callerchan
}</td></tr
>\n
552 <tr
><td align
=center colspan
=2>
553 <input name
="action" type
=submit value
="index"> 
;
554 <input name
="action" type
=submit value
="delete "> 
;
555 <input name
="action" type
=submit value
="forward to -> "> 
;
557 <input name
="action" type
=submit value
="save to ->">
559 <input name
="action" type
=submit value
="play ">
560 <input name
="action" type
=submit value
="download">
562 <tr
><td colspan
=2 align
=center
>
563 <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
>
567 <input type
=hidden name
="folder" value
="$folder">
568 <input type
=hidden name
="mailbox" value
="$mbox">
569 <input type
=hidden name
="context" value
="$context">
570 <input type
=hidden name
="password" value
="$passwd">
571 <input type
=hidden name
="msgid" value
="$msgid">
580 my ($forcedownload) = @_;
581 my $folder = &untaint
(param
('folder'));
582 my $msgid = &untaint
(param
('msgid'));
583 my $mailbox = &untaint
(param
('mailbox'));
584 my $context = &untaint
(param
('context'));
585 my $format = param
('format');
587 $format = &getcookie
('format');
591 my $path = "/var/spool/asterisk/voicemail/$context/$mailbox/$folder/msg${msgid}.$format";
593 $msgid =~ /^\d\d\d\d$/ || die("Msgid Liar ($msgid)!");
594 grep(/^${format}$/, keys %formats) || die("Format Liar ($format)!");
596 # Mailbox and folder are already verified
597 if (open(AUDIO
, "<$path")) {
600 if ($forcedownload) {
601 print header
(-type
=>$formats{$format}->{'mime'}, -Content_length
=> $size, -attachment
=> "msg${msgid}.$format");
603 print header
(-type
=>$formats{$format}->{'mime'}, -Content_length
=> $size);
606 while(($amt = sysread(AUDIO
, $data, 4096)) > 0) {
607 syswrite(STDOUT
, $data, $amt);
611 die("Hrm, can't seem to open $path\n");
617 my ($folder, $message) = @_;
618 my ($mbox, $context) = split(/\@/, param
('mailbox'));
619 my $passwd = param
('password');
623 my ($newmessages, $oldmessages);
624 my $format = param
('format');
626 $format = &getcookie
('format');
629 $context = param
('context');
632 $context = "default";
635 $msgcount = &msgcountstr
($context, $mbox, $folder);
636 $message2 = " Folder '$folder' has " . &msgcountstr
($context, $mbox, $folder);
638 $newmessages = &msgcount
($context, $mbox, "INBOX");
639 $oldmessages = &msgcount
($context, $mbox, "Old");
640 if (($newmessages > 0) || ($oldmessages < 1)) {
645 $message2 = "You have";
646 if ($newmessages > 0) {
647 $message2 .= " <b>$newmessages</b> NEW";
648 if ($oldmessages > 0) {
649 $message2 .= "and <b>$oldmessages</b> OLD";
650 if ($oldmessages != 1) {
651 $message2 .= " messages.";
653 $message2 .= "message.";
656 if ($newmessages != 1) {
657 $message2 .= " messages.";
659 $message2 .= " message.";
663 if ($oldmessages > 0) {
664 $message2 .= " <b>$oldmessages</b> OLD";
665 if ($oldmessages != 1) {
666 $message2 .= " messages.";
668 $message2 .= " message.";
671 $message2 .= " <b>no</b> messages.";
676 my $folders = &folder_list
('newfolder', $context, $mbox, $folder);
677 my $cfolders = &folder_list
('changefolder', $context, $mbox, $folder);
678 my $mailboxes = &mailbox_list
('forwardto', $context, $mbox);
679 print header
(-cookie
=> &makecookie
($format));
682 <TITLE
>Asterisk Web
-Voicemail
: $mbox\@
$context $folder</TITLE
>
683 <BODY BGCOLOR
="white">
686 <table width
=100% align
=center
>
687 <tr
><td align
=center colspan
=2><font size
=+2><I
>$message</I></font
></td></tr
>
688 <tr
><td align
=right colspan
=2><font size
=+1><b
>$folder</b> Messages</font
> <input type
=submit name
="action" value
="change to ->">$cfolders</td></tr
>
689 <tr
><td align
=left colspan
=2><font size
=+1>$message2</font></td
></tr
>
691 <table width
=100% align
=center cellpadding
=0 cellspacing
=0>
694 print "<tr><td> Msg</td><td> From</td><td> Duration</td><td> Date</td><td> </td></tr>\n";
695 print "<tr><td><hr></td><td><hr></td><td><hr></td><td><hr></td><td></td></tr>\n";
696 foreach $msg (&messages
($context, $mbox, $folder)) {
698 $fields = &getfields
($context, $mbox, $folder, $msg);
699 $duration = $fields->{'duration'};
701 $duration = sprintf "%d:%02d", $duration / 60, $duration % 60;
703 $duration = "<i>Unknown</i>";
706 print "<tr><td><input type=checkbox name=\"msgselect\" value=\"$msg\"> <b>$msg</b></td><td>$fields->{'callerid'}</td><td>$duration</td><td>$fields->{'origdate'}</td><td><input name='play$msg' alt=\"Play message $msg\" border=0 type=image align=left src=\"$astpath/play.gif\"></td></tr>\n";
710 print "<tr><td colspan=4 align=center><P><b><i>No messages</i></b><P></td></tr>";
715 <table width
=100% align
=center
>
716 <tr
><td align
=right colspan
=2>
717 <input type
="submit" name
="action" value
="refresh"> 
;
722 <input type
="submit" name
="action" value
="delete"> 
;
723 <input type
="submit" name
="action" value
="save to ->">
725 <input type
="submit" name
="action" value
="forward to ->">
732 <tr
><td align
=right colspan
=2>
733 <input type
="submit" name
="action" value
="preferences">
734 <input type
="submit" name
="action" value
="logout">
737 <input type
=hidden name
="folder" value
="$folder">
738 <input type
=hidden name
="mailbox" value
="$mbox">
739 <input type
=hidden name
="context" value
="$context">
740 <input type
=hidden name
="password" value
="$passwd">
750 return grep(/^$folder$/, @validfolders);
755 my ($name, $context, $mbox, $selected) = @_;
758 my $tmp = "<SELECT name=\"$name\">\n";
759 foreach $f (@validfolders) {
760 $count = &msgcount
($context, $mbox, $f);
761 if ($f eq $selected) {
762 $tmp .= "<OPTION SELECTED>$f ($count)</OPTION>\n";
764 $tmp .= "<OPTION>$f ($count)</OPTION>\n";
772 my ($context, $mbox, $oldfolder, $old, $newfolder, $new) = @_;
773 my ($oldfile, $newfile);
774 return if ($old eq $new) && ($oldfolder eq $newfolder);
776 if ($context =~ /^(\w+)$/) {
779 die("Invalid Context<BR>\n");
782 if ($mbox =~ /^(\w+)$/) {
785 die ("Invalid mailbox<BR>\n");
788 if ($oldfolder =~ /^(\w+)$/) {
791 die("Invalid old folder<BR>\n");
794 if ($newfolder =~ /^(\w+)$/) {
797 die("Invalid new folder ($newfolder)<BR>\n");
800 if ($old =~ /^(\d\d\d\d)$/) {
803 die("Invalid old Message<BR>\n");
806 if ($new =~ /^(\d\d\d\d)$/) {
809 die("Invalid old Message<BR>\n");
812 my $path = "/var/spool/asterisk/voicemail/$context/$mbox/$newfolder";
816 $path = "/var/spool/asterisk/voicemail/$context/$mbox/$oldfolder";
817 opendir(DIR
, $path) || die("Unable to open directory\n");
818 my @files = grep /^msg${old}\.\w+$/, readdir(DIR
);
820 foreach $oldfile (@files) {
822 if ($tmp =~ /^(msg${old}.\w+)$/) {
824 $oldfile = $path . "/$tmp";
825 $tmp =~ s/msg${old}/msg${new}/;
826 $newfile = "/var/spool/asterisk/voicemail/$context/$mbox/$newfolder/$tmp";
827 # print "Renaming $oldfile to $newfile<BR>\n";
828 rename($oldfile, $newfile);
835 my ($orig, $new) = @_;
842 open(IN
, "<$orig") || die("Unable to open '$orig'\n");
843 open(OUT
, ">$new") || DIE
("Unable to open '$new'\n");
844 while(($res = sysread(IN
, $data, 4096)) > 0) {
845 syswrite(OUT
, $data, $res);
853 my ($context, $mbox, $newmbox, $oldfolder, $old, $new) = @_;
854 my ($oldfile, $newfile);
855 return if ($mbox eq $newmbox);
857 if ($mbox =~ /^(\w+)$/) {
860 die ("Invalid mailbox<BR>\n");
863 if ($newmbox =~ /^(\w+)$/) {
866 die ("Invalid new mailbox<BR>\n");
869 if ($oldfolder =~ /^(\w+)$/) {
872 die("Invalid old folder<BR>\n");
875 if ($old =~ /^(\d\d\d\d)$/) {
878 die("Invalid old Message<BR>\n");
881 if ($new =~ /^(\d\d\d\d)$/) {
884 die("Invalid old Message<BR>\n");
887 my $path = "/var/spool/asterisk/voicemail/$context/$newmbox";
891 $path = "/var/spool/asterisk/voicemail/$context/$newmbox/INBOX";
895 $path = "/var/spool/asterisk/voicemail/$context/$mbox/$oldfolder";
896 opendir(DIR
, $path) || die("Unable to open directory\n");
897 my @files = grep /^msg${old}\.\w+$/, readdir(DIR
);
899 foreach $oldfile (@files) {
901 if ($tmp =~ /^(msg${old}.\w+)$/) {
903 $oldfile = $path . "/$tmp";
904 $tmp =~ s/msg${old}/msg${new}/;
905 $newfile = "/var/spool/asterisk/voicemail/$context/$newmbox/INBOX/$tmp";
906 # print "Copying $oldfile to $newfile<BR>\n";
907 &file_copy
($oldfile, $newfile);
914 my ($context, $mbox, $folder, $msg) = @_;
915 if ($mbox =~ /^(\w+)$/) {
918 die ("Invalid mailbox<BR>\n");
920 if ($context =~ /^(\w+)$/) {
923 die ("Invalid context<BR>\n");
925 if ($folder =~ /^(\w+)$/) {
928 die("Invalid folder<BR>\n");
930 if ($msg =~ /^(\d\d\d\d)$/) {
933 die("Invalid Message<BR>\n");
935 my $path = "/var/spool/asterisk/voicemail/$context/$mbox/$folder";
936 opendir(DIR
, $path) || die("Unable to open directory\n");
937 my @files = grep /^msg${msg}\.\w+$/, readdir(DIR
);
939 foreach $oldfile (@files) {
940 if ($oldfile =~ /^(msg${msg}.\w+)$/) {
941 $oldfile = $path . "/$1";
942 # print "Deleting $oldfile<BR>\n";
948 sub message_forward
()
950 my ($toindex, @msgs) = @_;
951 my $folder = param
('folder');
952 my ($mbox, $context) = split(/\@/, param
('mailbox'));
953 my $newmbox = param
('forwardto');
957 $context = param
('context');
960 $context = "default";
962 $newmbox =~ s/(\w+)(\s+.*)?$/$1/;
963 if (!&validmailbox
($context, $newmbox)) {
964 die("Bah! Not a valid mailbox '$newmbox'\n");
969 $context = &untaint
($context);
970 $newmbox = &untaint
($newmbox);
971 my $path = "/var/spool/asterisk/voicemail/$context/$newmbox/INBOX";
973 if (&lock_path
($path) == 0) {
974 $msgcount = &msgcount
($context, $newmbox, "INBOX");
976 if ($newmbox ne $mbox) {
978 foreach $msg (@msgs) {
979 # print "Forwarding $msg from $mbox to $newmbox<BR>\n";
980 &message_copy
($context, $mbox, $newmbox, $folder, $msg, sprintf "%04d", $msgcount);
983 $txt = "Forwarded messages " . join(', ', @msgs) . "to $newmbox";
985 $txt = "Can't forward messages to yourself!\n";
989 $txt = "Cannot forward messages: Unable to lock path.\n";
992 $txt = "Please Select Message(s) for this action.\n";
995 &message_index
($folder, $txt);
997 &message_play
($txt, $msgs[0]);
1001 sub message_delete_or_move
()
1003 my ($toindex, $del, @msgs) = @_;
1007 my $folder = param
('folder');
1008 my $newfolder = param
('newfolder') unless $del;
1009 $newfolder =~ s/^(\w+)\s+.*$/$1/;
1010 my ($mbox, $context) = split(/\@/, param
('mailbox'));
1012 $context = param
('context');
1015 $context = "default";
1017 my $passwd = param
('password');
1018 $context = &untaint
($context);
1019 $mbox = &untaint
($mbox);
1020 $folder = &untaint
($folder);
1021 $path = "/var/spool/asterisk/voicemail/$context/$mbox/$folder";
1023 if (&lock_path
($path) == 0) {
1024 my $msgcount = &msgcount
($context, $mbox, $folder);
1025 my $omsgcount = &msgcount
($context, $mbox, $newfolder) if $newfolder;
1027 if ($newfolder ne $folder) {
1029 for ($x=0;$x<$msgcount;$x++) {
1030 my $msg = sprintf "%04d", $x;
1031 my $newmsg = sprintf "%04d", $y;
1032 if (grep(/^$msg$/, @msgs)) {
1034 &message_rename
($context, $mbox, $folder, $msg, $newfolder, sprintf "%04d", $omsgcount);
1037 &message_delete
($context, $mbox, $folder, $msg);
1040 &message_rename
($context, $mbox, $folder, $msg, $folder, $newmsg);
1045 $txt = "Deleted messages " . join (', ', @msgs);
1047 $txt = "Moved messages " . join (', ', @msgs) . " to $newfolder";
1050 $txt = "Can't move a message to the same folder they're in already";
1052 &unlock_path
($path);
1054 $txt = "Cannot move/delete messages: Unable to lock path.\n";
1057 $txt = "Please Select Message(s) for this action.\n";
1059 # Not as many messages now
1061 if ($toindex || ($msgs[0] >= $msgcount)) {
1062 &message_index
($folder, $txt);
1064 &message_play
($txt, $msgs[0]);
1069 my $folder = param
('folder');
1070 my $changefolder = param
('changefolder');
1071 $changefolder =~ s/(\w+)\s+.*$/$1/;
1073 my $newfolder = param
('newfolder');
1074 $newfolder =~ s/^(\w+)\s+.*$/$1/;
1075 if ($newfolder && !&validfolder
($newfolder)) {
1077 die("Bah! new folder '$newfolder' isn't a folder.");
1079 $action = param
('action');
1080 $msgid = param
('msgid');
1082 my ($tmp) = grep /^play\d\d\d\d\.x$/, param
;
1083 if ($tmp =~ /^play(\d\d\d\d)/) {
1088 print "No message?<BR>\n";
1092 @msgs = param
('msgselect');
1093 @msgs = ($msgid) unless @msgs;
1095 ($mailbox) = &check_login
();
1096 if (length($mailbox)) {
1097 if ($action eq 'login') {
1098 &message_index
($folder, "Welcome, $mailbox");
1099 } elsif (($action eq 'refresh') || ($action eq 'index')) {
1100 &message_index
($folder, "Welcome, $mailbox");
1101 } elsif ($action eq 'change to ->') {
1102 if (&validfolder
($changefolder)) {
1103 $folder = $changefolder;
1104 &message_index
($folder, "Welcome, $mailbox");
1106 die("Bah! Not a valid change to folder '$changefolder'\n");
1108 } elsif ($action eq 'play') {
1109 &message_play
("$mailbox $folder $msgid", $msgid);
1110 } elsif ($action eq 'preferences') {
1111 &message_prefs
("refresh", $msgid);
1112 } elsif ($action eq 'download') {
1114 } elsif ($action eq 'play ') {
1116 } elsif ($action eq 'audio') {
1118 } elsif ($action eq 'delete') {
1119 &message_delete_or_move
(1, 1, @msgs);
1120 } elsif ($action eq 'delete ') {
1121 &message_delete_or_move
(0, 1, @msgs);
1122 } elsif ($action eq 'forward to ->') {
1123 &message_forward
(1, @msgs);
1124 } elsif ($action eq 'forward to -> ') {
1125 &message_forward
(0, @msgs);
1126 } elsif ($action eq 'save to ->') {
1127 &message_delete_or_move
(1, 0, @msgs);
1128 } elsif ($action eq 'save to -> ') {
1129 &message_delete_or_move
(0, 0, @msgs);
1130 } elsif ($action eq 'logout') {
1131 &login_screen
("Logged out!\n");
1135 &login_screen
("Login Incorrect!\n");
1139 &login_screen
("\ ");