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