Asterisk - The Open Source Telephony Project GIT-master-a358458
Data Structures | Macros | Enumerations | Functions | Variables
res_sorcery_realtime.c File Reference

Sorcery Realtime Object Wizard. More...

#include "asterisk.h"
#include <regex.h>
#include "asterisk/module.h"
#include "asterisk/sorcery.h"
Include dependency graph for res_sorcery_realtime.c:

Go to the source code of this file.

Data Structures

struct  sorcery_config
 Structure for storing configuration file sourced objects. More...
 

Macros

#define UUID_FIELD   "id"
 They key field used to store the unique identifier for the object. More...
 

Enumerations

enum  unqualified_fetch { UNQUALIFIED_FETCH_NO , UNQUALIFIED_FETCH_WARN , UNQUALIFIED_FETCH_YES , UNQUALIFIED_FETCH_ERROR }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int load_module (void)
 
static void sorcery_realtime_close (void *data)
 
static int sorcery_realtime_create (const struct ast_sorcery *sorcery, void *data, void *object)
 
static int sorcery_realtime_delete (const struct ast_sorcery *sorcery, void *data, void *object)
 
static struct ast_variablesorcery_realtime_filter_objectset (struct ast_variable *objectset, struct ast_variable **id, const struct ast_sorcery *sorcery, const char *type)
 Internal helper function which returns a filtered objectset. More...
 
static void * sorcery_realtime_open (const char *data)
 
static void * sorcery_realtime_retrieve_fields (const struct ast_sorcery *sorcery, void *data, const char *type, const struct ast_variable *fields)
 
static void * sorcery_realtime_retrieve_id (const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
 
static void sorcery_realtime_retrieve_multiple (const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const struct ast_variable *fields)
 
static void sorcery_realtime_retrieve_prefix (const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *prefix, const size_t prefix_len)
 
static void sorcery_realtime_retrieve_regex (const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *regex)
 
static int sorcery_realtime_update (const struct ast_sorcery *sorcery, void *data, void *object)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Sorcery Realtime Object Wizard" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DRIVER, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_sorcery_wizard realtime_object_wizard
 

Detailed Description

Sorcery Realtime Object Wizard.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file res_sorcery_realtime.c.

Macro Definition Documentation

◆ UUID_FIELD

#define UUID_FIELD   "id"

They key field used to store the unique identifier for the object.

Definition at line 39 of file res_sorcery_realtime.c.

Enumeration Type Documentation

◆ unqualified_fetch

Enumerator
UNQUALIFIED_FETCH_NO 
UNQUALIFIED_FETCH_WARN 
UNQUALIFIED_FETCH_YES 
UNQUALIFIED_FETCH_ERROR 

Definition at line 41 of file res_sorcery_realtime.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 382 of file res_sorcery_realtime.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 382 of file res_sorcery_realtime.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 382 of file res_sorcery_realtime.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 362 of file res_sorcery_realtime.c.

363{
366 }
367
369}
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct ast_sorcery_wizard realtime_object_wizard
#define ast_sorcery_wizard_register(interface)
See __ast_sorcery_wizard_register()
Definition: sorcery.h:383

References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_sorcery_wizard_register, and realtime_object_wizard.

◆ sorcery_realtime_close()

static void sorcery_realtime_close ( void *  data)
static

Definition at line 357 of file res_sorcery_realtime.c.

358{
359 ast_free(data);
360}
#define ast_free(a)
Definition: astmm.h:180

References ast_free.

◆ sorcery_realtime_create()

static int sorcery_realtime_create ( const struct ast_sorcery sorcery,
void *  data,
void *  object 
)
static

Definition at line 80 of file res_sorcery_realtime.c.

