source: roaraudio/libroar/error.c @ 5540:2fd95aa93c27

Last change on this file since 5540:2fd95aa93c27 was 5540:2fd95aa93c27, checked in by phi, 12 years ago

moved roar_errno2() into roar_errno2_impl (macro) to make other functions faster by enabling thhem to access without calling roar_errno2().

File size: 32.3 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 }
219}
220
221int    roar_err_is_errno_clear(void) {
222 return errno == CLEAN_ERRNO ? 1 : 0;
223}
224
225void   roar_err_set(const int error) {
226 *roar_errno2_impl = error;
227}
228
229void   roar_err_from_errno(void) {
230 int _roar_errno = ROAR_ERROR_NONE;
231
232 switch (errno) {
233#ifdef EACCES
234  case EACCES:       _roar_errno = ROAR_ERROR_PERM; break;
235#endif
236#ifdef EPERM
237  case EPERM:        _roar_errno = ROAR_ERROR_PERM; break;
238#endif
239#ifdef ENOENT
240  case ENOENT:       _roar_errno = ROAR_ERROR_NOENT; break;
241#endif
242#ifdef EBADMSG
243  case EBADMSG:      _roar_errno = ROAR_ERROR_BADMSG; break;
244#endif
245#ifdef EBUSY
246  case EBUSY:        _roar_errno = ROAR_ERROR_BUSY; break;
247#endif
248#ifdef ECONNREFUSED
249  case ECONNREFUSED: _roar_errno = ROAR_ERROR_CONNREFUSED; break;
250#endif
251#ifdef ENOSYS
252  case ENOSYS:       _roar_errno = ROAR_ERROR_NOSYS; break;
253#endif
254#ifdef ENOTSUP
255  case ENOTSUP:      _roar_errno = ROAR_ERROR_NOTSUP; break;
256#endif
257#ifdef EPIPE
258  case EPIPE:        _roar_errno = ROAR_ERROR_PIPE; break;
259#endif
260#ifdef EPROTO
261  case EPROTO:       _roar_errno = ROAR_ERROR_PROTO; break;
262#endif
263#ifdef ERANGE
264  case ERANGE:       _roar_errno = ROAR_ERROR_RANGE; break;
265#endif
266#ifdef EMSGSIZE
267  case EMSGSIZE:     _roar_errno = ROAR_ERROR_MSGSIZE; break;
268#endif
269#ifdef ENOMEM
270  case ENOMEM:       _roar_errno = ROAR_ERROR_NOMEM; break;
271#endif
272#ifdef EINVAL
273  case EINVAL:       _roar_errno = ROAR_ERROR_INVAL; break;
274#endif
275#ifdef EALREADY
276  case EALREADY:     _roar_errno = ROAR_ERROR_ALREADY; break;
277#endif
278#ifdef EBADRQC
279  case EBADRQC:      _roar_errno = ROAR_ERROR_BADRQC; break;
280#endif
281#ifdef EDOM
282  case EDOM:         _roar_errno = ROAR_ERROR_DOM; break;
283#endif
284#ifdef EEXIST
285  case EEXIST:       _roar_errno = ROAR_ERROR_EXIST; break;
286#endif
287#ifdef EFAULT
288  case EFAULT:       _roar_errno = ROAR_ERROR_FAULT; break;
289#endif
290#ifdef EIO
291  case EIO:          _roar_errno = ROAR_ERROR_IO; break;
292#endif
293#ifdef EREMOTEIO
294  case EREMOTEIO:    _roar_errno = ROAR_ERROR_RIO; break;
295#endif
296#ifdef EKEYEXPIRED
297  case EKEYEXPIRED:  _roar_errno = ROAR_ERROR_KEYEXPIRED; break;
298#endif
299#ifdef EKEYREJECTED
300  case EKEYREJECTED: _roar_errno = ROAR_ERROR_KEYREJECTED; break;
301#endif
302#ifdef ELOOP
303  case ELOOP:        _roar_errno = ROAR_ERROR_LOOP; break;
304#endif
305#ifdef EMFILE
306  case EMFILE:       _roar_errno = ROAR_ERROR_MFILE; break;
307#endif
308#ifdef ENAMETOOLONG
309  case ENAMETOOLONG: _roar_errno = ROAR_ERROR_NAMETOOLONG; break;
310#endif
311#ifdef ENODATA
312  case ENODATA:      _roar_errno = ROAR_ERROR_NODATA; break;
313#endif
314#ifdef ENODEV
315  case ENODEV:       _roar_errno = ROAR_ERROR_NODEV; break;
316#endif
317#ifdef ENOSPC
318  case ENOSPC:       _roar_errno = ROAR_ERROR_NOSPC; break;
319#endif
320#ifdef ENOTCONN
321  case ENOTCONN:     _roar_errno = ROAR_ERROR_NOTCONN; break;
322#endif
323#ifdef EPROTONOSUPPORT
324  case EPROTONOSUPPORT: _roar_errno = ROAR_ERROR_PROTONOSUP; break;
325#endif
326#ifdef EROFS
327  case EROFS:        _roar_errno = ROAR_ERROR_RO; break;
328#endif
329#ifdef ETIMEDOUT
330  case ETIMEDOUT:    _roar_errno = ROAR_ERROR_TIMEDOUT; break;
331#endif
332#ifdef EAGAIN
333  case EAGAIN:       _roar_errno = ROAR_ERROR_AGAIN; break;
334#endif
335#ifdef ENETDOWN
336  case ENETDOWN:     _roar_errno = ROAR_ERROR_LINKDOWN; break;
337#endif
338#ifdef EINTR
339  case EINTR:        _roar_errno = ROAR_ERROR_INTERRUPTED; break;
340#endif
341#ifdef EDQUOT
342  case EDQUOT:       _roar_errno = ROAR_ERROR_QUOTA; break;
343#endif
344#ifdef ELIBBAD
345  case ELIBBAD:      _roar_errno = ROAR_ERROR_BADLIB; break;
346#endif
347#ifdef ENOMEDIUM
348  case ENOMEDIUM:    _roar_errno = ROAR_ERROR_NOMEDIUM; break;
349#endif
350#ifdef ENOTUNIQ
351  case ENOTUNIQ:     _roar_errno = ROAR_ERROR_NOTUNIQ; break;
352#endif
353#ifdef EILSEQ
354  case EILSEQ:       _roar_errno = ROAR_ERROR_ILLSEQ; break;
355#endif
356#ifdef EADDRINUSE
357  case EADDRINUSE:   _roar_errno = ROAR_ERROR_ADDRINUSE; break;
358#endif
359#ifdef ESPIPE
360  case ESPIPE:       _roar_errno = ROAR_ERROR_BADSEEK; break;
361#endif
362#ifdef ECHERNOBYL
363  case ECHERNOBYL:   _roar_errno = ROAR_ERROR_CHERNOBYL; break;
364#endif
365#ifdef ECRAY
366  case ECRAY:        _roar_errno = ROAR_ERROR_CAUSALITY; break;
367#endif
368#ifdef ENOHORSE
369  case ENOHORSE:     _roar_errno = ROAR_ERROR_NOHORSE; break;
370#endif
371#ifdef ETXTBSY
372  case ETXTBSY:      _roar_errno = ROAR_ERROR_TEXTBUSY; break;
373#endif
374#ifdef ENOTEMPTY
375  case ENOTEMPTY:    _roar_errno = ROAR_ERROR_NOTEMPTY; break;
376#endif
377#ifdef EHOSTUNREACH
378  case EHOSTUNREACH: _roar_errno = ROAR_ERROR_NODEUNREACH; break;
379#endif
380#ifdef EIDRM
381  case EIDRM:        _roar_errno = ROAR_ERROR_IDREMOVED; break;
382#endif
383#ifdef EINPROGRESS
384  case EINPROGRESS:  _roar_errno = ROAR_ERROR_INPROGRESS; break;
385#endif
386#ifdef ECHILD
387  case ECHILD:       _roar_errno = ROAR_ERROR_NOCHILD; break;
388#endif
389#ifdef ENETUNREACH
390  case ENETUNREACH:  _roar_errno = ROAR_ERROR_NETUNREACH; break;
391#endif
392#ifdef ECANCELED
393  case ECANCELED:    _roar_errno = ROAR_ERROR_CANCELED; break;
394#endif
395#ifdef EISDIR
396  case EISDIR:       _roar_errno = ROAR_ERROR_ISDIR; break;
397#endif
398#ifdef ENOTDIR
399  case ENOTDIR:      _roar_errno = ROAR_ERROR_NOTDIR; break;
400#endif
401#ifdef ENOEXEC
402  case ENOEXEC:      _roar_errno = ROAR_ERROR_BADEXEC; break;
403#endif
404#ifdef EISCONN
405  case EISCONN:      _roar_errno = ROAR_ERROR_ISCONN; break;
406#endif
407#ifdef EDEADLK
408  case EDEADLK:      _roar_errno = ROAR_ERROR_DEADLOCK; break;
409#endif
410#ifdef ECONNRESET
411  case ECONNRESET:   _roar_errno = ROAR_ERROR_CONNRST; break;
412#endif
413#ifdef EBADF
414  case EBADF:        _roar_errno = ROAR_ERROR_BADFH; break;
415#endif
416#ifdef ENOTSOCK
417  case ENOTSOCK:     _roar_errno = ROAR_ERROR_NOTSOCK; break;
418#endif
419#ifdef E2BIG
420  case E2BIG:        _roar_errno = ROAR_ERROR_TOOMANYARGS; break;
421#endif
422#ifdef EFBIG
423  case EFBIG:        _roar_errno = ROAR_ERROR_TOOLARGE; break;
424#endif
425#ifdef EDESTADDRREQ
426  case EDESTADDRREQ: _roar_errno = ROAR_ERROR_DESTADDRREQ; break;
427#endif
428#ifdef EAFNOSUPPORT
429  case EAFNOSUPPORT: _roar_errno = ROAR_ERROR_AFNOTSUP; break;
430#endif
431#ifdef ENFILE
432  case ENFILE:       _roar_errno = ROAR_ERROR_NFILE; break;
433#endif
434#ifdef ESTALE
435  case ESTALE:       _roar_errno = ROAR_ERROR_STALE; break;
436#endif
437#ifdef EXDEV
438  case EXDEV:        _roar_errno = ROAR_ERROR_XDEVLINK; break;
439#endif
440#ifdef EMLINK
441  case EMLINK:       _roar_errno = ROAR_ERROR_MLINK; break;
442#endif
443#ifdef ENONET
444  case ENONET:       _roar_errno = ROAR_ERROR_NONET; break;
445#endif
446#ifdef ENETRESET
447  case ENETRESET:    _roar_errno = ROAR_ERROR_CONNRSTNET; break;
448#endif
449#ifdef ECONNABORTED
450  case ECONNABORTED: _roar_errno = ROAR_ERROR_CONNABORTED; break;
451#endif
452  default:
453    _roar_errno = ROAR_ERROR_UNKNOWN;
454   break;
455 }
456
457 roar_err_set(_roar_errno);
458}
459
460void   roar_err_to_errno(void) {
461 int * err = roar_errno2();
462 switch (*err) {
463  case ROAR_ERROR_NONE:
464    roar_err_clear_errno();
465   break;
466#ifdef EPERM
467  case ROAR_ERROR_PERM:
468    errno = EPERM;
469   break;
470#endif
471#ifdef ENOENT
472  case ROAR_ERROR_NOENT:
473    errno = ENOENT;
474   break;
475#endif
476#ifdef EBADMSG
477  case ROAR_ERROR_BADMSG:
478    errno = EBADMSG;
479   break;
480#endif
481#ifdef EBUSY
482  case ROAR_ERROR_BUSY:
483    errno = EBUSY;
484   break;
485#endif
486#ifdef ECONNREFUSED
487  case ROAR_ERROR_CONNREFUSED:
488    errno = ECONNREFUSED;
489   break;
490#endif
491#ifdef ENOSYS
492  case ROAR_ERROR_NOSYS:
493    errno = ENOSYS;
494   break;
495#endif
496#ifdef ENOTSUP
497  case ROAR_ERROR_NOTSUP:
498    errno = ENOTSUP;
499   break;
500#endif
501#ifdef EPIPE
502  case ROAR_ERROR_PIPE:
503    errno = EPIPE;
504   break;
505#endif
506#ifdef EPROTO
507  case ROAR_ERROR_PROTO:
508    errno = EPROTO;
509   break;
510#endif
511#ifdef ERANGE
512  case ROAR_ERROR_RANGE:
513    errno = ERANGE;
514   break;
515#endif
516#ifdef EMSGSIZE
517  case ROAR_ERROR_MSGSIZE:
518    errno = EMSGSIZE;
519   break;
520#endif
521#ifdef ENOMEM
522  case ROAR_ERROR_NOMEM:
523    errno = ENOMEM;
524   break;
525#endif
526#ifdef EINVAL
527  case ROAR_ERROR_INVAL:
528    errno = EINVAL;
529   break;
530#endif
531#ifdef EALREADY
532  case ROAR_ERROR_ALREADY:
533    errno = EALREADY;
534   break;
535#endif
536#ifdef EBADRQC
537  case ROAR_ERROR_BADRQC:
538    errno = EBADRQC;
539   break;
540#endif
541#ifdef EDOM
542  case ROAR_ERROR_DOM:
543    errno = EDOM;
544   break;
545#endif
546#ifdef EEXIST
547  case ROAR_ERROR_EXIST:
548    errno = EEXIST;
549   break;
550#endif
551#ifdef EFAULT
552  case ROAR_ERROR_FAULT:
553    errno = EFAULT;
554   break;
555#endif
556#if defined(EREMOTEIO) || defined(EIO)
557  case ROAR_ERROR_RIO:
558#ifdef EREMOTEIO
559    errno = EREMOTEIO;
560#else
561    errno = EIO;
562#endif
563   break;
564#endif
565#ifdef EIO
566  case ROAR_ERROR_IO:
567  case ROAR_ERROR_HOLE:
568  case ROAR_ERROR_BADCKSUM:
569  case ROAR_ERROR_LOSTSYNC:
570  case ROAR_ERROR_NOHORSE:
571    errno = EIO;
572   break;
573#endif
574#ifdef EKEYEXPIRED
575  case ROAR_ERROR_KEYEXPIRED:
576    errno = EKEYEXPIRED;
577   break;
578#endif
579#ifdef EKEYREJECTED
580  case ROAR_ERROR_KEYREJECTED:
581    errno = EKEYREJECTED;
582   break;
583#endif
584#ifdef ELOOP
585  case ROAR_ERROR_LOOP:
586    errno = ELOOP;
587   break;
588#endif
589#ifdef EMFILE
590  case ROAR_ERROR_MFILE:
591    errno = EMFILE;
592   break;
593#endif
594#ifdef ENAMETOOLONG
595  case ROAR_ERROR_NAMETOOLONG:
596    errno = ENAMETOOLONG;
597   break;
598#endif
599#ifdef ENODATA
600  case ROAR_ERROR_NODATA:
601    errno = ENODATA;
602   break;
603#endif
604#ifdef ENODEV
605  case ROAR_ERROR_NODEV:
606  case ROAR_ERROR_NODRV:
607    errno = ENODEV;
608   break;
609#endif
610#ifdef ENOSPC
611  case ROAR_ERROR_NOSPC:
612    errno = ENOSPC;
613   break;
614#endif
615#ifdef EINVAL
616  case ROAR_ERROR_TYPEMM:
617    errno = EINVAL;
618   break;
619#endif
620#ifdef ENOSYS
621  case ROAR_ERROR_NORSYS:
622    errno = ENOSYS;
623   break;
624#endif
625#ifdef ENOTCONN
626  case ROAR_ERROR_NOTCONN:
627    errno = ENOTCONN;
628   break;
629#endif
630#ifdef EPROTONOSUPPORT
631  case ROAR_ERROR_PROTONOSUP:
632    errno = EPROTONOSUPPORT;
633   break;
634#endif
635#ifdef EROFS
636  case ROAR_ERROR_RO:
637    errno = EROFS;
638   break;
639#endif
640#ifdef ETIMEDOUT
641  case ROAR_ERROR_TIMEDOUT:
642    errno = ETIMEDOUT;
643   break;
644#endif
645#ifdef EAGAIN
646  case ROAR_ERROR_AGAIN:
647    errno = EAGAIN;
648   break;
649#endif
650#ifdef ENETDOWN
651  case ROAR_ERROR_LINKDOWN:
652    errno = ENETDOWN;
653   break;
654#endif
655#ifdef EINTR
656  case ROAR_ERROR_INTERRUPTED:
657    errno = EINTR;
658   break;
659#endif
660#ifdef EDQUOT
661  case ROAR_ERROR_QUOTA:
662    errno = EDQUOT;
663   break;
664#endif
665#ifdef ELIBBAD
666  case ROAR_ERROR_BADLIB:
667    errno = ELIBBAD;
668   break;
669#endif
670#ifdef ENOMEDIUM
671  case ROAR_ERROR_NOMEDIUM:
672    errno = ENOMEDIUM;
673   break;
674#endif
675#ifdef ENOTUNIQ
676  case ROAR_ERROR_NOTUNIQ:
677    errno = ENOTUNIQ;
678   break;
679#endif
680#ifdef EILSEQ
681  case ROAR_ERROR_ILLSEQ:
682    errno = EILSEQ;
683   break;
684#endif
685#ifdef EADDRINUSE
686  case ROAR_ERROR_ADDRINUSE:
687    errno = EADDRINUSE;
688   break;
689#endif
690#ifdef ESPIPE
691  case ROAR_ERROR_BADSEEK:
692  case ROAR_ERROR_NOSEEK:
693    errno = ESPIPE;
694   break;
695#endif
696#ifdef ECHERNOBYL
697  case ROAR_ERROR_CHERNOBYL:
698    errno = ECHERNOBYL;
699   break;
700#endif
701#ifdef ECRAY
702  case ROAR_ERROR_CAUSALITY:
703    errno = ECRAY;
704   break;
705#endif
706#ifdef ENOHORSE
707  case ROAR_ERROR_NOHORSE:
708    errno = ENOHORSE;
709   break;
710#endif
711#ifdef ETXTBSY
712  case ROAR_ERROR_TEXTBUSY:
713    errno = ETXTBSY;
714   break;
715#endif
716#ifdef ENOTEMPTY
717  case ROAR_ERROR_NOTEMPTY:
718    errno = ENOTEMPTY;
719   break;
720#endif
721#ifdef EHOSTUNREACH
722  case ROAR_ERROR_NODEUNREACH:
723    errno = EHOSTUNREACH;
724   break;
725#endif
726#ifdef EIDRM
727  case ROAR_ERROR_IDREMOVED:
728    errno = EIDRM;
729   break;
730#endif
731#ifdef EINPROGRESS
732  case ROAR_ERROR_INPROGRESS:
733    errno = EINPROGRESS;
734   break;
735#endif
736#ifdef ECHILD
737  case ROAR_ERROR_NOCHILD:
738    errno = ECHILD;
739   break;
740#endif
741#ifdef ENETUNREACH
742  case ROAR_ERROR_NETUNREACH:
743    errno = ENETUNREACH;
744   break;
745#endif
746#ifdef ECANCELED
747  case ROAR_ERROR_CANCELED:
748    errno = ECANCELED;
749   break;
750#endif
751#ifdef EISDIR
752  case ROAR_ERROR_ISDIR:
753    errno = EISDIR;
754   break;
755#endif
756#ifdef ENOTDOR
757  case ROAR_ERROR_NOTDIR:
758    errno = ENOTDIR;
759   break;
760#endif
761#ifdef ENOEXEC
762  case ROAR_ERROR_BADEXEC:
763    errno = ENOEXEC;
764   break;
765#endif
766#ifdef EISCONN
767  case ROAR_ERROR_ISCONN:
768    errno = EISCONN;
769   break;
770#endif
771#ifdef EDEADLK
772  case ROAR_ERROR_DEADLOCK:
773    errno = EDEADLK;
774   break;
775#endif
776#ifdef ECONNRESET
777  case ROAR_ERROR_CONNRST:
778    errno = ECONNRESET;
779   break;
780#endif
781#ifdef EBADF
782  case ROAR_ERROR_BADFH:
783    errno = EBADF;
784   break;
785#endif
786#ifdef ENOTSOCK
787  case ROAR_ERROR_NOTSOCK:
788    errno = ENOTSOCK;
789   break;
790#endif
791#ifdef E2BIG
792  case ROAR_ERROR_TOOMANYARGS:
793    errno = E2BIG;
794   break;
795#endif
796#ifdef EFBIG
797  case ROAR_ERROR_TOOLARGE:
798    errno = EFBIG;
799   break;
800#endif
801#ifdef EDESTADDRREQ
802  case ROAR_ERROR_DESTADDRREQ:
803    errno = EDESTADDRREQ;
804   break;
805#endif
806#ifdef EAFNOSUPPORT
807  case ROAR_ERROR_AFNOTSUP:
808    errno = EAFNOSUPPORT;
809   break;
810#endif
811// FIXME....
812#ifdef ENOPOWER
813  case ROAR_ERROR_NOPOWER:
814    errno = ENOPOWER;
815   break;
816#endif
817#ifdef EUSER
818  case ROAR_ERROR_USER:
819    errno = EUSER;
820   break;
821#endif
822
823#ifdef ENFILE
824  case ROAR_ERROR_NFILE:
825    errno = ENFILE;
826   break;
827#endif
828#ifdef ESTALE
829  case ROAR_ERROR_STALE:
830    errno = ESTALE;
831   break;
832#endif
833#ifdef EXDEV
834  case ROAR_ERROR_XDEVLINK:
835    errno = EXDEV;
836   break;
837#endif
838#ifdef EMLINK
839  case ROAR_ERROR_MLINK:
840    errno = EMLINK;
841   break;
842#endif
843#ifdef ENONET
844  case ROAR_ERROR_NONET:
845    errno = ENONET;
846   break;
847#endif
848#ifdef ENETRESET
849  case ROAR_ERROR_CONNRSTNET:
850    errno = ENETRESET;
851   break;
852#endif
853#ifdef ECONNABORTED
854  case ROAR_ERROR_CONNABORTED:
855    errno = ECONNABORTED;
856   break;
857#endif
858
859  default:
860#ifdef EINVAL
861    errno = EINVAL;
862#else
863    errno = -1; // just guess
864#endif
865   break;
866 }
867}
868
869// Resets the stored state to 'no error' state. This can be used
870// to init the state.
871int    roar_err_initstore(struct roar_error_state * state) {
872 struct roar_error_state curstate;
873
874 if ( state == NULL ) {
875  roar_err_set(ROAR_ERROR_FAULT);
876  return -1;
877 }
878
879 roar_err_store(&curstate);
880 roar_err_clear_all();
881 roar_err_store(state);
882 roar_err_restore(&curstate);
883
884 return -1;
885}
886
887// store a error state (both libroar and system)
888int    roar_err_store(struct roar_error_state * state) {
889 if ( state == NULL )
890  return ROAR_ERROR_FAULT;
891
892 memset(state, 0, sizeof(struct roar_error_state));
893
894 state->refc          = 0;
895 state->libroar_error = roar_error;
896 state->system_error  = errno;
897
898#ifdef ROAR_TARGET_WIN32
899 state->winsock_error = WSAGetLastError();
900#endif
901#ifdef ROAR_HAVE_VAR_H_ERRNO
902 state->syssock_herror = h_errno;
903#endif
904
905#ifdef __YIFF__
906 state->yiffc_error = yiffc_error;
907#endif
908
909 return ROAR_ERROR_NONE;
910}
911
912// restore error state to values at time of call to roar_err_store()
913int    roar_err_restore(struct roar_error_state * state) {
914 if ( state == NULL )
915  return ROAR_ERROR_FAULT;
916
917 roar_err_set(state->libroar_error);
918 errno = state->system_error;
919
920#ifdef ROAR_TARGET_WIN32
921 WSASetLastError(state->winsock_error);
922#endif
923#ifdef ROAR_HAVE_VAR_H_ERRNO
924 h_errno = state->syssock_herror;
925#endif
926
927#ifdef __YIFF__
928 yiffc_error = state->yiffc_error;
929#endif
930
931 return ROAR_ERROR_NONE;
932}
933
934
935// 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
936
937static const char * roar_error2str_ms(const int error, const char * msg) {
938 static char buf[1024] = "";
939 int num[8];
940 size_t i;
941 int _ra_err = roar_error;
942 int _sys_err = errno;
943
944 for (i = 0; i < (sizeof(num)/sizeof(*num)); i++)
945  num[i] = roar_random_uint32();
946
947 snprintf(buf, sizeof(buf), "\e[44;39;1m\e[2J\e[H"
948                            "                                   RoarAudio\n"
949                            "\n\n"
950                            "Fatal error %.4x: %s\n"
951                            "RA Error: %.4i, Sys Error: %.4i (%s)\n"
952                            "Random numbers:\n"
953                            " A: 0x%.8X B: 0x%.8X\n"
954                            " C: 0x%.8X D: 0x%.8X\n"
955                            " E: 0x%.8X F: 0x%.8X\n"
956                            " G: 0x%.8X H: 0x%.8X\n"
957                            "\n\n"
958                            "\e[0m",
959                            error, msg,
960                            _ra_err, _sys_err, strerror(_sys_err),
961                            num[0], num[1], num[2], num[3], num[4], num[5], num[6], num[7]);
962
963 return buf;
964}
965
966const char * roar_error2str(const int error) {
967 struct roar_libroar_config * config = roar_libroar_get_config();
968 const struct {
969  const int    err;
970  const char * msg;
971 } msgs[] = {
972  {ROAR_ERROR_NONE,        "No error"},
973  {ROAR_ERROR_PERM,        "Operation not permitted"},
974  {ROAR_ERROR_NOENT,       "No such object, file, directory or node"},
975  {ROAR_ERROR_BADMSG,      "Bad message"},
976  {ROAR_ERROR_BUSY,        "Device or resource busy"},
977  {ROAR_ERROR_CONNREFUSED, "Connection refused"},
978  {ROAR_ERROR_NOSYS,       "Function not implemented"},
979  {ROAR_ERROR_NOTSUP,      "Operation not supported"},
980  {ROAR_ERROR_PIPE,        "Broken pipe"},
981  {ROAR_ERROR_PROTO,       "Protocol error"},
982  {ROAR_ERROR_RANGE,       "Result too large or parameter out of range"},
983  {ROAR_ERROR_MSGSIZE,     "Message too long"},
984  {ROAR_ERROR_NOMEM,       "Not enough space"},
985  {ROAR_ERROR_INVAL,       "Invalid argument"},
986  {ROAR_ERROR_ALREADY,     "Connection already in progress"},
987  {ROAR_ERROR_BADRQC,      "Invalid request code"},
988  {ROAR_ERROR_DOM,         "Mathematics argument out of domain of function"},
989  {ROAR_ERROR_EXIST,       "File or object exists"},
990  {ROAR_ERROR_FAULT,       "Bad address"},
991  {ROAR_ERROR_IO,          "I/O-Error"},
992  {ROAR_ERROR_KEYEXPIRED,  "Key has expired"},
993  {ROAR_ERROR_KEYREJECTED, "Key was rejected by service"},
994  {ROAR_ERROR_LOOP,        "Too many recursions"},
995  {ROAR_ERROR_MFILE,       "Too many open files or objects"},
996  {ROAR_ERROR_NAMETOOLONG, "File or object name too long"},
997  {ROAR_ERROR_NODATA,      "No message is available on the read queue"},
998  {ROAR_ERROR_NODEV,       "No such device"},
999  {ROAR_ERROR_NODRV,       "No such driver"},
1000  {ROAR_ERROR_NOSPC,       "No space left on device"},
1001  {ROAR_ERROR_TYPEMM,      "Type missmatch. Object of diffrent type required"},
1002  {ROAR_ERROR_NORSYS,      "Feature not implemented by remote end"},
1003  {ROAR_ERROR_NOTCONN,     "Socket or object not connected"},
1004  {ROAR_ERROR_PROTONOSUP,  "Protocol not supported"},
1005  {ROAR_ERROR_RIO,         "Remote I/O Error"},
1006  {ROAR_ERROR_RO,          "File or object is read only"},
1007  {ROAR_ERROR_TIMEDOUT,    "Connection timed out"},
1008  {ROAR_ERROR_AGAIN,       "Resource temporarily unavailable"},
1009  {ROAR_ERROR_NOISE,       "Line too noisy"},
1010  {ROAR_ERROR_LINKDOWN,    "Physical or logical link down"},
1011  {ROAR_ERROR_INTERRUPTED, "Operation was interruped"},
1012  {ROAR_ERROR_CAUSALITY,   "Causality error"},
1013  {ROAR_ERROR_QUOTA,       "Quota exceeded"},
1014  {ROAR_ERROR_BADLIB,      "Accessing a corrupted shared library"},
1015  {ROAR_ERROR_NOMEDIUM,    "No medium found"},
1016  {ROAR_ERROR_NOTUNIQ,     "Name not unique"},
1017  {ROAR_ERROR_ILLSEQ,      "Illegal byte sequence"},
1018  {ROAR_ERROR_ADDRINUSE,   "Address in use"},
1019  {ROAR_ERROR_HOLE,        "Hole in data"},
1020  {ROAR_ERROR_BADVERSION,  "Bad version"},
1021  {ROAR_ERROR_NSVERSION,   "Not supported version"},
1022  {ROAR_ERROR_BADMAGIC,    "Bad magic number"},
1023  {ROAR_ERROR_LOSTSYNC,    "Lost synchronization"},
1024  {ROAR_ERROR_BADSEEK,     "Can not seek to destination position"},
1025  {ROAR_ERROR_NOSEEK,      "Seeking not supported on resource"},
1026  {ROAR_ERROR_BADCKSUM,    "Data integrity error"},
1027  {ROAR_ERROR_NOHORSE,     "Mount failed"},
1028  {ROAR_ERROR_CHERNOBYL,   "Fatal device error"},
1029  {ROAR_ERROR_NOHUG,       "Device needs love"},
1030  {ROAR_ERROR_TEXTBUSY,    "Text file busy"},
1031  {ROAR_ERROR_NOTEMPTY,    "Directory not empty"},
1032  {ROAR_ERROR_NODEUNREACH, "Node is unreachable"},
1033  {ROAR_ERROR_IDREMOVED,   "Identifier removed"},
1034  {ROAR_ERROR_INPROGRESS,  "Operation in progress"},
1035  {ROAR_ERROR_NOCHILD,     "No child processes or object"},
1036  {ROAR_ERROR_NETUNREACH,  "Network unreachable"},
1037  {ROAR_ERROR_CANCELED,    "Operation canceled"},
1038  {ROAR_ERROR_ISDIR,       "Is a directory"},
1039  {ROAR_ERROR_NOTDIR,      "Not a directory"},
1040  {ROAR_ERROR_BADEXEC,     "Executable file format error"},
1041  {ROAR_ERROR_ISCONN,      "Socket or Object is connected"},
1042  {ROAR_ERROR_DEADLOCK,    "Resource deadlock would occur"},
1043  {ROAR_ERROR_CONNRST,     "Connection reset"},
1044  {ROAR_ERROR_BADFH,       "Bad file handle"},
1045  {ROAR_ERROR_NOTSOCK,     "Not a socket"},
1046  {ROAR_ERROR_TOOMANYARGS, "Argument list too long"},
1047  {ROAR_ERROR_TOOLARGE,    "File or Object too large"},
1048  {ROAR_ERROR_DESTADDRREQ, "Destination address required"},
1049  {ROAR_ERROR_AFNOTSUP,    "Address family not supported"},
1050  {ROAR_ERROR_NOPOWER,     "Operation can not be completed because we are low on power"},
1051  {ROAR_ERROR_USER,        "Error in front of screen"},
1052  {ROAR_ERROR_NFILE,       "Too many filesobjects open in system"},
1053  {ROAR_ERROR_STALE,       "Stale file handle or object"},
1054  {ROAR_ERROR_XDEVLINK,    "Cross-device link"},
1055  {ROAR_ERROR_MLINK,       "Too many links to file or object"},
1056  {ROAR_ERROR_NONET,       "Not connected to any network"},
1057  {ROAR_ERROR_CONNRSTNET,  "Connection reset by network"},
1058  {ROAR_ERROR_CONNABORTED, "Connection aborted"},
1059  {ROAR_ERROR_BADHOST,     "Bad host software or hardware"},
1060  {ROAR_ERROR_SWITCHPROTO, "Switch protocol"},
1061  {ROAR_ERROR_MOVEDPERM,   "Moved Permanently"},
1062  {ROAR_ERROR_MOVEDTEMP,   "Moved Temporary"},
1063  {ROAR_ERROR_USEPROXY,    "Use Proxy server"},
1064  {ROAR_ERROR_SEEOTHER,    "See other resource"},
1065  {ROAR_ERROR_GONE,        "Resource gone"},
1066  {ROAR_ERROR_BADLICENSE,  "Bad License"},
1067  {-1, NULL}
1068 }, msgs_funny[] = {
1069//  {ROAR_ERROR_UNKNOWN,     "Unknown (maybe no) error"},
1070  {ROAR_ERROR_NONE,        "No error, huh?"},
1071  {ROAR_ERROR_PERM,        "Little kitty is not allowed to do this"},
1072  {ROAR_ERROR_NOENT,       "Mouse not found"},
1073//  {ROAR_ERROR_BADMSG,      "Bad message"},
1074  {ROAR_ERROR_BUSY,        "Another kitty is playing with this mouse"},
1075//  {ROAR_ERROR_CONNREFUSED, "Connection refused"},
1076//  {ROAR_ERROR_NOSYS,       "Function not implemented"},
1077//  {ROAR_ERROR_NOTSUP,      "Operation not supported"},
1078  {ROAR_ERROR_PIPE,        "Flood"},
1079//  {ROAR_ERROR_PROTO,       "Protocol error"},
1080//  {ROAR_ERROR_RANGE,       "Result too largegeneral out of range"},
1081//  {ROAR_ERROR_MSGSIZE,     "Message too long"},
1082//  {ROAR_ERROR_NOMEM,       "Not enough space"},
1083//  {ROAR_ERROR_INVAL,       "Invalid argument"},
1084//  {ROAR_ERROR_ALREADY,     "Connection already in progress"},
1085  {ROAR_ERROR_BADRQC,      "Stupid staff"},
1086//  {ROAR_ERROR_DOM,         "Mathematics argument out of domain of function"},
1087//  {ROAR_ERROR_EXIST,       "File or object exists"},
1088//  {ROAR_ERROR_FAULT,       "Bad address"},
1089//  {ROAR_ERROR_IO,          "IO-Error"},
1090//  {ROAR_ERROR_KEYEXPIRED,  "Key has expired"},
1091//  {ROAR_ERROR_KEYREJECTED, "Key was rejected by service"},
1092//  {ROAR_ERROR_LOOP,        "Too many recursions"},
1093//  {ROAR_ERROR_MFILE,       "Too many open files or objects"},
1094  {ROAR_ERROR_NAMETOOLONG, "Staff can not remember long names"},
1095//  {ROAR_ERROR_NODATA,      "No message is available on the read queue"},
1096  {ROAR_ERROR_NODEV,       "No such mouse"},
1097//  {ROAR_ERROR_NODRV,       "No such driver"},
1098  {ROAR_ERROR_NOSPC,       "Too many fish on desk"},
1099//  {ROAR_ERROR_TYPEMM,      "Type missmatch. Object of diffrent type required"},
1100//  {ROAR_ERROR_NORSYS,      "Feature not implemented by remote end"},
1101//  {ROAR_ERROR_NOTCONN,     "Socket or object not connected"},
1102//  {ROAR_ERROR_PROTONOSUP,  "Protocol not supported"},
1103//  {ROAR_ERROR_RIO,         "Remote IO Error"},
1104  {ROAR_ERROR_RO,          "Touching disallowed"},
1105//  {ROAR_ERROR_TIMEDOUT,    "Connection timed out"},
1106//  {ROAR_ERROR_AGAIN,       "Resource temporarily unavailable"},
1107//  {ROAR_ERROR_NOISE,       "Line too noisy"},
1108//  {ROAR_ERROR_LINKDOWN,    "Physical or logical link down"},
1109//  {ROAR_ERROR_INTERRUPTED, "Operation was interruped"},
1110//  {ROAR_ERROR_CAUSALITY,   "Causality error"},
1111//  {ROAR_ERROR_QUOTA,       "Quota exceeded"},
1112//  {ROAR_ERROR_BADLIB,      "Accessing a corrupted shared library"},
1113//  {ROAR_ERROR_NOMEDIUM,    "No medium found"},
1114//  {ROAR_ERROR_NOTUNIQ,     "Name not unique"},
1115//  {ROAR_ERROR_ILLSEQ,      "Illegal byte sequence"},
1116//  {ROAR_ERROR_ADDRINUSE,   "Address in use"},
1117  {ROAR_ERROR_HOLE,        "Hole in wall"},
1118//  {ROAR_ERROR_BADVERSION,  "Bad version"},
1119//  {ROAR_ERROR_NSVERSION,   "Not supported version"},
1120  {ROAR_ERROR_BADMAGIC,    "Magician's fault"},
1121//  {ROAR_ERROR_LOSTSYNC,    "Lost synchronization"},
1122//  {ROAR_ERROR_BADSEEK,     "Can not seek to destination position"},
1123//  {ROAR_ERROR_NOSEEK,      "Seeking not supported on resource"},
1124//  {ROAR_ERROR_BADCKSUM,    "Data integrity error"},
1125  {ROAR_ERROR_NOHORSE,     "No horse"},
1126//  {ROAR_ERROR_CHERNOBYL,   "Fatal device error"},
1127  {ROAR_ERROR_NOHUG,       "No hug"},
1128//  {ROAR_ERROR_TEXTBUSY,    "Text file busy"},
1129//  {ROAR_ERROR_NOTEMPTY,    "Directory not empty"},
1130//  {ROAR_ERROR_NODEUNREACH, "Node is unreachable"},
1131//  {ROAR_ERROR_IDREMOVED,   "Identifier removed"},
1132//  {ROAR_ERROR_INPROGRESS,  "Operation in progress"},
1133//  {ROAR_ERROR_NOCHILD,     "No child processesobject"},
1134//  {ROAR_ERROR_NETUNREACH,  "Network unreachable"},
1135//  {ROAR_ERROR_CANCELED,    "Operation canceled"},
1136//  {ROAR_ERROR_ISDIR,       "Is a directory"},
1137//  {ROAR_ERROR_NOTDIR,      "Not a directory"},
1138//  {ROAR_ERROR_BADEXEC,     "Executable file format error"},
1139//  {ROAR_ERROR_ISCONN,      "Socket/Object is connected"},
1140  {ROAR_ERROR_DEADLOCK,    "Mouse would die"},
1141//  {ROAR_ERROR_CONNRST,     "Connection reset"},
1142//  {ROAR_ERROR_BADFH,       "Bad file handle"},
1143//  {ROAR_ERROR_NOTSOCK,     "Not a socket"},
1144//  {ROAR_ERROR_TOOMANYARGS, "Argument list too long"},
1145//  {ROAR_ERROR_TOOLARGE,    "File/Object too large"},
1146//  {ROAR_ERROR_DESTADDRREQ, "Destination address required"},
1147//  {ROAR_ERROR_AFNOTSUP,    "Address family not supported"},
1148//  {ROAR_ERROR_NOPOWER,     "Operation can not be completed because we are low on power"},
1149//  {ROAR_ERROR_USER,        "Error in front of screen"},
1150//  {ROAR_ERROR_NFILE,       "Too many filesobjects open in system"},
1151//  {ROAR_ERROR_STALE,       "Stale file handle or object"},
1152  {ROAR_ERROR_XDEVLINK,    "Mice tails too short for kinking"},
1153//  {ROAR_ERROR_MLINK,       "Too many links to file or object"},
1154//  {ROAR_ERROR_NONET,       "Not connected to any network"},
1155//  {ROAR_ERROR_CONNRSTNET,  "Connection reset by network"},
1156//  {ROAR_ERROR_CONNABORTED, "Connection aborted"},
1157//  {ROAR_ERROR_BADHOST,     "Bad host software or hardware"},
1158//  {ROAR_ERROR_SWITCHPROTO, "Switch protocol"},
1159//  {ROAR_ERROR_MOVEDPERM,   "Moved Permanently"},
1160//  {ROAR_ERROR_MOVEDTEMP,   "Moved Temporary"},
1161//  {ROAR_ERROR_USEPROXY,    "Use Proxy server"},
1162//  {ROAR_ERROR_SEEOTHER,    "See other resource"},
1163//  {ROAR_ERROR_GONE,        "Resource gone"},
1164  {-1, NULL}
1165 };
1166 int i;
1167
1168 if ( config->opmode == ROAR_LIBROAR_CONFIG_OPMODE_MS ) {
1169  for (i = 0; msgs[i].msg != NULL; i++) {
1170   if ( msgs[i].err == error ) {
1171    return roar_error2str_ms(error, msgs[i].msg);
1172   }
1173  }
1174  return roar_error2str_ms(error, "<<<unknown error>>>");
1175 }
1176
1177 if ( config->opmode == ROAR_LIBROAR_CONFIG_OPMODE_FUNNY )
1178  for (i = 0; msgs_funny[i].msg != NULL; i++)
1179   if ( msgs_funny[i].err == error )
1180    return msgs_funny[i].msg;
1181
1182 for (i = 0; msgs[i].msg != NULL; i++)
1183  if ( msgs[i].err == error )
1184   return msgs[i].msg;
1185
1186 return NULL;
1187}
1188
1189//ll
Note: See TracBrowser for help on using the repository browser.