fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <stdlib.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <stdio.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <unistd.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <libintl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <string.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <assert.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <getopt.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "cmdparse.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Usage types */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define GENERAL_USAGE 1
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define HELP_USAGE 2
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define DETAIL_USAGE 3
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* printable ascii character set len */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define MAXOPTIONS (uint_t)('~' - '!' + 1)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * MAXOPTIONSTRING is the max length of the options string used in getopt and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will be the printable character set + ':' for each character,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * providing for options with arguments. e.g. "t:Cs:hglr:"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define MAXOPTIONSTRING MAXOPTIONS * 2
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* standard command options table to support -?, -V */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct option standardCmdOptions[] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {"help", no_argument, NULL, '?'},
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {"version", no_argument, NULL, 'V'},
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {NULL, 0, NULL, 0}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* standard subcommand options table to support -? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct option standardSubCmdOptions[] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {"help", no_argument, NULL, '?'},
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {NULL, 0, NULL, 0}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* forward declarations */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int getSubcommand(char *, subcommand_t **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *getExecBasename(char *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void usage(uint_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void subUsage(uint_t, subcommand_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void subUsageObject(uint_t, subcommand_t *, object_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int getObject(char *, object_t **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int getObjectRules(uint_t, objectRules_t **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *getLongOption(int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic optionProp_t *getOptions(uint_t, uint_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *getOptionArgDesc(int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* global data */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct option *_longOptions;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic subcommand_t *_subcommands;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic object_t *_objects;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic objectRules_t *_objectRules;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic optionRules_t *_optionRules;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic optionTbl_t *_clientOptionTbl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *commandName;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * object - object value
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * output:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * opCmd - pointer to opCmd_t structure allocated by caller
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * On successful return, opCmd contains the rules for the value in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * object. On failure, the contents of opCmd is unspecified.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * zero on success
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * non-zero on failure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn FortegetObjectRules(uint_t object, objectRules_t **objectRules)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte objectRules_t *sp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (sp = _objectRules; sp->value; sp++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sp->value == object) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *objectRules = sp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * arg - pointer to array of char containing object string
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * output:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * object - pointer to object_t structure pointer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on success, contains the matching object structure based on
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * input object name
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * zero on success
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * non-zero otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn FortegetObject(char *arg, object_t **object)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte object_t *op;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (op = _objects; op->name; op++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = strlen(arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (len == strlen(op->name) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strncasecmp(arg, op->name, len) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *object = op;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * arg - pointer to array of char containing subcommand string
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * output:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * subcommand - pointer to subcommand_t pointer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on success, contains the matching subcommand structure based on
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * input subcommand name
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * zero on success
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * non-zero on failure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn FortegetSubcommand(char *arg, subcommand_t **subcommand)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subcommand_t *sp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (sp = _subcommands; sp->name; sp++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = strlen(arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (len == strlen(sp->name) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strncasecmp(arg, sp->name, len) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *subcommand = sp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * object - object for which to get options
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * subcommand - subcommand for which to get options
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on success, optionsProp_t pointer to structure matching input object
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * value
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on failure, NULL is returned
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic optionProp_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn FortegetOptions(uint_t object, uint_t subcommand)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint_t currObject;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte optionRules_t *op = _optionRules;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (op && ((currObject = op->objectValue) != 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((currObject == object) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (op->subcommandValue == subcommand)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (&(op->optionProp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * shortOption - short option character for which to return the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * associated long option string
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on success, long option name
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on failure, NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn FortegetLongOption(int shortOption)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct option *op;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (op = _longOptions; op->name; op++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (shortOption == op->val) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (op->name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * input
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * shortOption - short option character for which to return the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * option argument
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on success, argument string
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on failure, NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn FortegetOptionArgDesc(int shortOption)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte optionTbl_t *op;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (op = _clientOptionTbl; op->name; op++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (op->val == shortOption &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op->has_arg == required_argument) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (op->argDesc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Print usage for a subcommand.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * usage type - GENERAL_USAGE, HELP_USAGE, DETAIL_USAGE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * subcommand - pointer to subcommand_t structure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * none
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn FortesubUsage(uint_t usageType, subcommand_t *subcommand)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte object_t *objp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "%s:\t%s %s [",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("Usage"), commandName, subcommand->name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; standardSubCmdOptions[i].name; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "-%c",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte standardSubCmdOptions[i].val);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (standardSubCmdOptions[i+1].name)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, ",");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "] %s [", "<OBJECT>");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; standardSubCmdOptions[i].name; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "-%c",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte standardSubCmdOptions[i].val);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (standardSubCmdOptions[i+1].name)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, ",");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "] %s", "[<OPERAND>]");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (usageType == GENERAL_USAGE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "%s:\n", gettext("Usage by OBJECT"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iterate through object table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For each object, print appropriate usage
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * based on rules tables
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (objp = _objects; objp->value; objp++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsageObject(usageType, subcommand, objp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Print usage for a subcommand and object.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * usage type - GENERAL_USAGE, HELP_USAGE, DETAIL_USAGE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * subcommand - pointer to subcommand_t structure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * objp - pointer to a object_t structure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * none
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn FortesubUsageObject(uint_t usageType, subcommand_t *subcommand, object_t *objp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte objectRules_t *objRules = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opCmd_t *opCmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte optionProp_t *options;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *optionArgDesc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *longOpt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (getObjectRules(objp->value, &objRules) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * internal subcommand rules table error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * no object entry in object
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte assert(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opCmd = &(objRules->opCmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (opCmd->invOpCmd & subcommand->value) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte options = getOptions(objp->value, subcommand->value);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* print generic subcommand usage */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "\t%s %s ", commandName, subcommand->name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* print object */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "%s ", objp->name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* print options if applicable */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (options != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (options->required) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "%s", gettext("<"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "%s", gettext("["));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "%s", gettext("OPTIONS"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (options->required) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "%s ", gettext(">"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "%s ", gettext("]"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* print operand requirements */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (opCmd->optOpCmd & subcommand->value) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, gettext("["));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(opCmd->noOpCmd & subcommand->value)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, gettext("<"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (objRules->operandDefinition) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte objRules->operandDefinition);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Missing operand description
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte assert(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (opCmd->multOpCmd & subcommand->value) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, gettext(" ..."));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(opCmd->noOpCmd & subcommand->value)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, gettext(">"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (opCmd->optOpCmd & subcommand->value) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, gettext("]"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (usageType == HELP_USAGE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* print options for subcommand, object */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (options != NULL && options->optionString != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "\n\t%s:", gettext("OPTIONS"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < strlen(options->optionString); i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((longOpt = getLongOption(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte options->optionString[i]))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* no long option exists for short option */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte assert(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "\n\t\t-%c, --%s ",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte options->optionString[i], longOpt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte optionArgDesc =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte getOptionArgDesc(options->optionString[i]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (optionArgDesc != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "<%s>", optionArgDesc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (options->exclusive &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strchr(options->exclusive,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte options->optionString[i])) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, " (%s)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("exclusive"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * type of usage statement to print
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return value of subUsage
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteusage(uint_t usageType)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subcommand_t subcommand;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subcommand_t *sp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* print general command usage */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "%s:\t%s ",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("Usage"), commandName);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; standardCmdOptions[i].name; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "-%c",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte standardCmdOptions[i].val);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (standardCmdOptions[i+1].name)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, ",");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (usageType == HELP_USAGE || usageType == GENERAL_USAGE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; standardSubCmdOptions[i].name; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, ",--%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte standardSubCmdOptions[i].name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (standardSubCmdOptions[i+1].name)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, ",");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* print all subcommand usage */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (sp = _subcommands; sp->name; sp++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subcommand.name = sp->name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subcommand.value = sp->value;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (usageType == HELP_USAGE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsage(usageType, &subcommand);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * execFullName - exec name of program (argv[0])
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * command name portion of execFullName
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn FortegetExecBasename(char *execFullname)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *lastSlash, *execBasename;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* guard against '/' at end of command invocation */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (;;) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lastSlash = strrchr(execFullname, '/');
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lastSlash == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte execBasename = execFullname;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte execBasename = lastSlash + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*execBasename == '\0') {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *lastSlash = '\0';
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (execBasename);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cmdParse is a parser that checks syntax of the input command against
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * various rules tables.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It provides usage feedback based upon the passed rules tables by calling
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * two usage functions, usage, subUsage, and subUsageObject handling command,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * subcommand and object usage respectively.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When syntax is successfully validated, the associated function is called
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * using the subcommands table functions.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Syntax is as follows:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * command subcommand object [<options>] [<operand>]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There are two standard short and long options assumed:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * -?, --help Provides usage on a command or subcommand
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and stops further processing of the arguments
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * -V, --version Provides version information on the command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and stops further processing of the arguments
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * These options are loaded by this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * argc, argv from main
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * syntax rules tables (synTables_t structure)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * callArgs - void * passed by caller to be passed to subcommand function
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * output:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * funcRet - pointer to int that holds subcommand function return value
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * zero on successful syntax parse and function call
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 1 on unsuccessful syntax parse (no function has been called)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This could be due to a version or help call or simply a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * general usage call.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * -1 check errno, call failed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This module is not MT-safe.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn FortecmdParse(int argc, char *argv[], synTables_t synTable, void *callArgs,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int *funcRet)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int getoptargc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char **getoptargv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int opt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int operInd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i, j;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *versionString;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char optionStringAll[MAXOPTIONSTRING + 1];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte optionProp_t *availOptions;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte objectRules_t *objRules = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opCmd_t *opCmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subcommand_t *subcommand;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte object_t *object;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmdOptions_t cmdOptions[MAXOPTIONS + 1];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct option *lp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte optionTbl_t *optionTbl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct option intLongOpt[MAXOPTIONS + 1];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check for NULLs on mandatory input arguments
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note: longOptionTbl and optionRulesTbl can be NULL in the case
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * where there is no caller defined options
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (synTable.versionString == NULL ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte synTable.subcommandTbl == NULL ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte synTable.objectRulesTbl == NULL ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte synTable.objectTbl == NULL ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte funcRet == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte assert(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte versionString = synTable.versionString;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* set global command name */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte commandName = getExecBasename(argv[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Set unbuffered output */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte setbuf(stdout, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* load globals */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _subcommands = synTable.subcommandTbl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _objectRules = synTable.objectRulesTbl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _optionRules = synTable.optionRulesTbl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _objects = synTable.objectTbl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _clientOptionTbl = synTable.longOptionTbl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* There must be at least two arguments */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (argc < 2) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte usage(GENERAL_USAGE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memset(&intLongOpt[0], 0, sizeof (intLongOpt));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * load standard subcommand options to internal long options table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Two separate getopt_long(3C) tables are used.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; standardSubCmdOptions[i].name; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte intLongOpt[i].name = standardSubCmdOptions[i].name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte intLongOpt[i].has_arg = standardSubCmdOptions[i].has_arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte intLongOpt[i].flag = standardSubCmdOptions[i].flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte intLongOpt[i].val = standardSubCmdOptions[i].val;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * copy caller's long options into internal long options table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We do this for two reasons:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 1) We need to use the getopt_long option structure internally
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 2) We need to prepend the table with the standard option
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for all subcommands (currently -?)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (optionTbl = synTable.longOptionTbl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte optionTbl && optionTbl->name; optionTbl++, i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i > MAXOPTIONS - 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* option table too long */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte assert(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte intLongOpt[i].name = optionTbl->name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte intLongOpt[i].has_arg = optionTbl->has_arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte intLongOpt[i].flag = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte intLongOpt[i].val = optionTbl->val;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* set option table global */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _longOptions = &intLongOpt[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check for help/version request immediately following command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * '+' in option string ensures POSIX compliance in getopt_long()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * which means that processing will stop at first non-option
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * argument.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((opt = getopt_long(argc, argv, "+?V", standardCmdOptions,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL)) != EOF) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (opt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case '?':
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * getopt can return a '?' when no
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * option letters match string. Check for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the 'real' '?' in optopt.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (optopt == '?') {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte usage(HELP_USAGE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte usage(GENERAL_USAGE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 'V':
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "%s: %s %s\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte commandName, gettext("Version"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte versionString);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * subcommand is always in the second argument. If there is no
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * recognized subcommand in the second argument, print error,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * general usage and then return.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (getSubcommand(argv[1], &subcommand) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, "%s: %s\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte commandName, gettext("invalid subcommand"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte usage(GENERAL_USAGE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (argc == 2) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, "%s: %s\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte commandName, gettext("missing object"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsage(GENERAL_USAGE, subcommand);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte getoptargv = argv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte getoptargv++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte getoptargc = argc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte getoptargc -= 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((opt = getopt_long(getoptargc, getoptargv, "+?",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte standardSubCmdOptions, NULL)) != EOF) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (opt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case '?':
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * getopt can return a '?' when no
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * option letters match string. Check for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the 'real' '?' in optopt.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (optopt == '?') {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsage(HELP_USAGE, subcommand);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsage(GENERAL_USAGE, subcommand);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * object is always in the third argument. If there is no
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * recognized object in the third argument, print error,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * help usage for the subcommand and then return.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (getObject(argv[2], &object) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, "%s: %s\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte commandName, gettext("invalid object"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsage(HELP_USAGE, subcommand);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (getObjectRules(object->value, &objRules) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * internal subcommand rules table error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * no object entry in object table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte assert(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opCmd = &(objRules->opCmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Is command valid for this object?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (opCmd->invOpCmd & subcommand->value) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, "%s: %s %s\n", commandName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("invalid subcommand for"), object->name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsage(HELP_USAGE, subcommand);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * offset getopt arg begin since
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * getopt(3C) assumes options
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * follow first argument
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte getoptargv = argv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte getoptargv++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte getoptargv++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte getoptargc = argc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte getoptargc -= 2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memset(optionStringAll, 0, sizeof (optionStringAll));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memset(&cmdOptions[0], 0, sizeof (cmdOptions));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte j = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Build optionStringAll from long options table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (lp = _longOptions; lp->name; lp++, j++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* sanity check on string length */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (j + 1 >= sizeof (optionStringAll)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* option table too long */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte assert(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte optionStringAll[j] = lp->val;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lp->has_arg == required_argument) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte optionStringAll[++j] = ':';
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Run getopt for all arguments against all possible options
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Store all options/option arguments in an array for retrieval
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * later.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Once all options are retrieved, check against object
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and subcommand (option rules table) for validity.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is done later.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((opt = getopt_long(getoptargc, getoptargv, optionStringAll,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _longOptions, NULL)) != EOF) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (opt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case '?':
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (optopt == '?') {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsageObject(DETAIL_USAGE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subcommand, object);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsage(GENERAL_USAGE, subcommand);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmdOptions[i].optval = opt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (optarg) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = strlen(optarg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (len > sizeof (cmdOptions[i].optarg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte - 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s: %s\n", commandName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("option too long"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(cmdOptions[i].optarg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte optarg, len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * increment past last option
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte operInd = optind + 2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check validity of given options, if any were given
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get option string for this object and subcommand */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte availOptions = getOptions(object->value, subcommand->value);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmdOptions[0].optval != 0) { /* options were input */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (availOptions == NULL) { /* no options permitted */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, "%s: %s\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte commandName, gettext("no options permitted"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsageObject(HELP_USAGE, subcommand, object);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; cmdOptions[i].optval; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Check for invalid options */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (availOptions->optionString == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * internal option table error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There must be an option string if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * there is an entry in the table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte assert(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* is the option in the available option string? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(strchr(availOptions->optionString,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmdOptions[i].optval))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s: '-%c': %s\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte commandName, cmdOptions[i].optval,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("invalid option"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsageObject(DETAIL_USAGE, subcommand,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte object);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Check for exclusive options */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (cmdOptions[1].optval != 0 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte availOptions->exclusive &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strchr(availOptions->exclusive,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmdOptions[i].optval)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s: '-%c': %s\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte commandName, cmdOptions[i].optval,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("is an exclusive option"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsageObject(DETAIL_USAGE, subcommand,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte object);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else { /* no options were input */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (availOptions != NULL &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (availOptions->required)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, "%s: %s\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte commandName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("at least one option required"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsageObject(DETAIL_USAGE, subcommand,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte object);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there are no more arguments (operands),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check to see if this is okay
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((operInd == argc) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (opCmd->reqOpCmd & subcommand->value)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, "%s: %s %s %s\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte commandName, subcommand->name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte object->name, gettext("requires an operand"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsageObject(HELP_USAGE, subcommand, object);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there are more operands,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check to see if this is okay
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((argc > operInd) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (opCmd->noOpCmd & subcommand->value)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, "%s: %s %s %s\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte commandName, subcommand->name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte object->name, gettext("takes no operands"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsageObject(HELP_USAGE, subcommand, object);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there is more than one more operand,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check to see if this is okay
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((argc > operInd) && ((argc - operInd) != 1) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !(opCmd->multOpCmd & subcommand->value)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, "%s: %s %s %s\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte commandName, subcommand->name, object->name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("accepts only a single operand"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subUsageObject(HELP_USAGE, subcommand, object);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Finished syntax checks */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Call appropriate function */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *funcRet = subcommand->handler(argc - operInd, &argv[operInd],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte object->value, &cmdOptions[0], callArgs);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}