#include <sys/ioctl.h>
#include <sys/poll.h>
#include <syslog.h>
+#include <signal.h>
#include "utils.h"
+static int quit = 0;
+
static void usage(FILE *out)
{
- fprintf(out, "usage: mctap [-hd] [-D TAPNAME] MCASTGROUP PORT\n");
+ fprintf(out, "usage: mctap [-hdp] [-P PIDFILE] [-D TAPNAME] MCASTGROUP PORT\n");
}
static __attribute__ ((unused)) char *formataddress(struct sockaddr *arg, socklen_t arglen)
fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK);
fcntl(tap, F_SETFL, fcntl(tap, F_GETFL) | O_NONBLOCK);
- while(1) {
+ while(!quit) {
pfds[0].fd = sock;
pfds[0].events = POLLIN;
pfds[1].fd = tap;
return(fd);
}
+static void sighand(int sig)
+{
+ switch(sig) {
+ case SIGINT:
+ case SIGTERM:
+ quit = 1;
+ break;
+ case SIGHUP:
+ break;
+ }
+}
+
int main(int argc, char **argv)
{
int c;
struct in_addr group;
int port;
char *tapname;
+ char *pidfile;
int daemonize;
struct sockaddr_in dst;
+ FILE *pidfd;
tapname = "mctap";
daemonize = 0;
- while((c = getopt(argc, argv, "hD:d")) >= 0) {
+ pidfile = NULL;
+ while((c = getopt(argc, argv, "hD:dpP:")) >= 0) {
switch(c) {
case 'D':
tapname = optarg;
case 'd':
daemonize = 1;
break;
+ case 'p':
+ pidfile = (void *)-1;
+ break;
+ case 'P':
+ pidfile = optarg;
+ break;
case 'h':
usage(stdout);
return(0);
exit(1);
}
}
+ if(pidfile == (void *)-1)
+ pidfile = sprintf2("/var/run/mctap.%s.pid", tapname);
if(argc - optind < 2) {
usage(stderr);
exit(1);
}
openlog(sprintf2("mctap-%s", tapname), LOG_PID, LOG_DAEMON);
+ pidfd = NULL;
+ if((pidfile != NULL) && ((pidfd = fopen(pidfile, "w")) == NULL)) {
+ fprintf(stderr, "mctap: could not create PID file %s: %s\n", pidfile, strerror(errno));
+ exit(1);
+ }
if(daemonize)
daemon(0, 0);
+ if(pidfd != NULL) {
+ fprintf(pidfd, "%i\n", getpid());
+ fclose(pidfd);
+ }
+
+ signal(SIGTERM, sighand);
+ signal(SIGINT, sighand);
+ signal(SIGHUP, sighand);
memset(&dst, 0, sizeof(dst));
dst.sin_family = AF_INET;
dst.sin_addr = group;
dst.sin_port = htons(port);
bridge(sock, tap, (struct sockaddr *)&dst, sizeof(dst));
+ syslog(LOG_INFO, "exiting");
+
+ if(pidfile != NULL)
+ unlink(pidfile);
return(0);
}