4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
34 #include <slp-internal.h>
40 #define SLP_IANA "iana"
41 #define SERVICE_PREFIX "service"
43 /* service type struct */
44 typedef struct slp_type
{
45 SLPBoolean isServiceURL
;
52 static SLPError
parseType(char *, slp_type_t
*);
53 static int validateTypeChars(char *);
54 static int validateTransport(char *);
55 static int checkURLString(char *);
57 SLPError
SLPParseSrvURL(char *pcSrvURL
, SLPSrvURL
** ppSrvURL
) {
62 if (!pcSrvURL
|| !ppSrvURL
) {
63 return (SLP_PARAMETER_BAD
);
67 if (!checkURLString((char *)pcSrvURL
))
68 return (SLP_PARSE_ERROR
);
70 if (!(surl
= malloc(sizeof (*surl
)))) {
71 slp_err(LOG_CRIT
, 0, "SLPParseSrvURL", "out of memory");
72 return (SLP_MEMORY_ALLOC_FAILED
);
75 surl
->s_pcSrvType
= "";
76 surl
->s_pcNetFamily
= "";
79 surl
->s_pcSrvPart
= "";
82 p
= strstr(pcSrvURL
, ":/");
88 if (parseType(r
, type
) != SLP_OK
)
91 /* no need to free type since it is on the stack */
92 surl
->s_pcSrvType
= q
;
94 /* do we have a transport? */
99 if (!validateTransport(p
))
101 surl
->s_pcNetFamily
= p
; /* may be \0 */
104 /* do we have a port #? */
107 if (!p
&& !r
) { /* only host part */
111 if (p
&& !r
) { /* host + port, no URL part */
118 surl
->s_iPort
= port
;
122 if (!p
|| p
> r
) { /* no port */
124 } else { /* host + port + url part */
131 surl
->s_iPort
= port
;
134 /* r now points to the URL part */
135 surl
->s_pcSrvPart
= r
;
142 return (SLP_PARSE_ERROR
);
146 * typeString contains only the service type part of an URL. It should
147 * point to a string which parseType can destructively modify.
149 static SLPError
parseType(char *typeString
, slp_type_t
*type
) {
152 /* Initialize type structure */
153 type
->isServiceURL
= SLP_FALSE
;
157 type
->orig
= typeString
;
159 if (!validateTypeChars(typeString
))
160 return (SLP_PARSE_ERROR
);
162 /* Is this a service: URL? */
163 p
= strchr(typeString
, ':');
165 typeString
, SERVICE_PREFIX
, strlen(SERVICE_PREFIX
)) == 0) {
166 type
->isServiceURL
= SLP_TRUE
;
168 return (SLP_PARSE_ERROR
);
171 if (p
) /* can't have an abstract type in a non-service url */
172 return (SLP_PARSE_ERROR
);
176 /* p now points to the beginning of the type */
177 /* is this an abstract type? */
183 return (SLP_PARSE_ERROR
);
186 /* q should now point to the concrete type */
187 /* is there a naming authority? */
192 return (SLP_PARSE_ERROR
);
196 return (SLP_PARSE_ERROR
);
202 static int validateTransport(char *t
) {
204 strcasecmp(t
, "ipx") == 0 ||
205 strcasecmp(t
, "at") == 0)
210 static int checkURLString(char *s
) {
212 size_t l
= strlen(s
);
213 for (i
= 0; i
< l
; i
++) {
215 s
[i
] == '/' || s
[i
] == ':' || s
[i
] == '-' ||
216 s
[i
] == ':' || s
[i
] == '.' || s
[i
] == '%' ||
217 s
[i
] == '_' || s
[i
] == '\''|| s
[i
] == '*' ||
218 s
[i
] == '(' || s
[i
] == ')' || s
[i
] == '$' ||
219 s
[i
] == '!' || s
[i
] == ',' || s
[i
] == '+' ||
220 s
[i
] == '\\'|| s
[i
] == ';' || s
[i
] == '@' ||
221 s
[i
] == '?' || s
[i
] == '&' || s
[i
] == '=')
230 static int validateTypeChars(char *s
) {
232 size_t l
= strlen(s
);
233 for (i
= 0; i
< l
; i
++)
234 if (!isalnum(s
[i
]) &&