Jelajahi Sumber

add option to check_nrpe to allow output to be redirected from stderr to stdout

Bryan Heden 8 tahun lalu
induk
melakukan
10df3aa02b
3 mengubah file dengan 36 tambahan dan 17 penghapusan
  1. 2 2
      include/utils.h
  2. 14 3
      src/check_nrpe.c
  3. 20 12
      src/utils.c

+ 2 - 2
include/utils.h

@@ -35,9 +35,9 @@ unsigned long calculate_crc32(char*, int);
 void randomize_buffer(char*,int);
 int my_tcp_connect(char*, int, int*);
 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
-int my_connect(const char*, struct sockaddr_storage*, u_short, int, const char*);
+int my_connect(const char*, struct sockaddr_storage*, u_short, int, const char*, int);
 #else
-int my_connect(const char*, struct sockaddr*, u_short, int, const char*);
+int my_connect(const char*, struct sockaddr*, u_short, int, const char*, int);
 #endif
 void add_listen_addr(struct addrinfo**, int, char*, int);
 int clean_environ(const char *keep_env_vars, const char *nrpe_user);

+ 14 - 3
src/check_nrpe.c

@@ -56,6 +56,7 @@ char *command_name = NULL;
 int socket_timeout = DEFAULT_SOCKET_TIMEOUT;
 char timeout_txt[10];
 int timeout_return_code = -1;
+int stderr_to_stdout = 0;
 int sd;
 
 char rem_host[MAX_HOST_ADDRESS_LENGTH];
@@ -235,6 +236,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
 		{"help", no_argument, 0, 'h'},
 		{"license", no_argument, 0, 'l'},
 		{"version", no_argument, 0, 'V'},
+		{"stderr-to-stdout", no_argument, 0, 'E'},
 		{0, 0, 0, 0}
 	};
 #endif
@@ -244,7 +246,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
 		return ERROR;
 
 	optind = 0;
