#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#ifdef __CYGWIN__
#include <stdlib.h>
#include <signal.h>
#endif
#if defined(WIN32) && !defined(__CYGWIN__)
#include <X11/Xwinsock.h>
#endif
#include <X11/Xos.h>
#include <stdio.h>
#include <time.h>
#if !defined(WIN32) || !defined(__MINGW32__)
#include <sys/time.h>
#include <sys/resource.h>
#endif
#include "misc.h"
#include <X11/X.h>
#define XSERV_t
#define TRANS_SERVER
#define TRANS_REOPEN
#include <X11/Xtrans/Xtrans.h>
#include "input.h"
#include "dixfont.h"
#include "osdep.h"
#include "extension.h"
#ifdef X_POSIX_C_SOURCE
#define _POSIX_C_SOURCE X_POSIX_C_SOURCE
#include <signal.h>
#undef _POSIX_C_SOURCE
#else
#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
#include <signal.h>
#else
#define _POSIX_SOURCE
#include <signal.h>
#undef _POSIX_SOURCE
#endif
#endif
#ifndef WIN32
#include <sys/wait.h>
#endif
#if !defined(SYSV) && !defined(WIN32) && !defined(Lynx) && !defined(QNX4)
#include <sys/resource.h>
#endif
#include <sys/stat.h>
#include <ctype.h>
#include <stdarg.h>
#if defined(DGUX)
#include <sys/resource.h>
#include <netdb.h>
#endif
#include <stdlib.h>
#if defined(TCPCONN) || defined(STREAMSCONN)
# ifndef WIN32
# include <netdb.h>
# endif
#endif
#include "opaque.h"
#ifdef SMART_SCHEDULE
#include "dixstruct.h"
#endif
#ifdef XKB
#include <xkbsrv.h>
#endif
#ifdef XCSECURITY
#include "securitysrv.h"
#endif
#ifdef RENDER
#include "picture.h"
#endif
#ifdef XPRINT
#include "DiPrint.h"
#endif
_X_EXPORT Bool noTestExtensions;
#ifdef BIGREQS
_X_EXPORT Bool noBigReqExtension = FALSE;
#endif
#ifdef COMPOSITE
_X_EXPORT Bool noCompositeExtension = FALSE;
#endif
#ifdef DAMAGE
_X_EXPORT Bool noDamageExtension = FALSE;
#endif
#ifdef DBE
_X_EXPORT Bool noDbeExtension = FALSE;
#endif
#ifdef DPMSExtension
_X_EXPORT Bool noDPMSExtension = FALSE;
#endif
#ifdef EVI
_X_EXPORT Bool noEVIExtension = FALSE;
#endif
#ifdef FONTCACHE
_X_EXPORT Bool noFontCacheExtension = FALSE;
#endif
#ifdef GLXEXT
_X_EXPORT Bool noGlxExtension = FALSE;
#endif
#ifdef SCREENSAVER
_X_EXPORT Bool noScreenSaverExtension = FALSE;
#endif
#ifdef MITSHM
_X_EXPORT Bool noMITShmExtension = FALSE;
#endif
#ifdef MITMISC
_X_EXPORT Bool noMITMiscExtension = FALSE;
#endif
#ifdef MULTIBUFFER
_X_EXPORT Bool noMultibufferExtension = FALSE;
#endif
#ifdef RANDR
_X_EXPORT Bool noRRExtension = FALSE;
#endif
#ifdef RENDER
_X_EXPORT Bool noRenderExtension = FALSE;
#endif
#ifdef SHAPE
_X_EXPORT Bool noShapeExtension = FALSE;
#endif
#ifdef XCSECURITY
_X_EXPORT Bool noSecurityExtension = FALSE;
#endif
#ifdef XSYNC
_X_EXPORT Bool noSyncExtension = FALSE;
#endif
#ifdef TOGCUP
_X_EXPORT Bool noXcupExtension = FALSE;
#endif
#ifdef RES
_X_EXPORT Bool noResExtension = FALSE;
#endif
#ifdef XAPPGROUP
_X_EXPORT Bool noXagExtension = FALSE;
#endif
#ifdef XCMISC
_X_EXPORT Bool noXCMiscExtension = FALSE;
#endif
#ifdef XEVIE
_X_EXPORT Bool noXevieExtension = TRUE;
#endif
#ifdef XF86BIGFONT
_X_EXPORT Bool noXFree86BigfontExtension = FALSE;
#endif
#ifdef XFreeXDGA
_X_EXPORT Bool noXFree86DGAExtension = FALSE;
#endif
#ifdef XF86DRI
_X_EXPORT Bool noXFree86DRIExtension = FALSE;
#endif
#ifdef XF86MISC
_X_EXPORT Bool noXFree86MiscExtension = FALSE;
#endif
#ifdef XF86VIDMODE
_X_EXPORT Bool noXFree86VidModeExtension = FALSE;
#endif
#ifdef XFIXES
_X_EXPORT Bool noXFixesExtension = FALSE;
#endif
#ifdef PANORAMIX
_X_EXPORT Bool noPanoramiXExtension = TRUE;
#endif
#ifdef XINPUT
_X_EXPORT Bool noXInputExtension = FALSE;
#endif
#ifdef XIDLE
_X_EXPORT Bool noXIdleExtension = FALSE;
#endif
#ifdef XV
_X_EXPORT Bool noXvExtension = FALSE;
#endif
#define X_INCLUDE_NETDB_H
#include <X11/Xos_r.h>
#include <errno.h>
Bool CoreDump;
#ifdef PANORAMIX
Bool PanoramiXExtensionDisabledHack = FALSE;
#endif
int auditTrailLevel = 1;
_X_EXPORT Bool Must_have_memory = FALSE;
#ifdef AIXV3
int SyncOn = 0;
extern int SelectWaitTime;
#endif
#if defined(SVR4) || defined(__linux__) || defined(CSRG_BASED)
#define HAS_SAVED_IDS_AND_SETEUID
#endif
#ifdef MEMBUG
#define MEM_FAIL_SCALE 100000
long Memory_fail = 0;
#include <stdlib.h>
#endif
static char *dev_tty_from_init = NULL;
OsSigHandlerPtr
OsSignal(sig, handler)
int sig;
OsSigHandlerPtr handler;
{
#ifdef X_NOT_POSIX
return signal(sig, handler);
#else
struct sigaction act, oact;
sigemptyset(&act.sa_mask);
if (handler != SIG_IGN)
sigaddset(&act.sa_mask, sig);
act.sa_flags = 0;
act.sa_handler = handler;
if (sigaction(sig, &act, &oact))
perror("sigaction");
return oact.sa_handler;
#endif
}
#ifdef SERVER_LOCK
#define LOCK_DIR "/tmp"
#define LOCK_TMP_PREFIX "/.tX"
#define LOCK_PREFIX "/.X"
#define LOCK_SUFFIX "-lock"
#if defined(DGUX)
#include <limits.h>
#include <sys/param.h>
#endif
#ifndef PATH_MAX
#ifndef Lynx
#include <sys/param.h>
#else
#include <param.h>
#endif
#ifndef PATH_MAX
#ifdef MAXPATHLEN
#define PATH_MAX MAXPATHLEN
#else
#define PATH_MAX 1024
#endif
#endif
#endif
static Bool StillLocking = FALSE;
static char LockFile[PATH_MAX];
static Bool nolock = FALSE;
void
LockServer(void)
{
char tmp[PATH_MAX], pid_str[12];
int lfd, i, haslock, l_pid, t;
char *tmppath = NULL;
int len;
char port[20];
if (nolock) return;
tmppath = LOCK_DIR;
sprintf(port, "%d", atoi(display));
len = strlen(LOCK_PREFIX) > strlen(LOCK_TMP_PREFIX) ? strlen(LOCK_PREFIX) :
strlen(LOCK_TMP_PREFIX);
len += strlen(tmppath) + strlen(port) + strlen(LOCK_SUFFIX) + 1;
if (len > sizeof(LockFile))
FatalError("Display name `%s' is too long\n", port);
(void)sprintf(tmp, "%s" LOCK_TMP_PREFIX "%s" LOCK_SUFFIX, tmppath, port);
(void)sprintf(LockFile, "%s" LOCK_PREFIX "%s" LOCK_SUFFIX, tmppath, port);
StillLocking = TRUE;
i = 0;
do {
i++;
lfd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0644);
if (lfd < 0)
sleep(2);
else
break;
} while (i < 3);
if (lfd < 0) {
unlink(tmp);
i = 0;
do {
i++;
lfd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0644);
if (lfd < 0)
sleep(2);
else
break;
} while (i < 3);
}
if (lfd < 0)
FatalError("Could not create lock file in %s\n", tmp);
(void) sprintf(pid_str, "%10ld\n", (long)getpid());
(void) write(lfd, pid_str, 11);
#ifndef USE_CHMOD
(void) fchmod(lfd, 0444);
#else
(void) chmod(tmp, 0444);
#endif
(void) close(lfd);
i = 0;
haslock = 0;
while ((!haslock) && (i++ < 3)) {
haslock = (link(tmp,LockFile) == 0);
if (haslock) {
break;
}
else {
lfd = open(LockFile, O_RDONLY);
if (lfd < 0) {
unlink(tmp);
FatalError("Can't read lock file %s\n", LockFile);
}
pid_str[0] = '\0';
if (read(lfd, pid_str, 11) != 11) {
unlink(LockFile);
close(lfd);
continue;
}
pid_str[11] = '\0';
sscanf(pid_str, "%d", &l_pid);
close(lfd);
errno = 0;
t = kill(l_pid, 0);
if ((t< 0) && (errno == ESRCH)) {
unlink(LockFile);
continue;
}
else if (((t < 0) && (errno == EPERM)) || (t == 0)) {
unlink(tmp);
FatalError("Server is already active for display %s\n%s %s\n%s\n",
port, "\tIf this server is no longer running, remove",
LockFile, "\tand start again.");
}
}
}
unlink(tmp);
if (!haslock)
FatalError("Could not create server lock file: %s\n", LockFile);
StillLocking = FALSE;
}
void
UnlockServer(void)
{
if (nolock) return;
if (!StillLocking){
(void) unlink(LockFile);
}
}
#endif
SIGVAL
AutoResetServer (int sig)
{
int olderrno = errno;
dispatchException |= DE_RESET;
isItTimeToYield = TRUE;
#ifdef GPROF
chdir ("/tmp");
exit (0);
#endif
#if defined(SYSV) && defined(X_NOT_POSIX)
OsSignal (SIGHUP, AutoResetServer);
#endif
errno = olderrno;
}
_X_EXPORT SIGVAL
GiveUp(int sig)
{
int olderrno = errno;
dispatchException |= DE_TERMINATE;
isItTimeToYield = TRUE;
#if defined(SYSV) && defined(X_NOT_POSIX)
if (sig)
OsSignal(sig, SIG_IGN);
#endif
errno = olderrno;
}
#if defined WIN32 && defined __MINGW32__
_X_EXPORT CARD32
GetTimeInMillis (void)
{
return GetTickCount ();
}
#else
_X_EXPORT CARD32
GetTimeInMillis(void)
{
struct timeval tv;
#ifdef MONOTONIC_CLOCK
struct timespec tp;
if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L);
#endif
X_GETTIMEOFDAY(&tv);
return(tv.tv_sec * 1000) + (tv.tv_usec / 1000);
}
#endif
_X_EXPORT void
AdjustWaitForDelay (pointer waitTime, unsigned long newdelay)
{
static struct timeval delay_val;
struct timeval **wt = (struct timeval **) waitTime;
unsigned long olddelay;
if (*wt == NULL)
{
delay_val.tv_sec = newdelay / 1000;
delay_val.tv_usec = 1000 * (newdelay % 1000);
*wt = &delay_val;
}
else
{
olddelay = (*wt)->tv_sec * 1000 + (*wt)->tv_usec / 1000;
if (newdelay < olddelay)
{
(*wt)->tv_sec = newdelay / 1000;
(*wt)->tv_usec = 1000 * (newdelay % 1000);
}
}
}
void UseMsg(void)
{
#if !defined(AIXrt) && !defined(AIX386)
ErrorF("use: X [:<display>] [option]\n");
ErrorF("-a # mouse acceleration (pixels)\n");
ErrorF("-ac disable access control restrictions\n");
#ifdef MEMBUG
ErrorF("-alloc int chance alloc should fail\n");
#endif
ErrorF("-audit int set audit trail level\n");
ErrorF("-auth file select authorization file\n");
ErrorF("-br create root window with black background\n");
ErrorF("+bs enable any backing store support\n");
ErrorF("-bs disable any backing store support\n");
ErrorF("-c turns off key-click\n");
ErrorF("c # key-click volume (0-100)\n");
ErrorF("-cc int default color visual class\n");
ErrorF("-co file color database file\n");
#ifdef COMMANDLINE_CHALLENGED_OPERATING_SYSTEMS
ErrorF("-config file read options from file\n");
#endif
ErrorF("-core generate core dump on fatal error\n");
ErrorF("-dpi int screen resolution in dots per inch\n");
#ifdef DPMSExtension
ErrorF("dpms enables VESA DPMS monitor control\n");
ErrorF("-dpms disables VESA DPMS monitor control\n");
#endif
ErrorF("-deferglyphs [none|all|16] defer loading of [no|all|16-bit] glyphs\n");
ErrorF("-f # bell base (0-100)\n");
ErrorF("-fc string cursor font\n");
ErrorF("-fn string default font name\n");
ErrorF("-fp string default font path\n");
ErrorF("-help prints message with these options\n");
ErrorF("-I ignore all remaining arguments\n");
#ifdef RLIMIT_DATA
ErrorF("-ld int limit data space to N Kb\n");
#endif
#ifdef RLIMIT_NOFILE
ErrorF("-lf int limit number of open files to N\n");
#endif
#ifdef RLIMIT_STACK
ErrorF("-ls int limit stack space to N Kb\n");
#endif
#ifdef SERVER_LOCK
ErrorF("-nolock disable the locking mechanism\n");
#endif
#ifndef NOLOGOHACK
ErrorF("-logo enable logo in screen saver\n");
ErrorF("nologo disable logo in screen saver\n");
#endif
ErrorF("-nolisten string don't listen on protocol\n");
ErrorF("-noreset don't reset after last client exists\n");
ErrorF("-reset reset after last client exists\n");
ErrorF("-p # screen-saver pattern duration (minutes)\n");
ErrorF("-pn accept failure to listen on all ports\n");
ErrorF("-nopn reject failure to listen on all ports\n");
ErrorF("-r turns off auto-repeat\n");
ErrorF("r turns on auto-repeat \n");
#ifdef RENDER
ErrorF("-render [default|mono|gray|color] set render color alloc policy\n");
#endif
ErrorF("-s # screen-saver timeout (minutes)\n");
#ifdef XCSECURITY
ErrorF("-sp file security policy file\n");
#endif
#ifdef XPRINT
PrinterUseMsg();
#endif
ErrorF("-su disable any save under support\n");
ErrorF("-t # mouse threshold (pixels)\n");
ErrorF("-terminate terminate at server reset\n");
ErrorF("-to # connection time out\n");
ErrorF("-tst disable testing extensions\n");
ErrorF("ttyxx server started from init on /dev/ttyxx\n");
ErrorF("v video blanking for screen-saver\n");
ErrorF("-v screen-saver without video blanking\n");
ErrorF("-wm WhenMapped default backing-store\n");
ErrorF("-wr create root window with white background\n");
ErrorF("-x string loads named extension at init time \n");
ErrorF("-maxbigreqsize set maximal bigrequest size \n");
#ifdef PANORAMIX
ErrorF("+xinerama Enable XINERAMA extension\n");
ErrorF("-xinerama Disable XINERAMA extension\n");
#endif
#ifdef SMART_SCHEDULE
ErrorF("-dumbSched Disable smart scheduling, enable old behavior\n");
ErrorF("-schedInterval int Set scheduler interval in msec\n");
#endif
ErrorF("+extension name Enable extension\n");
ErrorF("-extension name Disable extension\n");
#ifdef XDMCP
XdmcpUseMsg();
#endif
#endif
#ifdef XKB
XkbUseMsg();
#endif
ddxUseMsg();
}
static int
VerifyDisplayName(const char *d)
{
if ( d == (char *)0 ) return( 0 );
if ( *d == '\0' ) return( 0 );
if ( *d == '-' ) return( 0 );
if ( *d == '.' ) return( 0 );
if ( strchr(d, '/') != (char *)0 ) return( 0 );
return( 1 );
}
void InitGlobals(void)
{
ddxInitGlobals();
}
void
ProcessCommandLine(int argc, char *argv[])
{
int i, skip;
defaultKeyboardControl.autoRepeat = TRUE;
#ifdef NO_PART_NET
PartialNetwork = FALSE;
#else
PartialNetwork = TRUE;
#endif
for ( i = 1; i < argc; i++ )
{
if((skip = ddxProcessArgument(argc, argv, i)))
{
i += (skip - 1);
}
else if(argv[i][0] == ':')
{
display = argv[i];
display++;
if( ! VerifyDisplayName( display ) ) {
ErrorF("Bad display name: %s\n", display);
UseMsg();
FatalError("Bad display name, exiting: %s\n", display);
}
}
else if ( strcmp( argv[i], "-a") == 0)
{
if(++i < argc)
defaultPointerControl.num = atoi(argv[i]);
else
UseMsg();
}
else if ( strcmp( argv[i], "-ac") == 0)
{
defeatAccessControl = TRUE;
}
#ifdef MEMBUG
else if ( strcmp( argv[i], "-alloc") == 0)
{
if(++i < argc)
Memory_fail = atoi(argv[i]);
else
UseMsg();
}
#endif
else if ( strcmp( argv[i], "-audit") == 0)
{
if(++i < argc)
auditTrailLevel = atoi(argv[i]);
else
UseMsg();
}
else if ( strcmp( argv[i], "-auth") == 0)
{
if(++i < argc)
InitAuthorization (argv[i]);
else
UseMsg();
}
else if ( strcmp( argv[i], "-br") == 0)
blackRoot = TRUE;
else if ( strcmp( argv[i], "+bs") == 0)
enableBackingStore = TRUE;
else if ( strcmp( argv[i], "-bs") == 0)
disableBackingStore = TRUE;
else if ( strcmp( argv[i], "c") == 0)
{
if(++i < argc)
defaultKeyboardControl.click = atoi(argv[i]);
else
UseMsg();
}
else if ( strcmp( argv[i], "-c") == 0)
{
defaultKeyboardControl.click = 0;
}
else if ( strcmp( argv[i], "-cc") == 0)
{
if(++i < argc)
defaultColorVisualClass = atoi(argv[i]);
else
UseMsg();
}
else if ( strcmp( argv[i], "-co") == 0)
{
if(++i < argc)
rgbPath = argv[i];
else
UseMsg();
}
else if ( strcmp( argv[i], "-core") == 0)
{
CoreDump = TRUE;
#if !defined(WIN32) || !defined(__MINGW32__)
struct rlimit core_limit;
getrlimit (RLIMIT_CORE, &core_limit);
core_limit.rlim_cur = core_limit.rlim_max;
setrlimit (RLIMIT_CORE, &core_limit);
#endif
}
else if ( strcmp( argv[i], "-dpi") == 0)
{
if(++i < argc)
monitorResolution = atoi(argv[i]);
else
UseMsg();
}
#ifdef DPMSExtension
else if ( strcmp( argv[i], "dpms") == 0)
DPMSEnabledSwitch = TRUE;
else if ( strcmp( argv[i], "-dpms") == 0)
DPMSDisabledSwitch = TRUE;
#endif
else if ( strcmp( argv[i], "-deferglyphs") == 0)
{
if(++i >= argc || !ParseGlyphCachingMode(argv[i]))
UseMsg();
}
else if ( strcmp( argv[i], "-f") == 0)
{
if(++i < argc)
defaultKeyboardControl.bell = atoi(argv[i]);
else
UseMsg();
}
else if ( strcmp( argv[i], "-fc") == 0)
{
if(++i < argc)
defaultCursorFont = argv[i];
else
UseMsg();
}
else if ( strcmp( argv[i], "-fn") == 0)
{
if(++i < argc)
defaultTextFont = argv[i];
else
UseMsg();
}
else if ( strcmp( argv[i], "-fp") == 0)
{
if(++i < argc)
{
defaultFontPath = argv[i];
}
else
UseMsg();
}
else if ( strcmp( argv[i], "-help") == 0)
{
UseMsg();
exit(0);
}
#ifdef XKB
else if ( (skip=XkbProcessArguments(argc,argv,i))!=0 ) {
if (skip>0)
i+= skip-1;
else UseMsg();
}
#endif
#ifdef RLIMIT_DATA
else if ( strcmp( argv[i], "-ld") == 0)
{
if(++i < argc)
{
limitDataSpace = atoi(argv[i]);
if (limitDataSpace > 0)
limitDataSpace *= 1024;
}
else
UseMsg();
}
#endif
#ifdef RLIMIT_NOFILE
else if ( strcmp( argv[i], "-lf") == 0)
{
if(++i < argc)
limitNoFile = atoi(argv[i]);
else
UseMsg();
}
#endif
#ifdef RLIMIT_STACK
else if ( strcmp( argv[i], "-ls") == 0)
{
if(++i < argc)
{
limitStackSpace = atoi(argv[i]);
if (limitStackSpace > 0)
limitStackSpace *= 1024;
}
else
UseMsg();
}
#endif
#ifdef SERVER_LOCK
else if ( strcmp ( argv[i], "-nolock") == 0)
{
#if !defined(WIN32) && !defined(__CYGWIN__)
if (getuid() != 0)
ErrorF("Warning: the -nolock option can only be used by root\n");
else
#endif
nolock = TRUE;
}
#endif
#ifndef NOLOGOHACK
else if ( strcmp( argv[i], "-logo") == 0)
{
logoScreenSaver = 1;
}
else if ( strcmp( argv[i], "nologo") == 0)
{
logoScreenSaver = 0;
}
#endif
else if ( strcmp( argv[i], "-nolisten") == 0)
{
if(++i < argc) {
if (_XSERVTransNoListen(argv[i]))
FatalError ("Failed to disable listen for %s transport",
argv[i]);
} else
UseMsg();
}
else if ( strcmp( argv[i], "-noreset") == 0)
{
dispatchExceptionAtReset = 0;
}
else if ( strcmp( argv[i], "-reset") == 0)
{
dispatchExceptionAtReset = DE_RESET;
}
else if ( strcmp( argv[i], "-p") == 0)
{
if(++i < argc)
defaultScreenSaverInterval = ((CARD32)atoi(argv[i])) *
MILLI_PER_MIN;
else
UseMsg();
}
else if ( strcmp( argv[i], "-pn") == 0)
PartialNetwork = TRUE;
else if ( strcmp( argv[i], "-nopn") == 0)
PartialNetwork = FALSE;
else if ( strcmp( argv[i], "r") == 0)
defaultKeyboardControl.autoRepeat = TRUE;
else if ( strcmp( argv[i], "-r") == 0)
defaultKeyboardControl.autoRepeat = FALSE;
else if ( strcmp( argv[i], "-s") == 0)
{
if(++i < argc)
defaultScreenSaverTime = ((CARD32)atoi(argv[i])) *
MILLI_PER_MIN;
else
UseMsg();
}
else if ( strcmp( argv[i], "-su") == 0)
disableSaveUnders = TRUE;
else if ( strcmp( argv[i], "-t") == 0)
{
if(++i < argc)
defaultPointerControl.threshold = atoi(argv[i]);
else
UseMsg();
}
else if ( strcmp( argv[i], "-terminate") == 0)
{
dispatchExceptionAtReset = DE_TERMINATE;
}
else if ( strcmp( argv[i], "-to") == 0)
{
if(++i < argc)
TimeOutValue = ((CARD32)atoi(argv[i])) * MILLI_PER_SECOND;
else
UseMsg();
}
else if ( strcmp( argv[i], "-tst") == 0)
{
noTestExtensions = TRUE;
}
else if ( strcmp( argv[i], "v") == 0)
defaultScreenSaverBlanking = PreferBlanking;
else if ( strcmp( argv[i], "-v") == 0)
defaultScreenSaverBlanking = DontPreferBlanking;
else if ( strcmp( argv[i], "-wm") == 0)
defaultBackingStore = WhenMapped;
else if ( strcmp( argv[i], "-wr") == 0)
whiteRoot = TRUE;
else if ( strcmp( argv[i], "-maxbigreqsize") == 0) {
if(++i < argc) {
long reqSizeArg = atol(argv[i]);
if( reqSizeArg > 0L && reqSizeArg < 128L ) {
maxBigRequestSize = (reqSizeArg * 1048576L) - 1L;
}
else
{
UseMsg();
}
}
else
{
UseMsg();
}
}
#ifdef PANORAMIX
else if ( strcmp( argv[i], "+xinerama") == 0){
noPanoramiXExtension = FALSE;
}
else if ( strcmp( argv[i], "-xinerama") == 0){
noPanoramiXExtension = TRUE;
}
else if ( strcmp( argv[i], "-disablexineramaextension") == 0){
PanoramiXExtensionDisabledHack = TRUE;
}
#endif
else if ( strcmp( argv[i], "-x") == 0)
{
if(++i >= argc)
UseMsg();
}
else if ( strcmp( argv[i], "-I") == 0)
{
break;
}
else if (strncmp (argv[i], "tty", 3) == 0)
{
dev_tty_from_init = argv[i];
}
#ifdef XDMCP
else if ((skip = XdmcpOptions(argc, argv, i)) != i)
{
i = skip - 1;
}
#endif
#ifdef XPRINT
else if ((skip = PrinterOptions(argc, argv, i)) != i)
{
i = skip - 1;
}
#endif
#ifdef XCSECURITY
else if ((skip = XSecurityOptions(argc, argv, i)) != i)
{
i = skip - 1;
}
#endif
#ifdef AIXV3
else if ( strcmp( argv[i], "-timeout") == 0)
{
if(++i < argc)
SelectWaitTime = atoi(argv[i]);
else
UseMsg();
}
else if ( strcmp( argv[i], "-sync") == 0)
{
SyncOn++;
}
#endif
#ifdef SMART_SCHEDULE
else if ( strcmp( argv[i], "-dumbSched") == 0)
{
SmartScheduleDisable = TRUE;
}
else if ( strcmp( argv[i], "-schedInterval") == 0)
{
if (++i < argc)
{
SmartScheduleInterval = atoi(argv[i]);
SmartScheduleSlice = SmartScheduleInterval;
}
else
UseMsg();
}
else if ( strcmp( argv[i], "-schedMax") == 0)
{
if (++i < argc)
{
SmartScheduleMaxSlice = atoi(argv[i]);
}
else
UseMsg();
}
#endif
#ifdef RENDER
else if ( strcmp( argv[i], "-render" ) == 0)
{
if (++i < argc)
{
int policy = PictureParseCmapPolicy (argv[i]);
if (policy != PictureCmapPolicyInvalid)
PictureCmapPolicy = policy;
else
UseMsg ();
}
else
UseMsg ();
}
#endif
else if ( strcmp( argv[i], "+extension") == 0)
{
if (++i < argc)
{
if (!EnableDisableExtension(argv[i], TRUE))
EnableDisableExtensionError(argv[i], TRUE);
}
else
UseMsg();
}
else if ( strcmp( argv[i], "-extension") == 0)
{
if (++i < argc)
{
if (!EnableDisableExtension(argv[i], FALSE))
EnableDisableExtensionError(argv[i], FALSE);
}
else
UseMsg();
}
else
{
ErrorF("Unrecognized option: %s\n", argv[i]);
UseMsg();
FatalError("Unrecognized option: %s\n", argv[i]);
}
}
}
#ifdef COMMANDLINE_CHALLENGED_OPERATING_SYSTEMS
static void
InsertFileIntoCommandLine(
int *resargc, char ***resargv,
int prefix_argc, char **prefix_argv,
char *filename,
int suffix_argc, char **suffix_argv)
{
struct stat st;
FILE *f;
char *p;
char *q;
int insert_argc;
char *buf;
int len;
int i;
f = fopen(filename, "r");
if (!f)
FatalError("Can't open option file %s\n", filename);
fstat(fileno(f), &st);
buf = (char *) xalloc((unsigned) st.st_size + 1);
if (!buf)
FatalError("Out of Memory\n");
len = fread(buf, 1, (unsigned) st.st_size, f);
fclose(f);
if (len < 0)
FatalError("Error reading option file %s\n", filename);
buf[len] = '\0';
p = buf;
q = buf;
insert_argc = 0;
while (*p)
{
while (isspace(*p))
p++;
if (!*p)
break;
if (*p == '#')
{
while (*p && *p != '\n')
p++;
} else
{
while (*p && !isspace(*p))
*q++ = *p++;
if (*p)
p++;
*q++ = '\0';
insert_argc++;
}
}
buf = (char *) xrealloc(buf, q - buf);
if (!buf)
FatalError("Out of memory reallocing option buf\n");
*resargc = prefix_argc + insert_argc + suffix_argc;
*resargv = (char **) xalloc((*resargc + 1) * sizeof(char *));
if (!*resargv)
FatalError("Out of Memory\n");
memcpy(*resargv, prefix_argv, prefix_argc * sizeof(char *));
p = buf;
for (i = 0; i < insert_argc; i++)
{
(*resargv)[prefix_argc + i] = p;
p += strlen(p) + 1;
}
memcpy(*resargv + prefix_argc + insert_argc,
suffix_argv, suffix_argc * sizeof(char *));
(*resargv)[*resargc] = NULL;
}
void
ExpandCommandLine(int *pargc, char ***pargv)
{
int i;
#if !defined(WIN32) && !defined(__CYGWIN__)
if (getuid() != geteuid())
return;
#endif
for (i = 1; i < *pargc; i++)
{
if ( (0 == strcmp((*pargv)[i], "-config")) && (i < (*pargc - 1)) )
{
InsertFileIntoCommandLine(pargc, pargv,
i, *pargv,
(*pargv)[i+1],
*pargc - i - 2, *pargv + i + 2);
i--;
}
}
}
#endif
int
set_font_authorizations(char **authorizations, int *authlen, pointer client)
{
#define AUTHORIZATION_NAME "hp-hostname-1"
#if defined(TCPCONN) || defined(STREAMSCONN)
static char *result = NULL;
static char *p = NULL;
if (p == NULL)
{
char hname[1024], *hnameptr;
unsigned int len;
#if defined(IPv6) && defined(AF_INET6)
struct addrinfo hints, *ai = NULL;
#else
struct hostent *host;
#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
_Xgethostbynameparams hparams;
#endif
#endif
gethostname(hname, 1024);
#if defined(IPv6) && defined(AF_INET6)
bzero(&hints, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
if (getaddrinfo(hname, NULL, &hints, &ai) == 0) {
hnameptr = ai->ai_canonname;
} else {
hnameptr = hname;
}
#else
host = _XGethostbyname(hname, hparams);
if (host == NULL)
hnameptr = hname;
else
hnameptr = host->h_name;
#endif
len = strlen(hnameptr) + 1;
result = xalloc(len + sizeof(AUTHORIZATION_NAME) + 4);
p = result;
*p++ = sizeof(AUTHORIZATION_NAME) >> 8;
*p++ = sizeof(AUTHORIZATION_NAME) & 0xff;
*p++ = (len) >> 8;
*p++ = (len & 0xff);
memmove(p, AUTHORIZATION_NAME, sizeof(AUTHORIZATION_NAME));
p += sizeof(AUTHORIZATION_NAME);
memmove(p, hnameptr, len);
p += len;
#if defined(IPv6) && defined(AF_INET6)
if (ai) {
freeaddrinfo(ai);
}
#endif
}
*authlen = p - result;
*authorizations = result;
return 1;
#else
return 0;
#endif
}
#ifndef INTERNAL_MALLOC
_X_EXPORT void *
Xalloc(unsigned long amount)
{
register pointer ptr;
if ((long)amount <= 0) {
return (unsigned long *)NULL;
}
amount = (amount + (sizeof(long) - 1)) & ~(sizeof(long) - 1);
#ifdef MEMBUG
if (!Must_have_memory && Memory_fail &&
((random() % MEM_FAIL_SCALE) < Memory_fail))
return (unsigned long *)NULL;
#endif
if ((ptr = (pointer)malloc(amount))) {
return (unsigned long *)ptr;
}
if (Must_have_memory)
FatalError("Out of memory");
return (unsigned long *)NULL;
}
_X_EXPORT void *
XNFalloc(unsigned long amount)
{
register pointer ptr;
if ((long)amount <= 0)
{
return (unsigned long *)NULL;
}
amount = (amount + (sizeof(long) - 1)) & ~(sizeof(long) - 1);
ptr = (pointer)malloc(amount);
if (!ptr)
{
FatalError("Out of memory");
}
return ((unsigned long *)ptr);
}
_X_EXPORT void *
Xcalloc(unsigned long amount)
{
unsigned long *ret;
ret = Xalloc (amount);
if (ret)
bzero ((char *) ret, (int) amount);
return ret;
}
_X_EXPORT void *
XNFcalloc(unsigned long amount)
{
unsigned long *ret;
ret = Xalloc (amount);
if (ret)
bzero ((char *) ret, (int) amount);
else if ((long)amount > 0)
FatalError("Out of memory");
return ret;
}
_X_EXPORT void *
Xrealloc(pointer ptr, unsigned long amount)
{
#ifdef MEMBUG
if (!Must_have_memory && Memory_fail &&
((random() % MEM_FAIL_SCALE) < Memory_fail))
return (unsigned long *)NULL;
#endif
if ((long)amount <= 0)
{
if (ptr && !amount)
free(ptr);
return (unsigned long *)NULL;
}
amount = (amount + (sizeof(long) - 1)) & ~(sizeof(long) - 1);
if (ptr)
ptr = (pointer)realloc((char *)ptr, amount);
else
ptr = (pointer)malloc(amount);
if (ptr)
return (unsigned long *)ptr;
if (Must_have_memory)
FatalError("Out of memory");
return (unsigned long *)NULL;
}
_X_EXPORT void *
XNFrealloc(pointer ptr, unsigned long amount)
{
if (( ptr = (pointer)Xrealloc( ptr, amount ) ) == NULL)
{
if ((long)amount > 0)
FatalError( "Out of memory" );
}
return ((unsigned long *)ptr);
}
_X_EXPORT void
Xfree(pointer ptr)
{
if (ptr)
free((char *)ptr);
}
void
OsInitAllocator (void)
{
#ifdef MEMBUG
static int been_here;
if (been_here)
CheckMemory ();
else
been_here = 1;
#endif
}
#endif
char *
Xstrdup(const char *s)
{
char *sd;
if (s == NULL)
return NULL;
sd = (char *)Xalloc(strlen(s) + 1);
if (sd != NULL)
strcpy(sd, s);
return sd;
}
_X_EXPORT char *
XNFstrdup(const char *s)
{
char *sd;
if (s == NULL)
return NULL;
sd = (char *)XNFalloc(strlen(s) + 1);
strcpy(sd, s);
return sd;
}
#ifdef SMART_SCHEDULE
unsigned long SmartScheduleIdleCount;
Bool SmartScheduleIdle;
Bool SmartScheduleTimerStopped;
#ifdef SIGVTALRM
#define SMART_SCHEDULE_POSSIBLE
#endif
#ifdef SMART_SCHEDULE_POSSIBLE
#define SMART_SCHEDULE_SIGNAL SIGALRM
#define SMART_SCHEDULE_TIMER ITIMER_REAL
#endif
static void
SmartScheduleStopTimer (void)
{
#ifdef SMART_SCHEDULE_POSSIBLE
struct itimerval timer;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 0;
(void) setitimer (ITIMER_REAL, &timer, 0);
SmartScheduleTimerStopped = TRUE;
#endif
}
Bool
SmartScheduleStartTimer (void)
{
#ifdef SMART_SCHEDULE_POSSIBLE
struct itimerval timer;
SmartScheduleTimerStopped = FALSE;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = SmartScheduleInterval * 1000;
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = SmartScheduleInterval * 1000;
return setitimer (ITIMER_REAL, &timer, 0) >= 0;
#endif
return FALSE;
}
#ifdef SMART_SCHEDULE_POSSIBLE
static void
SmartScheduleTimer (int sig)
{
int olderrno = errno;
SmartScheduleTime += SmartScheduleInterval;
if (SmartScheduleIdle)
{
SmartScheduleStopTimer ();
}
errno = olderrno;
}
#endif
Bool
SmartScheduleInit (void)
{
#ifdef SMART_SCHEDULE_POSSIBLE
struct sigaction act;
if (SmartScheduleDisable)
return TRUE;
bzero ((char *) &act, sizeof(struct sigaction));
act.sa_handler = SmartScheduleTimer;
sigemptyset (&act.sa_mask);
sigaddset (&act.sa_mask, SMART_SCHEDULE_SIGNAL);
if (sigaction (SMART_SCHEDULE_SIGNAL, &act, 0) < 0)
{
perror ("sigaction for smart scheduler");
return FALSE;
}
if (!SmartScheduleStartTimer ())
{
perror ("scheduling timer");
return FALSE;
}
SmartScheduleStopTimer ();
return TRUE;
#else
return FALSE;
#endif
}
#endif
#ifdef SIG_BLOCK
static sigset_t PreviousSignalMask;
static int BlockedSignalCount;
#endif
void
OsBlockSignals (void)
{
#ifdef SIG_BLOCK
if (BlockedSignalCount++ == 0)
{
sigset_t set;
sigemptyset (&set);
#ifdef SIGALRM
sigaddset (&set, SIGALRM);
#endif
#ifdef SIGVTALRM
sigaddset (&set, SIGVTALRM);
#endif
#ifdef SIGWINCH
sigaddset (&set, SIGWINCH);
#endif
#ifdef SIGIO
sigaddset (&set, SIGIO);
#endif
#ifdef SIGTSTP
sigaddset (&set, SIGTSTP);
#endif
#ifdef SIGTTIN
sigaddset (&set, SIGTTIN);
#endif
#ifdef SIGTTOU
sigaddset (&set, SIGTTOU);
#endif
#ifdef SIGCHLD
sigaddset (&set, SIGCHLD);
#endif
sigprocmask (SIG_BLOCK, &set, &PreviousSignalMask);
}
#endif
}
void
OsReleaseSignals (void)
{
#ifdef SIG_BLOCK
if (--BlockedSignalCount == 0)
{
sigprocmask (SIG_SETMASK, &PreviousSignalMask, 0);
}
#endif
}
#if !defined(WIN32)
int
System(char *command)
{
int pid, p;
#ifdef SIGCHLD
void (*csig)(int);
#endif
int status;
if (!command)
return(1);
#ifdef SIGCHLD
csig = signal(SIGCHLD, SIG_DFL);
if (csig == SIG_ERR) {
perror("signal");
return -1;
}
#endif
#ifdef DEBUG
ErrorF("System: `%s'\n", command);
#endif
switch (pid = fork()) {
case -1:
p = -1;
case 0:
if (setgid(getgid()) == -1)
_exit(127);
if (setuid(getuid()) == -1)
_exit(127);
execl("/bin/sh", "sh", "-c", command, (char *)NULL);
_exit(127);
default:
do {
p = waitpid(pid, &status, 0);
} while (p == -1 && errno == EINTR);
}
#ifdef SIGCHLD
if (signal(SIGCHLD, csig) == SIG_ERR) {
perror("signal");
return -1;
}
#endif
return p == -1 ? -1 : status;
}
static struct pid {
struct pid *next;
FILE *fp;
int pid;
} *pidlist;
void (*old_alarm)(int) = NULL;
pointer
Popen(char *command, char *type)
{
struct pid *cur;
FILE *iop;
int pdes[2], pid;
if (command == NULL || type == NULL)
return NULL;
if ((*type != 'r' && *type != 'w') || type[1])
return NULL;
if ((cur = (struct pid *)xalloc(sizeof(struct pid))) == NULL)
return NULL;
if (pipe(pdes) < 0) {
xfree(cur);
return NULL;
}
old_alarm = signal(SIGALRM, SIG_IGN);
if (old_alarm == SIG_ERR) {
perror("signal");
return NULL;
}
switch (pid = fork()) {
case -1:
close(pdes[0]);
close(pdes[1]);
xfree(cur);
if (signal(SIGALRM, old_alarm) == SIG_ERR)
perror("signal");
return NULL;
case 0:
if (setgid(getgid()) == -1)
_exit(127);
if (setuid(getuid()) == -1)
_exit(127);
if (*type == 'r') {
if (pdes[1] != 1) {
dup2(pdes[1], 1);
close(pdes[1]);
}
close(pdes[0]);
} else {
if (pdes[0] != 0) {
dup2(pdes[0], 0);
close(pdes[0]);
}
close(pdes[1]);
}
execl("/bin/sh", "sh", "-c", command, (char *)NULL);
_exit(127);
}
OsBlockSignals ();
if (*type == 'r') {
iop = fdopen(pdes[0], type);
close(pdes[1]);
} else {
iop = fdopen(pdes[1], type);
close(pdes[0]);
}
cur->fp = iop;
cur->pid = pid;
cur->next = pidlist;
pidlist = cur;
#ifdef DEBUG
ErrorF("Popen: `%s', fp = %p\n", command, iop);
#endif
return iop;
}
pointer
Fopen(char *file, char *type)
{
FILE *iop;
#ifndef HAS_SAVED_IDS_AND_SETEUID
struct pid *cur;
int pdes[2], pid;
if (file == NULL || type == NULL)
return NULL;
if ((*type != 'r' && *type != 'w') || type[1])
return NULL;
if ((cur = (struct pid *)xalloc(sizeof(struct pid))) == NULL)
return NULL;
if (pipe(pdes) < 0) {
xfree(cur);
return NULL;
}
switch (pid = fork()) {
case -1:
close(pdes[0]);
close(pdes[1]);
xfree(cur);
return NULL;
case 0:
if (setgid(getgid()) == -1)
_exit(127);
if (setuid(getuid()) == -1)
_exit(127);
if (*type == 'r') {
if (pdes[1] != 1) {
dup2(pdes[1], 1);
close(pdes[1]);
}
close(pdes[0]);
} else {
if (pdes[0] != 0) {
dup2(pdes[0], 0);
close(pdes[0]);
}
close(pdes[1]);
}
execl("/bin/cat", "cat", file, (char *)NULL);
_exit(127);
}
OsBlockSignals ();
if (*type == 'r') {
iop = fdopen(pdes[0], type);
close(pdes[1]);
} else {
iop = fdopen(pdes[1], type);
close(pdes[0]);
}
cur->fp = iop;
cur->pid = pid;
cur->next = pidlist;
pidlist = cur;
#ifdef DEBUG
ErrorF("Fopen(%s), fp = %p\n", file, iop);
#endif
return iop;
#else
int ruid, euid;
ruid = getuid();
euid = geteuid();
if (seteuid(ruid) == -1) {
return NULL;
}
iop = fopen(file, type);
if (seteuid(euid) == -1) {
fclose(iop);
return NULL;
}
return iop;
#endif
}
int
Pclose(pointer iop)
{
struct pid *cur, *last;
int pstat;
int pid;
#ifdef DEBUG
ErrorF("Pclose: fp = %p\n", iop);
#endif
fclose(iop);
for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
if (cur->fp == iop)
break;
if (cur == NULL)
return -1;
do {
pid = waitpid(cur->pid, &pstat, 0);
} while (pid == -1 && errno == EINTR);
if (last == NULL)
pidlist = cur->next;
else
last->next = cur->next;
xfree(cur);
OsReleaseSignals ();
if (old_alarm && signal(SIGALRM, old_alarm) == SIG_ERR) {
perror("signal");
return -1;
}
return pid == -1 ? -1 : pstat;
}
int
Fclose(pointer iop)
{
#ifdef HAS_SAVED_IDS_AND_SETEUID
return fclose(iop);
#else
return Pclose(iop);
#endif
}
#endif
#ifndef REMOVE_ENV_LD
#define REMOVE_ENV_LD 1
#endif
#ifndef REMOVE_LONG_ENV
#define REMOVE_LONG_ENV 1
#endif
#ifndef NO_OUTPUT_PIPES
#define NO_OUTPUT_PIPES 0
#endif
#ifndef CHECK_EUID
#ifndef WIN32
#define CHECK_EUID 1
#else
#define CHECK_EUID 0
#endif
#endif
#ifndef USE_ISPRINT
#define USE_ISPRINT 0
#endif
#define MAX_ARG_LENGTH 128
#define MAX_ENV_LENGTH 256
#define MAX_ENV_PATH_LENGTH 2048
#if USE_ISPRINT
#include <ctype.h>
#define checkPrintable(c) isprint(c)
#else
#define checkPrintable(c) (((c) & 0x7f) >= 0x20 && ((c) & 0x7f) != 0x7f)
#endif
enum BadCode {
NotBad = 0,
UnsafeArg,
ArgTooLong,
UnprintableArg,
EnvTooLong,
OutputIsPipe,
InternalError
};
#if defined(VENDORSUPPORT)
#define BUGADDRESS VENDORSUPPORT
#elif defined(BUILDERADDR)
#define BUGADDRESS BUILDERADDR
#else
#define BUGADDRESS "xorg@freedesktop.org"
#endif
#define ARGMSG \
"\nIf the arguments used are valid, and have been rejected incorrectly\n" \
"please send details of the arguments and why they are valid to\n" \
"%s. In the meantime, you can start the Xserver as\n" \
"the \"super user\" (root).\n"
#define ENVMSG \
"\nIf the environment is valid, and have been rejected incorrectly\n" \
"please send details of the environment and why it is valid to\n" \
"%s. In the meantime, you can start the Xserver as\n" \
"the \"super user\" (root).\n"
void
CheckUserParameters(int argc, char **argv, char **envp)
{
enum BadCode bad = NotBad;
int i = 0, j;
char *a, *e = NULL;
#if defined(__QNX__) && !defined(__QNXNTO__)
char cmd_name[64];
#endif
#if CHECK_EUID
if (geteuid() == 0 && getuid() != geteuid())
#endif
{
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-fp") == 0)
{
i++;
if (i >= argc)
break;
} else
{
if (strlen(argv[i]) > MAX_ARG_LENGTH) {
bad = ArgTooLong;
break;
}
}
a = argv[i];
while (*a) {
if (checkPrintable(*a) == 0) {
bad = UnprintableArg;
break;
}
a++;
}
if (bad)
break;
}
if (!bad) {
for (i = 0; envp[i]; i++) {
#if REMOVE_ENV_LD
while (envp[i] && (strncmp(envp[i], "LD", 2) == 0)) {
#ifdef ENVDEBUG
ErrorF("CheckUserParameters: removing %s from the "
"environment\n", strtok(envp[i], "="));
#endif
for (j = i; envp[j]; j++) {
envp[j] = envp[j+1];
}
}
#endif
if (envp[i] && (strlen(envp[i]) > MAX_ENV_LENGTH)) {
#if REMOVE_LONG_ENV
#ifdef ENVDEBUG
ErrorF("CheckUserParameters: removing %s from the "
"environment\n", strtok(envp[i], "="));
#endif
for (j = i; envp[j]; j++) {
envp[j] = envp[j+1];
}
i--;
#else
char *eq;
int len;
eq = strchr(envp[i], '=');
if (!eq)
continue;
len = eq - envp[i];
e = malloc(len + 1);
if (!e) {
bad = InternalError;
break;
}
strncpy(e, envp[i], len);
e[len] = 0;
if (len >= 4 &&
(strcmp(e + len - 4, "PATH") == 0 ||
strcmp(e, "TERMCAP") == 0)) {
if (strlen(envp[i]) > MAX_ENV_PATH_LENGTH) {
bad = EnvTooLong;
break;
} else {
free(e);
}
} else {
bad = EnvTooLong;
break;
}
#endif
}
}
}
#if NO_OUTPUT_PIPES
if (!bad) {
struct stat buf;
if (fstat(fileno(stdout), &buf) == 0 && S_ISFIFO(buf.st_mode))
bad = OutputIsPipe;
if (fstat(fileno(stderr), &buf) == 0 && S_ISFIFO(buf.st_mode))
bad = OutputIsPipe;
}
#endif
}
switch (bad) {
case NotBad:
return;
case UnsafeArg:
ErrorF("Command line argument number %d is unsafe\n", i);
ErrorF(ARGMSG, BUGADDRESS);
break;
case ArgTooLong:
ErrorF("Command line argument number %d is too long\n", i);
ErrorF(ARGMSG, BUGADDRESS);
break;
case UnprintableArg:
ErrorF("Command line argument number %d contains unprintable"
" characters\n", i);
ErrorF(ARGMSG, BUGADDRESS);
break;
case EnvTooLong:
ErrorF("Environment variable `%s' is too long\n", e);
ErrorF(ENVMSG, BUGADDRESS);
break;
case OutputIsPipe:
ErrorF("Stdout and/or stderr is a pipe\n");
break;
case InternalError:
ErrorF("Internal Error\n");
break;
default:
ErrorF("Unknown error\n");
ErrorF(ARGMSG, BUGADDRESS);
ErrorF(ENVMSG, BUGADDRESS);
break;
}
FatalError("X server aborted because of unsafe environment\n");
}
#ifdef USE_PAM
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <pwd.h>
#endif
void
CheckUserAuthorization(void)
{
#ifdef USE_PAM
static struct pam_conv conv = {
misc_conv,
NULL
};
pam_handle_t *pamh = NULL;
struct passwd *pw;
int retval;
if (getuid() != geteuid()) {
pw = getpwuid(getuid());
if (pw == NULL)
FatalError("getpwuid() failed for uid %d\n", getuid());
retval = pam_start("xserver", pw->pw_name, &conv, &pamh);
if (retval != PAM_SUCCESS)
FatalError("pam_start() failed.\n"
"\tMissing or mangled PAM config file or module?\n");
retval = pam_authenticate(pamh, 0);
if (retval != PAM_SUCCESS) {
pam_end(pamh, retval);
FatalError("PAM authentication failed, cannot start X server.\n"
"\tPerhaps you do not have console ownership?\n");
}
retval = pam_acct_mgmt(pamh, 0);
if (retval != PAM_SUCCESS) {
pam_end(pamh, retval);
FatalError("PAM authentication failed, cannot start X server.\n"
"\tPerhaps you do not have console ownership?\n");
}
pam_end(pamh, PAM_SUCCESS);
}
#endif
}
#ifdef __SCO__
#include <fcntl.h>
static void
lockit (int fd, short what)
{
struct flock lck;
lck.l_whence = 0;
lck.l_start = 0;
lck.l_len = 1;
lck.l_type = what;
(void)fcntl (fd, F_SETLKW, &lck);
}
ssize_t
pread (int fd, void *buf, size_t nbytes, off_t offset)
{
off_t saved;
ssize_t ret;
lockit (fd, F_RDLCK);
saved = lseek (fd, 0, SEEK_CUR);
lseek (fd, offset, SEEK_SET);
ret = read (fd, buf, nbytes);
lseek (fd, saved, SEEK_SET);
lockit (fd, F_UNLCK);
return ret;
}
ssize_t
pwrite (int fd, const void *buf, size_t nbytes, off_t offset)
{
off_t saved;
ssize_t ret;
lockit (fd, F_WRLCK);
saved = lseek (fd, 0, SEEK_CUR);
lseek (fd, offset, SEEK_SET);
ret = write (fd, buf, nbytes);
lseek (fd, saved, SEEK_SET);
lockit (fd, F_UNLCK);
return ret;
}
#endif