Exemplo n.º 1
0
static void setup_signals()
{
        /* signal mask define */
        sigemptyset(&sigmask);
        sigaddset(&sigmask, SIGTERM);
        sigaddset(&sigmask, SIGUSR1);
        sigaddset(&sigmask, SIGUSR2);

	/* setup signal handler */
	signal_setup(SIGTERM, lm_dataout_sighand);
	signal_setup(SIGUSR1, lm_last_sighand);
	signal_setup(SIGUSR2, lm_start_sighand);
}
Exemplo n.º 2
0
Arquivo: main.c Projeto: viettd56/SA
void init(char *name, char *pass, int port)
{
    signal_setup();
    memset(&config, 0, sizeof(config));

    // set defaults
    config.buffer_start_fill = 220;
    config.port = port;
    config.password = pass;
    config.apname = name;
    if (config.daemonise)
    {
        daemon_init();
    }

    log_setup();
    config.output = audio_get_output(config.output_name);
    config.output->init();

    uint8_t ap_md5[16];
    MD5_CTX ctx;
    MD5_Init(&ctx);
    MD5_Update(&ctx, config.apname, strlen(config.apname));
    MD5_Final(ap_md5, &ctx);
    memcpy(config.hw_addr, ap_md5, sizeof(config.hw_addr));
    if (config.meta_dir)
        metadata_open();

    rtsp_listen_loop();
}
Exemplo n.º 3
0
Arquivo: log.c Projeto: rzr/connman
int __connman_log_init(const char *program, const char *debug,
		gboolean detach, gboolean backtrace,
		const char *program_name, const char *program_version)
{
	static char path[PATH_MAX];
	int option = LOG_NDELAY | LOG_PID;

	program_exec = program;
	program_path = getcwd(path, sizeof(path));

	if (debug)
		enabled = g_strsplit_set(debug, ":, ", 0);

	__connman_log_enable(__start___debug, __stop___debug);

	if (!detach)
		option |= LOG_PERROR;

	if (backtrace)
		signal_setup(signal_handler);

	openlog(basename(program), option, LOG_DAEMON);

	syslog(LOG_INFO, "%s version %s", program_name, program_version);

	return 0;
}
Exemplo n.º 4
0
static int print_normal()
{
	int error = 0;
	int r_size;
	int w_size;
	char *buf;
	char *ptr;

	buf = (char *)malloc(MAX_DATA);

	signal_setup(SIGTERM, sighand_term);

	while((r_size = read(DATA_PATH, buf, MAX_DATA)) > 0){
		ptr = buf;
		for(;r_size > 0;r_size -= w_size){
			w_size = write(PRNT_PATH, ptr, r_size);
			if(w_size < 0){
				/* write error */
				error = -1;
				goto print_normal_exit;
			}
			ptr += w_size;
		}
	}

print_normal_exit:
	if(term_sig)
		do_printer_reset(1);

	free(buf);
	return 0;
}
Exemplo n.º 5
0
Arquivo: log.c Projeto: intgr/connman
int __connman_log_init(const char *program, const char *debug,
		connman_bool_t detach, connman_bool_t backtrace)
{
	static char path[PATH_MAX];
	int option = LOG_NDELAY | LOG_PID;

	program_exec = program;
	program_path = getcwd(path, sizeof(path));

	if (debug != NULL)
		enabled = g_strsplit_set(debug, ":, ", 0);

	__connman_log_enable(__start___debug, __stop___debug);

	if (detach == FALSE)
		option |= LOG_PERROR;

	if (backtrace == TRUE)
		signal_setup(signal_handler);

	openlog(basename(program), option, LOG_DAEMON);

	syslog(LOG_INFO, "Connection Manager version %s", VERSION);

	return 0;
}
Exemplo n.º 6
0
static int init_subsystems()
{
	struct ulog_dev *log;
	int ret;

	ret = signal_setup();
	if (ret)
		return ret;

	log = debug_log("Math: ");
	if (!log)
		return -ENOMEM;

	math_init(log);
	ulog_unref(log);

	log = debug_log("E3D: ");
	if (!log) {
		math_destroy();
		return -ENOMEM;
	}

	e3d_init(log);
	ulog_unref(log);

	ulog_flog(NULL, ULOG_INFO, "Creating subsystems\n");

	return 0;
}
Exemplo n.º 7
0
static void do_listen(char *port)
{
	struct addrinfo hints;
	struct addrinfo *result, *rp;
	int sfd, s, cfd;
	struct sockaddr_storage peer_addr;
	socklen_t peer_addr_len;
	int pid;

	if (!debug)
		signal_setup(SIGCHLD, clean_up);

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;

	s = getaddrinfo(NULL, port, &hints, &result);
	if (s != 0)
		pdie("getaddrinfo: error opening %s", port);

	for (rp = result; rp != NULL; rp = rp->ai_next) {
		sfd = socket(rp->ai_family, rp->ai_socktype,
			     rp->ai_protocol);
		if (sfd < 0)
			continue;

		if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
			break;

		close(sfd);
	}

	if (rp == NULL)
		pdie("Could not bind");

	freeaddrinfo(result);

	if (listen(sfd, backlog) < 0)
		pdie("listen");

	peer_addr_len = sizeof(peer_addr);

	do {
		cfd = accept(sfd, (struct sockaddr *)&peer_addr, &peer_addr_len);
		printf("connected!\n");
		if (cfd < 0 && errno == EINTR)
			continue;
		if (cfd < 0)
			pdie("connecting");

		pid = do_connection(cfd, &peer_addr, peer_addr_len);
		if (pid > 0)
			add_process(pid);

	} while (!done);

	kill_clients();
}
Exemplo n.º 8
0
int main(int argc, char *argv[])
{
	signal_setup();
	listenfd = tcp_listen();
	dtserv_run(listenfd);

	exit(0);
}
Exemplo n.º 9
0
void __connman_log_cleanup(void)
{
	syslog(LOG_INFO, "Exit");

	closelog();

	signal_setup(SIG_DFL);

	g_strfreev(enabled);
}
Exemplo n.º 10
0
static void process_udp_child(int sfd, const char *host, const char *port,
			      int cpu, int page_size)
{
	struct sockaddr_storage peer_addr;
	socklen_t peer_addr_len;
	char buf[page_size];
	char *tempfile;
	int cfd;
	int fd;
	int n;
	int once = 0;

	signal_setup(SIGUSR1, finish);

	tempfile = get_temp_file(host, port, cpu);
	fd = open(tempfile, O_WRONLY | O_TRUNC | O_CREAT, 0644);
	if (fd < 0)
		pdie("creating %s", tempfile);

	if (use_tcp) {
		if (listen(sfd, backlog) < 0)
			pdie("listen");
		peer_addr_len = sizeof(peer_addr);
		cfd = accept(sfd, (struct sockaddr *)&peer_addr, &peer_addr_len);
		if (cfd < 0 && errno == EINTR)
			goto done;
		if (cfd < 0)
			pdie("accept");
		close(sfd);
		sfd = cfd;
	}

	do {
		/* TODO, make this copyless! */
		n = read(sfd, buf, page_size);
		if (n < 0) {
			if (errno == EINTR)
				continue;
			pdie("reading client");
		}
		if (!n)
			break;
		/* UDP requires that we get the full size in one go */
		if (!use_tcp && n < page_size && !once) {
			once = 1;
			warning("read %d bytes, expected %d", n, page_size);
		}
		write(fd, buf, n);
	} while (!done);

 done:
	put_temp_file(tempfile);
	exit(0);
}
Exemplo n.º 11
0
Arquivo: log.c Projeto: intgr/connman
void __connman_log_cleanup(connman_bool_t backtrace)
{
	syslog(LOG_INFO, "Exit");

	closelog();

	if (backtrace == TRUE)
		signal_setup(SIG_DFL);

	g_strfreev(enabled);
}
Exemplo n.º 12
0
/* init/free */

static void
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
__attribute__ ((constructor))
#endif /* !__GNUC__ */
mp_init (void)
{
  GMemVTable mp_mem_table = {
    mp_malloc,
    mp_realloc,
    mp_free,
    NULL,
    NULL,
    NULL,
  };

#if 0
  gchar *envvar;

  unlink(MP_TIME_LOG);
  unlink(MP_FRAG_LOG);
  unlink(MP_USE_LOG);
  unlink(MP_BT_LOG);
  
  if( (envvar = getenv ("MP_TRACE_SIZE"))) {
    mp_trace_size = atoi (envvar);
  }
  if( (envvar = getenv ("MP_TRACE_INTERACTIVE"))) {
    mp_trace_interactive = atoi (envvar);
  }
  if( (envvar = getenv ("MP_USAGE_SCALE"))) {
    mp_usage_scale = atoi (envvar);
  }
  if( (envvar = getenv ("MP_LOG_START"))) {
    mp_log_start = atof (envvar);
  }
  if(!(mp_log_base = getenv ("MP_LOG_BASE"))) {
    mp_log_base = "/tmp/mp_";
  }
  
  /*
  if (!(time_log = fopen (MP_TIME_LOG, "wt"))) {
    fprintf(stderr,"cannot open "MP_TIME_LOG" for writing\n");
    return;
  }
  if (!(use_log = fopen (MP_USE_LOG, "wt"))) {
    fprintf(stderr,"cannot open "MP_USE_LOG" for writing\n");
    return;
  }
  */
  signal_setup();
#endif

  g_mem_set_vtable (&mp_mem_table);

#if 0
  its = mp_get_timestamp();
#endif
}
Exemplo n.º 13
0
int main(int argc, char *argv[])
{
	int c;
	bool daemon = false;

	while ((c = getopt(argc, argv, "dqvhV")) != -1) {
		switch (c) {
		case 'd':
			daemon = true;
			break;
		case 'v':
			cf_verbose++;
			break;
		case 'q':
			cf_quiet = 1;
			break;
		case 'h':
			printf(usage_str);
			return 0;
		default:
			printf("bad switch: ");
			printf(usage_str);
			return 1;
		}
	}
	if (optind + 1 != argc) {
		printf("pgqd requires config file\n");
		return 1;
	}

	cf.config_file = argv[optind];

	load_config(false);

	daemonize(cf.pidfile, daemon);

	if (!event_init())
		fatal("event_init failed");

	signal_setup();

	if (!cf.database_list || !cf.database_list[0]) {
		log_info("auto-detecting dbs ...");
		detect_dbs();
	} else {
		fatal("fixed list not implemented yet: '%s'", cf.database_list);
	}

	while (1)
		main_loop_once();

	return 0;
}
Exemplo n.º 14
0
void init_signals(void)
{
	signal_setup(SIGTERM, sighand_term);
	signal_setup(SIGUSR1, sighand_user1);
	signal_setup(SIGUSR2, sighand_user2);
	signal_setup(SIGINT,  sighand_int);
	signal_setup(SIGHUP,  sighand_hup);
	signal_setup(SIGPIPE, sighand_pipe);
	signal_setup(SIGQUIT, sighand_quit);
}
Exemplo n.º 15
0
static void
test_write_wantsignal(const char *testname, int sock1, int sock2)
{

	if (shutdown(sock2, SHUT_WR) < 0)
		err(-1, "%s: shutdown", testname);
	signal_setup(testname);
	test_write(testname, sock2);
	if (!got_signal())
		errx(-1, "%s: write: didn't receive SIGPIPE", testname);
	close(sock1);
	close(sock2);
}
Exemplo n.º 16
0
static void
test_write_dontsignal(const char *testname, int sock1, int sock2)
{
	int i;

	i = 1;
	if (setsockopt(sock2, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof(i)) < 0)
		err(-1, "%s: setsockopt(SOL_SOCKET, SO_NOSIGPIPE)", testname);
	if (shutdown(sock2, SHUT_WR) < 0)
		err(-1, "%s: shutdown", testname);
	signal_setup(testname);
	test_write(testname, sock2);
	if (got_signal())
		errx(-1, "%s: write: got SIGPIPE", testname);
	close(sock1);
	close(sock2);
}
Exemplo n.º 17
0
int main(int argc, char **argv) {
    signal_setup();
    memset(&config, 0, sizeof(config));

    // set defaults
    config.buffer_start_fill = 220;
    config.port = 5002;
    char hostname[100];
    gethostname(hostname, 100);
    config.apname = malloc(20 + 100);
    snprintf(config.apname, 20 + 100, "Shairport on %s", hostname);

    // parse arguments into config
    int audio_arg = parse_options(argc, argv);

    // mDNS supports maximum of 63-character names (we append 13).
    if (strlen(config.apname) > 50)
        die("Supplied name too long (max 50 characters)");

    if (config.daemonise) {
        daemon_init();
    }

    log_setup();

    config.output = audio_get_output(config.output_name);
    if (!config.output) {
        audio_ls_outputs();
        die("Invalid audio output specified!");
    }
    config.output->init(argc-audio_arg, argv+audio_arg);

    uint8_t ap_md5[16];
    MD5_CTX ctx;
    MD5_Init(&ctx);
    MD5_Update(&ctx, config.apname, strlen(config.apname));
    MD5_Final(ap_md5, &ctx);
    memcpy(config.hw_addr, ap_md5, sizeof(config.hw_addr));


    rtsp_listen_loop();

    // should not.
    shairport_shutdown(1);
    return 1;
}
Exemplo n.º 18
0
static void
cloader_run_child(MuTest* test, CTokenFork* token)
{
    MuThunk thunk;

    /* Set up the C/C++ interface to call into our token */
    mu_interface_set_current_token_callback(ctoken_current, token);
        
    /* Set up handlers to catch asynchronous/fatal signals */
    signal_setup();

    /* Stage: library setup */
    token->current_stage = MU_STAGE_LIBRARY_SETUP;
    
    if ((thunk = cloader_library_setup(test->loader, test->library)))
        INVOKE(thunk);
    
    /* Stage: fixture setup */
    token->current_stage = MU_STAGE_FIXTURE_SETUP;
    
    if ((thunk = cloader_fixture_setup(test->loader, test)))
        INVOKE(thunk);
    
    /* Stage: test */
    token->current_stage = MU_STAGE_TEST;
    
    INVOKE(((CTest*) test)->entry->run);
    
    /* Stage: fixture teardown */
    token->current_stage = MU_STAGE_FIXTURE_TEARDOWN;
    
    if ((thunk = cloader_fixture_teardown(test->loader, test)))
        INVOKE(thunk);
    
    /* Stage: library teardown */
    token->current_stage = MU_STAGE_LIBRARY_TEARDOWN;
    
    if ((thunk = cloader_library_teardown(test->loader, test->library)))
        INVOKE(thunk);
    
    /* If we got this far without incident, explicitly succeed */
    mu_interface_result(NULL, 0, MU_STATUS_SUCCESS, NULL);
}
Exemplo n.º 19
0
int __connman_log_init(const char *debug, connman_bool_t detach)
{
	int option = LOG_NDELAY | LOG_PID;

	if (debug != NULL)
		enabled = g_strsplit_set(debug, ":, ", 0);

	__connman_log_enable(__start___debug, __stop___debug);

	if (detach == FALSE)
		option |= LOG_PERROR;

	signal_setup(signal_handler);

	openlog("connmand", option, LOG_DAEMON);

	syslog(LOG_INFO, "Connection Manager version %s", VERSION);

	return 0;
}
Exemplo n.º 20
0
static int do_fork(int cfd)
{
	pid_t pid;

	/* in debug mode, we do not fork off children */
	if (debug)
		return 0;

	pid = fork();
	if (pid < 0) {
		warning("failed to create child");
		return -1;
	}

	if (pid > 0) {
		close(cfd);
		return pid;
	}

	signal_setup(SIGINT, finish);

	return 0;
}
Exemplo n.º 21
0
/**
 * main() - entry point
 *
 * Declare VRRP instance, init daemon
 * and launch state machine
 */
