1 /*- 2 * Copyright (c) 2017 Mariusz Zaborski <oshogbo@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 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, 0); 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 nvl = cap_xfer_nvlist(chan, nvl, 0); 90 if (nvl == NULL) { 91 return; 92 } 93 nvlist_destroy(nvl); 94 } 95 96 void 97 cap_closelog(cap_channel_t *chan) 98 { 99 nvlist_t *nvl; 100 101 nvl = nvlist_create(0); 102 nvlist_add_string(nvl, "cmd", "closelog"); 103 nvl = cap_xfer_nvlist(chan, nvl, 0); 104 if (nvl == NULL) { 105 return; 106 } 107 nvlist_destroy(nvl); 108 } 109 110 int 111 cap_setlogmask(cap_channel_t *chan, int maskpri) 112 { 113 nvlist_t *nvl; 114 int omask; 115 116 nvl = nvlist_create(0); 117 nvlist_add_string(nvl, "cmd", "setlogmask"); 118 nvlist_add_number(nvl, "maskpri", maskpri); 119 nvl = cap_xfer_nvlist(chan, nvl, 0); 120 omask = nvlist_get_number(nvl, "omask"); 121 122 nvlist_destroy(nvl); 123 124 return (omask); 125 } 126 127 /* 128 * Service functions. 129 */ 130 131 static char *LogTag; 132 133 static void 134 slog_vsyslog(const nvlist_t *limits __unused, const nvlist_t *nvlin, 135 nvlist_t *nvlout __unused) 136 { 137 138 syslog(nvlist_get_number(nvlin, "priority"), "%s", 139 nvlist_get_string(nvlin, "message")); 140 } 141 142 static void 143 slog_openlog(const nvlist_t *limits __unused, const nvlist_t *nvlin, 144 nvlist_t *nvlout __unused) 145 { 146 const char *ident; 147 148 ident = dnvlist_get_string(nvlin, "ident", NULL); 149 if (ident != NULL) { 150 free(LogTag); 151 LogTag = strdup(ident); 152 } 153 154 openlog(LogTag, nvlist_get_number(nvlin, "logopt"), 155 nvlist_get_number(nvlin, "facility")); 156 } 157 158 static void 159 slog_closelog(const nvlist_t *limits __unused, const nvlist_t *nvlin __unused, 160 nvlist_t *nvlout __unused) 161 { 162 163 closelog(); 164 165 free(LogTag); 166 LogTag = NULL; 167 } 168 169 static void 170 slog_setlogmask(const nvlist_t *limits __unused, const nvlist_t *nvlin, 171 nvlist_t *nvlout) 172 { 173 int omask; 174 175 omask = setlogmask(nvlist_get_number(nvlin, "maskpri")); 176 nvlist_add_number(nvlout, "omask", omask); 177 } 178 179 static int 180 syslog_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin, 181 nvlist_t *nvlout) 182 { 183 184 if (strcmp(cmd, "vsyslog") == 0) { 185 slog_vsyslog(limits, nvlin, nvlout); 186 } else if (strcmp(cmd, "openlog") == 0) { 187 slog_openlog(limits, nvlin, nvlout); 188 } else if (strcmp(cmd, "closelog") == 0) { 189 slog_closelog(limits, nvlin, nvlout); 190 } else if (strcmp(cmd, "setlogmask") == 0) { 191 slog_setlogmask(limits, nvlin, nvlout); 192 } else { 193 return (EINVAL); 194 } 195 196 return (0); 197 } 198 199 CREATE_SERVICE("system.syslog", NULL, syslog_command, 0); 200