
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
#include <nginx.h>


typedef struct {
     ngx_flag_t  daemon;
     ngx_flag_t  master;
     ngx_flag_t  worker_reopen;
     uid_t       user;
     gid_t       group;
     ngx_str_t   pid;
     ngx_str_t   newpid;
} ngx_core_conf_t;


typedef struct {
     ngx_file_t    pid;
     char         *name;
     char *const  *argv;
} ngx_master_ctx_t;


static void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx);
static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx);
static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data);
static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle, char **envp);
static ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv);
static ngx_int_t ngx_core_module_init(ngx_cycle_t *cycle);
static char *ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);


static ngx_str_t  core_name = ngx_string("core");

static ngx_command_t  ngx_core_commands[] = {

    { ngx_string("user"),
      NGX_MAIN_CONF|NGX_CONF_TAKE12,
      ngx_set_user,
      0,
      0,
      NULL },

    { ngx_string("daemon"),
      NGX_MAIN_CONF|NGX_CONF_TAKE1,
      ngx_conf_set_core_flag_slot,
      0,
      offsetof(ngx_core_conf_t, daemon),
      NULL },

    { ngx_string("master_process"),
      NGX_MAIN_CONF|NGX_CONF_TAKE1,
      ngx_conf_set_core_flag_slot,
      0,
      offsetof(ngx_core_conf_t, master),
      NULL },

    { ngx_string("worker_reopen"),
      NGX_MAIN_CONF|NGX_CONF_TAKE1,
      ngx_conf_set_core_flag_slot,
      0,
      offsetof(ngx_core_conf_t, worker_reopen),
      NULL },

      ngx_null_command
};


ngx_module_t  ngx_core_module = {
    NGX_MODULE,
    &core_name,                            /* module context */
    ngx_core_commands,                     /* module directives */
    NGX_CORE_MODULE,                       /* module type */
    ngx_core_module_init,                  /* init module */
    NULL                                   /* init child */
};


ngx_int_t   ngx_max_module;
ngx_uint_t  ngx_connection_counter;

ngx_int_t   ngx_process;
ngx_pid_t   ngx_pid;
ngx_pid_t   ngx_new_binary;

ngx_int_t   ngx_inherited;
ngx_int_t   ngx_reap;
ngx_int_t   ngx_timer;
ngx_int_t   ngx_terminate;
ngx_int_t   ngx_quit;
ngx_int_t   ngx_noaccept;
ngx_int_t   ngx_reconfigure;
ngx_int_t   ngx_reopen;
ngx_int_t   ngx_change_binary;


