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
init_fn(void)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 *
new_cname(const char * str)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
reftype(const FN_ref_t * ref)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
addrtype(const FN_ref_addr_t * addr)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
ident_equal(const FN_identifier_t * id1,const FN_identifier_t * id2)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
ident_str_equal(const FN_identifier_t * id,const char * str)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
logstat(const FN_status_t * status,const char * msg1,const char * msg2)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
transient(const FN_status_t * status)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
log_mem_failure(void)206 log_mem_failure(void)
207 {
208 if (verbose) {
209 syslog(LOG_ERR, "Memory allocation failed");
210 }
211 }
212