revert my pass through the tree to remove checks of the result of ast_strdupa
[asterisk/asterisk.git] / apps / app_mixmonitor.c
old mode 100755 (executable)
new mode 100644 (file)
index d659293..279f0e6
@@ -2,7 +2,7 @@
  * Asterisk -- An open source telephony toolkit.
  *
  * Copyright (C) 2005, Anthony Minessale II
- * Copyright (C) 2005, Digium, Inc.
+ * Copyright (C) 2005 - 2006, Digium, Inc.
  *
  * Mark Spencer <markster@digium.com>
  * Kevin P. Fleming <kpfleming@digium.com>
  */
 
 /*! \file
+ *
  * \brief MixMonitor() - Record a call and mix the audio during the recording
+ * \ingroup applications
+ *
+ * \author Mark Spencer <markster@digium.com>
+ * \author Kevin P. Fleming <kpfleming@digium.com>
+ *
+ * \note Based on app_muxmon.c provided by
+ * Anthony Minessale II <anthmct@yahoo.com>
  */
 
 #include <stdlib.h>
-#include <unistd.h>
+#include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "asterisk.h"
 
@@ -36,6 +45,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/file.h"
 #include "asterisk/logger.h"
 #include "asterisk/channel.h"
+#include "asterisk/chanspy.h"
 #include "asterisk/pbx.h"
 #include "asterisk/module.h"
 #include "asterisk/lock.h"
@@ -43,6 +53,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/options.h"
 #include "asterisk/app.h"
 #include "asterisk/linkedlists.h"
+#include "asterisk/utils.h"
 
 #define get_volfactor(x) x ? ((x > 0) ? (1 << x) : ((1 << abs(x)) * -1)) : 0
 
@@ -85,26 +96,33 @@ struct mixmonitor {
 };
 
 enum {
-    MUXFLAG_APPEND = (1 << 1),
-    MUXFLAG_BRIDGED = (1 << 2),
-    MUXFLAG_VOLUME = (1 << 3),
-    MUXFLAG_READVOLUME = (1 << 4),
-    MUXFLAG_WRITEVOLUME = (1 << 5),
+       MUXFLAG_APPEND = (1 << 1),
+       MUXFLAG_BRIDGED = (1 << 2),
+       MUXFLAG_VOLUME = (1 << 3),
+       MUXFLAG_READVOLUME = (1 << 4),
+       MUXFLAG_WRITEVOLUME = (1 << 5),
 } mixmonitor_flags;
 
