Wed Jan 8 2020 09:49:47

Asterisk developer's documentation


func_config.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2008, Digium, Inc.
5  *
6  * Russell Bryant <russell@digium.com>
7  * Tilghman Lesher <func_config__200803@the-tilghman.com>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19 
20 /*! \file
21  *
22  * \brief A function to retrieve variables from an Asterisk configuration file
23  *
24  * \author Russell Bryant <russell@digium.com>
25  * \author Tilghman Lesher <func_config__200803@the-tilghman.com>
26  *
27  * \ingroup functions
28  */
29 
30 /*** MODULEINFO
31  <support_level>core</support_level>
32  ***/
33 
34 #include "asterisk.h"
35 
36 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 421327 $")
37 
38 #include "asterisk/module.h"
39 #include "asterisk/channel.h"
40 #include "asterisk/pbx.h"
41 #include "asterisk/app.h"
42 
43 /*** DOCUMENTATION
44  <function name="AST_CONFIG" language="en_US">
45  <synopsis>
46  Retrieve a variable from a configuration file.
47  </synopsis>
48  <syntax>
49  <parameter name="config_file" required="true" />
50  <parameter name="category" required="true" />
51  <parameter name="variable_name" required="true" />
52  </syntax>
53  <description>
54  <para>This function reads a variable from an Asterisk configuration file.</para>
55  </description>
56  </function>
57 
58 ***/
59 
60 struct config_item {
62  struct ast_config *cfg;
63  char filename[0];
64 };
65 
67 
68 static int config_function_read(struct ast_channel *chan, const char *cmd, char *data,
69  char *buf, size_t len)
70 {
71  struct ast_config *cfg;
72  struct ast_flags cfg_flags = { CONFIG_FLAG_FILEUNCHANGED };
73  const char *val;
74  char *parse;
75  struct config_item *cur;
77  AST_APP_ARG(filename);
78  AST_APP_ARG(category);
79  AST_APP_ARG(variable);
80  AST_APP_ARG(index);
81  );
82 
83  if (ast_strlen_zero(data)) {
84  ast_log(LOG_ERROR, "AST_CONFIG() requires an argument\n");
85  return -1;
86  }
87 
88  parse = ast_strdupa(data);
90 
91  if (ast_strlen_zero(args.filename)) {
92  ast_log(LOG_ERROR, "AST_CONFIG() requires a filename\n");
93  return -1;
94  }
95 
96  if (ast_strlen_zero(args.category)) {
97  ast_log(LOG_ERROR, "AST_CONFIG() requires a category\n");
98  return -1;
99  }
100 
101  if (ast_strlen_zero(args.variable)) {
102  ast_log(LOG_ERROR, "AST_CONFIG() requires a variable\n");
103  return -1;
104  }
105 
106  if (!(cfg = ast_config_load(args.filename, cfg_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
107  return -1;
108  }
109 
110  if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
111  /* Retrieve cfg from list */
113  AST_RWLIST_TRAVERSE(&configs, cur, entry) {
114  if (!strcmp(cur->filename, args.filename)) {
115  break;
116  }
117  }
118 
119  if (!cur) {
120  /* At worst, we might leak an entry while upgrading locks */
123  if (!(cur = ast_calloc(1, sizeof(*cur) + strlen(args.filename) + 1))) {
125  return -1;
126  }
127 
128  strcpy(cur->filename, args.filename);
129 
131  if (!(cfg = ast_config_load(args.filename, cfg_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
132  ast_free(cur);
134  return -1;
135  }
136 
137  cur->cfg = cfg;
138  AST_RWLIST_INSERT_TAIL(&configs, cur, entry);
139  }
140 
141  cfg = cur->cfg;
142  } else {
143  /* Replace cfg in list */
145  AST_RWLIST_TRAVERSE(&configs, cur, entry) {
146  if (!strcmp(cur->filename, args.filename)) {
147  break;
148  }
149  }
150 
151  if (!cur) {
152  if (!(cur = ast_calloc(1, sizeof(*cur) + strlen(args.filename) + 1))) {
154  return -1;
155  }
156 
157  strcpy(cur->filename, args.filename);
158  cur->cfg = cfg;
159 
160  AST_RWLIST_INSERT_TAIL(&configs, cur, entry);
161  } else {
162  ast_config_destroy(cur->cfg);
163  cur->cfg = cfg;
164  }
165  }
166 
167  if (!(val = ast_variable_retrieve(cfg, args.category, args.variable))) {
168  ast_debug(1, "'%s' not found in [%s] of '%s'\n", args.variable,
169  args.category, args.filename);
171  return -1;
172  }
173 
174  ast_copy_string(buf, val, len);
175 
176  /* Unlock down here, so there's no chance the struct goes away while we're using it. */
178 
179  return 0;
180 }
181 
183  .name = "AST_CONFIG",
184  .read = config_function_read,
185 };
186 
187 static int unload_module(void)
188 {
189  struct config_item *current;
190  int res = ast_custom_function_unregister(&config_function);
191 
193  while ((current = AST_RWLIST_REMOVE_HEAD(&configs, entry))) {
194  ast_config_destroy(current->cfg);
195  ast_free(current);
196  }
198 
199  return res;
200 }
201 
202 static int load_module(void)
203 {
204  return ast_custom_function_register(&config_function);
205 }
206 
207 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Asterisk configuration file variable access");
Main Channel structure associated with a channel.
Definition: channel.h:742
static struct ast_custom_function config_function
Definition: func_config.c:182
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:396
Asterisk main include file. File version handling, generic pbx functions.
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
Definition: linkedlists.h:332
Definition: ast_expr2.c:325
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
General Asterisk PBX channel definitions.
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
Data structure associated with a custom dialplan function.
Definition: pbx.h:95
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
Core PBX routines and definitions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
#define ast_free(a)
Definition: astmm.h:97
static int load_module(void)
Definition: func_config.c:202
#define AST_RWLIST_REMOVE_HEAD
Definition: linkedlists.h:829
Structure used to handle boolean flags.
Definition: utils.h:200
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define AST_RWLIST_ENTRY
Definition: linkedlists.h:414
static int config_function_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_config.c:68
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
static int unload_module(void)
Definition: func_config.c:187
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
const char * name
Definition: pbx.h:96
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1164
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51