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