11d4b38e0Srsmaeda /* 21d4b38e0Srsmaeda * CDDL HEADER START 31d4b38e0Srsmaeda * 41d4b38e0Srsmaeda * The contents of this file are subject to the terms of the 51d4b38e0Srsmaeda * Common Development and Distribution License (the "License"). 61d4b38e0Srsmaeda * You may not use this file except in compliance with the License. 71d4b38e0Srsmaeda * 81d4b38e0Srsmaeda * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 91d4b38e0Srsmaeda * or http://www.opensolaris.org/os/licensing. 101d4b38e0Srsmaeda * See the License for the specific language governing permissions 111d4b38e0Srsmaeda * and limitations under the License. 121d4b38e0Srsmaeda * 131d4b38e0Srsmaeda * When distributing Covered Code, include this CDDL HEADER in each 141d4b38e0Srsmaeda * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 151d4b38e0Srsmaeda * If applicable, add the following below this CDDL HEADER, with the 161d4b38e0Srsmaeda * fields enclosed by brackets "[]" replaced with your own identifying 171d4b38e0Srsmaeda * information: Portions Copyright [yyyy] [name of copyright owner] 181d4b38e0Srsmaeda * 191d4b38e0Srsmaeda * CDDL HEADER END 201d4b38e0Srsmaeda */ 211d4b38e0Srsmaeda 221d4b38e0Srsmaeda /* 231d4b38e0Srsmaeda * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 241d4b38e0Srsmaeda * Use is subject to license terms. 251d4b38e0Srsmaeda */ 261d4b38e0Srsmaeda 271d4b38e0Srsmaeda #pragma ident "%Z%%M% %I% %E% SMI" 281d4b38e0Srsmaeda 291d4b38e0Srsmaeda /* 301d4b38e0Srsmaeda * Logging support for the DR Daemon 311d4b38e0Srsmaeda */ 321d4b38e0Srsmaeda 331d4b38e0Srsmaeda #include <stdio.h> 341d4b38e0Srsmaeda #include <stdarg.h> 35*20046e4cSjm22469 #include <string.h> 36*20046e4cSjm22469 #include <errno.h> 371d4b38e0Srsmaeda #include <syslog.h> 381d4b38e0Srsmaeda 391d4b38e0Srsmaeda #include "drd.h" 401d4b38e0Srsmaeda 411d4b38e0Srsmaeda #define DRD_MAX_MSG_LEN 512 42*20046e4cSjm22469 #define DRD_MAX_TIME_LEN 32 431d4b38e0Srsmaeda 441d4b38e0Srsmaeda static char *log_prio_str[] = { 451d4b38e0Srsmaeda "EMERG: ", /* LOG_EMERG */ 461d4b38e0Srsmaeda "ALERT: ", /* LOG_ALERT */ 471d4b38e0Srsmaeda "CRIT: ", /* LOG_CRIT */ 481d4b38e0Srsmaeda "ERROR: ", /* LOG_ERR */ 491d4b38e0Srsmaeda "WARNING: ", /* LOG_WARNING */ 501d4b38e0Srsmaeda "NOTICE: ", /* LOG_NOTICE */ 511d4b38e0Srsmaeda "INFO: ", /* LOG_INFO */ 521d4b38e0Srsmaeda "" /* LOG_DEBUG */ 531d4b38e0Srsmaeda }; 541d4b38e0Srsmaeda 55*20046e4cSjm22469 /* 56*20046e4cSjm22469 * Generate a timestamp string in the provided buffer. 57*20046e4cSjm22469 * If any errors are encountered, the function returns 58*20046e4cSjm22469 * with the buffer containing an empty string. 59*20046e4cSjm22469 */ 601d4b38e0Srsmaeda static void 61*20046e4cSjm22469 drd_timestamp(char *buf, size_t buflen) 621d4b38e0Srsmaeda { 63*20046e4cSjm22469 struct tm ltime; 64*20046e4cSjm22469 struct timeval now; 651d4b38e0Srsmaeda 66*20046e4cSjm22469 if ((buf == NULL) || (buflen == 0)) 67*20046e4cSjm22469 return; 681d4b38e0Srsmaeda 69*20046e4cSjm22469 buf[0] = '\0'; 70*20046e4cSjm22469 71*20046e4cSjm22469 if (gettimeofday(&now, NULL) != 0) { 72*20046e4cSjm22469 (void) fprintf(stderr, "gettimeofday failed: %s\n", 73*20046e4cSjm22469 strerror(errno)); 741d4b38e0Srsmaeda return; 751d4b38e0Srsmaeda } 761d4b38e0Srsmaeda 77*20046e4cSjm22469 if (localtime_r(&now.tv_sec, <ime) == NULL) { 78*20046e4cSjm22469 (void) fprintf(stderr, "localtime_r failed: %s\n", 79*20046e4cSjm22469 strerror(errno)); 80*20046e4cSjm22469 return; 81*20046e4cSjm22469 } 82*20046e4cSjm22469 83*20046e4cSjm22469 if (strftime(buf, buflen, "%b %e %T ", <ime) == 0) { 84*20046e4cSjm22469 (void) fprintf(stderr, "strftime failed: buffer[%d] too " 85*20046e4cSjm22469 "small\n", buflen); 86*20046e4cSjm22469 /* 87*20046e4cSjm22469 * On failure, the contents of the buffer 88*20046e4cSjm22469 * are indeterminate. Restore it to a known 89*20046e4cSjm22469 * state before returning. 90*20046e4cSjm22469 */ 91*20046e4cSjm22469 buf[0] = '\0'; 92*20046e4cSjm22469 } 93*20046e4cSjm22469 } 94*20046e4cSjm22469 95*20046e4cSjm22469 static void 96*20046e4cSjm22469 drd_log_msg(int prio, char *fmt, va_list vap) 97*20046e4cSjm22469 { 98*20046e4cSjm22469 char msgbuf[DRD_MAX_MSG_LEN]; 99*20046e4cSjm22469 char timebuf[DRD_MAX_TIME_LEN] = ""; 100*20046e4cSjm22469 101*20046e4cSjm22469 /* generate a timestamp for the SMF log */ 102*20046e4cSjm22469 drd_timestamp(timebuf, sizeof (timebuf)); 103*20046e4cSjm22469 104*20046e4cSjm22469 (void) vsnprintf(msgbuf, DRD_MAX_MSG_LEN, fmt, vap); 105*20046e4cSjm22469 106*20046e4cSjm22469 /* 107*20046e4cSjm22469 * Print the message to stderr. In daemon mode, it 108*20046e4cSjm22469 * will be sent to the SMF log. In standalone mode, 109*20046e4cSjm22469 * it will be sent to the controlling terminal. 110*20046e4cSjm22469 */ 111*20046e4cSjm22469 (void) fprintf(stderr, "%s%s%s\n", timebuf, log_prio_str[prio], msgbuf); 112*20046e4cSjm22469 113*20046e4cSjm22469 if (drd_daemonized) 114*20046e4cSjm22469 syslog(prio, msgbuf); 1151d4b38e0Srsmaeda } 1161d4b38e0Srsmaeda 1171d4b38e0Srsmaeda void 1181d4b38e0Srsmaeda drd_err(char *fmt, ...) 1191d4b38e0Srsmaeda { 1201d4b38e0Srsmaeda va_list vap; 1211d4b38e0Srsmaeda 1221d4b38e0Srsmaeda va_start(vap, fmt); 1231d4b38e0Srsmaeda drd_log_msg(LOG_ERR, fmt, vap); 1241d4b38e0Srsmaeda va_end(vap); 1251d4b38e0Srsmaeda } 1261d4b38e0Srsmaeda 1271d4b38e0Srsmaeda void 1281d4b38e0Srsmaeda drd_info(char *fmt, ...) 1291d4b38e0Srsmaeda { 1301d4b38e0Srsmaeda va_list vap; 1311d4b38e0Srsmaeda 1321d4b38e0Srsmaeda va_start(vap, fmt); 1331d4b38e0Srsmaeda drd_log_msg(LOG_INFO, fmt, vap); 1341d4b38e0Srsmaeda va_end(vap); 1351d4b38e0Srsmaeda } 1361d4b38e0Srsmaeda 1371d4b38e0Srsmaeda void 1381d4b38e0Srsmaeda drd_dbg(char *fmt, ...) 1391d4b38e0Srsmaeda { 1401d4b38e0Srsmaeda va_list vap; 1411d4b38e0Srsmaeda 1421d4b38e0Srsmaeda if (!drd_debug) { 1431d4b38e0Srsmaeda /* not debugging */ 1441d4b38e0Srsmaeda return; 1451d4b38e0Srsmaeda } 1461d4b38e0Srsmaeda 1471d4b38e0Srsmaeda va_start(vap, fmt); 1481d4b38e0Srsmaeda drd_log_msg(LOG_DEBUG, fmt, vap); 1491d4b38e0Srsmaeda va_end(vap); 1501d4b38e0Srsmaeda } 151