Coverage Report

Created: 2023-03-26 06:28

/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
}