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 <X11/apollosys.h> /* for pid_t, in hp-ux sys/types.h */
71 #include <sys/param.h>
72 #include <X11/Intrinsic.h>
73 #include <X11/Xutil.h>
74 #include <X11/StringDefs.h>
77 #include <Dt/SessionP.h>
80 #include <Dt/UserMsg.h>
81 #include <Dt/HourGlass.h>
82 #include <Dt/SessionM.h>
83 #include <Dt/EnvControlP.h>
84 #include <Dt/Qualify.h>
85 #include <Dt/MsgLog.h>
87 #include "SmResource.h"
90 #include "SmGlobals.h"
92 #include "SmRestore.h"
93 #include "SmProtocol.h"
97 * Internal Variable Declaraions
99 static char savedDir [MAXPATHLEN];
100 static char savedOldDir [MAXPATHLEN];
101 static char savedTmpDir [MAXPATHLEN];
104 * Internal Function Declaraions
107 static int SetSysDefaults( void ) ;
108 static int SetResSet( void ) ;
109 static void RemoveFiles( char *) ;
110 static void TrimErrorlog(void);
112 static void _SmWaitClientTimeoutDefault (
117 static void _SmWaitWmTimeoutDefault (
122 void SmCvtStringToContManagement (
128 unsigned char *_DtNextToken (
129 unsigned char *pchIn,
131 unsigned char **ppchNext);
133 Boolean _DtWmStringsAreEqual (
138 static Boolean InitializeSpecificSession (
144 static void InitializeGenericSession (
147 static void InitializePaths (
148 char *session_option,
151 static Boolean SetAlternateSession (
161 * These are the global structures used throughout dtsession
162 * They are defined in Sm.h
164 SessionResources smRes;
165 SaverResources smSaverRes;
168 SessionSettings smSettings;
170 char SM_SCREEN_SAVER_LOC [MAXPATHLEN + 1];
173 * Internal Global Data
175 static char tmpDisplayName[MAXPATHLEN + 1];
178 static XtResource sessionResources[]=
180 {SmNwmStartup, SmCwmStartup, XtRString, sizeof(String),
181 XtOffset(SessionResourcesPtr, wmStartup),
182 XtRImmediate, (XtPointer) NULL},
183 {SmNquerySettings, SmCquerySettings, XtRBoolean, sizeof(Boolean),
184 XtOffset(SessionResourcesPtr, querySettings),
185 XtRImmediate, (XtPointer) False},
186 {SmNkeys, SmCkeys, XtRString, sizeof(String),
187 XtOffset(SessionResourcesPtr, keyholders), XtRString, NULL},
188 {SmNalarmTime, SmCalarmTime, XtRInt, sizeof(int),
189 XtOffset(SessionResourcesPtr, alarmTime),
190 XtRImmediate, (XtPointer) 10},
191 {SmNmemThreshold, SmCmemThreshold, XtRInt, sizeof(int),
192 XtOffset(SessionResourcesPtr, memThreshold),
193 XtRImmediate, (XtPointer) 100},
194 {SmNsessionVersion, SmCsessionVersion, XtRString, sizeof(String),
195 XtOffset(SessionResourcesPtr, sessionVersion),
196 XtRImmediate, (XtPointer) NULL},
197 {SmNdisplayResolution, SmCdisplayResolution, XtRInt, sizeof(int),
198 XtOffset(SessionResourcesPtr, displayResolution),
199 XtRImmediate, (XtPointer) 0},
200 {SmNsessionLang, SmCsessionLang, XtRString, sizeof(String),
201 XtOffset(SessionResourcesPtr, sessionLang),
202 XtRImmediate, (XtPointer) ""},
203 {SmNcontManagement, SmCContManagement, SmRContManagement, sizeof(long),
204 XtOffset(SessionResourcesPtr, contManagement),
205 XtRImmediate, (XtPointer) (SM_CM_DEFAULT)},
206 {SmNwaitClientTimeout, SmCWaitClientTimeout, XtRInt, sizeof(int),
207 XtOffset(SessionResourcesPtr, waitClientTimeout),
208 XtRCallProc, (XtPointer)_SmWaitClientTimeoutDefault },
209 {SmNwaitWmTimeout, SmCWaitWmTimeout, XtRInt, sizeof(int),
210 XtOffset(SessionResourcesPtr, waitWmTimeout),
211 XtRCallProc, (XtPointer)_SmWaitWmTimeoutDefault },
212 {SmNuseMessaging, SmCUseMessaging, XtRBoolean, sizeof(Boolean),
213 XtOffset(SessionResourcesPtr, useBMS),
214 XtRImmediate, (XtPointer) True},
215 {SmNsaveFontPath, SmCsaveFontPath, XtRBoolean, sizeof(Boolean),
216 XtOffset(SessionResourcesPtr, saveFontPath),
217 XtRImmediate, (XtPointer) False},
218 {SmNsaveYourselfTimeout, SmCsaveYourselfTimeout, XtRInt, sizeof(int),
219 XtOffset(SessionResourcesPtr, saveYourselfTimeout),
220 XtRImmediate, (XtPointer) 5},
221 {SmNnumSessionsBackedup, SmCnumSessionsBackedup, XtRInt, sizeof(int),
222 XtOffset(SessionResourcesPtr, numSessionsBackedup),
223 XtRImmediate, (XtPointer) DEFAULT_NUM_SESSIONS_BACKED_UP},
224 {SmNignoreEnvironment, SmCignoreEnvironment, XtRString, sizeof(String),
225 XtOffset(SessionResourcesPtr, ignoreEnvironment),
226 XtRImmediate, (XtPointer) NULL},
227 #if defined(USE_XINERAMA) /* JET - Xinerama */
228 {SmNxineramaPreferredScreen, SmCxineramaPreferredScreen, XtRInt, sizeof(int),
229 XtOffset(SessionResourcesPtr, xineramaPreferredScreen),
230 XtRImmediate, (XtPointer) 0},
237 static XtResource saverResources[]=
239 {SmNcycleTimeout, SmCcycleTimeout, XtRInt, sizeof(int),
240 XtOffset(SaverResourcesPtr, cycleTimeout),
241 XtRImmediate, (XtPointer) -1},
242 {SmNlockTimeout, SmClockTimeout, XtRInt, sizeof(int),
243 XtOffset(SaverResourcesPtr, lockTimeout),
244 XtRImmediate, (XtPointer) -1},
245 {SmNsaverTimeout, SmCsaverTimeout, XtRInt, sizeof(int),
246 XtOffset(SaverResourcesPtr, saverTimeout),
247 XtRImmediate, (XtPointer) -1},
248 {SmNrandom, SmCrandom, XtRBoolean, sizeof(Boolean),
249 XtOffset(SaverResourcesPtr, random),
250 XtRImmediate, (XtPointer) False},
251 {SmNsaverList, SmCsaverList, XtRString, sizeof(String),
252 XtOffset(SaverResourcesPtr, saverList),
253 XtRImmediate, (XtPointer) ""},
261 * Machine specific defaults.
271 { 0, 20, 60}, /* Machine independent default */
273 {300, 10, 60}, /* HP s300 */
274 {400, 10, 60}, /* HP s400 */
275 {600, 5, 60}, /* HP s600 */
276 {700, 5, 60}, /* HP s700 */
277 {800, 5, 60}, /* HP s800 */
280 #define MACHINEDEFAULTS (sizeof(machineDefault) / sizeof(machineDefault[0]))
283 /*************************************<->*************************************
285 * _SmWaitClientTimeoutDefault (widget, offset, value)
290 * This function generates a default value for the waitClientTimeout resource.
291 * We dynamically default to 10 seconds for s400/s300 and to
292 * 5 seconds for s700/s800.
296 * widget = this is not used
298 * offset = this is the resource offset
300 * value = this is a pointer to a XrmValue in which to store the result
304 * value = default resource value and size
306 *************************************<->***********************************/
309 _SmWaitClientTimeoutDefault (Widget widget, int offset, XrmValue *value)
313 for (i = 0; i < MACHINEDEFAULTS; i++)
315 if (machineDefault[i].machineType == machineType)
321 if (i == MACHINEDEFAULTS)
326 value->addr = (char *)&machineDefault[i].clientTimeout;
327 value->size = sizeof (int);
329 } /* END OF FUNCTION _SmWaitClientTimeoutDefault */
333 /*************************************<->*************************************
335 * _SmWaitWmTimeoutDefault (widget, offset, value)
340 * This function generates a default value for the waitWmTimeout resource.
341 * We dynamically default to 60 seconds for s400/s300 and to
342 * 60 seconds for s700/s800. This could change if we get feedback indicating
343 * the need for a new default.
347 * widget = this is not used
349 * offset = this is the resource offset
351 * value = this is a pointer to a XrmValue in which to store the result
355 * value = default resource value and size
357 *************************************<->***********************************/
360 _SmWaitWmTimeoutDefault (Widget widget, int offset, XrmValue *value)
364 smGD.userSetWaitWmTimeout = False; /* if we are here, it is not user set */
366 for (i = 0; i < MACHINEDEFAULTS; i++)
368 if (machineDefault[i].machineType == machineType)
374 if (i == MACHINEDEFAULTS)
379 value->addr = (char *)&machineDefault[i].wmTimeout;
380 value->size = sizeof (int);
382 } /* END OF FUNCTION _SmWaitWmTimeoutDefault */
386 /*************************************<->*************************************
393 * Sets SM global resources and global settings to a starting value.
398 * buttonForm = form widget for button that allows cursor to get colors
399 * smRes(global) = structure that holds session resources.
400 * smToSet(global) = structure that holds "which settings to set and how" info
401 * smGD(global) = structure that holds general data info
405 * smRes(global) = structure that holds session resources.
406 * smToSet(global) = structure that holds "which settings to set and how" info
407 * smGD(global) = structure that holds general data info
411 * Resources are set to an initial value by the resource manager. The
412 * rest are set in the routine.
414 *************************************<->***********************************/
416 InitSMGlobals( void )
419 PropDtSmWindowInfo property;
420 struct utsname nameRec;
424 smGD.userSetWaitWmTimeout = True; /* assume it is */
427 if (uname(&nameRec) == 0)
429 keyNum = nameRec.machine;
430 if (firstSlash = strchr(keyNum, '/'))
432 keyNum = ++firstSlash;
434 if ( keyNum[0] == '3')
438 else if (keyNum[0] == '4')
442 else if (keyNum[0] == '6')
446 else if (keyNum[0] == '7')
450 else if (keyNum[0] == '8')
459 * Get application specific resource values
461 XtAppAddConverter (smGD.appCon, XtRString, SmRContManagement,
462 (XtConverter)SmCvtStringToContManagement, NULL, 0);
463 XtGetApplicationResources(smGD.topLevelWid, (XtPointer) &smRes,
465 XtNumber(sessionResources), NULL, 0);
467 if (smGD.lockOnTimeoutStatus == True)
470 * Pull screen saver resources from Dtsession*extension.<name>.
472 smGD.SmNextension = "extension";
473 smGD.SmCextension = "Extension";
474 smGD.extensionSpec = "extension.";
479 * Pull screen saver resources from Dtsession*<name>.
481 smGD.SmNextension = smGD.SmCextension = smGD.extensionSpec = "";
484 XtGetSubresources(smGD.topLevelWid, (XtPointer) &smSaverRes,
485 smGD.SmNextension, smGD.SmCextension,
487 XtNumber(saverResources), NULL, 0);
489 smGD.wmStartup = SmNewString(smRes.wmStartup);
490 smGD.keyholders = SmNewString(smRes.keyholders);
491 smGD.sessionLang = SmNewString(smRes.sessionLang);
492 smGD.saverList = SmNewString(smSaverRes.saverList);
495 * Initialize general data used by apps not initialized by
496 * XtInitialize or DtInitialize
498 smGD.topLevelWindow = XtWindow(smGD.topLevelWid);
499 smGD.numSavedScreens = (ScreenCount(smGD.display) > MAX_SCREENS_SAVED)
500 ? MAX_SCREENS_SAVED : ScreenCount(smGD.display);
501 smGD.dtwmRunning = False;
502 smSettings.confirmMode = DtSM_VERBOSE_MODE;
503 if (smGD.sessionType == CURRENT_SESSION ||
504 smGD.sessionType == DEFAULT_SESSION)
505 smSettings.startState = DtSM_CURRENT_STATE;
507 smSettings.startState = DtSM_HOME_STATE;
508 smGD.homeSave = False;
509 smGD.saverListParse = NULL;
511 smGD.loggingOut = False;
514 * Sanity check on timeouts for negative numbers
516 if (smRes.waitClientTimeout < 0)
518 smRes.waitClientTimeout = -smRes.waitClientTimeout;
520 if (smRes.waitWmTimeout < 0)
522 smRes.waitWmTimeout = -smRes.waitWmTimeout;
524 if (smRes.saveYourselfTimeout < 0)
526 smRes.saveYourselfTimeout = -smRes.saveYourselfTimeout;
531 * Now convert users view of seconds in to XtAppAddTimout's
532 * need for milliseconds.
534 smRes.waitClientTimeout = 1000 * smRes.waitClientTimeout;
535 smRes.waitWmTimeout = 1000 * smRes.waitWmTimeout;
536 smRes.saveYourselfTimeout = 1000 * smRes.saveYourselfTimeout;
537 smGD.savedWaitWmTimeout = smRes.waitWmTimeout;
540 * Initialize lock data
542 smGD.screen = XDefaultScreen(smGD.display);
543 smGD.blackPixel = XBlackPixel(smGD.display, smGD.screen);
544 smGD.whitePixel = XWhitePixel(smGD.display, smGD.screen);
545 smDD.lockDialog = NULL;
546 smDD.lockCoverDialog = NULL;
547 for(i = 0;i < smGD.numSavedScreens;i++)
549 smDD.coverDialog[i] = NULL;
550 smDD.coverDrawing[i] = NULL;
552 smGD.lockedState = UNLOCKED;
555 * Sanity check screen saver resource values.
557 if (smRes.alarmTime < 0) smRes.alarmTime = 0;
559 #define SMBOUND(A) (A < 0 ? 0 : A)
561 smSaverRes.lockTimeout = SMBOUND(smSaverRes.lockTimeout) * 60;
562 smSaverRes.saverTimeout = SMBOUND(smSaverRes.saverTimeout) * 60;
563 smSaverRes.cycleTimeout = SMBOUND(smSaverRes.cycleTimeout) * 60;
566 smGD.waitCursor = _DtGetHourGlassCursor(smGD.display);
569 * Initialize other global data related to dialogs
571 smDD.confExit = NULL;
573 smDD.compatExit = NULL;
575 smDD.saveSession = NULL; /* Error dialog for Save_Session */
577 if (!smDD.smHelpDialog)
579 * Don't wipe it out if it is already created
581 smDD.smHelpDialog = NULL;
584 * Intern all the atoms needed for the WSM communication
587 enum { XA_DT_SM_WINDOW_INFO, XA_DT_SM_WM_PROTOCOL,
588 XA_DT_SM_START_ACK_WINDOWS, XA_DT_SM_STOP_ACK_WINDOWS,
589 XA_DT_WM_WINDOW_ACK, XA_DT_WM_EXIT_SESSION,
590 XA_DT_WM_LOCK_DISPLAY, XA_DT_WM_READY, NUM_ATOMS };
591 static char *atom_names[] = {
592 _XA_DT_SM_WINDOW_INFO, _XA_DT_SM_WM_PROTOCOL,
593 _XA_DT_SM_START_ACK_WINDOWS, _XA_DT_SM_STOP_ACK_WINDOWS,
594 _XA_DT_WM_WINDOW_ACK, _XA_DT_WM_EXIT_SESSION,
595 _XA_DT_WM_LOCK_DISPLAY, _XA_DT_WM_READY };
597 Atom atoms[XtNumber(atom_names)];
599 XInternAtoms(smGD.display, atom_names, XtNumber(atom_names),
602 XaVsmInfo = atoms[XA_DT_SM_WINDOW_INFO];
603 XaSmWmProtocol = atoms[XA_DT_SM_WM_PROTOCOL];
604 XaSmStartAckWindow = atoms[XA_DT_SM_START_ACK_WINDOWS];
605 XaSmStopAckWindow = atoms[XA_DT_SM_STOP_ACK_WINDOWS];
606 XaWmWindowAck = atoms[XA_DT_WM_WINDOW_ACK];
607 XaWmExitSession = atoms[XA_DT_WM_EXIT_SESSION];
608 XaWmLockDisplay = atoms[XA_DT_WM_LOCK_DISPLAY];
609 XaWmReady = atoms[XA_DT_WM_READY];
613 * Set the session manager window property on the root window
616 property.smWindow = (unsigned long) smGD.topLevelWindow;
617 XChangeProperty (smGD.display, RootWindow(smGD.display, 0),
618 XaVsmInfo, XaVsmInfo,
619 32, PropModeReplace, (unsigned char *)&property,
620 PROP_DT_SM_WINDOW_INFO_ELEMENTS);
623 * Set up the signal handler for forking and execing
625 sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
630 /*************************************<->*************************************
637 * Sets SM global resources and global settings to a starting value.
642 * smGD.display = display structure for session manager. Used to construct
643 * a display directory
647 * smGD.resourcePath(global) = Path where the resources to be restored are
649 * smGD.settingPath(global) = Path where the settings to be restored are
651 * smGD.clientPath(global) = Path where the clients to be restored are
653 * smGD.savePath(global) = Path where all save files are to be saved
661 * WARNING: This routine also determines whether dtsession is being started
662 * in compatibility mode. If so - no restore paths are set up and
663 * the routine is exited.
665 *************************************<->***********************************/
673 char *displayName = NULL;
674 char *session_option = NULL;
676 smGD.compatMode = False;
678 for(i = 0;i < argc;i++)
680 if(!strcmp(argv[i], "-display"))
682 displayName = argv[i + 1];
684 * If -display is used but DISPLAY is not set,
685 * put DISPLAY into the environment
687 if (getenv("DISPLAY") == 0)
689 snprintf(tmpDisplayName, MAXPATHLEN, "DISPLAY=%s", displayName);
690 putenv(tmpDisplayName);
694 if(!strcmp(argv[i], "-norestore"))
696 smGD.compatMode = True;
699 if(!strcmp(argv[i], "-session"))
706 pch = strdup ((char *) GETMESSAGE (40, 15,
707 " No session name was provided for the -session command line option."));
710 DtMsgLogMessage (argv[0], DtMsgLogWarning, pch);
715 session_option = argv[i];
720 * If we are in compatibility mode - no restore paths are set
721 * up and we just return
723 if(smGD.compatMode == True)
725 smGD.clientPath[0] = 0;
726 smGD.resourcePath[0] = 0;
727 smGD.settingPath[0] = 0;
728 smGD.sessionType = DEFAULT_SESSION;
729 smGD.restoreSession = NULL;
733 tmpDisplay = XOpenDisplay(displayName);
734 if(tmpDisplay == NULL)
736 PrintError(DtError, GETMESSAGE(4, 1, "Invalid display name - exiting."));
742 if (!InitializeSpecificSession (session_option, tmpDisplay, argc, argv))
743 InitializeGenericSession (tmpDisplay);
746 InitializeGenericSession (tmpDisplay);
749 * Need to know if the session is for a specific display
751 smGD.displaySpecific = True;
752 if (session_option = strrchr (smGD.savePath, '/'))
755 if (!strcmp (session_option, DtSM_SESSION_DIRECTORY))
756 smGD.displaySpecific = False;
760 XCloseDisplay(tmpDisplay);
763 ** User's session startup script:
764 ** $HOME/.dt/sessions/sessionetc
766 strcpy(smGD.etcPath, smGD.savePath);
767 strcat(smGD.etcPath, "/");
768 strcat(smGD.etcPath, smEtcFile);
771 ** User's session shutdown script:
772 ** $HOME/.dt/sessions/sessionexit
774 strcpy(smGD.exitPath, smGD.savePath);
775 strcat(smGD.exitPath, "/");
776 strcat(smGD.exitPath, smExitFile);
788 char * pathList = (char *)XtMalloc(strlen(SM_SYSTEM_PATH) +
789 strlen(":" CDE_INSTALLATION_TOP "/config") + 1);
791 strcpy(pathList,SM_SYSTEM_PATH);
792 strcat(pathList,":" CDE_INSTALLATION_TOP "/config");
794 tempPath = _DtQualifyWithFirst(the1stPath,pathList);
795 if (tempPath != NULL) {
796 strcpy(the1stPath,tempPath);
804 /*************************************<->*************************************
811 * Sets the path to restore the system default files. A convenience routine
816 * smGD.savePath = path that files are to be saved in (set up in
821 * smGD.resourcePath(global) = Path where the resources to be saved are
823 * smGD.settingPath(global) = Path where the settings to be saved are
825 * smGD.clientPath(global) = Path where the clients to be saved are
831 *************************************<->***********************************/
833 SetSysDefaults( void )
842 * No files exist for restoration - use the
845 strcpy(smGD.resourcePath, "");
846 strcpy(smGD.clientPath, "");
847 smGD.settingPath[0] = 0;
848 smGD.sessionType = DEFAULT_SESSION;
849 smGD.restoreSession = (char *) SM_SYSTEM_DIRECTORY;
851 langSpec = getenv("LANG");
852 if ((langSpec != NULL) && (*langSpec != 0))
854 strcat(smGD.clientPath, "/");
855 strncat(smGD.clientPath, langSpec, MAXPATHLEN-2);
856 smGD.clientPath[MAXPATHLEN-1] = 0;
859 strcat(smGD.clientPath, "/");
860 strcat(smGD.clientPath, SM_SYSTEM_CLIENT_FILE);
862 FixPath(smGD.clientPath);
865 * If the system files don't exist - we're in
866 * trouble - First try LANG location then default
868 status = stat(smGD.clientPath, &buf);
871 if((langSpec == NULL) || (*langSpec == 0))
873 PrintErrnoError(DtError, GETMESSAGE(4, 2,
874 "No defaults files exist. "
875 "No applications will be restarted."));
876 smGD.clientPath[0] = 0;
877 smGD.resourcePath[0] = 0;
881 strcpy(smGD.clientPath, "/C/");
882 strcat(smGD.clientPath, SM_SYSTEM_CLIENT_FILE);
884 FixPath(smGD.clientPath);
886 status = stat(smGD.clientPath, &buf);
889 PrintErrnoError(DtError, GETMESSAGE(4, 3,
890 "No defaults files exist. "
891 "No applications will be restarted."));
892 smGD.clientPath[0] = 0;
893 smGD.resourcePath[0] = 0;
903 /*************************************<->*************************************
910 * Sets the path to restore the settings and resource files.
911 * A convenience routine
916 * smGD.savePath = path that files are to be saved in (set up in
921 * smGD.resourcePath(global) = Path where the resources to be saved are
923 * smGD.settingPath(global) = Path where the settings to be saved are
925 * smGD.clientPath(global) = Path where the clients to be saved are
931 *************************************<->***********************************/
939 * If resource or settings file does not exist - just null out
940 * the path so these things will not get restored
942 status = stat(smGD.resourcePath, &buf);
945 smGD.resourcePath[0] = 0;
948 status = stat(smGD.settingPath, &buf);
951 smGD.settingPath[0] = 0;
957 /*************************************<->*************************************
959 * UndoSetSavePath () - Undoes the directory manipulations done by
960 * SetSavePath. This function is only called if a shutdown/save
963 *************************************<->***********************************/
969 if (strcmp ("", savedDir)) {
972 * Remove the directory where the save occurred, e.g.:
974 * ~/.dt/<session_dir>/current
975 * ~/.dt/<session_dir>/home
977 buf = XtMalloc (strlen (savedDir) + 9);
978 sprintf (buf, "rm -rf %s", savedDir);
982 if (strcmp ("", savedOldDir)) {
984 MoveDirectory (savedOldDir, savedDir, False);
986 if (strcmp ("", savedTmpDir)) {
987 MoveDirectory (savedTmpDir, savedOldDir, False);
994 /*************************************<->*************************************
996 * SetSavePath (saveToHome, mode)
1001 * Sets up paths for files that need to be saved. Also removes any files
1002 * that shouldn't be there after the save.
1007 * smGD.display = display structure for session manager. Used to construct
1008 * a display directory
1009 * saveToHome = whether this is a save to home session or not
1010 * mode = whether we are resetting or restarting
1014 * smGD.resourcePath(global) = Path where the resources to be saved are
1016 * smGD.settingPath(global) = Path where the settings to be saved are
1018 * smGD.clientPath(global) = Path where the clients to be saved are
1024 *************************************<->***********************************/
1034 * These directory paths are needed in UndoSetSavePaths
1035 * if a shutdown/save is canceled.
1037 strcpy (savedDir, "");
1038 strcpy (savedOldDir, "");
1039 strcpy (savedTmpDir, "");
1042 * Make sure the user hasn't done something like delete the .dt
1043 * directories during the session. If so - recreate them
1045 SM_FREE(smGD.savePath);
1046 smGD.savePath = _DtCreateDtDirs(smGD.display);
1047 if(smGD.savePath == NULL)
1049 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1050 smGD.clientPath[0] = 0;
1051 smGD.settingPath[0] = 0;
1052 smGD.resourcePath[0] = 0;
1058 * Path for a save defaults to save the current session.
1059 * Otherwise just remove the directories
1061 strcpy(smGD.clientPath, smGD.savePath);
1062 strcpy(smGD.settingPath, smGD.savePath);
1063 strcpy(smGD.resourcePath, smGD.savePath);
1064 strcat(smGD.clientPath, "/");
1065 strcat(smGD.settingPath, "/");
1066 strcat(smGD.resourcePath, "/");
1068 if(saveToHome == False)
1070 strcat(smGD.clientPath, SM_CURRENT_DIRECTORY);
1071 strcat(smGD.resourcePath, SM_CURRENT_DIRECTORY);
1072 strcat(smGD.settingPath, SM_CURRENT_DIRECTORY);
1073 smGD.restoreSession = SM_CURRENT_DIRECTORY;
1077 strcat(smGD.clientPath, SM_HOME_DIRECTORY);
1078 strcat(smGD.resourcePath, SM_HOME_DIRECTORY);
1079 strcat(smGD.settingPath, SM_HOME_DIRECTORY);
1080 smGD.restoreSession = SM_HOME_DIRECTORY;
1083 if ((mode == DtSM_HOME_STATE) && (saveToHome == False) &&
1084 (smSettings.startState == DtSM_HOME_STATE))
1087 * The only time this should should be true is if the
1088 * current session is a Home session and the session
1089 * is being exited. The idea is that if a "current"
1090 * directory exits, it must be moved because when the
1091 * user next logs in, a Home session should be started
1092 * (if a session is not selected at the login screen)
1093 * and the Session Manager decides whether or not it
1094 * starts a Home or Current session based on if a
1095 * "current" directory exists. If a "current" directory
1096 * exists, a Current session will be started.
1098 status = stat(smGD.clientPath, &buf);
1102 * The "current" directory exists and must be moved to its
1103 * ".old" version. But first, if the ".old" version exists,
1104 * it must be moved to a temporary directory. This temporary
1105 * directory will eventually be pruned - when a user next
1106 * runs a Current session and saves the session.
1108 strcpy (savedDir, smGD.clientPath);
1109 sprintf(smGD.etcPath, "%s.%s", smGD.clientPath, SM_OLD_EXTENSION);
1110 status = stat(smGD.etcPath, &buf);
1116 strcpy(savedOldDir, smGD.etcPath);
1118 len = strlen(smGD.savePath) + strlen(smGD.restoreSession)
1119 + strlen("XXXXXX") + 3;
1120 tmpName = (char *) XtCalloc(1, len);
1122 sprintf(tmpName, "%s/%s.XXXXXX", smGD.savePath,
1123 smGD.restoreSession);
1125 if ((tfd = mkstemp(tmpName)) == -1)
1127 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1134 MoveDirectory(smGD.etcPath, tmpName, False);
1136 strncpy(savedTmpDir, tmpName, len - 1);
1138 XtFree((char *) tmpName);
1140 MoveDirectory(smGD.clientPath, smGD.etcPath, False);
1143 smGD.clientPath[0] = 0;
1144 smGD.settingPath[0] = 0;
1145 smGD.resourcePath[0] = 0;
1149 strcpy (savedDir, smGD.clientPath);
1152 * If the desired directory doesn't exist, create it.
1154 status = stat(smGD.clientPath, &buf);
1157 status = mkdir(smGD.clientPath, 0000);
1160 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1161 smGD.clientPath[0] = 0;
1162 smGD.settingPath[0] = 0;
1163 smGD.resourcePath[0] = 0;
1166 if(-1 == chmod(smGD.clientPath, 0755))
1168 fprintf(stderr, "%s chmod error %s\n", smGD.clientPath, strerror(errno));
1174 * The desired directory already exists so it must
1175 * be archived by moving it to its ".old" version. But
1176 * first, if its ".old" version already exists, it must
1177 * be moved to a temporary directory that will be removed
1178 * when the session directories are pruned - after the
1183 sprintf(smGD.etcPath, "%s.%s", smGD.clientPath, SM_OLD_EXTENSION);
1184 status = stat(smGD.etcPath, &buf);
1189 len = strlen(smGD.savePath) + strlen(smGD.restoreSession)
1190 + strlen("XXXXXX") + 3;
1191 tmpName = (char *) XtCalloc(1, len);
1192 sprintf(tmpName, "%s/%s.XXXXXX", smGD.savePath,
1193 smGD.restoreSession);
1195 strcpy (savedOldDir, smGD.etcPath);
1197 if ((tfd = mkstemp(tmpName)) == -1)
1199 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1206 MoveDirectory (smGD.etcPath, tmpName, False);
1208 strcpy (savedTmpDir, tmpName);
1210 XtFree((char *) tmpName);
1213 MoveDirectory(smGD.clientPath, smGD.etcPath, False);
1216 * Now re-make the directory
1218 status = mkdir(smGD.clientPath, 0000);
1221 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1222 smGD.clientPath[0] = 0;
1223 smGD.settingPath[0] = 0;
1224 smGD.resourcePath[0] = 0;
1227 status = chmod(smGD.clientPath, 0755);
1230 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1231 smGD.clientPath[0] = 0;
1232 smGD.settingPath[0] = 0;
1233 smGD.resourcePath[0] = 0;
1238 strcat(smGD.clientPath, "/");
1239 strcat(smGD.clientPath, SM_CLIENT_FILE2);
1240 strcat(smGD.settingPath, "/");
1241 strcat(smGD.settingPath, SM_SETTING_FILE);
1242 strcat(smGD.resourcePath, "/");
1243 strcat(smGD.resourcePath, SM_RESOURCE_FILE);
1250 /*************************************<->*************************************
1252 * SetFontSavePath (saveToHome, mode)
1257 * Sets up the save path for the auxillary directory.
1269 *************************************<->***********************************/
1271 SetFontSavePath(char *langPtr)
1279 * Set up the session font directory and see if it exists
1281 if(smGD.sessionType == CURRENT_SESSION)
1283 sessionSaved = SM_CURRENT_FONT_DIRECTORY;
1287 sessionSaved = SM_HOME_FONT_DIRECTORY;
1290 snprintf(smGD.fontPath, MAXPATHLEN, "%s/%s", smGD.savePath, sessionSaved);
1291 status = stat(smGD.fontPath, &buf);
1294 status = mkdir(smGD.fontPath, 0000);
1297 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1298 smGD.fontPath[0] = 0;
1301 if(-1 == chmod(smGD.fontPath, 0755))
1303 fprintf(stderr, "%s chmod error %s\n", smGD.fontPath, strerror(errno));
1308 * Now add the lang subdirectory and see if it exists
1310 strncat(smGD.fontPath, "/", MAXPATHLEN);
1311 strncat(smGD.fontPath, langPtr, MAXPATHLEN);
1312 status = stat(smGD.fontPath, &buf);
1315 status = mkdir(smGD.fontPath, 0000);
1318 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1319 smGD.fontPath[0] = 0;
1322 status = chmod(smGD.fontPath, 0755);
1325 PrintErrnoError(DtError, smNLS.cantCreateDirsString);
1326 smGD.fontPath[0] = 0;
1336 /*************************************<->*************************************
1343 * Remove the files that need to be removed
1356 *************************************<->***********************************/
1362 int execStatus, childStatus, i, statLoc;
1366 * Fork and exec the client process
1368 sigaction(SIGCHLD, &smGD.defvec, (struct sigaction *) NULL);
1370 clientFork = vfork();
1373 * If the fork fails - Send out an error and return
1377 PrintErrnoError(DtError, smNLS.cantForkClientString);
1382 * Fork succeeded - now do the exec
1386 SetSIGPIPEToDefault ();
1389 * Set the gid of the process back from bin
1393 setregid(smGD.runningGID, smGD.runningGID);
1395 setgid(smGD.runningGID);
1396 setegid(smGD.runningGID);
1400 _DtEnvControl(DT_ENV_RESTORE_PRE_DT);
1402 #if defined(__osf__) || defined(CSRG_BASED)
1406 #endif /* __osf__ */
1408 execStatus = execlp("rm","rm", "-rf", path, (char *) 0);
1411 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.")) ;
1412 PrintErrnoError(DtError, tmpString);
1418 while(wait(&statLoc) != clientFork);
1420 sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
1424 /*************************************<->*************************************
1430 * Move the directory specified by pathFrom - to the directory specified
1435 * pathFrom = the directory to move from
1436 * pathTo = the directory to move to
1437 * removeDestDir = if True, directory pathTo is removed before the
1446 *************************************<->***********************************/
1451 Boolean removeDestDir)
1455 int status, execStatus, childStatus, i, statLoc;
1459 * If the pathTo directory exists - remove it
1463 status = stat(pathTo, &buf);
1466 RemoveFiles(pathTo);
1471 * Fork and exec the client process
1473 sigaction(SIGCHLD, &smGD.defvec, (struct sigaction *) NULL);
1475 clientFork = vfork();
1478 * If the fork fails - Send out an error and return
1482 PrintErrnoError(DtError, smNLS.cantForkClientString);
1487 * Fork succeeded - now do the exec
1491 SetSIGPIPEToDefault ();
1494 * Set the gid of the process back from bin
1498 setregid(smGD.runningGID, smGD.runningGID);
1500 setgid(smGD.runningGID);
1501 setegid(smGD.runningGID);
1505 _DtEnvControl(DT_ENV_RESTORE_PRE_DT);
1507 #if defined(__osf__) || defined(CSRG_BASED)
1511 #endif /* __osf__ */
1513 execStatus = execlp("mv","mv", pathFrom, pathTo, (char *) 0);
1516 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.")) ;
1517 PrintErrnoError(DtError, tmpString);
1523 while(wait(&statLoc) != clientFork);
1525 sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
1530 /*************************************<->*************************************
1537 * Initialize the NLS strings used in dtsession
1550 *************************************<->***********************************/
1552 InitNlsStrings( void )
1557 * Malloc failure error message - THIS MESSAGE MUST BE INITIALIZED FIRST
1559 smNLS.cantMallocErrorString = strdup (((char *)GETMESSAGE(4, 5, "Unable to malloc memory for operation.")));
1562 * Error message when dtsession cant lock the display
1564 smNLS.cantLockErrorString = strdup (((char *)GETMESSAGE(4, 6, "Unable to lock display. Another application may have the pointer or keyboard grabbed.")));
1567 * Error message when dtsession cant open files for reading or writing
1569 smNLS.cantOpenFileString = strdup (((char *)GETMESSAGE(4, 7, "Unable to open session file. No clients will be restarted.")));
1572 * Error message when dtsession cant fork client process
1574 smNLS.cantForkClientString = strdup (((char *)GETMESSAGE(4, 8, "Unable to fork client process.")));
1577 * Error message when dtsession cant create dt directories
1579 smNLS.cantCreateDirsString = strdup (((char *)GETMESSAGE(4, 9, "Unable to create DT directories. Check permissions on home directory.")));
1582 * Error message when trying to lock display on trusted system
1584 smNLS.trustedSystemErrorString = strdup (((char *)GETMESSAGE(4, 10, "Unable to lock display due to security restrictions")));
1589 /*************************************<->*************************************
1596 * When a SIGCHLD signal comes in, wait for all child processes to die.
1609 *************************************<->***********************************/
1612 WaitChildDeath( int i )
1618 * Wait on any children that have died since the last SIGCHLD we
1619 * received. Any child process death that occurs while we are
1620 * in WaitChildDeath() will not result in a SIGCHLD. Any
1621 * child proceses that die after our last call to waitpid() will
1622 * remain zombiefied until the next invocation of WaitChildDeath().
1624 while ((pid = waitpid(-1, &stat_loc, WNOHANG)) > 0)
1627 sigaction(SIGCHLD, &smGD.childvec, (struct sigaction *) NULL);
1632 /*************************************<->*************************************
1639 * Trim the errorlog file using the following algorithm:
1640 * if(errorlog.old exists and is not empty) move it to errorlog.oldest
1641 * if(errorlog exists and is not empty) move it to errorlog.old
1654 *************************************<->***********************************/
1656 TrimErrorlog( void )
1658 char *savePath, /* common path element for all pathnames */
1666 * Allocate the strings needed
1668 savePath = (char *) SM_MALLOC(MAXPATHLEN + 1);
1669 checkPath1 = (char *) SM_MALLOC(MAXPATHLEN + 1);
1670 checkPath2 = (char *) SM_MALLOC(MAXPATHLEN + 1);
1671 if ((home=getenv("HOME")) == NULL)
1674 len = strlen(home) + strlen(DtPERSONAL_CONFIG_DIRECTORY) + 2;
1675 if (len > MAXPATHLEN) savePath = SM_REALLOC(savePath, len);
1676 snprintf(savePath, len, "%s/%s", home, DtPERSONAL_CONFIG_DIRECTORY);
1679 * If errorlog.old exists and it is not empty, delete
1680 * errorlog.older and then move errolog.old to
1683 if (len + strlen(DtOLDER_ERRORLOG_FILE) > MAXPATHLEN)
1684 checkPath1 = SM_REALLOC(savePath, len + strlen(DtOLDER_ERRORLOG_FILE));
1685 sprintf(checkPath1, "%s/%s", savePath, DtOLDER_ERRORLOG_FILE);
1687 if (len + strlen(DtOLD_ERRORLOG_FILE) > MAXPATHLEN)
1688 checkPath2 = SM_REALLOC(savePath, len + strlen(DtOLD_ERRORLOG_FILE));
1689 sprintf(checkPath2, "%s/%s", savePath, DtOLD_ERRORLOG_FILE);
1691 status = stat(checkPath2, &buf);
1692 if((status != -1) && (buf.st_size > 0))
1694 (void) unlink(checkPath1);
1695 (void) link(checkPath2, checkPath1);
1696 (void) unlink(checkPath2);
1700 * If errorlog exists and it is not empty, move it to
1703 if (len + strlen(DtERRORLOG_FILE) > MAXPATHLEN)
1704 checkPath1 = SM_REALLOC(savePath, len + strlen(DtERRORLOG_FILE));
1705 sprintf(checkPath1, "%s/%s", savePath, DtERRORLOG_FILE);
1707 status = stat(checkPath1, &buf);
1708 if((status != -1) && (buf.st_size > 0))
1710 (void) link(checkPath1, checkPath2);
1711 (void) unlink(checkPath1);
1714 SM_FREE((char *) savePath);
1715 SM_FREE((char *) checkPath1);
1716 SM_FREE((char *) checkPath2);
1723 /*************************************<->*************************************
1730 * Do everything that needs to be done to get the system back into a
1731 * READY state. This includes checking to be sure that the BMS did not
1732 * die while we were in process
1745 *************************************<->***********************************/
1747 SetSystemReady( void )
1749 smGD.smState = READY;
1750 if(smGD.bmsDead == True)
1759 /*************************************<->*************************************
1761 * SmCvtStringToContManagement (args, numArgs, fromVal, toVal)
1766 * This function converts a string to a value for the
1767 * contention management flag set.
1772 * args = additional XrmValue arguments to the converter - NULL here
1774 * numArgs = number of XrmValue arguments - 0 here
1776 * fromVal = resource value to convert
1781 * toVal = descriptor to use to return converted value
1783 *************************************<->***********************************/
1785 void SmCvtStringToContManagement (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
1788 unsigned char *pch = (unsigned char *) (fromVal->addr);
1789 unsigned char *pchNext;
1792 Boolean fHit = False;
1793 Boolean fAddNext = True;
1796 * Names of contention management options
1799 #define CM_ALL_STR (unsigned char *)"all"
1800 #define CM_SYSTEM_STR (unsigned char *)"system"
1801 #define CM_HANDSHAKE_STR (unsigned char *)"handshake"
1802 #define CM_NONE_STR (unsigned char *)"none"
1805 * Check first token. If '-' we subtract from all options.
1806 * Otherwise, we start with no contention management and add things in.
1810 (_DtNextToken (pch, &len, &pchNext)) &&
1821 while (*pch && _DtNextToken (pch, &len, &pchNext))
1824 * Strip off "sign" if prepended to another token, and process
1825 * that token the next time through.
1837 else if (*pch == '-')
1846 if ((*pch == 'A') || (*pch == 'a'))
1848 if (_DtWmStringsAreEqual (pch, CM_ALL_STR, len))
1850 cval = fAddNext ? (cval | SM_CM_ALL) :
1851 (cval & ~SM_CM_ALL);
1856 else if ((*pch == 'S') || (*pch == 's'))
1858 if (_DtWmStringsAreEqual (pch, CM_SYSTEM_STR, len))
1860 cval = fAddNext ? (cval | SM_CM_SYSTEM) :
1861 (cval & ~SM_CM_SYSTEM);
1866 else if ((*pch == 'H') || (*pch == 'h'))
1868 if (_DtWmStringsAreEqual (pch, CM_HANDSHAKE_STR, len))
1870 cval = fAddNext ? (cval | SM_CM_HANDSHAKE) :
1871 (cval & ~SM_CM_HANDSHAKE);
1876 else if ((*pch == 'N') || (*pch == 'n'))
1878 if (_DtWmStringsAreEqual (pch, CM_NONE_STR, len))
1880 /* don't bother adding or subtracting nothing */
1891 * If we didn't match anything then set to default.
1895 cval = SM_CM_DEFAULT;
1899 (*toVal).size = sizeof (long);
1900 (*toVal).addr = (caddr_t) &cval;
1903 } /* END OF FUNCTION SmCvtStringToContManagement */
1906 /*************************************<->*************************************
1908 * _DtNextToken (pchIn, pLen, ppchNext)
1918 * pchIn = pointer to start of next token
1923 * pLen = pointer to integer containing number of characters in next token
1924 * ppchNext = address of pointer to following token
1926 * Return = next token or NULL
1933 *************************************<->***********************************/
1935 unsigned char *_DtNextToken (unsigned char *pchIn, int *pLen,
1936 unsigned char **ppchNext)
1938 unsigned char *pchR = pchIn;
1944 for (i = 0; ((chlen = mblen ((char *)pchIn, MB_CUR_MAX)) > 0); i++)
1945 /* find end of word: requires singlebyte whitespace terminator */
1947 if ((chlen == 1) && isspace (*pchIn))
1955 for (i = 0; *pchIn && !isspace (*pchIn); i++, pchIn++)
1956 /* find end of word */
1961 /* skip to next word */
1962 ScanWhitespace (&pchIn);
1975 } /* END OF FUNCTION _DtNextToken */
1979 /*************************************<->*************************************
1981 * _DtWmStringsAreEqual (pch1, pch2, len)
1998 * Return = (Boolean) True iff strings match (case insensitive)
2005 *************************************<->***********************************/
2007 Boolean _DtWmStringsAreEqual (unsigned char *pch1, unsigned char *pch2, int len)
2016 ((chlen1 = mbtowc (&wch1, (char *) pch1, 2)) > 0) &&
2017 ((chlen2 = mbtowc (&wch2, (char *) pch2, 2)) == chlen1) )
2020 /* singlebyte characters -- make case insensitive */
2022 if ((isupper (*pch1) ? tolower(*pch1) : *pch1) !=
2023 (isupper (*pch2) ? tolower(*pch2) : *pch2))
2029 /* multibyte characters */
2042 while (len && *pch1 && *pch2 &&
2043 ((isupper (*pch1) ? tolower(*pch1) : *pch1) ==
2044 (isupper (*pch2) ? tolower(*pch2) : *pch2)))
2054 } /* END OF _DtWmStringsAreEqual */
2056 /*************************************<->*************************************
2058 * InitializeGenericSession - set the smGD paths using the CDE 1.0
2059 * session starting algorithm.
2063 * Initializes several variables in smGD
2076 *************************************<->***********************************/
2078 InitializeGenericSession (
2079 Display *tmpDisplay)
2082 int session_needed = 1;
2084 char tmpPath[MAXPATHLEN];
2086 smGD.savePath = _DtCreateDtDirs(tmpDisplay);
2090 strcpy(smGD.clientPath, smGD.savePath);
2091 strcat(smGD.clientPath, "/");
2092 strcat(smGD.clientPath, SM_CURRENT_DIRECTORY);
2093 strcat(smGD.clientPath, "/");
2094 strcpy (tmpPath, smGD.clientPath);
2095 strcat(smGD.clientPath, SM_CLIENT_FILE2);
2097 status = stat(smGD.clientPath, &buf);
2100 strcpy (smGD.clientPath, tmpPath);
2101 strcat (smGD.clientPath, SM_CLIENT_FILE);
2102 status = stat(smGD.clientPath, &buf);
2108 * sessions/current/dt.settings exist, restore to 'current' session
2110 strcpy(smGD.resourcePath, smGD.savePath);
2111 strcat(smGD.resourcePath, "/");
2112 strcat(smGD.resourcePath, SM_CURRENT_DIRECTORY);
2113 strcat(smGD.resourcePath, "/");
2114 strcat(smGD.resourcePath, SM_RESOURCE_FILE);
2115 strcpy(smGD.settingPath, smGD.savePath);
2116 strcat(smGD.settingPath, "/");
2117 strcat(smGD.settingPath, SM_CURRENT_DIRECTORY);
2118 strcat(smGD.settingPath, "/");
2119 strcat(smGD.settingPath, SM_SETTING_FILE);
2121 smGD.sessionType = CURRENT_SESSION;
2122 smGD.restoreSession = (char *) SM_CURRENT_DIRECTORY;
2129 strcpy(smGD.clientPath, smGD.savePath);
2130 strcat(smGD.clientPath, "/");
2131 strcat(smGD.clientPath, SM_HOME_DIRECTORY);
2132 strcat(smGD.clientPath, "/");
2133 strcpy(tmpPath, smGD.clientPath);
2134 strcat(smGD.clientPath, SM_CLIENT_FILE2);
2136 status = stat(smGD.clientPath, &buf);
2139 strcpy (smGD.clientPath, tmpPath);
2140 strcat (smGD.clientPath, SM_CLIENT_FILE);
2141 status = stat(smGD.clientPath, &buf);
2147 * sessions/home/dt.settings exist, restore to 'home' session
2149 strcpy(smGD.resourcePath, smGD.savePath);
2150 strcat(smGD.resourcePath, "/");
2151 strcat(smGD.resourcePath, SM_HOME_DIRECTORY);
2152 strcat(smGD.resourcePath, "/");
2153 strcat(smGD.resourcePath, SM_RESOURCE_FILE);
2154 strcpy(smGD.settingPath, smGD.savePath);
2155 strcat(smGD.settingPath, "/");
2156 strcat(smGD.settingPath, SM_HOME_DIRECTORY);
2157 strcat(smGD.settingPath, "/");
2158 strcat(smGD.settingPath, SM_SETTING_FILE);
2160 smGD.sessionType = HOME_SESSION;
2161 smGD.restoreSession = (char *) SM_HOME_DIRECTORY;
2172 /*************************************<->*************************************
2174 * InternSessionDir - intern the session dir property and put it
2175 * on the root window
2177 * NOTE: - also checks the validity of the -session command line
2182 * session_option - as given in the command line
2187 * smGD.restoreSession - initialized
2191 *************************************<->***********************************/
2194 char *session_option,
2199 if (!strcmp (session_option, SM_CURRENT_DIRECTORY)) {
2200 pch = DtSM_SESSION_DIRECTORY;
2201 smGD.restoreSession = SM_CURRENT_DIRECTORY;
2203 else if (!strcmp (session_option, SM_HOME_DIRECTORY)) {
2204 pch = DtSM_SESSION_DIRECTORY;
2205 smGD.restoreSession = SM_HOME_DIRECTORY;
2207 else if (!strcmp (session_option, SM_DISPLAY_HOME)) {
2208 pch = DtSM_SESSION_DISPLAY_DIRECTORY;
2209 smGD.restoreSession = SM_HOME_DIRECTORY;
2211 else if (!strcmp (session_option, SM_DISPLAY_CURRENT)) {
2212 pch = DtSM_SESSION_DISPLAY_DIRECTORY;
2213 smGD.restoreSession = SM_CURRENT_DIRECTORY;
2217 * The session_option is not supported
2221 XaSmRestoreDir = XInternAtom(disp, _XA_DT_RESTORE_DIR, False);
2223 XChangeProperty(disp, RootWindow(disp, 0),
2224 XaSmRestoreDir, XA_STRING, 8, PropModeReplace,
2225 (unsigned char *)pch, strlen(pch));
2234 /*************************************<->*************************************
2236 * InitializeSpecificSession - set the smGD paths based on the session
2237 * name given on the command line.
2241 * Initializes several variables in smGD
2255 *************************************<->***********************************/
2257 InitializeSpecificSession (
2258 char *session_option,
2263 char *session_dir = (char *) XtMalloc(MAXPATHLEN);
2264 char *alt_dir = (char *) XtMalloc(MAXPATHLEN);
2268 if (!InternSessionDir (session_option, disp))
2271 InitializePaths (smGD.restoreSession, disp);
2273 if (!strcmp (session_option, SM_HOME_DIRECTORY)) {
2277 if (smGD.clientPath[0] == '\0') {
2278 if ((stat (smGD.savePath, &buf)) != 0) {
2279 if ((mkdir (smGD.savePath, 0000)) == 0)
2280 (void) chmod (smGD.savePath, 0755);
2282 PrintErrnoError(DtError,
2283 smNLS.cantCreateDirsString);
2287 smGD.sessionType = HOME_SESSION;
2288 smGD.restoreSession = SM_HOME_DIRECTORY;
2290 else if (!strcmp (session_option, SM_CURRENT_DIRECTORY)) {
2294 if (smGD.clientPath[0] == '\0') {
2296 * Fallback to the generic home session
2298 (void) sprintf (session_dir, "%s/%s",
2299 smGD.savePath, SM_CURRENT_DIRECTORY);
2300 (void) sprintf (alt_dir, "%s/%s",
2301 smGD.savePath, SM_HOME_DIRECTORY);
2303 if (!SetAlternateSession (session_dir, alt_dir, True))
2306 smGD.sessionType = CURRENT_SESSION;
2307 smGD.restoreSession = SM_CURRENT_DIRECTORY;
2309 else if (!strcmp (session_option, SM_DISPLAY_HOME)) {
2311 * Display-specific Home session
2313 (void) sprintf (session_dir, "%s/%s",
2314 smGD.savePath, SM_HOME_DIRECTORY);
2316 if ((stat(session_dir, &buf)) != 0){
2318 * The session does not exist, give the user a
2321 if (!ConfirmSessionCreation (HOME_SESSION, argc, argv))
2326 if (smGD.clientPath[0] == '\0') {
2328 * Fallback to the generic home session
2332 if ((home = getenv ("HOME")) == 0)
2335 /* JET - VU#497553 */
2336 len = strlen(home) +
2337 strlen(DtPERSONAL_CONFIG_DIRECTORY) +
2338 strlen(DtSM_SESSION_DIRECTORY) +
2339 strlen(SM_HOME_DIRECTORY);
2341 if (len > MAXPATHLEN)
2342 alt_dir = XtRealloc(alt_dir, len + 1);
2344 (void) sprintf (alt_dir, "%s/%s/%s/%s",
2346 DtPERSONAL_CONFIG_DIRECTORY,
2347 DtSM_SESSION_DIRECTORY,
2349 if (!SetAlternateSession (session_dir, alt_dir, True))
2352 smGD.sessionType = HOME_SESSION;
2353 smGD.restoreSession = SM_HOME_DIRECTORY;
2355 else if (!strcmp (session_option, SM_DISPLAY_CURRENT)) {
2357 * Display-specific Current session
2359 (void) sprintf (session_dir, "%s/%s",
2360 smGD.savePath, SM_CURRENT_DIRECTORY);
2362 if ((stat(session_dir, &buf)) != 0){
2364 * The session does not exist, give the user a
2367 if (!ConfirmSessionCreation (CURRENT_SESSION, argc, argv))
2371 if (smGD.clientPath[0] == '\0') {
2373 * First, fallback to the display-specific home session
2377 (void) sprintf (alt_dir, "%s/%s",
2378 smGD.savePath, SM_HOME_DIRECTORY);
2380 if (!SetAlternateSession (session_dir, alt_dir, False)){
2382 * Try the generic home session
2384 if ((home = getenv ("HOME")) == 0)
2387 /* JET - VU#497553 */
2388 len = strlen(home) +
2389 strlen(DtPERSONAL_CONFIG_DIRECTORY) +
2390 strlen(DtSM_SESSION_DIRECTORY) +
2391 strlen(SM_HOME_DIRECTORY);
2393 if (len > MAXPATHLEN)
2394 alt_dir = XtRealloc(alt_dir, len + 1);
2396 snprintf(alt_dir, len, "%s/%s/%s/%s",
2398 DtPERSONAL_CONFIG_DIRECTORY,
2399 DtSM_SESSION_DIRECTORY,
2402 if (!SetAlternateSession (session_dir,
2408 smGD.sessionType = CURRENT_SESSION;
2409 smGD.restoreSession = SM_CURRENT_DIRECTORY;
2412 if (session_dir) XtFree(session_dir);
2413 if (alt_dir) XtFree(alt_dir);
2417 if (session_dir) XtFree(session_dir);
2418 if (alt_dir) XtFree(alt_dir);
2423 /*************************************<->*************************************
2429 * Initializes the following variables:
2434 * smGD.clientPath - [0] = '\0' if the database files do not exist
2438 * session_name = "current" or "home"
2447 *************************************<->***********************************/
2450 char * session_name,
2453 char *db_file = (char *) XtMalloc(MAXPATHLEN);
2458 PrintError(DtError, smNLS.cantMallocErrorString);
2462 smGD.savePath = _DtCreateDtDirs(disp);
2464 (void) sprintf (smGD.settingPath, "%s/%s/%s",
2465 smGD.savePath, session_name, SM_SETTING_FILE);
2467 (void) sprintf (smGD.resourcePath, "%s/%s/%s",
2468 smGD.savePath, session_name, SM_RESOURCE_FILE);
2471 smGD.clientPath[0] = '\0';
2473 (void) sprintf (db_file, "%s/%s/%s",
2474 smGD.savePath, session_name, SM_CLIENT_FILE2);
2476 if ((stat(db_file, &buf)) == 0)
2477 (void) strcpy (smGD.clientPath, db_file);
2479 (void) sprintf (db_file, "%s/%s/%s",
2480 smGD.savePath, session_name, SM_CLIENT_FILE);
2481 if ((stat(db_file, &buf)) == 0)
2482 (void) strcpy (smGD.clientPath, db_file);
2488 /*************************************<->*************************************
2490 * SetAlternateSession
2494 * Neither of the client databases in the session_dir directory
2499 * session_dir - the directory path for the session including home
2501 * alt_dir - the directory to use in the search for an alternate
2502 * or fallback session database
2503 * make_dir - if True, a session_dir will be created if it does not
2504 * exits; if False, session_dir will not be created
2510 *************************************<->***********************************/
2512 SetAlternateSession (
2517 char *tmp_dir = NULL;
2518 char *db_file1 = (char *) XtMalloc(MAXPATHLEN);
2519 char *db_file2 = (char *) XtMalloc(MAXPATHLEN);
2522 if (!db_file1 || !db_file2)
2524 PrintError(DtError, smNLS.cantMallocErrorString);
2529 if ((stat (session_dir, &buf)) != 0) {
2531 * The requested dir does not exist, create it
2532 * by either copying the session from alt_dir (if
2533 * it exists and has a client database) or by
2537 (void) sprintf (db_file1, "%s/%s",
2538 alt_dir, SM_CLIENT_FILE2);
2539 (void) sprintf (db_file2, "%s/%s",
2540 alt_dir, SM_CLIENT_FILE);
2542 if ((stat(db_file1, &buf)) == 0)
2544 else if ((stat(db_file2, &buf)) == 0)
2547 if (!tmp_dir && !make_dir) {
2548 if (db_file1) XtFree(db_file1);
2549 if (db_file2) XtFree(db_file2);
2551 * This alt_dir doesn't have a session database
2552 * return now and try another directory
2559 * The alt_dir has a session database, create
2560 * a copy of its entire directory because all
2561 * of the sessions state is needed.
2565 tmp = XtMalloc (strlen (alt_dir) +
2566 strlen (session_dir) + 10);
2570 (void) sprintf (tmp, "cp -r %s %s",
2571 alt_dir, session_dir);
2573 if ((system (tmp)) == -1)
2577 if ((stat(session_dir, &buf)) != 0)
2579 * It should have been created by the cp
2584 * The session database needs to be updated.
2586 if (tmp_dir == db_file1)
2587 sprintf (smGD.clientPath, "%s/%s",
2588 session_dir, SM_CLIENT_FILE2);
2590 sprintf (smGD.clientPath, "%s/%s",
2591 session_dir, SM_CLIENT_FILE);
2594 * The alt_dir did not have a session database.
2595 * Create a directory and load the system defaults
2597 if ((mkdir (session_dir, 0000)) == 0)
2598 (void) chmod (session_dir, 0755);
2600 PrintErrnoError(DtError,
2601 smNLS.cantCreateDirsString);
2608 * The directory for the specified session exists
2609 * but it doesn't have any client databases. Start
2610 * a new user session. If a user wants a sesssion
2611 * with no apps, they should create a zero-length
2627 /* JET - needed to rework this to avoid exiting before we are
2630 if (smGD.ExitComplete)
2632 if (smXSMP.saveState.saveComplete &&
2633 smXSMP.saveState.shutdown &&
2634 !smXSMP.saveState.shutdownCanceled)
2643 SetSIGPIPEToDefault ()
2645 struct sigaction pipeSig;
2647 sigemptyset(&pipeSig.sa_mask);
2648 pipeSig.sa_flags = 0;
2649 pipeSig.sa_handler = SIG_DFL;
2650 (void) sigaction(SIGPIPE, &pipeSig, (struct sigaction *) NULL);