summaryrefslogtreecommitdiff
authorsandman <sandman>2002-10-29 19:33:49 (UTC)
committer sandman <sandman>2002-10-29 19:33:49 (UTC)
commit7c340d2a08601f4d27f6d2a407fc0de437b8efad (patch) (unidiff)
treec6a01ef4e7623ea1da758030e691531f0476885e
parent2957aae1073f4c41dd6783c41d1199be71cd9f4a (diff)
downloadopie-7c340d2a08601f4d27f6d2a407fc0de437b8efad.zip
opie-7c340d2a08601f4d27f6d2a407fc0de437b8efad.tar.gz
opie-7c340d2a08601f4d27f6d2a407fc0de437b8efad.tar.bz2
when quitting opie-login, don't kill the process id returned by getppid(),
but use the previously saved "real" parent pid.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/opie-login/loginapplication.cpp5
-rw-r--r--core/opie-login/loginapplication.h5
-rw-r--r--core/opie-login/main.cpp11
3 files changed, 14 insertions, 7 deletions
diff --git a/core/opie-login/loginapplication.cpp b/core/opie-login/loginapplication.cpp
index 103d63b..8d86a71 100644
--- a/core/opie-login/loginapplication.cpp
+++ b/core/opie-login/loginapplication.cpp
@@ -1,220 +1,221 @@
1/* 1/*
2               =. This file is part of the OPIE Project 2               =. This file is part of the OPIE Project
3             .=l. Copyright (c) 2002 Robert Griebl <sandman@handhelds.org> 3             .=l. Copyright (c) 2002 Robert Griebl <sandman@handhelds.org>
4           .>+-= 4           .>+-=
5 _;:,     .>    :=|. This file is free software; you can 5 _;:,     .>    :=|. This file is free software; you can
6.> <`_,   >  .   <= redistribute it and/or modify it under 6.> <`_,   >  .   <= redistribute it and/or modify it under
7:`=1 )Y*s>-.--   : the terms of the GNU General Public 7:`=1 )Y*s>-.--   : the terms of the GNU General Public
8.="- .-=="i,     .._ License as published by the Free Software 8.="- .-=="i,     .._ License as published by the Free Software
9 - .   .-<_>     .<> Foundation; either version 2 of the License, 9 - .   .-<_>     .<> Foundation; either version 2 of the License,
10     ._= =}       : or (at your option) any later version. 10     ._= =}       : or (at your option) any later version.
11    .%`+i>       _;_. 11    .%`+i>       _;_.
12    .i_,=:_.      -<s. This file is distributed in the hope that 12    .i_,=:_.      -<s. This file is distributed in the hope that
13     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY; 13     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
14    : ..    .:,     . . . without even the implied warranty of 14    : ..    .:,     . . . without even the implied warranty of
15    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A 15    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
16  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU General 16  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU General
17..}^=.=       =       ; Public License for more details. 17..}^=.=       =       ; Public License for more details.
18++=   -.     .`     .: 18++=   -.     .`     .:
19 :     =  ...= . :.=- You should have received a copy of the GNU 19 :     =  ...= . :.=- You should have received a copy of the GNU
20 -.   .:....=;==+<; General Public License along with this file; 20 -.   .:....=;==+<; General Public License along with this file;
21  -_. . .   )=.  = see the file COPYING. If not, write to the 21  -_. . .   )=.  = see the file COPYING. If not, write to the
22    --        :-=` Free Software Foundation, Inc., 22    --        :-=` Free Software Foundation, Inc.,
23 59 Temple Place - Suite 330, 23 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, USA. 24 Boston, MA 02111-1307, USA.
25 25
26*/ 26*/
27 27
28#include <pwd.h> 28#include <pwd.h>
29#include <grp.h> 29#include <grp.h>
30#include <unistd.h> 30#include <unistd.h>
31#include <stdlib.h> 31#include <stdlib.h>
32#include <signal.h> 32#include <signal.h>
33 33
34#ifdef USEPAM 34#ifdef USEPAM
35extern "C" { 35extern "C" {
36#include <security/pam_appl.h> 36#include <security/pam_appl.h>
37} 37}
38#else 38#else
39#include <crypt.h> 39#include <crypt.h>
40#include <shadow.h> 40#include <shadow.h>
41#endif 41#endif
42 42
43#include "loginapplication.h" 43#include "loginapplication.h"
44 44
45LoginApplication *lApp; 45LoginApplication *lApp;
46 46
47LoginApplication::LoginApplication ( int &argc, char **argv ) 47LoginApplication::LoginApplication ( int &argc, char **argv, pid_t parentpid )
48 : QPEApplication ( argc, argv, GuiServer ) 48 : QPEApplication ( argc, argv, GuiServer )
49{ 49{
50 lApp = this; 50 lApp = this;
51 m_parentpid = parentpid;
51} 52}
52 53
53const char *LoginApplication::s_username = 0; 54const char *LoginApplication::s_username = 0;
54 55
55#ifdef USEPAM 56#ifdef USEPAM
56 57
57const char *LoginApplication::s_pam_password = 0; 58const char *LoginApplication::s_pam_password = 0;
58 59
59int LoginApplication::pam_helper ( int num_msg, const struct pam_message **msg, struct pam_response **resp, void * ) 60int LoginApplication::pam_helper ( int num_msg, const struct pam_message **msg, struct pam_response **resp, void * )
60{ 61{
61 int replies = 0; 62 int replies = 0;
62 struct pam_response *reply = 0; 63 struct pam_response *reply = 0;
63 int size = sizeof( struct pam_response ); 64 int size = sizeof( struct pam_response );
64 65
65 for ( int i = 0; i < num_msg; i++ ) { 66 for ( int i = 0; i < num_msg; i++ ) {
66 switch ( msg [i]-> msg_style ) { 67 switch ( msg [i]-> msg_style ) {
67 case PAM_PROMPT_ECHO_ON: // user name given to PAM already 68 case PAM_PROMPT_ECHO_ON: // user name given to PAM already
68 return PAM_CONV_ERR; 69 return PAM_CONV_ERR;
69 70
70 case PAM_PROMPT_ECHO_OFF: // wants password 71 case PAM_PROMPT_ECHO_OFF: // wants password
71 reply = (struct pam_response *) ::realloc ( reply, size ); 72 reply = (struct pam_response *) ::realloc ( reply, size );
72 if ( !reply ) 73 if ( !reply )
73 return PAM_CONV_ERR; 74 return PAM_CONV_ERR;
74 size += sizeof( struct pam_response ); 75 size += sizeof( struct pam_response );
75 76
76 reply [replies]. resp_retcode = PAM_SUCCESS; 77 reply [replies]. resp_retcode = PAM_SUCCESS;
77 reply [replies]. resp = ::strdup ( s_pam_password ); 78 reply [replies]. resp = ::strdup ( s_pam_password );
78 replies++; // PAM frees resp 79 replies++; // PAM frees resp
79 break; 80 break;
80 81
81 case PAM_TEXT_INFO: 82 case PAM_TEXT_INFO:
82 break; 83 break;
83 84
84 default: 85 default:
85 /* unknown or PAM_ERROR_MSG */ 86 /* unknown or PAM_ERROR_MSG */
86 if ( reply ) 87 if ( reply )
87 ::free ( reply ); 88 ::free ( reply );
88 return PAM_CONV_ERR; 89 return PAM_CONV_ERR;
89 } 90 }
90 } 91 }
91 if ( reply ) 92 if ( reply )
92 *resp = reply; 93 *resp = reply;
93 return PAM_SUCCESS; 94 return PAM_SUCCESS;
94} 95}
95 96
96 97
97bool LoginApplication::checkPassword ( const char *user, const char *pass ) 98bool LoginApplication::checkPassword ( const char *user, const char *pass )
98{ 99{
99 static struct pam_conv conv = { &LoginApplication::pam_helper, 0 }; 100 static struct pam_conv conv = { &LoginApplication::pam_helper, 0 };
100 101
101 int pam_error; 102 int pam_error;
102 pam_handle_t *pamh = 0; 103 pam_handle_t *pamh = 0;
103 104
104 pam_error = ::pam_start( "xdm", user, &conv, &pamh ); 105 pam_error = ::pam_start( "xdm", user, &conv, &pamh );
105 if ( pam_error == PAM_SUCCESS ) { 106 if ( pam_error == PAM_SUCCESS ) {
106 s_pam_password = pass; 107 s_pam_password = pass;
107 pam_error = ::pam_authenticate ( pamh, 0 ); 108 pam_error = ::pam_authenticate ( pamh, 0 );
108 s_pam_password = 0; 109 s_pam_password = 0;
109 } 110 }
110 ::pam_end ( pamh, pam_error ); 111 ::pam_end ( pamh, pam_error );
111 return ( pam_error == PAM_SUCCESS ); 112 return ( pam_error == PAM_SUCCESS );
112} 113}
113 114
114#else 115#else
115 116
116bool LoginApplication::checkPassword ( const char *user, const char *pass ) 117bool LoginApplication::checkPassword ( const char *user, const char *pass )
117{ 118{
118 char *encrypted, *correct; 119 char *encrypted, *correct;
119 struct passwd *pw; 120 struct passwd *pw;
120 121
121 if ( !user || !pass ) 122 if ( !user || !pass )
122 return false; 123 return false;
123 124
124 pw = ::getpwnam ( user ); 125 pw = ::getpwnam ( user );
125 126
126 if ( !pw ) 127 if ( !pw )
127 return false; 128 return false;
128 129
129 if (( ::strcmp ( pw-> pw_passwd, "x" ) == 0 ) || ( ::strcmp ( pw-> pw_passwd, "*" ) == 0 )) { 130 if (( ::strcmp ( pw-> pw_passwd, "x" ) == 0 ) || ( ::strcmp ( pw-> pw_passwd, "*" ) == 0 )) {
130 struct spwd *sp = ::getspnam ( pw-> pw_name ); 131 struct spwd *sp = ::getspnam ( pw-> pw_name );
131 132
132 if ( !sp ) 133 if ( !sp )
133 return false; 134 return false;
134 135
135 correct = sp-> sp_pwdp; 136 correct = sp-> sp_pwdp;
136 } 137 }
137 else 138 else
138 correct = pw-> pw_passwd; 139 correct = pw-> pw_passwd;
139 140
140 if ( correct == 0 || correct[0] == '\0' ) 141 if ( correct == 0 || correct[0] == '\0' )
141 return true; 142 return true;
142 143
143 encrypted = ::crypt ( pass, correct ); 144 encrypted = ::crypt ( pass, correct );
144 return ( ::strcmp ( encrypted, correct ) == 0 ); 145 return ( ::strcmp ( encrypted, correct ) == 0 );
145} 146}
146 147
147#endif 148#endif
148 149
149bool LoginApplication::changeIdentity ( ) 150bool LoginApplication::changeIdentity ( )
150{ 151{
151 const char *DEFAULT_LOGIN_PATH = "/bin:/usr/bin"; 152 const char *DEFAULT_LOGIN_PATH = "/bin:/usr/bin";
152 const char *DEFAULT_ROOT_LOGIN_PATH = "/usr/sbin:/bin:/usr/bin:/sbin"; 153 const char *DEFAULT_ROOT_LOGIN_PATH = "/usr/sbin:/bin:/usr/bin:/sbin";
153 154
154 if ( !s_username ) 155 if ( !s_username )
155 return false; 156 return false;
156 struct passwd *pw = ::getpwnam ( s_username ); 157 struct passwd *pw = ::getpwnam ( s_username );
157 if ( !pw ) 158 if ( !pw )
158 return false; 159 return false;
159 160
160 bool fail = false; 161 bool fail = false;
161 fail |= ( ::initgroups ( pw-> pw_name, pw-> pw_gid )); 162 fail |= ( ::initgroups ( pw-> pw_name, pw-> pw_gid ));
162 ::endgrent ( ); 163 ::endgrent ( );
163 fail |= ( ::setgid ( pw-> pw_gid )); 164 fail |= ( ::setgid ( pw-> pw_gid ));
164 fail |= ( ::setuid ( pw-> pw_uid )); 165 fail |= ( ::setuid ( pw-> pw_uid ));
165 166
166 fail |= ( ::chdir ( pw-> pw_dir ) && ::chdir ( "/" )); 167 fail |= ( ::chdir ( pw-> pw_dir ) && ::chdir ( "/" ));
167 168
168 fail |= ( ::setenv ( "HOME", pw-> pw_dir, 1 )); 169 fail |= ( ::setenv ( "HOME", pw-> pw_dir, 1 ));
169 fail |= ( ::setenv ( "SHELL", pw-> pw_shell, 1 )); 170 fail |= ( ::setenv ( "SHELL", pw-> pw_shell, 1 ));
170 fail |= ( ::setenv ( "USER", pw-> pw_name, 1 )); 171 fail |= ( ::setenv ( "USER", pw-> pw_name, 1 ));
171 fail |= ( ::setenv ( "LOGNAME", pw-> pw_name, 1 )); 172 fail |= ( ::setenv ( "LOGNAME", pw-> pw_name, 1 ));
172 fail |= ( ::setenv ( "PATH", ( pw-> pw_uid ? DEFAULT_LOGIN_PATH : DEFAULT_ROOT_LOGIN_PATH ), 1 )); 173 fail |= ( ::setenv ( "PATH", ( pw-> pw_uid ? DEFAULT_LOGIN_PATH : DEFAULT_ROOT_LOGIN_PATH ), 1 ));
173 174
174 return !fail; 175 return !fail;
175} 176}
176 177
177bool LoginApplication::login ( ) 178bool LoginApplication::login ( )
178{ 179{
179 char *opie = ::getenv ( "OPIEDIR" ); 180 char *opie = ::getenv ( "OPIEDIR" );
180 char *arg = new char [::strlen ( opie ) + 8 + 1]; 181 char *arg = new char [::strlen ( opie ) + 8 + 1];
181 182
182 ::strcpy ( arg, opie ); 183 ::strcpy ( arg, opie );
183 ::strcat ( arg, "/bin/qpe" ); 184 ::strcat ( arg, "/bin/qpe" );
184 185
185 // start qpe via a login shell 186 // start qpe via a login shell
186 ::execl ( "/bin/sh", "-sh", "-c", arg, 0 ); 187 ::execl ( "/bin/sh", "-sh", "-c", arg, 0 );
187 188
188 return false; 189 return false;
189} 190}
190 191
191const char *LoginApplication::loginAs ( ) 192const char *LoginApplication::loginAs ( )
192{ 193{
193 return s_username; 194 return s_username;
194} 195}
195 196
196void LoginApplication::setLoginAs ( const char *name ) 197void LoginApplication::setLoginAs ( const char *name )
197{ 198{
198 s_username = name; 199 s_username = name;
199} 200}
200 201
201QStringList LoginApplication::allUsers ( ) 202QStringList LoginApplication::allUsers ( )
202{ 203{
203 struct passwd *pwd; 204 struct passwd *pwd;
204 QStringList sl; 205 QStringList sl;
205 206
206 while (( pwd = ::getpwent ( ))) { 207 while (( pwd = ::getpwent ( ))) {
207 if (( pwd-> pw_uid == 0 ) || ( pwd-> pw_uid >= 500 && pwd-> pw_uid < 65534 )) 208 if (( pwd-> pw_uid == 0 ) || ( pwd-> pw_uid >= 500 && pwd-> pw_uid < 65534 ))
208 sl << QString ( pwd-> pw_name ); 209 sl << QString ( pwd-> pw_name );
209 } 210 }
210 211
211 ::endpwent ( ); 212 ::endpwent ( );
212 213
213 return sl; 214 return sl;
214} 215}
215 216
216void LoginApplication::quitToConsole ( ) 217void LoginApplication::quitToConsole ( )
217{ 218{
218 QPEApplication::quit ( ); 219 QPEApplication::quit ( );
219 ::kill ( ::getppid ( ), SIGTERM ); 220 ::kill ( m_parentpid, SIGTERM );
220} 221}
diff --git a/core/opie-login/loginapplication.h b/core/opie-login/loginapplication.h
index 062c088..4e7cf79 100644
--- a/core/opie-login/loginapplication.h
+++ b/core/opie-login/loginapplication.h
@@ -1,67 +1,70 @@
1/* 1/*
2               =. This file is part of the OPIE Project 2               =. This file is part of the OPIE Project
3             .=l. Copyright (c) 2002 Robert Griebl <sandman@handhelds.org> 3             .=l. Copyright (c) 2002 Robert Griebl <sandman@handhelds.org>
4           .>+-= 4           .>+-=
5 _;:,     .>    :=|. This file is free software; you can 5 _;:,     .>    :=|. This file is free software; you can
6.> <`_,   >  .   <= redistribute it and/or modify it under 6.> <`_,   >  .   <= redistribute it and/or modify it under
7:`=1 )Y*s>-.--   : the terms of the GNU General Public 7:`=1 )Y*s>-.--   : the terms of the GNU General Public
8.="- .-=="i,     .._ License as published by the Free Software 8.="- .-=="i,     .._ License as published by the Free Software
9 - .   .-<_>     .<> Foundation; either version 2 of the License, 9 - .   .-<_>     .<> Foundation; either version 2 of the License,
10     ._= =}       : or (at your option) any later version. 10     ._= =}       : or (at your option) any later version.
11    .%`+i>       _;_. 11    .%`+i>       _;_.
12    .i_,=:_.      -<s. This file is distributed in the hope that 12    .i_,=:_.      -<s. This file is distributed in the hope that
13     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY; 13     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
14    : ..    .:,     . . . without even the implied warranty of 14    : ..    .:,     . . . without even the implied warranty of
15    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A 15    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
16  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU General 16  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU General
17..}^=.=       =       ; Public License for more details. 17..}^=.=       =       ; Public License for more details.
18++=   -.     .`     .: 18++=   -.     .`     .:
19 :     =  ...= . :.=- You should have received a copy of the GNU 19 :     =  ...= . :.=- You should have received a copy of the GNU
20 -.   .:....=;==+<; General Public License along with this file; 20 -.   .:....=;==+<; General Public License along with this file;
21  -_. . .   )=.  = see the file COPYING. If not, write to the 21  -_. . .   )=.  = see the file COPYING. If not, write to the
22    --        :-=` Free Software Foundation, Inc., 22    --        :-=` Free Software Foundation, Inc.,
23 59 Temple Place - Suite 330, 23 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, USA. 24 Boston, MA 02111-1307, USA.
25 25
26*/ 26*/
27 27
28#ifndef __OPIE_LOGINAPPLICATION_H__ 28#ifndef __OPIE_LOGINAPPLICATION_H__
29#define __OPIE_LOGINAPPLICATION_H__ 29#define __OPIE_LOGINAPPLICATION_H__
30 30
31#include <qstringlist.h> 31#include <qstringlist.h>
32 32
33#include <qpe/qpeapplication.h> 33#include <qpe/qpeapplication.h>
34 34
35#ifdef USEPAM 35#ifdef USEPAM
36struct pam_message; 36struct pam_message;
37struct pam_response; 37struct pam_response;
38#endif 38#endif
39 39
40class LoginApplication : public QPEApplication { 40class LoginApplication : public QPEApplication {
41public: 41public:
42 LoginApplication ( int &argc, char **argv ); 42 LoginApplication ( int &argc, char **argv, pid_t parentpid );
43 43
44 static bool checkPassword ( const char *user, const char *password ); 44 static bool checkPassword ( const char *user, const char *password );
45 45
46 static const char *loginAs ( ); 46 static const char *loginAs ( );
47 static void setLoginAs ( const char *user ); 47 static void setLoginAs ( const char *user );
48 48
49 static bool changeIdentity ( ); 49 static bool changeIdentity ( );
50 static bool login ( ); 50 static bool login ( );
51 51
52 static QStringList allUsers ( ); 52 static QStringList allUsers ( );
53 53
54 void quitToConsole ( ); 54 void quitToConsole ( );
55 55
56private: 56private:
57 static const char *s_username; 57 static const char *s_username;
58 58
59#ifdef USEPAM 59#ifdef USEPAM
60 static int pam_helper ( int num_msg, const struct pam_message **msg, struct pam_response **resp, void * ); 60 static int pam_helper ( int num_msg, const struct pam_message **msg, struct pam_response **resp, void * );
61 static const char *s_pam_password; 61 static const char *s_pam_password;
62#endif 62#endif
63
64private:
65 pid_t m_parentpid;
63}; 66};
64 67
65extern LoginApplication *lApp; 68extern LoginApplication *lApp;
66 69
67#endif 70#endif
diff --git a/core/opie-login/main.cpp b/core/opie-login/main.cpp
index 579a93a..674829d 100644
--- a/core/opie-login/main.cpp
+++ b/core/opie-login/main.cpp
@@ -1,357 +1,360 @@
1/* 1/*
2               =. This file is part of the OPIE Project 2               =. This file is part of the OPIE Project
3             .=l. Copyright (c) 2002 Robert Griebl <sandman@handhelds.org> 3             .=l. Copyright (c) 2002 Robert Griebl <sandman@handhelds.org>
4           .>+-= 4           .>+-=
5 _;:,     .>    :=|. This file is free software; you can 5 _;:,     .>    :=|. This file is free software; you can
6.> <`_,   >  .   <= redistribute it and/or modify it under 6.> <`_,   >  .   <= redistribute it and/or modify it under
7:`=1 )Y*s>-.--   : the terms of the GNU General Public 7:`=1 )Y*s>-.--   : the terms of the GNU General Public
8.="- .-=="i,     .._ License as published by the Free Software 8.="- .-=="i,     .._ License as published by the Free Software
9 - .   .-<_>     .<> Foundation; either version 2 of the License, 9 - .   .-<_>     .<> Foundation; either version 2 of the License,
10     ._= =}       : or (at your option) any later version. 10     ._= =}       : or (at your option) any later version.
11    .%`+i>       _;_. 11    .%`+i>       _;_.
12    .i_,=:_.      -<s. This file is distributed in the hope that 12    .i_,=:_.      -<s. This file is distributed in the hope that
13     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY; 13     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
14    : ..    .:,     . . . without even the implied warranty of 14    : ..    .:,     . . . without even the implied warranty of
15    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A 15    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
16  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU General 16  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU General
17..}^=.=       =       ; Public License for more details. 17..}^=.=       =       ; Public License for more details.
18++=   -.     .`     .: 18++=   -.     .`     .:
19 :     =  ...= . :.=- You should have received a copy of the GNU 19 :     =  ...= . :.=- You should have received a copy of the GNU
20 -.   .:....=;==+<; General Public License along with this file; 20 -.   .:....=;==+<; General Public License along with this file;
21  -_. . .   )=.  = see the file COPYING. If not, write to the 21  -_. . .   )=.  = see the file COPYING. If not, write to the
22    --        :-=` Free Software Foundation, Inc., 22    --        :-=` Free Software Foundation, Inc.,
23 59 Temple Place - Suite 330, 23 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, USA. 24 Boston, MA 02111-1307, USA.
25 25
26*/ 26*/
27 27
28#define _GNU_SOURCE 28#define _GNU_SOURCE
29 29
30#include <sys/types.h> 30#include <sys/types.h>
31#include <time.h> 31#include <time.h>
32#include <sys/time.h> 32#include <sys/time.h>
33#include <sys/resource.h> 33#include <sys/resource.h>
34#include <unistd.h> 34#include <unistd.h>
35#include <syslog.h> 35#include <syslog.h>
36#include <sys/wait.h> 36#include <sys/wait.h>
37#include <stdio.h> 37#include <stdio.h>
38#include <stdlib.h> 38#include <stdlib.h>
39#include <signal.h> 39#include <signal.h>
40#include <getopt.h> 40#include <getopt.h>
41#include <string.h> 41#include <string.h>
42 42
43#include <qpe/qpeapplication.h> 43#include <qpe/qpeapplication.h>
44#include <qpe/qcopenvelope_qws.h> 44#include <qpe/qcopenvelope_qws.h>
45#include <qpe/qpestyle.h> 45#include <qpe/qpestyle.h>
46#include <qpe/power.h> 46#include <qpe/power.h>
47#include <qpe/config.h> 47#include <qpe/config.h>
48 48
49#include <opie/odevice.h> 49#include <opie/odevice.h>
50 50
51#include <qwindowsystem_qws.h> 51#include <qwindowsystem_qws.h>
52#include <qmessagebox.h> 52#include <qmessagebox.h>
53#include <qlabel.h> 53#include <qlabel.h>
54#include <qtimer.h> 54#include <qtimer.h>
55#include <qfile.h> 55#include <qfile.h>
56 56
57#include "loginapplication.h" 57#include "loginapplication.h"
58#include "loginwindowimpl.h" 58#include "loginwindowimpl.h"
59#include "calibrate.h" 59#include "calibrate.h"
60 60
61using namespace Opie; 61using namespace Opie;
62 62
63int login_main ( int argc, char **argv ); 63int login_main ( int argc, char **argv, pid_t ppid );
64void sigterm ( int sig ); 64void sigterm ( int sig );
65void exit_closelog ( ); 65void exit_closelog ( );
66 66
67static struct option long_options [] = { 67static struct option long_options [] = {
68 { "autologin", 1, 0, 'a' }, 68 { "autologin", 1, 0, 'a' },
69 { 0, 0, 0, 0 } 69 { 0, 0, 0, 0 }
70}; 70};
71 71
72 72
73int main ( int argc, char **argv ) 73int main ( int argc, char **argv )
74{ 74{
75 pid_t ppid = ::getpid ( );
76
77
75 if ( ::geteuid ( ) != 0 ) { 78 if ( ::geteuid ( ) != 0 ) {
76 ::fprintf ( stderr, "%s can only be executed by root. (or chmod +s)", argv [0] ); 79 ::fprintf ( stderr, "%s can only be executed by root. (or chmod +s)", argv [0] );
77 return 1; 80 return 1;
78 } 81 }
79 if ( ::getuid ( ) != 0 ) // qt doesn't really like SUID and 82 if ( ::getuid ( ) != 0 ) // qt doesn't really like SUID and
80 ::setuid ( 0 ); // messes up things like config files 83 ::setuid ( 0 ); // messes up things like config files
81 84
82 char *autolog = 0; 85 char *autolog = 0;
83 int c; 86 int c;
84 while (( c = ::getopt_long ( argc, argv, "a:", long_options, 0 )) != -1 ) { 87 while (( c = ::getopt_long ( argc, argv, "a:", long_options, 0 )) != -1 ) {
85 switch ( c ) { 88 switch ( c ) {
86 case 'a': 89 case 'a':
87 autolog = optarg; 90 autolog = optarg;
88 break; 91 break;
89 default: 92 default:
90 ::fprintf ( stderr, "Usage: %s [-a|--autologin=<user>]\n", argv [0] ); 93 ::fprintf ( stderr, "Usage: %s [-a|--autologin=<user>]\n", argv [0] );
91 return 2; 94 return 2;
92 } 95 }
93 } 96 }
94 97
95 //struct rlimit rl; 98 //struct rlimit rl;
96 //::getrlimit ( RLIMIT_NOFILE, &rl ); 99 //::getrlimit ( RLIMIT_NOFILE, &rl );
97 100
98 //for ( unsigned int i = 0; i < rl. rlim_cur; i++ ) 101 //for ( unsigned int i = 0; i < rl. rlim_cur; i++ )
99 // ::close ( i ); 102 // ::close ( i );
100 103
101 ::setpgid ( 0, 0 ); 104 ::setpgid ( 0, 0 );
102 ::setsid ( ); 105 ::setsid ( );
103 106
104 ::signal ( SIGTERM, sigterm ); 107 ::signal ( SIGTERM, sigterm );
105 108
106 ::openlog ( "opie-login", LOG_CONS, LOG_AUTHPRIV ); 109 ::openlog ( "opie-login", LOG_CONS, LOG_AUTHPRIV );
107 ::atexit ( exit_closelog ); 110 ::atexit ( exit_closelog );
108 111
109 while ( true ) { 112 while ( true ) {
110 pid_t child = ::fork ( ); 113 pid_t child = ::fork ( );
111 114
112 if ( child < 0 ) { 115 if ( child < 0 ) {
113 ::syslog ( LOG_ERR, "Could not fork GUI process\n" ); 116 ::syslog ( LOG_ERR, "Could not fork GUI process\n" );
114 break; 117 break;
115 } 118 }
116 else if ( child > 0 ) { 119 else if ( child > 0 ) {
117 int status = 0; 120 int status = 0;
118 time_t started = ::time ( 0 ); 121 time_t started = ::time ( 0 );
119 122
120 while ( ::waitpid ( child, &status, 0 ) < 0 ) { } 123 while ( ::waitpid ( child, &status, 0 ) < 0 ) { }
121 124
122 if (( ::time ( 0 ) - started ) < 3 ) { 125 if (( ::time ( 0 ) - started ) < 3 ) {
123 if ( autolog ) { 126 if ( autolog ) {
124 ::syslog ( LOG_ERR, "Respawning too fast -- disabling auto-login\n" ); 127 ::syslog ( LOG_ERR, "Respawning too fast -- disabling auto-login\n" );
125 autolog = 0; 128 autolog = 0;
126 } 129 }
127 else { 130 else {
128 ::syslog ( LOG_ERR, "Respawning too fast -- going down\n" ); 131 ::syslog ( LOG_ERR, "Respawning too fast -- going down\n" );
129 break; 132 break;
130 } 133 }
131 } 134 }
132 int killedbysig = 0; 135 int killedbysig = 0;
133 136
134 if ( WIFSIGNALED( status )) { 137 if ( WIFSIGNALED( status )) {
135 switch ( WTERMSIG( status )) { 138 switch ( WTERMSIG( status )) {
136 case SIGINT : 139 case SIGINT :
137 case SIGTERM: 140 case SIGTERM:
138 case SIGKILL: 141 case SIGKILL:
139 break; 142 break;
140 143
141 default : 144 default :
142 killedbysig = WTERMSIG( status ); 145 killedbysig = WTERMSIG( status );
143 break; 146 break;
144 } 147 }
145 } 148 }
146 if ( killedbysig ) { // qpe was killed by an uncaught signal 149 if ( killedbysig ) { // qpe was killed by an uncaught signal
147 qApp = 0; 150 qApp = 0;
148 151
149 QWSServer::setDesktopBackground ( QImage ( )); 152 QWSServer::setDesktopBackground ( QImage ( ));
150 QApplication *app = new QApplication ( argc, argv, QApplication::GuiServer ); 153 QApplication *app = new QApplication ( argc, argv, QApplication::GuiServer );
151 app-> setFont ( QFont ( "Helvetica", 10 )); 154 app-> setFont ( QFont ( "Helvetica", 10 ));
152 app-> setStyle ( new QPEStyle ( )); 155 app-> setStyle ( new QPEStyle ( ));
153 156
154 const char *sig = ::strsignal ( killedbysig ); 157 const char *sig = ::strsignal ( killedbysig );
155 QLabel *l = new QLabel ( 0, "sig", Qt::WStyle_Customize | Qt::WStyle_NoBorder | Qt::WStyle_Tool ); 158 QLabel *l = new QLabel ( 0, "sig", Qt::WStyle_Customize | Qt::WStyle_NoBorder | Qt::WStyle_Tool );
156 l-> setText ( LoginWindowImpl::tr( "OPIE was terminated\nby an uncaught signal\n(%1)\n" ). arg ( sig )); 159 l-> setText ( LoginWindowImpl::tr( "OPIE was terminated\nby an uncaught signal\n(%1)\n" ). arg ( sig ));
157 l-> setAlignment ( Qt::AlignCenter ); 160 l-> setAlignment ( Qt::AlignCenter );
158 l-> move ( 0, 0 ); 161 l-> move ( 0, 0 );
159 l-> resize ( app-> desktop ( )-> width ( ), app-> desktop ( )-> height ( )); 162 l-> resize ( app-> desktop ( )-> width ( ), app-> desktop ( )-> height ( ));
160 l-> show ( ); 163 l-> show ( );
161 QTimer::singleShot ( 3000, app, SLOT( quit ( ))); 164 QTimer::singleShot ( 3000, app, SLOT( quit ( )));
162 app-> exec ( ); 165 app-> exec ( );
163 delete app; 166 delete app;
164 qApp = 0; 167 qApp = 0;
165 } 168 }
166 } 169 }
167 else { 170 else {
168 if ( !autolog ) { 171 if ( !autolog ) {
169 Config cfg ( "opie-login" ); 172 Config cfg ( "opie-login" );
170 cfg. setGroup ( "General" ); 173 cfg. setGroup ( "General" );
171 QString user = cfg. readEntry ( "AutoLogin" ); 174 QString user = cfg. readEntry ( "AutoLogin" );
172 175
173 if ( !user. isEmpty ( )) 176 if ( !user. isEmpty ( ))
174 autolog = ::strdup ( user. latin1 ( )); 177 autolog = ::strdup ( user. latin1 ( ));
175 } 178 }
176 179
177 if ( autolog ) { 180 if ( autolog ) {
178 LoginApplication::setLoginAs ( autolog ); 181 LoginApplication::setLoginAs ( autolog );
179 182
180 if ( LoginApplication::changeIdentity ( )) 183 if ( LoginApplication::changeIdentity ( ))
181 ::exit ( LoginApplication::login ( )); 184 ::exit ( LoginApplication::login ( ));
182 else 185 else
183 ::exit ( 0 ); 186 ::exit ( 0 );
184 } 187 }
185 else 188 else
186 ::exit ( login_main ( argc, argv )); 189 ::exit ( login_main ( argc, argv, ppid ));
187 } 190 }
188 } 191 }
189 return 0; 192 return 0;
190} 193}
191 194
192void sigterm ( int /*sig*/ ) 195void sigterm ( int /*sig*/ )
193{ 196{
194 ::exit ( 0 ); 197 ::exit ( 0 );
195} 198}
196 199
197 200
198void exit_closelog ( ) 201void exit_closelog ( )
199{ 202{
200 ::closelog ( ); 203 ::closelog ( );
201} 204}
202 205
203 206
204class LoginScreenSaver : public QWSScreenSaver 207class LoginScreenSaver : public QWSScreenSaver
205{ 208{
206public: 209public:
207 LoginScreenSaver ( ) 210 LoginScreenSaver ( )
208 { 211 {
209 m_lcd_status = true; 212 m_lcd_status = true;
210 213
211 m_backlight_bright = -1; 214 m_backlight_bright = -1;
212 m_backlight_forcedoff = false; 215 m_backlight_forcedoff = false;
213 216
214 // Make sure the LCD is in fact on, (if opie was killed while the LCD is off it would still be off) 217 // Make sure the LCD is in fact on, (if opie was killed while the LCD is off it would still be off)
215 ODevice::inst ( )-> setDisplayStatus ( true ); 218 ODevice::inst ( )-> setDisplayStatus ( true );
216 } 219 }
217 void restore() 220 void restore()
218 { 221 {
219 if ( !m_lcd_status ) // We must have turned it off 222 if ( !m_lcd_status ) // We must have turned it off
220 ODevice::inst ( ) -> setDisplayStatus ( true ); 223 ODevice::inst ( ) -> setDisplayStatus ( true );
221 224
222 setBacklight ( -3 ); 225 setBacklight ( -3 );
223 } 226 }
224 bool save( int level ) 227 bool save( int level )
225 { 228 {
226 switch ( level ) { 229 switch ( level ) {
227 case 0: 230 case 0:
228 if ( backlight() > 1 ) 231 if ( backlight() > 1 )
229 setBacklight( 1 ); // lowest non-off 232 setBacklight( 1 ); // lowest non-off
230 return true; 233 return true;
231 break; 234 break;
232 case 1: 235 case 1:
233 setBacklight( 0 ); // off 236 setBacklight( 0 ); // off
234 return true; 237 return true;
235 break; 238 break;
236 case 2: 239 case 2:
237 // We're going to suspend the whole machine 240 // We're going to suspend the whole machine
238 if ( PowerStatusManager::readStatus().acStatus() != PowerStatus::Online ) { 241 if ( PowerStatusManager::readStatus().acStatus() != PowerStatus::Online ) {
239 QWSServer::sendKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE ); 242 QWSServer::sendKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE );
240 return true; 243 return true;
241 } 244 }
242 break; 245 break;
243 } 246 }
244 return false; 247 return false;
245 } 248 }
246 249
247private: 250private:
248public: 251public:
249 void setIntervals( int i1 = 30, int i2 = 20, int i3 = 60 ) 252 void setIntervals( int i1 = 30, int i2 = 20, int i3 = 60 )
250 { 253 {
251 int v [4]; 254 int v [4];
252 255
253 v [ 0 ] = QMAX( 1000 * i1, 100 ); 256 v [ 0 ] = QMAX( 1000 * i1, 100 );
254 v [ 1 ] = QMAX( 1000 * i2, 100 ); 257 v [ 1 ] = QMAX( 1000 * i2, 100 );
255 v [ 2 ] = QMAX( 1000 * i3, 100 ); 258 v [ 2 ] = QMAX( 1000 * i3, 100 );
256 v [ 3 ] = 0; 259 v [ 3 ] = 0;
257 260
258 if ( !i1 && !i2 && !i3 ) 261 if ( !i1 && !i2 && !i3 )
259 QWSServer::setScreenSaverInterval ( 0 ); 262 QWSServer::setScreenSaverInterval ( 0 );
260 else 263 else
261 QWSServer::setScreenSaverIntervals ( v ); 264 QWSServer::setScreenSaverIntervals ( v );
262 } 265 }
263 266
264 int backlight ( ) 267 int backlight ( )
265 { 268 {
266 if ( m_backlight_bright == -1 ) 269 if ( m_backlight_bright == -1 )
267 m_backlight_bright = 255; 270 m_backlight_bright = 255;
268 271
269 return m_backlight_bright; 272 return m_backlight_bright;
270 } 273 }
271 274
272 void setBacklight ( int bright ) 275 void setBacklight ( int bright )
273 { 276 {
274 if ( bright == -3 ) { 277 if ( bright == -3 ) {
275 // Forced on 278 // Forced on
276 m_backlight_forcedoff = false; 279 m_backlight_forcedoff = false;
277 bright = -1; 280 bright = -1;
278 } 281 }
279 if ( m_backlight_forcedoff && bright != -2 ) 282 if ( m_backlight_forcedoff && bright != -2 )
280 return ; 283 return ;
281 if ( bright == -2 ) { 284 if ( bright == -2 ) {
282 // Toggle between off and on 285 // Toggle between off and on
283 bright = m_backlight_bright ? 0 : -1; 286 bright = m_backlight_bright ? 0 : -1;
284 m_backlight_forcedoff = !bright; 287 m_backlight_forcedoff = !bright;
285 } 288 }
286 289
287 m_backlight_bright = bright; 290 m_backlight_bright = bright;
288 291
289 bright = backlight ( ); 292 bright = backlight ( );
290 ODevice::inst ( ) -> setDisplayBrightness ( bright ); 293 ODevice::inst ( ) -> setDisplayBrightness ( bright );
291 294
292 m_backlight_bright = bright; 295 m_backlight_bright = bright;
293 } 296 }
294 297
295private: 298private:
296 bool m_lcd_status; 299 bool m_lcd_status;
297 300
298 int m_backlight_bright; 301 int m_backlight_bright;
299 bool m_backlight_forcedoff; 302 bool m_backlight_forcedoff;
300}; 303};
301 304
302 305
303 306
304 307
305int login_main ( int argc, char **argv ) 308int login_main ( int argc, char **argv, pid_t ppid )
306{ 309{
307 QWSServer::setDesktopBackground( QImage() ); 310 QWSServer::setDesktopBackground( QImage() );
308 LoginApplication *app = new LoginApplication ( argc, argv ); 311 LoginApplication *app = new LoginApplication ( argc, argv, ppid );
309 312
310 app-> setFont ( QFont ( "Helvetica", 10 )); 313 app-> setFont ( QFont ( "Helvetica", 10 ));
311 app-> setStyle ( new QPEStyle ( )); 314 app-> setStyle ( new QPEStyle ( ));
312 315
313 ODevice::inst ( )-> setSoftSuspend ( true ); 316 ODevice::inst ( )-> setSoftSuspend ( true );
314 317
315#if defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX) 318#if defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX)
316 if ( !QFile::exists ( "/etc/pointercal" )) { 319 if ( !QFile::exists ( "/etc/pointercal" )) {
317 // Make sure calibration widget starts on top. 320 // Make sure calibration widget starts on top.
318 Calibrate *cal = new Calibrate; 321 Calibrate *cal = new Calibrate;
319 cal-> exec ( ); 322 cal-> exec ( );
320 delete cal; 323 delete cal;
321 } 324 }
322#endif 325#endif
323 326
324 LoginScreenSaver *saver = new LoginScreenSaver; 327 LoginScreenSaver *saver = new LoginScreenSaver;
325 328
326 saver-> setIntervals ( ); 329 saver-> setIntervals ( );
327 QWSServer::setScreenSaver ( saver ); 330 QWSServer::setScreenSaver ( saver );
328 saver-> restore ( ); 331 saver-> restore ( );
329 332
330 333
331 LoginWindowImpl *lw = new LoginWindowImpl ( ); 334 LoginWindowImpl *lw = new LoginWindowImpl ( );
332 app-> setMainWidget ( lw ); 335 app-> setMainWidget ( lw );
333 lw-> setGeometry ( 0, 0, app-> desktop ( )-> width ( ), app-> desktop ( )-> height ( )); 336 lw-> setGeometry ( 0, 0, app-> desktop ( )-> width ( ), app-> desktop ( )-> height ( ));
334 lw-> show ( ); 337 lw-> show ( );
335 338
336 int rc = app-> exec ( ); 339 int rc = app-> exec ( );
337 340
338 ODevice::inst ( )-> setSoftSuspend ( false ); 341 ODevice::inst ( )-> setSoftSuspend ( false );
339 342
340 if ( app-> loginAs ( )) { 343 if ( app-> loginAs ( )) {
341 if ( app-> changeIdentity ( )) { 344 if ( app-> changeIdentity ( )) {
342 app-> login ( ); 345 app-> login ( );
343 346
344 // if login succeeds, it never comes back 347 // if login succeeds, it never comes back
345 348
346 QMessageBox::critical ( 0, LoginWindowImpl::tr( "Failure" ), LoginWindowImpl::tr( "Could not start OPIE." )); 349 QMessageBox::critical ( 0, LoginWindowImpl::tr( "Failure" ), LoginWindowImpl::tr( "Could not start OPIE." ));
347 rc = 1; 350 rc = 1;
348 } 351 }
349 else { 352 else {
350 QMessageBox::critical ( 0, LoginWindowImpl::tr( "Failure" ), LoginWindowImpl::tr( "Could not switch to new user identity" )); 353 QMessageBox::critical ( 0, LoginWindowImpl::tr( "Failure" ), LoginWindowImpl::tr( "Could not switch to new user identity" ));
351 rc = 2; 354 rc = 2;
352 } 355 }
353 356
354 } 357 }
355 return rc; 358 return rc;
356} 359}
357 360