牵着老婆满街逛

严以律己,宽以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

webmin 之 setup.sh 脚本分析

#find install directory 
cd 'dirname $0' 
if [ -x /bin/pwd ]; then 
wadir
='/bin/pwd' 
else 
wadir
='pwd'
fi 
#查找并获得安装目录 -> wadir 
ver='cat $wadir/version' 
#获得安装版本 
echo "*****************" 
. 
#显示用户提示信息 
id | grep "uid=1<" >/dev/null 
if [ $? !="0" ]; then 
echo 
"ERROR:"
echo 
""
exit 1
fi 
#检查是否为root 安装否则提示出错,程序推出 
#才知道还有id 这么个命令,,见笑了 

echo "Installing webmin in $ wadir " 
allmods
='cd $wadir; ls */module.info | sed -e 's/\/module.info//g' | xargs e 
cho
' 
echo 
"" 
#获取所有的可安装模块信息 

printf "Config file directory [/etc/webmin]:" 
. 
. 
. 
if [ "$config_dir" = ""]; then 
config_dir 
= /etc/webmin 
fi 
# 询问配置文件目录 
abspath='echo $config_dir | grep "^/"' 
if [ "$abspath" = "" ]; then 
echo 
"Config directory must be an absolute path" 
echo 
"" 
exit 2 
fi 
#检查配置文件目录是否合法 
if [ ! -$config_dir ]; then 
mkdir $config_dir 
if [ $? !=0 ]; then 
echo 
"ERROR: failed to create directory $config_dir" 
echo 
"" 
exit 2 
fi 
fi 
#创建配置目录,并检查是否成功 
if [ -"$config_dir/config" ]; then 
echo 
"Found existing Webmin configuration in $config_dir" 
echo 
"" 
upgrading
=1 
fi 
#检查配置文件是否存在,并置标志upgrading 
## 注,版本更新部分暂略 


ls 
$config_dir | grep -v rpmsave >/dev/null 2>&1 
if [ "$?" = "0" -"$config_dir" != "/etc/webmin" ]; then 
echo 
" 

exit 2 
fi 
#配置目录非空,退出配置 
#否则继续安装 
pirntf 
"Log file directory [/var/webmin]:" 
if [ 
"$var_dir" = "" ]; then 
read var_dir 
fi 
if [ 
"$var_dir" = "" ]; then 
var_dir=/var/webmin 
fi 
#创建系统运行时目录 log directory 
#缺省使用/var/webmin 
abspath='echo $var_dir | grep 
"^/"
if [ 
" &abspath " = "" ]; then 
echo 
"log file d.." 
echo 
"" 
echo 3 
fi 
#检查该运行时文件目录是否合法,否则退出 
#grep 
"^/" 行首 以"/"开始 
if [ ! -d $var_dir ]; then 
mkdir $var_dir 
if [ $? !=0 ]; then 
ehco 
"error:" 


fi 
fi 
#运行时文件目录不存在,则创建之,若创建失败,退出 

依靠perl 运行的webmin当然要确定一下系统中是否有perl 的解释器, 
以下: 
if [ -x /usr/bin/perl ]; then 
perldef=/usr/bin/perl 
elif [ -x /usr/local/bin/perl ]; then 
perldef=/usr/local/bin/perl 
else 
perldef =
"" 
fi 
#检查几个常用perl安装路径是否有perl 存在,否则定义perldef变量为
"" 
if [ 
"$perl" = "" ]; then 
if [ 
"$perldef" = "" ]; then 
read perl 
if [ 
"$perl" = "" ];then 
echo 
"error:" 

