/* receives messages from a specified unix sockets and writes * output to specfied file. * * Command line options: * -s name of socket (required) * -o name of output file (stdout if not given) * -l add newline after each message received (default: do not add anything) * * Part of the testbench for rsyslog. * * Copyright 2010 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Rsyslog is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Rsyslog is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Rsyslog. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. */ #include "config.h" #include #include #include #include #include #include #include #include char *sockName = NULL; int sock; int addNL = 0; /* called to clean up on exit */ void cleanup(void) { unlink(sockName); close(sock); } void doTerm(int __attribute__((unused)) signum) { exit(1); } void usage(void) { fprintf(stderr, "usage: uxsockrcvr -s /socket/name -o /output/file -l\n" "-l adds newline after each message received\n" "-s MUST be specified\n" "if -o ist not specified, stdout is used\n"); exit(1); } int main(int argc, char *argv[]) { int opt; int rlen; FILE *fp = stdout; unsigned char data[128*1024]; struct sockaddr_un addr; /* address of server */ struct sockaddr from; socklen_t fromlen; if(argc < 2) { fprintf(stderr, "error: too few arguments!\n"); usage(); } while((opt = getopt(argc, argv, "s:o:l")) != EOF) { switch((char)opt) { case 'l': addNL = 1; break; case 's': sockName = optarg; break; case 'o': if((fp = fopen(optarg, "w")) == NULL) { perror(optarg); exit(1); } break; default:usage(); } } if(sockName == NULL) { fprintf(stderr, "error: -s /socket/name must be specified!\n"); exit(1); } if(signal(SIGTERM, doTerm) == SIG_ERR) { perror("signal(SIGTERM, ...)"); exit(1); } if(signal(SIGINT, doTerm) == SIG_ERR) { perror("signal(SIGINT, ...)"); exit(1); } /* Create a UNIX datagram socket for server */ if ((sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { perror("server: socket"); exit(1); } atexit(cleanup); /* Set up address structure for server socket */ memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strcpy(addr.sun_path, sockName); if (bind(sock, (struct sockaddr*) &addr, sizeof(addr)) < 0) { close(sock); perror("server: bind"); exit(1); } /* we now run in an endless loop. We do not check who sends us * data. This should be no problem for our testbench use. */ while(1) { fromlen = sizeof(from); rlen = recvfrom(sock, data, 2000, 0, &from, &fromlen); if(rlen == -1) { perror("uxsockrcvr : recv\n"); exit(1); } else { fwrite(data, 1, rlen, fp); if(addNL) fputc('\n', fp); } } return 0; }