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 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /* lfmt_log() - log info */ 33 34 #include "lint.h" 35 #include <mtlib.h> 36 #include <pfmt.h> 37 #include <stdio.h> 38 #include <sys/types.h> 39 #include <sys/types32.h> 40 #include <sys/stropts.h> 41 #include <sys/strlog.h> 42 #include <fcntl.h> 43 #include <errno.h> 44 #include <synch.h> 45 #include <thread.h> 46 #include "pfmt_data.h" 47 #include <time.h> 48 #include <stropts.h> 49 #include <unistd.h> 50 #include <strings.h> 51 #include <sys/uio.h> 52 53 #define MAXMSG 1024 54 #define LOGNAME "/dev/conslog" 55 #define LOG_CONSOLE "/dev/console" 56 57 int 58 __lfmt_log(const char *text, const char *sev, va_list args, long flag, int ret) 59 { 60 static int fd = -1; 61 struct strbuf dat; 62 int msg_offset; 63 long len; 64 union { 65 long flag; 66 char buf[MAXMSG]; 67 } msg; 68 int err; 69 int fdd; 70 71 len = ret + sizeof (long) + 3; 72 73 if (len > sizeof (msg)) { 74 errno = ERANGE; 75 return (-2); 76 } 77 78 msg.flag = flag; 79 msg_offset = (int)sizeof (long); 80 81 lrw_rdlock(&_rw_pfmt_label); 82 if (*__pfmt_label) 83 msg_offset += strlcpy(msg.buf + msg_offset, __pfmt_label, 84 sizeof (msg.buf) - msg_offset); 85 lrw_unlock(&_rw_pfmt_label); 86 87 if (sev) 88 msg_offset += sprintf(msg.buf + msg_offset, sev, flag & 0xff); 89 90 msg_offset += 1 + vsprintf(msg.buf + msg_offset, text, args); 91 msg.buf[msg_offset++] = '\0'; 92 93 if (fd == -1 && 94 ((fd = open(LOGNAME, O_WRONLY)) == -1 || 95 fcntl(fd, F_SETFD, 1) == -1)) 96 return (-2); 97 98 dat.maxlen = MAXMSG; 99 dat.len = (int)msg_offset; 100 dat.buf = msg.buf; 101 102 if (putmsg(fd, 0, &dat, 0) == -1) { 103 (void) close(fd); 104 return (-2); 105 } 106 107 /* 108 * Display it to a console 109 */ 110 if ((flag & MM_CONSOLE) != 0) { 111 char *p; 112 time_t t; 113 char buf[128]; 114 err = errno; 115 fdd = open(LOG_CONSOLE, O_WRONLY); 116 if (fdd != -1) { 117 /* 118 * Use C locale for time stamp. 119 */ 120 (void) time(&t); 121 (void) ctime_r(&t, buf, sizeof (buf)); 122 p = (char *)strrchr(buf, '\n'); 123 if (p != NULL) 124 *p = ':'; 125 (void) write(fdd, buf, strlen(buf)); 126 (void) write(fdd, msg.buf + sizeof (long), 127 msg_offset - sizeof (long)); 128 (void) write(fdd, "\n", 1); 129 } else 130 return (-2); 131 (void) close(fdd); 132 errno = err; 133 } 134 return (ret); 135 } 136