Reformat whole codebase with astyle.options (#128)
[openjpeg.git] / src / lib / openjpip / sock_manager.c
1 /*
2  * $Id$
3  *
4  * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
5  * Copyright (c) 2002-2014, Professor Benoit Macq
6  * Copyright (c) 2010-2011, Kaori Hagihara
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #ifdef _WIN32
32 #include <windows.h>
33 typedef SSIZE_T ssize_t;
34 #else
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <arpa/inet.h>
38 #include <unistd.h>
39 #endif
40
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include "sock_manager.h"
45
46 #ifdef SERVER
47 #include "fcgi_stdio.h"
48 #define logstream FCGI_stdout
49 #else
50 #define FCGI_stdout stdout
51 #define FCGI_stderr stderr
52 #define logstream stderr
53 #endif /*SERVER*/
54
55 SOCKET open_listeningsocket(uint16_t port)
56 {
57     SOCKET listening_socket;
58     struct sockaddr_in sin;
59     int sock_optval = 1;
60
61     listening_socket = socket(AF_INET, SOCK_STREAM, 0);
62     if (listening_socket == -1) {
63         perror("socket");
64         exit(1);
65     }
66
67     if (setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR,
68                    (const char *)&sock_optval, sizeof(sock_optval)) == -1) {
69         perror("setsockopt");
70         exit(1);
71     }
72
73     memset(&sin, 0, sizeof(sin));
74     sin.sin_family = AF_INET;
75     sin.sin_port = htons(port);
76     sin.sin_addr.s_addr = htonl(INADDR_ANY);
77
78     if (bind(listening_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
79         perror("bind");
80         close_socket(listening_socket);
81         exit(1);
82     }
83
84     if (listen(listening_socket, SOMAXCONN) == -1) {
85         perror("listen");
86         close_socket(listening_socket);
87         exit(1);
88     }
89     fprintf(FCGI_stderr, "port %d is listened\n", port);
90
91     return listening_socket;
92 }
93
94 SOCKET accept_socket(SOCKET listening_socket)
95 {
96     struct sockaddr_in peer_sin;
97     unsigned int addrlen = sizeof(peer_sin);
98
99     return accept(listening_socket, (struct sockaddr *)&peer_sin, &addrlen);
100 }
101
102 void send_stream(SOCKET connected_socket, const void *stream, OPJ_SIZE_T length)
103 {
104     char *ptr = (char*)stream;
105     OPJ_SIZE_T remlen = length;
106
107     while (remlen > 0) {
108         ssize_t sentlen = send(connected_socket, ptr, remlen, 0);
109         if (sentlen == -1) {
110             fprintf(FCGI_stderr, "sending stream error\n");
111             break;
112         }
113         remlen = remlen - (OPJ_SIZE_T)sentlen;
114         ptr = ptr + sentlen;
115     }
116 }
117
118 void * receive_stream(SOCKET connected_socket, OPJ_SIZE_T length)
119 {
120     char *stream, *ptr;
121     OPJ_SIZE_T remlen;
122
123     ptr = stream = malloc(length);
124     remlen = length;
125
126     while (remlen > 0) {
127         ssize_t redlen = recv(connected_socket, ptr, remlen, 0);
128         if (redlen == -1) {
129             fprintf(FCGI_stderr, "receive stream error\n");
130             free(stream);
131             stream = NULL;
132             break;
133         }
134         remlen -= (OPJ_SIZE_T)redlen;
135         ptr = ptr + redlen;
136     }
137     return stream;
138 }
139
140 OPJ_SIZE_T receive_line(SOCKET connected_socket, char *p)
141 {
142     OPJ_SIZE_T len = 0;
143     while (1) {
144         ssize_t ret;
145         ret = recv(connected_socket, p, 1, 0);
146         if (ret == -1) {
147             perror("receive");
148             exit(1);
149         } else if (ret == 0) {
150             break;
151         }
152         if (*p == '\n') {
153             break;
154         }
155         p++;
156         len++;
157     }
158     *p = '\0';
159
160     if (len == 0) {
161         fprintf(FCGI_stderr, "Header receive error\n");
162     }
163
164     return len;
165 }
166
167 char * receive_string(SOCKET connected_socket)
168 {
169     char buf[BUF_LEN];
170
171     /* MM FIXME: there is a nasty bug here, size of buf if BUF_LEN which is never
172     indicated to downstream receive_line */
173     receive_line(connected_socket, buf);
174
175     return strdup(buf);
176 }
177
178 int close_socket(SOCKET sock)
179 {
180 #ifdef _WIN32
181     return closesocket(sock);
182 #else
183     return close(sock);
184 #endif
185 }