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-gate-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); +} |