8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / common / tsol / ltos.c
blob58eb080abb5dc97865d175b6ee66105c13ad1aea
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #if !defined(_KERNEL)
27 #include <errno.h>
28 #endif /* !defined(_KERNEL) */
30 #include <sys/types.h>
31 #include <sys/mman.h>
32 #include <sys/tsol/label_macro.h>
34 #include <sys/tsol/label.h>
36 #if !defined(_KERNEL)
37 #include "clnt.h"
38 #include "labeld.h"
39 #endif /* !defined(_KERNEL) */
41 #if defined(_KERNEL)
42 #include <sys/systm.h>
43 #include <sys/sunddi.h>
44 #else
45 #include <stdlib.h>
46 #include <string.h>
47 #include <ctype.h>
48 #endif
52 static _mac_label_impl_t low;
53 static _mac_label_impl_t high;
54 static int inited = 0;
56 #if defined(_KERNEL)
57 #define malloc(l) kmem_alloc(l, KM_NOSLEEP)
58 #define freeit(a, l) kmem_free(a, l)
59 #else /* defined(_KERNEL) */
60 #define freeit(a, l) free(a)
61 #endif /* defined(_KERNEL) */
63 /* 0x + Classification + '-' + ll + '-' + Compartments + end of string */
64 #define _HEX_SIZE 2+(sizeof (Classification_t)*2)+4+\
65 (sizeof (Compartments_t)*2)+1
67 /* 0x + Classification + '-' + ll + '-' + end of string */
68 #define _MIN_HEX (2 + (sizeof (Classification_t)*2) + 4 + 1)
70 static char digits[] = "0123456789abcdef";
72 #define HEX(h, i, l, s) \
73 for (; i < s; /* */) {\
74 h[i++] = digits[(unsigned int)(*l >> 4)];\
75 h[i++] = digits[(unsigned int)(*l++&0xF)]; }
77 static int
78 __hex(char **s, const m_label_t *l)
80 char *hex;
81 int i = 0;
82 uchar_t *hl;
83 int hex_len;
84 uchar_t *len;
86 hl = (uchar_t *)&(((_mac_label_impl_t *)l)->_c_len);
87 len = hl;
89 if (*len == 0) {
90 /* old binary label */
91 hex_len = _HEX_SIZE;
92 } else {
93 hex_len = _MIN_HEX + (*len * sizeof (uint32_t) * 2);
96 if ((hex = malloc(hex_len)) == NULL) {
97 return (-1);
100 /* header */
102 hex[i++] = '0';
103 hex[i++] = 'x';
105 /* classification */
107 hl++; /* start at classification */
108 HEX(hex, i, hl, 6);
110 /* Add compartments length */
111 hex[i++] = '-';
112 HEX(hex, i, len, 9);
113 hex[i++] = '-';
115 /* compartments */
116 HEX(hex, i, hl, hex_len-1);
117 hex[i] = '\0';
119 /* truncate trailing zeros */
121 while (hex[i-1] == '0' && hex[i-2] == '0') {
122 i -= 2;
124 hex[i] = '\0';
126 if ((*s = strdup(hex)) == NULL) {
127 freeit(hex, hex_len);
128 return (-1);
131 freeit(hex, hex_len);
132 return (0);
137 l_to_str_internal(const m_label_t *l, char **s)
139 if (inited == 0) {
140 inited = 1;
141 _BSLLOW(&low);
142 _BSLHIGH(&high);
145 if (!(_MTYPE(l, SUN_MAC_ID) || _MTYPE(l, SUN_UCLR_ID))) {
146 #if !defined(_KERNEL)
147 errno = EINVAL;
148 #endif /* !defined(_KERNEL) */
149 *s = NULL;
150 return (-1);
152 if (_MEQUAL(&low, (_mac_label_impl_t *)l)) {
153 if ((*s = strdup(ADMIN_LOW)) == NULL) {
154 return (-1);
156 return (0);
158 if (_MEQUAL(&high, (_mac_label_impl_t *)l)) {
159 if ((*s = strdup(ADMIN_HIGH)) == NULL) {
160 return (-1);
162 return (0);
165 return (__hex(s, l));
168 #if !defined(_KERNEL)
170 * label_to_str -- convert a label to the requested type of string.
172 * Entry l = label to convert;
173 * t = type of conversion;
174 * f = flags for conversion type;
176 * Exit *s = allocated converted string;
177 * Caller must call free() to free.
179 * Returns 0, success.
180 * -1, error, errno set; *s = NULL.
182 * Calls labeld
186 label_to_str(const m_label_t *l, char **s, const m_label_str_t t, uint_t f)
188 labeld_data_t call;
189 labeld_data_t *callp = &call;
190 size_t bufsize = sizeof (labeld_data_t);
191 size_t datasize;
192 int err;
193 int string_start = 0;
195 if (inited == 0) {
196 inited = 1;
197 _BSLLOW(&low);
198 _BSLHIGH(&high);
201 #define lscall callp->param.acall.cargs.ls_arg
202 #define lsret callp->param.aret.rvals.ls_ret
203 switch (t) {
204 case M_LABEL:
205 call.callop = LTOS;
206 lscall.label = *l;
207 lscall.flags = f;
208 datasize = CALL_SIZE(ls_call_t, 0);
209 if ((err = __call_labeld(&callp, &bufsize, &datasize)) ==
210 SUCCESS) {
211 if (callp->reterr != 0) {
212 errno = EINVAL;
213 *s = NULL;
214 return (-1);
216 *s = strdup(lsret.buf);
217 if (callp != &call) {
218 /* release returned buffer */
219 (void) munmap((void *)callp, bufsize);
221 if (*s == NULL) {
222 return (-1);
224 return (0);
226 switch (err) {
227 case NOSERVER:
228 /* server not present */
229 /* special case admin_low and admin_high */
231 if (_MEQUAL(&low, (_mac_label_impl_t *)l)) {
232 if ((*s = strdup(ADMIN_LOW)) == NULL) {
233 return (-1);
235 return (0);
236 } else if (_MEQUAL(&high, (_mac_label_impl_t *)l)) {
237 if ((*s = strdup(ADMIN_HIGH)) == NULL) {
238 return (-1);
240 return (0);
242 errno = ENOTSUP;
243 break;
244 default:
245 errno = EINVAL;
246 break;
248 *s = NULL;
249 return (-1);
250 #undef lscall
251 #undef lsret
253 case M_INTERNAL: {
254 return (l_to_str_internal(l, s));
257 #define ccall callp->param.acall.cargs.color_arg
258 #define cret callp->param.aret.rvals.color_ret
259 case M_COLOR:
260 datasize = CALL_SIZE(color_call_t, 0);
261 call.callop = BLTOCOLOR;
262 ccall.label = *l;
264 if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) {
265 if (callp->reterr != 0) {
266 errno = EINVAL;
267 *s = NULL;
268 return (-1);
270 *s = strdup(cret.color);
271 if (callp != &call) {
272 /* release returned buffer */
273 (void) munmap((void *)callp, bufsize);
275 if (*s == NULL) {
276 return (-1);
278 return (0);
279 } else {
280 errno = ENOTSUP;
281 *s = NULL;
282 return (-1);
284 #undef ccall
285 #undef cret
287 #define prcall callp->param.acall.cargs.pr_arg
288 #define prret callp->param.aret.rvals.pr_ret
289 case PRINTER_TOP_BOTTOM:
290 call.callop = PR_TOP;
291 break;
292 case PRINTER_LABEL:
293 call.callop = PR_LABEL;
294 break;
295 case PRINTER_CAVEATS:
296 call.callop = PR_CAVEATS;
297 string_start = 1; /* compensate for leading space */
298 break;
299 case PRINTER_CHANNELS:
300 call.callop = PR_CHANNELS;
301 string_start = 1; /* compensate for leading space */
302 break;
303 default:
304 errno = EINVAL;
305 *s = NULL;
306 return (-1);
308 /* do the common printer calls */
309 datasize = CALL_SIZE(pr_call_t, 0);
310 prcall.label = *l;
311 prcall.flags = f;
312 if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) {
313 if (callp->reterr != 0) {
314 errno = EINVAL;
315 *s = NULL;
316 return (-1);
318 *s = strdup(&prret.buf[string_start]);
319 if (callp != &call) {
320 /* release returned buffer */
321 (void) munmap((void *)callp, bufsize);
323 if (*s == NULL) {
324 return (-1);
326 return (0);
327 } else {
328 errno = ENOTSUP;
329 *s = NULL;
330 return (-1);
332 #undef prcall
333 #undef prret
335 #endif /* !defined(_KERNEL) */