xref: /illumos-gate/usr/src/lib/libsip/common/sip_uri_ui.c (revision 4e93fb0f6383eaac21897dcdae56b87118131e4d)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <stdlib.h>
29 #include <string.h>
30 #include <ctype.h>
31 #include <errno.h>
32 
33 #include "sip_parse_uri.h"
34 
35 void
36 sip_free_parsed_uri(sip_uri_t uri)
37 {
38 	_sip_uri_t	*_uri;
39 
40 	if (uri == NULL)
41 		return;
42 
43 	_uri = (_sip_uri_t *)uri;
44 	if (_uri->sip_uri_issip) {
45 		sip_param_t	*param;
46 		sip_param_t	*param_next;
47 
48 		param = _uri->sip_uri_params;
49 		while (param != NULL) {
50 			param_next = param->param_next;
51 			free(param);
52 			param = param_next;
53 		}
54 	}
55 	free(_uri);
56 }
57 
58 /*
59  * Parse the URI in uri_str
60  */
61 struct sip_uri *
62 sip_parse_uri(sip_str_t *uri_str, int *error)
63 {
64 	struct sip_uri	*parsed_uri;
65 
66 	if (error != NULL)
67 		*error = 0;
68 
69 	if (uri_str == NULL) {
70 		if (error != NULL)
71 			*error = EINVAL;
72 		return (NULL);
73 	}
74 	parsed_uri = calloc(1, sizeof (_sip_uri_t));
75 	if (parsed_uri == NULL) {
76 		if (error != NULL)
77 			*error = ENOMEM;
78 		return (NULL);
79 	}
80 
81 	sip_uri_parse_it(parsed_uri, uri_str);
82 	if (parsed_uri->sip_uri_errflags & SIP_URIERR_MEMORY) {
83 		free(parsed_uri);
84 		if (error != NULL)
85 			*error = ENOMEM;
86 		return (NULL);
87 	}
88 	if (parsed_uri->sip_uri_errflags != 0 && error != NULL)
89 		*error = EPROTO;
90 	return ((sip_uri_t)parsed_uri);
91 }
92 
93 /*
94  * Get parsed URI
95  */
96 const struct sip_uri *
97 sip_get_uri_parsed(sip_header_value_t value, int *error)
98 {
99 	const struct sip_uri	*ret = NULL;
100 
101 	if (error != NULL)
102 		*error = 0;
103 	if (value == NULL || value->sip_value_parse_uri == NULL ||
104 	    value->value_state == SIP_VALUE_DELETED) {
105 		if (error != NULL)
106 			*error = EINVAL;
107 		return (NULL);
108 	}
109 	ret = value->sip_value_parse_uri;
110 	if (ret->sip_uri_errflags != 0 && error != NULL)
111 		*error = EINVAL;
112 	return ((sip_uri_t)ret);
113 }
114 
115 /*
116  * Return TRUE if this is a SIP URI
117  */
118 boolean_t
119 sip_is_sipuri(const struct sip_uri *uri)
120 {
121 	_sip_uri_t	*_uri;
122 
123 	if (uri == NULL)
124 		return (B_FALSE);
125 	_uri = (_sip_uri_t *)uri;
126 	if ((_uri->sip_uri_errflags & SIP_URIERR_SCHEME) == 0 &&
127 	    _uri->sip_uri_scheme.sip_str_len > 0 && _uri->sip_uri_issip) {
128 		return (B_TRUE);
129 	}
130 	return (B_FALSE);
131 }
132 
133 /*
134  * Some common checks
135  */
136 static _sip_uri_t *
137 sip_check_get_param(const struct sip_uri *uri, int *error)
138 {
139 	if (error != NULL)
140 		*error = 0;
141 
142 	if (uri == NULL) {
143 		if (error != NULL)
144 			*error = EINVAL;
145 		return (NULL);
146 	}
147 	return ((_sip_uri_t *)uri);
148 }
149 
150 
151 /*
152  * Return the URI scheme
153  */
154 const sip_str_t *
155 sip_get_uri_scheme(const struct sip_uri *uri, int *error)
156 {
157 	_sip_uri_t	*_uri;
158 
159 	_uri = sip_check_get_param(uri, error);
160 	if (_uri == NULL)
161 		return (NULL);
162 
163 	if (((_uri->sip_uri_errflags & SIP_URIERR_SCHEME) != 0 ||
164 	    _uri->sip_uri_scheme.sip_str_len == 0) && error != NULL) {
165 		*error = EINVAL;
166 	}
167 	if (_uri->sip_uri_scheme.sip_str_len > 0)
168 		return (&_uri->sip_uri_scheme);
169 	return (NULL);
170 }
171 
172 /*
173  *  Return user name from URI
174  */
175 const sip_str_t *
176 sip_get_uri_user(const struct sip_uri *uri, int *error)
177 {
178 	_sip_uri_t	*_uri;
179 
180 	_uri = sip_check_get_param(uri, error);
181 	if (_uri == NULL)
182 		return (NULL);
183 
184 	if ((_uri->sip_uri_errflags & SIP_URIERR_USER) != 0 && error != NULL)
185 		*error = EINVAL;
186 	if (uri->sip_uri_user.sip_str_len > 0)
187 		return (&uri->sip_uri_user);
188 	return (NULL);
189 }
190 
191 /*
192  *  Return password from URI
193  */
194 const sip_str_t *
195 sip_get_uri_password(const struct sip_uri *uri, int *error)
196 {
197 	_sip_uri_t	*_uri;
198 
199 	_uri = sip_check_get_param(uri, error);
200 	if (_uri == NULL)
201 		return (NULL);
202 
203 	if ((_uri->sip_uri_errflags & SIP_URIERR_PASS) != 0 && error != NULL)
204 		*error = EINVAL;
205 	if (_uri->sip_uri_password.sip_str_len > 0)
206 		return (&_uri->sip_uri_password);
207 	return (NULL);
208 }
209 
210 /*
211  * Get host from the URI
212  */
213 const sip_str_t *
214 sip_get_uri_host(const struct sip_uri *uri, int *error)
215 {
216 	_sip_uri_t	*_uri;
217 
218 	_uri = sip_check_get_param(uri, error);
219 	if (_uri == NULL)
220 		return (NULL);
221 
222 	if ((_uri->sip_uri_errflags & SIP_URIERR_HOST) != 0 && error != NULL)
223 		*error = EINVAL;
224 	if (_uri->sip_uri_host.sip_str_len > 0)
225 		return (&_uri->sip_uri_host);
226 	return (NULL);
227 }
228 
229 /*
230  * Get port from the URI
231  */
232 int
233 sip_get_uri_port(const struct sip_uri *uri, int *error)
234 {
235 	_sip_uri_t	*_uri;
236 
237 	_uri = sip_check_get_param(uri, error);
238 	if (_uri == NULL)
239 		return (NULL);
240 
241 	if ((_uri->sip_uri_errflags & SIP_URIERR_PORT) != 0) {
242 		if (error != NULL)
243 			*error = EINVAL;
244 		return (0);
245 	}
246 	return (_uri->sip_uri_port);
247 }
248 
249 const sip_param_t *
250 sip_get_uri_params(const struct sip_uri *uri, int *error)
251 {
252 	_sip_uri_t		*_uri;
253 
254 	_uri = sip_check_get_param(uri, error);
255 	if (_uri == NULL)
256 		return (NULL);
257 
258 	if (!_uri->sip_uri_issip) {
259 		if (error != NULL)
260 			*error = EINVAL;
261 		return (NULL);
262 	}
263 
264 	if ((_uri->sip_uri_errflags & SIP_URIERR_PARAM) != 0 && error != NULL)
265 		*error = EINVAL;
266 	return (_uri->sip_uri_params);
267 }
268 
269 /*
270  * Get headers from the URI
271  */
272 const sip_str_t *
273 sip_get_uri_headers(const struct sip_uri *uri, int *error)
274 {
275 	_sip_uri_t	*_uri;
276 
277 	_uri = sip_check_get_param(uri, error);
278 	if (_uri == NULL)
279 		return (NULL);
280 
281 	if (!_uri->sip_uri_issip) {
282 		if (error != NULL)
283 			*error = EINVAL;
284 		return (NULL);
285 	}
286 	if ((_uri->sip_uri_errflags & SIP_URIERR_HEADER) != 0 && error != NULL)
287 		*error = EINVAL;
288 	if (_uri->sip_uri_headers.sip_str_len > 0)
289 		return (&_uri->sip_uri_headers);
290 	return (NULL);
291 }
292 
293 /*
294  *  Return opaque value for an ABS URI
295  */
296 const sip_str_t *
297 sip_get_uri_opaque(const struct sip_uri *uri, int *error)
298 {
299 	_sip_uri_t	*_uri;
300 
301 	_uri = sip_check_get_param(uri, error);
302 	if (_uri == NULL)
303 		return (NULL);
304 
305 	if (_uri->sip_uri_issip) {
306 		if (error != NULL)
307 			*error = EINVAL;
308 		return (NULL);
309 	}
310 	if ((_uri->sip_uri_errflags & SIP_URIERR_OPAQUE) != 0 && error != NULL)
311 		*error = EINVAL;
312 	if (_uri->sip_uri_opaque.sip_str_len > 0)
313 		return (&_uri->sip_uri_opaque);
314 	return (NULL);
315 }
316 
317 /*
318  * Return query from an absolute URI
319  */
320 const sip_str_t *
321 sip_get_uri_query(const struct sip_uri *uri, int *error)
322 {
323 	_sip_uri_t	*_uri;
324 
325 	_uri = sip_check_get_param(uri, error);
326 	if (_uri == NULL)
327 		return (NULL);
328 
329 	if (_uri->sip_uri_issip) {
330 		if (error != NULL)
331 			*error = EINVAL;
332 		return (NULL);
333 	}
334 	if ((_uri->sip_uri_errflags & SIP_URIERR_QUERY) != 0 && error != NULL)
335 		*error = EINVAL;
336 	if (_uri->sip_uri_query.sip_str_len > 0)
337 		return (&_uri->sip_uri_query);
338 	return (NULL);
339 }
340 
341 /*
342  *  Get path from an assolute URI
343  */
344 const sip_str_t *
345 sip_get_uri_path(const struct sip_uri *uri, int *error)
346 {
347 	_sip_uri_t	*_uri;
348 
349 	_uri = sip_check_get_param(uri, error);
350 	if (_uri == NULL)
351 		return (NULL);
352 
353 	if (_uri->sip_uri_issip) {
354 		if (error != NULL)
355 			*error = EINVAL;
356 		return (NULL);
357 	}
358 	if ((_uri->sip_uri_errflags & SIP_URIERR_PATH) != 0 && error != NULL)
359 		*error = EINVAL;
360 	if (_uri->sip_uri_path.sip_str_len > 0)
361 		return (&_uri->sip_uri_path);
362 	return (NULL);
363 }
364 
365 /*
366  * Get the reg-name from absolute URI
367  */
368 const sip_str_t	*
369 sip_get_uri_regname(const struct sip_uri *uri, int *error)
370 {
371 	_sip_uri_t	*_uri;
372 
373 	_uri = sip_check_get_param(uri, error);
374 	if (_uri == NULL)
375 		return (NULL);
376 
377 	if (_uri->sip_uri_issip) {
378 		if (error != NULL)
379 			*error = EINVAL;
380 		return (NULL);
381 	}
382 	if ((_uri->sip_uri_errflags & SIP_URIERR_REGNAME) != 0 && error != NULL)
383 		*error = EINVAL;
384 	if (_uri->sip_uri_regname.sip_str_len > 0)
385 		return (&_uri->sip_uri_regname);
386 	return (NULL);
387 }
388 
389 /*
390  * Return TRUE if this is a teluser
391  */
392 boolean_t
393 sip_is_uri_teluser(const struct sip_uri *uri)
394 {
395 	_sip_uri_t	*_uri;
396 
397 	if (uri == NULL)
398 		return (B_FALSE);
399 
400 	_uri = (_sip_uri_t *)uri;
401 	return (_uri->sip_uri_isteluser);
402 }
403 
404 int
405 sip_get_uri_errflags(const struct sip_uri *uri, int *error)
406 {
407 	_sip_uri_t	*_uri;
408 
409 	_uri = sip_check_get_param(uri, error);
410 	if (_uri == NULL)
411 		return (0);
412 	return (_uri->sip_uri_errflags);
413 }
414 
415 /*
416  * the caller is responsible for freeing the returned string
417  */
418 char *
419 sip_uri_errflags_to_str(int errflags)
420 {
421 	char	*err_info = NULL;
422 
423 	if (errflags == 0)
424 		return (NULL);
425 
426 	err_info = (char *)malloc(SIP_URI_BUF_SIZE);
427 	if (err_info == NULL)
428 		return (NULL);
429 
430 	if (errflags & SIP_URIERR_NOURI) {
431 		(void) strncpy(err_info, "Error : No URI",
432 		    strlen("Error : No URI"));
433 		err_info[strlen("Error : No URI")] = '\0';
434 		return (err_info);
435 	}
436 
437 	(void) strncpy(err_info, "Error(s) in", strlen("Error(s) in"));
438 	err_info[strlen("Error(s) in")] = '\0';
439 	if (errflags & SIP_URIERR_SCHEME)
440 		(void) strncat(err_info, " SCHEME,", strlen(" SCHEME,"));
441 	if (errflags & SIP_URIERR_USER)
442 		(void) strncat(err_info, " USER,", strlen(" USER,"));
443 	if (errflags & SIP_URIERR_PASS)
444 		(void) strncat(err_info, " PASSWORD,", strlen(" PASSWORD,"));
445 	if (errflags & SIP_URIERR_HOST)
446 		(void) strncat(err_info, " HOST,", strlen(" HOST,"));
447 	if (errflags & SIP_URIERR_PORT)
448 		(void) strncat(err_info, " PORT,", strlen(" PORT,"));
449 	if (errflags & SIP_URIERR_PARAM) {
450 		(void) strncat(err_info, " PARAMETERS,",
451 		    strlen(" PARAMETERS,"));
452 	}
453 	if (errflags & SIP_URIERR_HEADER)
454 		(void) strncat(err_info, " HEADERS,", strlen(" HEADERS,"));
455 	if (errflags & SIP_URIERR_OPAQUE)
456 		(void) strncat(err_info, " OPAQUE,", strlen(" OPAQUE,"));
457 	if (errflags & SIP_URIERR_QUERY)
458 		(void) strncat(err_info, " QUERY,", strlen(" QUERY,"));
459 	if (errflags & SIP_URIERR_PATH)
460 		(void) strncat(err_info, " PATH,", strlen(" PATH,"));
461 	if (errflags & SIP_URIERR_REGNAME)
462 		(void) strncat(err_info, " REG-NAME,", strlen(" REG-NAME,"));
463 	if (strlen(err_info) == strlen("Error(s) in")) {
464 		free(err_info);
465 		err_info = NULL;
466 	} else {
467 		err_info[strlen(err_info) - 1] = '\0';
468 		(void) strncat(err_info, " part(s)", strlen(" part(s)"));
469 	}
470 	return (err_info);
471 }
472