exit 4 
fi 
else 
printf 
"Full path to perl " 
#提示输入 
read perl 
if [ 
"$perl" = ""];then 
perl=$perldef 
fi 
fi 
fi 
#上一步如果没有找到perl 的安装路径,则要求用户输入perl 的路径 
#有问题这里! perl & perldef ?! 真麻烦! 有一个不久行了吗?! 
if [ ! -x $perl ]; then 
echo 
"error: message" 
exit 5 
fi 
# 没有perl环境, 退出 
$perl -e 'print 
"foobar\n"' 2>/dev/null | grep foobar >/dev/null 
if [ $? != 
"0" ];then 
echo
"error" 
exit 6 
fi 
#否则测试perl 是否可以运行(打印一行试试,并进行检测) 
$perl -e 'exit ($] < 5.002 ? 1:0)' 
if [ $? = 
"1" ]; then 
echo 
"error : message" 
exit 7 
fi 
#检测版本信息,要求5.002 以上版本( 本setup.sh出自 ver0.88) 
$perl -e 'use Socket; print 
"foobar\n"' 2>/dev/null | grep foobar >/dev/null 
if [ $? != 
"0" ];then 
echo 
"error mesage." 
exit 8 
fi 
#检测socket 模块是否正确安装..否则退出 
$perl -e '$c = crypt(
"xx","yy"); exit($c ? 0:1)' 
if [ $? != 
"0" ]; then 
echo 
"erro mesage.." 
eixt 9 
fi 
#检测加密模块是否正确安装,否则退出 
echo 
" Pelr seems to be installed ok" 
echo 
"" 
#通知用户perl检测正常 


操作系统选择,见 oschooser.pl 和 os_list.txt 理的内容 
oschooser.pl 实现系统选择, 还没细看,大概就是根据不同的linux发 
布(因为它们的配置文件名会有所不同,怎么说,叫个案追究吧 呵呵) 
给webmin使用不同配置文件(参数变化) 

printf 
"Web server port (default 10000): " 
if [ 
"$port" = "" ]; then 
read port 
if [ 
"$port" = "" ]; then 
port=10000 

fi 

fi 
if [ $port -lt 1 ]; then 
echo 
"ERROR: $port is not a valid port number" 

echo 
"" 
exit 11 
fi 

if [ $port -gt 65535 ]; then 

echo 
"ERROR: $port is not a valid port number. Port numbers cannot be" 

echo 
" greater than 65535" 
echo 
"" 

exit 12 

fi 

$perl -e 'use Socket; socket(FOO, PF_INET, SOCK_STREAM, getprotobyname(
"tcp" 
)); 
setsockopt(FOO, SOL_SOCKET, SO_REUSEADDR, pack(
"l", 1)); 
bind(FOO, sockaddr_in($ARGV[0], INADDR_ANY)) || exit(1); 
exit(0);' 
$port 

if [ $? != 
"0" ]; then 

echo 
"ERROR: TCP port $port is already in use by another program" 

echo 
"" 

exit 13 

fi 

printf 
"Login name (default admin): " 
if [ 
"$login" = "" ]; then 

read login 

if [ 
"$login" = "" ]; then 

login=
"admin" 
fi 

fi 
echo $login | grep : >/dev/null 
if [ 
"$?" = "0" ]; then 
echo 
"ERROR: Username contains a : character" 

echo 
"" 

exit 14 

fi 
printf 
"Login password: " 

if [ 
"$password" = "" -a "$crypt" = "" ]; then 
stty -echo 

read password 

stty echo 

printf 
"\n" 

printf 
"Password again: " 
stty -echo 

read password2 

stty echo 
printf 
"\n" 
if [ 
"$password" != "$password2" ]; then 
echo 
"ERROR: Passwords don't match" 
echo "" 

exit 14 
fi 
echo $password | grep : >/dev/null 
if [ "$?" = "0" ]; then 

echo "ERROR: Password contains a : character" 
echo "" 
exit 14 

fi 

fi 

defhost=`hostname` 
printf "Web server hostname (default $defhost): " 
if [ "$host" = "" ]; then 

read host 

if [ "$host" = "" ]; then 

host=$defhost 
fi 
fi 
if [ "$ssl" = "" ]; then 
ssl=0 

