X-Git-Url: https://git.sesse.net/?p=rdpsrv;a=blobdiff_plain;f=Xserver%2Fprograms%2FXserver%2Fos%2Futils.c;fp=Xserver%2Fprograms%2FXserver%2Fos%2Futils.c;h=d2d042292676c48dc234d8c53a04e8ea85bd4f67;hp=0000000000000000000000000000000000000000;hb=b6e6afccf37f4ad0515ef2a698f714fdf1bf23b3;hpb=e3340a110a3b01756b8e67531395a33b40a17d37 diff --git a/Xserver/programs/Xserver/os/utils.c b/Xserver/programs/Xserver/os/utils.c new file mode 100644 index 0000000..d2d0422 --- /dev/null +++ b/Xserver/programs/Xserver/os/utils.c @@ -0,0 +1,1541 @@ +/* $TOG: utils.c /main/128 1997/06/01 13:50:39 sekhar $ */ +/* + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, +Copyright 1994 Quarterdeck Office Systems. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital and +Quarterdeck not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +DIGITAL AND QUARTERDECK DISCLAIM ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT +OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE +OR PERFORMANCE OF THIS SOFTWARE. + +*/ +/* $XFree86: xc/programs/Xserver/os/utils.c,v 3.27.2.6 1998/02/20 15:13:58 robin Exp $ */ + +#ifdef WIN32 +#include +#endif +#include "Xos.h" +#include +#include "misc.h" +#include "X.h" +#include "input.h" +#include "opaque.h" +#ifdef X_POSIX_C_SOURCE +#define _POSIX_C_SOURCE X_POSIX_C_SOURCE +#include +#undef _POSIX_C_SOURCE +#else +#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE) +#include +#else +#define _POSIX_SOURCE +#include +#undef _POSIX_SOURCE +#endif +#endif +#if !defined(SYSV) && !defined(AMOEBA) && !defined(_MINIX) && !defined(WIN32) && !defined(Lynx) || defined(hpux) || defined(AIXV4) +#include +#endif +#include +#include +#include /* for isspace */ +#if NeedVarargsPrototypes +#include +#endif + +#ifdef AMOEBA +#include "osdep.h" +#include +#include + +static mutex print_lock; +#endif + +#if defined(__STDC__) || defined(AMOEBA) +/* DHD: SVR4.0 has a prototype for abs() in stdlib.h */ +/* DHD: might be better to move this include higher up? */ +#ifdef abs +#undef abs +#endif +#ifndef NOSTDHDRS +#include /* for malloc() */ +#endif +#endif + +extern char *display; + +extern CARD32 defaultScreenSaverTime; /* for parsing command line */ +extern CARD32 defaultScreenSaverInterval; +extern int defaultScreenSaverBlanking; +extern int defaultBackingStore; +extern Bool disableBackingStore; +extern Bool disableSaveUnders; +extern Bool PartialNetwork; +#ifndef NOLOGOHACK +extern int logoScreenSaver; +#endif +#ifdef RLIMIT_DATA +extern int limitDataSpace; +#endif +#ifdef RLIMIT_STACK +extern int limitStackSpace; +#endif +#ifdef RLIMIT_NOFILE +extern int limitNoFile; +#endif +extern int defaultColorVisualClass; +extern Bool permitOldBugs; +extern int monitorResolution; +extern Bool defeatAccessControl; +#ifdef SERVER_LOCK +static Bool nolock = FALSE; +#endif + +extern char* protNoListen; + +Bool CoreDump; +Bool noTestExtensions; + +int auditTrailLevel = 1; + +void ddxUseMsg(); +#if NeedVarargsPrototypes +void VErrorF(char*, va_list); +#endif + +#ifdef DEBUG +#ifndef SPECIAL_MALLOC +#define MEMBUG +#endif +#endif + +#ifdef MEMBUG +#define MEM_FAIL_SCALE 100000 +long Memory_fail = 0; +#ifdef linux +#include /* for random() */ +#endif +#endif + +#ifdef sgi +int userdefinedfontpath = 0; +#endif /* sgi */ + +Bool Must_have_memory = FALSE; + +char *dev_tty_from_init = NULL; /* since we need to parse it anyway */ + +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; + sigaction(sig, &act, &oact); + return oact.sa_handler; +#endif +} + +#include +extern int errno; + +#ifdef SERVER_LOCK +/* + * Explicit support for a server lock file like the ones used for UUCP. + * For architectures with virtual terminals that can run more than one + * server at a time. This keeps the servers from stomping on each other + * if the user forgets to give them different display numbers. + */ +#ifndef __EMX__ +#define LOCK_DIR "/tmp" +#define LOCK_TMP_PREFIX "/.tX" +#define LOCK_PREFIX "/.X" +#define LOCK_SUFFIX "-lock" +#else +#define LOCK_TMP_PREFIX "/xf86$" +#define LOCK_PREFIX "/xf86_" +#define LOCK_SUFFIX ".lck" +#endif + +#ifdef _MINIX +#include /* For PATH_MAX */ +#endif + +#ifdef __EMX__ +#define link rename +#endif + +#ifndef PATH_MAX +#ifndef Lynx +#include +#else +#include +#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]; + +/* + * LockServer -- + * Check if the server lock file exists. If so, check if the PID + * contained inside is valid. If so, then die. Otherwise, create + * the lock file containing the PID. + */ +void +LockServer() +{ +#ifndef AMOEBA + char tmp[PATH_MAX], pid_str[12]; + int lfd, i, haslock, l_pid, t; + char *tmppath = NULL; + int len; + + if (nolock) return; + /* + * Path names + */ +#ifndef __EMX__ + tmppath = LOCK_DIR; +#else + /* OS/2 uses TMP directory, must also prepare for 8.3 names */ + tmppath = getenv("TMP"); + if (!tmppath) + FatalError("No TMP dir found\n"); +#endif + + len = strlen(LOCK_PREFIX) > strlen(LOCK_TMP_PREFIX) ? strlen(LOCK_PREFIX) : + strlen(LOCK_TMP_PREFIX); + len += strlen(tmppath) + strlen(display) + strlen(LOCK_SUFFIX) + 1; + if (len > sizeof(LockFile)) + FatalError("Display name `%s' is too long\n"); + (void)sprintf(tmp, "%s" LOCK_TMP_PREFIX "%s" LOCK_SUFFIX, tmppath, display); + (void)sprintf(LockFile, "%s" LOCK_PREFIX "%s" LOCK_SUFFIX, tmppath, display); + + /* + * Create a temporary file containing our PID. Attempt three times + * to create the file. + */ + 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, "%10d\n", getpid()); + (void) write(lfd, pid_str, 11); +#ifndef __EMX__ +#ifndef USE_CHMOD + (void) fchmod(lfd, 0444); +#else + (void) chmod(tmp, 0444); +#endif +#endif + (void) close(lfd); + + /* + * OK. Now the tmp file exists. Try three times to move it in place + * for the lock. + */ + i = 0; + haslock = 0; + while ((!haslock) && (i++ < 3)) { + haslock = (link(tmp,LockFile) == 0); + if (haslock) { + /* + * We're done. + */ + break; + } + else { + /* + * Read the pid from the existing file + */ + 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) { + /* + * Bogus lock file. + */ + unlink(LockFile); + close(lfd); + continue; + } + pid_str[11] = '\0'; + sscanf(pid_str, "%d", &l_pid); + close(lfd); + + /* + * Now try to kill the PID to see if it exists. + */ + errno = 0; + t = kill(l_pid, 0); + if ((t< 0) && (errno == ESRCH)) { + /* + * Stale lock file. + */ + unlink(LockFile); + continue; + } + else if (((t < 0) && (errno == EPERM)) || (t == 0)) { + /* + * Process is still active. + */ + unlink(tmp); + FatalError("Server is already active for display %s\n%s %s\n%s\n", + display, "\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; +#endif /* !AMOEBA */ +} + +/* + * UnlockServer -- + * Remove the server lock file. + */ +void +UnlockServer() +{ +#ifndef AMOEBA + if (nolock) return; + + if (!StillLocking){ + +#ifdef __EMX__ + (void) chmod(LockFile,S_IREAD|S_IWRITE); +#endif /* __EMX__ */ + (void) unlink(LockFile); + } +#endif + +} +#endif /* SERVER_LOCK */ + +/* Force connections to close on SIGHUP from init */ + +/*ARGSUSED*/ +SIGVAL +AutoResetServer (sig) + int sig; +{ + dispatchException |= DE_RESET; + isItTimeToYield = TRUE; +#ifdef GPROF + chdir ("/tmp"); + exit (0); +#endif +#if defined(SYSV) && defined(X_NOT_POSIX) + OsSignal (SIGHUP, AutoResetServer); +#endif +#ifdef AMOEBA + WakeUpMainThread(); +#endif +} + +/* Force connections to close and then exit on SIGTERM, SIGINT */ + +/*ARGSUSED*/ +SIGVAL +GiveUp(sig) + int sig; +{ + dispatchException |= DE_TERMINATE; + isItTimeToYield = TRUE; +#if defined(SYSV) && defined(X_NOT_POSIX) + if (sig) + OsSignal(sig, SIG_IGN); +#endif +#ifdef AMOEBA + WakeUpMainThread(); +#endif +} + +#if __GNUC__ +static void AbortServer() __attribute__((noreturn)); +#endif + +static void +AbortServer() +{ + extern void AbortDDX(); + + OsCleanup(); + AbortDDX(); + fflush(stderr); +#ifdef AMOEBA + IOPCleanUp(); +#endif + if (CoreDump) + abort(); + exit (1); +} + +void +Error(str) + char *str; +{ +#ifdef AMOEBA + mu_lock(&print_lock); +#endif + perror(str); +#ifdef AMOEBA + mu_unlock(&print_lock); +#endif +} + +#ifndef DDXTIME +CARD32 +GetTimeInMillis() +{ +#ifndef AMOEBA + struct timeval tp; + + X_GETTIMEOFDAY(&tp); + return(tp.tv_sec * 1000) + (tp.tv_usec / 1000); +#else + return sys_milli(); +#endif +} +#endif + +AdjustWaitForDelay (waitTime, newdelay) + 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() +{ +#if !defined(AIXrt) && !defined(AIX386) +#ifndef AMOEBA + ErrorF("use: X [:] [option]\n"); +#else + ErrorF("use: X [[]:] [option]\n"); +#endif + 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("bc enable bug compatibility\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"); +#if 0 + 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("-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"); + ErrorF("-s # screen-saver timeout (minutes)\n"); +#ifdef XCSECURITY + ErrorF("-sp file security policy file\n"); +#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("-x string loads named extension at init time \n"); +#ifdef AMOEBA + ErrorF("-tcp capability specify TCP/IP server capability\n"); +#endif +#ifdef XDMCP + XdmcpUseMsg(); +#endif +#endif /* !AIXrt && ! AIX386 */ +#ifdef XKB + XkbUseMsg(); +#endif + ddxUseMsg(); +} + +/* + * This function parses the command line. Handles device-independent fields + * and allows ddx to handle additional fields. It is not allowed to modify + * argc or any of the strings pointed to by argv. + */ +void +ProcessCommandLine ( argc, argv ) +int argc; +char *argv[]; + +{ + int i, skip; + +#ifdef AMOEBA + mu_init(&print_lock); +#endif + + defaultKeyboardControl.autoRepeat = TRUE; + +#ifdef PART_NET + PartialNetwork = TRUE; +#endif + + for ( i = 1; i < argc; i++ ) + { + /* call ddx first, so it can peek/override if it wants */ + if(skip = ddxProcessArgument(argc, argv, i)) + { + i += (skip - 1); + } + else if(argv[i][0] == ':') + { + /* initialize display */ + display = argv[i]; + display++; + } +#ifdef AMOEBA + else if (strchr(argv[i], ':') != NULL) { + char *p; + + XServerHostName = argv[i]; + if ((p = strchr(argv[i], ':')) != NULL) { + *p++ = '\0'; + display = p; + } + } else if (strcmp( argv[i], "-tcp") == 0) { + if (++i < argc) + XTcpServerName = argv[i]; + else + UseMsg(); + } +#endif /* AMOEBA */ + 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], "bc") == 0) + permitOldBugs = 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; + 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) + { +#ifdef sgi + userdefinedfontpath = 1; +#endif /* sgi */ + 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) + { + 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) + protNoListen = argv[i]; + else + UseMsg(); + } + 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) + { + extern Bool terminateAtReset; + + terminateAtReset = TRUE; + } + 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], "-x") == 0) + { + if(++i >= argc) + UseMsg(); + /* For U**x, which doesn't support dynamic loading, there's nothing + * to do when we see a -x. Either the extension is linked in or + * it isn't */ + } + else if ( strcmp( argv[i], "-I") == 0) + { + /* ignore all remaining arguments */ + break; + } + else if (strncmp (argv[i], "tty", 3) == 0) + { + /* just in case any body is interested */ + 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 = XprintOptions(argc, argv, i)) != i) + { + i = skip - 1; + } +#endif +#ifdef XCSECURITY + else if ((skip = XSecurityOptions(argc, argv, i)) != i) + { + i = skip - 1; + } +#endif + else + { + ErrorF("Unrecognized option: %s\n", argv[i]); + UseMsg(); + exit (1); + } + } +} + +#if 0 +static void +InsertFileIntoCommandLine(resargc, resargv, prefix_argc, prefix_argv, + filename, suffix_argc, suffix_argv) + 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++; + /* Since p and q might still be pointing at the same place, we */ + /* need to step p over the whitespace now before we add the null. */ + 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 *)); + + 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; +} /* end InsertFileIntoCommandLine */ + +void +ExpandCommandLine(pargc, pargv) + int *pargc; + char ***pargv; +{ + int i; + + for (i = 1; i < *pargc; i++) + { + if ( (0 == strcmp((*pargv)[i], "-config")) && (i < (*pargc - 1)) ) + { + InsertFileIntoCommandLine(pargc, pargv, + i, *pargv, + (*pargv)[i+1], /* filename */ + *pargc - i - 2, *pargv + i + 2); + i--; + } + } +} /* end ExpandCommandLine */ +#endif + +#if defined(TCPCONN) || defined(STREAMSCONN) +#ifndef WIN32 +#include +#endif +#endif + +/* Implement a simple-minded font authorization scheme. The authorization + name is "hp-hostname-1", the contents are simply the host name. */ +int +set_font_authorizations(authorizations, authlen, client) +char **authorizations; +int *authlen; +pointer client; +{ +#define AUTHORIZATION_NAME "hp-hostname-1" +#if defined(TCPCONN) || defined(STREAMSCONN) + static char result[1024]; + static char *p = NULL; + + if (p == NULL) + { + char hname[1024], *hnameptr; + struct hostent *host; + int len; + + gethostname(hname, 1024); + host = gethostbyname(hname); + if (host == NULL) + hnameptr = hname; + else + hnameptr = host->h_name; + + p = result; + *p++ = sizeof(AUTHORIZATION_NAME) >> 8; + *p++ = sizeof(AUTHORIZATION_NAME) & 0xff; + *p++ = (len = strlen(hnameptr) + 1) >> 8; + *p++ = (len & 0xff); + + memmove(p, AUTHORIZATION_NAME, sizeof(AUTHORIZATION_NAME)); + p += sizeof(AUTHORIZATION_NAME); + memmove(p, hnameptr, len); + p += len; + } + *authlen = p - result; + *authorizations = result; + return 1; +#else /* TCPCONN */ + return 0; +#endif /* TCPCONN */ +} + +/* XALLOC -- X's internal memory allocator. Why does it return unsigned + * long * instead of the more common char *? Well, if you read K&R you'll + * see they say that alloc must return a pointer "suitable for conversion" + * to whatever type you really want. In a full-blown generic allocator + * there's no way to solve the alignment problems without potentially + * wasting lots of space. But we have a more limited problem. We know + * we're only ever returning pointers to structures which will have to + * be long word aligned. So we are making a stronger guarantee. It might + * have made sense to make Xalloc return char * to conform with people's + * expectations of malloc, but this makes lint happier. + */ + +#ifndef INTERNAL_MALLOC + +unsigned long * +Xalloc (amount) + unsigned long amount; +{ +#if !defined(__STDC__) && !defined(AMOEBA) + char *malloc(); +#endif + register pointer ptr; + + if ((long)amount <= 0) { + return (unsigned long *)NULL; + } + /* aligned extra on long word boundary */ + 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; +} + +/***************** + * XNFalloc + * "no failure" realloc, alternate interface to Xalloc w/o Must_have_memory + *****************/ + +unsigned long * +XNFalloc (amount) + unsigned long amount; +{ +#if !defined(__STDC__) && !defined(AMOEBA) + char *malloc(); +#endif + register pointer ptr; + + if ((long)amount <= 0) + { + return (unsigned long *)NULL; + } + /* aligned extra on long word boundary */ + amount = (amount + (sizeof(long) - 1)) & ~(sizeof(long) - 1); + ptr = (pointer)malloc(amount); + if (!ptr) + { + FatalError("Out of memory"); + } + return ((unsigned long *)ptr); +} + +/***************** + * Xcalloc + *****************/ + +unsigned long * +Xcalloc (amount) + unsigned long amount; +{ + unsigned long *ret; + + ret = Xalloc (amount); + if (ret) + bzero ((char *) ret, (int) amount); + return ret; +} + +/***************** + * Xrealloc + *****************/ + +unsigned long * +Xrealloc (ptr, amount) + register pointer ptr; + unsigned long amount; +{ +#if !defined(__STDC__) && !defined(AMOEBA) + char *malloc(); + char *realloc(); +#endif + +#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; +} + +/***************** + * XNFrealloc + * "no failure" realloc, alternate interface to Xrealloc w/o Must_have_memory + *****************/ + +unsigned long * +XNFrealloc (ptr, amount) + register pointer ptr; + unsigned long amount; +{ + if (( ptr = (pointer)Xrealloc( ptr, amount ) ) == NULL) + { + FatalError( "Out of memory" ); + } + return ((unsigned long *)ptr); +} + +/***************** + * Xfree + * calls free + *****************/ + +void +Xfree(ptr) + register pointer ptr; +{ + if (ptr) + free((char *)ptr); +} + +void +OsInitAllocator () +{ +#ifdef MEMBUG + static int been_here; + + /* Check the memory system after each generation */ + if (been_here) + CheckMemory (); + else + been_here = 1; +#endif +} +#endif + +void +AuditPrefix(f) + char *f; +{ +#ifdef X_NOT_STDC_ENV + long tm; +#else + time_t tm; +#endif + char *autime, *s; + if (*f != ' ') + { + time(&tm); + autime = ctime(&tm); + if (s = strchr(autime, '\n')) + *s = '\0'; + if (s = strrchr(argvGlobal[0], '/')) + s++; + else + s = argvGlobal[0]; + ErrorF("AUDIT: %s: %d %s: ", autime, getpid(), s); + } +} + +/*VARARGS1*/ +void +AuditF( +#if NeedVarargsPrototypes + char * f, ...) +#else + f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) /* limit of ten args */ + char *f; + char *s0, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9; +#endif +{ +#if NeedVarargsPrototypes + va_list args; +#endif + + AuditPrefix(f); + +#if NeedVarargsPrototypes + va_start(args, f); + VErrorF(f, args); + va_end(args); +#else + ErrorF(f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); +#endif +} + +/*VARARGS1*/ +void +FatalError( +#if NeedVarargsPrototypes + char *f, ...) +#else +f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) /* limit of ten args */ + char *f; + char *s0, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9; +#endif +{ +#if NeedVarargsPrototypes + va_list args; +#endif + ErrorF("\nFatal server error:\n"); +#if NeedVarargsPrototypes + va_start(args, f); + VErrorF(f, args); + va_end(args); +#else + ErrorF(f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); +#endif + ErrorF("\n"); +#ifdef DDXOSFATALERROR + OsVendorFatalError(); +#endif + AbortServer(); + /*NOTREACHED*/ +} + +#if NeedVarargsPrototypes +void +VErrorF(f, args) + char *f; + va_list args; +{ + vfprintf(stderr, f, args); +} +#endif + +/*VARARGS1*/ +void +ErrorF( +#if NeedVarargsPrototypes + char * f, ...) +#else + f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) /* limit of ten args */ + char *f; + char *s0, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9; +#endif +{ +#if NeedVarargsPrototypes + va_list args; + va_start(args, f); + VErrorF(f, args); + va_end(args); +#else +#ifdef AMOEBA + mu_lock(&print_lock); +#endif + fprintf( stderr, f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); +#ifdef AMOEBA + mu_unlock(&print_lock); +#endif +#endif +} + +#if !defined(WIN32) && !defined(__EMX__) +/* + * "safer" versions of system(3), popen(3) and pclose(3) which give up + * all privs before running a command. + * + * This is based on the code in FreeBSD 2.2 libc. + */ + +int +System(command) + char *command; +{ + int pid, p; + void (*csig)(); + int status; + + if (!command) + return(1); + +#ifdef SIGCHLD + csig = signal(SIGCHLD, SIG_DFL); +#endif + + ErrorF("System: `%s'\n", command); + + switch (pid = fork()) { + case -1: /* error */ + p = -1; + case 0: /* child */ + setgid(getgid()); + setuid(getuid()); + execl("/bin/sh", "sh", "-c", command, (char *)NULL); + _exit(127); + default: /* parent */ + do { + p = waitpid(pid, &status, 0); + } while (p == -1 && errno == EINTR); + + } + +#ifdef SIGCHLD + signal(SIGCHLD, csig); +#endif + + return p == -1 ? -1 : status; +} + +static struct pid { + struct pid *next; + FILE *fp; + int pid; +} *pidlist; + +pointer +Popen(command, type) + char *command; + char *type; +{ + struct pid *cur; + FILE *iop; + int pdes[2], pid; + void (*csig)(); + + 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; + } + + switch (pid = fork()) { + case -1: /* error */ + close(pdes[0]); + close(pdes[1]); + xfree(cur); + return NULL; + case 0: /* child */ + setgid(getgid()); + setuid(getuid()); + if (*type == 'r') { + if (pdes[1] != 1) { + /* stdout */ + dup2(pdes[1], 1); + close(pdes[1]); + } + close(pdes[0]); + } else { + if (pdes[0] != 0) { + /* stdin */ + dup2(pdes[0], 0); + close(pdes[0]); + } + close(pdes[1]); + } + execl("/bin/sh", "sh", "-c", command, (char *)NULL); + _exit(127); + } + + /* parent */ + 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; + +#if 0 + ErrorF("Popen: `%s', fp = %p\n", command, iop); +#endif + + return iop; +} + +int +Pclose(iop) + pointer iop; +{ + struct pid *cur, *last; + int omask; + int pstat; + int pid; + +#if 0 + 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); + + return pid == -1 ? -1 : pstat; +} +#endif /* !WIN32 && !__EMX__ */