CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

address.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2004 Steve Harris
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation; either version 2.1 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * $Id$
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sys/types.h>
21
22 #ifdef _MSC_VER
23 #include <io.h>
24 #define snprintf _snprintf
25 #else
26 #include <unistd.h>
27 #endif
28
29 #ifdef WIN32
30 #include <winsock2.h>
31 #include <ws2tcpip.h>
32 #else
33 #include <netdb.h>
34 #include <sys/socket.h>
35 #endif
36
37 #include "lo_types_internal.h"
38 #include "lo/lo.h"
39 #include "config.h"
40
41 lo_address lo_address_new_with_proto(int proto, const char *host, const char *port)
42 {
43 lo_address a;
44
45 if(proto != LO_UDP && proto != LO_TCP && proto != LO_UNIX) return NULL;
46
47 a = calloc(1, sizeof(struct _lo_address));
48 if(a == NULL) return NULL;
49
50 a->ai = NULL;
51 a->socket = -1;
52 a->protocol = proto;
53 switch(proto) {
54 default:
55 case LO_UDP:
56 case LO_TCP:
57 if (host) {
58 a->host = strdup(host);
59 } else {
60 a->host = strdup("localhost");
61 }
62 break;
63 case LO_UNIX:
64 a->host = strdup("localhost");
65 break;
66 }
67 if (port) {
68 a->port = strdup(port);
69 } else {
70 a->port = NULL;
71 }
72
73 a->ttl = -1;
74
75 return a;
76 }
77
78 lo_address lo_address_new(const char *host, const char *port)
79 {
80 return lo_address_new_with_proto(LO_UDP, host ,port);
81 }
82
83 lo_address lo_address_new_from_url(const char *url)
84 {
85 lo_address a;
86 int protocol;
87 char *host, *port, *proto;
88
89 if (!url || !*url) {
90 return NULL;
91 }
92
93 protocol = lo_url_get_protocol_id(url);
94 if (protocol == LO_UDP || protocol == LO_TCP) {
95 host = lo_url_get_hostname(url);
96 port = lo_url_get_port(url);
97 a = lo_address_new_with_proto(protocol, host, port);
98 if(host) free(host);
99 if(port) free(port);
100 #ifndef WIN32
101 } else if (protocol == LO_UNIX) {
102 port = lo_url_get_path(url);
103 a = lo_address_new_with_proto(LO_UNIX, NULL, port);
104 if(port) free(port);
105 #endif
106 } else {
107 proto = lo_url_get_protocol(url);
108 fprintf(stderr, PACKAGE_NAME ": protocol '%s' not supported by this "
109 "version\n", proto);
110 if(proto) free(proto);
111
112 return NULL;
113 }
114
115 return a;
116 }
117
118 const char *lo_address_get_hostname(lo_address a)
119 {
120 if (!a) {
121 return NULL;
122 }
123
124 return a->host;
125 }
126
127 int lo_address_get_protocol(lo_address a)
128 {
129 if (!a) {
130 return -1;
131 }
132
133 return a->protocol;
134 }
135
136 const char *lo_address_get_port(lo_address a)
137 {
138 if (!a) {
139 return NULL;
140 }
141
142 return a->port;
143 }
144
145 static const char* get_protocol_name(int proto)
146 {
147 switch(proto) {
148 case LO_UDP:
149 return "udp";
150 case LO_TCP:
151 return "tcp";
152 #ifndef WIN32
153 case LO_UNIX:
154 return "unix";
155 #endif
156 }
157 return NULL;
158 }
159
160
161 char *lo_address_get_url(lo_address a)
162 {
163 char *buf;
164 int ret=0;
165 int needquote = strchr(a->host, ':') ? 1 : 0;
166 char *fmt;
167
168 if (needquote) {
169 fmt = "osc.%s://[%s]:%s/";
170 } else {
171 fmt = "osc.%s://%s:%s/";
172 }
173 #ifndef _MSC_VER
174 ret = snprintf(NULL, 0, fmt,
175 get_protocol_name(a->protocol), a->host, a->port);
176 #endif
177 if (ret <= 0) {
178 /* this libc is not C99 compliant, guess a size */
179 ret = 1023;
180 }
181 buf = malloc((ret + 2) * sizeof(char));
182 snprintf(buf, ret+1, fmt,
183 get_protocol_name(a->protocol), a->host, a->port);
184
185 return buf;
186 }
187
188 void lo_address_free(lo_address a)
189 {
190 if (a) {
191 if (a->socket != -1) {
192 close(a->socket);
193 }
194 if (a->host) free(a->host);
195 if (a->port) free(a->port);
196 if (a->ai) freeaddrinfo(a->ai);
197 free(a);
198 }
199 }
200
201 int lo_address_errno(lo_address a)
202 {
203 return a->errnum;
204 }
205
206 const char *lo_address_errstr(lo_address a)
207 {
208 char *msg;
209
210 if (a->errstr) {
211 return a->errstr;
212 }
213
214 msg = strerror(a->errnum);
215 if (msg) {
216 return msg;
217 } else {
218 return "unknown error";
219 }
220
221 return "unknown error";
222 }
223
224 char *lo_url_get_protocol(const char *url)
225 {
226 char *protocol,*ret;
227
228 if (!url) {
229 return NULL;
230 }
231
232 protocol = malloc(strlen(url));
233
234 if (sscanf(url, "osc://%s", protocol)) {
235 fprintf(stderr, PACKAGE_NAME " warning: no protocol specified in URL, "
236 "assuming UDP.\n");
237 ret = strdup("udp");
238 } else if (sscanf(url, "osc.%[^:/[]", protocol)) {
239 ret = strdup(protocol);
240 } else {
241 ret = NULL;
242 }
243
244 free(protocol);
245
246 return ret;
247 }
248
249 int lo_url_get_protocol_id(const char *url)
250 {
251 if(!url) {
252 return -1;
253 }
254
255 if(!strncmp(url, "osc:", 4)) {
256 fprintf(stderr, PACKAGE_NAME " warning: no protocol specified in URL, "
257 "assuming UDP.\n");
258 return LO_UDP; // should be LO_DEFAULT?
259 } else if(!strncmp(url, "osc.udp:", 8)) {
260 return LO_UDP;
261 } else if(!strncmp(url, "osc.tcp:", 8)) {
262 return LO_TCP;
263 } else if(!strncmp(url, "osc.unix:", 9)) {
264 return LO_UNIX;
265 }
266 return -1;
267 }
268
269 char *lo_url_get_hostname(const char *url)
270 {
271 char *hostname = malloc(strlen(url));
272
273 if (sscanf(url, "osc://%[^[:/]", hostname)) {
274 return hostname;
275 }
276 if (sscanf(url, "osc.%*[^:/]://[%[^]/]]", hostname)) {
277 return hostname;
278 }
279 if (sscanf(url, "osc.%*[^:/]://%[^[:/]", hostname)) {
280 return hostname;
281 }
282
283 /* doesnt look like an OSC URL */
284 free(hostname);
285
286 return NULL;
287 }
288
289 char *lo_url_get_port(const char *url)
290 {
291 char *port = malloc(strlen(url));
292
293 if (sscanf(url, "osc://%*[^:]:%[0-9]", port)) {
294 return port;
295 }
296 if (sscanf(url, "osc.%*[^:]://%*[^:]:%[0-9]", port)) {
297 return port;
298 }
299 if (sscanf(url, "osc://[%*[^]]]:%[0-9]", port)) {
300 return port;
301 }
302 if (sscanf(url, "osc.%*[^:]://[%*[^]]]:%[0-9]", port)) {
303 return port;
304 }
305
306 /* doesnt look like an OSC URL with port number */
307 free(port);
308
309 return NULL;
310 }
311
312 char *lo_url_get_path(const char *url)
313 {
314 char *path = malloc(strlen(url));
315
316 if (sscanf(url, "osc://%*[^:]:%*[0-9]%s", path)) {
317 return path;
318 }
319 if (sscanf(url, "osc.%*[^:]://%*[^:]:%*[0-9]%s", path) == 1) {
320 return path;
321 }
322 if (sscanf(url, "osc.unix://%*[^/]%s", path) == 1) {
323 return path;
324 }
325 if (sscanf(url, "osc.%*[^:]://%s", path)) {
326 return path;
327 }
328
329 /* doesnt look like an OSC URL with port number and path*/
330 free(path);
331
332 return NULL;
333 }
334
335 void lo_address_set_ttl(lo_address t, int ttl)
336 {
337 if (t->protocol == LO_UDP)
338 t->ttl = ttl;
339 }
340
341 int lo_address_get_ttl(lo_address t)
342 {
343 return t->ttl;
344 }
345
346 /* vi:set ts=8 sts=4 sw=4: */