Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

main.cpp

Go to the documentation of this file.
00001 /*
00002                =.            This file is part of the OPIE Project
00003              .=l.            Copyright (c)  2002 Robert Griebl <sandman@handhelds.org>
00004            .>+-=
00005  _;:,     .>    :=|.         This file is free software; you can
00006 .> <`_,   >  .   <=          redistribute it and/or modify it under
00007 :`=1 )Y*s>-.--   :           the terms of the GNU General Public
00008 .="- .-=="i,     .._         License as published by the Free Software
00009  - .   .-<_>     .<>         Foundation; version 2 of the License.
00010      ._= =}       :
00011     .%`+i>       _;_.
00012     .i_,=:_.      -<s.       This file is distributed in the hope that
00013      +  .  -:.       =       it will be useful, but WITHOUT ANY WARRANTY;
00014     : ..    .:,     . . .    without even the implied warranty of
00015     =_        +     =;=|`    MERCHANTABILITY or FITNESS FOR A
00016   _.=:.       :    :=>`:     PARTICULAR PURPOSE. See the GNU General
00017 ..}^=.=       =       ;      Public License for more details.
00018 ++=   -.     .`     .:
00019  :     =  ...= . :.=-        You should have received a copy of the GNU
00020  -.   .:....=;==+<;          General Public License along with this file;
00021   -_. . .   )=.  =           see the file COPYING. If not, write to the
00022     --        :-=`           Free Software Foundation, Inc.,
00023                              59 Temple Place - Suite 330,
00024                              Boston, MA 02111-1307, USA.
00025 
00026 */
00027 
00028 #include "loginapplication.h"
00029 #include "loginwindowimpl.h"
00030 #include "calibrate.h"
00031 
00032 /* OPIE */
00033 #include <opie2/odevice.h>
00034 #include <qpe/qpestyle.h>
00035 #include <qpe/power.h>
00036 #include <qpe/config.h>
00037 
00038 /* QT */
00039 #include <qwindowsystem_qws.h>
00040 #include <qmessagebox.h>
00041 #include <qlabel.h>
00042 #include <qtimer.h>
00043 #include <qfile.h>
00044 
00045 /* STD */
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 ) // qt doesn't really like SUID and
00076                 ::setuid ( 0 );      // messes up things like config files
00077 
00078 //      struct rlimit rl;
00079 //      ::getrlimit ( RLIMIT_NOFILE, &rl );
00080 
00081 //      for ( unsigned int i = 0; i < rl. rlim_cur; i++ )
00082 //              ::close ( i );
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 ) {  // qpe was killed by an uncaught signal
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 /*sig*/ )
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     // Make sure the LCD is in fact on, (if opie was killed while the LCD is off it would still be off)
00226     ODevice::inst ( )-> setDisplayStatus ( true );
00227   }
00228   void restore()
00229   {
00230     if ( !m_lcd_status )     // We must have turned it off
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 ); // lowest non-off
00241         return true;
00242         break;
00243       case 1:
00244         setBacklight( 0 ); // off
00245         return true;
00246         break;
00247       case 2:
00248         // We're going to suspend the whole machine
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       // Forced on
00287       m_backlight_forcedoff = false;
00288       bright = -1;
00289     }
00290     if ( m_backlight_forcedoff && bright != -2 )
00291       return ;
00292     if ( bright == -2 ) {
00293       // Toggle between off and on
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                         // Make sure calibration widget starts on top.
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                         // if login succeeds, it never comes back
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 

Generated on Sat Nov 5 16:15:25 2005 for OPIE by  doxygen 1.4.2