]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
set the DIALSTATUS variable to contain "INVALIDARGS" when the dial application
authorRussell Bryant <russell@russellbryant.com>
Sat, 3 Feb 2007 20:38:13 +0000 (20:38 +0000)
committerRussell Bryant <russell@russellbryant.com>
Sat, 3 Feb 2007 20:38:13 +0000 (20:38 +0000)
exits early because of invalid arguments instead of just leaving it empty.
(issue #8975)

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.2@53133 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_dial.c
apps/app_meetme.c
include/asterisk/lock.h
utils.c

index 522c47a3f0285e2912b196184a71c8193fcdbc11..69b5813d3cde311dcfad3d7bcd015e3f8a726ee9 100644 (file)
@@ -80,7 +80,7 @@ static char *descrip =
 "    ANSWEREDTIME - This is the amount of time for actual call.\n"
 "    DIALSTATUS   - This is the status of the call:\n"
 "                   CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL\n" 
-"                   DONTCALL | TORTURE\n"
+"                   DONTCALL | TORTURE | INVALIDARGS\n"
 "  For the Privacy and Screening Modes, the DIALSTATUS variable will be set to\n"
 "DONTCALL if the called party chooses to send the calling party to the 'Go Away'\n"
 "script. The DIALSTATUS variable will be set to TORTURE if the called party\n"
@@ -759,7 +759,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
        char *start_sound=NULL;
        char *dtmfcalled=NULL, *dtmfcalling=NULL;
        char *var;
-       char status[256];
+       char status[256] = "INVALIDARGS";
        int play_to_caller=0,play_to_callee=0;
        int sentringing=0, moh=0;
        char *outbound_group = NULL;
@@ -780,21 +780,19 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
 
        if (ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
+               pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
                return -1;
        }
 
        LOCAL_USER_ADD(u);
 
-       if (!(parse = ast_strdupa(data))) {
-               ast_log(LOG_WARNING, "Memory allocation failure\n");
-               LOCAL_USER_REMOVE(u);
-               return -1;
-       }
+       parse = ast_strdupa(data);
        
        AST_STANDARD_APP_ARGS(args, parse);
 
        if (!ast_strlen_zero(args.options)) {
                if (ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options)) {
+                       pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
                        LOCAL_USER_REMOVE(u);
                        return -1;
                }
@@ -802,6 +800,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
 
        if (ast_strlen_zero(args.peers)) {
                ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
+               pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
                LOCAL_USER_REMOVE(u);
                return -1;
        }
index 1efd4bbb4d346f20afcd98624870153780a523e5..8987de09633e7928a5b0cca57ad74c3b4ca159fa 100644 (file)
@@ -139,6 +139,7 @@ static struct ast_conference {
        struct ast_conf_user *firstuser;        /* Pointer to the first user struct */
        struct ast_conf_user *lastuser;         /* Pointer to the last user struct */
        time_t start;                           /* Start time (s) */
+       int refcount;
        int recording;                          /* recording status */
        int isdynamic;                          /* Created on the fly? */
        int locked;                             /* Is the conference locked? */
@@ -438,7 +439,7 @@ static void conf_play(struct ast_channel *chan, struct ast_conference *conf, int
                ast_autoservice_stop(chan);
 }
 
-static struct ast_conference *build_conf(char *confno, char *pin, char *pinadmin, int make, int dynamic)
+static struct ast_conference *build_conf(char *confno, char *pin, char *pinadmin, int make, int dynamic, int refcount)
 {
        struct ast_conference *cnf;
        struct zt_confinfo ztc;
@@ -501,6 +502,8 @@ static struct ast_conference *build_conf(char *confno, char *pin, char *pinadmin
                        ast_log(LOG_WARNING, "Out of memory\n");
        }
  cnfout:
+       if (cnf)
+               ast_atomic_fetchadd_int(&cnf->refcount, refcount);
        ast_mutex_unlock(&conflock);
        return cnf;
 }
@@ -835,6 +838,8 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
        
        if (!user) {
                ast_log(LOG_ERROR, "Out of memory\n");
+               if (ast_atomic_dec_and_test(&conf->refcount))
+                       conf_free(conf);
                return ret;
        }
 
@@ -1601,9 +1606,10 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
                              "Usernum: %d\r\n",
                              chan->name, chan->uniqueid, conf->confno, user->user_no);
                conf->users--;
+               ast_atomic_fetchadd_int(&conf->refcount, -1);
                if (confflags & CONFFLAG_MARKEDUSER) 
                        conf->markedusers--;
-               if (!conf->users) {
+               if (!conf->users && !conf->refcount) {
                        /* No more users -- close this one out */
                        conf_free(conf);
                } else {
@@ -1646,7 +1652,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
 }
 
 static struct ast_conference *find_conf(struct ast_channel *chan, char *confno, int make, int dynamic, char *dynamic_pin,
-                                       struct ast_flags *confflags)
+       int refcount, struct ast_flags *confflags)
 {
        struct ast_config *cfg;
        struct ast_variable *var;
@@ -1658,6 +1664,8 @@ static struct ast_conference *find_conf(struct ast_channel *chan, char *confno,
                if (!strcmp(confno, cnf->confno)) 
                        break;
        }
+       if (cnf)
+               ast_atomic_fetchadd_int(&cnf->refcount, refcount);
        ast_mutex_unlock(&conflock);
 
        if (!cnf) {
@@ -1670,9 +1678,9 @@ static struct ast_conference *find_conf(struct ast_channel *chan, char *confno,
                                        if (ast_app_getdata(chan, "conf-getpin", dynamic_pin, AST_MAX_EXTENSION - 1, 0) < 0)
                                                return NULL;
                                }
-                               cnf = build_conf(confno, dynamic_pin, "", make, dynamic);
+                               cnf = build_conf(confno, dynamic_pin, "", make, dynamic, refcount);
                        } else {
-                               cnf = build_conf(confno, "", "", make, dynamic);
+                               cnf = build_conf(confno, "", "", make, dynamic, refcount);
                        }
                } else {
                        /* Check the config */
@@ -1694,14 +1702,14 @@ static struct ast_conference *find_conf(struct ast_channel *chan, char *confno,
                                                        /* Bingo it's a valid conference */
                                                        if (pin)
                                                                if (pinadmin)
-                                                                       cnf = build_conf(confno, pin, pinadmin, make, dynamic);
+                                                                       cnf = build_conf(confno, pin, pinadmin, make, dynamic, refcount);
                                                                else
-                                                                       cnf = build_conf(confno, pin, "", make, dynamic);
+                                                                       cnf = build_conf(confno, pin, "", make, dynamic, refcount);
                                                        else
                                                                if (pinadmin)
-                                                                       cnf = build_conf(confno, "", pinadmin, make, dynamic);
+                                                                       cnf = build_conf(confno, "", pinadmin, make, dynamic, refcount);
                                                                else
-                                                                       cnf = build_conf(confno, "", "", make, dynamic);
+                                                                       cnf = build_conf(confno, "", "", make, dynamic, refcount);
                                                        break;
                                                }
                                        }
@@ -1764,10 +1772,11 @@ static int count_exec(struct ast_channel *chan, void *data)
        }
        
        confnum = strsep(&localdata,"|");       