81{
82 struct sorcery_config *config = data;
85
86 if (!fields || !id) {
88 return -1;
89 }
90
91 /* Place the identifier at the front for sanity sake */
92 id->next = fields;
93 fields = id;
94
95 return (ast_store_realtime_fields(config->family, fields) <= 0) ? -1 : 0;
96}
enum queue_result id
Definition: app_queue.c:1638
static const char config[]
Definition: chan_ooh323.c:111
int ast_store_realtime_fields(const char *family, const struct ast_variable *fields)
Create realtime configuration.
Definition: main/config.c:3719
#define ast_variable_new(name, value, filename)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
static struct ast_sorcery * sorcery
#define UUID_FIELD
They key field used to store the unique identifier for the object.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
Definition: sorcery.h:1137
Structure for variables, used for configurations and for channel variables.
Structure for storing configuration file sourced objects.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References ast_sorcery_object_get_id(), ast_sorcery_objectset_create, ast_store_realtime_fields(), ast_variable_new, ast_variables_destroy(), config, id, RAII_VAR, sorcery, and UUID_FIELD.

◆ sorcery_realtime_delete()

static int sorcery_realtime_delete ( const struct ast_sorcery sorcery,
void *  data,
void *  object 
)
static

Definition at line 297 of file res_sorcery_realtime.c.

298{
299 struct sorcery_config *config = data;
300
301 return (ast_destroy_realtime_fields(config->family, UUID_FIELD, ast_sorcery_object_get_id(object), NULL) <= 0) ? -1 : 0;
302}
int ast_destroy_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
Destroy realtime configuration.
Definition: main/config.c:3756
#define NULL
Definition: resample.c:96

References ast_destroy_realtime_fields(), ast_sorcery_object_get_id(), config, NULL, and UUID_FIELD.

◆ sorcery_realtime_filter_objectset()

static struct ast_variable * sorcery_realtime_filter_objectset ( struct ast_variable objectset,
struct ast_variable **  id,
const struct ast_sorcery sorcery,
const char *  type 
)
static

Internal helper function which returns a filtered objectset.

The following are filtered out of the objectset:

  • The id field. This is returned to the caller in an out parameter.
  • Fields that are not registered with sorcery.
Parameters
objectsetObjectset to filter.
[out]idThe ID of the sorcery object, as found in the objectset.
sorceryThe sorcery instance that is requesting an objectset.
typeThe object type
Returns
The filtered objectset

Definition at line 111 of file res_sorcery_realtime.c.

113{
114 struct ast_variable *previous = NULL, *field = objectset;
115 struct ast_sorcery_object_type *object_type;
116
118 if (!object_type) {
119 ast_log(LOG_WARNING, "Unknown sorcery object type %s. Expect errors\n", type);
120 /* Continue since we still want to filter out the id */
121 }
122
123 while (field) {
124 int remove_field = 0;
125 int delete_field = 0;
126
127 if (!strcmp(field->name, UUID_FIELD)) {
128 *id = field;
129 remove_field = 1;
130 } else if (object_type &&
131 !ast_sorcery_is_object_field_registered(object_type, field->name)) {
132 ast_debug(1, "Filtering out realtime field '%s' from retrieval\n", field->name);
133 remove_field = 1;
134 delete_field = 1;
135 }
136
137 if (remove_field) {
138 struct ast_variable *removed;
139
140 if (previous) {
141 previous->next = field->next;
142 } else {
143 objectset = field->next;
144 }
145
146 removed = field;
147 field = field->next;
148 removed->next = NULL;
149 if (delete_field) {
150 ast_variables_destroy(removed);
151 }
152 } else {
153 previous = field;
154 field = field->next;
155 }
156 }
157
158 ao2_cleanup(object_type);
159
160 return objectset;
161}
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
static const char type[]
Definition: chan_ooh323.c:109
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
struct ast_sorcery_object_type * ast_sorcery_get_object_type(const struct ast_sorcery *sorcery, const char *type)
Get the sorcery object type given a type name.
Definition: sorcery.c:2489
int ast_sorcery_is_object_field_registered(const struct ast_sorcery_object_type *object_type, const char *field_name)
Determine if a particular object field has been registered with sorcery.
Definition: sorcery.c:2509
Structure for registered object type.
Definition: sorcery.c:148
struct ast_variable * next

References ao2_cleanup, ast_debug, ast_log, ast_sorcery_get_object_type(), ast_sorcery_is_object_field_registered(), ast_variables_destroy(), LOG_WARNING, ast_sorcery_object_type::name, ast_variable::next, NULL, sorcery, type, and UUID_FIELD.

