void param_state_multipartite_mixed::initialize ( int n, int* subs, int d )
    {
    nr_mixtures = d;
    nr_subspaces = n ;
    subspaces = new int[n] {};
    dim = 1;
    nr_parameters=0;
    for ( int i = 0; i < n ; i++ )
        {
        nr_parameters += subs[i]*subs[i]+abs ( subs[i] )-1;
        dim *= abs ( subs[i] );
        subspaces[i] = abs ( subs[i] );
        }

    nr_parameters *=nr_mixtures;
    nr_parameters += d-1;

    product_states = new param_state_multipartite[d] {};

    for ( int i = 0; i < d ; i++ )
        {
        product_states[i].initialize ( n , subs );
        }

    parameters = new double [nr_parameters] {};
    par_max = new double [nr_parameters] {};
    par_min = new double [nr_parameters] {};
    representation = new std::complex< double > [dim*dim] {};
    temp1 = new std::complex< double > [dim*dim] {};
    buffer = new std::complex< double > [dim*dim] {};
    simplectic_prob = new double [d] {};
    theta_simplex = new double [d-1] {};
    set_limits();

    }
示例#2
0
void RelocIterator::initialize(intptr_t delta, CodeBlob* cb, address begin, address limit) {
#ifndef CORE  
  if (cb == NULL && delta == 0 && begin != NULL) {
    // allow CodeBlob to be deduced from beginning address
    cb = CodeCache::find_blob(begin);
  }
  assert(cb != NULL, "must be able to deduce nmethod from other arguments");

  _code    = cb;
  _current = cb->relocation_begin()-1;
  _end     = cb->relocation_end();
  _addr    = (address) cb->instructions_begin();

  assert(!has_current(), "just checking");  
  address code_end = cb->instructions_end();

  assert(begin == NULL || begin >= delta + cb->instructions_begin(), "in bounds");
 // FIX THIS  assert(limit == NULL || limit <= delta + code_end,                 "in bounds");
  if (begin != NULL)  begin -= delta;
  if (limit != NULL)  limit -= delta;
  set_limits(begin, limit);

  // after limits have been set and indexes consulted, then apply the delta
  if (delta == 0) {
    _is_copy = false;
  } else {
    _is_copy = true;
    _addr  += delta;		// we are operating on a copy of the code
    _limit += delta;
  }
#endif // !CORE
}
void param_state_multipartite::initialize ( int n, int* subs )
    {

    nr_subspaces = n ;
    subspaces = new int[n] {};
    dim = 1;
    for ( int i = 0; i < n ; i++ )
        {
        nr_parameters += subs[i]*subs[i]+abs ( subs[i] )-1;
        dim *= abs ( subs[i] );
        subspaces[i] = abs ( subs[i] );
        }


    states = new param_state[n] {};
    for ( int i = 0; i < n ; i++ )
        {
        states[i].initialize ( abs ( subs[i] ) );
        }

    parameters = new double [nr_parameters] {};
    par_max = new double [nr_parameters] {};
    par_min = new double [nr_parameters] {};
    representation = new std::complex< double > [dim*dim] {};
    temp1 = new std::complex< double > [dim*dim] {};
    buffer = new std::complex< double > [dim*dim] {};
    set_limits();

    }
示例#4
0
void
initialize()
{
	set_limits();
	initialize_velocities();
	randomize_particles();
	initialize_pbest();
	intialize_gbest();
}
示例#5
0
文件: Draw.hpp 项目: spott/petsc-cpp
 Draw( double xmin,
       double xmax,
       double ymin,
       double ymax,
       unsigned dim_ = 2,
       const MPI_Comm comm = PETSC_COMM_WORLD )
     : Draw( dim_, comm )
 {
     set_limits( xmin, xmax, ymin, ymax );
 }
