1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999-2021 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library. If not, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <syslog.h>
25 #include <string.h>
26 #include <mailutils/diag.h>
27 #include <mailutils/nls.h>
28 #include <mailutils/errno.h>
29 #include <mailutils/stdstream.h>
30 #include <mailutils/stream.h>
31 #include <mailutils/locus.h>
32
33 void
mu_diag_init()34 mu_diag_init ()
35 {
36 if (!mu_strerr)
37 mu_stdstream_setup (MU_STDSTREAM_RESET_NONE);
38 }
39
40 void
mu_diag_voutput(int level,const char * fmt,va_list ap)41 mu_diag_voutput (int level, const char *fmt, va_list ap)
42 {
43 mu_diag_init ();
44 mu_stream_printf (mu_strerr, "\033s<%d>", level);
45 mu_stream_vprintf (mu_strerr, fmt, ap);
46 mu_stream_write (mu_strerr, "\n", 1, NULL);
47 }
48
49 void
mu_diag_output(int level,const char * fmt,...)50 mu_diag_output (int level, const char *fmt, ...)
51 {
52 va_list ap;
53 va_start (ap, fmt);
54 mu_diag_voutput (level, fmt, ap);
55 va_end (ap);
56 }
57
58 void
mu_vdiag_at_locus_range(int level,struct mu_locus_range const * loc,const char * fmt,va_list ap)59 mu_vdiag_at_locus_range (int level, struct mu_locus_range const *loc,
60 const char *fmt, va_list ap)
61 {
62 struct mu_locus_range old_loc = MU_LOCUS_RANGE_INITIALIZER;
63 int old_mode;
64 int restore = 0;
65
66 if (loc)
67 {
68 if (mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
69 MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE, &old_loc) == 0)
70 {
71 if (mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
72 MU_IOCTL_LOGSTREAM_GET_MODE, &old_mode) == 0)
73 {
74 int mode = old_mode | MU_LOGMODE_LOCUS;
75 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
76 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
77 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
78 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, (void*) loc);
79 restore = 1;
80 }
81 }
82 }
83
84 mu_diag_voutput (level, fmt, ap);
85
86 if (restore)
87 {
88 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
89 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &old_loc);
90 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
91 MU_IOCTL_LOGSTREAM_SET_MODE, &old_mode);
92 mu_locus_range_deinit (&old_loc);
93 }
94 }
95
96 void
mu_diag_at_locus_range(int level,struct mu_locus_range const * loc,const char * fmt,...)97 mu_diag_at_locus_range (int level, struct mu_locus_range const *loc,
98 const char *fmt, ...)
99 {
100 va_list ap;
101 va_start (ap, fmt);
102 mu_vdiag_at_locus_range (level, loc, fmt, ap);
103 va_end (ap);
104 }
105
106 void
mu_diag_at_locus_point(int level,struct mu_locus_point const * loc,const char * fmt,...)107 mu_diag_at_locus_point (int level, struct mu_locus_point const *loc,
108 const char *fmt, ...)
109 {
110 va_list ap;
111 struct mu_locus_range lr = MU_LOCUS_RANGE_INITIALIZER;
112 lr.beg = *loc;
113 va_start (ap, fmt);
114 mu_vdiag_at_locus_range (level, &lr, fmt, ap);
115 va_end (ap);
116 }
117
118 void
mu_diag_vprintf(int level,const char * fmt,va_list ap)119 mu_diag_vprintf (int level, const char *fmt, va_list ap)
120 {
121 mu_diag_init ();
122 mu_stream_printf (mu_strerr, "\033s<%d>", level);
123 mu_stream_vprintf (mu_strerr, fmt, ap);
124 }
125
126 void
mu_diag_cont_vprintf(const char * fmt,va_list ap)127 mu_diag_cont_vprintf (const char *fmt, va_list ap)
128 {
129 mu_diag_init ();
130 mu_stream_vprintf (mu_strerr, fmt, ap);
131 }
132
133 void
mu_diag_printf(int level,const char * fmt,...)134 mu_diag_printf (int level, const char *fmt, ...)
135 {
136 va_list ap;
137 va_start (ap, fmt);
138 mu_diag_vprintf (level, fmt, ap);
139 va_end (ap);
140 }
141
142 void
mu_diag_cont_printf(const char * fmt,...)143 mu_diag_cont_printf (const char *fmt, ...)
144 {
145 va_list ap;
146 va_start (ap, fmt);
147 mu_diag_cont_vprintf (fmt, ap);
148 va_end (ap);
149 }
150
151 const char *
mu_diag_level_to_string(int level)152 mu_diag_level_to_string (int level)
153 {
154 switch (level)
155 {
156 case MU_DIAG_EMERG:
157 return _("emergency");
158
159 case MU_DIAG_ALERT:
160 return _("alert");
161
162 case MU_DIAG_CRIT:
163 return _("critical");
164
165 case MU_DIAG_ERROR:
166 return _("error");
167
168 case MU_DIAG_WARNING:
169 return _("warning");
170
171 case MU_DIAG_NOTICE:
172 return _("notice");
173
174 case MU_DIAG_INFO:
175 return _("info");
176
177 case MU_DIAG_DEBUG:
178 return _("debug");
179 }
180 return _("unknown");
181 }
182
183 void
mu_diag_funcall(mu_log_level_t level,const char * func,const char * arg,int err)184 mu_diag_funcall (mu_log_level_t level, const char *func,
185 const char *arg, int err)
186 {
187 if (err)
188 /* TRANSLATORS: First %s stands for function name, second for its
189 arguments, third one for the actual error message. */
190 mu_diag_output (level, _("%s(%s) failed: %s"), func, mu_prstr (arg),
191 mu_strerror (err));
192 else
193 /* TRANSLATORS: First %s stands for function name, second for its
194 arguments. */
195 mu_diag_output (level, _("%s(%s) failed"), func, mu_prstr (arg));
196 }
197