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