1*48875230Schristos /* $NetBSD: getsubopt.c,v 1.10 2018/08/30 12:06:06 christos Exp $ */
2edf59accSthorpej
378ef0c30Sperry /*-
478ef0c30Sperry * Copyright (c) 1990, 1993
578ef0c30Sperry * The Regents of the University of California. All rights reserved.
678ef0c30Sperry *
778ef0c30Sperry * Redistribution and use in source and binary forms, with or without
878ef0c30Sperry * modification, are permitted provided that the following conditions
978ef0c30Sperry * are met:
1078ef0c30Sperry * 1. Redistributions of source code must retain the above copyright
1178ef0c30Sperry * notice, this list of conditions and the following disclaimer.
1278ef0c30Sperry * 2. Redistributions in binary form must reproduce the above copyright
1378ef0c30Sperry * notice, this list of conditions and the following disclaimer in the
1478ef0c30Sperry * documentation and/or other materials provided with the distribution.
15eb7c1594Sagc * 3. Neither the name of the University nor the names of its contributors
1678ef0c30Sperry * may be used to endorse or promote products derived from this software
1778ef0c30Sperry * without specific prior written permission.
1878ef0c30Sperry *
1978ef0c30Sperry * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2078ef0c30Sperry * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2178ef0c30Sperry * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2278ef0c30Sperry * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2378ef0c30Sperry * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2478ef0c30Sperry * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2578ef0c30Sperry * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2678ef0c30Sperry * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2778ef0c30Sperry * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2878ef0c30Sperry * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2978ef0c30Sperry * SUCH DAMAGE.
3078ef0c30Sperry */
3178ef0c30Sperry
32*48875230Schristos #if HAVE_NBTOOL_CONFIG_H
33*48875230Schristos #include "nbtool_config.h"
34*48875230Schristos #endif
35*48875230Schristos
36edf59accSthorpej #include <sys/cdefs.h>
37edf59accSthorpej #if defined(LIBC_SCCS) && !defined(lint)
38edf59accSthorpej #if 0
3978ef0c30Sperry static char sccsid[] = "@(#)getsubopt.c 8.1 (Berkeley) 6/4/93";
40edf59accSthorpej #else
41*48875230Schristos __RCSID("$NetBSD: getsubopt.c,v 1.10 2018/08/30 12:06:06 christos Exp $");
42edf59accSthorpej #endif
43edf59accSthorpej #endif /* LIBC_SCCS and not lint */
4478ef0c30Sperry
45f379d2c8Skleink #include "namespace.h"
46f379d2c8Skleink
47b48252f3Slukem #include <assert.h>
4878ef0c30Sperry #include <stdlib.h>
49163c89fbSthorpej #include <string.h>
50163c89fbSthorpej #include <unistd.h>
5178ef0c30Sperry
52f379d2c8Skleink #ifdef __weak_alias
__weak_alias(getsubopt,_getsubopt)53f379d2c8Skleink __weak_alias(getsubopt,_getsubopt)
54f379d2c8Skleink #endif
55f379d2c8Skleink
5678ef0c30Sperry /*
5778ef0c30Sperry * The SVID interface to getsubopt provides no way of figuring out which
5878ef0c30Sperry * part of the suboptions list wasn't matched. This makes error messages
5978ef0c30Sperry * tricky... The extern variable suboptarg is a pointer to the token
6078ef0c30Sperry * which didn't match.
6178ef0c30Sperry */
6278ef0c30Sperry char *suboptarg;
6378ef0c30Sperry
64edf59accSthorpej int
659e66e6d7Sabs getsubopt(char **optionp, char * const *tokens, char **valuep)
6678ef0c30Sperry {
67c8bafd62Sperry int cnt;
68c8bafd62Sperry char *p;
6978ef0c30Sperry
70b48252f3Slukem _DIAGASSERT(tokens != NULL);
71f379d2c8Skleink _DIAGASSERT(valuep != NULL);
72b48252f3Slukem /* optionp is tested below */
73b48252f3Slukem
7478ef0c30Sperry suboptarg = *valuep = NULL;
7578ef0c30Sperry
7678ef0c30Sperry if (!optionp || !*optionp)
7778ef0c30Sperry return(-1);
7878ef0c30Sperry
7978ef0c30Sperry /* skip leading white-space, commas */
8078ef0c30Sperry for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
8178ef0c30Sperry
8278ef0c30Sperry if (!*p) {
8378ef0c30Sperry *optionp = p;
8478ef0c30Sperry return(-1);
8578ef0c30Sperry }
8678ef0c30Sperry
8778ef0c30Sperry /* save the start of the token, and skip the rest of the token. */
8878ef0c30Sperry for (suboptarg = p;
8978ef0c30Sperry *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
9078ef0c30Sperry
9178ef0c30Sperry if (*p) {
9278ef0c30Sperry /*
9378ef0c30Sperry * If there's an equals sign, set the value pointer, and
9478ef0c30Sperry * skip over the value part of the token. Terminate the
9578ef0c30Sperry * token.
9678ef0c30Sperry */
9778ef0c30Sperry if (*p == '=') {
9878ef0c30Sperry *p = '\0';
9978ef0c30Sperry for (*valuep = ++p;
10078ef0c30Sperry *p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
10178ef0c30Sperry if (*p)
10278ef0c30Sperry *p++ = '\0';
10378ef0c30Sperry } else
10478ef0c30Sperry *p++ = '\0';
10578ef0c30Sperry /* Skip any whitespace or commas after this token. */
10678ef0c30Sperry for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
10778ef0c30Sperry }
10878ef0c30Sperry
10978ef0c30Sperry /* set optionp for next round. */
11078ef0c30Sperry *optionp = p;
11178ef0c30Sperry
11278ef0c30Sperry for (cnt = 0; *tokens; ++tokens, ++cnt)
11378ef0c30Sperry if (!strcmp(suboptarg, *tokens))
11478ef0c30Sperry return(cnt);
11578ef0c30Sperry return(-1);
11678ef0c30Sperry }
117