summaryrefslogtreecommitdiffstats
path: root/kdm/backend/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'kdm/backend/session.c')
-rw-r--r--kdm/backend/session.c813
1 files changed, 0 insertions, 813 deletions
diff --git a/kdm/backend/session.c b/kdm/backend/session.c
deleted file mode 100644
index 9a12ce312..000000000
--- a/kdm/backend/session.c
+++ /dev/null
@@ -1,813 +0,0 @@
-/*
-
-Copyright 1988, 1998 The Open Group
-Copyright 2000-2004 Oswald Buddenhagen <ossi@kde.org>
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from the copyright holder.
-
-*/
-
-/*
- * xdm - display manager daemon
- * Author: Keith Packard, MIT X Consortium
- *
- * subdaemon event loop, etc.
- */
-
-#include "dm.h"
-#include "dm_error.h"
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/cursorfont.h>
-
-#include <stdio.h>
-#include <ctype.h>
-#include <signal.h>
-
-#ifdef WITH_CONSOLE_KIT
-#include "consolekit.h"
-#endif
-
-struct display *td;
-const char *td_setup = "auto";
-
-static void DeleteXloginResources( void );
-static void LoadXloginResources( void );
-static void SetupDisplay( const char *arg );
-
-
-static Jmp_buf pingTime;
-
-/* ARGSUSED */
-static void
-catchAlrm( int n ATTR_UNUSED )
-{
- Longjmp( pingTime, 1 );
-}
-
-static Jmp_buf tenaciousClient;
-
-/* ARGSUSED */
-static void
-waitAbort( int n ATTR_UNUSED )
-{
- Longjmp( tenaciousClient, 1 );
-}
-
-static void
-AbortClient( int pid )
-{
- int sig = SIGTERM;
- volatile int i;
- int retId;
-
- for (i = 0; i < 4; i++) {
- if (kill( -pid, sig ) == -1) {
- switch (errno) {
- case EPERM:
- LogError( "Can't kill client\n" );
- case EINVAL:
- case ESRCH:
- return;
- }
- }
- if (!Setjmp( tenaciousClient )) {
- (void)Signal( SIGALRM, waitAbort );
- (void)alarm( (unsigned)10 );
- retId = wait( (waitType *)0 );
- (void)alarm( (unsigned)0 );
- (void)Signal( SIGALRM, SIG_DFL );
- if (retId == pid)
- break;
- } else
- (void)Signal( SIGALRM, SIG_DFL );
- sig = SIGKILL;
- }
-}
-
-
-static char *
-conv_auto( int what, const char *prompt ATTR_UNUSED )
-{
- switch (what) {
- case GCONV_USER:
- return curuser;
- case GCONV_PASS:
- case GCONV_PASS_ND:
- return curpass;
- default:
- LogError( "Unknown authentication data type requested for autologin.\n" );
- return 0;
- }
-}
-
-static void
-DoAutoLogon( void )
-{
- ReStr( &curuser, td->autoUser );
- ReStr( &curpass, td->autoPass );
- ReStr( &curtype, "classic" );
- cursource = PWSRC_AUTOLOGIN;
-}
-
-static int
-AutoLogon( Time_t tdiff )
-{
- Debug( "autoLogon, tdiff = %d, rLogin = %d, goodexit = %d, nuser = %s\n",
- tdiff, td->hstent->rLogin, td->hstent->goodExit, td->hstent->nuser );
- if (td->hstent->rLogin == 2 ||
- (td->hstent->rLogin == 1 &&
- tdiff <= 0 && !td->hstent->goodExit && !td->hstent->lock))
- {
- curuser = td->hstent->nuser;
- td->hstent->nuser = 0;
- curpass = td->hstent->npass;
- td->hstent->npass = 0;
- newdmrc = td->hstent->nargs;
- td->hstent->nargs = 0;
- ReStr( &curtype, "classic" );
- cursource = (td->hstent->rLogin == 1) ? PWSRC_RELOGIN : PWSRC_MANUAL;
- return 1;
- } else if (*td->autoUser && !td->autoDelay &&
- ((tdiff > 0 && ((td->displayType & d_lifetime) == dTransient ||
- !td->hstent->lastExit)) ||
- td->autoAgain))
- {
- unsigned int lmask;
- Window dummy1, dummy2;
- int dummy3, dummy4, dummy5, dummy6;
- XQueryPointer( dpy, DefaultRootWindow( dpy ),
- &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6,
- &lmask );
- if (lmask & ShiftMask)
- return 0;
- DoAutoLogon();
- return 1;
- }
- return 0;
-}
-
-
-static const struct {
- int vcode, echo, ndelay;
-} grqs[] = {
- { V_GET_TEXT, TRUE, FALSE },
- { V_GET_TEXT, FALSE, FALSE },
- { V_GET_TEXT, TRUE, FALSE },
- { V_GET_TEXT, FALSE, FALSE },
- { V_GET_TEXT, FALSE, TRUE },
- { V_GET_BINARY, 0, 0 }
-};
-
-char *
-conv_interact( int what, const char *prompt )
-{
- char *ret;
- int tag;
-
- GSendInt( grqs[what].vcode );
- if (what == GCONV_BINARY) {
- unsigned const char *up = (unsigned const char *)prompt;
- int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24);
- GSendArr( len, prompt );
- GSendInt( FALSE ); /* ndelay */
- return GRecvArr( &len );
- } else {
- GSendStr( prompt );
- GSendInt( grqs[what].echo );
- GSendInt( grqs[what].ndelay );
- ret = GRecvStr();
- if (ret) {
- tag = GRecvInt();
- switch (what) {
- case GCONV_USER:
- /* assert(tag & V_IS_USER); */
- if (curuser)
- free( curuser );
- curuser = ret;
- break;
- case GCONV_PASS:
- case GCONV_PASS_ND:
- /* assert(tag & V_IS_PASSWORD); */
- if (curpass)
- free( curpass );
- curpass = ret;
- break;
- default:
- if (tag & V_IS_USER)
- ReStr( &curuser, ret );
- else if (tag & V_IS_PASSWORD)
- ReStr( &curpass, ret );
- else if (tag & V_IS_NEWPASSWORD)
- ReStr( &newpass, ret );
- else if (tag & V_IS_OLDPASSWORD)
- ReStr( &ret, curpass );
- }
- }
- return ret;
- }
-}
-
-static int greeter;
-GProc grtproc;
-GTalk grttalk;
-
-GTalk mstrtalk; /* make static; see dm.c */
-
-int
-CtrlGreeterWait( int wreply )
-{
- int i, cmd, type, rootok;
- char *name, *pass, **avptr;
-#ifdef XDMCP
- ARRAY8Ptr aptr;
-#endif
-
- if (Setjmp( mstrtalk.errjmp )) {
- CloseGreeter( TRUE );
- SessionExit( EX_UNMANAGE_DPY );
- }
-
- while (GRecvCmd( &cmd )) {
- switch (cmd)
- {
- case G_Ready:
- Debug( "G_Ready\n" );
- return 0;
- case G_GetCfg:
- /*Debug ("G_GetCfg\n");*/
- type = GRecvInt();
- /*Debug (" index %#x\n", type);*/
- if (type == C_isLocal)
- i = (td->displayType & d_location) == dLocal;
- else if (type == C_hasConsole)
-#ifdef HAVE_VTS
- i = *consoleTTYs != 0;
-#else
- i = td->console != 0;
-#endif
- else if (type == C_isAuthorized)
- i = td->authorizations != 0;
- else
- goto normal;
- GSendInt( GE_Ok );
- /*Debug (" -> bool %d\n", i);*/
- GSendInt( i );
- break;
- normal:
- if (!(avptr = FindCfgEnt( td, type ))) {
- /*Debug (" -> not found\n");*/
- GSendInt( GE_NoEnt );
- break;
- }
- switch (type & C_TYPE_MASK) {
- default:
- /*Debug (" -> unknown type\n");*/
- GSendInt( GE_BadType );
- break;
- case C_TYPE_INT:
- case C_TYPE_STR:
- case C_TYPE_ARGV:
-#ifdef XDMCP
- case C_TYPE_ARR:
-#endif
- GSendInt( GE_Ok );
- switch (type & C_TYPE_MASK) {
- case C_TYPE_INT:
- /*Debug (" -> int %#x (%d)\n", *(int *)avptr, *(int *)avptr);*/
- GSendInt( *(long *)avptr );
- break;
- case C_TYPE_STR:
- /*Debug (" -> string %\"s\n", *avptr);*/
- GSendStr( *avptr );
- break;
- case C_TYPE_ARGV:
- /*Debug (" -> sending argv %\"[{s\n", *(char ***)avptr);*/
- GSendArgv( *(char ***)avptr );
- break;
-#ifdef XDMCP
- case C_TYPE_ARR:
- aptr = *(ARRAY8Ptr *)avptr;
- /*Debug (" -> sending array %02[*:hhx\n",
- aptr->length, aptr->data);*/
- GSendArr( aptr->length, (char *)aptr->data );
- break;
-#endif
- }
- break;
- }
- break;
- case G_ReadDmrc:
- Debug( "G_ReadDmrc\n" );
- name = GRecvStr();
- Debug( " user %\"s\n", name );
- if (StrCmp( dmrcuser, name )) {
- if (curdmrc) { free( curdmrc ); curdmrc = 0; }
- if (dmrcuser)
- free( dmrcuser );
- dmrcuser = name;
- i = ReadDmrc();
- Debug( " -> status %d\n", i );
- GSendInt( i );
- Debug( " => %\"s\n", curdmrc );
- } else {
- if (name)
- free( name );
- Debug( " -> status " stringify( GE_Ok ) "\n" );
- GSendInt( GE_Ok );
- Debug( " => keeping old\n" );
- }
- break;
- case G_GetDmrc:
- Debug( "G_GetDmrc\n" );
- name = GRecvStr();
- Debug( " key %\"s\n", name );
- pass = iniEntry( curdmrc, "Desktop", name, 0 );
- Debug( " -> %\"s\n", pass );
- GSendStr( pass );
- if (pass)
- free( pass );
- free( name );
- break;
-/* case G_ResetDmrc:
- Debug ("G_ResetDmrc\n");
- if (newdmrc) { free (newdmrc); newdmrc = 0; }
- break; */
- case G_PutDmrc:
- Debug( "G_PutDmrc\n" );
- name = GRecvStr();
- Debug( " key %\"s\n", name );
- pass = GRecvStr();
- Debug( " value %\"s\n", pass );
- newdmrc = iniEntry( newdmrc, "Desktop", name, pass );
- free( pass );
- free( name );
- break;
- case G_VerifyRootOK:
- Debug( "G_VerifyRootOK\n" );
- rootok = TRUE;
- goto doverify;
- case G_Verify:
- Debug( "G_Verify\n" );
- rootok = FALSE;
- doverify:
- if (curuser) { free( curuser ); curuser = 0; }
- if (curpass) { free( curpass ); curpass = 0; }
- if (curtype) free( curtype );
- curtype = GRecvStr();
- Debug( " type %\"s\n", curtype );
- cursource = PWSRC_MANUAL;
- if (Verify( conv_interact, rootok )) {
- Debug( " -> return success\n" );
- GSendInt( V_OK );
- } else
- Debug( " -> failure returned\n" );
- break;
- case G_AutoLogin:
- Debug( "G_AutoLogin\n" );
- DoAutoLogon();
- if (Verify( conv_auto, FALSE )) {
- Debug( " -> return success\n" );
- GSendInt( V_OK );
- } else
- Debug( " -> failure returned\n" );
- break;
- case G_SetupDpy:
- Debug( "G_SetupDpy\n" );
- SetupDisplay( 0 );
- td_setup = 0;
- GSendInt( 0 );
- break;
- default:
- return cmd;
- }
- if (!wreply)
- return -1;
- }
- Debug( "lost connection to greeter\n" );
- return -2;
-}
-
-void
-OpenGreeter()
-{
- char *name, **env;
- static Time_t lastStart;
- int cmd;
- Cursor xcursor;
-
- GSet( &grttalk );
- if (greeter)
- return;
- if (time( 0 ) < lastStart + 10) /* XXX should use some readiness indicator instead */
- SessionExit( EX_UNMANAGE_DPY );
- greeter = 1;
- ASPrintf( &name, "greeter for display %s", td->name );
- Debug( "starting %s\n", name );
-
- /* Hourglass cursor */
- if ((xcursor = XCreateFontCursor( dpy, XC_watch ))) {
- XDefineCursor( dpy, DefaultRootWindow( dpy ), xcursor );
- XFreeCursor( dpy, xcursor );
- }
- XFlush( dpy );
-
- /* Load system default Resources (if any) */
- LoadXloginResources();
-
- grttalk.pipe = &grtproc.pipe;
- env = systemEnv( (char *)0 );
- if (GOpen( &grtproc, (char **)0, "_greet", env, name, &td->gpipe ))
- SessionExit( EX_UNMANAGE_DPY );
- freeStrArr( env );
- if ((cmd = CtrlGreeterWait( TRUE ))) {
- if (cmd != -2)
- LogError( "Received unknown or unexpected command %d from greeter\n", cmd );
- CloseGreeter( TRUE );
- SessionExit( EX_UNMANAGE_DPY );
- }
- Debug( "%s ready\n", name );
- time( &lastStart );
-}
-
-int
-CloseGreeter( int force )
-{
- int ret;
-
- if (!greeter)
- return EX_NORMAL;
- greeter = 0;
- ret = GClose (&grtproc, 0, force);
- Debug( "greeter for %s stopped\n", td->name );
- if (WaitCode( ret ) > EX_NORMAL && WaitCode( ret ) <= EX_MAX) {
- Debug( "greeter-initiated session exit, code %d\n", WaitCode( ret ) );
- SessionExit( WaitCode( ret ) );
- }
- return ret;
-}
-
-void
-PrepErrorGreet()
-{
- if (!greeter) {
- OpenGreeter();
- GSendInt( G_ErrorGreet );
- GSendStr( curuser );
- }
-}
-
-static Jmp_buf idleTOJmp;
-
-/* ARGSUSED */
-static void
-IdleTOJmp( int n ATTR_UNUSED )
-{
- Longjmp( idleTOJmp, 1 );
-}
-
-
-static Jmp_buf abortSession;
-
-/* ARGSUSED */
-static void
-catchTerm( int n ATTR_UNUSED )
-{
- Signal( SIGTERM, SIG_IGN );
- Longjmp( abortSession, EX_AL_RESERVER_DPY );
-}
-
-/*
- * We need our own error handlers because we can't be sure what exit code Xlib
- * will use, and our Xlib does exit(1) which matches EX_REMANAGE_DPY, which
- * can cause a race condition leaving the display wedged. We need to use
- * EX_RESERVER_DPY for IO errors, to ensure that the manager waits for the
- * server to terminate. For other X errors, we should give up.
- */
-
-/*ARGSUSED*/
-static int
-IOErrorHandler( Display *dspl ATTR_UNUSED )
-{
- LogError( "Fatal X server IO error: %m\n" );
- /* The only X interaction during the session are pings, and those
- have an own IOErrorHandler -> not EX_AL_RESERVER_DPY */
- Longjmp( abortSession, EX_RESERVER_DPY );
- /*NOTREACHED*/
- return 0;
-}
-
-/*ARGSUSED*/
-static int
-ErrorHandler( Display *dspl ATTR_UNUSED, XErrorEvent *event )
-{
- LogError( "X error\n" );
- if (event->error_code == BadImplementation)
- Longjmp( abortSession, EX_UNMANAGE_DPY );
- return 0;
-}
-
-void
-ManageSession( struct display *d )
-{
- int ex, cmd;
- volatile int clientPid = 0;
- volatile Time_t tdiff = 0;
-#ifdef WITH_CONSOLE_KIT
- char *ck_session_cookie;
-#endif
-
-
- td = d;
- Debug( "ManageSession %s\n", d->name );
- if ((ex = Setjmp( abortSession ))) {
- CloseGreeter( TRUE );
- if (clientPid)
- AbortClient( clientPid );
- SessionExit( ex );
- /* NOTREACHED */
- }
- (void)XSetIOErrorHandler( IOErrorHandler );
- (void)XSetErrorHandler( ErrorHandler );
- (void)Signal( SIGTERM, catchTerm );
-
- (void)Signal( SIGHUP, SIG_IGN );
-
- if (Setjmp( grttalk.errjmp ))
- Longjmp( abortSession, EX_RESERVER_DPY ); /* EX_RETRY_ONCE */
-
-#ifdef XDMCP
- if (d->useChooser)
- DoChoose();
- /* NOTREACHED */
-#endif
-
- if (d->hstent->sdRec.how) {
- OpenGreeter();
- GSendInt( G_ConfShutdown );
- GSendInt( d->hstent->sdRec.how );
- GSendInt( d->hstent->sdRec.uid );
- GSendStr( d->hstent->sdRec.osname );
- if ((cmd = CtrlGreeterWait( TRUE )) != G_Ready) {
- LogError( "Received unknown command %d from greeter\n", cmd );
- CloseGreeter( TRUE );
- }
- goto regreet;
- }
-
- tdiff = time( 0 ) - td->hstent->lastExit - td->openDelay;
- if (AutoLogon( tdiff )) {
- if (!Verify( conv_auto, FALSE ))
- goto gcont;
- if (greeter)
- GSendInt( V_OK );
- } else {
- regreet:
- OpenGreeter();
- if (Setjmp( idleTOJmp )) {
- CloseGreeter( TRUE );
- SessionExit( EX_NORMAL );
- }
- Signal( SIGALRM, IdleTOJmp );
- alarm( td->idleTimeout );
-#ifdef XDMCP
- if (((d->displayType & d_location) == dLocal) &&
- d->loginMode >= LOGIN_DEFAULT_REMOTE)
- goto choose;
-#endif
- for (;;) {
- Debug( "ManageSession, greeting, tdiff = %d\n", tdiff );
- GSendInt( (*td->autoUser && td->autoDelay &&
- (tdiff > 0 || td->autoAgain)) ?
- G_GreetTimed : G_Greet );
- gcont:
- cmd = CtrlGreeterWait( TRUE );
-#ifdef XDMCP
- recmd:
- if (cmd == G_DChoose) {
- choose:
- cmd = DoChoose();
- goto recmd;
- }
- if (cmd == G_DGreet)
- continue;
-#endif
- alarm( 0 );
- if (cmd == G_Ready)
- break;
- if (cmd == -2)
- CloseGreeter( FALSE );
- else {
- LogError( "Received unknown command %d from greeter\n", cmd );
- CloseGreeter( TRUE );
- }
- goto regreet;
- }
- }
-
- if (CloseGreeter( FALSE ) != EX_NORMAL)
- goto regreet;
-
- DeleteXloginResources();
-
- if (td_setup)
- SetupDisplay( td_setup );
-
-#ifdef WITH_CONSOLE_KIT
- ck_session_cookie = open_ck_session (getpwnam(curuser), d);
- if (!(clientPid = StartClient(ck_session_cookie))) {
-#else
- if (!(clientPid = StartClient())) {
-#endif
- LogError( "Client start failed\n" );
- SessionExit( EX_NORMAL ); /* XXX maybe EX_REMANAGE_DPY? -- enable in dm.c! */
- }
- Debug( "client Started\n" );
-
- /*
- * Wait for session to end,
- */
- for (;;) {
- if (!Setjmp( pingTime )) {
- (void)Signal( SIGALRM, catchAlrm );
- (void)alarm( d->pingInterval * 60 ); /* may be 0 */
- (void)Wait4( clientPid );
- (void)alarm( 0 );
- break;
- } else {
- (void)alarm( 0 );
- if (!PingServer( d ))
- catchTerm( SIGTERM );
- }
- }
-
-#ifdef WITH_CONSOLE_KIT
- if (ck_session_cookie != NULL) {
- close_ck_session (ck_session_cookie);
- free (ck_session_cookie);
- }
-#endif
-
- /*
- * Sometimes the Xsession somehow manages to exit before
- * a server crash is noticed - so we sleep a bit and wait
- * for being killed.
- */
- if (!PingServer( d )) {
- Debug( "X server dead upon session exit.\n" );
- if ((d->displayType & d_location) == dLocal)
- sleep( 10 );
- SessionExit( EX_AL_RESERVER_DPY );
- }
- SessionExit( EX_NORMAL ); /* XXX maybe EX_REMANAGE_DPY? -- enable in dm.c! */
-}
-
-static int xResLoaded;
-
-void
-LoadXloginResources()
-{
- char **args;
- char **env;
-
- if (!xResLoaded && td->resources[0] && access( td->resources, 4 ) == 0) {
- env = systemEnv( (char *)0 );
- if ((args = parseArgs( (char **)0, td->xrdb )) &&
- (args = addStrArr( args, td->resources, -1 )))
- {
- Debug( "loading resource file: %s\n", td->resources );
- (void)runAndWait( args, env );
- freeStrArr( args );
- }
- freeStrArr( env );
- xResLoaded = TRUE;
- }
-}
-
-void
-SetupDisplay( const char *arg )
-{
- char **env;
-
- env = systemEnv( (char *)0 );
- (void)source( env, td->setup, arg );
- freeStrArr( env );
-}
-
-void
-DeleteXloginResources()
-{
- int i;
- Atom prop;
-
- if (!xResLoaded)
- return;
- xResLoaded = FALSE;
- prop = XInternAtom( dpy, "SCREEN_RESOURCES", True );
- XDeleteProperty( dpy, RootWindow( dpy, 0 ), XA_RESOURCE_MANAGER );
- if (prop)
- for (i = ScreenCount(dpy); --i >= 0; )
- XDeleteProperty( dpy, RootWindow( dpy, i ), prop );
- XSync( dpy, 0 );
-}
-
-
-int
-source( char **env, const char *file, const char *arg )
-{
- char **args;
- int ret;
-
- if (file && file[0]) {
- Debug( "source %s\n", file );
- if (!(args = parseArgs( (char **)0, file )))
- return waitCompose( 0,0,3 );
- if (arg && !(args = addStrArr( args, arg, -1 )))
- return waitCompose( 0,0,3 );
- ret = runAndWait( args, env );
- freeStrArr( args );
- return ret;
- }
- return 0;
-}
-
-char **
-inheritEnv( char **env, const char **what )
-{
- char *value;
-
- for (; *what; ++what)
- if ((value = getenv( *what )))
- env = setEnv( env, *what, value );
- return env;
-}
-
-char **
-baseEnv( const char *user )
-{
- char **env;
-
- env = 0;
-
-#ifdef _AIX
- /* we need the tags SYSENVIRON: and USRENVIRON: in the call to setpenv() */
- env = setEnv( env, "SYSENVIRON:", 0 );
-#endif
-
- if (user) {
- env = setEnv( env, "USER", user );
-#ifdef _AIX
- env = setEnv( env, "LOGIN", user );
-#endif
- env = setEnv( env, "LOGNAME", user );
- }
-
-#ifdef _AIX
- env = setEnv( env, "USRENVIRON:", 0 );
-#endif
-
- env = inheritEnv( env, (const char **)exportList );
-
- env = setEnv( env, "DISPLAY",
- memcmp( td->name, "localhost:", 10 ) ?
- td->name : td->name + 9 );
-
- if (td->ctrl.path)
- env = setEnv( env, "DM_CONTROL", fifoDir );
-
- return env;
-}
-
-char **
-systemEnv( const char *user )
-{
- char **env;
-
- env = baseEnv( user );
- if (td->authFile)
- env = setEnv( env, "XAUTHORITY", td->authFile );
- env = setEnv( env, "PATH", td->systemPath );
- env = setEnv( env, "SHELL", td->systemShell );
- return env;
-}