Newer
Older
if (plus)
*plus++ = '\0';
if (!strcmp(pri,"hint"))
ipri=PRIORITY_HINT;
else if (!strcmp(pri, "next") || !strcmp(pri, "n")) {
if (lastpri > -2)
ipri = lastpri + 1;
else
ast_log(LOG_WARNING, "Can't use 'next' priority on the first entry!\n");
} else if (!strcmp(pri, "same") || !strcmp(pri, "s")) {
if (lastpri > -2)
ipri = lastpri;
else
ast_log(LOG_WARNING, "Can't use 'same' priority on the first entry!\n");
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
(ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) {
ast_log(LOG_WARNING, "Invalid priority/label '%s' at line %d\n", pri, v->lineno);
ipri = 0;
}
appl = S_OR(stringp, "");
/* Find the first occurrence of either '(' or ',' */
firstc = strchr(appl, ',');
firstp = strchr(appl, '(');
if (firstc && (!firstp || firstc < firstp)) {
/* comma found, no parenthesis */
/* or both found, but comma found first */
appl = strsep(&stringp, ",");
data = stringp;
} else if (!firstc && !firstp) {
/* Neither found */
data = "";
} else {
/* Final remaining case is parenthesis found first */
appl = strsep(&stringp, "(");
data = stringp;
end = strrchr(data, ')');
if ((end = strrchr(data, ')'))) {
*end = '\0';
} else {
ast_log(LOG_WARNING, "No closing parenthesis found? '%s(%s'\n", appl, data);
}
ast_process_quotes_and_slashes(data, ',', '|');
}
if (!data)
data="";
appl = ast_skip_blanks(appl);
if (ipri) {
if (plus)
ipri += atoi(plus);
lastpri = ipri;
if (!ast_opt_dont_warn && !strcmp(realext, "_."))
ast_log(LOG_WARNING, "The use of '_.' for an extension is strongly discouraged and can have unexpected behavior. Please use '_X.' instead at line %d\n", v->lineno);
if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), ast_free_ptr, global_registrar)) {
ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
}
}
free(tc);
}
} else if (!strcasecmp(v->name, "include")) {
memset(realvalue, 0, sizeof(realvalue));
pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
if (ast_context_add_include2(con, realvalue, global_registrar))
ast_log(LOG_WARNING, "Unable to include context '%s' in context '%s'\n", v->value, cxt);
} else if (!strcasecmp(v->name, "ignorepat")) {
memset(realvalue, 0, sizeof(realvalue));
pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
if (ast_context_add_ignorepat2(con, realvalue, global_registrar))
ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt);
} else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) {
char *stringp= realvalue;
char *appl, *data;
memset(realvalue, 0, sizeof(realvalue));
if (!strcasecmp(v->name, "switch"))
pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
else
ast_copy_string(realvalue, v->value, sizeof(realvalue));
appl = strsep(&stringp, "/");
data = strsep(&stringp, ""); /* XXX what for ? */
if (!data)
data = "";
if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), global_registrar))
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt);
} else {
ast_log(LOG_WARNING, "==!!== Unknown directive: %s at line %d -- IGNORING!!!\n", v->name, v->lineno);
}
}
}
ast_config_destroy(cfg);
return 1;
}
static void __ast_context_destroy(struct ast_context *con, const char *registrar)
{
struct ast_context *tmp, *tmpl=NULL;
struct ast_include *tmpi;
struct ast_sw *sw;
struct ast_exten *e, *el, *en;
struct ast_ignorepat *ipi;
for (tmp = contexts; tmp; ) {
struct ast_context *next; /* next starting point */
for (; tmp; tmpl = tmp, tmp = tmp->next) {
if (option_debug)
ast_log(LOG_DEBUG, "check ctx %s %s\n", tmp->name, tmp->registrar);
if ( (!registrar || !strcasecmp(registrar, tmp->registrar)) &&
(!con || !strcasecmp(tmp->name, con->name)) )
break; /* found it */
}
if (!tmp) /* not found, we are done */
break;
ast_wrlock_context(tmp);
if (option_debug)
ast_log(LOG_DEBUG, "delete ctx %s %s\n", tmp->name, tmp->registrar);
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
next = tmp->next;
if (tmpl)
tmpl->next = next;
else
contexts = next;
/* Okay, now we're safe to let it go -- in a sense, we were
ready to let it go as soon as we locked it. */
ast_unlock_context(tmp);
for (tmpi = tmp->includes; tmpi; ) { /* Free includes */
struct ast_include *tmpil = tmpi;
tmpi = tmpi->next;
free(tmpil);
}
for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */
struct ast_ignorepat *ipl = ipi;
ipi = ipi->next;
free(ipl);
}
while ((sw = AST_LIST_REMOVE_HEAD(&tmp->alts, list)))
free(sw);
for (e = tmp->root; e;) {
for (en = e->peer; en;) {
el = en;
en = en->peer;
destroy_exten(el);
}
el = e;
e = e->next;
destroy_exten(el);
}
ast_rwlock_destroy(&tmp->lock);
free(tmp);
/* if we have a specific match, we are done, otherwise continue */
tmp = con ? NULL : next;
}
}
void localized_context_destroy(struct ast_context *con, const char *registrar);
void localized_context_destroy(struct ast_context *con, const char *registrar)
{
ast_wrlock_contexts();
__ast_context_destroy(con,registrar);
ast_unlock_contexts();
}
static void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar)
{
struct ast_context *tmp, *lasttmp = NULL;
/* it is very important that this function hold the hint list lock _and_ the conlock
during its operation; not only do we need to ensure that the list of contexts
and extensions does not change, but also that no hint callbacks (watchers) are
added or removed during the merge/delete process
in addition, the locks _must_ be taken in this order, because there are already
other code paths that use this order
*/
ast_wrlock_contexts();
tmp = *extcontexts;
if (registrar) {
/* XXX remove previous contexts from same registrar */
if (option_debug)
ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar);
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
__ast_context_destroy(NULL,registrar);
while (tmp) {
lasttmp = tmp;
tmp = tmp->next;
}
} else {
/* XXX remove contexts with the same name */
while (tmp) {
ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar);
__ast_context_destroy(tmp,tmp->registrar);
lasttmp = tmp;
tmp = tmp->next;
}
}
if (lasttmp) {
lasttmp->next = contexts;
contexts = *extcontexts;
*extcontexts = NULL;
} else
ast_log(LOG_WARNING, "Requested contexts didn't get merged\n");
ast_unlock_contexts();
return;
}
void localized_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar);
void localized_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar)
{
ast_merge_contexts_and_delete(extcontexts, registrar);
}
static int ast_context_verify_includes(struct ast_context *con)
{
struct ast_include *inc = NULL;
int res = 0;
while ( (inc = ast_walk_context_includes(con, inc)) )
if (!ast_context_find(inc->rname)) {
res = -1;
if (strcasecmp(inc->rname,"parkedcalls")!=0)
ast_log(LOG_WARNING, "Context '%s' tries to include the nonexistent context '%s'\n",
ast_get_context_name(con), inc->rname);
}
return res;
}
int localized_context_verify_includes(struct ast_context *con);
int localized_context_verify_includes(struct ast_context *con)
{
return ast_context_verify_includes(con);
}
int localized_pbx_load_module(void);
int localized_pbx_load_module(void)
{
struct ast_context *con;
if(!pbx_load_config(config_filename))
return -1 /* AST_MODULE_LOAD_DECLINE*/;
/* pbx_load_users(); */ /* does this affect the dialplan? */
ast_merge_contexts_and_delete(&local_contexts, global_registrar);
for (con = NULL; (con = ast_walk_contexts(con));)
ast_context_verify_includes(con);
printf("=== Loading extensions.conf ===\n");
con = 0;
while ((con = ast_walk_contexts(con)) ) {
printf("Context: %s\n", con->name);
}
printf("=========\n");
return 0;
}