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 librararies 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 *************************************<+>*************************************/
62 #include <sys/types.h>
63 #include <sys/utsname.h>
66 #include <X11/apollosys.h> /* for pid_t, in hp-ux sys/types.h */
69 #include <sys/param.h>
70 #include <X11/Intrinsic.h>
71 #include <X11/Xutil.h>
72 #include <X11/StringDefs.h>
75 #include <Dt/SessionP.h>
78 #include <Dt/UserMsg.h>
79 #include <Dt/HourGlass.h>
80 #include <Dt/SessionM.h>
81 #include <Dt/EnvControlP.h>
82 #include <Dt/Qualify.h>
83 #include <Dt/MsgLog.h>
85 #include "SmResource.h"
88 #include "SmGlobals.h"
90 #include "SmRestore.h"
91 #include "SmProtocol.h"
95 * Internal Variable Declaraions
97 static char savedDir [MAXPATHLEN];
98 static char savedOldDir [MAXPATHLEN];
99 static char savedTmpDir [MAXPATHLEN];
102 * Internal Function Declaraions
105 static int SetSysDefaults( void ) ;
106 static int SetResSet( void ) ;
107 static void RemoveFiles( char *) ;
108 static void TrimErrorlog(void);
110 static void _SmWaitClientTimeoutDefault (
115 static void _SmWaitWmTimeoutDefault (
120 void SmCvtStringToContManagement (
126 unsigned char *_DtNextToken (
127 unsigned char *pchIn,
129 unsigned char **ppchNext);
131 Boolean _DtWmStringsAreEqual (
136 static Boolean InitializeSpecificSession (
142 static void InitializeGenericSession (
145 static void InitializePaths (
146 char *session_option,
149 static Boolean SetAlternateSession (
159 * These are the global structures used throughout dtsession
160 * They are defined in Sm.h
162 SessionResources smRes;
163 SaverResources smSaverRes;
166 SessionSettings smSettings;
168 char SM_SCREEN_SAVER_LOC [MAXPATHLEN + 1];
171 * Internal Global Data
173 static char tmpDisplayName[MAXPATHLEN + 1];
176 static XtResource sessionResources[]=
178 {SmNwmStartup, SmCwmStartup, XtRString, sizeof(String),
179 XtOffset(SessionResourcesPtr, wmStartup),
180 XtRImmediate, (XtPointer) NULL},
181 {SmNquerySettings, SmCquerySettings, XtRBoolean, sizeof(Boolean),
182 XtOffset(SessionResourcesPtr, querySettings),
183 XtRImmediate, (XtPointer) False},
184 {SmNkeys, SmCkeys, XtRString, sizeof(String),
185 XtOffset(SessionResourcesPtr, keyholders), XtRString, NULL},
186 {SmNalarmTime, SmCalarmTime, XtRInt, sizeof(int),
187 XtOffset(SessionResourcesPtr, alarmTime),
188 XtRImmediate, (XtPointer) 10},
189 {SmNmemThreshold, SmCmemThreshold, XtRInt, sizeof(int),
190 XtOffset(SessionResourcesPtr, memThreshold),
191 XtRImmediate, (XtPointer) 100},
192 {SmNsessionVersion, SmCsessionVersion, XtRString, sizeof(String),
193 XtOffset(SessionResourcesPtr, sessionVersion),
194 XtRImmediate, (XtPointer) NULL},
195 {SmNdisplayResolution, SmCdisplayResolution, XtRInt, sizeof(int),
196 XtOffset(SessionResourcesPtr, displayResolution),
197 XtRImmediate, (XtPointer) 0},
198 {SmNsessionLang, SmCsessionLang, XtRString, sizeof(String),
199 XtOffset(SessionResourcesPtr, sessionLang),
200 XtRImmediate, (XtPointer) ""},
201 {SmNcontManagement, SmCContManagement, SmRContManagement, sizeof(long),
202 XtOffset(SessionResourcesPtr, contManagement),
203 XtRImmediate, (XtPointer) (SM_CM_DEFAULT)},
204 {SmNwaitClientTimeout, SmCWaitClientTimeout, XtRInt, sizeof(int),
205 XtOffset(SessionResourcesPtr, waitClientTimeout),
206 XtRCallProc, (XtPointer)_SmWaitClientTimeoutDefault },
207 {SmNwaitWmTimeout, SmCWaitWmTimeout, XtRInt, sizeof(int),
208 XtOffset(SessionResourcesPtr, waitWmTimeout),
209 XtRCallProc, (XtPointer)_SmWaitWmTimeoutDefault },
210 {SmNuseMessaging, SmCUseMessaging, XtRBoolean, sizeof(Boolean),
211 XtOffset(SessionResourcesPtr, useBMS),
212 XtRImmediate, (XtPointer) True},
213 {SmNsaveFontPath, SmCsaveFontPath, XtRBoolean, sizeof(Boolean),
214 XtOffset(SessionResourcesPtr, saveFontPath),
215 XtRImmediate, (XtPointer) False},
216 {SmNsaveYourselfTimeout, SmCsaveYourselfTimeout, XtRInt, sizeof(int),
217 XtOffset(SessionResourcesPtr, saveYourselfTimeout),
218 XtRImmediate, (XtPointer) 5},
219 {SmNnumSessionsBackedup, SmCnumSessionsBackedup, XtRInt, sizeof(int),
220 XtOffset(SessionResourcesPtr, numSessionsBackedup),
221 XtRImmediate, (XtPointer) DEFAULT_NUM_SESSIONS_BACKED_UP},
222 {SmNignoreEnvironment, SmCignoreEnvironment, XtRString, sizeof(String),
223 XtOffset(SessionResourcesPtr, ignoreEnvironment),
224 XtRImmediate, (XtPointer) NULL},
225 #if defined(USE_XINERAMA) /* JET - Xinerama */
226 {SmNxineramaPreferredScreen, SmCxineramaPreferredScreen, XtRInt, sizeof(int),
227 XtOffset(SessionResourcesPtr, xineramaPreferredScreen),
228 XtRImmediate, (XtPointer) 0},
235 static XtResource saverResources[]=
237 {SmNcycleTimeout, SmCcycleTimeout, XtRInt, sizeof(int),
238 XtOffset(SaverResourcesPtr, cycleTimeout),
239 XtRImmediate, (XtPointer) -1},
240 {SmNlockTimeout, SmClockTimeout, XtRInt, sizeof(int),
241 XtOffset(SaverResourcesPtr, lockTimeout),
242 XtRImmediate, (XtPointer) -1},
243 {SmNsaverTimeout, SmCsaverTimeout, XtRInt, sizeof(int),
244 XtOffset(SaverResourcesPtr, saverTimeout),
245 XtRImmediate, (XtPointer) -1},
246 {SmNrandom, SmCrandom, XtRBoolean, sizeof(Boolean),
247 XtOffset(SaverResourcesPtr, random),
248 XtRImmediate, (XtPointer) False},
249 {SmNsaverList, SmCsaverList, XtRString, sizeof(String),
250 XtOffset(SaverResourcesPtr, saverList),
251 XtRImmediate, (XtPointer) ""},
259 * Machine specific defaults.
269 { 0, 20, 60}, /* Machine independent default */
271 {300, 10, 60}, /* HP s300 */
272 {400, 10, 60}, /* HP s400 */
273 {600, 5, 60}, /* HP s600 */
274 {700, 5, 60}, /* HP s700 */
275 {800, 5, 60}, /* HP s800 */
278 #define MACHINEDEFAULTS (sizeof(machineDefault) / sizeof(machineDefault[0]))
281 /*************************************<->*************************************
283 * _SmWaitClientTimeoutDefault (widget, offset, value)
288 * This function generates a default value for the waitClientTimeout resource.
289 * We dynamically default to 10 seconds for s400/s300 and to
290 * 5 seconds for s700/s800.
294 * widget = this is not used
296 * offset = this is the resource offset
298 * value = this is a pointer to a XrmValue in which to store the result
302 * value = default resource value and size
304 *************************************<->***********************************/
307 _SmWaitClientTimeoutDefault (Widget widget, int offset, XrmValue *value)
311 for (i = 0; i < MACHINEDEFAULTS; i++)
313 if (machineDefault[i].machineType == machineType)
319 if (i == MACHINEDEFAULTS)
324 value->addr = (char *)&machineDefault[i].clientTimeout;
325 value->size = sizeof (int);
327 } /* END OF FUNCTION _SmWaitClientTimeoutDefault */
331 /*************************************<->*************************************
333 * _SmWaitWmTimeoutDefault (widget, offset, value)
338 * This function generates a default value for the waitWmTimeout resource.
339 * We dynamically default to 60 seconds for s400/s300 and to
340 * 60 seconds for s700/s800. This could change if we get feedback indicating
341 * the need for a new default.
345 * widget = this is not used
347 * offset = this is the resource offset
349 * value = this is a pointer to a XrmValue in which to store the result
353 * value = default resource value and size
355 *************************************<->***********************************/
358 _SmWaitWmTimeoutDefault (Widget widget, int offset, XrmValue *value)
362 smGD.userSetWaitWmTimeout = False; /* if we are here, it is not user set */
364 for (i = 0; i < MACHINEDEFAULTS; i++)
366 if (machineDefault[i].machineType == machineType)
372 if (i == MACHINEDEFAULTS)
377 value->addr = (char *)&machineDefault[i].wmTimeout;
378 value->size = sizeof (int);
380 } /* END OF FUNCTION _SmWaitWmTimeoutDefault */
384 /*************************************<->*************************************
391 * Sets SM global resources and global settings to a starting value.
396 * buttonForm = form widget for button that allows cursor to get colors
397 * smRes(global) = structure that holds session resources.
398 * smToSet(global) = structure that holds "which settings to set and how" info
399 * smGD(global) = structure that holds general data info
403 * smRes(global) = structure that holds session resources.
404 * smToSet(global) = structure that holds "which settings to set and how" info
405 * smGD(global) = structure that holds general data info
409 * Resources are set to an initial value by the resource manager. The
410 * rest are set in the routine.
412 *************************************<->***********************************/
414 InitSMGlobals( void )
417 PropDtSmWindowInfo property;
418 struct utsname nameRec;
422 smGD.userSetWaitWmTimeout = True; /* assume it is */
425 if (uname(&nameRec) == 0)
427 keyNum = nameRec.machine;
428 if (firstSlash = strchr(keyNum, '/'))
430 keyNum = ++firstSlash;
432 if ( keyNum[0] == '3')
436 else if (keyNum[0] == '4')
440 else if (keyNum[0] == '6')
444 else if (keyNum[0] == '7')
448 else if (keyNum[0] == '8')
457 * Get application specific resource values
459 XtAppAddConverter (smGD.appCon, XtRString, SmRContManagement,
460 (XtConverter)SmCvtStringToContManagement, NULL, 0);
461 XtGetApplicationResources(smGD.topLevelWid, (XtPointer) &smRes,
463 XtNumber(sessionResources), NULL, 0);
465 if (smGD.lockOnTimeoutStatus == True)
468 * Pull screen saver resources from Dtsession*extension.<name>.
470 smGD.SmNextension = "extension";
471 smGD.SmCextension = "Extension";
472 smGD.extensionSpec = "extension.";
477 * Pull screen saver resources from Dtsession*<name>.
479 smGD.SmNextension = smGD.SmCextension = smGD.extensionSpec = "";
482 XtGetSubresources(smGD.topLevelWid, (XtPointer) &smSaverRes,
483 smGD.SmNextension, smGD.SmCextension,
485 XtNumber(saverResources), NULL, 0);
487 smGD.wmStartup = SmNewString(smRes.wmStartup);
488 smGD.keyholders = SmNewString(smRes.keyholders);
489 smGD.sessionLang = SmNewString(smRes.sessionLang);
490 smGD.saverList = SmNewString(smSaverRes.saverList);
493 * Initialize general data used by apps not initialized by
494 * XtInitialize or DtInitialize
496 smGD.topLevelWindow = XtWindow(smGD.topLevelWid);
497 smGD.numSavedScreens = (ScreenCount(smGD.display) > MAX_SCREENS_SAVED)
498 ? MAX_SCREENS_SAVED : ScreenCount(smGD.display);
499 smGD.dtwmRunning = False;
500 smSettings.confirmMode = DtSM_VERBOSE_MODE;
501 if (smGD.sessionType == CURRENT_SESSION ||
502 smGD.sessionType == DEFAULT_SESSION)
503 smSettings.startState = DtSM_CURRENT_STATE;
505 smSettings.startState = DtSM_HOME_STATE;
506 smGD.homeSave = False;
507 smGD.saverListParse = NULL;
509 smGD.loggingOut = False;
512 * Sanity check on timeouts for negative numbers
514 if (smRes.waitClientTimeout < 0)
516 smRes.waitClientTimeout = -smRes.waitClientTimeout;
518 if (smRes.waitWmTimeout < 0)
520 smRes.waitWmTimeout = -smRes.waitWmTimeout;
522 if (smRes.saveYourselfTimeout < 0)
524 smRes.saveYourselfTimeout = -smRes.saveYourselfTimeout;
529 * Now convert users view of seconds in to XtAppAddTimout's
530 * need for milliseconds.
532 smRes.waitClientTimeout = 1000 * smRes.waitClientTimeout;
533 smRes.waitWmTimeout = 1000 * smRes.waitWmTimeout;
534 smRes.saveYourselfTimeout = 1000 * smRes.saveYourselfTimeout;
535 smGD.savedWaitWmTimeout = smRes.waitWmTimeout;
538 * Initialize lock data
540 smGD.screen = XDefaultScreen(smGD.display);
541 smGD.blackPixel = XBlackPixel(smGD.display, smGD.screen);
542 smGD.whitePixel = XWhitePixel(smGD.display, smGD.screen);
543 smDD.lockDialog = NULL;
544 smDD.lockCoverDialog = NULL;
545 for(i = 0;i < smGD.numSavedScreens;i++)
547 smDD.coverDialog[i] = NULL;
548 smDD.coverDrawing[i] = NULL;
550 smGD.lockedState = UNLOCKED;
553 * Sanity check screen saver resource values.
555 if (smRes.alarmTime < 0) smRes.alarmTime = 0;
557 #define SMBOUND(A) (A < 0 ? 0 : A)
559 smSaverRes.lockTimeout = SMBOUND(smSaverRes.lockTimeout) * 60;
560 smSaverRes.saverTimeout = SMBOUND(smSaverRes.saverTimeout) * 60;
561 smSaverRes.cycleTimeout = SMBOUND(smSaverRes.cycleTimeout) * 60;
564 smGD.waitCursor = _DtGetHourGlassCursor(smGD.display);
567 * Initialize other global data related to dialogs
569 smDD.confExit = NULL;
571 smDD.compatExit = NULL;
573 smDD.saveSession = NULL; /* Error dialog for Save_Session */
575 if (!smDD.smHelpDialog)
577 * Don't wipe it out if it is already created
579 smDD.smHelpDialog = NULL;
582 * Intern all the atoms needed for the WSM communication
585 enum { XA_DT_SM_WINDOW_INFO, XA_DT_SM_WM_PROTOCOL,
586 XA_DT_SM_START_ACK_WINDOWS, XA_DT_SM_STOP_ACK_WINDOWS,
587 XA_DT_WM_WINDOW_ACK, XA_DT_WM_EXIT_SESSION,
588 XA_DT_WM_LOCK_DISPLAY, XA_DT_WM_READY, NUM_ATOMS };
589 static char *atom_names[] = {
590 _XA_DT_SM_WINDOW_INFO, _XA_DT_SM_WM_PROTOCOL,
591 _XA_DT_SM_START_ACK_WINDOWS, _XA_DT_SM_STOP_ACK_WINDOWS,
592 _XA_DT_WM_WINDOW_ACK, _XA_DT_WM_EXIT_SESSION,
593 _XA_DT_WM_LOCK_DISPLAY, _XA_DT_WM_READY };
595 Atom atoms[XtNumber(atom_names)];
597 XInternAtoms(smGD.display, atom_names, XtNumber(atom_names),
600 XaVsmInfo = atoms[XA_DT_SM_WINDOW_INFO];
601 XaSmWmProtocol = atoms[XA_DT_SM_WM_PROTOCOL];
602 XaSmStartAckWindow = atoms[XA_DT_SM_START_ACK_WINDOWS];
603 XaSmStopAckWindow = atoms[XA_DT_SM_STOP_ACK_WINDOWS];
604 XaWmWindowAck = atoms[XA_DT_WM_WINDOW_ACK];
605 XaWmExitSession = atoms[XA_DT_WM_EXIT_SESSION];
606 XaWmLockDisplay = atoms[XA_DT_WM_LOCK_DISPLAY];
607 XaWmReady = atoms[XA_DT_WM_READY];
611 * Set the session manager window property on the root window
614 property.smWindow = (unsigned long) smGD.topLevelWindow;
615 XChangeProperty (smGD.display, RootWindow(smGD.display, 0),
616 XaVsmInfo, XaVsmInfo,
617 32, PropModeReplace, (unsigned char *)&property,
618 PROP_DT_SM_WINDOW_INFO_ELEMENTS);
621 * Set up the signal handler for forking and execing
623 sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
628 /*************************************<->*************************************
635 * Sets SM global resources and global settings to a starting value.
640 * smGD.display = display structure for session manager. Used to construct
641 * a display directory
645 * smGD.resourcePath(global) = Path where the resources to be restored are
647 * smGD.settingPath(global) = Path where the settings to be restored are
649 * smGD.clientPath(global) = Path where the clients to be restored are
651 * smGD.savePath(global) = Path where all save files are to be saved
659 * WARNING: This routine also determines whether dtsession is being started
660 * in compatibility mode. If so - no restore paths are set up and
661 * the routine is exited.
663 *************************************<->***********************************/
671 char *displayName = NULL;
672 char *session_option = NULL;
674 smGD.compatMode = False;
676 for(i = 0;i < argc;i++)
678 if(!strcmp(argv[i], "-display"))
680 displayName = argv[i + 1];
682 * If -display is used but DISPLAY is not set,
683 * put DISPLAY into the environment
685 if (getenv("DISPLAY") == 0)
687 snprintf(tmpDisplayName, MAXPATHLEN, "DISPLAY=%s", displayName);
688 putenv(tmpDisplayName);
692 if(!strcmp(argv[i], "-norestore"))
694 smGD.compatMode = True;
697 if(!strcmp(argv[i], "-session"))
704 pch = strdup ((char *) GETMESSAGE (40, 15,
705 " No session name was provided for the -session command line option."));
708 DtMsgLogMessage (argv[0], DtMsgLogWarning, pch);
713 session_option = argv[i];
718 * If we are in compatibility mode - no restore paths are set
719 * up and we just return
721 if(smGD.compatMode == True)
723 smGD.clientPath[0] = 0;
724 smGD.resourcePath[0] = 0;
725 smGD.settingPath[0] = 0;
726 smGD.sessionType = DEFAULT_SESSION;
727 smGD.restoreSession = NULL;
731 tmpDisplay = XOpenDisplay(displayName);
732 if(tmpDisplay == NULL)
734 PrintError(DtError, GETMESSAGE(4, 1, "Invalid display name - exiting."));
740 if (!InitializeSpecificSession (session_option, tmpDisplay, argc, argv))
741 InitializeGenericSession (tmpDisplay);
744 InitializeGenericSession (tmpDisplay);
747 * Need to know if the session is for a specific display
749 smGD.displaySpecific = True;
750 if (session_option = strrchr (smGD.savePath, '/'))
753 if (!strcmp (session_option, DtSM_SESSION_DIRECTORY))
754 smGD.displaySpecific = False;
758 XCloseDisplay(tmpDisplay);
761 ** User's session startup script:
762 ** $HOME/.dt/sessions/sessionetc
764 strcpy(smGD.etcPath, smGD.savePath);
765 strcat(smGD.etcPath, "/");
766 strcat(smGD.etcPath, smEtcFile);
769 ** User's session shutdown script:
770 ** $HOME/.dt/sessions/sessionexit
772 strcpy(smGD.exitPath, smGD.savePath);
773 strcat(smGD.exitPath, "/");
774 strcat(smGD.exitPath, smExitFile);
786 char * pathList = (char *)XtMalloc(strlen(SM_SYSTEM_PATH) +
787 strlen(":" CDE_INSTALLATION_TOP "/config") + 1);
789 strcpy(pathList,SM_SYSTEM_PATH);
790 strcat(pathList,":" CDE_INSTALLATION_TOP "/config");
792 tempPath = _DtQualifyWithFirst(the1stPath,pathList);
793 if (tempPath != NULL) {
794 strcpy(the1stPath,tempPath);
802 /*************************************<->*************************************
809 * Sets the path to restore the system default files. A convenience routine
814 * smGD.savePath = path that files are to be saved in (set up in
819 * smGD.resourcePath(global) = Path where the resources to be saved are
821 * smGD.settingPath(global) = Path where the settings to be saved are
823 * smGD.clientPath(global) = Path where the clients to be saved are
829 *************************************<->***********************************/
831 SetSysDefaults( void )
840 * No files exist for restoration - use the
843 strcpy(smGD.resourcePath, "");
844 strcpy(smGD.clientPath, "");
845 smGD.settingPath[0] = 0;
846 smGD.sessionType = DEFAULT_SESSION;
847 smGD.restoreSession = (char *) SM_SYSTEM_DIRECTORY;
849 langSpec = getenv("LANG");
850 if ((langSpec != NULL) && (*langSpec != 0))
852 strcat(smGD.clientPath, "/");
853 strncat(smGD.clientPath, langSpec, MAXPATHLEN-2);
854 smGD.clientPath[MAXPATHLEN-1] = 0;
857 strcat(smGD.clientPath, "/");
858 strcat(smGD.clientPath, SM_SYSTEM_CLIENT_FILE);
860 FixPath(smGD.clientPath);
863 * If the system files don't exist - we're in
864 * trouble - First try LANG location then default
866 status = stat(smGD.clientPath, &buf);
869 if((langSpec == NULL) || (*langSpec == 0))
871 PrintErrnoError(DtError, GETMESSAGE(4, 2,
872 "No defaults files exist. "
873 "No applications will be restarted."));
874 smGD.clientPath[0] = 0;
875 smGD.resourcePath[0] = 0;
879 strcpy(smGD.clientPath, "/C/");
880 strcat(smGD.clientPath, SM_SYSTEM_CLIENT_FILE);
882 FixPath(smGD.clientPath);
884 status = stat(smGD.clientPath, &buf);
887 PrintErrnoError(DtError, GETMESSAGE(4, 3,
888 "No defaults files exist. "
889 "No applications will be restarted."));
890 smGD.clientPath[0] = 0;
891 smGD.resourcePath[0] = 0;
901 /*************************************<->*************************************
908 * Sets the path to restore the settings and resource files.
909 * A convenience routine
914 * smGD.savePath = path that files are to be saved in (set up in
919 * smGD.resourcePath(global) = Path where the resources to be saved are
921 * smGD.settingPath(global) = Path where the settings to be saved are
923 * smGD.clientPath(global) = Path where the clients to be saved are
929 *************************************<->***********************************/
937 * If resource or settings file does not exist - just null out
938 * the path so these things will not get restored
940 status = stat(smGD.resourcePath, &buf);
943 smGD.resourcePath[0] = 0;
946 status = stat(smGD.settingPath, &buf);
949 smGD.settingPath[0] = 0;
955 /*************************************<->*************************************
957 * UndoSetSavePath () - Undoes the directory manipulations done by
958 * SetSavePath. This function is only called if a shutdown/save
961 *************************************<->***********************************/
967 if (strcmp ("", savedDir)) {
970 * Remove the directory where the save occurred, e.g.:
972 * ~/.dt/<session_dir>/current
973 * ~/.dt/<session_dir>/home
975 buf = XtMalloc (strlen (savedDir) + 9);
976 sprintf (buf, "rm -rf %s", savedDir);
980 if (strcmp ("", savedOldDir)) {
982 MoveDirectory (savedOldDir, savedDir, False);
984 if (strcmp ("", savedTmpDir)) {
985 MoveDirectory (savedTmpDir, savedOldDir, False);
992 /*************************************<->*************************************
994 * SetSavePath (saveToHome, mode)
999 * Sets up paths for files that need to be saved. Also removes any files
1000 * that shouldn't be there after the save.
1005 * smGD.display = display structure for session manager. Used to construct
1006 * a display directory
1007 * saveToHome = whether this is a save to home session or not
1008 * mode = whether we are resetting or restarting
1012 * smGD.resourcePath(global) = Path where the resources to be saved are
1014 * smGD.settingPath(global) = Path where the settings to be saved are
1016 * smGD.clientPath(global) = Path where the clients to be saved are
1022 *************************************<->***********************************/
1032 * These directory paths are needed in UndoSetSavePaths
1033 * if a shutdown/save is canceled.
1035 strcpy (savedDir, "");
1036 strcpy (savedOldDir, "");
1037 strcpy (savedTmpDir, "");
1040 * Make sure the user hasn't done something like delete the .dt
1041 * directories during the session. If so - recreate them
1043 SM_FREE(smGD.savePath);
1044 smGD.savePath = _DtCreateDtDirs(smGD.display);
1045 if(smGD.savePath == NULL)
1047 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1048 smGD.clientPath[0] = 0;
1049 smGD.settingPath[0] = 0;
1050 smGD.resourcePath[0] = 0;
1056 * Path for a save defaults to save the current session.
1057 * Otherwise just remove the directories
1059 strcpy(smGD.clientPath, smGD.savePath);
1060 strcpy(smGD.settingPath, smGD.savePath);
1061 strcpy(smGD.resourcePath, smGD.savePath);
1062 strcat(smGD.clientPath, "/");
1063 strcat(smGD.settingPath, "/");
1064 strcat(smGD.resourcePath, "/");
1066 if(saveToHome == False)
1068 strcat(smGD.clientPath, SM_CURRENT_DIRECTORY);
1069 strcat(smGD.resourcePath, SM_CURRENT_DIRECTORY);
1070 strcat(smGD.settingPath, SM_CURRENT_DIRECTORY);
1071 smGD.restoreSession = SM_CURRENT_DIRECTORY;
1075 strcat(smGD.clientPath, SM_HOME_DIRECTORY);
1076 strcat(smGD.resourcePath, SM_HOME_DIRECTORY);
1077 strcat(smGD.settingPath, SM_HOME_DIRECTORY);
1078 smGD.restoreSession = SM_HOME_DIRECTORY;
1081 if ((mode == DtSM_HOME_STATE) && (saveToHome == False) &&
1082 (smSettings.startState == DtSM_HOME_STATE))
1085 * The only time this should should be true is if the
1086 * current session is a Home session and the session
1087 * is being exited. The idea is that if a "current"
1088 * directory exits, it must be moved because when the
1089 * user next logs in, a Home session should be started
1090 * (if a session is not selected at the login screen)
1091 * and the Session Manager decides whether or not it
1092 * starts a Home or Current session based on if a
1093 * "current" directory exists. If a "current" directory
1094 * exists, a Current session will be started.
1096 status = stat(smGD.clientPath, &buf);
1100 * The "current" directory exists and must be moved to its
1101 * ".old" version. But first, if the ".old" version exists,
1102 * it must be moved to a temporary directory. This temporary
1103 * directory will eventually be pruned - when a user next
1104 * runs a Current session and saves the session.
1106 strcpy (savedDir, smGD.clientPath);
1107 sprintf(smGD.etcPath, "%s.%s", smGD.clientPath, SM_OLD_EXTENSION);
1108 status = stat(smGD.etcPath, &buf);
1114 strcpy(savedOldDir, smGD.etcPath);
1116 len = strlen(smGD.savePath) + strlen(smGD.restoreSession)
1117 + strlen("XXXXXX") + 3;
1118 tmpName = (char *) XtCalloc(1, len);
1120 sprintf(tmpName, "%s/%s.XXXXXX", smGD.savePath,
1121 smGD.restoreSession);
1123 if ((tfd = mkstemp(tmpName)) == -1)
1125 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1132 MoveDirectory(smGD.etcPath, tmpName, False);
1134 strncpy(savedTmpDir, tmpName, len - 1);
1136 XtFree((char *) tmpName);
1138 MoveDirectory(smGD.clientPath, smGD.etcPath, False);
1141 smGD.clientPath[0] = 0;
1142 smGD.settingPath[0] = 0;
1143 smGD.resourcePath[0] = 0;
1147 strcpy (savedDir, smGD.clientPath);
1150 * If the desired directory doesn't exist, create it.
1152 status = stat(smGD.clientPath, &buf);
1155 status = mkdir(smGD.clientPath, 0000);
1158 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1159 smGD.clientPath[0] = 0;
1160 smGD.settingPath[0] = 0;
1161 smGD.resourcePath[0] = 0;
1164 chmod(smGD.clientPath, 0755);
1169 * The desired directory already exists so it must
1170 * be archived by moving it to its ".old" version. But
1171 * first, if its ".old" version already exists, it must
1172 * be moved to a temporary directory that will be removed
1173 * when the session directories are pruned - after the
1178 sprintf(smGD.etcPath, "%s.%s", smGD.clientPath, SM_OLD_EXTENSION);
1179 status = stat(smGD.etcPath, &buf);
1184 len = strlen(smGD.savePath) + strlen(smGD.restoreSession)
1185 + strlen("XXXXXX") + 3;
1186 tmpName = (char *) XtCalloc(1, len);
1187 sprintf(tmpName, "%s/%s.XXXXXX", smGD.savePath,
1188 smGD.restoreSession);
1190 strcpy (savedOldDir, smGD.etcPath);
1192 if ((tfd = mkstemp(tmpName)) == -1)
1194 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1201 MoveDirectory (smGD.etcPath, tmpName, False);
1203 strcpy (savedTmpDir, tmpName);
1205 XtFree((char *) tmpName);
1208 MoveDirectory(smGD.clientPath, smGD.etcPath, False);
1211 * Now re-make the directory
1213 status = mkdir(smGD.clientPath, 0000);
1216 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1217 smGD.clientPath[0] = 0;
1218 smGD.settingPath[0] = 0;
1219 smGD.resourcePath[0] = 0;
1222 status = chmod(smGD.clientPath, 0755);
1225 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1226 smGD.clientPath[0] = 0;
1227 smGD.settingPath[0] = 0;
1228 smGD.resourcePath[0] = 0;
1233 strcat(smGD.clientPath, "/");
1234 strcat(smGD.clientPath, SM_CLIENT_FILE2);
1235 strcat(smGD.settingPath, "/");
1236 strcat(smGD.settingPath, SM_SETTING_FILE);
1237 strcat(smGD.resourcePath, "/");
1238 strcat(smGD.resourcePath, SM_RESOURCE_FILE);
1245 /*************************************<->*************************************
1247 * SetFontSavePath (saveToHome, mode)
1252 * Sets up the save path for the auxillary directory.
1264 *************************************<->***********************************/
1266 SetFontSavePath(char *langPtr)
1274 * Set up the session font directory and see if it exists
1276 if(smGD.sessionType == CURRENT_SESSION)
1278 sessionSaved = SM_CURRENT_FONT_DIRECTORY;
1282 sessionSaved = SM_HOME_FONT_DIRECTORY;
1285 snprintf(smGD.fontPath, MAXPATHLEN, "%s/%s", smGD.savePath, sessionSaved);
1286 status = stat(smGD.fontPath, &buf);
1289 status = mkdir(smGD.fontPath, 0000);
1292 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1293 smGD.fontPath[0] = 0;
1296 chmod(smGD.fontPath, 0755);
1300 * Now add the lang subdirectory and see if it exists
1302 strncat(smGD.fontPath, "/", MAXPATHLEN);
1303 strncat(smGD.fontPath, langPtr, MAXPATHLEN);
1304 status = stat(smGD.fontPath, &buf);
1307 status = mkdir(smGD.fontPath, 0000);
1310 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1311 smGD.fontPath[0] = 0;
1314 status = chmod(smGD.fontPath, 0755);
1317 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1318 smGD.fontPath[0] = 0;
1328 /*************************************<->*************************************
1335 * Remove the files that need to be removed
1348 *************************************<->***********************************/
1354 int execStatus, childStatus, i, statLoc;
1358 * Fork and exec the client process
1360 sigaction(SIGCHLD, &smGD.defvec, (struct sigaction *) NULL);
1362 clientFork = vfork();
1365 * If the fork fails - Send out an error and return
1369 PrintErrnoError(DtError, smNLS.cantForkClientString);
1374 * Fork succeeded - now do the exec
1378 SetSIGPIPEToDefault ();
1381 * Set the gid of the process back from bin
1385 setregid(smGD.runningGID, smGD.runningGID);
1387 setgid(smGD.runningGID);
1388 setegid(smGD.runningGID);
1392 _DtEnvControl(DT_ENV_RESTORE_PRE_DT);
1394 #if defined(__osf__) || defined(CSRG_BASED)
1398 #endif /* __osf__ */
1400 execStatus = execlp("rm","rm", "-rf", path, (char *) 0);
1403 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.")) ;
1404 PrintErrnoError(DtError, tmpString);
1410 while(wait(&statLoc) != clientFork);
1412 sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
1416 /*************************************<->*************************************
1422 * Move the directory specified by pathFrom - to the directory specified
1427 * pathFrom = the directory to move from
1428 * pathTo = the directory to move to
1429 * removeDestDir = if True, directory pathTo is removed before the
1438 *************************************<->***********************************/
1443 Boolean removeDestDir)
1447 int status, execStatus, childStatus, i, statLoc;
1451 * If the pathTo directory exists - remove it
1455 status = stat(pathTo, &buf);
1458 RemoveFiles(pathTo);
1463 * Fork and exec the client process
1465 sigaction(SIGCHLD, &smGD.defvec, (struct sigaction *) NULL);
1467 clientFork = vfork();
1470 * If the fork fails - Send out an error and return
1474 PrintErrnoError(DtError, smNLS.cantForkClientString);
1479 * Fork succeeded - now do the exec
1483 SetSIGPIPEToDefault ();
1486 * Set the gid of the process back from bin
1490 setregid(smGD.runningGID, smGD.runningGID);
1492 setgid(smGD.runningGID);
1493 setegid(smGD.runningGID);
1497 _DtEnvControl(DT_ENV_RESTORE_PRE_DT);
1499 #if defined(__osf__) || defined(CSRG_BASED)
1503 #endif /* __osf__ */
1505 execStatus = execlp("mv","mv", pathFrom, pathTo, (char *) 0);
1508 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.")) ;
1509 PrintErrnoError(DtError, tmpString);
1515 while(wait(&statLoc) != clientFork);
1517 sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
1522 /*************************************<->*************************************
1529 * Initialize the NLS strings used in dtsession
1542 *************************************<->***********************************/
1544 InitNlsStrings( void )
1549 * Malloc failure error message - THIS MESSAGE MUST BE INITIALIZED FIRST
1551 smNLS.cantMallocErrorString = strdup (((char *)GETMESSAGE(4, 5, "Unable to malloc memory for operation.")));
1554 * Error message when dtsession cant lock the display
1556 smNLS.cantLockErrorString = strdup (((char *)GETMESSAGE(4, 6, "Unable to lock display. Another application may have the pointer or keyboard grabbed.")));
1559 * Error message when dtsession cant open files for reading or writing
1561 smNLS.cantOpenFileString = strdup (((char *)GETMESSAGE(4, 7, "Unable to open session file. No clients will be restarted.")));
1564 * Error message when dtsession cant fork client process
1566 smNLS.cantForkClientString = strdup (((char *)GETMESSAGE(4, 8, "Unable to fork client process.")));
1569 * Error message when dtsession cant create dt directories
1571 smNLS.cantCreateDirsString = strdup (((char *)GETMESSAGE(4, 9, "Unable to create DT directories. Check permissions on home directory.")));
1574 * Error message when trying to lock display on trusted system
1576 smNLS.trustedSystemErrorString = strdup (((char *)GETMESSAGE(4, 10, "Unable to lock display due to security restrictions")));
1581 /*************************************<->*************************************
1588 * When a SIGCHLD signal comes in, wait for all child processes to die.
1601 *************************************<->***********************************/
1604 WaitChildDeath( int i )
1610 * Wait on any children that have died since the last SIGCHLD we
1611 * received. Any child process death that occurs while we are
1612 * in WaitChildDeath() will not result in a SIGCHLD. Any
1613 * child proceses that die after our last call to waitpid() will
1614 * remain zombiefied until the next invocation of WaitChildDeath().
1616 while ((pid = waitpid(-1, &stat_loc, WNOHANG)) > 0)
1619 sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
1624 /*************************************<->*************************************
1631 * Trim the errorlog file using the following algorithm:
1632 * if(errorlog.old exists and is not empty) move it to errorlog.oldest
1633 * if(errorlog exists and is not empty) move it to errorlog.old
1646 *************************************<->***********************************/
1648 TrimErrorlog( void )
1650 char *savePath, /* common path element for all pathnames */
1658 * Allocate the strings needed
1660 savePath = (char *) SM_MALLOC(MAXPATHLEN + 1);
1661 checkPath1 = (char *) SM_MALLOC(MAXPATHLEN + 1);
1662 checkPath2 = (char *) SM_MALLOC(MAXPATHLEN + 1);
1663 if ((home=getenv("HOME")) == NULL)
1666 len = strlen(home) + strlen(DtPERSONAL_CONFIG_DIRECTORY) + 2;
1667 if (len > MAXPATHLEN) savePath = SM_REALLOC(savePath, len);
1668 snprintf(savePath, len - 1, "%s/%s", home, DtPERSONAL_CONFIG_DIRECTORY);
1671 * If errorlog.old exists and it is not empty, delete
1672 * errorlog.older and then move errolog.old to
1675 if (len + strlen(DtOLDER_ERRORLOG_FILE) > MAXPATHLEN)
1676 checkPath1 = SM_REALLOC(savePath, len + strlen(DtOLDER_ERRORLOG_FILE));
1677 sprintf(checkPath1, "%s/%s", savePath, DtOLDER_ERRORLOG_FILE);
1679 if (len + strlen(DtOLD_ERRORLOG_FILE) > MAXPATHLEN)
1680 checkPath2 = SM_REALLOC(savePath, len + strlen(DtOLD_ERRORLOG_FILE));
1681 sprintf(checkPath2, "%s/%s", savePath, DtOLD_ERRORLOG_FILE);
1683 status = stat(checkPath2, &buf);
1684 if((status != -1) && (buf.st_size > 0))
1686 (void) unlink(checkPath1);
1687 (void) link(checkPath2, checkPath1);
1688 (void) unlink(checkPath2);
1692 * If errorlog exists and it is not empty, move it to
1695 if (len + strlen(DtERRORLOG_FILE) > MAXPATHLEN)
1696 checkPath1 = SM_REALLOC(savePath, len + strlen(DtERRORLOG_FILE));
1697 sprintf(checkPath1, "%s/%s", savePath, DtERRORLOG_FILE);
1699 status = stat(checkPath1, &buf);
1700 if((status != -1) && (buf.st_size > 0))
1702 (void) link(checkPath1, checkPath2);
1703 (void) unlink(checkPath1);
1706 SM_FREE((char *) savePath);
1707 SM_FREE((char *) checkPath1);
1708 SM_FREE((char *) checkPath2);
1715 /*************************************<->*************************************
1722 * Do everything that needs to be done to get the system back into a
1723 * READY state. This includes checking to be sure that the BMS did not
1724 * die while we were in process
1737 *************************************<->***********************************/
1739 SetSystemReady( void )
1741 smGD.smState = READY;
1742 if(smGD.bmsDead == True)
1751 /*************************************<->*************************************
1753 * SmCvtStringToContManagement (args, numArgs, fromVal, toVal)
1758 * This function converts a string to a value for the
1759 * contention management flag set.
1764 * args = additional XrmValue arguments to the converter - NULL here
1766 * numArgs = number of XrmValue arguments - 0 here
1768 * fromVal = resource value to convert
1773 * toVal = descriptor to use to return converted value
1775 *************************************<->***********************************/
1777 void SmCvtStringToContManagement (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
1780 unsigned char *pch = (unsigned char *) (fromVal->addr);
1781 unsigned char *pchNext;
1784 Boolean fHit = False;
1785 Boolean fAddNext = True;
1788 * Names of contention management options
1791 #define CM_ALL_STR (unsigned char *)"all"
1792 #define CM_SYSTEM_STR (unsigned char *)"system"
1793 #define CM_HANDSHAKE_STR (unsigned char *)"handshake"
1794 #define CM_NONE_STR (unsigned char *)"none"
1797 * Check first token. If '-' we subtract from all options.
1798 * Otherwise, we start with no contention management and add things in.
1802 (_DtNextToken (pch, &len, &pchNext)) &&
1813 while (*pch && _DtNextToken (pch, &len, &pchNext))
1816 * Strip off "sign" if prepended to another token, and process
1817 * that token the next time through.
1829 else if (*pch == '-')
1838 if ((*pch == 'A') || (*pch == 'a'))
1840 if (_DtWmStringsAreEqual (pch, CM_ALL_STR, len))
1842 cval = fAddNext ? (cval | SM_CM_ALL) :
1843 (cval & ~SM_CM_ALL);
1848 else if ((*pch == 'S') || (*pch == 's'))
1850 if (_DtWmStringsAreEqual (pch, CM_SYSTEM_STR, len))
1852 cval = fAddNext ? (cval | SM_CM_SYSTEM) :
1853 (cval & ~SM_CM_SYSTEM);
1858 else if ((*pch == 'H') || (*pch == 'h'))
1860 if (_DtWmStringsAreEqual (pch, CM_HANDSHAKE_STR, len))
1862 cval = fAddNext ? (cval | SM_CM_HANDSHAKE) :
1863 (cval & ~SM_CM_HANDSHAKE);
1868 else if ((*pch == 'N') || (*pch == 'n'))
1870 if (_DtWmStringsAreEqual (pch, CM_NONE_STR, len))
1872 /* don't bother adding or subtracting nothing */
1883 * If we didn't match anything then set to default.
1887 cval = SM_CM_DEFAULT;
1891 (*toVal).size = sizeof (long);
1892 (*toVal).addr = (caddr_t) &cval;
1895 } /* END OF FUNCTION SmCvtStringToContManagement */
1898 /*************************************<->*************************************
1900 * _DtNextToken (pchIn, pLen, ppchNext)
1910 * pchIn = pointer to start of next token
1915 * pLen = pointer to integer containing number of characters in next token
1916 * ppchNext = address of pointer to following token
1918 * Return = next token or NULL
1925 *************************************<->***********************************/
1927 unsigned char *_DtNextToken (unsigned char *pchIn, int *pLen,
1928 unsigned char **ppchNext)
1930 unsigned char *pchR = pchIn;
1936 for (i = 0; ((chlen = mblen ((char *)pchIn, MB_CUR_MAX)) > 0); i++)
1937 /* find end of word: requires singlebyte whitespace terminator */
1939 if ((chlen == 1) && isspace (*pchIn))
1947 for (i = 0; *pchIn && !isspace (*pchIn); i++, pchIn++)
1948 /* find end of word */
1953 /* skip to next word */
1954 ScanWhitespace (&pchIn);
1967 } /* END OF FUNCTION _DtNextToken */
1971 /*************************************<->*************************************
1973 * _DtWmStringsAreEqual (pch1, pch2, len)
1990 * Return = (Boolean) True iff strings match (case insensitive)
1997 *************************************<->***********************************/
1999 Boolean _DtWmStringsAreEqual (unsigned char *pch1, unsigned char *pch2, int len)
2008 ((chlen1 = mbtowc (&wch1, (char *) pch1, 2)) > 0) &&
2009 ((chlen2 = mbtowc (&wch2, (char *) pch2, 2)) == chlen1) )
2012 /* singlebyte characters -- make case insensitive */
2014 if ((isupper (*pch1) ? tolower(*pch1) : *pch1) !=
2015 (isupper (*pch2) ? tolower(*pch2) : *pch2))
2021 /* multibyte characters */
2034 while (len && *pch1 && *pch2 &&
2035 ((isupper (*pch1) ? tolower(*pch1) : *pch1) ==
2036 (isupper (*pch2) ? tolower(*pch2) : *pch2)))
2046 } /* END OF _DtWmStringsAreEqual */
2048 /*************************************<->*************************************
2050 * InitializeGenericSession - set the smGD paths using the CDE 1.0
2051 * session starting algorithm.
2055 * Initializes several variables in smGD
2068 *************************************<->***********************************/
2070 InitializeGenericSession (
2071 Display *tmpDisplay)
2074 int session_needed = 1;
2076 char tmpPath[MAXPATHLEN];
2078 smGD.savePath = _DtCreateDtDirs(tmpDisplay);
2082 strcpy(smGD.clientPath, smGD.savePath);
2083 strcat(smGD.clientPath, "/");
2084 strcat(smGD.clientPath, SM_CURRENT_DIRECTORY);
2085 strcat(smGD.clientPath, "/");
2086 strcpy (tmpPath, smGD.clientPath);
2087 strcat(smGD.clientPath, SM_CLIENT_FILE2);
2089 status = stat(smGD.clientPath, &buf);
2092 strcpy (smGD.clientPath, tmpPath);
2093 strcat (smGD.clientPath, SM_CLIENT_FILE);
2094 status = stat(smGD.clientPath, &buf);
2100 * sessions/current/dt.settings exist, restore to 'current' session
2102 strcpy(smGD.resourcePath, smGD.savePath);
2103 strcat(smGD.resourcePath, "/");
2104 strcat(smGD.resourcePath, SM_CURRENT_DIRECTORY);
2105 strcat(smGD.resourcePath, "/");
2106 strcat(smGD.resourcePath, SM_RESOURCE_FILE);
2107 strcpy(smGD.settingPath, smGD.savePath);
2108 strcat(smGD.settingPath, "/");
2109 strcat(smGD.settingPath, SM_CURRENT_DIRECTORY);
2110 strcat(smGD.settingPath, "/");
2111 strcat(smGD.settingPath, SM_SETTING_FILE);
2113 smGD.sessionType = CURRENT_SESSION;
2114 smGD.restoreSession = (char *) SM_CURRENT_DIRECTORY;
2121 strcpy(smGD.clientPath, smGD.savePath);
2122 strcat(smGD.clientPath, "/");
2123 strcat(smGD.clientPath, SM_HOME_DIRECTORY);
2124 strcat(smGD.clientPath, "/");
2125 strcpy(tmpPath, smGD.clientPath);
2126 strcat(smGD.clientPath, SM_CLIENT_FILE2);
2128 status = stat(smGD.clientPath, &buf);
2131 strcpy (smGD.clientPath, tmpPath);
2132 strcat (smGD.clientPath, SM_CLIENT_FILE);
2133 status = stat(smGD.clientPath, &buf);
2139 * sessions/home/dt.settings exist, restore to 'home' session
2141 strcpy(smGD.resourcePath, smGD.savePath);
2142 strcat(smGD.resourcePath, "/");
2143 strcat(smGD.resourcePath, SM_HOME_DIRECTORY);
2144 strcat(smGD.resourcePath, "/");
2145 strcat(smGD.resourcePath, SM_RESOURCE_FILE);
2146 strcpy(smGD.settingPath, smGD.savePath);
2147 strcat(smGD.settingPath, "/");
2148 strcat(smGD.settingPath, SM_HOME_DIRECTORY);
2149 strcat(smGD.settingPath, "/");
2150 strcat(smGD.settingPath, SM_SETTING_FILE);
2152 smGD.sessionType = HOME_SESSION;
2153 smGD.restoreSession = (char *) SM_HOME_DIRECTORY;
2164 /*************************************<->*************************************
2166 * InternSessionDir - intern the session dir property and put it
2167 * on the root window
2169 * NOTE: - also checks the validity of the -session command line
2174 * session_option - as given in the command line
2179 * smGD.restoreSession - initialized
2183 *************************************<->***********************************/
2186 char *session_option,
2191 if (!strcmp (session_option, SM_CURRENT_DIRECTORY)) {
2192 pch = DtSM_SESSION_DIRECTORY;
2193 smGD.restoreSession = SM_CURRENT_DIRECTORY;
2195 else if (!strcmp (session_option, SM_HOME_DIRECTORY)) {
2196 pch = DtSM_SESSION_DIRECTORY;
2197 smGD.restoreSession = SM_HOME_DIRECTORY;
2199 else if (!strcmp (session_option, SM_DISPLAY_HOME)) {
2200 pch = DtSM_SESSION_DISPLAY_DIRECTORY;
2201 smGD.restoreSession = SM_HOME_DIRECTORY;
2203 else if (!strcmp (session_option, SM_DISPLAY_CURRENT)) {
2204 pch = DtSM_SESSION_DISPLAY_DIRECTORY;
2205 smGD.restoreSession = SM_CURRENT_DIRECTORY;
2209 * The session_option is not supported
2213 XaSmRestoreDir = XInternAtom(disp, _XA_DT_RESTORE_DIR, False);
2215 XChangeProperty(disp, RootWindow(disp, 0),
2216 XaSmRestoreDir, XA_STRING, 8, PropModeReplace,
2217 (unsigned char *)pch, strlen(pch));
2226 /*************************************<->*************************************
2228 * InitializeSpecificSession - set the smGD paths based on the session
2229 * name given on the command line.
2233 * Initializes several variables in smGD
2247 *************************************<->***********************************/
2249 InitializeSpecificSession (
2250 char *session_option,
2255 char *session_dir = (char *) XtMalloc(MAXPATHLEN);
2256 char *alt_dir = (char *) XtMalloc(MAXPATHLEN);
2260 if (!InternSessionDir (session_option, disp))
2263 InitializePaths (smGD.restoreSession, disp);
2265 if (!strcmp (session_option, SM_HOME_DIRECTORY)) {
2269 if (smGD.clientPath[0] == '\0') {
2270 if ((stat (smGD.savePath, &buf)) != 0) {
2271 if ((mkdir (smGD.savePath, 0000)) == 0)
2272 (void) chmod (smGD.savePath, 0755);
2274 PrintErrnoError(DtError,
2275 smNLS.cantCreateDirsString);
2279 smGD.sessionType = HOME_SESSION;
2280 smGD.restoreSession = SM_HOME_DIRECTORY;
2282 else if (!strcmp (session_option, SM_CURRENT_DIRECTORY)) {
2286 if (smGD.clientPath[0] == '\0') {
2288 * Fallback to the generic home session
2290 (void) sprintf (session_dir, "%s/%s",
2291 smGD.savePath, SM_CURRENT_DIRECTORY);
2292 (void) sprintf (alt_dir, "%s/%s",
2293 smGD.savePath, SM_HOME_DIRECTORY);
2295 if (!SetAlternateSession (session_dir, alt_dir, True))
2298 smGD.sessionType = CURRENT_SESSION;
2299 smGD.restoreSession = SM_CURRENT_DIRECTORY;
2301 else if (!strcmp (session_option, SM_DISPLAY_HOME)) {
2303 * Display-specific Home session
2305 (void) sprintf (session_dir, "%s/%s",
2306 smGD.savePath, SM_HOME_DIRECTORY);
2308 if ((stat(session_dir, &buf)) != 0){
2310 * The session does not exist, give the user a
2313 if (!ConfirmSessionCreation (HOME_SESSION, argc, argv))
2318 if (smGD.clientPath[0] == '\0') {
2320 * Fallback to the generic home session
2324 if ((home = getenv ("HOME")) == 0)
2327 /* JET - VU#497553 */
2328 len = strlen(home) +
2329 strlen(DtPERSONAL_CONFIG_DIRECTORY) +
2330 strlen(DtSM_SESSION_DIRECTORY) +
2331 strlen(SM_HOME_DIRECTORY);
2333 if (len > MAXPATHLEN)
2334 alt_dir = XtRealloc(alt_dir, len + 1);
2336 (void) sprintf (alt_dir, "%s/%s/%s/%s",
2338 DtPERSONAL_CONFIG_DIRECTORY,
2339 DtSM_SESSION_DIRECTORY,
2341 if (!SetAlternateSession (session_dir, alt_dir, True))
2344 smGD.sessionType = HOME_SESSION;
2345 smGD.restoreSession = SM_HOME_DIRECTORY;
2347 else if (!strcmp (session_option, SM_DISPLAY_CURRENT)) {
2349 * Display-specific Current session
2351 (void) sprintf (session_dir, "%s/%s",
2352 smGD.savePath, SM_CURRENT_DIRECTORY);
2354 if ((stat(session_dir, &buf)) != 0){
2356 * The session does not exist, give the user a
2359 if (!ConfirmSessionCreation (CURRENT_SESSION, argc, argv))
2363 if (smGD.clientPath[0] == '\0') {
2365 * First, fallback to the display-specific home session
2369 (void) sprintf (alt_dir, "%s/%s",
2370 smGD.savePath, SM_HOME_DIRECTORY);
2372 if (!SetAlternateSession (session_dir, alt_dir, False)){
2374 * Try the generic home session
2376 if ((home = getenv ("HOME")) == 0)
2379 /* JET - VU#497553 */
2380 len = strlen(home) +
2381 strlen(DtPERSONAL_CONFIG_DIRECTORY) +
2382 strlen(DtSM_SESSION_DIRECTORY) +
2383 strlen(SM_HOME_DIRECTORY);
2385 if (len > MAXPATHLEN)
2386 alt_dir = XtRealloc(alt_dir, len + 1);
2388 snprintf(alt_dir, len, "%s/%s/%s/%s",
2390 DtPERSONAL_CONFIG_DIRECTORY,
2391 DtSM_SESSION_DIRECTORY,
2394 if (!SetAlternateSession (session_dir,
2400 smGD.sessionType = CURRENT_SESSION;
2401 smGD.restoreSession = SM_CURRENT_DIRECTORY;
2404 if (session_dir) XtFree(session_dir);
2405 if (alt_dir) XtFree(alt_dir);
2409 if (session_dir) XtFree(session_dir);
2410 if (alt_dir) XtFree(alt_dir);
2415 /*************************************<->*************************************
2421 * Initializes the following variables:
2426 * smGD.clientPath - [0] = '\0' if the database files do not exist
2430 * session_name = "current" or "home"
2439 *************************************<->***********************************/
2442 char * session_name,
2445 char *db_file = (char *) XtMalloc(MAXPATHLEN);
2450 PrintError(DtError, smNLS.cantMallocErrorString);
2454 smGD.savePath = _DtCreateDtDirs(disp);
2456 (void) sprintf (smGD.settingPath, "%s/%s/%s",
2457 smGD.savePath, session_name, SM_SETTING_FILE);
2459 (void) sprintf (smGD.resourcePath, "%s/%s/%s",
2460 smGD.savePath, session_name, SM_RESOURCE_FILE);
2463 smGD.clientPath[0] = '\0';
2465 (void) sprintf (db_file, "%s/%s/%s",
2466 smGD.savePath, session_name, SM_CLIENT_FILE2);
2468 if ((stat(db_file, &buf)) == 0)
2469 (void) strcpy (smGD.clientPath, db_file);
2471 (void) sprintf (db_file, "%s/%s/%s",
2472 smGD.savePath, session_name, SM_CLIENT_FILE);
2473 if ((stat(db_file, &buf)) == 0)
2474 (void) strcpy (smGD.clientPath, db_file);
2480 /*************************************<->*************************************
2482 * SetAlternateSession
2486 * Neither of the client databases in the session_dir directory
2491 * session_dir - the directory path for the session including home
2493 * alt_dir - the directory to use in the search for an alternate
2494 * or fallback session database
2495 * make_dir - if True, a session_dir will be created if it does not
2496 * exits; if False, session_dir will not be created
2502 *************************************<->***********************************/
2504 SetAlternateSession (
2509 char *tmp_dir = NULL;
2510 char *db_file1 = (char *) XtMalloc(MAXPATHLEN);
2511 char *db_file2 = (char *) XtMalloc(MAXPATHLEN);
2514 if (!db_file1 || !db_file2)
2516 PrintError(DtError, smNLS.cantMallocErrorString);
2521 if ((stat (session_dir, &buf)) != 0) {
2523 * The requested dir does not exist, create it
2524 * by either copying the session from alt_dir (if
2525 * it exists and has a client database) or by
2529 (void) sprintf (db_file1, "%s/%s",
2530 alt_dir, SM_CLIENT_FILE2);
2531 (void) sprintf (db_file2, "%s/%s",
2532 alt_dir, SM_CLIENT_FILE);
2534 if ((stat(db_file1, &buf)) == 0)
2536 else if ((stat(db_file2, &buf)) == 0)
2539 if (!tmp_dir && !make_dir) {
2540 if (db_file1) XtFree(db_file1);
2541 if (db_file2) XtFree(db_file2);
2543 * This alt_dir doesn't have a session database
2544 * return now and try another directory
2551 * The alt_dir has a session database, create
2552 * a copy of its entire directory because all
2553 * of the sessions state is needed.
2557 tmp = XtMalloc (strlen (alt_dir) +
2558 strlen (session_dir) + 10);
2562 (void) sprintf (tmp, "cp -r %s %s",
2563 alt_dir, session_dir);
2565 if ((system (tmp)) == -1)
2569 if ((stat(session_dir, &buf)) != 0)
2571 * It should have been created by the cp
2576 * The session database needs to be updated.
2578 if (tmp_dir == db_file1)
2579 sprintf (smGD.clientPath, "%s/%s",
2580 session_dir, SM_CLIENT_FILE2);
2582 sprintf (smGD.clientPath, "%s/%s",
2583 session_dir, SM_CLIENT_FILE);
2586 * The alt_dir did not have a session database.
2587 * Create a directory and load the system defaults
2589 if ((mkdir (session_dir, 0000)) == 0)
2590 (void) chmod (session_dir, 0755);
2592 PrintErrnoError(DtError,
2593 smNLS.cantCreateDirsString);
2600 * The directory for the specified session exists
2601 * but it doesn't have any client databases. Start
2602 * a new user session. If a user wants a sesssion
2603 * with no apps, they should create a zero-length
2619 /* JET - needed to rework this to avoid exiting before we are
2622 if (smGD.ExitComplete)
2624 if (smXSMP.saveState.saveComplete &&
2625 smXSMP.saveState.shutdown &&
2626 !smXSMP.saveState.shutdownCanceled)
2635 SetSIGPIPEToDefault ()
2637 struct sigaction pipeSig;
2639 sigemptyset(&pipeSig.sa_mask);
2640 pipeSig.sa_flags = 0;
2641 pipeSig.sa_handler = SIG_DFL;
2642 (void) sigaction(SIGPIPE, &pipeSig, (struct sigaction *) NULL);