xref: /onnv-gate/usr/src/lib/print/libpapi-common/common/uri.c (revision 13093:48f2dbca79a2)
12264Sjacobs /*
22264Sjacobs  * CDDL HEADER START
32264Sjacobs  *
42264Sjacobs  * The contents of this file are subject to the terms of the
52264Sjacobs  * Common Development and Distribution License (the "License").
62264Sjacobs  * You may not use this file except in compliance with the License.
72264Sjacobs  *
82264Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92264Sjacobs  * or http://www.opensolaris.org/os/licensing.
102264Sjacobs  * See the License for the specific language governing permissions
112264Sjacobs  * and limitations under the License.
122264Sjacobs  *
132264Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
142264Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152264Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
162264Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
172264Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
182264Sjacobs  *
192264Sjacobs  * CDDL HEADER END
202264Sjacobs  */
212264Sjacobs 
222264Sjacobs /*
23*13093SRoger.Faulkner@Oracle.COM  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
242264Sjacobs  */
252264Sjacobs 
262264Sjacobs /* $Id: uri.c 146 2006-03-24 00:26:54Z njacobs $ */
272264Sjacobs 
282264Sjacobs /*LINTLIBRARY*/
292264Sjacobs 
302264Sjacobs #include <stdio.h>
312264Sjacobs #include <stdlib.h>
322264Sjacobs #include <unistd.h>
332264Sjacobs #include <string.h>
342264Sjacobs #include <sys/types.h>
352264Sjacobs #include <errno.h>
362264Sjacobs #include "uri.h"
372264Sjacobs 
382264Sjacobs /*
392264Sjacobs  * This will handle the following forms:
402264Sjacobs  *	scheme:scheme_data
412264Sjacobs  *	scheme://[[user[:password]@]host[:port]]/path[[#fragment]|[?query]]
422264Sjacobs  */
432264Sjacobs int
uri_from_string(char * string,uri_t ** uri)442264Sjacobs uri_from_string(char *string, uri_t **uri)
452264Sjacobs {
462264Sjacobs 	char *ptr;
472264Sjacobs 	uri_t *u;
482264Sjacobs 
492264Sjacobs 	if ((string == NULL) || (uri == NULL)) {
502264Sjacobs 		errno = EINVAL;
512264Sjacobs 		return (-1);
522264Sjacobs 	}
532264Sjacobs 
542264Sjacobs 	/* find the scheme:scheme_part split */
552264Sjacobs 	if ((ptr = strchr(string, ':')) == NULL) {
562264Sjacobs 		errno = EINVAL;
572264Sjacobs 		return (-1);
582264Sjacobs 	}
592264Sjacobs 
602264Sjacobs 	if ((*uri = u = calloc(1, sizeof (*u))) == NULL)
612264Sjacobs 		return (-1);
622264Sjacobs 
632264Sjacobs 	u->scheme = strndup(string, ptr - string);
642264Sjacobs 
652264Sjacobs 	if ((ptr[1] == '/') && (ptr[2] == '/')) {
662264Sjacobs 		/*
672264Sjacobs 		 * CSTYLED
682264Sjacobs 		 * scheme://[host_part]/[path_part]
692264Sjacobs 		 */
702264Sjacobs 		char *end = NULL, *user = NULL, *host = NULL, *path = NULL;
712264Sjacobs 
722264Sjacobs 		string = ptr + 3; /* skip the :// */
732264Sjacobs 
742264Sjacobs 		if ((path = end = strchr(string, '/')) == NULL)
75*13093SRoger.Faulkner@Oracle.COM 			for (end = string; *end != '\0'; end++)
76*13093SRoger.Faulkner@Oracle.COM 				continue;
772264Sjacobs 
782264Sjacobs 		u->host_part = strndup(string, end - string);
792264Sjacobs 
802264Sjacobs 		for (host = string; host < end; host ++)
812264Sjacobs 			if (*host == '@') {
822264Sjacobs 				/* string to host is the user part */
832264Sjacobs 				u->user_part = strndup(string, host-string);
842264Sjacobs 				/* host+1 to end is the host part */
852264Sjacobs 				u->host_part = strndup(host + 1,
86*13093SRoger.Faulkner@Oracle.COM 				    end - (host+1));
872264Sjacobs 				user = string;
882264Sjacobs 				host++;
892264Sjacobs 				break;
902264Sjacobs 			}
912264Sjacobs 
922264Sjacobs 		if (user != NULL) {
932264Sjacobs 			char *password  = NULL;
942264Sjacobs 
952264Sjacobs 			for (password = user; (password < host - 1); password++)
962264Sjacobs 				if (*password == ':') {
972264Sjacobs 					u->password = strndup(password + 1,
98*13093SRoger.Faulkner@Oracle.COM 					    host - password - 2);
992264Sjacobs 					break;
1002264Sjacobs 				}
1012264Sjacobs 			u->user = strndup(user, password - user);
1022264Sjacobs 		} else
1032264Sjacobs 			host = string;
1042264Sjacobs 
1052264Sjacobs 		if (host != NULL) {
1062264Sjacobs 			char *port  = NULL;
1072264Sjacobs 
1082264Sjacobs 			for (port = host; (port < path); port++)
1092264Sjacobs 				if ((*port == ':') || (*port == '/'))
1102264Sjacobs 					break;
1112264Sjacobs 
1122264Sjacobs 			if (port < path) {
1132264Sjacobs 				u->port = strndup(port + 1, path - port - 1);
1142264Sjacobs 			}
1152264Sjacobs 
1162264Sjacobs 			u->host = strndup(host, port - host);
1172264Sjacobs 		}
1182264Sjacobs 
1192264Sjacobs 		if (path != NULL) {
1202264Sjacobs 			char *name = strrchr(path, '/');
1212264Sjacobs 
1222264Sjacobs 			u->path_part = strdup(path);
1232264Sjacobs 
1242264Sjacobs 			if (name != NULL) {
1252264Sjacobs 				char *query, *fragment;
1262264Sjacobs 
1272264Sjacobs 				query = strrchr(name, '?');
1282264Sjacobs 				if ((query != NULL) && (*query != '\0')) {
1292264Sjacobs 					u->query = strdup(query + 1);
1302264Sjacobs 					end = query;
131*13093SRoger.Faulkner@Oracle.COM 				} else {
132*13093SRoger.Faulkner@Oracle.COM 					for (end = path; *end != '\0'; end++)
133*13093SRoger.Faulkner@Oracle.COM 						continue;
134*13093SRoger.Faulkner@Oracle.COM 				}
1352264Sjacobs 
1362264Sjacobs 				fragment = strrchr(name, '#');
1372264Sjacobs 				if ((fragment != NULL) && (*fragment != '\0')) {
1382264Sjacobs 					u->fragment = strndup(fragment + 1,
139*13093SRoger.Faulkner@Oracle.COM 					    end - fragment - 1);
1402264Sjacobs 					end = fragment;
1412264Sjacobs 				}
1422264Sjacobs 
1432264Sjacobs 				u->path = strndup(path, end - path);
1442264Sjacobs 			}
1452264Sjacobs 		}
1462264Sjacobs 	} else {	/* scheme:scheme_part */
1472264Sjacobs 		u->scheme_part = strdup(&ptr[1]);
1482264Sjacobs 	}
1492264Sjacobs 
1507253Sjacobs 	if ((u->host_part == NULL) && (u->path_part == NULL) &&
1517253Sjacobs 	    (u->scheme_part == NULL)) {
1527253Sjacobs 		errno = EINVAL;
1537253Sjacobs 		uri_free(u);
1547253Sjacobs 		*uri = NULL;
1557253Sjacobs 		return (-1);
1567253Sjacobs 	}
1577253Sjacobs 
1582264Sjacobs 	return (0);
1592264Sjacobs }
1602264Sjacobs 
1612264Sjacobs int
uri_to_string(uri_t * uri,char * buffer,size_t buflen)1622264Sjacobs uri_to_string(uri_t *uri, char *buffer, size_t buflen)
1632264Sjacobs {
1649411SKeerthi.Kondaka@Sun.COM 	char *uri_ppfix;
1659411SKeerthi.Kondaka@Sun.COM 
1662264Sjacobs 	if ((uri == NULL) || (buffer == NULL) || (buflen == 0) ||
1672264Sjacobs 	    (uri->scheme == NULL) ||
1682264Sjacobs 	    ((uri->password != NULL) && (uri->user == NULL)) ||
1692264Sjacobs 	    ((uri->user != NULL) && (uri->host == NULL)) ||
1702264Sjacobs 	    ((uri->port != NULL) && (uri->host == NULL)) ||
1712264Sjacobs 	    ((uri->fragment != NULL) && (uri->path == NULL)) ||
1722264Sjacobs 	    ((uri->query != NULL) && (uri->path == NULL))) {
1732264Sjacobs 		errno = EINVAL;
1742264Sjacobs 		return (-1);
1752264Sjacobs 	}
1769411SKeerthi.Kondaka@Sun.COM 	if (uri->path == NULL || uri->path[0] == '/')
1779411SKeerthi.Kondaka@Sun.COM 		uri_ppfix = "";
1789411SKeerthi.Kondaka@Sun.COM 	else
1799411SKeerthi.Kondaka@Sun.COM 		uri_ppfix = "/";
1802264Sjacobs 
1812264Sjacobs 	(void) memset(buffer, 0, buflen);
1822264Sjacobs 
1832264Sjacobs 	if (uri->scheme_part == NULL) {
1842264Sjacobs 		(void) snprintf(buffer, buflen,
1859411SKeerthi.Kondaka@Sun.COM 		    "%s://%s%s%s%s%s%s%s%s%s%s%s%s%s",
1869411SKeerthi.Kondaka@Sun.COM 		    uri->scheme,
1879411SKeerthi.Kondaka@Sun.COM 		    (uri->user ? uri->user : ""),
1889411SKeerthi.Kondaka@Sun.COM 		    (uri->password ? ":" : ""),
1899411SKeerthi.Kondaka@Sun.COM 		    (uri->password ? uri->password : ""),
1909411SKeerthi.Kondaka@Sun.COM 		    (uri->user ? "@": ""),
1919411SKeerthi.Kondaka@Sun.COM 		    (uri->host ? uri->host : ""),
1929411SKeerthi.Kondaka@Sun.COM 		    (uri->port ? ":" : ""),
1939411SKeerthi.Kondaka@Sun.COM 		    (uri->port ? uri->port : ""),
1949411SKeerthi.Kondaka@Sun.COM 		    uri_ppfix,
1959411SKeerthi.Kondaka@Sun.COM 		    (uri->path ? uri->path : ""),
1969411SKeerthi.Kondaka@Sun.COM 		    (uri->fragment ? "#" : ""),
1979411SKeerthi.Kondaka@Sun.COM 		    (uri->fragment ? uri->fragment : ""),
1989411SKeerthi.Kondaka@Sun.COM 		    (uri->query ? "?" : ""),
1999411SKeerthi.Kondaka@Sun.COM 		    (uri->query ? uri->query : ""));
2002264Sjacobs 	} else {
2012264Sjacobs 		(void) snprintf(buffer, buflen, "%s:%s", uri->scheme,
202*13093SRoger.Faulkner@Oracle.COM 		    uri->scheme_part);
2032264Sjacobs 	}
2042264Sjacobs 
2052264Sjacobs 	return (0);
2062264Sjacobs }
2072264Sjacobs 
2082264Sjacobs void
uri_free(uri_t * uri)2092264Sjacobs uri_free(uri_t *uri)
2102264Sjacobs {
2112264Sjacobs 	if (uri != NULL) {
2122264Sjacobs 		if (uri->scheme != NULL)
2132264Sjacobs 			free(uri->scheme);
2142264Sjacobs 		if (uri->scheme_part != NULL)
2152264Sjacobs 			free(uri->scheme_part);
2162264Sjacobs 		if (uri->user != NULL)
2172264Sjacobs 			free(uri->user);
2182264Sjacobs 		if (uri->password != NULL)
2192264Sjacobs 			free(uri->password);
2202264Sjacobs 		if (uri->host != NULL)
2212264Sjacobs 			free(uri->host);
2222264Sjacobs 		if (uri->port != NULL)
2232264Sjacobs 			free(uri->port);
2242264Sjacobs 		if (uri->path != NULL)
2252264Sjacobs 			free(uri->path);
2262264Sjacobs 		if (uri->fragment != NULL)
2272264Sjacobs 			free(uri->fragment);
2282264Sjacobs 		if (uri->query != NULL)
2292264Sjacobs 			free(uri->query);
2302264Sjacobs 		/* help me debug */
2312264Sjacobs 		if (uri->user_part != NULL)
2322264Sjacobs 			free(uri->user_part);
2332264Sjacobs 		if (uri->host_part != NULL)
2342264Sjacobs 			free(uri->host_part);
2352264Sjacobs 		if (uri->path_part != NULL)
2362264Sjacobs 			free(uri->path_part);
2372264Sjacobs 		free(uri);
2382264Sjacobs 	}
2392264Sjacobs }
2402264Sjacobs 
2412264Sjacobs #ifdef DEADBEEF
2422264Sjacobs static void
uri_dump(FILE * fp,uri_t * uri)2432264Sjacobs uri_dump(FILE *fp, uri_t *uri)
2442264Sjacobs {
2452264Sjacobs 	if (uri != NULL) {
2462264Sjacobs 		fprintf(fp, "URI:\n");
2472264Sjacobs 		if (uri->scheme != NULL)
2482264Sjacobs 			fprintf(fp, "scheme: %s\n", uri->scheme);
2492264Sjacobs 		if (uri->scheme_part != NULL)
2502264Sjacobs 			fprintf(fp, "scheme_part: %s\n", uri->scheme_part);
2512264Sjacobs 		if (uri->user != NULL)
2522264Sjacobs 			fprintf(fp, "user: %s\n", uri->user);
2532264Sjacobs 		if (uri->password != NULL)
2542264Sjacobs 			fprintf(fp, "password: %s\n", uri->password);
2552264Sjacobs 		if (uri->host != NULL)
2562264Sjacobs 			fprintf(fp, "host: %s\n", uri->host);
2572264Sjacobs 		if (uri->port != NULL)
2582264Sjacobs 			fprintf(fp, "port: %s\n", uri->port);
2592264Sjacobs 		if (uri->path != NULL)
2602264Sjacobs 			fprintf(fp, "path: %s\n", uri->path);
2612264Sjacobs 		if (uri->fragment != NULL)
2622264Sjacobs 			fprintf(fp, "fragment: %s\n", uri->fragment);
2632264Sjacobs 		if (uri->query != NULL)
2642264Sjacobs 			fprintf(fp, "query: %s\n", uri->query);
2652264Sjacobs 		/* help me debug */
2662264Sjacobs 		if (uri->user_part != NULL)
2672264Sjacobs 			fprintf(fp, "user_part: %s\n", uri->user_part);
2682264Sjacobs 		if (uri->host_part != NULL)
2692264Sjacobs 			fprintf(fp, "host_part: %s\n", uri->host_part);
2702264Sjacobs 		if (uri->path_part != NULL)
2712264Sjacobs 			fprintf(fp, "path_part: %s\n", uri->path_part);
2722264Sjacobs 		fflush(fp);
2732264Sjacobs 	}
2742264Sjacobs }
2752264Sjacobs 
2762264Sjacobs int
main(int argc,char * argv[])2772264Sjacobs main(int argc, char *argv[])
2782264Sjacobs {
2792264Sjacobs 	uri_t *u = NULL;
2802264Sjacobs 
2812264Sjacobs 	if (argc != 2) {
2822264Sjacobs 		fprintf(stderr, "Usage: %s uri\n", argv[0]);
2832264Sjacobs 		exit(1);
2842264Sjacobs 	}
2852264Sjacobs 
2862264Sjacobs 	if (uri_from_string(argv[1], &u) == 0) {
2872264Sjacobs 		char buf[BUFSIZ];
2882264Sjacobs 
2892264Sjacobs 		uri_dump(stdout, u);
2902264Sjacobs 		uri_to_string(u, buf, sizeof (buf));
2912264Sjacobs 		fprintf(stdout, "reconstituted: %s\n", buf);
2922264Sjacobs 
2932264Sjacobs 		uri_to_string(u, buf, 12);
2942264Sjacobs 		fprintf(stdout, "reconstituted(12): %s\n", buf);
2952264Sjacobs 	} else
2962264Sjacobs 		printf(" failed for %s  (%s)\n", argv[1], strerror(errno));
2972264Sjacobs 
2982264Sjacobs 	exit(0);
2992264Sjacobs }
3002264Sjacobs #endif /* DEADBEEF */
301