int main(int argc, char *const *argv, char **envp)
{
    ngx_fd_t           fd;
    ngx_int_t          i;
    ngx_log_t         *log;
    ngx_cycle_t       *cycle, init_cycle;
    ngx_open_file_t   *file;
    ngx_core_conf_t   *ccf;
    ngx_master_ctx_t   ctx;
#if !(WIN32)
    size_t             len;
    char               pid[/* STUB */ 10];
#endif

#if __FreeBSD__
    ngx_debug_init();
#endif

    /* TODO */ ngx_max_sockets = -1;

    ngx_time_init();

#if (HAVE_PCRE)
    ngx_regex_init();
#endif

    log = ngx_log_init_errlog();
    ngx_pid = ngx_getpid();

    /* init_cycle->log is required for signal handlers */

    ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
    init_cycle.log = log;
    ngx_cycle = &init_cycle;

    if (ngx_os_init(log) == NGX_ERROR) {
        return 1;
    }

    ngx_max_module = 0;
    for (i = 0; ngx_modules[i]; i++) {
        ngx_modules[i]->index = ngx_max_module++;
    }

    if (!(init_cycle.pool = ngx_create_pool(1024, log))) {
        return 1;
    }

    if (ngx_add_inherited_sockets(&init_cycle, envp) == NGX_ERROR) {
        return 1;
    }

    cycle = ngx_init_cycle(&init_cycle);
    if (cycle == NULL) {
        return 1;
    }

    ngx_cycle = cycle;

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    ngx_process = (ccf->master != 0) ? NGX_PROCESS_MASTER : NGX_PROCESS_SINGLE;

#if (WIN32)

#if 0

    if (run_as_service) {
        if (ngx_servie(cycle->log) == NGX_ERROR) {
            return 1;
        }

        return 0;
    }

#endif

#else

    if (!ngx_inherited && ccf->daemon != 0) {
        if (ngx_daemon(cycle->log) == NGX_ERROR) {
            return 1;
        }
    }

    if (ccf->pid.len == 0) {
        ccf->pid.len = sizeof(NGINX_PID) - 1;
        ccf->pid.data = NGINX_PID;
        ccf->newpid.len = sizeof(NGINX_NEW_PID) - 1;
        ccf->newpid.data = NGINX_NEW_PID;
    }

    len = ngx_snprintf(pid, /* STUB */ 10, PID_T_FMT, ngx_getpid());
    ngx_memzero(&ctx.pid, sizeof(ngx_file_t));
    ctx.pid.name = ngx_inherited ? ccf->newpid : ccf->pid;
    ctx.name = ccf->pid.data;

    ctx.pid.fd = ngx_open_file(ctx.pid.name.data, NGX_FILE_RDWR,
                               NGX_FILE_CREATE_OR_OPEN);

    if (ctx.pid.fd == NGX_INVALID_FILE) {
        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                      ngx_open_file_n " \"%s\" failed", ctx.pid.name.data);
        return 1;
    }

    if (ngx_write_file(&ctx.pid, pid, len, 0) == NGX_ERROR) {
        return 1;
    }

    if (ngx_close_file(ctx.pid.fd) == NGX_FILE_ERROR) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      ngx_close_file_n " \"%s\" failed", ctx.pid.name.data);
    }

#endif

    ctx.argv = argv;

    ngx_master_process_cycle(cycle, &ctx);

    return 0;
}


/* TODO: broken NGX_PROCESS_SINGLE */

