summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/opie-login/loginapplication.cpp74
-rw-r--r--core/opie-login/loginapplication.h6
-rw-r--r--core/opie-login/main.cpp12
3 files changed, 82 insertions, 10 deletions
diff --git a/core/opie-login/loginapplication.cpp b/core/opie-login/loginapplication.cpp
index 8d86a71..1facf2d 100644
--- a/core/opie-login/loginapplication.cpp
+++ b/core/opie-login/loginapplication.cpp
@@ -30,6 +30,8 @@
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
#ifdef USEPAM
extern "C" {
@@ -158,6 +160,10 @@ bool LoginApplication::changeIdentity ( )
if ( !pw )
return false;
+ // we are still root at this point - try to run the pre-session script
+ if ( !runRootScript ( "OPIEDIR", "share/opie-login/pre-session", s_username ))
+ qWarning ( "failed to run $OPIEDIR/share/opie-login/pre-session" );
+
bool fail = false;
fail |= ( ::initgroups ( pw-> pw_name, pw-> pw_gid ));
::endgrent ( );
@@ -177,16 +183,70 @@ bool LoginApplication::changeIdentity ( )
bool LoginApplication::login ( )
{
- char *opie = ::getenv ( "OPIEDIR" );
- char *arg = new char [::strlen ( opie ) + 8 + 1];
+ execUserScript ( "HOME", ".opie-session" );
+ execUserScript ( "OPIEDIR", "share/opie-login/opie-session" );
+ execUserScript ( "OPIEDIR", "bin/qpe" );
+
+ qWarning ( "failed to start an Opie session" );
+ return false;
+}
+
+void LoginApplication::logout ( )
+{
+ // we are now root again - try to run the post-session script
+ if ( !runRootScript ( "OPIEDIR", "share/opie-login/post-session" ))
+ qWarning ( "failed to run $OPIEDIR/scripts/post-session" );
+}
- ::strcpy ( arg, opie );
- ::strcat ( arg, "/bin/qpe" );
- // start qpe via a login shell
- ::execl ( "/bin/sh", "-sh", "-c", arg, 0 );
+static char *buildarg ( const char *base, const char *script )
+{
+ const char *dir = base ? ::getenv ( base ) : "/";
+ char *arg = new char [::strlen ( dir ) + ::strlen ( script ) + 2];
- return false;
+ ::strcpy ( arg, dir );
+ ::strcat ( arg, "/" );
+ ::strcat ( arg, script );
+
+ return arg;
+}
+
+bool LoginApplication::runRootScript ( const char *base, const char *script, const char *param )
+{
+ bool res = false;
+ char *arg = buildarg ( base, script );
+
+ struct stat st;
+ if (( ::stat ( arg, &st ) == 0 ) && ( st. st_uid == 0 )) {
+ pid_t child = ::fork ( );
+
+ if ( child == 0 ) {
+ ::execl ( "/bin/sh", "-sh", arg, param, 0 );
+ ::_exit ( -1 );
+ }
+ else if ( child > 0 ) {
+ int status = 0;
+
+ while ( ::waitpid ( child, &status, 0 ) < 0 ) { }
+ res = ( WIFEXITED( status )) && ( WEXITSTATUS( status ) == 0 );
+ }
+ }
+
+ delete [] arg;
+ return res;
+}
+
+void LoginApplication::execUserScript ( const char *base, const char *script )
+{
+ char *arg = buildarg ( base, script );
+
+ struct stat st;
+ if ( ::stat ( arg, &st ) == 0 ) {
+ if ( st. st_mode & S_IXUSR )
+ ::execl ( "/bin/sh", "-sh", "-c", arg, 0 );
+ else
+ ::execl ( "/bin/sh", "-sh", arg, 0 );
+ }
}
const char *LoginApplication::loginAs ( )
diff --git a/core/opie-login/loginapplication.h b/core/opie-login/loginapplication.h
index 4e7cf79..d8264ea 100644
--- a/core/opie-login/loginapplication.h
+++ b/core/opie-login/loginapplication.h
@@ -28,8 +28,8 @@
#ifndef __OPIE_LOGINAPPLICATION_H__
#define __OPIE_LOGINAPPLICATION_H__
+#include <sys/types.h>
#include <qstringlist.h>
-
#include <qpe/qpeapplication.h>
#ifdef USEPAM
@@ -48,11 +48,15 @@ public:
static bool changeIdentity ( );
static bool login ( );
+ static void logout ( );
static QStringList allUsers ( );
void quitToConsole ( );
+ static bool runRootScript ( const char *base, const char *script, const char *param = 0 );
+ static void execUserScript ( const char *base, const char *script );
+
private:
static const char *s_username;
diff --git a/core/opie-login/main.cpp b/core/opie-login/main.cpp
index 674829d..81f4d1e 100644
--- a/core/opie-login/main.cpp
+++ b/core/opie-login/main.cpp
@@ -62,6 +62,7 @@ using namespace Opie;
int login_main ( int argc, char **argv, pid_t ppid );
void sigterm ( int sig );
+void sigint ( int sig );
void exit_closelog ( );
static struct option long_options [] = {
@@ -74,7 +75,6 @@ int main ( int argc, char **argv )
{
pid_t ppid = ::getpid ( );
-
if ( ::geteuid ( ) != 0 ) {
::fprintf ( stderr, "%s can only be executed by root. (or chmod +s)", argv [0] );
return 1;
@@ -104,7 +104,8 @@ int main ( int argc, char **argv )
::setpgid ( 0, 0 );
::setsid ( );
- ::signal ( SIGTERM, sigterm );
+ ::signal ( SIGTERM, sigterm );
+ ::signal ( SIGINT, sigterm );
::openlog ( "opie-login", LOG_CONS, LOG_AUTHPRIV );
::atexit ( exit_closelog );
@@ -122,6 +123,8 @@ int main ( int argc, char **argv )
while ( ::waitpid ( child, &status, 0 ) < 0 ) { }
+ LoginApplication::logout ( );
+
if (( ::time ( 0 ) - started ) < 3 ) {
if ( autolog ) {
::syslog ( LOG_ERR, "Respawning too fast -- disabling auto-login\n" );
@@ -148,6 +151,8 @@ int main ( int argc, char **argv )
}
if ( killedbysig ) { // qpe was killed by an uncaught signal
qApp = 0;
+
+ ::syslog ( LOG_ERR, "Opie was killed by a signal #%d", killedbysig );
QWSServer::setDesktopBackground ( QImage ( ));
QApplication *app = new QApplication ( argc, argv, QApplication::GuiServer );
@@ -303,6 +308,7 @@ private:
};
+namespace Opie { extern int force_appearance; } // HACK to get around the force-style setting
int login_main ( int argc, char **argv, pid_t ppid )
@@ -310,6 +316,8 @@ int login_main ( int argc, char **argv, pid_t ppid )
QWSServer::setDesktopBackground( QImage() );
LoginApplication *app = new LoginApplication ( argc, argv, ppid );
+ Opie::force_appearance = 0;
+
app-> setFont ( QFont ( "Helvetica", 10 ));
app-> setStyle ( new QPEStyle ( ));