cdesktopenv/cde/programs/dtsession/SmGlobals.c

2649 lines
68 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $TOG: SmGlobals.c /main/37 1998/10/26 17:21:18 mgreess $ */
/*
* (c) Copyright 1995 Digital Equipment Corporation.
* (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
* (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
* (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
* (c) Copyright 1993, 1994, 1995 Novell, Inc.
* (c) Copyright 1995 FUJITSU LIMITED.
* (c) Copyright 1995 Hitachi.
*/
/*************************************<+>*************************************
*****************************************************************************
**
** File: SmGlobals.c
**
** Project: HP DT Session Manager (dtsession)
**
** Description:
** -----------
** This file contains all routines in charge of managing all global
** variables used by the session manager. These variables include
** mostly state and setting information.
**
**
**
*******************************************************************
** (c) Copyright Hewlett-Packard Company, 1990. All rights are
** reserved. Copying or other reproduction of this program
** except for archival purposes is prohibited without prior
** written consent of Hewlett-Packard Company.
********************************************************************
**
**
**
*****************************************************************************
*************************************<+>*************************************/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <X11/Intrinsic.h>
#include <X11/Xutil.h>
#include <X11/StringDefs.h>
#include <Xm/Xm.h>
#include <Dt/DtP.h>
#include <Dt/SessionP.h>
#include <Dt/Wsm.h>
#include <Dt/WsmP.h>
#include <Dt/UserMsg.h>
#include <Dt/HourGlass.h>
#include <Dt/SessionM.h>
#include <Dt/EnvControlP.h>
#include <Dt/Qualify.h>
#include <Dt/MsgLog.h>
#include "Sm.h"
#include "SmResource.h"
#include "SmError.h"
#include "SmUI.h"
#include "SmGlobals.h"
#include "SmLock.h"
#include "SmRestore.h"
#include "SmProtocol.h"
#include "SmXSMP.h"
/*
* Internal Variable Declaraions
*/
static char savedDir [MAXPATHLEN];
static char savedOldDir [MAXPATHLEN];
static char savedTmpDir [MAXPATHLEN];
/*
* Internal Function Declaraions
*/
static int SetSysDefaults( void ) ;
static int SetResSet( void ) ;
static void RemoveFiles( char *) ;
static void TrimErrorlog(void);
static void _SmWaitClientTimeoutDefault (
Widget widget,
int offset,
XrmValue *value);
static void _SmWaitWmTimeoutDefault (
Widget widget,
int offset,
XrmValue *value);
void SmCvtStringToContManagement (
XrmValue *args,
Cardinal numArgs,
XrmValue *fromVal,
XrmValue *toVal);
unsigned char *_DtNextToken (
unsigned char *pchIn,
int *pLen,
unsigned char **ppchNext);
Boolean _DtWmStringsAreEqual (
unsigned char *pch1,
unsigned char *pch2,
int len);
static Boolean InitializeSpecificSession (
char *session_name,
Display *disp,
unsigned int argc,
char **argv);
static void InitializeGenericSession (
Display *disp);
static void InitializePaths (
char *session_option,
Display *disp);
static Boolean SetAlternateSession (
char * session_dir,
char * alt_dir,
Boolean make_dir);
/*
* Global Data
*/
/*
* These are the global structures used throughout dtsession
* They are defined in Sm.h
*/
SessionResources smRes;
SaverResources smSaverRes;
SettingsSet smToSet;
SettingsCust smCust;
SessionSettings smSettings;
GeneralData smGD;
char SM_SCREEN_SAVER_LOC [MAXPATHLEN + 1];
/*
* Internal Global Data
*/
static char tmpDisplayName[MAXPATHLEN + 1];
int machineType = 0;
static XtResource sessionResources[]=
{
{SmNwmStartup, SmCwmStartup, XtRString, sizeof(String),
XtOffset(SessionResourcesPtr, wmStartup),
XtRImmediate, (XtPointer) NULL},
{SmNquerySettings, SmCquerySettings, XtRBoolean, sizeof(Boolean),
XtOffset(SessionResourcesPtr, querySettings),
XtRImmediate, (XtPointer) False},
{SmNkeys, SmCkeys, XtRString, sizeof(String),
XtOffset(SessionResourcesPtr, keyholders), XtRString, NULL},
{SmNalarmTime, SmCalarmTime, XtRInt, sizeof(int),
XtOffset(SessionResourcesPtr, alarmTime),
XtRImmediate, (XtPointer) 10},
{SmNmemThreshold, SmCmemThreshold, XtRInt, sizeof(int),
XtOffset(SessionResourcesPtr, memThreshold),
XtRImmediate, (XtPointer) 100},
{SmNsessionVersion, SmCsessionVersion, XtRString, sizeof(String),
XtOffset(SessionResourcesPtr, sessionVersion),
XtRImmediate, (XtPointer) NULL},
{SmNdisplayResolution, SmCdisplayResolution, XtRInt, sizeof(int),
XtOffset(SessionResourcesPtr, displayResolution),
XtRImmediate, (XtPointer) 0},
{SmNsessionLang, SmCsessionLang, XtRString, sizeof(String),
XtOffset(SessionResourcesPtr, sessionLang),
XtRImmediate, (XtPointer) ""},
{SmNcontManagement, SmCContManagement, SmRContManagement, sizeof(long),
XtOffset(SessionResourcesPtr, contManagement),
XtRImmediate, (XtPointer) (SM_CM_DEFAULT)},
{SmNwaitClientTimeout, SmCWaitClientTimeout, XtRInt, sizeof(int),
XtOffset(SessionResourcesPtr, waitClientTimeout),
XtRCallProc, (XtPointer)_SmWaitClientTimeoutDefault },
{SmNwaitWmTimeout, SmCWaitWmTimeout, XtRInt, sizeof(int),
XtOffset(SessionResourcesPtr, waitWmTimeout),
XtRCallProc, (XtPointer)_SmWaitWmTimeoutDefault },
{SmNuseMessaging, SmCUseMessaging, XtRBoolean, sizeof(Boolean),
XtOffset(SessionResourcesPtr, useBMS),
XtRImmediate, (XtPointer) True},
{SmNsaveFontPath, SmCsaveFontPath, XtRBoolean, sizeof(Boolean),
XtOffset(SessionResourcesPtr, saveFontPath),
XtRImmediate, (XtPointer) False},
{SmNsaveYourselfTimeout, SmCsaveYourselfTimeout, XtRInt, sizeof(int),
XtOffset(SessionResourcesPtr, saveYourselfTimeout),
XtRImmediate, (XtPointer) 5},
{SmNnumSessionsBackedup, SmCnumSessionsBackedup, XtRInt, sizeof(int),
XtOffset(SessionResourcesPtr, numSessionsBackedup),
XtRImmediate, (XtPointer) DEFAULT_NUM_SESSIONS_BACKED_UP},
{SmNignoreEnvironment, SmCignoreEnvironment, XtRString, sizeof(String),
XtOffset(SessionResourcesPtr, ignoreEnvironment),
XtRImmediate, (XtPointer) NULL},
#if defined(USE_XINERAMA) /* JET - Xinerama */
{SmNxineramaPreferredScreen, SmCxineramaPreferredScreen, XtRInt, sizeof(int),
XtOffset(SessionResourcesPtr, xineramaPreferredScreen),
XtRImmediate, (XtPointer) 0},
#endif
}
;
static XtResource saverResources[]=
{
{SmNcycleTimeout, SmCcycleTimeout, XtRInt, sizeof(int),
XtOffset(SaverResourcesPtr, cycleTimeout),
XtRImmediate, (XtPointer) -1},
{SmNlockTimeout, SmClockTimeout, XtRInt, sizeof(int),
XtOffset(SaverResourcesPtr, lockTimeout),
XtRImmediate, (XtPointer) -1},
{SmNsaverTimeout, SmCsaverTimeout, XtRInt, sizeof(int),
XtOffset(SaverResourcesPtr, saverTimeout),
XtRImmediate, (XtPointer) -1},
{SmNrandom, SmCrandom, XtRBoolean, sizeof(Boolean),
XtOffset(SaverResourcesPtr, random),
XtRImmediate, (XtPointer) False},
{SmNsaverList, SmCsaverList, XtRString, sizeof(String),
XtOffset(SaverResourcesPtr, saverList),
XtRImmediate, (XtPointer) ""},
}
;
/*
* Machine specific defaults.
*/
static struct
{
int machineType;
int clientTimeout;
int wmTimeout;
}
machineDefault[] =
{
{ 0, 20, 60}, /* Machine independent default */
#ifdef __hpux
{300, 10, 60}, /* HP s300 */
{400, 10, 60}, /* HP s400 */
{600, 5, 60}, /* HP s600 */
{700, 5, 60}, /* HP s700 */
{800, 5, 60}, /* HP s800 */
#endif /* __hpux */
};
#define MACHINEDEFAULTS (sizeof(machineDefault) / sizeof(machineDefault[0]))
/*************************************<->*************************************
*
* _SmWaitClientTimeoutDefault (widget, offset, value)
*
*
* Description:
* -----------
* This function generates a default value for the waitClientTimeout resource.
* We dynamically default to 10 seconds for s400/s300 and to
* 5 seconds for s700/s800.
*
* Inputs:
* ------
* widget = this is not used
*
* offset = this is the resource offset
*
* value = this is a pointer to a XrmValue in which to store the result
*
* Outputs:
* -------
* value = default resource value and size
*
*************************************<->***********************************/
static
void
_SmWaitClientTimeoutDefault (Widget widget, int offset, XrmValue *value)
{
int i;
for (i = 0; i < MACHINEDEFAULTS; i++)
{
if (machineDefault[i].machineType == machineType)
{
break;
}
}
if (i == MACHINEDEFAULTS)
{
i = 0;
}
value->addr = (char *)&machineDefault[i].clientTimeout;
value->size = sizeof (int);
} /* END OF FUNCTION _SmWaitClientTimeoutDefault */
/*************************************<->*************************************
*
* _SmWaitWmTimeoutDefault (widget, offset, value)
*
*
* Description:
* -----------
* This function generates a default value for the waitWmTimeout resource.
* We dynamically default to 60 seconds for s400/s300 and to
* 60 seconds for s700/s800. This could change if we get feedback indicating
* the need for a new default.
*
* Inputs:
* ------
* widget = this is not used
*
* offset = this is the resource offset
*
* value = this is a pointer to a XrmValue in which to store the result
*
* Outputs:
* -------
* value = default resource value and size
*
*************************************<->***********************************/
static
void
_SmWaitWmTimeoutDefault (Widget widget, int offset, XrmValue *value)
{
int i;
smGD.userSetWaitWmTimeout = False; /* if we are here, it is not user set */
for (i = 0; i < MACHINEDEFAULTS; i++)
{
if (machineDefault[i].machineType == machineType)
{
break;
}
}
if (i == MACHINEDEFAULTS)
{
i = 0;
}
value->addr = (char *)&machineDefault[i].wmTimeout;
value->size = sizeof (int);
} /* END OF FUNCTION _SmWaitWmTimeoutDefault */
/*************************************<->*************************************
*
* InitSMGlobals ()
*
*
* Description:
* -----------
* Sets SM global resources and global settings to a starting value.
*
*
* Inputs:
* ------
* buttonForm = form widget for button that allows cursor to get colors
* smRes(global) = structure that holds session resources.
* smToSet(global) = structure that holds "which settings to set and how" info
* smGD(global) = structure that holds general data info
*
* Outputs:
* -------
* smRes(global) = structure that holds session resources.
* smToSet(global) = structure that holds "which settings to set and how" info
* smGD(global) = structure that holds general data info
*
* Comments:
* --------
* Resources are set to an initial value by the resource manager. The
* rest are set in the routine.
*
*************************************<->***********************************/
void
InitSMGlobals( void )
{
int i;
PropDtSmWindowInfo property;
struct utsname nameRec;
char *firstSlash;
char *keyNum;
smGD.userSetWaitWmTimeout = True; /* assume it is */
#ifdef __hpux
if (uname(&nameRec) == 0)
{
keyNum = nameRec.machine;
if (firstSlash = strchr(keyNum, '/'))
{
keyNum = ++firstSlash;
if ( keyNum[0] == '3')
{
machineType = 300;
}
else if (keyNum[0] == '4')
{
machineType = 400;
}
else if (keyNum[0] == '6')
{
machineType = 600;
}
else if (keyNum[0] == '7')
{
machineType = 700;
}
else if (keyNum[0] == '8')
{
machineType = 800;
}
}
}
#endif /* __hpux */
/*
* Get application specific resource values
*/
XtAppAddConverter (smGD.appCon, XtRString, SmRContManagement,
(XtConverter)SmCvtStringToContManagement, NULL, 0);
XtGetApplicationResources(smGD.topLevelWid, (XtPointer) &smRes,
sessionResources,
XtNumber(sessionResources), NULL, 0);
if (smGD.lockOnTimeoutStatus == True)
{
/*
* Pull screen saver resources from Dtsession*extension.<name>.
*/
smGD.SmNextension = "extension";
smGD.SmCextension = "Extension";
smGD.extensionSpec = "extension.";
}
else
{
/*
* Pull screen saver resources from Dtsession*<name>.
*/
smGD.SmNextension = smGD.SmCextension = smGD.extensionSpec = "";
}
XtGetSubresources(smGD.topLevelWid, (XtPointer) &smSaverRes,
smGD.SmNextension, smGD.SmCextension,
saverResources,
XtNumber(saverResources), NULL, 0);
smGD.wmStartup = SmNewString(smRes.wmStartup);
smGD.keyholders = SmNewString(smRes.keyholders);
smGD.sessionLang = SmNewString(smRes.sessionLang);
smGD.saverList = SmNewString(smSaverRes.saverList);
/*
* Initialize general data used by apps not initialized by
* XtInitialize or DtInitialize
*/
smGD.topLevelWindow = XtWindow(smGD.topLevelWid);
smGD.numSavedScreens = (ScreenCount(smGD.display) > MAX_SCREENS_SAVED)
? MAX_SCREENS_SAVED : ScreenCount(smGD.display);
smGD.dtwmRunning = False;
smSettings.confirmMode = DtSM_VERBOSE_MODE;
if (smGD.sessionType == CURRENT_SESSION ||
smGD.sessionType == DEFAULT_SESSION)
smSettings.startState = DtSM_CURRENT_STATE;
else
smSettings.startState = DtSM_HOME_STATE;
smGD.homeSave = False;
smGD.saverListParse = NULL;
smGD.loggingOut = False;
/*
* Sanity check on timeouts for negative numbers
*/
if (smRes.waitClientTimeout < 0)
{
smRes.waitClientTimeout = -smRes.waitClientTimeout;
}
if (smRes.waitWmTimeout < 0)
{
smRes.waitWmTimeout = -smRes.waitWmTimeout;
}
if (smRes.saveYourselfTimeout < 0)
{
smRes.saveYourselfTimeout = -smRes.saveYourselfTimeout;
}
/*
* Now convert users view of seconds in to XtAppAddTimout's
* need for milliseconds.
*/
smRes.waitClientTimeout = 1000 * smRes.waitClientTimeout;
smRes.waitWmTimeout = 1000 * smRes.waitWmTimeout;
smRes.saveYourselfTimeout = 1000 * smRes.saveYourselfTimeout;
smGD.savedWaitWmTimeout = smRes.waitWmTimeout;
/*
* Initialize lock data
*/
smGD.screen = XDefaultScreen(smGD.display);
smGD.blackPixel = XBlackPixel(smGD.display, smGD.screen);
smGD.whitePixel = XWhitePixel(smGD.display, smGD.screen);
smDD.lockDialog = NULL;
smDD.lockCoverDialog = NULL;
for(i = 0;i < smGD.numSavedScreens;i++)
{
smDD.coverDialog[i] = NULL;
smDD.coverDrawing[i] = NULL;
}
smGD.lockedState = UNLOCKED;
/*
* Sanity check screen saver resource values.
*/
if (smRes.alarmTime < 0) smRes.alarmTime = 0;
#define SMBOUND(A) (A < 0 ? 0 : A)
smSaverRes.lockTimeout = SMBOUND(smSaverRes.lockTimeout) * 60;
smSaverRes.saverTimeout = SMBOUND(smSaverRes.saverTimeout) * 60;
smSaverRes.cycleTimeout = SMBOUND(smSaverRes.cycleTimeout) * 60;
CreateLockCursor();
smGD.waitCursor = _DtGetHourGlassCursor(smGD.display);
/*
* Initialize other global data related to dialogs
*/
smDD.confExit = NULL;
smDD.qExit = NULL;
smDD.compatExit = NULL;
smDD.deadWid = NULL;
smDD.saveSession = NULL; /* Error dialog for Save_Session */
if (!smDD.smHelpDialog)
/*
* Don't wipe it out if it is already created
*/
smDD.smHelpDialog = NULL;
/*
* Intern all the atoms needed for the WSM communication
*/
{
enum { XA_DT_SM_WINDOW_INFO, XA_DT_SM_WM_PROTOCOL,
XA_DT_SM_START_ACK_WINDOWS, XA_DT_SM_STOP_ACK_WINDOWS,
XA_DT_WM_WINDOW_ACK, XA_DT_WM_EXIT_SESSION,
XA_DT_WM_LOCK_DISPLAY, XA_DT_WM_READY, NUM_ATOMS };
static char *atom_names[] = {
_XA_DT_SM_WINDOW_INFO, _XA_DT_SM_WM_PROTOCOL,
_XA_DT_SM_START_ACK_WINDOWS, _XA_DT_SM_STOP_ACK_WINDOWS,
_XA_DT_WM_WINDOW_ACK, _XA_DT_WM_EXIT_SESSION,
_XA_DT_WM_LOCK_DISPLAY, _XA_DT_WM_READY };
Atom atoms[XtNumber(atom_names)];
XInternAtoms(smGD.display, atom_names, XtNumber(atom_names),
False, atoms);
XaVsmInfo = atoms[XA_DT_SM_WINDOW_INFO];
XaSmWmProtocol = atoms[XA_DT_SM_WM_PROTOCOL];
XaSmStartAckWindow = atoms[XA_DT_SM_START_ACK_WINDOWS];
XaSmStopAckWindow = atoms[XA_DT_SM_STOP_ACK_WINDOWS];
XaWmWindowAck = atoms[XA_DT_WM_WINDOW_ACK];
XaWmExitSession = atoms[XA_DT_WM_EXIT_SESSION];
XaWmLockDisplay = atoms[XA_DT_WM_LOCK_DISPLAY];
XaWmReady = atoms[XA_DT_WM_READY];
}
/*
* Set the session manager window property on the root window
*/
property.flags = 0;
property.smWindow = (unsigned long) smGD.topLevelWindow;
XChangeProperty (smGD.display, RootWindow(smGD.display, 0),
XaVsmInfo, XaVsmInfo,
32, PropModeReplace, (unsigned char *)&property,
PROP_DT_SM_WINDOW_INFO_ELEMENTS);
/*
* Set up the signal handler for forking and execing
*/
sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
}
/*************************************<->*************************************
*
* SetRestorePath ()
*
*
* Description:
* -----------
* Sets SM global resources and global settings to a starting value.
*
*
* Inputs:
* ------
* smGD.display = display structure for session manager. Used to construct
* a display directory
*
* Outputs:
* -------
* smGD.resourcePath(global) = Path where the resources to be restored are
* held
* smGD.settingPath(global) = Path where the settings to be restored are
* held
* smGD.clientPath(global) = Path where the clients to be restored are
* held
* smGD.savePath(global) = Path where all save files are to be saved
*
* Return:
* ------
* Display connection
*
* Comments:
* --------
* WARNING: This routine also determines whether dtsession is being started
* in compatibility mode. If so - no restore paths are set up and
* the routine is exited.
*
*************************************<->***********************************/
int
SetRestorePath(
unsigned int argc,
char *argv[] )
{
Display *tmpDisplay;
int i;
char *displayName = NULL;
char *session_option = NULL;
smGD.compatMode = False;
for(i = 0;i < argc;i++)
{
if(!strcmp(argv[i], "-display"))
{
displayName = argv[i + 1];
/*
* If -display is used but DISPLAY is not set,
* put DISPLAY into the environment
*/
if (getenv("DISPLAY") == 0)
{
snprintf(tmpDisplayName, MAXPATHLEN, "DISPLAY=%s", displayName);
putenv(tmpDisplayName);
}
}
if(!strcmp(argv[i], "-norestore"))
{
smGD.compatMode = True;
}
if(!strcmp(argv[i], "-session"))
{
i++;
if (i >= argc)
{
char *pch;
pch = strdup ((char *) GETMESSAGE (40, 15,
" No session name was provided for the -session command line option."));
if (pch)
{
DtMsgLogMessage (argv[0], DtMsgLogWarning, pch);
free (pch);
}
break;
}
session_option = argv[i];
}
}
/*
* If we are in compatibility mode - no restore paths are set
* up and we just return
*/
if(smGD.compatMode == True)
{
smGD.clientPath[0] = 0;
smGD.resourcePath[0] = 0;
smGD.settingPath[0] = 0;
smGD.sessionType = DEFAULT_SESSION;
smGD.restoreSession = NULL;
return(0);
}
tmpDisplay = XOpenDisplay(displayName);
if(tmpDisplay == NULL)
{
PrintError(DtError, GETMESSAGE(4, 1, "Invalid display name - exiting."));
SM_EXIT(-1);
}
if (session_option)
{
if (!InitializeSpecificSession (session_option, tmpDisplay, argc, argv))
InitializeGenericSession (tmpDisplay);
}
else
InitializeGenericSession (tmpDisplay);
/*
* Need to know if the session is for a specific display
*/
smGD.displaySpecific = True;
if (session_option = strrchr (smGD.savePath, '/'))
{
session_option++;
if (!strcmp (session_option, DtSM_SESSION_DIRECTORY))
smGD.displaySpecific = False;
}
TrimErrorlog();
XCloseDisplay(tmpDisplay);
/*
** User's session startup script:
** $HOME/.dt/sessions/sessionetc
*/
strcpy(smGD.etcPath, smGD.savePath);
strcat(smGD.etcPath, "/");
strcat(smGD.etcPath, smEtcFile);
/*
** User's session shutdown script:
** $HOME/.dt/sessions/sessionexit
*/
strcpy(smGD.exitPath, smGD.savePath);
strcat(smGD.exitPath, "/");
strcat(smGD.exitPath, smExitFile);
return(0);
}
void
FixPath
(
char * the1stPath
)
{
char * tempPath;
char * pathList = (char *)XtMalloc(strlen(SM_SYSTEM_PATH) +
strlen(":" CDE_INSTALLATION_TOP "/config") + 1);
strcpy(pathList,SM_SYSTEM_PATH);
strcat(pathList,":" CDE_INSTALLATION_TOP "/config");
tempPath = _DtQualifyWithFirst(the1stPath,pathList);
if (tempPath != NULL) {
strcpy(the1stPath,tempPath);
free(tempPath);
}
XtFree(pathList);
}
/*************************************<->*************************************
*
* SetSysDefaults ()
*
*
* Description:
* -----------
* Sets the path to restore the system default files. A convenience routine
*
*
* Inputs:
* ------
* smGD.savePath = path that files are to be saved in (set up in
* SetRestorePaths)
*
* Outputs:
* -------
* smGD.resourcePath(global) = Path where the resources to be saved are
* to be saved.
* smGD.settingPath(global) = Path where the settings to be saved are
* to be saved.
* smGD.clientPath(global) = Path where the clients to be saved are
* to be saved.
*
* Comments:
* --------
*
*************************************<->***********************************/
static int
SetSysDefaults( void )
{
int status;
struct stat buf;
String tmpString;
char *langSpec;
char *tempPath;
/*
* No files exist for restoration - use the
* system defaults
*/
strcpy(smGD.resourcePath, "");
strcpy(smGD.clientPath, "");
smGD.settingPath[0] = 0;
smGD.sessionType = DEFAULT_SESSION;
smGD.restoreSession = (char *) SM_SYSTEM_DIRECTORY;
langSpec = getenv("LANG");
if ((langSpec != NULL) && (*langSpec != 0))
{
strcat(smGD.clientPath, "/");
strncat(smGD.clientPath, langSpec, MAXPATHLEN-2);
smGD.clientPath[MAXPATHLEN-1] = 0;
}
strcat(smGD.clientPath, "/");
strcat(smGD.clientPath, SM_SYSTEM_CLIENT_FILE);
FixPath(smGD.clientPath);
/*
* If the system files don't exist - we're in
* trouble - First try LANG location then default
*/
status = stat(smGD.clientPath, &buf);
if(status == -1)
{
if((langSpec == NULL) || (*langSpec == 0))
{
PrintErrnoError(DtError, GETMESSAGE(4, 2,
"No defaults files exist. "
"No applications will be restarted."));
smGD.clientPath[0] = 0;
smGD.resourcePath[0] = 0;
}
else
{
strcpy(smGD.clientPath, "/C/");
strcat(smGD.clientPath, SM_SYSTEM_CLIENT_FILE);
FixPath(smGD.clientPath);
status = stat(smGD.clientPath, &buf);
if(status == -1)
{
PrintErrnoError(DtError, GETMESSAGE(4, 3,
"No defaults files exist. "
"No applications will be restarted."));
smGD.clientPath[0] = 0;
smGD.resourcePath[0] = 0;
}
}
}
return(0);
}
/*************************************<->*************************************
*
* SetResSet ()
*
*
* Description:
* -----------
* Sets the path to restore the settings and resource files.
* A convenience routine
*
*
* Inputs:
* ------
* smGD.savePath = path that files are to be saved in (set up in
* SetRestorePaths)
*
* Outputs:
* -------
* smGD.resourcePath(global) = Path where the resources to be saved are
* to be saved.
* smGD.settingPath(global) = Path where the settings to be saved are
* to be saved.
* smGD.clientPath(global) = Path where the clients to be saved are
* to be saved.
*
* Comments:
* --------
*
*************************************<->***********************************/
static int
SetResSet( void )
{
int status;
struct stat buf;
/*
* If resource or settings file does not exist - just null out
* the path so these things will not get restored
*/
status = stat(smGD.resourcePath, &buf);
if(status == -1)
{
smGD.resourcePath[0] = 0;
}
status = stat(smGD.settingPath, &buf);
if(status == -1)
{
smGD.settingPath[0] = 0;
}
return(0);
}
/*************************************<->*************************************
*
* UndoSetSavePath () - Undoes the directory manipulations done by
* SetSavePath. This function is only called if a shutdown/save
* is canceled.
*
*************************************<->***********************************/
void
UndoSetSavePath (void)
{
char * buf;
if (strcmp ("", savedDir)) {
/*
* Remove the directory where the save occurred, e.g.:
*
* ~/.dt/<session_dir>/current
* ~/.dt/<session_dir>/home
*/
buf = XtMalloc (strlen (savedDir) + 9);
sprintf (buf, "rm -rf %s", savedDir);
SystemCmd (buf);
XtFree (buf);
if (strcmp ("", savedOldDir)) {
MoveDirectory (savedOldDir, savedDir, False);
if (strcmp ("", savedTmpDir)) {
MoveDirectory (savedTmpDir, savedOldDir, False);
}
}
}
}
/*************************************<->*************************************
*
* SetSavePath (saveToHome, mode)
*
*
* Description:
* -----------
* Sets up paths for files that need to be saved. Also removes any files
* that shouldn't be there after the save.
*
*
* Inputs:
* ------
* smGD.display = display structure for session manager. Used to construct
* a display directory
* saveToHome = whether this is a save to home session or not
* mode = whether we are resetting or restarting
*
* Outputs:
* -------
* smGD.resourcePath(global) = Path where the resources to be saved are
* to be saved.
* smGD.settingPath(global) = Path where the settings to be saved are
* to be saved.
* smGD.clientPath(global) = Path where the clients to be saved are
* to be saved.
*
* Comments:
* --------
*
*************************************<->***********************************/
int
SetSavePath(
Boolean saveToHome,
int mode )
{
struct stat buf;
int status;
/*
* These directory paths are needed in UndoSetSavePaths
* if a shutdown/save is canceled.
*/
strcpy (savedDir, "");
strcpy (savedOldDir, "");
strcpy (savedTmpDir, "");
/*
* Make sure the user hasn't done something like delete the .dt
* directories during the session. If so - recreate them
*/
SM_FREE(smGD.savePath);
smGD.savePath = _DtCreateDtDirs(smGD.display);
if(smGD.savePath == NULL)
{
PrintErrnoError(DtError, smNLS.cantCreateDirsString);
smGD.clientPath[0] = 0;
smGD.settingPath[0] = 0;
smGD.resourcePath[0] = 0;
return(-1);
}
/*
* Path for a save defaults to save the current session.
* Otherwise just remove the directories
*/
strcpy(smGD.clientPath, smGD.savePath);
strcpy(smGD.settingPath, smGD.savePath);
strcpy(smGD.resourcePath, smGD.savePath);
strcat(smGD.clientPath, "/");
strcat(smGD.settingPath, "/");
strcat(smGD.resourcePath, "/");
if(saveToHome == False)
{
strcat(smGD.clientPath, SM_CURRENT_DIRECTORY);
strcat(smGD.resourcePath, SM_CURRENT_DIRECTORY);
strcat(smGD.settingPath, SM_CURRENT_DIRECTORY);
smGD.restoreSession = SM_CURRENT_DIRECTORY;
}
else
{
strcat(smGD.clientPath, SM_HOME_DIRECTORY);
strcat(smGD.resourcePath, SM_HOME_DIRECTORY);
strcat(smGD.settingPath, SM_HOME_DIRECTORY);
smGD.restoreSession = SM_HOME_DIRECTORY;
}
if ((mode == DtSM_HOME_STATE) && (saveToHome == False) &&
(smSettings.startState == DtSM_HOME_STATE))
{
/*
* The only time this should should be true is if the
* current session is a Home session and the session
* is being exited. The idea is that if a "current"
* directory exits, it must be moved because when the
* user next logs in, a Home session should be started
* (if a session is not selected at the login screen)
* and the Session Manager decides whether or not it
* starts a Home or Current session based on if a
* "current" directory exists. If a "current" directory
* exists, a Current session will be started.
*/
status = stat(smGD.clientPath, &buf);
if(status != -1)
{
/*
* The "current" directory exists and must be moved to its
* ".old" version. But first, if the ".old" version exists,
* it must be moved to a temporary directory. This temporary
* directory will eventually be pruned - when a user next
* runs a Current session and saves the session.
*/
strcpy (savedDir, smGD.clientPath);
snprintf(smGD.etcPath, sizeof(smGD.etcPath), "%s.%s", smGD.clientPath, SM_OLD_EXTENSION);
status = stat(smGD.etcPath, &buf);
if(status == 0)
{
char * tmpName;
int len, tfd;
strcpy(savedOldDir, smGD.etcPath);
len = strlen(smGD.savePath) + strlen(smGD.restoreSession)
+ strlen("XXXXXX") + 3;
tmpName = (char *) XtCalloc(1, len);
sprintf(tmpName, "%s/%s.XXXXXX", smGD.savePath,
smGD.restoreSession);
if ((tfd = mkstemp(tmpName)) == -1)
{
PrintErrnoError(DtError, smNLS.cantCreateDirsString);
}
else
{
close(tfd);
unlink(tmpName);
MoveDirectory(smGD.etcPath, tmpName, False);
strncpy(savedTmpDir, tmpName, len - 1);
}
XtFree((char *) tmpName);
}
MoveDirectory(smGD.clientPath, smGD.etcPath, False);
}
smGD.clientPath[0] = 0;
smGD.settingPath[0] = 0;
smGD.resourcePath[0] = 0;
}
else
{
strcpy (savedDir, smGD.clientPath);
/*
* If the desired directory doesn't exist, create it.
*/
status = stat(smGD.clientPath, &buf);
if(status == -1)
{
status = mkdir(smGD.clientPath, 0000);
if(status == -1)
{
PrintErrnoError(DtError, smNLS.cantCreateDirsString);
smGD.clientPath[0] = 0;
smGD.settingPath[0] = 0;
smGD.resourcePath[0] = 0;
return(-1);
}
if(-1 == chmod(smGD.clientPath, 0755))
{
fprintf(stderr, "%s chmod error %s\n", smGD.clientPath, strerror(errno));
}
}
else
{
/*
* The desired directory already exists so it must
* be archived by moving it to its ".old" version. But
* first, if its ".old" version already exists, it must
* be moved to a temporary directory that will be removed
* when the session directories are pruned - after the
* save is complete.
*/
char * tmpName;
snprintf(smGD.etcPath, sizeof(smGD.etcPath), "%s.%s", smGD.clientPath, SM_OLD_EXTENSION);
status = stat(smGD.etcPath, &buf);
if(status == 0)
{
int len, tfd;
len = strlen(smGD.savePath) + strlen(smGD.restoreSession)
+ strlen("XXXXXX") + 3;
tmpName = (char *) XtCalloc(1, len);
snprintf(tmpName, len, "%s/%s.XXXXXX", smGD.savePath,
smGD.restoreSession);
strcpy (savedOldDir, smGD.etcPath);
if ((tfd = mkstemp(tmpName)) == -1)
{
PrintErrnoError(DtError, smNLS.cantCreateDirsString);
}
else
{
close(tfd);
unlink(tmpName);
MoveDirectory (smGD.etcPath, tmpName, False);
strcpy (savedTmpDir, tmpName);
}
XtFree((char *) tmpName);
}
MoveDirectory(smGD.clientPath, smGD.etcPath, False);
/*
* Now re-make the directory
*/
status = mkdir(smGD.clientPath, 0000);
if(status == -1)
{
PrintErrnoError(DtError, smNLS.cantCreateDirsString);
smGD.clientPath[0] = 0;
smGD.settingPath[0] = 0;
smGD.resourcePath[0] = 0;
return(-1);
}
status = chmod(smGD.clientPath, 0755);
if(status == -1)
{
PrintErrnoError(DtError, smNLS.cantCreateDirsString);
smGD.clientPath[0] = 0;
smGD.settingPath[0] = 0;
smGD.resourcePath[0] = 0;
return(-1);
}
}
strcat(smGD.clientPath, "/");
strcat(smGD.clientPath, SM_CLIENT_FILE2);
strcat(smGD.settingPath, "/");
strcat(smGD.settingPath, SM_SETTING_FILE);
strcat(smGD.resourcePath, "/");
strcat(smGD.resourcePath, SM_RESOURCE_FILE);
}
return(0);
}
/*************************************<->*************************************
*
* SetFontSavePath (saveToHome, mode)
*
*
* Description:
* -----------
* Sets up the save path for the auxillary directory.
*
*
* Inputs:
* ------
*
* Outputs:
* -------
*
* Comments:
* --------
*
*************************************<->***********************************/
int
SetFontSavePath(char *langPtr)
{
struct stat buf;
int status;
char *sessionSaved;
/*
* Set up the session font directory and see if it exists
*/
if(smGD.sessionType == CURRENT_SESSION)
{
sessionSaved = SM_CURRENT_FONT_DIRECTORY;
}
else
{
sessionSaved = SM_HOME_FONT_DIRECTORY;
}
snprintf(smGD.fontPath, MAXPATHLEN, "%s/%s", smGD.savePath, sessionSaved);
status = stat(smGD.fontPath, &buf);
if(status == -1)
{
status = mkdir(smGD.fontPath, 0000);
if(status == -1)
{
PrintErrnoError(DtError, smNLS.cantCreateDirsString);
smGD.fontPath[0] = 0;
return(-1);
}
if(-1 == chmod(smGD.fontPath, 0755))
{
fprintf(stderr, "%s chmod error %s\n", smGD.fontPath, strerror(errno));
}
}
/*
* Now add the lang subdirectory and see if it exists
*/
strncat(smGD.fontPath, "/", MAXPATHLEN);
strncat(smGD.fontPath, langPtr, MAXPATHLEN);
status = stat(smGD.fontPath, &buf);
if(status == -1)
{
status = mkdir(smGD.fontPath, 0000);
if(status == -1)
{
PrintErrnoError(DtError, smNLS.cantCreateDirsString);
smGD.fontPath[0] = 0;
return(-1);
}
status = chmod(smGD.fontPath, 0755);
if(status == -1)
{
PrintErrnoError(DtError, smNLS.cantCreateDirsString);
smGD.fontPath[0] = 0;
return(-1);
}
}
return(0);
}
/*************************************<->*************************************
*
* RemoveFiles()
*
*
* Description:
* -----------
* Remove the files that need to be removed
*
*
* Inputs:
* ------
*
* Outputs:
* -------
*
*
* Comments:
* --------
*
*************************************<->***********************************/
static void
RemoveFiles(
char *path )
{
pid_t clientFork;
int execStatus, childStatus, i, statLoc;
String tmpString;
/*
* Fork and exec the client process
*/
sigaction(SIGCHLD, &smGD.defvec, (struct sigaction *) NULL);
clientFork = vfork();
/*
* If the fork fails - Send out an error and return
*/
if(clientFork < 0)
{
PrintErrnoError(DtError, smNLS.cantForkClientString);
return;
}
/*
* Fork succeeded - now do the exec
*/
if(clientFork == 0)
{
SetSIGPIPEToDefault ();
/*
* Set the gid of the process back from bin
*/
#ifndef __hpux
#ifndef SVR4
setregid(smGD.runningGID, smGD.runningGID);
#else
setgid(smGD.runningGID);
setegid(smGD.runningGID);
#endif
#endif
_DtEnvControl(DT_ENV_RESTORE_PRE_DT);
#if defined(CSRG_BASED)
setsid();
#else
(void) setpgrp();
#endif /* CSRG_BASED */
execStatus = execlp("rm","rm", "-rf", path, (char *) 0);
if(execStatus != 0)
{
tmpString = ((char *)GETMESSAGE(4, 4, "Unable to remove session directory. Make sure write permissions exist on $HOME/.dt directory. Invalid session files will not be removed.")) ;
PrintErrnoError(DtError, tmpString);
SM_FREE(tmpString);
SM_EXIT(-1);
}
}
while(wait(&statLoc) != clientFork);
sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
}
/*************************************<->*************************************
*
* MoveDirectory()
*
* Description:
* -----------
* Move the directory specified by pathFrom - to the directory specified
* by pathTo.
*
* Inputs:
* ------
* pathFrom = the directory to move from
* pathTo = the directory to move to
* removeDestDir = if True, directory pathTo is removed before the
* move occurs
*
* Outputs:
* -------
*
* Comments:
* --------
*
*************************************<->***********************************/
void
MoveDirectory(
char *pathFrom,
char *pathTo,
Boolean removeDestDir)
{
struct stat buf;
pid_t clientFork;
int status, execStatus, childStatus, i, statLoc;
String tmpString;
/*
* If the pathTo directory exists - remove it
*/
if (removeDestDir)
{
status = stat(pathTo, &buf);
if(status != -1)
{
RemoveFiles(pathTo);
}
}
/*
* Fork and exec the client process
*/
sigaction(SIGCHLD, &smGD.defvec, (struct sigaction *) NULL);
clientFork = vfork();
/*
* If the fork fails - Send out an error and return
*/
if(clientFork < 0)
{
PrintErrnoError(DtError, smNLS.cantForkClientString);
return;
}
/*
* Fork succeeded - now do the exec
*/
if(clientFork == 0)
{
SetSIGPIPEToDefault ();
/*
* Set the gid of the process back from bin
*/
#ifndef __hpux
#ifndef SVR4
setregid(smGD.runningGID, smGD.runningGID);
#else
setgid(smGD.runningGID);
setegid(smGD.runningGID);
#endif
#endif
_DtEnvControl(DT_ENV_RESTORE_PRE_DT);
#if defined(CSRG_BASED)
setsid();
#else
(void) setpgrp();
#endif /* CSRG_BASED */
execStatus = execlp("mv","mv", pathFrom, pathTo, (char *) 0);
if(execStatus != 0)
{
tmpString = ((char *)GETMESSAGE(4, 4, "Unable to remove session directory. Make sure write permissions exist on $HOME/.dt directory. Invalid session files will not be removed.")) ;
PrintErrnoError(DtError, tmpString);
SM_FREE(tmpString);
SM_EXIT(-1);
}
}
while(wait(&statLoc) != clientFork);
sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
}
/*************************************<->*************************************
*
* InitNlsStrings()
*
*
* Description:
* -----------
* Initialize the NLS strings used in dtsession
*
*
* Inputs:
* ------
*
* Outputs:
* -------
*
*
* Comments:
* --------
*
*************************************<->***********************************/
void
InitNlsStrings( void )
{
char *tmpString;
/*
* Malloc failure error message - THIS MESSAGE MUST BE INITIALIZED FIRST
*/
smNLS.cantMallocErrorString = strdup (((char *)GETMESSAGE(4, 5, "Unable to malloc memory for operation.")));
/*
* Error message when dtsession cant lock the display
*/
smNLS.cantLockErrorString = strdup (((char *)GETMESSAGE(4, 6, "Unable to lock display. Another application may have the pointer or keyboard grabbed.")));
/*
* Error message when dtsession cant open files for reading or writing
*/
smNLS.cantOpenFileString = strdup (((char *)GETMESSAGE(4, 7, "Unable to open session file. No clients will be restarted.")));
/*
* Error message when dtsession cant fork client process
*/
smNLS.cantForkClientString = strdup (((char *)GETMESSAGE(4, 8, "Unable to fork client process.")));
/*
* Error message when dtsession cant create dt directories
*/
smNLS.cantCreateDirsString = strdup (((char *)GETMESSAGE(4, 9, "Unable to create DT directories. Check permissions on home directory.")));
/*
* Error message when trying to lock display on trusted system
*/
smNLS.trustedSystemErrorString = strdup (((char *)GETMESSAGE(4, 10, "Unable to lock display due to security restrictions")));
}
/*************************************<->*************************************
*
* WaitChildDeath()
*
*
* Description:
* -----------
* When a SIGCHLD signal comes in, wait for all child processes to die.
*
*
* Inputs:
* ------
*
* Outputs:
* -------
*
*
* Comments:
* --------
*
*************************************<->***********************************/
void
WaitChildDeath( int i )
{
int stat_loc;
pid_t pid;
/*
* Wait on any children that have died since the last SIGCHLD we
* received. Any child process death that occurs while we are
* in WaitChildDeath() will not result in a SIGCHLD. Any
* child proceses that die after our last call to waitpid() will
* remain zombiefied until the next invocation of WaitChildDeath().
*/
while ((pid = waitpid(-1, &stat_loc, WNOHANG)) > 0)
;
sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
}
/*************************************<->*************************************
*
* TrimErrorlog()
*
*
* Description:
* -----------
* Trim the errorlog file using the following algorithm:
* if(errorlog.old exists and is not empty) move it to errorlog.oldest
* if(errorlog exists and is not empty) move it to errorlog.old
*
*
* Inputs:
* ------
*
* Outputs:
* -------
*
*
* Comments:
* --------
*
*************************************<->***********************************/
static void
TrimErrorlog( void )
{
char *savePath, /* common path element for all pathnames */
*checkPath1,
*checkPath2;
struct stat buf;
int len, status;
char *home;
/*
* Allocate the strings needed
*/
savePath = (char *) SM_MALLOC(MAXPATHLEN + 1);
checkPath1 = (char *) SM_MALLOC(MAXPATHLEN + 1);
checkPath2 = (char *) SM_MALLOC(MAXPATHLEN + 1);
if ((home=getenv("HOME")) == NULL)
home="";
len = strlen(home) + strlen(DtPERSONAL_CONFIG_DIRECTORY) + 2;
if (len > MAXPATHLEN) savePath = SM_REALLOC(savePath, len);
snprintf(savePath, len, "%s/%s", home, DtPERSONAL_CONFIG_DIRECTORY);
/*
* If errorlog.old exists and it is not empty, delete
* errorlog.older and then move errolog.old to
* errorlog.older
*/
if (len + strlen(DtOLDER_ERRORLOG_FILE) > MAXPATHLEN)
checkPath1 = SM_REALLOC(savePath, len + strlen(DtOLDER_ERRORLOG_FILE));
sprintf(checkPath1, "%s/%s", savePath, DtOLDER_ERRORLOG_FILE);
if (len + strlen(DtOLD_ERRORLOG_FILE) > MAXPATHLEN)
checkPath2 = SM_REALLOC(savePath, len + strlen(DtOLD_ERRORLOG_FILE));
sprintf(checkPath2, "%s/%s", savePath, DtOLD_ERRORLOG_FILE);
status = stat(checkPath2, &buf);
if((status != -1) && (buf.st_size > 0))
{
(void) unlink(checkPath1);
(void) link(checkPath2, checkPath1);
(void) unlink(checkPath2);
}
/*
* If errorlog exists and it is not empty, move it to
* errorlog.old
*/
if (len + strlen(DtERRORLOG_FILE) > MAXPATHLEN)
checkPath1 = SM_REALLOC(savePath, len + strlen(DtERRORLOG_FILE));
snprintf(checkPath1, len + strlen(DtERRORLOG_FILE), "%s/%s", savePath, DtERRORLOG_FILE);
status = stat(checkPath1, &buf);
if((status != -1) && (buf.st_size > 0))
{
(void) link(checkPath1, checkPath2);
(void) unlink(checkPath1);
}
SM_FREE((char *) savePath);
SM_FREE((char *) checkPath1);
SM_FREE((char *) checkPath2);
return;
}
/*************************************<->*************************************
*
* SetSystemReady()
*
*
* Description:
* -----------
* Do everything that needs to be done to get the system back into a
* READY state. This includes checking to be sure that the BMS did not
* die while we were in process
*
*
* Inputs:
* ------
*
* Outputs:
* -------
*
*
* Comments:
* --------
*
*************************************<->***********************************/
void
SetSystemReady( void )
{
smGD.smState = READY;
if(smGD.bmsDead == True)
{
WarnMsgFailure();
}
return;
}
/*************************************<->*************************************
*
* SmCvtStringToContManagement (args, numArgs, fromVal, toVal)
*
*
* Description:
* -----------
* This function converts a string to a value for the
* contention management flag set.
*
*
* Inputs:
* ------
* args = additional XrmValue arguments to the converter - NULL here
*
* numArgs = number of XrmValue arguments - 0 here
*
* fromVal = resource value to convert
*
*
* Outputs:
* -------
* toVal = descriptor to use to return converted value
*
*************************************<->***********************************/
void SmCvtStringToContManagement (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
{
unsigned char *pch = (unsigned char *) (fromVal->addr);
unsigned char *pchNext;
int len;
static long cval;
Boolean fHit = False;
Boolean fAddNext = True;
/*
* Names of contention management options
*/
#define CM_ALL_STR (unsigned char *)"all"
#define CM_SYSTEM_STR (unsigned char *)"system"
#define CM_HANDSHAKE_STR (unsigned char *)"handshake"
#define CM_NONE_STR (unsigned char *)"none"
/*
* Check first token. If '-' we subtract from all options.
* Otherwise, we start with no contention management and add things in.
*/
if (*pch &&
(_DtNextToken (pch, &len, &pchNext)) &&
(*pch == '-'))
{
cval = SM_CM_ALL;
fHit = True;
}
else
{
cval = SM_CM_NONE;
}
while (*pch && _DtNextToken (pch, &len, &pchNext))
{
/*
* Strip off "sign" if prepended to another token, and process
* that token the next time through.
*/
if (*pch == '+')
{
if (len != 1)
{
pchNext = pch + 1;
}
fAddNext = TRUE;
}
else if (*pch == '-')
{
if (len != 1)
{
pchNext = pch + 1;
}
fAddNext = FALSE;
}
if ((*pch == 'A') || (*pch == 'a'))
{
if (_DtWmStringsAreEqual (pch, CM_ALL_STR, len))
{
cval = fAddNext ? (cval | SM_CM_ALL) :
(cval & ~SM_CM_ALL);
fHit = True;
}
}
else if ((*pch == 'S') || (*pch == 's'))
{
if (_DtWmStringsAreEqual (pch, CM_SYSTEM_STR, len))
{
cval = fAddNext ? (cval | SM_CM_SYSTEM) :
(cval & ~SM_CM_SYSTEM);
fHit = True;
}
}
else if ((*pch == 'H') || (*pch == 'h'))
{
if (_DtWmStringsAreEqual (pch, CM_HANDSHAKE_STR, len))
{
cval = fAddNext ? (cval | SM_CM_HANDSHAKE) :
(cval & ~SM_CM_HANDSHAKE);
fHit = True;
}
}
else if ((*pch == 'N') || (*pch == 'n'))
{
if (_DtWmStringsAreEqual (pch, CM_NONE_STR, len))
{
/* don't bother adding or subtracting nothing */
fHit = True;
}
}
pch = pchNext;
}
/*
* If we didn't match anything then set to default.
*/
if (!fHit)
{
cval = SM_CM_DEFAULT;
}
(*toVal).size = sizeof (long);
(*toVal).addr = (caddr_t) &cval;
} /* END OF FUNCTION SmCvtStringToContManagement */
/*************************************<->*************************************
*
* _DtNextToken (pchIn, pLen, ppchNext)
*
*
* Description:
* -----------
* XXDescription ...
*
*
* Inputs:
* ------
* pchIn = pointer to start of next token
*
*
* Outputs:
* -------
* pLen = pointer to integer containing number of characters in next token
* ppchNext = address of pointer to following token
*
* Return = next token or NULL
*
*
* Comments:
* --------
* None.
*
*************************************<->***********************************/
unsigned char *_DtNextToken (unsigned char *pchIn, int *pLen,
unsigned char **ppchNext)
{
unsigned char *pchR = pchIn;
register int i;
#ifdef MULTIBYTE
register int chlen;
for (i = 0; ((chlen = mblen ((char *)pchIn, MB_CUR_MAX)) > 0); i++)
/* find end of word: requires singlebyte whitespace terminator */
{
if ((chlen == 1) && isspace (*pchIn))
{
break;
}
pchIn += chlen;
}
#else
for (i = 0; *pchIn && !isspace (*pchIn); i++, pchIn++)
/* find end of word */
{
}
#endif
/* skip to next word */
ScanWhitespace (&pchIn);
*ppchNext = pchIn;
*pLen = i;
if (i)
{
return(pchR);
}
else
{
return(NULL);
}
} /* END OF FUNCTION _DtNextToken */
/*************************************<->*************************************
*
* _DtWmStringsAreEqual (pch1, pch2, len)
*
*
* Description:
* -----------
* XXDescription ...
*
*
* Inputs:
* ------
* pch1 =
* pch2 =
* len =
*
*
* Outputs:
* -------
* Return = (Boolean) True iff strings match (case insensitive)
*
*
* Comments:
* --------
* None.
*
*************************************<->***********************************/
Boolean _DtWmStringsAreEqual (unsigned char *pch1, unsigned char *pch2, int len)
{
#ifdef MULTIBYTE
int chlen1;
int chlen2;
wchar_t wch1;
wchar_t wch2;
while (len &&
((chlen1 = mbtowc (&wch1, (char *) pch1, 2)) > 0) &&
((chlen2 = mbtowc (&wch2, (char *) pch2, 2)) == chlen1) )
{
if (chlen1 == 1)
/* singlebyte characters -- make case insensitive */
{
if ((isupper (*pch1) ? tolower(*pch1) : *pch1) !=
(isupper (*pch2) ? tolower(*pch2) : *pch2))
{
break;
}
}
else
/* multibyte characters */
{
if (wch1 != wch2)
{
break;
}
}
pch1 += chlen1;
pch2 += chlen2;
len--;
}
#else
while (len && *pch1 && *pch2 &&
((isupper (*pch1) ? tolower(*pch1) : *pch1) ==
(isupper (*pch2) ? tolower(*pch2) : *pch2)))
{
*pch1++;
*pch2++;
len--;
}
#endif
return (len == 0);
} /* END OF _DtWmStringsAreEqual */
/*************************************<->*************************************
*
* InitializeGenericSession - set the smGD paths using the CDE 1.0
* session starting algorithm.
*
* Description:
* -----------
* Initializes several variables in smGD
*
* Inputs:
* ------
* tmpDisplay
*
* Outputs:
* -------
* Return = void
*
* Comments:
* --------
*
*************************************<->***********************************/
static void
InitializeGenericSession (
Display *tmpDisplay)
{
struct stat buf;
int session_needed = 1;
int status;
char tmpPath[MAXPATHLEN];
smGD.savePath = _DtCreateDtDirs(tmpDisplay);
if (session_needed)
{
strcpy(smGD.clientPath, smGD.savePath);
strcat(smGD.clientPath, "/");
strcat(smGD.clientPath, SM_CURRENT_DIRECTORY);
strcat(smGD.clientPath, "/");
strcpy (tmpPath, smGD.clientPath);
strcat(smGD.clientPath, SM_CLIENT_FILE2);
status = stat(smGD.clientPath, &buf);
if (status != 0) {
strcpy (smGD.clientPath, tmpPath);
strcat (smGD.clientPath, SM_CLIENT_FILE);
status = stat(smGD.clientPath, &buf);
}
if(status == 0)
{
/*
* sessions/current/dt.settings exist, restore to 'current' session
*/
strcpy(smGD.resourcePath, smGD.savePath);
strcat(smGD.resourcePath, "/");
strcat(smGD.resourcePath, SM_CURRENT_DIRECTORY);
strcat(smGD.resourcePath, "/");
strcat(smGD.resourcePath, SM_RESOURCE_FILE);
strcpy(smGD.settingPath, smGD.savePath);
strcat(smGD.settingPath, "/");
strcat(smGD.settingPath, SM_CURRENT_DIRECTORY);
strcat(smGD.settingPath, "/");
strcat(smGD.settingPath, SM_SETTING_FILE);
SetResSet();
smGD.sessionType = CURRENT_SESSION;
smGD.restoreSession = (char *) SM_CURRENT_DIRECTORY;
session_needed = 0;
}
}
if (session_needed)
{
strcpy(smGD.clientPath, smGD.savePath);
strcat(smGD.clientPath, "/");
strcat(smGD.clientPath, SM_HOME_DIRECTORY);
strcat(smGD.clientPath, "/");
strcpy(tmpPath, smGD.clientPath);
strcat(smGD.clientPath, SM_CLIENT_FILE2);
status = stat(smGD.clientPath, &buf);
if (status != 0) {
strcpy (smGD.clientPath, tmpPath);
strcat (smGD.clientPath, SM_CLIENT_FILE);
status = stat(smGD.clientPath, &buf);
}
if(status == 0)
{
/*
* sessions/home/dt.settings exist, restore to 'home' session
*/
strcpy(smGD.resourcePath, smGD.savePath);
strcat(smGD.resourcePath, "/");
strcat(smGD.resourcePath, SM_HOME_DIRECTORY);
strcat(smGD.resourcePath, "/");
strcat(smGD.resourcePath, SM_RESOURCE_FILE);
strcpy(smGD.settingPath, smGD.savePath);
strcat(smGD.settingPath, "/");
strcat(smGD.settingPath, SM_HOME_DIRECTORY);
strcat(smGD.settingPath, "/");
strcat(smGD.settingPath, SM_SETTING_FILE);
SetResSet();
smGD.sessionType = HOME_SESSION;
smGD.restoreSession = (char *) SM_HOME_DIRECTORY;
session_needed = 0;
}
}
if (session_needed)
{
SetSysDefaults();
}
}
/*************************************<->*************************************
*
* InternSessionDir - intern the session dir property and put it
* on the root window
*
* NOTE: - also checks the validity of the -session command line
* option
*
* Inputs:
* ------
* session_option - as given in the command line
* display
*
* Outputs:
* ------
* smGD.restoreSession - initialized
*
* Return = void
*
*************************************<->***********************************/
static Boolean
InternSessionDir (
char *session_option,
Display *disp)
{
char *pch;
if (!strcmp (session_option, SM_CURRENT_DIRECTORY)) {
pch = DtSM_SESSION_DIRECTORY;
smGD.restoreSession = SM_CURRENT_DIRECTORY;
}
else if (!strcmp (session_option, SM_HOME_DIRECTORY)) {
pch = DtSM_SESSION_DIRECTORY;
smGD.restoreSession = SM_HOME_DIRECTORY;
}
else if (!strcmp (session_option, SM_DISPLAY_HOME)) {
pch = DtSM_SESSION_DISPLAY_DIRECTORY;
smGD.restoreSession = SM_HOME_DIRECTORY;
}
else if (!strcmp (session_option, SM_DISPLAY_CURRENT)) {
pch = DtSM_SESSION_DISPLAY_DIRECTORY;
smGD.restoreSession = SM_CURRENT_DIRECTORY;
}
else
/*
* The session_option is not supported
*/
return (False);
XaSmRestoreDir = XInternAtom(disp, _XA_DT_RESTORE_DIR, False);
XChangeProperty(disp, RootWindow(disp, 0),
XaSmRestoreDir, XA_STRING, 8, PropModeReplace,
(unsigned char *)pch, strlen(pch));
XFlush(disp);
return (True);
}
/*************************************<->*************************************
*
* InitializeSpecificSession - set the smGD paths based on the session
* name given on the command line.
*
* Description:
* -----------
* Initializes several variables in smGD
*
* Inputs:
* ------
* session_option
* tmpDisplay
*
* Outputs:
* -------
* Return = void
*
* Comments:
* --------
*
*************************************<->***********************************/
static Boolean
InitializeSpecificSession (
char *session_option,
Display *disp,
unsigned int argc,
char **argv)
{
char *session_dir = (char *) XtMalloc(MAXPATHLEN);
char *alt_dir = (char *) XtMalloc(MAXPATHLEN);
int len;
struct stat buf;
if (!InternSessionDir (session_option, disp))
return (False);
InitializePaths (smGD.restoreSession, disp);
if (!strcmp (session_option, SM_HOME_DIRECTORY)) {
/*
* Home session
*/
if (smGD.clientPath[0] == '\0') {
if ((stat (smGD.savePath, &buf)) != 0) {
if ((mkdir (smGD.savePath, 0000)) == 0)
(void) chmod (smGD.savePath, 0755);
else
PrintErrnoError(DtError,
smNLS.cantCreateDirsString);
}
SetSysDefaults ();
}
smGD.sessionType = HOME_SESSION;
smGD.restoreSession = SM_HOME_DIRECTORY;
}
else if (!strcmp (session_option, SM_CURRENT_DIRECTORY)) {
/*
* Current session
*/
if (smGD.clientPath[0] == '\0') {
/*
* Fallback to the generic home session
*/
(void) sprintf (session_dir, "%s/%s",
smGD.savePath, SM_CURRENT_DIRECTORY);
(void) sprintf (alt_dir, "%s/%s",
smGD.savePath, SM_HOME_DIRECTORY);
if (!SetAlternateSession (session_dir, alt_dir, True))
SetSysDefaults ();
}
smGD.sessionType = CURRENT_SESSION;
smGD.restoreSession = SM_CURRENT_DIRECTORY;
}
else if (!strcmp (session_option, SM_DISPLAY_HOME)) {
/*
* Display-specific Home session
*/
(void) sprintf (session_dir, "%s/%s",
smGD.savePath, SM_HOME_DIRECTORY);
if ((stat(session_dir, &buf)) != 0){
/*
* The session does not exist, give the user a
* change to exit.
*/
if (!ConfirmSessionCreation (HOME_SESSION, argc, argv))
SM_EXIT (0);
}
if (smGD.clientPath[0] == '\0') {
/*
* Fallback to the generic home session
*/
char *home;
if ((home = getenv ("HOME")) == 0)
home = "";
/* JET - VU#497553 */
len = strlen(home) +
strlen(DtPERSONAL_CONFIG_DIRECTORY) +
strlen(DtSM_SESSION_DIRECTORY) +
strlen(SM_HOME_DIRECTORY);
if (len > MAXPATHLEN)
alt_dir = XtRealloc(alt_dir, len + 1);
(void) sprintf (alt_dir, "%s/%s/%s/%s",
home,
DtPERSONAL_CONFIG_DIRECTORY,
DtSM_SESSION_DIRECTORY,
SM_HOME_DIRECTORY);
if (!SetAlternateSession (session_dir, alt_dir, True))
SetSysDefaults ();
}
smGD.sessionType = HOME_SESSION;
smGD.restoreSession = SM_HOME_DIRECTORY;
}
else if (!strcmp (session_option, SM_DISPLAY_CURRENT)) {
/*
* Display-specific Current session
*/
(void) sprintf (session_dir, "%s/%s",
smGD.savePath, SM_CURRENT_DIRECTORY);
if ((stat(session_dir, &buf)) != 0){
/*
* The session does not exist, give the user a
* change to exit.
*/
if (!ConfirmSessionCreation (CURRENT_SESSION, argc, argv))
SM_EXIT (0);
}
if (smGD.clientPath[0] == '\0') {
/*
* First, fallback to the display-specific home session
*/
char *home;
(void) sprintf (alt_dir, "%s/%s",
smGD.savePath, SM_HOME_DIRECTORY);
if (!SetAlternateSession (session_dir, alt_dir, False)){
/*
* Try the generic home session
*/
if ((home = getenv ("HOME")) == 0)
home = "";
/* JET - VU#497553 */
len = strlen(home) +
strlen(DtPERSONAL_CONFIG_DIRECTORY) +
strlen(DtSM_SESSION_DIRECTORY) +
strlen(SM_HOME_DIRECTORY);
if (len > MAXPATHLEN)
alt_dir = XtRealloc(alt_dir, len + 1);
snprintf(alt_dir, len, "%s/%s/%s/%s",
home,
DtPERSONAL_CONFIG_DIRECTORY,
DtSM_SESSION_DIRECTORY,
SM_HOME_DIRECTORY);
if (!SetAlternateSession (session_dir,
alt_dir,
True))
SetSysDefaults ();
}
}
smGD.sessionType = CURRENT_SESSION;
smGD.restoreSession = SM_CURRENT_DIRECTORY;
}
else {
if (session_dir) XtFree(session_dir);
if (alt_dir) XtFree(alt_dir);
return (False);
}
if (session_dir) XtFree(session_dir);
if (alt_dir) XtFree(alt_dir);
return (True);
}
/*************************************<->*************************************
*
* InitializePaths
*
* Description:
* -----------
* Initializes the following variables:
*
* smGD.savePath
* smGD.settingsPath
* smGD.resourcePath
* smGD.clientPath - [0] = '\0' if the database files do not exist
*
* Inputs:
* ------
* session_name = "current" or "home"
*
* Outputs:
* -------
* Return = void
*
* Comments:
* --------
*
*************************************<->***********************************/
static void
InitializePaths (
char * session_name,
Display * disp)
{
char *db_file = (char *) XtMalloc(MAXPATHLEN);
struct stat buf;
if (!db_file)
{
PrintError(DtError, smNLS.cantMallocErrorString);
return;
}
smGD.savePath = _DtCreateDtDirs(disp);
(void) sprintf (smGD.settingPath, "%s/%s/%s",
smGD.savePath, session_name, SM_SETTING_FILE);
(void) sprintf (smGD.resourcePath, "%s/%s/%s",
smGD.savePath, session_name, SM_RESOURCE_FILE);
smGD.clientPath[0] = '\0';
(void) sprintf (db_file, "%s/%s/%s",
smGD.savePath, session_name, SM_CLIENT_FILE2);
if ((stat(db_file, &buf)) == 0)
(void) strcpy (smGD.clientPath, db_file);
else {
(void) sprintf (db_file, "%s/%s/%s",
smGD.savePath, session_name, SM_CLIENT_FILE);
if ((stat(db_file, &buf)) == 0)
(void) strcpy (smGD.clientPath, db_file);
}
XtFree(db_file);
}
/*************************************<->*************************************
*
* SetAlternateSession
*
* Assumptions:
*
* Neither of the client databases in the session_dir directory
* exist.
*
* Inputs:
* ------
* session_dir - the directory path for the session including home
* or current
* alt_dir - the directory to use in the search for an alternate
* or fallback session database
* make_dir - if True, a session_dir will be created if it does not
* exits; if False, session_dir will not be created
*
* Outputs:
* -------
* Return = Boolean
*
*************************************<->***********************************/
static Boolean
SetAlternateSession (
char * session_dir,
char * alt_dir,
Boolean make_dir)
{
char *tmp_dir = NULL;
char *db_file1 = (char *) XtMalloc(MAXPATHLEN);
char *db_file2 = (char *) XtMalloc(MAXPATHLEN);
struct stat buf;
if (!db_file1 || !db_file2)
{
PrintError(DtError, smNLS.cantMallocErrorString);
return False;
}
if ((stat (session_dir, &buf)) != 0) {
/*
* The requested dir does not exist, create it
* by either copying the session from alt_dir (if
* it exists and has a client database) or by
* calling mkdir.
*/
(void) sprintf (db_file1, "%s/%s",
alt_dir, SM_CLIENT_FILE2);
(void) sprintf (db_file2, "%s/%s",
alt_dir, SM_CLIENT_FILE);
if ((stat(db_file1, &buf)) == 0)
tmp_dir = db_file1;
else if ((stat(db_file2, &buf)) == 0)
tmp_dir = db_file2;
if (!tmp_dir && !make_dir) {
if (db_file1) XtFree(db_file1);
if (db_file2) XtFree(db_file2);
/*
* This alt_dir doesn't have a session database
* return now and try another directory
*/
return (False);
}
if (tmp_dir) {
/*
* The alt_dir has a session database, create
* a copy of its entire directory because all
* of the sessions state is needed.
*/
char *tmp;
tmp = XtMalloc (strlen (alt_dir) +
strlen (session_dir) + 10);
if (!tmp)
return (False);
(void) sprintf (tmp, "cp -r %s %s",
alt_dir, session_dir);
if ((system (tmp)) == -1)
return (False);
XtFree (tmp);
if ((stat(session_dir, &buf)) != 0)
/*
* It should have been created by the cp
*/
return (False);
/*
* The session database needs to be updated.
*/
if (tmp_dir == db_file1)
sprintf (smGD.clientPath, "%s/%s",
session_dir, SM_CLIENT_FILE2);
else
sprintf (smGD.clientPath, "%s/%s",
session_dir, SM_CLIENT_FILE);
} else {
/*
* The alt_dir did not have a session database.
* Create a directory and load the system defaults
*/
if ((mkdir (session_dir, 0000)) == 0)
(void) chmod (session_dir, 0755);
else {
PrintErrnoError(DtError,
smNLS.cantCreateDirsString);
return (False);
}
SetSysDefaults ();
}
} else {
/*
* The directory for the specified session exists
* but it doesn't have any client databases. Start
* a new user session. If a user wants a session
* with no apps, they should create a zero-length
* session database.
*/
SetSysDefaults ();
}
XtFree(db_file1);
XtFree(db_file2);
return (True);
}
void
SmExit (
int exitStatus)
{
/* JET - needed to rework this to avoid exiting before we are
* *really* ready to
*/
if (smGD.ExitComplete)
{
if (smXSMP.saveState.saveComplete &&
smXSMP.saveState.shutdown &&
!smXSMP.saveState.shutdownCanceled)
XSMPExit ();
exit(exitStatus);
}
else
return;
}
void
SetSIGPIPEToDefault (void)
{
struct sigaction pipeSig;
sigemptyset(&pipeSig.sa_mask);
pipeSig.sa_flags = 0;
pipeSig.sa_handler = SIG_DFL;
(void) sigaction(SIGPIPE, &pipeSig, (struct sigaction *) NULL);
}