1 /*        $NetBSD: getopt.c,v 1.5 2020/05/25 20:47:24 christos Exp $  */
2 
3 /*
4  * getopt - get option letter from argv
5  *
6  * This is a version of the public domain getopt() implementation by
7  * Henry Spencer, changed for 4.3BSD compatibility (in addition to System V).
8  * It allows rescanning of an option list by setting optind to 0 before
9  * calling, which is why we use it even if the system has its own (in fact,
10  * this one has a unique name so as not to conflict with the system's).
11  * Thanks to Dennis Ferguson for the appropriate modifications.
12  *
13  * This file is in the Public Domain.
14  */
15 
16 /*LINTLIBRARY*/
17 
18 #include <config.h>
19 #include <stdio.h>
20 
21 #include "ntp_stdlib.h"
22 
23 #ifdef    lint
24 #undef    putc
25 #define   putc      fputc
26 #endif    /* lint */
27 
28 char      *ntp_optarg;        /* Global argument pointer. */
29 int       ntp_optind = 0;     /* Global argv index. */
30 int       ntp_opterr = 1;     /* for compatibility, should error be printed? */
31 int       ntp_optopt;         /* for compatibility, option character checked */
32 
33 static char         *scan = NULL;       /* Private scan pointer. */
34 static const char   *prog = "amnesia";
35 
36 /*
37  * Print message about a bad option.
38  */
39 static int
badopt(const char * mess,int ch)40 badopt(
41           const char *mess,
42           int ch
43           )
44 {
45           if (ntp_opterr) {
46                     fputs(prog, stderr);
47                     fputs(mess, stderr);
48                     (void) putc(ch, stderr);
49                     (void) putc('\n', stderr);
50           }
51           return ('?');
52 }
53 
54 int
ntp_getopt(int argc,char * argv[],const char * optstring)55 ntp_getopt(
56           int argc,
57           char *argv[],
58           const char *optstring
59           )
60 {
61           register char c;
62           register const char *place;
63 
64           prog = argv[0];
65           ntp_optarg = NULL;
66 
67           if (ntp_optind == 0) {
68                     scan = NULL;
69                     ntp_optind++;
70           }
71 
72           if (scan == NULL || *scan == '\0') {
73                     if (ntp_optind >= argc
74                         || argv[ntp_optind][0] != '-'
75                         || argv[ntp_optind][1] == '\0') {
76                               return (EOF);
77                     }
78                     if (argv[ntp_optind][1] == '-'
79                         && argv[ntp_optind][2] == '\0') {
80                               ntp_optind++;
81                               return (EOF);
82                     }
83 
84                     scan = argv[ntp_optind++]+1;
85           }
86 
87           c = *scan++;
88           ntp_optopt = c & 0377;
89           for (place = optstring; place != NULL && *place != '\0'; ++place)
90               if (*place == c)
91                     break;
92 
93           if (place == NULL || *place == '\0' || c == ':' || c == '?') {
94                     return (badopt(": unknown option -", c));
95           }
96 
97           place++;
98           if (*place == ':') {
99                     if (*scan != '\0') {
100                               ntp_optarg = scan;
101                               scan = NULL;
102                     } else if (ntp_optind >= argc) {
103                               return (badopt(": option requires argument -", c));
104                     } else {
105                               ntp_optarg = argv[ntp_optind++];
106                     }
107           }
108 
109           return (c & 0377);
110 }
111