/src/httpd/server/provider.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Licensed to the Apache Software Foundation (ASF) under one or more |
2 | | * contributor license agreements. See the NOTICE file distributed with |
3 | | * this work for additional information regarding copyright ownership. |
4 | | * The ASF licenses this file to You under the Apache License, Version 2.0 |
5 | | * (the "License"); you may not use this file except in compliance with |
6 | | * the License. You may obtain a copy of the License at |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | #include "apr_pools.h" |
18 | | #include "apr_hash.h" |
19 | | #include "apr_tables.h" |
20 | | #include "apr_strings.h" |
21 | | |
22 | | #include "ap_provider.h" |
23 | | |
24 | | static apr_hash_t *global_providers = NULL; |
25 | | static apr_hash_t *global_providers_names = NULL; |
26 | | |
27 | | |
28 | | static apr_status_t cleanup_global_providers(void *ctx) |
29 | 0 | { |
30 | 0 | global_providers = NULL; |
31 | 0 | global_providers_names = NULL; |
32 | 0 | return APR_SUCCESS; |
33 | 0 | } |
34 | | |
35 | | AP_DECLARE(apr_status_t) ap_register_provider(apr_pool_t *pool, |
36 | | const char *provider_group, |
37 | | const char *provider_name, |
38 | | const char *provider_version, |
39 | | const void *provider) |
40 | 0 | { |
41 | 0 | apr_hash_t *provider_group_hash, *provider_version_hash; |
42 | |
|
43 | 0 | if (global_providers == NULL) { |
44 | 0 | global_providers = apr_hash_make(pool); |
45 | 0 | global_providers_names = apr_hash_make(pool); |
46 | 0 | apr_pool_cleanup_register(pool, NULL, cleanup_global_providers, |
47 | 0 | apr_pool_cleanup_null); |
48 | 0 | } |
49 | | |
50 | | /* First, deal with storing the provider away */ |
51 | 0 | provider_group_hash = apr_hash_get(global_providers, provider_group, |
52 | 0 | APR_HASH_KEY_STRING); |
53 | |
|
54 | 0 | if (!provider_group_hash) { |
55 | 0 | provider_group_hash = apr_hash_make(pool); |
56 | 0 | apr_hash_set(global_providers, provider_group, APR_HASH_KEY_STRING, |
57 | 0 | provider_group_hash); |
58 | 0 | } |
59 | |
|
60 | 0 | provider_version_hash = apr_hash_get(provider_group_hash, provider_name, |
61 | 0 | APR_HASH_KEY_STRING); |
62 | |
|
63 | 0 | if (!provider_version_hash) { |
64 | 0 | provider_version_hash = apr_hash_make(pool); |
65 | 0 | apr_hash_set(provider_group_hash, provider_name, APR_HASH_KEY_STRING, |
66 | 0 | provider_version_hash); |
67 | 0 | } |
68 | | |
69 | | /* just set it. no biggy if it was there before. */ |
70 | 0 | apr_hash_set(provider_version_hash, provider_version, APR_HASH_KEY_STRING, |
71 | 0 | provider); |
72 | | |
73 | | /* Now, tuck away the provider names in an easy-to-get format */ |
74 | 0 | provider_group_hash = apr_hash_get(global_providers_names, provider_group, |
75 | 0 | APR_HASH_KEY_STRING); |
76 | |
|
77 | 0 | if (!provider_group_hash) { |
78 | 0 | provider_group_hash = apr_hash_make(pool); |
79 | 0 | apr_hash_set(global_providers_names, provider_group, APR_HASH_KEY_STRING, |
80 | 0 | provider_group_hash); |
81 | 0 | } |
82 | |
|
83 | 0 | provider_version_hash = apr_hash_get(provider_group_hash, provider_version, |
84 | 0 | APR_HASH_KEY_STRING); |
85 | |
|
86 | 0 | if (!provider_version_hash) { |
87 | 0 | provider_version_hash = apr_hash_make(pool); |
88 | 0 | apr_hash_set(provider_group_hash, provider_version, APR_HASH_KEY_STRING, |
89 | 0 | provider_version_hash); |
90 | 0 | } |
91 | | |
92 | | /* just set it. no biggy if it was there before. */ |
93 | 0 | apr_hash_set(provider_version_hash, provider_name, APR_HASH_KEY_STRING, |
94 | 0 | provider_name); |
95 | |
|
96 | 0 | return APR_SUCCESS; |
97 | 0 | } |
98 | | |
99 | | AP_DECLARE(void *) ap_lookup_provider(const char *provider_group, |
100 | | const char *provider_name, |
101 | | const char *provider_version) |
102 | 0 | { |
103 | 0 | apr_hash_t *provider_group_hash, *provider_name_hash; |
104 | |
|
105 | 0 | if (global_providers == NULL) { |
106 | 0 | return NULL; |
107 | 0 | } |
108 | | |
109 | 0 | provider_group_hash = apr_hash_get(global_providers, provider_group, |
110 | 0 | APR_HASH_KEY_STRING); |
111 | |
|
112 | 0 | if (provider_group_hash == NULL) { |
113 | 0 | return NULL; |
114 | 0 | } |
115 | | |
116 | 0 | provider_name_hash = apr_hash_get(provider_group_hash, provider_name, |
117 | 0 | APR_HASH_KEY_STRING); |
118 | |
|
119 | 0 | if (provider_name_hash == NULL) { |
120 | 0 | return NULL; |
121 | 0 | } |
122 | | |
123 | 0 | return apr_hash_get(provider_name_hash, provider_version, |
124 | 0 | APR_HASH_KEY_STRING); |
125 | 0 | } |
126 | | |
127 | | AP_DECLARE(apr_array_header_t *) ap_list_provider_names(apr_pool_t *pool, |
128 | | const char *provider_group, |
129 | | const char *provider_version) |
130 | 0 | { |
131 | 0 | apr_array_header_t *ret = NULL; |
132 | 0 | ap_list_provider_names_t *entry; |
133 | 0 | apr_hash_t *provider_group_hash, *h; |
134 | 0 | apr_hash_index_t *hi; |
135 | 0 | char *val; |
136 | |
|
137 | 0 | if (global_providers_names == NULL) { |
138 | 0 | goto out; |
139 | 0 | } |
140 | | |
141 | 0 | provider_group_hash = apr_hash_get(global_providers_names, provider_group, |
142 | 0 | APR_HASH_KEY_STRING); |
143 | |
|
144 | 0 | if (provider_group_hash == NULL) { |
145 | 0 | goto out; |
146 | 0 | } |
147 | | |
148 | 0 | h = apr_hash_get(provider_group_hash, provider_version, APR_HASH_KEY_STRING); |
149 | |
|
150 | 0 | if (h == NULL) { |
151 | 0 | goto out; |
152 | 0 | } |
153 | | |
154 | 0 | ret = apr_array_make(pool, apr_hash_count(h), sizeof(ap_list_provider_names_t)); |
155 | 0 | for (hi = apr_hash_first(pool, h); hi; hi = apr_hash_next(hi)) { |
156 | 0 | apr_hash_this(hi, NULL, NULL, (void *)&val); |
157 | 0 | entry = apr_array_push(ret); |
158 | 0 | entry->provider_name = apr_pstrdup(pool, val); |
159 | 0 | } |
160 | | |
161 | 0 | out: |
162 | 0 | if (ret == NULL) { |
163 | 0 | ret = apr_array_make(pool, 1, sizeof(ap_list_provider_names_t)); |
164 | 0 | } |
165 | 0 | return ret; |
166 | 0 | } |
167 | | |
168 | | AP_DECLARE(apr_array_header_t *) ap_list_provider_groups(apr_pool_t *pool) |
169 | 0 | { |
170 | 0 | apr_array_header_t *ret = apr_array_make(pool, 10, sizeof(ap_list_provider_groups_t)); |
171 | 0 | ap_list_provider_groups_t *entry; |
172 | 0 | apr_hash_t *provider_group_hash; |
173 | 0 | apr_hash_index_t *groups_hi, *vers_hi; |
174 | 0 | char *group, *version; |
175 | |
|
176 | 0 | if (global_providers_names == NULL) |
177 | 0 | return ret; |
178 | | |
179 | 0 | for (groups_hi = apr_hash_first(pool, global_providers_names); |
180 | 0 | groups_hi; |
181 | 0 | groups_hi = apr_hash_next(groups_hi)) |
182 | 0 | { |
183 | 0 | apr_hash_this(groups_hi, (void *)&group, NULL, (void *)&provider_group_hash); |
184 | 0 | if (provider_group_hash == NULL) |
185 | 0 | continue; |
186 | 0 | for (vers_hi = apr_hash_first(pool, provider_group_hash); |
187 | 0 | vers_hi; |
188 | 0 | vers_hi = apr_hash_next(vers_hi)) |
189 | 0 | { |
190 | 0 | apr_hash_this(vers_hi, (void *)&version, NULL, NULL); |
191 | |
|
192 | 0 | entry = apr_array_push(ret); |
193 | 0 | entry->provider_group = group; |
194 | 0 | entry->provider_version = version; |
195 | 0 | } |
196 | 0 | } |
197 | 0 | return ret; |
198 | 0 | } |