示例#6
0
RelocIterator::RelocIterator(CodeBuffer* cb, address begin, address limit) {
#ifndef CORE
  _current = cb->locs_start()-1;
  _end     = cb->locs_end();
  _addr    = (address) cb->code_begin();
  _code    = cb->get_blob();

  assert(!has_current(), "just checking");

  assert(begin == NULL || begin >= cb->code_begin(), "in bounds");
  assert(limit == NULL || limit <= cb->code_end(),   "in bounds");
  set_limits(begin, limit);
#endif // !CORE
}
void param_state::initialize ( int n )

    {
    dim = n ;
    nr_parameters = n*n+n-1;
    parameters = new double[nr_parameters] {};
    representation = new std::complex< double >[n*n] {};
    temp1 = new std::complex< double >[n*n] {};
    simplex_angles = new double [n-1] {};
    eigen = new std::complex< double >[n] {};
    par_max = new double [nr_parameters] {};
    par_min = new double [nr_parameters] {};
    UN.initialize ( n );
    set_limits();

    }
示例#8
0
int
main(int argc, char **argv) {
    const char *config_file = "/etc/sniproxy.conf";
    int background_flag = 1;
    int max_nofiles = 65536;
    int opt;

    while ((opt = getopt(argc, argv, "fc:n:V")) != -1) {
        switch (opt) {
            case 'c':
                config_file = optarg;
                break;
            case 'f': /* foreground */
                background_flag = 0;
                break;
            case 'n':
                max_nofiles = atoi(optarg);
                break;
            case 'V':
                printf("sniproxy %s\n", sniproxy_version);
#ifdef HAVE_LIBUDNS
                printf("compiled with udns support\n");
#endif
                return EXIT_SUCCESS;
            default:
                usage();
                return EXIT_FAILURE;
        }
    }

    config = init_config(config_file, EV_DEFAULT);
    if (config == NULL) {
        fprintf(stderr, "Unable to load %s\n", config_file);
        usage();
        return EXIT_FAILURE;
    }

    /* ignore SIGPIPE, or it will kill us */
    signal(SIGPIPE, SIG_IGN);

    if (background_flag) {
        if (config->pidfile != NULL)
            remove(config->pidfile);

        daemonize();


        if (config->pidfile != NULL)
            write_pidfile(config->pidfile, getpid());
    }

    start_binder();

    set_limits(max_nofiles);

    init_listeners(&config->listeners, &config->tables, EV_DEFAULT);

    /* Drop permissions only when we can */
    drop_perms(config->user ? config->user : default_username);

    ev_signal_init(&sighup_watcher, signal_cb, SIGHUP);
    ev_signal_init(&sigusr1_watcher, signal_cb, SIGUSR1);
    ev_signal_init(&sigusr2_watcher, signal_cb, SIGUSR2);
    ev_signal_init(&sigint_watcher, signal_cb, SIGINT);
    ev_signal_init(&sigterm_watcher, signal_cb, SIGTERM);
    ev_signal_start(EV_DEFAULT, &sighup_watcher);
    ev_signal_start(EV_DEFAULT, &sigusr1_watcher);
    ev_signal_start(EV_DEFAULT, &sigusr2_watcher);
    ev_signal_start(EV_DEFAULT, &sigint_watcher);
    ev_signal_start(EV_DEFAULT, &sigterm_watcher);

    resolv_init(EV_DEFAULT, config->resolver.nameservers,
            config->resolver.search, config->resolver.mode);

    init_connections();

    ev_run(EV_DEFAULT, 0);

    free_connections(EV_DEFAULT);
    resolv_shutdown(EV_DEFAULT);

    free_config(config, EV_DEFAULT);

    stop_binder();

    return 0;
}
示例#9
0
    // this function must be invoked by forked process
    void execute_command_in_jail(
        fs::path const& host_container_dir,
        container_options_t const& opts,
        linux::user const& user
        )
    {
        // create virtual root for container
        construct_virtual_root(
            host_container_dir,
            opts.mount_points,
            opts.copy_points,
            user
            );

        // into jail
        if ( ::chroot( host_container_dir.c_str() ) == -1 ) {
            std::stringstream ss;
            ss << "Failed to chroot: "
               << " errno=" << errno << " : " << std::strerror( errno );
            throw std::runtime_error( ss.str() );
        }

        // move to home
        fs::current_path( opts.in_container_start_path );

        // set limits
        set_limits( opts.limits );
        set_limit( RLIMIT_STACK, opts.stack_size );

        // overwrite host $PATH environment, to search an executable by execpve
        overwrite_path( opts.envs );
        auto const& path = ::getenv( "PATH" );
        if ( path != nullptr ) {
            std::cout << " = env PATH is " << path << std::endl;
        }

        // log
        std::cout << "[+] chrooted and resource limited!" << std::endl;

        // TODO: set umask

        // std::system("ls -la /proc/self/fd");

        // redirect: pipes[debug]
        for( auto const& pr : opts.pipe_redirects ) {
            std::cout << "==> host fd: " << pr.host_fd
                      << " will recieve data of child fd: " << pr.guest_fd
                      << std::endl;
        }

        // redirect: pipes
        for( auto const& pr : opts.pipe_redirects ) {
            if ( ::dup2( pr.host_fd, pr.guest_fd ) == -1 ) {
                std::stringstream ss;
                ss << "Failed to dup2: "
                   << " errno=" << errno << " : " << std::strerror( errno );
                throw std::runtime_error( ss.str() );
            }

            if ( ::close( pr.host_fd ) == -1 ) {
                std::stringstream ss;
                ss << "Failed to close the host pipe: "
                   << " errno=" << errno << " : " << std::strerror( errno );
                throw std::runtime_error( ss.str() );
            }
        }

        // === discard privilege
        // remove supplementary groups
        const gid_t s_groups[] = {};
        if ( ::setgroups( 0, s_groups ) == -1 ) {
            std::stringstream ss;
            ss << "Failed to setgroups: "
               << " errno=" << errno << " : " << std::strerror( errno );
            throw std::runtime_error( ss.str() );
        }

        // change group
        if ( ::setresgid( user.group_id(), user.group_id(), user.group_id() ) == -1 ) {
            std::stringstream ss;
            ss << "Failed to setresgid: "
               << " errno=" << errno << " : " << std::strerror( errno );
            throw std::runtime_error( ss.str() );
        }

        // change user
        if ( ::setresuid( user.user_id(), user.user_id(), user.user_id() ) == -1 ) {
            std::stringstream ss;
            ss << "Failed to setresuid: "
               << " errno=" << errno << " : " << std::strerror( errno );
            throw std::runtime_error( ss.str() );
        }
        // ===

        // ==
        // now I am in the sandbox!
        // ==
        if ( opts.commands.size() < 1 ) {
            std::stringstream ss;
            ss << "Failed to prepare environment: commands must have >= 1 elements (" << opts.commands.size() << ")";
            throw std::runtime_error( ss.str() );
        }

        auto const& filename = opts.commands[0];

        auto argv_pack = make_buffer_for_execve( opts.commands );
        auto& argv = std::get<0>( argv_pack );

        auto envp_pack = make_buffer_for_execve( opts.envs );
        auto& envp = std::get<0>( envp_pack );

        // replace self process
        if ( ::execvpe( filename.c_str(), argv.data(), envp.data() ) == -1 ) {
            std::stringstream ss;
            ss << "Failed to execvpe: "
               << " errno=" << errno << " : " << std::strerror( errno );
            throw std::runtime_error( ss.str() );
        }
    }
