Annotation of embedaddon/strongswan/src/pki/command.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2009 Martin Willi
! 3: * HSR Hochschule fuer Technik Rapperswil
! 4: *
! 5: * This program is free software; you can redistribute it and/or modify it
! 6: * under the terms of the GNU General Public License as published by the
! 7: * Free Software Foundation; either version 2 of the License, or (at your
! 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 9: *
! 10: * This program is distributed in the hope that it will be useful, but
! 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 13: * for more details.
! 14: */
! 15:
! 16: #include "command.h"
! 17: #include "pki.h"
! 18:
! 19: #define _GNU_SOURCE
! 20: #include <getopt.h>
! 21: #include <stdlib.h>
! 22: #include <string.h>
! 23: #include <stdio.h>
! 24:
! 25: #include <library.h>
! 26: #include <utils/debug.h>
! 27: #include <utils/optionsfrom.h>
! 28:
! 29: /**
! 30: * Registered commands.
! 31: */
! 32: static command_t cmds[MAX_COMMANDS];
! 33:
! 34: /**
! 35: * active command.
! 36: */
! 37: static int active = 0;
! 38:
! 39: /**
! 40: * number of registered commands
! 41: */
! 42: static int registered = 0;
! 43:
! 44: /**
! 45: * help command index
! 46: */
! 47: static int help_idx;
! 48:
! 49: static int argc;
! 50:
! 51: static char **argv;
! 52:
! 53: static options_t *options;
! 54:
! 55: /**
! 56: * Global options used by all subcommands
! 57: */
! 58: static struct option command_opts[MAX_COMMANDS > MAX_OPTIONS ? MAX_COMMANDS : MAX_OPTIONS];
! 59:
! 60: /**
! 61: * Global optstring used by all subcommands
! 62: */
! 63: static char command_optstring[(MAX_COMMANDS > MAX_OPTIONS ? MAX_COMMANDS : MAX_OPTIONS) * 3];
! 64:
! 65: /**
! 66: * Build command_opts/command_optstr for the active command
! 67: */
! 68: static void build_opts()
! 69: {
! 70: int i, pos = 0;
! 71:
! 72: memset(command_opts, 0, sizeof(command_opts));
! 73: memset(command_optstring, 0, sizeof(command_optstring));
! 74: if (active == help_idx)
! 75: {
! 76: for (i = 0; i < MAX_COMMANDS && cmds[i].cmd; i++)
! 77: {
! 78: command_opts[i].name = cmds[i].cmd;
! 79: command_opts[i].val = cmds[i].op;
! 80: command_optstring[i] = cmds[i].op;
! 81: }
! 82: }
! 83: else
! 84: {
! 85: for (i = 0; cmds[active].options[i].name; i++)
! 86: {
! 87: command_opts[i].name = cmds[active].options[i].name;
! 88: command_opts[i].has_arg = cmds[active].options[i].arg;
! 89: command_opts[i].val = cmds[active].options[i].op;
! 90: command_optstring[pos++] = cmds[active].options[i].op;
! 91: switch (cmds[active].options[i].arg)
! 92: {
! 93: case optional_argument:
! 94: command_optstring[pos++] = ':';
! 95: /* FALL */
! 96: case required_argument:
! 97: command_optstring[pos++] = ':';
! 98: /* FALL */
! 99: case no_argument:
! 100: default:
! 101: break;
! 102: }
! 103: }
! 104: }
! 105: }
! 106:
! 107: /**
! 108: * getopt_long wrapper
! 109: */
! 110: int command_getopt(char **arg)
! 111: {
! 112: int op;
! 113:
! 114: while (TRUE)
! 115: {
! 116: op = getopt_long(argc, argv, command_optstring, command_opts, NULL);
! 117: switch (op)
! 118: {
! 119: case '+':
! 120: if (!options->from(options, optarg, &argc, &argv, optind))
! 121: {
! 122: /* a error value */
! 123: return 255;
! 124: }
! 125: continue;
! 126: case 'v':
! 127: dbg_default_set_level(atoi(optarg));
! 128: continue;
! 129: default:
! 130: *arg = optarg;
! 131: return op;
! 132: }
! 133: }
! 134: }
! 135:
! 136: /**
! 137: * Register a command
! 138: */
! 139: void command_register(command_t command)
! 140: {
! 141: int i;
! 142:
! 143: if (registered == MAX_COMMANDS)
! 144: {
! 145: fprintf(stderr, "unable to register command, please increase "
! 146: "MAX_COMMANDS\n");
! 147: return;
! 148: }
! 149:
! 150: cmds[registered] = command;
! 151: /* append default options, but not to --help */
! 152: if (!active)
! 153: {
! 154: for (i = 0; i < countof(cmds[registered].options) - 1; i++)
! 155: {
! 156: if (!cmds[registered].options[i].name)
! 157: {
! 158: break;
! 159: }
! 160: }
! 161: if (i > countof(cmds[registered].options) - 3)
! 162: {
! 163: fprintf(stderr, "command '%s' registered too many options, please "
! 164: "increase MAX_OPTIONS\n", command.cmd);
! 165: }
! 166: else
! 167: {
! 168: cmds[registered].options[i++] = (command_option_t) {
! 169: "debug", 'v', 1, "set debug level, default: 1"
! 170: };
! 171: cmds[registered].options[i++] = (command_option_t) {
! 172: "options", '+', 1, "read command line options from file"
! 173: };
! 174: }
! 175: for (i = 0; cmds[registered].line[i]; i++)
! 176: {
! 177: if (i == MAX_LINES - 1)
! 178: {
! 179: fprintf(stderr, "command '%s' specifies too many usage summary "
! 180: "lines, please increase MAX_LINES\n", command.cmd);
! 181: break;
! 182: }
! 183: }
! 184: }
! 185: registered++;
! 186: }
! 187:
! 188: /**
! 189: * Print usage text, with an optional error
! 190: */
! 191: int command_usage(char *error)
! 192: {
! 193: FILE *out = stdout;
! 194: int i, indent = 0;
! 195:
! 196: if (error)
! 197: {
! 198: out = stderr;
! 199: fprintf(out, "Error: %s\n", error);
! 200: }
! 201: fprintf(out, "strongSwan %s PKI tool\n", VERSION);
! 202:
! 203: if (active == help_idx)
! 204: {
! 205: fprintf(out, "loaded plugins: %s\n",
! 206: lib->plugins->loaded_plugins(lib->plugins));
! 207: }
! 208:
! 209: fprintf(out, "usage:\n");
! 210: if (active == help_idx)
! 211: {
! 212: for (i = 0; i < MAX_COMMANDS && cmds[i].cmd; i++)
! 213: {
! 214: fprintf(out, " pki --%-7s (-%c) %s\n",
! 215: cmds[i].cmd, cmds[i].op, cmds[i].description);
! 216: }
! 217: }
! 218: else
! 219: {
! 220: for (i = 0; i < MAX_LINES && cmds[active].line[i]; i++)
! 221: {
! 222: if (i == 0)
! 223: {
! 224: indent = fprintf(out, " pki --%s ", cmds[active].cmd);
! 225: fprintf(out, "%s\n", cmds[active].line[i]);
! 226: }
! 227: else
! 228: {
! 229: fprintf(out, "%*s%s\n", indent, "", cmds[active].line[i]);
! 230: }
! 231: }
! 232: for (i = 0; cmds[active].options[i].name; i++)
! 233: {
! 234: fprintf(out, " --%-15s (-%c) %s\n",
! 235: cmds[active].options[i].name, cmds[active].options[i].op,
! 236: cmds[active].options[i].desc);
! 237: }
! 238: }
! 239: return error != NULL;
! 240: }
! 241:
! 242:
! 243: /**
! 244: * Show usage information
! 245: */
! 246: static int help(int c, char *v[])
! 247: {
! 248: return command_usage(NULL);
! 249: }
! 250:
! 251: /**
! 252: * Dispatch cleanup hook
! 253: */
! 254: static void cleanup()
! 255: {
! 256: options->destroy(options);
! 257: }
! 258:
! 259: /**
! 260: * Dispatch commands.
! 261: */
! 262: int command_dispatch(int c, char *v[])
! 263: {
! 264: int op, i;
! 265:
! 266: options = options_create();
! 267: atexit(cleanup);
! 268: active = help_idx = registered;
! 269: argc = c;
! 270: argv = v;
! 271: command_register((command_t){help, 'h', "help", "show usage information"});
! 272:
! 273: build_opts();
! 274: op = getopt_long(c, v, command_optstring, command_opts, NULL);
! 275: for (i = 0; i < MAX_COMMANDS && cmds[i].cmd; i++)
! 276: {
! 277: if (cmds[i].op == op)
! 278: {
! 279: active = i;
! 280: build_opts();
! 281: return cmds[i].call();
! 282: }
! 283: }
! 284: return command_usage(c > 1 ? "invalid operation" : NULL);
! 285: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>