Пример #1
0
/**
 * Parse command line options to initialize global options
 *
 * @param[in] argc number of command line arguments
 * @param[in] argv arguments provided by the command line
 */
static void parse_cmdline(int argc, char *argv[])
{
	/* long options */
	static const struct option long_opt[] = {
		{"help", no_argument, 0, 'h'},
		{"version", no_argument, 0, 'v'},
#ifdef DEBUG
		{"debug", no_argument, 0, 'd'},
#endif /* DEBUG */
		{NULL, 0, NULL, 0}
	};

	/* short options */
#ifdef HAVE_LIBPCAP
	static const char *short_opt = "b:c:dhp:w:v";
#else
	static const char *short_opt = "b:c:dhp:v";
#endif /* HAVE_LIBPCAP */

	/* variables from getopt() */
	extern char *optarg;    /* the option argument */
	extern int optind;	/* index of the next element */
	int ch = 0;		/* getopt_long() return value */

	/* parse command line */
	while ((ch = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1) {
		switch (ch) {
		case 'b':
			rpc_bind_addr = strdup(optarg);
			if (sscanf(optarg, "%s", rpc_bind_addr) != 1) {
				errx("failed to parse bind address");
				usage(EXIT_FAILURE);
			}
			break;
		case 'c':
			if (sscanf(optarg, "%i", &cpu) != 1) {
				errx("failed to parse CPU number");
				usage(EXIT_FAILURE);
			}
			break;
		case 'd':
			log_type = LOGTYPE_STDERR;
			increase_debuglevel();
			break;
		case 'h':
			usage(EXIT_SUCCESS);
			break;
		case 'p':
			if (sscanf(optarg, "%u", &port) != 1) {
				errx("failed to parse port number");
				usage(EXIT_FAILURE);
			}
			break;
#ifdef HAVE_LIBPCAP
		case 'w':
			dump_dir = optarg;
			break;
#endif /* HAVE_LIBPCAP */
		case 'v':
			fprintf(stderr, "%s version: %s\n", progname,
				FLOWGRIND_VERSION);
			exit(EXIT_SUCCESS);

		/* unknown option or missing option-argument */
		case '?':
			usage(EXIT_FAILURE);
			break;
		}
	}

	/* Do we have remaning command line arguments? */
	if (optind < argc) {
		char *args = NULL;
		while (optind < argc)
			asprintf_append(&args, "%s ", argv[optind++]);
		errx("invalid arguments: %s", args);
		free(args);
		usage(EXIT_FAILURE);
	}

	// TODO more sanity checks... (e.g. if port is in valid range)
}
Пример #2
0
static void parse_option(int argc, char ** argv) {
	int ch, rc;
	int argcorig = argc;
#ifdef HAVE_GETOPT_LONG
	/* getopt_long isn't portable, it's GNU extension */
	struct option lo[] = {  {"help", 0, 0, 'h' },
				{"version", 0, 0, 'v'},
				{"debug", 0, 0, 'd'},
				{0, 0, 0, 0}
				};
	while ((ch = getopt_long(argc, argv, "dDhp:vVw:W:", lo, 0)) != -1) {
#else
	while ((ch = getopt(argc, argv, "dDhp:vVw:W:")) != -1) {
#endif
		switch (ch) {
		case 'h':
			usage();
			break;

		case 'd':
		case 'D':
			log_type = LOGTYPE_STDERR;
			increase_debuglevel();
			break;

		case 'p':
			rc = sscanf(optarg, "%u", &port);
			if (rc != 1) {
				fprintf(stderr, "failed to "
					"parse port number.\n");
				usage();
			}
			break;

		case 'v':
		case 'V':
			fprintf(stderr, "flowgrindd version: %s\n", FLOWGRIND_VERSION);
			exit(0);

		case 'w':
		case 'W':
#ifdef HAVE_LIBPCAP
			dump_filename_prefix_server = optarg;
			break;
#endif
		default:
			usage();
		}
	}
	argc = argcorig;

	argc -= optind;

	if (argc != 0)
		usage();
}

int main(int argc, char ** argv)
{
	struct sigaction sa;

	xmlrpc_env env;

	/* update progname from argv[0] */
	if (argc > 0) {
		/* Strip path */
		char *tok = strrchr(argv[0], '/');
		if (tok)
			tok++;
		else
			tok = argv[0];
		if (*tok) {
			strncpy(progname, tok, sizeof(progname));
			progname[sizeof(progname) - 1] = 0;
		}
	}

	if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
		error(ERR_FATAL, "Could not ignore SIGPIPE: %s",
				strerror(errno));
		/* NOTREACHED */
	}

	sa.sa_handler = sighandler;
	sa.sa_flags = 0;
	sigemptyset (&sa.sa_mask);
	sigaction (SIGHUP, &sa, NULL);
	sigaction (SIGALRM, &sa, NULL);
	sigaction (SIGCHLD, &sa, NULL);

	parse_option(argc, argv);
	logging_init();
#ifdef HAVE_LIBPCAP
	fg_pcap_init();
#endif
	if (log_type == LOGTYPE_SYSLOG) {
		/* Need to call daemon() before creating the thread because
		 * it internally calls fork() which does not copy threads. */
		if (daemon(0, 0) == -1) {
			error(ERR_FATAL, "daemon() failed: %s", strerror(errno));
		}
		logging_log(LOG_NOTICE, "flowgrindd daemonized");
	}

	create_daemon_thread();

	xmlrpc_env_init(&env);

	run_rpc_server(&env, port);

	fprintf(stderr, "Control should never reach end of main()\n");

	return 0;
}