Пример #1
0
char *
iniMerge( char *data, const char *newdata )
{
    const char *p, *cb, *ce;
    char *section = 0, *key, *value;

    if (!newdata)
        return data;
    for (p = newdata;;) {
        for (; *p == ' ' || *p == '\t'; p++);
        if (!*p)
            break;
        if (*p == '\n') {
            p++;
            continue;
        }
        if (*p == '#') {
            for (p++; *p != '\n'; p++)
                if (!*p)
                    goto bail;
            p++;
            continue;
        }
        if (*p == '[') {
            cb = ++p;
            for (; *p != ']'; p++)
                if (!*p || *p == '\n') /* missing ] */
                    goto bail;
            if (!reStrN( &section, cb, p - cb ))
                break;
            p++;
        } else {
            cb = p;
            for (; *p != '='; p++)
                if (!*p || *p == '\n') /* missing = */
                    goto bail;
            for (ce = p; ce != cb && (*(ce - 1) == ' ' || *(ce - 1) == '\t'); ce--);
            if (!strNDup( &key, cb, ce - cb ))
                break;
            for (p++; *p == ' ' || *p == '\t'; p++);
            cb = p;
            for (; *p && *p != '\n'; p++);
            for (ce = p; ce != cb && (*(ce - 1) == ' ' || *(ce - 1) == '\t'); ce--);
            if (!strNDup( &value, cb, ce - cb ))
                break;
            if (section)
                data = iniEntry( data, section, key, value );
            free( value );
            free( key );
        }
    }
bail:
    if (section)
        free( section );
    return data;
}
Пример #2
0
char *
iniEntry( char *data, const char *section, const char *key, const char *value )
{
    char *p = data, *secinsert = 0, *pastinsert = 0, *cb, *ce, *ndata;
    const char *t;
    int insect = 0, ll, sl, kl, vl, len, nlen;

    if (p) {
        while (*p) {
            for (; *p == ' ' || *p == '\t'; p++);
            if (*p == '\n') {
                p++;
                continue;
            }
            if (*p == '[') {
                for (t = section; *++p == *t; t++);
                insect = !*t && *p == ']';
            } else if (insect) {
                for (t = key; *p == *t; t++, p++);
                for (; *p == ' ' || *p == '\t'; p++);
                if (!*t && *p == '=') {
                    for (p++; *p == ' ' || *p == '\t'; p++);
                    cb = p;
                    while (*p++ != '\n');
                    ce = p;
                    if (value) {
                        ll = sl = kl = 0;
                        len = (ce - data) + strlen( ce );
                        goto insert;
                    } else {
                        for (ce--; ce != cb && (*(ce - 1) == ' ' || *(ce - 1) == '\t'); ce--);
                        if (!strNDup( &p, cb, ce - cb ))
                            return 0;
                        return p;
                    }
                }
            }
            for (; *p != '\n'; p++);
            p++;
            if (insect)
                secinsert = p;
            else
                pastinsert = p;
        }
    }
    if (!value)
        return 0;
    len = p - data;
    if (secinsert) {
        ce = cb = secinsert;
        sl = ll = 0;
    } else {
        sl = strlen( section ) + 3;
        if (pastinsert) {
            ce = cb = pastinsert;
            ll = 1;
        } else {
            ce = cb = data;
            ll = 0;
        }
    }
    kl = strlen( key ) + 1;
insert:
    vl = strlen( value );
    nlen = len - (ce - cb) + ll + sl + kl + vl + 1;
    if (!(p = ndata = Malloc( nlen + 1 )))
        return data;
    apparr( p, data, cb - data ); /* zero length if data is null */
    if (kl) {
        if (sl) {
            if (ll)
                appbyte( p, '\n' );
            appbyte( p, '[' );
            apparr( p, section, sl - 3 );
            appbyte( p, ']' );
            appbyte( p, '\n' );
        }
        apparr( p, key, kl - 1 );
        appbyte( p, '=' );
    }
    apparr( p, value, vl );
    appbyte( p, '\n' );
    if (data) {
        apparr( p, ce, len - (ce - data) );
        free( data );
    }
    appbyte( p, 0 );
    return ndata;
}
Пример #3
0
int
main(int argc, char **argv)
{
    int oldpid, oldumask, fd, parentPid;
    char *pt, *errorLogFile, **opts;

    /* make sure at least world write access is disabled */
    if (((oldumask = umask(022)) & 002) == 002)
        (void)umask(oldumask);

    /* give /dev/null as stdin */
    if ((fd = open("/dev/null", O_RDONLY)) > 0) {
        dup2(fd, 0);
        close(fd);
    }
    if (fcntl(1, F_GETFD) < 0)
        dup2(0, 1);
    if (fcntl(2, F_GETFD) < 0)
        dup2(0, 2);

#ifndef nowMonotonic
    nowMonotonic = sysconf(_SC_MONOTONIC_CLOCK) >= 200112L;
#endif

#if KDM_LIBEXEC_STRIP == -1
    prog = strrchr(argv[0], '/');
    progname = prog = prog ? prog + 1 : argv[0];
#else
    if (argv[0][0] == '/') {
        if (!strDup(&progpath, argv[0]))
            panic("Out of memory");
    } else
# ifdef __linux__
    {
        /* note that this will resolve symlinks ... */
        int len;
        char fullpath[PATH_MAX];
        if ((len = readlink("/proc/self/exe", fullpath, sizeof(fullpath))) < 0)
            panic("Invoke with full path specification or mount /proc");
        if (!strNDup(&progpath, fullpath, len))
            panic("Out of memory");
    }
# else
#  if 0
        panic("Must be invoked with full path specification");
#  else
    {
        char directory[PATH_MAX+1];
        if (!getcwd(directory, sizeof(directory)))
            panic("Can't find myself (getcwd failed)");
        if (strchr(argv[0], '/')) {
            strApp(&progpath, directory, "/", argv[0], (char *)0);
        } else {
            int len;
            char *path, *pathe, *name, *thenam, nambuf[PATH_MAX+1];

            if (!(path = getenv("PATH")))
                panic("Can't find myself (no PATH)");
            len = strlen(argv[0]);
            name = nambuf + PATH_MAX - len;
            memcpy(name, argv[0], len + 1);
            *--name = '/';
            do {
                if (!(pathe = strchr(path, ':')))
                    pathe = path + strlen(path);
                len = pathe - path;
                if (!len || (len == 1 && *path == '.')) {
                    len = strlen(directory);
                    path = directory;
                }
                thenam = name - len;
                if (thenam >= nambuf) {
                    memcpy(thenam, path, len);
                    if (!access(thenam, X_OK))
                        goto found;
                }
                path = pathe;
            } while (*path++ != '\0');
            panic("Can't find myself (not in PATH)");
          found:
            if (!strDup(&progpath, thenam))
                panic("Out of memory");
        }
    }
#  endif
# endif
    prog = strrchr(progpath, '/') + 1;
# if KDM_LIBEXEC_STRIP
    for (progname = pt = prog, fd = 0; fd < KDM_LIBEXEC_STRIP + 1; fd++) {
        for (;;) {
            pt--;
            if (pt == progpath)
                panic("Executable is obviously located outside BINDIR");
            if (*pt == '/')
                break;
        }
    }
    *pt = 0;
# endif
#endif

#if !defined(HAVE_SETPROCTITLE) && !defined(NOXDMTITLE)
    title = argv[0];
    titleLen = (argv[argc - 1] + strlen(argv[argc - 1])) - title;
#endif

    /*
     * Parse command line options
     */
    parentPid = getppid();
    errorLogFile = 0;
    if (!(opts = Malloc(2 * sizeof(char *))))
        return 1;
    opts[0] = (char *)"";
    opts[1] = 0;
    while (*++argv) {
        if (**argv != '-')
            break;
        pt = *argv + 1;
        if (*pt == '-')
            pt++;
        if (!strcmp(pt, "help") || !strcmp(pt, "h")) {
            printf("Usage: %s [options] [tty]\n"
"  -daemon\t  - Daemonize even when started by init\n"
"  -nodaemon\t  - Do not daemonize even when started from command line\n"
"  -config <file>  - Use alternative master configuration file\n"
"  -xrm <res>\t  - Override frontend-specific resource\n"
"  -error <file>\t  - Use alternative log file\n"
"  -debug <num>\t  - Debug option bitfield:\n"
"\t\t\t0x1 - core log\n"
"\t\t\t0x2 - config reader log\n"
"\t\t\t0x4 - greeter log\n"
"\t\t\t0x8 - IPC log\n"
"\t\t\t0x10 - session sub-daemon post-fork delay\n"
"\t\t\t0x20 - config reader post-start delay\n"
"\t\t\t0x40 - greeter post-start delay\n"
"\t\t\t0x80 - do not use syslog\n"
"\t\t\t0x100 - core Xauth log\n"
"\t\t\t0x200 - debug greeter theming\n"
"\t\t\t0x400 - valgrind config reader and greeter\n"
"\t\t\t0x800 - strace config reader and greeter\n"
                    , prog);
            exit(0);
        } else if (!strcmp(pt, "daemon")) {
            parentPid = 0;
        } else if (!strcmp(pt, "nodaemon")) {
            parentPid = 1;
        } else if (argv[1] && !strcmp(pt, "config")) {
            strDup(opts, *++argv);
        } else if (argv[1] && !strcmp(pt, "xrm")) {
            opts = addStrArr(opts, *++argv, -1);
        } else if (argv[1] && !strcmp(pt, "debug")) {
            sscanf(*++argv, "%i", &debugLevel);
        } else if (argv[1] && (!strcmp(pt, "error") || !strcmp(pt, "logfile"))) {
            errorLogFile = *++argv;
        } else {
            fprintf(stderr, "\"%s\" is an unknown option or is missing a parameter\n", *argv);
            exit(1);
        }
    }

    /*
     * Only allow root to run in non-debug mode to avoid problems
     */
    if (!debugLevel && getuid()) {
        fprintf(stderr, "Only root wants to run %s\n", prog);
        exit(1);
    }

    initErrorLog(errorLogFile);

    if (parentPid != 1)
        becomeDaemon();

    /*
     * Step 1 - load configuration parameters
     */
    if (!initResources(opts) || scanConfigs(False) < 0)
        logPanic("Config reader failed. Aborting ...\n");

    /* SUPPRESS 560 */
    if ((oldpid = storePid())) {
        if (oldpid == -1)
            logError("Cannot create/lock pid file %s\n", pidFile);
        else
            logError("Cannot lock pid file %s, another xdm is running (pid %d)\n",
                     pidFile, oldpid);
        exit(1);
    }

#ifdef NEED_ENTROPY
    addOtherEntropy();
#endif

    /*
     * We used to clean up old authorization files here. As authDir is
     * supposed to be /var/run/xauth or /tmp, we needn't to care for it.
     */

#ifdef XDMCP
    initXdmcp();
#else
    debug("not compiled for XDMCP\n");
#endif
    if (pipe(signalFds))
        logPanic("Unable to create signal notification pipe.\n");
    registerInput(signalFds[0]);
    registerCloseOnFork(signalFds[0]);
    registerCloseOnFork(signalFds[1]);
    (void)Signal(SIGTERM, sigHandler);
    (void)Signal(SIGINT, sigHandler);
    (void)Signal(SIGHUP, sigHandler);
    (void)Signal(SIGCHLD, sigHandler);
    (void)Signal(SIGUSR1, sigHandler);

    /*
     * Step 2 - run a sub-daemon for each entry
     */
    openCtrl(0);
#ifdef XDMCP
    updateListenSockets();
#endif
    mainLoop();
    closeCtrl(0);
    if (sdRec.how) {
        int pid;
        commitBootOption();
        if (Fork(&pid) <= 0) {
            char *cmd = sdRec.how == SHUT_HALT ? cmdHalt : cmdReboot;
            execute(parseArgs((char **)0, cmd), (char **)0);
            logError("Failed to execute shutdown command %\"s\n", cmd);
            exit(1);
        } else {
            sigset_t mask;
            sigemptyset(&mask);
            sigaddset(&mask, SIGCHLD);
            sigaddset(&mask, SIGHUP);
            sigsuspend(&mask);
        }
    }
    debug("nothing left to do, exiting\n");
    return 0;
}