示例#10
0
int
main(int argc, char **argv)
#endif	/* WIN32 */
{
#ifdef	WIN32
	struct arg_param *p = (struct arg_param *)pv;
	int      		argc;
	char			**argv;
	SERVICE_STATUS          ss;
#endif	/* WIN32 */
	char *name = NULL;
	struct tpp_config conf;
	int rpp_fd;
	char *pc;
	int numthreads;
	char lockfile[MAXPATHLEN + 1];
	char path_log[MAXPATHLEN + 1];
	char svr_home[MAXPATHLEN + 1];
	char *log_file = 0;
	char *host;
	int port;
	char *routers = NULL;
	int c, i, rc;
	extern char *optarg;
	int	are_primary;
	int	num_var_env;
#ifndef WIN32
	struct sigaction act;
	struct sigaction oact;
#endif

#ifndef WIN32
	/*the real deal or just pbs_version and exit*/

	execution_mode(argc, argv);
#endif

	/* As a security measure and to make sure all file descriptors	*/
	/* are available to us,  close all above stderr			*/
#ifdef WIN32
	_fcloseall();
#else
	i = sysconf(_SC_OPEN_MAX);
	while (--i > 2)
		(void)close(i); /* close any file desc left open by parent */
#endif

	/* If we are not run with real and effective uid of 0, forget it */
#ifdef WIN32
	argc = p->argc;
	argv = p->argv;

	ZeroMemory(&ss, sizeof(ss));
	ss.dwCheckPoint = 0;
	ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
	ss.dwCurrentState = g_dwCurrentState;
	ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
	ss.dwWaitHint = 6000;

	if (g_ssHandle != 0)
		SetServiceStatus(g_ssHandle, &ss);

	if (!isAdminPrivilege(getlogin())) {
		fprintf(stderr, "%s: Must be run by root\n", argv[0]);
		return (2);
	}

#else
	if ((getuid() != 0) || (geteuid() != 0)) {
		fprintf(stderr, "%s: Must be run by root\n", argv[0]);
		return (2);
	}
#endif	/* WIN32 */

	/* set standard umask */
#ifndef WIN32
	umask(022);
#endif

	/* load the pbs conf file */
	if (pbs_loadconf(0) == 0) {
		fprintf(stderr, "%s: Configuration error\n", argv[0]);
		return (1);
	}

	umask(022);

#ifdef	WIN32
	save_env();
#endif
	/* The following is code to reduce security risks                */
	/* start out with standard umask, system resource limit infinite */
	if ((num_var_env = setup_env(pbs_conf.pbs_environment)) == -1) {
#ifdef	WIN32
		g_dwCurrentState = SERVICE_STOPPED;
		ss.dwCurrentState = g_dwCurrentState;
		ss.dwWin32ExitCode = ERROR_INVALID_ENVIRONMENT;
		if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss);
		return (1);
#else
		exit(1);
#endif	/* WIN32 */
	}

