diff options
| author | Mathieu Malaterre <mathieu.malaterre@gmail.com> | 2012-09-28 08:11:41 +0000 |
|---|---|---|
| committer | Mathieu Malaterre <mathieu.malaterre@gmail.com> | 2012-09-28 08:11:41 +0000 |
| commit | d518970039a19a2a9b6d2bdd592cc88a43897bbb (patch) | |
| tree | 57bac2cf7e63e9352228231062763baac627563c /src/lib/openjpip/sock_manager.c | |
| parent | 8363a6ab1e031bb4b2e40a92e56efd40fdab1aa1 (diff) | |
[trunk] Start FolderReorgProposal task
Update issue 177
Diffstat (limited to 'src/lib/openjpip/sock_manager.c')
| -rw-r--r-- | src/lib/openjpip/sock_manager.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/src/lib/openjpip/sock_manager.c b/src/lib/openjpip/sock_manager.c new file mode 100644 index 00000000..432b03fa --- /dev/null +++ b/src/lib/openjpip/sock_manager.c @@ -0,0 +1,181 @@ +/* + * $Id$ + * + * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2011, Professor Benoit Macq + * Copyright (c) 2010-2011, Kaori Hagihara + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef _WIN32 +#include <windows.h> +#else +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <unistd.h> +#endif + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "sock_manager.h" + +#ifdef SERVER +#include "fcgi_stdio.h" +#define logstream FCGI_stdout +#else +#define FCGI_stdout stdout +#define FCGI_stderr stderr +#define logstream stderr +#endif /*SERVER*/ + +SOCKET open_listeningsocket( uint16_t port) +{ + SOCKET listening_socket; + struct sockaddr_in sin; + int sock_optval = 1; + + listening_socket = socket(AF_INET, SOCK_STREAM, 0); + if ( listening_socket == -1 ){ + perror("socket"); + exit(1); + } + + if ( setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&sock_optval, sizeof(sock_optval)) == -1 ){ + perror("setsockopt"); + exit(1); + } + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + sin.sin_addr.s_addr = htonl(INADDR_ANY); + + if ( bind(listening_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0 ){ + perror("bind"); + close_socket(listening_socket); + exit(1); + } + + if( listen(listening_socket, SOMAXCONN) == -1){ + perror("listen"); + close_socket(listening_socket); + exit(1); + } + fprintf( FCGI_stderr, "port %d is listened\n", port); + + return listening_socket; +} + +SOCKET accept_socket( SOCKET listening_socket) +{ + struct sockaddr_in peer_sin; + unsigned int addrlen = sizeof(peer_sin); + + return accept( listening_socket, (struct sockaddr *)&peer_sin, &addrlen); +} + +void send_stream( SOCKET connected_socket, const void *stream, OPJ_SIZE_T length) +{ + char *ptr = (char*)stream; + OPJ_SIZE_T remlen = length; + + while( remlen > 0){ + ssize_t sentlen = send( connected_socket, ptr, remlen, 0); + if( sentlen == -1){ + fprintf( FCGI_stderr, "sending stream error\n"); + break; + } + remlen = remlen - (OPJ_SIZE_T)sentlen; + ptr = ptr + sentlen; + } +} + +void * receive_stream( SOCKET connected_socket, OPJ_SIZE_T length) +{ + char *stream, *ptr; + OPJ_SIZE_T remlen; + + ptr = stream = malloc( length); + remlen = length; + + while( remlen > 0){ + ssize_t redlen = recv( connected_socket, ptr, remlen, 0); + if( redlen == -1){ + fprintf( FCGI_stderr, "receive stream error\n"); + free( stream); + stream = NULL; + break; + } + remlen -= (OPJ_SIZE_T)redlen; + ptr = ptr + redlen; + } + return stream; +} + +OPJ_SIZE_T receive_line(SOCKET connected_socket, char *p) +{ + OPJ_SIZE_T len = 0; + while (1){ + ssize_t ret; + ret = recv( connected_socket, p, 1, 0); + if ( ret == -1 ){ + perror("receive"); + exit(1); + } else if ( ret == 0 ){ + break; + } + if ( *p == '\n' ) + break; + p++; + len++; + } + *p = '\0'; + + if( len == 0) + fprintf( FCGI_stderr, "Header receive error\n"); + + return len; +} + +char * receive_string( SOCKET connected_socket) +{ + char buf[BUF_LEN]; + + /* MM FIXME: there is a nasty bug here, size of buf if BUF_LEN which is never + indicated to downstream receive_line */ + receive_line( connected_socket, buf); + + return strdup(buf); +} + +int close_socket( SOCKET sock) +{ +#ifdef _WIN32 + return closesocket( sock); +#else + return close( sock); +#endif +} |
