1 /* $NetBSD: getopt.c,v 1.3 2021/08/14 16:14:58 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-2021 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.3 2021/08/14 16:14:58 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
ERR(char * const argv[],const char * s,char c)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
getopt(int argc,char * const argv[],const char * opts)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