mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-28 10:13:43 +00:00
This is a combination new feature/bug fix for app_chanspy.
New feature: Add the 'e' option, which takes as an argument a list of interfaces separated by colons. This way, you will only be able to spy on this limited list of interfaces. Bug fix: change some pointer checks to ast_strlen_zero so that spying would work properly even if no channel was specified as the first argument to chanspy. (closes issue #10072) Reported by: xmarksthespot Patches: bugfix+newfeature10072patchtotrunkrev102726.diff uploaded by xmarksthespot (license 16) Tested by: xmarksthespot, mvanbaak git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@102933 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -88,6 +88,9 @@ static const char *desc_chan =
|
||||
" specified by the SPY_EXIT_CONTEXT channel variable. The\n"
|
||||
" name of the last channel that was spied on will be stored\n"
|
||||
" in the SPY_CHANNEL variable.\n"
|
||||
" e(ext) - Enable 'enforced' mode, so the spying channel can\n"
|
||||
" only monitor extensions whose name is in the 'ext' : \n"
|
||||
" delimited list.\n"
|
||||
;
|
||||
|
||||
static const char *app_ext = "ExtenSpy";
|
||||
@@ -137,12 +140,14 @@ enum {
|
||||
OPTION_PRIVATE = (1 << 6), /* Private Whisper mode */
|
||||
OPTION_READONLY = (1 << 7), /* Don't mix the two channels */
|
||||
OPTION_EXIT = (1 << 8), /* Exit to a valid single digit extension */
|
||||
OPTION_ENFORCED = (1 << 9), /* Enforced mode */
|
||||
} chanspy_opt_flags;
|
||||
|
||||
enum {
|
||||
OPT_ARG_VOLUME = 0,
|
||||
OPT_ARG_GROUP,
|
||||
OPT_ARG_RECORD,
|
||||
OPT_ARG_ENFORCED,
|
||||
OPT_ARG_ARRAY_SIZE,
|
||||
} chanspy_opt_args;
|
||||
|
||||
@@ -154,6 +159,7 @@ AST_APP_OPTIONS(spy_opts, {
|
||||
AST_APP_OPTION_ARG('v', OPTION_VOLUME, OPT_ARG_VOLUME),
|
||||
AST_APP_OPTION_ARG('g', OPTION_GROUP, OPT_ARG_GROUP),
|
||||
AST_APP_OPTION_ARG('r', OPTION_RECORD, OPT_ARG_RECORD),
|
||||
AST_APP_OPTION_ARG('e', OPTION_ENFORCED, OPT_ARG_ENFORCED),
|
||||
AST_APP_OPTION('o', OPTION_READONLY),
|
||||
AST_APP_OPTION('X', OPTION_EXIT),
|
||||
});
|
||||
@@ -378,11 +384,12 @@ static struct ast_channel *next_channel(const struct ast_channel *last, const ch
|
||||
const char *exten, const char *context)
|
||||
{
|
||||
struct ast_channel *this;
|
||||
|
||||
|
||||
redo:
|
||||
if (spec)
|
||||
if (!ast_strlen_zero(spec))
|
||||
this = ast_walk_channel_by_name_prefix_locked(last, spec, strlen(spec));
|
||||
else if (exten)
|
||||
|
||||
else if (!ast_strlen_zero(exten))
|
||||
this = ast_walk_channel_by_exten_locked(last, exten, context);
|
||||
else
|
||||
this = ast_channel_walk_locked(last);
|
||||
@@ -397,8 +404,8 @@ static struct ast_channel *next_channel(const struct ast_channel *last, const ch
|
||||
}
|
||||
|
||||
static int common_exec(struct ast_channel *chan, const struct ast_flags *flags,
|
||||
int volfactor, const int fd, const char *mygroup, const char *spec,
|
||||
const char *exten, const char *context)
|
||||
int volfactor, const int fd, const char *mygroup, const char *myenforced,
|
||||
const char *spec, const char *exten, const char *context)
|
||||
{
|
||||
struct ast_channel *peer, *prev, *next;
|
||||
char nameprefix[AST_NAME_STRLEN];
|
||||
@@ -478,7 +485,12 @@ static int common_exec(struct ast_channel *chan, const struct ast_flags *flags,
|
||||
char *dup_group;
|
||||
int x;
|
||||
char *s;
|
||||
|
||||
char *buffer;
|
||||
char *end;
|
||||
char *ext;
|
||||
char *form_enforced;
|
||||
int ienf = !myenforced;
|
||||
|
||||
if (peer == prev)
|
||||
break;
|
||||
|
||||
@@ -509,6 +521,37 @@ static int common_exec(struct ast_channel *chan, const struct ast_flags *flags,
|
||||
if (!igrp)
|
||||
continue;
|
||||
|
||||
if (myenforced) {
|
||||
|
||||
/* We don't need to allocate more space than just the
|
||||
length of (peer->name) for ext as we will cut the
|
||||
channel name's ending before copying into ext */
|
||||
|
||||
ext = alloca(strlen(peer->name));
|
||||
|
||||
form_enforced = alloca(strlen(myenforced) + 3);
|
||||
|
||||
strcpy(form_enforced, ":");
|
||||
strcat(form_enforced, myenforced);
|
||||
strcat(form_enforced, ":");
|
||||
|
||||
buffer = ast_strdupa(peer->name);
|
||||
|
||||
if ((end = strchr(buffer, '-'))) {
|
||||
*end++ = ':';
|
||||
*end = '\0';
|
||||
}
|
||||
|
||||
strcpy(ext, ":");
|
||||
strcat(ext, buffer);
|
||||
|
||||
if (strcasestr(form_enforced, ext))
|
||||
ienf = 1;
|
||||
}
|
||||
|
||||
if (!ienf)
|
||||
continue;
|
||||
|
||||
strcpy(peer_name, "spy-");
|
||||
strncat(peer_name, peer->name, AST_NAME_STRLEN);
|
||||
ptr = strchr(peer_name, '/');
|
||||
@@ -562,6 +605,7 @@ exit:
|
||||
|
||||
static int chanspy_exec(struct ast_channel *chan, void *data)
|
||||
{
|
||||
char *myenforced = NULL;
|
||||
char *mygroup = NULL;
|
||||
char *recbase = NULL;
|
||||
int fd = 0;
|
||||
@@ -601,6 +645,10 @@ static int chanspy_exec(struct ast_channel *chan, void *data)
|
||||
|
||||
if (ast_test_flag(&flags, OPTION_PRIVATE))
|
||||
ast_set_flag(&flags, OPTION_WHISPER);
|
||||
|
||||
if (ast_test_flag(&flags, OPTION_ENFORCED))
|
||||
myenforced = opts[OPT_ARG_ENFORCED];
|
||||
|
||||
} else
|
||||
ast_clear_flag(&flags, AST_FLAGS_ALL);
|
||||
|
||||
@@ -620,7 +668,7 @@ static int chanspy_exec(struct ast_channel *chan, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
res = common_exec(chan, &flags, volfactor, fd, mygroup, args.spec, NULL, NULL);
|
||||
res = common_exec(chan, &flags, volfactor, fd, mygroup, myenforced, args.spec, NULL, NULL);
|
||||
|
||||
if (fd)
|
||||
close(fd);
|
||||
@@ -699,7 +747,8 @@ static int extenspy_exec(struct ast_channel *chan, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
res = common_exec(chan, &flags, volfactor, fd, mygroup, NULL, exten, args.context);
|
||||
|
||||
res = common_exec(chan, &flags, volfactor, fd, mygroup, NULL, NULL, exten, args.context);
|
||||
|
||||
if (fd)
|
||||
close(fd);
|
||||
|
Reference in New Issue
Block a user