#ifndef WIN32
	i = getgid();
	(void)setgroups(1, (gid_t *)&i);	/* secure suppl. groups */
#endif

	log_event_mask = &pbs_conf.pbs_comm_log_events;
	tpp_set_logmask(*log_event_mask);

#ifdef WIN32
	winsock_init();
#endif

	routers = pbs_conf.pbs_comm_routers;
	numthreads = pbs_conf.pbs_comm_threads;

	server_host[0] = '\0';
	if (pbs_conf.pbs_comm_name) {
		name = pbs_conf.pbs_comm_name;
		host = tpp_parse_hostname(name, &port);
		if (host)
			snprintf(server_host, sizeof(server_host), "%s", host);
		free(host);
		host = NULL;
	} else if (pbs_conf.pbs_leaf_name) {
		char *endp;

		snprintf(server_host, sizeof(server_host), "%s", pbs_conf.pbs_leaf_name);
		endp = strchr(server_host, ','); /* find the first name */
		if (endp)
			*endp = '\0';
		endp = strchr(server_host, ':'); /* cut out the port */
		if (endp)
			*endp = '\0';
		name = server_host;
	} else {
		if (gethostname(server_host, (sizeof(server_host) - 1)) == -1) {
#ifndef WIN32
			sprintf(log_buffer, "Could not determine my hostname, errno=%d", errno);
#else
			sprintf(log_buffer, "Could not determine my hostname, errno=%d", WSAGetLastError());
#endif
			fprintf(stderr, "%s\n", log_buffer);
			return (1);
		}
		if ((get_fullhostname(server_host, server_host, (sizeof(server_host) - 1)) == -1)) {
			sprintf(log_buffer, "Could not determine my hostname");
			fprintf(stderr, "%s\n", log_buffer);
			return (1);
		}
		name = server_host;
	}
	if (server_host[0] == '\0') {
		sprintf(log_buffer, "Could not determine server host");
		fprintf(stderr, "%s\n", log_buffer);
		return (1);
	}

	while ((c = getopt(argc, argv, "r:t:e:N")) != -1) {
		switch (c) {
			case 'e': *log_event_mask = strtol(optarg, NULL, 0);
				break;
			case 'r':
				routers = optarg;
				break;
			case 't':
				numthreads = atol(optarg);
				if (numthreads == -1) {
					usage(argv[0]);
					return (1);
				}
				break;
			case 'N':
				stalone = 1;
				break;
			default:
				usage(argv[0]);
				return (1);
		}
	}

	(void)strcpy(daemonname, "Comm@");
	(void)strcat(daemonname, name);
	if ((pc = strchr(daemonname, (int)'.')) != NULL)
		*pc = '\0';

	if(set_msgdaemonname(daemonname)) {
		fprintf(stderr, "Out of memory\n");
		return 1;
	}

	(void) snprintf(path_log, sizeof(path_log), "%s/%s", pbs_conf.pbs_home_path, PBS_COMM_LOGDIR);