$perl -e 
'use Net::SSLeay' >/dev/null 2>/dev/null 
if [ $? = "0" ]; then 
printf "Use SSL (y/n): " 
read sslyn 
if [ "$sslyn" = "y" -o "$sslyn" = "Y" ]; then 
ssl=1 
fi 
else 
echo "The Perl SSLeay library is not installed. SSL not available." 

rm -f core 
fi 

fi 

# Ask whether to run at boot time 

if [ "$atboot" = "" ]; then 

initsupp=`grep "^os_support=" $wadir/init/module.info | sed -e 
's/os_suppor 
t
=//g' | grep $os_type` 

atboot=0 
if [ "$initsupp" != "" ]; then 

printf "Start webmin at boot time (y/n): " 
read atbootyn 

if [ "$atbootyn" = "y" -o "$atbootyn" = "Y" ]; then 

atboot=1 

fi 
else 
echo "webmin does not support being started at boot time on your system." 

fi 
fi 

makeboot=$atboot 

#很无聊啊, 在分析下去.. 失败! 选择错误! 
#太失败拉.不好玩 

if [ "$port" = "" ];then 
read port 
if [ "$port" = "" ];then 
port=8081 
fi 
fi 
if [ $port -lt 1]; then 
echo "error message" 
eixt 11 
fi 
#接受拥护定义服务端口号, 缺省使用8081 
if [ $port -gt 65535 ] ;then 
#error message 
exit 12 
fi 
#若用户定义的端口号大于65535 , 则报错退出 
#用户可使用的端口是从1000 以后还是从1024 以后? 谁告诉我? 
$perl -e 
'use Socketsocket(FOO, PF_INET, SOCK_STREAM, getprotobyname("tcp" 
)); 
set 
socket(FOO,SOL_SOCKET,SO_REUSEADDR, pack("l",1)); 
bind(FOO,sockaddr_in($ARGV[0],INADDR_ANY)) || exit(1);exit(0);' $p 
ort 
if [ $? !="0" ]; then 
echo "error message
exit 13 
fi 
#测试端口是否被占用, 方法见perl -e 那行的代码 
printf "login name (default admin):" 
if [ "$loging" = ""] ; then 
read login 
if [ "$login" = ""]; then 
loging="admin" 
fi 
fi 
#接受用户输入的管理员名称,缺省使用admin 
echo $login | grep : >/dev/null 
if [ "$?" = "0" ] ; then 
echo error mesage.. 
exit 14 
fi 
# 检测用户名称是否合法, 这里可以稍加改进,不用动不动就退出安装. 
pirntf " loging passwd" 
if [ "$password" = "" -a "$crypt" = "" ]; then 
stty -echo 
read password 
stty echo 
printf "\n" 
printf "password agani:" 
stty -echo 
read password2 
stty echo 
printf "\n" 
if [ "$password" != "$pasword2" ] ;then 
echo "Error message" 
exit 14 
fi 
fi 
#检查密码,并控制屏显 
defhost=
'hostname' 
printf "web server hostname (default $defhost):" 
if [ "$host" = ""]; then 
read host 
if [ "$host" = "" ]; then 
host=$defhost 
fi 
fi 
# 设置主机名称,没有则接受用户输入 
if [ "$ssl" = ""]; then 
ssl = 0 
$perl -e 
'use Net::SSLeay'>/dev/null 2>/dev/null 
if [ $? = "0" ] ; then 
printf "Use SSL (y/n):" 
read sslyn 
if [ "$sslyn" = "y" -o "$sslyn" = "Y" ] ; then 
ssl=1 
fi 
else 
echo "asdfjalksdjfjcjvknx." 
rm -f core 
fi 
fi 
#检查是否正确安装支持 ssl 模块, 否则给出提示信息 
if [ "$atboot" = "" ];then 
initsupp=
'grep "^os_support=" $wadir/init/module.info | sed -'s/os_suppo 
rt=//g
' |grep $os_type' 
atboot=0 
if [ "$initsupp" != ""];then 
printf "Start webmin at boot time (y/n):" 
read atbootyn 
if [ "$atbootyn" = "y" -o "$atbootyn" = "Y"]; then 
atboot=1 
fi 
else 
echo 
fi 
fi 
#检测模块安装文件/init/module.info中查找os_support 项所支持的 
#os_type中是否有当前的os_type,有则提示用户选择是否在系统启动时 
#启动webmin 

