1#!/usr/local/bin/perl 2# oschooser.pl 3# Read the list of operating systems and ask the user to choose 4# an OS and version 5# auto param: 0 = always ask user 6# 1 = automatic, give up if fails 7# 2 = automatic, ask user if fails 8# 3 = automatic, ask user if fails and if a TTY 9 10$| = 1; 11 12($oslist, $out, $auto) = @ARGV; 13open(OS, "<".$oslist) || die "failed to open $oslist : $!"; 14while(<OS>) { 15 chop; 16 if (/^([^\t]+)\t+([^\t]+)\t+([^\t]+)\t+([^\t]+)\t*(.*)$/) { 17 push(@list, [ $1, $2, $3, $4, $5 ]); 18 push(@names, $1) if (!$donename{$1}++); 19 $names_to_real{$1} ||= $3; 20 } 21 } 22close(OS); 23 24if ($auto) { 25 # Try to guess the OS name and version 26 if (-r "/etc/.issue") { 27 $etc_issue = `cat /etc/.issue`; 28 } 29 elsif (-r "/etc/issue") { 30 $etc_issue = `cat /etc/issue`; 31 } 32 if (-r "/etc/os-release") { 33 $os_release = `cat /etc/os-release`; 34 } 35 if (&has_command('uname')) { 36 $uname = `uname -a 2>/dev/null`; 37 } 38 foreach $o (@list) { 39 if ("$^O" =~ /MSWin32/ && "$o->[2]" !~ /windows/) { 40 next; 41 } 42 if ($o->[4] && eval "$o->[4]") { 43 # Got a match! Resolve the versions 44 $ver = $o; 45 if ($ver->[1] =~ /\$/) { 46 $ver->[1] = eval "($o->[4]); $ver->[1]"; 47 } 48 if ($ver->[3] =~ /\$/) { 49 $ver->[3] = eval "($o->[4]); $ver->[3]"; 50 } 51 last; 52 } 53 if ($@) { 54 print STDERR "Error parsing $o->[4]\n"; 55 } 56 } 57 58 if (!$ver) { 59 if ($auto == 1) { 60 # Failed .. give up 61 print "Failed to detect operating system\n"; 62 exit 1; 63 } 64 elsif ($auto == 3) { 65 # Do we have a tty? 66 local $rv = system("tty >/dev/null 2>&1"); 67 if ($?) { 68 print "Failed to detect operating system\n"; 69 exit 1; 70 } 71 else { 72 $auto = 0; 73 } 74 } 75 else { 76 # Ask the user 77 $auto = 0; 78 } 79 } 80 } 81 82if (!$auto) { 83 if (0 && &has_command("dialog")) { 84 # call the dialog command to ask for the OS (disabled for now) 85 $cmd = "dialog --menu \"Please select your operating system type from the list below\" 20 60 12"; 86 for($i=0; $i<@names; $i++) { 87 $cmd .= " ".($i+1)." '$names[$i]'"; 88 } 89 $tmp_base = $ENV{'tempdir'} || "/tmp/.webmin"; 90 $temp = "$tmp_base/dialog.out"; 91 system("$cmd 2>$temp"); 92 $osnum = `cat $temp`; 93 $osnum = int($osnum); 94 if (!$osnum) { 95 #unlink($temp); 96 print "ERROR: No operating system selected\n\n"; 97 exit 9; 98 } 99 100 # call the dialog command to ask for the version 101 $name = $names[$osnum-1]; 102 @vers = grep { $_->[0] eq $name } @list; 103 $cmd = "dialog --menu \"Please select your operating system's version from the list below\" 20 60 12"; 104 for($i=0; $i<@vers; $i++) { 105 $cmd .= " ".($i+1)." '$name $vers[$i]->[1]'"; 106 } 107 system("$cmd 2>$temp"); 108 $vnum = `cat $temp`; 109 $vnum = int($vnum); 110 unlink($temp); 111 if (!$vnum) { 112 print "ERROR: No operating system version selected\n\n"; 113 exit 9; 114 } 115 $ver = $vers[$vnum-1]; 116 } 117 else { 118 # ask for the operating system name ourselves 119 $dashes = "-" x 75; 120 print <<EOF; 121For Webmin to work properly, it needs to know which operating system 122type and version you are running. Please select your system type by 123entering the number next to it from the list below 124$dashes 125EOF 126 for($i=0; $i<@names; $i++) { 127 printf " %2d) %-20.20s ", $i+1, $names[$i]; 128 print "\n" if ($i%3 == 2); 129 } 130 print "\n" if ($i%3); 131 print $dashes,"\n"; 132 print "Operating system: "; 133 chop($osnum = <STDIN>); 134 if ($osnum !~ /^\d+$/) { 135 print "ERROR: You must enter the number next to your operating\n"; 136 print "system, not its name or version number.\n\n"; 137 exit 9; 138 } 139 if ($osnum < 1 || $osnum > @names) { 140 print "ERROR: $osnum is not a valid operating system number.\n\n"; 141 exit 10; 142 } 143 print "\n"; 144 145 # Ask for the operating system version 146 $name = $names[$osnum-1]; 147 print <<EOF; 148Please enter the version of $name you are running 149EOF 150 print "Version: "; 151 chop($vnum = <STDIN>); 152 if ($vnum !~ /^\S+$/) { 153 print "ERROR: An operating system number cannot contain\n\n"; 154 print "spaces. It must be like 2.1 or ES4.0.\n"; 155 exit 10; 156 } 157 print "\n"; 158 $ver = [ $name, $vnum, 159 $names_to_real{$name}, $vnum ]; 160 } 161 } 162 163# Write the name, version and real name and version to a file 164open(OUT, ">$out"); 165print OUT "os_type='",$ver->[2],"'\n"; 166print OUT "os_version='",$ver->[3],"'\n"; 167print OUT "real_os_type='",$ver->[0],"'\n"; 168print OUT "real_os_version='",$ver->[1],"'\n"; 169close(OUT); 170 171# has_command(command) 172# Returns the full path if some command is in the path, undef if not 173sub has_command 174{ 175local($d); 176if (!$_[0]) { return undef; } 177local $rv = undef; 178if ($_[0] =~ /^\//) { 179 $rv = (-x $_[0]) ? $_[0] : undef; 180 } 181else { 182 foreach $d (split(/:/ , $ENV{PATH})) { 183 if (-x "$d/$_[0]") { $rv = "$d/$_[0]"; last; } 184 } 185 } 186return $rv; 187} 188 189 190