示例#1
0
void 
PingServerCB( XtPointer call_data, XtIntervalId *id )
{

    char *t;
    

    /*
     *  get ping values from the environment...
     */

    if ( pingInterval == 0 ) {
	pingInterval  = ((t = (char *)getenv(PINGINTERVAL)) == NULL ? 0 : atoi(t));
	pingTimeout   = ((t = (char *)getenv(PINGTIMEOUT))  == NULL ? 0 : atoi(t));
    }

    
    /*
     *  ping the server. If successful, set a timer for the next ping,
     *  otherwise cleanup and exit...
     */

    if ( pingInterval != 0 ) {
	if (PingServer())
	    XtAddTimeOut((unsigned long) pingInterval * 60 * 1000, 
	    		  PingServerCB, NULL);
	else
	    exit(NOTIFY_RESTART);
    }
}
示例#2
0
void
NetClientDlg::UpdateServers()
{
    if (!config || !lst_servers || lst_servers->NumItems() < 1) return;

    if (!PingComplete())
    return;

    PingServer(ping_index);

    for (int i = 0; i < lst_servers->NumItems(); i++) {
        int n = lst_servers->GetItemData(i);

        NetServerInfo* info = config->GetServerList().at(n);
        lst_servers->SetItemText(i, 0, info->name);

        Text status = Game::GetText("NetClientDlg.offline");

        if (info->ping_time > 0 && info->ping_time < 10000) {
            char buffer[32];
            sprintf_s(buffer, "%d ms", info->ping_time); //-V576
            lst_servers->SetItemText(i, 5, buffer);

            switch (info->status) {
            default:
            case NetServerInfo::OFFLINE:     status = Game::GetText("NetClientDlg.offline");     break;
            case NetServerInfo::LOBBY:       status = Game::GetText("NetClientDlg.lobby");       break;
            case NetServerInfo::BRIEFING:    status = Game::GetText("NetClientDlg.briefing");    break;
            case NetServerInfo::ACTIVE:      status = Game::GetText("NetClientDlg.active");      break;
            case NetServerInfo::DEBRIEFING:  status = Game::GetText("NetClientDlg.debriefing");  break;
            case NetServerInfo::PERSISTENT:  status = Game::GetText("NetClientDlg.persistent");  break;
            }
        }
        else {
            lst_servers->SetItemText(i, 5, Game::GetText("NetClientDlg.not-avail"));
        }

        lst_servers->SetItemText(i, 3, status);

        char num_users[16];
        sprintf_s(num_users, "%d", info->nplayers);
        lst_servers->SetItemText(i, 4, num_users);
    }
}
示例#3
0
文件: session.c 项目: cz172638/wdm
void
ManageSession (struct display *d)
{
    static int		pid = 0;
    Display		*dpy;
    greet_user_rtn	greet_stat; 
    static GreetUserProc greet_user_proc = NULL;
#ifndef GREET_USER_STATIC
    void		*greet_lib_handle;
#endif

    Debug ("ManageSession %s\n", d->name);
    (void)XSetIOErrorHandler(IOErrorHandler);
    (void)XSetErrorHandler(ErrorHandler);
#ifndef HAS_SETPROCTITLE
    SetTitle(d->name, (char *) 0);
#else
    setproctitle("%s", d->name);
#endif
    /*
     * Load system default Resources
     */
    LoadXloginResources (d);

#ifdef GREET_USER_STATIC
    greet_user_proc = GreetUser;
#else
    Debug("ManageSession: loading greeter library %s\n", greeterLib);
    greet_lib_handle = dlopen(greeterLib, RTLD_NOW);
    if (greet_lib_handle != NULL)
	greet_user_proc = (GreetUserProc)dlsym(greet_lib_handle, "GreetUser");
    if (greet_user_proc == NULL)
	{
	LogError("%s while loading %s\n", dlerror(), greeterLib);
	exit(UNMANAGE_DISPLAY);
	}
#endif

    /* tell the possibly dynamically loaded greeter function
     * what data structure formats to expect.
     * These version numbers are registered with The Open Group. */
    verify.version = 1;
    greet.version = 1;
    greet_stat = (*greet_user_proc)(d, &dpy, &verify, &greet, &dlfuncs);

    if (greet_stat == Greet_Success)
    {
	clientPid = 0;
	if (!Setjmp (abortSession)) {
	    (void) Signal (SIGTERM, catchTerm);
	    /*
	     * Start the clients, changing uid/groups
	     *	   setting up environment and running the session
	     */
	    if (StartClient (&verify, d, &clientPid, greet.name, greet.password)) {
		Debug ("Client Started\n");

#ifndef GREET_USER_STATIC
                /* Save memory; close library */
                dlclose(greet_lib_handle);
#endif
 
		/*
		 * Wait for session to end,
		 */
		for (;;) {
		    if (d->pingInterval)
		    {
			if (!Setjmp (pingTime))
			{
			    (void) Signal (SIGALRM, catchAlrm);
			    (void) alarm (d->pingInterval * 60);
			    pid = wait ((waitType *) 0);
			    (void) alarm (0);
			}
			else
			{
			    (void) alarm (0);
			    if (!PingServer (d, (Display *) NULL))
				SessionPingFailed (d);
			}
		    }
		    else
		    {
			pid = wait ((waitType *) 0);
		    }
		    if (pid == clientPid)
			break;
		}
	    } else {
		LogError ("session start failed\n");
	    }
	} else {
	    /*
	     * when terminating the session, nuke
	     * the child and then run the reset script
	     */
	    AbortClient (clientPid);
	}
    }
    /*
     * run system-wide reset file
     */
    Debug ("Source reset program %s\n", d->reset);
    source (verify.systemEnviron, d->reset);
    SessionExit (d, OBEYSESS_DISPLAY, TRUE);
}
示例#4
0
文件: session.c 项目: bbidulock/wdm
void ManageSession(struct display *d)
{
	static int pid = 0;
	Display *dpy;
	greet_user_rtn greet_stat;
#ifdef WITH_CONSOLE_KIT
	char *ck_session_cookie = NULL;
#endif

	WDMDebug("ManageSession %s\n", d->name);
	(void)XSetIOErrorHandler(IOErrorHandler);
	(void)XSetErrorHandler(ErrorHandler);
#ifndef HAS_SETPROCTITLE
	SetTitle(d->name, (char *)0);
#else
	setproctitle("%s", d->name);
#endif
	/*
	 * Load system default Resources
	 */
	LoadXloginResources(d);

	verify.version = 1;
	greet.version = 1;
	greet_stat = GreetUser(d, &dpy, &verify, &greet);

	if (greet_stat == Greet_Success) {
		clientPid = 0;
		if (!Setjmp(abortSession)) {
			(void)Signal(SIGTERM, catchTerm);
			/*
			 * Start the clients, changing uid/groups
			 *     setting up environment and running the session
			 */
#ifdef WITH_CONSOLE_KIT
			ck_session_cookie = open_ck_session(getpwnam(greet.name), d);
#endif
			if (StartClient(&verify, d, &clientPid, greet.name, greet.password
#ifdef WITH_CONSOLE_KIT
							, ck_session_cookie
#endif
				)) {
				WDMDebug("Client Started\n");

				/*
				 * Wait for session to end,
				 */
				for (;;) {
					if (d->pingInterval) {
						if (!Setjmp(pingTime)) {
							(void)Signal(SIGALRM, catchAlrm);
							(void)alarm(d->pingInterval * 60);
							pid = wait((waitType *) 0);
							(void)alarm(0);
						} else {
							(void)alarm(0);
							if (!PingServer(d, (Display *) NULL))
								SessionPingFailed(d);
						}
					} else {
						pid = wait((waitType *) 0);
					}
					if (pid == clientPid)
						break;
				}
			} else {
				WDMError("session start failed\n");
			}
		} else {
			/*
			 * when terminating the session, nuke
			 * the child and then run the reset script
			 */
			AbortClient(clientPid);
		}
	}
#ifdef WITH_CONSOLE_KIT
	if (ck_session_cookie != NULL) {
		close_ck_session(ck_session_cookie);
		free(ck_session_cookie);
	}
#endif

	/*
	 * run system-wide reset file
	 */
	WDMDebug("Source reset program %s\n", d->reset);
	source(verify.systemEnviron, d->reset);
	SessionExit(d, OBEYSESS_DISPLAY, TRUE);
}
示例#5
0
int main(int argc, char * argv[])
{
    /*
     * Before starting main application, need to set 'QT_X11_NO_MITSHM=1'
     * to make the runtime work with IBM PPC machine.
     */
#if defined (Q_OS_LINUX)
    QByteArray val("1");
    qputenv("QT_X11_NO_MITSHM", val);
#endif

    // Create the QT application
    QApplication app(argc, argv);
    app.setQuitOnLastWindowClosed(false);

    // Setup the settings management
    QCoreApplication::setOrganizationName("pgadmin");
    QCoreApplication::setOrganizationDomain("pgadmin.org");
    QCoreApplication::setApplicationName(PGA_APP_NAME.toLower().replace(" ", ""));

#if QT_VERSION >= 0x050000
    // Set high DPI pixmap to display icons clear on Qt widget.
    QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif

    // Create a hash of the executable path so we can run copies side-by-side
    QString homeDir = QDir::homePath();
    unsigned long exeHash = sdbm((unsigned char *)argv[0]);

    // Create the address file, that will be used to store the appserver URL for this instance
    addrFileName = homeDir + (QString("/.%1.%2.addr").arg(PGA_APP_NAME).arg(exeHash)).remove(" ");
    QFile addrFile(addrFileName);

    // Create a system-wide semaphore keyed by app name, exe hash and the username
    // to ensure instances are unique to the user and path
    QString userName = qgetenv("USER"); // *nix
    if (userName.isEmpty())
        userName = qgetenv("USERNAME"); // Windows

    QString semaName = QString("%1-%2-%3-sema").arg(PGA_APP_NAME).arg(userName).arg(exeHash);
    QString shmemName = QString("%1-%2-%3-shmem").arg(PGA_APP_NAME).arg(userName).arg(exeHash);

    QSystemSemaphore sema(semaName, 1);
    sema.acquire();

#ifndef Q_OS_WIN32
    // We may need to clean up stale shmem segments on *nix. Attaching and detaching
    // should remove the segment if it is orphaned.
    QSharedMemory stale_shmem(shmemName);
    if (stale_shmem.attach())
        stale_shmem.detach();
#endif

    QSharedMemory shmem(shmemName);
    bool is_running;
    if (shmem.attach())
    {
        is_running = true;
    }
    else
    {
        shmem.create(1);
        is_running = false;
    }
    sema.release();

    QSettings settings;

    if (is_running){
        addrFile.open(QIODevice::ReadOnly | QIODevice::Text);
        QTextStream in(&addrFile);
        QString addr = in.readLine();

        QString cmd = settings.value("BrowserCommand").toString();

        if (!cmd.isEmpty())
        {
            cmd.replace("%URL%", addr);
            QProcess::startDetached(cmd);
        }
        else
        {
            if (!QDesktopServices::openUrl(addr))
            {
                QString error(QWidget::tr("Failed to open the system default web browser. Is one installed?."));
                QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);

                exit(1);
            }
        }

        return 0;
    }

    atexit(cleanup);

    // In windows and linux, it is required to set application level proxy
    // because socket bind logic to find free port gives socket creation error
    // when system proxy is configured. We are also setting
    // "setUseSystemConfiguration"=true to use the system proxy which will
    // override this application level proxy. As this bug is fixed in Qt 5.9 so
    // need to set application proxy for Qt version < 5.9.
    //
