xref: /netbsd-src/external/bsd/openldap/dist/libraries/liblutil/getopt.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /*	$NetBSD: getopt.c,v 1.1.1.4 2014/05/28 09:58:45 tron 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-2014 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 "portable.h"
26 
27 #ifndef HAVE_GETOPT
28 
29 #include <stdio.h>
30 
31 #include <ac/string.h>
32 #include <ac/unistd.h>
33 
34 #ifdef HAVE_IO_H
35 #include <io.h>
36 #endif
37 
38 #include "lutil.h"
39 
40 #ifndef STDERR_FILENO
41 #define STDERR_FILENO 2
42 #endif
43 
44 int opterr = 1;
45 int optind = 1;
46 int optopt;
47 char * optarg;
48 
49 #ifdef HAVE_EBCDIC
50 extern int _trans_argv;
51 #endif
52 
53 static void ERR (char * const argv[], const char * s, char c)
54 {
55 #ifdef DF_TRACE_DEBUG
56 printf("DF_TRACE_DEBUG: 	static void ERR () in getopt.c\n");
57 #endif
58 	if (opterr)
59 	{
60 		char *ptr, outbuf[4096];
61 
62 		ptr = lutil_strncopy(outbuf, argv[0], sizeof(outbuf) - 2);
63 		ptr = lutil_strncopy(ptr, s, sizeof(outbuf)-2 -(ptr-outbuf));
64 		*ptr++ = c;
65 		*ptr++ = '\n';
66 #ifdef HAVE_EBCDIC
67 		__atoe_l(outbuf, ptr - outbuf);
68 #endif
69 		(void) write(STDERR_FILENO,outbuf,ptr - outbuf);
70 	}
71 }
72 
73 int getopt (int argc, char * const argv [], const char * opts)
74 {
75 	static int sp = 1, error = (int) '?';
76 	static char sw = '-', eos = '\0', arg = ':';
77 	register char c, * cp;
78 
79 #ifdef DF_TRACE_DEBUG
80 printf("DF_TRACE_DEBUG: 	int getopt () in getopt.c\n");
81 #endif
82 
83 #ifdef HAVE_EBCDIC
84 	if (_trans_argv) {
85 		int i;
86 		for (i=0; i<argc; i++) __etoa(argv[i]);
87 		_trans_argv = 0;
88 	}
89 #endif
90 	if (sp == 1)
91 	{
92 		if (optind >= argc || argv[optind][0] != sw
93 		|| argv[optind][1] == eos)
94 			return EOF;
95 		else if (strcmp(argv[optind],"--") == 0)
96 		{
97 			optind++;
98 			return EOF;
99 		}
100 	}
101 	c = argv[optind][sp];
102 	optopt = (int) c;
103 	if (c == arg || (cp = strchr(opts,c)) == NULL)
104 	{
105 		ERR(argv,_(": illegal option--"),c);
106 		if (argv[optind][++sp] == eos)
107 		{
108 			optind++;
109 			sp = 1;
110 		}
111 		return error;
112 	}
113 	else if (*++cp == arg)
114 	{
115 		if (argv[optind][sp + 1] != eos)
116 			optarg = &argv[optind++][sp + 1];
117 		else if (++optind >= argc)
118 		{
119 			ERR(argv,_(": option requires an argument--"),c);
120 			sp = 1;
121 			return error;
122 		}
123 		else
124 			optarg = argv[optind++];
125 		sp = 1;
126 	}
127 	else
128 	{
129 		if (argv[optind][++sp] == eos)
130 		{
131 			sp = 1;
132 			optind++;
133 		}
134 		optarg = NULL;
135 	}
136 	return (int) c;
137 }
138 #endif /* HAVE_GETOPT */
139