source: roaraudio/libroar/error.c @ 5646:962e433070f3

Last change on this file since 5646:962e433070f3 was 5646:962e433070f3, checked in by phi, 12 years ago

Updated list of error values.

File size: 45.1 KB
Line 
1//error.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2012
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38// 'no error' value for errno.
39// zero is true for GNU/Linux.
40// don't know about other systems.
41// IEEE Std 1003.1-2008 (POSIX 7) requires:
42// 'distinct positive values'.
43#define CLEAN_ERRNO 0
44
45static int roar_errno = ROAR_ERROR_NONE;
46
47struct roar_error_frame * roar_err_errorframe(void) {
48 static struct roar_error_frame frame = {
49  .version     =  0,
50  .cmd         = -1,
51  .ra_errno    = ROAR_ERROR_UNKNOWN,
52  .ra_suberrno = -1,
53  .p_errno     = -1,
54  .flags       =  0,
55  .datalen     =  0,
56  .data        = NULL
57 };
58
59 return &frame;
60}
61
62int    roar_err_init(struct roar_error_frame * frame) {
63 if ( frame == NULL ) {
64  roar_err_set(ROAR_ERROR_FAULT);
65  return -1;
66 }
67
68 memset(frame, 0, sizeof(struct roar_error_frame));
69
70 frame->cmd         = -1;
71 frame->ra_errno    = ROAR_ERROR_UNKNOWN;
72 frame->ra_suberrno = -1;
73 frame->p_errno     = -1;
74 frame->datalen     =  0;
75 frame->data        = NULL;
76
77 return 0;
78}
79
80
81void * roar_err_buildmsg(struct roar_message * mes, void ** data, struct roar_error_frame * frame) {
82 char * databuf = NULL;
83 int16_t * d;
84 size_t datalen;
85
86 if ( mes == NULL || frame == NULL ) {
87  roar_err_set(ROAR_ERROR_FAULT);
88  return NULL;
89 }
90
91 if ( data != NULL )
92  *data = NULL;
93
94 datalen = 8 + frame->datalen;
95 if ( datalen > LIBROAR_BUFFER_MSGDATA ) {
96  if ( data == NULL ) {
97   roar_err_set(ROAR_ERROR_FAULT);
98   return NULL;
99  }
100
101  roar_err_clear_errno();
102  *data = roar_mm_malloc(datalen);
103  roar_err_from_errno();
104  if ( *data == NULL )
105   return NULL;
106
107  databuf = *data;
108 } else {
109  databuf = mes->data;
110 }
111
112 memset(mes,  0, sizeof(struct roar_message));
113 memset(databuf, 0, mes->datalen);
114
115 mes->datalen = datalen;
116
117 d = (int16_t*)databuf;
118
119 frame->data  = &(databuf[8]);
120
121 databuf[0]    = 0; // version.
122 databuf[1]    = frame->cmd;
123 databuf[2]    = frame->ra_errno;
124 databuf[3]    = frame->ra_suberrno;
125 d[2]            = ROAR_HOST2NET16(frame->p_errno);
126 d[3]            = ROAR_HOST2NET16(frame->flags);
127
128 return frame->data;
129}
130
131int    roar_err_parsemsg(struct roar_message * mes, void *  data, struct roar_error_frame * frame) {
132 char * databuf = (char *)data;
133 int16_t * d;
134
135 ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?",
136          mes, (int)mes->datalen, mes->data, data, frame);
137
138 if ( mes == NULL || frame == NULL ) {
139  roar_err_set(ROAR_ERROR_FAULT);
140  ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = -1 // error=FAULT",
141           mes, (int)mes->datalen, mes->data, data, frame);
142  return -1;
143 }
144
145 ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?",
146          mes, (int)mes->datalen, mes->data, data, frame);
147
148 if ( databuf == NULL )
149  databuf = mes->data;
150
151 d = (int16_t*)databuf;
152
153 ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?",
154          mes, (int)mes->datalen, mes->data, data, frame);
155
156 if ( mes->datalen < 8 ) {
157  roar_err_set(ROAR_ERROR_MSGSIZE);
158  ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = -1 // error=MSGSIZE",
159           mes, (int)mes->datalen, mes->data, data, frame);
160  return -1;
161 }
162
163 ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?",
164          mes, (int)mes->datalen, mes->data, data, frame);
165
166 if ( databuf[0] != 0 ) {
167  roar_err_set(ROAR_ERROR_NSVERSION);
168  ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = -1 // error=NSVERSION",
169           mes, (int)mes->datalen, mes->data, data, frame);
170  return -1;
171 }
172
173 ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?",
174          mes, (int)mes->datalen, mes->data, data, frame);
175
176 frame->cmd         = databuf[1];
177 frame->ra_errno    = databuf[2];
178 frame->ra_suberrno = databuf[3];
179 frame->p_errno     = ROAR_NET2HOST16(d[2]);
180 frame->flags       = ROAR_NET2HOST16(d[3]);
181
182 frame->datalen     = mes->datalen - 8;
183 frame->data        = &(databuf[8]);
184
185 ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = 0",
186          mes, (int)mes->datalen, mes->data, data, frame);
187 return 0;
188}
189
190#define roar_errno2_impl (&roar_errno)
191int *  roar_errno2(void) {
192 return roar_errno2_impl;
193}
194
195void   roar_err_clear(void) {
196 *roar_errno2_impl = ROAR_ERROR_NONE;
197}
198
199void   roar_err_clear_errno(void) {
200 errno = CLEAN_ERRNO;
201}
202
203void   roar_err_clear_all(void) {
204 roar_err_clear();
205 roar_err_clear_errno();
206}
207
208void   roar_err_update(void) {
209 int * err = roar_errno2_impl;
210
211 // NOTE: _NEVER_ call ROAR_{DBG,INFO,WARN,ERR}() in here! (will result in endless loop)
212 //printf("*err=%i, errno=%i\n", *err, (int)errno);
213
214 if ( *err != ROAR_ERROR_NONE ) {
215  roar_err_to_errno();
216 } else if ( !roar_err_is_errno_clear() ) {
217  roar_err_from_errno();
218#ifdef ROAR_TARGET_WIN32
219 } else {
220  roar_err_convert(err, ROAR_ERROR_TYPE_ROARAUDIO, WSAGetLastError(), ROAR_ERROR_TYPE_WINSOCK);
221  roar_err_to_errno();
222#endif
223 }
224}
225
226int    roar_err_is_errno_clear(void) {
227 return errno == CLEAN_ERRNO ? 1 : 0;
228}
229
230void   roar_err_set(const int error) {
231 *roar_errno2_impl = error;
232}
233
234static int   __errno_to_roar(int error) {
235 int _roar_errno = ROAR_ERROR_NONE;
236
237 switch (error) {
238#ifdef EACCES
239  case EACCES:       _roar_errno = ROAR_ERROR_PERM; break;
240#endif
241#ifdef EPERM
242  case EPERM:        _roar_errno = ROAR_ERROR_PERM; break;
243#endif
244#ifdef ENOENT
245  case ENOENT:       _roar_errno = ROAR_ERROR_NOENT; break;
246#endif
247#ifdef EBADMSG
248  case EBADMSG:      _roar_errno = ROAR_ERROR_BADMSG; break;
249#endif
250#ifdef EBUSY
251  case EBUSY:        _roar_errno = ROAR_ERROR_BUSY; break;
252#endif
253#ifdef ECONNREFUSED
254  case ECONNREFUSED: _roar_errno = ROAR_ERROR_CONNREFUSED; break;
255#endif
256#ifdef ENOSYS
257  case ENOSYS:       _roar_errno = ROAR_ERROR_NOSYS; break;
258#endif
259#ifdef ENOTSUP
260  case ENOTSUP:      _roar_errno = ROAR_ERROR_NOTSUP; break;
261#endif
262#ifdef EPIPE
263  case EPIPE:        _roar_errno = ROAR_ERROR_PIPE; break;
264#endif
265#ifdef EPROTO
266  case EPROTO:       _roar_errno = ROAR_ERROR_PROTO; break;
267#endif
268#ifdef ERANGE
269  case ERANGE:       _roar_errno = ROAR_ERROR_RANGE; break;
270#endif
271#ifdef EMSGSIZE
272  case EMSGSIZE:     _roar_errno = ROAR_ERROR_MSGSIZE; break;
273#endif
274#ifdef ENOMEM
275  case ENOMEM:       _roar_errno = ROAR_ERROR_NOMEM; break;
276#endif
277#ifdef EINVAL
278  case EINVAL:       _roar_errno = ROAR_ERROR_INVAL; break;
279#endif
280#ifdef EALREADY
281  case EALREADY:     _roar_errno = ROAR_ERROR_ALREADY; break;
282#endif
283#ifdef EBADRQC
284  case EBADRQC:      _roar_errno = ROAR_ERROR_BADRQC; break;
285#endif
286#ifdef EDOM
287  case EDOM:         _roar_errno = ROAR_ERROR_DOM; break;
288#endif
289#ifdef EEXIST
290  case EEXIST:       _roar_errno = ROAR_ERROR_EXIST; break;
291#endif
292#ifdef EFAULT
293  case EFAULT:       _roar_errno = ROAR_ERROR_FAULT; break;
294#endif
295#ifdef EIO
296  case EIO:          _roar_errno = ROAR_ERROR_IO; break;
297#endif
298#ifdef EREMOTEIO
299  case EREMOTEIO:    _roar_errno = ROAR_ERROR_RIO; break;
300#endif
301#ifdef EKEYEXPIRED
302  case EKEYEXPIRED:  _roar_errno = ROAR_ERROR_KEYEXPIRED; break;
303#endif
304#ifdef EKEYREJECTED
305  case EKEYREJECTED: _roar_errno = ROAR_ERROR_KEYREJECTED; break;
306#endif
307#ifdef ELOOP
308  case ELOOP:        _roar_errno = ROAR_ERROR_LOOP; break;
309#endif
310#ifdef EMFILE
311  case EMFILE:       _roar_errno = ROAR_ERROR_MFILE; break;
312#endif
313#ifdef ENAMETOOLONG
314  case ENAMETOOLONG: _roar_errno = ROAR_ERROR_NAMETOOLONG; break;
315#endif
316#ifdef ENODATA
317  case ENODATA:      _roar_errno = ROAR_ERROR_NODATA; break;
318#endif
319#ifdef ENODEV
320  case ENODEV:       _roar_errno = ROAR_ERROR_NODEV; break;
321#endif
322#ifdef ENOSPC
323  case ENOSPC:       _roar_errno = ROAR_ERROR_NOSPC; break;
324#endif
325#ifdef ENOTCONN
326  case ENOTCONN:     _roar_errno = ROAR_ERROR_NOTCONN; break;
327#endif
328#ifdef EPROTONOSUPPORT
329  case EPROTONOSUPPORT: _roar_errno = ROAR_ERROR_PROTONOSUP; break;
330#endif
331#ifdef EROFS
332  case EROFS:        _roar_errno = ROAR_ERROR_RO; break;
333#endif
334#ifdef ETIMEDOUT
335  case ETIMEDOUT:    _roar_errno = ROAR_ERROR_TIMEDOUT; break;
336#endif
337#ifdef EAGAIN
338  case EAGAIN:       _roar_errno = ROAR_ERROR_AGAIN; break;
339#endif
340#ifdef ENETDOWN
341  case ENETDOWN:     _roar_errno = ROAR_ERROR_LINKDOWN; break;
342#endif
343#ifdef EINTR
344  case EINTR:        _roar_errno = ROAR_ERROR_INTERRUPTED; break;
345#endif
346#ifdef EDQUOT
347  case EDQUOT:       _roar_errno = ROAR_ERROR_QUOTA; break;
348#endif
349#ifdef ELIBBAD
350  case ELIBBAD:      _roar_errno = ROAR_ERROR_BADLIB; break;
351#endif
352#ifdef ENOMEDIUM
353  case ENOMEDIUM:    _roar_errno = ROAR_ERROR_NOMEDIUM; break;
354#endif
355#ifdef ENOTUNIQ
356  case ENOTUNIQ:     _roar_errno = ROAR_ERROR_NOTUNIQ; break;
357#endif
358#ifdef EILSEQ
359  case EILSEQ:       _roar_errno = ROAR_ERROR_ILLSEQ; break;
360#endif
361#ifdef EADDRINUSE
362  case EADDRINUSE:   _roar_errno = ROAR_ERROR_ADDRINUSE; break;
363#endif
364#ifdef ESPIPE
365  case ESPIPE:       _roar_errno = ROAR_ERROR_BADSEEK; break;
366#endif
367#ifdef ECHERNOBYL
368  case ECHERNOBYL:   _roar_errno = ROAR_ERROR_CHERNOBYL; break;
369#endif
370#ifdef ECRAY
371  case ECRAY:        _roar_errno = ROAR_ERROR_CAUSALITY; break;
372#endif
373#ifdef ENOHORSE
374  case ENOHORSE:     _roar_errno = ROAR_ERROR_NOHORSE; break;
375#endif
376#ifdef ETXTBSY
377  case ETXTBSY:      _roar_errno = ROAR_ERROR_TEXTBUSY; break;
378#endif
379#ifdef ENOTEMPTY
380  case ENOTEMPTY:    _roar_errno = ROAR_ERROR_NOTEMPTY; break;
381#endif
382#ifdef EHOSTUNREACH
383  case EHOSTUNREACH: _roar_errno = ROAR_ERROR_NODEUNREACH; break;
384#endif
385#ifdef EIDRM
386  case EIDRM:        _roar_errno = ROAR_ERROR_IDREMOVED; break;
387#endif
388#ifdef EINPROGRESS
389  case EINPROGRESS:  _roar_errno = ROAR_ERROR_INPROGRESS; break;
390#endif
391#ifdef ECHILD
392  case ECHILD:       _roar_errno = ROAR_ERROR_NOCHILD; break;
393#endif
394#ifdef ENETUNREACH
395  case ENETUNREACH:  _roar_errno = ROAR_ERROR_NETUNREACH; break;
396#endif
397#ifdef ECANCELED
398  case ECANCELED:    _roar_errno = ROAR_ERROR_CANCELED; break;
399#endif
400#ifdef EISDIR
401  case EISDIR:       _roar_errno = ROAR_ERROR_ISDIR; break;
402#endif
403#ifdef ENOTDIR
404  case ENOTDIR:      _roar_errno = ROAR_ERROR_NOTDIR; break;
405#endif
406#ifdef ENOEXEC
407  case ENOEXEC:      _roar_errno = ROAR_ERROR_BADEXEC; break;
408#endif
409#ifdef EISCONN
410  case EISCONN:      _roar_errno = ROAR_ERROR_ISCONN; break;
411#endif
412#ifdef EDEADLK
413  case EDEADLK:      _roar_errno = ROAR_ERROR_DEADLOCK; break;
414#endif
415#ifdef ECONNRESET
416  case ECONNRESET:   _roar_errno = ROAR_ERROR_CONNRST; break;
417#endif
418#ifdef EBADF
419  case EBADF:        _roar_errno = ROAR_ERROR_BADFH; break;
420#endif
421#ifdef ENOTSOCK
422  case ENOTSOCK:     _roar_errno = ROAR_ERROR_NOTSOCK; break;
423#endif
424#ifdef E2BIG
425  case E2BIG:        _roar_errno = ROAR_ERROR_TOOMANYARGS; break;
426#endif
427#ifdef EFBIG
428  case EFBIG:        _roar_errno = ROAR_ERROR_TOOLARGE; break;
429#endif
430#ifdef EDESTADDRREQ
431  case EDESTADDRREQ: _roar_errno = ROAR_ERROR_DESTADDRREQ; break;
432#endif
433#ifdef EAFNOSUPPORT
434  case EAFNOSUPPORT: _roar_errno = ROAR_ERROR_AFNOTSUP; break;
435#endif
436#ifdef ENFILE
437  case ENFILE:       _roar_errno = ROAR_ERROR_NFILE; break;
438#endif
439#ifdef ESTALE
440  case ESTALE:       _roar_errno = ROAR_ERROR_STALE; break;
441#endif
442#ifdef EXDEV
443  case EXDEV:        _roar_errno = ROAR_ERROR_XDEVLINK; break;
444#endif
445#ifdef EMLINK
446  case EMLINK:       _roar_errno = ROAR_ERROR_MLINK; break;
447#endif
448#ifdef ENONET
449  case ENONET:       _roar_errno = ROAR_ERROR_NONET; break;
450#endif
451#ifdef ENETRESET
452  case ENETRESET:    _roar_errno = ROAR_ERROR_CONNRSTNET; break;
453#endif
454#ifdef ECONNABORTED
455  case ECONNABORTED: _roar_errno = ROAR_ERROR_CONNABORTED; break;
456#endif
457#ifdef EBADFD
458  case EBADFD: _roar_errno = ROAR_ERROR_BADSTATE; break;
459#endif
460  default:
461    _roar_errno = ROAR_ERROR_UNKNOWN;
462   break;
463 }
464
465 return _roar_errno;
466}
467
468void   roar_err_from_errno(void) {
469 roar_err_set(__errno_to_roar(errno));
470}
471
472static int   __roar_to_errno(int error) {
473 switch (error) {
474  case ROAR_ERROR_NONE:
475    return CLEAN_ERRNO;
476   break;
477#ifdef EPERM
478  case ROAR_ERROR_PERM:
479    return EPERM;
480   break;
481#endif
482#ifdef ENOENT
483  case ROAR_ERROR_NOENT:
484    return ENOENT;
485   break;
486#endif
487#ifdef EBADMSG
488  case ROAR_ERROR_BADMSG:
489    return EBADMSG;
490   break;
491#endif
492#ifdef EBUSY
493  case ROAR_ERROR_BUSY:
494    return EBUSY;
495   break;
496#endif
497#ifdef ECONNREFUSED
498  case ROAR_ERROR_CONNREFUSED:
499    return ECONNREFUSED;
500   break;
501#endif
502#ifdef ENOSYS
503  case ROAR_ERROR_NOSYS:
504    return ENOSYS;
505   break;
506#endif
507#ifdef ENOTSUP
508  case ROAR_ERROR_NOTSUP:
509    return ENOTSUP;
510   break;
511#endif
512#ifdef EPIPE
513  case ROAR_ERROR_PIPE:
514    return EPIPE;
515   break;
516#endif
517#ifdef EPROTO
518  case ROAR_ERROR_PROTO:
519    return EPROTO;
520   break;
521#endif
522#ifdef ERANGE
523  case ROAR_ERROR_RANGE:
524    return ERANGE;
525   break;
526#endif
527#ifdef EMSGSIZE
528  case ROAR_ERROR_MSGSIZE:
529    return EMSGSIZE;
530   break;
531#endif
532#ifdef ENOMEM
533  case ROAR_ERROR_NOMEM:
534    return ENOMEM;
535   break;
536#endif
537#ifdef EINVAL
538  case ROAR_ERROR_INVAL:
539    return EINVAL;
540   break;
541#endif
542#ifdef EALREADY
543  case ROAR_ERROR_ALREADY:
544    return EALREADY;
545   break;
546#endif
547#ifdef EBADRQC
548  case ROAR_ERROR_BADRQC:
549    return EBADRQC;
550   break;
551#endif
552#ifdef EDOM
553  case ROAR_ERROR_DOM:
554    return EDOM;
555   break;
556#endif
557#ifdef EEXIST
558  case ROAR_ERROR_EXIST:
559    return EEXIST;
560   break;
561#endif
562#ifdef EFAULT
563  case ROAR_ERROR_FAULT:
564    return EFAULT;
565   break;
566#endif
567#if defined(EREMOTEIO) || defined(EIO)
568  case ROAR_ERROR_RIO:
569#ifdef EREMOTEIO
570    return EREMOTEIO;
571#else
572    return EIO;
573#endif
574   break;
575#endif
576#ifdef EIO
577  case ROAR_ERROR_IO:
578  case ROAR_ERROR_HOLE:
579  case ROAR_ERROR_BADCKSUM:
580  case ROAR_ERROR_LOSTSYNC:
581  case ROAR_ERROR_NOHORSE:
582    return EIO;
583   break;
584#endif
585#ifdef EKEYEXPIRED
586  case ROAR_ERROR_KEYEXPIRED:
587    return EKEYEXPIRED;
588   break;
589#endif
590#ifdef EKEYREJECTED
591  case ROAR_ERROR_KEYREJECTED:
592    return EKEYREJECTED;
593   break;
594#endif
595#ifdef ELOOP
596  case ROAR_ERROR_LOOP:
597    return ELOOP;
598   break;
599#endif
600#ifdef EMFILE
601  case ROAR_ERROR_MFILE:
602    return EMFILE;
603   break;
604#endif
605#ifdef ENAMETOOLONG
606  case ROAR_ERROR_NAMETOOLONG:
607    return ENAMETOOLONG;
608   break;
609#endif
610#ifdef ENODATA
611  case ROAR_ERROR_NODATA:
612    return ENODATA;
613   break;
614#endif
615#ifdef ENODEV
616  case ROAR_ERROR_NODEV:
617  case ROAR_ERROR_NODRV:
618    return ENODEV;
619   break;
620#endif
621#ifdef ENOSPC
622  case ROAR_ERROR_NOSPC:
623    return ENOSPC;
624   break;
625#endif
626#ifdef EINVAL
627  case ROAR_ERROR_TYPEMM:
628    return EINVAL;
629   break;
630#endif
631#ifdef ENOSYS
632  case ROAR_ERROR_NORSYS:
633    return ENOSYS;
634   break;
635#endif
636#ifdef ENOTCONN
637  case ROAR_ERROR_NOTCONN:
638    return ENOTCONN;
639   break;
640#endif
641#ifdef EPROTONOSUPPORT
642  case ROAR_ERROR_PROTONOSUP:
643    return EPROTONOSUPPORT;
644   break;
645#endif
646#ifdef EROFS
647  case ROAR_ERROR_RO:
648    return EROFS;
649   break;
650#endif
651#ifdef ETIMEDOUT
652  case ROAR_ERROR_TIMEDOUT:
653    return ETIMEDOUT;
654   break;
655#endif
656#ifdef EAGAIN
657  case ROAR_ERROR_AGAIN:
658    return EAGAIN;
659   break;
660#endif
661#ifdef ENETDOWN
662  case ROAR_ERROR_LINKDOWN:
663    return ENETDOWN;
664   break;
665#endif
666#ifdef EINTR
667  case ROAR_ERROR_INTERRUPTED:
668    return EINTR;
669   break;
670#endif
671#ifdef EDQUOT
672  case ROAR_ERROR_QUOTA:
673    return EDQUOT;
674   break;
675#endif
676#ifdef ELIBBAD
677  case ROAR_ERROR_BADLIB:
678    return ELIBBAD;
679   break;
680#endif
681#ifdef ENOMEDIUM
682  case ROAR_ERROR_NOMEDIUM:
683    return ENOMEDIUM;
684   break;
685#endif
686#ifdef ENOTUNIQ
687  case ROAR_ERROR_NOTUNIQ:
688    return ENOTUNIQ;
689   break;
690#endif
691#ifdef EILSEQ
692  case ROAR_ERROR_ILLSEQ:
693    return EILSEQ;
694   break;
695#endif
696#ifdef EADDRINUSE
697  case ROAR_ERROR_ADDRINUSE:
698    return EADDRINUSE;
699   break;
700#endif
701#ifdef ESPIPE
702  case ROAR_ERROR_BADSEEK:
703  case ROAR_ERROR_NOSEEK:
704    return ESPIPE;
705   break;
706#endif
707#ifdef ECHERNOBYL
708  case ROAR_ERROR_CHERNOBYL:
709    return ECHERNOBYL;
710   break;
711#endif
712#ifdef ECRAY
713  case ROAR_ERROR_CAUSALITY:
714    return ECRAY;
715   break;
716#endif
717#ifdef ENOHORSE
718  case ROAR_ERROR_NOHORSE:
719    return ENOHORSE;
720   break;
721#endif
722#ifdef ETXTBSY
723  case ROAR_ERROR_TEXTBUSY:
724    return ETXTBSY;
725   break;
726#endif
727#ifdef ENOTEMPTY
728  case ROAR_ERROR_NOTEMPTY:
729    return ENOTEMPTY;
730   break;
731#endif
732#ifdef EHOSTUNREACH
733  case ROAR_ERROR_NODEUNREACH:
734    return EHOSTUNREACH;
735   break;
736#endif
737#ifdef EIDRM
738  case ROAR_ERROR_IDREMOVED:
739    return EIDRM;
740   break;
741#endif
742#ifdef EINPROGRESS
743  case ROAR_ERROR_INPROGRESS:
744    return EINPROGRESS;
745   break;
746#endif
747#ifdef ECHILD
748  case ROAR_ERROR_NOCHILD:
749    return ECHILD;
750   break;
751#endif
752#ifdef ENETUNREACH
753  case ROAR_ERROR_NETUNREACH:
754    return ENETUNREACH;
755   break;
756#endif
757#ifdef ECANCELED
758  case ROAR_ERROR_CANCELED:
759    return ECANCELED;
760   break;
761#endif
762#ifdef EISDIR
763  case ROAR_ERROR_ISDIR:
764    return EISDIR;
765   break;
766#endif
767#ifdef ENOTDOR
768  case ROAR_ERROR_NOTDIR:
769    return ENOTDIR;
770   break;
771#endif
772#ifdef ENOEXEC
773  case ROAR_ERROR_BADEXEC:
774    return ENOEXEC;
775   break;
776#endif
777#ifdef EISCONN
778  case ROAR_ERROR_ISCONN:
779    return EISCONN;
780   break;
781#endif
782#ifdef EDEADLK
783  case ROAR_ERROR_DEADLOCK:
784    return EDEADLK;
785   break;
786#endif
787#ifdef ECONNRESET
788  case ROAR_ERROR_CONNRST:
789    return ECONNRESET;
790   break;
791#endif
792#ifdef EBADF
793  case ROAR_ERROR_BADFH:
794    return EBADF;
795   break;
796#endif
797#ifdef ENOTSOCK
798  case ROAR_ERROR_NOTSOCK:
799    return ENOTSOCK;
800   break;
801#endif
802#ifdef E2BIG
803  case ROAR_ERROR_TOOMANYARGS:
804    return E2BIG;
805   break;
806#endif
807#ifdef EFBIG
808  case ROAR_ERROR_TOOLARGE:
809    return EFBIG;
810   break;
811#endif
812#ifdef EDESTADDRREQ
813  case ROAR_ERROR_DESTADDRREQ:
814    return EDESTADDRREQ;
815   break;
816#endif
817#ifdef EAFNOSUPPORT
818  case ROAR_ERROR_AFNOTSUP:
819    return EAFNOSUPPORT;
820   break;
821#endif
822// FIXME....
823#ifdef ENOPOWER
824  case ROAR_ERROR_NOPOWER:
825    return ENOPOWER;
826   break;
827#endif
828#ifdef EUSER
829  case ROAR_ERROR_USER:
830    return EUSER;
831   break;
832#endif
833
834#ifdef ENFILE
835  case ROAR_ERROR_NFILE:
836    return ENFILE;
837   break;
838#endif
839#ifdef ESTALE
840  case ROAR_ERROR_STALE:
841    return ESTALE;
842   break;
843#endif
844#ifdef EXDEV
845  case ROAR_ERROR_XDEVLINK:
846    return EXDEV;
847   break;
848#endif
849#ifdef EMLINK
850  case ROAR_ERROR_MLINK:
851    return EMLINK;
852   break;
853#endif
854#ifdef ENONET
855  case ROAR_ERROR_NONET:
856    return ENONET;
857   break;
858#endif
859#ifdef ENETRESET
860  case ROAR_ERROR_CONNRSTNET:
861    return ENETRESET;
862   break;
863#endif
864#ifdef ECONNABORTED
865  case ROAR_ERROR_CONNABORTED:
866    return ECONNABORTED;
867   break;
868#endif
869#ifdef EBADFD
870  case ROAR_ERROR_BADSTATE:
871    return EBADFD;
872   break;
873#endif
874
875  default:
876#ifdef EINVAL
877    return EINVAL;
878#else
879    return -1; // just guess
880#endif
881   break;
882 }
883}
884
885void   roar_err_to_errno(void) {
886 errno = __roar_to_errno(roar_error);
887}
888
889static const struct error_table_entry {
890 const enum roar_error_type type;
891 const int error;
892 const int roarerror;
893} __libroar_error_table[] = {
894 {ROAR_ERROR_TYPE_HTTP, 200, ROAR_ERROR_NONE},
895 {ROAR_ERROR_TYPE_HTTP, 301, ROAR_ERROR_MOVEDPERM},
896 {ROAR_ERROR_TYPE_HTTP, 303, ROAR_ERROR_SEEOTHER},
897 {ROAR_ERROR_TYPE_HTTP, 305, ROAR_ERROR_USEPROXY},
898 {ROAR_ERROR_TYPE_HTTP, 307, ROAR_ERROR_MOVEDTEMP},
899 {ROAR_ERROR_TYPE_HTTP, 400, ROAR_ERROR_INVAL},
900 {ROAR_ERROR_TYPE_HTTP, 402, ROAR_ERROR_NEEDPAYMENT},
901 {ROAR_ERROR_TYPE_HTTP, 403, ROAR_ERROR_PERM},
902 {ROAR_ERROR_TYPE_HTTP, 404, ROAR_ERROR_NOENT},
903 {ROAR_ERROR_TYPE_HTTP, 408, ROAR_ERROR_TIMEDOUT},
904 {ROAR_ERROR_TYPE_HTTP, 410, ROAR_ERROR_GONE},
905 {ROAR_ERROR_TYPE_HTTP, 415, ROAR_ERROR_NSTYPE},
906 {ROAR_ERROR_TYPE_HTTP, 423, ROAR_ERROR_BUSY},
907 {ROAR_ERROR_TYPE_HTTP, 426, ROAR_ERROR_SWITCHPROTO},
908 {ROAR_ERROR_TYPE_HTTP, 501, ROAR_ERROR_NOSYS},
909 {ROAR_ERROR_TYPE_HTTP, 504, ROAR_ERROR_TIMEDOUT},
910 {ROAR_ERROR_TYPE_HTTP, 505, ROAR_ERROR_NSVERSION},
911 {ROAR_ERROR_TYPE_HTTP, 507, ROAR_ERROR_NOSPC},
912 {ROAR_ERROR_TYPE_HTTP, 451, ROAR_ERROR_CENSORED},
913 {ROAR_ERROR_TYPE_HTTP, 450, ROAR_ERROR_CENSORED},
914#ifdef NETDB_SUCCESS
915 {ROAR_ERROR_TYPE_HERROR, NETDB_SUCCESS, ROAR_ERROR_NONE},
916#endif
917#ifdef HOST_NOT_FOUND
918 {ROAR_ERROR_TYPE_HERROR, HOST_NOT_FOUND, ROAR_ERROR_NOENT},
919#endif
920#ifdef TRY_AGAIN
921 {ROAR_ERROR_TYPE_HERROR, TRY_AGAIN, ROAR_ERROR_AGAIN},
922#endif
923#ifdef NO_RECOVERY
924// {ROAR_ERROR_TYPE_HERROR, NO_RECOVERY, ROAR_ERROR_???},
925#endif
926#ifdef NO_DATA
927 {ROAR_ERROR_TYPE_HERROR, NO_DATA, ROAR_ERROR_NODATA},
928#endif
929#ifdef NO_ADDRESS
930 {ROAR_ERROR_TYPE_HERROR, NO_ADDRESS, ROAR_ERROR_NOENT},
931#endif
932#ifdef ROAR_TARGET_WIN32
933 {ROAR_ERROR_TYPE_WINSOCK, WSA_INVALID_HANDLE, ROAR_ERROR_BADFH},
934 {ROAR_ERROR_TYPE_WINSOCK, WSA_NOT_ENOUGH_MEMORY, ROAR_ERROR_NOMEM},
935 {ROAR_ERROR_TYPE_WINSOCK, WSA_INVALID_PARAMETER, ROAR_ERROR_INVAL},
936 {ROAR_ERROR_TYPE_WINSOCK, WSA_OPERATION_ABORTED, ROAR_ERROR_INTERRUPTED},
937// {ROAR_ERROR_TYPE_WINSOCK, WSA_IO_INCOMPLETE, ROAR_ERROR_???},
938// {ROAR_ERROR_TYPE_WINSOCK, WSA_IO_PENDING, ROAR_ERROR_???},
939 {ROAR_ERROR_TYPE_WINSOCK, WSAEINTR, ROAR_ERROR_INTERRUPTED},
940 {ROAR_ERROR_TYPE_WINSOCK, WSAEBADF, ROAR_ERROR_BADFH},
941 {ROAR_ERROR_TYPE_WINSOCK, WSAEACCES, ROAR_ERROR_PERM},
942 {ROAR_ERROR_TYPE_WINSOCK, WSAEFAULT, ROAR_ERROR_FAULT},
943 {ROAR_ERROR_TYPE_WINSOCK, WSAEINVAL, ROAR_ERROR_INVAL},
944 {ROAR_ERROR_TYPE_WINSOCK, WSAEMFILE, ROAR_ERROR_MFILE},
945 {ROAR_ERROR_TYPE_WINSOCK, WSAEWOULDBLOCK, ROAR_ERROR_AGAIN},
946 {ROAR_ERROR_TYPE_WINSOCK, WSAEINPROGRESS, ROAR_ERROR_INPROGRESS},
947 {ROAR_ERROR_TYPE_WINSOCK, WSAEALREADY, ROAR_ERROR_ALREADY},
948 {ROAR_ERROR_TYPE_WINSOCK, WSAENOTSOCK, ROAR_ERROR_NOTSOCK},
949 {ROAR_ERROR_TYPE_WINSOCK, WSAEDESTADDRREQ, ROAR_ERROR_DESTADDRREQ},
950 {ROAR_ERROR_TYPE_WINSOCK, WSAEMSGSIZE, ROAR_ERROR_MSGSIZE},
951// {ROAR_ERROR_TYPE_WINSOCK, WSAEPROTOTYPE, ROAR_ERROR_???},
952// {ROAR_ERROR_TYPE_WINSOCK, WSAENOPROTOOPT, ROAR_ERROR_???},
953 {ROAR_ERROR_TYPE_WINSOCK, WSAEPROTONOSUPPORT, ROAR_ERROR_PROTONOSUP},
954 {ROAR_ERROR_TYPE_WINSOCK, WSAESOCKTNOSUPPORT, ROAR_ERROR_PROTONOSUP},
955 {ROAR_ERROR_TYPE_WINSOCK, WSAEOPNOTSUPP, ROAR_ERROR_NOTSUP},
956 {ROAR_ERROR_TYPE_WINSOCK, WSAEPFNOSUPPORT, ROAR_ERROR_AFNOTSUP},
957 {ROAR_ERROR_TYPE_WINSOCK, WSAEAFNOSUPPORT, ROAR_ERROR_AFNOTSUP},
958 {ROAR_ERROR_TYPE_WINSOCK, WSAEADDRINUSE, ROAR_ERROR_ADDRINUSE},
959// {ROAR_ERROR_TYPE_WINSOCK, WSAEADDRNOTAVAIL, ROAR_ERROR_???},
960// {ROAR_ERROR_TYPE_WINSOCK, WSAENETDOWN, ROAR_ERROR_???},
961 {ROAR_ERROR_TYPE_WINSOCK, WSAENETUNREACH, ROAR_ERROR_NETUNREACH},
962// {ROAR_ERROR_TYPE_WINSOCK, WSAENETRESET, ROAR_ERROR_???},
963// {ROAR_ERROR_TYPE_WINSOCK, WSAECONNABORTED, ROAR_ERROR_???},
964// {ROAR_ERROR_TYPE_WINSOCK, WSAECONNRESET, ROAR_ERROR_???},
965// {ROAR_ERROR_TYPE_WINSOCK, WSAENOBUFS, ROAR_ERROR_???},
966 {ROAR_ERROR_TYPE_WINSOCK, WSAEISCONN, ROAR_ERROR_ISCONN},
967 {ROAR_ERROR_TYPE_WINSOCK, WSAENOTCONN, ROAR_ERROR_NOTCONN},
968// {ROAR_ERROR_TYPE_WINSOCK, WSAESHUTDOWN, ROAR_ERROR_???},
969// {ROAR_ERROR_TYPE_WINSOCK, WSAETOOMANYREFS, ROAR_ERROR_???},
970 {ROAR_ERROR_TYPE_WINSOCK, WSAETIMEDOUT, ROAR_ERROR_TIMEDOUT},
971 {ROAR_ERROR_TYPE_WINSOCK, WSAECONNREFUSED, ROAR_ERROR_CONNREFUSED},
972 {ROAR_ERROR_TYPE_WINSOCK, WSAELOOP, ROAR_ERROR_LOOP},
973 {ROAR_ERROR_TYPE_WINSOCK, WSAENAMETOOLONG, ROAR_ERROR_NAMETOOLONG},
974// {ROAR_ERROR_TYPE_WINSOCK, WSAEHOSTDOWN, ROAR_ERROR_???},
975 {ROAR_ERROR_TYPE_WINSOCK, WSAEHOSTUNREACH, ROAR_ERROR_NODEUNREACH},
976 {ROAR_ERROR_TYPE_WINSOCK, WSAENOTEMPTY, ROAR_ERROR_NOTEMPTY},
977// {ROAR_ERROR_TYPE_WINSOCK, WSAEPROCLIM, ROAR_ERROR_???},
978// {ROAR_ERROR_TYPE_WINSOCK, WSAEUSERS, ROAR_ERROR_???},
979// {ROAR_ERROR_TYPE_WINSOCK, WSAEDQUOT, ROAR_ERROR_???},
980 {ROAR_ERROR_TYPE_WINSOCK, WSAESTALE, ROAR_ERROR_STALE},
981// {ROAR_ERROR_TYPE_WINSOCK, WSAEREMOTE, ROAR_ERROR_???},
982// {ROAR_ERROR_TYPE_WINSOCK, WSASYSNOTREADY, ROAR_ERROR_???},
983 {ROAR_ERROR_TYPE_WINSOCK, WSAVERNOTSUPPORTED, ROAR_ERROR_NSVERSION},
984// {ROAR_ERROR_TYPE_WINSOCK, WSANOTINITIALISED, ROAR_ERROR_???},
985// {ROAR_ERROR_TYPE_WINSOCK, WSAEDISCON, ROAR_ERROR_???},
986// {ROAR_ERROR_TYPE_WINSOCK, WSAENOMORE, ROAR_ERROR_???},
987// {ROAR_ERROR_TYPE_WINSOCK, WSAECANCELLED, ROAR_ERROR_???},
988// {ROAR_ERROR_TYPE_WINSOCK, WSAEINVALIDPROCTABLE, ROAR_ERROR_???},
989// {ROAR_ERROR_TYPE_WINSOCK, WSAEINVALIDPROVIDER, ROAR_ERROR_???},
990// {ROAR_ERROR_TYPE_WINSOCK, WSAEPROVIDERFAILEDINIT, ROAR_ERROR_???},
991// {ROAR_ERROR_TYPE_WINSOCK, WSASYSCALLFAILURE, ROAR_ERROR_???},
992 {ROAR_ERROR_TYPE_WINSOCK, WSASERVICE_NOT_FOUND, ROAR_ERROR_NOENT},
993 {ROAR_ERROR_TYPE_WINSOCK, WSATYPE_NOT_FOUND, ROAR_ERROR_NOENT},
994 {ROAR_ERROR_TYPE_WINSOCK, WSA_E_NO_MORE, ROAR_ERROR_NOENT},
995// {ROAR_ERROR_TYPE_WINSOCK, WSA_E_CANCELLED, ROAR_ERROR_???},
996// {ROAR_ERROR_TYPE_WINSOCK, WSAEREFUSED, ROAR_ERROR_???},
997 {ROAR_ERROR_TYPE_WINSOCK, WSAHOST_NOT_FOUND, ROAR_ERROR_NOENT},
998 {ROAR_ERROR_TYPE_WINSOCK, WSATRY_AGAIN, ROAR_ERROR_AGAIN},
999// {ROAR_ERROR_TYPE_WINSOCK, WSANO_RECOVERY, ROAR_ERROR_???},
1000 {ROAR_ERROR_TYPE_WINSOCK, WSANO_DATA, ROAR_ERROR_NODATA},
1001#if 0
1002 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_RECEIVERS, ROAR_ERROR_???},
1003 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_SENDERS, ROAR_ERROR_???},
1004 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_NO_SENDERS, ROAR_ERROR_???},
1005 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_NO_RECEIVERS, ROAR_ERROR_???},
1006 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_REQUEST_CONFIRMED, ROAR_ERROR_???},
1007 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ADMISSION_FAILURE, ROAR_ERROR_???},
1008 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_POLICY_FAILURE, ROAR_ERROR_???},
1009 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_BAD_STYLE, ROAR_ERROR_???},
1010 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_BAD_OBJECT, ROAR_ERROR_???},
1011 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_TRAFFIC_CTRL_ERROR, ROAR_ERROR_???},
1012 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_GENERIC_ERROR, ROAR_ERROR_???},
1013 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESERVICETYPE, ROAR_ERROR_???},
1014 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWSPEC, ROAR_ERROR_???},
1015 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPROVSPECBUF, ROAR_ERROR_???},
1016 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERSTYLE, ROAR_ERROR_???},
1017 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERTYPE, ROAR_ERROR_???},
1018 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERCOUNT, ROAR_ERROR_???},
1019 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EOBJLENGTH, ROAR_ERROR_???},
1020 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWCOUNT, ROAR_ERROR_???},
1021 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EUNKOWNPSOBJ, ROAR_ERROR_???},
1022 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPOLICYOBJ, ROAR_ERROR_???},
1023 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWDESC, ROAR_ERROR_???},
1024 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPSFLOWSPEC, ROAR_ERROR_???},
1025 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPSFILTERSPEC, ROAR_ERROR_???},
1026 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESDMODEOBJ, ROAR_ERROR_???},
1027 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESHAPERATEOBJ, ROAR_ERROR_???},
1028 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_RESERVED_PETYPE, ROAR_ERROR_???},
1029#endif
1030#endif
1031 {ROAR_ERROR_TYPE_EAI, 0 /* defined value, see manpage */, ROAR_ERROR_NONE},
1032#ifdef EAI_ADDRFAMILY
1033 {ROAR_ERROR_TYPE_EAI, EAI_ADDRFAMILY, ROAR_ERROR_NOENT},
1034#endif
1035#ifdef EAI_AGAIN
1036 {ROAR_ERROR_TYPE_EAI, EAI_AGAIN, ROAR_ERROR_AGAIN},
1037#endif
1038#ifdef EAI_BADFLAGS
1039 {ROAR_ERROR_TYPE_EAI, EAI_BADFLAGS, ROAR_ERROR_INVAL},
1040#endif
1041#ifdef EAI_FAIL
1042 {ROAR_ERROR_TYPE_EAI, EAI_FAIL, ROAR_ERROR_RIO},
1043#endif
1044#ifdef EAI_FAMILY
1045 {ROAR_ERROR_TYPE_EAI, EAI_FAMILY, ROAR_ERROR_AFNOTSUP},
1046#endif
1047#ifdef EAI_MEMORY
1048 {ROAR_ERROR_TYPE_EAI, EAI_MEMORY, ROAR_ERROR_NOMEM},
1049#endif
1050#ifdef EAI_NODATA
1051 {ROAR_ERROR_TYPE_EAI, EAI_NODATA, ROAR_ERROR_NODATA},
1052#endif
1053#ifdef EAI_NONAME
1054 {ROAR_ERROR_TYPE_EAI, EAI_NONAME, ROAR_ERROR_NOENT},
1055#endif
1056#ifdef EAI_SERVICE
1057 {ROAR_ERROR_TYPE_EAI, EAI_SERVICE, ROAR_ERROR_PROTONOSUP},
1058#endif
1059#ifdef EAI_SOCKTYPE
1060 {ROAR_ERROR_TYPE_EAI, EAI_SOCKTYPE, ROAR_ERROR_INVAL},
1061#endif
1062#ifdef EAI_SYSTEM
1063// {ROAR_ERROR_TYPE_EAI, EAI_SYSTEM, ROAR_ERROR_???},
1064#endif
1065};
1066
1067static int roar_err_convert_table_lookup(const struct error_table_entry ** match,
1068                                         const int error,
1069                                         const enum roar_error_type type,
1070                                         const int to_roar) {
1071 size_t i;
1072
1073 // we have the following loop to times as an inner if() would cost more cycles
1074 // than the outer if we currently have.
1075
1076 if ( to_roar ) {
1077  for (i = 0; i < (sizeof(__libroar_error_table)/sizeof(*__libroar_error_table)); i++) {
1078   if ( __libroar_error_table[i].type == type && __libroar_error_table[i].error == error) {
1079    *match = &(__libroar_error_table[i]);
1080    return ROAR_ERROR_NONE;
1081   }
1082  }
1083 } else {
1084  for (i = 0; i < (sizeof(__libroar_error_table)/sizeof(*__libroar_error_table)); i++) {
1085   if ( __libroar_error_table[i].type == type && __libroar_error_table[i].roarerror == error) {
1086    *match = &(__libroar_error_table[i]);
1087    return ROAR_ERROR_NONE;
1088   }
1089  }
1090 }
1091
1092 return ROAR_ERROR_NOENT;
1093}
1094
1095// Convert error codes between diffrent representations.
1096// returnes the error or ROAR_ERROR_NONE on success so it does not alter global error state.
1097int    roar_err_convert(int * out, const enum roar_error_type outtype, const int in, const enum roar_error_type intype) {
1098 const struct error_table_entry * tablematch;
1099 int tmp;
1100 int ret;
1101
1102 if ( out == NULL )
1103  return ROAR_ERROR_FAULT;
1104
1105 if ( outtype == intype ) {
1106  *out = in;
1107  return ROAR_ERROR_NONE;
1108 }
1109
1110 // if not to/from roar, use roar as temp type so we do only need to code two kinds of translators (not any->any).
1111 if ( intype != ROAR_ERROR_TYPE_ROARAUDIO && outtype != ROAR_ERROR_TYPE_ROARAUDIO ) {
1112  ret = roar_err_convert(&tmp, ROAR_ERROR_TYPE_ROARAUDIO, in, intype);
1113  if ( ret != ROAR_ERROR_NONE )
1114   return ret;
1115
1116  return roar_err_convert(out, outtype, tmp, ROAR_ERROR_TYPE_ROARAUDIO);
1117 }
1118
1119 // from here we can asume that if intype != ROAR_ERROR_TYPE_ROARAUDIO outtype is ROAR_ERROR_TYPE_ROARAUDIO
1120 // and the other way around.
1121
1122 if ( intype == ROAR_ERROR_TYPE_ROARAUDIO ) {
1123  ret = roar_err_convert_table_lookup(&tablematch, in, outtype, 0);
1124 } else {
1125  ret = roar_err_convert_table_lookup(&tablematch, in, intype, 1);
1126 }
1127
1128 if ( ret == ROAR_ERROR_NONE ) {
1129  *out = intype == ROAR_ERROR_TYPE_ROARAUDIO ? tablematch->error : tablematch->roarerror;
1130  return ROAR_ERROR_NONE;
1131 }
1132
1133 if ( intype == ROAR_ERROR_TYPE_ROARAUDIO && outtype == ROAR_ERROR_TYPE_ERRNO ) {
1134  // the __roar_to_errno() function always succeeds.
1135  *out = __roar_to_errno(in);
1136  return ROAR_ERROR_NONE;
1137 }
1138
1139 if ( outtype == ROAR_ERROR_TYPE_ROARAUDIO && intype == ROAR_ERROR_TYPE_ERRNO ) {
1140  // the __errno_to_roar() function always succeeds.
1141  *out = __errno_to_roar(in);
1142  return ROAR_ERROR_NONE;
1143 }
1144
1145 roar_err_get_default_error(out, outtype);
1146 return ROAR_ERROR_NOENT;
1147}
1148
1149// Outputs a default error for the given type.
1150// returnes the error or ROAR_ERROR_NONE on success so it does not alter global error state.
1151int    roar_err_get_default_error(int * out, const enum roar_error_type type) {
1152 int is_set = 0;
1153
1154 if ( out == NULL )
1155  return ROAR_ERROR_FAULT;
1156
1157 switch (type) {
1158  case ROAR_ERROR_TYPE_ROARAUDIO: is_set = 1; *out = ROAR_ERROR_UNKNOWN; break;
1159#ifdef EINVAL
1160  case ROAR_ERROR_TYPE_ERRNO: is_set = 1; *out = EINVAL; break;
1161#endif
1162#ifdef NO_RECOVERY
1163  case ROAR_ERROR_TYPE_HERROR: is_set = 1; *out = NO_RECOVERY; break;
1164#endif
1165#ifdef __YIFF__
1166  case ROAR_ERROR_TYPE_YIFF: is_set = 1; *out = YIFF_ERRNO_UNKNOWN; break;
1167#endif
1168  case ROAR_ERROR_TYPE_HTTP: is_set = 1; *out = 500; break;
1169#ifndef DEBUG
1170  // enable compiler warnings in DEBUG mode.
1171  default:
1172   break;
1173#endif
1174 }
1175
1176 if ( is_set ) {
1177  return ROAR_ERROR_NONE;
1178 }
1179
1180 *out = -1; // some default so we do not leave it uninited.
1181 return ROAR_ERROR_NOENT;
1182}
1183
1184// Resets the stored state to 'no error' state. This can be used
1185// to init the state.
1186int    roar_err_initstore(struct roar_error_state * state) {
1187 struct roar_error_state curstate;
1188
1189 if ( state == NULL ) {
1190  roar_err_set(ROAR_ERROR_FAULT);
1191  return -1;
1192 }
1193
1194 roar_err_store(&curstate);
1195 roar_err_clear_all();
1196 roar_err_store(state);
1197 roar_err_restore(&curstate);
1198
1199 return -1;
1200}
1201
1202// store a error state (both libroar and system)
1203int    roar_err_store(struct roar_error_state * state) {
1204 if ( state == NULL )
1205  return ROAR_ERROR_FAULT;
1206
1207 memset(state, 0, sizeof(struct roar_error_state));
1208
1209 state->refc          = 0;
1210 state->libroar_error = roar_error;
1211 state->system_error  = errno;
1212
1213#ifdef ROAR_TARGET_WIN32
1214 state->winsock_error = WSAGetLastError();
1215#endif
1216#ifdef ROAR_HAVE_VAR_H_ERRNO
1217 state->syssock_herror = h_errno;
1218#endif
1219
1220#ifdef __YIFF__
1221 state->yiffc_error = yiffc_error;
1222#endif
1223
1224 return ROAR_ERROR_NONE;
1225}
1226
1227// restore error state to values at time of call to roar_err_store()
1228int    roar_err_restore(struct roar_error_state * state) {
1229 if ( state == NULL )
1230  return ROAR_ERROR_FAULT;
1231
1232 roar_err_set(state->libroar_error);
1233 errno = state->system_error;
1234
1235#ifdef ROAR_TARGET_WIN32
1236 WSASetLastError(state->winsock_error);
1237#endif
1238#ifdef ROAR_HAVE_VAR_H_ERRNO
1239 h_errno = state->syssock_herror;
1240#endif
1241
1242#ifdef __YIFF__
1243 yiffc_error = state->yiffc_error;
1244#endif
1245
1246 return ROAR_ERROR_NONE;
1247}
1248
1249
1250// phi@ph7:roaraudio $ grep '^#define ROAR_ERROR_' error.h  | tr -d /\* | while read d c d t; do printf "  {%-23s \"%s\"},\n" $c, "$t"; done
1251
1252static const char * roar_error2str_ms(const int error, const char * msg) {
1253 static char buf[1024] = "";
1254 int num[8];
1255 size_t i;
1256 int _ra_err = roar_error;
1257 int _sys_err = errno;
1258
1259 for (i = 0; i < (sizeof(num)/sizeof(*num)); i++)
1260  num[i] = roar_random_uint32();
1261
1262 snprintf(buf, sizeof(buf), "\e[44;39;1m\e[2J\e[H"
1263                            "                                   RoarAudio\n"
1264                            "\n\n"
1265                            "Fatal error %.4x: %s\n"
1266                            "RA Error: %.4i, Sys Error: %.4i (%s)\n"
1267                            "Random numbers:\n"
1268                            " A: 0x%.8X B: 0x%.8X\n"
1269                            " C: 0x%.8X D: 0x%.8X\n"
1270                            " E: 0x%.8X F: 0x%.8X\n"
1271                            " G: 0x%.8X H: 0x%.8X\n"
1272                            "\n\n"
1273                            "\e[0m",
1274                            error, msg,
1275                            _ra_err, _sys_err, strerror(_sys_err),
1276                            num[0], num[1], num[2], num[3], num[4], num[5], num[6], num[7]);
1277
1278 return buf;
1279}
1280
1281const char * roar_error2str(const int error) {
1282 struct roar_libroar_config * config = roar_libroar_get_config();
1283 const struct {
1284  const int    err;
1285  const char * msg;
1286 } msgs[] = {
1287  {ROAR_ERROR_NONE,        "No error"},
1288  {ROAR_ERROR_PERM,        "Operation not permitted"},
1289  {ROAR_ERROR_NOENT,       "No such object, file, directory or node"},
1290  {ROAR_ERROR_BADMSG,      "Bad message"},
1291  {ROAR_ERROR_BUSY,        "Device or resource busy"},
1292  {ROAR_ERROR_CONNREFUSED, "Connection refused"},
1293  {ROAR_ERROR_NOSYS,       "Function not implemented"},
1294  {ROAR_ERROR_NOTSUP,      "Operation not supported"},
1295  {ROAR_ERROR_PIPE,        "Broken pipe"},
1296  {ROAR_ERROR_PROTO,       "Protocol error"},
1297  {ROAR_ERROR_RANGE,       "Result too large or parameter out of range"},
1298  {ROAR_ERROR_MSGSIZE,     "Message too long"},
1299  {ROAR_ERROR_NOMEM,       "Not enough space"},
1300  {ROAR_ERROR_INVAL,       "Invalid argument"},
1301  {ROAR_ERROR_ALREADY,     "Connection already in progress"},
1302  {ROAR_ERROR_BADRQC,      "Invalid request code"},
1303  {ROAR_ERROR_DOM,         "Mathematics argument out of domain of function"},
1304  {ROAR_ERROR_EXIST,       "File or object exists"},
1305  {ROAR_ERROR_FAULT,       "Bad address"},
1306  {ROAR_ERROR_IO,          "I/O-Error"},
1307  {ROAR_ERROR_KEYEXPIRED,  "Key has expired"},
1308  {ROAR_ERROR_KEYREJECTED, "Key was rejected by service"},
1309  {ROAR_ERROR_LOOP,        "Too many recursions"},
1310  {ROAR_ERROR_MFILE,       "Too many open files or objects"},
1311  {ROAR_ERROR_NAMETOOLONG, "File or object name too long"},
1312  {ROAR_ERROR_NODATA,      "No message is available on the read queue"},
1313  {ROAR_ERROR_NODEV,       "No such device"},
1314  {ROAR_ERROR_NODRV,       "No such driver"},
1315  {ROAR_ERROR_NOSPC,       "No space left on device"},
1316  {ROAR_ERROR_TYPEMM,      "Type missmatch. Object of diffrent type required"},
1317  {ROAR_ERROR_NORSYS,      "Feature not implemented by remote end"},
1318  {ROAR_ERROR_NOTCONN,     "Socket or object not connected"},
1319  {ROAR_ERROR_PROTONOSUP,  "Protocol not supported"},
1320  {ROAR_ERROR_RIO,         "Remote I/O Error"},
1321  {ROAR_ERROR_RO,          "File or object is read only"},
1322  {ROAR_ERROR_TIMEDOUT,    "Connection timed out"},
1323  {ROAR_ERROR_AGAIN,       "Resource temporarily unavailable"},
1324  {ROAR_ERROR_NOISE,       "Line too noisy"},
1325  {ROAR_ERROR_LINKDOWN,    "Physical or logical link down"},
1326  {ROAR_ERROR_INTERRUPTED, "Operation was interruped"},
1327  {ROAR_ERROR_CAUSALITY,   "Causality error"},
1328  {ROAR_ERROR_QUOTA,       "Quota exceeded"},
1329  {ROAR_ERROR_BADLIB,      "Accessing a corrupted shared library"},
1330  {ROAR_ERROR_NOMEDIUM,    "No medium found"},
1331  {ROAR_ERROR_NOTUNIQ,     "Name not unique"},
1332  {ROAR_ERROR_ILLSEQ,      "Illegal byte sequence"},
1333  {ROAR_ERROR_ADDRINUSE,   "Address in use"},
1334  {ROAR_ERROR_HOLE,        "Hole in data"},
1335  {ROAR_ERROR_BADVERSION,  "Bad version"},
1336  {ROAR_ERROR_NSVERSION,   "Not supported version"},
1337  {ROAR_ERROR_BADMAGIC,    "Bad magic number"},
1338  {ROAR_ERROR_LOSTSYNC,    "Lost synchronization"},
1339  {ROAR_ERROR_BADSEEK,     "Can not seek to destination position"},
1340  {ROAR_ERROR_NOSEEK,      "Seeking not supported on resource"},
1341  {ROAR_ERROR_BADCKSUM,    "Data integrity error"},
1342  {ROAR_ERROR_NOHORSE,     "Mount failed"},
1343  {ROAR_ERROR_CHERNOBYL,   "Fatal device error"},
1344  {ROAR_ERROR_NOHUG,       "Device needs love"},
1345  {ROAR_ERROR_TEXTBUSY,    "Text file busy"},
1346  {ROAR_ERROR_NOTEMPTY,    "Directory not empty"},
1347  {ROAR_ERROR_NODEUNREACH, "Node is unreachable"},
1348  {ROAR_ERROR_IDREMOVED,   "Identifier removed"},
1349  {ROAR_ERROR_INPROGRESS,  "Operation in progress"},
1350  {ROAR_ERROR_NOCHILD,     "No child processes or object"},
1351  {ROAR_ERROR_NETUNREACH,  "Network unreachable"},
1352  {ROAR_ERROR_CANCELED,    "Operation canceled"},
1353  {ROAR_ERROR_ISDIR,       "Is a directory"},
1354  {ROAR_ERROR_NOTDIR,      "Not a directory"},
1355  {ROAR_ERROR_BADEXEC,     "Executable file format error"},
1356  {ROAR_ERROR_ISCONN,      "Socket or Object is connected"},
1357  {ROAR_ERROR_DEADLOCK,    "Resource deadlock would occur"},
1358  {ROAR_ERROR_CONNRST,     "Connection reset"},
1359  {ROAR_ERROR_BADFH,       "Bad file handle"},
1360  {ROAR_ERROR_NOTSOCK,     "Not a socket"},
1361  {ROAR_ERROR_TOOMANYARGS, "Argument list too long"},
1362  {ROAR_ERROR_TOOLARGE,    "File or Object too large"},
1363  {ROAR_ERROR_DESTADDRREQ, "Destination address required"},
1364  {ROAR_ERROR_AFNOTSUP,    "Address family not supported"},
1365  {ROAR_ERROR_NOPOWER,     "Operation can not be completed because we are low on power"},
1366  {ROAR_ERROR_USER,        "Error in front of screen"},
1367  {ROAR_ERROR_NFILE,       "Too many filesobjects open in system"},
1368  {ROAR_ERROR_STALE,       "Stale file handle or object"},
1369  {ROAR_ERROR_XDEVLINK,    "Cross-device link"},
1370  {ROAR_ERROR_MLINK,       "Too many links to file or object"},
1371  {ROAR_ERROR_NONET,       "Not connected to any network"},
1372  {ROAR_ERROR_CONNRSTNET,  "Connection reset by network"},
1373  {ROAR_ERROR_CONNABORTED, "Connection aborted"},
1374  {ROAR_ERROR_BADHOST,     "Bad host software or hardware"},
1375  {ROAR_ERROR_SWITCHPROTO, "Switch protocol"},
1376  {ROAR_ERROR_MOVEDPERM,   "Moved Permanently"},
1377  {ROAR_ERROR_MOVEDTEMP,   "Moved Temporary"},
1378  {ROAR_ERROR_USEPROXY,    "Use Proxy server"},
1379  {ROAR_ERROR_SEEOTHER,    "See other resource"},
1380  {ROAR_ERROR_GONE,        "Resource gone"},
1381  {ROAR_ERROR_BADLICENSE,  "Bad License"},
1382  {ROAR_ERROR_NEEDPAYMENT, "Payment Required"},
1383  {ROAR_ERROR_NSTYPE,      "Type or Format not supported"},
1384  {ROAR_ERROR_CENSORED,    "Access denied because of censorship"},
1385  {ROAR_ERROR_BADSTATE,    "Object is in bad/wrong state"},
1386  {ROAR_ERROR_DISABLED,    "This has been disabled by the administrator"},
1387  {-1, NULL}
1388 }, msgs_funny[] = {
1389//  {ROAR_ERROR_UNKNOWN,     "Unknown (maybe no) error"},
1390  {ROAR_ERROR_NONE,        "No error, huh?"},
1391  {ROAR_ERROR_PERM,        "Little kitty is not allowed to do this"},
1392  {ROAR_ERROR_NOENT,       "Mouse not found"},
1393//  {ROAR_ERROR_BADMSG,      "Bad message"},
1394  {ROAR_ERROR_BUSY,        "Another kitty is playing with this mouse"},
1395//  {ROAR_ERROR_CONNREFUSED, "Connection refused"},
1396//  {ROAR_ERROR_NOSYS,       "Function not implemented"},
1397//  {ROAR_ERROR_NOTSUP,      "Operation not supported"},
1398  {ROAR_ERROR_PIPE,        "Flood"},
1399//  {ROAR_ERROR_PROTO,       "Protocol error"},
1400//  {ROAR_ERROR_RANGE,       "Result too largegeneral out of range"},
1401//  {ROAR_ERROR_MSGSIZE,     "Message too long"},
1402//  {ROAR_ERROR_NOMEM,       "Not enough space"},
1403//  {ROAR_ERROR_INVAL,       "Invalid argument"},
1404//  {ROAR_ERROR_ALREADY,     "Connection already in progress"},
1405  {ROAR_ERROR_BADRQC,      "Stupid staff"},
1406//  {ROAR_ERROR_DOM,         "Mathematics argument out of domain of function"},
1407//  {ROAR_ERROR_EXIST,       "File or object exists"},
1408//  {ROAR_ERROR_FAULT,       "Bad address"},
1409//  {ROAR_ERROR_IO,          "IO-Error"},
1410//  {ROAR_ERROR_KEYEXPIRED,  "Key has expired"},
1411//  {ROAR_ERROR_KEYREJECTED, "Key was rejected by service"},
1412//  {ROAR_ERROR_LOOP,        "Too many recursions"},
1413//  {ROAR_ERROR_MFILE,       "Too many open files or objects"},
1414  {ROAR_ERROR_NAMETOOLONG, "Staff can not remember long names"},
1415//  {ROAR_ERROR_NODATA,      "No message is available on the read queue"},
1416  {ROAR_ERROR_NODEV,       "No such mouse"},
1417//  {ROAR_ERROR_NODRV,       "No such driver"},
1418  {ROAR_ERROR_NOSPC,       "Too many fish on desk"},
1419//  {ROAR_ERROR_TYPEMM,      "Type missmatch. Object of diffrent type required"},
1420//  {ROAR_ERROR_NORSYS,      "Feature not implemented by remote end"},
1421//  {ROAR_ERROR_NOTCONN,     "Socket or object not connected"},
1422//  {ROAR_ERROR_PROTONOSUP,  "Protocol not supported"},
1423//  {ROAR_ERROR_RIO,         "Remote IO Error"},
1424  {ROAR_ERROR_RO,          "Touching disallowed"},
1425//  {ROAR_ERROR_TIMEDOUT,    "Connection timed out"},
1426//  {ROAR_ERROR_AGAIN,       "Resource temporarily unavailable"},
1427//  {ROAR_ERROR_NOISE,       "Line too noisy"},
1428//  {ROAR_ERROR_LINKDOWN,    "Physical or logical link down"},
1429//  {ROAR_ERROR_INTERRUPTED, "Operation was interruped"},
1430//  {ROAR_ERROR_CAUSALITY,   "Causality error"},
1431//  {ROAR_ERROR_QUOTA,       "Quota exceeded"},
1432//  {ROAR_ERROR_BADLIB,      "Accessing a corrupted shared library"},
1433//  {ROAR_ERROR_NOMEDIUM,    "No medium found"},
1434//  {ROAR_ERROR_NOTUNIQ,     "Name not unique"},
1435//  {ROAR_ERROR_ILLSEQ,      "Illegal byte sequence"},
1436//  {ROAR_ERROR_ADDRINUSE,   "Address in use"},
1437  {ROAR_ERROR_HOLE,        "Hole in wall"},
1438//  {ROAR_ERROR_BADVERSION,  "Bad version"},
1439//  {ROAR_ERROR_NSVERSION,   "Not supported version"},
1440  {ROAR_ERROR_BADMAGIC,    "Magician's fault"},
1441//  {ROAR_ERROR_LOSTSYNC,    "Lost synchronization"},
1442//  {ROAR_ERROR_BADSEEK,     "Can not seek to destination position"},
1443//  {ROAR_ERROR_NOSEEK,      "Seeking not supported on resource"},
1444//  {ROAR_ERROR_BADCKSUM,    "Data integrity error"},
1445  {ROAR_ERROR_NOHORSE,     "No horse"},
1446//  {ROAR_ERROR_CHERNOBYL,   "Fatal device error"},
1447  {ROAR_ERROR_NOHUG,       "No hug"},
1448//  {ROAR_ERROR_TEXTBUSY,    "Text file busy"},
1449//  {ROAR_ERROR_NOTEMPTY,    "Directory not empty"},
1450//  {ROAR_ERROR_NODEUNREACH, "Node is unreachable"},
1451//  {ROAR_ERROR_IDREMOVED,   "Identifier removed"},
1452//  {ROAR_ERROR_INPROGRESS,  "Operation in progress"},
1453//  {ROAR_ERROR_NOCHILD,     "No child processesobject"},
1454//  {ROAR_ERROR_NETUNREACH,  "Network unreachable"},
1455//  {ROAR_ERROR_CANCELED,    "Operation canceled"},
1456//  {ROAR_ERROR_ISDIR,       "Is a directory"},
1457//  {ROAR_ERROR_NOTDIR,      "Not a directory"},
1458//  {ROAR_ERROR_BADEXEC,     "Executable file format error"},
1459//  {ROAR_ERROR_ISCONN,      "Socket/Object is connected"},
1460  {ROAR_ERROR_DEADLOCK,    "Mouse would die"},
1461//  {ROAR_ERROR_CONNRST,     "Connection reset"},
1462//  {ROAR_ERROR_BADFH,       "Bad file handle"},
1463//  {ROAR_ERROR_NOTSOCK,     "Not a socket"},
1464//  {ROAR_ERROR_TOOMANYARGS, "Argument list too long"},
1465//  {ROAR_ERROR_TOOLARGE,    "File/Object too large"},
1466//  {ROAR_ERROR_DESTADDRREQ, "Destination address required"},
1467//  {ROAR_ERROR_AFNOTSUP,    "Address family not supported"},
1468//  {ROAR_ERROR_NOPOWER,     "Operation can not be completed because we are low on power"},
1469//  {ROAR_ERROR_USER,        "Error in front of screen"},
1470//  {ROAR_ERROR_NFILE,       "Too many filesobjects open in system"},
1471//  {ROAR_ERROR_STALE,       "Stale file handle or object"},
1472  {ROAR_ERROR_XDEVLINK,    "Mice tails too short for kinking"},
1473//  {ROAR_ERROR_MLINK,       "Too many links to file or object"},
1474//  {ROAR_ERROR_NONET,       "Not connected to any network"},
1475//  {ROAR_ERROR_CONNRSTNET,  "Connection reset by network"},
1476//  {ROAR_ERROR_CONNABORTED, "Connection aborted"},
1477//  {ROAR_ERROR_BADHOST,     "Bad host software or hardware"},
1478//  {ROAR_ERROR_SWITCHPROTO, "Switch protocol"},
1479//  {ROAR_ERROR_MOVEDPERM,   "Moved Permanently"},
1480//  {ROAR_ERROR_MOVEDTEMP,   "Moved Temporary"},
1481//  {ROAR_ERROR_USEPROXY,    "Use Proxy server"},
1482//  {ROAR_ERROR_SEEOTHER,    "See other resource"},
1483//  {ROAR_ERROR_GONE,        "Resource gone"},
1484  {-1, NULL}
1485 };
1486 int i;
1487
1488 if ( config->opmode == ROAR_LIBROAR_CONFIG_OPMODE_MS ) {
1489  for (i = 0; msgs[i].msg != NULL; i++) {
1490   if ( msgs[i].err == error ) {
1491    return roar_error2str_ms(error, msgs[i].msg);
1492   }
1493  }
1494  return roar_error2str_ms(error, "<<<unknown error>>>");
1495 }
1496
1497 if ( config->opmode == ROAR_LIBROAR_CONFIG_OPMODE_FUNNY )
1498  for (i = 0; msgs_funny[i].msg != NULL; i++)
1499   if ( msgs_funny[i].err == error )
1500    return msgs_funny[i].msg;
1501
1502 for (i = 0; msgs[i].msg != NULL; i++)
1503  if ( msgs[i].err == error )
1504   return msgs[i].msg;
1505
1506 return NULL;
1507}
1508
1509//ll
Note: See TracBrowser for help on using the repository browser.