xref: /netbsd-src/external/bsd/ntp/dist/libntp/getopt.c (revision cdfa2a7ef92791ba9db70a584a1d904730e6fb46)
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