Handle hostnames with upper-case letters
[webmin.git] / fsdump / linux-lib.pl.bak
1 # linux-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, "ext2", "ext3") if (&has_command("dump"));
9 push(@rv, "xfs") if (&has_command("xfsdump"));
10 return @rv;
11 }
12
13 # dump_form(&dump)
14 sub dump_form
15 {
16 # Display common options
17 print "<tr> <td valign=top><b>",&hlink($text{'dump_dest'}, "dest"),
18       "</b></td> <td colspan=3>\n";
19 printf "<input type=radio name=mode value=0 %s> %s\n",
20         $_[0]->{'host'} ? '' : 'checked', $text{'dump_file'};
21 printf "<input name=file size=50 value='%s'> %s<br>\n",
22         $_[0]->{'host'} ? '' : $_[0]->{'file'},
23         &file_chooser_button("file");
24 printf "<input type=radio name=mode value=1 %s>\n",
25         $_[0]->{'host'} ? 'checked' : '';
26 print &text('dump_host',
27             "<input name=host size=15 value='$_[0]->{'host'}'>",
28             "<input name=huser size=8 value='$_[0]->{'huser'}'>",
29             "<input name=hfile size=20 value='$_[0]->{'hfile'}'>"),
30       "</td> </tr>\n";
31
32 if ($_[0]->{'fs'} eq 'xfs') {
33         # Display xfs dump options
34         print "<tr> <td><b>",&hlink($text{'dump_level'},"level"),"</b></td>\n";
35         print "<td><select name=level>\n";
36         foreach $l (0 .. 9) {
37                 printf "<option value=%d %s>%d %s\n",
38                         $l, $_[0]->{'level'} == $l ? "selected" : "", $l,
39                         $text{'dump_level_'.$l};
40                 }
41         print "</select></td>\n";
42
43         print "<td><b>",&hlink($text{'dump_label'},"label"),"</b></td>\n";
44         printf "<td><input name=label size=15 value='%s'></td> </tr>\n",
45                 $_[0]->{'label'};
46
47         print "<tr> <td><b>",&hlink($text{'dump_max'},"max"),"</b></td>\n";
48         printf "<td><input type=radio name=max_def value=1 %s> %s\n",
49                 $_[0]->{'max'} ? '' : 'checked', $text{'dump_unlimited'};
50         printf "<input type=radio name=max_def value=0 %s>\n",
51                 $_[0]->{'max'} ? 'checked' : '';
52         printf "<input name=max size=8 value='%s'> kB</td>\n", $_[0]->{'max'};
53
54         print "<td><b>",&hlink($text{'dump_attribs'},"attribs"),"</b></td>\n";
55         printf "<td><input type=radio name=noattribs value=0 %s> %s\n",
56                 $_[0]->{'noattribs'} ? '' : 'checked', $text{'yes'};
57         printf "<input type=radio name=noattribs value=1 %s> %s</td> </tr>\n",
58                 $_[0]->{'noattribs'} ? 'checked' : '', $text{'no'};
59
60         print "<tr> <td><b>",&hlink($text{'dump_over'},"over"),"</b></td>\n";
61         printf "<td><input type=radio name=over value=0 %s> %s\n",
62                 $_[0]->{'over'} ? '' : 'checked', $text{'yes'};
63         printf "<input type=radio name=over value=1 %s> %s</td>\n",
64                 $_[0]->{'over'} ? 'checked' : '', $text{'no'};
65
66         print "<td><b>",&hlink($text{'dump_invent'},"invent"),"</b></td>\n";
67         printf "<td><input type=radio name=noinvent value=0 %s> %s\n",
68                 $_[0]->{'noinvent'} ? '' : 'checked', $text{'yes'};
69         printf "<input type=radio name=noinvent value=1 %s> %s</td> </tr>\n",
70                 $_[0]->{'noinvent'} ? 'checked' : '', $text{'no'};
71
72         print "<tr> <td><b>",&hlink($text{'dump_overwrite'},"overwrite"),
73               "</b></td>\n";
74         printf "<td><input type=radio name=overwrite value=1 %s> %s\n",
75                 $_[0]->{'overwrite'} ? 'checked' : '', $text{'yes'};
76         printf "<input type=radio name=overwrite value=0 %s> %s</td>\n",
77                 $_[0]->{'overwrite'} ? '' : 'checked', $text{'no'};
78
79         print "<td><b>",&hlink($text{'dump_erase'},"erase"),"</b></td>\n";
80         printf "<td><input type=radio name=erase value=1 %s> %s\n",
81                 $_[0]->{'erase'} ? 'checked' : '', $text{'yes'};
82         printf "<input type=radio name=erase value=0 %s> %s</td> </tr>\n",
83                 $_[0]->{'erase'} ? '' : 'checked', $text{'no'};
84         }
85 else {
86         # Display ext2/3 filesystem dump options
87         print "<tr> <td><b>",&hlink($text{'dump_update'},"update"),
88               "</b></td>\n";
89         printf "<td><input name=update type=radio value=1 %s> %s\n",
90                 $_[0]->{'update'} ? 'checked' : '', $text{'yes'};
91         printf "<input name=update type=radio value=0 %s> %s</td>\n",
92                 $_[0]->{'update'} ? '' : 'checked', $text{'no'};
93
94         print "<td><b>",&hlink($text{'dump_multi'},"multi"),"</b></td>\n";
95         printf "<td><input name=multi type=radio value=1 %s> %s\n",
96                 $_[0]->{'multi'} ? 'checked' : '', $text{'yes'};
97         printf "<input name=multi type=radio value=0 %s> %s</td> </tr>\n",
98                 $_[0]->{'multi'} ? '' : 'checked', $text{'no'};
99
100         print "<tr> <td><b>",&hlink($text{'dump_level'},"level"),"</b></td>\n";
101         print "<td><select name=level>\n";
102         foreach $l (0 .. 9) {
103                 printf "<option value=%d %s>%d %s\n",
104                         $l, $_[0]->{'level'} == $l ? "selected" : "", $l,
105                         $text{'dump_level_'.$l};
106                 }
107         print "</select></td>\n";
108
109         print "<td><b>",&hlink($text{'dump_label'},"label"),"</b></td>\n";
110         printf "<td><input name=label size=15 value='%s'></td> </tr>\n",
111                 $_[0]->{'label'};
112         }
113 }
114
115 # parse_dump(&dump)
116 sub parse_dump
117 {
118 # Parse common options
119 if ($in{'mode'} == 0) {
120         $in{'file'} =~ /\S/ || &error($text{'dump_efile'});
121         $_[0]->{'file'} = $in{'file'};
122         delete($_[0]->{'host'});
123         delete($_[0]->{'huser'});
124         delete($_[0]->{'hfile'});
125         }
126 else {
127         gethostbyname($in{'host'}) || &check_ipaddress($in{'host'}) ||
128                 &error($text{'dump_ehost'});
129         $_[0]->{'host'} = $in{'host'};
130         $in{'huser'} =~ /^\S+$/ || &error($text{'dump_ehuser'});
131         $_[0]->{'huser'} = $in{'huser'};
132         $in{'hfile'} || &error($text{'dump_ehfile'});
133         $_[0]->{'hfile'} = $in{'hfile'};
134         delete($_[0]->{'file'});
135         }
136
137 if ($_[0]->{'fs'} eq 'xfs') {
138         # Parse xfs options
139         local $mp;
140         foreach $m (&foreign_call("mount", "list_mounted")) {
141                 $mp++ if ($m->[0] eq $in{'dir'});
142                 }
143         $mp || &error($text{'dump_emp'});
144         $in{'label'} =~ /^\S*$/ && length($in{'label'}) < 256 ||
145                 &error($text{'dump_elabel2'});
146         $_[0]->{'label'} = $in{'label'};
147         $_[0]->{'level'} = $in{'level'};
148         if ($in{'max_def'}) {
149                 delete($_[0]->{'max'});
150                 }
151         else {
152                 $in{'max'} =~ /^\d+$/ || &error($text{'dump_emax'});
153                 $_[0]->{'max'} = $in{'max'};
154                 }
155         $_[0]->{'noattribs'} = $in{'noattribs'};
156         $_[0]->{'over'} = $in{'over'};
157         $_[0]->{'noinvent'} = $in{'noinvent'};
158         $_[0]->{'overwrite'} = $in{'overwrite'};
159         $_[0]->{'erase'} = $in{'erase'};
160         }
161 else {
162         # Parse ext2/3 options
163         $_[0]->{'update'} = $in{'update'};
164         $_[0]->{'multi'} = $in{'multi'};
165         $_[0]->{'level'} = $in{'level'};
166         $in{'label'} =~ /^\S*$/ && length($in{'label'}) < 16 ||
167                 &error($text{'dump_elabel'});
168         $_[0]->{'label'} = $in{'label'};
169         }
170
171 }
172
173 # execute_dump(&dump, filehandle, escape)
174 # Executes a dump and displays the output
175 sub execute_dump
176 {
177 local $fh = $_[1];
178 local ($cmd, $flag);
179 if ($_[0]->{'huser'}) {
180         $flag = " -f '$_[0]->{'huser'}@$_[0]->{'host'}:$_[0]->{'hfile'}'";
181         }
182 elsif ($_[0]->{'host'}) {
183         $flag = " -f '$_[0]->{'host'}:$_[0]->{'hfile'}'";
184         }
185 else {
186         $flag = " -f '$_[0]->{'file'}'";
187         }
188 if ($_[0]->{'fs'} eq 'xfs') {
189         # xfs backup
190         $cmd = "xfsdump -l $_[0]->{'level'}";
191         $cmd .= $flag;
192         $cmd .= " -L '$_[0]->{'label'}'" if ($_[0]->{'label'});
193         $cmd .= " -M '$_[0]->{'label'}'" if ($_[0]->{'label'});
194         $cmd .= " -z '$_[0]->{'max'}'" if ($_[0]->{'max'});
195         $cmd .= " -A" if ($_[0]->{'noattribs'});
196         $cmd .= " -F" if ($_[0]->{'over'});
197         $cmd .= " -J" if ($_[0]->{'noinvent'});
198         $cmd .= " -o" if ($_[0]->{'overwrite'});
199         $cmd .= " -E -F" if ($_[0]->{'erase'});
200         $cmd .= " '$_[0]->{'dir'}'";
201         }
202 else {
203         # ext2/3 backup
204         $cmd = "dump -$_[0]->{'level'}";
205         $cmd .= $flag;
206         $cmd .= " -u" if ($_[0]->{'update'});
207         $cmd .= " -M" if ($_[0]->{'multi'});
208         $cmd .= " -L '$_[0]->{'label'}'" if ($_[0]->{'label'});
209         $cmd .= " '$_[0]->{'dir'}'";
210         }
211
212 &system_logged("sync");
213 sleep(1);
214 &additional_log('exec', undef, $cmd);
215 open(CMD, "$cmd 2>&1 </dev/null |");
216 while(<CMD>) {
217         if ($_[2]) {
218                 print $fh &html_escape($_);
219                 }
220         else {
221                 print $fh $_;
222                 }
223         }
224 close(CMD);
225 }
226
227 # dump_dest(&dump)
228 sub dump_dest
229 {
230 if ($_[0]->{'file'}) {
231         return "<tt>".&html_escape($_[0]->{'file'})."</tt>";
232         }
233 elsif ($_[0]->{'huser'}) {
234         return "<tt>".&html_escape("$_[0]->{'huser'}@$_[0]->{'host'}:$_[0]->{'hfile'}")."</tt>";
235         }
236 else {
237         return "<tt>".&html_escape("$_[0]->{'host'}:$_[0]->{'hfile'}")."</tt>";
238         }
239 }
240
241 # missing_restore_command(filesystem)
242 sub missing_restore_command
243 {
244 local $cmd = $_[0] eq 'xfs' ? 'xfsrestore' : 'restore';
245 return &has_command($cmd) ? undef : $cmd;
246 }
247
248 # restore_form(filesystem)
249 sub restore_form
250 {
251 # common options
252 print "<tr> <td valign=top><b>",&hlink($text{'restore_src'}, "rsrc"),
253       "</b></td>\n";
254 printf "<td colspan=3><input type=radio name=mode value=0 checked> %s\n",
255         $text{'dump_file'};
256 printf "<input name=file size=50> %s<br>\n",
257         &file_chooser_button("file");
258 printf "<input type=radio name=mode value=1>\n";
259 print &text('dump_host',
260             "<input name=host size=15>",
261             "<input name=huser size=8>",
262             "<input name=hfile size=20>"),
263       "</td> </tr>\n";
264
265 if ($_[0] eq 'xfs') {
266         # xfs restore options
267         print "<tr> <td><b>",&hlink($text{'restore_dir'},"rdir"),
268               "</b></td> <td colspan=3>\n";
269         print "<input name=dir size=50> ",&file_chooser_button("dir", 1),
270               "</td> </tr>\n";
271
272         print "<tr> <td><b>",&hlink($text{'restore_over'},"rover"),
273               "</b></td>\n";
274         print "<td colspan=3><input type=radio name=over value=0 checked> ",
275               "$text{'restore_over0'}\n";
276         print "<input type=radio name=over value=1> $text{'restore_over1'}\n";
277         print "<input type=radio name=over value=2> ",
278               "$text{'restore_over2'}</td> </tr>\n";
279
280         print "<tr> <td><b>",&hlink($text{'restore_noattribs'},"rnoattribs"),
281               "</b></td> <td>\n";
282         print "<input type=radio name=noattribs value=0 checked> $text{'yes'}\n";
283         print "<input type=radio name=noattribs value=1> $text{'no'}</td>\n";
284
285         print "<td><b>",&hlink($text{'restore_label'},"rlabel"),"</b></td>\n";
286         print "<td><input name=label size=20></td> </tr>\n";
287
288         print "<tr> <td><b>",&hlink($text{'restore_test'},"rtest"),"</td>\n";
289         print "<td><input type=radio name=test value=1> $text{'yes'}\n";
290         print "<input type=radio name=test value=0 checked> $text{'no'}</td> </tr>\n";
291         }
292 else {
293         # ext2/3 restore options
294         print "<tr> <td><b>",&hlink($text{'restore_files'},"rfiles"),
295               "</b></td>\n";
296         print "<td colspan=3><input type=radio name=files_def value=1 checked> ",
297               "$text{'restore_all'}\n";
298         print "<input type=radio name=files_def value=0> $text{'restore_sel'}\n";
299         print "<input name=files size=40></td> </tr>\n";
300
301         print "<tr> <td><b>",&hlink($text{'restore_dir'},"rdir"),"</td>\n";
302         print "<td colspan=3><input name=dir size=40> ",
303                 &file_chooser_button("dir", 1),"</td> </tr>\n";
304
305         print "<tr> <td><b>",&hlink($text{'restore_multi'},"rmulti"),
306               "</b></td>\n";
307         print "<td><input type=radio name=multi value=1> $text{'yes'}\n";
308         print "<input type=radio name=multi value=0 checked> $text{'no'}</td>\n";
309
310         print "<td><b>",&hlink($text{'restore_test'},"rtest"),"</td>\n";
311         print "<td><input type=radio name=test value=1> $text{'yes'}\n";
312         print "<input type=radio name=test value=0 checked> $text{'no'}</td> </tr>\n";
313         }
314 }
315
316 # parse_restore(filesystem)
317 # Parses inputs from restore_form() and returns a command to be passed to
318 # restore_backup()
319 sub parse_restore
320 {
321 local $cmd;
322 if ($_[0] eq 'xfs') {
323         $cmd = "xfsrestore";
324         $cmd .= " -t" if ($in{'test'});
325         }
326 else {
327         $cmd = "restore";
328         $cmd .= ($in{'test'} ? " -t" : " -x");
329         }
330 if ($in{'mode'} == 0) {
331         $in{'file'} || &error($text{'restore_efile'});
332         $cmd .= " -f '$in{'file'}'";
333         }
334 else {
335         gethostbyname($in{'host'}) || &check_ipaddress($in{'host'}) ||
336                 &error($text{'restore_ehost'});
337         $in{'huser'} =~ /^\S*$/ || &error($text{'restore_ehuser'});
338         $in{'hfile'} || &error($text{'restore_ehfile'});
339         if ($in{'huser'}) {
340                 $cmd .= " -f '$in{'huser'}@$in{'host'}:$in{'hfile'}'";
341                 }
342         else {
343                 $cmd .= " -f '$in{'host'}:$in{'hfile'}'";
344                 }
345         }
346 if ($_[0] eq 'xfs') {
347         # parse xfs options
348         $cmd .= " -E" if ($in{'over'} == 1);
349         $cmd .= " -e" if ($in{'over'} == 2);
350         $cmd .= " -A" if ($in{'noattribs'});
351         $cmd .= " -L '$in{'label'}'" if ($in{'label'});
352         $cmd .= " -F";
353         if (!$in{'test'}) {
354                 -d $in{'dir'} || &error($text{'restore_edir'});
355                 $cmd .= " '$in{'dir'}'";
356                 }
357         }
358 else {
359         # parse ext2/3 options
360         $cmd .= " -M" if ($in{'multi'});
361         if (!$in{'files_def'}) {
362                 $in{'files'} || &error($text{'restore_efiles'});
363                 $cmd .= " $in{'files'}";
364                 }
365         -d $in{'dir'} || &error($text{'restore_edir'});
366         }
367 return $cmd;
368 }
369
370 # restore_backup(filesystem, command)
371 # Restores a backup based on inputs from restore_form(), and displays the results
372 sub restore_backup
373 {
374 &additional_log('exec', undef, $_[1]);
375 if ($_[0] eq 'xfs') {
376         # Just run the backup command
377         open(CMD, "$_[1] 2>&1 </dev/null |");
378         while(<CMD>) {
379                 print &html_escape($_);
380                 }
381         close(CMD);
382         }
383 else {
384         # Need to supply prompts
385         &foreign_require("proc", "proc-lib.pl");
386         local ($fh, $fpid) = &foreign_call("proc", "pty_process_exec", "cd '$in{'dir'}' ; $_[1]");
387         local $donevolume;
388         while(1) {
389                 local $rv = &wait_for($fh, "(next volume #)", "(set owner.mode for.*\\[yn\\])", "((.*)\\[yn\\])", "(.*\\n)");
390                 last if ($rv < 0);
391                 print &html_escape($matches[1]);
392                 if ($rv == 0) {
393                         if ($donevolume++) {
394                                 return $text{'restore_evolume'};
395                                 }
396                         else {
397                                 syswrite($fh, "1\n");
398                                 }
399                         }
400                 elsif ($rv == 1) {
401                         syswrite($fh, "n\n");
402                         }
403                 elsif ($rv == 2) {
404                         return &text('restore_equestion',
405                                      "<tt>$matches[2]</tt>");
406                         }
407                 }
408         close($fh);
409         }
410 return undef;
411 }
412
413 1;
414