1#!/usr/local/bin/perl
2# edit_part.cgi
3# Edit an existing partition, or create a new one
4
5require './fdisk-lib.pl';
6&ReadParse();
7@dlist = &list_disks_partitions();
8$dinfo = $dlist[$in{'disk'}];
9&can_edit_disk($dinfo->{'device'}) ||
10	&error($text{'edit_ecannot'});
11if ($in{'new'}) {
12	&ui_print_header($dinfo->{'desc'}, $text{'create_title'}, "");
13	}
14else {
15	&ui_print_header($dinfo->{'desc'}, $text{'edit_title'}, "");
16	}
17
18print &ui_form_start("save_part.cgi");
19print &ui_table_start($text{'edit_details'}, "width=100%", 4);
20print &ui_hidden("disk", $in{'disk'});
21print &ui_hidden("part", $in{'part'});
22print &ui_hidden("new", $in{'new'});
23
24# Work out the start and end for the new partition
25@plist = @{$dinfo->{'parts'}};
26if ($in{'new'}) {
27	if ($in{'new'} == 1 || $in{'new'} == 3) {
28		# Adding a new primary or extended partition
29		$np = 1;
30		for($i=0; $i<@plist; $i++) {
31			if ($plist[$i]->{'number'} == $np) { $np++; }
32			push(@start, $plist[$i]->{'start'});
33			push(@end, $plist[$i]->{'end'});
34			}
35		$min = 1;
36		$max = $dinfo->{'cylinders'};
37		}
38	else {
39		# Adding a new logical partition (inside the extended partition)
40		$np = 5;
41		for($i=0; $i<@plist; $i++) {
42			if ($plist[$i]->{'number'} == $np) { $np++; }
43			if ($plist[$i]->{'extended'}) {
44				$min = $plist[$i]->{'start'};
45				$max = $plist[$i]->{'end'};
46				}
47			else {
48				push(@start, $plist[$i]->{'start'});
49				push(@end, $plist[$i]->{'end'});
50				}
51			}
52		}
53	print &ui_hidden("newpart", $np);
54	print &ui_hidden("min", $min);
55	print &ui_hidden("max", $max);
56
57	# find a gap in the partition map
58	for($start=$min; $start<=$max; $start++) {
59		$found = 1;
60		for($i=0; $i<@start; $i++) {
61			if ($start >= $start[$i] && $start <= $end[$i]) {
62				$found = 0;
63				last;
64				}
65			}
66		if ($found) { last; }
67		}
68	if ($found) {
69		# starting place found.. find the end
70		$found = 0;
71		for($end=$start; $end<=$max; $end++) {
72			for($i=0; $i<@start; $i++) {
73				if ($end >= $start[$i] && $end <= $end[$i]) {
74					$found = 1;
75					last;
76					}
77				}
78			if ($found) { last; }
79			}
80		$end--;
81		}
82	else {
83		# no place for new partition!
84		$start = $end = 0;
85		}
86	}
87else {
88	# Just editing an existing partition
89	$pinfo = $plist[$in{'part'}];
90	$np = $pinfo->{'number'};
91	}
92print &ui_hidden("np", $np);
93
94# Describe partition
95print &ui_table_row($text{'edit_location'},
96	     $dinfo->{'device'} =~ /^\/dev\/(s|h)d([a-z])$/ ?
97		&text('select_part', $1 eq 's' ? 'SCSI' : 'IDE', uc($2), $np) :
98	     $dinfo->{'device'} =~ /rd\/c(\d+)d(\d+)$/ ?
99		&text('select_mpart', "$1", "$2", $np) :
100	     $dinfo->{'device'} =~ /ida\/c(\d+)d(\d+)$/ ?
101		&text('select_cpart', "$1", "$2", $np) :
102	     $dinfo->{'device'} =~ /scsi\/host(\d+)\/bus(\d+)\/target(\d+)\/lun(\d+)\/disc/ ?
103		&text('select_spart', "$1", "$2", "$3", "$4", $np) :
104	     $dinfo->{'device'} =~ /ide\/host(\d+)\/bus(\d+)\/target(\d+)\/lun(\d+)\/disc/ ?
105		&text('select_snewide', "$1", "$2", "$3", "$4", $np) :
106		$dinfo->{'device'});
107
108# Device name
109$dev = $dinfo->{'prefix'} =~ /^\/dev\/mmcblk.*/ ?
110	$dinfo->{'prefix'}.'p'.$np :
111	$dinfo->{'prefix'}.$np;
112print &ui_table_row($text{'edit_device'}, $dev);
113
114# Partition type
115if ($pinfo->{'extended'} || $in{'new'} == 3) {
116	# Extended, cannot change
117	print &ui_table_row($text{'edit_type'}, $text{'extended'});
118	}
119elsif ($pinfo->{'edittype'} || $in{'new'}) {
120	# Can change
121	print &ui_table_row($text{'edit_type'},
122		&ui_select("type",
123			   $in{'new'} ? &default_tag() : $pinfo->{'type'},
124			   [ map { [ $_, &tag_name($_) ] }
125				 (sort { &tag_name($a) cmp &tag_name($b) }
126				       &list_tags()) ]));
127	}
128else {
129	# Tool doesn't allow change
130	print &ui_table_row($text{'edit_type'},
131			    &tag_name($pinfo->{'type'}));
132
133	}
134
135# Extent and cylinders
136if ($in{'new'}) {
137	$ext = &ui_textbox("start", $start, 4)." - ".&ui_textbox("end", $end, 4);
138	}
139else {
140	$ext = "$pinfo->{'start'} - $pinfo->{'end'}";
141	}
142$ext .= " ".$text{'edit_of'}." ".$dinfo->{'cylinders'};
143print &ui_table_row($text{'edit_extent'}, $ext);
144
145# Current status
146if ($pinfo->{'extended'}) {
147	foreach $p (@plist) {
148		$ecount++ if ($p->{'number'} > 4);
149		}
150	if ($ecount == 1) {
151		$stat = $text{'edit_cont1'};
152		}
153	else {
154		if ($ecount > 4) {
155			$stat = &text('edit_cont5', $ecount);
156			}
157		else {
158			$stat = &text('edit_cont234', $ecount);
159			}
160		}
161	}
162elsif (!$in{'new'}) {
163	@stat = &device_status($dev);
164	if (@stat) {
165		$msg = $stat[2] ? 'edit_mount' : 'edit_umount';
166		$msg .= 'vm' if ($stat[1] eq 'swap');
167		$msg .= 'raid' if ($stat[1] eq 'raid');
168		$msg .= 'lvm' if ($stat[1] eq 'lvm');
169		$msg .= 'iscsi' if ($stat[1] eq 'iscsi');
170		$stat = &text($msg, "<tt>$stat[0]</tt>",
171				    "<tt>$stat[1]</tt>");
172		}
173	else {
174		$stat = $text{'edit_notused'};
175		}
176	}
177if ($stat) {
178	print &ui_table_row($text{'edit_status'}, $stat);
179	}
180
181# Partition size
182if (!$in{'new'}) {
183	print &ui_table_row($text{'edit_size'},
184		$pinfo->{'size'} ? &nice_size($pinfo->{'size'})
185				 : &text('edit_blocks', $pinfo->{'blocks'}));
186	}
187
188# Show field for editing filesystem label
189if (($has_e2label || $has_xfs_db) && &supports_label($pinfo) && !$in{'new'}) {
190	local $label = $in{'new'} ? undef : &get_label($pinfo->{'device'});
191	if (@stat) {
192		print &ui_table_row($text{'edit_label'},
193			$label ? "<tt>$label</tt>" : $text{'edit_none'});
194		}
195	else {
196		print &ui_table_row($text{'edit_label'},
197			&ui_textbox("label", $label, 16));
198		}
199	}
200
201# Show field for partition name
202if (&supports_name($dinfo)) {
203	print &ui_table_row($text{'edit_name'},
204			&ui_textbox("name", $pinfo->{'name'}, 20));
205	}
206
207# Show current UUID
208if ($has_volid && !$in{'new'}) {
209	local $volid = &get_volid($pinfo->{'device'});
210	print &ui_table_row($text{'edit_volid'}, "<tt>$volid</tt>", 3);
211	}
212
213print &ui_table_end();
214if ($in{'new'}) {
215	print &ui_form_end([ [ undef, $text{'create'} ] ]);
216	}
217elsif (@stat && $stat[2]) {
218	print &ui_form_end();
219	print "<b>$text{'edit_inuse'}</b><p>\n";
220	}
221else {
222	print &ui_form_end([ $pinfo->{'extended'} ? ( ) :
223				( [ undef, $text{'save'} ] ),
224			     [ 'delete', $text{'delete'} ] ]);
225	}
226
227if (!$in{'new'} && !$pinfo->{'extended'}) {
228	print &ui_hr();
229	print &ui_buttons_start();
230
231	if (!@stat || $stat[2] == 0) {
232		# Show form for creating filesystem
233		local $rt = @stat ? $stat[1] : &conv_type($pinfo->{'type'});
234		print &ui_buttons_row("mkfs_form.cgi",
235			$text{'edit_mkfs2'}, $text{'edit_mkfsmsg2'},
236			&ui_hidden("dev", $dev),
237			&ui_select("type", $rt,
238                                [ map { [ $_, $fdisk::text{"fs_".$_}." ($_)" ] }
239                                      &fdisk::supported_filesystems() ]));
240		}
241
242	if (!$in{'new'} && @stat && $stat[2] == 0 && &can_fsck($stat[1])) {
243		# Show form to fsck filesystem
244		print &ui_buttons_row("fsck_form.cgi",
245			$text{'edit_fsck'},&text('edit_fsckmsg', "<tt>fsck</tt>"),
246			&ui_hidden("dev", $dev)." ".
247			&ui_hidden("type", $stat[1]));
248		}
249
250	if (!$in{'new'} && @stat && $stat[2] == 0 && &can_tune($stat[1])) {
251		# Show form to tune filesystem
252		print &ui_buttons_row("tunefs_form.cgi",
253			$text{'edit_tune'}, $text{'edit_tunemsg'},
254			&ui_hidden("dev", $dev)." ".
255			&ui_hidden("type", $stat[1]));
256		}
257
258	@types = &conv_type($pinfo->{'type'});
259	if (!$in{'new'} && !@stat && @types) {
260		# Show form to mount filesystem
261		if ($types[0] eq "swap") {
262			# Swap partition
263			print &ui_buttons_row("../mount/edit_mount.cgi",
264				$text{'edit_newmount2'},$text{'edit_mountmsg2'},
265				&ui_hidden("type", $types[0]).
266				&ui_hidden("newdev", $dev));
267			}
268		else {
269			# For some filesystem
270			$dirsel = &ui_textbox("newdir", undef, 20);
271			if (@types > 1) {
272				$dirsel .= $text{'edit_mountas'}." ".
273					&ui_select("type", undef, \@types);
274				}
275			else {
276				$dirsel .= &ui_hidden("type", $types[0]);
277				}
278			print &ui_buttons_row("../mount/edit_mount.cgi",
279				$text{'edit_newmount'}, $text{'edit_mountmsg'},
280				&ui_hidden("newdev", $dev),
281				$dirsel);
282			}
283		}
284
285	print &ui_buttons_end();
286	}
287
288&ui_print_footer("edit_disk.cgi?device=$dinfo->{'device'}",
289		 $text{'disk_return'});
290
291