1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Logging support for the DR Daemon 29 */ 30 31 #include <stdio.h> 32 #include <stdarg.h> 33 #include <string.h> 34 #include <errno.h> 35 #include <syslog.h> 36 37 #include "drd.h" 38 39 #define DRD_MAX_MSG_LEN 512 40 #define DRD_MAX_TIME_LEN 32 41 42 static char *log_prio_str[] = { 43 "EMERG: ", /* LOG_EMERG */ 44 "ALERT: ", /* LOG_ALERT */ 45 "CRIT: ", /* LOG_CRIT */ 46 "ERROR: ", /* LOG_ERR */ 47 "WARNING: ", /* LOG_WARNING */ 48 "NOTICE: ", /* LOG_NOTICE */ 49 "INFO: ", /* LOG_INFO */ 50 "" /* LOG_DEBUG */ 51 }; 52 53 /* 54 * Generate a timestamp string in the provided buffer. 55 * If any errors are encountered, the function returns 56 * with the buffer containing an empty string. 57 */ 58 static void 59 drd_timestamp(char *buf, size_t buflen) 60 { 61 struct tm ltime; 62 struct timeval now; 63 64 if ((buf == NULL) || (buflen == 0)) 65 return; 66 67 buf[0] = '\0'; 68 69 if (gettimeofday(&now, NULL) != 0) { 70 (void) fprintf(stderr, "gettimeofday failed: %s\n", 71 strerror(errno)); 72 return; 73 } 74 75 if (localtime_r(&now.tv_sec, <ime) == NULL) { 76 (void) fprintf(stderr, "localtime_r failed: %s\n", 77 strerror(errno)); 78 return; 79 } 80 81 if (strftime(buf, buflen, "%b %e %T ", <ime) == 0) { 82 (void) fprintf(stderr, "strftime failed: buffer[%d] too " 83 "small\n", buflen); 84 /* 85 * On failure, the contents of the buffer 86 * are indeterminate. Restore it to a known 87 * state before returning. 88 */ 89 buf[0] = '\0'; 90 } 91 } 92 93 static void 94 drd_log_msg(int prio, char *fmt, va_list vap) 95 { 96 char msgbuf[DRD_MAX_MSG_LEN]; 97 char timebuf[DRD_MAX_TIME_LEN] = ""; 98 99 /* generate a timestamp for the SMF log */ 100 drd_timestamp(timebuf, sizeof (timebuf)); 101 102 (void) vsnprintf(msgbuf, DRD_MAX_MSG_LEN, fmt, vap); 103 104 /* 105 * Print the message to stderr. In daemon mode, it 106 * will be sent to the SMF log. In standalone mode, 107 * it will be sent to the controlling terminal. 108 */ 109 (void) fprintf(stderr, "%s%s%s\n", timebuf, log_prio_str[prio], msgbuf); 110 111 if (drd_daemonized) 112 syslog(prio, msgbuf); 113 } 114 115 void 116 drd_err(char *fmt, ...) 117 { 118 va_list vap; 119 120 va_start(vap, fmt); 121 drd_log_msg(LOG_ERR, fmt, vap); 122 va_end(vap); 123 } 124 125 void 126 drd_info(char *fmt, ...) 127 { 128 va_list vap; 129 130 va_start(vap, fmt); 131 drd_log_msg(LOG_INFO, fmt, vap); 132 va_end(vap); 133 } 134 135 void 136 drd_dbg(char *fmt, ...) 137 { 138 va_list vap; 139 140 if (!drd_debug) { 141 /* not debugging */ 142 return; 143 } 144 145 va_start(vap, fmt); 146 drd_log_msg(LOG_DEBUG, fmt, vap); 147 va_end(vap); 148 } 149