Referenced by sorcery_realtime_retrieve_fields(), and sorcery_realtime_retrieve_multiple().

◆ sorcery_realtime_open()

static void * sorcery_realtime_open ( const char *  data)
static

Definition at line 304 of file res_sorcery_realtime.c.

305{
306 struct sorcery_config *config;
307 char *tmp;
308 char *family;
309 char *option;
310
311 /* We require a prefix for family string generation, or else stuff could mix together */
312 if (ast_strlen_zero(data)) {
313 return NULL;
314 }
315
316 tmp = ast_strdupa(data);
317 family = strsep(&tmp, ",");
318
320 return NULL;
321 }
322
323 config = ast_calloc(1, sizeof(*config) + strlen(family) + 1);
324 if (!config) {
325 return NULL;
326 }
327
328 strcpy(config->family, family); /* Safe */
330
331 while ((option = strsep(&tmp, ","))) {
332 char *name = strsep(&option, "=");
333 char *value = option;
334
335 if (!strcasecmp(name, "allow_unqualified_fetch")) {
336 if (ast_strlen_zero(value) || !strcasecmp(value, "yes")) {
338 } else if (!strcasecmp(value, "no")) {
340 } else if (!strcasecmp(value, "warn")) {
342 } else if (!strcasecmp(value, "error")) {
344 } else {
345 ast_log(LOG_ERROR, "Unrecognized value in %s:%s: '%s'\n", family, name, value);
346 return NULL;
347 }
348 } else {
349 ast_log(LOG_ERROR, "Unrecognized option in %s: '%s'\n", family, name);
350 return NULL;
351 }
352 }
353
354 return config;
355}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
static int tmp()
Definition: bt_open.c:389
static const char name[]
Definition: format_mp3.c:68
char * strsep(char **str, const char *delims)
int ast_realtime_is_mapping_defined(const char *family)
Determine if a mapping exists for a given family.
Definition: main/config.c:3193
#define LOG_ERROR
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
int value
Definition: syslog.c:37

References ast_calloc, ast_log, ast_realtime_is_mapping_defined(), ast_strdupa, ast_strlen_zero(), config, sorcery_config::family, LOG_ERROR, name, NULL, strsep(), tmp(), UNQUALIFIED_FETCH_ERROR, UNQUALIFIED_FETCH_NO, UNQUALIFIED_FETCH_WARN, UNQUALIFIED_FETCH_YES, and value.

◆ sorcery_realtime_retrieve_fields()

static void * sorcery_realtime_retrieve_fields ( const struct ast_sorcery sorcery,
void *  data,
const char *  type,
const struct ast_variable fields 
)
static

Definition at line 163 of file res_sorcery_realtime.c.

164{
165 struct sorcery_config *config = data;
166 RAII_VAR(struct ast_variable *, objectset, NULL, ast_variables_destroy);
168 void *object = NULL;
169
170 if (!(objectset = ast_load_realtime_fields(config->family, fields))) {
171 return NULL;
172 }
173
174 objectset = sorcery_realtime_filter_objectset(objectset, &id, sorcery, type);
175
176 if (!id
177 || !(object = ast_sorcery_alloc(sorcery, type, id->value))
178 || ast_sorcery_objectset_apply(sorcery, object, objectset)) {
179 ao2_cleanup(object);
180 return NULL;
181 }
182
183 return object;
184}
struct ast_variable * ast_load_realtime_fields(const char *family, const struct ast_variable *fields)
Retrieve realtime configuration.
Definition: main/config.c:3471
static struct ast_variable * sorcery_realtime_filter_objectset(struct ast_variable *objectset, struct ast_variable **id, const struct ast_sorcery *sorcery, const char *type)
Internal helper function which returns a filtered objectset.
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition: sorcery.c:1744
int ast_sorcery_objectset_apply(const struct ast_sorcery *sorcery, void *object, struct ast_variable *objectset)
Apply an object set (KVP list) to an object.
Definition: sorcery.c:1632

