数学建模社区-数学中国

标题: 如何自动登录linux[转载] [打印本页]

作者: huashi3483    时间: 2004-9-27 14:26
标题: 如何自动登录linux[转载]
<>如何自动登录linux[转载]</P>
, ^3 P$ c1 H0 a# r9 J5 v1 r<>本文以redhat 8.0操作系统平台为背景,阐述如何实现启动级别为3时的自动登录,及自动运行相应程序,并简要介绍了如何在redhat 8.0下自动登录X window(系统启动级别为5),并自动运行指定的应用程序。
3 d/ i+ P" [  ?4 v! u! O5 ?. S5 L[b:804aea7097]一、启动级别为3时自动登录的实现[/b:804aea7097]
8 O) ]. \1 B6 s% g1 Q9 c& V" K
- H1 F( R7 L7 q& B; F  _; _5 d2 n启动级别为3时自动登录的实现涉及两个软件包:mingetty-1.00-3.src.rpm软件包及util-linux-2.11r-10.src.rpm软件包。
" ]. T! X2 z: A; a  U* v, z7 k$ `  A) M+ m" f/ F. @
(1)mingetty-1.00-3.src.rpm软件包  0 e: S9 Z$ i" s/ j* G2 ^- a3 T
对于启动级别为3的自动登录的实现,仍然需要考察/etc/inittab脚本,  
# c( \7 b8 k- G- G3:123:respawn:/sbin/mingetty tty3 " ~' ?1 k  U( E- q  l, @  L8 V

, ]$ s* r" N/ O( \  |, D6 J3 f! r5 q
  
$ n& N" d$ W& S* N: J% g4 H1 V- o5 }
* Y# \" u- h# @; h, h8 ^0 m( ?( E
因此,如果想在启动级别3的情况下实现自动登录,必须要了解mingetty的功能,甚至要修改mingetty的代码。用命令rpm -qf /sbin/mingetty 可知redhat 8.0版本的mingetty包含在mingetty-1.00-3.src.rpm软件包中,下载该软件包,安装源代码,缺省情况下,代码会安装在/usr/src/redhat/下,我们关心的只是mingetty.c源文件。mingetty.c约有五百行代码,主要实现如下功能: 0 t8 E) C4 a) V. q$ S
" f. L: @; `4 m# [3 _, y- O3 T3 D
( ~7 E$ P6 C2 B* g
打开指定的tty(由参数指定);  ! C4 q0 w* }! I; \& Q8 m7 N
提示用户登录(login:);  / Z+ E6 x, [. v+ q: v
获得登录用户名;  + c9 e0 T  N. k+ t0 y1 G, T3 M! O* X
把用户登录名作为参数,调用/bin/login。  
1 Z5 D8 A+ k2 ?. K+ G
; C% Y/ N) k9 L/ u我们所关心的部分实质上只有以下三行:
$ S. Z1 E+ }( n/ y$ ^$ b3 K9 U* H

& v! U* g8 [( c... ...
) O- X' \1 K3 T8 J* m5 \; F: q438 while ((logname = get_logname ()) == 0); //mingetty.c文件438行 " F" k3 ]# r$ ~+ @9 l# b
439 execl (_PATH_LOGIN, _PATH_LOGIN, "--", logname, NULL);
" l( k( l9 B+ {" K7 Q/ l440 error ("%s: can't exec " _PATH_LOGIN ": %s", tty, sys_errlist[errno]); / j+ i; m, \5 ?
... ... 2 d8 ^6 c, c+ i+ Y: g* E6 d

8 K0 }( B$ M. E$ z. c0 q  4 P2 ]5 `5 \- v, y. `) S

