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>