From f43b5de649cdf8a36f7d90a96932800cb0e34162 Mon Sep 17 00:00:00 2001 From: Hiroshi Inoue Date: Fri, 11 Jan 2002 02:50:01 +0000 Subject: Add a directory to save the changes until 7.3-tree is branched. --- src/interfaces/odbc/windev/socket.c | 355 ++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 src/interfaces/odbc/windev/socket.c (limited to 'src/interfaces/odbc/windev/socket.c') diff --git a/src/interfaces/odbc/windev/socket.c b/src/interfaces/odbc/windev/socket.c new file mode 100644 index 00000000000..031a6779cba --- /dev/null +++ b/src/interfaces/odbc/windev/socket.c @@ -0,0 +1,355 @@ +/*------- + * Module: socket.c + * + * Description: This module contains functions for low level socket + * operations (connecting/reading/writing to the backend) + * + * Classes: SocketClass (Functions prefix: "SOCK_") + * + * API functions: none + * + * Comments: See "notice.txt" for copyright and license information. + *------- + */ + +#include "socket.h" + +#include "connection.h" + +#ifndef WIN32 +#include +#include /* for memset */ +#endif + +extern GLOBAL_VALUES globals; + +#ifndef BOOL +#define BOOL int +#endif +#ifndef TRUE +#define TRUE (BOOL)1 +#endif +#ifndef FALSE +#define FALSE (BOOL)0 +#endif + + +void +SOCK_clear_error(SocketClass *self) +{ + self->errornumber = 0; + self->errormsg = NULL; +} + + +SocketClass * +SOCK_Constructor(const ConnectionClass *conn) +{ + SocketClass *rv; + + rv = (SocketClass *) malloc(sizeof(SocketClass)); + + if (rv != NULL) + { + rv->socket = (SOCKETFD) - 1; + rv->buffer_filled_in = 0; + rv->buffer_filled_out = 0; + rv->buffer_read_in = 0; + + if (rv) + rv->buffer_size = conn->connInfo.drivers.socket_buffersize; + else + rv->buffer_size = globals.socket_buffersize; + rv->buffer_in = (unsigned char *) malloc(rv->buffer_size); + if (!rv->buffer_in) + { + free(rv); + return NULL; + } + + rv->buffer_out = (unsigned char *) malloc(rv->buffer_size); + if (!rv->buffer_out) + { + free(rv->buffer_in); + free(rv); + return NULL; + } + rv->errormsg = NULL; + rv->errornumber = 0; + rv->reverse = FALSE; + } + return rv; +} + + +void +SOCK_Destructor(SocketClass *self) +{ + mylog("SOCK_Destructor\n"); + if (self->socket != -1) + { + SOCK_put_char(self, 'X'); + SOCK_flush_output(self); + closesocket(self->socket); + } + + if (self->buffer_in) + free(self->buffer_in); + + if (self->buffer_out) + free(self->buffer_out); + + free(self); +} + + +char +SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname) +{ + struct hostent *host; + struct sockaddr_in sadr; + unsigned long iaddr; + + if (self->socket != -1) + { + self->errornumber = SOCKET_ALREADY_CONNECTED; + self->errormsg = "Socket is already connected"; + return 0; + } + + memset((char *) &sadr, 0, sizeof(sadr)); + + /* + * If it is a valid IP address, use it. Otherwise use hostname lookup. + */ + iaddr = inet_addr(hostname); + if (iaddr == INADDR_NONE) + { + host = gethostbyname(hostname); + if (host == NULL) + { + self->errornumber = SOCKET_HOST_NOT_FOUND; + self->errormsg = "Could not resolve hostname."; + return 0; + } + memcpy(&(sadr.sin_addr), host->h_addr, host->h_length); + } + else + memcpy(&(sadr.sin_addr), (struct in_addr *) & iaddr, sizeof(iaddr)); + + sadr.sin_family = AF_INET; + sadr.sin_port = htons(port); + + self->socket = socket(AF_INET, SOCK_STREAM, 0); + if (self->socket == -1) + { + self->errornumber = SOCKET_COULD_NOT_CREATE_SOCKET; + self->errormsg = "Could not create Socket."; + return 0; + } + + if (connect(self->socket, (struct sockaddr *) & (sadr), + sizeof(sadr)) < 0) + { + self->errornumber = SOCKET_COULD_NOT_CONNECT; + self->errormsg = "Could not connect to remote socket."; + closesocket(self->socket); + self->socket = (SOCKETFD) - 1; + return 0; + } + return 1; +} + + +void +SOCK_get_n_char(SocketClass *self, char *buffer, int len) +{ + int lf; + + if (!buffer) + { + self->errornumber = SOCKET_NULLPOINTER_PARAMETER; + self->errormsg = "get_n_char was called with NULL-Pointer"; + return; + } + + for (lf = 0; lf < len; lf++) + buffer[lf] = SOCK_get_next_byte(self); +} + + +void +SOCK_put_n_char(SocketClass *self, char *buffer, int len) +{ + int lf; + + if (!buffer) + { + self->errornumber = SOCKET_NULLPOINTER_PARAMETER; + self->errormsg = "put_n_char was called with NULL-Pointer"; + return; + } + + for (lf = 0; lf < len; lf++) + SOCK_put_next_byte(self, (unsigned char) buffer[lf]); +} + + +/* + * bufsize must include room for the null terminator + * will read at most bufsize-1 characters + null. + * returns TRUE if truncation occurs. + */ +BOOL +SOCK_get_string(SocketClass *self, char *buffer, int bufsize) +{ + register int lf = 0; + + for (lf = 0; lf < bufsize - 1; lf++) + if (!(buffer[lf] = SOCK_get_next_byte(self))) + return FALSE; + + buffer[bufsize - 1] = '\0'; + return TRUE; +} + + +void +SOCK_put_string(SocketClass *self, char *string) +{ + register int lf; + int len; + + len = strlen(string) + 1; + + for (lf = 0; lf < len; lf++) + SOCK_put_next_byte(self, (unsigned char) string[lf]); +} + + +int +SOCK_get_int(SocketClass *self, short len) +{ + switch (len) + { + case 2: + { + unsigned short buf; + + SOCK_get_n_char(self, (char *) &buf, len); + if (self->reverse) + return buf; + else + return ntohs(buf); + } + + case 4: + { + unsigned int buf; + + SOCK_get_n_char(self, (char *) &buf, len); + if (self->reverse) + return buf; + else + return ntohl(buf); + } + + default: + self->errornumber = SOCKET_GET_INT_WRONG_LENGTH; + self->errormsg = "Cannot read ints of that length"; + return 0; + } +} + + +void +SOCK_put_int(SocketClass *self, int value, short len) +{ + unsigned int rv; + + switch (len) + { + case 2: + rv = self->reverse ? value : htons((unsigned short) value); + SOCK_put_n_char(self, (char *) &rv, 2); + return; + + case 4: + rv = self->reverse ? value : htonl((unsigned int) value); + SOCK_put_n_char(self, (char *) &rv, 4); + return; + + default: + self->errornumber = SOCKET_PUT_INT_WRONG_LENGTH; + self->errormsg = "Cannot write ints of that length"; + return; + } +} + + +void +SOCK_flush_output(SocketClass *self) +{ + int written; + + written = send(self->socket, (char *) self->buffer_out, self->buffer_filled_out, 0); + if (written != self->buffer_filled_out) + { + self->errornumber = SOCKET_WRITE_ERROR; + self->errormsg = "Could not flush socket buffer."; + } + self->buffer_filled_out = 0; +} + + +unsigned char +SOCK_get_next_byte(SocketClass *self) +{ + if (self->buffer_read_in >= self->buffer_filled_in) + { + /* + * there are no more bytes left in the buffer so reload the buffer + */ + self->buffer_read_in = 0; + self->buffer_filled_in = recv(self->socket, (char *) self->buffer_in, self->buffer_size, 0); + + mylog("read %d, global_socket_buffersize=%d\n", self->buffer_filled_in, self->buffer_size); + + if (self->buffer_filled_in < 0) + { + self->errornumber = SOCKET_READ_ERROR; + self->errormsg = "Error while reading from the socket."; + self->buffer_filled_in = 0; + return 0; + } + if (self->buffer_filled_in == 0) + { + self->errornumber = SOCKET_CLOSED; + self->errormsg = "Socket has been closed."; + self->buffer_filled_in = 0; + return 0; + } + } + return self->buffer_in[self->buffer_read_in++]; +} + + +void +SOCK_put_next_byte(SocketClass *self, unsigned char next_byte) +{ + int bytes_sent; + + self->buffer_out[self->buffer_filled_out++] = next_byte; + + if (self->buffer_filled_out == self->buffer_size) + { + /* buffer is full, so write it out */ + bytes_sent = send(self->socket, (char *) self->buffer_out, self->buffer_size, 0); + if (bytes_sent != self->buffer_size) + { + self->errornumber = SOCKET_WRITE_ERROR; + self->errormsg = "Error while writing to the socket."; + } + self->buffer_filled_out = 0; + } +} -- cgit v1.2.3