1 /* $NetBSD: getopt.c,v 1.3 2015/07/10 14:20:32 christos Exp $ */ 2 3 /* 4 * getopt - get option letter from argv 5 * 6 * This is a version of the public domain getopt() implementation by 7 * Henry Spencer, changed for 4.3BSD compatibility (in addition to System V). 8 * It allows rescanning of an option list by setting optind to 0 before 9 * calling, which is why we use it even if the system has its own (in fact, 10 * this one has a unique name so as not to conflict with the system's). 11 * Thanks to Dennis Ferguson for the appropriate modifications. 12 * 13 * This file is in the Public Domain. 14 */ 15 16 /*LINTLIBRARY*/ 17 18 #include <config.h> 19 #include <stdio.h> 20 21 #include "ntp_stdlib.h" 22 23 #ifdef lint 24 #undef putc 25 #define putc fputc 26 #endif /* lint */ 27 28 char *ntp_optarg; /* Global argument pointer. */ 29 int ntp_optind = 0; /* Global argv index. */ 30 int ntp_opterr = 1; /* for compatibility, should error be printed? */ 31 int ntp_optopt; /* for compatibility, option character checked */ 32 33 static char *scan = NULL; /* Private scan pointer. */ 34 static const char *prog = "amnesia"; 35 36 /* 37 * Print message about a bad option. 38 */ 39 static int 40 badopt( 41 const char *mess, 42 int ch 43 ) 44 { 45 if (ntp_opterr) { 46 fputs(prog, stderr); 47 fputs(mess, stderr); 48 (void) putc(ch, stderr); 49 (void) putc('\n', stderr); 50 } 51 return ('?'); 52 } 53 54 int 55 ntp_getopt( 56 int argc, 57 char *argv[], 58 const char *optstring 59 ) 60 { 61 register char c; 62 register const char *place; 63 64 prog = argv[0]; 65 ntp_optarg = NULL; 66 67 if (ntp_optind == 0) { 68 scan = NULL; 69 ntp_optind++; 70 } 71 72 if (scan == NULL || *scan == '\0') { 73 if (ntp_optind >= argc 74 || argv[ntp_optind][0] != '-' 75 || argv[ntp_optind][1] == '\0') { 76 return (EOF); 77 } 78 if (argv[ntp_optind][1] == '-' 79 && argv[ntp_optind][2] == '\0') { 80 ntp_optind++; 81 return (EOF); 82 } 83 84 scan = argv[ntp_optind++]+1; 85 } 86 87 c = *scan++; 88 ntp_optopt = c & 0377; 89 for (place = optstring; place != NULL && *place != '\0'; ++place) 90 if (*place == c) 91 break; 92 93 if (place == NULL || *place == '\0' || c == ':' || c == '?') { 94 return (badopt(": unknown option -", c)); 95 } 96 97 place++; 98 if (*place == ':') { 99 if (*scan != '\0') { 100 ntp_optarg = scan; 101 scan = NULL; 102 } else if (ntp_optind >= argc) { 103 return (badopt(": option requires argument -", c)); 104 } else { 105 ntp_optarg = argv[ntp_optind++]; 106 } 107 } 108 109 return (c & 0377); 110 } 111