xref: /freebsd/contrib/ntp/libntp/getopt.c (revision dd41de95a84d979615a2ef11df6850622bf6184e)
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 <config.h>
17 #include <stdio.h>
18 
19 #include "ntp_stdlib.h"
20 
21 #ifdef	lint
22 #undef	putc
23 #define	putc	fputc
24 #endif	/* lint */
25 
26 char	*ntp_optarg;	/* Global argument pointer. */
27 int	ntp_optind = 0;	/* Global argv index. */
28 int	ntp_opterr = 1;	/* for compatibility, should error be printed? */
29 int	ntp_optopt;	/* for compatibility, option character checked */
30 
31 static char	*scan = NULL;	/* Private scan pointer. */
32 static const char	*prog = "amnesia";
33 
34 /*
35  * Print message about a bad option.
36  */
37 static int
38 badopt(
39 	const char *mess,
40 	int ch
41 	)
42 {
43 	if (ntp_opterr) {
44 		fputs(prog, stderr);
45 		fputs(mess, stderr);
46 		(void) putc(ch, stderr);
47 		(void) putc('\n', stderr);
48 	}
49 	return ('?');
50 }
51 
52 int
53 ntp_getopt(
54 	int argc,
55 	char *argv[],
56 	const char *optstring
57 	)
58 {
59 	register char c;
60 	register const char *place;
61 
62 	prog = argv[0];
63 	ntp_optarg = NULL;
64 
65 	if (ntp_optind == 0) {
66 		scan = NULL;
67 		ntp_optind++;
68 	}
69 
70 	if (scan == NULL || *scan == '\0') {
71 		if (ntp_optind >= argc
72 		    || argv[ntp_optind][0] != '-'
73 		    || argv[ntp_optind][1] == '\0') {
74 			return (EOF);
75 		}
76 		if (argv[ntp_optind][1] == '-'
77 		    && argv[ntp_optind][2] == '\0') {
78 			ntp_optind++;
79 			return (EOF);
80 		}
81 
82 		scan = argv[ntp_optind++]+1;
83 	}
84 
85 	c = *scan++;
86 	ntp_optopt = c & 0377;
87 	for (place = optstring; place != NULL && *place != '\0'; ++place)
88 	    if (*place == c)
89 		break;
90 
91 	if (place == NULL || *place == '\0' || c == ':' || c == '?') {
92 		return (badopt(": unknown option -", c));
93 	}
94 
95 	place++;
96 	if (*place == ':') {
97 		if (*scan != '\0') {
98 			ntp_optarg = scan;
99 			scan = NULL;
100 		} else if (ntp_optind >= argc) {
101 			return (badopt(": option requires argument -", c));
102 		} else {
103 			ntp_optarg = argv[ntp_optind++];
104 		}
105 	}
106 
107 	return (c & 0377);
108 }
109