echo $perl > $config_dir/perl-path 
echo $var_dir > $config_dir/var-path 
echo "******************************************" 

echo "Creating web server config files.." 

cfile=$config_dir/miniserv.conf 

echo "port=$port" >> $cfile 

echo "root=$wadir" >> $cfile 

echo "host=$host" >> $cfile 

echo "mimetypes=$wadir/mime.types" >> $cfile 

echo "addtype_cgi=internal/cgi" >> $cfile 

echo "realm=LNMS Server" >> $cfile 

echo "logfile=$var_dir/miniserv.log" >> $cfile 

echo "pidfile=$var_dir/miniserv.pid" >> $cfile 

echo "logtime=168" >> $cfile 

echo "ppath=$ppath" >> $cfile 

echo "ssl=$ssl" >> $cfile 

echo "env_LNMS_CONFIG=$config_dir" >> $cfile 

echo "env_LNMS_VAR=$var_dir" >> $cfile 

echo "atboot=$atboot" >> $cfile 

echo "logout=$config_dir/logout-flag" >> $cfile 

echo "listen=10000" >> $cfile 

echo "denyfile=\\.pl\$" >> $cfile 

if [ "$allow" != "" ]; then 

echo "allow=$allow" >> $cfile 

fi 

if [ "$session" != "" ]; then 

echo "session=$session" >> $cfile 

else 

echo "session=1" >> $cfile 

fi 
#创建/etc/webmin(配置文件目录)下的miniserv.conf 
#前面搜集的一些变量在此被写入文件 

ufile=$config_dir/miniserv.users 

if [ "$crypt" != "" ]; then 

echo "$login:$crypt:0" > $ufile 
else 

$perl -e 
'print "$ARGV[0]:",crypt($ARGV[1], "XX"),":0\n"' "$login" "$passwo 
rd" > $ufile 

fi 

chmod 600 $ufile 

echo "userfile=$ufile" >> $cfile 

#创建用户加密文件,并更改其权限 
kfile=$config_dir/miniserv.pem 

cp $wadir/miniserv.pem $kfile 

chmod 600 $kfile 

#拷贝安装目录下的miniserv必须的模块文件到/etc/webmin 目录 
#并设置权限 
echo "keyfile=$config_dir/miniserv.pem" >> $cfile 

#追加miniserv 模块文件信息至 miniserv.conf 文件 
chmod 600 $cfile 

echo "..done" 

echo "" 

echo "Creating access control file.." 

afile=$config_dir/webmin.acl 

rm -f $afile 

#清空已存在的webmin acl 文件,不管有没有,删下看! 
echo "$login: $allmods" >> $afile 

chmod 600 $afile 

echo "..done" 

echo "" 
#将现有的模块注册,并重新创建webmin.acl 文件 

还有一点.. 

#有问题啊这里,谁给我讲讲 
if [ "$noperlpath" = "" ]; then 
echo "Inserting path to perl into scripts.." 
(find $wadir -name 
'*.cgi' -print;find $wadir -name '*.pl' -print) 
| $perl $wadir/perlpath.pl $perl - 
echo "..done" 
echo "" 
fi 
# 有问题 :perl perlpath.pl perl -  这里在做什么?! 
#创建/etc/webmin/start & stop 脚本。。。略 
if [ -r /etc/system.cnf ] ; then 
source /etc/system.cnf 
if [ "$CONF_LST_LANG" = "us" ];then 
CONF_LST_LANG=en 
elif [ "$CONF_LST_LANG" = "uk" ]; then 
CONF_LST_LANG=en 
fi 
grep "lang=$CONF_LST_LANG," $wadir/lang_list.txt >/dev/null 2>&1 
if [ "$?" = 0 ]; then 
echo "lang=$CONF_LST_LANG" >> $config_dir/config 
fi 
fi 
#检查系统培植文件/etc/system.cnf中的CONF_LST_LANG 
#设置语言相关得选项 

