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 * ns_fnutils.c 23 * 24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 #include <syslog.h> 32 #include <synch.h> 33 #include <rpc/rpc.h> 34 #include <xfn/xfn.h> 35 #include "automount.h" 36 #include "ns_fnutils.h" 37 38 39 /* 40 * FNS file system reference and address types. Each array is indexed 41 * using the corresponding enumeration (reftype_t or addrtype_t). 42 */ 43 const char *reftypes[] = { 44 "onc_fn_fs", 45 }; 46 47 const char *addrtypes[] = { 48 "onc_fn_fs_mount", 49 "onc_fn_fs_host", 50 "onc_fn_fs_user", 51 }; 52 53 54 FN_string_t *empty_string = NULL; 55 FN_composite_name_t *empty_cname = NULL; 56 FN_composite_name_t *slash_cname = NULL; 57 58 59 int 60 init_fn(void) 61 { 62 static mutex_t init_lock = DEFAULTMUTEX; 63 64 if (slash_cname != NULL) { 65 return (0); 66 } 67 68 mutex_lock(&init_lock); 69 70 if (empty_string == NULL) { 71 if ((empty_string = fn_string_create()) == NULL) { 72 log_mem_failure(); 73 goto unlock; 74 } 75 } 76 if (empty_cname == NULL) { 77 if ((empty_cname = new_cname("")) == NULL) { 78 goto unlock; 79 } 80 } 81 if (slash_cname == NULL) { 82 if ((slash_cname = new_cname("/")) == NULL) { 83 goto unlock; 84 } 85 } 86 unlock: 87 mutex_unlock(&init_lock); 88 return ((slash_cname != NULL) ? 0 : -1); 89 } 90 91 92 FN_composite_name_t * 93 new_cname(const char *str) 94 { 95 FN_string_t *string; 96 FN_composite_name_t *cname; 97 98 string = fn_string_from_str((unsigned char *)str); 99 if (string == NULL) { 100 if (verbose) { 101 syslog(LOG_ERR, "Could not create FNS string object"); 102 } 103 return (NULL); 104 } 105 cname = fn_composite_name_from_string(string); 106 fn_string_destroy(string); 107 if ((cname == NULL) && verbose) { 108 syslog(LOG_ERR, "Could not create FNS composite name object"); 109 } 110 return (cname); 111 } 112 113 114 reftype_t 115 reftype(const FN_ref_t *ref) 116 { 117 reftype_t rtype; 118 119 for (rtype = 0; rtype < NUM_REFTYPES; rtype++) { 120 if (ident_str_equal(fn_ref_type(ref), reftypes[rtype])) { 121 break; 122 } 123 } 124 return (rtype); 125 } 126 127 128 addrtype_t 129 addrtype(const FN_ref_addr_t *addr) 130 { 131 addrtype_t atype; 132 const FN_identifier_t *ident = fn_ref_addr_type(addr); 133 134 for (atype = 0; atype < NUM_ADDRTYPES; atype++) { 135 if (ident_str_equal(ident, addrtypes[atype])) { 136 break; 137 } 138 } 139 return (atype); 140 } 141 142 143 bool_t 144 ident_equal(const FN_identifier_t *id1, const FN_identifier_t *id2) 145 { 146 return ((id1->format == id2->format) && 147 (id1->length == id2->length) && 148 (memcmp(id1->contents, id2->contents, id1->length) == 0)); 149 } 150 151 152 bool_t 153 ident_str_equal(const FN_identifier_t *id, const char *str) 154 { 155 return ((id->format == FN_ID_STRING) && 156 (id->length == strlen(str)) && 157 (strncmp(str, id->contents, id->length) == 0)); 158 } 159 160 161 void 162 logstat(const FN_status_t *status, const char *msg1, const char *msg2) 163 { 164 FN_string_t *desc_string; 165 const char *desc = NULL; 166 167 if (verbose) { 168 desc_string = fn_status_description(status, DETAIL, NULL); 169 if (desc_string != NULL) { 170 desc = (const char *)fn_string_str(desc_string, NULL); 171 } 172 if (desc == NULL) { 173 desc = "(no status description)"; 174 } 175 syslog(LOG_ERR, "FNS %s %s: %s (%u)", 176 msg1, msg2, desc, fn_status_code(status)); 177 fn_string_destroy(desc_string); 178 } 179 } 180 181 182 bool_t 183 transient(const FN_status_t *status) 184 { 185 unsigned int statcode; 186 187 statcode = fn_status_code(status); 188 if (statcode == FN_E_LINK_ERROR) { 189 statcode = fn_status_link_code(status); 190 } 191 switch (statcode) { 192 case FN_E_COMMUNICATION_FAILURE: 193 case FN_E_CTX_UNAVAILABLE: 194 case FN_E_INSUFFICIENT_RESOURCES: 195 case FN_E_INVALID_ENUM_HANDLE: 196 case FN_E_PARTIAL_RESULT: 197 case FN_E_UNSPECIFIED_ERROR: 198 return (TRUE); 199 default: 200 return (FALSE); 201 } 202 } 203 204 205 void 206 log_mem_failure(void) 207 { 208 if (verbose) { 209 syslog(LOG_ERR, "Memory allocation failed"); 210 } 211 } 212