1/*
2 * xdmshell - simple program for running xdm from login
3 *
4 *
5Copyright 1988, 1998  The Open Group
6
7Permission to use, copy, modify, distribute, and sell this software and its
8documentation for any purpose is hereby granted without fee, provided that
9the above copyright notice appear in all copies and that both that
10copyright notice and this permission notice appear in supporting
11documentation.
12
13The above copyright notice and this permission notice shall be included in
14all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23Except as contained in this notice, the name of The Open Group shall not be
24used in advertising or otherwise to promote the sale, use or other dealings
25in this Software without prior written authorization from The Open Group.
26 * *
27 * Author:  Jim Fulton, MIT X Consortium
28 *
29 * This program should probably be setuid to root.
30 *
31 * WARNING:  Make sure that you tailor your Xresources file to have a
32 * way of invoking the abort-display() action.  Otherwise, you won't be able
33 * bring down X when you are finished.
34 */
35
36
37#include <stdio.h>
38#include "dm.h"
39#include <errno.h>
40#include <unistd.h>
41
42#ifndef BINDIR
43# define BINDIR "/usr/bin/X11"
44#endif
45
46/*
47 * HP-UX does have vfork, but A/UX doesn't
48 */
49#ifdef HAVE_WORKING_VFORK /* autoconf's preferred name */
50# define HAS_VFORK
51#endif
52
53#ifndef HAS_VFORK
54# define vfork() fork()
55#endif
56
57static char *ProgramName;
58
59static int exec_args (
60    char *filename,
61    char **args)
62{
63    pid_t pid;
64    waitType status;
65
66    if (!filename) return -1;
67
68    if (filename[0] != '/') {
69	fprintf (stderr,
70	       "%s:  attempt to execute program with relative pathname:  %s\n",
71		 ProgramName, filename);
72	return -1;
73    }
74
75    if (access (filename, X_OK) != 0) return -1;
76
77    switch (pid = vfork ()) {
78      case -1:						/* error */
79	return -1;
80      case 0:    					/* child */
81	execv (filename, args);
82	_exit (1);
83	/* NOTREACHED */
84      default:						/* parent */
85	while (wait (&status) != pid) ;
86    }
87    return waitCode (status);
88}
89
90#if defined(sun)
91static int exec_one_arg (
92    char    *filename,
93    char    *arg)
94{
95    char    *argv[3];
96
97    argv[0] = filename;
98    argv[1] = arg;
99    argv[2] = NULL;
100    return exec_args (filename, argv);
101}
102#endif
103
104int
105main (
106    int argc,
107    char *argv[])
108{
109    int ttyfd;
110    char cmdbuf[256];
111    char *args[10];
112
113    ProgramName = argv[0];
114
115    if (argc > 1) {
116	fprintf (stderr, "usage:  %s\r\n", ProgramName);
117	exit (1);
118    }
119
120    ttyfd = open ("/dev/tty", O_RDWR, 0);
121    if (ttyfd < 3) {			/* stdin = 0, stdout = 1, stderr = 2 */
122	fprintf (stderr,
123		 "%s:  must be run directly from the console.\r\n",
124		 ProgramName);
125	exit (1);
126    }
127    (void) close (ttyfd);
128
129    /* make xdm run in a non-setuid environment */
130    if (setuid (geteuid()) == -1) {
131	fprintf(stderr, "%s: cannot setuid (error %d, %s)\r\n",
132		ProgramName, errno, strerror(errno));
133	exit(1);
134    }
135
136    /*
137     * exec /usr/bin/X11/xdm -nodaemon -udpPort 0
138     */
139    strcpy (cmdbuf, BINDIR);
140    strcat (cmdbuf, "/xdm");
141    args[0] = cmdbuf;
142    args[1] = "-nodaemon";
143    args[2] = "-udpPort";
144    args[3] = "0";
145    args[4] = NULL;
146    if (exec_args (cmdbuf, args) == -1) {
147	fprintf (stderr, "%s:  unable to execute %s (error %d, %s)\r\n",
148		 ProgramName, cmdbuf, errno, strerror(errno));
149	exit (1);
150    }
151
152#ifdef sun
153    strcpy (cmdbuf, BINDIR);
154    strcat (cmdbuf, "/kbd_mode");
155    (void) exec_one_arg (cmdbuf, "-a");
156#endif
157
158    exit (0);
159    /*NOTREACHED*/
160}
161