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