diff options
Diffstat (limited to 'lib/os_mon/c_src/ferrule.c')
-rw-r--r-- | lib/os_mon/c_src/ferrule.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/lib/os_mon/c_src/ferrule.c b/lib/os_mon/c_src/ferrule.c new file mode 100644 index 0000000000..744f302b2d --- /dev/null +++ b/lib/os_mon/c_src/ferrule.c @@ -0,0 +1,160 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +#include <stdio.h> +#include <string.h> +#include <stropts.h> +#include <poll.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/uio.h> + + /* arguments */ +#define OWNPATH 1 +#define NARG 1 + + /* status codes */ +#define OK 0 +#define NOT_OK 1 + + /* hardwired constants*/ +#define PIPENAME "syslog.otp" +#define DIE_CMD "die" +#define ONLY_STDIN_CMD "only_stdin" +#define BUFFER_SIZE 1001 +#define MAXPATH_SIZE 1001 +#define STDIN 0 +#define STDOUT 1 +#define HEADER_SIZE 2 +#define WAIT 10 +#define INTERVAL 1 +#define FALSE 0 +#define TRUE 1 +#define FDS_STDIN 0 +#define FDS_PIPE 1 + +main(int argc, char *argv[]) +/* usage: ferrule ownpath */ +{ + int i, pipe_fd; + long int nfds=2L; + char buf[BUFFER_SIZE], pipename[MAXPATH_SIZE], packet_size[2]; + struct pollfd fds[2]; + struct stat stat_buf; + + /* enough arguments? */ + if(argc < NARG+1) + exit(NOT_OK); + + /* make pipe name */ + strcpy(pipename, argv[OWNPATH]); + strcat(pipename, "/"); + strcat(pipename, PIPENAME); + + /* wait for creation of pipe */ + for(i=WAIT; i>0; i--) + if(stat(pipename, &stat_buf) == 0) + break; + else{ + if(i == 0) + exit(NOT_OK); + else + sleep(INTERVAL); + } + + /* open pipe, exit if error */ + if((pipe_fd = open(pipename, O_RDONLY | O_NONBLOCK)) == -1) + exit(NOT_OK); + + /* setup for pipe */ + fds[FDS_PIPE].fd = pipe_fd; + fds[FDS_PIPE].events = POLLRDNORM; + fds[FDS_PIPE].revents = 0; + + /* setup for stdin */ + fds[FDS_STDIN].fd = STDIN; + fds[FDS_STDIN].events = POLLRDNORM; + fds[FDS_STDIN].revents = 0; + + /* loop */ + while(1){ + /* wait for input */ + if(poll(&fds[0], nfds, INFTIM) == -1) + exit(NOT_OK); + + /* analyse input from pipe */ + if(fds[FDS_PIPE].revents != 0){ + + /* pipe error, error exit */ + if((fds[FDS_PIPE].revents & (POLLHUP | POLLERR | POLLNVAL)) != 0) + exit(NOT_OK); + + /* read pipe and write to stdout, exit if error */ + if((fds[FDS_PIPE].revents & POLLRDNORM) != 0){ + i=0; + do{ + read(pipe_fd, &buf[i++], (size_t)1); + }while(buf[i-1] != '\n'); + i--; + + /* send if string is not empty */ + if(i != 0){ + /* make packet size, [0]=MSB, [1]=LSB */ + packet_size[0] = (i >> 8) & 0xff; + packet_size[1] = i & 0xff; + + /* send to OTP process */ + if(write(STDOUT, packet_size, HEADER_SIZE) != HEADER_SIZE) + exit(NOT_OK); + if(write(STDOUT, buf, i) != i) + exit(NOT_OK); + } + } + } + + /* analyse input from stdin */ + if(fds[FDS_STDIN].revents != 0){ + + /* error exit */ + if((fds[FDS_STDIN].revents & (POLLHUP | POLLERR | POLLNVAL)) != 0) + exit(NOT_OK); + + /* read bytes */ + if((fds[FDS_STDIN].revents & POLLRDNORM) != 0){ + /* get packet size, [0]=MSB, [1]=LSB */ + if(read(STDIN, packet_size, HEADER_SIZE) != HEADER_SIZE) + exit(NOT_OK); + i = (packet_size[0] << 8) | packet_size[1]; + + /* get packet */ + if(read(STDIN, buf, i) != i) + exit(NOT_OK); + + /* check if die command */ + if(strncmp(DIE_CMD, buf, i) == FALSE) + exit(OK); + + /* check if only_stdin command */ + if(strncmp(ONLY_STDIN_CMD, buf, i) == FALSE) + nfds=1L; + } + } + } +} |