-AST_DECLARE_OPTIONS(mixmonitor_opts,{
-       ['a'] = { MUXFLAG_APPEND },
-       ['b'] = { MUXFLAG_BRIDGED },
-       ['v'] = { MUXFLAG_READVOLUME, 1 },
-       ['V'] = { MUXFLAG_WRITEVOLUME, 2 },
-       ['W'] = { MUXFLAG_VOLUME, 3 },
+enum {
+       OPT_ARG_READVOLUME = 0,
+       OPT_ARG_WRITEVOLUME,
+       OPT_ARG_VOLUME,
+       OPT_ARG_ARRAY_SIZE,
+} mixmonitor_args;
+
+AST_APP_OPTIONS(mixmonitor_opts, {
+       AST_APP_OPTION('a', MUXFLAG_APPEND),
+       AST_APP_OPTION('b', MUXFLAG_BRIDGED),
+       AST_APP_OPTION_ARG('v', MUXFLAG_READVOLUME, OPT_ARG_READVOLUME),
+       AST_APP_OPTION_ARG('V', MUXFLAG_WRITEVOLUME, OPT_ARG_WRITEVOLUME),
+       AST_APP_OPTION_ARG('W', MUXFLAG_VOLUME, OPT_ARG_VOLUME),
 });
 
 static void stopmon(struct ast_channel *chan, struct ast_channel_spy *spy) 
 {
-       /* If our status has changed, then the channel we're spying on is gone....
+       /* If our status has changed to DONE, then the channel we're spying on is gone....
           DON'T TOUCH IT!!!  RUN AWAY!!! */
-       if (spy->status != CHANSPY_RUNNING)
+       if (spy->status == CHANSPY_DONE)
                return;
 
        if (!chan)
@@ -152,7 +170,7 @@ static void *mixmonitor_thread(void *obj)
        oflags = O_CREAT|O_WRONLY;
        oflags |= ast_test_flag(mixmonitor, MUXFLAG_APPEND) ? O_APPEND : O_TRUNC;
                
-       if ((ext = strchr(mixmonitor->filename, '.'))) {
+       if ((ext = strrchr(mixmonitor->filename, '.'))) {
                *(ext++) = '\0';
        } else {
                ext = "raw";
@@ -272,18 +290,17 @@ static void launch_monitor_thread(struct ast_channel *chan, const char *filename
        int len;
 
        len = sizeof(*mixmonitor) + strlen(filename) + 1;
-       if (post_process && !ast_strlen_zero(post_process))
+       if (!ast_strlen_zero(post_process))
                len += strlen(post_process) + 1;
 
-       if (!(mixmonitor = calloc(1, len))) {
-               ast_log(LOG_ERROR, "Memory Error!\n");
+       if (!(mixmonitor = ast_calloc(1, len))) {
                return;
        }
 
        mixmonitor->chan = chan;
        mixmonitor->filename = (char *) mixmonitor + sizeof(*mixmonitor);
        strcpy(mixmonitor->filename, filename);
-       if (post_process && !ast_strlen_zero(post_process)) {
+       if (!ast_strlen_zero(post_process)) {
                mixmonitor->post_process = mixmonitor->filename + strlen(filename) + 1;
                strcpy(mixmonitor->post_process, post_process);
        }
@@ -325,41 +342,41 @@ static int mixmonitor_exec(struct ast_channel *chan, void *data)
        AST_STANDARD_APP_ARGS(args, parse);
        
        if (ast_strlen_zero(args.filename)) {
-               ast_log(LOG_WARNING, "Muxmon requires an argument (filename)\n");
+               ast_log(LOG_WARNING, "MixMonitor requires an argument (filename)\n");
                LOCAL_USER_REMOVE(u);
                return -1;
        }
 
        if (args.options) {
-               char *opts[3] = { NULL, };
+               char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };
 
-               ast_parseoptions(mixmonitor_opts, &flags, opts, args.options);
+               ast_app_parse_options(mixmonitor_opts, &flags, opts, args.options);
 
                if (ast_test_flag(&flags, MUXFLAG_READVOLUME)) {
-                       if (!opts[0] || ast_strlen_zero(opts[0])) {
+                       if (ast_strlen_zero(opts[OPT_ARG_READVOLUME])) {
                                ast_log(LOG_WARNING, "No volume level was provided for the heard volume ('v') option.\n");
-                       } else if ((sscanf(opts[0], "%d", &x) != 1) || (x < -4) || (x > 4)) {
-                               ast_log(LOG_NOTICE, "Heard volume must be a number between -4 and 4, not '%s'\n", opts[0]);
+                       } else if ((sscanf(opts[OPT_ARG_READVOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
+                               ast_log(LOG_NOTICE, "Heard volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_READVOLUME]);
                        } else {
                                readvol = get_volfactor(x);
                        }
                }
                
                if (ast_test_flag(&flags, MUXFLAG_WRITEVOLUME)) {
-                       if (!opts[1] || ast_strlen_zero(opts[1])) {
+                       if (ast_strlen_zero(opts[OPT_ARG_WRITEVOLUME])) {
                                ast_log(LOG_WARNING, "No volume level was provided for the spoken volume ('V') option.\n");
-                       } else if ((sscanf(opts[1], "%d", &x) != 1) || (x < -4) || (x > 4)) {
-                               ast_log(LOG_NOTICE, "Spoken volume must be a number between -4 and 4, not '%s'\n", opts[1]);
+                       } else if ((sscanf(opts[OPT_ARG_WRITEVOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
+                               ast_log(LOG_NOTICE, "Spoken volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_WRITEVOLUME]);
                        } else {
                                writevol = get_volfactor(x);
                        }
                }
                
                if (ast_test_flag(&flags, MUXFLAG_VOLUME)) {
-                       if (!opts[2] || ast_strlen_zero(opts[2])) {
+                       if (ast_strlen_zero(opts[OPT_ARG_VOLUME])) {
                                ast_log(LOG_WARNING, "No volume level was provided for the combined volume ('W') option.\n");
-                       } else if ((sscanf(opts[2], "%d", &x) != 1) || (x < -4) || (x > 4)) {
-                               ast_log(LOG_NOTICE, "Combined volume must be a number between -4 and 4, not '%s'\n", opts[2]);
+                       } else if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
+                               ast_log(LOG_NOTICE, "Combined volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_VOLUME]);
                        } else {
                                readvol = writevol = get_volfactor(x);
                        }
@@ -410,7 +427,7 @@ static struct ast_cli_entry cli_mixmonitor = {
        { "mixmonitor", NULL, NULL },
        mixmonitor_cli, 
        "Execute a MixMonitor command",
-       "mixmonitor <start|stop> <chan_name> [<args>]"
+       "mixmonitor <start|stop> <chan_name> [<args>]\n"
 };