diff options
| author | Marc G. Fournier <scrappy@hub.org> | 1998-04-13 15:02:05 +0000 |
|---|---|---|
| committer | Marc G. Fournier <scrappy@hub.org> | 1998-04-13 15:02:05 +0000 |
| commit | 9e3382dfc5affce3b653534714343d5e546e1a3e (patch) | |
| tree | e5627cb0e135d52c2e4af55a239795d18ba5e7f9 /src/interfaces/odbc/socket.c | |
| parent | d4d26f9c33791f7aefd667e3688d9a18400006e1 (diff) | |
| download | postgresql-9e3382dfc5affce3b653534714343d5e546e1a3e.tar.gz | |
Replace old PostODBC driver with new one...
This one is based on an older PostODBC driver, rewritten and maintained by
InsightDist(?)
Diffstat (limited to 'src/interfaces/odbc/socket.c')
| -rw-r--r-- | src/interfaces/odbc/socket.c | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/src/interfaces/odbc/socket.c b/src/interfaces/odbc/socket.c new file mode 100644 index 0000000000..40318ea502 --- /dev/null +++ b/src/interfaces/odbc/socket.c @@ -0,0 +1,289 @@ +
+/* 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" + +extern GLOBAL_VALUES globals; + +void +SOCK_clear_error(SocketClass *self) +{ + self->errornumber = 0; + self->errormsg = NULL; +} + +SocketClass * +SOCK_Constructor() +{ +SocketClass *rv; + + rv = (SocketClass *) malloc(sizeof(SocketClass)); + + if (rv != NULL) { + rv->socket = (SOCKET) -1; + rv->buffer_filled_in = 0; + rv->buffer_filled_out = 0; + rv->buffer_read_in = 0; + + rv->buffer_in = (unsigned char *) malloc(globals.socket_buffersize); + if ( ! rv->buffer_in) + return NULL; + + rv->buffer_out = (unsigned char *) malloc(globals.socket_buffersize); + if ( ! rv->buffer_out) + return NULL; + + rv->errormsg = NULL; + rv->errornumber = 0;
+
+ rv->reverse = FALSE; + } + return rv; + +} + +void +SOCK_Destructor(SocketClass *self) +{ + if (self->socket != -1) { + if ( ! shutdown(self->socket, 2)) /* no sends or receives */ + 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; + + if (self->socket != -1) { + self->errornumber = SOCKET_ALREADY_CONNECTED; + self->errormsg = "Socket is already connected"; + return 0; + } + + host = gethostbyname(hostname); + if (host == NULL) { + self->errornumber = SOCKET_HOST_NOT_FOUND; + self->errormsg = "Could not resolve hostname."; + return 0; + } + + memset((char *)&sadr, 0, sizeof(sadr)); + memcpy(&(sadr.sin_addr), host->h_addr, host->h_length); + 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 = (SOCKET) -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. +*/ +void +SOCK_get_string(SocketClass *self, char *buffer, int bufsize) +{ +register int lf = 0; + + for (lf = 0; lf < bufsize; lf++) + if ( ! (buffer[lf] = SOCK_get_next_byte(self))) + return; + + buffer[bufsize-1] = '\0'; +} + + +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) +{ +char buf[4]; + + switch (len) { + case 2: + SOCK_get_n_char(self, buf, len); + if (self->reverse)
+ return *((unsigned short *) buf);
+ else
+ return ntohs( *((unsigned short *) buf) ); + + case 4: + SOCK_get_n_char(self, buf, len);
+ if (self->reverse)
+ return *((unsigned int *) buf);
+ else + return ntohl( *((unsigned int *) 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 -> + // reload the buffer + + self->buffer_read_in = 0; + self->buffer_filled_in = recv(self->socket, (char *)self->buffer_in, globals.socket_buffersize, 0);
+ + mylog("read %d, global_socket_buffersize=%d\n", self->buffer_filled_in, globals.socket_buffersize); + + if (self->buffer_filled_in == -1) { + self->errornumber = SOCKET_READ_ERROR; + self->errormsg = "Error while reading from the socket."; + self->buffer_filled_in = 0; + } + if (self->buffer_filled_in == 0) { + self->errornumber = SOCKET_CLOSED; + self->errormsg = "Socket has been closed."; + self->buffer_filled_in = 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 == globals.socket_buffersize) { + // buffer is full, so write it out + bytes_sent = send(self->socket, (char *)self->buffer_out, globals.socket_buffersize, 0); + if (bytes_sent != globals.socket_buffersize) { + self->errornumber = SOCKET_WRITE_ERROR; + self->errormsg = "Error while writing to the socket."; + } + self->buffer_filled_out = 0; + } +} |