echo $ver > $config_dir/version 
echo "..done" 
if [ "$makeboot" = "1" ] ;then 
.. 
(cd $wadir/init; WEBMIN_CONFIG=$config_dir WEBMIN_VAR=$var_dir 
$wadir/init/atboot.pl) 
.. 
fi 
# 根据安装时的启动选项设置相关文件,参数 
# 注意最后运行的 atboot.pl 再作分析 
if [ "$nouninstall" = "" ]; then 
.. 
cat >$config_dir/uninstall.sh <<EOF 
#!/bin/sh 
printf " Are you sure you want to unistall Webmin? (Y/N):" 
read answer 
printf "\n" 
if [ "\$answer" = "y" ]; then 
$config_dir/stop 
if [ "$atboot" = "1" ]; then 
(cd $wadir/init ; WEBIN_CONFIG=$config_dir WEBMIN_VAR=$var_dir $wadir/init/ 
delboot.pl) 
fi 
echo "Deleting $wadir.." 
rm -rf $wadir 
echo "Deleting $config_dir ." 
rm -rf $config_dir 
echo "..Done" 
fi 
EOF 
chmod +x $config_dir/uninstall.sh 
echo "..done" 
fi 
# 创建卸载脚本, 很easy 给点提示,让后把相关得目录删掉即可 
# 注意$wadir/init/delboot.pl 并注意与adboot.pl 对照 

echo "Changing ownership and permissions .." 
chown -R root:bin $config_dir 
chmod -R og-rw $config_dir 
chmod 755 $config_dir/sendmail/config >/dev/null 2>&1 
chmod 755 $config_dir/sendmail/autoreply.pl >/dev/null 2>&1 
#改变配置模块文件属主及访问权限 
#为什么对sendmail单独处理? 我还不太清楚 
if [ "$nochown" = "" ]; then 

chown -R root:bin $wadir 

#chmod -R og-rwx $wadir 

if [ $var_dir != "/var" ]; then 
chown -R root:bin $var_dir 
chmod -R og-rwx $var_dir 

fi 
fi 
echo "..done" 
echo "" 
#改变安装目录(安装完后即执行目录)的属主 
#处理$var_dir 的属主及执行权限 比较周到 
if [ "$nostart" = "" ]; then 

echo "Attempting to start Webmin mini web server.." 

$config_dir/start 

if [ $? != "0" ]; then 
echo "ERROR: Failed to start web server!" 
echo "" 
exit 14 

fi 
# 试图启动webmin 的 mini server 
# 若失败则退出 

echo "..done" 

echo "" 

echo "***********************************" 

echo "Webmin has been installed and started successfully. Use your web" 
echo "browser to go to" 

echo "" 

#启动成功给出响应的提示信息 
if [ "$ssl" = "1" ]; then 
echo " https://$host:$port/" 

else 

echo " http://$host:$port/" 

fi 

echo "" 

echo "and login with the name and password you entered previously." 

echo "" 

if [ "$ssl" = "1" ]; then 
echo "Because Webmin uses SSL for encryption only, the certificate" 

echo "it uses is not signed by one of the recognized CAs such as" 

echo "Verisign. When you first connect to the Webmin server, your" 

echo "browser will ask you if you want to accept the certificate" 

echo "presented, as it does not recognize the CA. Say yes." 

echo "" 
fi 
#若ssl 有效,则给出启动客户端的方式:https://:prot 
fi 
# over 本次分析排除了,upgrade 操作的代码分析 不过我认为 
# 主要部分搞定的话,足以,省得看着那么多,不爽! :) 
# 欢迎转载 更希望与你交流(51run@21cn.com) 呵呵

posted on 2007-04-29 20:41 杨粼波 阅读(746) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理