Annotation of embedaddon/strongswan/src/libstrongswan/fetcher/fetcher_manager.c, revision 1.1.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>