~ubuntu-branches/ubuntu/gutsy/psqlodbc/gutsy

« back to all changes in this revision

Viewing changes to socket.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2007-03-05 22:28:19 UTC
  • mfrom: (3.1.4 edgy)
  • Revision ID: james.westby@ubuntu.com-20070305222819-95d0rzmt2ah6dwwc
Tags: 1:08.01.0200-2.1
* Non-maintainer upload.
* High-urgency upload for RC bugfix.
* Fix the signature of SQLGetData on 64-bit architectures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*-------
2
 
 * Module:                      socket.c
3
 
 *
4
 
 * Description:         This module contains functions for low level socket
5
 
 *                                      operations (connecting/reading/writing to the backend)
6
 
 *
7
 
 * Classes:                     SocketClass (Functions prefix: "SOCK_")
8
 
 *
9
 
 * API functions:       none
10
 
 *
11
 
 * Comments:            See "notice.txt" for copyright and license information.
12
 
 *-------
13
 
 */
14
 
 
15
 
#include "socket.h"
16
 
 
17
 
#include "connection.h"
18
 
 
19
 
#ifndef WIN32
20
 
#include <stdlib.h>
21
 
#include <string.h>                             /* for memset */
22
 
#endif
23
 
 
24
 
extern GLOBAL_VALUES globals;
25
 
 
26
 
#ifndef BOOL
27
 
#define BOOL    int
28
 
#endif
29
 
#ifndef TRUE
30
 
#define TRUE    (BOOL)1
31
 
#endif
32
 
#ifndef FALSE
33
 
#define FALSE   (BOOL)0
34
 
#endif
35
 
 
36
 
 
37
 
void
38
 
SOCK_clear_error(SocketClass *self)
39
 
{
40
 
        self->errornumber = 0;
41
 
        self->errormsg = NULL;
42
 
}
43
 
 
44
 
 
45
 
SocketClass *
46
 
SOCK_Constructor(const ConnectionClass *conn)
47
 
{
48
 
        SocketClass *rv;
49
 
 
50
 
        rv = (SocketClass *) malloc(sizeof(SocketClass));
51
 
 
52
 
        if (rv != NULL)
53
 
        {
54
 
                rv->socket = (SOCKETFD) - 1;
55
 
                rv->buffer_filled_in = 0;
56
 
                rv->buffer_filled_out = 0;
57
 
                rv->buffer_read_in = 0;
58
 
 
59
 
                if (rv)
60
 
                        rv->buffer_size = conn->connInfo.drivers.socket_buffersize;
61
 
                else
62
 
                        rv->buffer_size = globals.socket_buffersize;
63
 
                rv->buffer_in = (unsigned char *) malloc(rv->buffer_size);
64
 
                if (!rv->buffer_in)
65
 
                {
66
 
                        free(rv);
67
 
                        return NULL;
68
 
                }
69
 
 
70
 
                rv->buffer_out = (unsigned char *) malloc(rv->buffer_size);
71
 
                if (!rv->buffer_out)
72
 
                {
73
 
                        free(rv->buffer_in);
74
 
                        free(rv);
75
 
                        return NULL;
76
 
                }
77
 
                rv->errormsg = NULL;
78
 
                rv->errornumber = 0;
79
 
                rv->reverse = FALSE;
80
 
        }
81
 
        return rv;
82
 
}
83
 
 
84
 
 
85
 
void
86
 
SOCK_Destructor(SocketClass *self)
87
 
{
88
 
        mylog("SOCK_Destructor\n");
89
 
        if (!self)
90
 
                return;
91
 
        if (self->socket != -1)
92
 
        {
93
 
                SOCK_put_char(self, 'X');
94
 
                SOCK_flush_output(self);
95
 
                closesocket(self->socket);
96
 
        }
97
 
 
98
 
        if (self->buffer_in)
99
 
                free(self->buffer_in);
100
 
 
101
 
        if (self->buffer_out)
102
 
                free(self->buffer_out);
103
 
 
104
 
        free(self);
105
 
}
106
 
 
107
 
 
108
 
char
109
 
SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname)
110
 
