xref: /minix/external/bsd/bind/dist/lib/dns/gen-win32.h (revision 00b67f09)
1 /*	$NetBSD: gen-win32.h,v 1.5 2014/12/10 04:37:58 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2004-2007, 2009, 2014  Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (C) 1999-2001  Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*
21  * Copyright (c) 1987, 1993, 1994
22  *	The Regents of the University of California.  All rights reserved.
23  *
24  * Redistribution and use in source and binary forms, with or without
25  * modification, are permitted provided that the following conditions
26  * are met:
27  * 1. Redistributions of source code must retain the above copyright
28  *    notice, this list of conditions and the following disclaimer.
29  * 2. Redistributions in binary form must reproduce the above copyright
30  *    notice, this list of conditions and the following disclaimer in the
31  *    documentation and/or other materials provided with the distribution.
32  * 3. Neither the name of the University nor the names of its contributors
33  *    may be used to endorse or promote products derived from this software
34  *    without specific prior written permission.
35  *
36  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
37  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
40  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
42  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
44  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
45  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  */
48 
49 /* Id: gen-win32.h,v 1.25 2009/01/17 23:47:42 tbox Exp  */
50 
51 /*! \file
52  * \author Principal Authors: Computer Systems Research Group at UC Berkeley
53  * \author Principal ISC caretaker: DCL
54  */
55 
56 /*
57  * \note This file was adapted from the NetBSD project's source tree, RCS ID:
58  *    NetBSD: getopt.c,v 1.15 1999/09/20 04:39:37 lukem Exp
59  *
60  * The primary change has been to rename items to the ISC namespace
61  * and format in the ISC coding style.
62  *
63  * This file is responsible for defining two operations that are not
64  * directly portable between Unix-like systems and Windows NT, option
65  * parsing and directory scanning.  It is here because it was decided
66  * that the "gen" build utility was not to depend on libisc.a, so
67  * the functions declared in isc/commandline.h and isc/dir.h could not
68  * be used.
69  *
70  * The commandline stuff is pretty much a straight copy from the initial
71  * isc/commandline.c.  The dir stuff was shrunk to fit the needs of gen.c.
72  */
73 
74 #ifndef DNS_GEN_WIN32_H
75 #define DNS_GEN_WIN32_H 1
76 
77 #include <stdio.h>
78 #include <string.h>
79 #include <windows.h>
80 
81 #include <isc/boolean.h>
82 #include <isc/lang.h>
83 
84 int isc_commandline_index = 1;		/* Index into parent argv vector. */
85 int isc_commandline_option;		/* Character checked for validity. */
86 
87 char *isc_commandline_argument;		/* Argument associated with option. */
88 char *isc_commandline_progname;		/* For printing error messages. */
89 
90 isc_boolean_t isc_commandline_errprint = ISC_TRUE; /* Print error messages. */
91 isc_boolean_t isc_commandline_reset = ISC_TRUE; /* Reset processing. */
92 
93 #define BADOPT	'?'
94 #define BADARG	':'
95 #define ENDOPT	""
96 
97 ISC_LANG_BEGINDECLS
98 
99 /*
100  * getopt --
101  *	Parse argc/argv argument vector.
102  */
103 int
isc_commandline_parse(int argc,char * const * argv,const char * options)104 isc_commandline_parse(int argc, char * const *argv, const char *options) {
105 	static char *place = ENDOPT;
106 	char *option;			/* Index into *options of option. */
107 
108 	/*
109 	 * Update scanning pointer, either because a reset was requested or
110 	 * the previous argv was finished.
111 	 */
112 	if (isc_commandline_reset || *place == '\0') {
113 		isc_commandline_reset = ISC_FALSE;
114 
115 		if (isc_commandline_progname == NULL)
116 			isc_commandline_progname = argv[0];
117 
118 		if (isc_commandline_index >= argc ||
119 		    *(place = argv[isc_commandline_index]) != '-') {
120 			/*
121 			 * Index out of range or points to non-option.
122 			 */
123 			place = ENDOPT;
124 			return (-1);
125 		}
126 
127 		if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
128 			/*
129 			 * Found '--' to signal end of options.	 Advance
130 			 * index to next argv, the first non-option.
131 			 */
132 			isc_commandline_index++;
133 			place = ENDOPT;
134 			return (-1);
135 		}
136 	}
137 
138 	isc_commandline_option = *place++;
139 	option = strchr(options, isc_commandline_option);
140 
141 	/*
142 	 * Ensure valid option has been passed as specified by options string.
143 	 * '-:' is never a valid command line option because it could not
144 	 * distinguish ':' from the argument specifier in the options string.
145 	 */
146 	if (isc_commandline_option == ':' || option == NULL) {
147 		if (*place == '\0')
148 			isc_commandline_index++;
149 
150 		if (isc_commandline_errprint && *options != ':')
151 			fprintf(stderr, "%s: illegal option -- %c\n",
152 				isc_commandline_progname,
153 				isc_commandline_option);
154 
155 		return (BADOPT);
156 	}
157 
158 	if (*++option != ':') {
159 		/*
160 		 * Option does not take an argument.
161 		 */
162 		isc_commandline_argument = NULL;
163 
164 		/*
165 		 * Skip to next argv if at the end of the current argv.
166 		 */
167 		if (*place == '\0')
168 			++isc_commandline_index;
169 
170 	} else {
171 		/*
172 		 * Option needs an argument.
173 		 */
174 		if (*place != '\0')
175 			/*
176 			 * Option is in this argv, -D1 style.
177 			 */
178 			isc_commandline_argument = place;
179 
180 		else if (argc > ++isc_commandline_index)
181 			/*
182 			 * Option is next argv, -D 1 style.
183 			 */
184 			isc_commandline_argument = argv[isc_commandline_index];
185 
186 		else {
187 			/*
188 			 * Argument needed, but no more argv.
189 			 */
190 			place = ENDOPT;
191 
192 			/*
193 			 * Silent failure with "missing argument" return
194 			 * when ':' starts options string, per historical spec.
195 			 */
196 			if (*options == ':')
197 				return (BADARG);
198 
199 			if (isc_commandline_errprint)
200 				fprintf(stderr,
201 				    "%s: option requires an argument -- %c\n",
202 				    isc_commandline_progname,
203 				    isc_commandline_option);
204 
205 			return (BADOPT);
206 		}
207 
208 		place = ENDOPT;
209 
210 		/*
211 		 * Point to argv that follows argument.
212 		 */
213 		isc_commandline_index++;
214 	}
215 
216 	return (isc_commandline_option);
217 }
218 
219 typedef struct {
220 	HANDLE handle;
221 	WIN32_FIND_DATA	find_data;
222 	isc_boolean_t first_file;
223 	char *filename;
224 } isc_dir_t;
225 
226 isc_boolean_t
start_directory(const char * path,isc_dir_t * dir)227 start_directory(const char *path, isc_dir_t *dir) {
228 	char pattern[_MAX_PATH], *p;
229 
230 	/*
231 	 * Need space for slash-splat and final NUL.
232 	 */
233 	if (strlen(path) + 3 > sizeof(pattern))
234 		return (ISC_FALSE);
235 
236 	strcpy(pattern, path);
237 
238 	/*
239 	 * Append slash (if needed) and splat.
240 	 */
241 	p = pattern + strlen(pattern);
242 	if (p != pattern  && p[-1] != '\\' && p[-1] != ':')
243 		*p++ = '\\';
244 	*p++ = '*';
245 	*p++ = '\0';
246 
247 	dir->first_file = ISC_TRUE;
248 
249 	dir->handle = FindFirstFile(pattern, &dir->find_data);
250 
251 	if (dir->handle == INVALID_HANDLE_VALUE) {
252 		dir->filename = NULL;
253 		return (ISC_FALSE);
254 	} else {
255 		dir->filename = dir->find_data.cFileName;
256 		return (ISC_TRUE);
257 	}
258 }
259 
260 isc_boolean_t
next_file(isc_dir_t * dir)261 next_file(isc_dir_t *dir) {
262 	if (dir->first_file)
263 		dir->first_file = ISC_FALSE;
264 
265 	else if (dir->handle != INVALID_HANDLE_VALUE) {
266 		if (FindNextFile(dir->handle, &dir->find_data) == TRUE)
267 			dir->filename = dir->find_data.cFileName;
268 		else
269 			dir->filename = NULL;
270 
271 	} else
272 		dir->filename = NULL;
273 
274 	if (dir->filename != NULL)
275 		return (ISC_TRUE);
276 	else
277 		return (ISC_FALSE);
278 }
279 
280 void
end_directory(isc_dir_t * dir)281 end_directory(isc_dir_t *dir) {
282 	if (dir->handle != INVALID_HANDLE_VALUE)
283 		FindClose(dir->handle);
284 }
285 
286 ISC_LANG_ENDDECLS
287 
288 #endif /* DNS_GEN_WIN32_H */
289