1/* $OpenBSD: logger.c,v 1.19 2022/12/04 23:50:48 cheloha Exp $ */ 2/* $NetBSD: logger.c,v 1.4 1994/12/22 06:27:00 jtc Exp $ */ 3 4/* 5 * Copyright (c) 1983, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33#include <errno.h> 34#include <unistd.h> 35#include <limits.h> 36#include <stdlib.h> 37#include <stdio.h> 38#include <ctype.h> 39#include <string.h> 40#include <err.h> 41 42#define SYSLOG_NAMES 43#include <syslog.h> 44 45int decode(char *, CODE *); 46int pencode(char *); 47void usage(void); 48 49/* 50 * logger -- read and log utility 51 * 52 * Reads from an input and arranges to write the result on the system 53 * log. 54 */ 55int 56main(int argc, char *argv[]) 57{ 58 int ch, logflags, pri; 59 char *tag, buf[1024]; 60 61 tag = NULL; 62 pri = LOG_NOTICE; 63 logflags = 0; 64 while ((ch = getopt(argc, argv, "cf:ip:st:")) != -1) 65 switch(ch) { 66 case 'c': /* log to console */ 67 logflags |= LOG_CONS; 68 break; 69 case 'f': /* file to log */ 70 if (freopen(optarg, "r", stdin) == NULL) { 71 (void)fprintf(stderr, "logger: %s: %s.\n", 72 optarg, strerror(errno)); 73 exit(1); 74 } 75 break; 76 case 'i': /* log process id also */ 77 logflags |= LOG_PID; 78 break; 79 case 'p': /* priority */ 80 pri = pencode(optarg); 81 break; 82 case 's': /* log to standard error */ 83 logflags |= LOG_PERROR; 84 break; 85 case 't': /* tag */ 86 tag = optarg; 87 break; 88 default: 89 usage(); 90 } 91 argc -= optind; 92 argv += optind; 93 94 /* setup for logging */ 95 openlog(tag ? tag : getlogin(), logflags, 0); 96 (void) fclose(stdout); 97 98 if (pledge("stdio", NULL) == -1) 99 err(1, "pledge"); 100 101 /* log input line if appropriate */ 102 if (argc > 0) { 103 char *p, *endp; 104 size_t len; 105 106 for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) { 107 len = strlen(*argv); 108 if (p + len > endp && p > buf) { 109 syslog(pri, "%s", buf); 110 p = buf; 111 } 112 if (len > sizeof(buf) - 1) 113 syslog(pri, "%s", *argv++); 114 else { 115 if (p != buf) 116 *p++ = ' '; 117 bcopy(*argv++, p, len); 118 *(p += len) = '\0'; 119 } 120 } 121 if (p != buf) 122 syslog(pri, "%s", buf); 123 } else 124 while (fgets(buf, sizeof(buf), stdin) != NULL) 125 syslog(pri, "%s", buf); 126 exit(0); 127} 128 129/* 130 * Decode a symbolic name to a numeric value 131 */ 132int 133pencode(char *s) 134{ 135 char *save; 136 int fac, lev; 137 138 for (save = s; *s && *s != '.'; ++s); 139 if (*s) { 140 *s = '\0'; 141 fac = decode(save, facilitynames); 142 if (fac < 0) { 143 (void)fprintf(stderr, 144 "logger: unknown facility name: %s.\n", save); 145 exit(1); 146 } 147 *s++ = '.'; 148 } 149 else { 150 fac = 0; 151 s = save; 152 } 153 lev = decode(s, prioritynames); 154 if (lev < 0) { 155 (void)fprintf(stderr, 156 "logger: unknown priority name: %s.\n", save); 157 exit(1); 158 } 159 return ((lev & LOG_PRIMASK) | (fac & LOG_FACMASK)); 160} 161 162int 163decode(char *name, CODE *codetab) 164{ 165 CODE *c; 166 167 if (isdigit((unsigned char)*name)) { 168 const char *errstr; 169 int n = strtonum(name, 0, INT_MAX, &errstr); 170 if (!errstr) 171 return (n); 172 } 173 174 for (c = codetab; c->c_name; c++) 175 if (!strcasecmp(name, c->c_name)) 176 return (c->c_val); 177 178 return (-1); 179} 180 181void 182usage(void) 183{ 184 (void)fprintf(stderr, 185 "usage: logger [-cis] [-f file] [-p pri] [-t tag] [message ...]\n"); 186 exit(1); 187} 188