func_config.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "asterisk.h"
00031
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 136302 $")
00033
00034 #include "asterisk/module.h"
00035 #include "asterisk/channel.h"
00036 #include "asterisk/pbx.h"
00037 #include "asterisk/app.h"
00038
00039 struct config_item {
00040 AST_RWLIST_ENTRY(config_item) entry;
00041 struct ast_config *cfg;
00042 char filename[0];
00043 };
00044
00045 static AST_RWLIST_HEAD_STATIC(configs, config_item);
00046
00047 static int config_function_read(struct ast_channel *chan, const char *cmd, char *data,
00048 char *buf, size_t len)
00049 {
00050 struct ast_config *cfg;
00051 struct ast_flags cfg_flags = { CONFIG_FLAG_FILEUNCHANGED };
00052 const char *val;
00053 char *parse;
00054 struct config_item *cur;
00055 AST_DECLARE_APP_ARGS(args,
00056 AST_APP_ARG(filename);
00057 AST_APP_ARG(category);
00058 AST_APP_ARG(variable);
00059 AST_APP_ARG(index);
00060 );
00061
00062 if (ast_strlen_zero(data)) {
00063 ast_log(LOG_ERROR, "AST_CONFIG() requires an argument\n");
00064 return -1;
00065 }
00066
00067 parse = ast_strdupa(data);
00068 AST_STANDARD_APP_ARGS(args, parse);
00069
00070 if (ast_strlen_zero(args.filename)) {
00071 ast_log(LOG_ERROR, "AST_CONFIG() requires a filename\n");
00072 return -1;
00073 }
00074
00075 if (ast_strlen_zero(args.category)) {
00076 ast_log(LOG_ERROR, "AST_CONFIG() requires a category\n");
00077 return -1;
00078 }
00079
00080 if (ast_strlen_zero(args.variable)) {
00081 ast_log(LOG_ERROR, "AST_CONFIG() requires a variable\n");
00082 return -1;
00083 }
00084
00085 if (!(cfg = ast_config_load(args.filename, cfg_flags))) {
00086 return -1;
00087 }
00088
00089 if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
00090
00091 AST_RWLIST_RDLOCK(&configs);
00092 AST_RWLIST_TRAVERSE(&configs, cur, entry) {
00093 if (!strcmp(cur->filename, args.filename)) {
00094 break;
00095 }
00096 }
00097
00098 if (!cur) {
00099
00100 AST_RWLIST_UNLOCK(&configs);
00101 AST_RWLIST_WRLOCK(&configs);
00102 if (!(cur = ast_malloc(sizeof(*cur) + strlen(args.filename) + 1))) {
00103 AST_RWLIST_UNLOCK(&configs);
00104 return -1;
00105 }
00106
00107 strcpy(cur->filename, args.filename);
00108
00109 ast_clear_flag(&cfg_flags, CONFIG_FLAG_FILEUNCHANGED);
00110 if (!(cfg = ast_config_load(args.filename, cfg_flags))) {
00111 ast_free(cur);
00112 AST_RWLIST_UNLOCK(&configs);
00113 return -1;
00114 }
00115
00116 cur->cfg = cfg;
00117 AST_RWLIST_INSERT_TAIL(&configs, cur, entry);
00118 }
00119
00120 cfg = cur->cfg;
00121 } else {
00122
00123 AST_RWLIST_WRLOCK(&configs);
00124 AST_RWLIST_TRAVERSE(&configs, cur, entry) {
00125 if (!strcmp(cur->filename, args.filename)) {
00126 break;
00127 }
00128 }
00129
00130 if (!cur) {
00131 if (!(cur = ast_malloc(sizeof(*cur) + strlen(args.filename) + 1))) {
00132 AST_RWLIST_UNLOCK(&configs);
00133 return -1;
00134 }
00135
00136 strcpy(cur->filename, args.filename);
00137 cur->cfg = cfg;
00138
00139 AST_RWLIST_INSERT_TAIL(&configs, cur, entry);
00140 } else {
00141 ast_config_destroy(cur->cfg);
00142 cur->cfg = cfg;
00143 }
00144 }
00145
00146 if (!(val = ast_variable_retrieve(cfg, args.category, args.variable))) {
00147 ast_log(LOG_ERROR, "'%s' not found in [%s] of '%s'\n", args.variable,
00148 args.category, args.filename);
00149 AST_RWLIST_UNLOCK(&configs);
00150 return -1;
00151 }
00152
00153 ast_copy_string(buf, val, len);
00154
00155
00156 AST_RWLIST_UNLOCK(&configs);
00157
00158 return 0;
00159 }
00160
00161 static struct ast_custom_function config_function = {
00162 .name = "AST_CONFIG",
00163 .syntax = "AST_CONFIG(config_file,category,variable_name)",
00164 .synopsis = "Retrieve a variable from a configuration file",
00165 .desc =
00166 " This function reads a variable from an Asterisk configuration file.\n"
00167 "",
00168 .read = config_function_read,
00169 };
00170
00171 static int unload_module(void)
00172 {
00173 struct config_item *current;
00174 int res = ast_custom_function_unregister(&config_function);
00175
00176 AST_RWLIST_WRLOCK(&configs);
00177 while ((current = AST_RWLIST_REMOVE_HEAD(&configs, entry))) {
00178 ast_config_destroy(current->cfg);
00179 ast_free(current);
00180 }
00181 AST_RWLIST_UNLOCK(&configs);
00182
00183 return res;
00184 }
00185
00186 static int load_module(void)
00187 {
00188 return ast_custom_function_register(&config_function);
00189 }
00190
00191 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Asterisk configuration file variable access");