1*8a16b7a1SPedro F. Giffuni /*- 2*8a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 3*8a16b7a1SPedro F. Giffuni * 49b50d902SRodney W. Grimes * Copyright (c) 1983, 1993 59b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 69b50d902SRodney W. Grimes * 79b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 89b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 99b50d902SRodney W. Grimes * are met: 109b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 119b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 129b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 139b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 149b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 15fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 169b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 179b50d902SRodney W. Grimes * without specific prior written permission. 189b50d902SRodney W. Grimes * 199b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 209b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 219b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 229b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 239b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 249b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 259b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 269b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 279b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 289b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 299b50d902SRodney W. Grimes * SUCH DAMAGE. 309b50d902SRodney W. Grimes */ 319b50d902SRodney W. Grimes 329b50d902SRodney W. Grimes #ifndef lint 33df071556SPhilippe Charnier static const char copyright[] = 349b50d902SRodney W. Grimes "@(#) Copyright (c) 1983, 1993\n\ 359b50d902SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 369b50d902SRodney W. Grimes #endif /* not lint */ 379b50d902SRodney W. Grimes 38df071556SPhilippe Charnier #if 0 39865059c8SPhilippe Charnier #ifndef lint 409b50d902SRodney W. Grimes static char sccsid[] = "@(#)logger.c 8.1 (Berkeley) 6/6/93"; 419b50d902SRodney W. Grimes #endif /* not lint */ 42865059c8SPhilippe Charnier #endif 43865059c8SPhilippe Charnier 449bd5ae85SDavid Malone #include <sys/cdefs.h> 459bd5ae85SDavid Malone __FBSDID("$FreeBSD$"); 469bd5ae85SDavid Malone 47b0fe2da8SDavid Malone #include <sys/types.h> 48b0fe2da8SDavid Malone #include <sys/socket.h> 49b0fe2da8SDavid Malone #include <netinet/in.h> 50b0fe2da8SDavid Malone 519b50d902SRodney W. Grimes #include <ctype.h> 52df071556SPhilippe Charnier #include <err.h> 53b0fe2da8SDavid Malone #include <netdb.h> 54df071556SPhilippe Charnier #include <stdio.h> 55df071556SPhilippe Charnier #include <stdlib.h> 569b50d902SRodney W. Grimes #include <string.h> 57df071556SPhilippe Charnier #include <unistd.h> 589b50d902SRodney W. Grimes 599b50d902SRodney W. Grimes #define SYSLOG_NAMES 609b50d902SRodney W. Grimes #include <syslog.h> 619b50d902SRodney W. Grimes 62a04667abSHiroki Sato #define sstosa(ss) ((struct sockaddr *)(void *)ss) 639b50d902SRodney W. Grimes 640b5f90afSHajimu UMEMOTO struct socks { 65a04667abSHiroki Sato int sk_sock; 66a04667abSHiroki Sato int sk_addrlen; 67a04667abSHiroki Sato struct sockaddr_storage sk_addr; 680b5f90afSHajimu UMEMOTO }; 690b5f90afSHajimu UMEMOTO 70a04667abSHiroki Sato static int decode(char *, const CODE *); 71a04667abSHiroki Sato static int pencode(char *); 72a04667abSHiroki Sato static ssize_t socksetup(const char *, const char *, const char *, 73a04667abSHiroki Sato struct socks **); 74a04667abSHiroki Sato static void logmessage(int, const char *, struct socks *, ssize_t, 75a04667abSHiroki Sato const char *); 76a04667abSHiroki Sato static void usage(void); 77a04667abSHiroki Sato 780b5f90afSHajimu UMEMOTO #ifdef INET6 79481bce6cSEd Schouten static int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) */ 800b5f90afSHajimu UMEMOTO #else 81481bce6cSEd Schouten static int family = PF_INET; /* protocol family (IPv4 only) */ 820b5f90afSHajimu UMEMOTO #endif 83481bce6cSEd Schouten static int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */ 840b5f90afSHajimu UMEMOTO 859b50d902SRodney W. Grimes /* 869b50d902SRodney W. Grimes * logger -- read and log utility 879b50d902SRodney W. Grimes * 889b50d902SRodney W. Grimes * Reads from an input and arranges to write the result on the system 899b50d902SRodney W. Grimes * log. 909b50d902SRodney W. Grimes */ 919b50d902SRodney W. Grimes int 92f4ac32deSDavid Malone main(int argc, char *argv[]) 939b50d902SRodney W. Grimes { 94a04667abSHiroki Sato struct socks *socks; 95a04667abSHiroki Sato ssize_t nsock; 969b50d902SRodney W. Grimes int ch, logflags, pri; 976f62d863SDavid Malone char *tag, *host, buf[1024]; 98a04667abSHiroki Sato const char *svcname, *src; 999b50d902SRodney W. Grimes 1009b50d902SRodney W. Grimes tag = NULL; 101b0fe2da8SDavid Malone host = NULL; 1026b04b7f6SBruce M Simpson svcname = "syslog"; 103a04667abSHiroki Sato src = NULL; 1048f14a1afSHiroki Sato socks = NULL; 105ca122bf7SRuslan Ermilov pri = LOG_USER | LOG_NOTICE; 1069b50d902SRodney W. Grimes logflags = 0; 10740244c28SPoul-Henning Kamp unsetenv("TZ"); 108a04667abSHiroki Sato while ((ch = getopt(argc, argv, "46Af:h:iP:p:S:st:")) != -1) 1099b50d902SRodney W. Grimes switch((char)ch) { 1100b5f90afSHajimu UMEMOTO case '4': 1110b5f90afSHajimu UMEMOTO family = PF_INET; 1120b5f90afSHajimu UMEMOTO break; 1130b5f90afSHajimu UMEMOTO #ifdef INET6 1140b5f90afSHajimu UMEMOTO case '6': 1150b5f90afSHajimu UMEMOTO family = PF_INET6; 1160b5f90afSHajimu UMEMOTO break; 1170b5f90afSHajimu UMEMOTO #endif 1180b5f90afSHajimu UMEMOTO case 'A': 1190b5f90afSHajimu UMEMOTO send_to_all++; 1200b5f90afSHajimu UMEMOTO break; 1219b50d902SRodney W. Grimes case 'f': /* file to log */ 122df071556SPhilippe Charnier if (freopen(optarg, "r", stdin) == NULL) 123df071556SPhilippe Charnier err(1, "%s", optarg); 1244145bb53SKirk McKusick setvbuf(stdin, 0, _IONBF, 0); 1259b50d902SRodney W. Grimes break; 126b0fe2da8SDavid Malone case 'h': /* hostname to deliver to */ 127b0fe2da8SDavid Malone host = optarg; 128b0fe2da8SDavid Malone break; 1299b50d902SRodney W. Grimes case 'i': /* log process id also */ 1309b50d902SRodney W. Grimes logflags |= LOG_PID; 1319b50d902SRodney W. Grimes break; 1326b04b7f6SBruce M Simpson case 'P': /* service name or port number */ 1336b04b7f6SBruce M Simpson svcname = optarg; 1346b04b7f6SBruce M Simpson break; 1359b50d902SRodney W. Grimes case 'p': /* priority */ 1369b50d902SRodney W. Grimes pri = pencode(optarg); 1379b50d902SRodney W. Grimes break; 1389b50d902SRodney W. Grimes case 's': /* log to standard error */ 1399b50d902SRodney W. Grimes logflags |= LOG_PERROR; 1409b50d902SRodney W. Grimes break; 141a04667abSHiroki Sato case 'S': /* source address */ 142a04667abSHiroki Sato src = optarg; 143a04667abSHiroki Sato break; 1449b50d902SRodney W. Grimes case 't': /* tag */ 1459b50d902SRodney W. Grimes tag = optarg; 1469b50d902SRodney W. Grimes break; 1479b50d902SRodney W. Grimes case '?': 1489b50d902SRodney W. Grimes default: 1499b50d902SRodney W. Grimes usage(); 1509b50d902SRodney W. Grimes } 1519b50d902SRodney W. Grimes argc -= optind; 1529b50d902SRodney W. Grimes argv += optind; 1539b50d902SRodney W. Grimes 154a04667abSHiroki Sato if (host) { 155a04667abSHiroki Sato nsock = socksetup(src, host, svcname, &socks); 156a04667abSHiroki Sato if (nsock <= 0) 157a04667abSHiroki Sato errx(1, "socket"); 158a04667abSHiroki Sato } else { 159a04667abSHiroki Sato if (src) 160a04667abSHiroki Sato errx(1, "-h option is missing."); 161a04667abSHiroki Sato nsock = 0; 162a04667abSHiroki Sato } 163a04667abSHiroki Sato 16481280940SEdwin Groothuis if (tag == NULL) 16581280940SEdwin Groothuis tag = getlogin(); 1669b50d902SRodney W. Grimes /* setup for logging */ 16781280940SEdwin Groothuis if (host == NULL) 16881280940SEdwin Groothuis openlog(tag, logflags, 0); 1699b50d902SRodney W. Grimes (void) fclose(stdout); 1709b50d902SRodney W. Grimes 1719b50d902SRodney W. Grimes /* log input line if appropriate */ 1729b50d902SRodney W. Grimes if (argc > 0) { 173f4ac32deSDavid Malone char *p, *endp; 1749bd5ae85SDavid Malone size_t len; 1759b50d902SRodney W. Grimes 1769b50d902SRodney W. Grimes for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) { 1779b50d902SRodney W. Grimes len = strlen(*argv); 1789b50d902SRodney W. Grimes if (p + len > endp && p > buf) { 179a04667abSHiroki Sato logmessage(pri, tag, socks, nsock, buf); 1809b50d902SRodney W. Grimes p = buf; 1819b50d902SRodney W. Grimes } 1829b50d902SRodney W. Grimes if (len > sizeof(buf) - 1) 183a04667abSHiroki Sato logmessage(pri, tag, socks, nsock, *argv++); 1849b50d902SRodney W. Grimes else { 1859b50d902SRodney W. Grimes if (p != buf) 1869b50d902SRodney W. Grimes *p++ = ' '; 1879b50d902SRodney W. Grimes bcopy(*argv++, p, len); 1889b50d902SRodney W. Grimes *(p += len) = '\0'; 1899b50d902SRodney W. Grimes } 1909b50d902SRodney W. Grimes } 1919b50d902SRodney W. Grimes if (p != buf) 192a04667abSHiroki Sato logmessage(pri, tag, socks, nsock, buf); 1939b50d902SRodney W. Grimes } else 1949b50d902SRodney W. Grimes while (fgets(buf, sizeof(buf), stdin) != NULL) 195a04667abSHiroki Sato logmessage(pri, tag, socks, nsock, buf); 1969b50d902SRodney W. Grimes exit(0); 1979b50d902SRodney W. Grimes } 1989b50d902SRodney W. Grimes 199a04667abSHiroki Sato static ssize_t 200a04667abSHiroki Sato socksetup(const char *src, const char *dst, const char *svcname, 201a04667abSHiroki Sato struct socks **socks) 202a04667abSHiroki Sato { 203a04667abSHiroki Sato struct addrinfo hints, *res, *res0; 204a04667abSHiroki Sato struct sockaddr_storage *ss_src[AF_MAX]; 205a04667abSHiroki Sato struct socks *sk; 206a04667abSHiroki Sato ssize_t nsock = 0; 207a04667abSHiroki Sato int error, maxs; 208a04667abSHiroki Sato 209a04667abSHiroki Sato memset(&ss_src[0], 0, sizeof(ss_src)); 210a04667abSHiroki Sato if (src) { 211a04667abSHiroki Sato char *p, *p0, *hs, *hbuf, *sbuf; 212a04667abSHiroki Sato 213a04667abSHiroki Sato hbuf = sbuf = NULL; 214a04667abSHiroki Sato p0 = p = strdup(src); 215a04667abSHiroki Sato if (p0 == NULL) 216a04667abSHiroki Sato err(1, "strdup failed"); 217a04667abSHiroki Sato hs = p0; /* point to search ":" */ 218a04667abSHiroki Sato #ifdef INET6 219a04667abSHiroki Sato /* -S option supports IPv6 addr in "[2001:db8::1]:service". */ 220a04667abSHiroki Sato if (*p0 == '[') { 221a04667abSHiroki Sato p = strchr(p0, ']'); 222a04667abSHiroki Sato if (p == NULL) 223a04667abSHiroki Sato errx(1, "\"]\" not found in src addr"); 224a04667abSHiroki Sato *p = '\0'; 225a04667abSHiroki Sato /* hs points just after ']' (':' or '\0'). */ 226a04667abSHiroki Sato hs = p + 1; 227a04667abSHiroki Sato /* 228a04667abSHiroki Sato * p points just after '[' while it points hs 229a04667abSHiroki Sato * in the case of []. 230a04667abSHiroki Sato */ 231a04667abSHiroki Sato p = ((p0 + 1) == (hs - 1)) ? hs : p0 + 1; 232a04667abSHiroki Sato } 233a04667abSHiroki Sato #endif 234a04667abSHiroki Sato if (*p != '\0') { 235a04667abSHiroki Sato /* (p == hs) means ":514" or "[]:514". */ 236a04667abSHiroki Sato hbuf = (p == hs && *p == ':') ? NULL : p; 237a04667abSHiroki Sato p = strchr(hs, ':'); 238a04667abSHiroki Sato if (p != NULL) { 239a04667abSHiroki Sato *p = '\0'; 240a04667abSHiroki Sato sbuf = (*(p + 1) != '\0') ? p + 1 : NULL; 241a04667abSHiroki Sato } 242a04667abSHiroki Sato } 243a04667abSHiroki Sato hints = (struct addrinfo){ 244a04667abSHiroki Sato .ai_family = family, 245a04667abSHiroki Sato .ai_socktype = SOCK_DGRAM, 246a04667abSHiroki Sato .ai_flags = AI_PASSIVE 247a04667abSHiroki Sato }; 248a04667abSHiroki Sato error = getaddrinfo(hbuf, sbuf, &hints, &res0); 249a04667abSHiroki Sato if (error) 250a04667abSHiroki Sato errx(1, "%s: %s", gai_strerror(error), src); 251a04667abSHiroki Sato for (res = res0; res; res = res->ai_next) { 252a04667abSHiroki Sato switch (res->ai_family) { 253a04667abSHiroki Sato case AF_INET: 254a04667abSHiroki Sato #ifdef INET6 255a04667abSHiroki Sato case AF_INET6: 256a04667abSHiroki Sato #endif 257a04667abSHiroki Sato if (ss_src[res->ai_family] != NULL) 258a04667abSHiroki Sato continue; 259a04667abSHiroki Sato ss_src[res->ai_family] = 260a04667abSHiroki Sato malloc(sizeof(struct sockaddr_storage)); 261a04667abSHiroki Sato if (ss_src[res->ai_family] == NULL) 262a04667abSHiroki Sato err(1, "malloc failed"); 263a04667abSHiroki Sato memcpy(ss_src[res->ai_family], res->ai_addr, 264a04667abSHiroki Sato res->ai_addrlen); 265a04667abSHiroki Sato } 266a04667abSHiroki Sato } 267a04667abSHiroki Sato freeaddrinfo(res0); 268a04667abSHiroki Sato free(p0); 269a04667abSHiroki Sato } 270a04667abSHiroki Sato 271a04667abSHiroki Sato /* resolve hostname */ 272a04667abSHiroki Sato hints = (struct addrinfo){ 273a04667abSHiroki Sato .ai_family = family, 274a04667abSHiroki Sato .ai_socktype = SOCK_DGRAM 275a04667abSHiroki Sato }; 276a04667abSHiroki Sato error = getaddrinfo(dst, svcname, &hints, &res0); 277a04667abSHiroki Sato if (error == EAI_SERVICE) { 278a04667abSHiroki Sato warnx("%s/udp: unknown service", svcname); 279a04667abSHiroki Sato error = getaddrinfo(dst, "514", &hints, &res); 280a04667abSHiroki Sato } 281a04667abSHiroki Sato if (error) 282a04667abSHiroki Sato errx(1, "%s: %s", gai_strerror(error), dst); 283a04667abSHiroki Sato /* count max number of sockets we may open */ 284a04667abSHiroki Sato maxs = 0; 285a04667abSHiroki Sato for (res = res0; res; res = res->ai_next) 286a04667abSHiroki Sato maxs++; 287a04667abSHiroki Sato sk = calloc(maxs, sizeof(*sk)); 288a04667abSHiroki Sato if (sk == NULL) 289a04667abSHiroki Sato errx(1, "couldn't allocate memory for sockets"); 290a04667abSHiroki Sato for (res = res0; res; res = res->ai_next) { 291a04667abSHiroki Sato int s; 292a04667abSHiroki Sato 293a04667abSHiroki Sato s = socket(res->ai_family, res->ai_socktype, 294a04667abSHiroki Sato res->ai_protocol); 295a04667abSHiroki Sato if (s < 0) 296a04667abSHiroki Sato continue; 297a04667abSHiroki Sato if (src && ss_src[res->ai_family] == NULL) 298a04667abSHiroki Sato errx(1, "address family mismatch"); 299a04667abSHiroki Sato 300a04667abSHiroki Sato if (ss_src[res->ai_family]) { 301a04667abSHiroki Sato error = bind(s, sstosa(ss_src[res->ai_family]), 302a04667abSHiroki Sato ss_src[res->ai_family]->ss_len); 303a04667abSHiroki Sato if (error < 0) 304a04667abSHiroki Sato err(1, "bind"); 305a04667abSHiroki Sato } 306a04667abSHiroki Sato sk[nsock] = (struct socks){ 307a04667abSHiroki Sato .sk_addrlen = res->ai_addrlen, 308a04667abSHiroki Sato .sk_sock = s 309a04667abSHiroki Sato }; 310a04667abSHiroki Sato memcpy(&sk[nsock].sk_addr, res->ai_addr, res->ai_addrlen); 311a04667abSHiroki Sato nsock++; 312a04667abSHiroki Sato } 313a04667abSHiroki Sato freeaddrinfo(res0); 314a04667abSHiroki Sato 315a04667abSHiroki Sato *socks = sk; 316a04667abSHiroki Sato return (nsock); 317a04667abSHiroki Sato } 318a04667abSHiroki Sato 3199b50d902SRodney W. Grimes /* 320b0fe2da8SDavid Malone * Send the message to syslog, either on the local host, or on a remote host 321b0fe2da8SDavid Malone */ 322481bce6cSEd Schouten static void 323a04667abSHiroki Sato logmessage(int pri, const char *tag, struct socks *sk, ssize_t nsock, 32481280940SEdwin Groothuis const char *buf) 325b0fe2da8SDavid Malone { 326b0fe2da8SDavid Malone char *line; 327a04667abSHiroki Sato int len, i, lsent; 328b0fe2da8SDavid Malone 329a04667abSHiroki Sato if (nsock == 0) { 330b0fe2da8SDavid Malone syslog(pri, "%s", buf); 331b0fe2da8SDavid Malone return; 332b0fe2da8SDavid Malone } 33381280940SEdwin Groothuis if ((len = asprintf(&line, "<%d>%s: %s", pri, tag, buf)) == -1) 334b0fe2da8SDavid Malone errx(1, "asprintf"); 335b0fe2da8SDavid Malone 336865059c8SPhilippe Charnier lsent = -1; 337a04667abSHiroki Sato for (i = 0; i < nsock; i++) { 338a04667abSHiroki Sato lsent = sendto(sk[i].sk_sock, line, len, 0, 339a04667abSHiroki Sato sstosa(&sk[i].sk_addr), sk[i].sk_addrlen); 3400b5f90afSHajimu UMEMOTO if (lsent == len && !send_to_all) 3410b5f90afSHajimu UMEMOTO break; 3420b5f90afSHajimu UMEMOTO } 3439bd5ae85SDavid Malone if (lsent != len) { 34457c1a0b6SBill Fenner if (lsent == -1) 34557c1a0b6SBill Fenner warn("sendto"); 34657c1a0b6SBill Fenner else 34757c1a0b6SBill Fenner warnx("sendto: short send - %d bytes", lsent); 3489bd5ae85SDavid Malone } 349b0fe2da8SDavid Malone 350b0fe2da8SDavid Malone free(line); 351b0fe2da8SDavid Malone } 352b0fe2da8SDavid Malone 353b0fe2da8SDavid Malone /* 3549b50d902SRodney W. Grimes * Decode a symbolic name to a numeric value 3559b50d902SRodney W. Grimes */ 356481bce6cSEd Schouten static int 357f4ac32deSDavid Malone pencode(char *s) 3589b50d902SRodney W. Grimes { 3599b50d902SRodney W. Grimes char *save; 3609b50d902SRodney W. Grimes int fac, lev; 3619b50d902SRodney W. Grimes 3629b50d902SRodney W. Grimes for (save = s; *s && *s != '.'; ++s); 3639b50d902SRodney W. Grimes if (*s) { 3649b50d902SRodney W. Grimes *s = '\0'; 3659b50d902SRodney W. Grimes fac = decode(save, facilitynames); 366df071556SPhilippe Charnier if (fac < 0) 367df071556SPhilippe Charnier errx(1, "unknown facility name: %s", save); 3689b50d902SRodney W. Grimes *s++ = '.'; 3699b50d902SRodney W. Grimes } 3709b50d902SRodney W. Grimes else { 3719b50d902SRodney W. Grimes fac = 0; 3729b50d902SRodney W. Grimes s = save; 3739b50d902SRodney W. Grimes } 3749b50d902SRodney W. Grimes lev = decode(s, prioritynames); 375df071556SPhilippe Charnier if (lev < 0) 376df071556SPhilippe Charnier errx(1, "unknown priority name: %s", save); 3779b50d902SRodney W. Grimes return ((lev & LOG_PRIMASK) | (fac & LOG_FACMASK)); 3789b50d902SRodney W. Grimes } 3799b50d902SRodney W. Grimes 380481bce6cSEd Schouten static int 38139893d56SEd Schouten decode(char *name, const CODE *codetab) 3829b50d902SRodney W. Grimes { 38339893d56SEd Schouten const CODE *c; 3849b50d902SRodney W. Grimes 3859b50d902SRodney W. Grimes if (isdigit(*name)) 3869b50d902SRodney W. Grimes return (atoi(name)); 3879b50d902SRodney W. Grimes 3889b50d902SRodney W. Grimes for (c = codetab; c->c_name; c++) 3899b50d902SRodney W. Grimes if (!strcasecmp(name, c->c_name)) 3909b50d902SRodney W. Grimes return (c->c_val); 3919b50d902SRodney W. Grimes 3929b50d902SRodney W. Grimes return (-1); 3939b50d902SRodney W. Grimes } 3949b50d902SRodney W. Grimes 395df071556SPhilippe Charnier static void 396f4ac32deSDavid Malone usage(void) 3979b50d902SRodney W. Grimes { 398b0fe2da8SDavid Malone (void)fprintf(stderr, "usage: %s\n", 3996b04b7f6SBruce M Simpson "logger [-46Ais] [-f file] [-h host] [-P port] [-p pri] [-t tag]\n" 400a04667abSHiroki Sato " [-S addr:port] [message ...]" 401b0fe2da8SDavid Malone ); 4029b50d902SRodney W. Grimes exit(1); 4039b50d902SRodney W. Grimes } 404