8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libslp / clib / SLPParseSrvURL.c
blob90be36f2c11b05edcf2a679d97a58ed79e8cc0c2
1 /*
2 * CDDL HEADER START
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
7 * with the License.
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]
20 * CDDL HEADER END
23 * Copyright (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <ctype.h>
32 #include <string.h>
33 #include <syslog.h>
34 #include <slp-internal.h>
37 * URL parsing
40 #define SLP_IANA "iana"
41 #define SERVICE_PREFIX "service"
43 /* service type struct */
44 typedef struct slp_type {
45 SLPBoolean isServiceURL;
46 char *atype;
47 char *ctype;
48 char *na;
49 char *orig;
50 } slp_type_t;
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) {
58 char *p, *q, *r;
59 SLPSrvURL *surl;
60 slp_type_t type[1];
62 if (!pcSrvURL || !ppSrvURL) {
63 return (SLP_PARAMETER_BAD);
66 *ppSrvURL = NULL;
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);
74 *ppSrvURL = surl;
75 surl->s_pcSrvType = "";
76 surl->s_pcNetFamily = "";
77 surl->s_pcHost = "";
78 surl->s_iPort = 0;
79 surl->s_pcSrvPart = "";
81 /* parse type */
82 p = strstr(pcSrvURL, ":/");
83 if (!p)
84 goto error;
85 q = pcSrvURL;
86 *p++ = 0; p++;
87 r = strdup(q);
88 if (parseType(r, type) != SLP_OK)
89 goto error;
90 free(r);
91 /* no need to free type since it is on the stack */
92 surl->s_pcSrvType = q;
94 /* do we have a transport? */
95 q = strchr(p, '/');
96 if (!q)
97 goto error;
98 *q++ = 0;
99 if (!validateTransport(p))
100 goto error;
101 surl->s_pcNetFamily = p; /* may be \0 */
103 /* host part */
104 /* do we have a port #? */
105 p = strchr(q, ':');
106 r = strchr(q, '/');
107 if (!p && !r) { /* only host part */
108 surl->s_pcHost = q;
109 return (SLP_OK);
111 if (p && !r) { /* host + port, no URL part */
112 int port;
113 surl->s_pcHost = q;
114 *p++ = 0;
115 port = atoi(p);
116 if (port <= 0)
117 goto error;
118 surl->s_iPort = port;
119 return (SLP_OK);
121 *r++ = 0;
122 if (!p || p > r) { /* no port */
123 surl->s_pcHost = q;
124 } else { /* host + port + url part */
125 int port;
126 surl->s_pcHost = q;
127 *p++ = 0;
128 port = atoi(p);
129 if (port <= 0)
130 goto error;
131 surl->s_iPort = port;
134 /* r now points to the URL part */
135 surl->s_pcSrvPart = r;
137 return (SLP_OK);
139 error:
140 free(surl);
141 *ppSrvURL = NULL;
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) {
150 char *p, *q;
152 /* Initialize type structure */
153 type->isServiceURL = SLP_FALSE;
154 type->atype = NULL;
155 type->ctype = NULL;
156 type->na = NULL;
157 type->orig = typeString;
159 if (!validateTypeChars(typeString))
160 return (SLP_PARSE_ERROR);
162 /* Is this a service: URL? */
163 p = strchr(typeString, ':');
164 if (strncasecmp(
165 typeString, SERVICE_PREFIX, strlen(SERVICE_PREFIX)) == 0) {
166 type->isServiceURL = SLP_TRUE;
167 if (!p)
168 return (SLP_PARSE_ERROR);
169 *p++ = 0;
170 } else {
171 if (p) /* can't have an abstract type in a non-service url */
172 return (SLP_PARSE_ERROR);
173 p = typeString;
176 /* p now points to the beginning of the type */
177 /* is this an abstract type? */
178 q = strchr(p, ':');
179 if (q) {
180 type->atype = p;
181 *q++ = 0;
182 if (!*p)
183 return (SLP_PARSE_ERROR);
184 } else { q = p; }
186 /* q should now point to the concrete type */
187 /* is there a naming authority? */
188 p = strchr(q, '.');
189 if (p) {
190 *p++ = 0;
191 if (!*p)
192 return (SLP_PARSE_ERROR);
193 type->na = p;
195 if (!*q)
196 return (SLP_PARSE_ERROR);
197 type->ctype = q;
199 return (SLP_OK);
202 static int validateTransport(char *t) {
203 if (*t == 0 ||
204 strcasecmp(t, "ipx") == 0 ||
205 strcasecmp(t, "at") == 0)
206 return (1);
207 return (0);
210 static int checkURLString(char *s) {
211 int i;
212 size_t l = strlen(s);
213 for (i = 0; i < l; i++) {
214 if (isalnum(s[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] == '=')
222 continue;
223 return (0);
226 return (1);
230 static int validateTypeChars(char *s) {
231 int i;
232 size_t l = strlen(s);
233 for (i = 0; i < l; i++)
234 if (!isalnum(s[i]) &&
235 s[i] != '-' &&
236 s[i] != '+' &&
237 s[i] != '.' &&
238 s[i] != ':')
239 return (0);
240 return (1);