int getopt_long(int my_argc, char * const *my_argv, const char *optstring, const struct option *longopts, int *longindex) { const char *cur; if(optind >= my_argc) { /* end of args */ return -1; } cur = my_argv[optind]; if(cur[0] != '-' || (cur[1] == '-' && cur[2] == '\0')) { /* end of args */ /* need to handle POSIXLY_CORRECT case */ return -1; } if(cur[1] == '-') { /* this is a long option, dispatch appropriately */ return _getopt_long(my_argc, my_argv, optstring, longopts, longindex); } else { /* short opt */ return _getopt(my_argc, my_argv, optstring); } }
int getopt(int my_argc, char * const *my_argv, const char *optstring) { const char *cur; if(optind >= my_argc) { /* end of args */ return -1; } cur = my_argv[optind]; if(cur[0] != '-' || (cur[1] == '-' && cur[2] == '\0')) { /* end of args */ /* need to handle POSIXLY_CORRECT case */ return -1; } return _getopt(my_argc, my_argv, optstring); }
int xgetopt(int fd, int level, int opt, void *optval, int *optlen) { int rc; struct sockbase *sb = xget(fd); if (!sb) { errno = EBADF; return -1; } switch (level) { case XL_SOCKET: rc = _getopt(sb, opt, optval, optlen); break; default: rc = _tp_getopt(sb, level, opt, optval, optlen); break; } xput(fd); return rc; }
static int _getopt(int argc, char * argv[], const char *opts) { static int charind=0; const char *s; char mode, colon_mode; int off = 0, opt = -1; if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+'; else { if((colon_mode = *opts) == ':') off ++; if(((mode = opts[off]) == '+') || (mode == '-')) { off++; if((colon_mode != ':') && ((colon_mode = opts[off]) == ':')) off ++; } } optarg = 0; if(charind) { optopt = argv[optind][charind]; for(s=opts+off; *s; s++) if(optopt == *s) { charind++; if((*(++s) == ':') || ((optopt == 'W') && (*s == ';'))) { if(argv[optind][charind]) { optarg = &(argv[optind++][charind]); charind = 0; } else if(*(++s) != ':') { charind = 0; if(++optind >= argc) { if(opterr) fprintf(stderr, "%s: option requires an argument -- %c\n", argv[0], optopt); opt = (colon_mode == ':') ? ':' : '?'; goto my_getopt_ok; } optarg = argv[optind++]; } } opt = optopt; goto my_getopt_ok; } if(opterr) fprintf(stderr, "%s: illegal option -- %c\n", argv[0], optopt); opt = '?'; if(argv[optind][++charind] == '\0') { optind++; charind = 0; } my_getopt_ok: if(charind && ! argv[optind][charind]) { optind++; charind = 0; } } else if((optind >= argc) || ((argv[optind][0] == '-') && (argv[optind][1] == '-') && (argv[optind][2] == '\0'))) { optind++; opt = -1; } else if((argv[optind][0] != '-') || (argv[optind][1] == '\0')) { char *tmp; int i, j, k; if(mode == '+') opt = -1; else if(mode == '-') { optarg = argv[optind++]; charind = 0; opt = 1; } else { for(i=j=optind; i<argc; i++) if((argv[i][0] == '-') && (argv[i][1] != '\0')) { optind=i; opt=_getopt(argc, argv, opts); while(i > j) { tmp=argv[--i]; for(k=i; k+1<optind; k++) argv[k]=argv[k+1]; argv[--optind]=tmp; } break; } if(i == argc) opt = -1; } } else { charind++; opt = _getopt(argc, argv, opts); } if (optind > argc) optind = argc; return opt; }
int getopt(int argc, char * argv[], const char *opts) { return _getopt(argc, argv, opts); }
int _getopt_internal(int argc, char * argv[], const char *shortopts, const struct option *longopts, int *longind, int long_only) { char mode, colon_mode = *shortopts; int shortoff = 0, opt = -1; if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+'; else { if((colon_mode = *shortopts) == ':') shortoff ++; if(((mode = shortopts[shortoff]) == '+') || (mode == '-')) { shortoff++; if((colon_mode != ':') && ((colon_mode = shortopts[shortoff]) == ':')) shortoff ++; } } optarg = 0; if((optind >= argc) || ((argv[optind][0] == '-') && (argv[optind][1] == '-') && (argv[optind][2] == '\0'))) { optind++; opt = -1; } else if((argv[optind][0] != '-') || (argv[optind][1] == '\0')) { char *tmp; int i, j, k; opt = -1; if(mode == '+') return -1; else if(mode == '-') { optarg = argv[optind++]; return 1; } for(i=j=optind; i<argc; i++) if((argv[i][0] == '-') && (argv[i][1] != '\0')) { optind=i; opt=_getopt_internal(argc, argv, shortopts, longopts, longind, long_only); while(i > j) { tmp=argv[--i]; for(k=i; k+1<optind; k++) argv[k]=argv[k+1]; argv[--optind]=tmp; } break; } } else if((!long_only) && (argv[optind][1] != '-')) opt = _getopt(argc, argv, shortopts); else { int charind, offset; int found = 0, ind, hits = 0; if(((optopt = argv[optind][1]) != '-') && ! argv[optind][2]) { int c; ind = shortoff; while((c = shortopts[ind++])) { if(((shortopts[ind] == ':') || ((c == 'W') && (shortopts[ind] == ';'))) && (shortopts[++ind] == ':')) ind ++; if(optopt == c) return _getopt(argc, argv, shortopts); } } offset = 2 - (argv[optind][1] != '-'); for(charind = offset; (argv[optind][charind] != '\0') && (argv[optind][charind] != '='); charind++); for(ind = 0; longopts[ind].name && !hits; ind++) if((strlen(longopts[ind].name) == (size_t) (charind - offset)) && (strncmp(longopts[ind].name, argv[optind] + offset, charind - offset) == 0)) found = ind, hits++; if(!hits) for(ind = 0; longopts[ind].name; ind++) if(strncmp(longopts[ind].name, argv[optind] + offset, charind - offset) == 0) found = ind, hits++; if(hits == 1) { opt = 0; if(argv[optind][charind] == '=') { if(longopts[found].has_arg == 0) { opt = '?'; if(opterr) fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n", argv[0], longopts[found].name); } else { optarg = argv[optind] + ++charind; charind = 0; } } else if(longopts[found].has_arg == 1) { if(++optind >= argc) { opt = (colon_mode == ':') ? ':' : '?'; if(opterr) fprintf(stderr, "%s: option `--%s' requires an argument\n", argv[0], longopts[found].name); } else optarg = argv[optind]; } if(!opt) { if (longind) *longind = found; if(!longopts[found].flag) opt = longopts[found].val; else *(longopts[found].flag) = longopts[found].val; } optind++; } else if(!hits) { if(offset == 1) opt = _getopt(argc, argv, shortopts); else { opt = '?'; if(opterr) fprintf(stderr, "%s: unrecognized option `%s'\n", argv[0], argv[optind++]); } } else { opt = '?'; if(opterr) fprintf(stderr, "%s: option `%s' is ambiguous\n", argv[0], argv[optind++]); } } if (optind > argc) optind = argc; return opt; }
/* Do the callbacks for auxprop stores */ int sasl_auxprop_store(sasl_conn_t *conn, struct propctx *ctx, const char *user) { sasl_getopt_t *_getopt; int ret, found = 0; void *context; const char *plist = NULL; auxprop_plug_list_t *ptr; sasl_server_params_t *sparams = NULL; unsigned userlen = 0; if (ctx) { if (!conn || !user) return SASL_BADPARAM; sparams = ((sasl_server_conn_t *) conn)->sparams; userlen = (unsigned) strlen(user); } /* Pickup _getopt callback from the connection, if conn is not NULL */ if(_sasl_getcallback(conn, SASL_CB_GETOPT, &_getopt, &context) == SASL_OK) { ret = _getopt(context, NULL, "auxprop_plugin", &plist, NULL); if(ret != SASL_OK) plist = NULL; } ret = SASL_OK; if(!plist) { /* Do store in all plugins */ for(ptr = auxprop_head; ptr && ret == SASL_OK; ptr = ptr->next) { found=1; if (ptr->plug->auxprop_store) ret = ptr->plug->auxprop_store(ptr->plug->glob_context, sparams, ctx, user, userlen); } } else { char *pluginlist = NULL, *freeptr = NULL, *thisplugin = NULL; if(_sasl_strdup(plist, &pluginlist, NULL) != SASL_OK) return SASL_FAIL; thisplugin = freeptr = pluginlist; /* Do store in all *specified* plugins, in order */ while(*thisplugin) { char *p; int last=0; while(*thisplugin && isspace((int)*thisplugin)) thisplugin++; if(!(*thisplugin)) break; for(p = thisplugin;*p != '\0' && !isspace((int)*p); p++); if(*p == '\0') last = 1; else *p='\0'; for(ptr = auxprop_head; ptr && ret == SASL_OK; ptr = ptr->next) { /* Skip non-matching plugins */ if((!ptr->plug->name || strcasecmp(ptr->plug->name, thisplugin))) continue; found=1; if (ptr->plug->auxprop_store) ret = ptr->plug->auxprop_store(ptr->plug->glob_context, sparams, ctx, user, userlen); } if(last) break; thisplugin = p+1; } sasl_FREE(freeptr); } if(!found) { _sasl_log(NULL, SASL_LOG_ERR, "could not find auxprop plugin, was searching for %s", plist ? plist : "[all]"); return SASL_FAIL; } return ret; }
/* Do the callbacks for auxprop lookups */ void _sasl_auxprop_lookup(sasl_server_params_t *sparams, unsigned flags, const char *user, unsigned ulen) { sasl_getopt_t *_getopt; int ret, found = 0; void *context; const char *plist = NULL; auxprop_plug_list_t *ptr; if(_sasl_getcallback(sparams->utils->conn, SASL_CB_GETOPT, &_getopt, &context) == SASL_OK) { ret = _getopt(context, NULL, "auxprop_plugin", &plist, NULL); if(ret != SASL_OK) plist = NULL; } if(!plist) { /* Do lookup in all plugins */ for(ptr = auxprop_head; ptr; ptr = ptr->next) { found=1; ptr->plug->auxprop_lookup(ptr->plug->glob_context, sparams, flags, user, ulen); } } else { char *pluginlist = NULL, *freeptr = NULL, *thisplugin = NULL; if(_sasl_strdup(plist, &pluginlist, NULL) != SASL_OK) return; thisplugin = freeptr = pluginlist; /* Do lookup in all *specified* plugins, in order */ while(*thisplugin) { char *p; int last=0; while(*thisplugin && isspace((int)*thisplugin)) thisplugin++; if(!(*thisplugin)) break; for(p = thisplugin;*p != '\0' && !isspace((int)*p); p++); if(*p == '\0') last = 1; else *p='\0'; for(ptr = auxprop_head; ptr; ptr = ptr->next) { /* Skip non-matching plugins */ if(!ptr->plug->name || strcasecmp(ptr->plug->name, thisplugin)) continue; found=1; ptr->plug->auxprop_lookup(ptr->plug->glob_context, sparams, flags, user, ulen); } if(last) break; thisplugin = p+1; } sasl_FREE(freeptr); } if(!found) _sasl_log(sparams->utils->conn, SASL_LOG_DEBUG, "could not find auxprop plugin, was searching for '%s'", plist ? plist : "[all]"); }