1 /*
2  * This file is part of the Sofia-SIP package
3  *
4  * Copyright (C) 2005 Nokia Corporation.
5  *
6  * Contact: Pekka Pessi <pekka.pessi@nokia.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  */
24 
25 /**@CFILE su_errno.c errno compatibility
26  *
27  * @author Pekka Pessi <Pekka.Pessi@nokia.com>
28  *
29  * @date Original: Thu Mar 18 19:40:51 1999 pessi
30  * @date Split to su_errno.c: Thu Dec 22 18:37:02 EET 2005 pessi
31  */
32 
33 #include "config.h"
34 
35 #include <sofia-sip/su_errno.h>
36 #include <sofia-sip/su.h>
37 
38 #include <string.h>
39 
40 #if SU_HAVE_WINSOCK
41 
42 #include <stdio.h>
43 
44 /** Get the latest socket error. */
su_errno(void)45 int su_errno(void)
46 {
47   return WSAGetLastError();
48 }
49 
50 /** Set the socket error. */
su_seterrno(int errcode)51 int su_seterrno(int errcode)
52 {
53   WSASetLastError(errcode);
54 
55   return -1;
56 }
57 
su_strerror(int errcode)58 const char *su_strerror(int errcode)
59 {
60   struct errmsg { int no; const char *msg; };
61   static struct errmsg *msgp;
62   static struct errmsg msgs[] = {
63     { 0, "Success" },
64     { WSAEINTR, "Interrupted system call" },
65     { WSAEBADF, "Bad file descriptor" },
66     { WSAEACCES, "Permission denied" },
67     { WSAEFAULT, "Bad address" },
68     { WSAEINVAL, "Invalid argument" },
69     { WSAEMFILE, "Too many open files" },
70     { WSAEWOULDBLOCK, "Another winsock call while a "
71       "blocking function was in progress" },
72     { WSAEINPROGRESS, "Operation now in progress" },
73     { WSAEALREADY, "Operation already in progress" },
74     { WSAENOTSOCK, "Socket operation on non-socket" },
75     { WSAEDESTADDRREQ, "Destination address required" },
76     { WSAEMSGSIZE, "Message too long" },
77     { WSAEPROTOTYPE, "Protocol wrong type for socket" },
78     { WSAENOPROTOOPT, "Protocol not available" },
79     { WSAEPROTONOSUPPORT, "Protocol not supported" },
80     { WSAESOCKTNOSUPPORT, "Socket type not supported" },
81     { WSAEOPNOTSUPP, "Operation not supported" },
82     { WSAEPFNOSUPPORT, "Protocol family not supported" },
83     { WSAEAFNOSUPPORT, "Address family not supported" },
84     { WSAEADDRINUSE, "Address already in use" },
85     { WSAEADDRNOTAVAIL, "Can't assign requested address" },
86     { WSAENETDOWN, "Network is down" },
87     { WSAENETUNREACH, "Network is unreachable" },
88     { WSAENETRESET, "Network dropped connection on reset" },
89     { WSAECONNABORTED, "Software caused connection abort" },
90     { WSAECONNRESET, "Connection reset by peer" },
91     { WSAENOBUFS, "No buffer space available" },
92     { WSAEISCONN, "Socket is already connected" },
93     { WSAENOTCONN, "Socket is not connected" },
94     { WSAESHUTDOWN, "Can't send after socket shutdown" },
95     { WSAETOOMANYREFS, "Too many references: "
96       "can't splice" },
97     { WSAETIMEDOUT, "Operation timed out" },
98     { WSAECONNREFUSED, "Connection refused" },
99     { WSAELOOP, "Too many levels of symbolic links" },
100     { WSAENAMETOOLONG, "File name too long" },
101     { WSAEHOSTDOWN, "Host is down" },
102     { WSAEHOSTUNREACH, "No route to host" },
103     { WSAENOTEMPTY, "Directory not empty" },
104     { WSAEPROCLIM, "Too many processes" },
105     { WSAEUSERS, "Too many users" },
106     { WSAEDQUOT, "Disc quota exceeded" },
107     { WSAESTALE, "Stale NFS file handle" },
108     { WSAEREMOTE, "Too many levels of remote in path" },
109     { WSASYSNOTREADY, "Network subsystem is unvailable" },
110     { WSAVERNOTSUPPORTED, "WinSock version is not "
111       "supported" },
112     { WSANOTINITIALISED, "Successful WSAStartup() not yet "
113       "performed" },
114     { WSAEDISCON, "Graceful shutdown in progress" },
115     /* Resolver errors */
116     { WSAHOST_NOT_FOUND, "No such host is known" },
117     { WSATRY_AGAIN, "Host not found, or server failed" },
118     { WSANO_RECOVERY, "Unexpected server error "
119       "encountered" },
120     { WSANO_DATA, "Valid name without requested data" },
121     { WSANO_ADDRESS, "No address, look for MX record" },
122     { 0, NULL }
123   };
124   static struct errmsg sofia_msgs[] = {
125     { EBADMSG, "Bad message" },
126     { EPROTO, "Protocol error" },
127     { 0, NULL }
128   };
129   static char buf[64];
130 
131   if (errcode < WSABASEERR)
132     return strerror(errcode);
133 
134   if (errcode < 20000)
135     for (msgp = msgs; msgp->msg; msgp++) {
136       if (errcode == msgp->no) {
137 	return msgp->msg;
138       }
139     }
140   else
141     for (msgp = sofia_msgs; msgp->msg; msgp++) {
142       if (errcode == msgp->no) {
143 	return msgp->msg;
144       }
145     }
146 
147   /* This can not overflow, but in other hand, it is not thread-safe */
148   sprintf(buf, "winsock error %d", errcode);
149 
150   return buf;
151 }
152 
153 #else
154 
su_strerror(int errcode)155 const char *su_strerror(int errcode)
156 {
157   return strerror(errcode);
158 }
159 
su_errno(void)160 int su_errno(void) { return errno; }
su_seterrno(int n)161 int su_seterrno(int n) { errno = n; return -1; }
162 
163 #endif /* SU_HAVE_WINSOCK */
164