Exemplo n.º 1
0
/**
 * Main entry point
 */
int
main(int argc, char **argv)
{
	TRACE_FUNC_START();
	int rc;

	/* accept command-line arguments */
	while ( (rc = getopt(argc, argv, "a:b:hsdf:")) != -1) {
		switch(rc) {
		case 'a':
			pc_info.rshell_args = (int8_t *)strdup(optarg);
			if (NULL == pc_info.rshell_args) {
				TRACE_ERR("Can't strdup remote shell args!!\n");
			}
			break;
		case 'b':
			pc_info.batch_size = atoi(optarg);
			TRACE_DEBUG_LOG("Taking batch_size as %d\n", 
					pc_info.batch_size);
			break;
		case 'd':
			pc_info.daemonize = 1;
			break;
		case 'h':
			print_help(*argv);
			break;
		case 'f':
			pc_info.lua_startup_file = (uint8_t *)strdup(optarg);
			if (NULL == pc_info.lua_startup_file) {
				TRACE_ERR("Can't strdup string for lua_startup_file: %s\n",
					  strerror(errno));
			}
			TRACE_DEBUG_LOG("Taking file %s as startup\n",
					pc_info.lua_startup_file);
			load_lua_file(optarg);
			break;
		case 's':
			pc_info.rshell = 1;
			break;
		default:
			print_help(*argv);
			break;
		}
	}

	/* init_modules */
	init_modules();

	/* check if rshell and daemonize are both enabled */
	if (pc_info.daemonize && pc_info.rshell) {
		fprintf(stdout, "You cannot create a daemon process and "
			"a remote shell at the same time!\n");
		fflush(stdout);
		print_help(*argv);
		return EXIT_FAILURE;
	}
	
	/* warp to remote shell, if asked */
	if (pc_info.rshell) {
		if (pc_info.rshell_args == NULL)
			fprintf(stdout, "Using localhost and port %d by default\n",
				BRICKS_LISTEN_PORT);
		lua_kickoff(LUA_EXE_REMOTE_SHELL, pc_info.rshell_args);
		return EXIT_SUCCESS;
	}

	/* daemonize, if asked */
	if ((pc_info.daemonize && (rc=do_daemonize()) == 0) ||
	    !pc_info.daemonize) {
		if (mark_pid_file(pv.pid_file) != 0) {
			TRACE_FUNC_END();
			TRACE_ERR("Can't lock the pid file.\n"
				  "Is a previous bricks daemon already running??\n");
		}
		export_global_socket();
		lua_kickoff((pc_info.daemonize) ? 
			    LUA_EXE_SCRIPT : LUA_EXE_HOME_SHELL, NULL);
	}

	/* initialize file printing mini-module */
	print_status_file();

	/* 
	 * if the user wants to daemonize and the process 
	 * is the child, then jump to accepting requests...
	 */
	if (pc_info.daemonize && rc == 0) {
		start_listening_reqs();
	}
	
	TRACE_FUNC_END();
	clean_exit(EXIT_SUCCESS);

	/* control will never come here */
	return EXIT_SUCCESS;
}
Exemplo n.º 2
0
/*---------------------------------------------------------------------*/
void
start_listening_reqs()
{
	TRACE_BACKEND_FUNC_START();
	/* socket info about the listen sock */
	struct sockaddr_in serv; 
	int listen_fd, client_sock;
	struct kevent evlist;
	struct kevent chlist[KQUEUE_MAX_EVENTS];
	int kq, events, n;

	/* zero the struct before filling the fields */
	memset(&serv, 0, sizeof(serv));
	/* set the type of connection to TCP/IP */           
	serv.sin_family = AF_INET;
	/* set the address to any interface */                
	serv.sin_addr.s_addr = htonl(INADDR_ANY); 
	/* set the server port number */    
	serv.sin_port = htons(BRICKS_LISTEN_PORT);

	/* create bricks socket for listening remote shell requests */
	listen_fd = socket(AF_INET, SOCK_STREAM, 0);
	if (listen_fd == -1) {
		TRACE_ERR("Failed to create listening socket for bricks\n");
		TRACE_BACKEND_FUNC_END();
	}
	
	/* bind serv information to mysocket */
	if (bind(listen_fd, (struct sockaddr *)&serv, sizeof(struct sockaddr)) == -1) {
		TRACE_ERR("Failed to bind listening socket to port %d for bricks\n",
			  BRICKS_LISTEN_PORT);
		TRACE_BACKEND_FUNC_END();
	}
	
	/* start listening, allowing a queue of up to 1 pending connection */
	if (listen(listen_fd, LISTEN_BACKLOG) == -1) {
		TRACE_ERR("Failed to start listen on port %d (for bricks)\n",
			  BRICKS_LISTEN_PORT);
		TRACE_BACKEND_FUNC_END();
	}

	/* XXX - TODO: port this to kqueue version... */
	/* set up the kqueue structure */
	kq = kqueue();
	EV_SET(&chlist[listen_fd], listen_fd, EVFILT_READ, EV_ADD, 0, 0, NULL);

	/*
	 * Main loop that processes incoming remote shell commands
	 * if the remote request arrives at listen_fd, it accepts connections
	 * and creates a new 'shell'
	 * if the remote request comes from a client request, it calls
	 * the lua string command function to execute the command
	 */

	do {
		events = kevent(kq, chlist, 1, &evlist, 1, NULL);
		if (events == -1) {
			TRACE_ERR("kqueue error\n");
			TRACE_BACKEND_FUNC_END();
		}
		for (n = 0; n < events; n++) {
			/* the request is for a new shell */
			if ((int)chlist[n].ident == listen_fd) {
				client_sock = accept(listen_fd, NULL, NULL);
				if (client_sock < 0) {
					TRACE_ERR("accept failed: %s\n", strerror(errno));
					TRACE_BACKEND_FUNC_END();
				}
				lua_kickoff(LUA_EXE_STR, &client_sock);
				/* add client_sock and listen_fd for kqueueing again */
				EV_SET(&chlist[listen_fd], listen_fd, EVFILT_READ,
				       EV_ADD, 0, 0, NULL);
				EV_SET(&chlist[client_sock], client_sock, EVFILT_READ,
				       EV_ADD, 0, 0, NULL);
			}
#if 0 
			else { /* chlist[n].ident == regular sock */
				/* 
				 * if the client socket has incoming read, this means we are getting
				 * some lua commands.... execute them 
				 */
				if (events[n].events == EPOLLIN || events[n].events == EPOLLPRI) {
					lua_kickoff(LUA_EXE_STR, &events[n].data.fd);
					ev.data.fd = events[n].data.fd;
					ev.events = EPOLLIN;
					if (epoll_ctl(epoll_fd, EPOLL_CTL_MOD, ev.data.fd, &ev) == -1) {
						TRACE_ERR("Can't register client sock for epolling!\n");
						TRACE_BACKEND_FUNC_END();
					}
				} else { /* the only other epoll request is for error output.. close the socket then */
					ev.data.fd = events[n].data.fd;
					if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, ev.data.fd, &ev) == -1) {
						TRACE_ERR("Can't register client sock for epolling!\n");
						TRACE_BACKEND_FUNC_END();
					}	
					close(ev.data.fd);
				}
			}
#endif
		}
	} while (1);

	TRACE_BACKEND_FUNC_END();
}
Exemplo n.º 3
0
/*---------------------------------------------------------------------*/
void
start_listening_reqs()
{
	TRACE_BACKEND_FUNC_START();
	/* socket info about the listen sock */
	struct sockaddr_in serv; 
	int listen_fd, client_sock;
	struct epoll_event ev, events[EPOLL_MAX_EVENTS];
	int epoll_fd, nfds, n;	

	/* zero the struct before filling the fields */
	memset(&serv, 0, sizeof(serv));
	/* set the type of connection to TCP/IP */           
	serv.sin_family = AF_INET;
	/* set the address to any interface */                
	serv.sin_addr.s_addr = htonl(INADDR_ANY); 
	/* set the server port number */    
	serv.sin_port = htons(BRICKS_LISTEN_PORT);

	/* create bricks socket for listening remote shell requests */
	listen_fd = socket(AF_INET, SOCK_STREAM, 0);
	if (listen_fd == -1) {
		TRACE_ERR("Failed to create listening socket for bricks\n");
		TRACE_BACKEND_FUNC_END();
	}
	
	/* bind serv information to mysocket */
	if (bind(listen_fd, (struct sockaddr *)&serv, sizeof(struct sockaddr)) == -1) {
		TRACE_ERR("Failed to bind listening socket to port %d for bricks\n",
			  BRICKS_LISTEN_PORT);
		TRACE_BACKEND_FUNC_END();
	}
	
	/* start listening, allowing a queue of up to 1 pending connection */
	if (listen(listen_fd, LISTEN_BACKLOG) == -1) {
		TRACE_ERR("Failed to start listen on port %d (for bricks)\n",
			  BRICKS_LISTEN_PORT);
		TRACE_BACKEND_FUNC_END();
	}

	/* set up the epolling structure */
	epoll_fd = epoll_create(EPOLL_MAX_EVENTS);
	if (epoll_fd == -1) {
		TRACE_ERR("BRICKS failed to create an epoll fd!\n");
		TRACE_BACKEND_FUNC_END();
		return;
	}


	/* register listening socket */
	ev.events = EPOLLIN | EPOLLOUT;
	ev.data.fd = listen_fd;
	if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev) == -1) {
		TRACE_LOG("BRICKS failed to exe epoll_ctl for fd: %d\n",
			  epoll_fd);
		TRACE_BACKEND_FUNC_END();
		return;
	}
	
	/*
	 * Main loop that processes incoming remote shell commands
	 * if the remote request arrives at listen_fd, it accepts connections
	 * and creates a new 'shell'
	 * if the remote request comes from a client request, it calls
	 * the lua string command function to execute the command
	 */

	do {
		/* wait for new epoll requests */
		nfds = epoll_wait(epoll_fd, events, EPOLL_MAX_EVENTS, -1);
		if (nfds == -1) {
			if (errno == EINTR) continue;
			TRACE_ERR("BRICKS poll error: %s\n", strerror(errno));
			TRACE_BACKEND_FUNC_END();
		}
		/* got some request... now process each one of them */
		for (n = 0; n < nfds; n++) {
			/* the request is for a new shell */
			if (events[n].data.fd == listen_fd) {
				client_sock = accept(listen_fd, NULL, NULL);
				if (client_sock < 0) {
					TRACE_ERR("accept failed: %s\n", strerror(errno));
					TRACE_BACKEND_FUNC_END();
				}
				lua_kickoff(LUA_EXE_STR, &client_sock);
				/* add client_sock and listen_fd for epolling again */
				ev.data.fd = client_sock;
				ev.events = EPOLLIN;
				if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, ev.data.fd, &ev) == -1) {
					TRACE_ERR("Can't register client sock for epolling!\n");
					TRACE_BACKEND_FUNC_END();
				}
				ev.data.fd = listen_fd;
				ev.events = EPOLLIN | EPOLLOUT;
				if (epoll_ctl(epoll_fd, EPOLL_CTL_MOD, ev.data.fd, &ev) == -1) {
					TRACE_ERR("Can't register client sock for epolling!\n");
					TRACE_BACKEND_FUNC_END();
				}
			} else { /* events[n].data.fd == regular sock */
				/* 
				 * if the client socket has incoming read, this means we are getting
				 * some lua commands.... execute them 
				 */
				if (events[n].events == EPOLLIN || events[n].events == EPOLLPRI) {
					lua_kickoff(LUA_EXE_STR, &events[n].data.fd);
					ev.data.fd = events[n].data.fd;
					ev.events = EPOLLIN;
					if (epoll_ctl(epoll_fd, EPOLL_CTL_MOD, ev.data.fd, &ev) == -1) {
						TRACE_ERR("Can't register client sock for epolling!\n");
						TRACE_BACKEND_FUNC_END();
					}
				} else { /* the only other epoll request is for error output.. close the socket then */
					ev.data.fd = events[n].data.fd;
					if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, ev.data.fd, &ev) == -1) {
						TRACE_ERR("Can't register client sock for epolling!\n");
						TRACE_BACKEND_FUNC_END();
					}	
					close(ev.data.fd);
				}
			}
		}
	} while (1);

	TRACE_BACKEND_FUNC_END();
}