2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $TOG: SmGlobals.c /main/37 1998/10/26 17:21:18 mgreess $ */
25 * (c) Copyright 1995 Digital Equipment Corporation.
26 * (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
27 * (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
28 * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
29 * (c) Copyright 1993, 1994, 1995 Novell, Inc.
30 * (c) Copyright 1995 FUJITSU LIMITED.
31 * (c) Copyright 1995 Hitachi.
33 /*************************************<+>*************************************
34 *****************************************************************************
38 ** Project: HP DT Session Manager (dtsession)
42 ** This file contains all routines in charge of managing all global
43 ** variables used by the session manager. These variables include
44 ** mostly state and setting information.
48 *******************************************************************
49 ** (c) Copyright Hewlett-Packard Company, 1990. All rights are
50 ** reserved. Copying or other reproduction of this program
51 ** except for archival purposes is prohibited without prior
52 ** written consent of Hewlett-Packard Company.
53 ********************************************************************
57 *****************************************************************************
58 *************************************<+>*************************************/
64 #include <sys/types.h>
65 #include <sys/utsname.h>
68 #include <sys/param.h>
69 #include <X11/Intrinsic.h>
70 #include <X11/Xutil.h>
71 #include <X11/StringDefs.h>
74 #include <Dt/SessionP.h>
77 #include <Dt/UserMsg.h>
78 #include <Dt/HourGlass.h>
79 #include <Dt/SessionM.h>
80 #include <Dt/EnvControlP.h>
81 #include <Dt/Qualify.h>
82 #include <Dt/MsgLog.h>
84 #include "SmResource.h"
87 #include "SmGlobals.h"
89 #include "SmRestore.h"
90 #include "SmProtocol.h"
94 * Internal Variable Declaraions
96 static char savedDir [MAXPATHLEN];
97 static char savedOldDir [MAXPATHLEN];
98 static char savedTmpDir [MAXPATHLEN];
101 * Internal Function Declaraions
104 static int SetSysDefaults( void ) ;
105 static int SetResSet( void ) ;
106 static void RemoveFiles( char *) ;
107 static void TrimErrorlog(void);
109 static void _SmWaitClientTimeoutDefault (
114 static void _SmWaitWmTimeoutDefault (
119 void SmCvtStringToContManagement (
125 unsigned char *_DtNextToken (
126 unsigned char *pchIn,
128 unsigned char **ppchNext);
130 Boolean _DtWmStringsAreEqual (
135 static Boolean InitializeSpecificSession (
141 static void InitializeGenericSession (
144 static void InitializePaths (
145 char *session_option,
148 static Boolean SetAlternateSession (
158 * These are the global structures used throughout dtsession
159 * They are defined in Sm.h
161 SessionResources smRes;
162 SaverResources smSaverRes;
165 SessionSettings smSettings;
167 char SM_SCREEN_SAVER_LOC [MAXPATHLEN + 1];
170 * Internal Global Data
172 static char tmpDisplayName[MAXPATHLEN + 1];
175 static XtResource sessionResources[]=
177 {SmNwmStartup, SmCwmStartup, XtRString, sizeof(String),
178 XtOffset(SessionResourcesPtr, wmStartup),
179 XtRImmediate, (XtPointer) NULL},
180 {SmNquerySettings, SmCquerySettings, XtRBoolean, sizeof(Boolean),
181 XtOffset(SessionResourcesPtr, querySettings),
182 XtRImmediate, (XtPointer) False},
183 {SmNkeys, SmCkeys, XtRString, sizeof(String),
184 XtOffset(SessionResourcesPtr, keyholders), XtRString, NULL},
185 {SmNalarmTime, SmCalarmTime, XtRInt, sizeof(int),
186 XtOffset(SessionResourcesPtr, alarmTime),
187 XtRImmediate, (XtPointer) 10},
188 {SmNmemThreshold, SmCmemThreshold, XtRInt, sizeof(int),
189 XtOffset(SessionResourcesPtr, memThreshold),
190 XtRImmediate, (XtPointer) 100},
191 {SmNsessionVersion, SmCsessionVersion, XtRString, sizeof(String),
192 XtOffset(SessionResourcesPtr, sessionVersion),
193 XtRImmediate, (XtPointer) NULL},
194 {SmNdisplayResolution, SmCdisplayResolution, XtRInt, sizeof(int),
195 XtOffset(SessionResourcesPtr, displayResolution),
196 XtRImmediate, (XtPointer) 0},
197 {SmNsessionLang, SmCsessionLang, XtRString, sizeof(String),
198 XtOffset(SessionResourcesPtr, sessionLang),
199 XtRImmediate, (XtPointer) ""},
200 {SmNcontManagement, SmCContManagement, SmRContManagement, sizeof(long),
201 XtOffset(SessionResourcesPtr, contManagement),
202 XtRImmediate, (XtPointer) (SM_CM_DEFAULT)},
203 {SmNwaitClientTimeout, SmCWaitClientTimeout, XtRInt, sizeof(int),
204 XtOffset(SessionResourcesPtr, waitClientTimeout),
205 XtRCallProc, (XtPointer)_SmWaitClientTimeoutDefault },
206 {SmNwaitWmTimeout, SmCWaitWmTimeout, XtRInt, sizeof(int),
207 XtOffset(SessionResourcesPtr, waitWmTimeout),
208 XtRCallProc, (XtPointer)_SmWaitWmTimeoutDefault },
209 {SmNuseMessaging, SmCUseMessaging, XtRBoolean, sizeof(Boolean),
210 XtOffset(SessionResourcesPtr, useBMS),
211 XtRImmediate, (XtPointer) True},
212 {SmNsaveFontPath, SmCsaveFontPath, XtRBoolean, sizeof(Boolean),
213 XtOffset(SessionResourcesPtr, saveFontPath),
214 XtRImmediate, (XtPointer) False},
215 {SmNsaveYourselfTimeout, SmCsaveYourselfTimeout, XtRInt, sizeof(int),
216 XtOffset(SessionResourcesPtr, saveYourselfTimeout),
217 XtRImmediate, (XtPointer) 5},
218 {SmNnumSessionsBackedup, SmCnumSessionsBackedup, XtRInt, sizeof(int),
219 XtOffset(SessionResourcesPtr, numSessionsBackedup),
220 XtRImmediate, (XtPointer) DEFAULT_NUM_SESSIONS_BACKED_UP},
221 {SmNignoreEnvironment, SmCignoreEnvironment, XtRString, sizeof(String),
222 XtOffset(SessionResourcesPtr, ignoreEnvironment),
223 XtRImmediate, (XtPointer) NULL},
224 #if defined(USE_XINERAMA) /* JET - Xinerama */
225 {SmNxineramaPreferredScreen, SmCxineramaPreferredScreen, XtRInt, sizeof(int),
226 XtOffset(SessionResourcesPtr, xineramaPreferredScreen),
227 XtRImmediate, (XtPointer) 0},
234 static XtResource saverResources[]=
236 {SmNcycleTimeout, SmCcycleTimeout, XtRInt, sizeof(int),
237 XtOffset(SaverResourcesPtr, cycleTimeout),
238 XtRImmediate, (XtPointer) -1},
239 {SmNlockTimeout, SmClockTimeout, XtRInt, sizeof(int),
240 XtOffset(SaverResourcesPtr, lockTimeout),
241 XtRImmediate, (XtPointer) -1},
242 {SmNsaverTimeout, SmCsaverTimeout, XtRInt, sizeof(int),
243 XtOffset(SaverResourcesPtr, saverTimeout),
244 XtRImmediate, (XtPointer) -1},
245 {SmNrandom, SmCrandom, XtRBoolean, sizeof(Boolean),
246 XtOffset(SaverResourcesPtr, random),
247 XtRImmediate, (XtPointer) False},
248 {SmNsaverList, SmCsaverList, XtRString, sizeof(String),
249 XtOffset(SaverResourcesPtr, saverList),
250 XtRImmediate, (XtPointer) ""},
258 * Machine specific defaults.
268 { 0, 20, 60}, /* Machine independent default */
270 {300, 10, 60}, /* HP s300 */
271 {400, 10, 60}, /* HP s400 */
272 {600, 5, 60}, /* HP s600 */
273 {700, 5, 60}, /* HP s700 */
274 {800, 5, 60}, /* HP s800 */
277 #define MACHINEDEFAULTS (sizeof(machineDefault) / sizeof(machineDefault[0]))
280 /*************************************<->*************************************
282 * _SmWaitClientTimeoutDefault (widget, offset, value)
287 * This function generates a default value for the waitClientTimeout resource.
288 * We dynamically default to 10 seconds for s400/s300 and to
289 * 5 seconds for s700/s800.
293 * widget = this is not used
295 * offset = this is the resource offset
297 * value = this is a pointer to a XrmValue in which to store the result
301 * value = default resource value and size
303 *************************************<->***********************************/
306 _SmWaitClientTimeoutDefault (Widget widget, int offset, XrmValue *value)
310 for (i = 0; i < MACHINEDEFAULTS; i++)
312 if (machineDefault[i].machineType == machineType)
318 if (i == MACHINEDEFAULTS)
323 value->addr = (char *)&machineDefault[i].clientTimeout;
324 value->size = sizeof (int);
326 } /* END OF FUNCTION _SmWaitClientTimeoutDefault */
330 /*************************************<->*************************************
332 * _SmWaitWmTimeoutDefault (widget, offset, value)
337 * This function generates a default value for the waitWmTimeout resource.
338 * We dynamically default to 60 seconds for s400/s300 and to
339 * 60 seconds for s700/s800. This could change if we get feedback indicating
340 * the need for a new default.
344 * widget = this is not used
346 * offset = this is the resource offset
348 * value = this is a pointer to a XrmValue in which to store the result
352 * value = default resource value and size
354 *************************************<->***********************************/
357 _SmWaitWmTimeoutDefault (Widget widget, int offset, XrmValue *value)
361 smGD.userSetWaitWmTimeout = False; /* if we are here, it is not user set */
363 for (i = 0; i < MACHINEDEFAULTS; i++)
365 if (machineDefault[i].machineType == machineType)
371 if (i == MACHINEDEFAULTS)
376 value->addr = (char *)&machineDefault[i].wmTimeout;
377 value->size = sizeof (int);
379 } /* END OF FUNCTION _SmWaitWmTimeoutDefault */
383 /*************************************<->*************************************
390 * Sets SM global resources and global settings to a starting value.
395 * buttonForm = form widget for button that allows cursor to get colors
396 * smRes(global) = structure that holds session resources.
397 * smToSet(global) = structure that holds "which settings to set and how" info
398 * smGD(global) = structure that holds general data info
402 * smRes(global) = structure that holds session resources.
403 * smToSet(global) = structure that holds "which settings to set and how" info
404 * smGD(global) = structure that holds general data info
408 * Resources are set to an initial value by the resource manager. The
409 * rest are set in the routine.
411 *************************************<->***********************************/
413 InitSMGlobals( void )
416 PropDtSmWindowInfo property;
417 struct utsname nameRec;
421 smGD.userSetWaitWmTimeout = True; /* assume it is */
424 if (uname(&nameRec) == 0)
426 keyNum = nameRec.machine;
427 if (firstSlash = strchr(keyNum, '/'))
429 keyNum = ++firstSlash;
431 if ( keyNum[0] == '3')
435 else if (keyNum[0] == '4')
439 else if (keyNum[0] == '6')
443 else if (keyNum[0] == '7')
447 else if (keyNum[0] == '8')
456 * Get application specific resource values
458 XtAppAddConverter (smGD.appCon, XtRString, SmRContManagement,
459 (XtConverter)SmCvtStringToContManagement, NULL, 0);
460 XtGetApplicationResources(smGD.topLevelWid, (XtPointer) &smRes,
462 XtNumber(sessionResources), NULL, 0);
464 if (smGD.lockOnTimeoutStatus == True)
467 * Pull screen saver resources from Dtsession*extension.<name>.
469 smGD.SmNextension = "extension";
470 smGD.SmCextension = "Extension";
471 smGD.extensionSpec = "extension.";
476 * Pull screen saver resources from Dtsession*<name>.
478 smGD.SmNextension = smGD.SmCextension = smGD.extensionSpec = "";
481 XtGetSubresources(smGD.topLevelWid, (XtPointer) &smSaverRes,
482 smGD.SmNextension, smGD.SmCextension,
484 XtNumber(saverResources), NULL, 0);
486 smGD.wmStartup = SmNewString(smRes.wmStartup);
487 smGD.keyholders = SmNewString(smRes.keyholders);
488 smGD.sessionLang = SmNewString(smRes.sessionLang);
489 smGD.saverList = SmNewString(smSaverRes.saverList);
492 * Initialize general data used by apps not initialized by
493 * XtInitialize or DtInitialize
495 smGD.topLevelWindow = XtWindow(smGD.topLevelWid);
496 smGD.numSavedScreens = (ScreenCount(smGD.display) > MAX_SCREENS_SAVED)
497 ? MAX_SCREENS_SAVED : ScreenCount(smGD.display);
498 smGD.dtwmRunning = False;
499 smSettings.confirmMode = DtSM_VERBOSE_MODE;
500 if (smGD.sessionType == CURRENT_SESSION ||
501 smGD.sessionType == DEFAULT_SESSION)
502 smSettings.startState = DtSM_CURRENT_STATE;
504 smSettings.startState = DtSM_HOME_STATE;
505 smGD.homeSave = False;
506 smGD.saverListParse = NULL;
508 smGD.loggingOut = False;
511 * Sanity check on timeouts for negative numbers
513 if (smRes.waitClientTimeout < 0)
515 smRes.waitClientTimeout = -smRes.waitClientTimeout;
517 if (smRes.waitWmTimeout < 0)
519 smRes.waitWmTimeout = -smRes.waitWmTimeout;
521 if (smRes.saveYourselfTimeout < 0)
523 smRes.saveYourselfTimeout = -smRes.saveYourselfTimeout;
528 * Now convert users view of seconds in to XtAppAddTimout's
529 * need for milliseconds.
531 smRes.waitClientTimeout = 1000 * smRes.waitClientTimeout;
532 smRes.waitWmTimeout = 1000 * smRes.waitWmTimeout;
533 smRes.saveYourselfTimeout = 1000 * smRes.saveYourselfTimeout;
534 smGD.savedWaitWmTimeout = smRes.waitWmTimeout;
537 * Initialize lock data
539 smGD.screen = XDefaultScreen(smGD.display);
540 smGD.blackPixel = XBlackPixel(smGD.display, smGD.screen);
541 smGD.whitePixel = XWhitePixel(smGD.display, smGD.screen);
542 smDD.lockDialog = NULL;
543 smDD.lockCoverDialog = NULL;
544 for(i = 0;i < smGD.numSavedScreens;i++)
546 smDD.coverDialog[i] = NULL;
547 smDD.coverDrawing[i] = NULL;
549 smGD.lockedState = UNLOCKED;
552 * Sanity check screen saver resource values.
554 if (smRes.alarmTime < 0) smRes.alarmTime = 0;
556 #define SMBOUND(A) (A < 0 ? 0 : A)
558 smSaverRes.lockTimeout = SMBOUND(smSaverRes.lockTimeout) * 60;
559 smSaverRes.saverTimeout = SMBOUND(smSaverRes.saverTimeout) * 60;
560 smSaverRes.cycleTimeout = SMBOUND(smSaverRes.cycleTimeout) * 60;
563 smGD.waitCursor = _DtGetHourGlassCursor(smGD.display);
566 * Initialize other global data related to dialogs
568 smDD.confExit = NULL;
570 smDD.compatExit = NULL;
572 smDD.saveSession = NULL; /* Error dialog for Save_Session */
574 if (!smDD.smHelpDialog)
576 * Don't wipe it out if it is already created
578 smDD.smHelpDialog = NULL;
581 * Intern all the atoms needed for the WSM communication
584 enum { XA_DT_SM_WINDOW_INFO, XA_DT_SM_WM_PROTOCOL,
585 XA_DT_SM_START_ACK_WINDOWS, XA_DT_SM_STOP_ACK_WINDOWS,
586 XA_DT_WM_WINDOW_ACK, XA_DT_WM_EXIT_SESSION,
587 XA_DT_WM_LOCK_DISPLAY, XA_DT_WM_READY, NUM_ATOMS };
588 static char *atom_names[] = {
589 _XA_DT_SM_WINDOW_INFO, _XA_DT_SM_WM_PROTOCOL,
590 _XA_DT_SM_START_ACK_WINDOWS, _XA_DT_SM_STOP_ACK_WINDOWS,
591 _XA_DT_WM_WINDOW_ACK, _XA_DT_WM_EXIT_SESSION,
592 _XA_DT_WM_LOCK_DISPLAY, _XA_DT_WM_READY };
594 Atom atoms[XtNumber(atom_names)];
596 XInternAtoms(smGD.display, atom_names, XtNumber(atom_names),
599 XaVsmInfo = atoms[XA_DT_SM_WINDOW_INFO];
600 XaSmWmProtocol = atoms[XA_DT_SM_WM_PROTOCOL];
601 XaSmStartAckWindow = atoms[XA_DT_SM_START_ACK_WINDOWS];
602 XaSmStopAckWindow = atoms[XA_DT_SM_STOP_ACK_WINDOWS];
603 XaWmWindowAck = atoms[XA_DT_WM_WINDOW_ACK];
604 XaWmExitSession = atoms[XA_DT_WM_EXIT_SESSION];
605 XaWmLockDisplay = atoms[XA_DT_WM_LOCK_DISPLAY];
606 XaWmReady = atoms[XA_DT_WM_READY];
610 * Set the session manager window property on the root window
613 property.smWindow = (unsigned long) smGD.topLevelWindow;
614 XChangeProperty (smGD.display, RootWindow(smGD.display, 0),
615 XaVsmInfo, XaVsmInfo,
616 32, PropModeReplace, (unsigned char *)&property,
617 PROP_DT_SM_WINDOW_INFO_ELEMENTS);
620 * Set up the signal handler for forking and execing
622 sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
627 /*************************************<->*************************************
634 * Sets SM global resources and global settings to a starting value.
639 * smGD.display = display structure for session manager. Used to construct
640 * a display directory
644 * smGD.resourcePath(global) = Path where the resources to be restored are
646 * smGD.settingPath(global) = Path where the settings to be restored are
648 * smGD.clientPath(global) = Path where the clients to be restored are
650 * smGD.savePath(global) = Path where all save files are to be saved
658 * WARNING: This routine also determines whether dtsession is being started
659 * in compatibility mode. If so - no restore paths are set up and
660 * the routine is exited.
662 *************************************<->***********************************/
670 char *displayName = NULL;
671 char *session_option = NULL;
673 smGD.compatMode = False;
675 for(i = 0;i < argc;i++)
677 if(!strcmp(argv[i], "-display"))
679 displayName = argv[i + 1];
681 * If -display is used but DISPLAY is not set,
682 * put DISPLAY into the environment
684 if (getenv("DISPLAY") == 0)
686 snprintf(tmpDisplayName, MAXPATHLEN, "DISPLAY=%s", displayName);
687 putenv(tmpDisplayName);
691 if(!strcmp(argv[i], "-norestore"))
693 smGD.compatMode = True;
696 if(!strcmp(argv[i], "-session"))
703 pch = strdup ((char *) GETMESSAGE (40, 15,
704 " No session name was provided for the -session command line option."));
707 DtMsgLogMessage (argv[0], DtMsgLogWarning, pch);
712 session_option = argv[i];
717 * If we are in compatibility mode - no restore paths are set
718 * up and we just return
720 if(smGD.compatMode == True)
722 smGD.clientPath[0] = 0;
723 smGD.resourcePath[0] = 0;
724 smGD.settingPath[0] = 0;
725 smGD.sessionType = DEFAULT_SESSION;
726 smGD.restoreSession = NULL;
730 tmpDisplay = XOpenDisplay(displayName);
731 if(tmpDisplay == NULL)
733 PrintError(DtError, GETMESSAGE(4, 1, "Invalid display name - exiting."));
739 if (!InitializeSpecificSession (session_option, tmpDisplay, argc, argv))
740 InitializeGenericSession (tmpDisplay);
743 InitializeGenericSession (tmpDisplay);
746 * Need to know if the session is for a specific display
748 smGD.displaySpecific = True;
749 if (session_option = strrchr (smGD.savePath, '/'))
752 if (!strcmp (session_option, DtSM_SESSION_DIRECTORY))
753 smGD.displaySpecific = False;
757 XCloseDisplay(tmpDisplay);
760 ** User's session startup script:
761 ** $HOME/.dt/sessions/sessionetc
763 strcpy(smGD.etcPath, smGD.savePath);
764 strcat(smGD.etcPath, "/");
765 strcat(smGD.etcPath, smEtcFile);
768 ** User's session shutdown script:
769 ** $HOME/.dt/sessions/sessionexit
771 strcpy(smGD.exitPath, smGD.savePath);
772 strcat(smGD.exitPath, "/");
773 strcat(smGD.exitPath, smExitFile);
785 char * pathList = (char *)XtMalloc(strlen(SM_SYSTEM_PATH) +
786 strlen(":" CDE_INSTALLATION_TOP "/config") + 1);
788 strcpy(pathList,SM_SYSTEM_PATH);
789 strcat(pathList,":" CDE_INSTALLATION_TOP "/config");
791 tempPath = _DtQualifyWithFirst(the1stPath,pathList);
792 if (tempPath != NULL) {
793 strcpy(the1stPath,tempPath);
801 /*************************************<->*************************************
808 * Sets the path to restore the system default files. A convenience routine
813 * smGD.savePath = path that files are to be saved in (set up in
818 * smGD.resourcePath(global) = Path where the resources to be saved are
820 * smGD.settingPath(global) = Path where the settings to be saved are
822 * smGD.clientPath(global) = Path where the clients to be saved are
828 *************************************<->***********************************/
830 SetSysDefaults( void )
839 * No files exist for restoration - use the
842 strcpy(smGD.resourcePath, "");
843 strcpy(smGD.clientPath, "");
844 smGD.settingPath[0] = 0;
845 smGD.sessionType = DEFAULT_SESSION;
846 smGD.restoreSession = (char *) SM_SYSTEM_DIRECTORY;
848 langSpec = getenv("LANG");
849 if ((langSpec != NULL) && (*langSpec != 0))
851 strcat(smGD.clientPath, "/");
852 strncat(smGD.clientPath, langSpec, MAXPATHLEN-2);
853 smGD.clientPath[MAXPATHLEN-1] = 0;
856 strcat(smGD.clientPath, "/");
857 strcat(smGD.clientPath, SM_SYSTEM_CLIENT_FILE);
859 FixPath(smGD.clientPath);
862 * If the system files don't exist - we're in
863 * trouble - First try LANG location then default
865 status = stat(smGD.clientPath, &buf);
868 if((langSpec == NULL) || (*langSpec == 0))
870 PrintErrnoError(DtError, GETMESSAGE(4, 2,
871 "No defaults files exist. "
872 "No applications will be restarted."));
873 smGD.clientPath[0] = 0;
874 smGD.resourcePath[0] = 0;
878 strcpy(smGD.clientPath, "/C/");
879 strcat(smGD.clientPath, SM_SYSTEM_CLIENT_FILE);
881 FixPath(smGD.clientPath);
883 status = stat(smGD.clientPath, &buf);
886 PrintErrnoError(DtError, GETMESSAGE(4, 3,
887 "No defaults files exist. "
888 "No applications will be restarted."));
889 smGD.clientPath[0] = 0;
890 smGD.resourcePath[0] = 0;
900 /*************************************<->*************************************
907 * Sets the path to restore the settings and resource files.
908 * A convenience routine
913 * smGD.savePath = path that files are to be saved in (set up in
918 * smGD.resourcePath(global) = Path where the resources to be saved are
920 * smGD.settingPath(global) = Path where the settings to be saved are
922 * smGD.clientPath(global) = Path where the clients to be saved are
928 *************************************<->***********************************/
936 * If resource or settings file does not exist - just null out
937 * the path so these things will not get restored
939 status = stat(smGD.resourcePath, &buf);
942 smGD.resourcePath[0] = 0;
945 status = stat(smGD.settingPath, &buf);
948 smGD.settingPath[0] = 0;
954 /*************************************<->*************************************
956 * UndoSetSavePath () - Undoes the directory manipulations done by
957 * SetSavePath. This function is only called if a shutdown/save
960 *************************************<->***********************************/
962 UndoSetSavePath (void)
966 if (strcmp ("", savedDir)) {
969 * Remove the directory where the save occurred, e.g.:
971 * ~/.dt/<session_dir>/current
972 * ~/.dt/<session_dir>/home
974 buf = XtMalloc (strlen (savedDir) + 9);
975 sprintf (buf, "rm -rf %s", savedDir);
979 if (strcmp ("", savedOldDir)) {
981 MoveDirectory (savedOldDir, savedDir, False);
983 if (strcmp ("", savedTmpDir)) {
984 MoveDirectory (savedTmpDir, savedOldDir, False);
991 /*************************************<->*************************************
993 * SetSavePath (saveToHome, mode)
998 * Sets up paths for files that need to be saved. Also removes any files
999 * that shouldn't be there after the save.
1004 * smGD.display = display structure for session manager. Used to construct
1005 * a display directory
1006 * saveToHome = whether this is a save to home session or not
1007 * mode = whether we are resetting or restarting
1011 * smGD.resourcePath(global) = Path where the resources to be saved are
1013 * smGD.settingPath(global) = Path where the settings to be saved are
1015 * smGD.clientPath(global) = Path where the clients to be saved are
1021 *************************************<->***********************************/
1031 * These directory paths are needed in UndoSetSavePaths
1032 * if a shutdown/save is canceled.
1034 strcpy (savedDir, "");
1035 strcpy (savedOldDir, "");
1036 strcpy (savedTmpDir, "");
1039 * Make sure the user hasn't done something like delete the .dt
1040 * directories during the session. If so - recreate them
1042 SM_FREE(smGD.savePath);
1043 smGD.savePath = _DtCreateDtDirs(smGD.display);
1044 if(smGD.savePath == NULL)
1046 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1047 smGD.clientPath[0] = 0;
1048 smGD.settingPath[0] = 0;
1049 smGD.resourcePath[0] = 0;
1055 * Path for a save defaults to save the current session.
1056 * Otherwise just remove the directories
1058 strcpy(smGD.clientPath, smGD.savePath);
1059 strcpy(smGD.settingPath, smGD.savePath);
1060 strcpy(smGD.resourcePath, smGD.savePath);
1061 strcat(smGD.clientPath, "/");
1062 strcat(smGD.settingPath, "/");
1063 strcat(smGD.resourcePath, "/");
1065 if(saveToHome == False)
1067 strcat(smGD.clientPath, SM_CURRENT_DIRECTORY);
1068 strcat(smGD.resourcePath, SM_CURRENT_DIRECTORY);
1069 strcat(smGD.settingPath, SM_CURRENT_DIRECTORY);
1070 smGD.restoreSession = SM_CURRENT_DIRECTORY;
1074 strcat(smGD.clientPath, SM_HOME_DIRECTORY);
1075 strcat(smGD.resourcePath, SM_HOME_DIRECTORY);
1076 strcat(smGD.settingPath, SM_HOME_DIRECTORY);
1077 smGD.restoreSession = SM_HOME_DIRECTORY;
1080 if ((mode == DtSM_HOME_STATE) && (saveToHome == False) &&
1081 (smSettings.startState == DtSM_HOME_STATE))
1084 * The only time this should should be true is if the
1085 * current session is a Home session and the session
1086 * is being exited. The idea is that if a "current"
1087 * directory exits, it must be moved because when the
1088 * user next logs in, a Home session should be started
1089 * (if a session is not selected at the login screen)
1090 * and the Session Manager decides whether or not it
1091 * starts a Home or Current session based on if a
1092 * "current" directory exists. If a "current" directory
1093 * exists, a Current session will be started.
1095 status = stat(smGD.clientPath, &buf);
1099 * The "current" directory exists and must be moved to its
1100 * ".old" version. But first, if the ".old" version exists,
1101 * it must be moved to a temporary directory. This temporary
1102 * directory will eventually be pruned - when a user next
1103 * runs a Current session and saves the session.
1105 strcpy (savedDir, smGD.clientPath);
1106 snprintf(smGD.etcPath, sizeof(smGD.etcPath), "%s.%s", smGD.clientPath, SM_OLD_EXTENSION);
1107 status = stat(smGD.etcPath, &buf);
1113 strcpy(savedOldDir, smGD.etcPath);
1115 len = strlen(smGD.savePath) + strlen(smGD.restoreSession)
1116 + strlen("XXXXXX") + 3;
1117 tmpName = (char *) XtCalloc(1, len);
1119 sprintf(tmpName, "%s/%s.XXXXXX", smGD.savePath,
1120 smGD.restoreSession);
1122 if ((tfd = mkstemp(tmpName)) == -1)
1124 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1131 MoveDirectory(smGD.etcPath, tmpName, False);
1133 strncpy(savedTmpDir, tmpName, len - 1);
1135 XtFree((char *) tmpName);
1137 MoveDirectory(smGD.clientPath, smGD.etcPath, False);
1140 smGD.clientPath[0] = 0;
1141 smGD.settingPath[0] = 0;
1142 smGD.resourcePath[0] = 0;
1146 strcpy (savedDir, smGD.clientPath);
1149 * If the desired directory doesn't exist, create it.
1151 status = stat(smGD.clientPath, &buf);
1154 status = mkdir(smGD.clientPath, 0000);
1157 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1158 smGD.clientPath[0] = 0;
1159 smGD.settingPath[0] = 0;
1160 smGD.resourcePath[0] = 0;
1163 if(-1 == chmod(smGD.clientPath, 0755))
1165 fprintf(stderr, "%s chmod error %s\n", smGD.clientPath, strerror(errno));
1171 * The desired directory already exists so it must
1172 * be archived by moving it to its ".old" version. But
1173 * first, if its ".old" version already exists, it must
1174 * be moved to a temporary directory that will be removed
1175 * when the session directories are pruned - after the
1180 snprintf(smGD.etcPath, sizeof(smGD.etcPath), "%s.%s", smGD.clientPath, SM_OLD_EXTENSION);
1181 status = stat(smGD.etcPath, &buf);
1186 len = strlen(smGD.savePath) + strlen(smGD.restoreSession)
1187 + strlen("XXXXXX") + 3;
1188 tmpName = (char *) XtCalloc(1, len);
1189 snprintf(tmpName, len, "%s/%s.XXXXXX", smGD.savePath,
1190 smGD.restoreSession);
1192 strcpy (savedOldDir, smGD.etcPath);
1194 if ((tfd = mkstemp(tmpName)) == -1)
1196 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1203 MoveDirectory (smGD.etcPath, tmpName, False);
1205 strcpy (savedTmpDir, tmpName);
1207 XtFree((char *) tmpName);
1210 MoveDirectory(smGD.clientPath, smGD.etcPath, False);
1213 * Now re-make the directory
1215 status = mkdir(smGD.clientPath, 0000);
1218 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1219 smGD.clientPath[0] = 0;
1220 smGD.settingPath[0] = 0;
1221 smGD.resourcePath[0] = 0;
1224 status = chmod(smGD.clientPath, 0755);
1227 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1228 smGD.clientPath[0] = 0;
1229 smGD.settingPath[0] = 0;
1230 smGD.resourcePath[0] = 0;
1235 strcat(smGD.clientPath, "/");
1236 strcat(smGD.clientPath, SM_CLIENT_FILE2);
1237 strcat(smGD.settingPath, "/");
1238 strcat(smGD.settingPath, SM_SETTING_FILE);
1239 strcat(smGD.resourcePath, "/");
1240 strcat(smGD.resourcePath, SM_RESOURCE_FILE);
1247 /*************************************<->*************************************
1249 * SetFontSavePath (saveToHome, mode)
1254 * Sets up the save path for the auxillary directory.
1266 *************************************<->***********************************/
1268 SetFontSavePath(char *langPtr)
1276 * Set up the session font directory and see if it exists
1278 if(smGD.sessionType == CURRENT_SESSION)
1280 sessionSaved = SM_CURRENT_FONT_DIRECTORY;
1284 sessionSaved = SM_HOME_FONT_DIRECTORY;
1287 snprintf(smGD.fontPath, MAXPATHLEN, "%s/%s", smGD.savePath, sessionSaved);
1288 status = stat(smGD.fontPath, &buf);
1291 status = mkdir(smGD.fontPath, 0000);
1294 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1295 smGD.fontPath[0] = 0;
1298 if(-1 == chmod(smGD.fontPath, 0755))
1300 fprintf(stderr, "%s chmod error %s\n", smGD.fontPath, strerror(errno));
1305 * Now add the lang subdirectory and see if it exists
1307 strncat(smGD.fontPath, "/", MAXPATHLEN);
1308 strncat(smGD.fontPath, langPtr, MAXPATHLEN);
1309 status = stat(smGD.fontPath, &buf);
1312 status = mkdir(smGD.fontPath, 0000);
1315 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1316 smGD.fontPath[0] = 0;
1319 status = chmod(smGD.fontPath, 0755);
1322 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1323 smGD.fontPath[0] = 0;
1333 /*************************************<->*************************************
1340 * Remove the files that need to be removed
1353 *************************************<->***********************************/
1359 int execStatus, childStatus, i, statLoc;
1363 * Fork and exec the client process
1365 sigaction(SIGCHLD, &smGD.defvec, (struct sigaction *) NULL);
1367 clientFork = vfork();
1370 * If the fork fails - Send out an error and return
1374 PrintErrnoError(DtError, smNLS.cantForkClientString);
1379 * Fork succeeded - now do the exec
1383 SetSIGPIPEToDefault ();
1386 * Set the gid of the process back from bin
1390 setregid(smGD.runningGID, smGD.runningGID);
1392 setgid(smGD.runningGID);
1393 setegid(smGD.runningGID);
1397 _DtEnvControl(DT_ENV_RESTORE_PRE_DT);
1399 #if defined(CSRG_BASED)
1403 #endif /* CSRG_BASED */
1405 execStatus = execlp("rm","rm", "-rf", path, (char *) 0);
1408 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.")) ;
1409 PrintErrnoError(DtError, tmpString);
1415 while(wait(&statLoc) != clientFork);
1417 sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
1421 /*************************************<->*************************************
1427 * Move the directory specified by pathFrom - to the directory specified
1432 * pathFrom = the directory to move from
1433 * pathTo = the directory to move to
1434 * removeDestDir = if True, directory pathTo is removed before the
1443 *************************************<->***********************************/
1448 Boolean removeDestDir)
1452 int status, execStatus, childStatus, i, statLoc;
1456 * If the pathTo directory exists - remove it
1460 status = stat(pathTo, &buf);
1463 RemoveFiles(pathTo);
1468 * Fork and exec the client process
1470 sigaction(SIGCHLD, &smGD.defvec, (struct sigaction *) NULL);
1472 clientFork = vfork();
1475 * If the fork fails - Send out an error and return
1479 PrintErrnoError(DtError, smNLS.cantForkClientString);
1484 * Fork succeeded - now do the exec
1488 SetSIGPIPEToDefault ();
1491 * Set the gid of the process back from bin
1495 setregid(smGD.runningGID, smGD.runningGID);
1497 setgid(smGD.runningGID);
1498 setegid(smGD.runningGID);
1502 _DtEnvControl(DT_ENV_RESTORE_PRE_DT);
1504 #if defined(CSRG_BASED)
1508 #endif /* CSRG_BASED */
1510 execStatus = execlp("mv","mv", pathFrom, pathTo, (char *) 0);
1513 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.")) ;
1514 PrintErrnoError(DtError, tmpString);
1520 while(wait(&statLoc) != clientFork);
1522 sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
1527 /*************************************<->*************************************
1534 * Initialize the NLS strings used in dtsession
1547 *************************************<->***********************************/
1549 InitNlsStrings( void )
1554 * Malloc failure error message - THIS MESSAGE MUST BE INITIALIZED FIRST
1556 smNLS.cantMallocErrorString = strdup (((char *)GETMESSAGE(4, 5, "Unable to malloc memory for operation.")));
1559 * Error message when dtsession cant lock the display
1561 smNLS.cantLockErrorString = strdup (((char *)GETMESSAGE(4, 6, "Unable to lock display. Another application may have the pointer or keyboard grabbed.")));
1564 * Error message when dtsession cant open files for reading or writing
1566 smNLS.cantOpenFileString = strdup (((char *)GETMESSAGE(4, 7, "Unable to open session file. No clients will be restarted.")));
1569 * Error message when dtsession cant fork client process
1571 smNLS.cantForkClientString = strdup (((char *)GETMESSAGE(4, 8, "Unable to fork client process.")));
1574 * Error message when dtsession cant create dt directories
1576 smNLS.cantCreateDirsString = strdup (((char *)GETMESSAGE(4, 9, "Unable to create DT directories. Check permissions on home directory.")));
1579 * Error message when trying to lock display on trusted system
1581 smNLS.trustedSystemErrorString = strdup (((char *)GETMESSAGE(4, 10, "Unable to lock display due to security restrictions")));
1586 /*************************************<->*************************************
1593 * When a SIGCHLD signal comes in, wait for all child processes to die.
1606 *************************************<->***********************************/
1609 WaitChildDeath( int i )
1615 * Wait on any children that have died since the last SIGCHLD we
1616 * received. Any child process death that occurs while we are
1617 * in WaitChildDeath() will not result in a SIGCHLD. Any
1618 * child proceses that die after our last call to waitpid() will
1619 * remain zombiefied until the next invocation of WaitChildDeath().
1621 while ((pid = waitpid(-1, &stat_loc, WNOHANG)) > 0)
1624 sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
1629 /*************************************<->*************************************
1636 * Trim the errorlog file using the following algorithm:
1637 * if(errorlog.old exists and is not empty) move it to errorlog.oldest
1638 * if(errorlog exists and is not empty) move it to errorlog.old
1651 *************************************<->***********************************/
1653 TrimErrorlog( void )
1655 char *savePath, /* common path element for all pathnames */
1663 * Allocate the strings needed
1665 savePath = (char *) SM_MALLOC(MAXPATHLEN + 1);
1666 checkPath1 = (char *) SM_MALLOC(MAXPATHLEN + 1);
1667 checkPath2 = (char *) SM_MALLOC(MAXPATHLEN + 1);
1668 if ((home=getenv("HOME")) == NULL)
1671 len = strlen(home) + strlen(DtPERSONAL_CONFIG_DIRECTORY) + 2;
1672 if (len > MAXPATHLEN) savePath = SM_REALLOC(savePath, len);
1673 snprintf(savePath, len, "%s/%s", home, DtPERSONAL_CONFIG_DIRECTORY);
1676 * If errorlog.old exists and it is not empty, delete
1677 * errorlog.older and then move errolog.old to
1680 if (len + strlen(DtOLDER_ERRORLOG_FILE) > MAXPATHLEN)
1681 checkPath1 = SM_REALLOC(savePath, len + strlen(DtOLDER_ERRORLOG_FILE));
1682 sprintf(checkPath1, "%s/%s", savePath, DtOLDER_ERRORLOG_FILE);
1684 if (len + strlen(DtOLD_ERRORLOG_FILE) > MAXPATHLEN)
1685 checkPath2 = SM_REALLOC(savePath, len + strlen(DtOLD_ERRORLOG_FILE));
1686 sprintf(checkPath2, "%s/%s", savePath, DtOLD_ERRORLOG_FILE);
1688 status = stat(checkPath2, &buf);
1689 if((status != -1) && (buf.st_size > 0))
1691 (void) unlink(checkPath1);
1692 (void) link(checkPath2, checkPath1);
1693 (void) unlink(checkPath2);
1697 * If errorlog exists and it is not empty, move it to
1700 if (len + strlen(DtERRORLOG_FILE) > MAXPATHLEN)
1701 checkPath1 = SM_REALLOC(savePath, len + strlen(DtERRORLOG_FILE));
1702 snprintf(checkPath1, len + strlen(DtERRORLOG_FILE), "%s/%s", savePath, DtERRORLOG_FILE);
1704 status = stat(checkPath1, &buf);
1705 if((status != -1) && (buf.st_size > 0))
1707 (void) link(checkPath1, checkPath2);
1708 (void) unlink(checkPath1);
1711 SM_FREE((char *) savePath);
1712 SM_FREE((char *) checkPath1);
1713 SM_FREE((char *) checkPath2);
1720 /*************************************<->*************************************
1727 * Do everything that needs to be done to get the system back into a
1728 * READY state. This includes checking to be sure that the BMS did not
1729 * die while we were in process
1742 *************************************<->***********************************/
1744 SetSystemReady( void )
1746 smGD.smState = READY;
1747 if(smGD.bmsDead == True)
1756 /*************************************<->*************************************
1758 * SmCvtStringToContManagement (args, numArgs, fromVal, toVal)
1763 * This function converts a string to a value for the
1764 * contention management flag set.
1769 * args = additional XrmValue arguments to the converter - NULL here
1771 * numArgs = number of XrmValue arguments - 0 here
1773 * fromVal = resource value to convert
1778 * toVal = descriptor to use to return converted value
1780 *************************************<->***********************************/
1782 void SmCvtStringToContManagement (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
1785 unsigned char *pch = (unsigned char *) (fromVal->addr);
1786 unsigned char *pchNext;
1789 Boolean fHit = False;
1790 Boolean fAddNext = True;
1793 * Names of contention management options
1796 #define CM_ALL_STR (unsigned char *)"all"
1797 #define CM_SYSTEM_STR (unsigned char *)"system"
1798 #define CM_HANDSHAKE_STR (unsigned char *)"handshake"
1799 #define CM_NONE_STR (unsigned char *)"none"
1802 * Check first token. If '-' we subtract from all options.
1803 * Otherwise, we start with no contention management and add things in.
1807 (_DtNextToken (pch, &len, &pchNext)) &&
1818 while (*pch && _DtNextToken (pch, &len, &pchNext))
1821 * Strip off "sign" if prepended to another token, and process
1822 * that token the next time through.
1834 else if (*pch == '-')
1843 if ((*pch == 'A') || (*pch == 'a'))
1845 if (_DtWmStringsAreEqual (pch, CM_ALL_STR, len))
1847 cval = fAddNext ? (cval | SM_CM_ALL) :
1848 (cval & ~SM_CM_ALL);
1853 else if ((*pch == 'S') || (*pch == 's'))
1855 if (_DtWmStringsAreEqual (pch, CM_SYSTEM_STR, len))
1857 cval = fAddNext ? (cval | SM_CM_SYSTEM) :
1858 (cval & ~SM_CM_SYSTEM);
1863 else if ((*pch == 'H') || (*pch == 'h'))
1865 if (_DtWmStringsAreEqual (pch, CM_HANDSHAKE_STR, len))
1867 cval = fAddNext ? (cval | SM_CM_HANDSHAKE) :
1868 (cval & ~SM_CM_HANDSHAKE);
1873 else if ((*pch == 'N') || (*pch == 'n'))
1875 if (_DtWmStringsAreEqual (pch, CM_NONE_STR, len))
1877 /* don't bother adding or subtracting nothing */
1888 * If we didn't match anything then set to default.
1892 cval = SM_CM_DEFAULT;
1896 (*toVal).size = sizeof (long);
1897 (*toVal).addr = (caddr_t) &cval;
1900 } /* END OF FUNCTION SmCvtStringToContManagement */
1903 /*************************************<->*************************************
1905 * _DtNextToken (pchIn, pLen, ppchNext)
1915 * pchIn = pointer to start of next token
1920 * pLen = pointer to integer containing number of characters in next token
1921 * ppchNext = address of pointer to following token
1923 * Return = next token or NULL
1930 *************************************<->***********************************/
1932 unsigned char *_DtNextToken (unsigned char *pchIn, int *pLen,
1933 unsigned char **ppchNext)
1935 unsigned char *pchR = pchIn;
1941 for (i = 0; ((chlen = mblen ((char *)pchIn, MB_CUR_MAX)) > 0); i++)
1942 /* find end of word: requires singlebyte whitespace terminator */
1944 if ((chlen == 1) && isspace (*pchIn))
1952 for (i = 0; *pchIn && !isspace (*pchIn); i++, pchIn++)
1953 /* find end of word */
1958 /* skip to next word */
1959 ScanWhitespace (&pchIn);
1972 } /* END OF FUNCTION _DtNextToken */
1976 /*************************************<->*************************************
1978 * _DtWmStringsAreEqual (pch1, pch2, len)
1995 * Return = (Boolean) True iff strings match (case insensitive)
2002 *************************************<->***********************************/
2004 Boolean _DtWmStringsAreEqual (unsigned char *pch1, unsigned char *pch2, int len)
2013 ((chlen1 = mbtowc (&wch1, (char *) pch1, 2)) > 0) &&
2014 ((chlen2 = mbtowc (&wch2, (char *) pch2, 2)) == chlen1) )
2017 /* singlebyte characters -- make case insensitive */
2019 if ((isupper (*pch1) ? tolower(*pch1) : *pch1) !=
2020 (isupper (*pch2) ? tolower(*pch2) : *pch2))
2026 /* multibyte characters */
2039 while (len && *pch1 && *pch2 &&
2040 ((isupper (*pch1) ? tolower(*pch1) : *pch1) ==
2041 (isupper (*pch2) ? tolower(*pch2) : *pch2)))
2051 } /* END OF _DtWmStringsAreEqual */
2053 /*************************************<->*************************************
2055 * InitializeGenericSession - set the smGD paths using the CDE 1.0
2056 * session starting algorithm.
2060 * Initializes several variables in smGD
2073 *************************************<->***********************************/
2075 InitializeGenericSession (
2076 Display *tmpDisplay)
2079 int session_needed = 1;
2081 char tmpPath[MAXPATHLEN];
2083 smGD.savePath = _DtCreateDtDirs(tmpDisplay);
2087 strcpy(smGD.clientPath, smGD.savePath);
2088 strcat(smGD.clientPath, "/");
2089 strcat(smGD.clientPath, SM_CURRENT_DIRECTORY);
2090 strcat(smGD.clientPath, "/");
2091 strcpy (tmpPath, smGD.clientPath);
2092 strcat(smGD.clientPath, SM_CLIENT_FILE2);
2094 status = stat(smGD.clientPath, &buf);
2097 strcpy (smGD.clientPath, tmpPath);
2098 strcat (smGD.clientPath, SM_CLIENT_FILE);
2099 status = stat(smGD.clientPath, &buf);
2105 * sessions/current/dt.settings exist, restore to 'current' session
2107 strcpy(smGD.resourcePath, smGD.savePath);
2108 strcat(smGD.resourcePath, "/");
2109 strcat(smGD.resourcePath, SM_CURRENT_DIRECTORY);
2110 strcat(smGD.resourcePath, "/");
2111 strcat(smGD.resourcePath, SM_RESOURCE_FILE);
2112 strcpy(smGD.settingPath, smGD.savePath);
2113 strcat(smGD.settingPath, "/");
2114 strcat(smGD.settingPath, SM_CURRENT_DIRECTORY);
2115 strcat(smGD.settingPath, "/");
2116 strcat(smGD.settingPath, SM_SETTING_FILE);
2118 smGD.sessionType = CURRENT_SESSION;
2119 smGD.restoreSession = (char *) SM_CURRENT_DIRECTORY;
2126 strcpy(smGD.clientPath, smGD.savePath);
2127 strcat(smGD.clientPath, "/");
2128 strcat(smGD.clientPath, SM_HOME_DIRECTORY);
2129 strcat(smGD.clientPath, "/");
2130 strcpy(tmpPath, smGD.clientPath);
2131 strcat(smGD.clientPath, SM_CLIENT_FILE2);
2133 status = stat(smGD.clientPath, &buf);
2136 strcpy (smGD.clientPath, tmpPath);
2137 strcat (smGD.clientPath, SM_CLIENT_FILE);
2138 status = stat(smGD.clientPath, &buf);
2144 * sessions/home/dt.settings exist, restore to 'home' session
2146 strcpy(smGD.resourcePath, smGD.savePath);
2147 strcat(smGD.resourcePath, "/");
2148 strcat(smGD.resourcePath, SM_HOME_DIRECTORY);
2149 strcat(smGD.resourcePath, "/");
2150 strcat(smGD.resourcePath, SM_RESOURCE_FILE);
2151 strcpy(smGD.settingPath, smGD.savePath);
2152 strcat(smGD.settingPath, "/");
2153 strcat(smGD.settingPath, SM_HOME_DIRECTORY);
2154 strcat(smGD.settingPath, "/");
2155 strcat(smGD.settingPath, SM_SETTING_FILE);
2157 smGD.sessionType = HOME_SESSION;
2158 smGD.restoreSession = (char *) SM_HOME_DIRECTORY;
2169 /*************************************<->*************************************
2171 * InternSessionDir - intern the session dir property and put it
2172 * on the root window
2174 * NOTE: - also checks the validity of the -session command line
2179 * session_option - as given in the command line
2184 * smGD.restoreSession - initialized
2188 *************************************<->***********************************/
2191 char *session_option,
2196 if (!strcmp (session_option, SM_CURRENT_DIRECTORY)) {
2197 pch = DtSM_SESSION_DIRECTORY;
2198 smGD.restoreSession = SM_CURRENT_DIRECTORY;
2200 else if (!strcmp (session_option, SM_HOME_DIRECTORY)) {
2201 pch = DtSM_SESSION_DIRECTORY;
2202 smGD.restoreSession = SM_HOME_DIRECTORY;
2204 else if (!strcmp (session_option, SM_DISPLAY_HOME)) {
2205 pch = DtSM_SESSION_DISPLAY_DIRECTORY;
2206 smGD.restoreSession = SM_HOME_DIRECTORY;
2208 else if (!strcmp (session_option, SM_DISPLAY_CURRENT)) {
2209 pch = DtSM_SESSION_DISPLAY_DIRECTORY;
2210 smGD.restoreSession = SM_CURRENT_DIRECTORY;
2214 * The session_option is not supported
2218 XaSmRestoreDir = XInternAtom(disp, _XA_DT_RESTORE_DIR, False);
2220 XChangeProperty(disp, RootWindow(disp, 0),
2221 XaSmRestoreDir, XA_STRING, 8, PropModeReplace,
2222 (unsigned char *)pch, strlen(pch));
2231 /*************************************<->*************************************
2233 * InitializeSpecificSession - set the smGD paths based on the session
2234 * name given on the command line.
2238 * Initializes several variables in smGD
2252 *************************************<->***********************************/
2254 InitializeSpecificSession (
2255 char *session_option,
2260 char *session_dir = (char *) XtMalloc(MAXPATHLEN);
2261 char *alt_dir = (char *) XtMalloc(MAXPATHLEN);
2265 if (!InternSessionDir (session_option, disp))
2268 InitializePaths (smGD.restoreSession, disp);
2270 if (!strcmp (session_option, SM_HOME_DIRECTORY)) {
2274 if (smGD.clientPath[0] == '\0') {
2275 if ((stat (smGD.savePath, &buf)) != 0) {
2276 if ((mkdir (smGD.savePath, 0000)) == 0)
2277 (void) chmod (smGD.savePath, 0755);
2279 PrintErrnoError(DtError,
2280 smNLS.cantCreateDirsString);
2284 smGD.sessionType = HOME_SESSION;
2285 smGD.restoreSession = SM_HOME_DIRECTORY;
2287 else if (!strcmp (session_option, SM_CURRENT_DIRECTORY)) {
2291 if (smGD.clientPath[0] == '\0') {
2293 * Fallback to the generic home session
2295 (void) sprintf (session_dir, "%s/%s",
2296 smGD.savePath, SM_CURRENT_DIRECTORY);
2297 (void) sprintf (alt_dir, "%s/%s",
2298 smGD.savePath, SM_HOME_DIRECTORY);
2300 if (!SetAlternateSession (session_dir, alt_dir, True))
2303 smGD.sessionType = CURRENT_SESSION;
2304 smGD.restoreSession = SM_CURRENT_DIRECTORY;
2306 else if (!strcmp (session_option, SM_DISPLAY_HOME)) {
2308 * Display-specific Home session
2310 (void) sprintf (session_dir, "%s/%s",
2311 smGD.savePath, SM_HOME_DIRECTORY);
2313 if ((stat(session_dir, &buf)) != 0){
2315 * The session does not exist, give the user a
2318 if (!ConfirmSessionCreation (HOME_SESSION, argc, argv))
2323 if (smGD.clientPath[0] == '\0') {
2325 * Fallback to the generic home session
2329 if ((home = getenv ("HOME")) == 0)
2332 /* JET - VU#497553 */
2333 len = strlen(home) +
2334 strlen(DtPERSONAL_CONFIG_DIRECTORY) +
2335 strlen(DtSM_SESSION_DIRECTORY) +
2336 strlen(SM_HOME_DIRECTORY);
2338 if (len > MAXPATHLEN)
2339 alt_dir = XtRealloc(alt_dir, len + 1);
2341 (void) sprintf (alt_dir, "%s/%s/%s/%s",
2343 DtPERSONAL_CONFIG_DIRECTORY,
2344 DtSM_SESSION_DIRECTORY,
2346 if (!SetAlternateSession (session_dir, alt_dir, True))
2349 smGD.sessionType = HOME_SESSION;
2350 smGD.restoreSession = SM_HOME_DIRECTORY;
2352 else if (!strcmp (session_option, SM_DISPLAY_CURRENT)) {
2354 * Display-specific Current session
2356 (void) sprintf (session_dir, "%s/%s",
2357 smGD.savePath, SM_CURRENT_DIRECTORY);
2359 if ((stat(session_dir, &buf)) != 0){
2361 * The session does not exist, give the user a
2364 if (!ConfirmSessionCreation (CURRENT_SESSION, argc, argv))
2368 if (smGD.clientPath[0] == '\0') {
2370 * First, fallback to the display-specific home session
2374 (void) sprintf (alt_dir, "%s/%s",
2375 smGD.savePath, SM_HOME_DIRECTORY);
2377 if (!SetAlternateSession (session_dir, alt_dir, False)){
2379 * Try the generic home session
2381 if ((home = getenv ("HOME")) == 0)
2384 /* JET - VU#497553 */
2385 len = strlen(home) +
2386 strlen(DtPERSONAL_CONFIG_DIRECTORY) +
2387 strlen(DtSM_SESSION_DIRECTORY) +
2388 strlen(SM_HOME_DIRECTORY);
2390 if (len > MAXPATHLEN)
2391 alt_dir = XtRealloc(alt_dir, len + 1);
2393 snprintf(alt_dir, len, "%s/%s/%s/%s",
2395 DtPERSONAL_CONFIG_DIRECTORY,
2396 DtSM_SESSION_DIRECTORY,
2399 if (!SetAlternateSession (session_dir,
2405 smGD.sessionType = CURRENT_SESSION;
2406 smGD.restoreSession = SM_CURRENT_DIRECTORY;
2409 if (session_dir) XtFree(session_dir);
2410 if (alt_dir) XtFree(alt_dir);
2414 if (session_dir) XtFree(session_dir);
2415 if (alt_dir) XtFree(alt_dir);
2420 /*************************************<->*************************************
2426 * Initializes the following variables:
2431 * smGD.clientPath - [0] = '\0' if the database files do not exist
2435 * session_name = "current" or "home"
2444 *************************************<->***********************************/
2447 char * session_name,
2450 char *db_file = (char *) XtMalloc(MAXPATHLEN);
2455 PrintError(DtError, smNLS.cantMallocErrorString);
2459 smGD.savePath = _DtCreateDtDirs(disp);
2461 (void) sprintf (smGD.settingPath, "%s/%s/%s",
2462 smGD.savePath, session_name, SM_SETTING_FILE);
2464 (void) sprintf (smGD.resourcePath, "%s/%s/%s",
2465 smGD.savePath, session_name, SM_RESOURCE_FILE);
2468 smGD.clientPath[0] = '\0';
2470 (void) sprintf (db_file, "%s/%s/%s",
2471 smGD.savePath, session_name, SM_CLIENT_FILE2);
2473 if ((stat(db_file, &buf)) == 0)
2474 (void) strcpy (smGD.clientPath, db_file);
2476 (void) sprintf (db_file, "%s/%s/%s",
2477 smGD.savePath, session_name, SM_CLIENT_FILE);
2478 if ((stat(db_file, &buf)) == 0)
2479 (void) strcpy (smGD.clientPath, db_file);
2485 /*************************************<->*************************************
2487 * SetAlternateSession
2491 * Neither of the client databases in the session_dir directory
2496 * session_dir - the directory path for the session including home
2498 * alt_dir - the directory to use in the search for an alternate
2499 * or fallback session database
2500 * make_dir - if True, a session_dir will be created if it does not
2501 * exits; if False, session_dir will not be created
2507 *************************************<->***********************************/
2509 SetAlternateSession (
2514 char *tmp_dir = NULL;
2515 char *db_file1 = (char *) XtMalloc(MAXPATHLEN);
2516 char *db_file2 = (char *) XtMalloc(MAXPATHLEN);
2519 if (!db_file1 || !db_file2)
2521 PrintError(DtError, smNLS.cantMallocErrorString);
2526 if ((stat (session_dir, &buf)) != 0) {
2528 * The requested dir does not exist, create it
2529 * by either copying the session from alt_dir (if
2530 * it exists and has a client database) or by
2534 (void) sprintf (db_file1, "%s/%s",
2535 alt_dir, SM_CLIENT_FILE2);
2536 (void) sprintf (db_file2, "%s/%s",
2537 alt_dir, SM_CLIENT_FILE);
2539 if ((stat(db_file1, &buf)) == 0)
2541 else if ((stat(db_file2, &buf)) == 0)
2544 if (!tmp_dir && !make_dir) {
2545 if (db_file1) XtFree(db_file1);
2546 if (db_file2) XtFree(db_file2);
2548 * This alt_dir doesn't have a session database
2549 * return now and try another directory
2556 * The alt_dir has a session database, create
2557 * a copy of its entire directory because all
2558 * of the sessions state is needed.
2562 tmp = XtMalloc (strlen (alt_dir) +
2563 strlen (session_dir) + 10);
2567 (void) sprintf (tmp, "cp -r %s %s",
2568 alt_dir, session_dir);
2570 if ((system (tmp)) == -1)
2574 if ((stat(session_dir, &buf)) != 0)
2576 * It should have been created by the cp
2581 * The session database needs to be updated.
2583 if (tmp_dir == db_file1)
2584 sprintf (smGD.clientPath, "%s/%s",
2585 session_dir, SM_CLIENT_FILE2);
2587 sprintf (smGD.clientPath, "%s/%s",
2588 session_dir, SM_CLIENT_FILE);
2591 * The alt_dir did not have a session database.
2592 * Create a directory and load the system defaults
2594 if ((mkdir (session_dir, 0000)) == 0)
2595 (void) chmod (session_dir, 0755);
2597 PrintErrnoError(DtError,
2598 smNLS.cantCreateDirsString);
2605 * The directory for the specified session exists
2606 * but it doesn't have any client databases. Start
2607 * a new user session. If a user wants a session
2608 * with no apps, they should create a zero-length
2624 /* JET - needed to rework this to avoid exiting before we are
2627 if (smGD.ExitComplete)
2629 if (smXSMP.saveState.saveComplete &&
2630 smXSMP.saveState.shutdown &&
2631 !smXSMP.saveState.shutdownCanceled)
2640 SetSIGPIPEToDefault (void)
2642 struct sigaction pipeSig;
2644 sigemptyset(&pipeSig.sa_mask);
2645 pipeSig.sa_flags = 0;
2646 pipeSig.sa_handler = SIG_DFL;
2647 (void) sigaction(SIGPIPE, &pipeSig, (struct sigaction *) NULL);