00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "loginapplication.h"
00029 #include "loginwindowimpl.h"
00030 #include "calibrate.h"
00031
00032
00033 #include <opie2/odevice.h>
00034 #include <qpe/qpestyle.h>
00035 #include <qpe/power.h>
00036 #include <qpe/config.h>
00037
00038
00039 #include <qwindowsystem_qws.h>
00040 #include <qmessagebox.h>
00041 #include <qlabel.h>
00042 #include <qtimer.h>
00043 #include <qfile.h>
00044
00045
00046 #include <sys/types.h>
00047 #include <time.h>
00048 #include <sys/time.h>
00049 #include <sys/resource.h>
00050 #include <unistd.h>
00051 #include <syslog.h>
00052 #include <sys/wait.h>
00053 #include <stdio.h>
00054 #include <stdlib.h>
00055 #include <signal.h>
00056 #include <getopt.h>
00057 #include <string.h>
00058
00059 using namespace Opie::Core;
00060
00061 int login_main ( int argc, char **argv, pid_t ppid );
00062 void sigterm ( int sig );
00063 void sigint ( int sig );
00064 void exit_closelog ( );
00065
00066 int main ( int argc, char **argv )
00067 {
00068 int userExited = 0;
00069 pid_t ppid = ::getpid ( );
00070
00071 if ( ::geteuid ( ) != 0 ) {
00072 ::fprintf ( stderr, "%s can only be executed by root. (or chmod +s)\n", argv [0] );
00073 return 1;
00074 }
00075 if ( ::getuid ( ) != 0 )
00076 ::setuid ( 0 );
00077
00078
00079
00080
00081
00082
00083
00084 ::setpgid ( 0, 0 );
00085 ::setsid ( );
00086
00087 ::signal ( SIGTERM, sigterm );
00088 ::signal ( SIGINT, sigterm );
00089
00090 ::openlog ( "opie-login", LOG_CONS, LOG_AUTHPRIV );
00091 ::atexit ( exit_closelog );
00092
00093 const char* autolog = 0;
00094 Config c( "opie-login" );
00095 c.setGroup( "autologin" );
00096 QString entry = c.readEntry( "user", "" );
00097 if ( !entry.isEmpty() ) autolog = ::strdup( (const char*) entry );
00098
00099 while ( true ) {
00100 pid_t child = ::fork ( );
00101
00102 if ( child < 0 ) {
00103 ::syslog ( LOG_ERR, "Could not fork GUI process\n" );
00104 break;
00105 }
00106 else if ( child > 0 ) {
00107 int status = 0;
00108 time_t started = ::time ( 0 );
00109
00110 while ( ::waitpid ( child, &status, 0 ) < 0 ) { }
00111
00112 LoginApplication::logout ( );
00113
00114 if (( ::time ( 0 ) - started ) < 3 ) {
00115 if ( autolog ) {
00116 ::syslog ( LOG_ERR, "Respawning too fast -- disabling auto-login\n" );
00117 autolog = 0;
00118 }
00119 else {
00120 ::syslog ( LOG_ERR, "Respawning too fast -- going down\n" );
00121 break;
00122 }
00123 }
00124 int killedbysig = 0;
00125 userExited=0;
00126 if (WIFEXITED(status)!=0 ) {
00127 if (WEXITSTATUS(status)==137) {
00128 userExited=1;
00129 }
00130 }
00131
00132 if ( WIFSIGNALED( status )) {
00133 switch ( WTERMSIG( status )) {
00134 case SIGTERM:
00135 case SIGINT :
00136 case SIGKILL:
00137 break;
00138
00139 default :
00140 killedbysig = WTERMSIG( status );
00141 break;
00142 }
00143 }
00144 if ( killedbysig ) {
00145 qApp = 0;
00146
00147 ::syslog ( LOG_ERR, "Opie was killed by a signal #%d", killedbysig );
00148
00149 QWSServer::setDesktopBackground ( QImage ( ));
00150 QApplication *app = new QApplication ( argc, argv, QApplication::GuiServer );
00151 app-> setFont ( QFont ( "Helvetica", 10 ));
00152 app-> setStyle ( new QPEStyle ( ));
00153
00154 #ifndef __UCLIBC__
00155 const char *sig = ::sys_siglist[killedbysig];
00156 #else
00157 const char *sig = ::strsignal ( killedbysig );
00158 #endif
00159 QLabel *l = new QLabel ( 0, "sig", Qt::WStyle_Customize | Qt::WStyle_NoBorder | Qt::WStyle_Tool );
00160 l-> setText ( LoginWindowImpl::tr( "Opie was terminated\nby an uncaught signal\n(%1)\n" ). arg ( sig ));
00161 l-> setAlignment ( Qt::AlignCenter );
00162 l-> move ( 0, 0 );
00163 l-> resize ( app-> desktop ( )-> width ( ), app-> desktop ( )-> height ( ));
00164 l-> show ( );
00165 QTimer::singleShot ( 3000, app, SLOT( quit()));
00166 app-> exec ( );
00167 delete app;
00168 qApp = 0;
00169 }
00170 }
00171 else {
00172 if ( !autolog ) {
00173 QString confFile=QPEApplication::qpeDir() + "etc/opie-login.conf";
00174 Config cfg ( confFile, Config::File );
00175 cfg. setGroup ( "General" );
00176 QString user = cfg. readEntry ( "AutoLogin" );
00177
00178 if ( !user. isEmpty ( ))
00179 autolog = ::strdup ( user. latin1 ( ));
00180 }
00181
00182 if ( autolog && !userExited ) {
00183
00184 QWSServer::setDesktopBackground( QImage() );
00185 ODevice::inst()->setDisplayStatus( true );
00186 LoginApplication *app = new LoginApplication ( argc, argv, ppid );
00187 LoginApplication::setLoginAs( autolog );
00188
00189
00190 if ( LoginApplication::changeIdentity ( ))
00191 ::exit ( LoginApplication::login ( ));
00192 else
00193 ::exit ( 0 );
00194 }
00195 else {
00196 ::exit ( login_main ( argc, argv, ppid ));
00197 }
00198 }
00199 }
00200 return 0;
00201 }
00202
00203 void sigterm ( int )
00204 {
00205 ::exit ( 0 );
00206 }
00207
00208
00209 void exit_closelog ( )
00210 {
00211 ::closelog ( );
00212 }
00213
00214
00215 class LoginScreenSaver : public QWSScreenSaver
00216 {
00217 public:
00218 LoginScreenSaver ( )
00219 {
00220 m_lcd_status = true;
00221
00222 m_backlight_bright = -1;
00223 m_backlight_forcedoff = false;
00224
00225
00226 ODevice::inst ( )-> setDisplayStatus ( true );
00227 }
00228 void restore()
00229 {
00230 if ( !m_lcd_status )
00231 ODevice::inst ( ) -> setDisplayStatus ( true );
00232
00233 setBacklight ( -3 );
00234 }
00235 bool save( int level )
00236 {
00237 switch ( level ) {
00238 case 0:
00239 if ( backlight() > 1 )
00240 setBacklight( 1 );
00241 return true;
00242 break;
00243 case 1:
00244 setBacklight( 0 );
00245 return true;
00246 break;
00247 case 2:
00248
00249 if ( PowerStatusManager::readStatus().acStatus() != PowerStatus::Online ) {
00250 QWSServer::sendKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE );
00251 return true;
00252 }
00253 break;
00254 }
00255 return false;
00256 }
00257
00258 private:
00259 public:
00260 void setIntervals( int i1 = 30, int i2 = 20, int i3 = 60 )
00261 {
00262 int v [4];
00263
00264 v [ 0 ] = QMAX( 1000 * i1, 100 );
00265 v [ 1 ] = QMAX( 1000 * i2, 100 );
00266 v [ 2 ] = QMAX( 1000 * i3, 100 );
00267 v [ 3 ] = 0;
00268
00269 if ( !i1 && !i2 && !i3 )
00270 QWSServer::setScreenSaverInterval ( 0 );
00271 else
00272 QWSServer::setScreenSaverIntervals ( v );
00273 }
00274
00275 int backlight ( )
00276 {
00277 if ( m_backlight_bright == -1 )
00278 m_backlight_bright = 255;
00279
00280 return m_backlight_bright;
00281 }
00282
00283 void setBacklight ( int bright )
00284 {
00285 if ( bright == -3 ) {
00286
00287 m_backlight_forcedoff = false;
00288 bright = -1;
00289 }
00290 if ( m_backlight_forcedoff && bright != -2 )
00291 return ;
00292 if ( bright == -2 ) {
00293
00294 bright = m_backlight_bright ? 0 : -1;
00295 m_backlight_forcedoff = !bright;
00296 }
00297
00298 m_backlight_bright = bright;
00299
00300 bright = backlight ( );
00301 ODevice::inst ( ) -> setDisplayBrightness ( bright );
00302
00303 m_backlight_bright = bright;
00304 }
00305
00306 private:
00307 bool m_lcd_status;
00308
00309 int m_backlight_bright;
00310 bool m_backlight_forcedoff;
00311 };
00312
00313
00314 int login_main ( int argc, char **argv, pid_t ppid )
00315 {
00316 QWSServer::setDesktopBackground( QImage() );
00317 LoginApplication *app = new LoginApplication ( argc, argv, ppid );
00318
00319 app-> setFont ( QFont ( "Helvetica", 10 ));
00320 app-> setStyle ( new QPEStyle ( ));
00321
00322 if ( QWSServer::mouseHandler() &&
00323 QWSServer::mouseHandler() ->inherits("QCalibratedMouseHandler") ) {
00324 if ( !QFile::exists ( "/etc/pointercal" )) {
00325
00326 Calibrate *cal = new Calibrate;
00327 cal-> exec ( );
00328 delete cal;
00329 }
00330 }
00331
00332 LoginScreenSaver *saver = new LoginScreenSaver;
00333
00334 saver-> setIntervals ( );
00335 QWSServer::setScreenSaver ( saver );
00336 saver-> restore ( );
00337
00338
00339 LoginWindowImpl *lw = new LoginWindowImpl ( );
00340 app-> setMainWidget ( lw );
00341 lw-> setGeometry ( 0, 0, app-> desktop ( )-> width ( ), app-> desktop ( )-> height ( ));
00342 lw-> show ( );
00343
00344 int rc = app-> exec ( );
00345
00346 if ( app-> loginAs ( )) {
00347 if ( app-> changeIdentity ( )) {
00348 app-> login ( );
00349
00350
00351
00352 QMessageBox::critical ( 0, LoginWindowImpl::tr( "Failure" ), LoginWindowImpl::tr( "Could not start Opie." ));
00353 rc = 1;
00354 }
00355 else {
00356 QMessageBox::critical ( 0, LoginWindowImpl::tr( "Failure" ), LoginWindowImpl::tr( "Could not switch to new user identity" ));
00357 rc = 2;
00358 }
00359
00360 }
00361 return rc;
00362 }
00363