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 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * Logging support for the DR Daemon 31 */ 32 33 #include <stdio.h> 34 #include <stdarg.h> 35 #include <string.h> 36 #include <errno.h> 37 #include <syslog.h> 38 39 #include "drd.h" 40 41 #define DRD_MAX_MSG_LEN 512 42 #define DRD_MAX_TIME_LEN 32 43 44 static char *log_prio_str[] = { 45 "EMERG: ", /* LOG_EMERG */ 46 "ALERT: ", /* LOG_ALERT */ 47 "CRIT: ", /* LOG_CRIT */ 48 "ERROR: ", /* LOG_ERR */ 49 "WARNING: ", /* LOG_WARNING */ 50 "NOTICE: ", /* LOG_NOTICE */ 51 "INFO: ", /* LOG_INFO */ 52 "" /* LOG_DEBUG */ 53 }; 54 55 /* 56 * Generate a timestamp string in the provided buffer. 57 * If any errors are encountered, the function returns 58 * with the buffer containing an empty string. 59 */ 60 static void 61 drd_timestamp(char *buf, size_t buflen) 62 { 63 struct tm ltime; 64 struct timeval now; 65 66 if ((buf == NULL) || (buflen == 0)) 67 return; 68 69 buf[0] = '\0'; 70 71 if (gettimeofday(&now, NULL) != 0) { 72 (void) fprintf(stderr, "gettimeofday failed: %s\n", 73 strerror(errno)); 74 return; 75 } 76 77 if (localtime_r(&now.tv_sec, <ime) == NULL) { 78 (void) fprintf(stderr, "localtime_r failed: %s\n", 79 strerror(errno)); 80 return; 81 } 82 83 if (strftime(buf, buflen, "%b %e %T ", <ime) == 0) { 84 (void) fprintf(stderr, "strftime failed: buffer[%d] too " 85 "small\n", buflen); 86 /* 87 * On failure, the contents of the buffer 88 * are indeterminate. Restore it to a known 89 * state before returning. 90 */ 91 buf[0] = '\0'; 92 } 93 } 94 95 static void 96 drd_log_msg(int prio, char *fmt, va_list vap) 97 { 98 char msgbuf[DRD_MAX_MSG_LEN]; 99 char timebuf[DRD_MAX_TIME_LEN] = ""; 100 101 /* generate a timestamp for the SMF log */ 102 drd_timestamp(timebuf, sizeof (timebuf)); 103 104 (void) vsnprintf(msgbuf, DRD_MAX_MSG_LEN, fmt, vap); 105 106 /* 107 * Print the message to stderr. In daemon mode, it 108 * will be sent to the SMF log. In standalone mode, 109 * it will be sent to the controlling terminal. 110 */ 111 (void) fprintf(stderr, "%s%s%s\n", timebuf, log_prio_str[prio], msgbuf); 112 113 if (drd_daemonized) 114 syslog(prio, msgbuf); 115 } 116 117 void 118 drd_err(char *fmt, ...) 119 { 120 va_list vap; 121 122 va_start(vap, fmt); 123 drd_log_msg(LOG_ERR, fmt, vap); 124 va_end(vap); 125 } 126 127 void 128 drd_info(char *fmt, ...) 129 { 130 va_list vap; 131 132 va_start(vap, fmt); 133 drd_log_msg(LOG_INFO, fmt, vap); 134 va_end(vap); 135 } 136 137 void 138 drd_dbg(char *fmt, ...) 139 { 140 va_list vap; 141 142 if (!drd_debug) { 143 /* not debugging */ 144 return; 145 } 146 147 va_start(vap, fmt); 148 drd_log_msg(LOG_DEBUG, fmt, vap); 149 va_end(vap); 150 } 151