1/*++
2/* NAME
3/*	msg_vstream 3
4/* SUMMARY
5/*	report diagnostics to VSTREAM
6/* SYNOPSIS
7/*	#include <msg_vstream.h>
8/*
9/*	void	msg_vstream_init(progname, stream)
10/*	const char *progname;
11/*	VSTREAM	*stream;
12/* DESCRIPTION
13/*	This module implements support to report msg(3) diagnostics
14/*	to a VSTREAM.
15/*
16/*	msg_vstream_init() sets the program name that appears in each output
17/*	record, and directs diagnostics (see msg(3)) to the specified
18/*	VSTREAM. The \fIprogname\fR argument is not copied.
19/* SEE ALSO
20/*	msg(3)
21/* BUGS
22/*	No guarantee that long records are written atomically.
23/*	Only the last msg_vstream_init() call takes effect.
24/* LICENSE
25/* .ad
26/* .fi
27/*	The Secure Mailer license must be distributed with this software.
28/* AUTHOR(S)
29/*	Wietse Venema
30/*	IBM T.J. Watson Research
31/*	P.O. Box 704
32/*	Yorktown Heights, NY 10598, USA
33/*--*/
34
35/* System libraries. */
36
37#include <sys_defs.h>
38#include <errno.h>
39#include <stdlib.h>			/* 44BSD stdarg.h uses abort() */
40#include <stdarg.h>
41
42/* Utility library. */
43
44#include "vstream.h"
45#include "msg.h"
46#include "msg_output.h"
47#include "msg_vstream.h"
48
49 /*
50  * Private state.
51  */
52static const char *msg_tag;
53static VSTREAM *msg_stream;
54
55/* msg_vstream_print - log diagnostic to VSTREAM */
56
57static void msg_vstream_print(int level, const char *text)
58{
59    static const char *level_text[] = {
60	"info", "warning", "error", "fatal", "panic",
61    };
62
63    if (level < 0 || level >= (int) (sizeof(level_text) / sizeof(level_text[0])))
64	msg_panic("invalid severity level: %d", level);
65    if (level == MSG_INFO) {
66	vstream_fprintf(msg_stream, "%s: %s\n",
67			msg_tag, text);
68    } else {
69	vstream_fprintf(msg_stream, "%s: %s: %s\n",
70			msg_tag, level_text[level], text);
71    }
72    vstream_fflush(msg_stream);
73}
74
75/* msg_vstream_init - initialize */
76
77void    msg_vstream_init(const char *name, VSTREAM *vp)
78{
79    static int first_call = 1;
80
81    msg_tag = name;
82    msg_stream = vp;
83    if (first_call) {
84	first_call = 0;
85	msg_output(msg_vstream_print);
86    }
87}
88