src/mn-masterd/daemon.c
int
nol_daemon_launch(const char *config,
                  lmc_parser_t *lmc,
                  const char **user,
                  const char **group, 
                  const char *(*init_cb)(void),
                  const char *(*run_cb)(void),
                  int dofork)
{
    pid_t pid;
    const char *err;
    int   fds[2];
    char  buf[257];
    int   n;
    char  c;
    struct group  *g;
    struct passwd *p;
    M_CODE m;

    if (dofork) {
        /* set up the pipe so we can communicate with
         * the child process, and keep track of whether
         * it succeeds or not */
        if (pipe(fds) == -1) {
            fprintf(stderr, "pipe() failed\n");
            return 1;
        }
        if ((pid = fork()) == -1) {
            close(fds[1]);
            close(fds[0]);
            fprintf(stderr, "fork() failed\n");
            return 1;
        }
    } else
        pid = 0;
    if (pid == 0) { /* if we are the child or dofork was set to 0 */
        /*close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);*/
        if (dofork)
            close(fds[0]);

        do {
            /* now we'll configure and write any
             * error message to the pipe */
            if ((m = lmc_parse_file(lmc, config)) != M_OK) {
                if (!(err = lmc->last_error)) {
                    snprintf(buf, 255, "error %d while parsing configuration file", m);
                    err = buf;
                }
                break;
            }
            if ((err = init_cb()) != 0)
                break;
            if (group && *group) {
                if (!(g = getgrnam(*group))) {
                    snprintf(buf, 255, "could not get GID for '%s'", *group);
                    err = buf;
                    break;
                }
                if (setgid(g->gr_gid) != 0) {
                    snprintf(buf, 255, "could not change GID: %s",
                            strerror(errno));
                    err = buf;
                    break;
                }
            }
            if (user && *user) {
                if (!(p = getpwnam(*user))) {
                    snprintf(buf, 255, "could not get UID for '%s'", *user);
                    err = buf;
                    break;
                }
                if (setuid(p->pw_uid) != 0) {
                    snprintf(buf, 255, "could not change UID: %s",
                            strerror(errno));
                    err = buf;
                    break;
                }
            }
            if (dofork) {
                c = CHILD_SUCCESS;
                write(fds[1], &c, 1);
                close(fds[1]);
            }

            run_cb();
            exit(0);
        } while (0);

        /* reach here on error */
        n = strlen(err);
        if (dofork) {
            if (n > 255) n = 255;
            c = CHILD_FAILURE;
            write(fds[1], &c, 1);
            write(fds[1], err, n);
            close(fds[1]);
        } else 
            fprintf(stderr, "failed: %s\n", err);
        exit(1);
    }

    /* child doesn't reach here */
    close(fds[1]);
    if ((n = read(fds[0], &buf, 1)) <= 0)
        fprintf(stderr, "failed: no data from child, possible crash?\n");
    else if (*buf == CHILD_SUCCESS) {
        close(fds[0]);
        return 0;
    } else if (n == 1) {
        if ((n = read(fds[0], &buf, 255)) <= 0)
            fprintf(stderr, "failed: unknown error in child\n");
        else {
            buf[n] = '\0';
            fprintf(stderr, "failed: %s\n", buf);
        }
    }

    close(fds[0]);
    return 1;
}
/** 
 * Function used by mn-masterd, mn-slaved and mb-client.
 *
 * Fork and load the configuration file specified in
 * 'config'. 'user' and 'group' points to strings 
 * identifying the names of a user and group to 
 * setuid and setgid to. setuid is done AFTER the 
 * loading of the configuration file, so the configuration
 * file may alter the strings.
 *
 * A pipe will be opened to the forked process, this pipe
 * is used to notify failure or success.
 *
 * Once the fork and loading of the configuration 
 * is completed, 'run' will be called to start the
 * daemon.
 *
 * Return 0 if the daemon was successfully started.
 **/
Function used by mn-masterd, mn-slaved and mb-client.
Fork and load the configuration file specified in
'config'. 'user' and 'group' points to strings
identifying the names of a user and group to
setuid and setgid to. setuid is done AFTER the
loading of the configuration file, so the configuration
file may alter the strings.

A pipe will be opened to the forked process, this pipe
is used to notify failure or success.

Once the fork and loading of the configuration
is completed, 'run' will be called to start the
daemon.

