Exemple #1
0
void sploit_shutdown(void)
{
  ssl_shutdown();
  net_shutdown();
  str_shutdown();
  io_shutdown();
  dlink_shutdown();
  queue_shutdown();
  log_shutdown();
  timer_shutdown();
  mem_shutdown();
  
  syscall_exit(1);
}
Exemple #2
0
/*************************************************************
** MAIN
**	Reads the config file. Binds to a port. Launches the
**	worker and other threads. Listens for requests.
*/
int 
main(int argc, char **argv)
{
	char *		conf	= NULL;
	int	 	nthreads;
	int	 	c, ret;
	char**	 	ary;
	char*	 	prog;
	u_int		numfds		= 0;
	int	 	xerror;
	int	 	bg_flag	= TRUE;
	int	 	only_check_config;
	char		ebuf[BUFSIZ];
	char		nbuf[64];
	u_char *	gifimage	= NULL;
	u_char *	favicon		= NULL;
	int 		gifimagelen	= 0;
	int 		faviconlen	= 0;
	TPOOL_CTX *	tpool_ctx	= NULL;
	DEBUGS *	dp;
	LISTEN_CTX	*gctx		= NULL;
	LISTEN_CTX	*dctx		= NULL;
	LISTEN_CTX	*jctx		= NULL;
	pthread_t	gif_tid;
	pthread_t	data_tid;
	pthread_t	upload_tid;
#if HAVE_RESOURCE_H || HAVE_SYS_RESOURCE_H
	struct rlimit	rl;
#endif
	time_t		servertimeout;
	 
	prog = basename(argv[0]);
	if (prog == NULL)
		prog = argv[0];

	only_check_config = FALSE;
	servertimeout = 20;

	while ((c = getopt(argc, argv, "C:d:c:f")) != -1)
	{
		switch (c)
		{
			case 'f':
				bg_flag = FALSE;
				break;
			case 'C':
				only_check_config = TRUE;
				/*FALLTHROUGH*/
			case 'c':
				conf = optarg;
				break;
			case 'd':
				/*
				 * Debugging turned of if in background 
				 */
				if (bg_flag == TRUE)
					break;
				for (dp = DebugNames; dp->name != NULL; dp++)
				{
					if (strncasecmp(dp->name, optarg, strlen(optarg)) == 0)
					{
						setdebug(dp->flag);
						if (dp->flag == BUG_THREADS
							    || dp->flag == BUG_ALL)
							tpool_debug_set(TRUE);
						break;
					}
				}
				if (dp->name != NULL)
					break;
				printf("Unknown debug flag: %s, select from:\n", optarg);
				for (dp = DebugNames; dp->name != NULL; dp++)
					printf("\t%s\n", dp->name);
				return 0;
			case '?':
			default:
			usage:
				printf("Usage: %s "
					"[-c /path/onepixd.conf "
					"or "
					"-C /path/onepixd.conf] "
					"-d what "
					"[-f]\n",
					prog);
				return 0;
		}
	}
	if (argc != optind)
		goto usage;

	if (conf == NULL || strlen(conf) == 0)
	{
		(void) fprintf(stderr,
			"Required Parameter \"-c configfile\" missing.\n");
		goto usage;
	}
	ret = config_read_file(conf);
	if (ret != 0)
		return 0;

	/*
	 * All errors are logged, so we need to set up
	 * logging before checking the config file.
	 */
	ary = config_lookup(CONF_LOG_FACILITY);
	if (ary == NULL)
		ret = log_init(DEFAULT_LOG_FACILITY, prog);
	else
		ret = log_init(ary[0], prog);
	if (ret != 0)
		return 0;

	ret = config_validate();
	if (ret != 0)
		return 0;
	if (ret == 0 && only_check_config == TRUE)
		(void) printf("%s: FILE IS OKAY TO USE\n", conf);
	if (only_check_config == TRUE)
		return 0;


	ary = config_lookup(CONF_HOME_DIR);
	if (ary != NULL)
	{
		if (chdir(ary[0]) != 0)
		{
			xerror = errno;
			(void) snprintf(ebuf, sizeof ebuf,
				"Attempt to chdir(\"%s\"): %s",
				ary[0], strerror(xerror));
			log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf);
			goto shutdown_server;
		}
	}

	if (util_bg(bg_flag) != 0)
	{
		(void) snprintf(ebuf, sizeof ebuf, "fork(): %s\n", strerror(errno));
		log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf);
		goto shutdown_server;
	}


#if HAVE_RESOURCE_H || HAVE_SYS_RESOURCE_H
#ifdef RLIMIT_AS
	rl.rlim_cur = RLIM_INFINITY;
	rl.rlim_max = RLIM_INFINITY;
	(void) setrlimit(RLIMIT_AS, &rl); 	/* max size virtual memory */
#endif
#ifdef RLIMIT_CPU
	rl.rlim_cur = RLIM_INFINITY;
	rl.rlim_max = RLIM_INFINITY;
	(void) setrlimit(RLIMIT_CPU, &rl);	/* unlimited CPU usage */