#ifdef WIN32
	/*
	 * let SCM wait 10 seconds for log_open() to complete
	 * as it does network interface query which can take time
	 */

	ss.dwCheckPoint++;
	ss.dwWaitHint = 60000;
	if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss);
#endif
	(void) log_open(log_file, path_log);

	/* set pbs_comm's process limits */
	set_limits(); /* set_limits can call log_record, so call only after opening log file */

	/* set tcp function pointers */
	set_tpp_funcs(log_tppmsg);

	(void) snprintf(svr_home, sizeof(svr_home), "%s/%s", pbs_conf.pbs_home_path, PBS_SVR_PRIVATE);
	if (chdir(svr_home) != 0) {
		(void) sprintf(log_buffer, msg_init_chdir, svr_home);
		log_err(-1, __func__, log_buffer);
		return (1);
	}

	(void) sprintf(lockfile, "%s/%s/comm.lock", pbs_conf.pbs_home_path, PBS_SVR_PRIVATE);
	if ((are_primary = are_we_primary()) == FAILOVER_SECONDARY) {
		strcat(lockfile, ".secondary");
	} else if (are_primary == FAILOVER_CONFIG_ERROR) {
		sprintf(log_buffer, "Failover configuration error");
		log_err(-1, __func__, log_buffer);
#ifdef WIN32
		g_dwCurrentState = SERVICE_STOPPED;
		ss.dwCurrentState = g_dwCurrentState;
		ss.dwWin32ExitCode = ERROR_SERVICE_NOT_ACTIVE;
		if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss);
