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 44static 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 */ 60static void 61drd_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 95static void 96drd_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 117void 118drd_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 127void 128drd_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 137void 138drd_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