Path: blob/main/lib/libcasper/services/cap_syslog/cap_syslog.c
48260 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2017 Mariusz Zaborski <[email protected]>4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND16* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE17* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE18* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE19* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS21* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT23* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY24* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF25* SUCH DAMAGE.26*/2728#include <sys/cdefs.h>29#include <sys/dnv.h>30#include <sys/nv.h>3132#include <assert.h>33#include <errno.h>34#include <stdarg.h>35#include <stdio.h>36#include <stdlib.h>37#include <string.h>38#include <syslog.h>3940#include <libcasper.h>41#include <libcasper_service.h>4243#include "cap_syslog.h"4445#define CAP_SYSLOG_LIMIT 20484647void48cap_syslog(cap_channel_t *chan, int pri, const char *fmt, ...)49{50va_list ap;5152va_start(ap, fmt);53cap_vsyslog(chan, pri, fmt, ap);54va_end(ap);55}5657void58cap_vsyslog(cap_channel_t *chan, int priority, const char *fmt, va_list ap)59{60nvlist_t *nvl;61char message[CAP_SYSLOG_LIMIT];6263(void)vsnprintf(message, sizeof(message), fmt, ap);6465nvl = nvlist_create(0);66nvlist_add_string(nvl, "cmd", "vsyslog");67nvlist_add_number(nvl, "priority", priority);68nvlist_add_string(nvl, "message", message);69nvl = cap_xfer_nvlist(chan, nvl);70if (nvl == NULL) {71return;72}73nvlist_destroy(nvl);74}7576void77cap_openlog(cap_channel_t *chan, const char *ident, int logopt, int facility)78{79nvlist_t *nvl;8081nvl = nvlist_create(0);82nvlist_add_string(nvl, "cmd", "openlog");83if (ident != NULL) {84nvlist_add_string(nvl, "ident", ident);85}86nvlist_add_number(nvl, "logopt", logopt);87nvlist_add_number(nvl, "facility", facility);88if (logopt & LOG_PERROR) {89nvlist_add_descriptor(nvl, "stderr", STDERR_FILENO);90}91nvl = cap_xfer_nvlist(chan, nvl);92if (nvl == NULL) {93return;94}95nvlist_destroy(nvl);96}9798void99cap_closelog(cap_channel_t *chan)100{101nvlist_t *nvl;102103nvl = nvlist_create(0);104nvlist_add_string(nvl, "cmd", "closelog");105nvl = cap_xfer_nvlist(chan, nvl);106if (nvl == NULL) {107return;108}109nvlist_destroy(nvl);110}111112int113cap_setlogmask(cap_channel_t *chan, int maskpri)114{115nvlist_t *nvl;116int omask;117118nvl = nvlist_create(0);119nvlist_add_string(nvl, "cmd", "setlogmask");120nvlist_add_number(nvl, "maskpri", maskpri);121nvl = cap_xfer_nvlist(chan, nvl);122omask = nvlist_get_number(nvl, "omask");123124nvlist_destroy(nvl);125126return (omask);127}128129/*130* Service functions.131*/132133static char *LogTag;134static int prev_stderr = -1;135136static void137slog_vsyslog(const nvlist_t *limits __unused, const nvlist_t *nvlin,138nvlist_t *nvlout __unused)139{140141syslog(nvlist_get_number(nvlin, "priority"), "%s",142nvlist_get_string(nvlin, "message"));143}144145static void146slog_openlog(const nvlist_t *limits __unused, const nvlist_t *nvlin,147nvlist_t *nvlout __unused)148{149const char *ident;150uint64_t logopt;151int stderr_fd;152153ident = dnvlist_get_string(nvlin, "ident", NULL);154if (ident != NULL) {155free(LogTag);156LogTag = strdup(ident);157}158159logopt = nvlist_get_number(nvlin, "logopt");160if (logopt & LOG_PERROR) {161stderr_fd = dnvlist_get_descriptor(nvlin, "stderr", -1);162if (prev_stderr == -1)163prev_stderr = dup(STDERR_FILENO);164if (prev_stderr != -1)165(void)dup2(stderr_fd, STDERR_FILENO);166} else if (prev_stderr != -1) {167(void)dup2(prev_stderr, STDERR_FILENO);168close(prev_stderr);169prev_stderr = -1;170}171openlog(LogTag, logopt, nvlist_get_number(nvlin, "facility"));172}173174static void175slog_closelog(const nvlist_t *limits __unused, const nvlist_t *nvlin __unused,176nvlist_t *nvlout __unused)177{178179closelog();180181free(LogTag);182LogTag = NULL;183184if (prev_stderr != -1) {185(void)dup2(prev_stderr, STDERR_FILENO);186close(prev_stderr);187prev_stderr = -1;188}189}190191static void192slog_setlogmask(const nvlist_t *limits __unused, const nvlist_t *nvlin,193nvlist_t *nvlout)194{195int omask;196197omask = setlogmask(nvlist_get_number(nvlin, "maskpri"));198nvlist_add_number(nvlout, "omask", omask);199}200201static int202syslog_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin,203nvlist_t *nvlout)204{205206if (strcmp(cmd, "vsyslog") == 0) {207slog_vsyslog(limits, nvlin, nvlout);208} else if (strcmp(cmd, "openlog") == 0) {209slog_openlog(limits, nvlin, nvlout);210} else if (strcmp(cmd, "closelog") == 0) {211slog_closelog(limits, nvlin, nvlout);212} else if (strcmp(cmd, "setlogmask") == 0) {213slog_setlogmask(limits, nvlin, nvlout);214} else {215return (EINVAL);216}217218return (0);219}220221CREATE_SERVICE("system.syslog", NULL, syslog_command, 0);222223224