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>