1/*-
2 * Copyright (c) 2008 Apple Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1.  Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 * 2.  Redistributions in binary form must reproduce the above copyright
11 *     notice, this list of conditions and the following disclaimer in the
12 *     documentation and/or other materials provided with the distribution.
13 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14 *     its contributors may be used to endorse or promote products derived
15 *     from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <sys/types.h>
31
32#include <config/config.h>
33
34#include <bsm/audit_errno.h>
35#include <bsm/libbsm.h>
36
37#include <errno.h>
38#include <string.h>
39
40/*
41 * Different operating systems use different numeric constants for different
42 * error numbers, and sometimes error numbers don't exist in more than one
43 * operating system.  These routines convert between BSM and local error
44 * number spaces, subject to the above realities.  BSM error numbers are
45 * stored in a single 8-bit character, so don't have a byte order.
46 *
47 * Don't include string definitions when this code is compiled into a kernel.
48 */
49struct bsm_errno {
50	int		 be_bsm_errno;
51	int		 be_local_errno;
52#if !defined(KERNEL) && !defined(_KERNEL)
53	const char	*be_strerror;
54#endif
55};
56
57#define	ERRNO_NO_LOCAL_MAPPING	-600
58
59#if !defined(KERNEL) && !defined(_KERNEL)
60#define	ES(x)	x
61#else
62#define	ES(x)
63#endif
64
65/*
66 * Mapping table -- please maintain in numeric sorted order with respect to
67 * the BSM constant.  Today we do a linear lookup, but could switch to a
68 * binary search if it makes sense.  We only ifdef errors that aren't
69 * generally available, but it does make the table a lot more ugly.
70 *
71 * XXXRW: It would be nice to have a similar ordered table mapping to BSM
72 * constant from local constant, but the order of local constants varies by
73 * OS.  Really we need to build that table at compile-time but don't do that
74 * yet.
75 *
76 * XXXRW: We currently embed English-language error strings here, but should
77 * support catalogues; these are only used if the OS doesn't have an error
78 * string using strerror(3).
79 */
80static const struct bsm_errno bsm_errnos[] = {
81	{ BSM_ERRNO_ESUCCESS, 0, ES("Success") },
82	{ BSM_ERRNO_EPERM, EPERM, ES("Operation not permitted") },
83	{ BSM_ERRNO_ENOENT, ENOENT, ES("No such file or directory") },
84	{ BSM_ERRNO_ESRCH, ESRCH, ES("No such process") },
85	{ BSM_ERRNO_EINTR, EINTR, ES("Interrupted system call") },
86	{ BSM_ERRNO_EIO, EIO, ES("Input/output error") },
87	{ BSM_ERRNO_ENXIO, ENXIO, ES("Device not configured") },
88	{ BSM_ERRNO_E2BIG, E2BIG, ES("Argument list too long") },
89	{ BSM_ERRNO_ENOEXEC, ENOEXEC, ES("Exec format error") },
90	{ BSM_ERRNO_EBADF, EBADF, ES("Bad file descriptor") },
91	{ BSM_ERRNO_ECHILD, ECHILD, ES("No child processes") },
92	{ BSM_ERRNO_EAGAIN, EAGAIN, ES("Resource temporarily unavailable") },
93	{ BSM_ERRNO_ENOMEM, ENOMEM, ES("Cannot allocate memory") },
94	{ BSM_ERRNO_EACCES, EACCES, ES("Permission denied") },
95	{ BSM_ERRNO_EFAULT, EFAULT, ES("Bad address") },
96	{ BSM_ERRNO_ENOTBLK, ENOTBLK, ES("Block device required") },
97	{ BSM_ERRNO_EBUSY, EBUSY, ES("Device busy") },
98	{ BSM_ERRNO_EEXIST, EEXIST, ES("File exists") },
99	{ BSM_ERRNO_EXDEV, EXDEV, ES("Cross-device link") },
100	{ BSM_ERRNO_ENODEV, ENODEV, ES("Operation not supported by device") },
101	{ BSM_ERRNO_ENOTDIR, ENOTDIR, ES("Not a directory") },
102	{ BSM_ERRNO_EISDIR, EISDIR, ES("Is a directory") },
103	{ BSM_ERRNO_EINVAL, EINVAL, ES("Invalid argument") },
104	{ BSM_ERRNO_ENFILE, ENFILE, ES("Too many open files in system") },
105	{ BSM_ERRNO_EMFILE, EMFILE, ES("Too many open files") },
106	{ BSM_ERRNO_ENOTTY, ENOTTY, ES("Inappropriate ioctl for device") },
107	{ BSM_ERRNO_ETXTBSY, ETXTBSY, ES("Text file busy") },
108	{ BSM_ERRNO_EFBIG, EFBIG, ES("File too large") },
109	{ BSM_ERRNO_ENOSPC, ENOSPC, ES("No space left on device") },
110	{ BSM_ERRNO_ESPIPE, ESPIPE, ES("Illegal seek") },
111	{ BSM_ERRNO_EROFS, EROFS, ES("Read-only file system") },
112	{ BSM_ERRNO_EMLINK, EMLINK, ES("Too many links") },
113	{ BSM_ERRNO_EPIPE, EPIPE, ES("Broken pipe") },
114	{ BSM_ERRNO_EDOM, EDOM, ES("Numerical argument out of domain") },
115	{ BSM_ERRNO_ERANGE, ERANGE, ES("Result too large") },
116	{ BSM_ERRNO_ENOMSG, ENOMSG, ES("No message of desired type") },
117	{ BSM_ERRNO_EIDRM, EIDRM, ES("Identifier removed") },
118	{ BSM_ERRNO_ECHRNG,
119#ifdef ECHRNG
120	ECHRNG,
121#else
122	ERRNO_NO_LOCAL_MAPPING,
123#endif
124	ES("Channel number out of range") },
125	{ BSM_ERRNO_EL2NSYNC,
126#ifdef EL2NSYNC
127	EL2NSYNC,
128#else
129	ERRNO_NO_LOCAL_MAPPING,
130#endif
131	ES("Level 2 not synchronized") },
132	{ BSM_ERRNO_EL3HLT,
133#ifdef EL3HLT
134	EL3HLT,
135#else
136	ERRNO_NO_LOCAL_MAPPING,
137#endif
138	ES("Level 3 halted") },
139	{ BSM_ERRNO_EL3RST,
140#ifdef EL3RST
141	EL3RST,
142#else
143	ERRNO_NO_LOCAL_MAPPING,
144#endif
145	ES("Level 3 reset") },
146	{ BSM_ERRNO_ELNRNG,
147#ifdef ELNRNG
148	ELNRNG,
149#else
150	ERRNO_NO_LOCAL_MAPPING,
151#endif
152	ES("Link number out of range") },
153	{ BSM_ERRNO_EUNATCH,
154#ifdef EUNATCH
155	EUNATCH,
156#else
157	ERRNO_NO_LOCAL_MAPPING,
158#endif
159	ES("Protocol driver not attached") },
160	{ BSM_ERRNO_ENOCSI,
161#ifdef ENOCSI
162	ENOCSI,
163#else
164	ERRNO_NO_LOCAL_MAPPING,
165#endif
166	ES("No CSI structure available") },
167	{ BSM_ERRNO_EL2HLT,
168#ifdef EL2HLT
169	EL2HLT,
170#else
171	ERRNO_NO_LOCAL_MAPPING,
172#endif
173	ES("Level 2 halted") },
174	{ BSM_ERRNO_EDEADLK, EDEADLK, ES("Resource deadlock avoided") },
175	{ BSM_ERRNO_ENOLCK, ENOLCK, ES("No locks available") },
176	{ BSM_ERRNO_ECANCELED, ECANCELED, ES("Operation canceled") },
177	{ BSM_ERRNO_ENOTSUP, ENOTSUP, ES("Operation not supported") },
178	{ BSM_ERRNO_EDQUOT, EDQUOT, ES("Disc quota exceeded") },
179	{ BSM_ERRNO_EBADE,
180#ifdef EBADE
181	EBADE,
182#else
183	ERRNO_NO_LOCAL_MAPPING,
184#endif
185	ES("Invalid exchange") },
186	{ BSM_ERRNO_EBADR,
187#ifdef EBADR
188	EBADR,
189#else
190	ERRNO_NO_LOCAL_MAPPING,
191#endif
192	ES("Invalid request descriptor") },
193	{ BSM_ERRNO_EXFULL,
194#ifdef EXFULL
195	EXFULL,
196#else
197	ERRNO_NO_LOCAL_MAPPING,
198#endif
199	ES("Exchange full") },
200	{ BSM_ERRNO_ENOANO,
201#ifdef ENOANO
202	ENOANO,
203#else
204	ERRNO_NO_LOCAL_MAPPING,
205#endif
206	ES("No anode") },
207	{ BSM_ERRNO_EBADRQC,
208#ifdef EBADRQC
209	EBADRQC,
210#else
211	ERRNO_NO_LOCAL_MAPPING,
212#endif
213	ES("Invalid request descriptor") },
214	{ BSM_ERRNO_EBADSLT,
215#ifdef EBADSLT
216	EBADSLT,
217#else
218	ERRNO_NO_LOCAL_MAPPING,
219#endif
220	ES("Invalid slot") },
221	{ BSM_ERRNO_EDEADLOCK,
222#ifdef EDEADLOCK
223	EDEADLOCK,
224#else
225	ERRNO_NO_LOCAL_MAPPING,
226#endif
227	ES("Resource deadlock avoided") },
228	{ BSM_ERRNO_EBFONT,
229#ifdef EBFONT
230	EBFONT,
231#else
232	ERRNO_NO_LOCAL_MAPPING,
233#endif
234	ES("Bad font file format") },
235	{ BSM_ERRNO_EOWNERDEAD,
236#ifdef EOWNERDEAD
237	EOWNERDEAD,
238#else
239	ERRNO_NO_LOCAL_MAPPING,
240#endif
241	ES("Process died with the lock") },
242	{ BSM_ERRNO_ENOTRECOVERABLE,
243#ifdef ENOTRECOVERABLE
244	ENOTRECOVERABLE,
245#else
246	ERRNO_NO_LOCAL_MAPPING,
247#endif
248	ES("Lock is not recoverable") },
249	{ BSM_ERRNO_ENOSTR,
250#ifdef ENOSTR
251	ENOSTR,
252#else
253	ERRNO_NO_LOCAL_MAPPING,
254#endif
255	ES("Device not a stream") },
256	{ BSM_ERRNO_ENONET,
257#ifdef ENONET
258	ENONET,
259#else
260	ERRNO_NO_LOCAL_MAPPING,
261#endif
262	ES("Machine is not on the network") },
263	{ BSM_ERRNO_ENOPKG,
264#ifdef ENOPKG
265	ENOPKG,
266#else
267	ERRNO_NO_LOCAL_MAPPING,
268#endif
269	ES("Package not installed") },
270	{ BSM_ERRNO_EREMOTE, EREMOTE,
271	    ES("Too many levels of remote in path") },
272	{ BSM_ERRNO_ENOLINK,
273#ifdef ENOLINK
274	ENOLINK,
275#else
276	ERRNO_NO_LOCAL_MAPPING,
277#endif
278	ES("Link has been severed") },
279	{ BSM_ERRNO_EADV,
280#ifdef EADV
281	EADV,
282#else
283	ERRNO_NO_LOCAL_MAPPING,
284#endif
285	ES("Advertise error") },
286	{ BSM_ERRNO_ESRMNT,
287#ifdef ESRMNT
288	ESRMNT,
289#else
290	ERRNO_NO_LOCAL_MAPPING,
291#endif
292	ES("srmount error") },
293	{ BSM_ERRNO_ECOMM,
294#ifdef ECOMM
295	ECOMM,
296#else
297	ERRNO_NO_LOCAL_MAPPING,
298#endif
299	ES("Communication error on send") },
300	{ BSM_ERRNO_EPROTO,
301#ifdef EPROTO
302	EPROTO,
303#else
304	ERRNO_NO_LOCAL_MAPPING,
305#endif
306	ES("Protocol error") },
307	{ BSM_ERRNO_ELOCKUNMAPPED,
308#ifdef ELOCKUNMAPPED
309	ELOCKUNMAPPED,
310#else
311	ERRNO_NO_LOCAL_MAPPING,
312#endif
313	ES("Locked lock was unmapped") },
314	{ BSM_ERRNO_ENOTACTIVE,
315#ifdef ENOTACTIVE
316	ENOTACTIVE,
317#else
318	ERRNO_NO_LOCAL_MAPPING,
319#endif
320	ES("Facility is not active") },
321	{ BSM_ERRNO_EMULTIHOP,
322#ifdef EMULTIHOP
323	EMULTIHOP,
324#else
325	ERRNO_NO_LOCAL_MAPPING,
326#endif
327	ES("Multihop attempted") },
328	{ BSM_ERRNO_EBADMSG,
329#ifdef EBADMSG
330	EBADMSG,
331#else
332	ERRNO_NO_LOCAL_MAPPING,
333#endif
334	ES("Bad message") },
335	{ BSM_ERRNO_ENAMETOOLONG, ENAMETOOLONG, ES("File name too long") },
336	{ BSM_ERRNO_EOVERFLOW, EOVERFLOW,
337	    ES("Value too large to be stored in data type") },
338	{ BSM_ERRNO_ENOTUNIQ,
339#ifdef ENOTUNIQ
340	ENOTUNIQ,
341#else
342	ERRNO_NO_LOCAL_MAPPING,
343#endif
344	ES("Given log name not unique") },
345	{ BSM_ERRNO_EBADFD,
346#ifdef EBADFD
347	EBADFD,
348#else
349	ERRNO_NO_LOCAL_MAPPING,
350#endif
351	ES("Given f.d. invalid for this operation") },
352	{ BSM_ERRNO_EREMCHG,
353#ifdef EREMCHG
354	EREMCHG,
355#else
356	ERRNO_NO_LOCAL_MAPPING,
357#endif
358	ES("Remote address changed") },
359	{ BSM_ERRNO_ELIBACC,
360#ifdef ELIBACC
361	ELIBACC,
362#else
363	ERRNO_NO_LOCAL_MAPPING,
364#endif
365	ES("Can't access a needed shared lib") },
366	{ BSM_ERRNO_ELIBBAD,
367#ifdef ELIBBAD
368	ELIBBAD,
369#else
370	ERRNO_NO_LOCAL_MAPPING,
371#endif
372	ES("Accessing a corrupted shared lib") },
373	{ BSM_ERRNO_ELIBSCN,
374#ifdef ELIBSCN
375	ELIBSCN,
376#else
377	ERRNO_NO_LOCAL_MAPPING,
378#endif
379	ES(".lib section in a.out corrupted") },
380	{ BSM_ERRNO_ELIBMAX,
381#ifdef ELIBMAX
382	ELIBMAX,
383#else
384	ERRNO_NO_LOCAL_MAPPING,
385#endif
386	ES("Attempting to link in too many libs") },
387	{ BSM_ERRNO_ELIBEXEC,
388#ifdef ELIBEXEC
389	ELIBEXEC,
390#else
391	ERRNO_NO_LOCAL_MAPPING,
392#endif
393	ES("Attempting to exec a shared library") },
394	{ BSM_ERRNO_EILSEQ, EILSEQ, ES("Illegal byte sequence") },
395	{ BSM_ERRNO_ENOSYS, ENOSYS, ES("Function not implemented") },
396	{ BSM_ERRNO_ELOOP, ELOOP, ES("Too many levels of symbolic links") },
397	{ BSM_ERRNO_ERESTART,
398#ifdef ERESTART
399	ERESTART,
400#else
401	ERRNO_NO_LOCAL_MAPPING,
402#endif
403	ES("Restart syscall") },
404	{ BSM_ERRNO_ESTRPIPE,
405#ifdef ESTRPIPE
406	ESTRPIPE,
407#else
408	ERRNO_NO_LOCAL_MAPPING,
409#endif
410	ES("If pipe/FIFO, don't sleep in stream head") },
411	{ BSM_ERRNO_ENOTEMPTY, ENOTEMPTY, ES("Directory not empty") },
412	{ BSM_ERRNO_EUSERS, EUSERS, ES("Too many users") },
413	{ BSM_ERRNO_ENOTSOCK, ENOTSOCK,
414	    ES("Socket operation on non-socket") },
415	{ BSM_ERRNO_EDESTADDRREQ, EDESTADDRREQ,
416	    ES("Destination address required") },
417	{ BSM_ERRNO_EMSGSIZE, EMSGSIZE, ES("Message too long") },
418	{ BSM_ERRNO_EPROTOTYPE, EPROTOTYPE,
419	    ES("Protocol wrong type for socket") },
420	{ BSM_ERRNO_ENOPROTOOPT, ENOPROTOOPT, ES("Protocol not available") },
421	{ BSM_ERRNO_EPROTONOSUPPORT, EPROTONOSUPPORT,
422	    ES("Protocol not supported") },
423	{ BSM_ERRNO_ESOCKTNOSUPPORT, ESOCKTNOSUPPORT,
424	    ES("Socket type not supported") },
425	{ BSM_ERRNO_EOPNOTSUPP, EOPNOTSUPP, ES("Operation not supported") },
426	{ BSM_ERRNO_EPFNOSUPPORT, EPFNOSUPPORT,
427	    ES("Protocol family not supported") },
428	{ BSM_ERRNO_EAFNOSUPPORT, EAFNOSUPPORT,
429	    ES("Address family not supported by protocol family") },
430	{ BSM_ERRNO_EADDRINUSE, EADDRINUSE, ES("Address already in use") },
431	{ BSM_ERRNO_EADDRNOTAVAIL, EADDRNOTAVAIL,
432	    ES("Can't assign requested address") },
433	{ BSM_ERRNO_ENETDOWN, ENETDOWN, ES("Network is down") },
434	{ BSM_ERRNO_ENETRESET, ENETRESET,
435	    ES("Network dropped connection on reset") },
436	{ BSM_ERRNO_ECONNABORTED, ECONNABORTED,
437	    ES("Software caused connection abort") },
438	{ BSM_ERRNO_ECONNRESET, ECONNRESET, ES("Connection reset by peer") },
439	{ BSM_ERRNO_ENOBUFS, ENOBUFS, ES("No buffer space available") },
440	{ BSM_ERRNO_EISCONN, EISCONN, ES("Socket is already connected") },
441	{ BSM_ERRNO_ENOTCONN, ENOTCONN, ES("Socket is not connected") },
442	{ BSM_ERRNO_ESHUTDOWN, ESHUTDOWN,
443	    ES("Can't send after socket shutdown") },
444	{ BSM_ERRNO_ETOOMANYREFS, ETOOMANYREFS,
445	    ES("Too many references: can't splice") },
446	{ BSM_ERRNO_ETIMEDOUT, ETIMEDOUT, ES("Operation timed out") },
447	{ BSM_ERRNO_ECONNREFUSED, ECONNREFUSED, ES("Connection refused") },
448	{ BSM_ERRNO_EHOSTDOWN, EHOSTDOWN, ES("Host is down") },
449	{ BSM_ERRNO_EHOSTUNREACH, EHOSTUNREACH, ES("No route to host") },
450	{ BSM_ERRNO_EALREADY, EALREADY, ES("Operation already in progress") },
451	{ BSM_ERRNO_EINPROGRESS, EINPROGRESS,
452	    ES("Operation now in progress") },
453	{ BSM_ERRNO_ESTALE, ESTALE, ES("Stale NFS file handle") },
454	{ BSM_ERRNO_EPROCLIM,
455#ifdef EPROCLIM
456	EPROCLIM,
457#else
458	ERRNO_NO_LOCAL_MAPPING,
459#endif
460	ES("Too many processes") },
461	{ BSM_ERRNO_EBADRPC,
462#ifdef EBADRPC
463	EBADRPC,
464#else
465	ERRNO_NO_LOCAL_MAPPING,
466#endif
467	ES("RPC struct is bad") },
468	{ BSM_ERRNO_ERPCMISMATCH,
469#ifdef ERPCMISMATCH
470	ERPCMISMATCH,
471#else
472	ERRNO_NO_LOCAL_MAPPING,
473#endif
474	ES("RPC version wrong") },
475	{ BSM_ERRNO_EPROGUNAVAIL,
476#ifdef EPROGUNAVAIL
477	EPROGUNAVAIL,
478#else
479	ERRNO_NO_LOCAL_MAPPING,
480#endif
481	ES("RPC prog. not avail") },
482	{ BSM_ERRNO_EPROGMISMATCH,
483#ifdef EPROGMISMATCH
484	EPROGMISMATCH,
485#else
486	ERRNO_NO_LOCAL_MAPPING,
487#endif
488	ES("RPC version wrong") },
489	{ BSM_ERRNO_EPROCUNAVAIL,
490#ifdef EPROCUNAVAIL
491	EPROCUNAVAIL,
492#else
493	ERRNO_NO_LOCAL_MAPPING,
494#endif
495	ES("Bad procedure for program") },
496	{ BSM_ERRNO_EFTYPE,
497#ifdef EFTYPE
498	EFTYPE,
499#else
500	ERRNO_NO_LOCAL_MAPPING,
501#endif
502	ES("Inappropriate file type or format") },
503	{ BSM_ERRNO_EAUTH,
504#ifdef EAUTH
505	EAUTH,
506#else
507	ERRNO_NO_LOCAL_MAPPING,
508#endif
509	ES("Authenticateion error") },
510	{ BSM_ERRNO_ENEEDAUTH,
511#ifdef ENEEDAUTH
512	ENEEDAUTH,
513#else
514	ERRNO_NO_LOCAL_MAPPING,
515#endif
516	ES("Need authenticator") },
517	{ BSM_ERRNO_ENOATTR,
518#ifdef ENOATTR
519	ENOATTR,
520#else
521	ERRNO_NO_LOCAL_MAPPING,
522#endif
523	ES("Attribute not found") },
524	{ BSM_ERRNO_EDOOFUS,
525#ifdef EDOOFUS
526	EDOOFUS,
527#else
528	ERRNO_NO_LOCAL_MAPPING,
529#endif
530	ES("Programming error") },
531	{ BSM_ERRNO_EJUSTRETURN,
532#ifdef EJUSTRETURN
533	EJUSTRETURN,
534#else
535	ERRNO_NO_LOCAL_MAPPING,
536#endif
537	ES("Just return") },
538	{ BSM_ERRNO_ENOIOCTL,
539#ifdef ENOIOCTL
540	ENOIOCTL,
541#else
542	ERRNO_NO_LOCAL_MAPPING,
543#endif
544	ES("ioctl not handled by this layer") },
545	{ BSM_ERRNO_EDIRIOCTL,
546#ifdef EDIRIOCTL
547	EDIRIOCTL,
548#else
549	ERRNO_NO_LOCAL_MAPPING,
550#endif
551	ES("do direct ioctl in GEOM") },
552	{ BSM_ERRNO_EPWROFF,
553#ifdef EPWROFF
554	EPWROFF,
555#else
556	ERRNO_NO_LOCAL_MAPPING,
557#endif
558	ES("Device power is off") },
559	{ BSM_ERRNO_EDEVERR,
560#ifdef EDEVERR
561	EDEVERR,
562#else
563	ERRNO_NO_LOCAL_MAPPING,
564#endif
565	ES("Device error") },
566	{ BSM_ERRNO_EBADEXEC,
567#ifdef EBADEXEC
568	EBADEXEC,
569#else
570	ERRNO_NO_LOCAL_MAPPING,
571#endif
572	ES("Bad executable") },
573	{ BSM_ERRNO_EBADARCH,
574#ifdef EBADARCH
575	EBADARCH,
576#else
577	ERRNO_NO_LOCAL_MAPPING,
578#endif
579	ES("Bad CPU type in executable") },
580	{ BSM_ERRNO_ESHLIBVERS,
581#ifdef ESHLIBVERS
582	ESHLIBVERS,
583#else
584	ERRNO_NO_LOCAL_MAPPING,
585#endif
586	ES("Shared library version mismatch") },
587	{ BSM_ERRNO_EBADMACHO,
588#ifdef EBADMACHO
589	EBADMACHO,
590#else
591	ERRNO_NO_LOCAL_MAPPING,
592#endif
593	ES("Malformed Macho file") },
594	{ BSM_ERRNO_EPOLICY,
595#ifdef EPOLICY
596	EPOLICY,
597#else
598	ERRNO_NO_LOCAL_MAPPING,
599#endif
600	ES("Operation failed by policy") },
601	{ BSM_ERRNO_EDOTDOT,
602#ifdef EDOTDOT
603	EDOTDOT,
604#else
605	ERRNO_NO_LOCAL_MAPPING,
606#endif
607	ES("RFS specific error") },
608	{ BSM_ERRNO_EUCLEAN,
609#ifdef EUCLEAN
610	EUCLEAN,
611#else
612	ERRNO_NO_LOCAL_MAPPING,
613#endif
614	ES("Structure needs cleaning") },
615	{ BSM_ERRNO_ENOTNAM,
616#ifdef ENOTNAM
617	ENOTNAM,
618#else
619	ERRNO_NO_LOCAL_MAPPING,
620#endif
621	ES("Not a XENIX named type file") },
622	{ BSM_ERRNO_ENAVAIL,
623#ifdef ENAVAIL
624	ENAVAIL,
625#else
626	ERRNO_NO_LOCAL_MAPPING,
627#endif
628	ES("No XENIX semaphores available") },
629	{ BSM_ERRNO_EISNAM,
630#ifdef EISNAM
631	EISNAM,
632#else
633	ERRNO_NO_LOCAL_MAPPING,
634#endif
635	ES("Is a named type file") },
636	{ BSM_ERRNO_EREMOTEIO,
637#ifdef EREMOTEIO
638	EREMOTEIO,
639#else
640	ERRNO_NO_LOCAL_MAPPING,
641#endif
642	ES("Remote I/O error") },
643	{ BSM_ERRNO_ENOMEDIUM,
644#ifdef ENOMEDIUM
645	ENOMEDIUM,
646#else
647	ERRNO_NO_LOCAL_MAPPING,
648#endif
649	ES("No medium found") },
650	{ BSM_ERRNO_EMEDIUMTYPE,
651#ifdef EMEDIUMTYPE
652	EMEDIUMTYPE,
653#else
654	ERRNO_NO_LOCAL_MAPPING,
655#endif
656	ES("Wrong medium type") },
657	{ BSM_ERRNO_ENOKEY,
658#ifdef ENOKEY
659	ENOKEY,
660#else
661	ERRNO_NO_LOCAL_MAPPING,
662#endif
663	ES("Required key not available") },
664	{ BSM_ERRNO_EKEYEXPIRED,
665#ifdef EKEYEXPIRED
666	EKEYEXPIRED,
667#else
668	ERRNO_NO_LOCAL_MAPPING,
669#endif
670	ES("Key has expired") },
671	{ BSM_ERRNO_EKEYREVOKED,
672#ifdef EKEYREVOKED
673	EKEYREVOKED,
674#else
675	ERRNO_NO_LOCAL_MAPPING,
676#endif
677	ES("Key has been revoked") },
678	{ BSM_ERRNO_EKEYREJECTED,
679#ifdef EKEYREJECTED
680	EKEYREJECTED,
681#else
682	ERRNO_NO_LOCAL_MAPPING,
683#endif
684	ES("Key was rejected by service") },
685	{ BSM_ERRNO_ENOTCAPABLE,
686#ifdef ENOTCAPABLE
687	ENOTCAPABLE,
688#else
689	ERRNO_NO_LOCAL_MAPPING,
690#endif
691	ES("Capabilities insufficient") },
692	{ BSM_ERRNO_ECAPMODE,
693#ifdef ECAPMODE
694	ECAPMODE,
695#else
696	ERRNO_NO_LOCAL_MAPPING,
697#endif
698	ES("Not permitted in capability mode") },
699};
700static const int bsm_errnos_count = sizeof(bsm_errnos) / sizeof(bsm_errnos[0]);
701
702static const struct bsm_errno *
703bsm_lookup_errno_local(int local_errno)
704{
705	int i;
706
707	for (i = 0; i < bsm_errnos_count; i++) {
708		if (bsm_errnos[i].be_local_errno == local_errno)
709			return (&bsm_errnos[i]);
710	}
711	return (NULL);
712}
713
714/*
715 * Conversion to the BSM errno space isn't allowed to fail; we simply map to
716 * BSM_ERRNO_UNKNOWN and let the remote endpoint deal with it.
717 */
718u_char
719au_errno_to_bsm(int local_errno)
720{
721	const struct bsm_errno *bsme;
722
723	bsme = bsm_lookup_errno_local(local_errno);
724	if (bsme == NULL)
725		return (BSM_ERRNO_UNKNOWN);
726	return (bsme->be_bsm_errno);
727}
728
729static const struct bsm_errno *
730bsm_lookup_errno_bsm(u_char bsm_errno)
731{
732	int i;
733
734	for (i = 0; i < bsm_errnos_count; i++) {
735		if (bsm_errnos[i].be_bsm_errno == bsm_errno)
736			return (&bsm_errnos[i]);
737	}
738	return (NULL);
739}
740
741/*
742 * Converstion from a BSM error to a local error number may fail if either
743 * OpenBSM doesn't recognize the error on the wire, or because there is no
744 * appropriate local mapping.
745 */
746int
747au_bsm_to_errno(u_char bsm_errno, int *errorp)
748{
749	const struct bsm_errno *bsme;
750
751	bsme = bsm_lookup_errno_bsm(bsm_errno);
752	if (bsme == NULL || bsme->be_local_errno == ERRNO_NO_LOCAL_MAPPING)
753		return (-1);
754	*errorp = bsme->be_local_errno;
755	return (0);
756}
757
758#if !defined(KERNEL) && !defined(_KERNEL)
759const char *
760au_strerror(u_char bsm_errno)
761{
762	const struct bsm_errno *bsme;
763
764	bsme = bsm_lookup_errno_bsm(bsm_errno);
765	if (bsme == NULL)
766		return ("Unrecognized BSM error");
767	if (bsme->be_local_errno != ERRNO_NO_LOCAL_MAPPING)
768		return (strerror(bsme->be_local_errno));
769	return (bsme->be_strerror);
770}
771#endif
772