( K; @) d0 h, o8 t3 t% `第一行的功能是输出login提示,并获得用户输入的登录用户名,登录用户名由logname返回。因此,可作如下修改
7 X9 ?) Z+ t/ V' F8 @2 O# c: G/ e1 O/ k# c$ k* r7 [
  |; A+ U. g% j8 \
... ...
2 K0 t0 K+ K7 X) |3 \438 // while ((logname = get_logname ()) == 0); //注释掉本行,不再提示login: . t' @( L/ M1 c5 f' L1 P) u
439 logname = "root"; //添加本行代码
9 _; G( D; _2 x' o, v4 m7 Y2 S+ o) i440 execl (_PATH_LOGIN, _PATH_LOGIN, "--", logname, NULL);
4 t) P7 U1 a) m( _. L441 error ("%s: can't exec " _PATH_LOGIN ": %s", tty, sys_errlist[errno]);
! a  R$ n$ b* T% J1 p5 ]... ...
* X: f  e: B; t  o) t
" m& X7 P6 N7 c& g( }, ?  
" W! t4 ?. B& y0 e/ S: K! w
& S; K6 c* R4 ~7 W1 v- I) V注意,这里假定用户以超级用户身份登录。
8 @( `$ P9 x5 n( H' D* Y8 d
0 d0 t* a& g' P3 |7 ?, i) I第二行以用户登录名为参数,调用/bin/login程序,进一步实现登录。因此,要想实现自动登录,还应该了解/bin/login的功能,必要时还应修改其源代码。 2 G/ |3 n1 z% N$ X1 z" t% Z2 u

5 [% G# l. ?! r3 y) r第三行为出错处理。
8 O3 p! E/ L  I9 `, [# x$ m% Y
! d$ V* X% F2 D  Q& x; Z4 B' v(2)util-linux-2.11r-10.src.rpm软件包  9 F, Z7 {8 w' W* }. w$ H
采用同样的方法,查看/bin/login所属软件包(redhad8.0版本的login包含在util-linux-2.11r-10.src.rpm软件包中),下载并安装util-linux-2.11r-10.src.rpm,login可执行文件有几个源文件编译而成,我们最关心的是login.c源文件(大约1500行的代码)。下面简要分析一下login要实现的功能,并对相应部分作必要的修改。
3 a. ~& n& C! {- S" N
: y0 @1 l0 ^9 y8 V& {Login程序主要可以分为以下几个主要部分: 7 l6 i  [6 m# c1 B& b5 V1 O

' ?- ?/ M5 f* I4 E) _1.Login首先检查登录者是否为超级用户,如果不是超级用户,并且存在/etc/nologin文件,则输出该文件内容,并中止登录过程;主要由checknologin()实现;  0 V9 m" g5 F/ d
2.如果登录用户是超级用户,那么login必须在/etc/securetty/中指定的tty列表中实现登录,否则将导致登录失败。同样可以不指定/etc/securetty文件,此时,超级用户可以在任何tty上登录。  7 j* R" ?# y% p
3.经过前两步测试后,login接下来将提示输入登录密码(由getpass()调用完成,有兴趣的读者可参考其手册页面),并进行验证,如果密码不对,则提示重新登录。  
& u+ `3 V$ E" k4.顺利经过密码验证后,login还将检查是否存在.hushlogin文件,如果该文件存在,则执行一次"quiet"登录(所谓的quiet登录指的是,登录时不再提示邮件mail,不再显示最后一次登录时间,不输出任何消息。启动级别为3时,正常情况下输出这些信息)  
: `5 f: z( w5 P$ S& B9 P$ K5.login接下来设置登录tty的用户ID和组ID,并设置相应的环境变量,包括HOME、PATH、SHELL、TERM、LOGNAME等。对于普通用户来说,PATH缺省被设置成/usr/local/bin: /bin/usr/bin:;对于超级用户来说,PATH被设置成/sbin: /bin: /usr/sbin: /usr/bin:  
# y. Y( N2 K6 ]: I' z. r$ \( b2 \6.login的最后一步是为用户启动shell。如果在/etc/passwd中没有为用户指定shell,那么将使用/bin/sh,如果在/etc/passwd中没有给出当前工作目录,则使用"/"。  5 {: A6 |6 a4 p6 o2 {
至此,一个完整的登录过程就结束了。
7 ~& U" O4 B, E3 W
; Q6 p1 Q0 Y( \3 [# x% R" }从以上对login源程序分析过程中可发现,如果要实现自动登录,应该在第三步做文章,设法绕过提示输入密码以及对密码进行验证这一过程。实际上很简单,login源程序对是否要求输入密码设置了一个开关控制passwd_req,缺省情况下,其值为1(passwd_req = 1),即要求输入密码进行身份验证。把该行代码改为(passwd_req = 0)后,问题就解决了。即对源文件作如下修改即可:
1 Q; N4 @. |2 _6 h5 Z
* j0 u- R9 J9 e1 h# }8 h/ U" p- n' X, G" N' F. m
... ...
3 C" N8 M  z- U" |) D$ l" ?402 fflag = hflag = pflag = 0; //login.c文件402行 ( u) R& S+ J% l( C0 l! j
403 //passwd_req = 1   //缺省时,要求进行密码验证,注释掉本行 0 z0 a& _% J5 C5 ]
404 passwd_req = 0 //添加本行 ' F# D' ~  q3 K  Y4 Z, ~
... ... 4 F1 t9 M, O  ]; c* z, t
8 k9 `! ^/ O* k! l: Q8 W
  2 N: }& q$ {7 v2 l: h* r

5 z2 I/ d: n: {7 c( g+ o& q  [- b5 K修改后,可以直接使用util-linux-2.11r-10.src.rpm提供的Makefile进行重新编译,也可以自己对其编译: . m0 f, p  Q% U* H1 f, B# D# O

$ U  m1 T' K/ }6 l
  l+ J1 w# I8 @5 h! e! [gcc -o login login.c setproctitle.c checktty.c xstrncpy.c -Wall -lcrypt注意包含后面的编译选项-lcrypt,否则会出问题。 + i9 a$ Q1 I$ F$ n% a; N

, G5 l4 f$ }6 j( u( A
( d1 O. G3 B) r9 _6 l有了新版的mingetty及login后,拷贝mingetty到/sbin/目录,拷贝login到/bin目录,并将/etc/inittab中的启动级别设置为3,再重新引导系统即可(读者可以自己写一个脚本实现上述过程)。 + _& {) ~4 f; l9 C) T9 \( @  d
/ q2 ^7 ~, p* l0 V8 ?& q( I4 ~8 S! b
如果读者对mingetty或login代码的其他部分感兴趣,可以反复修改login.c或mingetty.c的源代码,测试一下代码的功能,这里要注意的是,在拷贝新版mingetty和login之前,一定要把原来的mingetty和login备份,同时还要准备系统引导盘(有系统安装盘亦可,这样读者有机会键入linux rescue),在测试新版程序前更应如此,如果对代码修改稍有不当,系统将不能正常启动。   b4 N. Z- Q3 W! r6 D! Z# p5 b* e

; g2 h) i! X/ ~( [如果不想再作进一步的代码测试,只是按本文给出的方法进行代码修改,在系统启动上不会出现什么问题。
$ k$ J& E) e- N1 \6 ]5 a* r" H- c
4 l( b) c0 {: r9 ?/ y[b:804aea7097]二、自动登录后,自动运行特定的应用程序[/b:804aea7097]
0 y4 w2 K: l5 W, d: h) `/ E; x* M8 R
在实现了启动级别3时的自动登录后,自动运行应用程序非常简单,把应用程序添加在/etc/rc.d/rc.local脚本中既可。(读者可以尝试一下把startx加入脚本中,看一看效果如何。在某种意义上,又增加了一种自动登录X window的方法)
( }* ~  P  }8 j. P6 [) }  `$ {
9 G! A% e4 `. Z. Y% ]% w[b:804aea7097]三、对自动登录X window(系统启动级别为5),并自动运行指定的应用程序的补充[/b:804aea7097] 5 p- X% ?4 p0 g+ @9 c

5 f* L3 F* L; y( @: ^) s! E在"如何实现自动登录linux"中,主要以redhat 7.2平台为背景进行阐述的,其中的自动登录部分可以直接用于redhat 8.0中,不需要任何修改。 6 ]8 n4 A( g, `/ Q7 q! I& J

6 U7 q$ }  w( ~6 f但是,登录后自动运行应用程序的接口在redhat 8.0中有所不同,主要是登录gnome后,自动运行应用程序的接口有所改变:首先点击面板上的GNOME帮助(那个红色的小帽子),然后选择/其它/首选项/Sessions,在Session对话框的启动程序属性页中添加要启动的程序即可。 ' A% e9 j# I$ V: M- F
: z$ p. J  T" V) U) g4 N% N3 s
对于登录kde后,自动运行程序的接口没有改变。
0 w" n% c+ S- q" b9 U6 Z6 ^) i# g4 @3 c
4 N- `& P9 Z2 F% p2 J/ N[b:804aea7097]四、结论[/b:804aea7097] 8 R7 f' D  ?; f9 k( y2 U

4 A& |' u) Y! d( ?$ d. s本文同"如何实现自动登录linux"一文,基本上解决了如何实现自动登录Linux,并自动运行相应应用程序的问题。对于两个最常见的启动级别(3、5),都给出了各自的方法。 - [+ c- R2 j# q2 b  a5 N) i" J
9 c$ H4 B, ~0 U7 X% X7 S
在系统初始化到mingetty及login这一阶段,内核实际上已经完成了引导过程,已经到了系统初始化的最高阶段,与内核没什么关系了。此时,主要是/sbin/init根据/etc/inittab的内容而相机行事。读者可通过(man 8 init)或者(man 5 inittab)了解更多东西。
% ^9 M* ^- W( g6 K2 [, b) P
, `. o$ M& z3 [( }在对文中提到的软件包修改时,请遵守GNU General Public License(GPL)相关标准,另外,替换login通常被视为黑客行为,应当谨慎行事。
5 h: m& u! W0 n. \5 R9 Z0 c
1 S  A2 w5 M/ ^5 A
9 ?( b2 ]# `8 k6 c6 E* [
) P2 n- f- g. m- _+ s; B[b:804aea7097]参考文献[/b:804aea7097] 9 C# k; d- c/ D! l

5 \( [  [+ Q  _. j; C; D
8 ^5 @: K$ W3 d# _1.login手册页面  
5 L% p3 X! B7 \4 W2.mingetty-1.00-3.src.rpm,在redhat 8.0的发行版本的源代码中,包含该软件包;  ' l" z( D! R# b+ F  ~9 {
3.util-linux-2.11r-10.src.rpm,  0 [* Y, S: E0 Z1 D# N+ R
( L6 u: h1 B/ t7 X& B
可在http://rpmfind.net/linux/RPM/redhat/8.0/i386/util-linux-2.11r-10.i386.html处下载,注意下载源代码包(..src.rpm)
3 c; ~5 P$ F7 x1 d. ]5 Q; D3 W
$ |$ h! E2 C. Q4 d2 l[b:804aea7097]关于作者[/b:804aea7097]  4 D$ _+ j! N2 [; ]  {! u

" M% K5 ]4 r# F* Y7 Q! Y, ]2 `郑彦兴,男,现攻读国防科大计算机学院博士学位。您可以通过电子邮件 mlinux@163.com和他联系: X! ]6 ?) ?, F8 h# m3 U3 n# ?/ l
/ A/ J( u- O8 q- b( A
</P>
作者: huashi3483    时间: 2004-9-27 14:27
如何实现自动登录Linux (Runlevel 5)
  a. `! `0 G5 a
8 m7 s. }% @/ p3 [, j机自动登录linux,并自动运行X window应用程序,有其特殊的应用背景,如基于linux平台的监控系统,linux启动后不需要身份验证,而直接运行监控程序等等。本文以Redhat7.2为平台,结合linux启动过程,介绍了如何避免身份验证自动登录,并直接进入X window自动运行应用程序。
) H; a6 Q# [- j: \" o一、linux启动的最后阶段的工作
3 B" V% W7 `% R- s1 m/ X9 k" T6 A& B0 w2 ?
linux 在启动过程的最后阶段(具体启动步骤略),init 会根据 /etc/inittab文件的最后一行x:5:respawn:/etc/X11/prefdm -nodaemon运行/etc/X11/prefdm脚本,(Red hat 7.2缺省时是这样的)。prefdm脚本的主要任务是完成X window的启动,可以有几种启动X window的方法,都包含在prefdm脚本中,几种主要方法有:
: ?6 q9 ~8 \4 ?6 _
. `9 u5 \9 K/ h# z运行xdm启动X window;  
( C- I* S2 }  ~! B9 H运行gdm,进入gnome桌面环境;  
' q4 U4 A8 M5 q( M2 i7 r3 s2 l运行kdm进入kde桌面环境;  " }: b4 f. @& T* E0 ]( ?" H3 n
自动登录进入linux;  . _" @6 }) [! i* C% d4 [1 c
prefdm脚本框架大致如下:
& T! z# b% ~; x0 t2 r5 x9 ~3 O- g$ i! \0 \- M' z5 A, p
#!/bin/sh * R6 \; s, ]9 }/ y  ^8 T
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin . }& t# n! D: C" p+ v7 J! l
. /etc/profile.d/lang.sh 3 V  C2 a% T5 r" ]% s
# 第一步:查看是否为自动登录 0 E0 ~- O8 j% W, [# ?' h2 V' G2 j
if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then   k. l) F5 r3 t* p' M! J) L
if /usr/sbin/autologin; then 0 I2 x- X9 ~' ]0 q- ?; e2 G' m; f
exit 0
* k7 V/ l, M/ a3 r& y) mfi
9 L5 Q3 i) S$ Q+ F) U$ rfi
3 z" |- m4 ^$ U# E: Q  p
' X1 w4 K, X) u# 第二步:如果不是自动登录方式,就会在/etc/sysconfig/desktop中搜寻用户偏爱的登录方式
% ~/ Z9 \. P& G. s1 }...... 5 n! H% O) O6 L" i* z
# 可以是kdm、gdm以及xdm,并运行相应的kdm、gdm以及xdm。
/ S% j  C6 N& ?  o( O/ \8 z" }8 P/ c...... : k# ^3 k6 D8 w8 @1 D7 ?

& I! |9 W& _; _  8 L9 b+ y4 x/ I6 P

  |, w$ H' D8 l
* g% U! O" ]/ h& x( e8 A$ p, ]二、自动登录的实现(autologin的实现)
: i& o: I; ~% L' U& e* ~6 I( N2 e0 E2 n9 I8 J
在/etc/X11/prefdm脚本中,是否实现自动登录有一个条件测试开关,事实上,可以在这里注释掉测试开关,直接执行启动X window的操作。 7 e. i) }$ u# c# Y

' u/ P9 _% L4 t' L: U+ a自动登录实质上就是绕过身份验证,直接启动X window。X window的启动可以由xinit来完成。 ; X# {. s: y7 l: n0 y/ \
. |% U; u$ C$ m1 r2 {# Q! Z
Xinit用来启动X window系统服务器以及系统上的第一个客户程序,可以通过为xinit传递命令行参数的形式指定要启动的服务器及客户程序。如果不传递参数给xinit,它将在用户的根目录下寻找并运行 .xinitrc脚本来启动客户程序;在用户的根目录下寻找并运行 .xserverrc脚本来启动服务器。如果xinit在用户的根目录下找不到.xinitrc、.xserverrc,xinit将使用缺省的X :0。  
5 d/ e1 x, |- r9 A: o实际上,用startx来启动X更为方便。对于运行单一会话的X window 系统,startx提供了更为良好的用户接口。同样,startx首先在用户的根目录下寻找 .xinitrc及.xserverrc脚本,如果找不到这两个脚本,startx将使用/etc/X11/xinit/xinitrc以及/etc/X11/xinit/xserverrc脚本。  
/ _* c/ M5 O" L# S7 x! O+ x8 _startx脚本的最基本框架是: 6 i+ N6 W# i8 f
; ]( X$ j, Y; y
a、 寻找.xinitrc,如果没有则使用xinitrc;
, x% M, b# t7 `( d: \& @- E/ R: E1 Pb、 寻找.xserverrc,如果没有则使用xserverrc;
# i% c; v0 N& x/ p- V. [! i, B6 q! qc、 根据找到的脚本确定xinit的参数;
2 V* v) o2 Z# j6 @  f2 n. n- _: W9 C1 W) |
由此可看出,startx在不需要传递任何参数的情况下,可以完成启动X的任务,因此,可以如下修改/etc/X11/prefdm脚本来实现自动登录: ( G8 |$ r6 I5 d- w2 q

. ^. f) N) N9 s( B$ n6 f1 o5 g: j) E# @5 Q: L* E: c. A2 F" u
#!/bin/sh 4 s* j+ {/ ~6 {
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
6 d% P7 ~$ }9 f, K7 R. /etc/profile.d/lang.sh
- [, y0 j/ {; X4 Y# 第一步:查看是否为自动登录 ) x: o. s% G3 }) Q" p1 U4 |4 X
#if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then & U5 ]$ K/ Z" x. k
#注释掉上边的条件测试,直接运行startx ; I: m9 p7 f: k
if /usr/X11R6/bin/startx; then
) V2 D5 ~# }; n  J  s. wexit 0 & ?% `" ~, n+ N, v$ v
fi 2 K$ @3 a& F$ F: n/ g9 E
#fi % G5 B8 u: N. P0 L/ l" F$ q5 `

# a* A6 V) ]' d6 W) J  
. T. e. Y+ Q6 E5 D$ ^2 }9 x( h/ l" V
( B# E& c6 a; K6 Y8 @6 C+ J; D
当然,应确保/etc/inittab中的启动级别为5。 + ?  A* U, s' t& R# s3 M

5 T8 i9 c2 R0 Z重新启动系统,会发现系统不验证用户身份,直接进入X window,此时的用户身份为root。但是,如果原来root有自己的桌面、默认shell时,上述方法启动X不一定保证还能拥有原来的设置。为了在启动X后,在避免验证身份的同时,又不改变用户原来的设置,那么在运行startx之前,还有工作要做。
# z2 t$ f9 S/ i5 d$ I3 C: [. B; g5 V. }
三、自动登录后,保持用户原来的配置(桌面、shell以及其它的一些环境变量)。 2 R, E& q7 m8 f
( M, h+ m2 E* C# A% o0 b# q
观察原来/etc/X11/prefdm脚本的自动登录部分:
$ ?# r) Y( C2 y! T9 @0 a, `( a5 d
% a1 r- g+ W+ W/ H# L# {9 l
* ~6 H" u& ~5 s  I/ x...... / b& V* x! }, `6 X: `, V& _
# 第一步:查看是否为自动登录
7 t  }* \. v* Iif [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then - i) w: v, [( N- Y: [. A+ a
if /usr/sbin/autologin; then
- U# M( }3 k! V2 p3 n* Wexit 0
. }/ T6 v, ~& x6 B! Yfi : l! J) S  y6 b3 u& V& v4 F
fi * Z7 K" c# r6 [) e
...... 4 O# E" z4 ~5 b- f" H

: l9 K1 K# V. k4 [0 R# E( u( W  
1 y$ x2 B; N. J6 }* f6 S6 i* \: B/ V6 d
3 y0 @1 l& X0 d) ~
不难看出,脚本中保留了自动登录的接口:一个可执行文件/usr/sbin/autologin以及一个配置文件/etc/sysconfig/autologin。
# F5 e$ l, ~+ z8 c. ?& C& l7 ?* |# I; n0 k4 e* f, [4 }
1、/etc/sysconfig/autologin配置文件的实现:
& H9 H0 c* Y; Y9 q/ T8 J1 ?& p: [1 L
% v& o' X, B* [  U4 j9 m. x' X& g' t
#config for autologin
1 M! s# f6 U' o" }8 vUSER=root
$ b$ }4 Q! v3 L3 eEXEC=/usr/X11R6/bin/startx
/ H3 q: Z6 V. j6 ]  U/ o说明,USER指定自动登录时的用户名;EXEC指定启动X要运行的程序。 6 |2 y2 X4 N! Y+ c& o& C  M

( h/ o; \/ a# @3 J* e* G  ( ~2 b/ m- V$ y' Q1 f/ I
+ z% d, d4 p. ]& I6 D

5 q; r9 M6 C4 H3 z2 J. m% s2、/usr/sbin/autologin可执行文件的实现: # T3 Y5 j2 \0 }" G7 s1 h
9 c1 h& @; S- ^2 B

" V3 ~5 {: t. n/********************* ' O) _+ h/ v  ~6 V  Y
****  autologin.c  **** 1 L9 o( S0 p/ G+ |( I: ]1 \- x
*********************/ # Y% p- t2 M4 h# e% s$ D
#include &lt;stdio.h&gt;
; a( t; R) |7 \3 q6 b#include &lt;unistd.h&gt;
# N* |9 ^! h* C$ u6 V#include &lt;string.h&gt;
' q# z2 i- O  Q; G* ^#include &lt;errno.h&gt; 7 \- H) _, ], ]  w8 v* z6 h% e) e
#include &lt;sys/types.h&gt; ! _$ p" Q! I# @. F% I3 _9 c# p
#include &lt;sys/stat.h&gt; 6 z& M( k) ~: Q9 C
#include &lt;pwd.h&gt; : a: X- j( B7 R$ W. x7 k
2 ]9 W( `0 ~+ p
int main(int argc, char **argv)   ~8 ]0 T0 `' \( I8 k6 T. S( Y
{
7 k8 F% {: M4 s$ x  J! |7 Vstruct stat st;
' p0 {# @* H7 IFILE *f; 6 e/ A9 ?8 E9 i. f( r) h- R
char *cfg; ( [* d0 |3 e1 i, D
struct passwd *pw; ! O: H6 b# o, E4 O
uid_t uid; , f2 N. B' D5 F8 d1 r) f' K1 [
gid_t gid; / ?( N2 x* a3 T
char *dir, *shell;
( _7 P! ?6 `$ F/ K. [6 [char *user=NULL;
3 H( W" E  K" N4 Vchar *cmd=NULL;   r8 y' b6 I& J0 @' J& }7 s5 u
- F7 b  F3 E! K! `, ?4 W# t0 k
user="root"; ! f6 M' b4 |3 V7 N6 N+ J6 n9 \: u
/*为了能说明问题又保持程序简洁,这里默认登录用户为root,实际上, 8 j6 y. [/ `( S* i7 a- Q
登陆用户名应该从/etc/sysconfig/autologin中得到,   g& V  H$ V3 q) x1 p" _" G7 |
程序实现时要注意过滤掉/etc/sysconfig/autologin中的无效用户名*/
# k+ r1 c+ d6 g. y  ^3 G2 z  ^cmd="/usr/X11R6/bin/startx"; ( @4 O2 s  D/ }5 x
/*同样,这里直接指定启动X window的程序,实际上,该程序应该从/etc/sysconfig/autologin中得到*/ & x' D* z, j, j. Y- J& h# }- n2 ?
1 M2 O! `3 P, g) _0 N5 y/ U/ d* R
pw = getpwnam(user);
# G+ P# U) S( h3 j//getpwnam返回包含用户信息的passwd结构(该结构在pwd.h中定义)。 1 x* G' u" |1 `: J, G+ D  e# F
if(pw) {
6 y4 |5 T3 w0 F: O) quid=pw-&gt;pw_uid; 9 L7 S6 x' T/ w6 @% ^! J
gid=pw-&gt;pw_gid; dir=strdup(pw-&gt;pw_dir); / i, M/ V4 u4 C6 _& k
shell=strdup(pw-&gt;pw_shell);
5 X2 Z. X, N+ k& o}
5 A1 O) n  e1 i9 s, ?# j//获得用户相关信息   r1 _, L$ H. a/ m1 ?- l
else {
" k% x. J8 v$ ^0 L! v' \  ~printf("ERROR: No such user %s!\n", user);
0 w( i" B6 {5 A2 Creturn 1; 6 k' I( }% v& E* E6 f7 j- [' f
} ' G  ^; M( L2 h, }8 j7 y

' ~3 o# k. W- [9 \# Schown("/dev/console", uid, gid);
( w6 G1 ~) T% a. ?) t3 T. g' @" k( rchown("/dev/tty", uid, gid); 3 q  {# u8 \- f: r4 ]
//为控制台和终端设置用户ID及组ID ' }$ n" C# O4 T+ V3 t: z1 F
/ ]4 y. q0 M3 P. u2 Q
//下面是设置用户相关ID $ ^1 X* X9 E8 t  y5 l1 Q- V
setregid(gid, gid); ) t( @/ n/ Z7 A4 x
setegid(gid);
. c5 l' j+ h2 m( w. J2 gsetgid(gid);
/ o9 x: H8 O! Z( Y$ hsetreuid(uid, uid); # D- v. @; M. S3 P2 B
seteuid(uid); 1 o1 N+ n$ G/ a) h5 D
setuid(uid); 7 F. W3 @8 R7 G: B* W7 b( K% v

! a4 r+ V4 F- t/ r5 Ysetenv("HOME", dir, 1); 9 p% g! I5 N0 f* w; g4 L
setenv("SHELL", shell, 1);
; ^( w% D0 _# c8 U, a' @setenv("USER", user, 1);
' b& U) s9 p+ Osetenv("LOGNAME", user, 1);
+ p% m0 \5 v& h7 R) W# Q0 s//设置用户相关环境变量
  u" a1 ]/ {) t# ~* A/ [( v, E3 n$ }- K! Y
chdir(dir); ' A* U$ q8 V2 t9 v/ C& W3 Y* I
//切换到用户根目录 & {# u5 l" j# l) H( _) Z1 o3 j
user=NULL; 7 U7 F0 {; J: A' Y  r8 u
4 T: R6 v" O. _2 }9 u
execvp(cmd, argv);
# w7 b# x4 p4 j# ~+ w- {, }/*在配置完用户的相关信息后,执行启动X window操作。注意这里默认执行/usr/X11R6/bin/startx */
8 I3 C8 N, C$ \- ~printf("ERROR: Couldn't exec %s: %s\n", cmd, strerror(errno));
9 N& X$ Q2 b2 u9 h3 Rreturn 2;
& m* \# P4 j. p1 r0 U# P# W: m}
) i  F. `7 Q6 Y  h, b4 e, V3 t1 [) m- W- U  Q& h
  ' k! w2 e4 R: Z# t5 Y2 k: ^; R
3 S. t1 I0 R1 x3 o8 w

, g  _" J2 s) A4 G9 v+ z" I# W* P& ~运行gcc -o autologin autologin.c,拷贝autologin可执行文件到/usr/sbin/autologin,拷贝autologin配置文件到/etc/sysconfig/autologin。 重新启动系统,会直接进入X window并保留用户原来所有的风格。 * {: ?1 K6 ?: \" m( r
/ b# M* n; J( u& P- ]
如果不需要自动登录的配置文件/etc/sysconfig/autologin,所有的操作都在/usr/sbin/autologin以默认的方式实现(比如,默认登录身份为root,默认执行操作为/usr/X11R6/bin/startx等),那么,/etc/X11/prefdm脚本的自动登录部分可简化如下:
! x1 L3 |$ J) K" k  n, }- W6 m& t6 M& Q9 i- u9 t

  w- U- L* A: A$ S......
  d) Z" C( d) z$ n$ F- Z4 f$ D# 第一步:查看是否为自动登录
3 D+ Z) p& D- L+ `; dif /usr/sbin/autologin; then
6 E' v, f, [- H( e) V5 }$ Dexit 0
/ x8 J. b% z* r/ K. a7 ~fi ! }5 r0 ~- O% ^6 L: {( \
//第二步 ...... 6 E6 u  y9 ]1 K. ~: t" t
......
9 h* G; l( z1 r+ V" `+ X
9 A2 o; C! h) W& r# e" k  
2 R: G. {' t4 L7 G7 ]7 T. ]7 K) d4 D, o

% a1 \' f7 t1 g) G$ B7 }即在脚本中去掉条件测试开关,直接执行/usr/sbin/autologin,这时,只需要拷贝autologin可执行文件到/usr/sbin/autologin,不再需要拷贝autologin配置文件到/etc/sysconfig/autologin。 + m1 `! t3 g, ^+ r4 @0 x# F

, g) |& e" y- M( S  a7 |: K+ O. S四、选择进入kde或者gnome,并自动启动X window应用程序 & p. [1 m4 f& v' J( e5 a
' S7 W/ U0 D7 S# z) D" `# e7 f- `
如果重新启动后系统进入了kde,而用户需要进入gnome,只需运行switchdesk gnome在重新启动系统即可,以后每次启动时会自动进入gnome;反之亦然。  
6 M- x4 D: S1 P3 }& @: H2 b9 D一般系统自动登录的目的是启动X window 后自动运行某个X window程序。如果系统默认的启动级别为3,那么如果要在系统启动后自动运行某些应用程序,只需要在某些脚本中加入相应命令即可,不再详述。在X window启动后自动运行应用程序要复杂一些,幸好,kde和gnome都为此留下了自动启动接口。如果在kde桌面环境下自动启动应用程序,只需要把应用程序名字加入/root/.kde/Autostart/目录下即可(这里注意不同用户的根目录可能不同,如用户zyx的根目录可能为/home/zyx)。如果在gnome桌面环境下自动启动应用程序,只需把应用程序的名字加入/主菜单/程序/设置/会话/会话特性及启动程序的startup programs属性页中即可。  ! \* [' m5 t! N" [1 N1 g

1 M! @. w! ^# U/ H; r+ @7 c' _& y/ p
http://www-900.ibm.com/developerWorks/cn/linux/l-tip-prompt/tip20/index.shtml




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5