Lock around variables retrieved, and copy the values, if they stay persistent,
[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                 ast_channel_lock(chan);
600                 if ((c = pbx_builtin_getvar_helper(chan, "SPY_EXIT_CONTEXT"))) {
601                         ast_copy_string(exitcontext, c, sizeof(exitcontext));
602                 } else if (!ast_strlen_zero(chan->macrocontext)) {
603                         ast_copy_string(exitcontext, chan->macrocontext, sizeof(exitcontext));
604                 } else {
605                         ast_copy_string(exitcontext, chan->context, sizeof(exitcontext));
606                 }
607                 ast_channel_unlock(chan);
608         }
609
610         ast_mutex_init(&chanspy_ds.lock);
611
612         if (chan->_state != AST_STATE_UP)
613                 ast_answer(chan);
614
615         ast_set_flag(chan, AST_FLAG_SPYING); /* so nobody can spy on us while we are spying */
616
617         waitms = 100;
618
619         for (;;) {
620                 struct chanspy_ds *peer_chanspy_ds = NULL, *next_chanspy_ds = NULL;
621                 struct ast_channel *prev = NULL, *peer = NULL;
622
623                 if (!ast_test_flag(flags, OPTION_QUIET) && num_spyed_upon) {
624                         res = ast_streamfile(chan, "beep", chan->language);
625                         if (!res)
626                                 res = ast_waitstream(chan, "");
627                         else if (res < 0) {
628                                 ast_clear_flag(chan, AST_FLAG_SPYING);
629                                 break;
630                         }
631                         if (!ast_strlen_zero(exitcontext)) {
632                                 char tmp[2];
633                                 tmp[0] = res;
634                                 tmp[1] = '\0';
635                                 if (!ast_goto_if_exists(chan, exitcontext, tmp, 1))
636                                         goto exit;
637                                 else
638                                         ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
639                         }
640                 }
641
642                 res = ast_waitfordigit(chan, waitms);
643                 if (res < 0) {
644                         ast_clear_flag(chan, AST_FLAG_SPYING);
645                         break;
646                 }
647                 if (!ast_strlen_zero(exitcontext)) {
648                         char tmp[2];
649                         tmp[0] = res;
650                         tmp[1] = '\0';
651                         if (!ast_goto_if_exists(chan, exitcontext, tmp, 1))
652                                 goto exit;
653                         else
654                                 ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
655                 }
656
657                 /* reset for the next loop around, unless overridden later */
658                 waitms = 100;
659                 num_spyed_upon = 0;
660
661                 for (peer_chanspy_ds = next_channel(chan, prev, spec, exten, context, &chanspy_ds);
662                      peer_chanspy_ds;
663                          chanspy_ds_free(peer_chanspy_ds), prev = peer,
664                      peer_chanspy_ds = next_chanspy_ds ? next_chanspy_ds : 
665                                 next_channel(chan, prev, spec, exten, context, &chanspy_ds), next_chanspy_ds = NULL) {
666                         const char *group;
667                         int igrp = !mygroup;
668                         char *groups[NUM_SPYGROUPS];
669                         char *mygroups[NUM_SPYGROUPS];
670                         int num_groups = 0;
671                         char *dup_group;
672                         int num_mygroups = 0;
673                         char *dup_mygroup;
674                         int x;
675                         int y;
676                         char *s;
677                         char *buffer;
678                         char *end;
679                         char *ext;
680                         char *form_enforced;
681                         int ienf = !myenforced;
682
683                         peer = peer_chanspy_ds->chan;
684
685                         ast_mutex_unlock(&peer_chanspy_ds->lock);
686
687                         if (peer == prev) {
688                                 ast_channel_unlock(peer);
689                                 chanspy_ds_free(peer_chanspy_ds);
690                                 break;
691                         }
692
693                         if (ast_check_hangup(chan)) {
694                                 ast_channel_unlock(peer);
695                                 chanspy_ds_free(peer_chanspy_ds);
696                                 break;
697                         }
698
699                         if (ast_test_flag(flags, OPTION_BRIDGED) && !ast_bridged_channel(peer)) {
700                                 ast_channel_unlock(peer);
701                                 continue;
702                         }
703
704                         if (ast_check_hangup(peer) || ast_test_flag(peer, AST_FLAG_SPYING)) {
705                                 ast_channel_unlock(peer);
706                                 continue;
707                         }
708
709                         if (mygroup) {
710                                 dup_mygroup = ast_strdupa(mygroup);
711                                 num_mygroups = ast_app_separate_args(dup_mygroup, ':', mygroups,
712                                         sizeof(mygroups) / sizeof(mygroups[0]));
713
714                                 if ((group = pbx_builtin_getvar_helper(peer, "SPYGROUP"))) {
715                                         dup_group = ast_strdupa(group);
716                                         num_groups = ast_app_separate_args(dup_group, ':', groups,
717                                                 sizeof(groups) / sizeof(groups[0]));
718                                 }
719
720                                 for (y = 0; y < num_mygroups; y++) {
721                                         for (x = 0; x < num_groups; x++) {
722                                                 if (!strcmp(mygroups[y], groups[x])) {
723                                                         igrp = 1;
724                                                         break;
725                                                 }
726                                         }
727                                 }
728                         }
729
730                         if (!igrp) {
731                                 ast_channel_unlock(peer);
732                                 continue;
733                         }
734
735                         if (myenforced) {
736
737                                 /* We don't need to allocate more space than just the
738                                 length of (peer->name) for ext as we will cut the
739                                 channel name's ending before copying into ext */
740
741                                 ext = alloca(strlen(peer->name));
742
743                                 form_enforced = alloca(strlen(myenforced) + 3);
744
745                                 strcpy(form_enforced, ":");
746                                 strcat(form_enforced, myenforced);
747                                 strcat(form_enforced, ":");
748
749                                 buffer = ast_strdupa(peer->name);
750                                 
751                                 if ((end = strchr(buffer, '-'))) {
752                                         *end++ = ':';
753                                         *end = '\0';
754                                 }
755
756                                 strcpy(ext, ":");
757                                 strcat(ext, buffer);
758
759                                 if (strcasestr(form_enforced, ext))
760                                         ienf = 1;
761                         }
762
763                         if (!ienf)
764                                 continue;
765
766                         strcpy(peer_name, "spy-");
767                         strncat(peer_name, peer->name, AST_NAME_STRLEN - 4 - 1);
768                         ptr = strchr(peer_name, '/');
769                         *ptr++ = '\0';
770                         ptr = strsep(&ptr, "-");
771
772                         for (s = peer_name; s < ptr; s++)
773                                 *s = tolower(*s);
774                         /* We have to unlock the peer channel here to avoid a deadlock.
775                          * So, when we need to dereference it again, we have to lock the 
776                          * datastore and get the pointer from there to see if the channel 
777                          * is still valid. */
778                         ast_channel_unlock(peer);
779
780                         if (!ast_test_flag(flags, OPTION_QUIET)) {
781                                 if (ast_test_flag(flags, OPTION_NAME)) {
782                                         const char *local_context = S_OR(name_context, "default");
783                                         const char *local_mailbox = S_OR(mailbox, ptr);
784                                         res = ast_app_sayname(chan, local_mailbox, local_context);
785                                 }
786                                 if (!ast_test_flag(flags, OPTION_NAME) || res < 0) {
787                                         if (!ast_test_flag(flags, OPTION_NOTECH)) {
788                                                 if (ast_fileexists(peer_name, NULL, NULL) != -1) {
789                                                         res = ast_streamfile(chan, peer_name, chan->language);
790                                                         if (!res) {
791                                                                 res = ast_waitstream(chan, "");
792                                                         }
793                                                         if (res) {
794                                                                 chanspy_ds_free(peer_chanspy_ds);
795                                                                 break;
796                                                         }
797                                                 } else {
798                                                         res = ast_say_character_str(chan, peer_name, "", chan->language);
799                                                 }
800                                         }
801                                         if ((num = atoi(ptr)))
802                                                 ast_say_digits(chan, atoi(ptr), "", chan->language);
803                                 }
804                         }
805
806                         res = channel_spy(chan, peer_chanspy_ds, &volfactor, fd, flags, exitcontext);
807                         num_spyed_upon++;       
808
809                         if (res == -1) {
810                                 chanspy_ds_free(peer_chanspy_ds);
811                                 goto exit;
812                         } else if (res == -2) {
813                                 res = 0;
814                                 chanspy_ds_free(peer_chanspy_ds);
815                                 goto exit;
816                         } else if (res > 1 && spec) {
817                                 struct ast_channel *next;
818
819                                 snprintf(nameprefix, AST_NAME_STRLEN, "%s/%d", spec, res);
820
821                                 if ((next = ast_get_channel_by_name_prefix_locked(nameprefix, strlen(nameprefix)))) {
822                                         peer_chanspy_ds = chanspy_ds_free(peer_chanspy_ds);
823                                         next_chanspy_ds = setup_chanspy_ds(next, &chanspy_ds);
824                                 } else {
825                                         /* stay on this channel, if it is still valid */
826
827                                         ast_mutex_lock(&peer_chanspy_ds->lock);
828                                         if (peer_chanspy_ds->chan) {
829                                                 ast_channel_lock(peer_chanspy_ds->chan);
830                                                 next_chanspy_ds = peer_chanspy_ds;
831                                                 peer_chanspy_ds = NULL;
832                                         } else {
833                                                 /* the channel is gone */
834                                                 ast_mutex_unlock(&peer_chanspy_ds->lock);
835                                                 next_chanspy_ds = NULL;
836                                         }
837                                 }
838
839                                 peer = NULL;
840                         }
841                 }
842                 if (res == -1 || ast_check_hangup(chan))
843                         break;
844         }
845 exit:
846
847         ast_clear_flag(chan, AST_FLAG_SPYING);
848
849         ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);
850
851         ast_mutex_destroy(&chanspy_ds.lock);
852
853         return res;
854 }
855
856 static int chanspy_exec(struct ast_channel *chan, void *data)
857 {
858         char *myenforced = NULL;
859         char *mygroup = NULL;
860         char *recbase = NULL;
861         int fd = 0;
862         struct ast_flags flags;
863         int oldwf = 0;
864         int volfactor = 0;
865         int res;
866         char *mailbox = NULL;
867         char *name_context = NULL;
868         AST_DECLARE_APP_ARGS(args,
869                 AST_APP_ARG(spec);
870                 AST_APP_ARG(options);
871         );
872         char *opts[OPT_ARG_ARRAY_SIZE];
873
874         data = ast_strdupa(data);
875         AST_STANDARD_APP_ARGS(args, data);
876
877         if (args.spec && !strcmp(args.spec, "all"))
878                 args.spec = NULL;
879
880         if (args.options) {
881                 ast_app_parse_options(spy_opts, &flags, opts, args.options);
882                 if (ast_test_flag(&flags, OPTION_GROUP))
883                         mygroup = opts[OPT_ARG_GROUP];
884
885                 if (ast_test_flag(&flags, OPTION_RECORD) &&
886                         !(recbase = opts[OPT_ARG_RECORD]))
887                         recbase = "chanspy";
888
889                 if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
890                         int vol;
891
892                         if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &vol) != 1) || (vol > 4) || (vol < -4))
893                                 ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n");
894                         else
895                                 volfactor = vol;
896                 }
897
898                 if (ast_test_flag(&flags, OPTION_PRIVATE))
899                         ast_set_flag(&flags, OPTION_WHISPER);
900
901                 if (ast_test_flag(&flags, OPTION_ENFORCED))
902                         myenforced = opts[OPT_ARG_ENFORCED];
903                 
904                 if (ast_test_flag(&flags, OPTION_NAME)) {
905                         if (!ast_strlen_zero(opts[OPT_ARG_NAME])) {
906                                 char *delimiter;
907                                 if ((delimiter = strchr(opts[OPT_ARG_NAME], '@'))) {
908                                         mailbox = opts[OPT_ARG_NAME];
909                                         *delimiter++ = '\0';
910                                         name_context = delimiter;
911                                 } else {
912                                         mailbox = opts[OPT_ARG_NAME];
913                                 }
914                         }
915                 }
916
917
918         } else
919                 ast_clear_flag(&flags, AST_FLAGS_ALL);
920
921         oldwf = chan->writeformat;
922         if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
923                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
924                 return -1;
925         }
926
927         if (recbase) {
928                 char filename[PATH_MAX];
929
930                 snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL));
931                 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, AST_FILE_MODE)) <= 0) {
932                         ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
933                         fd = 0;
934                 }
935         }
936
937         res = common_exec(chan, &flags, volfactor, fd, mygroup, myenforced, args.spec, NULL, NULL, mailbox, name_context);
938
939         if (fd)
940                 close(fd);
941
942         if (oldwf && ast_set_write_format(chan, oldwf) < 0)
943                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
944
945         return res;
946 }
947
948 static int extenspy_exec(struct ast_channel *chan, void *data)
949 {
950         char *ptr, *exten = NULL;
951         char *mygroup = NULL;
952         char *recbase = NULL;
953         int fd = 0;
954         struct ast_flags flags;
955         int oldwf = 0;
956         int volfactor = 0;
957         int res;
958         char *mailbox = NULL;
959         char *name_context = NULL;
960         AST_DECLARE_APP_ARGS(args,
961                 AST_APP_ARG(context);
962                 AST_APP_ARG(options);
963         );
964
965         data = ast_strdupa(data);
966
967         AST_STANDARD_APP_ARGS(args, data);
968         if (!ast_strlen_zero(args.context) && (ptr = strchr(args.context, '@'))) {
969                 exten = args.context;
970                 *ptr++ = '\0';
971                 args.context = ptr;
972         }
973
974         if (ast_strlen_zero(args.context))
975                 args.context = ast_strdupa(chan->context);
976
977         if (args.options) {
978                 char *opts[OPT_ARG_ARRAY_SIZE];
979
980                 ast_app_parse_options(spy_opts, &flags, opts, args.options);
981                 if (ast_test_flag(&flags, OPTION_GROUP))
982                         mygroup = opts[OPT_ARG_GROUP];
983
984                 if (ast_test_flag(&flags, OPTION_RECORD) &&
985                         !(recbase = opts[OPT_ARG_RECORD]))
986                         recbase = "chanspy";
987
988                 if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
989                         int vol;
990
991                         if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &vol) != 1) || (vol > 4) || (vol < -4))
992                                 ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n");
993                         else
994                                 volfactor = vol;
995                 }
996
997                 if (ast_test_flag(&flags, OPTION_PRIVATE))
998                         ast_set_flag(&flags, OPTION_WHISPER);
999
1000                 
1001                 if (ast_test_flag(&flags, OPTION_NAME)) {
1002                         if (!ast_strlen_zero(opts[OPT_ARG_NAME])) {
1003                                 char *delimiter;
1004                                 if ((delimiter = strchr(opts[OPT_ARG_NAME], '@'))) {
1005                                         mailbox = opts[OPT_ARG_NAME];
1006                                         *delimiter++ = '\0';
1007                                         name_context = delimiter;
1008                                 } else {
1009                                         mailbox = opts[OPT_ARG_NAME];
1010                                 }
1011                         }
1012                 }
1013
1014         } else
1015                 ast_clear_flag(&flags, AST_FLAGS_ALL);
1016
1017         oldwf = chan->writeformat;
1018         if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
1019                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1020                 return -1;
1021         }
1022
1023         if (recbase) {
1024                 char filename[PATH_MAX];
1025
1026                 snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL));
1027                 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, AST_FILE_MODE)) <= 0) {
1028                         ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
1029                         fd = 0;
1030                 }
1031         }
1032
1033
1034         res = common_exec(chan, &flags, volfactor, fd, mygroup, NULL, NULL, exten, args.context, mailbox, name_context);
1035
1036         if (fd)
1037                 close(fd);
1038
1039         if (oldwf && ast_set_write_format(chan, oldwf) < 0)
1040                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1041
1042         return res;
1043 }
1044
1045 static int unload_module(void)
1046 {
1047         int res = 0;
1048
1049         res |= ast_unregister_application(app_chan);
1050         res |= ast_unregister_application(app_ext);
1051
1052         return res;
1053 }
1054
1055 static int load_module(void)
1056 {
1057         int res = 0;
1058
1059         res |= ast_register_application(app_chan, chanspy_exec, tdesc, desc_chan);
1060         res |= ast_register_application(app_ext, extenspy_exec, tdesc, desc_ext);
1061
1062         return res;
1063 }
1064
1065 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Listen to the audio of an active channel");