1 /* $TOG: SmMain.c /main/18 1998/04/20 12:59:26 mgreess $ */
3 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
4 * (c) Copyright 1993, 1994 International Business Machines Corp. *
5 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
6 * (c) Copyright 1993, 1994 Novell, Inc. *
8 /*************************************<+>*************************************
9 *****************************************************************************
13 ** Project: HP DT Session Manager (dtsession)
17 ** This is the controlling program for the session manager. It
18 ** calls routines to start the BMS, initialize globals and handlers,
19 ** and restore the correct session.
22 *******************************************************************
23 ** (c) Copyright Hewlett-Packard Company, 1990. All rights are
24 ** reserved. Copying or other reproduction of this program
25 ** except for archival purposes is prohibited without prior
26 ** written consent of Hewlett-Packard Company.
27 ********************************************************************
31 *****************************************************************************
32 *************************************<+>*************************************/
37 #include <sys/access.h>
39 #include <X11/Intrinsic.h>
40 #include <X11/StringDefs.h>
42 #if defined (USE_X11SSEXT)
43 #include <X11/extensions/scrnsaver.h>
44 #endif /* USE_X11SSEXT */
47 #include <Dt/UserMsg.h>
48 #include <Dt/EnvControlP.h>
52 #include "SmGlobals.h"
54 #include "SmRestore.h"
56 #include "SrvPalette.h"
57 #include "SmProtocol.h"
63 void main(int, char **);
64 static void StopAll(int i);
65 static int RegisterX11ScreenSaver(Display *display, int *ssEventType);
71 #define SECURE_SYS_PATH "/.secure/etc/passwd"
74 #define SECURE_SYS_PATH "/etc/security/passwd"
77 #define SECURE_SYS_PATH "/etc/shadow"
82 /*************************************<->*************************************
89 * Controls the startup and event dispatching of the session manager.
94 * argc = command line options
95 * argv = number of command line options
105 *************************************<->***********************************/
114 XWindowAttributes windAtt;
115 XPropertyEvent *pEvent = (XPropertyEvent *) &next;
119 struct sigaction stopvec;
124 # include <sys/sysinfo.h>
125 # include <sys/proc.h>
129 unsigned long nbytes = 1;
131 unsigned long flag = 0;
137 buffer[0] = SSIN_UACPROC;
138 buffer[1] = UAC_NOPRINT;
140 buffer[1] |= UAC_SIGBUS;
143 ssi_status = setsysinfo ( op, buffer, nbytes, arg, flag );
146 setlocale( LC_ALL, "" );
147 XtSetLanguageProc( NULL, NULL, NULL );
149 smGD.smState = IN_PROCESS;
150 smGD.programName = strdup (argv[0]);
153 * We report some errors before we call the DtInitialize procedure.
154 * The Dt initialize procedure sets this name. If we report
155 * an error via DtSimple error before this is set we see the message
156 * prepended with <unknown program name> in the error log.
158 DtProgName = SM_RESOURCE_NAME ;
171 * Set our effective gid to the real gid until we need it to be
172 * sys (during contention management)
174 smGD.runningGID = getgid();
175 smGD.conMgmtGID = getegid();
178 * Set uid up according to whether this is a secure system
179 * Secure systems need root priviledges to read the /etc/passwd file
181 smGD.runningUID = getuid();
183 #ifdef SECURE_SYS_PATH
184 status = stat(SECURE_SYS_PATH, &buf);
190 * Initialize LANG if it isn't defined.
192 if ((lang = getenv ("LANG")) == NULL)
195 (void) strcpy (lang, "LANG=C");
196 (void) putenv (lang);
202 * this is not a secure system - remove all suid priviledges
204 smGD.unLockUID = smGD.runningUID;
205 smGD.secureSystem = False;
206 SM_SETESUID(smGD.runningUID);
211 * Save the root priviledge to be restored when trying to unlock
213 smGD.unLockUID = geteuid();
214 smGD.secureSystem = True;
215 SM_SETEUID(smGD.runningUID);
219 setresgid(-1, smGD.runningGID, -1);
220 #else /* _AIX or any other system */
222 setregid(smGD.conMgmtGID, smGD.runningGID);
224 setgid(smGD.conMgmtGID);
225 setegid(smGD.runningGID);
230 * Set up POSIX sigaction structs
234 * Must set SIGPIPE to SIG_IGN so the process does not exit
235 * if a child terminates unexpectedly during an I/O operation
236 * that raises SIGPIPE. Note that before this process exec's
237 * any subprocesses, SIGPIPE must be set to SIG_DFL.
239 sigemptyset(&stopvec.sa_mask);
240 stopvec.sa_flags = 0;
241 stopvec.sa_handler = SIG_IGN;
242 (void) sigaction(SIGPIPE, &stopvec, (struct sigaction *) NULL);
244 stopvec.sa_handler = StopAll;
245 sigemptyset(&stopvec.sa_mask);
246 stopvec.sa_flags = 0;
248 smGD.childvec.sa_handler = WaitChildDeath;
249 sigemptyset(&smGD.childvec.sa_mask);
250 smGD.childvec.sa_flags = 0;
252 smGD.defvec.sa_handler = SIG_DFL;
253 sigemptyset(&smGD.defvec.sa_mask);
254 smGD.defvec.sa_flags = 0;
260 * This must be done before XtToolkitInitialize
261 * to set up the local environment
263 _DtEnvControl(DT_ENV_SET);
264 _DtEnvControl(DT_ENV_SET_BIN);
267 * Set up NLS error messages first
272 * Set the paths of where resources are to be restored from
274 SetRestorePath(argc, argv);
277 * The first thing that must happen is that resources must be restored
278 * so that my resources will be correct
280 if(smGD.compatMode == False)
283 * Load session resources.
285 RestoreResources(False,
289 smGD.resourcePath[0] != '\0' ? "-file" : NULL,
295 * Set up to catch SIGTERM
297 stopvec.sa_handler = StopAll;
298 sigemptyset(&stopvec.sa_mask);
299 stopvec.sa_flags = 0;
301 sigaction(SIGTERM, &stopvec, (struct sigaction *) NULL);
304 * Now set up a communication with the toolkit
306 * Create one display connection for dtsession, and one for
307 * the color server. We cannot share a display connection since
308 * motif creates a display object for the color server's display during
309 * color server initialization. Since the color server is not yet
310 * operational, any dialogs (ie the dtsession logout confirmation
311 * dialogs) created on that display do not get the color server colors.
312 * The dtsession display object is created after color server
313 * initialization is complete.
315 if (smGD.appCon == 0) {
317 * The following code will have been initialized if the
318 * session creation code posted a dialog.
320 XtToolkitInitialize();
321 smGD.appCon = XtCreateApplicationContext();
322 smGD.display = XtOpenDisplay(smGD.appCon, NULL, argv[0],
324 NULL, 0, &argc, argv);
327 srvDisplay = XtOpenDisplay(smGD.appCon, NULL, argv[0], SM_RESOURCE_CLASS,
328 NULL, 0, &argc, argv);
333 if (!InitXSMP (argv[0]))
336 /* Added the following check to exit in case of error RK 09.08.93 */
337 if(smGD.display == NULL)
339 PrintError(DtError, GETMESSAGE(4, 1, "Invalid display name - exiting."));
344 * Lock out other session managers from running - if there is one
345 * running already - exit
347 if(!_DtGetLock(smGD.display, SM_RUNNING_LOCK))
349 PrintError(DtError, GETMESSAGE(2, 2, "Another dtsession is currently running - exiting."));
354 * Restore preferences
356 if (smGD.resourcePath[0] != '\0')
358 RestorePreferences(smGD.resourcePath);
362 * Start up the color server
364 InitializeDtcolor(srvDisplay, smGD.sessionType);
367 * AFTER the colors are set up - create the top level widget
368 * Set up a NULL WM_COMMAND property
371 XtSetArg(args[n], XmNbackground,
372 XBlackPixel(smGD.display, XDefaultScreen(smGD.display))); n++;
373 XtSetArg(args[n], XmNmappedWhenManaged, False); n++;
374 XtSetArg (args[n], XmNwidth, 1); n++;
375 XtSetArg (args[n], XmNheight, 1); n++;
376 smGD.topLevelWid = XtAppCreateShell (SM_RESOURCE_NAME, SM_RESOURCE_CLASS,
377 applicationShellWidgetClass,
378 smGD.display, args, n);
379 XtRealizeWidget(smGD.topLevelWid);
382 * Select to get the lock on timeout if the user requests it
383 * and if the server supports it. This must be done before
384 * InitSMGlobals() so smGD.lockOnTimeoutStatus is known.
386 #if defined (USE_HPSSEXT)
387 #ifdef USE_HP_SPECIFIC_XLIB
388 tmp = XHPSSChangeNotify(smGD.display, &XaSmScreenSaveRet, 3);
389 #else /* USE_HP_SPECIFIC_XLIB */
391 #endif /* USE_HP_SPECIFIC_XLIB */
392 #elif defined (USE_X11SSEXT)
393 tmp = RegisterX11ScreenSaver(smGD.display, &smGD.ssEventType);
400 smGD.lockOnTimeoutStatus = False;
401 XaSmScreenSaveRet = None;
402 #if defined (USE_X11SSEXT)
403 smGD.ssEventType = None;
408 smGD.lockOnTimeoutStatus = True;
414 * Put the program into a wait state
421 * Restore resources for lang/resolution independence
423 if((smGD.resourcePath[0] != NULL) || (smGD.compatMode == False))
425 RestoreIndependentResources();
429 * Now restore the rest of the clients and the settings
431 if((smGD.clientPath[0] != NULL) && (smGD.compatMode == False))
433 if(RestoreState() == -1)
440 if(smGD.compatMode == True)
443 * dtstyle needs the DT_SESSION_STATE even in
452 * Run the user's startup script if there is one
455 if(smGD.compatMode == False)
457 StartEtc(False); /* run sessionetc */
463 * If we are in compatibility mode - kill the parent and leave the
464 * child running so that the script exits
466 if(smGD.compatMode == True)
472 * Select for property notify on the top level window - so that
473 * when the style manager changes something - it is known
475 XGetWindowAttributes(smGD.display, smGD.topLevelWindow, &windAtt);
476 XSelectInput(smGD.display, smGD.topLevelWindow,
477 windAtt.your_event_mask | PropertyChangeMask);
479 ShowWaitState(False);
482 * Register for events
483 * - PropertyChange (maskable)
484 * - ClientMessage (non-maskable)
486 XtAddEventHandler(smGD.topLevelWid,
488 True, ProcessEvent, NULL);
490 smGD.smState = READY;
493 /* If we've just populated a new .dtprofile into the user's home
494 * directory, put up a popup dialog explaining the need to edit it
495 * to allow .login/.profile to work properly
498 arg = getenv("DTNEWPROFILE");
505 XtAppNextEvent(smGD.appCon, &next);
508 #if defined (USE_X11SSEXT)
509 if (next.type == smGD.ssEventType)
512 * We should simply be calling XtDispatchEvent() but the toolkit
513 * doesn't seem to know how to dispatch a run-time generated
516 ProcessEvent(smGD.topLevelWid, NULL, &next, NULL);
520 XtDispatchEvent(&next);
523 XtDispatchEvent(&next);
532 /*************************************<->*************************************
539 * Signal handler for SIGTERM. Causes dtsession to do a normal shutdown
540 * procedure without saving any state.
545 * shutDown (state flag)
555 * We want to be careful to ignore the TERM signal if we are already
556 * shutting down when it occurs.
558 *************************************<->***********************************/
563 ImmediateExit(-1, 0, True);
566 /*************************************<->*************************************
568 * RegisterX11ScreenSaver
573 * Register with X11 screen saver server extension for screen saver events.
577 * display - display from XtOpenDisplay()
578 * pssEventType - pointer to buffer in which to return ss event type
582 * pssEventType - (rc=0) screen saver event type, (rc!=0) undefined
586 * 0 - successfully registered for screen saver events
587 * other - failed to register for screen saver events
592 *************************************<->***********************************/
594 #if defined (USE_X11SSEXT)
596 RegisterX11ScreenSaver(
601 * Register with X11 screen saver server extension.
610 XSetWindowAttributes attr;
613 if (XScreenSaverQueryExtension(display, pssEventType, &ssErrorBase) &&
614 XScreenSaverQueryVersion(display, &majorVersion, &minorVersion) &&
618 * Server supports requested version of X11 screen saver extension.
620 screen = DefaultScreen(display);
621 root = DefaultRootWindow(display);
623 XGrabServer(display);
624 if (!XScreenSaverGetRegistered(display, screen, &xid, &type))
627 * No other clients registered with this server so register this one.
629 XScreenSaverRegister(display, screen, XtWindow(smGD.topLevelWid), XA_WINDOW);
632 XUngrabServer(display);
637 * Registration successful.
639 XScreenSaverSelectInput(display, root,
640 ScreenSaverNotifyMask|ScreenSaverCycleMask);
641 XScreenSaverSetAttributes(display, root, 0, 0, 1, 1, 0, CopyFromParent,
642 CopyFromParent, CopyFromParent, CWBackPixel, &attr);
647 #endif /* USE_X11SSEXT */