#endif
#ifdef RLIMIT_DATA
	rl.rlim_cur = RLIM_INFINITY;
	rl.rlim_max = RLIM_INFINITY;
	(void) setrlimit(RLIMIT_DATA, &rl);	/* unlimited memory */
#endif
#ifdef RLIMIT_FSIZE
	rl.rlim_cur = RLIM_INFINITY;
	rl.rlim_max = RLIM_INFINITY;
	(void) setrlimit(RLIMIT_FSIZE, &rl);	/* unlimited file sizes */
#endif
#ifdef RLIMIT_STACK
	rl.rlim_cur = RLIM_INFINITY;
	rl.rlim_max = RLIM_INFINITY;
	(void) setrlimit(RLIMIT_STACK, &rl);	/* unlimited stack */
#endif
#ifdef RLIMIT_CORE
	rl.rlim_cur = RLIM_INFINITY;
	rl.rlim_max = RLIM_INFINITY;
	(void) setrlimit(RLIMIT_CORE, &rl);	/* allow core dumps */
#endif
#ifdef RLIMIT_NOFILE
	rl.rlim_cur = RLIM_INFINITY;
	rl.rlim_max = RLIM_INFINITY;
	(void) setrlimit(RLIMIT_NOFILE, &rl);	/* maximum file descriptors */
	(void) getrlimit(RLIMIT_NOFILE, &rl);
	numfds = (rl.rlim_cur);

#endif
#endif /* HAVE_RESOURCE_H */

	ary = config_lookup(CONF_BECOME_USER);
	if (ary != NULL)
	{
		/*
		 * Note that setrunasuser() logs its own errors 
		 */
		if (setrunasuser(ary[0]) != 0)
			goto shutdown_server;
	}

	ary = config_lookup(CONF_NUMTHREADS);
	if (ary == NULL)
		nthreads = DEFAULT_THREADS;
	else
	{
		nthreads = strtoul(ary[0], NULL, 10);
		if (nthreads <= 0)
		{
			(void) fprintf(stderr,
				"Configuration item \"%s\" illegal value: %d.\n", 
					CONF_NUMTHREADS, nthreads);
			return 0;
		}
	}
	if (numfds == 0 || numfds > (nthreads * 3))
		numfds = nthreads * 3;
	(void) io_init(numfds);

	gifimage = gif_get1x1gif(&gifimagelen);
	if (gifimage == NULL)
	{
		(void) snprintf(ebuf, sizeof ebuf, "Load gif image: %s\n", strerror(errno));
		log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf);
		goto shutdown_server;
	}
	favicon  = gif_getfavicon_ico(&faviconlen);

	/*
	 * Prepare to launch the thread to listen for inbound
	 * gif requests.
	 */
	gctx = str_alloc(sizeof(LISTEN_CTX), 1, __FILE__, __LINE__);
	if (gctx == NULL)
	{
		(void) snprintf(ebuf, sizeof ebuf, "alloc(): %s\n", strerror(errno));
		log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf);
		goto shutdown_server;
	}
	gctx->type = LISTEN_TYPE_GIF;
	/* gif image only, no favicon */
	gctx->gifimage = gifimage;
	gctx->gifimagelen = gifimagelen;
	gctx->favicon  = NULL;
	gctx->faviconlen = 0;
	ary = config_lookup(CONF_GIF_PORT);
	if (ary == NULL)
		(void) strlcpy(gctx->port, "80", sizeof gctx->port);
	else
		(void) strlcpy(gctx->port, ary[0], sizeof gctx->port);

	ary = config_lookup(CONF_GIF_INTERFACE);
	if (ary == NULL)
		(void) strlcpy(gctx->interface, "INADDR_ANY", sizeof gctx->interface);
	else
		(void) strlcpy(gctx->interface, ary[0], sizeof gctx->interface);

	/*
	 * Everything from here down must be thread safe.
	 */

	tpool_ctx = tpool_init(nthreads, ebuf, sizeof ebuf);
	if (tpool_ctx == NULL)
		goto shutdown_server;
	gctx->tpool_ctx = tpool_ctx;


	/*
	 * The GIF server may have to bind to a privaliged port, such
	 * as port 80, so we launch it and expect it to change the
	 * user id after its bind.
	 */
	ret = pthread_create(&gif_tid, NULL, thread_listener, (void *)gctx);
	if (ret != 0)
	{
	}

	/*
	 * Prepare to launch the thread to listen for inbound
	 * data requests.
	 */
	dctx = str_alloc(sizeof(LISTEN_CTX), 1, __FILE__, __LINE__);
	if (dctx == NULL)
	{
		(void) snprintf(ebuf, sizeof ebuf, "alloc(): %s\n", strerror(errno));
		log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf);
		goto shutdown_server;
	}
	dctx->type = LISTEN_TYPE_DATA;
	/* a favicon only, no gif */
	dctx->gifimage = NULL;
	dctx->favicon  = favicon;
	dctx->gifimagelen = 0;
	dctx->faviconlen  = faviconlen;
	ary = config_lookup(CONF_DATA_PORT);
	if (ary == NULL)
		(void) strlcpy(dctx->port, "8100", sizeof dctx->port);
	else
		(void) strlcpy(dctx->port, ary[0], sizeof dctx->port);

	ary = config_lookup(CONF_DATA_INTERFACE);
	if (ary == NULL)
		(void) strlcpy(dctx->interface, "INADDR_ANY", sizeof dctx->interface);
	else
		(void) strlcpy(dctx->interface, ary[0], sizeof dctx->interface);

	dctx->tpool_ctx = tpool_ctx;

	ret = pthread_create(&data_tid, NULL, thread_listener, (void *)dctx);
	if (ret != 0)
	{
	}

	/*
	 * Prepare to launch the thread to listen for uploads of more.
	 */
	(void) verify_threads_locking_init();
	jctx = str_alloc(sizeof(LISTEN_CTX), 1, __FILE__, __LINE__);
	if (jctx == NULL)
	{
		(void) snprintf(ebuf, sizeof ebuf, "alloc(): %s\n", strerror(errno));
		log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf);
		goto shutdown_server;
	}
	jctx->type = LISTEN_TYPE_UPLOAD;
	/* a favicon only, no gif */
	jctx->gifimage = NULL;
	jctx->favicon  = favicon;
	jctx->gifimagelen = 0;
	jctx->faviconlen  = faviconlen;
	ary = config_lookup(CONF_UPLOAD_PORT);
	if (ary == NULL)
		(void) strlcpy(jctx->port, "8101", sizeof jctx->port);
	else
		(void) strlcpy(jctx->port, ary[0], sizeof jctx->port);

	ary = config_lookup(CONF_UPLOAD_INTERFACE);
	if (ary == NULL)
		(void) strlcpy(jctx->interface, "INADDR_ANY", sizeof jctx->interface);
	else
		(void) strlcpy(jctx->interface, ary[0], sizeof jctx->interface);

	jctx->tpool_ctx = tpool_ctx;

	ret = pthread_create(&upload_tid, NULL, thread_listener, (void *)jctx);
	if (ret != 0)
	{
	}

	ary = config_lookup(CONF_PIDFILE);
	if (ary != NULL)
	{
		/*
		 * Note that write_pid_file() logs its own errors 
		 */
		if (write_pid_file(ary[0]) != 0)
			goto shutdown_server;
	}

	(void) strlcpy(ebuf, "Startup: version=", sizeof ebuf);
	(void) strlcat(ebuf, VERSION, sizeof ebuf);
	(void) strlcat(ebuf, ", gif_interface=", sizeof ebuf);
	(void) strlcat(ebuf, gctx->interface, sizeof ebuf);
	(void) strlcat(ebuf, ", gif_port=", sizeof ebuf);
	(void) strlcat(ebuf, gctx->port, sizeof ebuf);
	(void) strlcat(ebuf, ", data_interface=", sizeof ebuf);
	(void) strlcat(ebuf, dctx->interface, sizeof ebuf);
	(void) strlcat(ebuf, ", data_port=", sizeof ebuf);
	(void) strlcat(ebuf, dctx->port, sizeof ebuf);
	(void) strlcat(ebuf, ", threads=", sizeof ebuf);
	(void) str_ultoa(nthreads, nbuf, sizeof nbuf);
	(void) strlcat(ebuf, nbuf, sizeof ebuf);
	log_emit(LOG_INFO, NULL, __FILE__, __LINE__, ebuf);


	Global_Die = FALSE;

	(void) signal(SIGINT,  catch_sig);
	(void) signal(SIGQUIT, catch_sig);
	(void) signal(SIGKILL, catch_sig);
	(void) signal(SIGTERM, catch_sig);
	(void) signal(SIGPIPE, SIG_IGN);

	if (Global_Die == TRUE)
		goto shutdown_server;
	(void) file_prune_garbage(&Global_Die);


