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