Handle hostnames with upper-case letters
[webmin.git] / fsdump / irix-lib.pl
1 # irix-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, "xfs") if (&has_command("xfsdump"));
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;
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 # Display xfs dump options
37 print &ui_table_row(&hlink($text{'dump_level'},"level"),
38                     &ui_select("level", int($_[0]->{'level'}),
39                         [ map { [ $_, $text{'dump_level_'.$_} ] }
40                               (0 .. 9) ]), 1, $tds);
41
42 print &ui_table_row(&hlink($text{'dump_label'},"label"),
43                     &ui_textbox("label", $_[0]->{'label'}, 15),
44                     1, $tds);
45
46 print &ui_table_row(&hlink($text{'dump_max'},"max"),
47     &ui_opt_textbox("max", $_[0]->{'max'}, 8,
48                     $text{'dump_unlimited'})." kB", 1, $tds);
49
50 print &ui_table_row(&hlink($text{'dump_attribs'},"attribs"),
51                     &ui_yesno_radio("attribs", int($_[0]->{'attribs'})),
52                     1, $tds);
53
54 print &ui_table_row(&hlink($text{'dump_over'},"over"),
55                     &ui_yesno_radio("over", int($_[0]->{'over'})),
56                     1, $tds);
57
58 print &ui_table_row(&hlink($text{'dump_invent'},"invent"),
59                     &ui_radio("noinvent", int($_[0]->{'noinvent'}),
60                       [ [ 0, $text{'yes'} ], [ 1, $text{'no'} ] ]),
61                     1, $tds);
62
63 print &ui_table_row(&hlink($text{'dump_overwrite'},"overwrite"),
64             &ui_yesno_radio("overwrite", int($_[0]->{'overwrite'})),
65             1, $tds);
66
67 print &ui_table_row(&hlink($text{'dump_erase'},"erase"),
68                     &ui_yesno_radio("erase", int($_[0]->{'erase'})),
69                     1, $tds);
70 }
71
72 # parse_dump(&dump)
73 sub parse_dump
74 {
75 # Parse common options
76 if ($in{'mode'} == 0) {
77         $in{'file'} =~ /\S/ || &error($text{'dump_efile'});
78         $_[0]->{'file'} = $in{'file'};
79         delete($_[0]->{'host'});
80         delete($_[0]->{'huser'});
81         delete($_[0]->{'hfile'});
82         }
83 else {
84         &to_ipaddress($in{'host'}) ||
85             &to_ip6address($in{'host'}) ||
86                 &error($text{'dump_ehost'});
87         $_[0]->{'host'} = $in{'host'};
88         $in{'huser'} =~ /^\S+$/ || &error($text{'dump_ehuser'});
89         $_[0]->{'huser'} = $in{'huser'};
90         $in{'hfile'} || &error($text{'dump_ehfile'});
91         $_[0]->{'hfile'} = $in{'hfile'};
92         delete($_[0]->{'file'});
93         }
94
95 # Parse xfs options
96 &is_mount_point($in{'dir'}) || &error($text{'dump_emp'});
97 $in{'label'} =~ /^\S*$/ && length($in{'label'}) < 256 ||
98         &error($text{'dump_elabel2'});
99 $_[0]->{'label'} = $in{'label'};
100 $_[0]->{'level'} = $in{'level'};
101 if ($in{'max_def'}) {
102         delete($_[0]->{'max'});
103         }
104 else {
105         $in{'max'} =~ /^\d+$/ || &error($text{'dump_emax'});
106         $_[0]->{'max'} = $in{'max'};
107         }
108 $_[0]->{'noattribs'} = $in{'noattribs'};
109 $_[0]->{'over'} = $in{'over'};
110 $_[0]->{'noinvent'} = $in{'noinvent'};
111 $_[0]->{'overwrite'} = $in{'overwrite'};
112 $_[0]->{'erase'} = $in{'erase'};
113 }
114
115 # execute_dump(&dump, filehandle, escape, background-mode, [time])
116 # Executes a dump and displays the output
117 sub execute_dump
118 {
119 local $fh = $_[1];
120 local ($cmd, $flag);
121 if ($_[0]->{'huser'}) {
122         $flag = " -f '$_[0]->{'huser'}\@$_[0]->{'host'}:".
123                 &date_subs($_[0]->{'hfile'}, $_[4])."'";
124         }
125 elsif ($_[0]->{'host'}) {
126         $flag = " -f '$_[0]->{'host'}:".&date_subs($_[0]->{'hfile'}, $_[4])."'";
127         }
128 else {
129         $flag = " -f '".&date_subs($_[0]->{'file'}, $_[4])."'";
130         }
131 $cmd = "xfsdump -l $_[0]->{'level'}";
132 $cmd .= $flag;
133 $cmd .= " -L '$_[0]->{'label'}'" if ($_[0]->{'label'});
134 $cmd .= " -M '$_[0]->{'label'}'" if ($_[0]->{'label'});
135 $cmd .= " -z '$_[0]->{'max'}'" if ($_[0]->{'max'});
136 $cmd .= " -A" if ($_[0]->{'noattribs'});
137 $cmd .= " -F" if ($_[0]->{'over'});
138 $cmd .= " -J" if ($_[0]->{'noinvent'});
139 $cmd .= " -o" if ($_[0]->{'overwrite'});
140 $cmd .= " -c \"$_[3] $_[0]->{'id'}\"" if ($_[3]);
141 $cmd .= " -E -F" if ($_[0]->{'erase'});
142 $cmd .= " $_[0]->{'extra'}" if ($_[0]->{'extra'});
143 $cmd .= " '$_[0]->{'dir'}'";
144
145 &system_logged("sync");
146 sleep(1);
147 &additional_log('exec', undef, $cmd);
148 &open_execute_command(CMD, "$cmd 2>&1 </dev/null", 1);
149 while(<CMD>) {
150         if ($_[2]) {
151                 print $fh &html_escape($_);
152                 }
153         else {
154                 print $fh $_;
155                 }
156         }
157 close(CMD);
158 return $? ? 0 : 1;
159 }
160
161 # dump_dest(&dump)
162 sub dump_dest
163 {
164 if ($_[0]->{'file'}) {
165         return "<tt>".&html_escape($_[0]->{'file'})."</tt>";
166         }
167 elsif ($_[0]->{'huser'}) {
168         return "<tt>".&html_escape("$_[0]->{'huser'}\@$_[0]->{'host'}:$_[0]->{'hfile'}")."</tt>";
169         }
170 else {
171         return "<tt>".&html_escape("$_[0]->{'host'}:$_[0]->{'hfile'}")."</tt>";
172         }
173 }
174
175 # missing_restore_command(filesystem)
176 sub missing_restore_command
177 {
178 local $cmd = $_[0] eq 'xfs' ? 'xfsrestore' : 'restore';
179 return &has_command($cmd) ? undef : $cmd;
180 }
181
182 # restore_form(filesystem)
183 sub restore_form
184 {
185 # Restore from
186 print &ui_table_row(&hlink($text{'restore_src'}, "rsrc"),
187    &ui_radio("mode", $_[1]->{'host'} ? 1 : 0,
188         [ [ 0, $text{'dump_file'}." ".
189                &ui_textbox("file", $_[1]->{'file'}, 50).
190                " ".&file_chooser_button("file")."<br>" ],
191           [ 1, &text('dump_host',
192                      &ui_textbox("host", $_[1]->{'host'}, 15),
193                      &ui_textbox("huser", $_[1]->{'huser'}, 8),
194                      &ui_textbox("hfile", $_[1]->{'hfile'}, 20)) ] ]), 3, $tds);
195
196 # Target dir
197 print &ui_table_row(&hlink($text{'restore_dir'},"rdir"),
198               &ui_textbox("dir", undef, 50)." ".
199               &file_chooser_button("dir", 1), 3, $tds);
200
201 # Overwrite
202 print &ui_table_row(&hlink($text{'restore_over'},"rover"),
203         &ui_radio("over", 0, [ [ 0, $text{'restore_over0'} ],
204                                [ 1, $text{'restore_over1'} ],
205                                [ 2, $text{'restore_over2'} ] ]), 3, $tds);
206
207 # Attributes?
208 print &ui_table_row(&hlink($text{'restore_noattribs'},"rnoattribs"),
209         &ui_radio("noattribs", 0, [ [ 0, $text{'yes'} ],
210                                     [ 1, $text{'no'} ] ]), 1, $tds);
211
212 # Label to restore from
213 print &ui_table_row(&hlink($text{'restore_label'},"rlabel"),
214         &ui_textbox("label", undef, 20), 1, $tds);
215
216 # Show only
217 print &ui_table_row(&hlink($text{'restore_test'},"rtest"),
218               &ui_yesno_radio("test", 1), 1, $tds);
219 }
220
221 # parse_restore(filesystem)
222 # Parses inputs from restore_form() and returns a command to be passed to
223 # restore_backup()
224 sub parse_restore
225 {
226 local $cmd = "xfsrestore";
227 $cmd .= " -t" if ($in{'test'});
228 if ($in{'mode'} == 0) {
229         $in{'file'} || &error($text{'restore_efile'});
230         $cmd .= " -f '$in{'file'}'";
231         }
232 else {
233         &to_ipaddress($in{'host'}) ||
234             &to_ip6address($in{'host'}) ||
235                 &error($text{'restore_ehost'});
236         $in{'huser'} =~ /^\S*$/ || &error($text{'restore_ehuser'});
237         $in{'hfile'} || &error($text{'restore_ehfile'});
238         if ($in{'huser'}) {
239                 $cmd .= " -f '$in{'huser'}\@$in{'host'}:$in{'hfile'}'";
240                 }
241         else {
242                 $cmd .= " -f '$in{'host'}:$in{'hfile'}'";
243                 }
244         }
245 $cmd .= " -E" if ($in{'over'} == 1);
246 $cmd .= " -e" if ($in{'over'} == 2);
247 $cmd .= " -A" if ($in{'noattribs'});
248 $cmd .= " -L '$in{'label'}'" if ($in{'label'});
249 $cmd .= " -F";
250 $cmd .= " $in{'extra'}" if ($in{'extra'});
251 if (!$in{'test'}) {
252         -d $in{'dir'} || &error($text{'restore_edir'});
253         $cmd .= " '$in{'dir'}'";
254         }
255 return $cmd;
256 }
257
258 # restore_backup(filesystem, command)
259 # Restores a backup based on inputs from restore_form(), and displays the results
260 sub restore_backup
261 {
262 &additional_log('exec', undef, $_[1]);
263 if ($_[0] eq 'xfs') {
264         # Just run the backup command
265         &open_execute_command(CMD, "$_[1] 2>&1 </dev/null", 1);
266         while(<CMD>) {
267                 print &html_escape($_);
268                 }
269         close(CMD);
270         return $? || undef;
271         }
272 else {
273         # Need to supply prompts
274         &foreign_require("proc", "proc-lib.pl");
275         local ($fh, $fpid) = &foreign_call("proc", "pty_process_exec", "cd '$in{'dir'}' ; $_[1]");
276         local $donevolume;
277         while(1) {
278                 local $rv = &wait_for($fh, "(next volume #)", "(set owner.mode for.*\\[yn\\])", "((.*)\\[yn\\])", "(.*\\n)");
279                 last if ($rv < 0);
280                 print &html_escape($matches[1]);
281                 if ($rv == 0) {
282                         if ($donevolume++) {
283                                 return $text{'restore_evolume'};
284                                 }
285                         else {
286                                 syswrite($fh, "1\n", 2);
287                                 }
288                         }
289                 elsif ($rv == 1) {
290                         syswrite($fh, "n\n", 2);
291                         }
292                 elsif ($rv == 2) {
293                         return &text('restore_equestion',
294                                      "<tt>$matches[2]</tt>");
295                         }
296                 }
297         close($fh);
298         waitpid($fpid, 0);
299         return $? || undef;
300         }
301 }
302
303 1;
304