Handle hostnames with upper-case letters
[webmin.git] / fsdump / solaris-lib.pl
1 # solaris-lib.pl
2
3 # supported_filesystems()
4 # Returns a list of filesystem types on which dumping is supported
5 sub supported_filesystems
6 {
7 local @rv;
8 push(@rv, "ufs") if (&has_command("ufsdump"));
9 return @rv;
10 }
11
12 # multiple_directory_support(fs)
13 # Returns 1 if some filesystem dump supports multiple directories
14 sub multiple_directory_support
15 {
16 return $_[0] eq "ufs";
17 }
18
19 # dump_form(&dump)
20 sub dump_form
21 {
22 # Display destination options
23 print &ui_table_row(&hlink($text{'dump_dest'}, "dest"),
24    &ui_radio("mode", $_[0]->{'host'} ? 1 : 0,
25         [ [ 0, $text{'dump_file'}." ".
26                &ui_textbox("file", $_[0]->{'file'}, 50).
27                " ".&file_chooser_button("file")."<br>" ],
28           [ 1, &text('dump_host',
29                      &ui_textbox("host", $_[0]->{'host'}, 15),
30                      &ui_textbox("huser", $_[0]->{'huser'}, 8),
31                      &ui_textbox("hfile", $_[0]->{'hfile'}, 20)) ] ]), 3);
32 }
33
34 sub dump_options_form
35 {
36 local ($dump, $tds) = @_;
37
38 print &ui_table_row(&hlink($text{'dump_update'},"update"),
39                     &ui_yesno_radio("update", int($_[0]->{'update'})),
40                     1, $tds);
41
42 print &ui_table_row(&hlink($text{'dump_verify'},"verify"),
43                     &ui_yesno_radio("verify", int($_[0]->{'verify'})),
44                     1, $tds);
45
46 print &ui_table_row(&hlink($text{'dump_level'},"level"),
47                     &ui_select("level", int($_[0]->{'level'}),
48                         [ map { [ $_, $text{'dump_level_'.$_} ] }
49                               (0 .. 9) ]), 1, $tds);
50
51 print &ui_table_row(&hlink($text{'dump_offline'},"offline"),
52                     &ui_yesno_radio("offline", int($_[0]->{'offline'})),
53                     1, $tds);
54 }
55
56 # parse_dump(&dump)
57 sub parse_dump
58 {
59 # Parse common options
60 if ($in{'mode'} == 0) {
61         $in{'file'} =~ /\S/ || &error($text{'dump_efile'});
62         $_[0]->{'file'} = $in{'file'};
63         delete($_[0]->{'host'});
64         delete($_[0]->{'huser'});
65         delete($_[0]->{'hfile'});
66         }
67 else {
68         &to_ipaddress($in{'host'}) ||
69           &to_ip6address($in{'host'}) ||
70                 &error($text{'dump_ehost'});
71         $_[0]->{'host'} = $in{'host'};
72         $in{'huser'} =~ /^\S+$/ || &error($text{'dump_ehuser'});
73         $_[0]->{'huser'} = $in{'huser'};
74         $in{'hfile'} || &error($text{'dump_ehfile'});
75         $_[0]->{'hfile'} = $in{'hfile'};
76         delete($_[0]->{'file'});
77         }
78
79 $_[0]->{'update'} = $in{'update'};
80 $_[0]->{'verify'} = $in{'verify'};
81 $_[0]->{'level'} = $in{'level'};
82 $_[0]->{'offline'} = $in{'offline'};
83 }
84
85 # execute_dump(&dump, filehandle, escape, background-mode, [time])
86 # Executes a dump and displays the output
87 sub execute_dump
88 {
89 local $fh = $_[1];
90 local $cmd = "ufsdump $_[0]->{'level'}";
91 $cmd .= "u" if ($_[0]->{'update'});
92 $cmd .= "v" if ($_[0]->{'verify'});
93 $cmd .= "o" if ($_[0]->{'offline'});
94 if ($_[0]->{'huser'}) {
95         $cmd .= "f '$_[0]->{'huser'}\@$_[0]->{'host'}:".
96                 &date_subs($_[0]->{'hfile'}, $_[4])."'";
97         }
98 elsif ($_[0]->{'host'}) {
99         $cmd .= "f '$_[0]->{'host'}:".&date_subs($_[0]->{'hfile'}, $_[4])."'";
100         }
101 else {
102         $cmd .= "f '".&date_subs($_[0]->{'file'}, $_[4])."'";
103         }
104 $cmd .= " $_[0]->{'extra'}" if ($_[0]->{'extra'});
105 local @dirs = $_[0]->{'tabs'} ? split(/\t+/, $_[0]->{'dir'})
106                               : split(/\s+/, $_[0]->{'dir'});
107 $cmd .= " ".join(" ", map { "'$_'" } @dirs);
108
109 &system_logged("sync");
110 sleep(1);
111 &additional_log('exec', undef, $cmd);
112 &open_execute_command(CMD, "$cmd 2>&1 </dev/null", 1);
113 while(<CMD>) {
114         if ($_[2]) {
115                 print $fh &html_escape($_);
116                 }
117         else {
118                 print $fh $_;
119                 }
120         }
121 close(CMD);
122 return $? ? 0 : 1;
123 }
124
125 # dump_dest(&dump)
126 sub dump_dest
127 {
128 if ($_[0]->{'file'}) {
129         return "<tt>".&html_escape($_[0]->{'file'})."</tt>";
130         }
131 elsif ($_[0]->{'huser'}) {
132         return "<tt>".&html_escape("$_[0]->{'huser'}\@$_[0]->{'host'}:$_[0]->{'hfile'}")."</tt>";
133         }
134 else {
135         return "<tt>".&html_escape("$_[0]->{'host'}:$_[0]->{'hfile'}")."</tt>";
136         }
137 }
138
139 # missing_restore_command(filesystem)
140 sub missing_restore_command
141 {
142 return &has_command("ufsrestore") ? undef : "ufsrestore";
143 }
144
145 # restore_form(filesystem)
146 sub restore_form
147 {
148 # Restore from
149 print &ui_table_row(&hlink($text{'restore_src'}, "rsrc"),
150    &ui_radio("mode", $_[1]->{'host'} ? 1 : 0,
151         [ [ 0, $text{'dump_file'}." ".
152                &ui_textbox("file", $_[1]->{'file'}, 50).
153                " ".&file_chooser_button("file")."<br>" ],
154           [ 1, &text('dump_host',
155                      &ui_textbox("host", $_[1]->{'host'}, 15),
156                      &ui_textbox("huser", $_[1]->{'huser'}, 8),
157                      &ui_textbox("hfile", $_[1]->{'hfile'}, 20)) ] ]), 3, $tds);
158
159 # Files to restore
160 print &ui_table_row(&hlink($text{'restore_files'},"rfiles"),
161               &ui_opt_textbox("files", undef, 40, $text{'restore_all'},
162                               $text{'restore_sel'}), 3, $tds);
163
164 # Target dir
165 print &ui_table_row(&hlink($text{'restore_dir'},"rdir"),
166               &ui_textbox("dir", undef, 50)." ".
167               &file_chooser_button("dir", 1), 3, $tds);
168
169 # Show only
170 print &ui_table_row(&hlink($text{'restore_test'},"rtest"),
171               &ui_yesno_radio("test", 1), 1, $tds);
172 }
173
174 # parse_restore(filesystem)
175 # Parses inputs from restore_form() and returns a command to be passed to
176 # restore_backup()
177 sub parse_restore
178 {
179 local $cmd;
180 $cmd = "ufsrestore";
181 $cmd .= ($in{'test'} ? " t" : " x");
182 if ($in{'mode'} == 0) {
183         $in{'file'} || &error($text{'restore_efile'});
184         $cmd .= "f '$in{'file'}'";
185         }
186 else {
187         &to_ipaddress($in{'host'}) ||
188             &to_ip6address($in{'host'}) ||
189                 &error($text{'restore_ehost'});
190         $in{'huser'} =~ /^\S*$/ || &error($text{'restore_ehuser'});
191         $in{'hfile'} || &error($text{'restore_ehfile'});
192         if ($in{'huser'}) {
193                 $cmd .= "f '$in{'huser'}\@$in{'host'}:$in{'hfile'}'";
194                 }
195         else {
196                 $cmd .= "f '$in{'host'}:$in{'hfile'}'";
197                 }
198         }
199
200 $cmd .= " $in{'extra'}" if ($in{'extra'});
201 if (!$in{'files_def'}) {
202         $in{'files'} || &error($text{'restore_efiles'});
203         $cmd .= " $in{'files'}";
204         }
205 -d $in{'dir'} || &error($text{'restore_edir'});
206
207 return $cmd;
208 }
209
210 # restore_backup(filesystem, command)
211 # Restores a backup based on inputs from restore_form(), and displays the results
212 sub restore_backup
213 {
214 &additional_log('exec', undef, $_[1]);
215
216 &foreign_require("proc", "proc-lib.pl");
217 local ($fh, $fpid) = &foreign_call("proc", "pty_process_exec", "cd '$in{'dir'}' ; $_[1]");
218 local $donevolume;
219 while(1) {
220         local $rv = &wait_for($fh, "(next volume #)", "(set owner.mode for.*\\[yn\\])", "(Directories already exist, set modes anyway. \\[yn\\])", "((.*)\\[yn\\])", "(.*\\n)");
221         last if ($rv < 0);
222         print &html_escape($matches[1]);
223         if ($rv == 0) {
224                 if ($donevolume++) {
225                         return $text{'restore_evolume'};
226                         }
227                 else {
228                         syswrite($fh, "1\n", 2);
229                         }
230                 }
231         elsif ($rv == 1 || $rv == 2) {
232                 syswrite($fh, "n\n", 2);
233                 }
234         elsif ($rv == 3) {
235                 return &text('restore_equestion',
236                              "<tt>$matches[2]</tt>");
237                 }
238         }
239 close($fh);
240 waitpid($fpid, 0);
241 return $? || undef;
242 }
243
244 1;
245