/*
* 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
* 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
*/
/* service type struct */
typedef struct slp_type {
char *atype;
char *ctype;
char *na;
char *orig;
} slp_type_t;
static int validateTypeChars(char *);
static int validateTransport(char *);
static int checkURLString(char *);
char *p, *q, *r;
return (SLP_PARAMETER_BAD);
}
if (!checkURLString((char *)pcSrvURL))
return (SLP_PARSE_ERROR);
return (SLP_MEMORY_ALLOC_FAILED);
}
/* parse type */
if (!p)
goto error;
q = pcSrvURL;
*p++ = 0; p++;
r = strdup(q);
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;
/* host part */
/* do we have a port #? */
p = strchr(q, ':');
r = strchr(q, '/');
if (!p && !r) { /* only host part */
return (SLP_OK);
}
if (p && !r) { /* host + port, no URL part */
int port;
*p++ = 0;
if (port <= 0)
goto error;
return (SLP_OK);
}
*r++ = 0;
if (!p || p > r) { /* no port */
} else { /* host + port + url part */
int port;
*p++ = 0;
if (port <= 0)
goto error;
}
/* r now points to the URL part */
surl->s_pcSrvPart = r;
return (SLP_OK);
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.
*/
char *p, *q;
/* Initialize type structure */
if (!validateTypeChars(typeString))
return (SLP_PARSE_ERROR);
/* Is this a service: URL? */
if (strncasecmp(
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) {
*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);
}
if (!*q)
return (SLP_PARSE_ERROR);
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;
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;
for (i = 0; i < l; i++)
if (!isalnum(s[i]) &&
s[i] != '-' &&
s[i] != '+' &&
s[i] != '.' &&
s[i] != ':')
return (0);
return (1);
}