static void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx)
{
    int                signo;
    sigset_t           set;
    struct timeval     tv;
    struct itimerval   itv;
    ngx_uint_t         i, live;
    ngx_msec_t         delay;
    ngx_core_conf_t   *ccf;

    sigemptyset(&set);
    sigaddset(&set, SIGCHLD);
    sigaddset(&set, SIGALRM);
    sigaddset(&set, SIGINT);
    sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));

    if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "sigprocmask() failed");
    }

    sigemptyset(&set);

    ngx_setproctitle("master process");

    ngx_new_binary = 0;
    delay = 0;
    signo = 0;
    live = 0;

    for ( ;; ) {
        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "new cycle");

        if (ngx_process == NGX_PROCESS_MASTER) {
            ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL,
                              "worker process", NGX_PROCESS_RESPAWN);

            /*
             * we have to limit the maximum life time of the worker processes
             * by 1 month because our millisecond event timer is limited
             * by 49 days on 32-bit platforms
             */

            itv.it_interval.tv_sec = 0;
            itv.it_interval.tv_usec = 0;
            itv.it_value.tv_sec = 30 * 24 * 60 * 60;
            itv.it_value.tv_usec = 0;

            if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                              "setitimer() failed");
            }

            live = 1;

        } else {
            ngx_init_temp_number();

            for (i = 0; ngx_modules[i]; i++) {
                if (ngx_modules[i]->init_process) {
                    if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
                        /* fatal */
                        exit(1);
                    }
                }
            }
        }

        ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
                                               ngx_core_module);

        /* a cycle with the same configuration because a new one is invalid */

        for ( ;; ) {

            /* an event loop */

            for ( ;; ) {

                if (ngx_process == NGX_PROCESS_MASTER) {
                    if (delay) {
                        delay *= 2;

                        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                                       "temination cycle: %d", delay);

                        itv.it_interval.tv_sec = 0;
                        itv.it_interval.tv_usec = 0;
                        itv.it_value.tv_sec = delay / 1000;
                        itv.it_value.tv_usec = (delay % 1000 ) * 1000;

                        if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
                            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                                          "setitimer() failed");
                        }
                    }

                    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                                   "sigsuspend");

                    sigsuspend(&set);

                    ngx_gettimeofday(&tv);
                    ngx_time_update(tv.tv_sec);

                    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                                   "wake up");

                } else { /* NGX_PROCESS_SINGLE */
                    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                                   "worker cycle");

                    ngx_process_events(cycle->log);
                    live = 0;
                }

                if (ngx_reap) {
                    ngx_reap = 0;
                    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                                   "reap childs");

                    live = 0;
                    for (i = 0; i < ngx_last_process; i++) {

                        ngx_log_debug5(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                                       "child: " PID_T_FMT
                                       " e:%d t:%d d:%d r:%d",
                                       ngx_processes[i].pid,
                                       ngx_processes[i].exiting,
                                       ngx_processes[i].exited,
                                       ngx_processes[i].detached,
                                       ngx_processes[i].respawn);

                        if (ngx_processes[i].exited) {

                            if (ngx_processes[i].respawn
                                && !ngx_processes[i].exiting
                                && !ngx_terminate
                                && !ngx_quit)
                            {
                                 if (ngx_spawn_process(cycle,
                                                       ngx_processes[i].proc,
                                                       ngx_processes[i].data,
                                                       ngx_processes[i].name, i)
                                                                  == NGX_ERROR)
                                 {
                                     ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
                                                   "can not respawn %s",
                                                   ngx_processes[i].name);
                                     continue;
                                 }

                                 live = 1;

                                 continue;
                            }

                            if (ngx_processes[i].pid == ngx_new_binary) {
                                ngx_new_binary = 0;

                                /* TODO: if (ngx_noaccept) ngx_configure = 1 */
                            }

                            if (i != --ngx_last_process) {
                                ngx_processes[i--] =
                                               ngx_processes[ngx_last_process];
                            }

                        } else if (ngx_processes[i].exiting
                                   || !ngx_processes[i].detached)
                        {
                            live = 1;
                        }
                    }
                }

                if (!live && (ngx_terminate || ngx_quit)) {
                    ngx_master_exit(cycle, ctx);
                }

                if (ngx_terminate) {
                    if (delay == 0) {
                        delay = 50;
                    }

                    if (delay > 1000) {
                        signo = SIGKILL;
                    } else {
                        signo = ngx_signal_value(NGX_TERMINATE_SIGNAL);
                    }

                } else if (ngx_quit) {
                    signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL);

                } else if (ngx_timer) {
                    signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL);

                } else {

                    if (ngx_noaccept) {
                        signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL);
                    }

                    if (ngx_change_binary) {
                        ngx_change_binary = 0;
                        ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
                                      "changing binary");
                        ngx_new_binary = ngx_exec_new_binary(cycle, ctx->argv);
                    }

                    if (ngx_reconfigure) {
                        signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL);
                        ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
                                      "reconfiguring");
                    }

                    if (ngx_reopen) {
                        if (ngx_process == NGX_PROCESS_MASTER) {
                            if (ccf->worker_reopen != 0) {
                                signo = ngx_signal_value(NGX_REOPEN_SIGNAL);
                                ngx_reopen = 0;

                            } else if (ngx_noaccept) {
                                ngx_reopen = 0;

                            } else {
                                signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL);
                            }

                        } else { /* NGX_PROCESS_SINGLE */
                            ngx_reopen = 0;
                        }

                        ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
                                      "reopening logs");
                        ngx_reopen_files(cycle,
                             ccf->worker_reopen != 0 ? ccf->user : (uid_t) -1);
                    }
                }

                if (signo) {
                    for (i = 0; i < ngx_last_process; i++) {

                        if (ngx_processes[i].detached) {
                            continue;
                        }

                        ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
                                       "kill (" PID_T_FMT ", %d)" ,
                                       ngx_processes[i].pid, signo);

                        if (kill(ngx_processes[i].pid, signo) == -1) {
                            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                                          "kill(%d, %d) failed",
                                          ngx_processes[i].pid, signo);
                            continue;
                        }

                        if (signo != ngx_signal_value(NGX_REOPEN_SIGNAL)) {
                            ngx_processes[i].exiting = 1;
                        }
                    }

                    signo = 0;
                }

                if (ngx_reopen || ngx_reconfigure || ngx_timer) {
                    break;
                }
            }

            if (ngx_reopen) {
                ngx_reopen = 0;

            } else if (ngx_timer) {
                ngx_timer = 0;

            } else if (ngx_noaccept) {
                ngx_noaccept = 0;
                ngx_reconfigure = 0;

            } else {
                cycle = ngx_init_cycle(cycle);
                if (cycle == NULL) {
                    cycle = (ngx_cycle_t *) ngx_cycle;
                    continue;
                }

                ngx_cycle = cycle;
                ngx_reconfigure = 0;
            }

            break;
        }
    }
}


