19b50d902SRodney W. Grimes /* 29b50d902SRodney W. Grimes * Copyright (c) 1983, 1993 39b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 49b50d902SRodney W. Grimes * 59b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 69b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 79b50d902SRodney W. Grimes * are met: 89b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 99b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 109b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 119b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 129b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 13*fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 149b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 159b50d902SRodney W. Grimes * without specific prior written permission. 169b50d902SRodney W. Grimes * 179b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 189b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 199b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 209b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 219b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 229b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 239b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 249b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 259b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 269b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 279b50d902SRodney W. Grimes * SUCH DAMAGE. 289b50d902SRodney W. Grimes */ 299b50d902SRodney W. Grimes 309b50d902SRodney W. Grimes #ifndef lint 31df071556SPhilippe Charnier static const char copyright[] = 329b50d902SRodney W. Grimes "@(#) Copyright (c) 1983, 1993\n\ 339b50d902SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 349b50d902SRodney W. Grimes #endif /* not lint */ 359b50d902SRodney W. Grimes 36df071556SPhilippe Charnier #if 0 37865059c8SPhilippe Charnier #ifndef lint 389b50d902SRodney W. Grimes static char sccsid[] = "@(#)logger.c 8.1 (Berkeley) 6/6/93"; 399b50d902SRodney W. Grimes #endif /* not lint */ 40865059c8SPhilippe Charnier #endif 41865059c8SPhilippe Charnier 429bd5ae85SDavid Malone #include <sys/cdefs.h> 439bd5ae85SDavid Malone __FBSDID("$FreeBSD$"); 449bd5ae85SDavid Malone 45b0fe2da8SDavid Malone #include <sys/types.h> 46b0fe2da8SDavid Malone #include <sys/socket.h> 47b0fe2da8SDavid Malone #include <netinet/in.h> 48b0fe2da8SDavid Malone 499b50d902SRodney W. Grimes #include <ctype.h> 50df071556SPhilippe Charnier #include <err.h> 51b0fe2da8SDavid Malone #include <netdb.h> 52df071556SPhilippe Charnier #include <stdio.h> 53df071556SPhilippe Charnier #include <stdlib.h> 549b50d902SRodney W. Grimes #include <string.h> 55df071556SPhilippe Charnier #include <unistd.h> 569b50d902SRodney W. Grimes 579b50d902SRodney W. Grimes #define SYSLOG_NAMES 589b50d902SRodney W. Grimes #include <syslog.h> 599b50d902SRodney W. Grimes 60a04667abSHiroki Sato #define sstosa(ss) ((struct sockaddr *)(void *)ss) 619b50d902SRodney W. Grimes 620b5f90afSHajimu UMEMOTO struct socks { 63a04667abSHiroki Sato int sk_sock; 64a04667abSHiroki Sato int sk_addrlen; 65a04667abSHiroki Sato struct sockaddr_storage sk_addr; 660b5f90afSHajimu UMEMOTO }; 670b5f90afSHajimu UMEMOTO 68a04667abSHiroki Sato static int decode(char *, const CODE *); 69a04667abSHiroki Sato static int pencode(char *); 70a04667abSHiroki Sato static ssize_t socksetup(const char *, const char *, const char *, 71a04667abSHiroki Sato struct socks **); 72a04667abSHiroki Sato static void logmessage(int, const char *, struct socks *, ssize_t, 73a04667abSHiroki Sato const char *); 74a04667abSHiroki Sato static void usage(void); 75a04667abSHiroki Sato 760b5f90afSHajimu UMEMOTO #ifdef INET6 77481bce6cSEd Schouten static int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) */ 780b5f90afSHajimu UMEMOTO #else 79481bce6cSEd Schouten static int family = PF_INET; /* protocol family (IPv4 only) */ 800b5f90afSHajimu UMEMOTO #endif 81481bce6cSEd Schouten static int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */ 820b5f90afSHajimu UMEMOTO 839b50d902SRodney W. Grimes /* 849b50d902SRodney W. Grimes * logger -- read and log utility 859b50d902SRodney W. Grimes * 869b50d902SRodney W. Grimes * Reads from an input and arranges to write the result on the system 879b50d902SRodney W. Grimes * log. 889b50d902SRodney W. Grimes */ 899b50d902SRodney W. Grimes int 90f4ac32deSDavid Malone main(int argc, char *argv[]) 919b50d902SRodney W. Grimes { 92a04667abSHiroki Sato struct socks *socks; 93a04667abSHiroki Sato ssize_t nsock; 949b50d902SRodney W. Grimes int ch, logflags, pri; 956f62d863SDavid Malone char *tag, *host, buf[1024]; 96a04667abSHiroki Sato const char *svcname, *src; 979b50d902SRodney W. Grimes 989b50d902SRodney W. Grimes tag = NULL; 99b0fe2da8SDavid Malone host = NULL; 1006b04b7f6SBruce M Simpson svcname = "syslog"; 101a04667abSHiroki Sato src = NULL; 1028f14a1afSHiroki Sato socks = NULL; 103ca122bf7SRuslan Ermilov pri = LOG_USER | LOG_NOTICE; 1049b50d902SRodney W. Grimes logflags = 0; 10540244c28SPoul-Henning Kamp unsetenv("TZ"); 106a04667abSHiroki Sato while ((ch = getopt(argc, argv, "46Af:h:iP:p:S:st:")) != -1) 1079b50d902SRodney W. Grimes switch((char)ch) { 1080b5f90afSHajimu UMEMOTO case '4': 1090b5f90afSHajimu UMEMOTO family = PF_INET; 1100b5f90afSHajimu UMEMOTO break; 1110b5f90afSHajimu UMEMOTO #ifdef INET6 1120b5f90afSHajimu UMEMOTO case '6': 1130b5f90afSHajimu UMEMOTO family = PF_INET6; 1140b5f90afSHajimu UMEMOTO break; 1150b5f90afSHajimu UMEMOTO #endif 1160b5f90afSHajimu UMEMOTO case 'A': 1170b5f90afSHajimu UMEMOTO send_to_all++; 1180b5f90afSHajimu UMEMOTO break; 1199b50d902SRodney W. Grimes case 'f': /* file to log */ 120df071556SPhilippe Charnier if (freopen(optarg, "r", stdin) == NULL) 121df071556SPhilippe Charnier err(1, "%s", optarg); 1224145bb53SKirk McKusick setvbuf(stdin, 0, _IONBF, 0); 1239b50d902SRodney W. Grimes break; 124b0fe2da8SDavid Malone case 'h': /* hostname to deliver to */ 125b0fe2da8SDavid Malone host = optarg; 126b0fe2da8SDavid Malone break; 1279b50d902SRodney W. Grimes case 'i': /* log process id also */ 1289b50d902SRodney W. Grimes logflags |= LOG_PID; 1299b50d902SRodney W. Grimes break; 1306b04b7f6SBruce M Simpson case 'P': /* service name or port number */ 1316b04b7f6SBruce M Simpson svcname = optarg; 1326b04b7f6SBruce M Simpson break; 1339b50d902SRodney W. Grimes case 'p': /* priority */ 1349b50d902SRodney W. Grimes pri = pencode(optarg); 1359b50d902SRodney W. Grimes break; 1369b50d902SRodney W. Grimes case 's': /* log to standard error */ 1379b50d902SRodney W. Grimes logflags |= LOG_PERROR; 1389b50d902SRodney W. Grimes break; 139a04667abSHiroki Sato case 'S': /* source address */ 140a04667abSHiroki Sato src = optarg; 141a04667abSHiroki Sato break; 1429b50d902SRodney W. Grimes case 't': /* tag */ 1439b50d902SRodney W. Grimes tag = optarg; 1449b50d902SRodney W. Grimes break; 1459b50d902SRodney W. Grimes case '?': 1469b50d902SRodney W. Grimes default: 1479b50d902SRodney W. Grimes usage(); 1489b50d902SRodney W. Grimes } 1499b50d902SRodney W. Grimes argc -= optind; 1509b50d902SRodney W. Grimes argv += optind; 1519b50d902SRodney W. Grimes 152a04667abSHiroki Sato if (host) { 153a04667abSHiroki Sato nsock = socksetup(src, host, svcname, &socks); 154a04667abSHiroki Sato if (nsock <= 0) 155a04667abSHiroki Sato errx(1, "socket"); 156a04667abSHiroki Sato } else { 157a04667abSHiroki Sato if (src) 158a04667abSHiroki Sato errx(1, "-h option is missing."); 159a04667abSHiroki Sato nsock = 0; 160a04667abSHiroki Sato } 161a04667abSHiroki Sato 16281280940SEdwin Groothuis if (tag == NULL) 16381280940SEdwin Groothuis tag = getlogin(); 1649b50d902SRodney W. Grimes /* setup for logging */ 16581280940SEdwin Groothuis if (host == NULL) 16681280940SEdwin Groothuis openlog(tag, logflags, 0); 1679b50d902SRodney W. Grimes (void) fclose(stdout); 1689b50d902SRodney W. Grimes 1699b50d902SRodney W. Grimes /* log input line if appropriate */ 1709b50d902SRodney W. Grimes if (argc > 0) { 171f4ac32deSDavid Malone char *p, *endp; 1729bd5ae85SDavid Malone size_t len; 1739b50d902SRodney W. Grimes 1749b50d902SRodney W. Grimes for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) { 1759b50d902SRodney W. Grimes len = strlen(*argv); 1769b50d902SRodney W. Grimes if (p + len > endp && p > buf) { 177a04667abSHiroki Sato logmessage(pri, tag, socks, nsock, buf); 1789b50d902SRodney W. Grimes p = buf; 1799b50d902SRodney W. Grimes } 1809b50d902SRodney W. Grimes if (len > sizeof(buf) - 1) 181a04667abSHiroki Sato logmessage(pri, tag, socks, nsock, *argv++); 1829b50d902SRodney W. Grimes else { 1839b50d902SRodney W. Grimes if (p != buf) 1849b50d902SRodney W. Grimes *p++ = ' '; 1859b50d902SRodney W. Grimes bcopy(*argv++, p, len); 1869b50d902SRodney W. Grimes *(p += len) = '\0'; 1879b50d902SRodney W. Grimes } 1889b50d902SRodney W. Grimes } 1899b50d902SRodney W. Grimes if (p != buf) 190a04667abSHiroki Sato logmessage(pri, tag, socks, nsock, buf); 1919b50d902SRodney W. Grimes } else 1929b50d902SRodney W. Grimes while (fgets(buf, sizeof(buf), stdin) != NULL) 193a04667abSHiroki Sato logmessage(pri, tag, socks, nsock, buf); 1949b50d902SRodney W. Grimes exit(0); 1959b50d902SRodney W. Grimes } 1969b50d902SRodney W. Grimes 197a04667abSHiroki Sato static ssize_t 198a04667abSHiroki Sato socksetup(const char *src, const char *dst, const char *svcname, 199a04667abSHiroki Sato struct socks **socks) 200a04667abSHiroki Sato { 201a04667abSHiroki Sato struct addrinfo hints, *res, *res0; 202a04667abSHiroki Sato struct sockaddr_storage *ss_src[AF_MAX]; 203a04667abSHiroki Sato struct socks *sk; 204a04667abSHiroki Sato ssize_t nsock = 0; 205a04667abSHiroki Sato int error, maxs; 206a04667abSHiroki Sato 207a04667abSHiroki Sato memset(&ss_src[0], 0, sizeof(ss_src)); 208a04667abSHiroki Sato if (src) { 209a04667abSHiroki Sato char *p, *p0, *hs, *hbuf, *sbuf; 210a04667abSHiroki Sato 211a04667abSHiroki Sato hbuf = sbuf = NULL; 212a04667abSHiroki Sato p0 = p = strdup(src); 213a04667abSHiroki Sato if (p0 == NULL) 214a04667abSHiroki Sato err(1, "strdup failed"); 215a04667abSHiroki Sato hs = p0; /* point to search ":" */ 216a04667abSHiroki Sato #ifdef INET6 217a04667abSHiroki Sato /* -S option supports IPv6 addr in "[2001:db8::1]:service". */ 218a04667abSHiroki Sato if (*p0 == '[') { 219a04667abSHiroki Sato p = strchr(p0, ']'); 220a04667abSHiroki Sato if (p == NULL) 221a04667abSHiroki Sato errx(1, "\"]\" not found in src addr"); 222a04667abSHiroki Sato *p = '\0'; 223a04667abSHiroki Sato /* hs points just after ']' (':' or '\0'). */ 224a04667abSHiroki Sato hs = p + 1; 225a04667abSHiroki Sato /* 226a04667abSHiroki Sato * p points just after '[' while it points hs 227a04667abSHiroki Sato * in the case of []. 228a04667abSHiroki Sato */ 229a04667abSHiroki Sato p = ((p0 + 1) == (hs - 1)) ? hs : p0 + 1; 230a04667abSHiroki Sato } 231a04667abSHiroki Sato #endif 232a04667abSHiroki Sato if (*p != '\0') { 233a04667abSHiroki Sato /* (p == hs) means ":514" or "[]:514". */ 234a04667abSHiroki Sato hbuf = (p == hs && *p == ':') ? NULL : p; 235a04667abSHiroki Sato p = strchr(hs, ':'); 236a04667abSHiroki Sato if (p != NULL) { 237a04667abSHiroki Sato *p = '\0'; 238a04667abSHiroki Sato sbuf = (*(p + 1) != '\0') ? p + 1 : NULL; 239a04667abSHiroki Sato } 240a04667abSHiroki Sato } 241a04667abSHiroki Sato hints = (struct addrinfo){ 242a04667abSHiroki Sato .ai_family = family, 243a04667abSHiroki Sato .ai_socktype = SOCK_DGRAM, 244a04667abSHiroki Sato .ai_flags = AI_PASSIVE 245a04667abSHiroki Sato }; 246a04667abSHiroki Sato error = getaddrinfo(hbuf, sbuf, &hints, &res0); 247a04667abSHiroki Sato if (error) 248a04667abSHiroki Sato errx(1, "%s: %s", gai_strerror(error), src); 249a04667abSHiroki Sato for (res = res0; res; res = res->ai_next) { 250a04667abSHiroki Sato switch (res->ai_family) { 251a04667abSHiroki Sato case AF_INET: 252a04667abSHiroki Sato #ifdef INET6 253a04667abSHiroki Sato case AF_INET6: 254a04667abSHiroki Sato #endif 255a04667abSHiroki Sato if (ss_src[res->ai_family] != NULL) 256a04667abSHiroki Sato continue; 257a04667abSHiroki Sato ss_src[res->ai_family] = 258a04667abSHiroki Sato malloc(sizeof(struct sockaddr_storage)); 259a04667abSHiroki Sato if (ss_src[res->ai_family] == NULL) 260a04667abSHiroki Sato err(1, "malloc failed"); 261a04667abSHiroki Sato memcpy(ss_src[res->ai_family], res->ai_addr, 262a04667abSHiroki Sato res->ai_addrlen); 263a04667abSHiroki Sato } 264a04667abSHiroki Sato } 265a04667abSHiroki Sato freeaddrinfo(res0); 266a04667abSHiroki Sato free(p0); 267a04667abSHiroki Sato } 268a04667abSHiroki Sato 269a04667abSHiroki Sato /* resolve hostname */ 270a04667abSHiroki Sato hints = (struct addrinfo){ 271a04667abSHiroki Sato .ai_family = family, 272a04667abSHiroki Sato .ai_socktype = SOCK_DGRAM 273a04667abSHiroki Sato }; 274a04667abSHiroki Sato error = getaddrinfo(dst, svcname, &hints, &res0); 275a04667abSHiroki Sato if (error == EAI_SERVICE) { 276a04667abSHiroki Sato warnx("%s/udp: unknown service", svcname); 277a04667abSHiroki Sato error = getaddrinfo(dst, "514", &hints, &res); 278a04667abSHiroki Sato } 279a04667abSHiroki Sato if (error) 280a04667abSHiroki Sato errx(1, "%s: %s", gai_strerror(error), dst); 281a04667abSHiroki Sato /* count max number of sockets we may open */ 282a04667abSHiroki Sato maxs = 0; 283a04667abSHiroki Sato for (res = res0; res; res = res->ai_next) 284a04667abSHiroki Sato maxs++; 285a04667abSHiroki Sato sk = calloc(maxs, sizeof(*sk)); 286a04667abSHiroki Sato if (sk == NULL) 287a04667abSHiroki Sato errx(1, "couldn't allocate memory for sockets"); 288a04667abSHiroki Sato for (res = res0; res; res = res->ai_next) { 289a04667abSHiroki Sato int s; 290a04667abSHiroki Sato 291a04667abSHiroki Sato s = socket(res->ai_family, res->ai_socktype, 292a04667abSHiroki Sato res->ai_protocol); 293a04667abSHiroki Sato if (s < 0) 294a04667abSHiroki Sato continue; 295a04667abSHiroki Sato if (src && ss_src[res->ai_family] == NULL) 296a04667abSHiroki Sato errx(1, "address family mismatch"); 297a04667abSHiroki Sato 298a04667abSHiroki Sato if (ss_src[res->ai_family]) { 299a04667abSHiroki Sato error = bind(s, sstosa(ss_src[res->ai_family]), 300a04667abSHiroki Sato ss_src[res->ai_family]->ss_len); 301a04667abSHiroki Sato if (error < 0) 302a04667abSHiroki Sato err(1, "bind"); 303a04667abSHiroki Sato } 304a04667abSHiroki Sato sk[nsock] = (struct socks){ 305a04667abSHiroki Sato .sk_addrlen = res->ai_addrlen, 306a04667abSHiroki Sato .sk_sock = s 307a04667abSHiroki Sato }; 308a04667abSHiroki Sato memcpy(&sk[nsock].sk_addr, res->ai_addr, res->ai_addrlen); 309a04667abSHiroki Sato nsock++; 310a04667abSHiroki Sato } 311a04667abSHiroki Sato freeaddrinfo(res0); 312a04667abSHiroki Sato 313a04667abSHiroki Sato *socks = sk; 314a04667abSHiroki Sato return (nsock); 315a04667abSHiroki Sato } 316a04667abSHiroki Sato 3179b50d902SRodney W. Grimes /* 318b0fe2da8SDavid Malone * Send the message to syslog, either on the local host, or on a remote host 319b0fe2da8SDavid Malone */ 320481bce6cSEd Schouten static void 321a04667abSHiroki Sato logmessage(int pri, const char *tag, struct socks *sk, ssize_t nsock, 32281280940SEdwin Groothuis const char *buf) 323b0fe2da8SDavid Malone { 324b0fe2da8SDavid Malone char *line; 325a04667abSHiroki Sato int len, i, lsent; 326b0fe2da8SDavid Malone 327a04667abSHiroki Sato if (nsock == 0) { 328b0fe2da8SDavid Malone syslog(pri, "%s", buf); 329b0fe2da8SDavid Malone return; 330b0fe2da8SDavid Malone } 33181280940SEdwin Groothuis if ((len = asprintf(&line, "<%d>%s: %s", pri, tag, buf)) == -1) 332b0fe2da8SDavid Malone errx(1, "asprintf"); 333b0fe2da8SDavid Malone 334865059c8SPhilippe Charnier lsent = -1; 335a04667abSHiroki Sato for (i = 0; i < nsock; i++) { 336a04667abSHiroki Sato lsent = sendto(sk[i].sk_sock, line, len, 0, 337a04667abSHiroki Sato sstosa(&sk[i].sk_addr), sk[i].sk_addrlen); 3380b5f90afSHajimu UMEMOTO if (lsent == len && !send_to_all) 3390b5f90afSHajimu UMEMOTO break; 3400b5f90afSHajimu UMEMOTO } 3419bd5ae85SDavid Malone if (lsent != len) { 34257c1a0b6SBill Fenner if (lsent == -1) 34357c1a0b6SBill Fenner warn("sendto"); 34457c1a0b6SBill Fenner else 34557c1a0b6SBill Fenner warnx("sendto: short send - %d bytes", lsent); 3469bd5ae85SDavid Malone } 347b0fe2da8SDavid Malone 348b0fe2da8SDavid Malone free(line); 349b0fe2da8SDavid Malone } 350b0fe2da8SDavid Malone 351b0fe2da8SDavid Malone /* 3529b50d902SRodney W. Grimes * Decode a symbolic name to a numeric value 3539b50d902SRodney W. Grimes */ 354481bce6cSEd Schouten static int 355f4ac32deSDavid Malone pencode(char *s) 3569b50d902SRodney W. Grimes { 3579b50d902SRodney W. Grimes char *save; 3589b50d902SRodney W. Grimes int fac, lev; 3599b50d902SRodney W. Grimes 3609b50d902SRodney W. Grimes for (save = s; *s && *s != '.'; ++s); 3619b50d902SRodney W. Grimes if (*s) { 3629b50d902SRodney W. Grimes *s = '\0'; 3639b50d902SRodney W. Grimes fac = decode(save, facilitynames); 364df071556SPhilippe Charnier if (fac < 0) 365df071556SPhilippe Charnier errx(1, "unknown facility name: %s", save); 3669b50d902SRodney W. Grimes *s++ = '.'; 3679b50d902SRodney W. Grimes } 3689b50d902SRodney W. Grimes else { 3699b50d902SRodney W. Grimes fac = 0; 3709b50d902SRodney W. Grimes s = save; 3719b50d902SRodney W. Grimes } 3729b50d902SRodney W. Grimes lev = decode(s, prioritynames); 373df071556SPhilippe Charnier if (lev < 0) 374df071556SPhilippe Charnier errx(1, "unknown priority name: %s", save); 3759b50d902SRodney W. Grimes return ((lev & LOG_PRIMASK) | (fac & LOG_FACMASK)); 3769b50d902SRodney W. Grimes } 3779b50d902SRodney W. Grimes 378481bce6cSEd Schouten static int 37939893d56SEd Schouten decode(char *name, const CODE *codetab) 3809b50d902SRodney W. Grimes { 38139893d56SEd Schouten const CODE *c; 3829b50d902SRodney W. Grimes 3839b50d902SRodney W. Grimes if (isdigit(*name)) 3849b50d902SRodney W. Grimes return (atoi(name)); 3859b50d902SRodney W. Grimes 3869b50d902SRodney W. Grimes for (c = codetab; c->c_name; c++) 3879b50d902SRodney W. Grimes if (!strcasecmp(name, c->c_name)) 3889b50d902SRodney W. Grimes return (c->c_val); 3899b50d902SRodney W. Grimes 3909b50d902SRodney W. Grimes return (-1); 3919b50d902SRodney W. Grimes } 3929b50d902SRodney W. Grimes 393df071556SPhilippe Charnier static void 394f4ac32deSDavid Malone usage(void) 3959b50d902SRodney W. Grimes { 396b0fe2da8SDavid Malone (void)fprintf(stderr, "usage: %s\n", 3976b04b7f6SBruce M Simpson "logger [-46Ais] [-f file] [-h host] [-P port] [-p pri] [-t tag]\n" 398a04667abSHiroki Sato " [-S addr:port] [message ...]" 399b0fe2da8SDavid Malone ); 4009b50d902SRodney W. Grimes exit(1); 4019b50d902SRodney W. Grimes } 402