shutdown_server:
	Global_Die = TRUE;

	(void) pthread_join(data_tid, NULL);
	(void) pthread_join(gif_tid, NULL);
	(void) pthread_join(upload_tid, NULL);

	(void) verify_threads_locking_shutdown();

	if (tpool_ctx != NULL)
		tpool_ctx = tpool_shutdown(tpool_ctx, ebuf, sizeof ebuf);

	if (gctx != NULL)
		gctx = str_free(gctx, __FILE__, __LINE__);
	if (dctx != NULL)
		dctx = str_free(dctx, __FILE__, __LINE__);
	if (jctx != NULL)
		jctx = str_free(jctx, __FILE__, __LINE__);
	if (gifimage != NULL)
		gifimage = str_free(gifimage, __FILE__, __LINE__);
	if (favicon != NULL)
		favicon = str_free(favicon, __FILE__, __LINE__);

	ary = config_lookup(CONF_PIDFILE);
	if (ary != NULL)
		(void) unlink(ary[0]);

	io_shutdown();
	config_shutdown();

	(void) strlcpy(ebuf, "Shutdown: version=", sizeof ebuf);
	(void) strlcat(ebuf, VERSION, sizeof ebuf);
	log_emit(LOG_INFO, NULL, __FILE__, __LINE__, ebuf);
	/*
	 * This str_shutdown must always be last.
	 */
	str_shutdown();

	return 0;
}