xref: /dragonfly/contrib/smbfs/lib/smb/cfopt.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1 /*
2  * Copyright (c) 2000, Boris Popov
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *    This product includes software developed by Boris Popov.
16  * 4. Neither the name of the author nor the names of any co-contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $Id: cfopt.c,v 1.3 2000/07/11 01:51:49 bp Exp $
33  */
34 #include <sys/param.h>
35 
36 #include <stdio.h>
37 #include <string.h>
38 
39 #include <cflib.h>
40 
41 extern char *__progname;
42 
43 int       cf_opterr = 1,                /* if error message should be printed */
44           cf_optind = 1,                /* index into parent argv vector */
45           cf_optopt,                              /* character checked for validity */
46           cf_optreset;                  /* reset getopt */
47 const char* cf_optarg;                  /* argument associated with option */
48 
49 #define   BADCH     (int)'?'
50 #define   BADARG    (int)':'
51 #define   EMSG      ""
52 
53 int
cf_getopt(nargc,nargv,ostr)54 cf_getopt(nargc, nargv, ostr)
55           int nargc;
56           char * const *nargv;
57           const char *ostr;
58 {
59           static const char *place = EMSG;                  /* option letter processing */
60           char *oli;                                        /* option letter list index */
61           int tmpind;
62 
63           if (cf_optreset || !*place) {           /* update scanning pointer */
64                     cf_optreset = 0;
65                     tmpind = cf_optind;
66                     while (1) {
67                               if (tmpind >= nargc) {
68                                         place = EMSG;
69                                         return (-1);
70                               }
71                               if (*(place = nargv[tmpind]) != '-') {
72                                         tmpind++;
73                                         continue; /* lookup next option */
74                               }
75                               if (place[1] && *++place == '-') {      /* found "--" */
76                                         cf_optind = ++tmpind;
77                                         place = EMSG;
78                                         return (-1);
79                               }
80                               cf_optind = tmpind;
81                               break;
82                     }
83           }                                                 /* option letter okay? */
84           if ((cf_optopt = (int)*place++) == (int)':' ||
85               !(oli = strchr(ostr, cf_optopt))) {
86                     /*
87                      * if the user didn't specify '-' as an option,
88                      * assume it means -1.
89                      */
90                     if (cf_optopt == (int)'-')
91                               return (-1);
92                     if (!*place)
93                               ++cf_optind;
94                     if (cf_opterr && *ostr != ':')
95                               (void)fprintf(stderr,
96                                   "%s: illegal option -- %c\n", __progname, cf_optopt);
97                     return (BADCH);
98           }
99           if (*++oli != ':') {                              /* don't need argument */
100                     cf_optarg = NULL;
101                     if (!*place)
102                               ++cf_optind;
103           }
104           else {                                            /* need an argument */
105                     if (*place)                             /* no white space */
106                               cf_optarg = place;
107                     else if (nargc <= ++cf_optind) {        /* no arg */
108                               place = EMSG;
109                               if (*ostr == ':')
110                                         return (BADARG);
111                               if (cf_opterr)
112                                         (void)fprintf(stderr,
113                                             "%s: option requires an argument -- %c\n",
114                                             __progname, cf_optopt);
115                               return (BADCH);
116                     }
117                     else                                    /* white space */
118                               cf_optarg = nargv[cf_optind];
119                     place = EMSG;
120                     ++cf_optind;
121           }
122           return (cf_optopt);                     /* dump back option letter */
123 }
124