📄 fdisk-lib.pl
字号:
# fdisk-lib.pl# Functions for disk management under linuxdo '../web-lib.pl';&init_config();&foreign_require("mount", "mount-lib.pl");&foreign_require("proc", "proc-lib.pl");%access = &get_module_acl();$| = 1;# list_disks()# Returns a list of structures, one per disksub list_disks{local (@rv, $f, $i);local $idx = 0;if ((-d "/proc/ide" || -d "/proc/scsi") && -r "/proc/partitions") { # Get the list of IDE disks from the kernel opendir(IDE, "/proc/ide"); foreach $f (sort { $a cmp $b } readdir(IDE)) { next if ($f !~ /hd(\S)$/); local $disk = { "device" => "/dev/$f", "type" => "ide" }; open(MEDIA, "/proc/ide/$f/media"); local $media = <MEDIA>; close(MEDIA); next if ($media !~ /^disk/); open(GEOM, "/proc/ide/$f/geometry"); while(<GEOM>) { if (/logical\s+(\d+)\/(\d+)\/(\d+)/) { $disk->{'cylinders'} = $1; $disk->{'heads'} = $2; $disk->{'sectors'} = $3; } } close(GEOM); open(MODEL, "/proc/ide/$f/model"); chop($disk->{'model'} = <MODEL>); close(MODEL); $disk->{'index'} = $idx++; push(@rv, $disk); } closedir(IDE); # Get the list of SCSI disks from the kernel and fdisk local @scsi; open(PARTS, "/proc/partitions"); while(<PARTS>) { s/\r|\n//g; if (/\d+\s+\d+\s+\d+\s+sd(\S)$/) { push(@scsi, "/dev/sd$1"); } } close(PARTS); local @pscsi; open(SCSI, "/proc/scsi/scsi"); while(<SCSI>) { s/\s/ /g; if (/^Host:/) { push(@pscsi, $_); } elsif (/^\s+\S/) { $pscsi[$#pscsi] .= $_; } } close(SCSI); @pscsi = grep { /Type:\s+Direct-Access/ } @pscsi; for($i=0; $i<@scsi; $i++) { &open_fdisk("-l", $scsi[$i]); while(<$fh>) { if (/Disk\s+([^ :]+):\s+(\d+)\s+\S+\s+(\d+)\s+\S+\s+(\d+)/) { local @st = stat($1); local $disk = { 'device' => $1, 'heads' => $2, 'sectors' => $3, 'cylinders' => $4, 'index' => $idx++, 'type' => 'scsi' }; if ($pscsi[$i] =~ /Vendor:\s+(\S+).*Model:\s+(\S+)/i) { $disk->{'model'} = "$1 $2"; } if ($pscsi[$i] =~ /Host:\s+scsi(\d+).*Id:\s+(\d+)/i) { $disk->{'controller'} = int($1); $disk->{'scsiid'} = int($2); } push(@rv, $disk); } } &close_fdisk(); } }else { # Get the list from fdisk -l local @cdstat = stat("/dev/cdrom"); &open_fdisk("-l"); while(<$fh>) { if (/Disk\s+([^ :]+):\s+(\d+)\s+\S+\s+(\d+)\s+\S+\s+(\d+)/) { local @st = stat($1); if ($st[1] != $cdstat[1]) { local $disk = { 'device' => $1, 'heads' => $2, 'sectors' => $3, 'cylinders' => $4, 'index' => $idx++ }; $disk->{'type'} = $disk->{'device'} =~ /hd.$/ ? 'ide' : 'scsi'; push(@rv, $disk); } } } }return @rv;}# list_partitions(disk)# Returns a list of structures, one per partitionsub list_partitions{local(@rv, $wf);local $idx = 0;&open_fdisk($_[0]);&wprint("p\nq\n");&wait_for($fh, 'System\r');while(1) { $wf = &wait_for($fh, '\n\/dev\/...(\d+)[ \t*]+\d+\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S{1,2})\s+(.*)\r', '\n\/dev\/...(\d+)[ \t*]+(\d+)\s+(\d+)\s+(\S+)\s+(\S{1,2})\s+(.*)\r'); last if ($wf < 0); $matches[4] =~ s/\+$//g; push(@rv, { 'number' => $matches[1], 'type' => $matches[5], 'start' => $matches[2], 'end' => $matches[3], 'blocks' => $matches[4], 'extended' => $matches[5] eq '5' || $matches[5] eq 'f' ? 1 : 0, 'index' => $idx++ }); }&close_fdisk();return @rv;}# change_type(disk, partition, type)# Changes the type of an existing partitionsub change_type{&open_fdisk("$_[0]");&wprint("t\n");&wait_for($fh, 'Partition.*:');&wprint("$_[1]\n");&wait_for($fh, 'Hex.*:');&wprint("$_[2]\n");&wait_for($fh, 'Command.*:');&wprint("w\n"); sleep(1);&close_fdisk();}# delete_partition(disk, partition)# Delete an existing partitionsub delete_partition{&open_fdisk("$_[0]");&wprint("d\n");&wait_for($fh, 'Partition.*:');&wprint("$_[1]\n");&wait_for($fh, 'Command.*:');&wprint("w\n");&wait_for($fh, 'Syncing'); sleep(3);&close_fdisk();}# create_partition(disk, partition, start, end, type)# Create a new partition with the given extent and typesub create_partition{&open_fdisk("$_[0]");&wprint("n\n");local $wf = &wait_for($fh, 'primary.*\r\n', 'First.*:');if ($_[1] > 4) { &wprint("l\n"); }else { &wprint("p\n"); &wait_for($fh, 'Partition.*:'); &wprint("$_[1]\n"); }&wait_for($fh, 'First.*:') if ($wf != 1);&wprint("$_[2]\n");&wait_for($fh, 'Last.*:');&wprint("$_[3]\n");&wait_for($fh, 'Command.*:');&wprint("t\n");&wait_for($fh, 'Partition.*:');&wprint("$_[1]\n");&wait_for($fh, 'Hex.*:');&wprint("$_[4]\n");&wait_for($fh, 'Command.*:');&wprint("w\n");&wait_for($fh, 'Syncing'); sleep(3);&close_fdisk();}# create_extended(disk, partition, start, end)sub create_extended{&open_fdisk("$_[0]");&wprint("n\n");&wait_for($fh, 'primary.*\r\n');&wprint("e\n");&wait_for($fh, 'Partition.*:');&wprint("$_[1]\n");&wait_for($fh, 'First.*:');&wprint("$_[2]\n");&wait_for($fh, 'Last.*:');&wprint("$_[3]\n");&wait_for($fh, 'Command.*:');&wprint("w\n");&wait_for($fh, 'Syncing'); sleep(3);&close_fdisk();}# list_tags()# Returns a list of known partition tag numberssub list_tags{return sort { hex($a) <=> hex($b) } (keys %tags);}# tag_name(tag)# Returns a human-readable version of a tagsub tag_name{return $tags{$_[0]} ? $tags{$_[0]} : $hidden_tags{$_[0]};}# conv_type(tag)# Given a partition tag, returns the filesystem type (assuming it is supported)sub conv_type{if ($_[0] eq "4" || $_[0] eq "6" || $_[0] eq "1" || $_[0] eq "e") { $rv = "msdos"; }elsif ($_[0] eq "b" || $_[0] eq "c") { return "vfat"; }elsif ($_[0] eq "83") { $rv = "ext2"; }elsif ($_[0] eq "81") { $rv = "minix"; }else { return undef; }if (&has_command("mkfs.$rv")) { return $rv; }return undef;}# fstype_name(type)# Returns a readable name for a filesystem typesub fstype_name{return $fstypes{$_[0]};}sub mkfs_options{if ($_[0] eq "ext2") { &opt_input("ext2_b", "bytes", 1); &opt_input("ext2_f", "bytes", 0); &opt_input("ext2_i", "", 1); &opt_input("ext2_m", "%", 0); &opt_input("ext2_g", "", 1); print "<td align=right><b>$text{'ext2_c'}</b></td>\n"; print "<td><input type=radio name=ext2_c value=1> $text{'yes'}\n"; print "<input type=radio name=ext2_c value=0 checked> $text{'no'}", "</td> </tr>\n"; }elsif ($_[0] eq "msdos" || $_[0] eq "vfat") { &opt_input("msdos_f", "", 1); &opt_input("msdos_F", "bits", 0); &opt_input("msdos_i", "", 1); &opt_input("msdos_n", "", 0); &opt_input("msdos_r", "", 1); &opt_input("msdos_s", "sectors", 0); print "<tr> <td align=right><b>$text{'msdos_c'}</b></td>\n"; print "<td><input type=radio name=msdos_c value=1> $text{'yes'}\n"; print "<input type=radio name=msdos_c value=0 checked> $text{'no'}", "</td> </tr>\n"; }elsif ($_[0] eq "minix") { &opt_input("minix_n", "", 1); &opt_input("minix_i", "", 0); &opt_input("minix_b", "", 1); print "<td align=right><b>$text{'minix_c'}</b></td>\n"; print "<td><input type=radio name=msdos_c value=1> $text{'yes'}\n"; print "<input type=radio name=msdos_c value=0 checked> $text{'no'}", "</td> </tr>\n"; }}# mkfs_parse(type, device)# Returns a command to build a new filesystem of the given type on the# given device. Options are taken from %in.sub mkfs_parse{local($cmd);if ($_[0] eq "ext2") { $cmd = "mkfs -t ext2"; $cmd .= &opt_check("ext2_b", '\d+', "-b"); $cmd .= &opt_check("ext2_f", '\d+', "-f"); $cmd .= &opt_check("ext2_i", '\d{4,}', "-i"); $cmd .= &opt_check("ext2_m", '\d+', "-m"); $cmd .= &opt_check("ext2_g", '\d+', "-g"); $cmd .= $in{'ext2_c'} ? " -c" : ""; $cmd .= " $_[1]"; }elsif ($_[0] eq "msdos" || $_[0] eq "vfat") { $cmd = "mkfs -t $_[0]"; $cmd .= &opt_check("msdos_f", '[1-2]', "-f"); $cmd .= &opt_check("msdos_F", '\d+', "-F"); $cmd .= &opt_check("msdos_i", '[0-9a-f]{8}', "-i"); $cmd .= &opt_check("msdos_n", '\S{1,11}', "-n"); $cmd .= &opt_check("msdos_r", '\d+', "-r"); $cmd .= &opt_check("msdos_s", '\d+', "-s"); $cmd .= $in{'msdos_c'} ? " -c" : ""; $cmd .= " $_[1]"; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -