1 /*
2 TiMidity++ -- MIDI to WAVE converter and player
3 Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
4 Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif /* HAVE_CONFIG_H */
25 #include <stdio.h>
26 #include <stdlib.h>
27 #if !defined(WINSOCK)
28 #include <unistd.h>
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <netdb.h>
33 #include <arpa/inet.h> /* for inet_ntoa */
34 #ifndef NO_STRING_H
35 #include <string.h>
36 #else
37 #include <strings.h>
38 #endif
39 #endif
40
41 #include "timidity.h"
42 #include "common.h"
43 #include "net.h"
44
45 #ifndef INADDR_NONE
46 #define INADDR_NONE 0xffffffff
47 #endif /* INADDR_NONE */
48
49 #if !defined(WINSOCK)
50 #ifndef INVALID_SOCKET
51 #define INVALID_SOCKET -1
52 #endif /* INVALID_SOCKET */
53 #ifndef SOCKET_ERROR
54 #define SOCKET_ERROR -1
55 #endif /* SOCKET_ERROR */
56 #endif
57
58 #ifdef WIN32
59 #if _WIN32_WINNT < 0x0501
60 typedef int (WSAAPI * GETADDRINFO) (const char FAR *, const char FAR *,
61 const struct addrinfo FAR *,
62 struct addrinfo FAR * FAR *);
63
64 typedef void (WSAAPI * FREEADDRINFO) ( struct addrinfo FAR * );
65 extern GETADDRINFO ws2_getaddrinfo;
66 extern FREEADDRINFO ws2_freeaddrinfo;
67 #define getaddrinfo ws2_getaddrinfo
68 #define freeaddrinfo ws2_freeaddrinfo
69 #else
70 #include <wspiapi.h>
71 #endif
72 #endif
73
open_socket(char * host,unsigned short port)74 SOCKET open_socket(char *host, unsigned short port)
75 {
76 SOCKET fd = -1;
77 struct addrinfo hints, *result, *rp;
78 char service[NI_MAXSERV];
79 int s;
80
81 #if defined(WINSOCK)
82 static int first = 1;
83 if(first) {
84 WSADATA dmy;
85 WSAStartup(MAKEWORD(1,1), &dmy);
86 first = 0;
87 }
88 #endif
89
90 memset(&hints, 0, sizeof(struct addrinfo));
91 hints.ai_family = AF_UNSPEC;
92 hints.ai_socktype = SOCK_STREAM;
93 #ifdef AI_ADDRCONFIG
94 /* By default, only look up addresses using address types for
95 * which a local interface is configured (i.e. no IPv6 if no IPv6
96 * interfaces. */
97 hints.ai_flags = AI_ADDRCONFIG;
98 #endif
99
100 snprintf(service, sizeof(service), "%d", port);
101
102 s = getaddrinfo(host, service, &hints, &result);
103 #ifdef AI_ADDRCONFIG
104 if (s == EAI_BADFLAGS) {
105 /* Retry with no flags if AI_ADDRCONFIG was rejected. */
106 hints.ai_flags = 0;
107 s = getaddrinfo(host, service, &hints, &result);
108 }
109 #endif
110
111 if (s)
112 return (SOCKET)-1;
113
114 for (rp = result; rp != NULL; rp = rp->ai_next)
115 {
116 if (rp->ai_family != AF_INET && rp->ai_family != AF_INET6)
117 continue;
118
119 fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
120
121 if (fd != -1 && connect(fd, rp->ai_addr, rp->ai_addrlen) != -1)
122 break;
123
124 if (fd != -1) {
125 close(fd);
126 fd = -1;
127 }
128 }
129
130 freeaddrinfo(result);
131 return (SOCKET) fd;
132 }
133
134 #if !defined(__W32__) || defined(__CYGWIN32__)
socket_write(SOCKET fd,char * buff,long bufsiz)135 long socket_write(SOCKET fd, char *buff, long bufsiz)
136 {
137 return write(fd, buff, bufsiz);
138 }
139
socket_shutdown(SOCKET fd,int how)140 int socket_shutdown(SOCKET fd, int how)
141 {
142 return shutdown(fd, how);
143 }
144
socket_fdopen(SOCKET fd,char * mode)145 FILE *socket_fdopen(SOCKET fd, char *mode)
146 {
147 return fdopen(fd, mode);
148 }
149
socket_fgets(char * buff,int n,FILE * fp)150 char *socket_fgets(char *buff, int n, FILE *fp)
151 {
152 return fgets(buff, n, fp);
153 }
154
socket_fgetc(FILE * fp)155 int socket_fgetc(FILE *fp)
156 {
157 return getc(fp);
158 }
159
socket_fread(void * buff,long bufsiz,FILE * fp)160 long socket_fread(void *buff, long bufsiz, FILE *fp)
161 {
162 return (long)fread(buff, 1, bufsiz, fp);
163 }
164
socket_fwrite(void * buff,long bufsiz,FILE * fp)165 long socket_fwrite(void *buff, long bufsiz, FILE *fp)
166 {
167 return (long)fwrite(buff, 1, bufsiz, fp);
168 }
169
socket_fclose(FILE * fp)170 int socket_fclose(FILE *fp)
171 {
172 return fclose(fp);
173 }
174
socket_fflush(FILE * fp)175 int socket_fflush(FILE *fp)
176 {
177 return fflush(fp);
178 }
179 #else /* __W32__ */
180
181 #include "url.h"
182
183 /* Fake FILE * */
184
185 typedef struct _w32_fp_socket_t
186 {
187 SOCKET fd; /* Now, It has only fd */
188 } w32_fp_socket;
189 #define W32_FP2SOCKET(fp) (((w32_fp_socket *)(fp))->fd)
190
socket_safe_recv(SOCKET fd,char * buff,long bufsiz)191 static long socket_safe_recv(SOCKET fd, char *buff, long bufsiz)
192 {
193 fd_set fds;
194 int maxfd, n;
195
196 FD_ZERO(&fds);
197 FD_SET(fd, &fds);
198 maxfd = fd + 1;
199
200 n = select(maxfd, &fds, NULL, NULL, NULL);
201 if(n <= 0)
202 return n;
203 return recv(fd, buff, bufsiz, 0);
204 }
205
socket_write(SOCKET fd,char * buff,long bufsiz)206 long socket_write(SOCKET fd, char *buff, long bufsiz)
207 {
208 return send(fd, buff, bufsiz, 0);
209 }
210
socket_shutdown(SOCKET fd,int how)211 int socket_shutdown(SOCKET fd, int how)
212 {
213 return shutdown(fd, how);
214 }
215
216 #pragma argsused
socket_fdopen(SOCKET fd,char * mode)217 FILE *socket_fdopen(SOCKET fd, char *mode)
218 {
219 FILE *fp;
220
221 /* w32_fp_socket fake FILE.
222 * `mode' argument is ignored.
223 */
224 if((fp = (FILE *)safe_malloc(sizeof(w32_fp_socket))) == NULL)
225 return NULL;
226 memset(fp, 0, sizeof(w32_fp_socket));
227 W32_FP2SOCKET(fp) = fd;
228 return fp;
229 }
230
socket_getc(SOCKET fd)231 static int socket_getc(SOCKET fd)
232 {
233 int n;
234 unsigned char c;
235
236 n = socket_safe_recv(fd, (char *)&c, 1);
237 if(n <= 0)
238 return EOF;
239 return (int)c;
240 }
241
socket_fgets(char * buff,int n,FILE * fp)242 char *socket_fgets(char *buff, int n, FILE *fp)
243 {
244 SOCKET fd = W32_FP2SOCKET(fp);
245 int len;
246
247 n--; /* for '\0' */
248 if(n == 0)
249 *buff = '\0';
250 if(n <= 0)
251 return buff;
252
253 len = 0;
254 while(len < n)
255 {
256 int c;
257 c = socket_getc(fd);
258 if(c == -1)
259 break;
260 buff[len++] = c;
261 if(c == url_newline_code)
262 break;
263 }
264 if(len == 0)
265 return NULL;
266 buff[len] = '\0';
267 return buff;
268 }
269
socket_fgetc(FILE * fp)270 int socket_fgetc(FILE *fp)
271 {
272 SOCKET fd = W32_FP2SOCKET(fp);
273 return socket_getc(fd);
274 }
275
socket_fread(void * buff,long bufsiz,FILE * fp)276 long socket_fread(void *buff, long bufsiz, FILE *fp)
277 {
278 SOCKET fd = W32_FP2SOCKET(fp);
279 return socket_safe_recv(fd, buff, bufsiz);
280 }
281
socket_fwrite(void * buff,long bufsiz,FILE * fp)282 long socket_fwrite(void *buff, long bufsiz, FILE *fp)
283 {
284 SOCKET fd = W32_FP2SOCKET(fp);
285 return socket_write(fd, buff, bufsiz);
286 }
287
socket_fclose(FILE * fp)288 int socket_fclose(FILE *fp)
289 {
290 SOCKET fd = W32_FP2SOCKET(fp);
291 int ret;
292 ret = closesocket(fd);
293 free(fp);
294 return ret;
295 }
296
socket_fflush(FILE * fp)297 int socket_fflush(FILE *fp)
298 {
299 return 0;
300 }
301
302 #endif
303