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 }