source: src-qt4/PCDM/src/main.cpp @ 28c79ad

releng/10.0.1releng/10.0.2releng/10.0.3
Last change on this file since 28c79ad was 28c79ad, checked in by Ken Moore <ken@…>, 6 months ago

Add an auto-login delay function for PCDM that defaults to 10 seconds. This will pop-up a window giving the user the specified amount of time to either cancel the auto-login or immediately continue on.

  • Property mode set to 100644
File size: 8.3 KB
Line 
1/* PCDM Login Manager:
2*  Written by Ken Moore (ken@pcbsd.org) 2012/2013
3*  Copyright(c) 2013 by the PC-BSD Project
4*  Available under the 3-clause BSD license
5*/
6
7#include <QtGui/QApplication>
8#include <QTranslator>
9#include <QLocale>
10#include <QDesktopWidget>
11#include <QFile>
12#include <QSplashScreen>
13#include <QTime>
14#include <QDebug>
15#include <QX11Info>
16
17#include <sys/types.h>
18#include <sys/wait.h>
19#include <unistd.h>
20
21#include "pcdm-gui.h"
22#include "pcdm-backend.h"
23#include "pcdm-config.h"
24#include "pcdm-xprocess.h"
25#include "pcdm-logindelay.h"
26
27#define TMPLANGFILE QString("/tmp/.PCDMLang")
28#define TMPAUTOLOGINFILE QString("/tmp/.PCDMAutoLogin")
29#define TMPAUTHFILE QString("/tmp/.PCDMAuth")
30#define TMPSTOPFILE QString("/tmp/.PCDMstop")
31//Make sure that prefix is set
32//#ifndef prefix
33//#define prefix "/usr/local/"
34//#endif
35
36//bool USECLIBS=false;
37
38int runSingleSession(int argc, char *argv[]){
39  //QTime clock;
40  //clock.start();
41  Backend::checkLocalDirs();  // Create and fill "/usr/local/share/PCDM" if needed
42  Backend::openLogFile("/var/log/PCDM.log"); 
43  qDebug() << "PCDM Log File: /var/log/PCDM.log";
44  //qDebug() << "Backend Checks Finished:" << QString::number(clock.elapsed())+" ms";
45  //Setup the initial system environment (locale, keyboard)
46  QString lang, kmodel, klayout, kvariant;
47  Backend::readDefaultSysEnvironment(lang,kmodel,klayout,kvariant);
48  setenv("LANG", lang.toUtf8(), 0);
49  Backend::changeKbMap(kmodel,klayout,kvariant);
50  //Check for the flag to try and auto-login
51  bool ALtriggered = FALSE;
52  if(QFile::exists(TMPAUTOLOGINFILE)){ ALtriggered=TRUE; QFile::remove(TMPAUTOLOGINFILE); }
53 
54  //QString changeLang;
55  // Load the configuration file
56  QString confFile = "/usr/local/etc/pcdm.conf";
57  if(!QFile::exists(confFile)){ 
58    qDebug() << "PCDM: Configuration file missing:"<<confFile<<"\n  - Using default configuration";
59    QFile::copy(":samples/pcdm.conf", confFile);
60  }
61 
62  Config::loadConfigFile(confFile);
63  //qDebug() << "Config File Loaded:" << QString::number(clock.elapsed())+" ms";
64  // Startup the main application
65  QApplication a(argc,argv); 
66  int retCode = 0; //used for UI/application return
67  // Show our splash screen, so the user doesn't freak that that it takes a few seconds to show up
68  QSplashScreen splash;
69  if(!Config::splashscreen().isEmpty()){
70    splash.setPixmap( QPixmap(Config::splashscreen()) ); //load the splashscreen file
71  }
72  splash.show();
73  QCoreApplication::processEvents(); //Process the splash screen event immediately
74  //qDebug() << "SplashScreen Started:" << QString::number(clock.elapsed())+" ms";
75  //Initialize the xprocess
76  XProcess desktop;
77 
78  // Check what directory our app is in
79    QString appDir = "/usr/local/share/PCDM";
80    // Load the translator
81    QTranslator translator;
82    QString langCode = lang;
83    //Check for a language change detected
84    //if ( ! changeLang.isEmpty() )       
85       //langCode = changeLang;
86    //Load the proper locale for the translator
87    if ( QFile::exists(appDir + "/i18n/PCDM_" + langCode + ".qm" ) ) {
88      translator.load( QString("PCDM_") + langCode, appDir + "/i18n/" );
89      a.installTranslator(&translator);
90      Backend::log("Loaded Translation:" + appDir + "/i18n/PCDM_" + langCode + ".qm");
91    } else {
92      Backend::log("Could not find: " + appDir + "/i18n/PCDM_" + langCode + ".qm");
93      langCode = "";
94    }
95    //qDebug() << "Translation Finished:" << QString::number(clock.elapsed())+" ms";
96   
97  //*** STARTUP THE PROGRAM ***
98  bool goodAL = FALSE; //Flag for whether the autologin was successful
99  // Start the autologin procedure if applicable
100  if( ALtriggered && Config::useAutoLogin() ){
101    //Setup the Auto Login
102    QString user = Backend::getALUsername();
103    QString pwd = Backend::getALPassword();
104    QString dsk = Backend::getLastDE(user);
105    if( user.isEmpty() || dsk.isEmpty() ){
106         goodAL=FALSE;   
107    }else{
108        //Run the time delay for the autologin attempt
109        if(Config::autoLoginDelay() > 1){
110          loginDelay dlg(Config::autoLoginDelay(), user);
111          splash.close();
112          dlg.start();
113          dlg.exec();
114          goodAL = dlg.continueLogin;
115        }else{
116          goodAL = true;
117        }
118        //now start the autologin if appropriate
119        if(goodAL){
120          desktop.loginToXSession(user,pwd, dsk,lang);
121          splash.close();
122          if(desktop.isRunning()){
123            goodAL=TRUE; //flag this as a good login to skip the GUI
124          }
125        }
126    }
127  }
128  //qDebug() << "AutoLogin Finished:" << QString::number(clock.elapsed())+" ms";
129  if(!goodAL){
130    // ------START THE PCDM GUI-------
131
132    Backend::log("Starting up PCDM interface");
133    PCDMgui w;
134    //qDebug() << "Main GUI Created:" << QString::number(clock.elapsed())+" ms";
135    splash.finish(&w); //close the splash when the GUI starts up
136
137    // Set full-screen dimensions
138    QRect dimensions = QApplication::desktop()->screenGeometry();
139    int wid = dimensions.width();     // returns desktop width
140    int hig = dimensions.height();    // returns desktop height
141    w.setGeometry(0, 0, wid, hig);
142
143    //Set the proper size on the Application
144    w.setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnBottomHint);
145    w.setWindowState(Qt::WindowMaximized); //Qt::WindowFullScreen);
146
147    //Setup the signals/slots to startup the desktop session
148    //if(USECLIBS){ QObject::connect( &w,SIGNAL(xLoginAttempt(QString,QString,QString)), &desktop,SLOT(setupDesktop(QString,QString,QString))); }
149    //else{
150            QObject::connect( &w,SIGNAL(xLoginAttempt(QString,QString,QString,QString)), &desktop,SLOT(loginToXSession(QString,QString,QString,QString)) ); 
151    //}
152    //Setup the signals/slots for return information for the GUI
153    QObject::connect( &desktop, SIGNAL(InvalidLogin()), &w, SLOT(slotLoginFailure()) );
154    QObject::connect( &desktop, SIGNAL(started()), &w, SLOT(slotLoginSuccess()) );
155    QObject::connect( &desktop, SIGNAL(ValidLogin()), &w, SLOT(slotLoginSuccess()) );
156   
157    //qDebug() << "Showing GUI:" << QString::number(clock.elapsed())+" ms";
158    w.show();
159    retCode = a.exec();
160  }  // end of PCDM GUI running
161  //Wait for the desktop session to finish before exiting
162  //if(USECLIBS){ desktop.startDesktop(); }
163  //else{
164    desktop.waitForSessionClosed(); 
165  //}
166  splash.show(); //show the splash screen again
167  //Now wait a couple seconds for things to settle
168  QTime wTime = QTime::currentTime().addSecs(2);
169  while( QTime::currentTime() < wTime ){
170    QCoreApplication::processEvents(QEventLoop::AllEvents,100);
171  }
172  //check for shutdown process
173  if( QFile::exists(TMPSTOPFILE) || QFile::exists("/var/run/nologin") || retCode > 0){
174    splash.showMessage(QObject::tr("System Shutting Down"), Qt::AlignHCenter | Qt::AlignBottom, Qt::white);
175    QCoreApplication::processEvents();
176    //Pause for a few seconds to prevent starting a new session during a shutdown
177    wTime = QTime::currentTime().addSecs(30);
178    while( QTime::currentTime() < wTime ){ 
179      //Keep processing events during the wait (for splashscreen)
180      QCoreApplication::processEvents(QEventLoop::AllEvents, 100); 
181    }
182    //set the return code for a shutdown
183    retCode = -1; //make sure it does not start a new session
184  }
185 
186  //Clean up Code
187  delete &desktop;
188  delete &a;
189  delete &splash;
190 
191 
192  return retCode;
193}
194
195int main(int argc, char *argv[])
196{
197 bool neverquit = TRUE;
198 bool runonce = FALSE;
199 if(argc==2){ if( QString(argv[1]) == "-once"){ runonce = TRUE; } }
200 
201 while(neverquit){
202  if(runonce){ neverquit = FALSE; }
203  qDebug() << " -- PCDM Session Starting...";
204  int sid = -1;
205  int pid = fork();
206  if(pid < 0){
207    qDebug() << "Error: Could not fork the PCDM session";
208    return -1;
209  }else if( pid ==0 ){
210    //New Child Process
211    sid = setsid(); //start a session
212    qDebug() << "-- Session ID:" << sid;
213    int retCode = runSingleSession(argc,argv);
214    qDebug() << "-- PCDM Session Ended --";
215    //check for special exit code
216    if(retCode != 0){ neverquit=FALSE; }
217    //Now kill the shild process (whole session)
218    qDebug() << "Exiting child process";
219    exit(3);
220  }else{ 
221    //Parent (calling) process
222    int status;
223    sleep(2);
224    waitpid(sid,&status,0); //wait for the child (session) to finish
225    //NOTE: the parent will eventually become a login-watcher daemon process that
226    //   can spawn multiple child sessions on different TTY displays
227  }
228  qDebug() << "-- PCDM Session Ended --";
229  if(QFile::exists("/var/run/nologin") || QFile::exists(TMPSTOPFILE) ){ neverquit = FALSE; } 
230 }
231 return 0;
232}
Note: See TracBrowser for help on using the repository browser.