]> code.delx.au - pulseaudio/blob - src/pulsecore/parseaddr.c
Fix dependencies and include necessary headers
[pulseaudio] / src / pulsecore / parseaddr.c
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 #ifdef HAVE_ARPA_INET_H
30 #include <arpa/inet.h>
31 #endif
32
33 #include <pulse/xmalloc.h>
34 #include <pulse/util.h>
35
36 #include <pulsecore/core-util.h>
37 #include <pulsecore/macro.h>
38 #include <pulsecore/inet_pton.h>
39
40 #include "parseaddr.h"
41
42 /* Parse addresses in one of the following forms:
43 * HOSTNAME
44 * HOSTNAME:PORT
45 * [HOSTNAME]
46 * [HOSTNAME]:PORT
47 *
48 * Return a newly allocated string of the hostname and fill in *ret_port if specified */
49
50 static char *parse_host(const char *s, uint16_t *ret_port) {
51 pa_assert(s);
52 pa_assert(ret_port);
53
54 if (*s == '[') {
55 char *e;
56 if (!(e = strchr(s+1, ']')))
57 return NULL;
58
59 if (e[1] == ':') {
60 uint32_t p;
61
62 if (pa_atou(e+2, &p) < 0)
63 return NULL;
64
65 *ret_port = (uint16_t) p;
66 } else if (e[1] != 0)
67 return NULL;
68
69 return pa_xstrndup(s+1, (size_t) (e-s-1));
70 } else {
71 char *e;
72 uint32_t p;
73
74 if (!(e = strrchr(s, ':')))
75 return pa_xstrdup(s);
76
77 if (pa_atou(e+1, &p) < 0)
78 return NULL;
79
80 *ret_port = (uint16_t) p;
81 return pa_xstrndup(s, (size_t) (e-s));
82 }
83 }
84
85 int pa_parse_address(const char *name, pa_parsed_address *ret_p) {
86 const char *p;
87
88 pa_assert(name);
89 pa_assert(ret_p);
90
91 memset(ret_p, 0, sizeof(pa_parsed_address));
92 ret_p->type = PA_PARSED_ADDRESS_TCP_AUTO;
93
94 if (*name == '{') {
95 char *id, *pfx;
96
97 /* The URL starts with a host id for detecting local connections */
98 if (!(id = pa_machine_id()))
99 return -1;
100
101 pfx = pa_sprintf_malloc("{%s}", id);
102 pa_xfree(id);
103
104 if (!pa_startswith(name, pfx)) {
105 pa_xfree(pfx);
106 /* Not local */
107 return -1;
108 }
109
110 p = name + strlen(pfx);
111 pa_xfree(pfx);
112 } else
113 p = name;
114
115 if (*p == '/')
116 ret_p->type = PA_PARSED_ADDRESS_UNIX;
117 else if (pa_startswith(p, "unix:")) {
118 ret_p->type = PA_PARSED_ADDRESS_UNIX;
119 p += sizeof("unix:")-1;
120 } else if (pa_startswith(p, "tcp:")) {
121 ret_p->type = PA_PARSED_ADDRESS_TCP4;
122 p += sizeof("tcp:")-1;
123 } else if (pa_startswith(p, "tcp4:")) {
124 ret_p->type = PA_PARSED_ADDRESS_TCP4;
125 p += sizeof("tcp4:")-1;
126 } else if (pa_startswith(p, "tcp6:")) {
127 ret_p->type = PA_PARSED_ADDRESS_TCP6;
128 p += sizeof("tcp6:")-1;
129 }
130
131 if (ret_p->type == PA_PARSED_ADDRESS_UNIX)
132 ret_p->path_or_host = pa_xstrdup(p);
133 else
134 if (!(ret_p->path_or_host = parse_host(p, &ret_p->port)))
135 return -1;
136
137 return 0;
138 }
139
140 pa_bool_t pa_is_ip_address(const char *a) {
141 char buf[INET6_ADDRSTRLEN];
142
143 pa_assert(a);
144
145 if (inet_pton(AF_INET6, a, buf) >= 1)
146 return TRUE;
147
148 if (inet_pton(AF_INET, a, buf) >= 1)
149 return TRUE;
150
151 return FALSE;
152 }