References ao2_cleanup, ast_load_realtime_fields(), ast_sorcery_alloc(), ast_sorcery_objectset_apply(), ast_variables_destroy(), config, id, NULL, RAII_VAR, sorcery, sorcery_realtime_filter_objectset(), and type.

Referenced by sorcery_realtime_retrieve_id().

◆ sorcery_realtime_retrieve_id()

static void * sorcery_realtime_retrieve_id ( const struct ast_sorcery sorcery,
void *  data,
const char *  type,
const char *  id 
)
static

Definition at line 186 of file res_sorcery_realtime.c.

187{
189
190 return sorcery_realtime_retrieve_fields(sorcery, data, type, fields);
191}
static void * sorcery_realtime_retrieve_fields(const struct ast_sorcery *sorcery, void *data, const char *type, const struct ast_variable *fields)

References ast_variable_new, ast_variables_destroy(), RAII_VAR, sorcery, sorcery_realtime_retrieve_fields(), type, and UUID_FIELD.

◆ sorcery_realtime_retrieve_multiple()

static void sorcery_realtime_retrieve_multiple ( const struct ast_sorcery sorcery,
void *  data,
const char *  type,
struct ao2_container objects,
const struct ast_variable fields 
)
static

Definition at line 193 of file res_sorcery_realtime.c.

194{
195 struct sorcery_config *config = data;
196 RAII_VAR(struct ast_config *, rows, NULL, ast_config_destroy);
198 struct ast_category *row = NULL;
199
200 if (!fields) {
201 char field[strlen(UUID_FIELD) + 6], value[2];
202
203 if (config->fetch == UNQUALIFIED_FETCH_NO) {
204 return;
205 }
206 if (config->fetch == UNQUALIFIED_FETCH_ERROR) {
207 ast_log(LOG_ERROR, "Unqualified fetch prevented on %s\n", config->family);
208 return;
209 }
210 if (config->fetch == UNQUALIFIED_FETCH_WARN) {
211 ast_log(LOG_WARNING, "Unqualified fetch requested on %s\n", config->family);
212 }
213
214 /* If no fields have been specified we want all rows, so trick realtime into doing it */
215 snprintf(field, sizeof(field), "%s LIKE", UUID_FIELD);
216 snprintf(value, sizeof(value), "%%");
217
218 if (!(all = ast_variable_new(field, value, ""))) {
219 return;
220 }
221
222 fields = all;
223 }
224
225 if (!(rows = ast_load_realtime_multientry_fields(config->family, fields))) {
226 return;
227 }
228
229 while ((row = ast_category_browse_filtered(rows, NULL, row, NULL))) {
230 struct ast_variable *objectset = ast_category_detach_variables(row);
232 RAII_VAR(void *, object, NULL, ao2_cleanup);
233
234 objectset = sorcery_realtime_filter_objectset(objectset, &id, sorcery, type);
235
236 if (id
237 && (object = ast_sorcery_alloc(sorcery, type, id->value))
238 && !ast_sorcery_objectset_apply(sorcery, object, objectset)) {
239 ao2_link(objects, object);
240 }
241
242 ast_variables_destroy(objectset);
243 }
244}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
struct ast_variable * ast_category_detach_variables(struct ast_category *cat)
Definition: main/config.c:1440
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
struct ast_config * ast_load_realtime_multientry_fields(const char *family, const struct ast_variable *fields)
Retrieve realtime configuration.
Definition: main/config.c:3596
struct ast_category * ast_category_browse_filtered(struct ast_config *config, const char *category_name, struct ast_category *prev, const char *filter)
Browse categories with filters.
Definition: main/config.c:1424

References ao2_cleanup, ao2_link, ast_category_browse_filtered(), ast_category_detach_variables(), ast_config_destroy(), ast_load_realtime_multientry_fields(), ast_log, ast_sorcery_alloc(), ast_sorcery_objectset_apply(), ast_variable_new, ast_variables_destroy(), config, id, LOG_ERROR, LOG_WARNING, NULL, RAII_VAR, sorcery, sorcery_realtime_filter_objectset(), type, UNQUALIFIED_FETCH_ERROR, UNQUALIFIED_FETCH_NO, UNQUALIFIED_FETCH_WARN, UUID_FIELD, and value.

