f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * CDDL HEADER START
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * The contents of this file are subject to the terms of the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Common Development and Distribution License (the "License").
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * You may not use this file except in compliance with the License.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * or http://www.opensolaris.org/os/licensing.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * See the License for the specific language governing permissions
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * and limitations under the License.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * When distributing Covered Code, include this CDDL HEADER in each
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If applicable, add the following below this CDDL HEADER, with the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * fields enclosed by brackets "[]" replaced with your own identifying
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * information: Portions Copyright [yyyy] [name of copyright owner]
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * CDDL HEADER END
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <alloca.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include "libfmnotify.h"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*ARGSUSED*/
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyvoid
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_cleanup(nd_hdl_t *nhdl)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Cleaning up ...");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nhdl->nh_evhdl)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fmev_shdl_fini(nhdl->nh_evhdl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nhdl->nh_msghdl)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmd_msg_fini(nhdl->nh_msghdl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_keep_running = B_FALSE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fclose(nhdl->nh_log_fd);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyget_timestamp(char *buf, size_t bufsize)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby time_t utc_time;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby struct tm *p_tm;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) time(&utc_time);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby p_tm = localtime(&utc_time);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) strftime(buf, bufsize, "%b %d %H:%M:%S", p_tm);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/* PRINTFLIKE2 */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyvoid
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_debug(nd_hdl_t *nhdl, const char *format, ...)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char timestamp[64];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby va_list ap;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nhdl->nh_debug) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby get_timestamp(timestamp, sizeof (timestamp));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fprintf(nhdl->nh_log_fd, "[ %s ", timestamp);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby va_start(ap, format);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) vfprintf(nhdl->nh_log_fd, format, ap);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby va_end(ap);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fprintf(nhdl->nh_log_fd, " ]\n");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fflush(nhdl->nh_log_fd);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyvoid
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_dump_nvlist(nd_hdl_t *nhdl, nvlist_t *nvl)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nhdl->nh_debug)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_print(nhdl->nh_log_fd, nvl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/* PRINTFLIKE2 */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyvoid
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_error(nd_hdl_t *nhdl, const char *format, ...)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char timestamp[64];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby va_list ap;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby get_timestamp(timestamp, sizeof (timestamp));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fprintf(nhdl->nh_log_fd, "[ %s ", timestamp);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby va_start(ap, format);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) vfprintf(nhdl->nh_log_fd, format, ap);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby va_end(ap);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fprintf(nhdl->nh_log_fd, " ]\n");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fflush(nhdl->nh_log_fd);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/* PRINTFLIKE2 */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyvoid
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_abort(nd_hdl_t *nhdl, const char *format, ...)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char timestamp[64];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby va_list ap;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby get_timestamp(timestamp, sizeof (timestamp));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fprintf(nhdl->nh_log_fd, "[ %s ", timestamp);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby va_start(ap, format);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) vfprintf(nhdl->nh_log_fd, format, ap);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby va_end(ap);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fprintf(nhdl->nh_log_fd, " ]\n");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fflush(nhdl->nh_log_fd);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_cleanup(nhdl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyvoid
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_daemonize(nd_hdl_t *nhdl)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby pid_t pid;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((pid = fork()) < 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_abort(nhdl, "Failed to fork child (%s)", strerror(errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else if (pid > 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby exit(0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) setsid();
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) close(0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) close(1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * We leave stderr open so we can write debug/err messages to the SMF
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * service log
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_is_daemon = B_TRUE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * This function returns a pointer to the specified SMF property group for the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * specified SMF service. The caller is responsible for freeing the property
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * group. On failure, the function returns NULL.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic scf_propertygroup_t *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_get_pg(nd_hdl_t *nhdl, scf_handle_t *handle, const char *svcname,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby const char *pgname)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_scope_t *sc = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_service_t *svc = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_propertygroup_t *pg = NULL, *ret = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sc = scf_scope_create(handle);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby svc = scf_service_create(handle);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby pg = scf_pg_create(handle);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (sc == NULL || svc == NULL || pg == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to allocate libscf structures");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_pg_destroy(pg);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto get_pg_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (scf_handle_bind(handle) != -1 &&
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, sc) != -1 &&
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_scope_get_service(sc, svcname, svc) != -1 &&
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_service_get_pg(svc, pgname, pg) != -1)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ret = pg;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_pg_destroy(pg);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyget_pg_done:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_service_destroy(svc);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_scope_destroy(sc);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (ret);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyint
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_get_astring_prop(nd_hdl_t *nhdl, const char *svcname, const char *pgname,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby const char *propname, char **val)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_handle_t *handle = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_propertygroup_t *pg;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_property_t *prop = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_value_t *value = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char strval[255];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int ret = -1;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((handle = scf_handle_create(SCF_VERSION)) == NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (ret);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((pg = nd_get_pg(nhdl, handle, svcname, pgname)) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to read retrieve %s "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "property group for %s", pgname, svcname);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto astring_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby prop = scf_property_create(handle);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby value = scf_value_create(handle);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (prop == NULL || value == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to allocate SMF structures");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto astring_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (scf_pg_get_property(pg, propname, prop) == -1 ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_property_get_value(prop, value) == -1 ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_value_get_astring(value, strval, 255) == -1) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to retrieve %s prop (%s)", propname,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_strerror(scf_error()));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto astring_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *val = strdup(strval);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ret = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyastring_done:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_value_destroy(value);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_property_destroy(prop);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_pg_destroy(pg);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_handle_destroy(handle);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (ret);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyint
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_get_boolean_prop(nd_hdl_t *nhdl, const char *svcname, const char *pgname,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby const char *propname, uint8_t *val)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_handle_t *handle = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_propertygroup_t *pg;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_property_t *prop = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_value_t *value = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int ret = -1;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((handle = scf_handle_create(SCF_VERSION)) == NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (ret);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((pg = nd_get_pg(nhdl, handle, svcname, pgname)) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to read retrieve %s "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "property group for %s", pgname, svcname);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto bool_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby prop = scf_property_create(handle);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby value = scf_value_create(handle);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (prop == NULL || value == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to allocate SMF structures");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto bool_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (scf_pg_get_property(pg, propname, prop) == -1 ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_property_get_value(prop, value) == -1 ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_value_get_boolean(value, val) == -1) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to retrieve %s prop (%s)", propname,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_strerror(scf_error()));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto bool_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ret = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbybool_done:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_value_destroy(value);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_property_destroy(prop);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_pg_destroy(pg);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby scf_handle_destroy(handle);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (ret);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbychar *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_get_event_fmri(nd_hdl_t *nhdl, fmev_t ev)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_t *ev_nvl, *attr_nvl;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *svcname;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((ev_nvl = fmev_attr_list(ev)) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to lookup event attr nvlist");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_nvlist(ev_nvl, "attr", &attr_nvl) ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_lookup_string(attr_nvl, "svc-string", &svcname)) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Malformed event 0x%p", (void *)ev_nvl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (strdup((const char *)svcname));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyint
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_get_notify_prefs(nd_hdl_t *nhdl, const char *mech, fmev_t ev,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_t ***pref_nvl, uint_t *nprefs)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_t *ev_nvl, *top_nvl, **np_nvlarr, *mech_nvl;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int ret = 1;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint_t nelem;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((ev_nvl = fmev_attr_list(ev)) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to lookup event attr nvlist");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((ret = smf_notify_get_params(&top_nvl, ev_nvl)) != SCF_SUCCESS) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ret = scf_error();
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (ret == SCF_ERROR_NOT_FOUND) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "No notification preferences specified "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "for this event");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto pref_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Error looking up notification "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "preferences (%s)", scf_strerror(ret));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_dump_nvlist(nhdl, top_nvl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto pref_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_nvlist_array(top_nvl, SCF_NOTIFY_PARAMS, &np_nvlarr,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &nelem) != 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Malformed nvlist");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_dump_nvlist(nhdl, top_nvl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ret = 1;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto pref_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *pref_nvl = malloc(nelem * sizeof (nvlist_t *));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *nprefs = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (int i = 0; i < nelem; i++) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_nvlist(np_nvlarr[i], mech, &mech_nvl) == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) nvlist_dup(mech_nvl, *pref_nvl + *nprefs, 0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ++*nprefs;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (*nprefs == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "No %s notification preferences specified",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby mech);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(*pref_nvl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ret = SCF_ERROR_NOT_FOUND;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto pref_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ret = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbypref_done:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_free(top_nvl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (ret);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_seq_search(char *key, char **list, uint_t nelem)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (int i = 0; i < nelem; i++)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (strcmp(key, list[i]) == 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * This function takes a single string list and splits it into
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * an string array (analogous to PERL split)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * The caller is responsible for freeing the array.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyint
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_split_list(nd_hdl_t *nhdl, char *list, char *delim, char ***arr,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint_t *nelem)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *item, *tmpstr;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int i = 1, size = 1;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby tmpstr = strdup(list);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby item = strtok(tmpstr, delim);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby while (item && strtok(NULL, delim) != NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby size++;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(tmpstr);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((*arr = calloc(size, sizeof (char *))) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Error allocating memory (%s)", strerror(errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (size == 1)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (*arr)[0] = strdup(list);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby tmpstr = strdup(list);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby item = strtok(tmpstr, delim);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (*arr)[0] = strdup(item);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby while ((item = strtok(NULL, delim)) != NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (*arr)[i++] = strdup(item);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(tmpstr);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *nelem = size;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * This function merges two string arrays into a single array, removing any
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * duplicates
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * The caller is responsible for freeing the merged array.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyint
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_merge_strarray(nd_hdl_t *nhdl, char **arr1, uint_t n1, char **arr2,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint_t n2, char ***buf)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char **tmparr;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int uniq = -1;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby tmparr = alloca((n1 + n2) * sizeof (char *));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby bzero(tmparr, (n1 + n2) * sizeof (char *));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby while (++uniq < n1)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby tmparr[uniq] = strdup(arr1[uniq]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (int j = 0; j < n2; j++)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (!nd_seq_search(arr2[j], tmparr, uniq))
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby tmparr[uniq++] = strdup(arr2[j]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((*buf = calloc(uniq, sizeof (char *))) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Error allocating memory (%s)", strerror(errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (int j = 0; j < uniq; j++) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (tmparr[j])
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(tmparr[j]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby bcopy(tmparr, *buf, uniq * sizeof (char *));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (uniq);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyvoid
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_free_strarray(char **arr, uint_t arrsz)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (uint_t i = 0; i < arrsz; i++)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(arr[i]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(arr);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * This function joins all the strings in a string array into a single string
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Each element will be delimited by a comma
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * The caller is responsible for freeing the joined string.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyint
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_join_strarray(nd_hdl_t *nhdl, char **arr, uint_t arrsz, char **buf)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint_t len = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *jbuf;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int i;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * First, figure out how much space we need to allocate to store the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * joined string.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (i = 0; i < arrsz; i++)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby len += strlen(arr[i]) + 1;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((jbuf = calloc(len, sizeof (char))) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Error allocating memory (%s)", strerror(errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(jbuf, len, "%s", arr[0]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (i = 1; i < arrsz; i++)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(jbuf, len, "%s,%s", jbuf, arr[i]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *buf = jbuf;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyvoid
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_free_nvlarray(nvlist_t **arr, uint_t arrsz)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (uint_t i = 0; i < arrsz; i++)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_free(arr[i]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(arr);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * This function takes a dictionary name and event class and then uses
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * libdiagcode to compute the MSG ID. We need this for looking up messages
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * for the committed ireport.* events. For FMA list.* events, the MSG ID is
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * is contained in the event payload.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyint
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_get_diagcode(nd_hdl_t *nhdl, const char *dict, const char *class, char *buf,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby size_t buflen)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fm_dc_handle_t *dhp;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby size_t dlen;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *dirpath;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby const char *key[2];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int ret = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby dlen = (strlen(nhdl->nh_rootdir) + strlen(ND_DICTDIR) + 2);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby dirpath = alloca(dlen);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snprintf(dirpath, dlen, "%s/%s", nhdl->nh_rootdir, ND_DICTDIR);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((dhp = fm_dc_opendict(FM_DC_VERSION, dirpath, dict)) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "fm_dc_opendict failed for %s/%s",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby dirpath, dict);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby key[0] = class;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby key[1] = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (fm_dc_key2code(dhp, key, buf, buflen) < 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "fm_dc_key2code failed for %s", key[0]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ret = -1;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fm_dc_closedict(dhp);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (ret);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * This function takes an event and extracts the bits of the event payload that
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * are of interest to notification daemons and conveniently tucks them into a
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * single struct.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * The caller is responsible for freeing ev_info and any contained strings and
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * nvlists. A convenience function, nd_free_event_info(), is provided for this
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * purpose.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyint
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_get_event_info(nd_hdl_t *nhdl, const char *class, fmev_t ev,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_ev_info_t **ev_info)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_t *ev_nvl, *attr_nvl;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_ev_info_t *evi;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *code, *uuid, *fmri, *from_state, *to_state, *reason;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((evi = calloc(1, sizeof (nd_ev_info_t))) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to allocate memory");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Hold event; class and payload will be valid for as long as
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * we hold the event.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmev_hold(ev);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_ev = ev;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ev_nvl = fmev_attr_list(ev);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Lookup the MSGID, event description and severity and KA URL
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * For FMA list.* events we just pull it out of the the event nvlist.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * For all other events we call a utility function that computes the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * diagcode using the dict name and class.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_diagcode = calloc(32, sizeof (char));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((nvlist_lookup_string(ev_nvl, FM_SUSPECT_DIAG_CODE, &code) == 0 &&
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby strcpy(evi->ei_diagcode, code)) ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_get_diagcode(nhdl, "SMF", class, evi->ei_diagcode, 32)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_severity = fmd_msg_getitem_id(nhdl->nh_msghdl,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby NULL, evi->ei_diagcode, FMD_MSG_ITEM_SEVERITY);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_descr = fmd_msg_getitem_id(nhdl->nh_msghdl,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby NULL, evi->ei_diagcode, FMD_MSG_ITEM_DESC);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_url = fmd_msg_getitem_id(nhdl->nh_msghdl,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby NULL, evi->ei_diagcode, FMD_MSG_ITEM_URL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) strcpy(evi->ei_diagcode, ND_UNKNOWN);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (!evi->ei_severity)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_severity = strdup(ND_UNKNOWN);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (!evi->ei_descr)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_descr = strdup(ND_UNKNOWN);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (!evi->ei_url)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_url = strdup(ND_UNKNOWN);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_payload = ev_nvl;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_class = fmev_class(ev);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_string(ev_nvl, FM_SUSPECT_UUID, &uuid) == 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_uuid = strdup(uuid);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Malformed event");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_dump_nvlist(nhdl, evi->ei_payload);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_event_info(evi);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (strncmp(class, "ireport.os.smf", 14) == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((fmri = nd_get_event_fmri(nhdl, ev)) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to get fmri from event payload");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_event_info(evi);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_nvlist(evi->ei_payload, "attr", &attr_nvl) ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_lookup_string(attr_nvl, "from-state", &from_state) ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_lookup_string(attr_nvl, "to-state", &to_state) ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_lookup_string(attr_nvl, "reason-long", &reason)) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Malformed event");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_dump_nvlist(nhdl, evi->ei_payload);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_event_info(evi);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(fmri);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_fmri = fmri;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_to_state = strdup(to_state);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_from_state = strdup(from_state);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby evi->ei_reason = strdup(reason);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *ev_info = evi;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbycondfree(void *buf)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (buf != NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(buf);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyvoid
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_free_event_info(nd_ev_info_t *ev_info)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby condfree(ev_info->ei_severity);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby condfree(ev_info->ei_descr);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby condfree(ev_info->ei_diagcode);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby condfree(ev_info->ei_url);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby condfree(ev_info->ei_uuid);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby condfree(ev_info->ei_fmri);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby condfree(ev_info->ei_from_state);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby condfree(ev_info->ei_to_state);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby condfree(ev_info->ei_reason);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmev_rele(ev_info->ei_ev);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(ev_info);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}