Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libcasper/services/cap_syslog/cap_syslog.c
48260 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2017 Mariusz Zaborski <[email protected]>
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
#include <sys/cdefs.h>
30
#include <sys/dnv.h>
31
#include <sys/nv.h>
32
33
#include <assert.h>
34
#include <errno.h>
35
#include <stdarg.h>
36
#include <stdio.h>
37
#include <stdlib.h>
38
#include <string.h>
39
#include <syslog.h>
40
41
#include <libcasper.h>
42
#include <libcasper_service.h>
43
44
#include "cap_syslog.h"
45
46
#define CAP_SYSLOG_LIMIT 2048
47
48
void
49
cap_syslog(cap_channel_t *chan, int pri, const char *fmt, ...)
50
{
51
va_list ap;
52
53
va_start(ap, fmt);
54
cap_vsyslog(chan, pri, fmt, ap);
55
va_end(ap);
56
}
57
58
void
59
cap_vsyslog(cap_channel_t *chan, int priority, const char *fmt, va_list ap)
60
{
61
nvlist_t *nvl;
62
char message[CAP_SYSLOG_LIMIT];
63
64
(void)vsnprintf(message, sizeof(message), fmt, ap);
65
66
nvl = nvlist_create(0);
67
nvlist_add_string(nvl, "cmd", "vsyslog");
68
nvlist_add_number(nvl, "priority", priority);
69
nvlist_add_string(nvl, "message", message);
70
nvl = cap_xfer_nvlist(chan, nvl);
71
if (nvl == NULL) {
72
return;
73
}
74
nvlist_destroy(nvl);
75
}
76
77
void
78
cap_openlog(cap_channel_t *chan, const char *ident, int logopt, int facility)
79
{
80
nvlist_t *nvl;
81
82
nvl = nvlist_create(0);
83
nvlist_add_string(nvl, "cmd", "openlog");
84
if (ident != NULL) {
85
nvlist_add_string(nvl, "ident", ident);
86
}
87
nvlist_add_number(nvl, "logopt", logopt);
88
nvlist_add_number(nvl, "facility", facility);
89
if (logopt & LOG_PERROR) {
90
nvlist_add_descriptor(nvl, "stderr", STDERR_FILENO);
91
}
92
nvl = cap_xfer_nvlist(chan, nvl);
93
if (nvl == NULL) {
94
return;
95
}
96
nvlist_destroy(nvl);
97
}
98
99
void
100
cap_closelog(cap_channel_t *chan)
101
{
102
nvlist_t *nvl;
103
104
nvl = nvlist_create(0);
105
nvlist_add_string(nvl, "cmd", "closelog");
106
nvl = cap_xfer_nvlist(chan, nvl);
107
if (nvl == NULL) {
108
return;
109
}
110
nvlist_destroy(nvl);
111
}
112
113
int
114
cap_setlogmask(cap_channel_t *chan, int maskpri)
115
{
116
nvlist_t *nvl;
117
int omask;
118
119
nvl = nvlist_create(0);
120
nvlist_add_string(nvl, "cmd", "setlogmask");
121
nvlist_add_number(nvl, "maskpri", maskpri);
122
nvl = cap_xfer_nvlist(chan, nvl);
123
omask = nvlist_get_number(nvl, "omask");
124
125
nvlist_destroy(nvl);
126
127
return (omask);
128
}
129
130
/*
131
* Service functions.
132
*/
133
134
static char *LogTag;
135
static int prev_stderr = -1;
136
137
static void
138
slog_vsyslog(const nvlist_t *limits __unused, const nvlist_t *nvlin,
139
nvlist_t *nvlout __unused)
140
{
141
142
syslog(nvlist_get_number(nvlin, "priority"), "%s",
143
nvlist_get_string(nvlin, "message"));
144
}
145
146
static void
147
slog_openlog(const nvlist_t *limits __unused, const nvlist_t *nvlin,
148
nvlist_t *nvlout __unused)
149
{
150
const char *ident;
151
uint64_t logopt;
152
int stderr_fd;
153
154
ident = dnvlist_get_string(nvlin, "ident", NULL);
155
if (ident != NULL) {
156
free(LogTag);
157
LogTag = strdup(ident);
158
}
159
160
logopt = nvlist_get_number(nvlin, "logopt");
161
if (logopt & LOG_PERROR) {
162
stderr_fd = dnvlist_get_descriptor(nvlin, "stderr", -1);
163
if (prev_stderr == -1)
164
prev_stderr = dup(STDERR_FILENO);
165
if (prev_stderr != -1)
166
(void)dup2(stderr_fd, STDERR_FILENO);
167
} else if (prev_stderr != -1) {
168
(void)dup2(prev_stderr, STDERR_FILENO);
169
close(prev_stderr);
170
prev_stderr = -1;
171
}
172
openlog(LogTag, logopt, nvlist_get_number(nvlin, "facility"));
173
}
174
175
static void
176
slog_closelog(const nvlist_t *limits __unused, const nvlist_t *nvlin __unused,
177
nvlist_t *nvlout __unused)
178
{
179
180
closelog();
181
182
free(LogTag);
183
LogTag = NULL;
184
185
if (prev_stderr != -1) {
186
(void)dup2(prev_stderr, STDERR_FILENO);
187
close(prev_stderr);
188
prev_stderr = -1;
189
}
190
}
191
192
static void
193
slog_setlogmask(const nvlist_t *limits __unused, const nvlist_t *nvlin,
194
nvlist_t *nvlout)
195
{
196
int omask;
197
198
omask = setlogmask(nvlist_get_number(nvlin, "maskpri"));
199
nvlist_add_number(nvlout, "omask", omask);
200
}
201
202
static int
203
syslog_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin,
204
nvlist_t *nvlout)
205
{
206
207
if (strcmp(cmd, "vsyslog") == 0) {
208
slog_vsyslog(limits, nvlin, nvlout);
209
} else if (strcmp(cmd, "openlog") == 0) {
210
slog_openlog(limits, nvlin, nvlout);
211
} else if (strcmp(cmd, "closelog") == 0) {
212
slog_closelog(limits, nvlin, nvlout);
213
} else if (strcmp(cmd, "setlogmask") == 0) {
214
slog_setlogmask(limits, nvlin, nvlout);
215
} else {
216
return (EINVAL);
217
}
218
219
return (0);
220
}
221
222
CREATE_SERVICE("system.syslog", NULL, syslog_command, 0);
223
224