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