static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx)
{
    char  *name;

    if (ngx_inherited && getppid() > 1) {
        name = ctx->pid.name.data;

    } else {
        name = ctx->name;
    }

    if (ngx_delete_file(name) == NGX_FILE_ERROR) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      ngx_delete_file_n " \"%s\" failed", name);
    }

    ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exit");
    exit(0);
}


static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
{
    sigset_t          set;
    ngx_int_t         i;
    ngx_listening_t  *ls;
    ngx_core_conf_t  *ccf;

    ngx_process = NGX_PROCESS_WORKER;
    ngx_last_process = 0;

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    if (ccf->group != (gid_t) NGX_CONF_UNSET) {
        if (setuid(ccf->group) == -1) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "setgid(%d) failed", ccf->group);
            /* fatal */
            exit(2);
        }
    }

    if (ccf->user != (uid_t) NGX_CONF_UNSET && geteuid() == 0) {
        if (setuid(ccf->user) == -1) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "setuid(%d) failed", ccf->user);
            /* fatal */
            exit(2);
        }
    }

#if (HAVE_PR_SET_DUMPABLE)

    /* allow coredump after setuid() in Linux 2.4.x */

    if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "prctl(PR_SET_DUMPABLE) failed");
    }

#endif

    sigemptyset(&set);

    if (sigprocmask(SIG_SETMASK, &set, NULL) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "sigprocmask() failed");
    }

    ngx_init_temp_number();

    /*
     * disable deleting previous events for the listening sockets because
     * in the worker processes there are no events at all at this point
     */ 
    ls = cycle->listening.elts;
    for (i = 0; i < cycle->listening.nelts; i++) {
        ls[i].remain = 0;
    }

    for (i = 0; ngx_modules[i]; i++) {
        if (ngx_modules[i]->init_process) {
            if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
                /* fatal */
                exit(1);
            }
        }
    }

    ngx_setproctitle("worker process");

    /* TODO: threads: start ngx_worker_thread_cycle() */

    for ( ;; ) {
        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");

        ngx_process_events(cycle->log);

        if (ngx_terminate) {
            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting");
            exit(0);
        }

        if (ngx_quit) {
            ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
                          "gracefully shutting down");
            ngx_setproctitle("worker process is shutting down");
            break;
        }

        if (ngx_reopen) {
            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopen logs");
            ngx_reopen_files(cycle, -1);
            ngx_reopen = 0;
        }
    }

    ngx_close_listening_sockets(cycle);

    for ( ;; ) {
        if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) {
            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting");
            exit(0);
        }

        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");

        ngx_process_events(cycle->log);

        if (ngx_reopen) {
            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopen logs");
            ngx_reopen_files(cycle, -1);
            ngx_reopen = 0;
        }
    }
}


