1 /* getopt.c -- replacement getopt(3) routines */ 2 /* $OpenLDAP: pkg/ldap/libraries/liblutil/getopt.c,v 1.16.2.3 2008/02/11 23:26:42 kurt Exp $ */ 3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 4 * 5 * Copyright 1998-2008 The OpenLDAP Foundation. 6 * Portions Copyright 1998-2003 Kurt D. Zeilenga. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted only as authorized by the OpenLDAP 11 * Public License. 12 * 13 * A copy of this license is available in the file LICENSE in the 14 * top-level directory of the distribution or, alternatively, at 15 * <http://www.OpenLDAP.org/license.html>. 16 */ 17 /* This work is based upon the public-domain getopt(3) routines 18 * developed by AT&T. Modified by Kurt D. Zeilenga for inclusion 19 * into OpenLDAP Software. Significant contributors include: 20 * Howard Chu 21 */ 22 23 #include "portable.h" 24 25 #ifndef HAVE_GETOPT 26 27 #include <stdio.h> 28 29 #include <ac/string.h> 30 #include <ac/unistd.h> 31 32 #ifdef HAVE_IO_H 33 #include <io.h> 34 #endif 35 36 #include "lutil.h" 37 38 #ifndef STDERR_FILENO 39 #define STDERR_FILENO 2 40 #endif 41 42 int opterr = 1; 43 int optind = 1; 44 int optopt; 45 char * optarg; 46 47 #ifdef HAVE_EBCDIC 48 extern int _trans_argv; 49 #endif 50 51 static void ERR (char * const argv[], const char * s, char c) 52 { 53 #ifdef DF_TRACE_DEBUG 54 printf("DF_TRACE_DEBUG: static void ERR () in getopt.c\n"); 55 #endif 56 if (opterr) 57 { 58 char *ptr, outbuf[4096]; 59 60 ptr = lutil_strncopy(outbuf, argv[0], sizeof(outbuf) - 2); 61 ptr = lutil_strncopy(ptr, s, sizeof(outbuf)-2 -(ptr-outbuf)); 62 *ptr++ = c; 63 *ptr++ = '\n'; 64 #ifdef HAVE_EBCDIC 65 __atoe_l(outbuf, ptr - outbuf); 66 #endif 67 (void) write(STDERR_FILENO,outbuf,ptr - outbuf); 68 } 69 } 70 71 int getopt (int argc, char * const argv [], const char * opts) 72 { 73 static int sp = 1, error = (int) '?'; 74 static char sw = '-', eos = '\0', arg = ':'; 75 register char c, * cp; 76 77 #ifdef DF_TRACE_DEBUG 78 printf("DF_TRACE_DEBUG: int getopt () in getopt.c\n"); 79 #endif 80 81 #ifdef HAVE_EBCDIC 82 if (_trans_argv) { 83 int i; 84 for (i=0; i<argc; i++) __etoa(argv[i]); 85 _trans_argv = 0; 86 } 87 #endif 88 if (sp == 1) 89 { 90 if (optind >= argc || argv[optind][0] != sw 91 || argv[optind][1] == eos) 92 return EOF; 93 else if (strcmp(argv[optind],"--") == 0) 94 { 95 optind++; 96 return EOF; 97 } 98 } 99 c = argv[optind][sp]; 100 optopt = (int) c; 101 if (c == arg || (cp = strchr(opts,c)) == NULL) 102 { 103 ERR(argv,_(": illegal option--"),c); 104 if (argv[optind][++sp] == eos) 105 { 106 optind++; 107 sp = 1; 108 } 109 return error; 110 } 111 else if (*++cp == arg) 112 { 113 if (argv[optind][sp + 1] != eos) 114 optarg = &argv[optind++][sp + 1]; 115 else if (++optind >= argc) 116 { 117 ERR(argv,_(": option requires an argument--"),c); 118 sp = 1; 119 return error; 120 } 121 else 122 optarg = argv[optind++]; 123 sp = 1; 124 } 125 else 126 { 127 if (argv[optind][++sp] == eos) 128 { 129 sp = 1; 130 optind++; 131 } 132 optarg = NULL; 133 } 134 return (int) c; 135 } 136 #endif /* HAVE_GETOPT */ 137