-       conf = find_conf(chan, confnum, 0, 0, NULL, NULL);
-       if (conf)
+       conf = find_conf(chan, confnum, 0, 0, NULL, 1, NULL);
+       if (conf) {
                count = conf->users;
-       else
+               ast_atomic_fetchadd_int(&conf->refcount, -1);
+       } else
                count = 0;
 
        if (!ast_strlen_zero(localdata)){
@@ -1952,7 +1961,7 @@ static int conf_exec(struct ast_channel *chan, void *data)
                }
                if (!ast_strlen_zero(confno)) {
                        /* Check the validity of the conference */
-                       cnf = find_conf(chan, confno, 1, dynamic, the_pin, &confflags);
+                       cnf = find_conf(chan, confno, 1, dynamic, the_pin, 1, &confflags);
                        if (!cnf) {
                                res = ast_streamfile(chan, "conf-invalid", chan->language);
                                if (!res)
@@ -1998,8 +2007,13 @@ static int conf_exec(struct ast_channel *chan, void *data)
                                                                        ast_log(LOG_WARNING, "Couldn't play invalid pin msg!\n");
                                                                        break;
                                                                }
-                                                               if (res < 0)
+                                                               if (res < 0) {
+                                                                       ast_mutex_lock(&conflock);
+                                                                       if (ast_atomic_dec_and_test(&cnf->refcount))
+                                                                               conf_free(cnf);
+                                                                       ast_mutex_unlock(&conflock);
                                                                        break;
+                                                               }
                                                                pin[0] = res;
                                                                pin[1] = '\0';
                                                                res = -1;
@@ -2012,9 +2026,8 @@ static int conf_exec(struct ast_channel *chan, void *data)
                                                        allowretry = 0;
                                                        /* see if we need to get rid of the conference */
                                                        ast_mutex_lock(&conflock);
-                                                       if (!cnf->users) {
+                                                       if (ast_atomic_dec_and_test(&cnf->refcount))
                                                                conf_free(cnf); 
-                                                       }
                                                        ast_mutex_unlock(&conflock);
                                                        break;
                                                }
index dc9cf9a280de2581f691f20c2dabd2720ba9fdc6..67deba4dd6357290119ec6fdae64fee12f229b6d 100644 (file)
@@ -666,4 +666,31 @@ static inline int ast_cond_timedwait(ast_cond_t *cond, ast_mutex_t *t, const str
 #define pthread_create __use_ast_pthread_create_instead__
 #endif
 
+int ast_atomic_fetchadd_int_slow(volatile int *p, int v);
+
+#include "asterisk/inline_api.h"
+
+#if defined (__i386__)
+AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
+{
+       __asm __volatile (
+       "       lock   xaddl   %0, %1 ;        "
+       : "+r" (v),                     /* 0 (result) */   
+         "=m" (*p)                     /* 1 */
+       : "m" (*p));                    /* 2 */
+       return (v);
+})
+#else   /* low performance version in utils.c */
+AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
+{
+       return ast_atomic_fetchadd_int_slow(p, v);
+})
+#endif
+
+AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
+{
+       int a = ast_atomic_fetchadd_int(p, -1);
+       return a == 1; /* true if the value is 0 now (so it was 1 previously) */
+})
+
 #endif /* _ASTERISK_LOCK_H */
diff --git a/utils.c b/utils.c
index 6b3680b8fa29bb5254af16d7df5b0537e4cdb644..321f9113ab170bc0a380e76d55408f4aab40f23d 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -907,3 +907,14 @@ void ast_enable_packet_fragmentation(int sock)
 #endif
 }
 
+AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
+
+int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
+{
+        int ret;
+        ast_mutex_lock(&fetchadd_m);
+        ret = *p;
+        *p += v;
+        ast_mutex_unlock(&fetchadd_m);
+        return ret;
+}