-	snprintf(optchars, MAX_INPUT_BUFFER, "H:f:b:c:a:t:p:S:L:C:K:A:d:s:P:g:246hlnuV");
+	snprintf(optchars, MAX_INPUT_BUFFER, "H:f:b:c:a:t:p:S:L:C:K:A:d:s:P:g:246hlnuVE");
 
 	while (1) {
 		if (argindex > 0)
@@ -323,6 +325,14 @@ int process_arguments(int argc, char **argv, int from_config_file)
 			server_name = strdup(optarg);
 			break;
 
+		case 'E':
+			if (from_config_file && stderr_to_stdout != 0) {
+				logit(LOG_WARNING, "WARNING: Command-line stderr redirection overrides the config file option.");
+				break;
+			}
+			stderr_to_stdout = 1;
+			break;
+
 		case 'c':
 			if (from_config_file) {
 				printf("Error: The config file should not have a command (-c) option.\n");
@@ -675,7 +685,7 @@ void usage(int result)
 		printf("       [-P <size>] [-S <ssl version>]  [-L <cipherlist>] [-C <clientcert>]\n");
 		printf("       [-K <key>] [-A <ca-certificate>] [-s <logopts>] [-b <bindaddr>]\n");
 		printf("       [-f <cfg-file>] [-p <port>] [-t <interval>:<state>] [-g <log-file>]\n");
-		printf("       [-c <command>] [-a <arglist...>]\n");
+		printf("       [-c <command>] [-E] [-a <arglist...>]\n");
 		printf("\n");
 		printf("Options:\n");
 		printf(" -H, --host=HOST              The address of the host running the NRPE daemon\n");
@@ -686,6 +696,7 @@ void usage(int result)
 		printf(" -u, --unknown-timeout        Make connection problems return UNKNOWN instead of CRITICAL\n");
 		printf(" -V, --version                Print version info and quit\n");
 		printf(" -l, --license                Show license\n");
+		printf(" -E, --stderr-to-stdout       Redirect stderr to stdout\n");
 		printf(" -d, --use-dh=DHOPT           Anonymous Diffie Hellman use:\n");
 		printf("                              0         Don't use Anonymous Diffie Hellman\n");
 		printf("                                        (This will be the default in a future release.)\n");
@@ -987,7 +998,7 @@ int connect_to_remote()
 	int result, rc, ssl_err, ern, x, nerrs = 0;
 
 	/* try to connect to the host at the given port number */
-	if ((sd = my_connect(server_name, &hostaddr, server_port, address_family, bind_address)) < 0)
+	if ((sd = my_connect(server_name, &hostaddr, server_port, address_family, bind_address, stderr_to_stdout)) < 0)
 		exit(timeout_return_code);
 
 	result = STATE_OK;

+ 20 - 12
src/utils.c

@@ -57,7 +57,7 @@ static unsigned long crc32_table[256];
 char *log_file = NULL;
 FILE *log_fp = NULL;
 
-static int my_create_socket(struct addrinfo *ai, const char *bind_address);
+static int my_create_socket(struct addrinfo *ai, const char *bind_address, int redirect_stderr);
 
 
 /* build the crc table - must be called before calculating the crc value */
@@ -133,10 +133,10 @@ void randomize_buffer(char *buffer, int buffer_size)
 /* opens a connection to a remote host */
 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
 int my_connect(const char *host, struct sockaddr_storage *hostaddr, u_short port,
-			   int address_family, const char *bind_address)
+			   int address_family, const char *bind_address, int redirect_stderr)
 #else
 int my_connect(const char *host, struct sockaddr *hostaddr, u_short port,
-			   int address_family, const char *bind_address)
+			   int address_family, const char *bind_address, int redirect_stderr)
 #endif
 {
 	struct addrinfo hints, *ai, *aitop;
@@ -144,12 +144,16 @@ int my_connect(const char *host, struct sockaddr *hostaddr, u_short port,
 	int gaierr;
 	int sock = -1;
 
+	FILE *output = stderr;
+	if (redirect_stderr)
+		output = stdout;
+
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_family = address_family;
 	hints.ai_socktype = SOCK_STREAM;
 	snprintf(strport, sizeof strport, "%u", port);
 	if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) {
-		fprintf(stderr, "Could not resolve hostname %.100s: %s\n", host, gai_strerror(gaierr));
+		fprintf(output, "Could not resolve hostname %.100s: %s\n", host, gai_strerror(gaierr));
 		exit(1);
 	}
 
@@ -162,12 +166,12 @@ int my_connect(const char *host, struct sockaddr *hostaddr, u_short port,
 			continue;
 		if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
 						strport, sizeof(strport), NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
-			fprintf(stderr, "my_connect: getnameinfo failed\n");
+			fprintf(output, "my_connect: getnameinfo failed\n");
 			continue;
 		}
 
 		/* Create a socket for connecting. */
-		sock = my_create_socket(ai, bind_address);
+		sock = my_create_socket(ai, bind_address, redirect_stderr);
 		if (sock < 0)
 			continue;			/* Any error is already output */
 
@@ -176,7 +180,7 @@ int my_connect(const char *host, struct sockaddr *hostaddr, u_short port,
 			memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
 			break;
 		} else {
-			fprintf(stderr, "connect to address %s port %s: %s\n", ntop, strport,
+			fprintf(output, "connect to address %s port %s: %s\n", ntop, strport,
 					strerror(errno));
 			close(sock);
 			sock = -1;
@@ -187,21 +191,25 @@ int my_connect(const char *host, struct sockaddr *hostaddr, u_short port,
 
 	/* Return failure if we didn't get a successful connection. */
 	if (sock == -1) {
-		fprintf(stderr, "connect to host %s port %s: %s\n", host, strport, strerror(errno));
+		fprintf(output, "connect to host %s port %s: %s\n", host, strport, strerror(errno));
 		return -1;
 	}
 	return sock;
 }
 
 /* Creates a socket for the connection. */
-int my_create_socket(struct addrinfo *ai, const char *bind_address)
+int my_create_socket(struct addrinfo *ai, const char *bind_address, int redirect_stderr)
 {
 	int sock, gaierr;
 	struct addrinfo hints, *res;
 
+	FILE *output = stderr;
+	if (redirect_stderr)
+		output = stdout;
+
 	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
 	if (sock < 0)
-		fprintf(stderr, "socket: %.100s\n", strerror(errno));
+		fprintf(output, "socket: %.100s\n", strerror(errno));
 
 	/* Bind the socket to an alternative local IP address */
 	if (bind_address == NULL)
@@ -214,12 +222,12 @@ int my_create_socket(struct addrinfo *ai, const char *bind_address)
 	hints.ai_flags = AI_PASSIVE;
 	gaierr = getaddrinfo(bind_address, NULL, &hints, &res);
 	if (gaierr) {
-		fprintf(stderr, "getaddrinfo: %s: %s\n", bind_address, gai_strerror(gaierr));
+		fprintf(output, "getaddrinfo: %s: %s\n", bind_address, gai_strerror(gaierr));
 		close(sock);
 		return -1;
 	}
 	if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
-		fprintf(stderr, "bind: %s: %s\n", bind_address, strerror(errno));
+		fprintf(output, "bind: %s: %s\n", bind_address, strerror(errno));
 		close(sock);
 		freeaddrinfo(res);
 		return -1;