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
57int
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