Merge "AST-2018-005: Fix tdata leaks when calling pjsip_endpt_send_response(2)"
[asterisk/asterisk.git] / apps / app_dumpchan.c
index 5125354..bec7788 100644 (file)
@@ -5,7 +5,8 @@
  *
  * Anthony Minessale <anthmct@yahoo.com>
  *
- * disclaimed to Digium
+ * A license has been granted to Digium (via disclaimer) for the use of
+ * this code.
  *
  * See http://www.asterisk.org for more information about
  * the Asterisk project. Please do not directly contact
  * \ingroup applications
  */
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
+/*** MODULEINFO
+       <support_level>core</support_level>
+ ***/
 
 #include "asterisk.h"
 
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
 #include "asterisk/pbx.h"
 #include "asterisk/module.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-
-static char *tdesc = "Dump Info About The Calling Channel";
-static char *app = "DumpChan";
-static char *synopsis = "Dump Info About The Calling Channel";
-static char *desc = 
-"   DumpChan([<min_verbose_level>])\n"
-"Displays information on channel and listing of all channel\n"
-"variables. If min_verbose_level is specified, output is only\n"
-"displayed when the verbose level is currently set to that number\n"
-"or greater. \n";
-
-LOCAL_USER_DECL;
-
-static int ast_serialize_showchan(struct ast_channel *c, char *buf, size_t size)
+#include "asterisk/channel.h"
+#include "asterisk/app.h"
+#include "asterisk/translate.h"
+#include "asterisk/bridge.h"
+
+/*** DOCUMENTATION
+       <application name="DumpChan" language="en_US">
+               <synopsis>
+                       Dump Info About The Calling Channel.
+               </synopsis>
+               <syntax>
+                       <parameter name="level">
+                               <para>Minimum verbose level</para>
+                       </parameter>
+               </syntax>
+               <description>
+                       <para>Displays information on channel and listing of all channel
+                       variables. If <replaceable>level</replaceable> is specified, output is only
+                       displayed when the verbose level is currently set to that number
+                       or greater.</para>
+               </description>
+               <see-also>
+                       <ref type="application">NoOp</ref>
+                       <ref type="application">Verbose</ref>
+               </see-also>
+       </application>
+ ***/
+
+static const char app[] = "DumpChan";
+
+static int serialize_showchan(struct ast_channel *c, char *buf, size_t size)
 {
-       struct timeval now;
-       long elapsed_seconds=0;
-       int hour=0, min=0, sec=0;
+       long elapsed_seconds = 0;
+       int hour = 0, min = 0, sec = 0;
+       struct ast_str *format_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
        char cgrp[256];
        char pgrp[256];
-       
-       now = ast_tvnow();
-       memset(buf,0,size);
+       struct ast_str *write_transpath = ast_str_alloca(256);
+       struct ast_str *read_transpath = ast_str_alloca(256);
+       struct ast_bridge *bridge;
+
+       memset(buf, 0, size);
        if (!c)
                return 0;
 
-       if (c->cdr) {
-               elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
-               hour = elapsed_seconds / 3600;
-               min = (elapsed_seconds % 3600) / 60;
-               sec = elapsed_seconds % 60;
-       }
-
-       snprintf(buf,size, 
-                        "Name=               %s\n"
-                        "Type=               %s\n"
-                        "UniqueID=           %s\n"
-                        "CallerID=           %s\n"
-                        "CallerIDName=       %s\n"
-                        "DNIDDigits=         %s\n"
-                        "State=              %s (%d)\n"
-                        "Rings=              %d\n"
-                        "NativeFormat=       %d\n"
-                        "WriteFormat=        %d\n"
-                        "ReadFormat=         %d\n"
-                        "1stFileDescriptor=  %d\n"
-                        "Framesin=           %d %s\n"
-                        "Framesout=          %d %s\n"
-                        "TimetoHangup=       %ld\n"
-                        "ElapsedTime=        %dh%dm%ds\n"
-                        "Context=            %s\n"
-                        "Extension=          %s\n"
-                        "Priority=           %d\n"
-                        "CallGroup=          %s\n"
-                        "PickupGroup=        %s\n"
-                        "Application=        %s\n"
-                        "Data=               %s\n"
-                        "Blocking_in=        %s\n",
-                        c->name,
-                        c->tech->type,
-                        c->uniqueid,
-                        (c->cid.cid_num ? c->cid.cid_num : "(N/A)"),
-                        (c->cid.cid_name ? c->cid.cid_name : "(N/A)"),
-                        (c->cid.cid_dnid ? c->cid.cid_dnid : "(N/A)" ),
-                        ast_state2str(c->_state),
-                        c->_state,
-                        c->rings,
-                        c->nativeformats,
-                        c->writeformat,
-                        c->readformat,
-                        c->fds[0], c->fin & 0x7fffffff, (c->fin & 0x80000000) ? " (DEBUGGED)" : "",
-                        c->fout & 0x7fffffff, (c->fout & 0x80000000) ? " (DEBUGGED)" : "", (long)c->whentohangup,
-                        hour,
-                        min,
-                        sec,
-                        c->context,
-                        c->exten,
-                        c->priority,
-                        ast_print_group(cgrp, sizeof(cgrp), c->callgroup),
-                        ast_print_group(pgrp, sizeof(pgrp), c->pickupgroup),
-                        ( c->appl ? c->appl : "(N/A)" ),
-                        ( c-> data ? S_OR(c->data, "(Empty)") : "(None)"),
-                        (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)"));
-
+       elapsed_seconds = ast_channel_get_duration(c);
+       hour = elapsed_seconds / 3600;
+       min = (elapsed_seconds % 3600) / 60;
+       sec = elapsed_seconds % 60;
+
+       ast_channel_lock(c);
+       bridge = ast_channel_get_bridge(c);
+       snprintf(buf,size,
+               "Name=               %s\n"
+               "Type=               %s\n"
+               "UniqueID=           %s\n"
+               "LinkedID=           %s\n"
+               "CallerIDNum=        %s\n"
+               "CallerIDName=       %s\n"
+               "ConnectedLineIDNum= %s\n"
+               "ConnectedLineIDName=%s\n"
+               "DNIDDigits=         %s\n"
+               "RDNIS=              %s\n"
+               "Parkinglot=         %s\n"
+               "Language=           %s\n"
+               "State=              %s (%u)\n"
+               "Rings=              %d\n"
+               "NativeFormat=       %s\n"
+               "WriteFormat=        %s\n"
+               "ReadFormat=         %s\n"
+               "RawWriteFormat=     %s\n"
+               "RawReadFormat=      %s\n"
+               "WriteTranscode=     %s %s\n"
+               "ReadTranscode=      %s %s\n"
+               "1stFileDescriptor=  %d\n"
+               "Framesin=           %u %s\n"
+               "Framesout=          %u %s\n"
+               "TimetoHangup=       %ld\n"
+               "ElapsedTime=        %dh%dm%ds\n"
+               "BridgeID=           %s\n"
+               "Context=            %s\n"
+               "Extension=          %s\n"
+               "Priority=           %d\n"
+               "CallGroup=          %s\n"
+               "PickupGroup=        %s\n"
+               "Application=        %s\n"
+               "Data=               %s\n"
+               "Blocking_in=        %s\n",
+               ast_channel_name(c),
+               ast_channel_tech(c)->type,
+               ast_channel_uniqueid(c),
+               ast_channel_linkedid(c),
+               S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, "(N/A)"),
+               S_COR(ast_channel_caller(c)->id.name.valid, ast_channel_caller(c)->id.name.str, "(N/A)"),
+               S_COR(ast_channel_connected(c)->id.number.valid, ast_channel_connected(c)->id.number.str, "(N/A)"),
+               S_COR(ast_channel_connected(c)->id.name.valid, ast_channel_connected(c)->id.name.str, "(N/A)"),
+               S_OR(ast_channel_dialed(c)->number.str, "(N/A)"),
+               S_COR(ast_channel_redirecting(c)->from.number.valid, ast_channel_redirecting(c)->from.number.str, "(N/A)"),
+               ast_channel_parkinglot(c),
+               ast_channel_language(c),
+               ast_state2str(ast_channel_state(c)),
+               ast_channel_state(c),
+               ast_channel_rings(c),
+               ast_format_cap_get_names(ast_channel_nativeformats(c), &format_buf),
+               ast_format_get_name(ast_channel_writeformat(c)),
+               ast_format_get_name(ast_channel_readformat(c)),
+               ast_format_get_name(ast_channel_rawwriteformat(c)),
+               ast_format_get_name(ast_channel_rawreadformat(c)),
+               ast_channel_writetrans(c) ? "Yes" : "No",
+               ast_translate_path_to_str(ast_channel_writetrans(c), &write_transpath),
+               ast_channel_readtrans(c) ? "Yes" : "No",
+               ast_translate_path_to_str(ast_channel_readtrans(c), &read_transpath),
+               ast_channel_fd(c, 0),
+               ast_channel_fin(c) & ~DEBUGCHAN_FLAG, (ast_channel_fin(c) & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
+               ast_channel_fout(c) & ~DEBUGCHAN_FLAG, (ast_channel_fout(c) & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
+               (long)ast_channel_whentohangup(c)->tv_sec,
+               hour,
+               min,
+               sec,
+               bridge ? bridge->uniqueid : "(Not bridged)",
+               ast_channel_context(c),
+               ast_channel_exten(c),
+               ast_channel_priority(c),
+               ast_print_group(cgrp, sizeof(cgrp), ast_channel_callgroup(c)),
+               ast_print_group(pgrp, sizeof(pgrp), ast_channel_pickupgroup(c)),
+               ast_channel_appl(c) ? ast_channel_appl(c) : "(N/A)",
+               ast_channel_data(c) ? S_OR(ast_channel_data(c), "(Empty)") : "(None)",
+               (ast_test_flag(ast_channel_flags(c), AST_FLAG_BLOCKING) ? ast_channel_blockproc(c) : "(Not Blocking)"));
+       ast_channel_unlock(c);
+       ao2_cleanup(bridge);
        return 0;
 }
 
-static int dumpchan_exec(struct ast_channel *chan, void *data)
+static int dumpchan_exec(struct ast_channel *chan, const char *data)
 {
-       int res=0;
-       struct localuser *u;
-       char vars[1024];
-       char info[1024];
+       struct ast_str *vars = ast_str_thread_get(&ast_str_thread_global_buf, 16);
+       char info[2048];
        int level = 0;
        static char *line = "================================================================================";
-       
-       LOCAL_USER_ADD(u);
 
-       if (!ast_strlen_zero(data)) {
+       if (!ast_strlen_zero(data))
                level = atoi(data);
-       }
-
-       pbx_builtin_serialize_variables(chan, vars, sizeof(vars));
-       ast_serialize_showchan(chan, info, sizeof(info));
-       if (option_verbose >= level)
-               ast_verbose("\nDumping Info For Channel: %s:\n%s\nInfo:\n%s\nVariables:\n%s%s\n",chan->name, line, info, vars, line);
-
-       LOCAL_USER_REMOVE(u);
-       
-       return res;
-}
 
-int unload_module(void)
-{
-       int res;
-
-       res = ast_unregister_application(app);
-
-       STANDARD_HANGUP_LOCALUSERS;
-
-       return res;
-}
-
-int load_module(void)
-{
-       return ast_register_application(app, dumpchan_exec, synopsis, desc);
-}
+       if (VERBOSITY_ATLEAST(level)) {
+               serialize_showchan(chan, info, sizeof(info));
+               pbx_builtin_serialize_variables(chan, &vars);
+               ast_verb(level, "\n"
+                       "Dumping Info For Channel: %s:\n"
+                       "%s\n"
+                       "Info:\n"
+                       "%s\n"
+                       "Variables:\n"
+                       "%s%s\n", ast_channel_name(chan), line, info, ast_str_buffer(vars), line);
+       }
 
-char *description(void)
-{
-       return tdesc;
+       return 0;
 }
 
-int usecount(void)
+static int unload_module(void)
 {
-       int res;
-       STANDARD_USECOUNT(res);
-       return res;
+       return ast_unregister_application(app);
 }
 
-char *key()
+static int load_module(void)
 {
-       return ASTERISK_GPL_KEY;
+       return ast_register_application_xml(app, dumpchan_exec);
 }
 
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dump Info About The Calling Channel");