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