#if defined (Q_OS_WIN) && QT_VERSION <= 0x050800
    // Give dummy URL required to find proxy server configured in windows.
    QNetworkProxyQuery proxyQuery(QUrl("https://www.pgadmin.org"));
    QNetworkProxy l_proxy;
    QList<QNetworkProxy> listOfProxies = QNetworkProxyFactory::systemProxyForQuery(proxyQuery);

    if (listOfProxies.size())
    {
        l_proxy = listOfProxies[0];

        // If host name is not empty means proxy server is configured.
        if (!l_proxy.hostName().isEmpty()) {
            QNetworkProxy::setApplicationProxy(QNetworkProxy());
        }
    }
#endif

#if defined (Q_OS_LINUX) && QT_VERSION <= 0x050800
    QByteArray proxy_env;
    proxy_env = qgetenv("http_proxy");
    // If http_proxy environment is defined in linux then proxy server is configured.
    if (!proxy_env.isEmpty()) {
        QNetworkProxy::setApplicationProxy(QNetworkProxy());
    }
#endif

    // Display the spash screen
    QSplashScreen *splash = new QSplashScreen();
    splash->setPixmap(QPixmap(":/splash.png"));
    splash->show();
    app.processEvents(QEventLoop::AllEvents);

    quint16 port = 0L;

    // Find an unused port number. Essentially, we're just reserving one
    // here that Flask will use when we start up the server.
    // In order to use the socket, we need to free this socket ASAP.
    // Hence - putting this code in a code block so the scope of the socket
    // variable vanishes to make that socket available.
    {
#if QT_VERSION >= 0x050000
        QTcpSocket socket;

        #if QT_VERSION >= 0x050900
        socket.setProxy(QNetworkProxy::NoProxy);
        #endif

        socket.bind(0, QTcpSocket::ShareAddress);
#else
        QUdpSocket socket;
        socket.bind(0, QUdpSocket::ShareAddress);
#endif
        port = socket.localPort();
    }

    // Generate a random key to authenticate the client to the server
    QString key = QUuid::createUuid().toString();
    key = key.mid(1, key.length() - 2);

    // Generate the filename for the log
    logFileName = homeDir + (QString("/.%1.%2.log").arg(PGA_APP_NAME).arg(exeHash)).remove(" ");

    // Start the tray service
    TrayIcon *trayicon = new TrayIcon(logFileName);

    if (!trayicon->Init())
    {
        QString error = QString(QWidget::tr("An error occurred initialising the tray icon"));
        QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);

        exit(1);
    }

    // Fire up the webserver
    Server *server;

    bool done = false;

    while (done != true)
    {
        server = new Server(port, key, logFileName);

        if (!server->Init())
        {
            splash->finish(NULL);

            qDebug() << server->getError();

            QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
            QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);

            exit(1);
        }

        server->start();

        // This is a hack to give the server a chance to start and potentially fail. As
        // the Python interpreter is a synchronous call, we can't check for proper startup
        // easily in a more robust way - we have to rely on a clean startup not returning.
        // It should always fail pretty quickly, and take longer to start if it succeeds, so
        // we don't really get a visible delay here.
        delay(1000);

        // Any errors?
        if (server->isFinished() || server->getError().length() > 0)
        {
            splash->finish(NULL);

            qDebug() << server->getError();

            QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
            QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);

            // Allow the user to tweak the Python Path if needed
            bool ok;

            ConfigWindow *dlg = new ConfigWindow();
            dlg->setWindowTitle(QWidget::tr("Configuration"));
            dlg->setBrowserCommand(settings.value("BrowserCommand").toString());
            dlg->setPythonPath(settings.value("PythonPath").toString());
            dlg->setApplicationPath(settings.value("ApplicationPath").toString());
            dlg->setModal(true);
            ok = dlg->exec();

            QString browsercommand = dlg->getBrowserCommand();
            QString pythonpath = dlg->getPythonPath();
            QString applicationpath = dlg->getApplicationPath();

            if (ok)
            {
                settings.setValue("BrowserCommand", browsercommand);
                settings.setValue("PythonPath", pythonpath);
                settings.setValue("ApplicationPath", applicationpath);
                settings.sync();
            }
            else
            {
                exit(1);
            }

            delete server;
        }
        else
            done = true;
    }

    // Ensure the server gets cleaned up later
    QObject::connect(server, SIGNAL(finished()), server, SLOT(deleteLater()));

    // Generate the app server URL
    QString appServerUrl = QString("http://127.0.0.1:%1/?key=%2").arg(port).arg(key);

    // Read the server connection timeout from the registry or set the default timeout.
    int timeout = settings.value("ConnectionTimeout", 30).toInt();

    // Now the server should be up, we'll attempt to connect and get a response.
    // We'll retry in a loop a few time before aborting if necessary.

    QTime endTime = QTime::currentTime().addSecs(timeout);
    bool alive = false;

    while(QTime::currentTime() <= endTime)
    {
        alive = PingServer(QUrl(appServerUrl));

        if (alive)
        {
            break;
        }

        delay(200);
    }

    // Attempt to connect one more time in case of a long network timeout while looping
    if (!alive && !PingServer(QUrl(appServerUrl)))
    {
        splash->finish(NULL);
        QString error(QWidget::tr("The application server could not be contacted."));
        QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);

        exit(1);
    }

    // Stash the URL for any duplicate processes to open
    if (addrFile.open(QIODevice::WriteOnly))
    {
        addrFile.setPermissions(QFile::ReadOwner|QFile::WriteOwner);
        QTextStream out(&addrFile);
        out << appServerUrl << endl;
    }

    // Go!
    trayicon->setAppServerUrl(appServerUrl);
    // Enable the shutdown server menu as server started successfully.
    trayicon->enableShutdownMenu();

    QString cmd = settings.value("BrowserCommand").toString();

    if (!cmd.isEmpty())
    {
        cmd.replace("%URL%", appServerUrl);
        QProcess::startDetached(cmd);
    }
    else
    {
        if (!QDesktopServices::openUrl(appServerUrl))
        {
            QString error(QWidget::tr("Failed to open the system default web browser. Is one installed?."));
            QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);

            exit(1);
        }
    }

    QObject::connect(trayicon, SIGNAL(shutdownSignal(QUrl)), server, SLOT(shutdown(QUrl)));

    splash->finish(NULL);

    return app.exec();
}