d77fa4bbc81d9b6276008e1c5f103428a6511e30
[asterisk/asterisk.git] / apps / app_chanspy.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2005 Anthony Minessale II (anthmct@yahoo.com)
5  * Copyright (C) 2005 - 2008, Digium, Inc.
6  *
7  * A license has been granted to Digium (via disclaimer) for the use of
8  * this code.
9  *
10  * See http://www.asterisk.org for more information about
11  * the Asterisk project. Please do not directly contact
12  * any of the maintainers of this project for assistance;
13  * the project provides a web site, mailing lists and IRC
14  * channels for your use.
15  *
16  * This program is free software, distributed under the terms of
17  * the GNU General Public License Version 2. See the LICENSE file
18  * at the top of the source tree.
19  */
20
21 /*! \file
22  *
23  * \brief ChanSpy: Listen in on any channel.
24  *
25  * \author Anthony Minessale II <anthmct@yahoo.com>
26  * \author Joshua Colp <jcolp@digium.com>
27  * \author Russell Bryant <russell@digium.com>
28  *
29  * \ingroup applications
30  */
31
32 #include "asterisk.h"
33
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35
36 #include <ctype.h>
37
38 #include "asterisk/paths.h" /* use ast_config_AST_MONITOR_DIR */
39 #include "asterisk/file.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/audiohook.h"
42 #include "asterisk/features.h"
43 #include "asterisk/app.h"
44 #include "asterisk/utils.h"
45 #include "asterisk/say.h"
46 #include "asterisk/pbx.h"
47 #include "asterisk/translate.h"
48 #include "asterisk/module.h"
49 #include "asterisk/lock.h"
50
51 #define AST_NAME_STRLEN 256
52 #define NUM_SPYGROUPS 128
53
54 static const char *tdesc = "Listen to a channel, and optionally whisper into it";
55 static const char *app_chan = "ChanSpy";
56 static const char *desc_chan =
57 "  ChanSpy([chanprefix][,options]): This application is used to listen to the\n"
58 "audio from an Asterisk channel. This includes the audio coming in and\n"
59 "out of the channel being spied on. If the 'chanprefix' parameter is specified,\n"
60 "only channels beginning with this string will be spied upon.\n"
61 "  While spying, the following actions may be performed:\n"
62 "    - Dialing # cycles the volume level.\n"
63 "    - Dialing * will stop spying and look for another channel to spy on.\n"
64 "    - Dialing a series of digits followed by # builds a channel name to append\n"
65 "      to 'chanprefix'. For example, executing ChanSpy(Agent) and then dialing\n"
66 "      the digits '1234#' while spying will begin spying on the channel\n"
67 "      'Agent/1234'.\n"
68 "  Note: The X option supersedes the three features above in that if a valid\n"
69 "        single digit extension exists in the correct context ChanSpy will\n"
70 "        exit to it. This also disables choosing a channel based on 'chanprefix'\n"
71 "        and a digit sequence.\n"
72 "  Options:\n"
73 "    b                      - Only spy on channels involved in a bridged call.\n"
74 "    g(grp)                 - Only spy on channels in which one or more of the groups \n"
75 "                             listed in 'grp' matches one or more groups from the\n"
76 "                             SPYGROUP variable set on the channel to be spied upon.\n"
77 "                             Note that both 'grp' and SPYGROUP can contain either a\n"
78 "                             single group or a colon-delimited list of groups, such\n"
79 "                             as 'sales:support:accounting'.\n"
80 "    n([mailbox][@context]) - Say the name of the person being spied on if that person has recorded\n"
81 "                             his/her name. If a context is specified, then that voicemail context will\n"
82 "                             be searched when retrieving the name, otherwise the \"default\" context\n"
83 "                             will be searched. If no mailbox is specified, then the channel name will\n"
84 "                             be used when searching for the name (i.e. if SIP/1000 is the channel being\n"
85 "                             spied on and no mailbox is specified, then \"1000\" will be used when searching\n"
86 "                             for the name).\n"
87 "    q                      - Don't play a beep when beginning to spy on a channel, or speak the\n"
88 "                             selected channel name.\n"
89 "    r[(basename)]          - Record the session to the monitor spool directory. An\n"
90 "                             optional base for the filename may be specified. The\n"
91 "                             default is 'chanspy'.\n"
92 "    s                      - Skip the playback of the channel type (i.e. SIP, IAX, etc) when\n"
93 "                             speaking the selected channel name.\n"
94 "    v([value])             - Adjust the initial volume in the range from -4 to 4. A\n"
95 "                             negative value refers to a quieter setting.\n"
96 "    w                      - Enable 'whisper' mode, so the spying channel can talk to\n"
97 "                             the spied-on channel.\n"
98 "    W                      - Enable 'private whisper' mode, so the spying channel can\n"
99 "                             talk to the spied-on channel but cannot listen to that\n"
100 "                             channel.\n"
101 "    o                      - Only listen to audio coming from this channel.\n"
102 "    X                      - Allow the user to exit ChanSpy to a valid single digit\n"
103 "                             numeric extension in the current context or the context\n"
104 "                             specified by the SPY_EXIT_CONTEXT channel variable. The\n"
105 "                             name of the last channel that was spied on will be stored\n"
106 "                             in the SPY_CHANNEL variable.\n"
107 "    e(ext)                 - Enable 'enforced' mode, so the spying channel can\n"
108 "                             only monitor extensions whose name is in the 'ext' : \n"
109 "                             delimited list.\n"
110 ;
111
112 static const char *app_ext = "ExtenSpy";
113 static const char *desc_ext =
114 "  ExtenSpy(exten[@context][,options]): This application is used to listen to the\n"
115 "audio from an Asterisk channel. This includes the audio coming in and\n"
116 "out of the channel being spied on. Only channels created by outgoing calls for the\n"
117 "specified extension will be selected for spying. If the optional context is not\n"
118 "supplied, the current channel's context will be used.\n"
119 "  While spying, the following actions may be performed:\n"
120 "    - Dialing # cycles the volume level.\n"
121 "    - Dialing * will stop spying and look for another channel to spy on.\n"
122 "  Note: The X option superseeds the two features above in that if a valid\n"
123 "        single digit extension exists in the correct context it ChanSpy will\n"
124 "        exit to it.\n"
125 "  Options:\n"
126 "    b                      - Only spy on channels involved in a bridged call.\n"
127 "    g(grp)                 - Only spy on channels in which one or more of the groups \n"
128 "                             listed in 'grp' matches one or more groups from the\n"
129 "                             SPYGROUP variable set on the channel to be spied upon.\n"
130 "                             Note that both 'grp' and SPYGROUP can contain either a\n"
131 "                             single group or a colon-delimited list of groups, such\n"
132 "                             as 'sales:support:accounting'.\n"
133 "    n([mailbox][@context]) - Say the name of the person being spied on if that person has recorded\n"
134 "                             his/her name. If a context is specified, then that voicemail context will\n"
135 "                             be searched when retrieving the name, otherwise the \"default\" context\n"
136 "                             will be searched. If no mailbox is specified, then the channel name will\n"
137 "                             be used when searching for the name (i.e. if SIP/1000 is the channel being\n"
138 "                             spied on and no mailbox is specified, then \"1000\" will be used when searching\n"
139 "                             for the name).\n"
140 "    q                      - Don't play a beep when beginning to spy on a channel, or speak the\n"
141 "                             selected channel name.\n"
142 "    r[(basename)]          - Record the session to the monitor spool directory. An\n"
143 "                             optional base for the filename may be specified. The\n"
144 "                             default is 'chanspy'.\n"
145 "    s                      - Skip the playback of the channel type (i.e. SIP, IAX, etc) when\n"
146 "                             speaking the selected channel name.\n"
147 "    v([value])             - Adjust the initial volume in the range from -4 to 4. A\n"
148 "                             negative value refers to a quieter setting.\n"
149 "    w                      - Enable 'whisper' mode, so the spying channel can talk to\n"
150 "                             the spied-on channel.\n"
151 "    W                      - Enable 'private whisper' mode, so the spying channel can\n"
152 "                             talk to the spied-on channel but cannot listen to that\n"
153 "                             channel.\n"
154 "    o                      - Only listen to audio coming from this channel.\n"
155 "    X                      - Allow the user to exit ChanSpy to a valid single digit\n"
156 "                             numeric extension in the current context or the context\n"
157 "                             specified by the SPY_EXIT_CONTEXT channel variable. The\n"
158 "                             name of the last channel that was spied on will be stored\n"
159 "                             in the SPY_CHANNEL variable.\n"
160 ;
161
162 enum {
163         OPTION_QUIET     = (1 << 0),    /* Quiet, no announcement */
164         OPTION_BRIDGED   = (1 << 1),    /* Only look at bridged calls */
165         OPTION_VOLUME    = (1 << 2),    /* Specify initial volume */
166         OPTION_GROUP     = (1 << 3),    /* Only look at channels in group */
167         OPTION_RECORD    = (1 << 4),
168         OPTION_WHISPER   = (1 << 5),
169         OPTION_PRIVATE   = (1 << 6),    /* Private Whisper mode */
170         OPTION_READONLY  = (1 << 7),    /* Don't mix the two channels */
171         OPTION_EXIT      = (1 << 8),    /* Exit to a valid single digit extension */
172         OPTION_ENFORCED  = (1 << 9),    /* Enforced mode */
173         OPTION_NOTECH    = (1 << 10),   /* Skip technology name playback */
174         OPTION_BARGE     = (1 << 11),   /* Barge mode (whisper to both channels) */
175         OPTION_NAME      = (1 << 12),   /* Say the name of the person on whom we will spy */
176 } chanspy_opt_flags;
177
178 enum {
179         OPT_ARG_VOLUME = 0,
180         OPT_ARG_GROUP,
181         OPT_ARG_RECORD,
182         OPT_ARG_ENFORCED,
183         OPT_ARG_NAME,
184         OPT_ARG_ARRAY_SIZE,
185 } chanspy_opt_args;
186
187 AST_APP_OPTIONS(spy_opts, {
188         AST_APP_OPTION('q', OPTION_QUIET),
189         AST_APP_OPTION('b', OPTION_BRIDGED),
190         AST_APP_OPTION('B', OPTION_BARGE),
191         AST_APP_OPTION('w', OPTION_WHISPER),
192         AST_APP_OPTION('W', OPTION_PRIVATE),
193         AST_APP_OPTION_ARG('v', OPTION_VOLUME, OPT_ARG_VOLUME),
194         AST_APP_OPTION_ARG('g', OPTION_GROUP, OPT_ARG_GROUP),
195         AST_APP_OPTION_ARG('r', OPTION_RECORD, OPT_ARG_RECORD),
196         AST_APP_OPTION_ARG('e', OPTION_ENFORCED, OPT_ARG_ENFORCED),
197         AST_APP_OPTION('o', OPTION_READONLY),
198         AST_APP_OPTION('X', OPTION_EXIT),
199         AST_APP_OPTION('s', OPTION_NOTECH),
200         AST_APP_OPTION_ARG('n', OPTION_NAME, OPT_ARG_NAME),
201 });
202
203
204 struct chanspy_translation_helper {
205         /* spy data */
206         struct ast_audiohook spy_audiohook;
207         struct ast_audiohook whisper_audiohook;
208         struct ast_audiohook bridge_whisper_audiohook;
209         int fd;
210         int volfactor;
211 };
212
213 static void *spy_alloc(struct ast_channel *chan, void *data)
214 {
215         /* just store the data pointer in the channel structure */
216         return data;
217 }
218
219 static void spy_release(struct ast_channel *chan, void *data)
220 {
221         /* nothing to do */
222 }
223
224 static int spy_generate(struct ast_channel *chan, void *data, int len, int samples)
225 {
226         struct chanspy_translation_helper *csth = data;
227         struct ast_frame *f = NULL;
228
229         ast_audiohook_lock(&csth->spy_audiohook);
230         if (csth->spy_audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) {
231                 /* Channel is already gone more than likely */
232                 ast_audiohook_unlock(&csth->spy_audiohook);
233                 return -1;
234         }
235
236         f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR);
237
238         ast_audiohook_unlock(&csth->spy_audiohook);
239
240         if (!f)
241                 return 0;
242
243         if (ast_write(chan, f)) {
244                 ast_frfree(f);
245                 return -1;
246         }
247
248         if (csth->fd)
249                 write(csth->fd, f->data, f->datalen);
250
251         ast_frfree(f);
252
253         return 0;
254 }
255
256 static struct ast_generator spygen = {
257         .alloc = spy_alloc,
258         .release = spy_release,
259         .generate = spy_generate,
260 };
261
262 static int start_spying(struct ast_channel *chan, const char *spychan_name, struct ast_audiohook *audiohook)
263 {
264         int res = 0;
265         struct ast_channel *peer = NULL;
266
267         ast_log(LOG_NOTICE, "Attaching %s to %s\n", spychan_name, chan->name);
268
269         res = ast_audiohook_attach(chan, audiohook);
270
271         if (!res && ast_test_flag(chan, AST_FLAG_NBRIDGE) && (peer = ast_bridged_channel(chan))) { 
272                 ast_softhangup(peer, AST_SOFTHANGUP_UNBRIDGE);
273         }
274         return res;
275 }
276
277 struct chanspy_ds {
278         struct ast_channel *chan;
279         ast_mutex_t lock;
280 };
281
282 static int channel_spy(struct ast_channel *chan, struct chanspy_ds *spyee_chanspy_ds, 
283         int *volfactor, int fd, const struct ast_flags *flags, char *exitcontext) 
284 {
285         struct chanspy_translation_helper csth;
286         int running = 0, res, x = 0;
287         char inp[24] = {0};
288         char *name;
289         struct ast_frame *f;
290         struct ast_silence_generator *silgen = NULL;
291         struct ast_channel *spyee = NULL;
292         const char *spyer_name;
293
294         ast_channel_lock(chan);
295         spyer_name = ast_strdupa(chan->name);
296         ast_channel_unlock(chan);
297
298         ast_mutex_lock(&spyee_chanspy_ds->lock);
299         if (spyee_chanspy_ds->chan) {
300                 spyee = spyee_chanspy_ds->chan;
301                 ast_channel_lock(spyee);
302         }
303         ast_mutex_unlock(&spyee_chanspy_ds->lock);
304
305         if (!spyee)
306                 return 0;
307
308         /* We now hold the channel lock on spyee */
309
310         if (ast_check_hangup(chan) || ast_check_hangup(spyee)) {
311                 ast_channel_unlock(spyee);
312                 return 0;
313         }
314
315         name = ast_strdupa(spyee->name);
316         ast_verb(2, "Spying on channel %s\n", name);
317
318         memset(&csth, 0, sizeof(csth));
319
320         ast_audiohook_init(&csth.spy_audiohook, AST_AUDIOHOOK_TYPE_SPY, "ChanSpy");
321
322         if (start_spying(spyee, spyer_name, &csth.spy_audiohook)) {
323                 ast_audiohook_destroy(&csth.spy_audiohook);
324                 ast_channel_unlock(spyee);
325                 return 0;
326         }
327
328         if (ast_test_flag(flags, OPTION_BARGE)) {
329                 ast_audiohook_init(&csth.whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "ChanSpy");
330                 ast_audiohook_init(&csth.bridge_whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "Chanspy");
331                 start_spying(spyee, spyer_name, &csth.whisper_audiohook); /* Unlocks spyee */
332                 start_spying(ast_bridged_channel(spyee), spyer_name, &csth.bridge_whisper_audiohook);
333         } else if (ast_test_flag(flags, OPTION_WHISPER)) {
334                 ast_audiohook_init(&csth.whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "ChanSpy");
335                 start_spying(spyee, spyer_name, &csth.whisper_audiohook); /* Unlocks spyee */
336         }
337
338         ast_channel_unlock(spyee);
339         spyee = NULL;
340
341         csth.volfactor = *volfactor;
342
343         if (csth.volfactor) {
344                 csth.spy_audiohook.options.read_volume = csth.volfactor;
345                 csth.spy_audiohook.options.write_volume = csth.volfactor;
346         }
347
348         csth.fd = fd;
349
350         if (ast_test_flag(flags, OPTION_PRIVATE))
351                 silgen = ast_channel_start_silence_generator(chan);
352         else
353                 ast_activate_generator(chan, &spygen, &csth);
354
355         /* We can no longer rely on 'spyee' being an actual channel;
356            it can be hung up and freed out from under us. However, the
357            channel destructor will put NULL into our csth.spy.chan
358            field when that happens, so that is our signal that the spyee
359            channel has gone away.
360         */
361
362         /* Note: it is very important that the ast_waitfor() be the first
363            condition in this expression, so that if we wait for some period
364            of time before receiving a frame from our spying channel, we check
365            for hangup on the spied-on channel _after_ knowing that a frame
366            has arrived, since the spied-on channel could have gone away while
367            we were waiting
368         */
369         while ((res = ast_waitfor(chan, -1) > -1) && csth.spy_audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING) {
370                 if (!(f = ast_read(chan)) || ast_check_hangup(chan)) {
371                         running = -1;
372                         break;
373                 }
374
375                 if (ast_test_flag(flags, OPTION_BARGE) && f->frametype == AST_FRAME_VOICE) {
376                         ast_audiohook_lock(&csth.whisper_audiohook);
377                         ast_audiohook_lock(&csth.bridge_whisper_audiohook);
378                         ast_audiohook_write_frame(&csth.whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f);
379                         ast_audiohook_write_frame(&csth.bridge_whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f);
380                         ast_audiohook_unlock(&csth.whisper_audiohook);
381                         ast_audiohook_unlock(&csth.bridge_whisper_audiohook);
382                         ast_frfree(f);
383                         continue;
384                 } else if (ast_test_flag(flags, OPTION_WHISPER) && f->frametype == AST_FRAME_VOICE) {
385                         ast_audiohook_lock(&csth.whisper_audiohook);
386                         ast_audiohook_write_frame(&csth.whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f);
387                         ast_audiohook_unlock(&csth.whisper_audiohook);
388                         ast_frfree(f);
389                         continue;
390                 }
391                 
392                 res = (f->frametype == AST_FRAME_DTMF) ? f->subclass : 0;
393                 ast_frfree(f);
394                 if (!res)
395                         continue;
396
397                 if (x == sizeof(inp))
398                         x = 0;
399
400                 if (res < 0) {
401                         running = -1;
402                         break;
403                 }
404
405                 if (ast_test_flag(flags, OPTION_EXIT)) {
406                         char tmp[2];
407                         tmp[0] = res;
408                         tmp[1] = '\0';
409                         if (!ast_goto_if_exists(chan, exitcontext, tmp, 1)) {
410                                 ast_debug(1, "Got DTMF %c, goto context %s\n", tmp[0], exitcontext);
411                                 pbx_builtin_setvar_helper(chan, "SPY_CHANNEL", name);
412                                 running = -2;
413                                 break;
414                         } else {
415                                 ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
416                         }
417                 } else if (res >= '0' && res <= '9') {
418                         inp[x++] = res;
419                 }
420
421                 if (res == '*') {
422                         running = 0;
423                         break;
424                 } else if (res == '#') {
425                         if (!ast_strlen_zero(inp)) {
426                                 running = atoi(inp);
427                                 break;
428                         }
429
430                         (*volfactor)++;
431                         if (*volfactor > 4)
432                                 *volfactor = -4;
433                         ast_verb(3, "Setting spy volume on %s to %d\n", chan->name, *volfactor);
434
435                         csth.volfactor = *volfactor;
436                         csth.spy_audiohook.options.read_volume = csth.volfactor;
437                         csth.spy_audiohook.options.write_volume = csth.volfactor;
438                 }
439         }
440
441         if (ast_test_flag(flags, OPTION_PRIVATE))
442                 ast_channel_stop_silence_generator(chan, silgen);
443         else
444                 ast_deactivate_generator(chan);
445
446         if (ast_test_flag(flags, OPTION_BARGE)) {
447                 ast_audiohook_lock(&csth.whisper_audiohook);
448                 ast_audiohook_detach(&csth.whisper_audiohook);
449                 ast_audiohook_unlock(&csth.whisper_audiohook);
450                 ast_audiohook_destroy(&csth.whisper_audiohook);
451                 ast_audiohook_lock(&csth.bridge_whisper_audiohook);
452                 ast_audiohook_detach(&csth.bridge_whisper_audiohook);
453                 ast_audiohook_unlock(&csth.bridge_whisper_audiohook);
454                 ast_audiohook_destroy(&csth.bridge_whisper_audiohook);
455         } else if (ast_test_flag(flags, OPTION_WHISPER)) {
456                 ast_audiohook_lock(&csth.whisper_audiohook);
457                 ast_audiohook_detach(&csth.whisper_audiohook);
458                 ast_audiohook_unlock(&csth.whisper_audiohook);
459                 ast_audiohook_destroy(&csth.whisper_audiohook);
460         }
461
462         ast_audiohook_lock(&csth.spy_audiohook);
463         ast_audiohook_detach(&csth.spy_audiohook);
464         ast_audiohook_unlock(&csth.spy_audiohook);
465         ast_audiohook_destroy(&csth.spy_audiohook);
466         
467         ast_verb(2, "Done Spying on channel %s\n", name);
468
469         return running;
470 }
471
472 /*!
473  * \note This relies on the embedded lock to be recursive, as it may be called
474  * due to a call to chanspy_ds_free with the lock held there.
475  */
476 static void chanspy_ds_destroy(void *data)
477 {
478         struct chanspy_ds *chanspy_ds = data;
479
480         /* Setting chan to be NULL is an atomic operation, but we don't want this
481          * value to change while this lock is held.  The lock is held elsewhere
482          * while it performs non-atomic operations with this channel pointer */
483
484         ast_mutex_lock(&chanspy_ds->lock);
485         chanspy_ds->chan = NULL;
486         ast_mutex_unlock(&chanspy_ds->lock);
487 }
488
489 static void chanspy_ds_chan_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
490 {
491         struct chanspy_ds *chanspy_ds = data;
492         
493         ast_mutex_lock(&chanspy_ds->lock);
494         chanspy_ds->chan = new_chan;
495         ast_mutex_unlock(&chanspy_ds->lock);
496 }
497
498 static const struct ast_datastore_info chanspy_ds_info = {
499         .type = "chanspy",
500         .destroy = chanspy_ds_destroy,
501         .chan_fixup = chanspy_ds_chan_fixup,
502 };
503
504 static struct chanspy_ds *chanspy_ds_free(struct chanspy_ds *chanspy_ds)
505 {
506         if (!chanspy_ds)
507                 return NULL;
508
509         ast_mutex_lock(&chanspy_ds->lock);
510         if (chanspy_ds->chan) {
511                 struct ast_datastore *datastore;
512                 struct ast_channel *chan;
513
514                 chan = chanspy_ds->chan;
515
516                 ast_channel_lock(chan);
517                 if ((datastore = ast_channel_datastore_find(chan, &chanspy_ds_info, NULL))) {
518                         ast_channel_datastore_remove(chan, datastore);
519                         /* chanspy_ds->chan is NULL after this call */
520                         chanspy_ds_destroy(datastore->data);
521                         datastore->data = NULL;
522                         ast_channel_datastore_free(datastore);
523                 }
524                 ast_channel_unlock(chan);
525         }
526         ast_mutex_unlock(&chanspy_ds->lock);
527
528         return NULL;
529 }
530
531 /*! \note Returns the channel in the chanspy_ds locked as well as the chanspy_ds locked */
532 static struct chanspy_ds *setup_chanspy_ds(struct ast_channel *chan, struct chanspy_ds *chanspy_ds)
533 {
534         struct ast_datastore *datastore = NULL;
535
536         ast_mutex_lock(&chanspy_ds->lock);
537
538         if (!(datastore = ast_channel_datastore_alloc(&chanspy_ds_info, NULL))) {
539                 ast_mutex_unlock(&chanspy_ds->lock);
540                 chanspy_ds = chanspy_ds_free(chanspy_ds);
541                 ast_channel_unlock(chan);
542                 return NULL;
543         }
544         
545         chanspy_ds->chan = chan;
546         datastore->data = chanspy_ds;
547         ast_channel_datastore_add(chan, datastore);
548
549         return chanspy_ds;
550 }
551
552 static struct chanspy_ds *next_channel(struct ast_channel *chan,
553         const struct ast_channel *last, const char *spec,
554         const char *exten, const char *context, struct chanspy_ds *chanspy_ds)
555 {
556         struct ast_channel *next;
557
558 redo:
559         if (!ast_strlen_zero(spec))
560                 next = ast_walk_channel_by_name_prefix_locked(last, spec, strlen(spec));
561         else if (!ast_strlen_zero(exten))
562                 next = ast_walk_channel_by_exten_locked(last, exten, context);
563         else
564                 next = ast_channel_walk_locked(last);
565
566         if (!next)
567                 return NULL;
568
569         if (!strncmp(next->name, "Zap/pseudo", 10)) {
570                 ast_channel_unlock(next);
571                 goto redo;
572         } else if (next == chan) {
573                 last = next;
574                 ast_channel_unlock(next);
575                 goto redo;
576         }
577
578         return setup_chanspy_ds(next, chanspy_ds);
579 }
580
581 static int common_exec(struct ast_channel *chan, const struct ast_flags *flags,
582         int volfactor, const int fd, const char *mygroup, const char *myenforced,
583         const char *spec, const char *exten, const char *context, const char *mailbox,
584         const char *name_context)
585 {
586         char nameprefix[AST_NAME_STRLEN];
587         char peer_name[AST_NAME_STRLEN + 5];
588         char exitcontext[AST_MAX_CONTEXT] = "";
589         signed char zero_volume = 0;
590         int waitms;
591         int res;
592         char *ptr;
593         int num;
594         int num_spyed_upon = 1;
595         struct chanspy_ds chanspy_ds;
596
597         if (ast_test_flag(flags, OPTION_EXIT)) {
598                 const char *c;
599                 if ((c = pbx_builtin_getvar_helper(chan, "SPY_EXIT_CONTEXT")))
600                         ast_copy_string(exitcontext, c, sizeof(exitcontext));
601                 else if (!ast_strlen_zero(chan->macrocontext))
602                         ast_copy_string(exitcontext, chan->macrocontext, sizeof(exitcontext));
603                 else
604                         ast_copy_string(exitcontext, chan->context, sizeof(exitcontext));
605         }
606
607         ast_mutex_init(&chanspy_ds.lock);
608
609         if (chan->_state != AST_STATE_UP)
610                 ast_answer(chan);
611
612         ast_set_flag(chan, AST_FLAG_SPYING); /* so nobody can spy on us while we are spying */
613
614         waitms = 100;
615
616         for (;;) {
617                 struct chanspy_ds *peer_chanspy_ds = NULL, *next_chanspy_ds = NULL;
618                 struct ast_channel *prev = NULL, *peer = NULL;
619
620                 if (!ast_test_flag(flags, OPTION_QUIET) && num_spyed_upon) {
621                         res = ast_streamfile(chan, "beep", chan->language);
622                         if (!res)
623                                 res = ast_waitstream(chan, "");
624                         else if (res < 0) {
625                                 ast_clear_flag(chan, AST_FLAG_SPYING);
626                                 break;
627                         }
628                         if (!ast_strlen_zero(exitcontext)) {
629                                 char tmp[2];
630                                 tmp[0] = res;
631                                 tmp[1] = '\0';
632                                 if (!ast_goto_if_exists(chan, exitcontext, tmp, 1))
633                                         goto exit;
634                                 else
635                                         ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
636                         }
637                 }
638
639                 res = ast_waitfordigit(chan, waitms);
640                 if (res < 0) {
641                         ast_clear_flag(chan, AST_FLAG_SPYING);
642                         break;
643                 }
644                 if (!ast_strlen_zero(exitcontext)) {
645                         char tmp[2];
646                         tmp[0] = res;
647                         tmp[1] = '\0';
648                         if (!ast_goto_if_exists(chan, exitcontext, tmp, 1))
649                                 goto exit;
650                         else
651                                 ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
652                 }
653
654                 /* reset for the next loop around, unless overridden later */
655                 waitms = 100;
656                 num_spyed_upon = 0;
657
658                 for (peer_chanspy_ds = next_channel(chan, prev, spec, exten, context, &chanspy_ds);
659                      peer_chanspy_ds;
660                          chanspy_ds_free(peer_chanspy_ds), prev = peer,
661                      peer_chanspy_ds = next_chanspy_ds ? next_chanspy_ds : 
662                                 next_channel(chan, prev, spec, exten, context, &chanspy_ds), next_chanspy_ds = NULL) {
663                         const char *group;
664                         int igrp = !mygroup;
665                         char *groups[NUM_SPYGROUPS];
666                         char *mygroups[NUM_SPYGROUPS];
667                         int num_groups = 0;
668                         char *dup_group;
669                         int num_mygroups = 0;
670                         char *dup_mygroup;
671                         int x;
672                         int y;
673                         char *s;
674                         char *buffer;
675                         char *end;
676                         char *ext;
677                         char *form_enforced;
678                         int ienf = !myenforced;
679
680                         peer = peer_chanspy_ds->chan;
681
682                         ast_mutex_unlock(&peer_chanspy_ds->lock);
683
684                         if (peer == prev) {
685                                 ast_channel_unlock(peer);
686                                 chanspy_ds_free(peer_chanspy_ds);
687                                 break;
688                         }
689
690                         if (ast_check_hangup(chan)) {
691                                 ast_channel_unlock(peer);
692                                 chanspy_ds_free(peer_chanspy_ds);
693                                 break;
694                         }
695
696                         if (ast_test_flag(flags, OPTION_BRIDGED) && !ast_bridged_channel(peer)) {
697                                 ast_channel_unlock(peer);
698                                 continue;
699                         }
700
701                         if (ast_check_hangup(peer) || ast_test_flag(peer, AST_FLAG_SPYING)) {
702                                 ast_channel_unlock(peer);
703                                 continue;
704                         }
705
706                         if (mygroup) {
707                                 dup_mygroup = ast_strdupa(mygroup);
708                                 num_mygroups = ast_app_separate_args(dup_mygroup, ':', mygroups,
709                                         sizeof(mygroups) / sizeof(mygroups[0]));
710
711                                 if ((group = pbx_builtin_getvar_helper(peer, "SPYGROUP"))) {
712                                         dup_group = ast_strdupa(group);
713                                         num_groups = ast_app_separate_args(dup_group, ':', groups,
714                                                 sizeof(groups) / sizeof(groups[0]));
715                                 }
716
717                                 for (y = 0; y < num_mygroups; y++) {
718                                         for (x = 0; x < num_groups; x++) {
719                                                 if (!strcmp(mygroups[y], groups[x])) {
720                                                         igrp = 1;
721                                                         break;
722                                                 }
723                                         }
724                                 }
725                         }
726
727                         if (!igrp) {
728                                 ast_channel_unlock(peer);
729                                 continue;
730                         }
731
732                         if (myenforced) {
733
734                                 /* We don't need to allocate more space than just the
735                                 length of (peer->name) for ext as we will cut the
736                                 channel name's ending before copying into ext */
737
738                                 ext = alloca(strlen(peer->name));
739
740                                 form_enforced = alloca(strlen(myenforced) + 3);
741
742                                 strcpy(form_enforced, ":");
743                                 strcat(form_enforced, myenforced);
744                                 strcat(form_enforced, ":");
745
746                                 buffer = ast_strdupa(peer->name);
747                                 
748                                 if ((end = strchr(buffer, '-'))) {
749                                         *end++ = ':';
750                                         *end = '\0';
751                                 }
752
753                                 strcpy(ext, ":");
754                                 strcat(ext, buffer);
755
756                                 if (strcasestr(form_enforced, ext))
757                                         ienf = 1;
758                         }
759
760                         if (!ienf)
761                                 continue;
762
763                         strcpy(peer_name, "spy-");
764                         strncat(peer_name, peer->name, AST_NAME_STRLEN - 4 - 1);
765                         ptr = strchr(peer_name, '/');
766                         *ptr++ = '\0';
767                         ptr = strsep(&ptr, "-");
768
769                         for (s = peer_name; s < ptr; s++)
770                                 *s = tolower(*s);
771                         /* We have to unlock the peer channel here to avoid a deadlock.
772                          * So, when we need to dereference it again, we have to lock the 
773                          * datastore and get the pointer from there to see if the channel 
774                          * is still valid. */
775                         ast_channel_unlock(peer);
776
777                         if (!ast_test_flag(flags, OPTION_QUIET)) {
778                                 if (ast_test_flag(flags, OPTION_NAME)) {
779                                         const char *local_context = S_OR(name_context, "default");
780                                         const char *local_mailbox = S_OR(mailbox, ptr);
781                                         res = ast_app_sayname(chan, local_mailbox, local_context);
782                                 }
783                                 if (!ast_test_flag(flags, OPTION_NAME) || res < 0) {
784                                         if (!ast_test_flag(flags, OPTION_NOTECH)) {
785                                                 if (ast_fileexists(peer_name, NULL, NULL) != -1) {
786                                                         res = ast_streamfile(chan, peer_name, chan->language);
787                                                         if (!res) {
788                                                                 res = ast_waitstream(chan, "");
789                                                         }
790                                                         if (res) {
791                                                                 chanspy_ds_free(peer_chanspy_ds);
792                                                                 break;
793                                                         }
794                                                 } else {
795                                                         res = ast_say_character_str(chan, peer_name, "", chan->language);
796                                                 }
797                                         }
798                                         if ((num = atoi(ptr)))
799                                                 ast_say_digits(chan, atoi(ptr), "", chan->language);
800                                 }
801                         }
802
803                         res = channel_spy(chan, peer_chanspy_ds, &volfactor, fd, flags, exitcontext);
804                         num_spyed_upon++;       
805
806                         if (res == -1) {
807                                 chanspy_ds_free(peer_chanspy_ds);
808                                 goto exit;
809                         } else if (res == -2) {
810                                 res = 0;
811                                 chanspy_ds_free(peer_chanspy_ds);
812                                 goto exit;
813                         } else if (res > 1 && spec) {
814                                 struct ast_channel *next;
815
816                                 snprintf(nameprefix, AST_NAME_STRLEN, "%s/%d", spec, res);
817
818                                 if ((next = ast_get_channel_by_name_prefix_locked(nameprefix, strlen(nameprefix)))) {
819                                         peer_chanspy_ds = chanspy_ds_free(peer_chanspy_ds);
820                                         next_chanspy_ds = setup_chanspy_ds(next, &chanspy_ds);
821                                 } else {
822                                         /* stay on this channel, if it is still valid */
823
824                                         ast_mutex_lock(&peer_chanspy_ds->lock);
825                                         if (peer_chanspy_ds->chan) {
826                                                 ast_channel_lock(peer_chanspy_ds->chan);
827                                                 next_chanspy_ds = peer_chanspy_ds;
828                                                 peer_chanspy_ds = NULL;
829                                         } else {
830                                                 /* the channel is gone */
831                                                 ast_mutex_unlock(&peer_chanspy_ds->lock);
832                                                 next_chanspy_ds = NULL;
833                                         }
834                                 }
835
836                                 peer = NULL;
837                         }
838                 }
839                 if (res == -1 || ast_check_hangup(chan))
840                         break;
841         }
842 exit:
843
844         ast_clear_flag(chan, AST_FLAG_SPYING);
845
846         ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);
847
848         ast_mutex_destroy(&chanspy_ds.lock);
849
850         return res;
851 }
852
853 static int chanspy_exec(struct ast_channel *chan, void *data)
854 {
855         char *myenforced = NULL;
856         char *mygroup = NULL;
857         char *recbase = NULL;
858         int fd = 0;
859         struct ast_flags flags;
860         int oldwf = 0;
861         int volfactor = 0;
862         int res;
863         char *mailbox = NULL;
864         char *name_context = NULL;
865         AST_DECLARE_APP_ARGS(args,
866                 AST_APP_ARG(spec);
867                 AST_APP_ARG(options);
868         );
869         char *opts[OPT_ARG_ARRAY_SIZE];
870
871         data = ast_strdupa(data);
872         AST_STANDARD_APP_ARGS(args, data);
873
874         if (args.spec && !strcmp(args.spec, "all"))
875                 args.spec = NULL;
876
877         if (args.options) {
878                 ast_app_parse_options(spy_opts, &flags, opts, args.options);
879                 if (ast_test_flag(&flags, OPTION_GROUP))
880                         mygroup = opts[OPT_ARG_GROUP];
881
882                 if (ast_test_flag(&flags, OPTION_RECORD) &&
883                         !(recbase = opts[OPT_ARG_RECORD]))
884                         recbase = "chanspy";
885
886                 if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
887                         int vol;
888
889                         if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &vol) != 1) || (vol > 4) || (vol < -4))
890                                 ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n");
891                         else
892                                 volfactor = vol;
893                 }
894
895                 if (ast_test_flag(&flags, OPTION_PRIVATE))
896                         ast_set_flag(&flags, OPTION_WHISPER);
897
898                 if (ast_test_flag(&flags, OPTION_ENFORCED))
899                         myenforced = opts[OPT_ARG_ENFORCED];
900                 
901                 if (ast_test_flag(&flags, OPTION_NAME)) {
902                         if (!ast_strlen_zero(opts[OPT_ARG_NAME])) {
903                                 char *delimiter;
904                                 if ((delimiter = strchr(opts[OPT_ARG_NAME], '@'))) {
905                                         mailbox = opts[OPT_ARG_NAME];
906                                         *delimiter++ = '\0';
907                                         name_context = delimiter;
908                                 } else {
909                                         mailbox = opts[OPT_ARG_NAME];
910                                 }
911                         }
912                 }
913
914
915         } else
916                 ast_clear_flag(&flags, AST_FLAGS_ALL);
917
918         oldwf = chan->writeformat;
919         if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
920                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
921                 return -1;
922         }
923
924         if (recbase) {
925                 char filename[PATH_MAX];
926
927                 snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL));
928                 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, AST_FILE_MODE)) <= 0) {
929                         ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
930                         fd = 0;
931                 }
932         }
933
934         res = common_exec(chan, &flags, volfactor, fd, mygroup, myenforced, args.spec, NULL, NULL, mailbox, name_context);
935
936         if (fd)
937                 close(fd);
938
939         if (oldwf && ast_set_write_format(chan, oldwf) < 0)
940                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
941
942         return res;
943 }
944
945 static int extenspy_exec(struct ast_channel *chan, void *data)
946 {
947         char *ptr, *exten = NULL;
948         char *mygroup = NULL;
949         char *recbase = NULL;
950         int fd = 0;
951         struct ast_flags flags;
952         int oldwf = 0;
953         int volfactor = 0;
954         int res;
955         char *mailbox = NULL;
956         char *name_context = NULL;
957         AST_DECLARE_APP_ARGS(args,
958                 AST_APP_ARG(context);
959                 AST_APP_ARG(options);
960         );
961
962         data = ast_strdupa(data);
963
964         AST_STANDARD_APP_ARGS(args, data);
965         if (!ast_strlen_zero(args.context) && (ptr = strchr(args.context, '@'))) {
966                 exten = args.context;
967                 *ptr++ = '\0';
968                 args.context = ptr;
969         }
970
971         if (ast_strlen_zero(args.context))
972                 args.context = ast_strdupa(chan->context);
973
974         if (args.options) {
975                 char *opts[OPT_ARG_ARRAY_SIZE];
976
977                 ast_app_parse_options(spy_opts, &flags, opts, args.options);
978                 if (ast_test_flag(&flags, OPTION_GROUP))
979                         mygroup = opts[OPT_ARG_GROUP];
980
981                 if (ast_test_flag(&flags, OPTION_RECORD) &&
982                         !(recbase = opts[OPT_ARG_RECORD]))
983                         recbase = "chanspy";
984
985                 if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
986                         int vol;
987
988                         if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &vol) != 1) || (vol > 4) || (vol < -4))
989                                 ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n");
990                         else
991                                 volfactor = vol;
992                 }
993
994                 if (ast_test_flag(&flags, OPTION_PRIVATE))
995                         ast_set_flag(&flags, OPTION_WHISPER);
996
997                 
998                 if (ast_test_flag(&flags, OPTION_NAME)) {
999                         if (!ast_strlen_zero(opts[OPT_ARG_NAME])) {
1000                                 char *delimiter;
1001                                 if ((delimiter = strchr(opts[OPT_ARG_NAME], '@'))) {
1002                                         mailbox = opts[OPT_ARG_NAME];
1003                                         *delimiter++ = '\0';
1004                                         name_context = delimiter;
1005                                 } else {
1006                                         mailbox = opts[OPT_ARG_NAME];
1007                                 }
1008                         }
1009                 }
1010
1011         } else
1012                 ast_clear_flag(&flags, AST_FLAGS_ALL);
1013
1014         oldwf = chan->writeformat;
1015         if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
1016                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1017                 return -1;
1018         }
1019
1020         if (recbase) {
1021                 char filename[PATH_MAX];
1022
1023                 snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL));
1024                 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, AST_FILE_MODE)) <= 0) {
1025                         ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
1026                         fd = 0;
1027                 }
1028         }
1029
1030
1031         res = common_exec(chan, &flags, volfactor, fd, mygroup, NULL, NULL, exten, args.context, mailbox, name_context);
1032
1033         if (fd)
1034                 close(fd);
1035
1036         if (oldwf && ast_set_write_format(chan, oldwf) < 0)
1037                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1038
1039         return res;
1040 }
1041
1042 static int unload_module(void)
1043 {
1044         int res = 0;
1045
1046         res |= ast_unregister_application(app_chan);
1047         res |= ast_unregister_application(app_ext);
1048
1049         return res;
1050 }
1051
1052 static int load_module(void)
1053 {
1054         int res = 0;
1055
1056         res |= ast_register_application(app_chan, chanspy_exec, tdesc, desc_chan);
1057         res |= ast_register_application(app_ext, extenspy_exec, tdesc, desc_ext);
1058
1059         return res;
1060 }
1061
1062 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Listen to the audio of an active channel");