initial load of upstream version 1.06.32
[xmlrpc-c] / lib / abyss / src / socket.c
1 /*============================================================================
2   socket.c
3 ==============================================================================
4   Implementation of TSocket class: A generic socket over which one can
5   transport an HTTP stream or manage HTTP connections
6 ============================================================================*/
7
8 #include <sys/types.h>
9 #include <assert.h>
10 #include <netinet/in.h>
11 #include <arpa/inet.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14
15 #include "mallocvar.h"
16 #include "xmlrpc-c/util_int.h"
17 #include "xmlrpc-c/abyss.h"
18 #include "xmlrpc-c/util_int.h"
19 #ifdef WIN32
20   #include "socket_win.h"
21 #else
22   #include "socket_unix.h"
23 #endif
24 #include "socket.h"
25
26
27 #ifdef WIN32
28   #include "socket_win.h"
29 #else
30   #include "socket_unix.h"
31 #endif
32
33 #include "socket.h"
34
35
36 static void
37 socketOsInit(abyss_bool * const succeededP) {
38
39 #ifdef WIN32
40     SocketWinInit(succeededP);
41 #else
42     SocketUnixInit(succeededP);
43 #endif
44 }
45
46
47
48 static void
49 socketOsTerm(void) {
50
51 #ifdef WIN32
52     SocketWinTerm();
53 #else
54     SocketUnixTerm();
55 #endif
56 }
57     
58
59
60 abyss_bool SocketTraceIsActive;
61
62 abyss_bool
63 SocketInit(void) {
64     abyss_bool retval;
65
66     socketOsInit(&retval);
67
68     SocketTraceIsActive = (getenv("ABYSS_TRACE_SOCKET") != NULL);
69     if (SocketTraceIsActive)
70         fprintf(stderr, "Abyss socket layer will trace socket traffic "
71                 "due to ABYSS_TRACE_SOCKET environment variable\n");
72
73     return retval;
74 }
75
76
77
78 void
79 SocketTerm(void) {
80
81     socketOsTerm();
82 }
83
84
85
86 /* SocketCreate() is not exported to the Abyss user.  It is meant to
87    be used by an implementation-specific TSocket generator which is
88    exported to the Abyss user, e.g. SocketCreateUnix() in
89    socket_unix.c
90
91    The TSocket generator functions are the _only_ user-accessible
92    functions that are particular to an implementation.
93 */
94
95 static uint const socketSignature = 0x060609;
96
97 void
98 SocketCreate(const struct TSocketVtbl * const vtblP,
99              void *                     const implP,
100              TSocket **                 const socketPP) {
101
102     TSocket * socketP;
103
104     MALLOCVAR(socketP);
105
106     if (socketP) {
107         socketP->implP = implP;
108         socketP->vtbl = *vtblP;
109         socketP->signature = socketSignature;
110         *socketPP = socketP;
111     }
112 }
113
114
115
116 void
117 SocketDestroy(TSocket * const socketP) {
118
119     assert(socketP->signature == socketSignature);
120
121     socketP->vtbl.destroy(socketP);
122
123     socketP->signature = 0;  /* For debuggability */
124
125     free(socketP);
126 }
127
128
129
130 void
131 SocketWrite(TSocket *             const socketP,
132             const unsigned char * const buffer,
133             uint32_t              const len,
134             abyss_bool *          const failedP) {
135
136     (*socketP->vtbl.write)(socketP, buffer, len, failedP );
137 }
138
139
140
141 uint32_t
142 SocketRead(TSocket *       const socketP, 
143            unsigned char * const buffer, 
144            uint32_t        const len) {
145     
146     return (*socketP->vtbl.read)(socketP, buffer, len);
147 }
148
149
150
151 abyss_bool
152 SocketConnect(TSocket * const socketP,
153               TIPAddr * const addrP,
154               uint16_t  const portNumber) {
155
156     return (*socketP->vtbl.connect)(socketP, addrP, portNumber);
157 }
158
159
160
161 abyss_bool
162 SocketBind(TSocket * const socketP,
163            TIPAddr * const addrP,
164            uint16_t  const portNumber) {
165
166     return (*socketP->vtbl.bind)(socketP, addrP, portNumber);
167 }
168
169
170
171 abyss_bool
172 SocketListen(TSocket * const socketP,
173              uint32_t  const backlog) {
174
175     return (*socketP->vtbl.listen)(socketP, backlog);
176 }
177
178
179
180 void
181 SocketAccept(TSocket *    const listenSocketP,
182              abyss_bool * const connectedP,
183              abyss_bool * const failedP,
184              TSocket **   const acceptedSocketPP,
185              TIPAddr *    const ipAddrP) {
186
187     (*listenSocketP->vtbl.accept)(listenSocketP,
188                                   connectedP,
189                                   failedP,
190                                   acceptedSocketPP,
191                                   ipAddrP);
192 }
193
194
195
196 uint32_t
197 SocketWait(TSocket *  const socketP,
198            abyss_bool const rd,
199            abyss_bool const wr,
200            uint32_t   const timems) {
201
202     return (*socketP->vtbl.wait)(socketP, rd, wr, timems);
203 }
204
205
206
207 uint32_t
208 SocketAvailableReadBytes(TSocket * const socketP) {
209
210     return (*socketP->vtbl.availableReadBytes)(socketP);
211 }
212
213
214
215 void
216 SocketGetPeerName(TSocket *    const socketP,
217                   TIPAddr *    const ipAddrP,
218                   uint16_t *   const portNumberP,
219                   abyss_bool * const successP) {
220
221     (*socketP->vtbl.getPeerName)(socketP, ipAddrP, portNumberP, successP);
222 }
223
224
225
226 uint32_t
227 SocketError(TSocket * const socketP) {
228
229     return (*socketP->vtbl.error)(socketP);
230 }