Annotation of embedaddon/strongswan/src/libstrongswan/fetcher/fetcher_manager.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2008 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 "fetcher_manager.h"
! 17:
! 18: #include <utils/debug.h>
! 19: #include <threading/rwlock.h>
! 20: #include <collections/linked_list.h>
! 21:
! 22: typedef struct private_fetcher_manager_t private_fetcher_manager_t;
! 23:
! 24: /**
! 25: * private data of fetcher_manager
! 26: */
! 27: struct private_fetcher_manager_t {
! 28:
! 29: /**
! 30: * public functions
! 31: */
! 32: fetcher_manager_t public;
! 33:
! 34: /**
! 35: * list of registered fetchers, as entry_t
! 36: */
! 37: linked_list_t *fetchers;
! 38:
! 39: /**
! 40: * read write lock to list
! 41: */
! 42: rwlock_t *lock;
! 43: };
! 44:
! 45: typedef struct {
! 46: /** associated fetcher construction function */
! 47: fetcher_constructor_t create;
! 48: /** URL this fetcher support */
! 49: char *url;
! 50: } entry_t;
! 51:
! 52: /**
! 53: * destroy an entry_t
! 54: */
! 55: static void entry_destroy(entry_t *entry)
! 56: {
! 57: free(entry->url);
! 58: free(entry);
! 59: }
! 60:
! 61: METHOD(fetcher_manager_t, fetch, status_t,
! 62: private_fetcher_manager_t *this, char *url, void *userdata, ...)
! 63: {
! 64: enumerator_t *enumerator;
! 65: status_t status = NOT_SUPPORTED;
! 66: entry_t *entry;
! 67: bool capable = FALSE;
! 68:
! 69: this->lock->read_lock(this->lock);
! 70: enumerator = this->fetchers->create_enumerator(this->fetchers);
! 71: while (enumerator->enumerate(enumerator, &entry))
! 72: {
! 73: fetcher_option_t opt;
! 74: fetcher_t *fetcher;
! 75: bool good = TRUE;
! 76: host_t *host;
! 77: va_list args;
! 78:
! 79: /* check URL support of fetcher */
! 80: if (strncasecmp(entry->url, url, strlen(entry->url)))
! 81: {
! 82: continue;
! 83: }
! 84: /* create fetcher instance and set options */
! 85: fetcher = entry->create();
! 86: if (!fetcher)
! 87: {
! 88: continue;
! 89: }
! 90: va_start(args, userdata);
! 91: while (good)
! 92: {
! 93: opt = va_arg(args, int);
! 94: switch (opt)
! 95: {
! 96: case FETCH_REQUEST_DATA:
! 97: good = fetcher->set_option(fetcher, opt,
! 98: va_arg(args, chunk_t));
! 99: continue;
! 100: case FETCH_REQUEST_TYPE:
! 101: case FETCH_REQUEST_HEADER:
! 102: good = fetcher->set_option(fetcher, opt,
! 103: va_arg(args, char*));
! 104: continue;
! 105: case FETCH_HTTP_VERSION_1_0:
! 106: good = fetcher->set_option(fetcher, opt);
! 107: continue;
! 108: case FETCH_TIMEOUT:
! 109: good = fetcher->set_option(fetcher, opt,
! 110: va_arg(args, u_int));
! 111: continue;
! 112: case FETCH_CALLBACK:
! 113: good = fetcher->set_option(fetcher, opt,
! 114: va_arg(args, fetcher_callback_t));
! 115: continue;
! 116: case FETCH_RESPONSE_CODE:
! 117: good = fetcher->set_option(fetcher, opt,
! 118: va_arg(args, u_int*));
! 119: continue;
! 120: case FETCH_SOURCEIP:
! 121: host = va_arg(args, host_t*);
! 122: if (host && !host->is_anyaddr(host))
! 123: {
! 124: good = fetcher->set_option(fetcher, opt, host);
! 125: }
! 126: continue;
! 127: case FETCH_END:
! 128: break;
! 129: }
! 130: break;
! 131: }
! 132: va_end(args);
! 133: if (!good)
! 134: { /* fetcher does not support supplied options, try another */
! 135: fetcher->destroy(fetcher);
! 136: continue;
! 137: }
! 138:
! 139: status = fetcher->fetch(fetcher, url, userdata);
! 140: fetcher->destroy(fetcher);
! 141: /* try another fetcher only if this one does not support that URL */
! 142: if (status == NOT_SUPPORTED)
! 143: {
! 144: continue;
! 145: }
! 146: capable = TRUE;
! 147: break;
! 148: }
! 149: enumerator->destroy(enumerator);
! 150: this->lock->unlock(this->lock);
! 151: if (!capable)
! 152: {
! 153: DBG1(DBG_LIB, "unable to fetch from %s, no capable fetcher found", url);
! 154: }
! 155: return status;
! 156: }
! 157:
! 158: METHOD(fetcher_manager_t, add_fetcher, void,
! 159: private_fetcher_manager_t *this, fetcher_constructor_t create, char *url)
! 160: {
! 161: entry_t *entry;
! 162:
! 163: INIT(entry,
! 164: .url = strdup(url),
! 165: .create = create,
! 166: );
! 167: this->lock->write_lock(this->lock);
! 168: this->fetchers->insert_last(this->fetchers, entry);
! 169: this->lock->unlock(this->lock);
! 170: }
! 171:
! 172: METHOD(fetcher_manager_t, remove_fetcher, void,
! 173: private_fetcher_manager_t *this, fetcher_constructor_t create)
! 174: {
! 175: enumerator_t *enumerator;
! 176: entry_t *entry;
! 177:
! 178: this->lock->write_lock(this->lock);
! 179: enumerator = this->fetchers->create_enumerator(this->fetchers);
! 180: while (enumerator->enumerate(enumerator, &entry))
! 181: {
! 182: if (entry->create == create)
! 183: {
! 184: this->fetchers->remove_at(this->fetchers, enumerator);
! 185: entry_destroy(entry);
! 186: }
! 187: }
! 188: enumerator->destroy(enumerator);
! 189: this->lock->unlock(this->lock);
! 190: }
! 191:
! 192: METHOD(fetcher_manager_t, destroy, void,
! 193: private_fetcher_manager_t *this)
! 194: {
! 195: this->fetchers->destroy_function(this->fetchers, (void*)entry_destroy);
! 196: this->lock->destroy(this->lock);
! 197: free(this);
! 198: }
! 199:
! 200: /*
! 201: * see header file
! 202: */
! 203: fetcher_manager_t *fetcher_manager_create()
! 204: {
! 205: private_fetcher_manager_t *this;
! 206:
! 207: INIT(this,
! 208: .public = {
! 209: .fetch = _fetch,
! 210: .add_fetcher = _add_fetcher,
! 211: .remove_fetcher = _remove_fetcher,
! 212: .destroy = _destroy,
! 213: },
! 214: .fetchers = linked_list_create(),
! 215: .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
! 216: );
! 217:
! 218: return &this->public;
! 219: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>