2 # Send the webmin feedback form
4 BEGIN { push(@INC, ".."); };
8 if (&get_product_name() eq 'usermin') {
9 &switch_to_remote_user();
12 &error_setup($text{'feedback_err'});
13 %access = &get_module_acl();
14 $access{'feedback'} || &error($text{'feedback_ecannot'});
16 # Construct the email body
17 $in{'text'} =~ s/\r//g;
18 $date = localtime(time());
19 $ver = &get_webmin_version();
20 if ($in{'name'} && $in{'email'}) {
21 $from = "$in{'name'} <$in{'email'}>";
22 $email = $in{'email'};
24 elsif ($in{'email'}) {
25 $email = $from = $in{'email'};
28 $email = $from = "feedback\@".&get_system_hostname();
30 local $m = $in{'module'};
31 $m || !$in{'config'} || &error($text{'feedback_emodule'});
32 &check_os_support($m) && $m !~ /\.\./ || &error($text{'feedback_emodule2'});
34 %minfo = &get_module_info($m);
35 $ver .= " (Module: $minfo{'version'})" if ($minfo{'version'});
36 $module = "$m ($minfo{'desc'})";
41 if ($gconfig{'nofeedbackcc'}) {
42 @tolist = ( $gconfig{'feedback_to'} ||
44 $webmin_feedback_address );
47 @tolist = split(/\s+/, $in{'to'});
49 @tolist || &error($text{'feedback_enoto'});
50 foreach $t (@tolist) {
51 $headers .= "To: $t\n";
53 $headers .= "From: $from\n";
54 $headers .= "Subject: $text{'feedback_title'}\n";
57 Content-Type: text/plain
58 Content-Transfer-Encoding: 7bit
61 Email address: $in{'email'}
66 Browser: $ENV{'HTTP_USER_AGENT'}
72 OS from webmin: $gconfig{'real_os_type'} $gconfig{'real_os_version'}
73 OS code: $gconfig{'os_type'} $gconfig{'os_version'}
78 $attach[0] .= "\n".$in{'text'}."\n";
80 if ($in{'config'} && !$gconfig{'nofeedbackconfig'}) {
81 # Check if this user has full rights to the module
82 $access{'feedback'} >= 2 || &error($text{'feedback_ecannot2'});
83 local %uacl = &get_module_acl(undef, $m);
85 local $mdir = &module_root_directory($m);
86 &read_file("$mdir/defaultacl", \%defacl);
87 if ($access{'feedback'} != 3) {
88 foreach $k (keys %uacl) {
89 if ($defacl{$k} ne $uacl{$k}) {
90 &error($text{'feedback_econfig'});
95 # Attach all the text file from the module's config
96 local %mconfig = &foreign_config($m);
99 $a .= "Content-Type: text/plain; name=\"config\"\n";
100 $a .= "Content-Transfer-Encoding: 7bit\n";
102 foreach $k (keys %mconfig) {
103 $a .= "$k=$mconfig{$k}\n";
108 # Find out what config files the module uses
110 if (-r "$mdir/feedback_files.pl") {
111 # Ask the module for it's files
112 &foreign_require($m, "feedback_files.pl");
113 @files = &foreign_call($m, "feedback_files", $m);
116 # Use all the path in the config
117 foreach $k (keys %mconfig) {
118 push(@files, $mconfig{$k}) if ($mconfig{$k} =~ /^\//);
120 @files = &unique(@files);
122 # Attach those config files that are plain text (less than 5%
123 # non-ascii characters). Also skip logfiles.
124 foreach $f (@files) {
125 next if (!$f || -d $f);
126 next if ($f =~ /\/var\/log\//);
128 open(FILE, $f) || next;
129 local $data = <FILE>;
131 local $count = ($data =~ tr/[\000-\176]/[\000-\176]/);
132 if (!length($data) || 100*$count / length($data) > 95) {
135 local $sf = &short_name($f);
136 $a .= "Content-Type: text/plain; name=\"$sf\"\n";
137 $a .= "Content-Transfer-Encoding: 7bit\n";
145 # Include uploaded attached files
146 foreach $u ('attach0', 'attach1') {
149 local $name = &short_name($in{"${u}_filename"});
150 local $type = $in{"${u}_content_type"};
151 $type = &guess_mime_type($name) if (!$type);
152 $a .= "Content-type: $type; name=\"$name\"\n";
153 $a .= "Content-Transfer-Encoding: base64\n";
155 $a .= &encode_base64($in{$u});
160 # Build the MIME email
161 $bound = "bound".time();
163 $mail .= "Content-Type: multipart/mixed; boundary=\"$bound\"\n";
164 $mail .= "MIME-Version: 1.0\n";
166 $mail .= "This is a multi-part message in MIME format.\n";
167 foreach $a (@attach) {
168 $mail .= "\n--".$bound."\n";
171 $mail .= "\n--".$bound."--\n";
173 if (!$in{'mailserver_def'}) {
174 $ok = &send_via_smtp($in{'mailserver'});
179 # Try to send the email by calling sendmail -t
180 %sconfig = &foreign_config("sendmail");
181 $sendmail = $sconfig{'sendmail_path'} ? $sconfig{'sendmail_path'}
182 : &has_command("sendmail");
183 if (-x $sendmail && open(MAIL, "| $sendmail -t")) {
192 # Try to connect to a local SMTP server
193 $ok = &send_via_smtp("localhost");
198 # Tell the user that it was sent OK
199 &ui_print_header(undef, $text{'feedback_title'}, "", undef, 0, 1);
201 print &text('feedback_via', join(",", @tolist),
202 "<tt>$in{'mailserver'}</tt>"),"\n";
205 print &text('feedback_prog', join(",", @tolist),
206 "<tt>$sendmail</tt>"),"\n";
209 print &text('feedback_via', join(",", @tolist),
210 "<tt>localhost</tt>"),"\n";
213 &ui_print_footer("/?cat=$minfo{'category'}", $text{'index'});
215 # Save settings in config
216 $gconfig{'feedback_name'} = $in{'name'};
217 $gconfig{'feedback_email'} = $in{'email'};
218 $gconfig{'feedback_mailserver'} =
219 $in{'mailserver_def'} ? undef : $in{'mailserver'};
220 &write_file("$config_directory/config", \%gconfig);
223 # Give up! Tell the user ..
224 &error($text{'feedback_esend'});
230 &open_socket($_[0], 25, MAIL, \$error);
231 return 0 if ($error);
232 &smtp_command(MAIL) || return 0;
233 &smtp_command(MAIL, "helo ".&get_system_hostname()."\r\n") || return 0;
234 &smtp_command(MAIL, "mail from: <$email>\r\n") || return 0;
235 foreach $t (@tolist) {
236 &smtp_command(MAIL, "rcpt to: <$t>\r\n") || return 0;
238 &smtp_command(MAIL, "data\r\n");
240 $mail =~ s/\n/\r\n/g;
242 &smtp_command(MAIL, ".\r\n");
243 &smtp_command(MAIL, "quit\r\n");
248 # smtp_command(handle, command)
254 return $r =~ /^[23]\d+/;
259 $_[0] =~ /([^\\\/]+)$/;