static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle, char **envp)
{
    char                *p, *v;
    ngx_socket_t         s;
    ngx_listening_t     *ls;

    for ( /* void */ ; *envp; envp++) {
        if (ngx_strncmp(*envp, NGINX_VAR, NGINX_VAR_LEN) != 0) {
            continue;
        }

        ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
                      "using inherited sockets from \"%s\"", *envp);

        ngx_init_array(cycle->listening, cycle->pool,
                       10, sizeof(ngx_listening_t), NGX_ERROR);

        for (p = *envp + NGINX_VAR_LEN, v = p; *p; p++) {
            if (*p == ':' || *p == ';') {
                s = ngx_atoi(v, p - v);
                if (s == NGX_ERROR) {
                    ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                                  "invalid socket number \"%s\" "
                                  "in NGINX enviroment variable, "
                                  "ignoring the rest of the variable", v);
                    break;
                }
                v = p + 1;

                if (!(ls = ngx_push_array(&cycle->listening))) {
                    return NGX_ERROR;
                }

                ls->fd = s;
            }
        }

        ngx_inherited = 1;

        return ngx_set_inherited_sockets(cycle);
    }

    return NGX_OK;
}


static ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
{
    char             *env[2], *var, *p;
    ngx_int_t         i;
    ngx_pid_t         pid;
    ngx_exec_ctx_t    ctx;
    ngx_listening_t  *ls;

    ctx.path = argv[0];
    ctx.name = "new binary process";
    ctx.argv = argv;

    var = ngx_alloc(NGINX_VAR_LEN
                            + cycle->listening.nelts * (NGX_INT32_LEN + 1) + 1,
                    cycle->log);

    p = ngx_cpymem(var, NGINX_VAR, NGINX_VAR_LEN);

    ls = cycle->listening.elts;
    for (i = 0; i < cycle->listening.nelts; i++) {
        p += ngx_snprintf(p, NGX_INT32_LEN + 2, "%u;", ls[i].fd);
    }

    env[0] = var;
    env[1] = NULL;
    ctx.envp = (char *const *) &env;

    pid = ngx_exec(cycle, &ctx);

    ngx_free(var);

    return pid;
}


static ngx_int_t ngx_core_module_init(ngx_cycle_t *cycle)
{
    ngx_core_conf_t  *ccf;

    /*
     * ngx_core_module has a special init procedure: it is called by
     * ngx_init_cycle() before the configuration file parsing to create
     * ngx_core_module configuration and to set its default parameters
     */

    if (((void **)(cycle->conf_ctx))[ngx_core_module.index] != NULL) {
        return NGX_OK;
    }

    if (!(ccf = ngx_pcalloc(cycle->pool, sizeof(ngx_core_conf_t)))) {
        return NGX_ERROR;
    }
    /* set by pcalloc()
     *
     * ccf->pid = NULL;
     */
    ccf->daemon = NGX_CONF_UNSET;
    ccf->master = NGX_CONF_UNSET;
    ccf->worker_reopen = NGX_CONF_UNSET;
    ccf->user = (uid_t) NGX_CONF_UNSET;
    ccf->group = (gid_t) NGX_CONF_UNSET;

    ((void **)(cycle->conf_ctx))[ngx_core_module.index] = ccf;

    return NGX_OK;
}


static char *ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    struct passwd    *pwd;
    struct group     *grp;
    ngx_str_t        *value;
    ngx_core_conf_t  *ccf;

    ccf = *(void **)conf;

    if (ccf->user != (uid_t) NGX_CONF_UNSET) {
        return "is duplicate";
    }

    value = (ngx_str_t *) cf->args->elts;

    pwd = getpwnam(value[1].data);
    if (pwd == NULL) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
                           "getpwnam(%s) failed", value[1].data);
        return NGX_CONF_ERROR;
    }

    ccf->user = pwd->pw_uid;

    if (cf->args->nelts == 2) {
        return NGX_CONF_OK;
    }

    grp = getgrnam(value[2].data);
    if (grp == NULL) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
                           "getgrnam(%s) failed", value[1].data);
        return NGX_CONF_ERROR;
    }

    ccf->group = grp->gr_gid;

    return NGX_CONF_OK;
}
