xref: /netbsd-src/external/bsd/openldap/dist/libraries/liblutil/getopt.c (revision 181254a7b1bdde6873432bffef2d2decc4b5c22f)
1 /*	$NetBSD: getopt.c,v 1.2 2020/08/11 13:15:39 christos Exp $	*/
2 
3 /* getopt.c -- replacement getopt(3) routines */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6  *
7  * Copyright 1998-2020 The OpenLDAP Foundation.
8  * Portions Copyright 1998-2003 Kurt D. Zeilenga.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted only as authorized by the OpenLDAP
13  * Public License.
14  *
15  * A copy of this license is available in the file LICENSE in the
16  * top-level directory of the distribution or, alternatively, at
17  * <http://www.OpenLDAP.org/license.html>.
18  */
19 /* This work is based upon the public-domain getopt(3) routines
20  * developed by AT&T.  Modified by Kurt D. Zeilenga for inclusion
21  * into OpenLDAP Software.  Significant contributors include:
22  *   Howard Chu
23  */
24 
25 #include <sys/cdefs.h>
26 __RCSID("$NetBSD: getopt.c,v 1.2 2020/08/11 13:15:39 christos Exp $");
27 
28 #include "portable.h"
29 
30 #ifndef HAVE_GETOPT
31 
32 #include <stdio.h>
33 
34 #include <ac/string.h>
35 #include <ac/unistd.h>
36 
37 #ifdef HAVE_IO_H
38 #include <io.h>
39 #endif
40 
41 #include "lutil.h"
42 
43 #ifndef STDERR_FILENO
44 #define STDERR_FILENO 2
45 #endif
46 
47 int opterr = 1;
48 int optind = 1;
49 int optopt;
50 char * optarg;
51 
52 #ifdef HAVE_EBCDIC
53 extern int _trans_argv;
54 #endif
55 
56 static void ERR (char * const argv[], const char * s, char c)
57 {
58 #ifdef DF_TRACE_DEBUG
59 printf("DF_TRACE_DEBUG: 	static void ERR () in getopt.c\n");
60 #endif
61 	if (opterr)
62 	{
63 		char *ptr, outbuf[4096];
64 
65 		ptr = lutil_strncopy(outbuf, argv[0], sizeof(outbuf) - 2);
66 		ptr = lutil_strncopy(ptr, s, sizeof(outbuf)-2 -(ptr-outbuf));
67 		*ptr++ = c;
68 		*ptr++ = '\n';
69 #ifdef HAVE_EBCDIC
70 		__atoe_l(outbuf, ptr - outbuf);
71 #endif
72 		(void) write(STDERR_FILENO,outbuf,ptr - outbuf);
73 	}
74 }
75 
76 int getopt (int argc, char * const argv [], const char * opts)
77 {
78 	static int sp = 1, error = (int) '?';
79 	static char sw = '-', eos = '\0', arg = ':';
80 	register char c, * cp;
81 
82 #ifdef DF_TRACE_DEBUG
83 printf("DF_TRACE_DEBUG: 	int getopt () in getopt.c\n");
84 #endif
85 
86 #ifdef HAVE_EBCDIC
87 	if (_trans_argv) {
88 		int i;
89 		for (i=0; i<argc; i++) __etoa(argv[i]);
90 		_trans_argv = 0;
91 	}
92 #endif
93 	if (sp == 1)
94 	{
95 		if (optind >= argc || argv[optind][0] != sw
96 		|| argv[optind][1] == eos)
97 			return EOF;
98 		else if (strcmp(argv[optind],"--") == 0)
99 		{
100 			optind++;
101 			return EOF;
102 		}
103 	}
104 	c = argv[optind][sp];
105 	optopt = (int) c;
106 	if (c == arg || (cp = strchr(opts,c)) == NULL)
107 	{
108 		ERR(argv,_(": illegal option--"),c);
109 		if (argv[optind][++sp] == eos)
110 		{
111 			optind++;
112 			sp = 1;
113 		}
114 		return error;
115 	}
116 	else if (*++cp == arg)
117 	{
118 		if (argv[optind][sp + 1] != eos)
119 			optarg = &argv[optind++][sp + 1];
120 		else if (++optind >= argc)
121 		{
122 			ERR(argv,_(": option requires an argument--"),c);
123 			sp = 1;
124 			return error;
125 		}
126 		else
127 			optarg = argv[optind++];
128 		sp = 1;
129 	}
130 	else
131 	{
132 		if (argv[optind][++sp] == eos)
133 		{
134 			sp = 1;
135 			optind++;
136 		}
137 		optarg = NULL;
138 	}
139 	return (int) c;
140 }
141 #endif /* HAVE_GETOPT */
142