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