1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
23 */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <err.h>
30
31 #include <libscf.h>
32
33 #include "cron_scf.h"
34
35 extern void *xmalloc(size_t); /* from funcs.c */
36
37 static char *fmri;
38 static scf_handle_t *scf;
39 static scf_instance_t *inst;
40 static scf_propertygroup_t *pg;
41
42 /*
43 * Initialise our connection to smf(5). Returns:
44 * 0 on success
45 * <0 for any failure
46 * -2 if we believe we're not actually running under smf(5)
47 */
48 int
49 init_scf(void)
50 {
51 int rc = -1;
52 size_t fmrisz;
53
54 scf = scf_handle_create(SCF_VERSION);
55 if (scf == NULL)
56 return (-1);
57 if (scf_handle_bind(scf) != 0)
58 goto cleanup0;
59
60 #ifdef DEBUG
61 if (getenv("SMF_TEST_FMRI") != NULL) {
62 printf("DEBUG: smf test mode engaged\n");
63 fmri = strdup(getenv("SMF_TEST_FMRI"));
64 goto have_fmri;
65 }
66 #endif /* DEBUG */
67
68 fmrisz = scf_myname(scf, NULL, 0);
69 if (fmrisz == -1) {
70 if (scf_error() == SCF_ERROR_NOT_SET) {
71 rc = -2;
72 }
73 goto cleanup1;
74 }
75 fmri = xmalloc(fmrisz + 1);
76 fmrisz = scf_myname(scf, fmri, fmrisz + 1);
77 if (fmrisz == -1)
78 goto cleanup2;
79
80 have_fmri:
81
82 if ((inst = scf_instance_create(scf)) == NULL ||
83 (pg = scf_pg_create(scf)) == NULL)
84 goto cleanup3;
85
86 if (scf_handle_decode_fmri(scf, fmri, NULL, NULL, inst,
87 NULL, NULL, SCF_DECODE_FMRI_EXACT) != 0)
88 goto cleanup3;
89
90 if (scf_instance_get_pg_composed(inst, NULL, "config", pg) != 0)
91 goto cleanup3;
92
93 return (0);
94
95 cleanup3:
96 if (pg != NULL) {
97 scf_pg_destroy(pg);
98 pg = NULL;
99 }
100 if (inst != NULL) {
101 scf_instance_destroy(inst);
102 inst = NULL;
103 }
104 cleanup2:
105 free(fmri);
106 fmri = NULL;
107 cleanup1:
108 (void) scf_handle_unbind(scf);
109 cleanup0:
110 (void) scf_handle_destroy(scf);
111 scf = NULL;
112 return (rc);
113 }
114
115 void
116 fini_scf(void)
117 {
118 (void) scf_pg_destroy(pg);
119 pg = NULL;
120 (void) scf_instance_destroy(inst);
121 inst = NULL;
122 free(fmri);
123 fmri = NULL;
124 (void) scf_handle_unbind(scf);
125 (void) scf_handle_destroy(scf);
126 scf = NULL;
127 }
128
129 /*
130 * Fetch the boolean value of a property from the 'config' property
131 * group in our smf(5) instance.
132 * Returns:
133 * <0 on failure
134 * 0 if found and false
135 * 1 if found and true
136 */
137 int
138 get_config_boolean(char *name)
139 {
140 scf_property_t *prop = NULL;
141 scf_value_t *val = NULL;
142 uint8_t out;
143 int rc = -1;
144
145 prop = scf_property_create(scf);
146 val = scf_value_create(scf);
147 if (prop == NULL || val == NULL)
148 goto cleanup0;
149
150 if (scf_pg_get_property(pg, name, prop) != 0)
151 goto cleanup0;
152
153 if (scf_property_is_type(prop, SCF_TYPE_BOOLEAN) != 0)
154 goto cleanup0;
155
156 if (scf_property_get_value(prop, val) != 0)
157 goto cleanup0;
158
159 if (scf_value_get_boolean(val, &out) != 0)
160 goto cleanup0;
161
162 rc = out;
163
164 cleanup0:
165 if (val != NULL)
166 scf_value_destroy(val);
167 if (prop != NULL)
168 scf_property_destroy(prop);
169
170 return (rc);
171 }