#endif
		return (3);
	}

	if ((lockfds = open(lockfile, O_CREAT | O_WRONLY, 0600)) < 0) {
		(void) sprintf(log_buffer, "pbs_comm: unable to open lock file");
		log_err(errno, __func__, log_buffer);
		return (1);
	}

	if ((host = tpp_parse_hostname(name, &port)) == NULL) {
		sprintf(log_buffer, "Out of memory parsing leaf name");
		log_err(errno, __func__, log_buffer);
		return (1);
	}

	rc = 0;
	if (pbs_conf.auth_method == AUTH_RESV_PORT) {
		rc = set_tpp_config(&pbs_conf, &conf, host, port, routers, pbs_conf.pbs_use_compression,
				TPP_AUTH_RESV_PORT, NULL, NULL);
	} else {
		/* for all non-resv-port based authentication use a callback from TPP */
		rc = set_tpp_config(&pbs_conf, &conf, host, port, routers, pbs_conf.pbs_use_compression,
				TPP_AUTH_EXTERNAL, get_ext_auth_data, validate_ext_auth_data);
	}
	if (rc == -1) {
		(void) sprintf(log_buffer, "Error setting TPP config");
		log_err(-1, __func__, log_buffer);
		return (1);
	}
	free(host);

	i = 0;
	if (conf.routers) {
		while (conf.routers[i]) {
			sprintf(log_buffer, "Router[%d]:%s", i, conf.routers[i]);
			fprintf(stdout, "%s\n", log_buffer);
			log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_INFO, msg_daemonname, log_buffer);
			i++;
		}
	}

#ifndef DEBUG
#ifndef WIN32
	if (stalone != 1)
		go_to_background();
#endif
#endif


#ifdef WIN32
	ss.dwCheckPoint = 0;
	g_dwCurrentState = SERVICE_RUNNING;
	ss.dwCurrentState = g_dwCurrentState;
	if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss);
#endif

	if (already_forked == 0)
		lock_out(lockfds, F_WRLCK);

	/* go_to_backgroud call creates a forked process,
	 * thus print/log pid only after go_to_background()
	 * has been called
	 */
	sprintf(log_buffer, "%s ready (pid=%d), Proxy Name:%s, Threads:%d", argv[0], getpid(), conf.node_name, numthreads);
	fprintf(stdout, "%s\n", log_buffer);
	log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_INFO, msg_daemonname, log_buffer);

#ifndef DEBUG
	pbs_close_stdfiles();
#endif

#ifdef WIN32
	signal(SIGINT, stop_me);
	signal(SIGTERM, stop_me);
#else
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	act.sa_handler = hup_me;
	if (sigaction(SIGHUP, &act, &oact) != 0) {
		log_err(errno, __func__, "sigaction for HUP");
		return (2);
	}
	act.sa_handler = stop_me;
	if (sigaction(SIGINT, &act, &oact) != 0) {
		log_err(errno, __func__, "sigaction for INT");
		return (2);
	}
	if (sigaction(SIGTERM, &act, &oact) != 0) {
		log_err(errno, __func__, "sigactin for TERM");
		return (2);
	}
	if (sigaction(SIGQUIT, &act, &oact) != 0) {
		log_err(errno, __func__, "sigactin for QUIT");
		return (2);
	}
#ifdef SIGSHUTDN
	if (sigaction(SIGSHUTDN, &act, &oact) != 0) {
		log_err(errno, __func__, "sigactin for SHUTDN");
		return (2);
	}
#endif	/* SIGSHUTDN */

	act.sa_handler = SIG_IGN;
	if (sigaction(SIGPIPE, &act, &oact) != 0) {
		log_err(errno, __func__, "sigaction for PIPE");
		return (2);
	}
	if (sigaction(SIGUSR1, &act, &oact) != 0) {
		log_err(errno, __func__, "sigaction for USR1");
		return (2);
	}
	if (sigaction(SIGUSR2, &act, &oact) != 0) {
		log_err(errno, __func__, "sigaction for USR2");
		return (2);
	}