{
111
 
#if defined (POSIX_MULTITHREAD_SUPPORT)
112
 
    const int bufsz = 8192; 
113
 
    char buf[bufsz];
114
 
    int error = 0;
115
 
    struct hostent host;
116
 
    struct hostent* hp = &host;
117
 
#else
118
 
    struct hostent* hp;
119
 
#endif 
120
 
        unsigned long iaddr;
121
 
 
122
 
        if (self->socket != -1)
123
 
        {
124
 
                self->errornumber = SOCKET_ALREADY_CONNECTED;
125
 
                self->errormsg = "Socket is already connected";
126
 
                return 0;
127
 
        }
128
 
 
129
 
        memset((char *) &(self->sadr), 0, sizeof(self->sadr));
130
 
 
131
 
        /*
132
 
         * If it is a valid IP address, use it. Otherwise use hostname lookup.
133
 
         */
134
 
        iaddr = inet_addr(hostname);
135
 
        if (iaddr == INADDR_NONE)
136
 
        {
137
 
#if defined (POSIX_MULTITHREAD_SUPPORT) 
138
 
  #if defined (HAVE_GETIPNODEBYNAME) /* Free-BSD ? */
139
 
        hp = getipnodebyname(hostname, AF_INET, 0, &error); 
140
 
  #elif defined (PGS_REENTRANT_API_1) /* solaris, irix */
141
 
        hp = gethostbyname_r(hostname, hp, buf, bufsz, &error);
142
 
  #elif defined (PGS_REENTRANT_API_2) /* linux */
143
 
        int result = 0;
144
 
        result = gethostbyname_r(hostname, hp, buf, bufsz, &hp, &error);
145
 
        if (result)
146
 
          hp = 0;
147
 
  #else
148
 
        hp = gethostbyname(hostname);
149
 
  #endif
150
 
#else
151
 
        hp = gethostbyname(hostname);
152
 
#endif
153
 
                if (hp == NULL)
154
 
                {
155
 
                        self->errornumber = SOCKET_HOST_NOT_FOUND;
156
 
                        self->errormsg = "Could not resolve hostname.";
157
 
                        return 0;
158
 
                }
159
 
                memcpy(&(self->sadr.sin_addr), hp->h_addr, hp->h_length);
160
 
        }
161
 
        else
162
 
                memcpy(&(self->sadr.sin_addr), (struct in_addr *) & iaddr, sizeof(iaddr));
163
 
 
164
 
#if defined (HAVE_GETIPNODEBYNAME)
165
 
        freehostent(hp);
166
 
#endif /* HAVE_GETIPNODEBYNAME */
167
 
        self->sadr.sin_family = AF_INET;
168
 
        self->sadr.sin_port = htons(port);
169
 
 
170
 
        self->socket = socket(AF_INET, SOCK_STREAM, 0);
171
 
        if (self->socket == -1)
172
 
        {
173
 
                self->errornumber = SOCKET_COULD_NOT_CREATE_SOCKET;
174
 
                self->errormsg = "Could not create Socket.";
175
 
                return 0;
176
 
        }
177
 
 
178
 
        if (connect(self->socket, (struct sockaddr *) & (self->sadr),
179
 
                                sizeof(self->sadr)) < 0)
180
 
        {
181
 
                self->errornumber = SOCKET_COULD_NOT_CONNECT;
182
 
                self->errormsg = "Could not connect to remote socket.";
183
 
                closesocket(self->socket);
184
 
                self->socket = (SOCKETFD) - 1;
185
 
                return 0;
186
 
        }
187
 
        return 1;
188
 
}
189
 
 
190
 
 
191
 
void
192
 
SOCK_get_n_char(SocketClass *self, char *buffer, int len)
193
 
{
194
 
        int                     lf;
195
 
 
196
 
        if (!self)
197
 
                return;
198
 
        if (!buffer)
199
 
        {
200
 
                self->errornumber = SOCKET_NULLPOINTER_PARAMETER;
201
 
                self->errormsg = "get_n_char was called with NULL-Pointer";
202
 
                return;
203
 
        }
204
 
 
205
 
        for (lf = 0; lf < len; lf++)
206
 
                buffer[lf] = SOCK_get_next_byte(self);
207
 
}
208
 
 
209
 
 
210
 
void
211
 
SOCK_put_n_char(SocketClass *self, char *buffer, int len)
212
 
{
213
 
        int                     lf;
214
 
 
215
 
        if (!self)
216
 
                return;
217
 
        if (!buffer)
218
 
        {
219
 
                self->errornumber = SOCKET_NULLPOINTER_PARAMETER;
220
 
                self->errormsg = "put_n_char was called with NULL-Pointer";
221
 
                return;
222
 
        }
223
 
 
224
 
        for (lf = 0; lf < len; lf++)
225
 
                SOCK_put_next_byte(self, (unsigned char) buffer[lf]);
226
 
}
227
 
 
228
 
 
229
 
/*
230
 
 *      bufsize must include room for the null terminator
231
 
 *      will read at most bufsize-1 characters + null.
232
 
 *      returns TRUE if truncation occurs.
233
 
 */
234
 
BOOL
235
 
SOCK_get_string(SocketClass *self, char *buffer, int bufsize)
236
 
{
237
 
        register int lf = 0;
238
 
 
239
 
        for (lf = 0; lf < bufsize - 1; lf++)
240
 
                if (!(buffer[lf] = SOCK_get_next_byte(self)))
241
 
                        return FALSE;
242
 
 
243
 
        buffer[bufsize - 1] = '\0';
244
 
        return TRUE;
245
 
}
246
 
 
247
 
 
248
 
void
249
 
SOCK_put_string(SocketClass *self, char *string)
250
 
{
251
 
        register int lf;
252
 
        int                     len;
253
 
 
254
 
        len = strlen(string) + 1;
255
 
 
256
 
        for (lf = 0; lf < len; lf++)
257
 
                SOCK_put_next_byte(self, (unsigned char) string[lf]);
258
 
}
259
 
 
260
 
 
261
 
