mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-01 03:04:19 +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"
|
" specified by the SPY_EXIT_CONTEXT channel variable. The\n"
|
||||||
" name of the last channel that was spied on will be stored\n"
|
" name of the last channel that was spied on will be stored\n"
|
||||||
" in the SPY_CHANNEL variable.\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";
|
static const char *app_ext = "ExtenSpy";
|
||||||
@@ -137,12 +140,14 @@ enum {
|
|||||||
OPTION_PRIVATE = (1 << 6), /* Private Whisper mode */
|
OPTION_PRIVATE = (1 << 6), /* Private Whisper mode */
|
||||||
OPTION_READONLY = (1 << 7), /* Don't mix the two channels */
|
OPTION_READONLY = (1 << 7), /* Don't mix the two channels */
|
||||||
OPTION_EXIT = (1 << 8), /* Exit to a valid single digit extension */
|
OPTION_EXIT = (1 << 8), /* Exit to a valid single digit extension */
|
||||||
|
OPTION_ENFORCED = (1 << 9), /* Enforced mode */
|
||||||
} chanspy_opt_flags;
|
} chanspy_opt_flags;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
OPT_ARG_VOLUME = 0,
|
OPT_ARG_VOLUME = 0,
|
||||||
OPT_ARG_GROUP,
|
OPT_ARG_GROUP,
|
||||||
OPT_ARG_RECORD,
|
OPT_ARG_RECORD,
|
||||||
|
OPT_ARG_ENFORCED,
|
||||||
OPT_ARG_ARRAY_SIZE,
|
OPT_ARG_ARRAY_SIZE,
|
||||||
} chanspy_opt_args;
|
} 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('v', OPTION_VOLUME, OPT_ARG_VOLUME),
|
||||||
AST_APP_OPTION_ARG('g', OPTION_GROUP, OPT_ARG_GROUP),
|
AST_APP_OPTION_ARG('g', OPTION_GROUP, OPT_ARG_GROUP),
|
||||||
AST_APP_OPTION_ARG('r', OPTION_RECORD, OPT_ARG_RECORD),
|
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('o', OPTION_READONLY),
|
||||||
AST_APP_OPTION('X', OPTION_EXIT),
|
AST_APP_OPTION('X', OPTION_EXIT),
|
||||||
});
|
});
|
||||||
@@ -380,9 +386,10 @@ static struct ast_channel *next_channel(const struct ast_channel *last, const ch
|
|||||||
struct ast_channel *this;
|
struct ast_channel *this;
|
||||||
|
|
||||||
redo:
|
redo:
|
||||||
if (spec)
|
if (!ast_strlen_zero(spec))
|
||||||
this = ast_walk_channel_by_name_prefix_locked(last, spec, strlen(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);
|
this = ast_walk_channel_by_exten_locked(last, exten, context);
|
||||||
else
|
else
|
||||||
this = ast_channel_walk_locked(last);
|
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,
|
static int common_exec(struct ast_channel *chan, const struct ast_flags *flags,
|
||||||
int volfactor, const int fd, const char *mygroup, const char *spec,
|
int volfactor, const int fd, const char *mygroup, const char *myenforced,
|
||||||
const char *exten, const char *context)
|
const char *spec, const char *exten, const char *context)
|
||||||
{
|
{
|
||||||
struct ast_channel *peer, *prev, *next;
|
struct ast_channel *peer, *prev, *next;
|
||||||
char nameprefix[AST_NAME_STRLEN];
|
char nameprefix[AST_NAME_STRLEN];
|
||||||
@@ -478,6 +485,11 @@ static int common_exec(struct ast_channel *chan, const struct ast_flags *flags,
|
|||||||
char *dup_group;
|
char *dup_group;
|
||||||
int x;
|
int x;
|
||||||
char *s;
|
char *s;
|
||||||
|
char *buffer;
|
||||||
|
char *end;
|
||||||
|
char *ext;
|
||||||
|
char *form_enforced;
|
||||||
|
int ienf = !myenforced;
|
||||||
|
|
||||||
if (peer == prev)
|
if (peer == prev)
|
||||||
break;
|
break;
|
||||||
@@ -509,6 +521,37 @@ static int common_exec(struct ast_channel *chan, const struct ast_flags *flags,
|
|||||||
if (!igrp)
|
if (!igrp)
|
||||||
continue;
|
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-");
|
strcpy(peer_name, "spy-");
|
||||||
strncat(peer_name, peer->name, AST_NAME_STRLEN);
|
strncat(peer_name, peer->name, AST_NAME_STRLEN);
|
||||||
ptr = strchr(peer_name, '/');
|
ptr = strchr(peer_name, '/');
|
||||||
@@ -562,6 +605,7 @@ exit:
|
|||||||
|
|
||||||
static int chanspy_exec(struct ast_channel *chan, void *data)
|
static int chanspy_exec(struct ast_channel *chan, void *data)
|
||||||
{
|
{
|
||||||
|
char *myenforced = NULL;
|
||||||
char *mygroup = NULL;
|
char *mygroup = NULL;
|
||||||
char *recbase = NULL;
|
char *recbase = NULL;
|
||||||
int fd = 0;
|
int fd = 0;
|
||||||
@@ -601,6 +645,10 @@ static int chanspy_exec(struct ast_channel *chan, void *data)
|
|||||||
|
|
||||||
if (ast_test_flag(&flags, OPTION_PRIVATE))
|
if (ast_test_flag(&flags, OPTION_PRIVATE))
|
||||||
ast_set_flag(&flags, OPTION_WHISPER);
|
ast_set_flag(&flags, OPTION_WHISPER);
|
||||||
|
|
||||||
|
if (ast_test_flag(&flags, OPTION_ENFORCED))
|
||||||
|
myenforced = opts[OPT_ARG_ENFORCED];
|
||||||
|
|
||||||
} else
|
} else
|
||||||
ast_clear_flag(&flags, AST_FLAGS_ALL);
|
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)
|
if (fd)
|
||||||
close(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)
|
if (fd)
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|||||||
Reference in New Issue
Block a user