From fbd44b6c70a6ac93cc794f7f0ac7aec358a19a97 Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Tue, 19 Mar 2013 17:53:37 -0700 Subject: [PATCH] Basic FreeBSD disk list --- blue-theme/bsdfdisk/images/icon.gif | Bin 0 -> 4365 bytes bsdfdisk/bsdfdisk-lib.pl | 115 ++++++++++++++++++++++++++++ bsdfdisk/index.cgi | 38 +++++++++ bsdfdisk/lang/en | 7 ++ gray-theme/bsdfdisk | 1 + software/ports-lib.pl | 1 + 6 files changed, 162 insertions(+) create mode 100644 blue-theme/bsdfdisk/images/icon.gif create mode 100644 bsdfdisk/index.cgi create mode 120000 gray-theme/bsdfdisk diff --git a/blue-theme/bsdfdisk/images/icon.gif b/blue-theme/bsdfdisk/images/icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..41d7ddaa4c1a18b94055be65caffcdb811b6ccee GIT binary patch literal 4365 zcmW+)c|4Te7k_3&9!3%~gh`Q78Kx{*W<=IRtFhFKv9%~m3rS{1p-`4KT8z~DCX_*` zBr~?`@s^788vByUjHMZ7d4BW${7bH3+Z_1)v9wnBFW003$p?k@Wj zlJMV9Mk{7N_)?leAS0Z-odBS`)f$yPtytsE?4q369~FKkE;u#}a0-p0hv7X=21kVL z3kwcCAJZ0Q4*(i$4;QBc@!#lD2qHE5q5)V_6QK!42Gq`D0Ax?L2p|I$JZxrWX5T@M zswKe`X-VkYO{dZ5;WSz}dLz0rACE=KEeL0*v{24%8f_>ngw`_>!GWbOSyomZC2*?R zEI1V_2pqy`3#n4Nd}%&qcycxlBrzPt&^-TODi@q&n%sxF8w6T6^&#jI?GNg*KBk?k z&_ubTiQ<3{Z{yMI?y*=txT!vFyhCB-&6MGDVk$vmZr8Eb#81`C73PRWA1X{RaaBf_ zqP~fgil@Ftr9#vs0-;vcDu9{?CLuQ07J?c@`VbChRat3aUn98A3ZC7MP92ZKVn4it z?a)qB0^nCrrC;-GaoA21BEd9;06423oi@KRnp00jYvT`v(C9--BcpMSK(m}fkjj^o zrs_$ZoymNrfew%^gZEz!wK5%K6%5nqG_4WXx3xT8YoTeIV6=P;nlyYT|IO{OneK7x zh-2VRRU$s$O(zh7E_MSq-y5g`u*=ghtF>r!%SjMSzDstKBX`_K4U0)&5Xg|*S;i2= zs>)E+uuibAOpuc^E~|+REc}_1hsXrII+?d+p|o(BAe+UaYE9ABSRpQA)W1+kI39RT zJC$7tg4{Qd%7?o5__O1Bjo$P*g-;(QFmrCP>XWPyh*#@-DyYo0s9SOwHF=oNJ+RT^ zZ^}Vq*Mn<=!&A9XKDO>+1T9{Ak2UOY=gcO;-Rqm*N$vz+Rq>sPNVS8G)LIAUB3xC? z%-8Q7-Q8M938sr>zf>FNl|NDJVYBT6|o?j73;v7>&eOWad%ec3pQ z;OeA~tn}y5vTf`L5fIcS_&JC`r}~hvNsf?Y=5tgkrYQlyGc^o+OVEFN8Pl#XKN7N` zQMNis!j<{UgB)-$sV1B^GCpqRnwrIC%HiKST9NgIwQU==u4~2rT8*@PKZjq1m|>(M zNVC8V-u^;!91C}A(Qy67hauIBp@!l9t~8KOVuWef%C0@6ceC#f@Nrv9o=$6w!I{+GFWsFn?KP!zgSJkgRyLfD5CqIvZE8wPGwtRjZet^e;SE)ZKOWBBcb$jFM zH9)xjZ7SGNcQ{zwCeXyHmN6_GfX!2b|6XVl{1`rg7D~7{t4MjpJGq7P)uP;G?#PHX z?X2)#eM1B5Vf8te0TMzZ+^>4su9Ty8h>-GnQcoVzv!bxjx>d~m6qvvzFV-+PDI!1Ft8t@(Dur`DNaoqs*b;tb$u?Vg z95)}EB;VQVfczKZsm3#U;QyYO$I1yT{Gsh@Zn}?T(FvVXH(mOpW>b|++(H;*)Jhrz zf~FAkhd2gyFmg#~IkCyPsJfzSm7fmDnbz7Zlgr*>wz;zmmRbZdi62@|&pP$Tk0an) z7+iUn6~(XGpWGaovc3;jm$+e2C{RYC)!)9jjzpBFn7_EGH2#l1yPRN8e=S4b+`_yL zbqkaz9^d(xvUP)qCA%cq6+02>)?ts)NT*ZJ#zeE!FX`zkjD_>_k?7+#%d>ovdEOE! zDKSJt=T11MYTl(n2hSWb7}B9{+~1q4fTDKL6GAkcXrN^F!kBm24ufxjmtr}ZT8rsQ zLht85nVOhnU#$qKR!;ZE)6zyTq>7VUm%6ATDIM_*99y`Y%6i$fmPEp&^Q z6R*I%R$I`Bu9wqtSQza1&oYhe_->9O4&@ofA(uQoPvLJ@zmi;_21q8dBK+#Nq|JgE zq=InMky_F1ap9Y8aMm!9o^3zRekkeTs@#)X?!J5AlPZY6oxgKuVzs?JFJ0bEJzCFe zz#ADg@!Hx}Ld%PRRSJ#W;Md-YMYD!z2Z#NyUji_shzGGr{z;IuQ-JO(IFHConSrot zpJwOhuvSq5h0z2HL98X~n7Wk-Z6X|gh@2^~(zm%yZVNheZPEPIVX$#>{MH(>jMp1K z-l3Mdj(WZJbi7Juw$WEPvFzJo)aV!=yp@vT&1)}sd5Fxk+vDyI{EYW~q#62!%gFx7 zN=wrl!*%JHANeI;Uc6`SD<7NXbIHrR-)LpLOLdZHLAUX|i32TwP6JYr2pxhND_}pF znh2qrc*$dnBv;CSUY|W3UY(m?pNH!kqamyF<-kB(rV(#y)mco0xc2$4rb#yYv(uKG zui!i>C^%YU3~GsvorkK7NjS@WpFA1GB|ltZPghxcc%~DjGKtPqv}Dh z@Q<2c;?77AF6F&0k=Hj8d}&)cvug}0L=Sg&519nS2H+Z>uA9Madv#KlEzPZ8)pvTy z{MpGf#zvcW{pNG2rMVZp1+AKt>5To8`xr1}_= zxXa?{(FZ>4L23dd?^=2lb)=jzzuYyZ(`_hCT%6N`1|*#&?7F03Nr&La3e%GnGUBGO$hYD zQ{!fjAc)sA2~UUv?p_%d%D^Wshl97#WudRgq)T2uJMPRLVzai?`mpPmf>%ClN0M}5 zy76U}A^!nG^t)^PRn+2H=3nj3h0U{!=on(_+#C!scDnTWbJyZ+gh19BAJcwXWj?RX z+uc3eY1gh*KNaOP`2x^8Ay@#zvTq-vi2-m6ZEtgD%ZB0)&CRGk+uhf#*H89D9V%QK zIkZA4Xhtq;L7mB-5Y3XdaTAxcL1CXCnwEP(C6q4_j<)<&PTuM5z0vRrEBuj(p6@rb zZ7$Y_`7;7lZD73q@j<7=|E^;`c%VN;I2V1gMJ>`0kzsa@1_}tyfu~y^qAZaV=LUxb zOy6Fmr-*|t_|0qA!nGyyZr;+#ZuSW8@lllp?4`UsfW)63h0uV zk87bnxBip@sWRn zi>e=gp%k&Zkm|5rnzc9YRGC@se(7jrWYCYR|74VC_o0NQ{x;xl){Qbr7M8iF z(fG(sw1@d!!FNmzUZ0-S^_^4tj^G(ZcYQ9kuHUOvqUtV0K40&WX=AB37VoeZ`7dHAtt-z>1t3-L{qGOWM{ISm5Zi55Y%@xuN$r(2e3 ze-zkGRXXx6;eE7NuqXNxJYeR*yTql0{sM z63Ln~7ear1L1aMa{|;=>^DTLOQSzJrEYNQ?Jg`a>{9EDtvS+ zVnm6($@*v&1DkQ~CGn+uKn=Wy#067euGFr>3NQ zee=c^Pzy(I*x*aj)*i=aF>4t3Zk{DR_7mJ?UFzet1*m+rO$Qwrak?HB^YmD+v z*iExj*jajU^nF;EXqJCJ*|A;`BI1anOuR*f@|2BLbQjpU#4Gx9EbqpRfy+EH$peML zMNcDRfwJZmC;lYs2H~@KYmx=6r08H^#bIACd5yB?b-awTW7WPNvat9+KaB}K26Z)2 z{M#e1qNu-{teg=VWTbr0yW{8yz0c>*FEs`F=T|9; zDocOG@zG1Vk%VrtZVEJn{Za=2Ij|wgJq>lBy*6Pnb@=07Ub9(i`mH73UY@>4 zUNn#C%7Gy@oG?sgaMXgbL`2r+%b#6vn%LI2RFv4p# zFdcJJN2M6K>sLn5ykjVp$;J;chK{ff1*Q91PQ4H^-MAf3E=m z^YHLThlJ?S9AB%vP~NAUC|kx&si@O7$9M?@$~7GwW(g%FCHZX~X02B;GOFf;LKgb( zq4RL9xk4=57Tf0r>{vz+tf)y0srVn6L^OLpK`i)v-8!nkkhglI&t8E!mkWTswAH*7 zziE?N=ExI)(6ex~ep;VG1@uLTP)$P}o$^iQ=3F$1n{CN)+kp6q7s80v*2N51SxB8i zpYcY8)eGQn3*%Vgi7Z3vY%*HOHMh+t`0Cjq@M^fT4j& Yv(6#uC#5%v{|vxm*B+PWJ88-P0}1jSGynhq literal 0 HcmV?d00001 diff --git a/bsdfdisk/bsdfdisk-lib.pl b/bsdfdisk/bsdfdisk-lib.pl index a3bf84fa7..deb01670a 100644 --- a/bsdfdisk/bsdfdisk-lib.pl +++ b/bsdfdisk/bsdfdisk-lib.pl @@ -11,4 +11,119 @@ use WebminCore; &init_config(); &foreign_require("mount"); +sub check_fdisk +{ +if (!&has_command("fdisk")) { + return &text('index_ecmd', "fdisk"); + } +return undef; +} + +# list_disks_partitions() +# Returns a list of all disks, partitions and slices +sub list_disks_partitions +{ +my @rv; + +# Iterate over disk devices +foreach my $dev (glob("/dev/ada[0-9]"), + glob("/dev/ad[0-9]"), + glob("/dev/da[0-9]")) { + next if (!-r $dev || -l $dev); + my $disk = { 'device' => $dev, + 'prefix' => $dev, + 'parts' => [ ] }; + if ($dev =~ /^\/dev\/(.*)/) { + $disk->{'short'} = $1; + } + push(@rv, $disk); + + # Get size and partitions + my $out = &backquote_command("fdisk $dev"); + my @lines = split(/\r?\n/, $out); + my $part; + for(my $i=0; $i<@lines; $i++) { + if ($lines[$i] =~ /cylinders=(\d+)\s+heads=(\d+)\s+sectors\/tracks=(\d+)\s+\((\d+)/) { + # Disk information + # XXX model and size? + $disk->{'cylinders'} = $1; + $disk->{'heads'} = $2; + $disk->{'sectors'} = $3; + $disk->{'blksper'} = $4; + $disk->{'size'} = $disk->{'cylinders'} * + $disk->{'blksper'} * 512; + $disk->{'index'} = scalar(@rv); + } + elsif ($lines[$i] =~ /data\s+for\s+partition\s+(\d+)/ && + $lines[$i+1] !~ //) { + # Start of a partition + $part = { 'number' => $2, + 'device' => $dev."p".$2, + 'index' => scalar(@{$disk->{'parts'}}) }; + push(@{$disk->{'parts'}}, $part); + } + elsif ($lines[$i] =~ /sysid\s+(\d+)/ && $part) { + # Partition type + $part->{'type'} = $2; + } + elsif ($lines[$i] =~ /start\s+(\d+),\s+size\s+(\d+)\s+\((.*)\)/ && $part) { + # Partition start and size + $part->{'blocks'} = $2; + $part->{'size'} = &string_to_size("$3"); + } + elsif ($lines[$i] =~ /beg:\s+cyl\s+(\d+)/ && $part) { + # Partition start + $part->{'start'} = $1; + } + elsif ($lines[$i] =~ /end:\s+cyl\s+(\d+)/ && $part) { + # Partition end + $part->{'end'} = $1; + } + } + + # Get disk model from dmesg + open(DMESG, "/var/run/dmesg.boot"); + while() { + if (/^(\S+):\s+<(.*)>/ && $1 eq $disk->{'short'}) { + $disk->{'model'} = $2; + } + elsif (/^(\S+):\s+(\d+)(\S+)\s+\((\d+)\s+(\d+)\s+byte\s+sectors/ && + $1 eq $disk->{'short'}) { + $disk->{'sectorsize'} = $5; + $disk->{'size'} = &string_to_size("$2 $3"); + } + } + close(DMESG); + + # Get slices within partitions + # XXX + } + +return @rv; +} + +# string_to_size(str) +# Convert a string like 100 Meg to a number in bytes +sub string_to_size +{ +my ($str) = @_; +my ($n, $pfx) = split(/\s+/, $str); +if ($pfx =~ /^b/i) { + return $n; + } +if ($pfx =~ /^k/i) { + return $n * 1024; + } +if ($pfx =~ /^m/i) { + return $n * 1024 * 1024; + } +if ($pfx =~ /^g/i) { + return $n * 1024 * 1024 * 1024; + } +if ($pfx =~ /^t/i) { + return $n * 1024 * 1024 * 1024 * 1024; + } +return undef; +} + 1; diff --git a/bsdfdisk/index.cgi b/bsdfdisk/index.cgi new file mode 100644 index 000000000..9336135df --- /dev/null +++ b/bsdfdisk/index.cgi @@ -0,0 +1,38 @@ +#!/usr/local/bin/perl +# Show a list of disks + +use strict; +use warnings; +require './bsdfdisk-lib.pl'; +our (%in, %text, %config, $module_name); + +&ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1, 0); + +my $err = &check_fdisk(); +if ($err) { + &ui_print_endpage(&text('index_problem', $err)); + } + +my @disks = &list_disks_partitions(); +@disks = sort { $a->{'device'} cmp $b->{'device'} } @disks; +if (@disks) { + print &ui_columns_start([ $text{'index_dname'}, + $text{'index_dsize'}, + $text{'index_dmodel'}, + $text{'index_dparts'} ]); + foreach my $d (@disks) { + print &ui_columns_row([ + "".&html_escape($d->{'device'})."", + &nice_size($d->{'size'}), + $d->{'model'}, + scalar(@{$d->{'parts'}}), + ]); + } + print &ui_columns_end(); + } +else { + print "$text{'index_none'}

\n"; + } + +&ui_print_footer("/", $text{'index'}); diff --git a/bsdfdisk/lang/en b/bsdfdisk/lang/en index 62c24279f..01d963290 100644 --- a/bsdfdisk/lang/en +++ b/bsdfdisk/lang/en @@ -1 +1,8 @@ index_title=Partitions on Local Disks +index_ecmd=The required command $1 is missing +index_problem=This module cannot be used : $1 +index_none=No disks were found on this system! +index_dname=Disk name +index_dsize=Total size +index_dmodel=Make and model +index_dparts=Partitions diff --git a/gray-theme/bsdfdisk b/gray-theme/bsdfdisk new file mode 120000 index 000000000..7764e2b6b --- /dev/null +++ b/gray-theme/bsdfdisk @@ -0,0 +1 @@ +../blue-theme/bsdfdisk \ No newline at end of file diff --git a/software/ports-lib.pl b/software/ports-lib.pl index 761ab2a74..95e8eeb4a 100644 --- a/software/ports-lib.pl +++ b/software/ports-lib.pl @@ -111,6 +111,7 @@ return $name eq "apache" ? "apache22 ap22-mod_.*" : $name eq "openssh" ? "openssh-portable" : $name eq "postgresql" ? "postgresql-server" : $name eq "openldap" ? "openldap-server openldap-client" : + $name eq "samba" ? "samba36 samba36-nmblookup samba36-smbclient" : $name; }