int
262
 
SOCK_get_int(SocketClass *self, short len)
263
 
{
264
 
        if (!self)
265
 
                return 0;
266
 
        switch (len)
267
 
        {
268
 
                case 2:
269
 
                        {
270
 
                                unsigned short buf;
271
 
 
272
 
                                SOCK_get_n_char(self, (char *) &buf, len);
273
 
                                if (self->reverse)
274
 
                                        return buf;
275
 
                                else
276
 
                                        return ntohs(buf);
277
 
                        }
278
 
 
279
 
                case 4:
280
 
                        {
281
 
                                unsigned int buf;
282
 
 
283
 
                                SOCK_get_n_char(self, (char *) &buf, len);
284
 
                                if (self->reverse)
285
 
                                        return buf;
286
 
                                else
287
 
                                        return ntohl(buf);
288
 
                        }
289
 
 
290
 
                default:
291
 
                        self->errornumber = SOCKET_GET_INT_WRONG_LENGTH;
292
 
                        self->errormsg = "Cannot read ints of that length";
293
 
                        return 0;
294
 
        }
295
 
}
296
 
 
297
 
 
298
 
void
299
 
SOCK_put_int(SocketClass *self, int value, short len)
300
 
{
301
 
        unsigned int rv;
302
 
 
303
 
        if (!self)
304
 
                return;
305
 
        switch (len)
306
 
        {
307
 
                case 2:
308
 
                        rv = self->reverse ? value : htons((unsigned short) value);
309
 
                        SOCK_put_n_char(self, (char *) &rv, 2);
310
 
                        return;
311
 
 
312
 
                case 4:
313
 
                        rv = self->reverse ? value : htonl((unsigned int) value);
314
 
                        SOCK_put_n_char(self, (char *) &rv, 4);
315
 
                        return;
316
 
 
317
 
                default:
318
 
                        self->errornumber = SOCKET_PUT_INT_WRONG_LENGTH;
319
 
                        self->errormsg = "Cannot write ints of that length";
320
 
                        return;
321
 
        }
322
 
}
323
 
 
324
 
 
325
 
void
326
 
SOCK_flush_output(SocketClass *self)
327
 
{
328
 
        int                     written;
329
 
 
330
 
        if (!self)
331
 
                return;
332
 
        written = send(self->socket, (char *) self->buffer_out, self->buffer_filled_out, 0);
333
 
        if (written != self->buffer_filled_out)
334
 
        {
335
 
                self->errornumber = SOCKET_WRITE_ERROR;
336
 
                self->errormsg = "Could not flush socket buffer.";
337
 
        }
338
 
        self->buffer_filled_out = 0;
339
 
}
340
 
 
341
 
 
342
 
unsigned char
343
 
SOCK_get_next_byte(SocketClass *self)
344
 
{
345
 
        if (!self)
346
 
                return 0;
347
 
        if (self->buffer_read_in >= self->buffer_filled_in)
348
 
        {
349
 
                /*
350
 
                 * there are no more bytes left in the buffer so reload the buffer
351
 
                 */
352
 
                self->buffer_read_in = 0;
353
 
                self->buffer_filled_in = recv(self->socket, (char *) self->buffer_in, self->buffer_size, 0);
354
 
 
355
 
                mylog("read %d, global_socket_buffersize=%d\n", self->buffer_filled_in, self->buffer_size);
356
 
 
357
 
                if (self->buffer_filled_in < 0)
358
 
                {
359
 
                        self->errornumber = SOCKET_READ_ERROR;
360
 
                        self->errormsg = "Error while reading from the socket.";
361
 
                        self->buffer_filled_in = 0;
362
 
                        return 0;
363
 
                }
364
 
                if (self->buffer_filled_in == 0)
365
 
                {
366
 
                        self->errornumber = SOCKET_CLOSED;
367
 
                        self->errormsg = "Socket has been closed.";
368
 
                        self->buffer_filled_in = 0;
369
 
                        return 0;
370
 
                }
371
 
        }
372
 
        return self->buffer_in[self->buffer_read_in++];
373
 
}
374
 
 
375
 
 
376
 
void
377
 
SOCK_put_next_byte(SocketClass *self, unsigned char next_byte)
378
 
{
379
 
        int                     bytes_sent;
380
 
 
381
 
        if (!self)
382
 
                return;
383
 
        self->buffer_out[self->buffer_filled_out++] = next_byte;
384
 
 
385
 
        if (self->buffer_filled_out == self->buffer_size)
386
 
        {
387
 
                /* buffer is full, so write it out */
388
 
                bytes_sent = send(self->socket, (char *) self->buffer_out, self->buffer_size, 0);
389
 
                if (bytes_sent != self->buffer_size)
390
 
                {
391
 
                        self->errornumber = SOCKET_WRITE_ERROR;
392
 
                        self->errormsg = "Error while writing to the socket.";
393
 
                }
394
 
                self->buffer_filled_out = 0;
395
 
        }
396
 
}