diff options
| author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 | 
|---|---|---|
| committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 | 
| commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
| tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/lib/libslp/clib/SLPParseSrvURL.c | |
| download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz | |
OpenSolaris Launch
Diffstat (limited to 'usr/src/lib/libslp/clib/SLPParseSrvURL.c')
| -rw-r--r-- | usr/src/lib/libslp/clib/SLPParseSrvURL.c | 241 | 
1 files changed, 241 insertions, 0 deletions
| diff --git a/usr/src/lib/libslp/clib/SLPParseSrvURL.c b/usr/src/lib/libslp/clib/SLPParseSrvURL.c new file mode 100644 index 0000000000..90be36f2c1 --- /dev/null +++ b/usr/src/lib/libslp/clib/SLPParseSrvURL.c @@ -0,0 +1,241 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License").  You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1999 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident	"%Z%%M%	%I%	%E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include <syslog.h> +#include <slp-internal.h> + +/* + * URL parsing + */ + +#define	SLP_IANA	"iana" +#define	SERVICE_PREFIX	"service" + +/* service type struct */ +typedef struct slp_type { +	SLPBoolean isServiceURL; +	char *atype; +	char *ctype; +	char *na; +	char *orig; +} slp_type_t; + +static SLPError parseType(char *, slp_type_t *); +static int validateTypeChars(char *); +static int validateTransport(char *); +static int checkURLString(char *); + +SLPError SLPParseSrvURL(char *pcSrvURL, SLPSrvURL** ppSrvURL) { +	char *p, *q, *r; +	SLPSrvURL *surl; +	slp_type_t type[1]; + +	if (!pcSrvURL || !ppSrvURL) { +		return (SLP_PARAMETER_BAD); +	} + +	*ppSrvURL = NULL; +	if (!checkURLString((char *)pcSrvURL)) +		return (SLP_PARSE_ERROR); + +	if (!(surl = malloc(sizeof (*surl)))) { +		slp_err(LOG_CRIT, 0, "SLPParseSrvURL", "out of memory"); +		return (SLP_MEMORY_ALLOC_FAILED); +	} +	*ppSrvURL = surl; +	surl->s_pcSrvType = ""; +	surl->s_pcNetFamily = ""; +	surl->s_pcHost = ""; +	surl->s_iPort = 0; +	surl->s_pcSrvPart = ""; + +	/* parse type */ +	p = strstr(pcSrvURL, ":/"); +	if (!p) +		goto error; +	q = pcSrvURL; +	*p++ = 0; p++; +	r = strdup(q); +	if (parseType(r, type) != SLP_OK) +	goto error; +	free(r); +	/* no need to free type since it is on the stack */ +	surl->s_pcSrvType = q; + +	/* do we have a transport? */ +	q = strchr(p, '/'); +	if (!q) +		goto error; +	*q++ = 0; +	if (!validateTransport(p)) +		goto error; +	surl->s_pcNetFamily = p;	/* may be \0 */ + +	/* host part */ +	/* do we have a port #? */ +	p = strchr(q, ':'); +	r = strchr(q, '/'); +	if (!p && !r) {	/* only host part */ +		surl->s_pcHost = q; +		return (SLP_OK); +	} +	if (p && !r) {	/* host + port, no URL part */ +		int port; +		surl->s_pcHost = q; +		*p++ = 0; +		port = atoi(p); +		if (port <= 0) +			goto error; +		surl->s_iPort = port; +		return (SLP_OK); +	} +	*r++ = 0; +	if (!p || p > r) {	/* no port */ +		surl->s_pcHost = q; +	} else {		/* host + port + url part */ +		int port; +		surl->s_pcHost = q; +		*p++ = 0; +		port = atoi(p); +		if (port <= 0) +			goto error; +		surl->s_iPort = port; +	} + +	/* r now points to the URL part */ +	surl->s_pcSrvPart = r; + +	return (SLP_OK); + +error: +	free(surl); +	*ppSrvURL = NULL; +	return (SLP_PARSE_ERROR); +} + +/* + * typeString contains only the service type part of an URL. It should + * point to a string which parseType can destructively modify. + */ +static SLPError parseType(char *typeString, slp_type_t *type) { +	char *p, *q; + +	/* Initialize type structure */ +	type->isServiceURL = SLP_FALSE; +	type->atype = NULL; +	type->ctype = NULL; +	type->na = NULL; +	type->orig = typeString; + +	if (!validateTypeChars(typeString)) +		return (SLP_PARSE_ERROR); + +	/* Is this a service: URL? */ +	p = strchr(typeString, ':'); +	if (strncasecmp( +		typeString, SERVICE_PREFIX, strlen(SERVICE_PREFIX)) == 0) { +		type->isServiceURL = SLP_TRUE; +		if (!p) +			return (SLP_PARSE_ERROR); +		*p++ = 0; +	} else { +		if (p)	/* can't have an abstract type in a non-service url */ +			return (SLP_PARSE_ERROR); +		p = typeString; +	} + +	/* p now points to the beginning of the type */ +	/* is this an abstract type? */ +	q = strchr(p, ':'); +	if (q) { +		type->atype = p; +		*q++ = 0; +		if (!*p) +			return (SLP_PARSE_ERROR); +	} else { q = p; } + +	/* q should now point to the concrete type */ +	/* is there a naming authority? */ +	p = strchr(q, '.'); +	if (p) { +		*p++ = 0; +		if (!*p) +			return (SLP_PARSE_ERROR); +		type->na = p; +	} +	if (!*q) +		return (SLP_PARSE_ERROR); +	type->ctype = q; + +	return (SLP_OK); +} + +static int validateTransport(char *t) { +	if (*t == 0 || +	    strcasecmp(t, "ipx") == 0 || +	    strcasecmp(t, "at") == 0) +		return (1); +	return (0); +} + +static int checkURLString(char *s) { +	int i; +	size_t l = strlen(s); +	for (i = 0; i < l; i++) { +		if (isalnum(s[i]) || +		    s[i] == '/' || s[i] == ':' || s[i] == '-' || +		    s[i] == ':' || s[i] == '.' || s[i] == '%' || +		    s[i] == '_' || s[i] == '\''|| s[i] == '*' || +		    s[i] == '(' || s[i] == ')' || s[i] == '$' || +		    s[i] == '!' || s[i] == ',' || s[i] == '+' || +		    s[i] == '\\'|| s[i] == ';' || s[i] == '@' || +		    s[i] == '?' || s[i] == '&' || s[i] == '=') +			continue; +		return (0); +	} + +	return (1); +} + + +static int validateTypeChars(char *s) { +	int i; +	size_t l = strlen(s); +	for (i = 0; i < l; i++) +		if (!isalnum(s[i]) && +		    s[i] != '-' && +		    s[i] != '+' && +		    s[i] != '.' && +		    s[i] != ':') +			return (0); +	return (1); +} | 
