1 /* $OpenBSD: logger.c,v 1.18 2019/06/17 00:23:03 guenther 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 45 int decode(char *, CODE *); 46 int pencode(char *); 47 void 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 */ 55 int 56 main(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 case '?': 89 default: 90 usage(); 91 } 92 argc -= optind; 93 argv += optind; 94 95 /* setup for logging */ 96 openlog(tag ? tag : getlogin(), logflags, 0); 97 (void) fclose(stdout); 98 99 if (pledge("stdio", NULL) == -1) 100 err(1, "pledge"); 101 102 /* log input line if appropriate */ 103 if (argc > 0) { 104 char *p, *endp; 105 size_t len; 106 107 for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) { 108 len = strlen(*argv); 109 if (p + len > endp && p > buf) { 110 syslog(pri, "%s", buf); 111 p = buf; 112 } 113 if (len > sizeof(buf) - 1) 114 syslog(pri, "%s", *argv++); 115 else { 116 if (p != buf) 117 *p++ = ' '; 118 bcopy(*argv++, p, len); 119 *(p += len) = '\0'; 120 } 121 } 122 if (p != buf) 123 syslog(pri, "%s", buf); 124 } else 125 while (fgets(buf, sizeof(buf), stdin) != NULL) 126 syslog(pri, "%s", buf); 127 exit(0); 128 } 129 130 /* 131 * Decode a symbolic name to a numeric value 132 */ 133 int 134 pencode(char *s) 135 { 136 char *save; 137 int fac, lev; 138 139 for (save = s; *s && *s != '.'; ++s); 140 if (*s) { 141 *s = '\0'; 142 fac = decode(save, facilitynames); 143 if (fac < 0) { 144 (void)fprintf(stderr, 145 "logger: unknown facility name: %s.\n", save); 146 exit(1); 147 } 148 *s++ = '.'; 149 } 150 else { 151 fac = 0; 152 s = save; 153 } 154 lev = decode(s, prioritynames); 155 if (lev < 0) { 156 (void)fprintf(stderr, 157 "logger: unknown priority name: %s.\n", save); 158 exit(1); 159 } 160 return ((lev & LOG_PRIMASK) | (fac & LOG_FACMASK)); 161 } 162 163 int 164 decode(char *name, CODE *codetab) 165 { 166 CODE *c; 167 168 if (isdigit((unsigned char)*name)) { 169 const char *errstr; 170 int n = strtonum(name, 0, INT_MAX, &errstr); 171 if (!errstr) 172 return (n); 173 } 174 175 for (c = codetab; c->c_name; c++) 176 if (!strcasecmp(name, c->c_name)) 177 return (c->c_val); 178 179 return (-1); 180 } 181 182 void 183 usage(void) 184 { 185 (void)fprintf(stderr, 186 "usage: logger [-cis] [-f file] [-p pri] [-t tag] [message ...]\n"); 187 exit(1); 188 } 189