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, ¤t))
! 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, §ion))
! 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**)§ion) == 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>