]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Trying to remove a non-dynamic queue member via dynamic means can lead to some
authorMark Michelson <mmichelson@digium.com>
Tue, 16 Oct 2007 21:14:34 +0000 (21:14 +0000)
committerMark Michelson <mmichelson@digium.com>
Tue, 16 Oct 2007 21:14:34 +0000 (21:14 +0000)
interesting (read nasty) situations. This patch clears up the issue by making
only dynamic queue members removable via dynamic methods.

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

apps/app_queue.c

index 3fee3f28bfafe02a87f5099bbcc17e71e5e3867c..b178a9b999f69e5ea5bbacde98a0d30fe06f7529 100644 (file)
@@ -124,6 +124,7 @@ static struct strategy {
 #define        RES_EXISTS      (-1)            /* Entry already exists */
 #define        RES_OUTOFMEMORY (-2)            /* Out of memory */
 #define        RES_NOSUCHQUEUE (-3)            /* No such queue */
+#define RES_NOT_DYNAMIC (-4)           /* Member is not dynamic */
 
 static char *app = "Queue";
 
@@ -2962,13 +2963,21 @@ static int remove_from_queue(const char *queuename, const char *interface)
                        continue;
                }
 
-               if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER | OBJ_UNLINK))) {
+               if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER))) {
+                       /* XXX future changes should beware of this assumption!! */
+                       if(!mem->dynamic) {
+                               res = RES_NOT_DYNAMIC;
+                               ao2_ref(mem, -1);
+                               ast_mutex_unlock(&q->lock);
+                               break;
+                       }
                        q->membercount--;
                        manager_event(EVENT_FLAG_AGENT, "QueueMemberRemoved",
                                "Queue: %s\r\n"
                                "Location: %s\r\n"
                                "MemberName: %s\r\n",
                                q->name, mem->interface, mem->membername);
+                       ao2_unlink(q->members, mem);
                        ao2_ref(mem, -1);
 
                        if (queue_persistent_members)
@@ -3345,6 +3354,11 @@ static int rqm_exec(struct ast_channel *chan, void *data)
                pbx_builtin_setvar_helper(chan, "RQMSTATUS", "NOSUCHQUEUE");
                res = 0;
                break;
+       case RES_NOT_DYNAMIC:
+               ast_log(LOG_WARNING, "Unable to remove interface from queue '%s': '%s' is not a dynamic member\n", args.queuename, args.interface);
+               pbx_builtin_setvar_helper(chan, "RQMSTATUS", "NOTDYNAMIC");
+               res = 0;
+               break;
        }
 
        ast_module_user_remove(lu);
@@ -4411,6 +4425,9 @@ static int manager_remove_queue_member(struct mansession *s, const struct messag
        case RES_OUTOFMEMORY:
                astman_send_error(s, m, "Out of memory");
                break;
+       case RES_NOT_DYNAMIC:
+               astman_send_error(s, m, "Member not dynamic");
+               break;
        }
 
        return 0;
@@ -4551,6 +4568,9 @@ static int handle_queue_remove_member(int fd, int argc, char *argv[])
        case RES_OUTOFMEMORY:
                ast_cli(fd, "Out of memory\n");
                return RESULT_FAILURE;
+       case RES_NOT_DYNAMIC:
+               ast_cli(fd, "Member not dynamic\n");
+               return RESULT_FAILURE;
        default:
                return RESULT_FAILURE;
        }