b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross/*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * This file and its contents are supplied under the terms of the
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * Common Development and Distribution License ("CDDL"), version 1.0.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * You may only use this file in accordance with the terms of version
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * 1.0 of the CDDL.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross *
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * A full copy of the text of the CDDL should have accompanied this
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * source. A copy of the CDDL is also available via the Internet at
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * http://www.illumos.org/license/CDDL.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross/*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross#include <stdio.h>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross#include <libintl.h>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross#include <stdlib.h>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross#include <strings.h>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross#include <err.h>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross#include <ads/dsgetdc.h>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross#include <smb/nterror.h>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross#include <uuid/uuid.h>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic void dclist_usage(void);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic int cmd_dclist(char *);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic void dcname_usage(void);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic int cmd_dcname(char *);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic void dsgetdc_usage(void);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic int cmd_dsgetdc(char *);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic void dsgetdcname_usage(void);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic int cmd_dsgetdcname(char *);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic void kick_usage(void);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic int cmd_kick(char *);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic void help(void);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosstypedef int cmd_fn_t (char *);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosstypedef void cmd_usage_t (void);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic struct commands {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross const char *name; /* name of subcommand */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross cmd_fn_t *fn; /* pointer to subcommand handler function */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross cmd_usage_t *usage; /* pointer to subcommand help function */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross int optreq; /* does this have a required optval */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross} commands[] = {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross {"dclist", cmd_dclist, dclist_usage, 0},
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross {"dcname", cmd_dcname, dcname_usage, 0},
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross {"dsgetdc", cmd_dsgetdc, dsgetdc_usage, 0},
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross {"dsgetdcname", cmd_dsgetdcname, dsgetdcname_usage, 0},
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross {"kick", cmd_kick, kick_usage, 0},
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross {NULL, NULL, NULL, 0}
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross};
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross/*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * lookupcmd
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic struct commands *
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosslookupcmd(const char *name)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross{
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross struct commands *cmd;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross for (cmd = commands; cmd->name; cmd++) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if (strcasecmp(cmd->name, name) == 0)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (cmd);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (NULL);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross}
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross/*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * dclist
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic void
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossdclist_usage(void)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross{
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(gettext("usage: nltest dclist... \n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross exit(1);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross}
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross/* ARGSUSED */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic int
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosscmd_dclist(char *optval)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross{
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf("cmd_dclist() \n");
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (0);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross}
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross/*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * dcname
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic void
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossdcname_usage(void)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross{
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(gettext("usage: nltest dcname... \n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross exit(1);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross}
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross/* ARGSUSED */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic int
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosscmd_dcname(char *optval)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross{
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf("cmd_dcname() \n");
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (0);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross}
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross/*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * dsgetdc
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic void
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossdsgetdc_usage(void)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross{
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(gettext("usage: nltest dsgetdc... \n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross exit(1);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross}
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross/* ARGSUSED */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic int
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosscmd_dsgetdc(char *optval)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross{
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf("cmd_dsgetdc() \n");
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (0);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross}
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross/*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * dsgetdcname
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic void
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossdsgetdcname_usage(void)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross{
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(gettext("usage: nltest dsgetdcname domainname \n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross exit(1);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross}
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic int
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosscmd_dsgetdcname(char *domname)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross{
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross char uuid_buf[UUID_PRINTABLE_STRING_LENGTH];
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross int err = 0;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross char *atype;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross DOMAIN_CONTROLLER_INFO *dcinfo;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if (domname != NULL)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(" Domain name supplied: %s \n", domname);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross err = DsGetDcName(NULL, domname, NULL, NULL, 0, &dcinfo);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross switch (err) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross case 0:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross break;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross case ERROR_NO_SUCH_DOMAIN:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf("Domain controller not found.\n");
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf("See: /var/run/idmap/discovery.log\n");
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross exit(1);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross default:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf("Unexpected error %d\n", err);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross exit(1);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross switch (dcinfo->DomainControllerAddressType) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross case DS_INET_ADDRESS:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross atype = "inet";
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross break;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross case DS_NETBIOS_ADDRESS:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross atype = "netbios";
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross break;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross default:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross atype = "?";
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross break;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross uuid_unparse(dcinfo->DomainGuid, uuid_buf);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf("Data Returned from DsGetDcName() call: \n");
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(" DC Name: %s \n", dcinfo->DomainControllerName);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(" DC Addr: %s \n", dcinfo->DomainControllerAddress);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(" DC Addr Type: %s \n", atype);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(" Domain Name: %s \n", dcinfo->DomainName);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(" Domain GUID: %s \n", uuid_buf);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(" DNS Forest Name: %s \n", dcinfo->DnsForestName);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(" Flags: 0x%x \n", dcinfo->Flags);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(" DC Site Name: %s \n", dcinfo->DcSiteName);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(" Client Site Name: %s \n", dcinfo->ClientSiteName);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (0);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross}
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross/*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * kick
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic void
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosskick_usage(void)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross{
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(gettext("usage: nltest /KICK \n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross exit(1);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross}
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic int
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosscmd_kick(char *domname)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross{
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross int flags = 0;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross int result;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross result = _DsForceRediscovery(domname, flags);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (result);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross}
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross/*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * help functions
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstatic void
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosshelp(void) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf("\n");
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * TODO: We may want to revise this help text. It's basically
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * a copy-paste from:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * http://technet.microsoft.com/en-us/library/cc731935.aspx
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(gettext("usage: %s /subcommand\n"),
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (char *)getexecname());
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf(gettext("where subcommands are:\n"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross#if 0 /* not yet */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross " dclist Lists all domain controllers in the domain.\n"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross " dcname Lists the PDC or PDC emulator.\n"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross " dsgetdc Queries DNS server for list of DCs and"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross " their IP addresses and contacts each DC to check"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross " for connectivity.\n"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross#endif
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross " dsgetdcname returns the name of a domain controller in a"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross " specified domain\n"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross " help display help on specified subcommand\n"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross " kick trigger domain controller re-discovery\n"
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "\n"));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross exit(1);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross}
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossint
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossmain(int argc, char *argv[])
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross{
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross struct commands *cmd;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross int err = 0;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross char *option_cmd = NULL;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross char *arg;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross char *p;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross char *optname;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross char *optval = NULL;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross int i;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross int optind = 1;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * Parse options.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross while (optind < argc) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross arg = argv[optind];
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross optname = NULL;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross optval = NULL;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /* Is this an option? */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if (arg[0] == '/') {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross optname = arg + 1;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross optind++;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * May have /optname:value
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if ((p = strchr(optname, ':')) != NULL) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross *p++ = '\0';
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross optval = p;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross } else if (arg[0] == '-' && arg[1] == '-') {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross optname = arg + 2;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross optind++;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * May have --optname=value
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if ((p = strchr(optname, '=')) != NULL) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross *p++ = '\0';
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross optval = p;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross } else {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /* Not an option. Stop parsing. */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross break;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * Handle each optname (and maybe its optval)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * Might put this logic in a table of options.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * (including a flag for "optval required",
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * so that check could be factored out)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross for (cmd = commands; cmd->name; cmd++) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if (!strcasecmp(optname, cmd->name)) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /* cmd->name requires an optval */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if (optval == NULL && optind < argc)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross optval = argv[optind++];
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if (optval == NULL && cmd->optreq > 0) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) fprintf(stderr,
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "%s: option %s requires a value\n",
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross argv[0], optname);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (1);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross option_cmd = optname;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /*
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * Handle remaining non-option arguments
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross for (i = optind; i < argc; i++) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross (void) printf("arg: %s\n", argv[i]);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if (option_cmd == NULL)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross help();
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross cmd = lookupcmd(option_cmd);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if (cmd == NULL)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross err = 1;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross else
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross err = cmd->fn(optval);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (err);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross}