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: SmMain.c /main/18 1998/04/20 12:59:26 mgreess $ */
25 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
26 * (c) Copyright 1993, 1994 International Business Machines Corp. *
27 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
28 * (c) Copyright 1993, 1994 Novell, Inc. *
30 /*************************************<+>*************************************
31 *****************************************************************************
35 ** Project: HP DT Session Manager (dtsession)
39 ** This is the controlling program for the session manager. It
40 ** calls routines to start the BMS, initialize globals and handlers,
41 ** and restore the correct session.
44 *******************************************************************
45 ** (c) Copyright Hewlett-Packard Company, 1990. All rights are
46 ** reserved. Copying or other reproduction of this program
47 ** except for archival purposes is prohibited without prior
48 ** written consent of Hewlett-Packard Company.
49 ********************************************************************
53 *****************************************************************************
54 *************************************<+>*************************************/
59 #include <sys/access.h>
61 #include <X11/Intrinsic.h>
62 #include <X11/StringDefs.h>
64 #if defined (USE_X11SSEXT)
65 #include <X11/extensions/scrnsaver.h>
66 #endif /* USE_X11SSEXT */
69 #include <Dt/UserMsg.h>
70 #include <Dt/EnvControlP.h>
75 #include "SmGlobals.h"
77 #include "SmRestore.h"
79 #include "SrvPalette.h"
80 #include "SmProtocol.h"
86 static void StopAll(int i);
87 static int RegisterX11ScreenSaver(Display *display, int *ssEventType);
93 #define SECURE_SYS_PATH "/.secure/etc/passwd"
96 #define SECURE_SYS_PATH "/etc/security/passwd"
99 #define SECURE_SYS_PATH "/etc/shadow"
104 /*************************************<->*************************************
111 * Controls the startup and event dispatching of the session manager.
116 * argc = command line options
117 * argv = number of command line options
127 *************************************<->***********************************/
129 main (int argc, char **argv)
135 XWindowAttributes windAtt;
136 XPropertyEvent *pEvent = (XPropertyEvent *) &next;
140 struct sigaction stopvec;
145 # include <sys/sysinfo.h>
146 # include <sys/proc.h>
150 unsigned long nbytes = 1;
152 unsigned long flag = 0;
158 buffer[0] = SSIN_UACPROC;
159 buffer[1] = UAC_NOPRINT;
161 buffer[1] |= UAC_SIGBUS;
164 ssi_status = setsysinfo ( op, buffer, nbytes, arg, flag );
167 setlocale( LC_ALL, "" );
168 XtSetLanguageProc( NULL, NULL, NULL );
170 smGD.smState = IN_PROCESS;
171 smGD.programName = strdup (argv[0]);
173 /* JET - By default, we always want to leave when SmExit() is called. */
174 smGD.ExitComplete = True;
177 * We report some errors before we call the DtInitialize procedure.
178 * The Dt initialize procedure sets this name. If we report
179 * an error via DtSimple error before this is set we see the message
180 * prepended with <unknown program name> in the error log.
182 DtProgName = SM_RESOURCE_NAME ;
195 * Set our effective gid to the real gid until we need it to be
196 * sys (during contention management)
198 smGD.runningGID = getgid();
199 smGD.conMgmtGID = getegid();
202 * Set uid up according to whether this is a secure system
203 * Secure systems need root priviledges to read the /etc/passwd file
205 smGD.runningUID = getuid();
207 #ifdef linux /* linux always needs to be setup as secure */
210 * Save the root priviledge to be restored when trying to unlock
212 smGD.unLockUID = geteuid();
213 smGD.secureSystem = True;
214 SM_SETEUID(smGD.runningUID);
218 # ifdef SECURE_SYS_PATH
219 status = stat(SECURE_SYS_PATH, &buf);
227 * this is not a secure system - remove all suid priviledges
229 smGD.unLockUID = smGD.runningUID;
230 smGD.secureSystem = False;
231 SM_SETESUID(smGD.runningUID);
236 * Save the root priviledge to be restored when trying to unlock
238 smGD.unLockUID = geteuid();
239 smGD.secureSystem = True;
240 SM_SETEUID(smGD.runningUID);
246 * Initialize LANG if it isn't defined.
248 if ((lang = getenv ("LANG")) == NULL)
251 (void) strcpy (lang, "LANG=C");
252 (void) putenv (lang);
256 setresgid(-1, smGD.runningGID, -1);
257 #else /* _AIX or any other system */
259 setregid(smGD.conMgmtGID, smGD.runningGID);
261 setgid(smGD.conMgmtGID);
262 setegid(smGD.runningGID);
267 * Set up POSIX sigaction structs
271 * Must set SIGPIPE to SIG_IGN so the process does not exit
272 * if a child terminates unexpectedly during an I/O operation
273 * that raises SIGPIPE. Note that before this process exec's
274 * any subprocesses, SIGPIPE must be set to SIG_DFL.
276 sigemptyset(&stopvec.sa_mask);
277 stopvec.sa_flags = 0;
278 stopvec.sa_handler = SIG_IGN;
279 (void) sigaction(SIGPIPE, &stopvec, (struct sigaction *) NULL);
281 stopvec.sa_handler = StopAll;
282 sigemptyset(&stopvec.sa_mask);
283 stopvec.sa_flags = 0;
285 smGD.childvec.sa_handler = WaitChildDeath;
286 sigemptyset(&smGD.childvec.sa_mask);
287 smGD.childvec.sa_flags = 0;
289 smGD.defvec.sa_handler = SIG_DFL;
290 sigemptyset(&smGD.defvec.sa_mask);
291 smGD.defvec.sa_flags = 0;
297 * This must be done before XtToolkitInitialize
298 * to set up the local environment
300 _DtEnvControl(DT_ENV_SET);
301 _DtEnvControl(DT_ENV_SET_BIN);
304 * Set up NLS error messages first
309 * Set the paths of where resources are to be restored from
311 SetRestorePath(argc, argv);
314 * The first thing that must happen is that resources must be restored
315 * so that my resources will be correct
317 if(smGD.compatMode == False)
320 * Load session resources.
322 RestoreResources(False,
326 smGD.resourcePath[0] != '\0' ? "-file" : NULL,
332 * Set up to catch SIGTERM
334 stopvec.sa_handler = StopAll;
335 sigemptyset(&stopvec.sa_mask);
336 stopvec.sa_flags = 0;
338 sigaction(SIGTERM, &stopvec, (struct sigaction *) NULL);
341 * Now set up a communication with the toolkit
343 * Create one display connection for dtsession, and one for
344 * the color server. We cannot share a display connection since
345 * motif creates a display object for the color server's display during
346 * color server initialization. Since the color server is not yet
347 * operational, any dialogs (ie the dtsession logout confirmation
348 * dialogs) created on that display do not get the color server colors.
349 * The dtsession display object is created after color server
350 * initialization is complete.
352 if (smGD.appCon == 0) {
354 * The following code will have been initialized if the
355 * session creation code posted a dialog.
357 XtToolkitInitialize();
358 smGD.appCon = XtCreateApplicationContext();
359 smGD.display = XtOpenDisplay(smGD.appCon, NULL, argv[0],
361 NULL, 0, &argc, argv);
364 srvDisplay = XtOpenDisplay(smGD.appCon, NULL, argv[0], SM_RESOURCE_CLASS,
365 NULL, 0, &argc, argv);
370 if (!InitXSMP (argv[0]))
373 /* Added the following check to exit in case of error RK 09.08.93 */
374 if(smGD.display == NULL)
376 PrintError(DtError, GETMESSAGE(4, 1, "Invalid display name - exiting."));
381 * Lock out other session managers from running - if there is one
382 * running already - exit
384 if(!_DtGetLock(smGD.display, SM_RUNNING_LOCK))
386 PrintError(DtError, GETMESSAGE(2, 2, "Another dtsession is currently running - exiting."));
391 * Restore preferences
393 if (smGD.resourcePath[0] != '\0')
395 RestorePreferences(smGD.resourcePath);
399 * Start up the color server
401 InitializeDtcolor(srvDisplay, smGD.sessionType);
404 * AFTER the colors are set up - create the top level widget
405 * Set up a NULL WM_COMMAND property
408 XtSetArg(args[n], XmNbackground,
409 XBlackPixel(smGD.display, XDefaultScreen(smGD.display))); n++;
410 XtSetArg(args[n], XmNmappedWhenManaged, False); n++;
411 XtSetArg (args[n], XmNwidth, 1); n++;
412 XtSetArg (args[n], XmNheight, 1); n++;
413 smGD.topLevelWid = XtAppCreateShell (SM_RESOURCE_NAME, SM_RESOURCE_CLASS,
414 applicationShellWidgetClass,
415 smGD.display, args, n);
416 XtRealizeWidget(smGD.topLevelWid);
419 * Select to get the lock on timeout if the user requests it
420 * and if the server supports it. This must be done before
421 * InitSMGlobals() so smGD.lockOnTimeoutStatus is known.
423 #if defined (USE_HPSSEXT)
424 #ifdef USE_HP_SPECIFIC_XLIB
425 tmp = XHPSSChangeNotify(smGD.display, &XaSmScreenSaveRet, 3);
426 #else /* USE_HP_SPECIFIC_XLIB */
428 #endif /* USE_HP_SPECIFIC_XLIB */
429 #elif defined (USE_X11SSEXT)
430 tmp = RegisterX11ScreenSaver(smGD.display, &smGD.ssEventType);
437 smGD.lockOnTimeoutStatus = False;
438 XaSmScreenSaveRet = None;
439 #if defined (USE_X11SSEXT)
440 smGD.ssEventType = None;
445 smGD.lockOnTimeoutStatus = True;
451 * Put the program into a wait state
458 * Restore resources for lang/resolution independence
460 if((smGD.resourcePath[0] != 0) || (smGD.compatMode == False))
462 RestoreIndependentResources();
466 * Now restore the rest of the clients and the settings
468 if((smGD.clientPath[0] != 0) && (smGD.compatMode == False))
470 if(RestoreState() == -1)
477 if(smGD.compatMode == True)
480 * dtstyle needs the DT_SESSION_STATE even in
489 * Run the user's startup script if there is one
492 if(smGD.compatMode == False)
494 StartEtc(False); /* run sessionetc */
500 * If we are in compatibility mode - kill the parent and leave the
501 * child running so that the script exits
503 if(smGD.compatMode == True)
509 * Select for property notify on the top level window - so that
510 * when the style manager changes something - it is known
512 XGetWindowAttributes(smGD.display, smGD.topLevelWindow, &windAtt);
513 XSelectInput(smGD.display, smGD.topLevelWindow,
514 windAtt.your_event_mask | PropertyChangeMask);
516 ShowWaitState(False);
519 * Register for events
520 * - PropertyChange (maskable)
521 * - ClientMessage (non-maskable)
523 XtAddEventHandler(smGD.topLevelWid,
525 True, ProcessEvent, NULL);
527 smGD.smState = READY;
530 /* If we've just populated a new .dtprofile into the user's home
531 * directory, put up a popup dialog explaining the need to edit it
532 * to allow .login/.profile to work properly
535 arg = getenv("DTNEWPROFILE");
542 XtAppNextEvent(smGD.appCon, &next);
545 #if defined (USE_X11SSEXT)
546 if (next.type == smGD.ssEventType)
549 * We should simply be calling XtDispatchEvent() but the toolkit
550 * doesn't seem to know how to dispatch a run-time generated
553 ProcessEvent(smGD.topLevelWid, NULL, &next, NULL);
557 XtDispatchEvent(&next);
560 XtDispatchEvent(&next);
569 /*************************************<->*************************************
576 * Signal handler for SIGTERM. Causes dtsession to do a normal shutdown
577 * procedure without saving any state.
582 * shutDown (state flag)
592 * We want to be careful to ignore the TERM signal if we are already
593 * shutting down when it occurs.
595 *************************************<->***********************************/
600 ImmediateExit(-1, 0, True);
603 /*************************************<->*************************************
605 * RegisterX11ScreenSaver
610 * Register with X11 screen saver server extension for screen saver events.
614 * display - display from XtOpenDisplay()
615 * pssEventType - pointer to buffer in which to return ss event type
619 * pssEventType - (rc=0) screen saver event type, (rc!=0) undefined
623 * 0 - successfully registered for screen saver events
624 * other - failed to register for screen saver events
629 *************************************<->***********************************/
631 #if defined (USE_X11SSEXT)
633 RegisterX11ScreenSaver(
638 * Register with X11 screen saver server extension.
647 XSetWindowAttributes attr;
650 if (XScreenSaverQueryExtension(display, pssEventType, &ssErrorBase) &&
651 XScreenSaverQueryVersion(display, &majorVersion, &minorVersion) &&
655 * Server supports requested version of X11 screen saver extension.
657 screen = DefaultScreen(display);
658 root = DefaultRootWindow(display);
660 XGrabServer(display);
661 if (!XScreenSaverGetRegistered(display, screen, &xid, &type))
664 * No other clients registered with this server so register this one.
666 XScreenSaverRegister(display, screen, XtWindow(smGD.topLevelWid), XA_WINDOW);
669 XUngrabServer(display);
674 * Registration successful.
676 XScreenSaverSelectInput(display, root,
677 ScreenSaverNotifyMask|ScreenSaverCycleMask);
678 XScreenSaverSetAttributes(display, root, 0, 0, 1, 1, 0, CopyFromParent,
679 CopyFromParent, CopyFromParent, CWBackPixel, &attr);
684 #endif /* USE_X11SSEXT */