update doxygen configuration file to current version (bug #4144)
[asterisk/asterisk.git] / contrib / scripts / vmail.cgi
1 #!/usr/bin/perl
2 #
3 # Web based Voicemail for Asterisk
4 #
5 # Copyright (C) 2002, Linux Support Services, Inc.
6 #
7 # Distributed under the terms of the GNU General Public License
8 #
9 # Written by Mark Spencer <markster@linux-support.net>
10 #
11 # (icky, I know....  if you know better perl please help!)
12 #
13 #
14 use CGI qw/:standard/;
15 use Carp::Heavy;
16 use CGI::Carp qw(fatalsToBrowser);
17 use DBI;
18
19 $context=""; # Define here your by default context (so you dont need to put voicemail@context in the login
20
21 @validfolders = ( "INBOX", "Old", "Work", "Family", "Friends", "Cust1", "Cust2", "Cust3", "Cust4", "Cust5" );
22
23 %formats = (
24         "wav" => {
25                 name => "Uncompressed WAV",
26                 mime => "audio/x-wav",
27                 pref => 1
28         },
29         "WAV" => {
30                 name => "GSM Compressed WAV",
31                 mime => "audio/x-wav",
32                 pref => 2
33         },
34         "gsm" => {
35                 name => "Raw GSM Audio",
36                 mime => "audio/x-gsm",
37                 pref => 3
38         }
39 );
40
41 $astpath = "/_asterisk";
42
43 $stdcontainerstart = "<table align=center width=600><tr><td>\n";
44 $footer = "<hr><font size=-1><a href=\"http://www.asterisk.org\">The Asterisk Open Source PBX</a> Copyright 2004, <a href=\"http://www.digium.com\">Digium, Inc.</a></a>";
45 $stdcontainerend = "</td></tr><tr><td align=right>$footer</td></tr></table>\n";
46
47 sub login_screen() {
48         print header;
49         my ($message) = @_;
50         print <<_EOH;
51
52 <TITLE>Asterisk Web-Voicemail</TITLE>
53 <BODY BGCOLOR="white">
54 $stdcontainerstart
55 <FORM METHOD="post">
56 <input type=hidden name="action" value="login">
57 <table align=center>
58 <tr><td valign=top align=center rowspan=6><img align=center src="$astpath/animlogo.gif"></td></tr>
59 <tr><td align=center colspan=2><font size=+2>Comedian Mail Login</font></td></tr>
60 <tr><td align=center colspan=2><font size=+1>$message</font></td></tr>
61 <tr><td>Mailbox:</td><td><input type=text name="mailbox"></td></tr>
62 <tr><td>Password:</td><td><input type=password name="password"></td></tr>
63 <tr><td align=right colspan=2><input value="Login" type=submit></td></tr>
64 <input type=hidden name="context" value="$context">
65 </table>
66 </FORM>
67 $stdcontainerend
68 </BODY>\n
69 _EOH
70
71 }
72
73 sub check_login()
74 {
75         local ($filename, $startcat) = @_;
76         local ($mbox, $context) = split(/\@/, param('mailbox'));
77         local $pass = param('password');
78         local $category = $startcat;
79         local @fields;
80         local $tmp;
81         local (*VMAIL);
82         if (!$category) {
83                 $category = "general";
84         }
85         if (!$context) {
86                 $context = param('context');
87         }
88         if (!$context) {
89                 $context = "default";
90         }
91         if (!$filename) {
92                 $filename = "/etc/asterisk/voicemail.conf";
93         }
94 #       print header;
95 #       print "Including <h2>$filename</h2> while in <h2>$category</h2>...\n";
96         open(VMAIL, "<$filename") || die("Bleh, no $filename");
97         while(<VMAIL>) {
98                 chomp;
99                 if (/include\s\"([^\"]+)\"$/) {
100                         ($tmp, $category) = &check_login("/etc/asterisk/$1", $category);
101                         if (length($tmp)) {
102 #                               print "Got '$tmp'\n";
103                                 return ($tmp, $category);
104                         }
105                 } elsif (/\[(.*)\]/) {
106                         $category = $1;
107                 } elsif ($category eq "general") {
108                         if (/([^\s]+)\s*\=\s*(.*)/) {
109                                 if ($1 eq "dbname") {
110                                         $dbname = $2;
111                                 } elsif ($1 eq "dbpass") {
112                                         $dbpass = $2;
113                                 } elsif ($1 eq "dbhost") {
114                                         $dbhost = $2;
115                                 } elsif ($1 eq "dbuser") {
116                                         $dbuser = $2;
117                                 }
118                         }
119                         if ($dbname and $dbpass and $dbhost and $dbuser) {
120
121                                 # db variables are present.  Use db for authentication.
122                                 my $dbh = DBI->connect("DBI:mysql:$dbname:$dbhost",$dbuser,$dbpass);
123                                 my $sth = $dbh->prepare(qq{select fullname,context from voicemail where mailbox='$mbox' and password='$pass' and context='$context'});
124                                 $sth->execute();
125                                 if (($fullname, $category) = $sth->fetchrow_array()) {;
126                                         return ($fullname ? $fullname : "Extension $mbox in $context",$category);
127                                 }
128                         }
129                 } elsif (($category ne "general") && ($category ne "zonemessages")) { 
130                         if (/([^\s]+)\s*\=\>?\s*(.*)/) {
131                                 @fields = split(/\,\s*/, $2);
132 #                               print "<p>Mailbox is $1\n";
133                                 if (($mbox eq $1) && (($pass eq $fields[0]) || ("-${pass}" eq $fields[0])) && ($context eq $category)) {
134                                         return ($fields[1] ? $fields[1] : "Extension $mbox in $context", $category);
135                                 }
136                         }
137                 }
138         }
139         close(VMAIL);
140         return ("", $category);
141 }
142
143 sub validmailbox()
144 {
145         local ($context, $mbox, $filename, $startcat) = @_;
146         local $category = $startcat;
147         local @fields;
148         local (*VMAIL);
149         if (!$context) {
150                 $context = param('context');
151         }
152         if (!$context) {
153                 $context = "default";
154         }
155         if (!$filename) {
156                 $filename = "/etc/asterisk/voicemail.conf";
157         }
158         if (!$category) {
159                 $category = "general";
160         }
161         open(VMAIL, "<$filename") || die("Bleh, no $filename");
162         while(<VMAIL>) {
163                 chomp;
164                 if (/include\s\"([^\"]+)\"$/) {
165                         ($tmp, $category) = &validmailbox($mbox, $context, "/etc/asterisk/$1");
166                         if ($tmp) {
167                                 return ($tmp, $category);
168                         }
169                 } elsif (/\[(.*)\]/) {
170                         $category = $1;
171                 } elsif ($category eq "general") {
172                         if (/([^\s]+)\s*\=\s*(.*)/) {
173                                 if ($1 eq "dbname") {
174                                         $dbname = $2;
175                                 } elsif ($1 eq "dbpass") {
176                                         $dbpass = $2;
177                                 } elsif ($1 eq "dbhost") {
178                                         $dbhost = $2;
179                                 } elsif ($1 eq "dbuser") {
180                                         $dbuser = $2;
181                                 }
182                         }
183                         if ($dbname and $dbpass and $dbhost and $dbuser) {
184
185                                 # db variables are present.  Use db for authentication.
186                                 my $dbh = DBI->connect("DBI:mysql:$dbname:$dbhost",$dbuser,$dbpass);
187                                 my $sth = $dbh->prepare(qq{select fullname,context from voicemail where mailbox='$mbox' and password='$pass' and context='$context'});
188                                 $sth->execute();
189                                 if (($fullname, $category) = $sth->fetchrow_array()) {;
190                                         return ($fullname ? $fullname : "unknown", $category);
191                                 }
192                         }
193                 } elsif (($category ne "general") && ($category ne "zonemessages") && ($category eq $context)) {
194                         if (/([^\s]+)\s*\=\>?\s*(.*)/) {
195                                 @fields = split(/\,\s*/, $2);
196                                 if (($mbox eq $1) && ($context eq $category)) {
197                                         return ($fields[2] ? $fields[2] : "unknown", $category);
198                                 }
199                         }
200                 }
201         }
202         return ("", $category);
203 }
204
205 sub mailbox_options()
206 {
207         local($context, $current, $filename, $category) = @_;
208         local (*VMAIL);
209         local $tmp2;
210         local $tmp;
211         if (!$filename) {
212                 $filename = "/etc/asterisk/voicemail.conf";
213         }
214         if (!$category) {
215                 $category = "general";
216         }
217 #       print header;
218 #       print "Including <h2>$filename</h2> while in <h2>$category</h2>...\n";
219         open(VMAIL, "<$filename") || die("Bleh, no voicemail.conf");
220         while(<VMAIL>) {
221                 chomp;
222                 s/\;.*$//;
223                 if (/include\s\"([^\"]+)\"$/) {
224                         ($tmp2, $category) = &mailbox_options($context, $current, "/etc/asterisk/$1", $category);
225 #                       print "Got '$tmp2'...\n";
226                         $tmp .= $tmp2;
227                 } elsif (/\[(.*)\]/) {
228                         $category = $1;
229                 } elsif ($category eq "general") {
230                         if (/([^\s]+)\s*\=\s*(.*)/) {
231                                 if ($1 eq "dbname") {
232                                         $dbname = $2;
233                                 } elsif ($1 eq "dbpass") {
234                                         $dbpass = $2;
235                                 } elsif ($1 eq "dbhost") {
236                                         $dbhost = $2;
237                                 } elsif ($1 eq "dbuser") {
238                                         $dbuser = $2;
239                                 }
240                         }
241                         if ($dbname and $dbpass and $dbhost and $dbuser) {
242
243                                 # db variables are present.  Use db for authentication.
244                                 my $dbh = DBI->connect("DBI:mysql:$dbname:$dbhost",$dbuser,$dbpass);
245                                 my $sth = $dbh->prepare(qq{select mailbox,fullname,context from voicemail where context='$context' order by mailbox});
246                                 $sth->execute();
247                                 while (($mailbox, $fullname, $category) = $sth->fetchrow_array()) {
248                                         $text = $mailbox;
249                                         if ($fullname) {
250                                                 $text .= " (".$fullname.")";
251                                         }
252                                         if ($mailbox eq $current) {
253                                                 $tmp .= "<OPTION SELECTED>$text</OPTION>\n";
254                                         } else {
255                                                 $tmp .= "<OPTION>$text</OPTION>\n";
256                                         }
257                                 }
258                                 return ($tmp, $category);
259                         }
260                 } elsif (($category ne "general") && ($category ne "zonemessages")) {
261                         if (/([^\s]+)\s*\=\>?\s*(.*)/) {
262                                 @fields = split(/\,\s*/, $2);
263                                 $text = "$1";
264                                 if ($fields[1]) {
265                                         $text .= " ($fields[1])";
266                                 }
267                                 if ($1 eq $current) {
268                                         $tmp .= "<OPTION SELECTED>$text</OPTION>\n";
269                                 } else {
270                                         $tmp .= "<OPTION>$text</OPTION>\n";
271                                 }
272                                 
273                         }
274                 }
275         }
276         close(VMAIL);
277         return ($tmp, $category);
278 }
279
280 sub mailbox_list()
281 {
282         local ($name, $context, $current) = @_;
283         local $tmp;
284         local $text;
285         local $tmp;
286         local $opts;
287         if (!$context) {
288                 $context = "default";
289         }
290         $tmp = "<SELECT name=\"$name\">\n";
291         ($opts) = &mailbox_options($context, $current);
292         $tmp .= $opts;
293         $tmp .= "</SELECT>\n";
294         
295 }
296
297 sub msgcount() 
298 {
299         my ($context, $mailbox, $folder) = @_;
300         my $path = "/var/spool/asterisk/voicemail/$context/$mailbox/$folder";
301         if (opendir(DIR, $path)) {
302                 my @msgs = grep(/^msg....\.txt$/, readdir(DIR));
303                 closedir(DIR);
304                 return sprintf "%d", $#msgs + 1;
305         }
306         return "0";
307 }
308
309 sub msgcountstr()
310 {
311         my ($context, $mailbox, $folder) = @_;
312         my $count = &msgcount($context, $mailbox, $folder);
313         if ($count > 1) {
314                 "$count messages";
315         } elsif ($count > 0) {
316                 "$count message";
317         } else {
318                 "no messages";
319         }
320 }
321 sub messages()
322 {
323         my ($context, $mailbox, $folder) = @_;
324         my $path = "/var/spool/asterisk/voicemail/$context/$mailbox/$folder";
325         if (opendir(DIR, $path)) {
326                 my @msgs = sort grep(/^msg....\.txt$/, readdir(DIR));
327                 closedir(DIR);
328                 return map { s/^msg(....)\.txt$/$1/; $_ } @msgs;
329         }
330         return ();
331 }
332
333 sub getcookie()
334 {
335         my ($var) = @_;
336         return cookie($var);
337 }
338
339 sub makecookie()
340 {
341         my ($format) = @_;
342         cookie(-name => "format", -value =>["$format"], -expires=>"+1y");
343 }
344
345 sub getfields()
346 {
347         my ($context, $mailbox, $folder, $msg) = @_;
348         my $fields;
349         if (open(MSG, "</var/spool/asterisk/voicemail/$context/$mailbox/$folder/msg${msg}.txt")) {
350                 while(<MSG>) {
351                         s/\#.*$//g;
352                         if (/^(\w+)\s*\=\s*(.*)$/) {
353                                 $fields->{$1} = $2;
354                         }
355                 }
356                 close(MSG);
357                 $fields->{'msgid'} = $msg;
358         } else { print "<BR>Unable to open '$msg' in '$mailbox', '$folder'\n<B>"; }
359         $fields;
360 }
361
362 sub message_prefs()
363 {
364         my ($nextaction, $msgid) = @_;
365         my $folder = param('folder');
366         my $mbox = param('mailbox');
367         my $context = param('context');
368         my $passwd = param('password');
369         my $format = param('format');
370         if (!$format) {
371                 $format = &getcookie('format');
372         }
373         print header;
374         print <<_EOH;
375
376 <TITLE>Asterisk Web-Voicemail: Preferences</TITLE>
377 <BODY BGCOLOR="white">
378 $stdcontainerstart
379 <FORM METHOD="post">
380 <table width=100% align=center>
381 <tr><td align=right colspan=3><font size=+2>Web Voicemail Preferences</font></td></tr>
382 <tr><td align=left><font size=+1>Preferred&nbsp;Audio&nbsp;Format:</font></td><td colspan=2></td></tr>
383 _EOH
384
385 foreach $fmt (sort { $formats{$a}->{'pref'} <=> $formats{$b}->{'pref'} } keys %formats) {
386         my $clicked = "checked" if $fmt eq $format;
387         print "<tr><td></td><td align=left><input type=radio name=\"format\" $clicked value=\"$fmt\"></td><td width=100%>&nbsp;$formats{$fmt}->{name}</td></tr>\n";
388 }
389
390 print <<_EOH;
391 <tr><td align=right colspan=3><input type=submit value="save settings..."></td></tr>
392 </table>
393 <input type=hidden name="action" value="$nextaction">
394 <input type=hidden name="folder" value="$folder">
395 <input type=hidden name="mailbox" value="$mbox">
396 <input type=hidden name="context" value="$context">
397 <input type=hidden name="password" value="$passwd">
398 <input type=hidden name="msgid" value="$msgid">
399 $stdcontainerend
400 </BODY>\n
401 _EOH
402
403 }
404
405 sub message_play()
406 {
407         my ($message, $msgid) = @_;
408         my $folder = param('folder');
409         my ($mbox, $context) = split(/\@/, param('mailbox'));
410         my $passwd = param('password');
411         my $format = param('format');
412         
413         my $fields;
414         if (!$context) {
415                 $context = param('context');
416         }
417         if (!$context) {
418                 $context = "default";
419         }
420         
421         my $folders = &folder_list('newfolder', $context, $mbox, $folder);
422         my $mailboxes = &mailbox_list('forwardto', $context, $mbox);
423         if (!$format) {
424                 $format = &getcookie('format');
425         }
426         if (!$format) {
427                 &message_prefs("play", $msgid);
428         } else {
429                 print header(-cookie => &makecookie($format));
430                 $fields = &getfields($context, $mbox, $folder, $msgid);
431                 if (!$fields) {
432                         print "<BR>Bah!\n";
433                         return;
434                 }
435                 my $duration = $fields->{'duration'};
436                 if ($duration) {
437                         $duration = sprintf "%d:%02d", $duration/60, $duration % 60; 
438                 } else {
439                         $duration = "<i>Unknown</i>";
440                 }
441                 print <<_EOH;
442         
443 <TITLE>Asterisk Web-Voicemail: $folder Message $msgid</TITLE>
444 <BODY BGCOLOR="white">
445 $stdcontainerstart
446 <FORM METHOD="post">
447 <table width=100% align=center>
448 <tr><td align=right colspan=3><font size=+1>$folder Message $msgid</font></td></tr>
449 _EOH
450
451                 print <<_EOH;
452 <tr><td align=center colspan=3>
453 <table>
454         <tr><td colspan=2 align=center><font size=+1>$folder <b>$msgid</b></font></td></tr>
455         <tr><td><b>Message:</b></td><td>$msgid</td></tr>\n
456         <tr><td><b>Mailbox:</b></td><td>$mbox\@$context</td></tr>\n
457         <tr><td><b>Folder:</b></td><td>$folder</td></tr>\n
458         <tr><td><b>From:</b></td><td>$fields->{callerid}</td></tr>\n
459         <tr><td><b>Duration:</b></td><td>$duration</td></tr>\n
460         <tr><td><b>Original Date:</b></td><td>$fields->{origdate}</td></tr>\n
461         <tr><td><b>Original Mailbox:</b></td><td>$fields->{origmailbox}</td></tr>\n
462         <tr><td><b>Caller Channel:</b></td><td>$fields->{callerchan}</td></tr>\n
463         <tr><td align=center colspan=2>
464         <input name="action" type=submit value="index">&nbsp;
465         <input name="action" type=submit value="delete ">&nbsp;
466         <input name="action" type=submit value="forward to -> ">&nbsp;
467         $mailboxes&nbsp;
468         <input name="action" type=submit value="save to ->">
469         $folders&nbsp;
470         <input name="action" type=submit value="play ">
471         <input name="action" type=submit value="download">
472 </td></tr>
473 <tr><td colspan=2 align=center>
474 <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>
475 </td></tr></table>
476 </td></tr>
477 </table>
478 <input type=hidden name="folder" value="$folder">
479 <input type=hidden name="mailbox" value="$mbox">
480 <input type=hidden name="context" value="$context">
481 <input type=hidden name="password" value="$passwd">
482 <input type=hidden name="msgid" value="$msgid">
483 $stdcontainerend
484 </BODY>\n
485 _EOH
486         }
487 }
488
489 sub message_audio()
490 {
491         my ($forcedownload) = @_;
492         my $folder = param('folder');
493         my $msgid = param('msgid');
494         my $mailbox = param('mailbox');
495         my $context = param('context');
496         my $format = param('format');
497         if (!$format) {
498                 $format = &getcookie('format');
499         }
500         my $path = "/var/spool/asterisk/voicemail/$context/$mailbox/$folder/msg${msgid}.$format";
501
502         $msgid =~ /^\d\d\d\d$/ || die("Msgid Liar ($msgid)!");
503         grep(/^${format}$/, keys %formats) || die("Format Liar ($format)!");
504
505         # Mailbox and folder are already verified
506         if (open(AUDIO, "<$path")) {
507                 $size = -s $path;
508                 $|=1;
509                 if ($forcedownload) {
510                         print header(-type=>$formats{$format}->{'mime'}, -Content_length => $size, -attachment => "msg${msgid}.$format");
511                 } else {                
512                         print header(-type=>$formats{$format}->{'mime'}, -Content_length => $size);
513                 }
514                 
515                 while(($amt = sysread(AUDIO, $data, 4096)) > 0) {
516                         syswrite(STDOUT, $data, $amt);
517                 }
518                 close(AUDIO);
519         } else {
520                 die("Hrm, can't seem to open $path\n");
521         }
522 }
523
524 sub message_index() 
525 {
526         my ($folder, $message) = @_;
527         my ($mbox, $context) = split(/\@/, param('mailbox'));
528         my $passwd = param('password');
529         my $message2;
530         my $msgcount;   
531         my $hasmsg;
532         my $newmessages, $oldmessages;
533         my $format = param('format');
534         if (!$format) {
535                 $format = &getcookie('format');
536         }
537         if (!$context) {
538                 $context = param('context');
539         }
540         if (!$context) {
541                 $context = "default";
542         }
543         if ($folder) {
544                 $msgcount = &msgcountstr($context, $mbox, $folder);
545                 $message2 = "&nbsp;&nbsp;&nbsp;Folder '$folder' has " . &msgcountstr($context, $mbox, $folder);
546         } else {
547                 $newmessages = &msgcount($context, $mbox, "INBOX");
548                 $oldmessages = &msgcount($context, $mbox, "Old");
549                 if (($newmessages > 0) || ($oldmessages < 1)) {
550                         $folder = "INBOX";
551                 } else {
552                         $folder = "Old";
553                 }
554                 $message2 = "You have";
555                 if ($newmessages > 0) {
556                         $message2 .= " <b>$newmessages</b> NEW";
557                         if ($oldmessages > 0) {
558                                 $message2 .= "and <b>$oldmessages</b> OLD";
559                                 if ($oldmessages != 1) {
560                                         $message2 .= " messages.";
561                                 } else {
562                                         $message2 .= "message.";
563                                 }
564                         } else {
565                                 if ($newmessages != 1) {
566                                         $message2 .= " messages.";
567                                 } else {
568                                         $message2 .= " message.";
569                                 }
570                         }
571                 } else {
572                         if ($oldmessages > 0) {
573                                 $message2 .= " <b>$oldmessages</b> OLD";
574                                 if ($oldmessages != 1) {
575                                         $message2 .= " messages.";
576                                 } else {
577                                         $message2 .= " message.";
578                                 }
579                         } else {
580                                 $message2 .= " <b>no</b> messages.";
581                         }
582                 }
583         }
584         
585         my $folders = &folder_list('newfolder', $context, $mbox, $folder);
586         my $cfolders = &folder_list('changefolder', $context, $mbox, $folder);
587         my $mailboxes = &mailbox_list('forwardto', $context, $mbox);
588         print header(-cookie => &makecookie($format));
589         print <<_EOH;
590
591 <TITLE>Asterisk Web-Voicemail: $mbox\@$context $folder</TITLE>
592 <BODY BGCOLOR="white">
593 $stdcontainerstart
594 <FORM METHOD="post">
595 <table width=100% align=center>
596 <tr><td align=center colspan=2><font size=+2><I>$message</I></font></td></tr>
597 <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>
598 <tr><td align=left colspan=2><font size=+1>$message2</font></td></tr>
599 </table>
600 <table width=100% align=center cellpadding=0 cellspacing=0>
601 _EOH
602
603 print "<tr><td>&nbsp;Msg</td><td>&nbsp;From</td><td>&nbsp;Duration</td><td>&nbsp;Date</td><td>&nbsp;</td></tr>\n";
604 print "<tr><td><hr></td><td><hr></td><td><hr></td><td><hr></td><td></td></tr>\n";
605 foreach $msg (&messages($context, $mbox, $folder)) {
606
607         $fields = &getfields($context, $mbox, $folder, $msg);
608         $duration = $fields->{'duration'};
609         if ($duration) {
610                 $duration = sprintf "%d:%02d", $duration / 60, $duration % 60;
611         } else {
612                 $duration = "<i>Unknown</i>";
613         }
614         $hasmsg++;
615         print "<tr><td><input type=checkbox name=\"msgselect\" value=\"$msg\">&nbsp;<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";
616
617 }
618 if (!$hasmsg) {
619         print "<tr><td colspan=4 align=center><P><b><i>No messages</i></b><P></td></tr>";
620 }
621
622 print <<_EOH;
623 </table>
624 <table width=100% align=center>
625 <tr><td align=right colspan=2>
626         <input type="submit" name="action" value="refresh">&nbsp;
627 _EOH
628
629 if ($hasmsg) {
630 print <<_EOH;
631         <input type="submit" name="action" value="delete">&nbsp;
632         <input type="submit" name="action" value="save to ->">
633         $folders&nbsp;
634         <input type="submit" name="action" value="forward to ->">
635         $mailboxes
636 _EOH
637 }
638
639 print <<_EOH;
640 </td></tr>
641 <tr><td align=right colspan=2>
642         <input type="submit" name="action" value="preferences">
643         <input type="submit" name="action" value="logout">
644 </td></tr>
645 </table>
646 <input type=hidden name="folder" value="$folder">
647 <input type=hidden name="mailbox" value="$mbox">
648 <input type=hidden name="context" value="$context">
649 <input type=hidden name="password" value="$passwd">
650 </FORM>
651 $stdcontainerend
652 </BODY>\n
653 _EOH
654 }
655
656 sub validfolder()
657 {
658         my ($folder) = @_;
659         return grep(/^$folder$/, @validfolders);
660 }
661
662 sub folder_list()
663 {
664         my ($name, $context, $mbox, $selected) = @_;
665         my $f;
666         my $count;
667         my $tmp = "<SELECT name=\"$name\">\n";
668         foreach $f (@validfolders) {
669                 $count =  &msgcount($context, $mbox, $f);
670                 if ($f eq $selected) {
671                         $tmp .= "<OPTION SELECTED>$f ($count)</OPTION>\n";
672                 } else {
673                         $tmp .= "<OPTION>$f ($count)</OPTION>\n";
674                 }
675         }
676         $tmp .= "</SELECT>";
677 }
678
679 sub message_rename()
680 {
681         my ($context, $mbox, $oldfolder, $old, $newfolder, $new) = @_;
682         my $oldfile, $newfile;
683         return if ($old eq $new) && ($oldfolder eq $newfolder);
684
685         if ($context =~ /^(\w+)$/) {
686                 $context = $1;
687         } else {
688                 die("Invalid Context<BR>\n");
689         }
690         
691         if ($mbox =~ /^(\w+)$/) {
692                 $mbox = $1;
693         } else {
694                 die ("Invalid mailbox<BR>\n");
695         }
696         
697         if ($oldfolder =~ /^(\w+)$/) {
698                 $oldfolder = $1;
699         } else {
700                 die("Invalid old folder<BR>\n");
701         }
702         
703         if ($newfolder =~ /^(\w+)$/) {
704                 $newfolder = $1;
705         } else {
706                 die("Invalid new folder ($newfolder)<BR>\n");
707         }
708         
709         if ($old =~ /^(\d\d\d\d)$/) {
710                 $old = $1;
711         } else {
712                 die("Invalid old Message<BR>\n");
713         }
714         
715         if ($new =~ /^(\d\d\d\d)$/) {
716                 $new = $1;
717         } else {
718                 die("Invalid old Message<BR>\n");
719         }
720         
721         my $path = "/var/spool/asterisk/voicemail/$context/$mbox/$newfolder";
722         $path =~ /^(.*)$/;
723         $path = $1;
724         mkdir $path, 0770;
725         my $path = "/var/spool/asterisk/voicemail/$context/$mbox/$oldfolder";
726         opendir(DIR, $path) || die("Unable to open directory\n");
727         my @files = grep /^msg${old}\.\w+$/, readdir(DIR);
728         closedir(DIR);
729         foreach $oldfile (@files) {
730                 my $tmp = $oldfile;
731                 if ($tmp =~ /^(msg${old}.\w+)$/) {
732                         $tmp = $1;
733                         $oldfile = $path . "/$tmp";
734                         $tmp =~ s/msg${old}/msg${new}/;
735                         $newfile = "/var/spool/asterisk/voicemail/$context/$mbox/$newfolder/$tmp";
736 #                       print "Renaming $oldfile to $newfile<BR>\n";
737                         rename($oldfile, $newfile);
738                 }
739         }
740 }
741
742 sub file_copy()
743 {
744         my ($orig, $new) = @_;
745         my $res;
746         my $data;
747         $orig =~ /^(.*)$/;
748         $orig = $1;
749         $new =~ /^(.*)$/;
750         $new = $1;
751         open(IN, "<$orig") || die("Unable to open '$orig'\n");
752         open(OUT, ">$new") || DIE("Unable to open '$new'\n");
753         while(($res = sysread(IN, $data, 4096)) > 0) {
754                 syswrite(OUT, $data, $res);
755         }
756         close(OUT);
757         close(IN);
758 }
759
760 sub message_copy()
761 {
762         my ($context, $mbox, $newmbox, $oldfolder, $old, $new) = @_;
763         my $oldfile, $newfile;
764         return if ($mbox eq $newmbox);
765         
766         if ($mbox =~ /^(\w+)$/) {
767                 $mbox = $1;
768         } else {
769                 die ("Invalid mailbox<BR>\n");
770         }
771
772         if ($newmbox =~ /^(\w+)$/) {
773                 $newmbox = $1;
774         } else {
775                 die ("Invalid new mailbox<BR>\n");
776         }
777         
778         if ($oldfolder =~ /^(\w+)$/) {
779                 $oldfolder = $1;
780         } else {
781                 die("Invalid old folder<BR>\n");
782         }
783         
784         if ($old =~ /^(\d\d\d\d)$/) {
785                 $old = $1;
786         } else {
787                 die("Invalid old Message<BR>\n");
788         }
789         
790         if ($new =~ /^(\d\d\d\d)$/) {
791                 $new = $1;
792         } else {
793                 die("Invalid old Message<BR>\n");
794         }
795         
796         my $path = "/var/spool/asterisk/voicemail/$context/$newmbox";
797         $path =~ /^(.*)$/;
798         $path = $1;
799         mkdir $path, 0770;
800         my $path = "/var/spool/asterisk/voicemail/$context/$newmbox/INBOX";
801         $path =~ /^(.*)$/;
802         $path = $1;
803         mkdir $path, 0770;
804         my $path = "/var/spool/asterisk/voicemail/$context/$mbox/$oldfolder";
805         opendir(DIR, $path) || die("Unable to open directory\n");
806         my @files = grep /^msg${old}\.\w+$/, readdir(DIR);
807         closedir(DIR);
808         foreach $oldfile (@files) {
809                 my $tmp = $oldfile;
810                 if ($tmp =~ /^(msg${old}.\w+)$/) {
811                         $tmp = $1;
812                         $oldfile = $path . "/$tmp";
813                         $tmp =~ s/msg${old}/msg${new}/;
814                         $newfile = "/var/spool/asterisk/voicemail/$context/$newmbox/INBOX/$tmp";
815 #                       print "Copying $oldfile to $newfile<BR>\n";
816                         &file_copy($oldfile, $newfile);
817                 }
818         }
819 }
820
821 sub message_delete()
822 {
823         my ($context, $mbox, $folder, $msg) = @_;
824         if ($mbox =~ /^(\w+)$/) {
825                 $mbox = $1;
826         } else {
827                 die ("Invalid mailbox<BR>\n");
828         }
829         if ($context =~ /^(\w+)$/) {
830                 $context = $1;
831         } else {
832                 die ("Invalid context<BR>\n");
833         }
834         if ($folder =~ /^(\w+)$/) {
835                 $folder = $1;
836         } else {
837                 die("Invalid folder<BR>\n");
838         }
839         if ($msg =~ /^(\d\d\d\d)$/) {
840                 $msg = $1;
841         } else {
842                 die("Invalid Message<BR>\n");
843         }
844         my $path = "/var/spool/asterisk/voicemail/$context/$mbox/$folder";
845         opendir(DIR, $path) || die("Unable to open directory\n");
846         my @files = grep /^msg${msg}\.\w+$/, readdir(DIR);
847         closedir(DIR);
848         foreach $oldfile (@files) {
849                 if ($oldfile =~ /^(msg${msg}.\w+)$/) {
850                         $oldfile = $path . "/$1";
851 #                       print "Deleting $oldfile<BR>\n";
852                         unlink($oldfile);
853                 }
854         }
855 }
856
857 sub message_forward()
858 {
859         my ($toindex, @msgs) = @_;
860         my $folder = param('folder');
861         my ($mbox, $context) = split(/\@/, param('mailbox'));
862         my $newmbox = param('forwardto');
863         my $msg;
864         my $msgcount;
865         if (!$context) {
866                 $context = param('context');
867         }
868         if (!$context) {
869                 $context = "default";
870         }
871         $newmbox =~ s/(\w+)(\s+.*)?$/$1/;
872         if (!&validmailbox($context, $newmbox)) {
873                 die("Bah! Not a valid mailbox '$newmbox'\n");
874                 return "";
875         }
876         $msgcount = &msgcount($context, $newmbox, "INBOX");
877         my $txt;
878         if ($newmbox ne $mbox) {
879 #               print header;
880                 foreach $msg (@msgs) {
881 #                       print "Forwarding $msg from $mbox to $newmbox<BR>\n";
882                         &message_copy($context, $mbox, $newmbox, $folder, $msg, sprintf "%04d", $msgcount);
883                         $msgcount++;
884                 }
885                 $txt = "Forwarded messages " . join(', ', @msgs) . "to $newmbox";
886         } else {
887                 $txt = "Can't forward messages to yourself!\n";
888         } 
889         if ($toindex) {
890                 &message_index($folder, $txt);
891         } else {
892                 &message_play($txt, $msgs[0]);
893         }
894 }
895
896 sub message_delete_or_move()
897 {
898         my ($toindex, $del, @msgs) = @_;
899         my $txt;
900         my $path;
901         my $y, $x;
902         my $folder = param('folder');
903         my $newfolder = param('newfolder') unless $del;
904         $newfolder =~ s/^(\w+)\s+.*$/$1/;
905         my ($mbox, $context) = split(/\@/, param('mailbox'));
906         if (!$context) {
907                 $context = param('context');
908         }
909         if (!$context) {
910                 $context = "default";
911         }
912         my $passwd = param('password');
913         my $msgcount = &msgcount($context, $mbox, $folder);
914         my $omsgcount = &msgcount($context, $mbox, $newfolder) if $newfolder;
915 #       print header;
916         if ($newfolder ne $folder) {
917                 $y = 0;
918                 for ($x=0;$x<$msgcount;$x++) {
919                         my $msg = sprintf "%04d", $x;
920                         my $newmsg = sprintf "%04d", $y;
921                         if (grep(/^$msg$/, @msgs)) {
922                                 if ($newfolder) {
923                                         &message_rename($context, $mbox, $folder, $msg, $newfolder, sprintf "%04d", $omsgcount);
924                                         $omsgcount++;
925                                 } else {
926                                         &message_delete($context, $mbox, $folder, $msg);
927                                 }
928                         } else {
929                                 &message_rename($context, $mbox, $folder, $msg, $folder, $newmsg);
930                                 $y++;
931                         }
932                 }
933                 if ($del) {
934                         $txt = "Deleted messages "  . join (', ', @msgs);
935                 } else {
936                         $txt = "Moved messages "  . join (', ', @msgs) . " to $newfolder";
937                 }
938         } else {
939                 $txt = "Can't move a message to the same folder they're in already";
940         }
941         # Not as many messages now
942         $msgcount--;
943         if ($toindex || ($msgs[0] >= $msgcount)) {
944                 &message_index($folder, $txt);  
945         } else {
946                 &message_play($txt, $msgs[0]);
947         }
948 }
949
950 if (param()) {
951         my $folder = param('folder');
952         my $changefolder = param('changefolder');
953         $changefolder =~ s/(\w+)\s+.*$/$1/;
954         
955         my $newfolder = param('newfolder');
956         $newfolder =~ s/^(\w+)\s+.*$/$1/;
957         if ($newfolder && !&validfolder($newfolder)) {
958                 print header;
959                 die("Bah! new folder '$newfolder' isn't a folder.");
960         }
961         $action = param('action');
962         $msgid = param('msgid');
963         if (!$action) {
964                 my ($tmp) = grep /^play\d\d\d\d\.x$/, param;
965                 if ($tmp =~ /^play(\d\d\d\d)/) {
966                         $msgid = $1;
967                         $action = "play";
968                 } else {
969                         print header;
970                         print "No message?<BR>\n";
971                         return;
972                 }
973         }
974         @msgs = param('msgselect');
975         @msgs = ($msgid) unless @msgs;
976         {
977                 ($mailbox) = &check_login();
978                 if (length($mailbox)) {
979                         if ($action eq 'login') {
980                                 &message_index($folder, "Welcome, $mailbox");
981                         } elsif (($action eq 'refresh') || ($action eq 'index')) {
982                                 &message_index($folder, "Welcome, $mailbox");
983                         } elsif ($action eq 'change to ->') {
984                                 if (&validfolder($changefolder)) {
985                                         $folder = $changefolder;
986                                         &message_index($folder, "Welcome, $mailbox");
987                                 } else {
988                                         die("Bah!  Not a valid change to folder '$changefolder'\n");
989                                 }
990                         } elsif ($action eq 'play') {
991                                 &message_play("$mailbox $folder $msgid", $msgid);
992                         } elsif ($action eq 'preferences') {
993                                 &message_prefs("refresh", $msgid);
994                         } elsif ($action eq 'download') {
995                                 &message_audio(1);
996                         } elsif ($action eq 'play ') {
997                                 &message_audio(0);
998                         } elsif ($action eq 'audio') {
999                                 &message_audio(0);
1000                         } elsif ($action eq 'delete') {
1001                                 &message_delete_or_move(1, 1, @msgs);
1002                         } elsif ($action eq 'delete ') {
1003                                 &message_delete_or_move(0, 1, @msgs);
1004                         } elsif ($action eq 'forward to ->') {
1005                                 &message_forward(1, @msgs);
1006                         } elsif ($action eq 'forward to -> ') {
1007                                 &message_forward(0, @msgs);
1008                         } elsif ($action eq 'save to ->') {
1009                                 &message_delete_or_move(1, 0, @msgs);
1010                         } elsif ($action eq 'save to -> ') {
1011                                 &message_delete_or_move(0, 0, @msgs);
1012                         } elsif ($action eq 'logout') {
1013                                 &login_screen("Logged out!\n");
1014                         }
1015                 } else {
1016                         sleep(1);
1017                         &login_screen("Login Incorrect!\n");
1018                 }
1019         }
1020 } else {
1021         &login_screen("\&nbsp;");
1022 }