Annotation of embedaddon/strongswan/src/swanctl/commands/load_pools.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2014 Martin Willi
        !             3:  * Copyright (C) 2014 revosec AG
        !             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: #define _GNU_SOURCE
        !            17: #include <stdio.h>
        !            18: #include <errno.h>
        !            19: #include <limits.h>
        !            20: 
        !            21: #include "command.h"
        !            22: #include "swanctl.h"
        !            23: #include "load_pools.h"
        !            24: 
        !            25: /**
        !            26:  * Add a vici list from a comma separated string value
        !            27:  */
        !            28: static void add_list_key(vici_req_t *req, char *key, char *value)
        !            29: {
        !            30:        enumerator_t *enumerator;
        !            31:        char *token;
        !            32: 
        !            33:        vici_begin_list(req, key);
        !            34:        enumerator = enumerator_create_token(value, ",", " ");
        !            35:        while (enumerator->enumerate(enumerator, &token))
        !            36:        {
        !            37:                vici_add_list_itemf(req, "%s", token);
        !            38:        }
        !            39:        enumerator->destroy(enumerator);
        !            40:        vici_end_list(req);
        !            41: }
        !            42: 
        !            43: /**
        !            44:  * Translate setting key/values from a section enumerator into vici
        !            45:  * key-values/lists. Destroys the enumerator.
        !            46:  */
        !            47: static void add_key_values(vici_req_t *req, enumerator_t *enumerator)
        !            48: {
        !            49:        char *key, *value;
        !            50: 
        !            51:        while (enumerator->enumerate(enumerator, &key, &value))
        !            52:        {
        !            53:                /* pool subnet is encoded as key/value, all other attributes as list */
        !            54:                if (streq(key, "addrs"))
        !            55:                {
        !            56:                        vici_add_key_valuef(req, key, "%s", value);
        !            57:                }
        !            58:                else
        !            59:                {
        !            60:                        add_list_key(req, key, value);
        !            61:                }
        !            62:        }
        !            63:        enumerator->destroy(enumerator);
        !            64: }
        !            65: 
        !            66: /**
        !            67:  * Load a pool configuration
        !            68:  */
        !            69: static bool load_pool(vici_conn_t *conn, settings_t *cfg,
        !            70:                                          char *section, command_format_options_t format)
        !            71: {
        !            72:        enumerator_t *enumerator;
        !            73:        vici_req_t *req;
        !            74:        vici_res_t *res;
        !            75:        bool ret = TRUE;
        !            76: 
        !            77:        req = vici_begin("load-pool");
        !            78: 
        !            79:        vici_begin_section(req, section);
        !            80:        enumerator = cfg->create_key_value_enumerator(cfg, "pools.%s", section);
        !            81:        add_key_values(req, enumerator);
        !            82:        vici_end_section(req);
        !            83: 
        !            84:        res = vici_submit(req, conn);
        !            85:        if (!res)
        !            86:        {
        !            87:                fprintf(stderr, "load-pool request failed: %s\n", strerror(errno));
        !            88:                return FALSE;
        !            89:        }
        !            90:        if (format & COMMAND_FORMAT_RAW)
        !            91:        {
        !            92:                vici_dump(res, "load-pool reply", format & COMMAND_FORMAT_PRETTY,
        !            93:                                  stdout);
        !            94:        }
        !            95:        else if (!streq(vici_find_str(res, "no", "success"), "yes"))
        !            96:        {
        !            97:                fprintf(stderr, "loading pool '%s' failed: %s\n",
        !            98:                                section, vici_find_str(res, "", "errmsg"));
        !            99:                ret = FALSE;
        !           100:        }
        !           101:        else
        !           102:        {
        !           103:                printf("loaded pool '%s'\n", section);
        !           104:        }
        !           105:        vici_free_res(res);
        !           106:        return ret;
        !           107: }
        !           108: 
        !           109: CALLBACK(list_pool, int,
        !           110:        linked_list_t *list, vici_res_t *res, char *name)
        !           111: {
        !           112:        list->insert_last(list, strdup(name));
        !           113:        return 0;
        !           114: }
        !           115: 
        !           116: /**
        !           117:  * Create a list of currently loaded pools
        !           118:  */
        !           119: static linked_list_t* list_pools(vici_conn_t *conn,
        !           120:                                                                 command_format_options_t format)
        !           121: {
        !           122:        linked_list_t *list;
        !           123:        vici_res_t *res;
        !           124: 
        !           125:        list = linked_list_create();
        !           126: 
        !           127:        res = vici_submit(vici_begin("get-pools"), conn);
        !           128:        if (res)
        !           129:        {
        !           130:                if (format & COMMAND_FORMAT_RAW)
        !           131:                {
        !           132:                        vici_dump(res, "get-pools reply", format & COMMAND_FORMAT_PRETTY,
        !           133:                                          stdout);
        !           134:                }
        !           135:                vici_parse_cb(res, list_pool, NULL, NULL, list);
        !           136:                vici_free_res(res);
        !           137:        }
        !           138:        return list;
        !           139: }
        !           140: 
        !           141: /**
        !           142:  * Remove and free a string from a list
        !           143:  */
        !           144: static void remove_from_list(linked_list_t *list, char *str)
        !           145: {
        !           146:        enumerator_t *enumerator;
        !           147:        char *current;
        !           148: 
        !           149:        enumerator = list->create_enumerator(list);
        !           150:        while (enumerator->enumerate(enumerator, &current))
        !           151:        {
        !           152:                if (streq(current, str))
        !           153:                {
        !           154:                        list->remove_at(list, enumerator);
        !           155:                        free(current);
        !           156:                }
        !           157:        }
        !           158:        enumerator->destroy(enumerator);
        !           159: }
        !           160: 
        !           161: /**
        !           162:  * Unload a pool by name
        !           163:  */
        !           164: static bool unload_pool(vici_conn_t *conn, char *name,
        !           165:                                                command_format_options_t format)
        !           166: {
        !           167:        vici_req_t *req;
        !           168:        vici_res_t *res;
        !           169:        bool ret = TRUE;
        !           170: 
        !           171:        req = vici_begin("unload-pool");
        !           172:        vici_add_key_valuef(req, "name", "%s", name);
        !           173:        res = vici_submit(req, conn);
        !           174:        if (!res)
        !           175:        {
        !           176:                fprintf(stderr, "unload-pool request failed: %s\n", strerror(errno));
        !           177:                return FALSE;
        !           178:        }
        !           179:        if (format & COMMAND_FORMAT_RAW)
        !           180:        {
        !           181:                vici_dump(res, "unload-pool reply", format & COMMAND_FORMAT_PRETTY,
        !           182:                                  stdout);
        !           183:        }
        !           184:        else if (!streq(vici_find_str(res, "no", "success"), "yes"))
        !           185:        {
        !           186:                fprintf(stderr, "unloading pool '%s' failed: %s\n",
        !           187:                                name, vici_find_str(res, "", "errmsg"));
        !           188:                ret = FALSE;
        !           189:        }
        !           190:        vici_free_res(res);
        !           191:        return ret;
        !           192: }
        !           193: 
        !           194: /**
        !           195:  * See header.
        !           196:  */
        !           197: int load_pools_cfg(vici_conn_t *conn, command_format_options_t format,
        !           198:                                   settings_t *cfg)
        !           199: {
        !           200:        u_int found = 0, loaded = 0, unloaded = 0;
        !           201:        char *section;
        !           202:        enumerator_t *enumerator;
        !           203:        linked_list_t *pools;
        !           204: 
        !           205:        pools = list_pools(conn, format);
        !           206: 
        !           207:        enumerator = cfg->create_section_enumerator(cfg, "pools");
        !           208:        while (enumerator->enumerate(enumerator, &section))
        !           209:        {
        !           210:                remove_from_list(pools, section);
        !           211:                found++;
        !           212:                if (load_pool(conn, cfg, section, format))
        !           213:                {
        !           214:                        loaded++;
        !           215:                }
        !           216:        }
        !           217:        enumerator->destroy(enumerator);
        !           218: 
        !           219:        /* unload all pools in daemon, but not in file */
        !           220:        while (pools->remove_first(pools, (void**)&section) == SUCCESS)
        !           221:        {
        !           222:                if (unload_pool(conn, section, format))
        !           223:                {
        !           224:                        unloaded++;
        !           225:                }
        !           226:                free(section);
        !           227:        }
        !           228:        pools->destroy(pools);
        !           229: 
        !           230:        if (format & COMMAND_FORMAT_RAW)
        !           231:        {
        !           232:                return 0;
        !           233:        }
        !           234:        if (found == 0)
        !           235:        {
        !           236:                fprintf(stderr, "no pools found, %u unloaded\n", unloaded);
        !           237:                return 0;
        !           238:        }
        !           239:        if (loaded == found)
        !           240:        {
        !           241:                printf("successfully loaded %u pools, %u unloaded\n",
        !           242:                           loaded, unloaded);
        !           243:                return 0;
        !           244:        }
        !           245:        fprintf(stderr, "loaded %u of %u pools, %u failed to load, "
        !           246:                        "%u unloaded\n", loaded, found, found - loaded, unloaded);
        !           247:        return EINVAL;
        !           248: }
        !           249: 
        !           250: static int load_pools(vici_conn_t *conn)
        !           251: {
        !           252:        command_format_options_t format = COMMAND_FORMAT_NONE;
        !           253:        settings_t *cfg;
        !           254:        char *arg, *file = NULL;
        !           255:        int ret;
        !           256: 
        !           257:        while (TRUE)
        !           258:        {
        !           259:                switch (command_getopt(&arg))
        !           260:                {
        !           261:                        case 'h':
        !           262:                                return command_usage(NULL);
        !           263:                        case 'P':
        !           264:                                format |= COMMAND_FORMAT_PRETTY;
        !           265:                                /* fall through to raw */
        !           266:                        case 'r':
        !           267:                                format |= COMMAND_FORMAT_RAW;
        !           268:                                continue;
        !           269:                        case 'f':
        !           270:                                file = arg;
        !           271:                                continue;
        !           272:                        case EOF:
        !           273:                                break;
        !           274:                        default:
        !           275:                                return command_usage("invalid --load-pools option");
        !           276:                }
        !           277:                break;
        !           278:        }
        !           279: 
        !           280:        cfg = load_swanctl_conf(file);
        !           281:        if (!cfg)
        !           282:        {
        !           283:                return EINVAL;
        !           284:        }
        !           285: 
        !           286:        ret = load_pools_cfg(conn, format, cfg);
        !           287: 
        !           288:        cfg->destroy(cfg);
        !           289: 
        !           290:        return ret;
        !           291: }
        !           292: 
        !           293: /**
        !           294:  * Register the command.
        !           295:  */
        !           296: static void __attribute__ ((constructor))reg()
        !           297: {
        !           298:        command_register((command_t) {
        !           299:                load_pools, 'a', "load-pools", "(re-)load pool configuration",
        !           300:                {"[--raw|--pretty]"},
        !           301:                {
        !           302:                        {"help",                'h', 0, "show usage information"},
        !           303:                        {"raw",                 'r', 0, "dump raw response message"},
        !           304:                        {"pretty",              'P', 0, "dump raw response message in pretty print"},
        !           305:                        {"file",                'f', 1, "custom path to swanctl.conf"},
        !           306:                }
        !           307:        });
        !           308: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>