123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641 |
- /*
- Copyright 1987, 1998 The Open Group
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
- 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 OPEN GROUP 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 Open Group 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 Open Group.
- 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.
- */
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include <X11/Xos.h>
- #include <stdio.h>
- #include <time.h>
- #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
- #include <sys/wait.h>
- #include <sys/resource.h>
- #include <sys/stat.h>
- #include <ctype.h> /* for isspace */
- #include <stdarg.h>
- #include <stdlib.h> /* for malloc() */
- #if defined(TCPCONN)
- # include <netdb.h>
- #endif
- #include "opaque.h"
- #ifdef SMART_SCHEDULE
- #include "dixstruct.h"
- #endif
- #include "picture.h"
- _X_EXPORT Bool noTestExtensions;
- _X_EXPORT Bool noBigReqExtension = FALSE;
- _X_EXPORT Bool noDamageExtension = FALSE;
- #ifdef DBE
- _X_EXPORT Bool noDbeExtension = FALSE;
- #endif
- #ifdef DPMSExtension
- _X_EXPORT Bool noDPMSExtension = FALSE;
- #endif
- #ifdef SCREENSAVER
- _X_EXPORT Bool noScreenSaverExtension = FALSE;
- #endif
- _X_EXPORT Bool noMITShmExtension = FALSE;
- _X_EXPORT Bool noRRExtension = FALSE;
- _X_EXPORT Bool noRenderExtension = FALSE;
- _X_EXPORT Bool noShapeExtension = FALSE;
- _X_EXPORT Bool noSyncExtension = FALSE;
- #ifdef RES
- _X_EXPORT Bool noResExtension = FALSE;
- #endif
- _X_EXPORT Bool noXCMiscExtension = FALSE;
- #ifdef XF86BIGFONT
- _X_EXPORT Bool noXFree86BigfontExtension = FALSE;
- #endif
- _X_EXPORT Bool noXFixesExtension = FALSE;
- #define X_INCLUDE_NETDB_H
- #include <X11/Xos_r.h>
- #include <errno.h>
- Bool CoreDump;
- int auditTrailLevel = 0;
- _X_EXPORT Bool Must_have_memory = FALSE;
- #if 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> /* for random() */
- #endif
- char *dev_tty_from_init = NULL; /* since we need to parse it anyway */
- OsSigHandlerPtr
- OsSignal(sig, handler)
- int sig;
- OsSigHandlerPtr handler;
- {
- 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;
- }
- /*
- * 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.
- */
- #define LOCK_DIR "/tmp"
- #define LOCK_TMP_PREFIX "/.tX"
- #define LOCK_PREFIX "/.X"
- #define LOCK_SUFFIX "-lock"
- #ifndef PATH_MAX
- #include <sys/param.h>
- #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;
- /*
- * 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(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;
- /*
- * Path names
- */
- 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);
- /*
- * 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, "%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);
- /*
- * 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",
- 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;
- }
- /*
- * UnlockServer --
- * Remove the server lock file.
- */
- void
- UnlockServer(void)
- {
- if (nolock) return;
- if (!StillLocking){
- (void) unlink(LockFile);
- }
- }
- /* Force connections to close on SIGHUP from init */
- /*ARGSUSED*/
- SIGVAL
- AutoResetServer (int sig)
- {
- int olderrno = errno;
- dispatchException |= DE_RESET;
- isItTimeToYield = TRUE;
- #ifdef GPROF
- chdir ("/tmp");
- exit (0);
- #endif
- errno = olderrno;
- }
- /* Force connections to close and then exit on SIGTERM, SIGINT */
- /*ARGSUSED*/
- _X_EXPORT SIGVAL
- GiveUp(int sig)
- {
- int olderrno = errno;
- dispatchException |= DE_TERMINATE;
- isItTimeToYield = TRUE;
- errno = olderrno;
- }
- _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);
- }
- _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)
- {
- ErrorF("%s\n\n", PACKAGE_STRING);
- 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("-c turns off key-click\n");
- ErrorF("c # key-click volume (0-100)\n");
- ErrorF("-cc int default color visual class\n");
- 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
- ErrorF("-nolock disable the locking mechanism\n");
- #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");
- ErrorF("-render [default|mono|gray|color] set render color alloc policy\n");
- ErrorF("-s # screen-saver timeout (minutes)\n");
- ErrorF("-startbench shut down immediately\n");
- ErrorF("-t # mouse threshold (pixels)\n");
- ErrorF("-tcp listen for TCP (default is nolisten tcp)\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("-version show the server version\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 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
- ddxUseMsg();
- }
- /* This function performs a rudimentary sanity check
- * on the display name passed in on the command-line,
- * since this string is used to generate filenames.
- * It is especially important that the display name
- * not contain a "/" and not start with a "-".
- * --kvajk
- */
- static int
- VerifyDisplayName(const char *d)
- {
- if ( d == (char *)0 ) return( 0 ); /* null */
- if ( *d == '\0' ) return( 0 ); /* empty */
- if ( *d == '-' ) return( 0 ); /* could be confused for an option */
- if ( *d == '.' ) return( 0 ); /* must not equal "." or ".." */
- if ( strchr(d, '/') != (char *)0 ) return( 0 ); /* very important!!! */
- return( 1 );
- }
- /*
- * 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(int argc, char *argv[])
- {
- int i, skip;
- int tcp = 0;
- defaultKeyboardControl.autoRepeat = TRUE;
- #ifdef NO_PART_NET
- PartialNetwork = FALSE;
- #else
- 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++;
- 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], "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], "-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)
- {
- defaultFontPath = argv[i];
- }
- else
- UseMsg();
- }
- else if ( strcmp( argv[i], "-help") == 0)
- {
- UseMsg();
- exit(0);
- }
- #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
- else if ( strcmp ( argv[i], "-nolock") == 0)
- {
- if (getuid() != 0)
- ErrorF("Warning: the -nolock option can only be used by root\n");
- else
- nolock = TRUE;
- }
- #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], "-startbench") == 0)
- {
- GiveUp(0);
- }
- 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], "-t") == 0)
- {
- if(++i < argc)
- defaultPointerControl.threshold = atoi(argv[i]);
- else
- UseMsg();
- }
- else if ( strcmp( argv[i], "-tcp") == 0)
- {
- tcp = 1;
- }
- 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], "-wr") == 0)
- whiteRoot = TRUE;
- else if ( strcmp( argv[i], "-maxbigreqsize") == 0) {
- if(++i < argc) {
- long reqSizeArg = atol(argv[i]);
- /* Request size > 128MB does not make much sense... */
- if( reqSizeArg > 0L && reqSizeArg < 128L ) {
- maxBigRequestSize = (reqSizeArg * 1048576L) - 1L;
- }
- else
- {
- UseMsg();
- }
- }
- else
- {
- UseMsg();
- }
- }
- 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 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
- else if ( strcmp( argv[i], "-render" ) == 0)
- {
- if (++i < argc)
- {
- int policy = PictureParseCmapPolicy (argv[i]);
- if (policy != PictureCmapPolicyInvalid)
- PictureCmapPolicy = policy;
- else
- UseMsg ();
- }
- else
- UseMsg ();
- }
- 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]);
- }
- }
- if (!tcp)
- _XSERVTransNoListen("tcp");
- }
- /* 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(char **authorizations, int *authlen, pointer client)
- {
- #define AUTHORIZATION_NAME "hp-hostname-1"
- #if defined(TCPCONN)
- 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 = malloc(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 /* TCPCONN */
- return 0;
- #endif /* TCPCONN */
- }
- void
- OsInitAllocator (void)
- {
- #ifdef MEMBUG
- static int been_here;
- /* Check the memory system after each generation */
- if (been_here)
- CheckMemory ();
- else
- been_here = 1;
- #endif
- }
- #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));
- /* Set up the timer signal function */
- 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;
- }
- /* Set up the virtual timer */
- if (!SmartScheduleStartTimer ())
- {
- perror ("scheduling timer");
- return FALSE;
- }
- /* stop the timer and wait for WaitForSomething to start it */
- 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
- }
- /*
- * "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.
- *
- * XXX It'd be good to redirect stderr so that it ends up in the log file
- * as well. As it is now, xkbcomp messages don't end up in the log file.
- */
- 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);
- #endif
- #ifdef DEBUG
- ErrorF("System: `%s'\n", command);
- #endif
- switch (pid = fork()) {
- case -1: /* error */
- return -1;
- case 0: /* child */
- if (setgid(getgid()) == -1)
- _exit(127);
- if (setuid(getuid()) == -1)
- _exit(127);
- 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(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 *)malloc(sizeof(struct pid))) == NULL)
- return NULL;
- if (pipe(pdes) < 0) {
- free(cur);
- return NULL;
- }
- switch (pid = fork()) {
- case -1: /* error */
- close(pdes[0]);
- close(pdes[1]);
- free(cur);
- return NULL;
- case 0: /* child */
- if (setgid(getgid()) == -1)
- _exit(127);
- if (setuid(getuid()) == -1)
- _exit(127);
- 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);
- }
- /* Avoid EINTR during stdio calls */
- OsBlockSignals ();
- /* 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;
- #ifdef DEBUG
- ErrorF("Popen: `%s', fp = %p\n", command, iop);
- #endif
- return iop;
- }
- /* fopen that drops privileges */
- 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 *)malloc(sizeof(struct pid))) == NULL)
- return NULL;
- if (pipe(pdes) < 0) {
- free(cur);
- return NULL;
- }
- switch (pid = fork()) {
- case -1: /* error */
- close(pdes[0]);
- close(pdes[1]);
- free(cur);
- return NULL;
- case 0: /* child */
- if (setgid(getgid()) == -1)
- _exit(127);
- if (setuid(getuid()) == -1)
- _exit(127);
- 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/cat", "cat", file, (char *)NULL);
- _exit(127);
- }
- /* Avoid EINTR during stdio calls */
- OsBlockSignals ();
- /* 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;
- #ifdef DEBUG
- ErrorF("Popen: `%s', fp = %p\n", command, 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 /* HAS_SAVED_IDS_AND_SETEUID */
- }
- 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;
- free(cur);
- /* allow EINTR again */
- OsReleaseSignals ();
- return pid == -1 ? -1 : pstat;
- }
- int
- Fclose(pointer iop)
- {
- #ifdef HAS_SAVED_IDS_AND_SETEUID
- return fclose(iop);
- #else
- return Pclose(iop);
- #endif
- }
- /*
- * CheckUserParameters: check for long command line arguments and long
- * environment variables. By default, these checks are only done when
- * the server's euid != ruid. In 3.3.x, these checks were done in an
- * external wrapper utility.
- */
- /* Consider LD* variables insecure? */
- #ifndef REMOVE_ENV_LD
- #define REMOVE_ENV_LD 1
- #endif
- /* Remove long environment variables? */
- #ifndef REMOVE_LONG_ENV
- #define REMOVE_LONG_ENV 1
- #endif
- /*
- * Disallow stdout or stderr as pipes? It's possible to block the X server
- * when piping stdout+stderr to a pipe.
- *
- * Don't enable this because it looks like it's going to cause problems.
- */
- #ifndef NO_OUTPUT_PIPES
- #define NO_OUTPUT_PIPES 0
- #endif
- /* Check args and env only if running setuid (euid == 0 && euid != uid) ? */
- #ifndef CHECK_EUID
- #define CHECK_EUID 1
- #endif
- /*
- * Maybe the locale can be faked to make isprint(3) report that everything
- * is printable? Avoid it by default.
- */
- #ifndef USE_ISPRINT
- #define USE_ISPRINT 0
- #endif
- #define MAX_ARG_LENGTH 128
- #define MAX_ENV_LENGTH 256
- #define MAX_ENV_PATH_LENGTH 2048 /* Limit for *PATH and TERMCAP */
- #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 CHECK_EUID
- if (geteuid() == 0 && getuid() != geteuid())
- #endif
- {
- /* Check each argv[] */
- for (i = 1; i < argc; i++) {
- if (strcmp(argv[i], "-fp") == 0)
- {
- i++; /* continue with next argument. skip the length check */
- 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) {
- /* Check each envp[] */
- for (i = 0; envp[i]; i++) {
- /* Check for bad environment variables and values */
- #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");
- }
- /*
- * CheckUserAuthorization: check if the user is allowed to start the
- * X server. This usually means some sort of PAM checking, and it is
- * usually only done for setuid servers (uid != euid).
- */
- void
- CheckUserAuthorization(void)
- {
- }
|