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