//error.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2012 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" // 'no error' value for errno. // zero is true for GNU/Linux. // don't know about other systems. // IEEE Std 1003.1-2008 (POSIX 7) requires: // 'distinct positive values'. #define CLEAN_ERRNO 0 static int roar_errno = ROAR_ERROR_NONE; struct roar_error_frame * roar_err_errorframe(void) { static struct roar_error_frame frame = { .version = 0, .cmd = -1, .ra_errno = ROAR_ERROR_UNKNOWN, .ra_suberrno = -1, .p_errno = -1, .flags = 0, .datalen = 0, .data = NULL }; return &frame; } int roar_err_init(struct roar_error_frame * frame) { if ( frame == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(frame, 0, sizeof(struct roar_error_frame)); frame->cmd = -1; frame->ra_errno = ROAR_ERROR_UNKNOWN; frame->ra_suberrno = -1; frame->p_errno = -1; frame->datalen = 0; frame->data = NULL; return 0; } void * roar_err_buildmsg(struct roar_message * mes, void ** data, struct roar_error_frame * frame) { char * databuf = NULL; int16_t * d; size_t datalen; if ( mes == NULL || frame == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } if ( data != NULL ) *data = NULL; datalen = 8 + frame->datalen; if ( datalen > LIBROAR_BUFFER_MSGDATA ) { if ( data == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } roar_err_clear_errno(); *data = roar_mm_malloc(datalen); roar_err_from_errno(); if ( *data == NULL ) return NULL; databuf = *data; } else { databuf = mes->data; } memset(mes, 0, sizeof(struct roar_message)); memset(databuf, 0, mes->datalen); mes->datalen = datalen; d = (int16_t*)databuf; frame->data = &(databuf[8]); databuf[0] = 0; // version. databuf[1] = frame->cmd; databuf[2] = frame->ra_errno; databuf[3] = frame->ra_suberrno; d[2] = ROAR_HOST2NET16(frame->p_errno); d[3] = ROAR_HOST2NET16(frame->flags); return frame->data; } int roar_err_parsemsg(struct roar_message * mes, void * data, struct roar_error_frame * frame) { char * databuf = (char *)data; int16_t * d; ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?", mes, (int)mes->datalen, mes->data, data, frame); if ( mes == NULL || frame == NULL ) { roar_err_set(ROAR_ERROR_FAULT); ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = -1 // error=FAULT", mes, (int)mes->datalen, mes->data, data, frame); return -1; } ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?", mes, (int)mes->datalen, mes->data, data, frame); if ( databuf == NULL ) databuf = mes->data; d = (int16_t*)databuf; ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?", mes, (int)mes->datalen, mes->data, data, frame); if ( mes->datalen < 8 ) { roar_err_set(ROAR_ERROR_MSGSIZE); ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = -1 // error=MSGSIZE", mes, (int)mes->datalen, mes->data, data, frame); return -1; } ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?", mes, (int)mes->datalen, mes->data, data, frame); if ( databuf[0] != 0 ) { roar_err_set(ROAR_ERROR_NSVERSION); ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = -1 // error=NSVERSION", mes, (int)mes->datalen, mes->data, data, frame); return -1; } ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?", mes, (int)mes->datalen, mes->data, data, frame); frame->cmd = databuf[1]; frame->ra_errno = databuf[2]; frame->ra_suberrno = databuf[3]; frame->p_errno = ROAR_NET2HOST16(d[2]); frame->flags = ROAR_NET2HOST16(d[3]); frame->datalen = mes->datalen - 8; frame->data = &(databuf[8]); ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = 0", mes, (int)mes->datalen, mes->data, data, frame); return 0; } #define roar_errno2_impl (&roar_errno) int * roar_errno2(void) { return roar_errno2_impl; } void roar_err_clear(void) { *roar_errno2_impl = ROAR_ERROR_NONE; } void roar_err_clear_errno(void) { errno = CLEAN_ERRNO; } void roar_err_clear_all(void) { roar_err_clear(); roar_err_clear_errno(); } void roar_err_update(void) { int * err = roar_errno2_impl; // NOTE: _NEVER_ call ROAR_{DBG,INFO,WARN,ERR}() in here! (will result in endless loop) //printf("*err=%i, errno=%i\n", *err, (int)errno); if ( *err != ROAR_ERROR_NONE ) { roar_err_to_errno(); } else if ( !roar_err_is_errno_clear() ) { roar_err_from_errno(); #ifdef ROAR_TARGET_WIN32 } else { roar_err_convert(err, ROAR_ERROR_TYPE_ROARAUDIO, WSAGetLastError(), ROAR_ERROR_TYPE_WINSOCK); roar_err_to_errno(); #endif } } int roar_err_is_errno_clear(void) { return errno == CLEAN_ERRNO ? 1 : 0; } void roar_err_set(const int error) { *roar_errno2_impl = error; } static int __errno_to_roar(int error) { int _roar_errno = ROAR_ERROR_NONE; switch (error) { #ifdef EACCES case EACCES: _roar_errno = ROAR_ERROR_PERM; break; #endif #ifdef EPERM case EPERM: _roar_errno = ROAR_ERROR_PERM; break; #endif #ifdef ENOENT case ENOENT: _roar_errno = ROAR_ERROR_NOENT; break; #endif #ifdef EBADMSG case EBADMSG: _roar_errno = ROAR_ERROR_BADMSG; break; #endif #ifdef EBUSY case EBUSY: _roar_errno = ROAR_ERROR_BUSY; break; #endif #ifdef ECONNREFUSED case ECONNREFUSED: _roar_errno = ROAR_ERROR_CONNREFUSED; break; #endif #ifdef ENOSYS case ENOSYS: _roar_errno = ROAR_ERROR_NOSYS; break; #endif #ifdef ENOTSUP case ENOTSUP: _roar_errno = ROAR_ERROR_NOTSUP; break; #endif #ifdef EPIPE case EPIPE: _roar_errno = ROAR_ERROR_PIPE; break; #endif #ifdef EPROTO case EPROTO: _roar_errno = ROAR_ERROR_PROTO; break; #endif #ifdef ERANGE case ERANGE: _roar_errno = ROAR_ERROR_RANGE; break; #endif #ifdef EMSGSIZE case EMSGSIZE: _roar_errno = ROAR_ERROR_MSGSIZE; break; #endif #ifdef ENOMEM case ENOMEM: _roar_errno = ROAR_ERROR_NOMEM; break; #endif #ifdef EINVAL case EINVAL: _roar_errno = ROAR_ERROR_INVAL; break; #endif #ifdef EALREADY case EALREADY: _roar_errno = ROAR_ERROR_ALREADY; break; #endif #ifdef EBADRQC case EBADRQC: _roar_errno = ROAR_ERROR_BADRQC; break; #endif #ifdef EDOM case EDOM: _roar_errno = ROAR_ERROR_DOM; break; #endif #ifdef EEXIST case EEXIST: _roar_errno = ROAR_ERROR_EXIST; break; #endif #ifdef EFAULT case EFAULT: _roar_errno = ROAR_ERROR_FAULT; break; #endif #ifdef EIO case EIO: _roar_errno = ROAR_ERROR_IO; break; #endif #ifdef EREMOTEIO case EREMOTEIO: _roar_errno = ROAR_ERROR_RIO; break; #endif #ifdef EKEYEXPIRED case EKEYEXPIRED: _roar_errno = ROAR_ERROR_KEYEXPIRED; break; #endif #ifdef EKEYREJECTED case EKEYREJECTED: _roar_errno = ROAR_ERROR_KEYREJECTED; break; #endif #ifdef ELOOP case ELOOP: _roar_errno = ROAR_ERROR_LOOP; break; #endif #ifdef EMFILE case EMFILE: _roar_errno = ROAR_ERROR_MFILE; break; #endif #ifdef ENAMETOOLONG case ENAMETOOLONG: _roar_errno = ROAR_ERROR_NAMETOOLONG; break; #endif #ifdef ENODATA case ENODATA: _roar_errno = ROAR_ERROR_NODATA; break; #endif #ifdef ENODEV case ENODEV: _roar_errno = ROAR_ERROR_NODEV; break; #endif #ifdef ENOSPC case ENOSPC: _roar_errno = ROAR_ERROR_NOSPC; break; #endif #ifdef ENOTCONN case ENOTCONN: _roar_errno = ROAR_ERROR_NOTCONN; break; #endif #ifdef EPROTONOSUPPORT case EPROTONOSUPPORT: _roar_errno = ROAR_ERROR_PROTONOSUP; break; #endif #ifdef EROFS case EROFS: _roar_errno = ROAR_ERROR_RO; break; #endif #ifdef ETIMEDOUT case ETIMEDOUT: _roar_errno = ROAR_ERROR_TIMEDOUT; break; #endif #ifdef EAGAIN case EAGAIN: _roar_errno = ROAR_ERROR_AGAIN; break; #endif #ifdef ENETDOWN case ENETDOWN: _roar_errno = ROAR_ERROR_LINKDOWN; break; #endif #ifdef EINTR case EINTR: _roar_errno = ROAR_ERROR_INTERRUPTED; break; #endif #ifdef EDQUOT case EDQUOT: _roar_errno = ROAR_ERROR_QUOTA; break; #endif #ifdef ELIBBAD case ELIBBAD: _roar_errno = ROAR_ERROR_BADLIB; break; #endif #ifdef ENOMEDIUM case ENOMEDIUM: _roar_errno = ROAR_ERROR_NOMEDIUM; break; #endif #ifdef ENOTUNIQ case ENOTUNIQ: _roar_errno = ROAR_ERROR_NOTUNIQ; break; #endif #ifdef EILSEQ case EILSEQ: _roar_errno = ROAR_ERROR_ILLSEQ; break; #endif #ifdef EADDRINUSE case EADDRINUSE: _roar_errno = ROAR_ERROR_ADDRINUSE; break; #endif #ifdef ESPIPE case ESPIPE: _roar_errno = ROAR_ERROR_BADSEEK; break; #endif #ifdef ECHERNOBYL case ECHERNOBYL: _roar_errno = ROAR_ERROR_CHERNOBYL; break; #endif #ifdef ECRAY case ECRAY: _roar_errno = ROAR_ERROR_CAUSALITY; break; #endif #ifdef ENOHORSE case ENOHORSE: _roar_errno = ROAR_ERROR_NOHORSE; break; #endif #ifdef ETXTBSY case ETXTBSY: _roar_errno = ROAR_ERROR_TEXTBUSY; break; #endif #ifdef ENOTEMPTY case ENOTEMPTY: _roar_errno = ROAR_ERROR_NOTEMPTY; break; #endif #ifdef EHOSTUNREACH case EHOSTUNREACH: _roar_errno = ROAR_ERROR_NODEUNREACH; break; #endif #ifdef EIDRM case EIDRM: _roar_errno = ROAR_ERROR_IDREMOVED; break; #endif #ifdef EINPROGRESS case EINPROGRESS: _roar_errno = ROAR_ERROR_INPROGRESS; break; #endif #ifdef ECHILD case ECHILD: _roar_errno = ROAR_ERROR_NOCHILD; break; #endif #ifdef ENETUNREACH case ENETUNREACH: _roar_errno = ROAR_ERROR_NETUNREACH; break; #endif #ifdef ECANCELED case ECANCELED: _roar_errno = ROAR_ERROR_CANCELED; break; #endif #ifdef EISDIR case EISDIR: _roar_errno = ROAR_ERROR_ISDIR; break; #endif #ifdef ENOTDIR case ENOTDIR: _roar_errno = ROAR_ERROR_NOTDIR; break; #endif #ifdef ENOEXEC case ENOEXEC: _roar_errno = ROAR_ERROR_BADEXEC; break; #endif #ifdef EISCONN case EISCONN: _roar_errno = ROAR_ERROR_ISCONN; break; #endif #ifdef EDEADLK case EDEADLK: _roar_errno = ROAR_ERROR_DEADLOCK; break; #endif #ifdef ECONNRESET case ECONNRESET: _roar_errno = ROAR_ERROR_CONNRST; break; #endif #ifdef EBADF case EBADF: _roar_errno = ROAR_ERROR_BADFH; break; #endif #ifdef ENOTSOCK case ENOTSOCK: _roar_errno = ROAR_ERROR_NOTSOCK; break; #endif #ifdef E2BIG case E2BIG: _roar_errno = ROAR_ERROR_TOOMANYARGS; break; #endif #ifdef EFBIG case EFBIG: _roar_errno = ROAR_ERROR_TOOLARGE; break; #endif #ifdef EDESTADDRREQ case EDESTADDRREQ: _roar_errno = ROAR_ERROR_DESTADDRREQ; break; #endif #ifdef EAFNOSUPPORT case EAFNOSUPPORT: _roar_errno = ROAR_ERROR_AFNOTSUP; break; #endif #ifdef ENFILE case ENFILE: _roar_errno = ROAR_ERROR_NFILE; break; #endif #ifdef ESTALE case ESTALE: _roar_errno = ROAR_ERROR_STALE; break; #endif #ifdef EXDEV case EXDEV: _roar_errno = ROAR_ERROR_XDEVLINK; break; #endif #ifdef EMLINK case EMLINK: _roar_errno = ROAR_ERROR_MLINK; break; #endif #ifdef ENONET case ENONET: _roar_errno = ROAR_ERROR_NONET; break; #endif #ifdef ENETRESET case ENETRESET: _roar_errno = ROAR_ERROR_CONNRSTNET; break; #endif #ifdef ECONNABORTED case ECONNABORTED: _roar_errno = ROAR_ERROR_CONNABORTED; break; #endif default: _roar_errno = ROAR_ERROR_UNKNOWN; break; } return _roar_errno; } void roar_err_from_errno(void) { roar_err_set(__errno_to_roar(errno)); } static int __roar_to_errno(int error) { switch (error) { case ROAR_ERROR_NONE: return CLEAN_ERRNO; break; #ifdef EPERM case ROAR_ERROR_PERM: return EPERM; break; #endif #ifdef ENOENT case ROAR_ERROR_NOENT: return ENOENT; break; #endif #ifdef EBADMSG case ROAR_ERROR_BADMSG: return EBADMSG; break; #endif #ifdef EBUSY case ROAR_ERROR_BUSY: return EBUSY; break; #endif #ifdef ECONNREFUSED case ROAR_ERROR_CONNREFUSED: return ECONNREFUSED; break; #endif #ifdef ENOSYS case ROAR_ERROR_NOSYS: return ENOSYS; break; #endif #ifdef ENOTSUP case ROAR_ERROR_NOTSUP: return ENOTSUP; break; #endif #ifdef EPIPE case ROAR_ERROR_PIPE: return EPIPE; break; #endif #ifdef EPROTO case ROAR_ERROR_PROTO: return EPROTO; break; #endif #ifdef ERANGE case ROAR_ERROR_RANGE: return ERANGE; break; #endif #ifdef EMSGSIZE case ROAR_ERROR_MSGSIZE: return EMSGSIZE; break; #endif #ifdef ENOMEM case ROAR_ERROR_NOMEM: return ENOMEM; break; #endif #ifdef EINVAL case ROAR_ERROR_INVAL: return EINVAL; break; #endif #ifdef EALREADY case ROAR_ERROR_ALREADY: return EALREADY; break; #endif #ifdef EBADRQC case ROAR_ERROR_BADRQC: return EBADRQC; break; #endif #ifdef EDOM case ROAR_ERROR_DOM: return EDOM; break; #endif #ifdef EEXIST case ROAR_ERROR_EXIST: return EEXIST; break; #endif #ifdef EFAULT case ROAR_ERROR_FAULT: return EFAULT; break; #endif #if defined(EREMOTEIO) || defined(EIO) case ROAR_ERROR_RIO: #ifdef EREMOTEIO return EREMOTEIO; #else return EIO; #endif break; #endif #ifdef EIO case ROAR_ERROR_IO: case ROAR_ERROR_HOLE: case ROAR_ERROR_BADCKSUM: case ROAR_ERROR_LOSTSYNC: case ROAR_ERROR_NOHORSE: return EIO; break; #endif #ifdef EKEYEXPIRED case ROAR_ERROR_KEYEXPIRED: return EKEYEXPIRED; break; #endif #ifdef EKEYREJECTED case ROAR_ERROR_KEYREJECTED: return EKEYREJECTED; break; #endif #ifdef ELOOP case ROAR_ERROR_LOOP: return ELOOP; break; #endif #ifdef EMFILE case ROAR_ERROR_MFILE: return EMFILE; break; #endif #ifdef ENAMETOOLONG case ROAR_ERROR_NAMETOOLONG: return ENAMETOOLONG; break; #endif #ifdef ENODATA case ROAR_ERROR_NODATA: return ENODATA; break; #endif #ifdef ENODEV case ROAR_ERROR_NODEV: case ROAR_ERROR_NODRV: return ENODEV; break; #endif #ifdef ENOSPC case ROAR_ERROR_NOSPC: return ENOSPC; break; #endif #ifdef EINVAL case ROAR_ERROR_TYPEMM: return EINVAL; break; #endif #ifdef ENOSYS case ROAR_ERROR_NORSYS: return ENOSYS; break; #endif #ifdef ENOTCONN case ROAR_ERROR_NOTCONN: return ENOTCONN; break; #endif #ifdef EPROTONOSUPPORT case ROAR_ERROR_PROTONOSUP: return EPROTONOSUPPORT; break; #endif #ifdef EROFS case ROAR_ERROR_RO: return EROFS; break; #endif #ifdef ETIMEDOUT case ROAR_ERROR_TIMEDOUT: return ETIMEDOUT; break; #endif #ifdef EAGAIN case ROAR_ERROR_AGAIN: return EAGAIN; break; #endif #ifdef ENETDOWN case ROAR_ERROR_LINKDOWN: return ENETDOWN; break; #endif #ifdef EINTR case ROAR_ERROR_INTERRUPTED: return EINTR; break; #endif #ifdef EDQUOT case ROAR_ERROR_QUOTA: return EDQUOT; break; #endif #ifdef ELIBBAD case ROAR_ERROR_BADLIB: return ELIBBAD; break; #endif #ifdef ENOMEDIUM case ROAR_ERROR_NOMEDIUM: return ENOMEDIUM; break; #endif #ifdef ENOTUNIQ case ROAR_ERROR_NOTUNIQ: return ENOTUNIQ; break; #endif #ifdef EILSEQ case ROAR_ERROR_ILLSEQ: return EILSEQ; break; #endif #ifdef EADDRINUSE case ROAR_ERROR_ADDRINUSE: return EADDRINUSE; break; #endif #ifdef ESPIPE case ROAR_ERROR_BADSEEK: case ROAR_ERROR_NOSEEK: return ESPIPE; break; #endif #ifdef ECHERNOBYL case ROAR_ERROR_CHERNOBYL: return ECHERNOBYL; break; #endif #ifdef ECRAY case ROAR_ERROR_CAUSALITY: return ECRAY; break; #endif #ifdef ENOHORSE case ROAR_ERROR_NOHORSE: return ENOHORSE; break; #endif #ifdef ETXTBSY case ROAR_ERROR_TEXTBUSY: return ETXTBSY; break; #endif #ifdef ENOTEMPTY case ROAR_ERROR_NOTEMPTY: return ENOTEMPTY; break; #endif #ifdef EHOSTUNREACH case ROAR_ERROR_NODEUNREACH: return EHOSTUNREACH; break; #endif #ifdef EIDRM case ROAR_ERROR_IDREMOVED: return EIDRM; break; #endif #ifdef EINPROGRESS case ROAR_ERROR_INPROGRESS: return EINPROGRESS; break; #endif #ifdef ECHILD case ROAR_ERROR_NOCHILD: return ECHILD; break; #endif #ifdef ENETUNREACH case ROAR_ERROR_NETUNREACH: return ENETUNREACH; break; #endif #ifdef ECANCELED case ROAR_ERROR_CANCELED: return ECANCELED; break; #endif #ifdef EISDIR case ROAR_ERROR_ISDIR: return EISDIR; break; #endif #ifdef ENOTDOR case ROAR_ERROR_NOTDIR: return ENOTDIR; break; #endif #ifdef ENOEXEC case ROAR_ERROR_BADEXEC: return ENOEXEC; break; #endif #ifdef EISCONN case ROAR_ERROR_ISCONN: return EISCONN; break; #endif #ifdef EDEADLK case ROAR_ERROR_DEADLOCK: return EDEADLK; break; #endif #ifdef ECONNRESET case ROAR_ERROR_CONNRST: return ECONNRESET; break; #endif #ifdef EBADF case ROAR_ERROR_BADFH: return EBADF; break; #endif #ifdef ENOTSOCK case ROAR_ERROR_NOTSOCK: return ENOTSOCK; break; #endif #ifdef E2BIG case ROAR_ERROR_TOOMANYARGS: return E2BIG; break; #endif #ifdef EFBIG case ROAR_ERROR_TOOLARGE: return EFBIG; break; #endif #ifdef EDESTADDRREQ case ROAR_ERROR_DESTADDRREQ: return EDESTADDRREQ; break; #endif #ifdef EAFNOSUPPORT case ROAR_ERROR_AFNOTSUP: return EAFNOSUPPORT; break; #endif // FIXME.... #ifdef ENOPOWER case ROAR_ERROR_NOPOWER: return ENOPOWER; break; #endif #ifdef EUSER case ROAR_ERROR_USER: return EUSER; break; #endif #ifdef ENFILE case ROAR_ERROR_NFILE: return ENFILE; break; #endif #ifdef ESTALE case ROAR_ERROR_STALE: return ESTALE; break; #endif #ifdef EXDEV case ROAR_ERROR_XDEVLINK: return EXDEV; break; #endif #ifdef EMLINK case ROAR_ERROR_MLINK: return EMLINK; break; #endif #ifdef ENONET case ROAR_ERROR_NONET: return ENONET; break; #endif #ifdef ENETRESET case ROAR_ERROR_CONNRSTNET: return ENETRESET; break; #endif #ifdef ECONNABORTED case ROAR_ERROR_CONNABORTED: return ECONNABORTED; break; #endif default: #ifdef EINVAL return EINVAL; #else return -1; // just guess #endif break; } } void roar_err_to_errno(void) { errno = __roar_to_errno(roar_error); } static const struct error_table_entry { const enum roar_error_type type; const int error; const int roarerror; } __libroar_error_table[] = { {ROAR_ERROR_TYPE_HTTP, 200, ROAR_ERROR_NONE}, {ROAR_ERROR_TYPE_HTTP, 301, ROAR_ERROR_MOVEDPERM}, {ROAR_ERROR_TYPE_HTTP, 303, ROAR_ERROR_SEEOTHER}, {ROAR_ERROR_TYPE_HTTP, 305, ROAR_ERROR_USEPROXY}, {ROAR_ERROR_TYPE_HTTP, 307, ROAR_ERROR_MOVEDTEMP}, {ROAR_ERROR_TYPE_HTTP, 400, ROAR_ERROR_INVAL}, {ROAR_ERROR_TYPE_HTTP, 403, ROAR_ERROR_PERM}, {ROAR_ERROR_TYPE_HTTP, 404, ROAR_ERROR_NOENT}, {ROAR_ERROR_TYPE_HTTP, 408, ROAR_ERROR_TIMEDOUT}, {ROAR_ERROR_TYPE_HTTP, 410, ROAR_ERROR_GONE}, {ROAR_ERROR_TYPE_HTTP, 423, ROAR_ERROR_BUSY}, {ROAR_ERROR_TYPE_HTTP, 426, ROAR_ERROR_SWITCHPROTO}, {ROAR_ERROR_TYPE_HTTP, 501, ROAR_ERROR_NOSYS}, {ROAR_ERROR_TYPE_HTTP, 504, ROAR_ERROR_TIMEDOUT}, {ROAR_ERROR_TYPE_HTTP, 505, ROAR_ERROR_NSVERSION}, {ROAR_ERROR_TYPE_HTTP, 507, ROAR_ERROR_NOSPC}, #ifdef NETDB_SUCCESS {ROAR_ERROR_TYPE_HERROR, NETDB_SUCCESS, ROAR_ERROR_NONE}, #endif #ifdef HOST_NOT_FOUND {ROAR_ERROR_TYPE_HERROR, HOST_NOT_FOUND, ROAR_ERROR_NOENT}, #endif #ifdef TRY_AGAIN {ROAR_ERROR_TYPE_HERROR, TRY_AGAIN, ROAR_ERROR_AGAIN}, #endif #ifdef NO_RECOVERY // {ROAR_ERROR_TYPE_HERROR, NO_RECOVERY, ROAR_ERROR_???}, #endif #ifdef NO_DATA {ROAR_ERROR_TYPE_HERROR, NO_DATA, ROAR_ERROR_NODATA}, #endif #ifdef NO_ADDRESS {ROAR_ERROR_TYPE_HERROR, NO_ADDRESS, ROAR_ERROR_NOENT}, #endif #ifdef ROAR_TARGET_WIN32 {ROAR_ERROR_TYPE_WINSOCK, WSA_INVALID_HANDLE, ROAR_ERROR_BADFH}, {ROAR_ERROR_TYPE_WINSOCK, WSA_NOT_ENOUGH_MEMORY, ROAR_ERROR_NOMEM}, {ROAR_ERROR_TYPE_WINSOCK, WSA_INVALID_PARAMETER, ROAR_ERROR_INVAL}, {ROAR_ERROR_TYPE_WINSOCK, WSA_OPERATION_ABORTED, ROAR_ERROR_INTERRUPTED}, // {ROAR_ERROR_TYPE_WINSOCK, WSA_IO_INCOMPLETE, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSA_IO_PENDING, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAEINTR, ROAR_ERROR_INTERRUPTED}, {ROAR_ERROR_TYPE_WINSOCK, WSAEBADF, ROAR_ERROR_BADFH}, {ROAR_ERROR_TYPE_WINSOCK, WSAEACCES, ROAR_ERROR_PERM}, {ROAR_ERROR_TYPE_WINSOCK, WSAEFAULT, ROAR_ERROR_FAULT}, {ROAR_ERROR_TYPE_WINSOCK, WSAEINVAL, ROAR_ERROR_INVAL}, {ROAR_ERROR_TYPE_WINSOCK, WSAEMFILE, ROAR_ERROR_MFILE}, {ROAR_ERROR_TYPE_WINSOCK, WSAEWOULDBLOCK, ROAR_ERROR_AGAIN}, {ROAR_ERROR_TYPE_WINSOCK, WSAEINPROGRESS, ROAR_ERROR_INPROGRESS}, {ROAR_ERROR_TYPE_WINSOCK, WSAEALREADY, ROAR_ERROR_ALREADY}, {ROAR_ERROR_TYPE_WINSOCK, WSAENOTSOCK, ROAR_ERROR_NOTSOCK}, {ROAR_ERROR_TYPE_WINSOCK, WSAEDESTADDRREQ, ROAR_ERROR_DESTADDRREQ}, {ROAR_ERROR_TYPE_WINSOCK, WSAEMSGSIZE, ROAR_ERROR_MSGSIZE}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEPROTOTYPE, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAENOPROTOOPT, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAEPROTONOSUPPORT, ROAR_ERROR_PROTONOSUP}, {ROAR_ERROR_TYPE_WINSOCK, WSAESOCKTNOSUPPORT, ROAR_ERROR_PROTONOSUP}, {ROAR_ERROR_TYPE_WINSOCK, WSAEOPNOTSUPP, ROAR_ERROR_NOTSUP}, {ROAR_ERROR_TYPE_WINSOCK, WSAEPFNOSUPPORT, ROAR_ERROR_AFNOTSUP}, {ROAR_ERROR_TYPE_WINSOCK, WSAEAFNOSUPPORT, ROAR_ERROR_AFNOTSUP}, {ROAR_ERROR_TYPE_WINSOCK, WSAEADDRINUSE, ROAR_ERROR_ADDRINUSE}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEADDRNOTAVAIL, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAENETDOWN, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAENETUNREACH, ROAR_ERROR_NETUNREACH}, // {ROAR_ERROR_TYPE_WINSOCK, WSAENETRESET, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAECONNABORTED, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAECONNRESET, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAENOBUFS, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAEISCONN, ROAR_ERROR_ISCONN}, {ROAR_ERROR_TYPE_WINSOCK, WSAENOTCONN, ROAR_ERROR_NOTCONN}, // {ROAR_ERROR_TYPE_WINSOCK, WSAESHUTDOWN, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAETOOMANYREFS, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAETIMEDOUT, ROAR_ERROR_TIMEDOUT}, {ROAR_ERROR_TYPE_WINSOCK, WSAECONNREFUSED, ROAR_ERROR_CONNREFUSED}, {ROAR_ERROR_TYPE_WINSOCK, WSAELOOP, ROAR_ERROR_LOOP}, {ROAR_ERROR_TYPE_WINSOCK, WSAENAMETOOLONG, ROAR_ERROR_NAMETOOLONG}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEHOSTDOWN, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAEHOSTUNREACH, ROAR_ERROR_NODEUNREACH}, {ROAR_ERROR_TYPE_WINSOCK, WSAENOTEMPTY, ROAR_ERROR_NOTEMPTY}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEPROCLIM, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEUSERS, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEDQUOT, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAESTALE, ROAR_ERROR_STALE}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEREMOTE, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSASYSNOTREADY, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAVERNOTSUPPORTED, ROAR_ERROR_NSVERSION}, // {ROAR_ERROR_TYPE_WINSOCK, WSANOTINITIALISED, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEDISCON, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAENOMORE, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAECANCELLED, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEINVALIDPROCTABLE, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEINVALIDPROVIDER, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEPROVIDERFAILEDINIT, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSASYSCALLFAILURE, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSASERVICE_NOT_FOUND, ROAR_ERROR_NOENT}, {ROAR_ERROR_TYPE_WINSOCK, WSATYPE_NOT_FOUND, ROAR_ERROR_NOENT}, {ROAR_ERROR_TYPE_WINSOCK, WSA_E_NO_MORE, ROAR_ERROR_NOENT}, // {ROAR_ERROR_TYPE_WINSOCK, WSA_E_CANCELLED, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEREFUSED, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAHOST_NOT_FOUND, ROAR_ERROR_NOENT}, {ROAR_ERROR_TYPE_WINSOCK, WSATRY_AGAIN, ROAR_ERROR_AGAIN}, // {ROAR_ERROR_TYPE_WINSOCK, WSANO_RECOVERY, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSANO_DATA, ROAR_ERROR_NODATA}, #if 0 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_RECEIVERS, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_SENDERS, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_NO_SENDERS, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_NO_RECEIVERS, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_REQUEST_CONFIRMED, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ADMISSION_FAILURE, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_POLICY_FAILURE, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_BAD_STYLE, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_BAD_OBJECT, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_TRAFFIC_CTRL_ERROR, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_GENERIC_ERROR, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESERVICETYPE, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWSPEC, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPROVSPECBUF, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERSTYLE, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERTYPE, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERCOUNT, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EOBJLENGTH, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWCOUNT, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EUNKOWNPSOBJ, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPOLICYOBJ, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWDESC, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPSFLOWSPEC, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPSFILTERSPEC, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESDMODEOBJ, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESHAPERATEOBJ, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_RESERVED_PETYPE, ROAR_ERROR_???}, #endif #endif {ROAR_ERROR_TYPE_EAI, 0 /* defined value, see manpage */, ROAR_ERROR_NONE}, #ifdef EAI_ADDRFAMILY {ROAR_ERROR_TYPE_EAI, EAI_ADDRFAMILY, ROAR_ERROR_NOENT}, #endif #ifdef EAI_AGAIN {ROAR_ERROR_TYPE_EAI, EAI_AGAIN, ROAR_ERROR_AGAIN}, #endif #ifdef EAI_BADFLAGS {ROAR_ERROR_TYPE_EAI, EAI_BADFLAGS, ROAR_ERROR_INVAL}, #endif #ifdef EAI_FAIL {ROAR_ERROR_TYPE_EAI, EAI_FAIL, ROAR_ERROR_RIO}, #endif #ifdef EAI_FAMILY {ROAR_ERROR_TYPE_EAI, EAI_FAMILY, ROAR_ERROR_AFNOTSUP}, #endif #ifdef EAI_MEMORY {ROAR_ERROR_TYPE_EAI, EAI_MEMORY, ROAR_ERROR_NOMEM}, #endif #ifdef EAI_NODATA {ROAR_ERROR_TYPE_EAI, EAI_NODATA, ROAR_ERROR_NODATA}, #endif #ifdef EAI_NONAME {ROAR_ERROR_TYPE_EAI, EAI_NONAME, ROAR_ERROR_NOENT}, #endif #ifdef EAI_SERVICE {ROAR_ERROR_TYPE_EAI, EAI_SERVICE, ROAR_ERROR_PROTONOSUP}, #endif #ifdef EAI_SOCKTYPE {ROAR_ERROR_TYPE_EAI, EAI_SOCKTYPE, ROAR_ERROR_INVAL}, #endif #ifdef EAI_SYSTEM // {ROAR_ERROR_TYPE_EAI, EAI_SYSTEM, ROAR_ERROR_???}, #endif }; static int roar_err_convert_table_lookup(const struct error_table_entry ** match, const int error, const enum roar_error_type type, const int to_roar) { size_t i; // we have the following loop to times as an inner if() would cost more cycles // than the outer if we currently have. if ( to_roar ) { for (i = 0; i < (sizeof(__libroar_error_table)/sizeof(*__libroar_error_table)); i++) { if ( __libroar_error_table[i].type == type && __libroar_error_table[i].error == error) { *match = &(__libroar_error_table[i]); return ROAR_ERROR_NONE; } } } else { for (i = 0; i < (sizeof(__libroar_error_table)/sizeof(*__libroar_error_table)); i++) { if ( __libroar_error_table[i].type == type && __libroar_error_table[i].roarerror == error) { *match = &(__libroar_error_table[i]); return ROAR_ERROR_NONE; } } } return ROAR_ERROR_NOENT; } // Convert error codes between diffrent representations. // returnes the error or ROAR_ERROR_NONE on success so it does not alter global error state. int roar_err_convert(int * out, const enum roar_error_type outtype, const int in, const enum roar_error_type intype) { const struct error_table_entry * tablematch; int tmp; int ret; if ( out == NULL ) return ROAR_ERROR_FAULT; if ( outtype == intype ) { *out = in; return ROAR_ERROR_NONE; } // if not to/from roar, use roar as temp type so we do only need to code two kinds of translators (not any->any). if ( intype != ROAR_ERROR_TYPE_ROARAUDIO && outtype != ROAR_ERROR_TYPE_ROARAUDIO ) { ret = roar_err_convert(&tmp, ROAR_ERROR_TYPE_ROARAUDIO, in, intype); if ( ret != ROAR_ERROR_NONE ) return ret; return roar_err_convert(out, outtype, tmp, ROAR_ERROR_TYPE_ROARAUDIO); } // from here we can asume that if intype != ROAR_ERROR_TYPE_ROARAUDIO outtype is ROAR_ERROR_TYPE_ROARAUDIO // and the other way around. if ( intype == ROAR_ERROR_TYPE_ROARAUDIO ) { ret = roar_err_convert_table_lookup(&tablematch, in, outtype, 0); } else { ret = roar_err_convert_table_lookup(&tablematch, in, intype, 1); } if ( ret == ROAR_ERROR_NONE ) { *out = intype == ROAR_ERROR_TYPE_ROARAUDIO ? tablematch->error : tablematch->roarerror; return ROAR_ERROR_NONE; } if ( intype == ROAR_ERROR_TYPE_ROARAUDIO && outtype == ROAR_ERROR_TYPE_ERRNO ) { // the __roar_to_errno() function always succeeds. *out = __roar_to_errno(in); return ROAR_ERROR_NONE; } if ( outtype == ROAR_ERROR_TYPE_ROARAUDIO && intype == ROAR_ERROR_TYPE_ERRNO ) { // the __errno_to_roar() function always succeeds. *out = __errno_to_roar(in); return ROAR_ERROR_NONE; } roar_err_get_default_error(out, outtype); return ROAR_ERROR_NOENT; } // Outputs a default error for the given type. // returnes the error or ROAR_ERROR_NONE on success so it does not alter global error state. int roar_err_get_default_error(int * out, const enum roar_error_type type) { int is_set = 0; if ( out == NULL ) return ROAR_ERROR_FAULT; switch (type) { case ROAR_ERROR_TYPE_ROARAUDIO: is_set = 1; *out = ROAR_ERROR_UNKNOWN; break; #ifdef EINVAL case ROAR_ERROR_TYPE_ERRNO: is_set = 1; *out = EINVAL; break; #endif #ifdef NO_RECOVERY case ROAR_ERROR_TYPE_HERROR: is_set = 1; *out = NO_RECOVERY; break; #endif #ifdef __YIFF__ case ROAR_ERROR_TYPE_YIFF: is_set = 1; *out = YIFF_ERRNO_UNKNOWN; break; #endif case ROAR_ERROR_TYPE_HTTP: is_set = 1; *out = 500; break; #ifndef DEBUG // enable compiler warnings in DEBUG mode. default: break; #endif } if ( is_set ) { return ROAR_ERROR_NONE; } *out = -1; // some default so we do not leave it uninited. return ROAR_ERROR_NOENT; } // Resets the stored state to 'no error' state. This can be used // to init the state. int roar_err_initstore(struct roar_error_state * state) { struct roar_error_state curstate; if ( state == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } roar_err_store(&curstate); roar_err_clear_all(); roar_err_store(state); roar_err_restore(&curstate); return -1; } // store a error state (both libroar and system) int roar_err_store(struct roar_error_state * state) { if ( state == NULL ) return ROAR_ERROR_FAULT; memset(state, 0, sizeof(struct roar_error_state)); state->refc = 0; state->libroar_error = roar_error; state->system_error = errno; #ifdef ROAR_TARGET_WIN32 state->winsock_error = WSAGetLastError(); #endif #ifdef ROAR_HAVE_VAR_H_ERRNO state->syssock_herror = h_errno; #endif #ifdef __YIFF__ state->yiffc_error = yiffc_error; #endif return ROAR_ERROR_NONE; } // restore error state to values at time of call to roar_err_store() int roar_err_restore(struct roar_error_state * state) { if ( state == NULL ) return ROAR_ERROR_FAULT; roar_err_set(state->libroar_error); errno = state->system_error; #ifdef ROAR_TARGET_WIN32 WSASetLastError(state->winsock_error); #endif #ifdef ROAR_HAVE_VAR_H_ERRNO h_errno = state->syssock_herror; #endif #ifdef __YIFF__ yiffc_error = state->yiffc_error; #endif return ROAR_ERROR_NONE; } // 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 static const char * roar_error2str_ms(const int error, const char * msg) { static char buf[1024] = ""; int num[8]; size_t i; int _ra_err = roar_error; int _sys_err = errno; for (i = 0; i < (sizeof(num)/sizeof(*num)); i++) num[i] = roar_random_uint32(); snprintf(buf, sizeof(buf), "\e[44;39;1m\e[2J\e[H" " RoarAudio\n" "\n\n" "Fatal error %.4x: %s\n" "RA Error: %.4i, Sys Error: %.4i (%s)\n" "Random numbers:\n" " A: 0x%.8X B: 0x%.8X\n" " C: 0x%.8X D: 0x%.8X\n" " E: 0x%.8X F: 0x%.8X\n" " G: 0x%.8X H: 0x%.8X\n" "\n\n" "\e[0m", error, msg, _ra_err, _sys_err, strerror(_sys_err), num[0], num[1], num[2], num[3], num[4], num[5], num[6], num[7]); return buf; } const char * roar_error2str(const int error) { struct roar_libroar_config * config = roar_libroar_get_config(); const struct { const int err; const char * msg; } msgs[] = { {ROAR_ERROR_NONE, "No error"}, {ROAR_ERROR_PERM, "Operation not permitted"}, {ROAR_ERROR_NOENT, "No such object, file, directory or node"}, {ROAR_ERROR_BADMSG, "Bad message"}, {ROAR_ERROR_BUSY, "Device or resource busy"}, {ROAR_ERROR_CONNREFUSED, "Connection refused"}, {ROAR_ERROR_NOSYS, "Function not implemented"}, {ROAR_ERROR_NOTSUP, "Operation not supported"}, {ROAR_ERROR_PIPE, "Broken pipe"}, {ROAR_ERROR_PROTO, "Protocol error"}, {ROAR_ERROR_RANGE, "Result too large or parameter out of range"}, {ROAR_ERROR_MSGSIZE, "Message too long"}, {ROAR_ERROR_NOMEM, "Not enough space"}, {ROAR_ERROR_INVAL, "Invalid argument"}, {ROAR_ERROR_ALREADY, "Connection already in progress"}, {ROAR_ERROR_BADRQC, "Invalid request code"}, {ROAR_ERROR_DOM, "Mathematics argument out of domain of function"}, {ROAR_ERROR_EXIST, "File or object exists"}, {ROAR_ERROR_FAULT, "Bad address"}, {ROAR_ERROR_IO, "I/O-Error"}, {ROAR_ERROR_KEYEXPIRED, "Key has expired"}, {ROAR_ERROR_KEYREJECTED, "Key was rejected by service"}, {ROAR_ERROR_LOOP, "Too many recursions"}, {ROAR_ERROR_MFILE, "Too many open files or objects"}, {ROAR_ERROR_NAMETOOLONG, "File or object name too long"}, {ROAR_ERROR_NODATA, "No message is available on the read queue"}, {ROAR_ERROR_NODEV, "No such device"}, {ROAR_ERROR_NODRV, "No such driver"}, {ROAR_ERROR_NOSPC, "No space left on device"}, {ROAR_ERROR_TYPEMM, "Type missmatch. Object of diffrent type required"}, {ROAR_ERROR_NORSYS, "Feature not implemented by remote end"}, {ROAR_ERROR_NOTCONN, "Socket or object not connected"}, {ROAR_ERROR_PROTONOSUP, "Protocol not supported"}, {ROAR_ERROR_RIO, "Remote I/O Error"}, {ROAR_ERROR_RO, "File or object is read only"}, {ROAR_ERROR_TIMEDOUT, "Connection timed out"}, {ROAR_ERROR_AGAIN, "Resource temporarily unavailable"}, {ROAR_ERROR_NOISE, "Line too noisy"}, {ROAR_ERROR_LINKDOWN, "Physical or logical link down"}, {ROAR_ERROR_INTERRUPTED, "Operation was interruped"}, {ROAR_ERROR_CAUSALITY, "Causality error"}, {ROAR_ERROR_QUOTA, "Quota exceeded"}, {ROAR_ERROR_BADLIB, "Accessing a corrupted shared library"}, {ROAR_ERROR_NOMEDIUM, "No medium found"}, {ROAR_ERROR_NOTUNIQ, "Name not unique"}, {ROAR_ERROR_ILLSEQ, "Illegal byte sequence"}, {ROAR_ERROR_ADDRINUSE, "Address in use"}, {ROAR_ERROR_HOLE, "Hole in data"}, {ROAR_ERROR_BADVERSION, "Bad version"}, {ROAR_ERROR_NSVERSION, "Not supported version"}, {ROAR_ERROR_BADMAGIC, "Bad magic number"}, {ROAR_ERROR_LOSTSYNC, "Lost synchronization"}, {ROAR_ERROR_BADSEEK, "Can not seek to destination position"}, {ROAR_ERROR_NOSEEK, "Seeking not supported on resource"}, {ROAR_ERROR_BADCKSUM, "Data integrity error"}, {ROAR_ERROR_NOHORSE, "Mount failed"}, {ROAR_ERROR_CHERNOBYL, "Fatal device error"}, {ROAR_ERROR_NOHUG, "Device needs love"}, {ROAR_ERROR_TEXTBUSY, "Text file busy"}, {ROAR_ERROR_NOTEMPTY, "Directory not empty"}, {ROAR_ERROR_NODEUNREACH, "Node is unreachable"}, {ROAR_ERROR_IDREMOVED, "Identifier removed"}, {ROAR_ERROR_INPROGRESS, "Operation in progress"}, {ROAR_ERROR_NOCHILD, "No child processes or object"}, {ROAR_ERROR_NETUNREACH, "Network unreachable"}, {ROAR_ERROR_CANCELED, "Operation canceled"}, {ROAR_ERROR_ISDIR, "Is a directory"}, {ROAR_ERROR_NOTDIR, "Not a directory"}, {ROAR_ERROR_BADEXEC, "Executable file format error"}, {ROAR_ERROR_ISCONN, "Socket or Object is connected"}, {ROAR_ERROR_DEADLOCK, "Resource deadlock would occur"}, {ROAR_ERROR_CONNRST, "Connection reset"}, {ROAR_ERROR_BADFH, "Bad file handle"}, {ROAR_ERROR_NOTSOCK, "Not a socket"}, {ROAR_ERROR_TOOMANYARGS, "Argument list too long"}, {ROAR_ERROR_TOOLARGE, "File or Object too large"}, {ROAR_ERROR_DESTADDRREQ, "Destination address required"}, {ROAR_ERROR_AFNOTSUP, "Address family not supported"}, {ROAR_ERROR_NOPOWER, "Operation can not be completed because we are low on power"}, {ROAR_ERROR_USER, "Error in front of screen"}, {ROAR_ERROR_NFILE, "Too many filesobjects open in system"}, {ROAR_ERROR_STALE, "Stale file handle or object"}, {ROAR_ERROR_XDEVLINK, "Cross-device link"}, {ROAR_ERROR_MLINK, "Too many links to file or object"}, {ROAR_ERROR_NONET, "Not connected to any network"}, {ROAR_ERROR_CONNRSTNET, "Connection reset by network"}, {ROAR_ERROR_CONNABORTED, "Connection aborted"}, {ROAR_ERROR_BADHOST, "Bad host software or hardware"}, {ROAR_ERROR_SWITCHPROTO, "Switch protocol"}, {ROAR_ERROR_MOVEDPERM, "Moved Permanently"}, {ROAR_ERROR_MOVEDTEMP, "Moved Temporary"}, {ROAR_ERROR_USEPROXY, "Use Proxy server"}, {ROAR_ERROR_SEEOTHER, "See other resource"}, {ROAR_ERROR_GONE, "Resource gone"}, {ROAR_ERROR_BADLICENSE, "Bad License"}, {-1, NULL} }, msgs_funny[] = { // {ROAR_ERROR_UNKNOWN, "Unknown (maybe no) error"}, {ROAR_ERROR_NONE, "No error, huh?"}, {ROAR_ERROR_PERM, "Little kitty is not allowed to do this"}, {ROAR_ERROR_NOENT, "Mouse not found"}, // {ROAR_ERROR_BADMSG, "Bad message"}, {ROAR_ERROR_BUSY, "Another kitty is playing with this mouse"}, // {ROAR_ERROR_CONNREFUSED, "Connection refused"}, // {ROAR_ERROR_NOSYS, "Function not implemented"}, // {ROAR_ERROR_NOTSUP, "Operation not supported"}, {ROAR_ERROR_PIPE, "Flood"}, // {ROAR_ERROR_PROTO, "Protocol error"}, // {ROAR_ERROR_RANGE, "Result too largegeneral out of range"}, // {ROAR_ERROR_MSGSIZE, "Message too long"}, // {ROAR_ERROR_NOMEM, "Not enough space"}, // {ROAR_ERROR_INVAL, "Invalid argument"}, // {ROAR_ERROR_ALREADY, "Connection already in progress"}, {ROAR_ERROR_BADRQC, "Stupid staff"}, // {ROAR_ERROR_DOM, "Mathematics argument out of domain of function"}, // {ROAR_ERROR_EXIST, "File or object exists"}, // {ROAR_ERROR_FAULT, "Bad address"}, // {ROAR_ERROR_IO, "IO-Error"}, // {ROAR_ERROR_KEYEXPIRED, "Key has expired"}, // {ROAR_ERROR_KEYREJECTED, "Key was rejected by service"}, // {ROAR_ERROR_LOOP, "Too many recursions"}, // {ROAR_ERROR_MFILE, "Too many open files or objects"}, {ROAR_ERROR_NAMETOOLONG, "Staff can not remember long names"}, // {ROAR_ERROR_NODATA, "No message is available on the read queue"}, {ROAR_ERROR_NODEV, "No such mouse"}, // {ROAR_ERROR_NODRV, "No such driver"}, {ROAR_ERROR_NOSPC, "Too many fish on desk"}, // {ROAR_ERROR_TYPEMM, "Type missmatch. Object of diffrent type required"}, // {ROAR_ERROR_NORSYS, "Feature not implemented by remote end"}, // {ROAR_ERROR_NOTCONN, "Socket or object not connected"}, // {ROAR_ERROR_PROTONOSUP, "Protocol not supported"}, // {ROAR_ERROR_RIO, "Remote IO Error"}, {ROAR_ERROR_RO, "Touching disallowed"}, // {ROAR_ERROR_TIMEDOUT, "Connection timed out"}, // {ROAR_ERROR_AGAIN, "Resource temporarily unavailable"}, // {ROAR_ERROR_NOISE, "Line too noisy"}, // {ROAR_ERROR_LINKDOWN, "Physical or logical link down"}, // {ROAR_ERROR_INTERRUPTED, "Operation was interruped"}, // {ROAR_ERROR_CAUSALITY, "Causality error"}, // {ROAR_ERROR_QUOTA, "Quota exceeded"}, // {ROAR_ERROR_BADLIB, "Accessing a corrupted shared library"}, // {ROAR_ERROR_NOMEDIUM, "No medium found"}, // {ROAR_ERROR_NOTUNIQ, "Name not unique"}, // {ROAR_ERROR_ILLSEQ, "Illegal byte sequence"}, // {ROAR_ERROR_ADDRINUSE, "Address in use"}, {ROAR_ERROR_HOLE, "Hole in wall"}, // {ROAR_ERROR_BADVERSION, "Bad version"}, // {ROAR_ERROR_NSVERSION, "Not supported version"}, {ROAR_ERROR_BADMAGIC, "Magician's fault"}, // {ROAR_ERROR_LOSTSYNC, "Lost synchronization"}, // {ROAR_ERROR_BADSEEK, "Can not seek to destination position"}, // {ROAR_ERROR_NOSEEK, "Seeking not supported on resource"}, // {ROAR_ERROR_BADCKSUM, "Data integrity error"}, {ROAR_ERROR_NOHORSE, "No horse"}, // {ROAR_ERROR_CHERNOBYL, "Fatal device error"}, {ROAR_ERROR_NOHUG, "No hug"}, // {ROAR_ERROR_TEXTBUSY, "Text file busy"}, // {ROAR_ERROR_NOTEMPTY, "Directory not empty"}, // {ROAR_ERROR_NODEUNREACH, "Node is unreachable"}, // {ROAR_ERROR_IDREMOVED, "Identifier removed"}, // {ROAR_ERROR_INPROGRESS, "Operation in progress"}, // {ROAR_ERROR_NOCHILD, "No child processesobject"}, // {ROAR_ERROR_NETUNREACH, "Network unreachable"}, // {ROAR_ERROR_CANCELED, "Operation canceled"}, // {ROAR_ERROR_ISDIR, "Is a directory"}, // {ROAR_ERROR_NOTDIR, "Not a directory"}, // {ROAR_ERROR_BADEXEC, "Executable file format error"}, // {ROAR_ERROR_ISCONN, "Socket/Object is connected"}, {ROAR_ERROR_DEADLOCK, "Mouse would die"}, // {ROAR_ERROR_CONNRST, "Connection reset"}, // {ROAR_ERROR_BADFH, "Bad file handle"}, // {ROAR_ERROR_NOTSOCK, "Not a socket"}, // {ROAR_ERROR_TOOMANYARGS, "Argument list too long"}, // {ROAR_ERROR_TOOLARGE, "File/Object too large"}, // {ROAR_ERROR_DESTADDRREQ, "Destination address required"}, // {ROAR_ERROR_AFNOTSUP, "Address family not supported"}, // {ROAR_ERROR_NOPOWER, "Operation can not be completed because we are low on power"}, // {ROAR_ERROR_USER, "Error in front of screen"}, // {ROAR_ERROR_NFILE, "Too many filesobjects open in system"}, // {ROAR_ERROR_STALE, "Stale file handle or object"}, {ROAR_ERROR_XDEVLINK, "Mice tails too short for kinking"}, // {ROAR_ERROR_MLINK, "Too many links to file or object"}, // {ROAR_ERROR_NONET, "Not connected to any network"}, // {ROAR_ERROR_CONNRSTNET, "Connection reset by network"}, // {ROAR_ERROR_CONNABORTED, "Connection aborted"}, // {ROAR_ERROR_BADHOST, "Bad host software or hardware"}, // {ROAR_ERROR_SWITCHPROTO, "Switch protocol"}, // {ROAR_ERROR_MOVEDPERM, "Moved Permanently"}, // {ROAR_ERROR_MOVEDTEMP, "Moved Temporary"}, // {ROAR_ERROR_USEPROXY, "Use Proxy server"}, // {ROAR_ERROR_SEEOTHER, "See other resource"}, // {ROAR_ERROR_GONE, "Resource gone"}, {-1, NULL} }; int i; if ( config->opmode == ROAR_LIBROAR_CONFIG_OPMODE_MS ) { for (i = 0; msgs[i].msg != NULL; i++) { if ( msgs[i].err == error ) { return roar_error2str_ms(error, msgs[i].msg); } } return roar_error2str_ms(error, "<<>>"); } if ( config->opmode == ROAR_LIBROAR_CONFIG_OPMODE_FUNNY ) for (i = 0; msgs_funny[i].msg != NULL; i++) if ( msgs_funny[i].err == error ) return msgs_funny[i].msg; for (i = 0; msgs[i].msg != NULL; i++) if ( msgs[i].err == error ) return msgs[i].msg; return NULL; } //ll