diff options
-rw-r--r-- | usr.bin/logger/Makefile | 2 | ||||
-rw-r--r-- | usr.bin/logger/logger.1 | 15 | ||||
-rw-r--r-- | usr.bin/logger/logger.c | 90 |
3 files changed, 82 insertions, 25 deletions
diff --git a/usr.bin/logger/Makefile b/usr.bin/logger/Makefile index a5d143b..163cdec 100644 --- a/usr.bin/logger/Makefile +++ b/usr.bin/logger/Makefile @@ -1,5 +1,7 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 +# $FreeBSD$ PROG= logger +COPTS+= -DINET6 .include <bsd.prog.mk> diff --git a/usr.bin/logger/logger.1 b/usr.bin/logger/logger.1 index a5f52a2..c415a71 100644 --- a/usr.bin/logger/logger.1 +++ b/usr.bin/logger/logger.1 @@ -54,6 +54,21 @@ system log module. .Pp The following options are available: .Bl -tag -width indent +.It Fl 4 +Forces +.Nm +to use IPv4 addresses only. +.It Fl 6 +Forces +.Nm +to use IPv6 addresses only. +.It Fl A +.Nm +tries to send the message to only one address +even if the host has more than one A or AAAA record. +If this option is specified, +.Nm +tries to send the message to all addresses. .It Fl i Log the process id of the logger process with each line. diff --git a/usr.bin/logger/logger.c b/usr.bin/logger/logger.c index 6cbba4b..27983a0 100644 --- a/usr.bin/logger/logger.c +++ b/usr.bin/logger/logger.c @@ -65,6 +65,19 @@ int pencode __P((char *)); static void logmessage __P((int, char *, char *)); static void usage __P((void)); +struct socks { + int sock; + int addrlen; + struct sockaddr_storage addr; +}; + +#ifdef INET6 +int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) */ +#else +int family = PF_INET; /* protocol family (IPv4 only) */ +#endif +int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */ + /* * logger -- read and log utility * @@ -84,8 +97,19 @@ main(argc, argv) pri = LOG_NOTICE; logflags = 0; unsetenv("TZ"); - while ((ch = getopt(argc, argv, "f:h:ip:st:")) != -1) + while ((ch = getopt(argc, argv, "46Af:h:ip:st:")) != -1) switch((char)ch) { + case '4': + family = PF_INET; + break; +#ifdef INET6 + case '6': + family = PF_INET6; + break; +#endif + case 'A': + send_to_all++; + break; case 'f': /* file to log */ if (freopen(optarg, "r", stdin) == NULL) err(1, "%s", optarg); @@ -150,43 +174,59 @@ main(argc, argv) void logmessage(int pri, char *host, char *buf) { - static int sock = -1; - static struct sockaddr_in sin; + static struct socks *socks; + static int nsock = 0; + struct addrinfo hints, *res, *r; char *line; - int len; + int maxs, len, sock, error, i, lsent; if (host == NULL) { syslog(pri, "%s", buf); return; } - if (sock == -1) { /* set up socket stuff */ - struct servent *sp; - struct hostent *hp = NULL; - - sin.sin_family = AF_INET; - - if ((sp = getservbyname("syslog", "udp")) == NULL) - warnx ("syslog/udp: unknown service"); /* not fatal */ - sin.sin_port = (sp == NULL ? htons(514) : sp->s_port); - + if (nsock <= 0) { /* set up socket stuff */ /* resolve hostname */ - if (!(inet_aton(host, &sin.sin_addr)) && - (hp = gethostbyname(host)) == NULL) - errx(1, "unknown host: %s", host); - if (hp != NULL) - memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); - - sock = socket(PF_INET, SOCK_DGRAM, 0); - if (sock < 0) + memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_socktype = SOCK_DGRAM; + error = getaddrinfo(host, "syslog", &hints, &res); + if (error == EAI_SERVICE) { + warnx ("syslog/udp: unknown service"); /* not fatal */ + error = getaddrinfo(host, "514", &hints, &res); + } + if (error) + errx(1, "%s: %s", gai_strerror(error), host); + /* count max number of sockets we may open */ + for (maxs = 0, r = res; r; r = r->ai_next, maxs++); + socks = malloc(maxs * sizeof(struct socks)); + if (!socks) + errx(1, "couldn't allocate memory for sockets"); + for (r = res; r; r = r->ai_next) { + sock = socket(r->ai_family, r->ai_socktype, + r->ai_protocol); + if (sock < 0) + continue; + memcpy(&socks[nsock].addr, r->ai_addr, r->ai_addrlen); + socks[nsock].addrlen = r->ai_addrlen; + socks[nsock++].sock = sock; + } + freeaddrinfo(res); + if (nsock <= 0) errx(1, "socket"); } if ((len = asprintf(&line, "<%d>%s", pri, buf)) == -1) errx(1, "asprintf"); - if (sendto(sock, line, len, 0, (struct sockaddr *)&sin, sizeof(sin)) - < len) + for (i = 0; i < nsock; ++i) { + lsent = sendto(socks[i].sock, line, len, 0, + (struct sockaddr *)&socks[i].addr, + socks[i].addrlen); + if (lsent == len && !send_to_all) + break; + } + if (lsent != len) warnx ("sendmsg"); free(line); @@ -241,7 +281,7 @@ static void usage() { (void)fprintf(stderr, "usage: %s\n", - "logger [-is] [-f file] [-h host] [-p pri] [-t tag] [message ...]" + "logger [-46Ais] [-f file] [-h host] [-p pri] [-t tag] [message ...]" ); exit(1); } |