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: 153365 $")
00033
00034 #include "asterisk/module.h"
00035 #include "asterisk/channel.h"
00036 #include "asterisk/pbx.h"
00037 #include "asterisk/app.h"
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 struct config_item {
00057 AST_RWLIST_ENTRY(config_item) entry;
00058 struct ast_config *cfg;
00059 char filename[0];
00060 };
00061
00062 static AST_RWLIST_HEAD_STATIC(configs, config_item);
00063
00064 static int config_function_read(struct ast_channel *chan, const char *cmd, char *data,
00065 char *buf, size_t len)
00066 {
00067 struct ast_config *cfg;
00068 struct ast_flags cfg_flags = { CONFIG_FLAG_FILEUNCHANGED };
00069 const char *val;
00070 char *parse;
00071 struct config_item *cur;
00072 AST_DECLARE_APP_ARGS(args,
00073 AST_APP_ARG(filename);
00074 AST_APP_ARG(category);
00075 AST_APP_ARG(variable);
00076 AST_APP_ARG(index);
00077 );
00078
00079 if (ast_strlen_zero(data)) {
00080 ast_log(LOG_ERROR, "AST_CONFIG() requires an argument\n");
00081 return -1;
00082 }
00083
00084 parse = ast_strdupa(data);
00085 AST_STANDARD_APP_ARGS(args, parse);
00086
00087 if (ast_strlen_zero(args.filename)) {
00088 ast_log(LOG_ERROR, "AST_CONFIG() requires a filename\n");
00089 return -1;
00090 }
00091
00092 if (ast_strlen_zero(args.category)) {
00093 ast_log(LOG_ERROR, "AST_CONFIG() requires a category\n");
00094 return -1;
00095 }
00096
00097 if (ast_strlen_zero(args.variable)) {
00098 ast_log(LOG_ERROR, "AST_CONFIG() requires a variable\n");
00099 return -1;
00100 }
00101
00102 if (!(cfg = ast_config_load(args.filename, cfg_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
00103 return -1;
00104 }
00105
00106 if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
00107
00108 AST_RWLIST_RDLOCK(&configs);
00109 AST_RWLIST_TRAVERSE(&configs, cur, entry) {
00110 if (!strcmp(cur->filename, args.filename)) {
00111 break;
00112 }
00113 }
00114
00115 if (!cur) {
00116
00117 AST_RWLIST_UNLOCK(&configs);
00118 AST_RWLIST_WRLOCK(&configs);
00119 if (!(cur = ast_malloc(sizeof(*cur) + strlen(args.filename) + 1))) {
00120 AST_RWLIST_UNLOCK(&configs);
00121 return -1;
00122 }
00123
00124 strcpy(cur->filename, args.filename);
00125
00126 ast_clear_flag(&cfg_flags, CONFIG_FLAG_FILEUNCHANGED);
00127 if (!(cfg = ast_config_load(args.filename, cfg_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
00128 ast_free(cur);
00129 AST_RWLIST_UNLOCK(&configs);
00130 return -1;
00131 }
00132
00133 cur->cfg = cfg;
00134 AST_RWLIST_INSERT_TAIL(&configs, cur, entry);
00135 }
00136
00137 cfg = cur->cfg;
00138 } else {
00139
00140 AST_RWLIST_WRLOCK(&configs);
00141 AST_RWLIST_TRAVERSE(&configs, cur, entry) {
00142 if (!strcmp(cur->filename, args.filename)) {
00143 break;
00144 }
00145 }
00146
00147 if (!cur) {
00148 if (!(cur = ast_malloc(sizeof(*cur) + strlen(args.filename) + 1))) {
00149 AST_RWLIST_UNLOCK(&configs);
00150 return -1;
00151 }
00152
00153 strcpy(cur->filename, args.filename);
00154 cur->cfg = cfg;
00155
00156 AST_RWLIST_INSERT_TAIL(&configs, cur, entry);
00157 } else {
00158 ast_config_destroy(cur->cfg);
00159 cur->cfg = cfg;
00160 }
00161 }
00162
00163 if (!(val = ast_variable_retrieve(cfg, args.category, args.variable))) {
00164 ast_log(LOG_ERROR, "'%s' not found in [%s] of '%s'\n", args.variable,
00165 args.category, args.filename);
00166 AST_RWLIST_UNLOCK(&configs);
00167 return -1;
00168 }
00169
00170 ast_copy_string(buf, val, len);
00171
00172
00173 AST_RWLIST_UNLOCK(&configs);
00174
00175 return 0;
00176 }
00177
00178 static struct ast_custom_function config_function = {
00179 .name = "AST_CONFIG",
00180 .read = config_function_read,
00181 };
00182
00183 static int unload_module(void)
00184 {
00185 struct config_item *current;
00186 int res = ast_custom_function_unregister(&config_function);
00187
00188 AST_RWLIST_WRLOCK(&configs);
00189 while ((current = AST_RWLIST_REMOVE_HEAD(&configs, entry))) {
00190 ast_config_destroy(current->cfg);
00191 ast_free(current);
00192 }
00193 AST_RWLIST_UNLOCK(&configs);
00194
00195 return res;
00196 }
00197
00198 static int load_module(void)
00199 {
00200 return ast_custom_function_register(&config_function);
00201 }
00202
00203 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Asterisk configuration file variable access");