00001 /* $Id$ */ 00002 /* 00003 ** Copyright (C) 2002 Martin Roesch <roesch@sourcefire.com> 00004 ** 00005 ** This program is free software; you can redistribute it and/or modify 00006 ** it under the terms of the GNU General Public License as published by 00007 ** the Free Software Foundation; either version 2 of the License, or 00008 ** (at your option) any later version. 00009 ** 00010 ** This program is distributed in the hope that it will be useful, 00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 ** GNU General Public License for more details. 00014 ** 00015 ** You should have received a copy of the GNU General Public License 00016 ** along with this program; if not, write to the Free Software 00017 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 */ 00019 00020 00021 #include <stdio.h> /* for EOF */ 00022 #include <string.h> /* for strchr() */ 00023 00024 #include "getopt.h" 00025 00026 /* static (global) variables that are specified as exported by getopt() */ 00027 char *optarg = NULL; /* pointer to the start of the option argument */ 00028 int optind = 1; /* number of the next argv[] to be evaluated */ 00029 int optopt = 0; 00030 int opterr = 1; /* non-zero if a question mark should be returned 00031 when a non-valid option character is detected */ 00032 int optopt; 00033 00034 int getopt(int argc, char *argv[], const char *opstring) 00035 { 00036 static char *pIndexPosition = NULL; /* place inside current argv string */ 00037 char *pArgString = NULL; /* where to start from next */ 00038 char *pOptString; /* the string in our program */ 00039 00040 00041 if (pIndexPosition != NULL) { 00042 /* we last left off inside an argv string */ 00043 if (*(++pIndexPosition)) { 00044 /* there is more to come in the most recent argv */ 00045 pArgString = pIndexPosition; 00046 } 00047 } 00048 00049 if (pArgString == NULL) { 00050 /* we didn't leave off in the middle of an argv string */ 00051 if (optind >= argc) { 00052 /* more command-line arguments than the argument count */ 00053 pIndexPosition = NULL; /* not in the middle of anything */ 00054 return EOF; /* used up all command-line arguments */ 00055 } 00056 00057 /*--------------------------------------------------------------------- 00058 * If the next argv[] is not an option, there can be no more options. 00059 *-------------------------------------------------------------------*/ 00060 pArgString = argv[optind++]; /* set this to the next argument ptr */ 00061 00062 if (('/' != *pArgString) && /* doesn't start with a slash or a dash? */ 00063 ('-' != *pArgString)) { 00064 --optind; /* point to current arg once we're done */ 00065 optarg = NULL; /* no argument follows the option */ 00066 pIndexPosition = NULL; /* not in the middle of anything */ 00067 return EOF; /* used up all the command-line flags */ 00068 } 00069 00070 /* check for special end-of-flags markers */ 00071 if ((strcmp(pArgString, "-") == 0) || 00072 (strcmp(pArgString, "--") == 0)) { 00073 optarg = NULL; /* no argument follows the option */ 00074 pIndexPosition = NULL; /* not in the middle of anything */ 00075 return EOF; /* encountered the special flag */ 00076 } 00077 00078 pArgString++; /* look past the / or - */ 00079 } 00080 00081 if (':' == *pArgString) { /* is it a colon? */ 00082 /*--------------------------------------------------------------------- 00083 * Rare case: if opterr is non-zero, return a question mark; 00084 * otherwise, just return the colon we're on. 00085 *-------------------------------------------------------------------*/ 00086 optopt = *pArgString; 00087 return (opterr ? (int)'?' : (int)':'); 00088 } 00089 else if ((pOptString = strchr(opstring, *pArgString)) == 0) { 00090 /*--------------------------------------------------------------------- 00091 * The letter on the command-line wasn't any good. 00092 *-------------------------------------------------------------------*/ 00093 optarg = NULL; /* no argument follows the option */ 00094 pIndexPosition = NULL; /* not in the middle of anything */ 00095 optopt = *pArgString; 00096 return (opterr ? (int)'?' : (int)*pArgString); 00097 } 00098 else { 00099 /*--------------------------------------------------------------------- 00100 * The letter on the command-line matches one we expect to see 00101 *-------------------------------------------------------------------*/ 00102 if (':' == _next_char(pOptString)) { /* is the next letter a colon? */ 00103 /* It is a colon. Look for an argument string. */ 00104 if ('\0' != _next_char(pArgString)) { /* argument in this argv? */ 00105 optarg = &pArgString[1]; /* Yes, it is */ 00106 } 00107 else { 00108 /*------------------------------------------------------------- 00109 * The argument string must be in the next argv. 00110 * But, what if there is none (bad input from the user)? 00111 * In that case, return the letter, and optarg as NULL. 00112 *-----------------------------------------------------------*/ 00113 if (optind < argc) 00114 optarg = argv[optind++]; 00115 else { 00116 optarg = NULL; 00117 optopt = *pArgString; 00118 return (opterr ? (int)'?' : (int)*pArgString); 00119 } 00120 } 00121 00122 pIndexPosition = NULL; /* not in the middle of anything */ 00123 } 00124 else { 00125 /* it's not a colon, so just return the letter */ 00126 optarg = NULL; /* no argument follows the option */ 00127 pIndexPosition = pArgString; /* point to the letter we're on */ 00128 } 00129 return (int)*pArgString; /* return the letter that matched */ 00130 } 00131 } 00132