diff options
Diffstat (limited to 'os/utils.c')
-rw-r--r-- | os/utils.c | 271 |
1 files changed, 202 insertions, 69 deletions
@@ -46,15 +46,25 @@ in this Software without prior written authorization from The Open Group. * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF * THIS SOFTWARE. */ +/* $XFree86: xc/programs/xfs/os/utils.c,v 3.20 2002/10/15 01:45:03 dawes Exp $ */ #include <stdio.h> #include <X11/Xos.h> +#include <stdlib.h> #include "misc.h" #include "globals.h" #include <signal.h> #ifdef MEMBUG #include <util/memleak/memleak.h> #endif +#include <sys/wait.h> +#include <unistd.h> +#include <pwd.h> +#include <grp.h> +#include <errno.h> +#include <sys/types.h> +#include <errno.h> +#include <string.h> #ifndef X_NOT_POSIX #ifdef _POSIX_SOURCE @@ -76,32 +86,46 @@ in this Software without prior written authorization from The Open Group. #endif #endif /* PATH_MAX */ -#ifdef SIGNALRETURNSINT -#define SIGVAL int -#else -#define SIGVAL void -#endif - #if defined(X_NOT_POSIX) && (defined(SYSV) || defined(SVR4)) #define SIGNALS_RESET_WHEN_CAUGHT #endif +#include <stdlib.h> + extern char *configfilename; +static Bool dropPriv = FALSE; /* whether or not to drop root privileges */ +#ifdef DEFAULT_DAEMON +static Bool becomeDaemon = TRUE; /* whether to become a daemon or not */ +#else +static Bool becomeDaemon = FALSE; /* whether to become a daemon or not */ +#endif +static const char *userId = NULL; char *progname; Bool CloneSelf; -extern int ListenPort; +Bool portFromCmdline = FALSE; OldListenRec *OldListen = NULL; int OldListenCount = 0; +#ifdef STDERR_FILENO +# define WRITES write(STDERR_FILENO, s, strlen(s)) +#else +# define WRITES write(fileno(stderr), s, strlen(s)) +#endif + +static char *pidFile = XFSPIDDIR "/xfs.pid"; +static int pidFd; +static FILE *pidFilePtr; +static int StorePid (void); + /* ARGSUSED */ SIGVAL -AutoResetServer(n) - int n; +AutoResetServer(int n) { + int olderrno = errno; #ifdef DEBUG - fprintf(stderr, "got a reset signal\n"); + WRITES("got a reset signal\n"); #endif dispatchException |= DE_RESET; @@ -110,28 +134,31 @@ AutoResetServer(n) #ifdef SIGNALS_RESET_WHEN_CAUGHT signal(SIGHUP, AutoResetServer); #endif + errno = olderrno; } +/* ARGSUSED */ SIGVAL -GiveUp() +GiveUp(int n) { - + int olderrno = errno; #ifdef DEBUG - fprintf(stderr, "got a TERM signal\n"); + WRITES("got a TERM signal\n"); #endif dispatchException |= DE_TERMINATE; isItTimeToYield = TRUE; + errno = olderrno; } /* ARGSUSED */ SIGVAL -ServerReconfig(n) - int n; +ServerReconfig(int n) { + int olderrno = errno; #ifdef DEBUG - fprintf(stderr, "got a re-config signal\n"); + WRITES("got a re-config signal\n"); #endif dispatchException |= DE_RECONFIG; @@ -140,16 +167,17 @@ ServerReconfig(n) #ifdef SIGNALS_RESET_WHEN_CAUGHT signal(SIGUSR1, ServerReconfig); #endif + errno = olderrno; } /* ARGSUSED */ SIGVAL -ServerCacheFlush(n) - int n; +ServerCacheFlush(int n) { + int olderrno = errno; #ifdef DEBUG - fprintf(stderr, "got a flush signal\n"); + WRITES("got a flush signal\n"); #endif dispatchException |= DE_FLUSH; @@ -158,16 +186,17 @@ ServerCacheFlush(n) #ifdef SIGNALS_RESET_WHEN_CAUGHT signal(SIGUSR2, ServerCacheFlush); #endif + errno = olderrno; } /* ARGSUSED */ SIGVAL -CleanupChild(n) - int n; +CleanupChild(int n) { + int olderrno = errno; #ifdef DEBUG - fprintf(stderr, "got a child signal\n"); + WRITES("got a child signal\n"); #endif wait(NULL); @@ -175,10 +204,11 @@ CleanupChild(n) #ifdef SIGNALS_RESET_WHEN_CAUGHT signal(SIGCHLD, CleanupChild); #endif + errno = olderrno; } long -GetTimeInMillis() +GetTimeInMillis(void) { struct timeval tp; @@ -187,14 +217,15 @@ GetTimeInMillis() } static void -usage() +usage(void) { - fprintf(stderr, "usage: %s [-config config_file] [-port tcp_port]\n", + fprintf(stderr, "usage: %s [-config config_file] [-port tcp_port] [-droppriv] [-daemon] [-nodaemon] [-user user_name] [-ls listen_socket]\n", progname); exit(1); } -OsInitAllocator () +void +OsInitAllocator (void) { #ifdef MEMBUG CheckMemory (); @@ -211,19 +242,14 @@ OsInitAllocator () * * [] denotes optional and ... denotes repitition. * - * The string must be _exactly_ in the above format. Since this is - * an internal option used by the font server, it's ok to be strict - * about the format of the string. + * The string must be _exactly_ in the above format. */ void -ProcessLSoption (str) - -char *str; - +ProcessLSoption (char *str) { char *ptr = str; - char *slash, *next; + char *slash; char number[20]; int count = 0; int len, i; @@ -238,12 +264,18 @@ char *str; OldListenCount = count + 1; OldListen = (OldListenRec *) malloc ( OldListenCount * sizeof (OldListenRec)); - + if (OldListen == NULL) { + fprintf(stderr, "ProcessLSoption: malloc error\n"); + exit(1); + } ptr = str; for (i = 0; i < OldListenCount; i++) { slash = (char *) strchr (ptr, '/'); + if (slash == NULL) { + usage(); + } len = slash - ptr; strncpy (number, ptr, len); number[len] = '\0'; @@ -252,6 +284,9 @@ char *str; ptr = slash + 1; slash = (char *) strchr (ptr, '/'); + if (slash == NULL) { + usage(); + } len = slash - ptr; strncpy (number, ptr, len); number[len] = '\0'; @@ -264,7 +299,9 @@ char *str; else { char *comma = (char *) strchr (ptr, ','); - + if (comma == NULL) { + usage(); + } len = comma - ptr; strncpy (number, ptr, len); number[len] = '\0'; @@ -279,24 +316,34 @@ char *str; /* ARGSUSED */ void -ProcessCmdLine(argc, argv) - int argc; - char **argv; +ProcessCmdLine(int argc, char **argv) { int i; progname = argv[0]; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-port")) { - if (argv[i + 1]) + if (argv[i + 1]) { ListenPort = atoi(argv[++i]); - else + portFromCmdline = TRUE; + } else usage(); } else if (!strcmp(argv[i], "-ls")) { if (argv[i + 1]) ProcessLSoption (argv[++i]); else usage(); + } else if (!strcmp(argv[i], "-droppriv")) { + dropPriv = TRUE; + } else if (!strcmp(argv[i], "-daemon")) { + becomeDaemon = TRUE; + } else if (!strcmp(argv[i], "-nodaemon")) { + becomeDaemon = FALSE; + } else if (!strcmp(argv[i], "-user")) { + if (argv[i + 1]) + userId = argv[++i]; + else + usage(); } else if (!strcmp(argv[i], "-cf") || !strcmp(argv[i], "-config")) { if (argv[i + 1]) configfilename = argv[++i]; @@ -341,14 +388,13 @@ unsigned long MemoryFail; * expectations of malloc, but this makes lint happier. */ -unsigned long * -FSalloc (amount) - unsigned long amount; +pointer +FSalloc (unsigned long amount) { register pointer ptr; if ((long)amount < 0) - return (unsigned long *)NULL; + return 0; if (amount == 0) amount++; /* aligned extra on long word boundary */ @@ -356,27 +402,26 @@ FSalloc (amount) #ifdef MEMBUG if (!Must_have_memory && MemoryFail && ((random() % MEM_FAIL_SCALE) < MemoryFail)) - return (unsigned long *)NULL; + return 0; if (ptr = (pointer)fmalloc(amount)) - return (unsigned long *) ptr; + return ptr; #else - if (ptr = (pointer)malloc(amount)) - return (unsigned long *)ptr; + if ((ptr = (pointer)malloc(amount)) != 0) + return ptr; #endif if (Must_have_memory) - FatalError("Out of memory\n"); - return (unsigned long *)NULL; + FatalError("out of memory\n"); + return 0; } /***************** * FScalloc *****************/ -unsigned long * -FScalloc (amount) - unsigned long amount; +pointer +FScalloc (unsigned long amount) { - unsigned long *ret; + pointer ret; ret = FSalloc (amount); if (ret) @@ -388,26 +433,22 @@ FScalloc (amount) * FSrealloc *****************/ -unsigned long * -FSrealloc (ptr, amount) - register pointer ptr; - unsigned long amount; +pointer +FSrealloc (pointer ptr, unsigned long amount) { - char *realloc(); - #ifdef MEMBUG if (!Must_have_memory && MemoryFail && ((random() % MEM_FAIL_SCALE) < MemoryFail)) - return (unsigned long *)NULL; + return 0; ptr = (pointer)frealloc((char *) ptr, amount); if (ptr) - return (unsigned long *) ptr; + return ptr; #else if ((long)amount <= 0) { if (ptr && !amount) free(ptr); - return (unsigned long *)NULL; + return 0; } amount = (amount + 3) & ~3; if (ptr) @@ -415,11 +456,11 @@ FSrealloc (ptr, amount) else ptr = (pointer)malloc(amount); if (ptr) - return (unsigned long *)ptr; + return ptr; #endif if (Must_have_memory) - FatalError("Out of memory\n"); - return (unsigned long *)NULL; + FatalError("out of memory\n"); + return 0; } /***************** @@ -428,8 +469,7 @@ FSrealloc (ptr, amount) *****************/ void -FSfree(ptr) - register pointer ptr; +FSfree(pointer ptr) { #ifdef MEMBUG if (ptr) @@ -441,3 +481,96 @@ FSfree(ptr) } #endif /* SPECIAL_MALLOC */ + + +void +SetUserId(void) +{ + /* become xfs user (or other specified on command line) if possible */ + if ((geteuid() == 0) && (dropPriv || userId)) { + const char *user; + struct passwd *pwent; + + if (!userId) + user = "xfs"; + else + user = userId; + pwent = getpwnam(user); + if (pwent) { + if (setgid(pwent->pw_gid)) { + FatalError("fatal: couldn't set groupid to xfs user's group\n"); + } +#ifndef QNX4 +#ifndef __CYGWIN__ + if (setgroups(0, NULL)) { + FatalError("fatal: couldn't drop supplementary groups\n"); + } +#endif + if (initgroups(user, pwent->pw_gid)) { + FatalError("fatal: couldn't init supplementary groups\n"); + } +#endif /* QNX4 */ + if (setuid(pwent->pw_uid)) { + FatalError("fatal: couldn't set userid to %s user\n", user); + } + } + } else if (dropPriv || userId) { + FatalError("fatal: -droppriv or -user flag specified, but xfs not run as root\n"); + } +} + + +void +SetDaemonState(void) +{ + int oldpid; + + if (becomeDaemon) { + BecomeOrphan(); + BecomeDaemon(); + if ((oldpid = StorePid ())) { + if (oldpid == -1) + ErrorF ("error opening process-id file %s\n", pidFile); + else + ErrorF ("process-id file %s indicates another xfs is " + "running (pid %d); exiting\n", pidFile, oldpid); + exit(1); + } + } +} + + +static int +StorePid (void) +{ + int oldpid; + + if (pidFile[0] != '\0') { + pidFd = open (pidFile, O_RDWR); + if (pidFd == -1 && errno == ENOENT) + pidFd = open (pidFile, O_RDWR|O_CREAT, 0666); + if (pidFd == -1 || !(pidFilePtr = fdopen (pidFd, "r+"))) + { + ErrorF ("cannot open process-id file %s: %s\n", pidFile, + strerror (errno)); + return -1; + } + if (fscanf (pidFilePtr, "%d\n", &oldpid) != 1) + oldpid = -1; + if (fseek (pidFilePtr, 0L, SEEK_SET) == -1) + { + ErrorF ("cannot seek process-id file %s: %s\n", pidFile, + strerror (errno)); + return -1; + } + if (fprintf (pidFilePtr, "%5ld\n", (long) getpid ()) != 6) + { + ErrorF ("cannot write to process-id file %s: %s\n", pidFile, + strerror (errno)); + return -1; + } + (void) fflush (pidFilePtr); + (void) fclose (pidFilePtr); + } + return 0; +} |