Annotation of embedaddon/strongswan/src/pki/command.c, revision 1.1.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>