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 /* 23 * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org> 24 */ 25 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <unistd.h> 29 #include <string.h> 30 #include <err.h> 31 #include <limits.h> 32 #include <libscf.h> 33 34 #include "utils.h" 35 #include "scf.h" 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 int 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 if (getenv("SMF_TEST_FMRI") != NULL) { 61 fprintf(stderr, "DEBUG: smf test mode engaged\n"); 62 fmri = strdup(getenv("SMF_TEST_FMRI")); 63 goto have_fmri; 64 } 65 66 fmrisz = scf_myname(scf, NULL, 0); 67 if (fmrisz == -1) { 68 if (scf_error() == SCF_ERROR_NOT_SET) { 69 rc = -2; 70 } 71 goto cleanup1; 72 } 73 fmri = xmalloc(fmrisz + 1); 74 fmrisz = scf_myname(scf, fmri, fmrisz + 1); 75 if (fmrisz == -1) 76 goto cleanup2; 77 78 have_fmri: 79 80 if ((inst = scf_instance_create(scf)) == NULL || 81 (pg = scf_pg_create(scf)) == NULL) 82 goto cleanup3; 83 84 if (scf_handle_decode_fmri(scf, fmri, NULL, NULL, inst, 85 NULL, NULL, SCF_DECODE_FMRI_EXACT) != 0) 86 goto cleanup3; 87 88 if (scf_instance_get_pg_composed(inst, NULL, "config", pg) != 0) 89 goto cleanup3; 90 91 return (0); 92 93 cleanup3: 94 if (pg != NULL) { 95 scf_pg_destroy(pg); 96 pg = NULL; 97 } 98 if (inst != NULL) { 99 scf_instance_destroy(inst); 100 inst = NULL; 101 } 102 cleanup2: 103 free(fmri); 104 fmri = NULL; 105 cleanup1: 106 (void) scf_handle_unbind(scf); 107 cleanup0: 108 (void) scf_handle_destroy(scf); 109 scf = NULL; 110 return (rc); 111 } 112 113 void 114 fini_scf(void) 115 { 116 (void) scf_pg_destroy(pg); 117 pg = NULL; 118 (void) scf_instance_destroy(inst); 119 inst = NULL; 120 free(fmri); 121 fmri = NULL; 122 (void) scf_handle_unbind(scf); 123 (void) scf_handle_destroy(scf); 124 scf = NULL; 125 } 126 127 /* 128 * Fetch the boolean value of a property from the 'config' property 129 * group in our smf(5) instance. 130 * Returns: 131 * <0 on failure 132 * 0 if found and false 133 * 1 if found and true 134 */ 135 int 136 get_config_boolean(char *name) 137 { 138 scf_property_t *prop = NULL; 139 scf_value_t *val = NULL; 140 uint8_t out; 141 int rc = -1; 142 143 prop = scf_property_create(scf); 144 val = scf_value_create(scf); 145 if (prop == NULL || val == NULL) 146 goto cleanup0; 147 148 if (scf_pg_get_property(pg, name, prop) != 0) 149 goto cleanup0; 150 151 if (scf_property_is_type(prop, SCF_TYPE_BOOLEAN) != 0) 152 goto cleanup0; 153 154 if (scf_property_get_value(prop, val) != 0) 155 goto cleanup0; 156 157 if (scf_value_get_boolean(val, &out) != 0) 158 goto cleanup0; 159 160 rc = out; 161 162 cleanup0: 163 if (val != NULL) 164 scf_value_destroy(val); 165 if (prop != NULL) 166 scf_property_destroy(prop); 167 168 return (rc); 169 } 170 171 /* 172 * Fetch the boolean value of a property from the 'config' property 173 * group in our smf(5) instance. 174 * Returns: 175 * NULL on failure 176 * a NUL-terminated string value on success, caller to free 177 */ 178 char * 179 get_config_string(char *name) 180 { 181 scf_property_t *prop = NULL; 182 scf_value_t *val = NULL; 183 char out[PATH_MAX]; 184 char *rc = NULL; 185 186 prop = scf_property_create(scf); 187 val = scf_value_create(scf); 188 if (prop == NULL || val == NULL) 189 goto cleanup0; 190 191 if (scf_pg_get_property(pg, name, prop) != 0) 192 goto cleanup0; 193 194 if (scf_property_is_type(prop, SCF_TYPE_ASTRING) != 0) 195 goto cleanup0; 196 197 if (scf_property_get_value(prop, val) != 0) 198 goto cleanup0; 199 200 if (scf_value_get_astring(val, out, sizeof (out)) == -1) 201 goto cleanup0; 202 203 rc = xstrdup(out); 204 205 cleanup0: 206 if (val != NULL) 207 scf_value_destroy(val); 208 if (prop != NULL) 209 scf_property_destroy(prop); 210 211 return (rc); 212 }