Branch data Line data Source code
1 : : /***
2 : : This file is part of PulseAudio.
3 : :
4 : : Copyright 2004-2006 Lennart Poettering
5 : :
6 : : PulseAudio is free software; you can redistribute it and/or modify
7 : : it under the terms of the GNU Lesser General Public License as
8 : : published by the Free Software Foundation; either version 2.1 of the
9 : : License, or (at your option) any later version.
10 : :
11 : : PulseAudio is distributed in the hope that it will be useful, but
12 : : WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : Lesser General Public License for more details.
15 : :
16 : : You should have received a copy of the GNU Lesser General Public
17 : : License along with PulseAudio; if not, write to the Free Software
18 : : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 : : USA.
20 : : ***/
21 : :
22 : : #ifdef HAVE_CONFIG_H
23 : : #include <config.h>
24 : : #endif
25 : :
26 : : #include <string.h>
27 : : #include <stdlib.h>
28 : :
29 : : #include <pulse/xmalloc.h>
30 : :
31 : : #include <pulsecore/core-util.h>
32 : : #include <pulsecore/macro.h>
33 : : #include <pulsecore/arpa-inet.h>
34 : :
35 : : #include "parseaddr.h"
36 : :
37 : : /* Parse addresses in one of the following forms:
38 : : * HOSTNAME
39 : : * HOSTNAME:PORT
40 : : * [HOSTNAME]
41 : : * [HOSTNAME]:PORT
42 : : *
43 : : * Return a newly allocated string of the hostname and fill in *ret_port if specified */
44 : :
45 : 0 : static char *parse_host(const char *s, uint16_t *ret_port) {
46 [ # # ]: 0 : pa_assert(s);
47 [ # # ]: 0 : pa_assert(ret_port);
48 : :
49 [ # # ]: 0 : if (*s == '[') {
50 : : char *e;
51 [ # # ]: 0 : if (!(e = strchr(s+1, ']')))
52 : : return NULL;
53 : :
54 [ # # ]: 0 : if (e[1] == ':') {
55 : : uint32_t p;
56 : :
57 [ # # ]: 0 : if (pa_atou(e+2, &p) < 0)
58 : : return NULL;
59 : :
60 : 0 : *ret_port = (uint16_t) p;
61 [ # # ]: 0 : } else if (e[1] != 0)
62 : : return NULL;
63 : :
64 : 0 : return pa_xstrndup(s+1, (size_t) (e-s-1));
65 : : } else {
66 : : char *e;
67 : : uint32_t p;
68 : :
69 [ # # ]: 0 : if (!(e = strrchr(s, ':')))
70 : 0 : return pa_xstrdup(s);
71 : :
72 [ # # ]: 0 : if (pa_atou(e+1, &p) < 0)
73 : : return NULL;
74 : :
75 : 0 : *ret_port = (uint16_t) p;
76 : 0 : return pa_xstrndup(s, (size_t) (e-s));
77 : : }
78 : : }
79 : :
80 : 0 : int pa_parse_address(const char *name, pa_parsed_address *ret_p) {
81 : : const char *p;
82 : :
83 [ # # ]: 0 : pa_assert(name);
84 [ # # ]: 0 : pa_assert(ret_p);
85 : :
86 : : memset(ret_p, 0, sizeof(pa_parsed_address));
87 : 0 : ret_p->type = PA_PARSED_ADDRESS_TCP_AUTO;
88 : :
89 [ # # ]: 0 : if (*name == '{') {
90 : : char *id, *pfx;
91 : :
92 : : /* The URL starts with a host id for detecting local connections */
93 [ # # ]: 0 : if (!(id = pa_machine_id()))
94 : : return -1;
95 : :
96 : 0 : pfx = pa_sprintf_malloc("{%s}", id);
97 : 0 : pa_xfree(id);
98 : :
99 [ # # ]: 0 : if (!pa_startswith(name, pfx)) {
100 : 0 : pa_xfree(pfx);
101 : : /* Not local */
102 : 0 : return -1;
103 : : }
104 : :
105 : 0 : p = name + strlen(pfx);
106 : 0 : pa_xfree(pfx);
107 : : } else
108 : : p = name;
109 : :
110 [ # # ]: 0 : if (*p == '/')
111 : 0 : ret_p->type = PA_PARSED_ADDRESS_UNIX;
112 [ # # ]: 0 : else if (pa_startswith(p, "unix:")) {
113 : 0 : ret_p->type = PA_PARSED_ADDRESS_UNIX;
114 : 0 : p += sizeof("unix:")-1;
115 [ # # ]: 0 : } else if (pa_startswith(p, "tcp:")) {
116 : 0 : ret_p->type = PA_PARSED_ADDRESS_TCP4;
117 : 0 : p += sizeof("tcp:")-1;
118 [ # # ]: 0 : } else if (pa_startswith(p, "tcp4:")) {
119 : 0 : ret_p->type = PA_PARSED_ADDRESS_TCP4;
120 : 0 : p += sizeof("tcp4:")-1;
121 [ # # ]: 0 : } else if (pa_startswith(p, "tcp6:")) {
122 : 0 : ret_p->type = PA_PARSED_ADDRESS_TCP6;
123 : 0 : p += sizeof("tcp6:")-1;
124 : : }
125 : :
126 [ # # ]: 0 : if (ret_p->type == PA_PARSED_ADDRESS_UNIX)
127 : 0 : ret_p->path_or_host = pa_xstrdup(p);
128 : : else
129 [ # # ]: 0 : if (!(ret_p->path_or_host = parse_host(p, &ret_p->port)))
130 : : return -1;
131 : :
132 : 0 : return 0;
133 : : }
134 : :
135 : 0 : pa_bool_t pa_is_ip_address(const char *a) {
136 : : char buf[INET6_ADDRSTRLEN];
137 : :
138 [ # # ]: 0 : pa_assert(a);
139 : :
140 [ # # ]: 0 : if (inet_pton(AF_INET6, a, buf) >= 1)
141 : : return TRUE;
142 : :
143 [ # # ]: 0 : if (inet_pton(AF_INET, a, buf) >= 1)
144 : : return TRUE;
145 : :
146 : 0 : return FALSE;
147 : : }
|