#endif 	/* WIN32 */

	conf.node_type = TPP_ROUTER_NODE;
	conf.numthreads = numthreads;

	if ((rpp_fd = tpp_init_router(&conf)) == -1) {
		log_err(-1, __func__, "tpp init failed\n");
		return 1;
	}

	/* Protect from being killed by kernel */
	daemon_protect(0, PBS_DAEMON_PROTECT_ON);

	/* go in a while loop */
	while (get_out == 0) {

		if (hupped == 1) {
			struct pbs_config pbs_conf_bak;
			int new_logevent;

			hupped = 0; /* reset back */
			memcpy(&pbs_conf_bak, &pbs_conf, sizeof(struct pbs_config));

			if (pbs_loadconf(1) == 0) {
				log_tppmsg(LOG_CRIT, NULL, "Configuration error, ignoring");
				memcpy(&pbs_conf, &pbs_conf_bak, sizeof(struct pbs_config));
			} else {
				/* restore old pbs.conf */
				new_logevent = pbs_conf.pbs_comm_log_events;
				memcpy(&pbs_conf, &pbs_conf_bak, sizeof(struct pbs_config));
				pbs_conf.pbs_comm_log_events = new_logevent;
				log_tppmsg(LOG_INFO, NULL, "Processed SIGHUP");

				log_event_mask = &pbs_conf.pbs_comm_log_events;
				tpp_set_logmask(*log_event_mask);
			}
		}

		sleep(3);
	}

	tpp_router_shutdown();

	log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_NOTICE, msg_daemonname, "Exiting");
	log_close(1);

	lock_out(lockfds, F_UNLCK);	/* unlock  */
	(void)close(lockfds);
	(void)unlink(lockfile);

	return 0;
}
示例#11
0
文件: chressh.c 项目: surjit/chroot
int
main(const int argc, char * const argv[])
/*@globals environ, errno@*/
/*@modifies environ, errno@*/
{
    struct passwd *pw;
    char **target_env = environ;
    static char *empty_env[] = { NULL };
    environ = empty_env;
    (void) umask(~(mode_t)0);  /* (no file perms, if signalled to dump core)*/

    /* check that calling UID exists, is not root, and shell matches */
    if (NULL != (pw = getpwuid(getuid()))
	&& 0 != pw->pw_uid
	&& 0 == memcmp(pw->pw_shell,CHROOTING_SHELL,sizeof(CHROOTING_SHELL)) ) {

	/* require commands of the form: "sh" "-c" "command args args args" */
	if (3 == argc && 0 == memcmp(argv[1], "-c", 3)) {
	    const char *chroot_dir = (const char *)pw->pw_dir;
	    const char *home = "/";
	    struct stat st;
	    if (0 == memcmp(pw->pw_dir, GROUP_CHROOT_DIR,
			    sizeof(GROUP_CHROOT_DIR)-1)
		&& getgroups(0, (gid_t *)NULL) > 1) {
		chroot_dir = GROUP_CHROOT_DIR;
		home = (const char *)pw->pw_dir+(sizeof(GROUP_CHROOT_DIR)-2);
		if (*home != '/' && *++home != '/') {
		    home = "/";
		}
	    }
	    if (!(   0 == stat(chroot_dir, &st)
		  && pw->pw_uid != st.st_uid  /* (not caller; typically root) */
		  && 0 == (st.st_mode & (S_IWGRP|S_IWOTH)))) {
		fatal(argc, pw, chroot_dir);
	    }
	    openlog("chressh", LOG_NDELAY|LOG_PID, LOG_AUTHPRIV);
	    if (/*@-superuser@*/
		   0 == chroot(chroot_dir)
		/*@=superuser@*/
		&& 0 == setuid(getuid())
		&& 0 != setuid(0)
		&& 0 == chdir(home)) {

		char **target_argv;
		size_t len;
		errno = 0;  /* (reset errno after expected setuid(0) failure) */

		environ = target_env = env_clean(target_env, pw, home);
		target_argv = shell_parse(argv[2]);
		if (NULL == target_argv || NULL == target_argv[0]) {
		    fatal(argc, pw, NULL);
		}
		(void) umask((mode_t)UMASK);

		if (0 == strcmp(target_argv[0], "scp")) {
		    if (0 == set_limits(NPROC_SCP)) {
			(void) execve(CHROOTED_CMD_DIR "scp",
				      target_argv, target_env);
		    }
		}
		else if (0 == strcmp(target_argv[0], "rsync")) {
		    if (0 == filter_args_rsync(target_argv)
			&& 0 == set_limits(NPROC_RSYNC)) {
			(void) execve(CHROOTED_CMD_DIR "rsync",
				      target_argv, target_env);
		    }
		}
		else if (0 == strcmp(target_argv[0], "unison")) {
		    if (0 == filter_args_unison(target_argv)
			&& 0 == set_limits(NPROC_UNISON)) {
			(void) execve(CHROOTED_CMD_DIR "unison",
				      target_argv, target_env);
		    }
		}
		else {
		    if (  11 <= (len = strlen(target_argv[0]))
			&& 0 == memcmp(target_argv[0]+len-11, "sftp-server", 11)
			&& 0 == set_limits(NPROC_SFTP_SERVER)) {
			/*('chressh -c /usr/local/libexec/sftp-server')*/
			/*(only tests for "sftp-server" suffix, which is fine)*/
			/*(discard additional args to sftp-server, if present)*/
			char sftp_server[] = "sftp-server";
			char *target_argv_static[] = { sftp_server, NULL };
			(void) execve(CHROOTED_CMD_DIR "sftp-server",
				      target_argv_static, target_env);
		    }
		}


#if 0  /* which code do you think is clearer?  above or below? */

		switch ((len = strlen(target_argv[0]))) {
		  case  3:
		    if (0 == memcmp(target_argv[0], "scp", 3)
			&& 0 == set_limits(NPROC_SCP)) {
			(void) execve(CHROOTED_CMD_DIR "scp",
				      target_argv, target_env);
		    }
		    break;
		  case  5:
		    if (0 == memcmp(target_argv[0], "rsync", 5)
			&& 0 == filter_args_rsync(target_argv)
			&& 0 == set_limits(NPROC_RSYNC)) {
			(void) execve(CHROOTED_CMD_DIR "rsync",
				      target_argv, target_env);
		    }
		    break;
		  case  6:
		    if (0 == memcmp(target_argv[0], "unison", 6)
			&& 0 == filter_args_unison(target_argv)
			&& 0 == set_limits(NPROC_UNISON)) {
			(void) execve(CHROOTED_CMD_DIR "unison",
				      target_argv, target_env);
		    }
		    break;
		  default:
		    if (  11 <= len
			&& 0 == memcmp(target_argv[0]+len-11, "sftp-server", 11)
			&& 0 == set_limits(NPROC_SFTP_SERVER)) {
			/*('chressh -c /usr/local/libexec/sftp-server')*/
			/*(only tests for "sftp-server" suffix, which is fine)*/
			/*(discard additional args to sftp-server, if present)*/
			char sftp_server[] = "sftp-server";
			char *target_argv_static[] = { sftp_server, NULL };
			(void) execve(CHROOTED_CMD_DIR "sftp-server",
				      target_argv_static, target_env);
		    }
		    break;
		}
#endif


	    }
	}

      #ifdef PASSWD_PROGRAM
	/* If login attempt (argc == 1), use PASSWD_PROGRAM as 'shell'
	 * (*argv[0] == '-', too, for login shells on most (all?) systems)
	 * (privileges intentionally dropped even if passwd_program setuid)
	 */
	else if (1 == argc && 0 == setuid(getuid()) && 0 != setuid(0)) {
	    char passwd_program[] = PASSWD_PROGRAM;
	    char *target_argv[] = { passwd_program, NULL };
	    errno = 0;  /* (reset errno after expected setuid(0) failure) */
	    target_env = env_clean(target_env, pw, NULL);
	    (void) execve(PASSWD_PROGRAM, target_argv, target_env);
	}
      #endif

    }

    fatal(argc, pw, NULL);
    return 0; /*(UNREACHED)*/
}