xref: /netbsd-src/external/bsd/openldap/dist/libraries/liblutil/getopt.c (revision 404fbe5fb94ca1e054339640cabb2801ce52dd30)
1 /* getopt.c -- replacement getopt(3) routines */
2 /* $OpenLDAP: pkg/ldap/libraries/liblutil/getopt.c,v 1.16.2.3 2008/02/11 23:26:42 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2008 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 
42 int opterr = 1;
43 int optind = 1;
44 int optopt;
45 char * optarg;
46 
47 #ifdef HAVE_EBCDIC
48 extern int _trans_argv;
49 #endif
50 
51 static void ERR (char * const argv[], const char * s, char c)
52 {
53 #ifdef DF_TRACE_DEBUG
54 printf("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 
71 int 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
78 printf("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