Handle hostnames with upper-case letters
[webmin.git] / mailboxes / detach.cgi
1 #!/usr/local/bin/perl
2 # detach.cgi
3 # View one attachment from a message
4
5 use Socket;
6 require './mailboxes-lib.pl';
7 &ReadParse();
8 &can_user($in{'user'}) || &error($text{'mail_ecannot'});
9
10 @folders = &list_user_folders($in{'user'});
11 $folder = $folders[$in{'folder'}];
12 @mail = &mailbox_list_mails($in{'idx'}, $in{'idx'}, $folder);
13 $mail = $mail[$in{'idx'}];
14 &parse_mail($mail);
15 @sub = split(/\0/, $in{'sub'});
16 foreach $s (@sub) {
17         # We are looking at a mail within a mail ..
18         local $amail = &extract_mail($mail->{'attach'}->[$s]->{'data'});
19         &parse_mail($amail);
20         $mail = $amail;
21         }
22 $attach = $mail->{'attach'}->[$in{'attach'}];
23
24 if ($in{'scale'}) {
25         # Scale the gif or jpeg image to 48 pixels high
26         local $temp = &transname();
27         open(TEMP, ">$temp");
28         print TEMP $attach->{'data'};
29         close(TEMP);
30         $SIG{'CHLD'} = sub { wait; };
31         if ($attach->{'type'} eq 'image/gif') {
32                 ($pnmin, $pnmout) = &pipeopen("giftopnm $temp");
33                 }
34         elsif ($attach->{'type'} eq 'image/jpeg') {
35                 ($pnmin, $pnmout) = &pipeopen("djpeg -fast $temp");
36                 }
37         else {
38                 &dump_erroricon();
39                 }
40         close($pnmin);
41         $type = <$pnmout>;
42         $size = <$pnmout>;
43         unlink($temp);
44         $type =~ /^P[0-9]/ || &dump_erroricon();
45         $size =~ /(\d+)\s+(\d+)/ || &dump_erroricon();
46         ($w, $h) = ($1, $2);
47         if ($w > 48) {
48                 $scale = 48.0 / $w;
49                 }
50         else {
51                 $scale = 48.0 / $h;
52                 }
53         ($jpegin, $jpegout) = &pipeopen("pnmscale $scale 2>/dev/null | cjpeg");
54         print $jpegin $type;
55         print $jpegin $size;
56         while(read($pnmout, $buf, 1024)) {
57                 print $jpegin $buf;
58                 }
59         close($jpegin);
60         close($pnmout);
61         print "Content-type: image/jpeg\n\n";
62         while(read($jpegout, $buf, 1024)) {
63                 print $buf;
64                 }
65         close($jpegout);
66         }
67 else {
68         # Just output the attachment
69         print "X-no-links: 1\n";
70         @download = split(/\t+/, $config{'download'});
71         if ($in{'type'}) {
72                 # Display as a specific MIME type
73                 print "Content-type: $in{'type'}\n\n";
74                 print $attach->{'data'};
75                 }
76         else {
77                 # Auto-detect type
78                 if ($in{'save'}) {
79                         # Force download
80                         print "Content-Disposition: Attachment\n";
81                         }
82                 if ($attach->{'type'} eq 'message/delivery-status') {
83                         print "Content-type: text/plain\n\n";
84                         }
85                 else {
86                         print "Content-type: $attach->{'type'}\n\n";
87                         }
88                 }
89         if ($attach->{'type'} =~ /^text\/html/i && !$in{'save'}) {
90                 print &safe_urls(&filter_javascript($attach->{'data'}));
91                 }
92         else {
93                 print $attach->{'data'};
94                 }
95         }
96 &pop3_logout_all();
97
98 sub dump_erroricon
99 {
100 print "Content-type: image/gif\n\n";
101 open(ICON, "images/error.gif");
102 while(<ICON>) { print; }
103 close(ICON);
104 exit;
105 }
106
107 # pipeopen(command)
108 sub pipeopen
109 {
110 $pipe++;
111 local $inr = "INr$pipe";
112 local $inw = "INw$pipe";
113 local $outr = "OUTr$pipe";
114 local $outw = "OUTw$pipe";
115 pipe($inr, $inw);
116 pipe($outr, $outw);
117 if (!fork()) {
118         untie(*STDIN);
119         untie(*STDOUT);
120         open(STDIN, "<&$inr");
121         open(STDOUT, ">&$outw");
122         close($inw);
123         close($outr);
124         exec($_[0]);
125         print STDERR "exec failed : $!\n";
126         exit 1;
127         }
128 close($inr);
129 close($outw);
130 return ($inw, $outr);
131 }