int main(int argc, char *argv[])
{
	signal_setup();

	/* Current VRRP instance */
	struct vrrp vrrp;
	struct vrrp_net vnet;

	/* Init VRRP instance */
	vrrp_init(&vrrp);
	vrrp_net_init(&vnet);

	/* cmdline options */
	if (! !vrrp_options(&vrrp, &vnet, argc, argv))
		exit(EXIT_FAILURE);

	/* pidfile init && check */
	if (pidfile_init(vrrp.vrid) != 0)
		exit(EXIT_FAILURE);

	pidfile_check(vrrp.vrid);

	/* logs */
	log_open("uvrrpd", (char const *) loglevel);

	/* open sockets */
	if ((vrrp_net_socket(&vnet) != 0) || (vrrp_net_socket_xmit(&vnet) != 0))
		exit(EXIT_FAILURE);

	/* hook script */
	if (vrrp_exec_init(&vrrp) != 0)
		exit(EXIT_FAILURE);

	/* advertisement pkt */
	if (vrrp_adv_init(&vnet, &vrrp) != 0)
		exit(EXIT_FAILURE);

	/* net topology */
	if (vnet.family == AF_INET) {
		if (vrrp_arp_init(&vnet) != 0)
			exit(EXIT_FAILURE);
	}
	else if (vnet.family == AF_INET6) {
		if (vrrp_na_init(&vnet) != 0)
			exit(EXIT_FAILURE);
	}

	/* daemonize */
	if (background) {
		daemon(0, (log_trigger(NULL) > LOG_INFO));
	}
	else
		chdir("/");


	/* pidfile */
	pidfile(vrrp.vrid);

	/* process */
	set_bit(KEEP_GOING, &reg);
	while (test_bit(KEEP_GOING, &reg) && !vrrp_process(&vrrp, &vnet));

	/* shutdown */
	vrrp_adv_cleanup(&vnet);

	if (vnet.family == AF_INET)
		vrrp_arp_cleanup(&vnet);
	else	/* AF_INET6 */
		vrrp_na_cleanup(&vnet);

	vrrp_cleanup(&vrrp);
	vrrp_exec_cleanup(&vrrp);
	vrrp_net_cleanup(&vnet);

	log_close();
	free(loglevel);
	pidfile_unlink();
	free(pidfile_name);

	return EXIT_SUCCESS;
}
Exemplo n.º 22
0
int
socks5_negotiate(int clisock, struct conndesc *conn)
{
	u_int i;
	char hostname[256];
	u_char nmethods, len, junk; 
	struct sockaddr_in rem_in;
	struct socks5_req req5;
	struct socks5_v_repl rep5;
	struct hostent *hent;	
	
	req5.vn = 5;
	req5.rsv = 0;
	
	/*
	 * Start by retrieving number of methods, version number has
	 * already been consumed by the calling procedure
	 */

	if (atomicio(read, clisock, &nmethods, 1) != 1) {
		warnv(1, "read()");
		return (-1);
	}

	/* Eat up methods */

	i = 0;
	while (i++ < nmethods) 
		if (atomicio(read, clisock, &junk, 1) != 1) {
			warnv(1, "read()");
			return (-1);
		}

	/*
	 * We don't support any authentication methods yet, so simply
	 * ignore it and send reply with no authentication required.
	 */

	rep5.ver = 5;
	rep5.res = 0;

	if (atomicio(write, clisock, &rep5, 2) != 2) {
		warnv(1, "write()");
		return (-1);
	}

	/* Receive data up to atyp */
	if (atomicio(read, clisock, &req5, 4) != 4) {
		warnv(1, "read()");
		return (-1);
	}
	if (req5.vn != 5)
		return (-1);

	memset(&rem_in, 0, sizeof(rem_in));

	switch (req5.atyp) {
	case SOCKS5_ATYP_IPV4:
		if (atomicio(read, clisock, &req5.destaddr, 4) != 4) {
			warnv(1, "read()");
			return (-1);
		}
		rem_in.sin_family = AF_INET;
		rem_in.sin_addr.s_addr = req5.destaddr;
		break;
	case SOCKS5_ATYP_FQDN:
		if (atomicio(read, clisock, &len, 1) != 1) {
			warnv(1, "read()");
			return (-1);
		}
		if (atomicio(read, clisock, hostname, len) != len) {
			warnv(1, "read()");
			return (-1);
		}
		hostname[len] = '\0';
		if ((hent = gethostbyname(hostname)) == NULL) {
			/* XXX no hstrerror() on solaris */
#ifndef __sun__			
			warnxv(1, "gethostbyname(): %s", hstrerror(h_errno));
#endif /* __sun__ */
			return (-1);
		}
		rem_in.sin_family = AF_INET;
		rem_in.sin_addr = *(struct in_addr *)hent->h_addr;
		break;
	default:
		return (-1);
	}

	if (atomicio(read, clisock, &req5.destport, 2) != 2) {
		warnv(1, "read()");
		return (-1);
	}

	rem_in.sin_port = req5.destport;

	/*
	 * Now we have a filled in in_addr for the target host:
	 * target_in, no socket yet.  This is provided by the command
	 * specific functions multiplexed in the next switch
	 * statement.
	 */

	switch (req5.cd) {
	case SOCKS5_CD_CONNECT:
		return (socks5_connect(clisock, &rem_in, &req5, conn));
	case SOCKS5_CD_BIND:
	        signal_setup();
	        event_dispatch();
		return (socks5_bind(clisock, &rem_in, &req5));
	case SOCKS5_CD_UDP_ASSOC:
	default:
		return (-1);
	}
}
Exemplo n.º 23
0
int
main(int argc, char **argv)
{
	const char *av = NULL;
	int func_total, file_total;
        char arg_dbpath[MAXPATHLEN];
	const char *index = NULL;
	int optchar;
        int option_index = 0;
	STATISTICS_TIME *tim;

	arg_dbpath[0] = 0;
	basic_check();
	/*
	 * Setup GTAGSCONF and GTAGSLABEL environment variable
	 * according to the --gtagsconf and --gtagslabel option.
	 */
	preparse_options(argc, argv);
	/*
	 * Load configuration values.
	 */
	if (!vgetcwd(cwdpath, sizeof(cwdpath)))
		die("cannot get current directory.");
	openconf(cwdpath);
	configuration();
	/*
	 * setup_langmap() is needed to use decide_lang().
	 */
	setup_langmap(langmap);
	save_environment(argc, argv);
	/*
	 * insert htags_options at the head of argv.
	 */
	setenv_from_config();
	{
		char *env = getenv("HTAGS_OPTIONS");
		if (env && *env)
			argv = prepend_options(&argc, argv, env);
	}
	while ((optchar = getopt_long(argc, argv, "acd:DfFghIm:nNoqst:Tvwx", long_options, &option_index)) != EOF) {
		switch (optchar) {
		case 0:
			/* already flags set */
			break;
		case OPT_AUTO_COMPLETION:
			auto_completion = 1;
			if (optarg) {
				if (atoi(optarg) > 0)
					auto_completion_limit = optarg;
				else
					die("The option value of --auto-completion must be numeric.");
			}
			break;
		case OPT_CFLOW:
			call_file = optarg;
			break;
		case OPT_CALL_TREE:
			call_file = optarg;
			break;
		case OPT_CALLEE_TREE:
			callee_file = optarg;
			break;
		case OPT_CVSWEB:
			cvsweb_url = optarg;
			break;
		case OPT_CVSWEB_CVSROOT:
			cvsweb_cvsroot = optarg;
			break;
		case OPT_GTAGSCONF:
		case OPT_GTAGSLABEL:
			/* These options are already parsed in preparse_options() */
			break;
		case OPT_INSERT_FOOTER:
			insert_footer = optarg;
			break;
		case OPT_INSERT_HEADER:
			insert_header = optarg;
			break;
		case OPT_HTML_HEADER:
			{
				STATIC_STRBUF(sb);
				if (!test("r", optarg))
					die("file '%s' not found.", optarg);
				strbuf_clear(sb);
				loadfile(optarg, sb);
				html_header = strbuf_value(sb);
			}
			break;
		case OPT_ITEM_ORDER:
			item_order = optarg;
			break;
		case OPT_TABS:
			if (atoi(optarg) > 0)
				tabs = atoi(optarg);
			else
				die("--tabs option requires numeric value.");
                        break;
		case OPT_NCOL:
			if (atoi(optarg) > 0)
				ncol = atoi(optarg);
			else
				die("--ncol option requires numeric value.");
                        break;
		case OPT_TREE_VIEW:
			tree_view = 1;
			if (optarg)
				tree_view_type = optarg;
			break;
                case 'a':
                        aflag++;
                        break;
                case 'd':
			strlimcpy(arg_dbpath, optarg, sizeof(arg_dbpath));
                        break;
                case 'D':
			dynamic = 1;
                        break;
                case 'f':
                        fflag++;
                        break;
                case 'F':
                        Fflag++;
                        break;
                case 'g':
                        gflag++;
                        break;
                case 'h':
			definition_header = AFTER_HEADER;
			if (optarg) {
				if (!strcmp(optarg, "before"))
					definition_header = BEFORE_HEADER;
				else if (!strcmp(optarg, "right"))
					definition_header = RIGHT_HEADER;
				else if (!strcmp(optarg, "after"))
					definition_header = AFTER_HEADER;
				else
					die("The option value of --func-header must be one of 'before', 'right' and 'after'.");
			}
                        break;
                case 'I':
                        Iflag++;
                        break;
                case 'm':
			main_func = optarg;
                        break;
                case 'n':
                        nflag++;
			if (optarg) {
				if (atoi(optarg) > 0)
					ncol = atoi(optarg);
				else
					die("The option value of --line-number must be numeric.");
			}
                        break;
                case 'o':
			other_files = 1;
                        break;
                case 's':
			symbol = 1;
                        break;
                case 'T':
			table_flist = 1;
			if (optarg) {
				if (atoi(optarg) > 0)
					flist_fields = atoi(optarg);
				else
					die("The option value of the --table-flist must be numeric.");
			}
                        break;
                case 't':
			title = optarg;
                        break;
                case 'q':
                        qflag++;
			setquiet();
                        break;
                case 'v':
                        vflag++;
			setverbose();
                        break;
                case 'w':
                        wflag++;
                        break;
                default:
                        usage();
                        break;
		}
	}
	/*
	 * Leaving everything to htags.
	 * Htags selects popular options for you.
	 */
	if (suggest2)
		suggest = 1;
	if (suggest) {
		int gtags_not_found = 0;
		char dbpath[MAXPATHLEN];

		aflag = Iflag = nflag = vflag = 1;
		setverbose();
		definition_header = AFTER_HEADER;
		other_files = symbol = show_position = table_flist = fixed_guide = 1;
		if (arg_dbpath[0]) {
			if (!test("f", makepath(arg_dbpath, dbname(GTAGS), NULL)))
				gtags_not_found = 1;
		} else if (gtagsexist(".", dbpath, sizeof(dbpath), 0) == 0) {
			gtags_not_found = 1;
		}
		if (gtags_not_found)
			gflag = 1;
	}
	if (suggest2) {
		Fflag = 1;				/* uses frame */
		fflag = dynamic = 1;			/* needs a HTTP server */
		auto_completion = tree_view = 1;	/* needs javascript */
	}
	if (call_file && !test("fr", call_file))
		die("cflow file not found. '%s'", call_file);
	if (callee_file && !test("fr", callee_file))
		die("cflow file not found. '%s'", callee_file);
	if (insert_header && !test("fr", insert_header))
		die("page header file '%s' not found.", insert_header);
	if (insert_footer && !test("fr", insert_footer))
		die("page footer file '%s' not found.", insert_footer);
	if (!fflag)
		auto_completion = 0;
        argc -= optind;
        argv += optind;
        if (!av)
                av = (argc > 0) ? *argv : NULL;

	if (debug)
		setdebug();
	settabs(tabs);					/* setup tab skip */
        if (qflag) {
                setquiet();
		vflag = 0;
	}
        if (show_version)
                version(av, vflag);
        if (show_help)
                help();
	/*
	 * Invokes gtags beforehand.
	 */
	if (gflag) {
		STRBUF *sb = strbuf_open(0);

		strbuf_puts(sb, gtags_path);
		if (vflag)
			strbuf_puts(sb, " -v");
		if (wflag)
			strbuf_puts(sb, " -w");
		if (suggest2 && enable_idutils && usable("mkid"))
			strbuf_puts(sb, " -I");
		if (arg_dbpath[0]) {
			strbuf_putc(sb, ' ');
			strbuf_puts(sb, arg_dbpath);
		}
		if (system(strbuf_value(sb)))
			die("cannot execute gtags(1) command.");
		strbuf_close(sb);
	}
	/*
	 * get dbpath.
	 */
	if (arg_dbpath[0]) {
		strlimcpy(dbpath, arg_dbpath, sizeof(dbpath));
	} else {
		int status = setupdbpath(0);
		if (status < 0)
			die_with_code(-status, "%s", gtags_dbpath_error);
		strlimcpy(dbpath, get_dbpath(), sizeof(dbpath));
	}
	if (!title) {
		char *p = strrchr(cwdpath, sep);
		title = p ? p + 1 : cwdpath;
	}
	if (cvsweb_url && test("d", "CVS"))
		use_cvs_module = 1;
	/*
	 * decide directory in which we make hypertext.
	 */
	if (av) {
		char realpath[MAXPATHLEN];

		if (!test("dw", av))
			die("'%s' is not writable directory.", av);
		if (chdir(av) < 0)
			die("directory '%s' not found.", av);
		if (!vgetcwd(realpath, sizeof(realpath)))
			die("cannot get current directory");
		if (chdir(cwdpath) < 0)
			die("cannot return to original directory.");
		snprintf(distpath, sizeof(distpath), "%s/HTML", realpath);
	} else {
		snprintf(distpath, sizeof(distpath), "%s/HTML", cwdpath);
	}
	/*
	 * Existence check of tag files.
	 */
	{
		int i;
		const char *path;
		GTOP *gtop;

		for (i = GPATH; i < GTAGLIM; i++) {
			path = makepath(dbpath, dbname(i), NULL);
			gtags_exist[i] = test("fr", path);
		}
		/*
		 * Real GRTAGS includes virtual GSYMS.
		 */
		gtags_exist[GSYMS] = symbol ? 1 : 0;
		if (!gtags_exist[GPATH] || !gtags_exist[GTAGS] || !gtags_exist[GRTAGS])
			die("GPATH, GTAGS and/or GRTAGS not found. Please reexecute htags with the -g option.");
		/*
		 * version check.
		 * Do nothing, but the version of tag file will be checked.
		 */
		gtop = gtags_open(dbpath, cwdpath, GTAGS, GTAGS_READ, 0);
		gtags_close(gtop);
		/*
		 * Check whether GRTAGS is empty.
		 */
		gtop = gtags_open(dbpath, cwdpath, GRTAGS, GTAGS_READ, 0);
		if (gtags_first(gtop, NULL, 0) == NULL)
			grtags_is_empty = 1;
		gtags_close(gtop);
	}
	/*
	 * make dbpath absolute.
	 */
	{
		char buf[MAXPATHLEN];
		if (realpath(dbpath, buf) == NULL)
			die("cannot get realpath of dbpath.");
		strlimcpy(dbpath, buf, sizeof(dbpath));
	}
	/*
	 * The older version (4.8.7 or former) of GPATH doesn't have files
         * other than source file. The oflag requires new version of GPATH.
	 */
	if (other_files) {
		GFIND *gp = gfind_open(dbpath, NULL, 0, 0);
		if (gp->version < 2)
			die("GPATH is old format. Please remake it by invoking gtags(1).");
		gfind_close(gp);
	}
	/*
	 * for global(1) and gtags(1).
	 */
	set_env("GTAGSROOT", cwdpath);
	set_env("GTAGSDBPATH", dbpath);
	set_env("GTAGSLIBPATH", "");
	/*------------------------------------------------------------------
	 * MAKE FILES
	 *------------------------------------------------------------------
	 *       HTML/cgi-bin/global.cgi ... CGI program (1)
	 *       HTML/cgi-bin/ghtml.cgi  ... unzip script (1)
	 *       HTML/.htaccess          ... skeleton of .htaccess (1)
	 *       HTML/help.html          ... help file (2)
	 *       HTML/R/                 ... references (3)
	 *       HTML/D/                 ... definitions (3)
	 *       HTML/search.html        ... search index (4)
	 *       HTML/defines.html       ... definitions index (5)
	 *       HTML/defines/           ... definitions index (5)
	 *       HTML/files/             ... file index (6)
	 *       HTML/index.html         ... index file (7)
	 *       HTML/mains.html         ... main index (8)
	 *       HTML/null.html          ... main null html (8)
	 *       HTML/S/                 ... source files (9)
	 *       HTML/I/                 ... include file index (9)
	 *       HTML/rebuild.sh         ... rebuild script (10)
	 *       HTML/style.css          ... style sheet (11)
	 *------------------------------------------------------------------
	 */
	/* for clean up */
	signal_setup();
	sethandler(clean);

        HTML = normal_suffix;

	message("[%s] Htags started", now());
	init_statistics();
	/*
	 * (#) check if GTAGS, GRTAGS is the latest.
	 */
	if (get_dbpath())
		message(" Using %s/GTAGS.", get_dbpath());
	if (grtags_is_empty)
		message(" GRTAGS is empty.");
	if (gpath_open(dbpath, 0) < 0)
		die("GPATH not found.");
	if (!w32) {
		/* UNDER CONSTRUCTION */
	}
	if (auto_completion || tree_view) {
		STATIC_STRBUF(sb);
		strbuf_clear(sb);
		strbuf_puts_nl(sb, "<script type='text/javascript' src='js/jquery.js'></script>");
		if (auto_completion)
			loadfile(makepath(datadir, "gtags/jscode_suggest", NULL), sb);
		if (tree_view)
			loadfile(makepath(datadir, "gtags/jscode_treeview", NULL), sb);
		jscode = strbuf_value(sb);
	}
	/*
	 * (0) make directories
	 */
	message("[%s] (0) making directories ...", now());
	if (!test("d", distpath))
		if (mkdir(distpath, 0777) < 0)
			die("cannot make directory '%s'.", distpath);
	make_directory_in_distpath("files");
	make_directory_in_distpath("defines");
	make_directory_in_distpath(SRCS);
	make_directory_in_distpath(INCS);
	make_directory_in_distpath(INCREFS);
	if (!dynamic) {
		make_directory_in_distpath(DEFS);
		make_directory_in_distpath(REFS);
		if (symbol)
			make_directory_in_distpath(SYMS);
	}
	if (fflag || dynamic)
		make_directory_in_distpath("cgi-bin");
	if (Iflag)
		make_directory_in_distpath("icons");
	if (auto_completion || tree_view)
		 make_directory_in_distpath("js");
	/*
	 * (1) make CGI program
	 */
	if (fflag || dynamic) {
		char cgidir[MAXPATHLEN];

		snprintf(cgidir, sizeof(cgidir), "%s/cgi-bin", distpath);
		message("[%s] (1) making CGI program ...", now());
		if (fflag || dynamic)
			makeprogram(cgidir, "global.cgi", 0755);
		if (auto_completion)
			makeprogram(cgidir, "completion.cgi", 0755);
		makehtaccess(cgidir, ".htaccess", 0644);
	} else {
		message("[%s] (1) making CGI program ...(skipped)", now());
	}
	if (av) {
		const char *path = makepath(distpath, "GTAGSROOT", NULL);
		FILE *op = fopen(path, "w");
		if (op == NULL)
			die("cannot make file '%s'.", path);
		fputs(cwdpath, op);
		fputc('\n', op);
		fclose(op);
	}
	/*
	 * (2) make help file
	 */
	message("[%s] (2) making help.html ...", now());
	makehelp("help.html");
	/*
	 * (#) load GPATH
	 */
	load_gpath(dbpath);

	/*
	 * (3) make function entries (D/ and R/)
	 *     MAKING TAG CACHE
	 */
	message("[%s] (3) making tag lists ...", now());
	cache_open();
	tim = statistics_time_start("Time of making tag lists");
	func_total = makedupindex();
	statistics_time_end(tim);
	message("Total %d functions.", func_total);
	/*
	 * (4) search index. (search.html)
	 */
	if (Fflag && fflag) {
		message("[%s] (4) making search index ...", now());
		makesearchindex("search.html");
	}
	{
		STRBUF *defines = strbuf_open(0);
		STRBUF *files = strbuf_open(0);

		/*
		 * (5) make definition index (defines.html and defines/)
		 *     PRODUCE @defines
		 */
		message("[%s] (5) making definition index ...", now());
		tim = statistics_time_start("Time of making definition index");
		func_total = makedefineindex("defines.html", func_total, defines);
		statistics_time_end(tim);
		message("Total %d functions.", func_total);
		/*
		 * (6) make file index (files.html and files/)
		 *     PRODUCE @files, %includes
		 */
		message("[%s] (6) making file index ...", now());
		init_inc();
		tim = statistics_time_start("Time of making file index");
		file_total = makefileindex("files.html", files);
		statistics_time_end(tim);
		message("Total %d files.", file_total);
		html_count += file_total;
		/*
		 * (7) make call tree using cflow(1)'s output (cflow.html)
		 */
		if (call_file || callee_file) {
			message("[%s] (7) making cflow index ...", now());
			tim = statistics_time_start("Time of making cflow index");
			if (call_file)
				if (makecflowindex("call.html", call_file) < 0)
					call_file = NULL;
			if (callee_file)
				if (makecflowindex("callee.html", callee_file) < 0)
					callee_file = NULL;
			statistics_time_end(tim);
		}
		/*
		 * [#] make include file index.
		 */
		message("[%s] (#) making include file index ...", now());
		tim = statistics_time_start("Time of making include file index");
		makeincludeindex();
		statistics_time_end(tim);
		/*
		 * [#] make a common part for mains.html and index.html
		 *     USING @defines @files
		 */
		message("[%s] (#) making a common part ...", now());
		index = makecommonpart(title, strbuf_value(defines), strbuf_value(files));

		strbuf_close(defines);
		strbuf_close(files);
	}
	/*
	 * (7)make index file (index.html)
	 */
	message("[%s] (7) making index file ...", now());
	makeindex("index.html", title, index);
	/*
	 * (8) make main index (mains.html)
	 */
	message("[%s] (8) making main index ...", now());
	makemainindex("mains.html", index);
	/*
	 * (9) make HTML files (SRCS/)
	 *     USING TAG CACHE, %includes and anchor database.
	 */
	message("[%s] (9) making hypertext from source code ...", now());
	tim = statistics_time_start("Time of making hypertext");
	makehtml(file_total);
	statistics_time_end(tim);
	/*
	 * (10) rebuild script. (rebuild.sh)
	 *
	 * Don't grant execute permission to rebuild script.
	 */
	makerebuild("rebuild.sh");
	if (chmod(makepath(distpath, "rebuild.sh", NULL), 0640) < 0)
		die("cannot chmod rebuild script.");
	/*
	 * (11) style sheet file (style.css)
	 */
	if (enable_xhtml) {
		char src[MAXPATHLEN];
		char dist[MAXPATHLEN];
		snprintf(src, sizeof(src), "%s/gtags/style.css", datadir);
		snprintf(dist, sizeof(dist), "%s/style.css", distpath);
		copyfile(src, dist);
	}
	if (auto_completion || tree_view) {
		char src[MAXPATHLEN];
		char dist[MAXPATHLEN];

		snprintf(src, sizeof(src), "%s/gtags/jquery", datadir);
		snprintf(dist, sizeof(dist), "%s/js", distpath);
		copydirectory(src, dist);
		snprintf(src, sizeof(src), "%s/gtags/jquery/images", datadir);
		snprintf(dist, sizeof(dist), "%s/js/images", distpath);
		copydirectory(src, dist);
	}
	message("[%s] Done.", now());
	if (vflag && (fflag || dynamic || auto_completion)) {
		message("\n[Information]\n");
		message(" o Htags was invoked with the -f, -c, -D or --auto-completion option. You should");
		message("   start http server so that cgi-bin/*.cgi is executed as a CGI script.");
 		message("\n If you are using Apache, 'HTML/.htaccess' might be helpful for you.\n");
		message(" Good luck!\n");
	}
	if (Iflag) {
		char src[MAXPATHLEN];
		char dist[MAXPATHLEN];

		snprintf(src, sizeof(src), "%s/gtags/icons", datadir);
		snprintf(dist, sizeof(dist), "%s/icons", distpath);
		copydirectory(src, dist);
	}
	gpath_close();
	/*
	 * Print statistics information.
	 */
	print_statistics(statistics);
	clean();
	return 0;
}
Exemplo n.º 24
0
int main(int argc, char **argv)
{
	int devnull_fd = -1;
#ifdef TIOCNOTTY
	int tty_fd = -1;
#endif

#ifdef HAVE_PAM
	pam_handle_t *pamh = NULL;
	int pamr;
	const char *const *pamenv = NULL;
#endif

	int opt;
	bool start = false;
	bool stop = false;
	bool oknodo = false;
	bool test = false;
	char *exec = NULL;
	char *startas = NULL;
	char *name = NULL;
	char *pidfile = NULL;
	char *retry = NULL;
	int sig = -1;
	int nicelevel = 0, ionicec = -1, ioniced = 0;
	bool background = false;
	bool makepidfile = false;
	bool interpreted = false;
	bool progress = false;
	uid_t uid = 0;
	gid_t gid = 0;
	char *home = NULL;
	int tid = 0;
	char *redirect_stderr = NULL;
	char *redirect_stdout = NULL;
	int stdin_fd;
	int stdout_fd;
	int stderr_fd;
	pid_t pid, spid;
	int i;
	char *svcname = getenv("RC_SVCNAME");
	RC_STRINGLIST *env_list;
	RC_STRING *env;
	char *tmp, *newpath, *np;
	char *p;
	char *token;
	char exec_file[PATH_MAX];
	struct passwd *pw;
	struct group *gr;
	char line[130];
	FILE *fp;
	size_t len;
	mode_t numask = 022;
	char **margv;
	unsigned int start_wait = 0;

	applet = basename_c(argv[0]);
	TAILQ_INIT(&schedule);
#ifdef DEBUG_MEMORY
	atexit(cleanup);
#endif

	signal_setup(SIGINT, handle_signal);
	signal_setup(SIGQUIT, handle_signal);
	signal_setup(SIGTERM, handle_signal);

	if ((tmp = getenv("SSD_NICELEVEL")))
		if (sscanf(tmp, "%d", &nicelevel) != 1)
			eerror("%s: invalid nice level `%s' (SSD_NICELEVEL)",
			    applet, tmp);

	/* Get our user name and initial dir */
	p = getenv("USER");
	home = getenv("HOME");
	if (home == NULL || p == NULL) {
		pw = getpwuid(getuid());
		if (pw != NULL) {
			if (p == NULL)
				setenv("USER", pw->pw_name, 1);
			if (home == NULL) {
				setenv("HOME", pw->pw_dir, 1);
				home = pw->pw_dir;
			}
		}
	}

	while ((opt = getopt_long(argc, argv, getoptstring, longopts,
		    (int *) 0)) != -1)
		switch (opt) {
		case 'I': /* --ionice */
			if (sscanf(optarg, "%d:%d", &ionicec, &ioniced) == 0)
				eerrorx("%s: invalid ionice `%s'",
				    applet, optarg);
			if (ionicec == 0)
				ioniced = 0;
			else if (ionicec == 3)
				ioniced = 7;
			ionicec <<= 13; /* class shift */
			break;

		case 'K':  /* --stop */
			stop = true;
			break;

		case 'N':  /* --nice */
			if (sscanf(optarg, "%d", &nicelevel) != 1)
				eerrorx("%s: invalid nice level `%s'",
				    applet, optarg);
			break;

		case 'P':  /* --progress */
			progress = true;
			break;

		case 'R':  /* --retry <schedule>|<timeout> */
			retry = optarg;
			break;

		case 'S':  /* --start */
			start = true;
			break;

		case 'b':  /* --background */
			background = true;
			break;

		case 'c':  /* --chuid <username>|<uid> */
			/* DEPRECATED */
			ewarn("WARNING: -c/--chuid is deprecated and will be removed in the future, please use -u/--user instead");
		case 'u':  /* --user <username>|<uid> */
		{
			p = optarg;
			tmp = strsep(&p, ":");
			changeuser = xstrdup(tmp);
			if (sscanf(tmp, "%d", &tid) != 1)
				pw = getpwnam(tmp);
			else
				pw = getpwuid((uid_t)tid);

			if (pw == NULL)
				eerrorx("%s: user `%s' not found",
				    applet, tmp);
			uid = pw->pw_uid;
			home = pw->pw_dir;
			unsetenv("HOME");
			if (pw->pw_dir)
				setenv("HOME", pw->pw_dir, 1);
			unsetenv("USER");
			if (pw->pw_name)
				setenv("USER", pw->pw_name, 1);
			if (gid == 0)
				gid = pw->pw_gid;

			if (p) {
				tmp = strsep (&p, ":");
				if (sscanf(tmp, "%d", &tid) != 1)
					gr = getgrnam(tmp);
				else
					gr = getgrgid((gid_t) tid);

				if (gr == NULL)
					eerrorx("%s: group `%s'"
					    " not found",
					    applet, tmp);
				gid = gr->gr_gid;
			}
		}
		break;

		case 'd':  /* --chdir /new/dir */
			ch_dir = optarg;
			break;

		case 'e': /* --env */
			putenv(optarg);
			break;

		case 'g':  /* --group <group>|<gid> */
			if (sscanf(optarg, "%d", &tid) != 1)
				gr = getgrnam(optarg);
			else
				gr = getgrgid((gid_t)tid);
			if (gr == NULL)
				eerrorx("%s: group `%s' not found",
				    applet, optarg);
			gid = gr->gr_gid;
			break;

		case 'i': /* --interpreted */
			interpreted = true;
			break;

		case 'k':
			if (parse_mode(&numask, optarg))
				eerrorx("%s: invalid mode `%s'",
				    applet, optarg);
			break;

		case 'm':  /* --make-pidfile */
			makepidfile = true;
			break;

		case 'n':  /* --name <process-name> */
			name = optarg;
			break;

		case 'o':  /* --oknodo */
			/* DEPRECATED */
			ewarn("WARNING: -o/--oknodo is deprecated and will be removed in the future");
			oknodo = true;
			break;

		case 'p':  /* --pidfile <pid-file> */
			pidfile = optarg;
			break;

		case 's':  /* --signal <signal> */
			sig = parse_signal(optarg);
			break;

		case 't':  /* --test */
			test = true;
			break;

		case 'r':  /* --chroot /new/root */
			ch_root = optarg;
			break;

		case 'a': /* --startas <name> */
			/* DEPRECATED */
			ewarn("WARNING: -a/--startas is deprecated and will be removed in the future, please use -x/--exec or -n/--name instead");
			startas = optarg;
			break;
		case 'w':
			if (sscanf(optarg, "%d", &start_wait) != 1)
				eerrorx("%s: `%s' not a number",
				    applet, optarg);
			break;
		case 'x':  /* --exec <executable> */
			exec = optarg;
			break;

		case '1':   /* --stdout /path/to/stdout.lgfile */
			redirect_stdout = optarg;
			break;

		case '2':  /* --stderr /path/to/stderr.logfile */
			redirect_stderr = optarg;
			break;

		case_RC_COMMON_GETOPT
		}

	endpwent();
	argc -= optind;
	argv += optind;

	/* Allow start-stop-daemon --signal HUP --exec /usr/sbin/dnsmasq
	 * instead of forcing --stop --oknodo as well */
	if (!start &&
	    !stop &&
	    sig != SIGINT &&
	    sig != SIGTERM &&
	    sig != SIGQUIT &&
	    sig != SIGKILL)
		oknodo = true;

	if (!exec)
		exec = startas;
	else if (!name)
		name = startas;

	if (!exec) {
		exec = *argv;
		if (!exec)
			exec = name;
		if (name && start)
			*argv = name;
	} else if (name) {
		*--argv = name;
		++argc;
    } else if (exec) {
		*--argv = exec;
		++argc;
	};

	if (stop || sig != -1) {
		if (sig == -1)
			sig = SIGTERM;
		if (!*argv && !pidfile && !name && !uid)
			eerrorx("%s: --stop needs --exec, --pidfile,"
			    " --name or --user", applet);
		if (background)
			eerrorx("%s: --background is only relevant with"
			    " --start", applet);
		if (makepidfile)
			eerrorx("%s: --make-pidfile is only relevant with"
			    " --start", applet);
		if (redirect_stdout || redirect_stderr)
			eerrorx("%s: --stdout and --stderr are only relevant"
			    " with --start", applet);
	} else {
		if (!exec)
			eerrorx("%s: nothing to start", applet);
		if (makepidfile && !pidfile)
			eerrorx("%s: --make-pidfile is only relevant with"
			    " --pidfile", applet);
		if ((redirect_stdout || redirect_stderr) && !background)
			eerrorx("%s: --stdout and --stderr are only relevant"
			    " with --background", applet);
	}

	/* Expand ~ */
	if (ch_dir && *ch_dir == '~')
		ch_dir = expand_home(home, ch_dir);
	if (ch_root && *ch_root == '~')
		ch_root = expand_home(home, ch_root);
	if (exec) {
		if (*exec == '~')
			exec = expand_home(home, exec);

		/* Validate that the binary exists if we are starting */
		if (*exec == '/' || *exec == '.') {
			/* Full or relative path */
			if (ch_root)
				snprintf(exec_file, sizeof(exec_file),
				    "%s/%s", ch_root, exec);
			else
				snprintf(exec_file, sizeof(exec_file),
				    "%s", exec);
		} else {
			/* Something in $PATH */
			p = tmp = xstrdup(getenv("PATH"));
			*exec_file = '\0';
			while ((token = strsep(&p, ":"))) {
				if (ch_root)
					snprintf(exec_file, sizeof(exec_file),
					    "%s/%s/%s",
					    ch_root, token, exec);
				else
					snprintf(exec_file, sizeof(exec_file),
					    "%s/%s", token, exec);
				if (exists(exec_file))
					break;
				*exec_file = '\0';
			}
			free(tmp);
		}
	}
	if (start && !exists(exec_file)) {
		eerror("%s: %s does not exist", applet,
		    *exec_file ? exec_file : exec);
		exit(EXIT_FAILURE);
	}

	/* If we don't have a pidfile we should check if it's interpreted
	 * or not. If it we, we need to pass the interpreter through
	 * to our daemon calls to find it correctly. */
	if (interpreted && !pidfile) {
		fp = fopen(exec_file, "r");
		if (fp) {
			p = fgets(line, sizeof(line), fp);
			fclose(fp);
			if (p != NULL && line[0] == '#' && line[1] == '!') {
				p = line + 2;
				/* Strip leading spaces */
				while (*p == ' ' || *p == '\t')
					p++;
				/* Remove the trailing newline */
				len = strlen(p) - 1;
				if (p[len] == '\n')
					p[len] = '\0';
				token = strsep(&p, " ");
				strncpy(exec_file, token, sizeof(exec_file));
				opt = 0;
				for (nav = argv; *nav; nav++)
					opt++;
				nav = xmalloc(sizeof(char *) * (opt + 3));
				nav[0] = exec_file;
				len = 1;
				if (p)
					nav[len++] = p;
				for (i = 0; i < opt; i++)
					nav[i + len] = argv[i];
				nav[i + len] = '\0';
			}
		}
	}
	margv = nav ? nav : argv;

	if (stop || sig != -1) {
		if (sig == -1)
			sig = SIGTERM;
		if (!stop)
			oknodo = true;
		if (retry)
			parse_schedule(retry, sig);
		else if (test || oknodo)
			parse_schedule("0", sig);
		else
			parse_schedule(NULL, sig);
		i = run_stop_schedule(exec, (const char *const *)margv,
		    pidfile, uid, test, progress);

		if (i < 0)
			/* We failed to stop something */
			exit(EXIT_FAILURE);
		if (test || oknodo)
			return i > 0 ? EXIT_SUCCESS : EXIT_FAILURE;

		/* Even if we have not actually killed anything, we should
		 * remove information about it as it may have unexpectedly
		 * crashed out. We should also return success as the end
		 * result would be the same. */
		if (pidfile && exists(pidfile))
			unlink(pidfile);
		if (svcname)
			rc_service_daemon_set(svcname, exec,
			    (const char *const *)argv,
			    pidfile, false);
		exit(EXIT_SUCCESS);
	}

	if (pidfile)
		pid = get_pid(pidfile);
	else
		pid = 0;

	if (do_stop(exec, (const char * const *)margv, pid, uid,
		0, test) > 0)
		eerrorx("%s: %s is already running", applet, exec);

	if (test) {
		if (rc_yesno(getenv("EINFO_QUIET")))
			exit (EXIT_SUCCESS);

		einfon("Would start");
		while (argc-- > 0)
			printf(" %s", *argv++);
		printf("\n");
		eindent();
		if (uid != 0)
			einfo("as user id %d", uid);
		if (gid != 0)
			einfo("as group id %d", gid);
		if (ch_root)
			einfo("in root `%s'", ch_root);
		if (ch_dir)
			einfo("in dir `%s'", ch_dir);
		if (nicelevel != 0)
			einfo("with a priority of %d", nicelevel);
		if (name)
			einfo ("with a process name of %s", name);
		eoutdent();
		exit(EXIT_SUCCESS);
	}

	ebeginv("Detaching to start `%s'", exec);
	eindentv();

	/* Remove existing pidfile */
	if (pidfile)
		unlink(pidfile);

	if (background)
		signal_setup(SIGCHLD, handle_signal);

	if ((pid = fork()) == -1)
		eerrorx("%s: fork: %s", applet, strerror(errno));

	/* Child process - lets go! */
	if (pid == 0) {
		pid_t mypid = getpid();
		umask(numask);

#ifdef TIOCNOTTY
		tty_fd = open("/dev/tty", O_RDWR);
#endif

		devnull_fd = open("/dev/null", O_RDWR);

		if (nicelevel) {
			if (setpriority(PRIO_PROCESS, mypid, nicelevel) == -1)
				eerrorx("%s: setpritory %d: %s",
				    applet, nicelevel,
				    strerror(errno));
		}

		if (ionicec != -1 &&
		    ioprio_set(1, mypid, ionicec | ioniced) == -1)
			eerrorx("%s: ioprio_set %d %d: %s", applet,
			    ionicec, ioniced, strerror(errno));

		if (ch_root && chroot(ch_root) < 0)
			eerrorx("%s: chroot `%s': %s",
			    applet, ch_root, strerror(errno));

		if (ch_dir && chdir(ch_dir) < 0)
			eerrorx("%s: chdir `%s': %s",
			    applet, ch_dir, strerror(errno));

		if (makepidfile && pidfile) {
			fp = fopen(pidfile, "w");
			if (! fp)
				eerrorx("%s: fopen `%s': %s", applet, pidfile,
				    strerror(errno));
			fprintf(fp, "%d\n", mypid);
			fclose(fp);
		}

#ifdef HAVE_PAM
		if (changeuser != NULL) {
			pamr = pam_start("start-stop-daemon",
			    changeuser, &conv, &pamh);

			if (pamr == PAM_SUCCESS)
				pamr = pam_acct_mgmt(pamh, PAM_SILENT);
			if (pamr == PAM_SUCCESS)
				pamr = pam_open_session(pamh, PAM_SILENT);
			if (pamr != PAM_SUCCESS)
				eerrorx("%s: pam error: %s",
					applet, pam_strerror(pamh, pamr));
		}
#endif

		if (gid && setgid(gid))
			eerrorx("%s: unable to set groupid to %d",
			    applet, gid);
		if (changeuser && initgroups(changeuser, gid))
			eerrorx("%s: initgroups (%s, %d)",
			    applet, changeuser, gid);
		if (uid && setuid(uid))
			eerrorx ("%s: unable to set userid to %d",
			    applet, uid);

		/* Close any fd's to the passwd database */
		endpwent();

#ifdef TIOCNOTTY
		ioctl(tty_fd, TIOCNOTTY, 0);
		close(tty_fd);
#endif

		/* Clean the environment of any RC_ variables */
		env_list = rc_stringlist_new();
		i = 0;
		while (environ[i])
			rc_stringlist_add(env_list, environ[i++]);

#ifdef HAVE_PAM
		if (changeuser != NULL) {
			pamenv = (const char *const *)pam_getenvlist(pamh);
			if (pamenv) {
				while (*pamenv) {
					/* Don't add strings unless they set a var */
					if (strchr(*pamenv, '='))
						putenv(xstrdup(*pamenv));
					else
						unsetenv(*pamenv);
					pamenv++;
				}
			}
		}
#endif

		TAILQ_FOREACH(env, env_list, entries) {
			if ((strncmp(env->value, "RC_", 3) == 0 &&
				strncmp(env->value, "RC_SERVICE=", 10) != 0 &&
				strncmp(env->value, "RC_SVCNAME=", 10) != 0) ||
			    strncmp(env->value, "SSD_NICELEVEL=", 14) == 0)
			{
				p = strchr(env->value, '=');
				*p = '\0';
				unsetenv(env->value);
				continue;
			}
		}
		rc_stringlist_free(env_list);

		/* For the path, remove the rcscript bin dir from it */
		if ((token = getenv("PATH"))) {
			len = strlen(token);
			newpath = np = xmalloc(len + 1);
			while (token && *token) {
				p = strchr(token, ':');
				if (p) {
					*p++ = '\0';
					while (*p == ':')
						p++;
				}
				if (strcmp(token, RC_LIBEXECDIR "/bin") != 0 &&
				    strcmp(token, RC_LIBEXECDIR "/sbin") != 0)
				{
					len = strlen(token);
					if (np != newpath)
						*np++ = ':';
					memcpy(np, token, len);
					np += len;
				}
				token = p;
			}
			*np = '\0';
			unsetenv("PATH");
			setenv("PATH", newpath, 1);
		}

		stdin_fd = devnull_fd;
		stdout_fd = devnull_fd;
		stderr_fd = devnull_fd;
		if (redirect_stdout) {
			if ((stdout_fd = open(redirect_stdout,
				    O_WRONLY | O_CREAT | O_APPEND,
				    S_IRUSR | S_IWUSR)) == -1)
				eerrorx("%s: unable to open the logfile"
				    " for stdout `%s': %s",
				    applet, redirect_stdout, strerror(errno));
		}
		if (redirect_stderr) {
			if ((stderr_fd = open(redirect_stderr,
				    O_WRONLY | O_CREAT | O_APPEND,
				    S_IRUSR | S_IWUSR)) == -1)
				eerrorx("%s: unable to open the logfile"
				    " for stderr `%s': %s",
				    applet, redirect_stderr, strerror(errno));
		}

		if (background)
			dup2(stdin_fd, STDIN_FILENO);
		if (background || redirect_stdout || rc_yesno(getenv("EINFO_QUIET")))
			dup2(stdout_fd, STDOUT_FILENO);
		if (background || redirect_stderr || rc_yesno(getenv("EINFO_QUIET")))
			dup2(stderr_fd, STDERR_FILENO);

		for (i = getdtablesize() - 1; i >= 3; --i)
			close(i);

		setsid();
		execvp(exec, argv);
#ifdef HAVE_PAM
		if (changeuser != NULL && pamr == PAM_SUCCESS)
			pam_close_session(pamh, PAM_SILENT);
#endif
		eerrorx("%s: failed to exec `%s': %s",
		    applet, exec,strerror(errno));
	}
Exemplo n.º 25
0
/* This state machine is based on the one from udhcpc
   written by Russ Dill */
int dhcp_run (options_t *options)
{
  interface_t *iface;
  int mode = SOCKET_CLOSED;
  int state = STATE_INIT;
  struct timeval tv;
  int xid = 0;
  long timeout = 0;
  fd_set rset;
  int maxfd;
  int retval;
  dhcpmessage_t message;
  dhcp_t *dhcp;
  int type = DHCP_DISCOVER;
  int last_type = DHCP_DISCOVER;
  bool daemonised = false;
  unsigned long start = 0;
  unsigned long last_send = 0;
  int sig;
  unsigned char *buffer = NULL;
  int buffer_len = 0;
  int buffer_pos = 0;

  if (! options || (iface = (read_interface (options->interface,
					     options->metric))) == NULL)
    return -1;

  /* Remove all existing addresses.
     After all, we ARE a DHCP client whose job it is to configure the
     interface. We only do this on start, so persistent addresses can be added
     afterwards by the user if needed. */
  flush_addresses (iface->name);

  dhcp = xmalloc (sizeof (dhcp_t));
  memset (dhcp, 0, sizeof (dhcp_t));

  strcpy (dhcp->classid, options->classid);
  if (options->clientid[0])
    strcpy (dhcp->clientid, options->clientid);
  else
    sprintf (dhcp->clientid, "%s", ether_ntoa (&iface->ethernet_address));

  if (options->requestaddress.s_addr != 0)
    dhcp->address.s_addr = options->requestaddress.s_addr;

  signal_setup ();

  while (1)
    {
      if (timeout > 0 || (options->timeout == 0 &&
			  (state != STATE_INIT || xid)))
	{
	  if (options->timeout == 0 || dhcp->leasetime == -1)
	    {
	      logger (LOG_DEBUG, "waiting on select for infinity");
	      maxfd = signal_fd_set (&rset, iface->fd);
	      retval = select (maxfd + 1, &rset, NULL, NULL, NULL);
	    }
	  else
	    {
	      /* Resend our message if we're getting loads of packets
		 that aren't for us. This mainly happens on Linux as it
		 doesn't have a nice BPF filter. */
	      if (iface->fd > -1 && uptime () - last_send >= TIMEOUT_MINI)
		SEND_MESSAGE (last_type);

	      logger (LOG_DEBUG, "waiting on select for %d seconds",
		      timeout);
	      /* If we're waiting for a reply, then we re-send the last
		 DHCP request periodically in-case of a bad line */
	      retval = 0;
	      while (timeout > 0 && retval == 0)
		{
		  if (iface->fd == -1)
		    tv.tv_sec = SELECT_MAX;
		  else
		    tv.tv_sec = TIMEOUT_MINI;
		  if (timeout < tv.tv_sec)
		    tv.tv_sec = timeout;
		  tv.tv_usec = 0;
		  start = uptime ();
		  maxfd = signal_fd_set (&rset, iface->fd);
		  retval = select (maxfd + 1, &rset, NULL, NULL, &tv);
		  timeout -= uptime () - start;
		  if (retval == 0 && iface->fd != -1 && timeout > 0)
		    SEND_MESSAGE (last_type);
		}
	    }
	}
      else
	retval = 0;

      /* We should always handle our signals first */
      if (retval > 0 && (sig = signal_read (&rset)))
	{
	  switch (sig)
	    {
	    case SIGINT:
	      logger (LOG_INFO, "receieved SIGINT, stopping");
	      retval = 0;
	      goto eexit;

	    case SIGTERM:
	      logger (LOG_INFO, "receieved SIGTERM, stopping");
	      retval = 0;
	      goto eexit;

	    case SIGALRM:

	      logger (LOG_INFO, "receieved SIGALRM, renewing lease");
	      switch (state)
		{
		case STATE_BOUND:
		case STATE_RENEWING:
		case STATE_REBINDING:
		  state = STATE_RENEW_REQUESTED;
		  break;
		case STATE_RENEW_REQUESTED:
		case STATE_REQUESTING:
		case STATE_RELEASED:
		  state = STATE_INIT;
		  break;
		}

	      timeout = 0;
	      xid = 0;
	      break;

	    case SIGHUP:
	      if (state == STATE_BOUND || state == STATE_RENEWING
		  || state == STATE_REBINDING)
		{
		  logger (LOG_INFO, "received SIGHUP, releasing lease");
		  SOCKET_MODE (SOCKET_OPEN);
		  xid = random_xid ();
		  if ((open_socket (iface, false)) >= 0)
		    SEND_MESSAGE (DHCP_RELEASE);
		  SOCKET_MODE (SOCKET_CLOSED);
		  unlink (iface->infofile);
		}
	      else
		logger (LOG_ERR,
			"receieved SIGUP, but no we have lease to release");
	      retval = 0;
	      goto eexit;

	    default:
	      logger (LOG_ERR,
		      "received signal %d, but don't know what to do with it",
		      sig);
	    }
	}
      else if (retval == 0) /* timed out */
	{
	  switch (state)
	    {
	    case STATE_INIT:
	      if (iface->previous_address.s_addr != 0)
		{
		  logger (LOG_ERR, "lost lease");
		  xid = 0;
		  SOCKET_MODE (SOCKET_CLOSED);
		  if (! options->persistent)
		    {
		      free_dhcp (dhcp);
		      memset (dhcp, 0, sizeof (dhcp_t));
		      configure (options, iface, dhcp);
		    }
		  if (! daemonised)
		    {
		      retval = -1;
		      goto eexit;
		    }
		  break;
		}

	      if (xid == 0)
		xid = random_xid ();
	      else
		{
		  logger (LOG_ERR, "timed out");
		  if (! daemonised)
		    {
		      retval = -1;
		      goto eexit;
		    }
		}

	      SOCKET_MODE (SOCKET_OPEN);
	      timeout = options->timeout;
	      iface->start_uptime = uptime ();
	      if (dhcp->address.s_addr == 0)
		{
		  logger (LOG_INFO, "broadcasting for a lease");
		  SEND_MESSAGE (DHCP_DISCOVER);
		}
	      else
		{
		  logger (LOG_INFO, "broadcasting for a lease of %s",
			  inet_ntoa (dhcp->address));
		  SEND_MESSAGE (DHCP_REQUEST);
		  state = STATE_REQUESTING;
		}

	      break;
	    case STATE_BOUND:
	    case STATE_RENEW_REQUESTED:
	      state = STATE_RENEWING;
	      xid = random_xid ();
	    case STATE_RENEWING:
	      iface->start_uptime = uptime ();
	      logger (LOG_INFO, "renewing lease of %s", inet_ntoa
		      (dhcp->address));
	      SOCKET_MODE (SOCKET_OPEN);
	      SEND_MESSAGE (DHCP_REQUEST);
	      timeout = dhcp->rebindtime - dhcp->renewaltime;
	      state = STATE_REBINDING;
	      break;
	    case STATE_REBINDING:
	      logger (LOG_ERR, "lost lease, attemping to rebind");
	      SOCKET_MODE (SOCKET_OPEN);
	      SEND_MESSAGE (DHCP_DISCOVER);
	      timeout = dhcp->leasetime - dhcp->rebindtime;
	      state = STATE_INIT;
	      break;
	    case STATE_REQUESTING:
	      logger (LOG_ERR, "timed out");
	      if (! daemonised)
		goto eexit;

	      state = STATE_INIT;
	      SOCKET_MODE (SOCKET_CLOSED);
	      timeout = 0;
	      xid = 0;
	      free_dhcp (dhcp);
	      memset (dhcp, 0, sizeof (dhcp_t));
	      break;

	    case STATE_RELEASED:
	      dhcp->leasetime = -1;
	      break;
	    }
	}
      else if (retval > 0 && mode != SOCKET_CLOSED && FD_ISSET(iface->fd, &rset))
	{

	  /* Allocate our buffer space for BPF.
	     We cannot do this until we have opened our socket as we don't
	     know how much of a buffer we need until then. */
	  if (! buffer)
	    buffer = xmalloc (iface->buffer_length);
	  buffer_len = iface->buffer_length;
	  buffer_pos = -1;

	  /* We loop through until our buffer is empty.
	     The benefit is that if we get >1 DHCP packet in our buffer and
	     the first one fails for any reason, we can use the next. */

	  memset (&message, 0, sizeof (struct dhcpmessage_t));
	  int valid = 0;
	  struct dhcp_t *new_dhcp;
	  new_dhcp = xmalloc (sizeof (dhcp_t));

	  while (buffer_pos != 0)
	    {
	      if (get_packet (iface, (unsigned char *) &message, buffer,
			      &buffer_len, &buffer_pos) < 0)
		break;

	      if (xid != message.xid)
		{
		  logger (LOG_ERR,
			  "ignoring packet with xid %d as it's not ours (%d)",
			  message.xid, xid);
		  continue;
		}

	      logger (LOG_DEBUG, "got a packet with xid %d", message.xid);
	      memset (new_dhcp, 0, sizeof (dhcp_t));
	      if ((type = parse_dhcpmessage (new_dhcp, &message)) < 0)
		{
		  logger (LOG_ERR, "failed to parse packet");
		  free_dhcp (new_dhcp);
		  continue;
		}

	      /* If we got here then the DHCP packet is valid and appears to
		 be for us, so let's clear the buffer as we don't care about
		 any more DHCP packets at this point. */
	      valid = 1;
	      break;
	    }

	  /* No packets for us, so wait until we get one */
	  if (! valid)
	    {
	      free (new_dhcp);
	      continue;
	    }

	  /* new_dhcp is now our master DHCP message */
	  free_dhcp (dhcp);
	  free (dhcp);
	  dhcp = new_dhcp;
	  new_dhcp = NULL;

	  /* We should restart on a NAK */
	  if (type == DHCP_NAK)
	    {
	      logger (LOG_INFO, "received NAK: %s", dhcp->message);
	      state = STATE_INIT;
	      timeout = 0;
	      xid = 0;
	      free_dhcp (dhcp);
	      memset (dhcp, 0, sizeof (dhcp_t));
	      configure (options, iface, dhcp);
	      continue;
	    }

	  switch (state)
	    {
	    case STATE_INIT:
	      if (type == DHCP_OFFER)
		{
		  logger (LOG_INFO, "offered lease of %s",
			  inet_ntoa (dhcp->address));

		  SEND_MESSAGE (DHCP_REQUEST);
		  state = STATE_REQUESTING;
		}
	      break;

	    case STATE_RENEW_REQUESTED:
	    case STATE_REQUESTING:
	    case STATE_RENEWING:
	    case STATE_REBINDING:
	      if (type == DHCP_ACK)
		{
		  SOCKET_MODE (SOCKET_CLOSED);
		  if (options->doarp && iface->previous_address.s_addr !=
		      dhcp->address.s_addr)
		    {
		      if (arp_check (iface, dhcp->address))
			{
			  SOCKET_MODE (SOCKET_OPEN);
			  SEND_MESSAGE (DHCP_DECLINE);
			  SOCKET_MODE (SOCKET_CLOSED);
			  free_dhcp (dhcp);
			  memset (dhcp, 0, sizeof (dhcp));
			  if (daemonised)
			    configure (options, iface, dhcp);

			  xid = 0;
			  state = STATE_INIT;
			  /* RFC 2131 says that we should wait for 10 seconds
			     before doing anything else */
			  sleep (10);
			  continue;
			}
		    }

		  if (! dhcp->leasetime)
		    {
		      dhcp->leasetime = DEFAULT_TIMEOUT;
		      logger(LOG_INFO,
			     "no lease time supplied, assuming %d seconds",
			     dhcp->leasetime);
		    }

		  if (! dhcp->renewaltime) 
		    {
		      dhcp->renewaltime = dhcp->leasetime / 2;
		      logger (LOG_INFO,
			      "no renewal time supplied, assuming %d seconds",
			      dhcp->renewaltime);
		    }

		  if (! dhcp->rebindtime)
		    {
		      dhcp->rebindtime = (dhcp->leasetime * 0x7) >> 3;
		      logger (LOG_INFO,
			      "no rebind time supplied, assuming %d seconds",
			      dhcp->rebindtime);
		    }

		  if (dhcp->leasetime == -1)
		    logger (LOG_INFO, "leased %s for infinity",
			    inet_ntoa (dhcp->address));
		  else
		    logger (LOG_INFO, "leased %s for %u seconds",
			    inet_ntoa (dhcp->address),
			    dhcp->leasetime, dhcp->renewaltime);

		  state = STATE_BOUND;
		  timeout = dhcp->renewaltime;
		  xid = 0;

		  if (configure (options, iface, dhcp) < 0 && ! daemonised)
		    {
		      retval = -1;
		      goto eexit;
		    }

		  if (! daemonised)
		    {
		      if ((daemonise (options->pidfile)) < 0 )
			{
			  retval = -1;
			  goto eexit;
			}
		      daemonised = true;
		    }
		}
	      else if (type == DHCP_OFFER)
		logger (LOG_INFO, "got subsequent offer of %s, ignoring ",
			inet_ntoa (dhcp->address));
	      else
		logger (LOG_ERR,
			"no idea what to do with DHCP type %d at this point",
			type);
	      break;
	    }
Exemplo n.º 26
0
int main(int argc, const char **argv)
{
  int c, len;
#ifdef HAVE_LIBPQ
  char *pass_replace = "--pg-pass=WITHHELD", *conninfo_replace = "--pg-connect=WITHHELD";
#endif

  oml_setup(&argc, argv);

  poptContext optCon = poptGetContext(NULL, argc, (const char**) argv, options, 0);

  while ((c = poptGetNextOpt(optCon)) >= 0) {
    switch (c) {
    case 'v':
      printf(V_STRING, VERSION);
      printf("OML Protocol V%d--%d\n", MIN_PROTOCOL_VERSION, MAX_PROTOCOL_VERSION);
      printf(COPYRIGHT);
      return 0;
    }
  }

#ifdef HAVE_LIBPQ
  /* Cleanup command line to avoid showing credentials in ps(1) output, amongst
   * others.
   *
   * XXX: This is a poor man's security measure, as this creates a race
   * condition where, prior to doing the following, the credentials are still
   * visible to everybody.
   */
  if (pg_pass || pg_conninfo) {
    for(c=1; c<argc; c++) {
      len = strlen(argv[c]);
      if(pg_pass && !strncmp(argv[c],"--pg-pass", 9)) {
        strncpy((char*)argv[c], pass_replace, len);
        ((char*)argv[c])[len] = 0;
      }

      if(pg_conninfo && !strncmp(argv[c],"--pg-connect", 12)) {
        strncpy((char*)argv[c], conninfo_replace, len);
        ((char*)argv[c])[len] = 0;
      }
    }
  }
#endif /* HAVE_LIBPQ */

  logging_setup (logfile_name, log_level);

  if (c < -1) {
    die ("%s: %s\n", poptBadOption (optCon, POPT_BADOPTION_NOALIAS), poptStrerror (c));
  }

  loginfo(V_STRING, VERSION);
  loginfo("OML Protocol V%d--%d\n", MIN_PROTOCOL_VERSION, MAX_PROTOCOL_VERSION);
  loginfo(COPYRIGHT);

  eventloop_init();
  eventloop_set_socket_timeout(socket_timeout);

  Socket* server_sock;
  server_sock = socket_server_new("server", NULL, listen_service, on_connect, NULL);

  if (!server_sock) {
    die ("Failed to create listening socket for service %s\n", listen_service);
  }

  drop_privileges (uidstr, gidstr);

  /* Important that this comes after drop_privileges(). */
  if(database_setup_backend(dbbackend)) {
      die("Failed to setup database backend '%s'\n", dbbackend);
  }

  signal_setup();

  hook_setup();

  eventloop_run();

  signal_cleanup();

  hook_cleanup();

  oml_cleanup();

  oml_memreport(O_LOG_INFO);

  return 0;
}
Exemplo n.º 27
0
int main(int argc, char *argv[])
{
    ex_t rc = EX_OK;

    bfpath *bfp;
    bfpath_mode mode;

    fBogoutil = true;

    signal_setup();			/* setup to catch signals */
    atexit(bf_exit);

    progtype = build_progtype(progname, DB_TYPE);

    set_today();			/* compute current date for token age */

    process_arglist(argc, argv);
    process_config_files(false, longopts_bogoutil);	/* need to read lock sizes */

    /* Extra or missing parameters */
    if (flag != M_WORD && flag != M_LIST_LOGFILES && argc != optind) {
	fprintf(stderr, "Missing or extraneous argument.\n");
	usage(stderr);
	exit(EX_ERROR);
    }

    bfp = bfpath_create(ds_file);
    if (bogohome == NULL)
	set_bogohome( "." );		/* set default */

    bfpath_set_bogohome(bfp);

    mode = get_mode(flag);
    if (bfpath_check_mode(bfp, mode)) {
	if (bfp->isdir)
	    bfpath_set_filename(bfp, WORDLIST);
    }

    if (!bfpath_check_mode(bfp, mode)) {
	fprintf(stderr, "Can't open wordlist '%s'\n", bfp->filepath);
	exit(EX_ERROR);
    }

    errno = 0;		/* clear error status */

    switch (flag) {
	case M_RECOVER:
	    ds_init(bfp);
	    rc = ds_recover(bfp, false);
	    break;
	case M_CRECOVER:
	    ds_init(bfp);
	    rc = ds_recover(bfp, true);
	    break;
	case M_CHECKPOINT:
	    ds_init(bfp);
	    rc = ds_checkpoint(bfp);
	    break;
	case M_LIST_LOGFILES:
	    dsm_init(bfp);
	    rc = ds_list_logfiles(bfp, argc - optind, argv + optind);
	    break;
	case M_PURGELOGS:
	    ds_init(bfp);
	    rc = ds_purgelogs(bfp);
	    break;
	case M_REMOVEENV:
	    dsm_init(bfp);
	    rc = ds_remove(bfp);
	    break;
	case M_VERIFY:
	    dsm_init(bfp);
	    rc = ds_verify(bfp);
	    break;
	case M_LEAFPAGES:
	    {
		u_int32_t c;

		dsm_init(bfp);
		c = ds_leafpages(bfp);
		if (c == 0xffffffff) {
		    fprintf(stderr, "%s: error getting leaf page count.\n", ds_file);
		    rc = EX_ERROR;
		} else if (c == 0) {
		    puts("UNKNOWN");
		} else {
		    printf("%lu\n", (unsigned long)c);
		}
	    }
	    break;
	case M_PAGESIZE:
	    {
		u_int32_t s;

		dsm_init(bfp);
		s = ds_pagesize(bfp);
		if (s == 0xffffffff) {
		    fprintf(stderr, "%s: error getting page size.\n", ds_file);
		} else if (s == 0) {
		    puts("UNKNOWN");
		} else {
		    printf("%lu\n", (unsigned long)s);
		}
	    }
	    break;
	case M_DUMP:
	    rc = dump_wordlist(bfp);
	    break;
	case M_LOAD:
	    rc = load_wordlist(bfp) ? EX_ERROR : EX_OK;
	    break;
	case M_MAINTAIN:
	    maintain = true;
	    rc = maintain_wordlist_file(bfp);
	    break;
	case M_WORD:
	    argc -= optind;
	    argv += optind;
	    rc = display_words(bfp, argc, argv, prob);
	    break;
	case M_HIST:
	    rc = histogram(bfp);
	    break;
	case M_ROBX:
	    rc = get_robx(bfp);
	    break;
	case M_NONE:
	default:
	    /* should have been handled above */
	    abort();
	    break;
    }

    bfpath_free(bfp);

    return rc;
}
Exemplo n.º 28
0
int main(int argc, char **argv)
{
	int opt;
	bool start = false;
	bool stop = false;
	char *exec = NULL;
	char *pidfile = NULL;
	char *home = NULL;
	int tid = 0;
	pid_t child_pid, pid;
	char *svcname = getenv("RC_SVCNAME");
	char *tmp;
	char *p;
	char *token;
	int i;
	char exec_file[PATH_MAX];
	struct passwd *pw;
	struct group *gr;
	FILE *fp;
	mode_t numask = 022;

	applet = basename_c(argv[0]);
	atexit(cleanup);

	signal_setup(SIGINT, handle_signal);
	signal_setup(SIGQUIT, handle_signal);
	signal_setup(SIGTERM, handle_signal);
	openlog(applet, LOG_PID, LOG_DAEMON);

	if ((tmp = getenv("SSD_NICELEVEL")))
		if (sscanf(tmp, "%d", &nicelevel) != 1)
			eerror("%s: invalid nice level `%s' (SSD_NICELEVEL)",
			    applet, tmp);

	/* Get our user name and initial dir */
	p = getenv("USER");
	home = getenv("HOME");
	if (home == NULL || p == NULL) {
		pw = getpwuid(getuid());
		if (pw != NULL) {
			if (p == NULL)
				setenv("USER", pw->pw_name, 1);
			if (home == NULL) {
				setenv("HOME", pw->pw_dir, 1);
				home = pw->pw_dir;
			}
		}
	}

	while ((opt = getopt_long(argc, argv, getoptstring, longopts,
		    (int *) 0)) != -1)
		switch (opt) {
		case 'I': /* --ionice */
			if (sscanf(optarg, "%d:%d", &ionicec, &ioniced) == 0)
				eerrorx("%s: invalid ionice `%s'",
				    applet, optarg);
			if (ionicec == 0)
				ioniced = 0;
			else if (ionicec == 3)
				ioniced = 7;
			ionicec <<= 13; /* class shift */
			break;

		case 'K':  /* --stop */
			stop = true;
			break;

		case 'N':  /* --nice */
			if (sscanf(optarg, "%d", &nicelevel) != 1)
				eerrorx("%s: invalid nice level `%s'",
				    applet, optarg);
			break;

		case 'S':  /* --start */
			start = true;
			break;

		case 'd':  /* --chdir /new/dir */
			ch_dir = optarg;
			break;

		case 'e': /* --env */
			putenv(optarg);
			break;

		case 'g':  /* --group <group>|<gid> */
			if (sscanf(optarg, "%d", &tid) != 1)
				gr = getgrnam(optarg);
			else
				gr = getgrgid((gid_t)tid);
			if (gr == NULL)
				eerrorx("%s: group `%s' not found",
				    applet, optarg);
			gid = gr->gr_gid;
			break;

		case 'k':
			if (parse_mode(&numask, optarg))
				eerrorx("%s: invalid mode `%s'",
				    applet, optarg);
			break;

		case 'p':  /* --pidfile <pid-file> */
			pidfile = optarg;
			break;

		case 'r':  /* --chroot /new/root */
			ch_root = optarg;
			break;

		case 'u':  /* --user <username>|<uid> */
		{
			p = optarg;
			tmp = strsep(&p, ":");
			changeuser = xstrdup(tmp);
			if (sscanf(tmp, "%d", &tid) != 1)
				pw = getpwnam(tmp);
			else
				pw = getpwuid((uid_t)tid);

			if (pw == NULL)
				eerrorx("%s: user `%s' not found",
				    applet, tmp);
			uid = pw->pw_uid;
			home = pw->pw_dir;
			unsetenv("HOME");
			if (pw->pw_dir)
				setenv("HOME", pw->pw_dir, 1);
			unsetenv("USER");
			if (pw->pw_name)
				setenv("USER", pw->pw_name, 1);
			if (gid == 0)
				gid = pw->pw_gid;

			if (p) {
				tmp = strsep (&p, ":");
				if (sscanf(tmp, "%d", &tid) != 1)
					gr = getgrnam(tmp);
				else
					gr = getgrgid((gid_t) tid);

				if (gr == NULL)
					eerrorx("%s: group `%s'"
					    " not found",
					    applet, tmp);
				gid = gr->gr_gid;
			}
		}
		break;

		case '1':   /* --stdout /path/to/stdout.lgfile */
			redirect_stdout = optarg;
			break;

		case '2':  /* --stderr /path/to/stderr.logfile */
			redirect_stderr = optarg;
			break;

		case_RC_COMMON_GETOPT
		}

	if (!pidfile)
		eerrorx("%s: --pidfile must be specified", applet);

	endpwent();
	argc -= optind;
	argv += optind;
	exec = *argv;

	if (start) {
		if (!exec)
			eerrorx("%s: nothing to start", applet);
	}

	/* Expand ~ */
	if (ch_dir && *ch_dir == '~')
		ch_dir = expand_home(home, ch_dir);
	if (ch_root && *ch_root == '~')
		ch_root = expand_home(home, ch_root);
	if (exec) {
		if (*exec == '~')
			exec = expand_home(home, exec);

		/* Validate that the binary exists if we are starting */
		if (*exec == '/' || *exec == '.') {
			/* Full or relative path */
			if (ch_root)
				snprintf(exec_file, sizeof(exec_file),
				    "%s/%s", ch_root, exec);
			else
				snprintf(exec_file, sizeof(exec_file),
				    "%s", exec);
		} else {
			/* Something in $PATH */
			p = tmp = xstrdup(getenv("PATH"));
			*exec_file = '\0';
			while ((token = strsep(&p, ":"))) {
				if (ch_root)
					snprintf(exec_file, sizeof(exec_file),
					    "%s/%s/%s",
					    ch_root, token, exec);
				else
					snprintf(exec_file, sizeof(exec_file),
					    "%s/%s", token, exec);
				if (exists(exec_file))
					break;
				*exec_file = '\0';
			}
			free(tmp);
		}
	}
	if (start && !exists(exec_file))
		eerrorx("%s: %s does not exist", applet,
		    *exec_file ? exec_file : exec);

	if (stop) {
		pid = get_pid(pidfile);
		if (pid == -1)
			i = pid;
		else
			i = kill(pid, SIGTERM);
		if (i != 0)
			/* We failed to stop something */
			exit(EXIT_FAILURE);

		/* Even if we have not actually killed anything, we should
		 * remove information about it as it may have unexpectedly
		 * crashed out. We should also return success as the end
		 * result would be the same. */
		if (pidfile && exists(pidfile))
			unlink(pidfile);
		if (svcname)
			rc_service_daemon_set(svcname, exec,
			    (const char *const *)argv,
			    pidfile, false);
		exit(EXIT_SUCCESS);
	}

	pid = get_pid(pidfile);
	if (pid != -1)
		if (kill(pid, 0) == 0)
			eerrorx("%s: %s is already running", applet, exec);

	einfov("Detaching to start `%s'", exec);
	eindentv();

	/* Remove existing pidfile */
	if (pidfile)
		unlink(pidfile);

	/*
	 * Make sure we can write a pid file
	 */
	fp = fopen(pidfile, "w");
	if (! fp)
		eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
		fclose(fp);

	child_pid = fork();
	if (child_pid == -1)
		eerrorx("%s: fork: %s", applet, strerror(errno));

	/* first parent process, do nothing. */
	if (child_pid != 0)
		exit(EXIT_SUCCESS);

	child_pid = fork();
	if (child_pid == -1)
		eerrorx("%s: fork: %s", applet, strerror(errno));

	if (child_pid != 0) {
		/* this is the supervisor */
		umask(numask);

#ifdef TIOCNOTTY
		tty_fd = open("/dev/tty", O_RDWR);
#endif

		devnull_fd = open("/dev/null", O_RDWR);

		fp = fopen(pidfile, "w");
		if (! fp)
			eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
		fprintf(fp, "%d\n", getpid());
		fclose(fp);

		/*
		 * Supervisor main loop
		 */
		i = 0;
		while (!exiting) {
			wait(&i);
			if (exiting) {
				syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid);
				kill(child_pid, SIGTERM);
			} else {
				if (WIFEXITED(i))
					syslog(LOG_INFO, "%s, pid %d, exited with return code %d",
							exec, child_pid, WEXITSTATUS(i));
				else if (WIFSIGNALED(i))
					syslog(LOG_INFO, "%s, pid %d, terminated by signal %d",
							exec, child_pid, WTERMSIG(i));
				child_pid = fork();
				if (child_pid == -1)
					eerrorx("%s: fork: %s", applet, strerror(errno));
				if (child_pid == 0)
					child_process(exec, argv);
			}
		}

		if (svcname)
			rc_service_daemon_set(svcname, exec,
									(const char * const *) argv, pidfile, true);

		exit(EXIT_SUCCESS);
	} else if (child_pid == 0)
		child_process(exec, argv);
}
Exemplo n.º 29
0
int main (int argc, char *argv[])
{
    coproc_t *c;
    int i;
    int rc;

    plan (29);

    ok ((c = coproc_create (foo_cb)) != NULL,
        "coproc_create works");

    i = 0;
    rc = -1;
    ok (coproc_start (c, &i) == 0,
        "coproc_start works");
    ok (coproc_returned (c, &rc),
        "coproc returned");
    cmp_ok (rc, "==", 0,
        "rc is set to coproc return value");

    i = 2;
    rc = -1;
    ok (coproc_start (c, &i) == 0,
        "coproc_start works");
    ok (!coproc_returned (c, NULL),
        "coproc did not return (yielded)");

    ok (coproc_resume (c) == 0,
        "coproc_resume works");
    ok (!coproc_returned (c, NULL),
        "coproc did not return (yielded)");

    ok (coproc_resume (c) == 0,
        "coproc_resume works");
    ok (coproc_returned (c, &rc),
        "coproc returned");
    cmp_ok (rc, "==", 0,
        "rc is set to coproc return value");

    errno = 0;
    ok (coproc_resume (c) < 0 && errno == EINVAL,
        "coproc_resume on returned coproc fails with EINVAL");

    coproc_destroy (c);

    pthread_t t;
    ok (pthread_create (&t, NULL, threadmain, NULL) == 0,
        "pthread_create OK");
    ok (pthread_join (t, NULL) == 0,
        "pthread_join OK");

    coproc_t *cps[10000];
    for (i = 0; i < 10000; i++) {
        if (!(cps[i] = coproc_create (bar_cb)))
            break;
        if (coproc_start (cps[i], NULL) < 0 || coproc_returned (cps[i], NULL))
            break;
    }
    ok (i == 10000,
        "started 10000 coprocs that yielded");
    for (i = 0; i < 10000; i++) {
        if (coproc_resume (cps[i]) < 0 || coproc_returned (cps[i], NULL))
            break;
    }
    ok (i == 10000,
        "resumed 10000 coprocs that yielded");
    death = true;
    for (i = 0; i < 10000; i++) {
        if (coproc_resume (cps[i]) < 0 || !coproc_returned (cps[i], &rc)
                                       || rc != 0)
            break;
    }
    ok (i == 10000,
        "resumed 10000 coprocs that exited with rc=0");

    for (i = 0; i < 10000; i++)
        coproc_destroy (cps[i]);

    /* Test stack guard page(s)
     */
    ok (signal_setup () == 0,
        "installed SIGSEGV handler with sigaltstack");
    ok ((co = coproc_create (stack_cb)) != NULL,
        "coproc_create works");
    size_t ssize = coproc_get_stacksize (co);
    ok (ssize > 0,
        "coproc_get_stacksize returned %d", ssize);

    /* We can't use all of the stack and get away with it.
     * FIXME: it is unclear why this number must be so large.
     * I found it experimentally; maybe it is non-portable and that
     * will make this test fragile?
     */
    //const size_t stack_reserve = 2560; // XXX 2540 is too small
    const size_t stack_reserve = 3000;

    /* should be OK */
    ssize -= stack_reserve;
    ok (coproc_start (co, &ssize) == 0,
        "coproc_start works");
    rc = -1;
    ok (coproc_returned (co, &rc) && rc == 0,
        "coproc successfully scribbled on stack");

    /* should fail */
    ssize += stack_reserve + 8;
    ok (coproc_start (co, &ssize) == 0,
        "coproc_start works");
    ok (!coproc_returned (co, NULL),
        "coproc scribbled on guard page and segfaulted");

    done_testing ();

}
Exemplo n.º 30
0
int
main(int argc, char* argv[])
{
	signal_setup();

	fprintf(stdout, "\nACT version %s\n", VERSION);
	fprintf(stdout, "Storage device IO test\n");
	fprintf(stdout, "Copyright 2018 by Aerospike. All rights reserved.\n\n");

	if (! storage_configure(argc, argv)) {
		exit(-1);
	}

	device devices[g_scfg.num_devices];
	queue* trans_qs[g_scfg.num_queues];

	g_devices = devices;
	g_trans_qs = trans_qs;

	histogram_scale scale =
			g_scfg.us_histograms ? HIST_MICROSECONDS : HIST_MILLISECONDS;

	if (! (g_large_block_read_hist = histogram_create(scale)) ||
		! (g_large_block_write_hist = histogram_create(scale)) ||
		! (g_raw_read_hist = histogram_create(scale)) ||
		! (g_read_hist = histogram_create(scale)) ||
		! (g_raw_write_hist = histogram_create(scale)) ||
		! (g_write_hist = histogram_create(scale))) {
		exit(-1);
	}

	for (uint32_t n = 0; n < g_scfg.num_devices; n++) {
		device* dev = &g_devices[n];

		dev->name = (const char*)g_scfg.device_names[n];

		if (g_scfg.file_size == 0) { // normally 0
			set_scheduler(dev->name, g_scfg.scheduler_mode);
		}

		if (! (dev->fd_q = queue_create(sizeof(int), true)) ||
			! discover_device(dev) ||
			! (dev->raw_read_hist = histogram_create(scale)) ||
			! (dev->raw_write_hist = histogram_create(scale))) {
			exit(-1);
		}

		sprintf(dev->read_hist_tag, "%s-reads", dev->name);
		sprintf(dev->write_hist_tag, "%s-writes", dev->name);
	}

	rand_seed();

	g_run_start_us = get_us();

	uint64_t run_stop_us = g_run_start_us + g_scfg.run_us;

	g_running = true;

	if (g_scfg.write_reqs_per_sec != 0) {
		for (uint32_t n = 0; n < g_scfg.num_devices; n++) {
			device* dev = &g_devices[n];

			if (pthread_create(&dev->large_block_read_thread, NULL,
					run_large_block_reads, (void*)dev) != 0) {
				fprintf(stdout, "ERROR: create large op read thread\n");
				exit(-1);
			}

			if (pthread_create(&dev->large_block_write_thread, NULL,
					run_large_block_writes, (void*)dev) != 0) {
				fprintf(stdout, "ERROR: create large op write thread\n");
				exit(-1);
			}
		}
	}

	if (g_scfg.tomb_raider) {
		for (uint32_t n = 0; n < g_scfg.num_devices; n++) {
			device* dev = &g_devices[n];

			if (pthread_create(&dev->tomb_raider_thread, NULL,
					run_tomb_raider, (void*)dev) != 0) {
				fprintf(stdout, "ERROR: create tomb raider thread\n");
				exit(-1);
			}
		}
	}

	uint32_t n_trans_tids = g_scfg.num_queues * g_scfg.threads_per_queue;
	pthread_t trans_tids[n_trans_tids];

	for (uint32_t i = 0; i < g_scfg.num_queues; i++) {
		if (! (g_trans_qs[i] = queue_create(sizeof(trans_req), true))) {
			exit(-1);
		}

		for (uint32_t j = 0; j < g_scfg.threads_per_queue; j++) {
			if (pthread_create(&trans_tids[(i * g_scfg.threads_per_queue) + j],
					NULL, run_transactions, (void*)g_trans_qs[i]) != 0) {
				fprintf(stdout, "ERROR: create transaction thread\n");
				exit(-1);
			}
		}
	}

	// Equivalent: g_scfg.internal_read_reqs_per_sec != 0.
	bool do_reads = g_scfg.read_reqs_per_sec != 0;

	pthread_t read_req_tids[g_scfg.read_req_threads];

	if (do_reads) {
		for (uint32_t k = 0; k < g_scfg.read_req_threads; k++) {
			if (pthread_create(&read_req_tids[k], NULL, run_generate_read_reqs,
					NULL) != 0) {
				fprintf(stdout, "ERROR: create read request thread\n");
				exit(-1);
			}
		}
	}

	// Equivalent: g_scfg.internal_write_reqs_per_sec != 0.
	bool do_commits = g_scfg.commit_to_device && g_scfg.write_reqs_per_sec != 0;

	pthread_t write_req_tids[g_scfg.write_req_threads];

	if (do_commits) {
		for (uint32_t k = 0; k < g_scfg.write_req_threads; k++) {
			if (pthread_create(&write_req_tids[k], NULL,
					run_generate_write_reqs, NULL) != 0) {
				fprintf(stdout, "ERROR: create write request thread\n");
				exit(-1);
			}
		}
	}

	fprintf(stdout, "\nHISTOGRAM NAMES\n");

	if (do_reads) {
		fprintf(stdout, "reads\n");
		fprintf(stdout, "device-reads\n");

		for (uint32_t d = 0; d < g_scfg.num_devices; d++) {
			fprintf(stdout, "%s\n", g_devices[d].read_hist_tag);
		}
	}

	if (g_scfg.write_reqs_per_sec != 0) {
		fprintf(stdout, "large-block-reads\n");
		fprintf(stdout, "large-block-writes\n");
	}

	if (do_commits) {
		fprintf(stdout, "writes\n");
		fprintf(stdout, "device-writes\n");

		for (uint32_t d = 0; d < g_scfg.num_devices; d++) {
			fprintf(stdout, "%s\n", g_devices[d].write_hist_tag);
		}
	}

	fprintf(stdout, "\n");

	uint64_t now_us = 0;
	uint64_t count = 0;

	while (g_running && (now_us = get_us()) < run_stop_us) {
		count++;

		int64_t sleep_us = (int64_t)
				((count * g_scfg.report_interval_us) -
						(now_us - g_run_start_us));

		if (sleep_us > 0) {
			usleep((uint32_t)sleep_us);
		}

		fprintf(stdout, "after %" PRIu64 " sec:\n",
				(count * g_scfg.report_interval_us) / 1000000);

		fprintf(stdout, "requests-queued: %" PRIu32 "\n",
				atomic32_get(g_reqs_queued));

		if (do_reads) {
			histogram_dump(g_read_hist, "reads");
			histogram_dump(g_raw_read_hist, "device-reads");

			for (uint32_t d = 0; d < g_scfg.num_devices; d++) {
				histogram_dump(g_devices[d].raw_read_hist,
						g_devices[d].read_hist_tag);
			}
		}

		if (g_scfg.write_reqs_per_sec != 0) {
			histogram_dump(g_large_block_read_hist, "large-block-reads");
			histogram_dump(g_large_block_write_hist, "large-block-writes");
		}

		if (do_commits) {
			histogram_dump(g_write_hist, "writes");
			histogram_dump(g_raw_write_hist, "device-writes");

			for (uint32_t d = 0; d < g_scfg.num_devices; d++) {
				histogram_dump(g_devices[d].raw_write_hist,
						g_devices[d].write_hist_tag);
			}
		}

		fprintf(stdout, "\n");
		fflush(stdout);
	}

	g_running = false;

	if (do_reads) {
		for (uint32_t k = 0; k < g_scfg.read_req_threads; k++) {
			pthread_join(read_req_tids[k], NULL);
		}
	}

	if (do_commits) {
		for (uint32_t k = 0; k < g_scfg.write_req_threads; k++) {
			pthread_join(write_req_tids[k], NULL);
		}
	}

	for (uint32_t j = 0; j < n_trans_tids; j++) {
		pthread_join(trans_tids[j], NULL);
	}

	for (uint32_t i = 0; i < g_scfg.num_queues; i++) {
		queue_destroy(g_trans_qs[i]);
	}

	for (uint32_t d = 0; d < g_scfg.num_devices; d++) {
		device* dev = &g_devices[d];

		if (g_scfg.tomb_raider) {
			pthread_join(dev->tomb_raider_thread, NULL);
		}

		if (g_scfg.write_reqs_per_sec != 0) {
			pthread_join(dev->large_block_read_thread, NULL);
			pthread_join(dev->large_block_write_thread, NULL);
		}

		fd_close_all(dev);
		queue_destroy(dev->fd_q);
		free(dev->raw_read_hist);
		free(dev->raw_write_hist);
	}

	free(g_large_block_read_hist);
	free(g_large_block_write_hist);
	free(g_raw_read_hist);
	free(g_read_hist);
	free(g_raw_write_hist);
	free(g_write_hist);

	return 0;
}