1 /* $OpenBSD: logger.c,v 1.17 2016/03/28 18:18:52 chl 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, "f:ip:st:")) != -1) 65 switch(ch) { 66 case 'f': /* file to log */ 67 if (freopen(optarg, "r", stdin) == NULL) { 68 (void)fprintf(stderr, "logger: %s: %s.\n", 69 optarg, strerror(errno)); 70 exit(1); 71 } 72 break; 73 case 'i': /* log process id also */ 74 logflags |= LOG_PID; 75 break; 76 case 'p': /* priority */ 77 pri = pencode(optarg); 78 break; 79 case 's': /* log to standard error */ 80 logflags |= LOG_PERROR; 81 break; 82 case 't': /* tag */ 83 tag = optarg; 84 break; 85 case '?': 86 default: 87 usage(); 88 } 89 argc -= optind; 90 argv += optind; 91 92 /* setup for logging */ 93 openlog(tag ? tag : getlogin(), logflags, 0); 94 (void) fclose(stdout); 95 96 if (pledge("stdio", NULL) == -1) 97 err(1, "pledge"); 98 99 /* log input line if appropriate */ 100 if (argc > 0) { 101 char *p, *endp; 102 size_t len; 103 104 for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) { 105 len = strlen(*argv); 106 if (p + len > endp && p > buf) { 107 syslog(pri, "%s", buf); 108 p = buf; 109 } 110 if (len > sizeof(buf) - 1) 111 syslog(pri, "%s", *argv++); 112 else { 113 if (p != buf) 114 *p++ = ' '; 115 bcopy(*argv++, p, len); 116 *(p += len) = '\0'; 117 } 118 } 119 if (p != buf) 120 syslog(pri, "%s", buf); 121 } else 122 while (fgets(buf, sizeof(buf), stdin) != NULL) 123 syslog(pri, "%s", buf); 124 exit(0); 125 } 126 127 /* 128 * Decode a symbolic name to a numeric value 129 */ 130 int 131 pencode(char *s) 132 { 133 char *save; 134 int fac, lev; 135 136 for (save = s; *s && *s != '.'; ++s); 137 if (*s) { 138 *s = '\0'; 139 fac = decode(save, facilitynames); 140 if (fac < 0) { 141 (void)fprintf(stderr, 142 "logger: unknown facility name: %s.\n", save); 143 exit(1); 144 } 145 *s++ = '.'; 146 } 147 else { 148 fac = 0; 149 s = save; 150 } 151 lev = decode(s, prioritynames); 152 if (lev < 0) { 153 (void)fprintf(stderr, 154 "logger: unknown priority name: %s.\n", save); 155 exit(1); 156 } 157 return ((lev & LOG_PRIMASK) | (fac & LOG_FACMASK)); 158 } 159 160 int 161 decode(char *name, CODE *codetab) 162 { 163 CODE *c; 164 165 if (isdigit((unsigned char)*name)) { 166 const char *errstr; 167 int n = strtonum(name, 0, INT_MAX, &errstr); 168 if (!errstr) 169 return (n); 170 } 171 172 for (c = codetab; c->c_name; c++) 173 if (!strcasecmp(name, c->c_name)) 174 return (c->c_val); 175 176 return (-1); 177 } 178 179 void 180 usage(void) 181 { 182 (void)fprintf(stderr, 183 "usage: logger [-is] [-f file] [-p pri] [-t tag] [message ...]\n"); 184 exit(1); 185 } 186