Return 0 if the daemon was successfully started.
Function used by mn - masterd mn - slaved and mb - client . Fork and load the configuration file specified in ' config ' . ' user ' and ' group ' points to strings identifying the names of a user and group to setuid and setgid to . setuid is done AFTER the loading of the configuration file so the configuration file may alter the strings . A pipe will be opened to the forked process this pipe is used to notify failure or success . Once the fork and loading of the configuration is completed ' run ' will be called to start the daemon . Return 0 if the daemon was successfully started .
int
nol_daemon_launch(const char *config,
                  lmc_parser_t *lmc,
                  const char **user,
                  const char **group, 
                  const char *(*init_cb)(void),
                  const char *(*run_cb)(void),
                  int dofork)
{
    pid_t pid;
    const char *err;
    int   fds[2];
    char  buf[257];
    int   n;
    char  c;
    struct group  *g;
    struct passwd *p;
    M_CODE m;
    if (dofork) {
        if (pipe(fds) == -1) {
            fprintf(stderr, "pipe() failed\n");
            return 1;
        }
        if ((pid = fork()) == -1) {
            close(fds[1]);
            close(fds[0]);
            fprintf(stderr, "fork() failed\n");
            return 1;
        }
    } else
        pid = 0;
    if (pid == 0) { 
        if (dofork)
            close(fds[0]);
        do {
            if ((m = lmc_parse_file(lmc, config)) != M_OK) {
                if (!(err = lmc->last_error)) {
                    snprintf(buf, 255, "error %d while parsing configuration file", m);
                    err = buf;
                }
                break;
            }
            if ((err = init_cb()) != 0)
                break;
            if (group && *group) {
                if (!(g = getgrnam(*group))) {
                    snprintf(buf, 255, "could not get GID for '%s'", *group);
                    err = buf;
                    break;
                }
                if (setgid(g->gr_gid) != 0) {
                    snprintf(buf, 255, "could not change GID: %s",
                            strerror(errno));
                    err = buf;
                    break;
                }
            }
            if (user && *user) {
                if (!(p = getpwnam(*user))) {
                    snprintf(buf, 255, "could not get UID for '%s'", *user);
                    err = buf;
                    break;
                }
                if (setuid(p->pw_uid) != 0) {
                    snprintf(buf, 255, "could not change UID: %s",
                            strerror(errno));
                    err = buf;
                    break;
                }
            }
            if (dofork) {
                c = CHILD_SUCCESS;
                write(fds[1], &c, 1);
                close(fds[1]);
            }
            run_cb();
            exit(0);
        } while (0);
        n = strlen(err);
        if (dofork) {
            if (n > 255) n = 255;
            c = CHILD_FAILURE;
            write(fds[1], &c, 1);
            write(fds[1], err, n);
            close(fds[1]);
        } else 
            fprintf(stderr, "failed: %s\n", err);
        exit(1);
    }
    close(fds[1]);
    if ((n = read(fds[0], &buf, 1)) <= 0)
        fprintf(stderr, "failed: no data from child, possible crash?\n");
    else if (*buf == CHILD_SUCCESS) {
        close(fds[0]);
        return 0;
    } else if (n == 1) {
        if ((n = read(fds[0], &buf, 255)) <= 0)
            fprintf(stderr, "failed: unknown error in child\n");
        else {
            buf[n] = '\0';
            fprintf(stderr, "failed: %s\n", buf);
        }
    }
    close(fds[0]);
    return 1;
}
int nol_daemon_launch ( const char * config , lmc_parser_t * lmc , const char * * user , const char * * group , const char * ( * init_cb ) ( void ) , const char * ( * run_cb ) ( void ) , int dofork ) { pid_t pid ; const char * err ; int fds [ 2 ] ; char buf [ 257 ] ; int n ; char c ; struct group * g ; struct passwd * p ; M_CODE m ; if ( dofork ) { if ( pipe ( fds ) == -1 ) { fprintf ( stderr , " \n " ) ; return 1 ; } if ( ( pid = fork ( ) ) == -1 ) { close ( fds [ 1 ] ) ; close ( fds [ 0 ] ) ; fprintf ( stderr , " \n " ) ; return 1 ; } } else pid = 0 ; if ( pid == 0 ) { if ( dofork ) close ( fds [ 0 ] ) ; do { if ( ( m = lmc_parse_file ( lmc , config ) ) != M_OK ) { if ( ! ( err = lmc -> last_error ) ) { snprintf ( buf , 255 , " " , m ) ; err = buf ; } break ; } if ( ( err = init_cb ( ) ) != 0 ) break ; if ( group && * group ) { if ( ! ( g = getgrnam ( * group ) ) ) { snprintf ( buf , 255 , " " , * group ) ; err = buf ; break ; } if ( setgid ( g -> gr_gid ) != 0 ) { snprintf ( buf , 255 , " " , strerror ( errno ) ) ; err = buf ; break ; } } if ( user && * user ) { if ( ! ( p = getpwnam ( * user ) ) ) { snprintf ( buf , 255 , " " , * user ) ; err = buf ; break ; } if ( setuid ( p -> pw_uid ) != 0 ) { snprintf ( buf , 255 , " " , strerror ( errno ) ) ; err = buf ; break ; } } if ( dofork ) { c = CHILD_SUCCESS ; write ( fds [ 1 ] , & c , 1 ) ; close ( fds [ 1 ] ) ; } run_cb ( ) ; exit ( 0 ) ; } while ( 0 ) ; n = strlen ( err ) ; if ( dofork ) { if ( n > 255 ) n = 255 ; c = CHILD_FAILURE ; write ( fds [ 1 ] , & c , 1 ) ; write ( fds [ 1 ] , err , n ) ; close ( fds [ 1 ] ) ; } else fprintf ( stderr , " \n " , err ) ; exit ( 1 ) ; } close ( fds [ 1 ] ) ; if ( ( n = read ( fds [ 0 ] , & buf , 1 ) ) <= 0 ) fprintf ( stderr , " \n " ) ; else if ( * buf == CHILD_SUCCESS ) { close ( fds [ 0 ] ) ; return 0 ; } else if ( n == 1 ) { if ( ( n = read ( fds [ 0 ] , & buf , 255 ) ) <= 0 ) fprintf ( stderr , " \n " ) ; else { buf [ n ] = ' \0 ' ; fprintf ( stderr , " \n " , buf ) ; } } close ( fds [ 0 ] ) ; return 1 ; }
Function used by mn-masterd, mn-slaved and mb-client.
Function used by mn - masterd mn - slaved and mb - client .
/* set up the pipe so we can communicate with
         * the child process, and keep track of whether
         * it succeeds or not */ /* if we are the child or dofork was set to 0 */ /*close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);*/ /* now we'll configure and write any
             * error message to the pipe */ /* reach here on error */ /* child doesn't reach here */