Referenced by sorcery_realtime_retrieve_prefix(), and sorcery_realtime_retrieve_regex().

◆ sorcery_realtime_retrieve_prefix()

static void sorcery_realtime_retrieve_prefix ( const struct ast_sorcery sorcery,
void *  data,
const char *  type,
struct ao2_container objects,
const char *  prefix,
const size_t  prefix_len 
)
static

Definition at line 268 of file res_sorcery_realtime.c.

270{
271 char field[strlen(UUID_FIELD) + 6], value[prefix_len + 2];
273
274 if (prefix_len) {
275 snprintf(field, sizeof(field), "%s LIKE", UUID_FIELD);
276 snprintf(value, sizeof(value), "%.*s%%", (int) prefix_len, prefix);
277 if (!(fields = ast_variable_new(field, value, ""))) {
278 return;
279 }
280 }
281
282 sorcery_realtime_retrieve_multiple(sorcery, data, type, objects, fields);
283}
static char prefix[MAX_PREFIX]
Definition: http.c:144
static void sorcery_realtime_retrieve_multiple(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const struct ast_variable *fields)

References ast_variable_new, ast_variables_destroy(), NULL, prefix, RAII_VAR, sorcery, sorcery_realtime_retrieve_multiple(), type, UUID_FIELD, and value.

◆ sorcery_realtime_retrieve_regex()

static void sorcery_realtime_retrieve_regex ( const struct ast_sorcery sorcery,
void *  data,
const char *  type,
struct ao2_container objects,
const char *  regex 
)
static

Definition at line 246 of file res_sorcery_realtime.c.

247{
248 char field[strlen(UUID_FIELD) + 6], value[strlen(regex) + 3];
250
251 if (!ast_strlen_zero(regex)) {
252 /* The realtime API provides no direct ability to do regex so for now we support a limited subset using pattern matching */
253 snprintf(field, sizeof(field), "%s LIKE", UUID_FIELD);
254 if (regex[0] == '^') {
255 snprintf(value, sizeof(value), "%s%%", regex + 1);
256 } else {
257 snprintf(value, sizeof(value), "%%%s%%", regex);
258 }
259
260 if (!(fields = ast_variable_new(field, value, ""))) {
261 return;
262 }
263 }
264
265 sorcery_realtime_retrieve_multiple(sorcery, data, type, objects, fields);
266}
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)

References ast_strlen_zero(), ast_variable_new, ast_variables_destroy(), NULL, RAII_VAR, regex(), sorcery, sorcery_realtime_retrieve_multiple(), type, UUID_FIELD, and value.

◆ sorcery_realtime_update()

static int sorcery_realtime_update ( const struct ast_sorcery sorcery,
void *  data,
void *  object 
)
static

Definition at line 285 of file res_sorcery_realtime.c.

286{
287 struct sorcery_config *config = data;
289
290 if (!fields) {
291 return -1;
292 }
293
294 return (ast_update_realtime_fields(config->family, UUID_FIELD, ast_sorcery_object_get_id(object), fields) < 0) ? -1 : 0;
295}
int ast_update_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
Update realtime configuration.
Definition: main/config.c:3638

References ast_sorcery_object_get_id(), ast_sorcery_objectset_create, ast_update_realtime_fields(), ast_variables_destroy(), config, RAII_VAR, sorcery, and UUID_FIELD.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 371 of file res_sorcery_realtime.c.

372{
374 return 0;
375}
int ast_sorcery_wizard_unregister(const struct ast_sorcery_wizard *interface)
Unregister a sorcery wizard.
Definition: sorcery.c:474

References ast_sorcery_wizard_unregister(), and realtime_object_wizard.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Sorcery Realtime Object Wizard" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DRIVER, }
static

Definition at line 382 of file res_sorcery_realtime.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 382 of file res_sorcery_realtime.c.

◆ realtime_object_wizard

struct ast_sorcery_wizard realtime_object_wizard
static

Definition at line 66 of file res_sorcery_realtime.c.

Referenced by load_module(), and unload_module().