diff --git a/src/mygetopt.c b/src/mygetopt.c new file mode 100644 index 0000000..969d866 --- /dev/null +++ b/src/mygetopt.c @@ -0,0 +1,122 @@ +/* + * zzuf - general purpose fuzzer + * Copyright (c) 2002, 2007 Sam Hocevar + * All Rights Reserved + * + * $Id: mygetopt.c 271 2007-02-02 11:58:06Z sam $ + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + */ + +/* + * mygetopt.c: getopt_long reimplementation + */ + +#include "config.h" + +#if defined HAVE_STDINT_H +# include +#elif defined HAVE_INTTYPES_H +# include +#endif + +#include +#include + +#include "mygetopt.h" + +int myoptind = 1; +char *myoptarg = NULL; + +/* XXX: this getopt_long implementation should not be trusted for other + * applications without any serious peer reviewing. It “just works” with + * zzuf but may fail miserably in other programs. */ +int mygetopt(int argc, char * const _argv[], const char *optstring, + const struct myoption *longopts, int *longindex) +{ + char **argv = (char **)(uintptr_t)_argv; + char *flag; + int i; + + if(myoptind >= argc) + return -1; + + flag = argv[myoptind]; + + if(flag[0] == '-' && flag[1] != '-') + { + char *tmp; + int ret = flag[1]; + + if(ret == '\0') + return -1; + + tmp = strchr(optstring, ret); + if(!tmp || ret == ':') + return '?'; + + myoptind++; + if(tmp[1] == ':') + { + if(flag[2] != '\0') + myoptarg = tmp + 2; + else + myoptarg = argv[myoptind++]; + return ret; + } + + if(flag[2] != '\0') + { + flag[1] = '-'; + myoptind--; + argv[myoptind]++; + } + + return ret; + } + + if(flag[0] == '-' && flag[1] == '-') + { + if(flag[2] == '\0') + return -1; + + for(i = 0; longopts[i].name; i++) + { + size_t l = strlen(longopts[i].name); + + if(strncmp(flag + 2, longopts[i].name, l)) + continue; + + switch(flag[2 + l]) + { + case '=': + if(!longopts[i].has_arg) + goto bad_opt; + if(longindex) + *longindex = i; + myoptind++; + myoptarg = flag + 2 + l + 1; + return longopts[i].val; + case '\0': + if(longindex) + *longindex = i; + myoptind++; + if(longopts[i].has_arg) + myoptarg = argv[myoptind++]; + return longopts[i].val; + default: + break; + } + } + bad_opt: + fprintf(stderr, "%s: unrecognized option `%s'\n", argv[0], flag); + return '?'; + } + + return -1; +} + diff --git a/src/mygetopt.h b/src/mygetopt.h new file mode 100644 index 0000000..2cf62e5 --- /dev/null +++ b/src/mygetopt.h @@ -0,0 +1,31 @@ +/* + * zzuf - general purpose fuzzer + * Copyright (c) 2002, 2007 Sam Hocevar + * All Rights Reserved + * + * $Id: mygetopt.h 268 2007-02-01 22:33:07Z sam $ + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + */ + +/* + * mygetopt.h: getopt_long reimplementation + */ + +struct myoption +{ + const char *name; + int has_arg; + int *flag; + int val; +}; + +extern int myoptind; +extern char *myoptarg; + +int mygetopt(int, char * const[], const char *, const struct myoption *, int *); +