add a QueueLog application that allows for custom entries in the queue_log
[asterisk/asterisk.git] / apps / app_queue.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief True call queues with optional send URL on answer
22  *
23  * \author Mark Spencer <markster@digium.com>
24  *
25  * \arg Config in \ref Config_qu queues.conf
26  *
27  * \par Development notes
28  * \note 2004-11-25: Persistent Dynamic Members added by:
29  *             NetNation Communications (www.netnation.com)
30  *             Kevin Lindsay <kevinl@netnation.com>
31  *
32  *             Each dynamic agent in each queue is now stored in the astdb.
33  *             When asterisk is restarted, each agent will be automatically
34  *             readded into their recorded queues. This feature can be
35  *             configured with the 'persistent_members=<1|0>' setting in the
36  *             '[general]' category in queues.conf. The default is on.
37  *
38  * \note 2004-06-04: Priorities in queues added by inAccess Networks (work funded by Hellas On Line (HOL) www.hol.gr).
39  *
40  * \note These features added by David C. Troy <dave@toad.net>:
41  *    - Per-queue holdtime calculation
42  *    - Estimated holdtime announcement
43  *    - Position announcement
44  *    - Abandoned/completed call counters
45  *    - Failout timer passed as optional app parameter
46  *    - Optional monitoring of calls, started when call is answered
47  *
48  * Patch Version 1.07 2003-12-24 01
49  *
50  * Added servicelevel statistic by Michiel Betel <michiel@betel.nl>
51  * Added Priority jumping code for adding and removing queue members by Jonathan Stanton <asterisk@doilooklikeicare.com>
52  *
53  * Fixed to work with CVS as of 2004-02-25 and released as 1.07a
54  * by Matthew Enger <m.enger@xi.com.au>
55  *
56  * \ingroup applications
57  */
58
59 #include "asterisk.h"
60
61 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
62
63 #include <stdlib.h>
64 #include <errno.h>
65 #include <unistd.h>
66 #include <string.h>
67 #include <stdlib.h>
68 #include <stdio.h>
69 #include <sys/time.h>
70 #include <sys/signal.h>
71 #include <netinet/in.h>
72
73 #include "asterisk/lock.h"
74 #include "asterisk/file.h"
75 #include "asterisk/logger.h"
76 #include "asterisk/channel.h"
77 #include "asterisk/pbx.h"
78 #include "asterisk/options.h"
79 #include "asterisk/app.h"
80 #include "asterisk/linkedlists.h"
81 #include "asterisk/module.h"
82 #include "asterisk/translate.h"
83 #include "asterisk/say.h"
84 #include "asterisk/features.h"
85 #include "asterisk/musiconhold.h"
86 #include "asterisk/cli.h"
87 #include "asterisk/manager.h"
88 #include "asterisk/config.h"
89 #include "asterisk/monitor.h"
90 #include "asterisk/utils.h"
91 #include "asterisk/causes.h"
92 #include "asterisk/astdb.h"
93 #include "asterisk/devicestate.h"
94 #include "asterisk/stringfields.h"
95
96 enum {
97         QUEUE_STRATEGY_RINGALL = 0,
98         QUEUE_STRATEGY_ROUNDROBIN,
99         QUEUE_STRATEGY_LEASTRECENT,
100         QUEUE_STRATEGY_FEWESTCALLS,
101         QUEUE_STRATEGY_RANDOM,
102         QUEUE_STRATEGY_RRMEMORY
103 };
104
105 static struct strategy {
106         int strategy;
107         char *name;
108 } strategies[] = {
109         { QUEUE_STRATEGY_RINGALL, "ringall" },
110         { QUEUE_STRATEGY_ROUNDROBIN, "roundrobin" },
111         { QUEUE_STRATEGY_LEASTRECENT, "leastrecent" },
112         { QUEUE_STRATEGY_FEWESTCALLS, "fewestcalls" },
113         { QUEUE_STRATEGY_RANDOM, "random" },
114         { QUEUE_STRATEGY_RRMEMORY, "rrmemory" },
115 };
116
117 #define DEFAULT_RETRY           5
118 #define DEFAULT_TIMEOUT         15
119 #define RECHECK                 1               /* Recheck every second to see we we're at the top yet */
120 #define MAX_PERIODIC_ANNOUNCEMENTS 10 /* The maximum periodic announcements we can have */
121
122 #define RES_OKAY        0               /* Action completed */
123 #define RES_EXISTS      (-1)            /* Entry already exists */
124 #define RES_OUTOFMEMORY (-2)            /* Out of memory */
125 #define RES_NOSUCHQUEUE (-3)            /* No such queue */
126
127 static char *tdesc = "True Call Queueing";
128
129 static char *app = "Queue";
130
131 static char *synopsis = "Queue a call for a call queue";
132
133 static char *descrip =
134 "  Queue(queuename[|options[|URL][|announceoverride][|timeout][|AGI]):\n"
135 "Queues an incoming call in a particular call queue as defined in queues.conf.\n"
136 "This application will return to the dialplan if the queue does not exist, or\n"
137 "any of the join options cause the caller to not enter the queue.\n"
138 "The option string may contain zero or more of the following characters:\n"
139 "      'd' -- data-quality (modem) call (minimum delay).\n"
140 "      'h' -- allow callee to hang up by hitting *.\n"
141 "      'H' -- allow caller to hang up by hitting *.\n"
142 "      'n' -- no retries on the timeout; will exit this application and \n"
143 "             go to the next step.\n"
144 "      'r' -- ring instead of playing MOH\n"
145 "      't' -- allow the called user transfer the calling user\n"
146 "      'T' -- to allow the calling user to transfer the call.\n"
147 "      'w' -- allow the called user to write the conversation to disk via Monitor\n"
148 "      'W' -- allow the calling user to write the conversation to disk via Monitor\n"
149 "  In addition to transferring the call, a call may be parked and then picked\n"
150 "up by another user.\n"
151 "  The optional URL will be sent to the called party if the channel supports\n"
152 "it.\n"
153 "  The optional AGI parameter will setup an AGI script to be executed on the \n"
154 "calling party's channel once they are connected to a queue member.\n"
155 "  The timeout will cause the queue to fail out after a specified number of\n"
156 "seconds, checked between each queues.conf 'timeout' and 'retry' cycle.\n"
157 "  This application sets the following channel variable upon completion:\n"
158 "      QUEUESTATUS    The status of the call as a text string, one of\n"
159 "             TIMEOUT | FULL | JOINEMPTY | LEAVEEMPTY | JOINUNAVAIL | LEAVEUNAVAIL\n";
160
161 static char *app_aqm = "AddQueueMember" ;
162 static char *app_aqm_synopsis = "Dynamically adds queue members" ;
163 static char *app_aqm_descrip =
164 "   AddQueueMember(queuename[|interface[|penalty[|options]]]):\n"
165 "Dynamically adds interface to an existing queue.\n"
166 "If the interface is already in the queue and there exists an n+101 priority\n"
167 "then it will then jump to this priority.  Otherwise it will return an error\n"
168 "The option string may contain zero or more of the following characters:\n"
169 "       'j' -- jump to +101 priority when appropriate.\n"
170 "  This application sets the following channel variable upon completion:\n"
171 "     AQMSTATUS    The status of the attempt to add a queue member as a \n"
172 "                     text string, one of\n"
173 "           ADDED | MEMBERALREADY | NOSUCHQUEUE \n"
174 "Example: AddQueueMember(techsupport|SIP/3000)\n"
175 "";
176
177 static char *app_rqm = "RemoveQueueMember" ;
178 static char *app_rqm_synopsis = "Dynamically removes queue members" ;
179 static char *app_rqm_descrip =
180 "   RemoveQueueMember(queuename[|interface[|options]]):\n"
181 "Dynamically removes interface to an existing queue\n"
182 "If the interface is NOT in the queue and there exists an n+101 priority\n"
183 "then it will then jump to this priority.  Otherwise it will return an error\n"
184 "The option string may contain zero or more of the following characters:\n"
185 "       'j' -- jump to +101 priority when appropriate.\n"
186 "  This application sets the following channel variable upon completion:\n"
187 "     RQMSTATUS      The status of the attempt to remove a queue member as a\n"
188 "                     text string, one of\n"
189 "           REMOVED | NOTINQUEUE | NOSUCHQUEUE \n"
190 "Example: RemoveQueueMember(techsupport|SIP/3000)\n"
191 "";
192
193 static char *app_pqm = "PauseQueueMember" ;
194 static char *app_pqm_synopsis = "Pauses a queue member" ;
195 static char *app_pqm_descrip =
196 "   PauseQueueMember([queuename]|interface[|options]):\n"
197 "Pauses (blocks calls for) a queue member.\n"
198 "The given interface will be paused in the given queue.  This prevents\n"
199 "any calls from being sent from the queue to the interface until it is\n"
200 "unpaused with UnpauseQueueMember or the manager interface.  If no\n"
201 "queuename is given, the interface is paused in every queue it is a\n"
202 "member of.  If the interface is not in the named queue, or if no queue\n"
203 "is given and the interface is not in any queue, it will jump to\n"
204 "priority n+101, if it exists and the appropriate options are set.\n"
205 "The application will fail if the interface is not found and no extension\n"
206 "to jump to exists.\n"
207 "The option string may contain zero or more of the following characters:\n"
208 "       'j' -- jump to +101 priority when appropriate.\n"
209 "  This application sets the following channel variable upon completion:\n"
210 "     PQMSTATUS      The status of the attempt to pause a queue member as a\n"
211 "                     text string, one of\n"
212 "           PAUSED | NOTFOUND\n"
213 "Example: PauseQueueMember(|SIP/3000)\n";
214
215 static char *app_upqm = "UnpauseQueueMember" ;
216 static char *app_upqm_synopsis = "Unpauses a queue member" ;
217 static char *app_upqm_descrip =
218 "   UnpauseQueueMember([queuename]|interface[|options]):\n"
219 "Unpauses (resumes calls to) a queue member.\n"
220 "This is the counterpart to PauseQueueMember and operates exactly the\n"
221 "same way, except it unpauses instead of pausing the given interface.\n"
222 "The option string may contain zero or more of the following characters:\n"
223 "       'j' -- jump to +101 priority when appropriate.\n"
224 "  This application sets the following channel variable upon completion:\n"
225 "     UPQMSTATUS       The status of the attempt to unpause a queue \n"
226 "                      member as a text string, one of\n"
227 "            UNPAUSED | NOTFOUND\n"
228 "Example: UnpauseQueueMember(|SIP/3000)\n";
229
230 static char *app_ql = "QueueLog" ;
231 static char *app_ql_synopsis = "Writes to the queue_log" ;
232 static char *app_ql_descrip =
233 "   QueueLog(queuename|uniqueid|agent|event[|additionalinfo]):\n"
234 "Allows you to write your own events into the queue log\n"
235 "Example: QueueLog(101|${UNIQUEID}|${AGENT}|WENTONBREAK|600)\n";
236
237 /*! \brief Persistent Members astdb family */
238 static const char *pm_family = "/Queue/PersistentMembers";
239 /* The maximum length of each persistent member queue database entry */
240 #define PM_MAX_LEN 2048
241
242 /*! \brief queues.conf [general] option */
243 static int queue_persistent_members = 0;
244
245 /*! \brief queues.conf per-queue weight option */
246 static int use_weight = 0;
247
248 /*! \brief queues.conf [general] option */
249 static int autofill_default = 0;
250
251 /*! \brief queues.conf [general] option */
252 static int montype_default = 0;
253
254 enum queue_result {
255         QUEUE_UNKNOWN = 0,
256         QUEUE_TIMEOUT = 1,
257         QUEUE_JOINEMPTY = 2,
258         QUEUE_LEAVEEMPTY = 3,
259         QUEUE_JOINUNAVAIL = 4,
260         QUEUE_LEAVEUNAVAIL = 5,
261         QUEUE_FULL = 6,
262 };
263
264 const struct {
265         enum queue_result id;
266         char *text;
267 } queue_results[] = {
268         { QUEUE_UNKNOWN, "UNKNOWN" },
269         { QUEUE_TIMEOUT, "TIMEOUT" },
270         { QUEUE_JOINEMPTY,"JOINEMPTY" },
271         { QUEUE_LEAVEEMPTY, "LEAVEEMPTY" },
272         { QUEUE_JOINUNAVAIL, "JOINUNAVAIL" },
273         { QUEUE_LEAVEUNAVAIL, "LEAVEUNAVAIL" },
274         { QUEUE_FULL, "FULL" },
275 };
276
277 /*! \brief We define a custom "local user" structure because we
278    use it not only for keeping track of what is in use but
279    also for keeping track of who we're dialing. */
280
281 struct callattempt {
282         struct callattempt *q_next;
283         struct ast_channel *chan;
284         char interface[256];
285         int stillgoing;
286         int metric;
287         int oldstatus;
288         time_t lastcall;
289         struct member *member;
290 };
291
292 LOCAL_USER_DECL;
293
294 struct queue_ent {
295         struct call_queue *parent;          /*!< What queue is our parent */
296         char moh[80];                       /*!< Name of musiconhold to be used */
297         char announce[80];                  /*!< Announcement to play for member when call is answered */
298         char context[AST_MAX_CONTEXT];      /*!< Context when user exits queue */
299         char digits[AST_MAX_EXTENSION];     /*!< Digits entered while in queue */
300         int pos;                            /*!< Where we are in the queue */
301         int prio;                           /*!< Our priority */
302         int last_pos_said;                  /*!< Last position we told the user */
303         time_t last_periodic_announce_time; /*!< The last time we played a periodic announcement */
304         int last_periodic_announce_sound;   /*!< The last periodic announcement we made */
305         time_t last_pos;                    /*!< Last time we told the user their position */
306         int opos;                           /*!< Where we started in the queue */
307         int handled;                        /*!< Whether our call was handled */
308         int max_penalty;                    /*!< Limit the members that can take this call to this penalty or lower */
309         time_t start;                       /*!< When we started holding */
310         time_t expire;                      /*!< When this entry should expire (time out of queue) */
311         struct ast_channel *chan;           /*!< Our channel */
312         struct queue_ent *next;             /*!< The next queue entry */
313 };
314
315 struct member {
316         char interface[80];                 /*!< Technology/Location */
317         int penalty;                        /*!< Are we a last resort? */
318         int calls;                          /*!< Number of calls serviced by this member */
319         int dynamic;                        /*!< Are we dynamically added? */
320         int status;                         /*!< Status of queue member */
321         int paused;                         /*!< Are we paused (not accepting calls)? */
322         time_t lastcall;                    /*!< When last successful call was hungup */
323         unsigned int dead:1;                /*!< Used to detect members deleted in realtime */
324         unsigned int delme:1;               /*!< Flag to delete entry on reload */
325         struct member *next;                /*!< Next member */
326 };
327
328 struct member_interface {
329         char interface[80];
330         AST_LIST_ENTRY(member_interface) list;    /*!< Next call queue */
331 };
332
333 static AST_LIST_HEAD_STATIC(interfaces, member_interface);
334
335 /* values used in multi-bit flags in call_queue */
336 #define QUEUE_EMPTY_NORMAL 1
337 #define QUEUE_EMPTY_STRICT 2
338 #define ANNOUNCEHOLDTIME_ALWAYS 1
339 #define ANNOUNCEHOLDTIME_ONCE 2
340 #define QUEUE_EVENT_VARIABLES 3
341
342 struct call_queue {
343         ast_mutex_t lock;       
344         char name[80];                      /*!< Name */
345         char moh[80];                       /*!< Music On Hold class to be used */
346         char announce[80];                  /*!< Announcement to play when call is answered */
347         char context[AST_MAX_CONTEXT];      /*!< Exit context */
348         unsigned int monjoin:1;
349         unsigned int dead:1;
350         unsigned int joinempty:2;
351         unsigned int eventwhencalled:2;
352         unsigned int leavewhenempty:2;
353         unsigned int ringinuse:1;
354         unsigned int setinterfacevar:1;
355         unsigned int reportholdtime:1;
356         unsigned int wrapped:1;
357         unsigned int timeoutrestart:1;
358         unsigned int announceholdtime:2;
359         unsigned int strategy:3;
360         unsigned int maskmemberstatus:1;
361         unsigned int realtime:1;
362         int announcefrequency;              /*!< How often to announce their position */
363         int periodicannouncefrequency;      /*!< How often to play periodic announcement */
364         int roundingseconds;                /*!< How many seconds do we round to? */
365         int holdtime;                       /*!< Current avg holdtime, based on recursive boxcar filter */
366         int callscompleted;                 /*!< Number of queue calls completed */
367         int callsabandoned;                 /*!< Number of queue calls abandoned */
368         int servicelevel;                   /*!< seconds setting for servicelevel*/
369         int callscompletedinsl;             /*!< Number of calls answered with servicelevel*/
370         char monfmt[8];                     /*!< Format to use when recording calls */
371         int montype;                        /*!< Monitor type  Monitor vs. MixMonitor */
372         char sound_next[80];                /*!< Sound file: "Your call is now first in line" (def. queue-youarenext) */
373         char sound_thereare[80];            /*!< Sound file: "There are currently" (def. queue-thereare) */
374         char sound_calls[80];               /*!< Sound file: "calls waiting to speak to a representative." (def. queue-callswaiting)*/
375         char sound_holdtime[80];            /*!< Sound file: "The current estimated total holdtime is" (def. queue-holdtime) */
376         char sound_minutes[80];             /*!< Sound file: "minutes." (def. queue-minutes) */
377         char sound_lessthan[80];            /*!< Sound file: "less-than" (def. queue-lessthan) */
378         char sound_seconds[80];             /*!< Sound file: "seconds." (def. queue-seconds) */
379         char sound_thanks[80];              /*!< Sound file: "Thank you for your patience." (def. queue-thankyou) */
380         char sound_reporthold[80];          /*!< Sound file: "Hold time" (def. queue-reporthold) */
381         char sound_periodicannounce[MAX_PERIODIC_ANNOUNCEMENTS][80];/*!< Sound files: Custom announce, no default */
382
383         int count;                          /*!< How many entries */
384         int maxlen;                         /*!< Max number of entries */
385         int wrapuptime;                     /*!< Wrapup Time */
386
387         int retry;                          /*!< Retry calling everyone after this amount of time */
388         int timeout;                        /*!< How long to wait for an answer */
389         int weight;                         /*!< Respective weight */
390         int autopause;                      /*!< Auto pause queue members if they fail to answer */
391
392         /* Queue strategy things */
393         int rrpos;                          /*!< Round Robin - position */
394         int memberdelay;                    /*!< Seconds to delay connecting member to caller */
395         int autofill;                       /*!< Ignore the head call status and ring an available agent */
396         
397         struct member *members;             /*!< Head of the list of members */
398         struct queue_ent *head;             /*!< Head of the list of callers */
399         AST_LIST_ENTRY(call_queue) list;    /*!< Next call queue */
400 };
401
402 static AST_LIST_HEAD_STATIC(queues, call_queue);
403
404 static int set_member_paused(char *queuename, char *interface, int paused);
405
406 static void rr_dep_warning(void)
407 {
408         static unsigned int warned = 0;
409
410         if (!warned) {
411                 ast_log(LOG_NOTICE, "The 'roundrobin' queue strategy is deprecated. Please use the 'rrmemory' strategy instead.\n");
412                 warned = 1;
413         }
414 }
415
416 static void set_queue_result(struct ast_channel *chan, enum queue_result res)
417 {
418         int i;
419
420         for (i = 0; i < sizeof(queue_results) / sizeof(queue_results[0]); i++) {
421                 if (queue_results[i].id == res) {
422                         pbx_builtin_setvar_helper(chan, "QUEUESTATUS", queue_results[i].text);
423                         return;
424                 }
425         }
426 }
427
428 static char *int2strat(int strategy)
429 {
430         int x;
431
432         for (x = 0; x < sizeof(strategies) / sizeof(strategies[0]); x++) {
433                 if (strategy == strategies[x].strategy)
434                         return strategies[x].name;
435         }
436
437         return "<unknown>";
438 }
439
440 static int strat2int(const char *strategy)
441 {
442         int x;
443
444         for (x = 0; x < sizeof(strategies) / sizeof(strategies[0]); x++) {
445                 if (!strcasecmp(strategy, strategies[x].name))
446                         return strategies[x].strategy;
447         }
448
449         return -1;
450 }
451
452 /*! \brief Insert the 'new' entry after the 'prev' entry of queue 'q' */
453 static inline void insert_entry(struct call_queue *q, struct queue_ent *prev, struct queue_ent *new, int *pos)
454 {
455         struct queue_ent *cur;
456
457         if (!q || !new)
458                 return;
459         if (prev) {
460                 cur = prev->next;
461                 prev->next = new;
462         } else {
463                 cur = q->head;
464                 q->head = new;
465         }
466         new->next = cur;
467         new->parent = q;
468         new->pos = ++(*pos);
469         new->opos = *pos;
470 }
471
472 enum queue_member_status {
473         QUEUE_NO_MEMBERS,
474         QUEUE_NO_REACHABLE_MEMBERS,
475         QUEUE_NORMAL
476 };
477
478 static enum queue_member_status get_member_status(const struct call_queue *q, int max_penalty)
479 {
480         struct member *member;
481         enum queue_member_status result = QUEUE_NO_MEMBERS;
482
483         for (member = q->members; member; member = member->next) {
484                 if (max_penalty && (member->penalty > max_penalty))
485                         continue;
486
487                 if (member->paused) continue;
488
489                 switch (member->status) {
490                 case AST_DEVICE_INVALID:
491                         /* nothing to do */
492                         break;
493                 case AST_DEVICE_UNAVAILABLE:
494                         result = QUEUE_NO_REACHABLE_MEMBERS;
495                         break;
496                 default:
497                         return QUEUE_NORMAL;
498                 }
499         }
500         
501         return result;
502 }
503
504 struct statechange {
505         int state;
506         char dev[0];
507 };
508
509 static void *changethread(void *data)
510 {
511         struct call_queue *q;
512         struct statechange *sc = data;
513         struct member *cur;
514         struct member_interface *curint;
515         char *loc;
516         char *technology;
517
518         technology = ast_strdupa(sc->dev);
519         loc = strchr(technology, '/');
520         if (loc) {
521                 *loc++ = '\0';
522         } else {
523                 free(sc);
524                 return NULL;
525         }
526
527         AST_LIST_LOCK(&interfaces);
528         AST_LIST_TRAVERSE(&interfaces, curint, list) {
529                 if (!strcasecmp(curint->interface, sc->dev))
530                         break;
531         }
532         AST_LIST_UNLOCK(&interfaces);
533
534         if (!curint) {
535                 if (option_debug)
536                         ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s) but we don't care because they're not a member of any queue.\n", technology, loc, sc->state, devstate2str(sc->state));
537                 free(sc);
538                 return NULL;
539         }
540
541         if (option_debug)
542                 ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state));
543         AST_LIST_LOCK(&queues);
544         AST_LIST_TRAVERSE(&queues, q, list) {
545                 ast_mutex_lock(&q->lock);
546                 for (cur = q->members; cur; cur = cur->next) {
547                         if (strcasecmp(sc->dev, cur->interface))
548                                 continue;
549
550                         if (cur->status != sc->state) {
551                                 cur->status = sc->state;
552                                 if (q->maskmemberstatus)
553                                         continue;
554
555                                 manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
556                                         "Queue: %s\r\n"
557                                         "Location: %s\r\n"
558                                         "Membership: %s\r\n"
559                                         "Penalty: %d\r\n"
560                                         "CallsTaken: %d\r\n"
561                                         "LastCall: %d\r\n"
562                                         "Status: %d\r\n"
563                                         "Paused: %d\r\n",
564                                         q->name, cur->interface, cur->dynamic ? "dynamic" : "static",
565                                         cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
566                         }
567                 }
568                 ast_mutex_unlock(&q->lock);
569         }
570         AST_LIST_UNLOCK(&queues);
571
572         return NULL;
573 }
574
575 static int statechange_queue(const char *dev, int state, void *ign)
576 {
577         /* Avoid potential for deadlocks by spawning a new thread to handle
578            the event */
579         struct statechange *sc;
580         pthread_t t;
581         pthread_attr_t attr;
582
583         if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(dev) + 1)))
584                 return 0;
585
586         sc->state = state;
587         strcpy(sc->dev, dev);
588         pthread_attr_init(&attr);
589         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
590         if (ast_pthread_create(&t, &attr, changethread, sc)) {
591                 ast_log(LOG_WARNING, "Failed to create update thread!\n");
592                 free(sc);
593         }
594
595         return 0;
596 }
597
598 static struct member *create_queue_member(char *interface, int penalty, int paused)
599 {
600         struct member *cur;
601         
602         if ((cur = ast_calloc(1, sizeof(*cur)))) {
603                 cur->penalty = penalty;
604                 cur->paused = paused;
605                 ast_copy_string(cur->interface, interface, sizeof(cur->interface));
606                 if (!strchr(cur->interface, '/'))
607                         ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
608                 cur->status = ast_device_state(interface);
609         }
610
611         return cur;
612 }
613
614 static struct call_queue *alloc_queue(const char *queuename)
615 {
616         struct call_queue *q;
617
618         if ((q = ast_calloc(1, sizeof(*q)))) {
619                 ast_mutex_init(&q->lock);
620                 ast_copy_string(q->name, queuename, sizeof(q->name));
621         }
622         return q;
623 }
624
625 static void init_queue(struct call_queue *q)
626 {
627         int i;
628
629         q->dead = 0;
630         q->retry = DEFAULT_RETRY;
631         q->timeout = -1;
632         q->maxlen = 0;
633         q->announcefrequency = 0;
634         q->announceholdtime = 0;
635         q->roundingseconds = 0; /* Default - don't announce seconds */
636         q->servicelevel = 0;
637         q->ringinuse = 1;
638         q->setinterfacevar = 0;
639         q->autofill = autofill_default;
640         q->montype = montype_default;
641         q->moh[0] = '\0';
642         q->announce[0] = '\0';
643         q->context[0] = '\0';
644         q->monfmt[0] = '\0';
645         q->periodicannouncefrequency = 0;
646         ast_copy_string(q->sound_next, "queue-youarenext", sizeof(q->sound_next));
647         ast_copy_string(q->sound_thereare, "queue-thereare", sizeof(q->sound_thereare));
648         ast_copy_string(q->sound_calls, "queue-callswaiting", sizeof(q->sound_calls));
649         ast_copy_string(q->sound_holdtime, "queue-holdtime", sizeof(q->sound_holdtime));
650         ast_copy_string(q->sound_minutes, "queue-minutes", sizeof(q->sound_minutes));
651         ast_copy_string(q->sound_seconds, "queue-seconds", sizeof(q->sound_seconds));
652         ast_copy_string(q->sound_thanks, "queue-thankyou", sizeof(q->sound_thanks));
653         ast_copy_string(q->sound_lessthan, "queue-less-than", sizeof(q->sound_lessthan));
654         ast_copy_string(q->sound_reporthold, "queue-reporthold", sizeof(q->sound_reporthold));
655         ast_copy_string(q->sound_periodicannounce[0], "queue-periodic-announce", sizeof(q->sound_periodicannounce[0]));
656         for (i = 1; i < MAX_PERIODIC_ANNOUNCEMENTS; i++) {
657                 q->sound_periodicannounce[i][0]='\0';
658         }
659 }
660
661 static void clear_queue(struct call_queue *q)
662 {
663         q->holdtime = 0;
664         q->callscompleted = 0;
665         q->callsabandoned = 0;
666         q->callscompletedinsl = 0;
667         q->wrapuptime = 0;
668 }
669
670 static int add_to_interfaces(char *interface)
671 {
672         struct member_interface *curint;
673
674         AST_LIST_LOCK(&interfaces);
675         AST_LIST_TRAVERSE(&interfaces, curint, list) {
676                 if (!strcasecmp(curint->interface, interface))
677                         break;
678         }
679
680         if (curint) {
681                 AST_LIST_UNLOCK(&interfaces);
682                 return 0;
683         }
684
685         if (option_debug)
686                 ast_log(LOG_DEBUG, "Adding %s to the list of interfaces that make up all of our queue members.\n", interface);
687         
688         if ((curint = ast_calloc(1, sizeof(*curint)))) {
689                 ast_copy_string(curint->interface, interface, sizeof(curint->interface));
690                 AST_LIST_INSERT_HEAD(&interfaces, curint, list);
691         }
692         AST_LIST_UNLOCK(&interfaces);
693
694         return 0;
695 }
696
697 static int interface_exists_global(char *interface)
698 {
699         struct call_queue *q;
700         struct member *mem;
701         int ret = 0;
702
703         AST_LIST_LOCK(&queues);
704         AST_LIST_TRAVERSE(&queues, q, list) {
705                 ast_mutex_lock(&q->lock);
706                 for (mem = q->members; mem && !ret; mem = mem->next) {
707                         if (!strcasecmp(interface, mem->interface))
708                                 ret = 1;
709                 }
710                 ast_mutex_unlock(&q->lock);
711                 if (ret)
712                         break;
713         }
714         AST_LIST_UNLOCK(&queues);
715
716         return ret;
717 }
718
719 static int remove_from_interfaces(char *interface)
720 {
721         struct member_interface *curint;
722
723         AST_LIST_LOCK(&interfaces);
724         AST_LIST_TRAVERSE_SAFE_BEGIN(&interfaces, curint, list) {
725                 if (!strcasecmp(curint->interface, interface)) {
726                         if (!interface_exists_global(interface)) {
727                                 if (option_debug)
728                                         ast_log(LOG_DEBUG, "Removing %s from the list of interfaces that make up all of our queue members.\n", interface);
729                                 AST_LIST_REMOVE_CURRENT(&interfaces, list);
730                                 free(curint);
731                         }
732                         break;
733                 }
734         }
735         AST_LIST_TRAVERSE_SAFE_END;
736         AST_LIST_UNLOCK(&interfaces);
737
738         return 0;
739 }
740
741 static void clear_and_free_interfaces(void)
742 {
743         struct member_interface *curint;
744
745         AST_LIST_LOCK(&interfaces);
746         while ((curint = AST_LIST_REMOVE_HEAD(&interfaces, list)))
747                 free(curint);
748         AST_LIST_UNLOCK(&interfaces);
749 }
750
751 /*! \brief Configure a queue parameter.
752 \par
753    For error reporting, line number is passed for .conf static configuration.
754    For Realtime queues, linenum is -1.
755    The failunknown flag is set for config files (and static realtime) to show
756    errors for unknown parameters. It is cleared for dynamic realtime to allow
757    extra fields in the tables. */
758 static void queue_set_param(struct call_queue *q, const char *param, const char *val, int linenum, int failunknown)
759 {
760         int i = 0;
761         char *c, *lastc;
762         char buff[80];
763
764         if (!strcasecmp(param, "music") || !strcasecmp(param, "musiconhold")) {
765                 ast_copy_string(q->moh, val, sizeof(q->moh));
766         } else if (!strcasecmp(param, "announce")) {
767                 ast_copy_string(q->announce, val, sizeof(q->announce));
768         } else if (!strcasecmp(param, "context")) {
769                 ast_copy_string(q->context, val, sizeof(q->context));
770         } else if (!strcasecmp(param, "timeout")) {
771                 q->timeout = atoi(val);
772                 if (q->timeout < 0)
773                         q->timeout = DEFAULT_TIMEOUT;
774         } else if (!strcasecmp(param, "ringinuse")) {
775                 q->ringinuse = ast_true(val);
776         } else if (!strcasecmp(param, "setinterfacevar")) {
777                 q->setinterfacevar = ast_true(val);
778         } else if (!strcasecmp(param, "monitor-join")) {
779                 q->monjoin = ast_true(val);
780         } else if (!strcasecmp(param, "monitor-format")) {
781                 ast_copy_string(q->monfmt, val, sizeof(q->monfmt));
782         } else if (!strcasecmp(param, "queue-youarenext")) {
783                 ast_copy_string(q->sound_next, val, sizeof(q->sound_next));
784         } else if (!strcasecmp(param, "queue-thereare")) {
785                 ast_copy_string(q->sound_thereare, val, sizeof(q->sound_thereare));
786         } else if (!strcasecmp(param, "queue-callswaiting")) {
787                 ast_copy_string(q->sound_calls, val, sizeof(q->sound_calls));
788         } else if (!strcasecmp(param, "queue-holdtime")) {
789                 ast_copy_string(q->sound_holdtime, val, sizeof(q->sound_holdtime));
790         } else if (!strcasecmp(param, "queue-minutes")) {
791                 ast_copy_string(q->sound_minutes, val, sizeof(q->sound_minutes));
792         } else if (!strcasecmp(param, "queue-seconds")) {
793                 ast_copy_string(q->sound_seconds, val, sizeof(q->sound_seconds));
794         } else if (!strcasecmp(param, "queue-lessthan")) {
795                 ast_copy_string(q->sound_lessthan, val, sizeof(q->sound_lessthan));
796         } else if (!strcasecmp(param, "queue-thankyou")) {
797                 ast_copy_string(q->sound_thanks, val, sizeof(q->sound_thanks));
798         } else if (!strcasecmp(param, "queue-reporthold")) {
799                 ast_copy_string(q->sound_reporthold, val, sizeof(q->sound_reporthold));
800         } else if (!strcasecmp(param, "announce-frequency")) {
801                 q->announcefrequency = atoi(val);
802         } else if (!strcasecmp(param, "announce-round-seconds")) {
803                 q->roundingseconds = atoi(val);
804                 if (q->roundingseconds>60 || q->roundingseconds<0) {
805                         if (linenum >= 0) {
806                                 ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
807                                         "using 0 instead for queue '%s' at line %d of queues.conf\n",
808                                         val, param, q->name, linenum);
809                         } else {
810                                 ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
811                                         "using 0 instead for queue '%s'\n", val, param, q->name);
812                         }
813                         q->roundingseconds=0;
814                 }
815         } else if (!strcasecmp(param, "announce-holdtime")) {
816                 if (!strcasecmp(val, "once"))
817                         q->announceholdtime = ANNOUNCEHOLDTIME_ONCE;
818                 else if (ast_true(val))
819                         q->announceholdtime = ANNOUNCEHOLDTIME_ALWAYS;
820                 else
821                         q->announceholdtime = 0;
822         } else if (!strcasecmp(param, "periodic-announce")) {
823                 if (strchr(val,'|')) {
824                         lastc = (char *)val;
825                         while ((c = strchr(lastc,'|'))) {
826                                 if (i > MAX_PERIODIC_ANNOUNCEMENTS)
827                                         break;
828                                 strncpy(buff, lastc, abs(lastc - c));
829                                 buff[abs(lastc - c)] = '\0';
830                                 ast_copy_string(q->sound_periodicannounce[i], buff, sizeof(q->sound_periodicannounce[i]));
831                                 lastc = (c + 1);
832                                 i++;
833                         }
834                         if (strlen(lastc)) {
835                                 ast_copy_string(q->sound_periodicannounce[i], lastc, sizeof(q->sound_periodicannounce[i]));
836                         }
837                 } else {
838                         ast_copy_string(q->sound_periodicannounce[i], val, sizeof(q->sound_periodicannounce[i]));
839                 }
840         } else if (!strcasecmp(param, "periodic-announce-frequency")) {
841                 q->periodicannouncefrequency = atoi(val);
842         } else if (!strcasecmp(param, "retry")) {
843                 q->retry = atoi(val);
844                 if (q->retry < 0)
845                         q->retry = DEFAULT_RETRY;
846         } else if (!strcasecmp(param, "wrapuptime")) {
847                 q->wrapuptime = atoi(val);
848         } else if (!strcasecmp(param, "autofill")) {
849                 q->autofill = ast_true(val);
850         } else if (!strcasecmp(param, "monitor-type")) {
851                 if (!strcasecmp(val, "mixmonitor"))
852                         q->montype = 1;
853         } else if (!strcasecmp(param, "autopause")) {
854                 q->autopause = ast_true(val);
855         } else if (!strcasecmp(param, "maxlen")) {
856                 q->maxlen = atoi(val);
857                 if (q->maxlen < 0)
858                         q->maxlen = 0;
859         } else if (!strcasecmp(param, "servicelevel")) {
860                 q->servicelevel= atoi(val);
861         } else if (!strcasecmp(param, "strategy")) {
862                 q->strategy = strat2int(val);
863                 if (q->strategy < 0) {
864                         ast_log(LOG_WARNING, "'%s' isn't a valid strategy for queue '%s', using ringall instead\n",
865                                 val, q->name);
866                         q->strategy = QUEUE_STRATEGY_RINGALL;
867                 }
868         } else if (!strcasecmp(param, "joinempty")) {
869                 if (!strcasecmp(val, "strict"))
870                         q->joinempty = QUEUE_EMPTY_STRICT;
871                 else if (ast_true(val))
872                         q->joinempty = QUEUE_EMPTY_NORMAL;
873                 else
874                         q->joinempty = 0;
875         } else if (!strcasecmp(param, "leavewhenempty")) {
876                 if (!strcasecmp(val, "strict"))
877                         q->leavewhenempty = QUEUE_EMPTY_STRICT;
878                 else if (ast_true(val))
879                         q->leavewhenempty = QUEUE_EMPTY_NORMAL;
880                 else
881                         q->leavewhenempty = 0;
882         } else if (!strcasecmp(param, "eventmemberstatus")) {
883                 q->maskmemberstatus = !ast_true(val);
884         } else if (!strcasecmp(param, "eventwhencalled")) {
885                 if (strcasecmp(val, "vars")) {
886                         q->eventwhencalled = QUEUE_EVENT_VARIABLES;
887                 } else {
888                         q->eventwhencalled = ast_true(val);
889                 }
890         } else if (!strcasecmp(param, "reportholdtime")) {
891                 q->reportholdtime = ast_true(val);
892         } else if (!strcasecmp(param, "memberdelay")) {
893                 q->memberdelay = atoi(val);
894         } else if (!strcasecmp(param, "weight")) {
895                 q->weight = atoi(val);
896                 if (q->weight)
897                         use_weight++;
898                 /* With Realtime queues, if the last queue using weights is deleted in realtime,
899                    we will not see any effect on use_weight until next reload. */
900         } else if (!strcasecmp(param, "timeoutrestart")) {
901                 q->timeoutrestart = ast_true(val);
902         } else if (failunknown) {
903                 if (linenum >= 0) {
904                         ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s at line %d of queues.conf\n",
905                                 q->name, param, linenum);
906                 } else {
907                         ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s\n", q->name, param);
908                 }
909         }
910 }
911
912 static void rt_handle_member_record(struct call_queue *q, char *interface, const char *penalty_str)
913 {
914         struct member *m, *prev_m;
915         int penalty = 0;
916
917         if (penalty_str) {
918                 penalty = atoi(penalty_str);
919                 if (penalty < 0)
920                         penalty = 0;
921         }
922
923         /* Find the member, or the place to put a new one. */
924         for (m = q->members, prev_m = NULL;
925                 m && strcmp(m->interface, interface);
926                 prev_m = m, m = m->next);
927
928         /* Create a new one if not found, else update penalty */
929         if (!m) {
930                 if ((m = create_queue_member(interface, penalty, 0))) {
931                         m->dead = 0;
932                         add_to_interfaces(interface);
933                         if (prev_m) {
934                                 prev_m->next = m;
935                         } else {
936                                 q->members = m;
937                         }
938                 }
939         } else {
940                 m->dead = 0;    /* Do not delete this one. */
941                 m->penalty = penalty;
942         }
943 }
944
945 static void free_members(struct call_queue *q, int all)
946 {
947         /* Free non-dynamic members */
948         struct member *curm, *next, *prev = NULL;
949
950         for (curm = q->members; curm; curm = next) {
951                 next = curm->next;
952                 if (all || !curm->dynamic) {
953                         if (prev)
954                                 prev->next = next;
955                         else
956                                 q->members = next;
957                         remove_from_interfaces(curm->interface);
958                         free(curm);
959                 } else
960                         prev = curm;
961         }
962 }
963
964 static void destroy_queue(struct call_queue *q)
965 {
966         free_members(q, 1);
967         ast_mutex_destroy(&q->lock);
968         free(q);
969 }
970
971 /*!\brief Reload a single queue via realtime.
972    \return Return the queue, or NULL if it doesn't exist.
973    \note Should be called with the global qlock locked. */
974 static struct call_queue *find_queue_by_name_rt(const char *queuename, struct ast_variable *queue_vars, struct ast_config *member_config)
975 {
976         struct ast_variable *v;
977         struct call_queue *q;
978         struct member *m, *prev_m, *next_m;
979         char *interface = NULL;
980         char *tmp, *tmp_name;
981         char tmpbuf[64];        /* Must be longer than the longest queue param name. */
982
983         /* Find the queue in the in-core list (we will create a new one if not found). */
984         AST_LIST_TRAVERSE(&queues, q, list) {
985                 if (!strcasecmp(q->name, queuename))
986                         break;
987         }
988
989         /* Static queues override realtime. */
990         if (q) {
991                 ast_mutex_lock(&q->lock);
992                 if (!q->realtime) {
993                         if (q->dead) {
994                                 ast_mutex_unlock(&q->lock);
995                                 return NULL;
996                         } else {
997                                 ast_mutex_unlock(&q->lock);
998                                 return q;
999                         }
1000                 }
1001         } else if (!member_config)
1002                 /* Not found in the list, and it's not realtime ... */
1003                 return NULL;
1004
1005         /* Check if queue is defined in realtime. */
1006         if (!queue_vars) {
1007                 /* Delete queue from in-core list if it has been deleted in realtime. */
1008                 if (q) {
1009                         /*! \note Hmm, can't seem to distinguish a DB failure from a not
1010                            found condition... So we might delete an in-core queue
1011                            in case of DB failure. */
1012                         ast_log(LOG_DEBUG, "Queue %s not found in realtime.\n", queuename);
1013
1014                         q->dead = 1;
1015                         /* Delete if unused (else will be deleted when last caller leaves). */
1016                         if (!q->count) {
1017                                 /* Delete. */
1018                                 AST_LIST_REMOVE(&queues, q, list);
1019                                 ast_mutex_unlock(&q->lock);
1020                                 destroy_queue(q);
1021                         } else
1022                                 ast_mutex_unlock(&q->lock);
1023                 }
1024                 return NULL;
1025         }
1026
1027         /* Create a new queue if an in-core entry does not exist yet. */
1028         if (!q) {
1029                 if (!(q = alloc_queue(queuename)))
1030                         return NULL;
1031                 ast_mutex_lock(&q->lock);
1032                 clear_queue(q);
1033                 q->realtime = 1;
1034                 AST_LIST_INSERT_HEAD(&queues, q, list);
1035         }
1036         init_queue(q);          /* Ensure defaults for all parameters not set explicitly. */
1037
1038         memset(tmpbuf, 0, sizeof(tmpbuf));
1039         for (v = queue_vars; v; v = v->next) {
1040                 /* Convert to dashes `-' from underscores `_' as the latter are more SQL friendly. */
1041                 if ((tmp = strchr(v->name, '_'))) {
1042                         ast_copy_string(tmpbuf, v->name, sizeof(tmpbuf));
1043                         tmp_name = tmpbuf;
1044                         tmp = tmp_name;
1045                         while ((tmp = strchr(tmp, '_')))
1046                                 *tmp++ = '-';
1047                 } else
1048                         tmp_name = v->name;
1049                 queue_set_param(q, tmp_name, v->value, -1, 0);
1050         }
1051
1052         if (q->strategy == QUEUE_STRATEGY_ROUNDROBIN)
1053                 rr_dep_warning();
1054
1055         /* Temporarily set non-dynamic members dead so we can detect deleted ones. */
1056         for (m = q->members; m; m = m->next) {
1057                 if (!m->dynamic)
1058                         m->dead = 1;
1059         }
1060
1061         while ((interface = ast_category_browse(member_config, interface)))
1062                 rt_handle_member_record(q, interface, ast_variable_retrieve(member_config, interface, "penalty"));
1063
1064         /* Delete all realtime members that have been deleted in DB. */
1065         m = q->members;
1066         prev_m = NULL;
1067         while (m) {
1068                 next_m = m->next;
1069                 if (m->dead) {
1070                         if (prev_m) {
1071                                 prev_m->next = next_m;
1072                         } else {
1073                                 q->members = next_m;
1074                         }
1075                         remove_from_interfaces(m->interface);
1076                         free(m);
1077                 } else {
1078                         prev_m = m;
1079                 }
1080                 m = next_m;
1081         }
1082
1083         ast_mutex_unlock(&q->lock);
1084
1085         return q;
1086 }
1087
1088 static struct call_queue *load_realtime_queue(char *queuename)
1089 {
1090         struct ast_variable *queue_vars;
1091         struct ast_config *member_config = NULL;
1092         struct call_queue *q;
1093
1094         /* Find the queue in the in-core list first. */
1095         AST_LIST_LOCK(&queues);
1096         AST_LIST_TRAVERSE(&queues, q, list) {
1097                 if (!strcasecmp(q->name, queuename)) {
1098                         break;
1099                 }
1100         }
1101         AST_LIST_UNLOCK(&queues);
1102
1103         if (!q || q->realtime) {
1104                 /*! \note Load from realtime before taking the global qlock, to avoid blocking all
1105                    queue operations while waiting for the DB.
1106
1107                    This will be two separate database transactions, so we might
1108                    see queue parameters as they were before another process
1109                    changed the queue and member list as it was after the change.
1110                    Thus we might see an empty member list when a queue is
1111                    deleted. In practise, this is unlikely to cause a problem. */
1112
1113                 queue_vars = ast_load_realtime("queues", "name", queuename, NULL);
1114                 if (queue_vars) {
1115                         member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", queuename, NULL);
1116                         if (!member_config) {
1117                                 ast_log(LOG_ERROR, "no queue_members defined in your config (extconfig.conf).\n");
1118                                 return NULL;
1119                         }
1120                 }
1121
1122                 AST_LIST_LOCK(&queues);
1123
1124                 q = find_queue_by_name_rt(queuename, queue_vars, member_config);
1125                 if (member_config)
1126                         ast_config_destroy(member_config);
1127                 if (queue_vars)
1128                         ast_variables_destroy(queue_vars);
1129
1130                 AST_LIST_UNLOCK(&queues);
1131         }
1132         return q;
1133 }
1134
1135 static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
1136 {
1137         struct call_queue *q;
1138         struct queue_ent *cur, *prev = NULL;
1139         int res = -1;
1140         int pos = 0;
1141         int inserted = 0;
1142         enum queue_member_status stat;
1143
1144         if (!(q = load_realtime_queue(queuename)))
1145                 return res;
1146
1147         AST_LIST_LOCK(&queues);
1148         ast_mutex_lock(&q->lock);
1149
1150         /* This is our one */
1151         stat = get_member_status(q, qe->max_penalty);
1152         if (!q->joinempty && (stat == QUEUE_NO_MEMBERS))
1153                 *reason = QUEUE_JOINEMPTY;
1154         else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS))
1155                 *reason = QUEUE_JOINUNAVAIL;
1156         else if (q->maxlen && (q->count >= q->maxlen))
1157                 *reason = QUEUE_FULL;
1158         else {
1159                 /* There's space for us, put us at the right position inside
1160                  * the queue.
1161                  * Take into account the priority of the calling user */
1162                 inserted = 0;
1163                 prev = NULL;
1164                 cur = q->head;
1165                 while (cur) {
1166                         /* We have higher priority than the current user, enter
1167                          * before him, after all the other users with priority
1168                          * higher or equal to our priority. */
1169                         if ((!inserted) && (qe->prio > cur->prio)) {
1170                                 insert_entry(q, prev, qe, &pos);
1171                                 inserted = 1;
1172                         }
1173                         cur->pos = ++pos;
1174                         prev = cur;
1175                         cur = cur->next;
1176                 }
1177                 /* No luck, join at the end of the queue */
1178                 if (!inserted)
1179                         insert_entry(q, prev, qe, &pos);
1180                 ast_copy_string(qe->moh, q->moh, sizeof(qe->moh));
1181                 ast_copy_string(qe->announce, q->announce, sizeof(qe->announce));
1182                 ast_copy_string(qe->context, q->context, sizeof(qe->context));
1183                 q->count++;
1184                 res = 0;
1185                 manager_event(EVENT_FLAG_CALL, "Join",
1186                         "Channel: %s\r\nCallerID: %s\r\nCallerIDName: %s\r\nQueue: %s\r\nPosition: %d\r\nCount: %d\r\nUniqueid: %s\r\n",
1187                         qe->chan->name,
1188                         S_OR(qe->chan->cid.cid_num, "unknown"), /* XXX somewhere else it is <unknown> */
1189                         S_OR(qe->chan->cid.cid_name, "unknown"),
1190                         q->name, qe->pos, q->count, qe->chan->uniqueid );
1191                 if (option_debug)
1192                         ast_log(LOG_DEBUG, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos );
1193         }
1194         ast_mutex_unlock(&q->lock);
1195         AST_LIST_UNLOCK(&queues);
1196
1197         return res;
1198 }
1199
1200 static int play_file(struct ast_channel *chan, char *filename)
1201 {
1202         int res;
1203
1204         ast_stopstream(chan);
1205         res = ast_streamfile(chan, filename, chan->language);
1206         if (!res)
1207                 res = ast_waitstream(chan, AST_DIGIT_ANY);
1208         ast_stopstream(chan);
1209
1210         return res;
1211 }
1212
1213 static int valid_exit(struct queue_ent *qe, char digit)
1214 {
1215         int digitlen = strlen(qe->digits);
1216
1217         /* Prevent possible buffer overflow */
1218         if (digitlen < sizeof(qe->digits) - 2) {
1219                 qe->digits[digitlen] = digit;
1220                 qe->digits[digitlen + 1] = '\0';
1221         } else {
1222                 qe->digits[0] = '\0';
1223                 return 0;
1224         }
1225
1226         /* If there's no context to goto, short-circuit */
1227         if (ast_strlen_zero(qe->context))
1228                 return 0;
1229
1230         /* If the extension is bad, then reset the digits to blank */
1231         if (!ast_canmatch_extension(qe->chan, qe->context, qe->digits, 1, qe->chan->cid.cid_num)) {
1232                 qe->digits[0] = '\0';
1233                 return 0;
1234         }
1235
1236         /* We have an exact match */
1237         if (!ast_goto_if_exists(qe->chan, qe->context, qe->digits, 1)) {
1238                 /* Return 1 on a successful goto */
1239                 return 1;
1240         }
1241
1242         return 0;
1243 }
1244
1245 static int say_position(struct queue_ent *qe)
1246 {
1247         int res = 0, avgholdmins, avgholdsecs;
1248         time_t now;
1249
1250         /* Check to see if this is ludicrous -- if we just announced position, don't do it again*/
1251         time(&now);
1252         if ((now - qe->last_pos) < 15)
1253                 return 0;
1254
1255         /* If either our position has changed, or we are over the freq timer, say position */
1256         if ((qe->last_pos_said == qe->pos) && ((now - qe->last_pos) < qe->parent->announcefrequency))
1257                 return 0;
1258
1259         ast_moh_stop(qe->chan);
1260         /* Say we're next, if we are */
1261         if (qe->pos == 1) {
1262                 res = play_file(qe->chan, qe->parent->sound_next);
1263                 if (res && valid_exit(qe, res))
1264                         goto playout;
1265                 else
1266                         goto posout;
1267         } else {
1268                 res = play_file(qe->chan, qe->parent->sound_thereare);
1269                 if (res && valid_exit(qe, res))
1270                         goto playout;
1271                 res = ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language, (char *) NULL); /* Needs gender */
1272                 if (res && valid_exit(qe, res))
1273                         goto playout;
1274                 res = play_file(qe->chan, qe->parent->sound_calls);
1275                 if (res && valid_exit(qe, res))
1276                         goto playout;
1277         }
1278         /* Round hold time to nearest minute */
1279         avgholdmins = abs(((qe->parent->holdtime + 30) - (now - qe->start)) / 60);
1280
1281         /* If they have specified a rounding then round the seconds as well */
1282         if (qe->parent->roundingseconds) {
1283                 avgholdsecs = (abs(((qe->parent->holdtime + 30) - (now - qe->start))) - 60 * avgholdmins) / qe->parent->roundingseconds;
1284                 avgholdsecs *= qe->parent->roundingseconds;
1285         } else {
1286                 avgholdsecs = 0;
1287         }
1288
1289         if (option_verbose > 2)
1290                 ast_verbose(VERBOSE_PREFIX_3 "Hold time for %s is %d minutes %d seconds\n", qe->parent->name, avgholdmins, avgholdsecs);
1291
1292         /* If the hold time is >1 min, if it's enabled, and if it's not
1293            supposed to be only once and we have already said it, say it */
1294         if ((avgholdmins+avgholdsecs) > 0 && (qe->parent->announceholdtime) &&
1295                 (!(qe->parent->announceholdtime == ANNOUNCEHOLDTIME_ONCE) && qe->last_pos)) {
1296                 res = play_file(qe->chan, qe->parent->sound_holdtime);
1297                 if (res && valid_exit(qe, res))
1298                         goto playout;
1299
1300                 if (avgholdmins > 0) {
1301                         if (avgholdmins < 2) {
1302                                 res = play_file(qe->chan, qe->parent->sound_lessthan);
1303                                 if (res && valid_exit(qe, res))
1304                                         goto playout;
1305
1306                                 res = ast_say_number(qe->chan, 2, AST_DIGIT_ANY, qe->chan->language, NULL);
1307                                 if (res && valid_exit(qe, res))
1308                                         goto playout;
1309                         } else {
1310                                 res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, NULL);
1311                                 if (res && valid_exit(qe, res))
1312                                         goto playout;
1313                         }
1314                         
1315                         res = play_file(qe->chan, qe->parent->sound_minutes);
1316                         if (res && valid_exit(qe, res))
1317                                 goto playout;
1318                 }
1319                 if (avgholdsecs>0) {
1320                         res = ast_say_number(qe->chan, avgholdsecs, AST_DIGIT_ANY, qe->chan->language, NULL);
1321                         if (res && valid_exit(qe, res))
1322                                 goto playout;
1323
1324                         res = play_file(qe->chan, qe->parent->sound_seconds);
1325                         if (res && valid_exit(qe, res))
1326                                 goto playout;
1327                 }
1328
1329         }
1330
1331 posout:
1332         if (option_verbose > 2)
1333                 ast_verbose(VERBOSE_PREFIX_3 "Told %s in %s their queue position (which was %d)\n",
1334                         qe->chan->name, qe->parent->name, qe->pos);
1335         res = play_file(qe->chan, qe->parent->sound_thanks);
1336         if (res && !valid_exit(qe, res))
1337                 res = 0;
1338
1339 playout:
1340         /* Set our last_pos indicators */
1341         qe->last_pos = now;
1342         qe->last_pos_said = qe->pos;
1343
1344         /* Don't restart music on hold if we're about to exit the caller from the queue */
1345         if (!res)
1346                 ast_moh_start(qe->chan, qe->moh);
1347
1348         return res;
1349 }
1350
1351 static void recalc_holdtime(struct queue_ent *qe)
1352 {
1353         int oldvalue, newvalue;
1354
1355         /* Calculate holdtime using a recursive boxcar filter */
1356         /* Thanks to SRT for this contribution */
1357         /* 2^2 (4) is the filter coefficient; a higher exponent would give old entries more weight */
1358
1359         newvalue = time(NULL) - qe->start;
1360
1361         ast_mutex_lock(&qe->parent->lock);
1362         if (newvalue <= qe->parent->servicelevel)
1363                 qe->parent->callscompletedinsl++;
1364         oldvalue = qe->parent->holdtime;
1365         qe->parent->holdtime = (((oldvalue << 2) - oldvalue) + newvalue) >> 2;
1366         ast_mutex_unlock(&qe->parent->lock);
1367 }
1368
1369
1370 static void leave_queue(struct queue_ent *qe)
1371 {
1372         struct call_queue *q;
1373         struct queue_ent *cur, *prev = NULL;
1374         int pos = 0;
1375
1376         if (!(q = qe->parent))
1377                 return;
1378         ast_mutex_lock(&q->lock);
1379
1380         prev = NULL;
1381         for (cur = q->head; cur; cur = cur->next) {
1382                 if (cur == qe) {
1383                         q->count--;
1384
1385                         /* Take us out of the queue */
1386                         manager_event(EVENT_FLAG_CALL, "Leave",
1387                                 "Channel: %s\r\nQueue: %s\r\nCount: %d\r\nUniqueid: %s\r\n",
1388                                 qe->chan->name, q->name,  q->count, qe->chan->uniqueid);
1389                         if (option_debug)
1390                                 ast_log(LOG_DEBUG, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name );
1391                         /* Take us out of the queue */
1392                         if (prev)
1393                                 prev->next = cur->next;
1394                         else
1395                                 q->head = cur->next;
1396                 } else {
1397                         /* Renumber the people after us in the queue based on a new count */
1398                         cur->pos = ++pos;
1399                         prev = cur;
1400                 }
1401         }
1402         ast_mutex_unlock(&q->lock);
1403
1404         if (q->dead && !q->count) {     
1405                 /* It's dead and nobody is in it, so kill it */
1406                 AST_LIST_LOCK(&queues);
1407                 AST_LIST_REMOVE(&queues, q, list);
1408                 AST_LIST_UNLOCK(&queues);
1409                 destroy_queue(q);
1410         }
1411 }
1412
1413 /* Hang up a list of outgoing calls */
1414 static void hangupcalls(struct callattempt *outgoing, struct ast_channel *exception)
1415 {
1416         struct callattempt *oo;
1417
1418         while (outgoing) {
1419                 /* Hangup any existing lines we have open */
1420                 if (outgoing->chan && (outgoing->chan != exception))
1421                         ast_hangup(outgoing->chan);
1422                 oo = outgoing;
1423                 outgoing = outgoing->q_next;
1424                 free(oo);
1425         }
1426 }
1427
1428 static int update_status(struct call_queue *q, struct member *member, int status)
1429 {
1430         struct member *cur;
1431
1432         /* Since a reload could have taken place, we have to traverse the list to
1433                 be sure it's still valid */
1434         ast_mutex_lock(&q->lock);
1435         for (cur = q->members; cur; cur = cur->next) {
1436                 if (member != cur)
1437                         continue;
1438
1439                 cur->status = status;
1440                 if (!q->maskmemberstatus) {
1441                         manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
1442                                 "Queue: %s\r\n"
1443                                 "Location: %s\r\n"
1444                                 "Membership: %s\r\n"
1445                                 "Penalty: %d\r\n"
1446                                 "CallsTaken: %d\r\n"
1447                                 "LastCall: %d\r\n"
1448                                 "Status: %d\r\n"
1449                                 "Paused: %d\r\n",
1450                                 q->name, cur->interface, cur->dynamic ? "dynamic" : "static",
1451                                 cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
1452                 }
1453         }
1454         ast_mutex_unlock(&q->lock);
1455         return 0;
1456 }
1457
1458 static int update_dial_status(struct call_queue *q, struct member *member, int status)
1459 {
1460         if (status == AST_CAUSE_BUSY)
1461                 status = AST_DEVICE_BUSY;
1462         else if (status == AST_CAUSE_UNREGISTERED)
1463                 status = AST_DEVICE_UNAVAILABLE;
1464         else if (status == AST_CAUSE_NOSUCHDRIVER)
1465                 status = AST_DEVICE_INVALID;
1466         else
1467                 status = AST_DEVICE_UNKNOWN;
1468         return update_status(q, member, status);
1469 }
1470
1471 /* traverse all defined queues which have calls waiting and contain this member
1472    return 0 if no other queue has precedence (higher weight) or 1 if found  */
1473 static int compare_weight(struct call_queue *rq, struct member *member)
1474 {
1475         struct call_queue *q;
1476         struct member *mem;
1477         int found = 0;
1478         
1479         /* &qlock and &rq->lock already set by try_calling()
1480          * to solve deadlock */
1481         AST_LIST_TRAVERSE(&queues, q, list) {
1482                 if (q == rq) /* don't check myself, could deadlock */
1483                         continue;
1484                 ast_mutex_lock(&q->lock);
1485                 if (q->count && q->members) {
1486                         for (mem = q->members; mem; mem = mem->next) {
1487                                 if (strcmp(mem->interface, member->interface))
1488                                         continue;
1489
1490                                 ast_log(LOG_DEBUG, "Found matching member %s in queue '%s'\n", mem->interface, q->name);
1491                                 if (q->weight > rq->weight) {
1492                                         ast_log(LOG_DEBUG, "Queue '%s' (weight %d, calls %d) is preferred over '%s' (weight %d, calls %d)\n", q->name, q->weight, q->count, rq->name, rq->weight, rq->count);
1493                                         found = 1;
1494                                         break;
1495                                 }
1496                         }
1497                 }
1498                 ast_mutex_unlock(&q->lock);
1499                 if (found)
1500                         break;
1501         }
1502         return found;
1503 }
1504
1505 /*! \brief common hangup actions */
1506 static void do_hang(struct callattempt *o)
1507 {
1508         o->stillgoing = 0;
1509         ast_hangup(o->chan);
1510         o->chan = NULL;
1511 }
1512
1513 static char *vars2manager(struct ast_channel *chan, char *vars, size_t len)
1514 {
1515         char *tmp = alloca(len);
1516
1517         if (pbx_builtin_serialize_variables(chan, tmp, len)) {
1518                 int i, j;
1519
1520                 /* convert "\n" to "\nVariable: " */
1521                 strcpy(vars, "Variable: ");
1522
1523                 for (i = 0, j = 10; (i < len - 1) && (j < len - 1); i++, j++) {
1524                         vars[j] = tmp[i];
1525
1526                         if (tmp[i + 1] == '\0')
1527                                 break;
1528                         if (tmp[i] == '\n') {
1529                                 vars[j] = '\r';
1530                                 vars[++j] = '\n';
1531
1532                                 ast_copy_string(&(vars[j]), "Variable: ", len - j);
1533                                 j += 9;
1534                         }
1535                 }
1536                 if (j > len - 1)
1537                         j = len - 1;
1538                 vars[j - 2] = '\r';
1539                 vars[j - 1] = '\n';
1540                 vars[j] = '\0';
1541         } else {
1542                 /* there are no channel variables; leave it blank */
1543                 *vars = '\0';
1544         }
1545         return vars;
1546 }
1547
1548 static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies)
1549 {
1550         int res;
1551         int status;
1552         char tech[256];
1553         char *location;
1554
1555         /* on entry here, we know that tmp->chan == NULL */
1556         if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) {
1557                 if (option_debug)
1558                         ast_log(LOG_DEBUG, "Wrapuptime not yet expired for %s\n", tmp->interface);
1559                 if (qe->chan->cdr)
1560                         ast_cdr_busy(qe->chan->cdr);
1561                 tmp->stillgoing = 0;
1562                 (*busies)++;
1563                 return 0;
1564         }
1565
1566         if (!qe->parent->ringinuse && (tmp->member->status == AST_DEVICE_INUSE)) {
1567                 if (option_debug)
1568                         ast_log(LOG_DEBUG, "%s in use, can't receive call\n", tmp->interface);
1569                 if (qe->chan->cdr)
1570                         ast_cdr_busy(qe->chan->cdr);
1571                 tmp->stillgoing = 0;
1572                 return 0;
1573         }
1574
1575         if (tmp->member->paused) {
1576                 if (option_debug)
1577                         ast_log(LOG_DEBUG, "%s paused, can't receive call\n", tmp->interface);
1578                 if (qe->chan->cdr)
1579                         ast_cdr_busy(qe->chan->cdr);
1580                 tmp->stillgoing = 0;
1581                 return 0;
1582         }
1583         if (use_weight && compare_weight(qe->parent,tmp->member)) {
1584                 ast_log(LOG_DEBUG, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->interface);
1585                 if (qe->chan->cdr)
1586                         ast_cdr_busy(qe->chan->cdr);
1587                 tmp->stillgoing = 0;
1588                 (*busies)++;
1589                 return 0;
1590         }
1591
1592         ast_copy_string(tech, tmp->interface, sizeof(tech));
1593         if ((location = strchr(tech, '/')))
1594                 *location++ = '\0';
1595         else
1596                 location = "";
1597
1598         /* Request the peer */
1599         tmp->chan = ast_request(tech, qe->chan->nativeformats, location, &status);
1600         if (!tmp->chan) {                       /* If we can't, just go on to the next call */
1601                 if (qe->chan->cdr)
1602                         ast_cdr_busy(qe->chan->cdr);
1603                 tmp->stillgoing = 0;
1604                 update_dial_status(qe->parent, tmp->member, status);
1605                 (*busies)++;
1606                 return 0;
1607         } else if (status != tmp->oldstatus)
1608                 update_dial_status(qe->parent, tmp->member, status);
1609         
1610         tmp->chan->appl = "AppQueue";
1611         tmp->chan->data = "(Outgoing Line)";
1612         tmp->chan->whentohangup = 0;
1613         if (tmp->chan->cid.cid_num)
1614                 free(tmp->chan->cid.cid_num);
1615         tmp->chan->cid.cid_num = ast_strdup(qe->chan->cid.cid_num);
1616         if (tmp->chan->cid.cid_name)
1617                 free(tmp->chan->cid.cid_name);
1618         tmp->chan->cid.cid_name = ast_strdup(qe->chan->cid.cid_name);
1619         if (tmp->chan->cid.cid_ani)
1620                 free(tmp->chan->cid.cid_ani);
1621         tmp->chan->cid.cid_ani = ast_strdup(qe->chan->cid.cid_ani);
1622
1623         /* Inherit specially named variables from parent channel */
1624         ast_channel_inherit_variables(qe->chan, tmp->chan);
1625
1626         /* Presense of ADSI CPE on outgoing channel follows ours */
1627         tmp->chan->adsicpe = qe->chan->adsicpe;
1628
1629         /* Place the call, but don't wait on the answer */
1630         if ((res = ast_call(tmp->chan, location, 0))) {
1631                 /* Again, keep going even if there's an error */
1632                 if (option_debug)
1633                         ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
1634                 else if (option_verbose > 2)
1635                         ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", tmp->interface);
1636                 do_hang(tmp);
1637                 (*busies)++;
1638                 return 0;
1639         } else if (qe->parent->eventwhencalled) {
1640                 char vars[2048];
1641
1642                 manager_event(EVENT_FLAG_AGENT, "AgentCalled",
1643                                         "AgentCalled: %s\r\n"
1644                                         "ChannelCalling: %s\r\n"
1645                                         "CallerID: %s\r\n"
1646                                         "CallerIDName: %s\r\n"
1647                                         "Context: %s\r\n"
1648                                         "Extension: %s\r\n"
1649                                         "Priority: %d\r\n"
1650                                         "%s",
1651                                         tmp->interface, qe->chan->name,
1652                                         tmp->chan->cid.cid_num ? tmp->chan->cid.cid_num : "unknown",
1653                                         tmp->chan->cid.cid_name ? tmp->chan->cid.cid_name : "unknown",
1654                                         qe->chan->context, qe->chan->exten, qe->chan->priority,
1655                                         qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
1656                 if (option_verbose > 2)
1657                         ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", tmp->interface);
1658         }
1659
1660         return 1;
1661 }
1662
1663 /*! \brief find the entry with the best metric, or NULL */
1664 static struct callattempt *find_best(struct callattempt *outgoing)
1665 {
1666         struct callattempt *best = NULL, *cur;
1667
1668         for (cur = outgoing; cur; cur = cur->q_next) {
1669                 if (cur->stillgoing &&                                  /* Not already done */
1670                         !cur->chan &&                                   /* Isn't already going */
1671                         (!best || cur->metric < best->metric)) {                /* We haven't found one yet, or it's better */
1672                         best = cur;
1673                 }
1674         }
1675
1676         return best;
1677 }
1678
1679 static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies)
1680 {
1681         int ret = 0;
1682
1683         while (ret == 0) {
1684                 struct callattempt *best = find_best(outgoing);
1685                 if (!best) {
1686                         if (option_debug)
1687                                 ast_log(LOG_DEBUG, "Nobody left to try ringing in queue\n");
1688                         break;
1689                 }
1690                 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
1691                         struct callattempt *cur;
1692                         /* Ring everyone who shares this best metric (for ringall) */
1693                         for (cur = outgoing; cur; cur = cur->q_next) {
1694                                 if (cur->stillgoing && !cur->chan && cur->metric <= best->metric) {
1695                                         if (option_debug)
1696                                                 ast_log(LOG_DEBUG, "(Parallel) Trying '%s' with metric %d\n", cur->interface, cur->metric);
1697                                         ring_entry(qe, cur, busies);
1698                                 }
1699                         }
1700                 } else {
1701                         /* Ring just the best channel */
1702                         if (option_debug)
1703                                 ast_log(LOG_DEBUG, "Trying '%s' with metric %d\n", best->interface, best->metric);
1704                         ring_entry(qe, best, busies);
1705                 }
1706                 if (best->chan) /* break out with result = 1 */
1707                         ret = 1;
1708         }
1709
1710         return ret;
1711 }
1712
1713 static int store_next(struct queue_ent *qe, struct callattempt *outgoing)
1714 {
1715         struct callattempt *best = find_best(outgoing);
1716
1717         if (best) {
1718                 /* Ring just the best channel */
1719                 if (option_debug)
1720                         ast_log(LOG_DEBUG, "Next is '%s' with metric %d\n", best->interface, best->metric);
1721                 qe->parent->rrpos = best->metric % 1000;
1722         } else {
1723                 /* Just increment rrpos */
1724                 if (qe->parent->wrapped) {
1725                         /* No more channels, start over */
1726                         qe->parent->rrpos = 0;
1727                 } else {
1728                         /* Prioritize next entry */
1729                         qe->parent->rrpos++;
1730                 }
1731         }
1732         qe->parent->wrapped = 0;
1733
1734         return 0;
1735 }
1736
1737 static int background_file(struct queue_ent *qe, struct ast_channel *chan, char *filename)
1738 {
1739         int res;
1740
1741         ast_stopstream(chan);
1742         res = ast_streamfile(chan, filename, chan->language);
1743
1744         if (!res) {
1745                 /* Wait for a keypress */
1746                 res = ast_waitstream(chan, AST_DIGIT_ANY);
1747                 if (res < 0 || !valid_exit(qe, res))
1748                         res = 0;
1749
1750                 /* Stop playback */
1751                 ast_stopstream(chan);
1752         }
1753         
1754         return res;
1755 }
1756
1757 static int say_periodic_announcement(struct queue_ent *qe)
1758 {
1759         int res = 0;
1760         time_t now;
1761
1762         /* Get the current time */
1763         time(&now);
1764
1765         /* Check to see if it is time to announce */
1766         if ((now - qe->last_periodic_announce_time) < qe->parent->periodicannouncefrequency)
1767                 return 0;
1768
1769         /* Stop the music on hold so we can play our own file */
1770         ast_moh_stop(qe->chan);
1771
1772         if (option_verbose > 2)
1773                 ast_verbose(VERBOSE_PREFIX_3 "Playing periodic announcement\n");
1774
1775         /* Check to make sure we have a sound file. If not, reset to the first sound file */
1776         if (qe->last_periodic_announce_sound >= MAX_PERIODIC_ANNOUNCEMENTS || !strlen(qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound])) {
1777                 qe->last_periodic_announce_sound = 0;
1778         }
1779         
1780         /* play the announcement */
1781         res = background_file(qe, qe->chan, qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]);
1782
1783         /* Resume Music on Hold if the caller is going to stay in the queue */
1784         if (!res)
1785                 ast_moh_start(qe->chan, qe->moh);
1786
1787         /* update last_periodic_announce_time */
1788         qe->last_periodic_announce_time = now;
1789
1790         /* Update the current periodic announcement to the next announcement */
1791         qe->last_periodic_announce_sound++;
1792         
1793         return res;
1794 }
1795
1796 static void record_abandoned(struct queue_ent *qe)
1797 {
1798         ast_mutex_lock(&qe->parent->lock);
1799         manager_event(EVENT_FLAG_AGENT, "QueueCallerAbandon",
1800                 "Queue: %s\r\n"
1801                 "Uniqueid: %s\r\n"
1802                 "Position: %d\r\n"
1803                 "OriginalPosition: %d\r\n"
1804                 "HoldTime: %d\r\n",
1805                 qe->parent->name, qe->chan->uniqueid, qe->pos, qe->opos, (int)(time(NULL) - qe->start));
1806
1807         qe->parent->callsabandoned++;
1808         ast_mutex_unlock(&qe->parent->lock);
1809 }
1810
1811 /*! \brief RNA == Ring No Answer. Common code that is executed when we try a queue member and they don't answer. */
1812 static void rna(int rnatime, struct queue_ent *qe, char *membername)
1813 {
1814         if (option_verbose > 2)
1815                 ast_verbose( VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", rnatime);
1816         ast_queue_log(qe->parent->name, qe->chan->uniqueid, membername, "RINGNOANSWER", "%d", rnatime);
1817         if (qe->parent->autopause) {
1818                 if (!set_member_paused(qe->parent->name, membername, 1)) {
1819                         if (option_verbose > 2)
1820                                 ast_verbose( VERBOSE_PREFIX_3 "Auto-Pausing Queue Member %s in queue %s since they failed to answer.\n", membername, qe->parent->name);
1821                 } else {
1822                         if (option_verbose > 2)
1823                                 ast_verbose( VERBOSE_PREFIX_3 "Failed to pause Queue Member %s in queue %s!\n", membername, qe->parent->name);
1824                 }
1825         }
1826         return;
1827 }
1828
1829 #define AST_MAX_WATCHERS 256
1830
1831 static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect)
1832 {
1833         char *queue = qe->parent->name;
1834         struct callattempt *o;
1835         int status;
1836         int sentringing = 0;
1837         int numbusies = prebusies;
1838         int numnochan = 0;
1839         int stillgoing = 0;
1840         int orig = *to;
1841         struct ast_frame *f;
1842         struct callattempt *peer = NULL;
1843         struct ast_channel *winner;
1844         struct ast_channel *in = qe->chan;
1845         char on[256] = "";
1846         long starttime = 0;
1847         long endtime = 0;       
1848
1849         starttime = (long) time(NULL);
1850         
1851         while (*to && !peer) {
1852                 int numlines, retry, pos = 1;
1853                 struct ast_channel *watchers[AST_MAX_WATCHERS];
1854                 watchers[0] = in;
1855
1856                 for (retry = 0; retry < 2; retry++) {
1857                         numlines = 0;
1858                         for (o = outgoing; o; o = o->q_next) { /* Keep track of important channels */
1859                                 if (o->stillgoing) {    /* Keep track of important channels */
1860                                         stillgoing = 1;
1861                                         if (o->chan)
1862                                                 watchers[pos++] = o->chan;
1863                                 }
1864                                 numlines++;
1865                         }
1866                         if (pos > 1 /* found */ || !stillgoing /* nobody listening */ ||
1867                                 (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) /* ring would not be delivered */)
1868                                 break;
1869                         /* On "ringall" strategy we only move to the next penalty level
1870                            when *all* ringing phones are done in the current penalty level */
1871                         ring_one(qe, outgoing, &numbusies);
1872                         /* and retry... */
1873                 }
1874                 if (pos == 1 /* not found */) {
1875                         if (numlines == (numbusies + numnochan)) {
1876                                 ast_log(LOG_DEBUG, "Everyone is busy at this time\n");
1877                         } else {
1878                                 ast_log(LOG_NOTICE, "No one is answering queue '%s' (%d/%d/%d)\n", queue, numlines, numbusies, numnochan);
1879                         }
1880                         *to = 0;
1881                         return NULL;
1882                 }
1883                 winner = ast_waitfor_n(watchers, pos, to);
1884                 for (o = outgoing; o; o = o->q_next) {
1885                         if (o->stillgoing && (o->chan) &&  (o->chan->_state == AST_STATE_UP)) {
1886                                 if (!peer) {
1887                                         if (option_verbose > 2)
1888                                                 ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
1889                                         peer = o;
1890                                 }
1891                         } else if (o->chan && (o->chan == winner)) {
1892                                 ast_copy_string(on, o->member->interface, sizeof(on));
1893                                 if (!ast_strlen_zero(o->chan->call_forward)) {
1894                                         char tmpchan[256];
1895                                         char *stuff;
1896                                         char *tech;
1897
1898                                         ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan));
1899                                         if ((stuff = strchr(tmpchan, '/'))) {
1900                                                 *stuff++ = '\0';
1901                                                 tech = tmpchan;
1902                                         } else {
1903                                                 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, o->chan->context);
1904                                                 stuff = tmpchan;
1905                                                 tech = "Local";
1906                                         }
1907                                         /* Before processing channel, go ahead and check for forwarding */
1908                                         if (option_verbose > 2)
1909                                                 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
1910                                         /* Setup parameters */
1911                                         o->chan = ast_request(tech, in->nativeformats, stuff, &status);
1912                                         if (status != o->oldstatus)
1913                                                 update_dial_status(qe->parent, o->member, status);                                              
1914                                         if (!o->chan) {
1915                                                 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
1916                                                 o->stillgoing = 0;
1917                                                 numnochan++;
1918                                         } else {
1919                                                 if (o->chan->cid.cid_num)
1920                                                         free(o->chan->cid.cid_num);
1921                                                 o->chan->cid.cid_num = ast_strdup(in->cid.cid_num);
1922
1923                                                 if (o->chan->cid.cid_name)
1924                                                         free(o->chan->cid.cid_name);
1925                                                 o->chan->cid.cid_name = ast_strdup(in->cid.cid_name);
1926
1927                                                 ast_string_field_set(o->chan, accountcode, in->accountcode);
1928                                                 o->chan->cdrflags = in->cdrflags;
1929
1930                                                 if (in->cid.cid_ani) {
1931                                                         if (o->chan->cid.cid_ani)
1932                                                                 free(o->chan->cid.cid_ani);
1933                                                         o->chan->cid.cid_ani = ast_strdup(in->cid.cid_ani);
1934                                                 }
1935                                                 if (o->chan->cid.cid_rdnis)
1936                                                         free(o->chan->cid.cid_rdnis);
1937                                                 o->chan->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
1938                                                 if (ast_call(o->chan, tmpchan, 0)) {
1939                                                         ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
1940                                                         do_hang(o);
1941                                                         numnochan++;
1942                                                 }
1943                                         }
1944                                         /* Hangup the original channel now, in case we needed it */
1945                                         ast_hangup(winner);
1946                                         continue;
1947                                 }
1948                                 f = ast_read(winner);
1949                                 if (f) {
1950                                         if (f->frametype == AST_FRAME_CONTROL) {
1951                                                 switch (f->subclass) {
1952                                                 case AST_CONTROL_ANSWER:
1953                                                         /* This is our guy if someone answered. */
1954                                                         if (!peer) {
1955                                                                 if (option_verbose > 2)
1956                                                                         ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
1957                                                                 peer = o;
1958                                                         }
1959                                                         break;
1960                                                 case AST_CONTROL_BUSY:
1961                                                         if (option_verbose > 2)
1962                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", o->chan->name);
1963                                                         if (in->cdr)
1964                                                                 ast_cdr_busy(in->cdr);
1965                                                         do_hang(o);
1966                                                         endtime = (long)time(NULL);
1967                                                         endtime -= starttime;
1968                                                         rna(endtime*1000, qe, on);
1969                                                         if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
1970                                                                 if (qe->parent->timeoutrestart)
1971                                                                         *to = orig;
1972                                                                 ring_one(qe, outgoing, &numbusies);
1973                                                         }
1974                                                         numbusies++;
1975                                                         break;
1976                                                 case AST_CONTROL_CONGESTION:
1977                                                         if (option_verbose > 2)
1978                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is circuit-busy\n", o->chan->name);
1979                                                         if (in->cdr)
1980                                                                 ast_cdr_busy(in->cdr);
1981                                                         endtime = (long)time(NULL);
1982                                                         endtime -= starttime;
1983                                                         rna(endtime*1000, qe, on);
1984                                                         do_hang(o);
1985                                                         if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
1986                                                                 if (qe->parent->timeoutrestart)
1987                                                                         *to = orig;
1988                                                                 ring_one(qe, outgoing, &numbusies);
1989                                                         }
1990                                                         numbusies++;
1991                                                         break;
1992                                                 case AST_CONTROL_RINGING:
1993                                                         if (option_verbose > 2)
1994                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
1995                                                         if (!sentringing) {
1996 #if 0
1997                                                                 ast_indicate(in, AST_CONTROL_RINGING);
1998 #endif                                                          
1999                                                                 sentringing++;
2000                                                         }
2001                                                         break;
2002                                                 case AST_CONTROL_OFFHOOK:
2003                                                         /* Ignore going off hook */
2004                                                         break;
2005                                                 default:
2006                                                         ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
2007                                                 }
2008                                         }
2009                                         ast_frfree(f);
2010                                 } else {
2011                                         endtime = (long) time(NULL) - starttime;
2012                                         rna(endtime * 1000, qe, on);
2013                                         do_hang(o);
2014                                         if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2015                                                 if (qe->parent->timeoutrestart)
2016                                                         *to = orig;
2017                                                 ring_one(qe, outgoing, &numbusies);
2018                                         }
2019                                 }
2020                         }
2021                 }
2022                 if (winner == in) {
2023                         f = ast_read(in);
2024                         if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
2025                                 /* Got hung up */
2026                                 *to = -1;
2027                                 if (f)
2028                                         ast_frfree(f);
2029                                 return NULL;
2030                         }
2031                         if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass == '*')) {
2032                                 if (option_verbose > 3)
2033                                         ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
2034                                 *to = 0;
2035                                 ast_frfree(f);
2036                                 return NULL;
2037                         }
2038                         if ((f->frametype == AST_FRAME_DTMF) && (f->subclass != '*') && valid_exit(qe, f->subclass)) {
2039                                 if (option_verbose > 3)
2040                                         ast_verbose(VERBOSE_PREFIX_3 "User pressed digit: %c\n", f->subclass);
2041                                 *to = 0;
2042                                 *digit = f->subclass;
2043                                 ast_frfree(f);
2044                                 return NULL;
2045                         }
2046                         ast_frfree(f);
2047                 }
2048                 if (!*to)
2049                         rna(orig, qe, on);
2050         }
2051
2052         return peer;
2053 }
2054
2055 static int is_our_turn(struct queue_ent *qe)
2056 {
2057         struct queue_ent *ch;
2058         struct member *cur;
2059         int avl = 0;
2060         int idx = 0;
2061         int res;
2062
2063         if (!qe->parent->autofill) {
2064                 /* Atomically read the parent head -- does not need a lock */
2065                 ch = qe->parent->head;
2066                 /* If we are now at the top of the head, break out */
2067                 if (ch == qe) {
2068                         if (option_debug)
2069                                 ast_log(LOG_DEBUG, "It's our turn (%s).\n", qe->chan->name);
2070                         res = 1;
2071                 } else {
2072                         if (option_debug)
2073                                 ast_log(LOG_DEBUG, "It's not our turn (%s).\n", qe->chan->name);
2074                         res = 0;
2075                 }       
2076
2077         } else {
2078                 /* This needs a lock. How many members are available to be served? */
2079                 ast_mutex_lock(&qe->parent->lock);
2080                         
2081                 ch = qe->parent->head;
2082         
2083                 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
2084                         if (option_debug)
2085                                 ast_log(LOG_DEBUG, "Even though there are %d available members, the strategy is ringall so only the head call is allowed in\n", avl);
2086                         avl = 1;
2087                 } else {
2088                         for (cur = qe->parent->members; cur; cur = cur->next) {
2089                                 switch (cur->status) {
2090                                 case AST_DEVICE_NOT_INUSE:
2091                                 case AST_DEVICE_UNKNOWN:
2092                                         avl++;
2093                                         break;
2094                                 }
2095                         }
2096                 }
2097
2098                 if (option_debug)
2099                         ast_log(LOG_DEBUG, "There are %d available members.\n", avl);
2100         
2101                 while ((idx < avl) && (ch) && (ch != qe)) {
2102                         idx++;
2103                         ch = ch->next;                  
2104                 }
2105         
2106                 /* If the queue entry is within avl [the number of available members] calls from the top ... */
2107                 if (ch && idx < avl) {
2108                         if (option_debug)
2109                                 ast_log(LOG_DEBUG, "It's our turn (%s).\n", qe->chan->name);
2110                         res = 1;
2111                 } else {
2112                         if (option_debug)
2113                                 ast_log(LOG_DEBUG, "It's not our turn (%s).\n", qe->chan->name);
2114                         res = 0;
2115                 }
2116                 
2117                 ast_mutex_unlock(&qe->parent->lock);
2118         }
2119
2120         return res;
2121 }
2122
2123 static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *reason)
2124 {
2125         int res = 0;
2126
2127         /* This is the holding pen for callers 2 through maxlen */
2128         for (;;) {
2129                 enum queue_member_status stat;
2130
2131                 if (is_our_turn(qe))
2132                         break;
2133
2134                 /* If we have timed out, break out */
2135                 if (qe->expire && (time(NULL) > qe->expire)) {
2136                         *reason = QUEUE_TIMEOUT;
2137                         ast_queue_log(qe->parent->name, qe->chan->uniqueid,"NONE", "EXITWITHTIMEOUT", "%d", qe->pos);
2138                         break;
2139                 }
2140
2141                 stat = get_member_status(qe->parent, qe->max_penalty);
2142
2143                 /* leave the queue if no agents, if enabled */
2144                 if (qe->parent->leavewhenempty && (stat == QUEUE_NO_MEMBERS)) {
2145                         *reason = QUEUE_LEAVEEMPTY;
2146                         ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
2147                         leave_queue(qe);
2148                         break;
2149                 }
2150
2151                 /* leave the queue if no reachable agents, if enabled */
2152                 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
2153                         *reason = QUEUE_LEAVEUNAVAIL;
2154                         ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
2155                         leave_queue(qe);
2156                         break;
2157                 }
2158
2159                 /* Make a position announcement, if enabled */
2160                 if (qe->parent->announcefrequency && !ringing &&
2161                         (res = say_position(qe)))
2162                         break;
2163
2164                 /* Make a periodic announcement, if enabled */
2165                 if (qe->parent->periodicannouncefrequency && !ringing &&
2166                         (res = say_periodic_announcement(qe)))
2167                         break;
2168
2169                 /* Wait a second before checking again */
2170                 if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000)))
2171                         break;
2172         }
2173
2174         return res;
2175 }
2176
2177 static int update_queue(struct call_queue *q, struct member *member)
2178 {
2179         struct member *cur;
2180
2181         /* Since a reload could have taken place, we have to traverse the list to
2182                 be sure it's still valid */
2183         ast_mutex_lock(&q->lock);
2184         cur = q->members;
2185         while (cur) {
2186                 if (member == cur) {
2187                         time(&cur->lastcall);
2188                         cur->calls++;
2189                         break;
2190                 }
2191                 cur = cur->next;
2192         }
2193         q->callscompleted++;
2194         ast_mutex_unlock(&q->lock);
2195         return 0;
2196 }
2197
2198 static int calc_metric(struct call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp)
2199 {
2200         if (qe->max_penalty && (mem->penalty > qe->max_penalty))
2201                 return -1;
2202
2203         switch (q->strategy) {
2204         case QUEUE_STRATEGY_RINGALL:
2205                 /* Everyone equal, except for penalty */
2206                 tmp->metric = mem->penalty * 1000000;
2207                 break;
2208         case QUEUE_STRATEGY_ROUNDROBIN:
2209                 if (!pos) {
2210                         if (!q->wrapped) {
2211                                 /* No more channels, start over */
2212                                 q->rrpos = 0;
2213                         } else {
2214                                 /* Prioritize next entry */
2215                                 q->rrpos++;
2216                         }
2217                         q->wrapped = 0;
2218                 }
2219                 /* Fall through */
2220         case QUEUE_STRATEGY_RRMEMORY:
2221                 if (pos < q->rrpos) {
2222                         tmp->metric = 1000 + pos;
2223                 } else {
2224                         if (pos > q->rrpos)
2225                                 /* Indicate there is another priority */
2226                                 q->wrapped = 1;
2227                         tmp->metric = pos;
2228                 }
2229                 tmp->metric += mem->penalty * 1000000;
2230                 break;
2231         case QUEUE_STRATEGY_RANDOM:
2232                 tmp->metric = ast_random() % 1000;
2233                 tmp->metric += mem->penalty * 1000000;
2234                 break;
2235         case QUEUE_STRATEGY_FEWESTCALLS:
2236                 tmp->metric = mem->calls;
2237                 tmp->metric += mem->penalty * 1000000;
2238                 break;
2239         case QUEUE_STRATEGY_LEASTRECENT:
2240                 if (!mem->lastcall)
2241                         tmp->metric = 0;
2242                 else
2243                         tmp->metric = 1000000 - (time(NULL) - mem->lastcall);
2244                 tmp->metric += mem->penalty * 1000000;
2245                 break;
2246         default:
2247                 ast_log(LOG_WARNING, "Can't calculate metric for unknown strategy %d\n", q->strategy);
2248                 break;
2249         }
2250         return 0;
2251 }
2252
2253 static int try_calling(struct queue_ent *qe, const char *options, char *announceoverride, const char *url, int *go_on, const char *agi)
2254 {
2255         struct member *cur;
2256         struct callattempt *outgoing = NULL; /* the list of calls we are building */
2257         int to;
2258         char oldexten[AST_MAX_EXTENSION]="";
2259         char oldcontext[AST_MAX_CONTEXT]="";
2260         char queuename[256]="";
2261         struct ast_channel *peer;
2262         struct ast_channel *which;
2263         struct callattempt *lpeer;
2264         struct member *member;
2265         struct ast_app *app;
2266         int res = 0, bridge = 0;
2267         int numbusies = 0;
2268         int x=0;
2269         char *announce = NULL;
2270         char digit = 0;
2271         time_t callstart;
2272         time_t now = time(NULL);
2273         struct ast_bridge_config bridge_config;
2274         char nondataquality = 1;
2275         char *agiexec = NULL;
2276         int ret = 0;
2277         const char *monitorfilename;
2278         const char *monitor_exec;
2279         const char *monitor_options;
2280         char tmpid[256], tmpid2[256];
2281         char meid[1024], meid2[1024];
2282         char mixmonargs[1512];
2283         struct ast_app *mixmonapp = NULL;
2284         char *p;
2285         char vars[2048];
2286
2287         memset(&bridge_config, 0, sizeof(bridge_config));
2288         time(&now);
2289                 
2290         for (; options && *options; options++)
2291                 switch (*options) {
2292                 case 't':
2293                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_REDIRECT);
2294                         break;
2295                 case 'T':
2296                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_REDIRECT);
2297                         break;
2298                 case 'w':
2299                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMON);
2300                         break;
2301                 case 'W':
2302                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMON);
2303                         break;
2304                 case 'd':
2305                         nondataquality = 0;
2306                         break;
2307                 case 'h':
2308                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_DISCONNECT);
2309                         break;
2310                 case 'H':
2311                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT);
2312                         break;
2313                 case 'n':
2314                         if ((now - qe->start >= qe->parent->timeout))
2315                                 *go_on = 1;
2316                         break;
2317                 }
2318
2319         /* Hold the lock while we setup the outgoing calls */
2320         if (use_weight)
2321                 AST_LIST_LOCK(&queues);
2322         ast_mutex_lock(&qe->parent->lock);
2323         if (option_debug)
2324                 ast_log(LOG_DEBUG, "%s is trying to call a queue member.\n",
2325                                                         qe->chan->name);
2326         ast_copy_string(queuename, qe->parent->name, sizeof(queuename));
2327         cur = qe->parent->members;
2328         if (!ast_strlen_zero(qe->announce))
2329                 announce = qe->announce;
2330         if (!ast_strlen_zero(announceoverride))
2331                 announce = announceoverride;
2332
2333         for (; cur; cur = cur->next) {
2334                 struct callattempt *tmp = ast_calloc(1, sizeof(*tmp));
2335
2336                 if (!tmp) {
2337                         ast_mutex_unlock(&qe->parent->lock);
2338                         if (use_weight)
2339                                 AST_LIST_UNLOCK(&queues);
2340                         goto out;
2341                 }
2342                 tmp->stillgoing = -1;
2343                 tmp->member = cur;              /* Never directly dereference!  Could change on reload */
2344                 tmp->oldstatus = cur->status;
2345                 tmp->lastcall = cur->lastcall;
2346                 ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
2347                 /* Special case: If we ring everyone, go ahead and ring them, otherwise
2348                    just calculate their metric for the appropriate strategy */
2349                 if (!calc_metric(qe->parent, cur, x++, qe, tmp)) {
2350                         /* Put them in the list of outgoing thingies...  We're ready now.
2351                            XXX If we're forcibly removed, these outgoing calls won't get
2352                            hung up XXX */
2353                         tmp->q_next = outgoing;
2354                         outgoing = tmp;         
2355                         /* If this line is up, don't try anybody else */
2356                         if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
2357                                 break;
2358                 } else {
2359                         free(tmp);
2360                 }
2361         }
2362         if (qe->expire && (!qe->parent->timeout || (qe->expire - now) <= qe->parent->timeout))
2363                 to = (qe->expire - now) * 1000;
2364         else
2365                 to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
2366         ring_one(qe, outgoing, &numbusies);
2367         ast_mutex_unlock(&qe->parent->lock);
2368         if (use_weight)
2369                 AST_LIST_UNLOCK(&queues);
2370         lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT));
2371         ast_mutex_lock(&qe->parent->lock);
2372         if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
2373                 store_next(qe, outgoing);
2374         }
2375         ast_mutex_unlock(&qe->parent->lock);
2376         peer = lpeer ? lpeer->chan : NULL;
2377         if (!peer) {
2378                 if (to) {
2379                         /* Must gotten hung up */
2380                         res = -1;
2381                 } else {
2382                         res = digit;
2383                 }
2384                 if (option_debug)
2385                         ast_log(LOG_DEBUG, "%s: Nobody answered.\n", qe->chan->name);
2386         } else { /* peer is valid */
2387                 /* Ah ha!  Someone answered within the desired timeframe.  Of course after this
2388                    we will always return with -1 so that it is hung up properly after the
2389                    conversation.  */
2390                 qe->handled++;
2391                 if (!strcmp(qe->chan->tech->type, "Zap"))
2392                         ast_channel_setoption(qe->chan, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
2393                 if (!strcmp(peer->tech->type, "Zap"))
2394                         ast_channel_setoption(peer, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
2395                 /* Update parameters for the queue */
2396                 recalc_holdtime(qe);
2397                 member = lpeer->member;
2398                 hangupcalls(outgoing, peer);
2399                 outgoing = NULL;
2400                 if (announce || qe->parent->reportholdtime || qe->parent->memberdelay) {
2401                         int res2;
2402
2403                         res2 = ast_autoservice_start(qe->chan);
2404                         if (!res2) {
2405                                 if (qe->parent->memberdelay) {
2406                                         ast_log(LOG_NOTICE, "Delaying member connect for %d seconds\n", qe->parent->memberdelay);
2407                                         res2 |= ast_safe_sleep(peer, qe->parent->memberdelay * 1000);
2408                                 }
2409                                 if (!res2 && announce) {
2410                                         if (play_file(peer, announce))
2411                                                 ast_log(LOG_WARNING, "Announcement file '%s' is unavailable, continuing anyway...\n", announce);
2412                                 }
2413                                 if (!res2 && qe->parent->reportholdtime) {
2414                                         if (!play_file(peer, qe->parent->sound_reporthold)) {
2415                                                 int holdtime;
2416
2417                                                 time(&now);
2418                                                 holdtime = abs((now - qe->start) / 60);
2419                                                 if (holdtime < 2) {
2420                                                         play_file(peer, qe->parent->sound_lessthan);
2421                                                         ast_say_number(peer, 2, AST_DIGIT_ANY, peer->language, NULL);
2422                                                 } else
2423                                                         ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
2424                                                 play_file(peer, qe->parent->sound_minutes);
2425                                         }
2426                                 }
2427                         }
2428                         res2 |= ast_autoservice_stop(qe->chan);
2429                         if (peer->_softhangup) {
2430                                 /* Agent must have hung up */
2431                                 ast_log(LOG_WARNING, "Agent on %s hungup on the customer.  They're going to be pissed.\n", peer->name);
2432                                 ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "AGENTDUMP", "%s", "");
2433                                 record_abandoned(qe);
2434                                 if (qe->parent->eventwhencalled)
2435                                         manager_event(EVENT_FLAG_AGENT, "AgentDump",
2436                                                         "Queue: %s\r\n"
2437                                                         "Uniqueid: %s\r\n"
2438                                                         "Channel: %s\r\n"
2439                                                         "Member: %s\r\n"
2440                                                         "%s",
2441                                                         queuename, qe->chan->uniqueid, peer->name, member->interface,
2442                                                         qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2443                                 ast_hangup(peer);
2444                                 goto out;
2445                         } else if (res2) {
2446                                 /* Caller must have hung up just before being connected*/
2447                                 ast_log(LOG_NOTICE, "Caller was about to talk to agent on %s but the caller hungup.\n", peer->name);
2448                                 ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "ABANDON", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
2449                                 record_abandoned(qe);
2450                                 ast_hangup(peer);
2451                                 return -1;
2452                         }
2453                 }
2454                 /* Stop music on hold */
2455                 ast_moh_stop(qe->chan);
2456                 /* If appropriate, log that we have a destination channel */
2457                 if (qe->chan->cdr)
2458                         ast_cdr_setdestchan(qe->chan->cdr, peer->name);
2459                 /* Make sure channels are compatible */
2460                 res = ast_channel_make_compatible(qe->chan, peer);
2461                 if (res < 0) {
2462                         ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "SYSCOMPAT", "%s", "");
2463                         ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name);
2464                         record_abandoned(qe);
2465                         ast_hangup(peer);
2466                         return -1;
2467                 }
2468                 /* Begin Monitoring */
2469                 if (qe->parent->monfmt && *qe->parent->monfmt) {
2470                         if (!qe->parent->montype) {
2471                                 if (option_debug)
2472                                         ast_log(LOG_DEBUG, "Starting Monitor as requested.\n");
2473                                 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
2474                                 if (pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC") || pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC_ARGS"))
2475                                         which = qe->chan;
2476                                 else
2477                                         which = peer;
2478                                 if (monitorfilename)
2479                                         ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1 );
2480                                 else if (qe->chan->cdr)
2481                                         ast_monitor_start(which, qe->parent->monfmt, qe->chan->cdr->uniqueid, 1 );
2482                                 else {
2483                                         /* Last ditch effort -- no CDR, make up something */
2484                                         snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
2485                                         ast_monitor_start(which, qe->parent->monfmt, tmpid, 1 );
2486                                 }
2487                                 if (qe->parent->monjoin)
2488                                         ast_monitor_setjoinfiles(which, 1);
2489                         } else {
2490                                 if (option_debug)
2491                                         ast_log(LOG_DEBUG, "Starting MixMonitor as requested.\n");
2492                                 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
2493                                 if (!monitorfilename) {
2494                                         if (qe->chan->cdr)
2495                                                 ast_copy_string(tmpid, qe->chan->cdr->uniqueid, sizeof(tmpid)-1);
2496                                         else
2497                                                 snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
2498                                 } else {
2499                                         ast_copy_string(tmpid2, monitorfilename, sizeof(tmpid2)-1);
2500                                         for (p = tmpid2; *p ; p++) {
2501                                                 if (*p == '^' && *(p+1) == '{') {
2502                                                         *p = '$';
2503                                                 }
2504                                         }
2505
2506                                         memset(tmpid, 0, sizeof(tmpid));
2507                                         pbx_substitute_variables_helper(qe->chan, tmpid2, tmpid, sizeof(tmpid) - 1);
2508                                 }
2509
2510                                 monitor_exec = pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC");
2511                                 monitor_options = pbx_builtin_getvar_helper(qe->chan, "MONITOR_OPTIONS");
2512
2513                                 if (monitor_exec) {
2514                                         ast_copy_string(meid2, monitor_exec, sizeof(meid2)-1);
2515                                         for (p = meid2; *p ; p++) {
2516                                                 if (*p == '^' && *(p+1) == '{') {
2517                                                         *p = '$';
2518                                                 }
2519                                         }
2520
2521                                         memset(meid, 0, sizeof(meid));
2522                                         pbx_substitute_variables_helper(qe->chan, meid2, meid, sizeof(meid) - 1);
2523                                 }
2524         
2525                                 snprintf(tmpid2, sizeof(tmpid2)-1, "%s.%s", tmpid, qe->parent->monfmt);
2526
2527                                 mixmonapp = pbx_findapp("MixMonitor");
2528
2529                                 if (strchr(tmpid2, '|')) {
2530                                         ast_log(LOG_WARNING, "monitor-format (in queues.conf) and MONITOR_FILENAME cannot contain a '|'! Not recording.\n");
2531                                         mixmonapp = NULL;
2532                                 }
2533
2534                                 if (!monitor_options)
2535                                         monitor_options = "";
2536                                 
2537                                 if (strchr(monitor_options, '|')) {
2538                                         ast_log(LOG_WARNING, "MONITOR_OPTIONS cannot contain a '|'! Not recording.\n");
2539                                         mixmonapp = NULL;
2540                                 }
2541
2542                                 if (mixmonapp) {
2543                                         if (!ast_strlen_zero(monitor_exec) && !ast_strlen_zero(monitor_options))
2544                                                 snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s|%s", tmpid2, monitor_options, monitor_exec);
2545                                         else
2546                                                 snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s", tmpid2, monitor_options);
2547                                                 
2548                                         if (option_debug)
2549                                                 ast_log(LOG_DEBUG, "Arguments being passed to MixMonitor: %s\n", mixmonargs);
2550
2551                                         ret = pbx_exec(qe->chan, mixmonapp, mixmonargs);
2552
2553                                 } else
2554                                         ast_log(LOG_WARNING, "Asked to run MixMonitor on this call, but cannot find the MixMonitor app!\n");
2555
2556                         }
2557                 }
2558                 /* Drop out of the queue at this point, to prepare for next caller */
2559                 leave_queue(qe);                        
2560                 if (!ast_strlen_zero(url) && ast_channel_supports_html(peer)) {
2561                         if (option_debug)
2562                                 ast_log(LOG_DEBUG, "app_queue: sendurl=%s.\n", url);
2563                         ast_channel_sendurl(peer, url);
2564                 }
2565                 if (qe->parent->setinterfacevar)
2566                                 pbx_builtin_setvar_helper(qe->chan, "MEMBERINTERFACE", member->interface);
2567                 if (!ast_strlen_zero(agi)) {
2568                         if (option_debug)
2569                                 ast_log(LOG_DEBUG, "app_queue: agi=%s.\n", agi);
2570                         app = pbx_findapp("agi");
2571                         if (app) {
2572                                 agiexec = ast_strdupa(agi);
2573                                 ret = pbx_exec(qe->chan, app, agiexec);
2574                         } else
2575                                 ast_log(LOG_WARNING, "Asked to execute an AGI on this channel, but could not find application (agi)!\n");
2576                 }
2577                 ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "CONNECT", "%ld|%s", (long)time(NULL) - qe->start, peer->uniqueid);
2578                 if (qe->parent->eventwhencalled)
2579                         manager_event(EVENT_FLAG_AGENT, "AgentConnect",
2580                                         "Queue: %s\r\n"
2581                                         "Uniqueid: %s\r\n"
2582                                         "Channel: %s\r\n"
2583                                         "Member: %s\r\n"
2584                                         "Holdtime: %ld\r\n"
2585                                         "BridgedChannel: %s\r\n"
2586                                         "%s",
2587                                         queuename, qe->chan->uniqueid, peer->name, member->interface,
2588                                         (long)time(NULL) - qe->start, peer->uniqueid,
2589                                         qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2590                 ast_copy_string(oldcontext, qe->chan->context, sizeof(oldcontext));
2591                 ast_copy_string(oldexten, qe->chan->exten, sizeof(oldexten));
2592                 time(&callstart);
2593
2594                 bridge = ast_bridge_call(qe->chan,peer, &bridge_config);
2595
2596                 if (strcasecmp(oldcontext, qe->chan->context) || strcasecmp(oldexten, qe->chan->exten)) {
2597                         ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "TRANSFER", "%s|%s|%ld|%ld",
2598                                 qe->chan->exten, qe->chan->context, (long) (callstart - qe->start),
2599                                 (long) (time(NULL) - callstart));
2600                 } else if (qe->chan->_softhangup) {
2601                         ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "COMPLETECALLER", "%ld|%ld",
2602                                 (long) (callstart - qe->start), (long) (time(NULL) - callstart));
2603                         if (qe->parent->eventwhencalled)
2604                                 manager_event(EVENT_FLAG_AGENT, "AgentComplete",
2605                                                 "Queue: %s\r\n"
2606                                                 "Uniqueid: %s\r\n"
2607                                                 "Channel: %s\r\n"
2608                                                 "Member: %s\r\n"
2609                                                 "HoldTime: %ld\r\n"
2610                                                 "TalkTime: %ld\r\n"
2611                                                 "Reason: caller\r\n"
2612                                                 "%s",
2613                                                 queuename, qe->chan->uniqueid, peer->name, member->interface,
2614                                                 (long)(callstart - qe->start), (long)(time(NULL) - callstart),
2615                                                 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2616                 } else {
2617                         ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "COMPLETEAGENT", "%ld|%ld",
2618                                 (long) (callstart - qe->start), (long) (time(NULL) - callstart));
2619                         if (qe->parent->eventwhencalled)
2620                                 manager_event(EVENT_FLAG_AGENT, "AgentComplete",
2621                                                 "Queue: %s\r\n"
2622                                                 "Uniqueid: %s\r\n"
2623                                                 "Channel: %s\r\n"
2624                                                 "HoldTime: %ld\r\n"
2625                                                 "TalkTime: %ld\r\n"
2626                                                 "Reason: agent\r\n"
2627                                                 "%s",
2628                                                 queuename, qe->chan->uniqueid, peer->name, (long)(callstart - qe->start),
2629                                                 (long)(time(NULL) - callstart),
2630                                                 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2631                 }
2632
2633                 if (bridge != AST_PBX_NO_HANGUP_PEER)
2634                         ast_hangup(peer);
2635                 update_queue(qe->parent, member);
2636                 res = bridge ? bridge : 1;
2637         }
2638 out:
2639         hangupcalls(outgoing, NULL);
2640
2641         return res;
2642 }
2643
2644 static int wait_a_bit(struct queue_ent *qe)
2645 {
2646         /* Don't need to hold the lock while we setup the outgoing calls */
2647         int retrywait = qe->parent->retry * 1000;
2648
2649         return ast_waitfordigit(qe->chan, retrywait);
2650 }
2651
2652 static struct member *interface_exists(struct call_queue *q, char *interface)
2653 {
2654         struct member *mem;
2655
2656         if (!q)
2657                 return NULL;
2658
2659         for (mem = q->members; mem; mem = mem->next) {
2660                 if (!strcasecmp(interface, mem->interface))
2661                         return mem;
2662         }
2663
2664         return NULL;
2665 }
2666
2667
2668 /* Dump all members in a specific queue to the database
2669  *
2670  * <pm_family>/<queuename> = <interface>;<penalty>;<paused>[|...]
2671  *
2672  */
2673 static void dump_queue_members(struct call_queue *pm_queue)
2674 {
2675         struct member *cur_member;
2676         char value[PM_MAX_LEN];
2677         int value_len = 0;
2678         int res;
2679
2680         memset(value, 0, sizeof(value));
2681
2682         if (!pm_queue)
2683                 return;
2684
2685         for (cur_member = pm_queue->members; cur_member; cur_member = cur_member->next) {
2686                 if (!cur_member->dynamic)
2687                         continue;
2688
2689                 res = snprintf(value + value_len, sizeof(value) - value_len, "%s;%d;%d%s",
2690                         cur_member->interface, cur_member->penalty, cur_member->paused,
2691                         cur_member->next ? "|" : "");
2692                 if (res != strlen(value + value_len)) {
2693                         ast_log(LOG_WARNING, "Could not create persistent member string, out of space\n");
2694                         break;
2695                 }
2696                 value_len += res;
2697         }
2698         
2699         if (value_len && !cur_member) {
2700                 if (ast_db_put(pm_family, pm_queue->name, value))
2701                         ast_log(LOG_WARNING, "failed to create persistent dynamic entry!\n");
2702         } else
2703                 /* Delete the entry if the queue is empty or there is an error */
2704                 ast_db_del(pm_family, pm_queue->name);
2705 }
2706
2707 static int remove_from_queue(char *queuename, char *interface)
2708 {
2709         struct call_queue *q;
2710         struct member *last_member, *look;
2711         int res = RES_NOSUCHQUEUE;
2712
2713         AST_LIST_LOCK(&queues);
2714         AST_LIST_TRAVERSE(&queues, q, list) {
2715                 ast_mutex_lock(&q->lock);
2716                 if (strcmp(q->name, queuename)) {
2717                         ast_mutex_unlock(&q->lock);
2718                         continue;
2719                 }
2720
2721                 if ((last_member = interface_exists(q, interface))) {
2722                         if ((look = q->members) == last_member) {
2723                                 q->members = last_member->next;
2724                         } else {
2725                                 while (look != NULL) {
2726                                         if (look->next == last_member) {
2727                                                 look->next = last_member->next;
2728                                                 break;
2729                                         } else {
2730                                                 look = look->next;
2731                                         }
2732                                 }
2733                         }
2734                         manager_event(EVENT_FLAG_AGENT, "QueueMemberRemoved",
2735                                 "Queue: %s\r\n"
2736                                 "Location: %s\r\n",
2737                                 q->name, last_member->interface);
2738                         free(last_member);
2739                         
2740                         if (queue_persistent_members)
2741                                 dump_queue_members(q);
2742                         
2743                         res = RES_OKAY;
2744                 } else {
2745                         res = RES_EXISTS;
2746                 }
2747                 ast_mutex_unlock(&q->lock);
2748                 break;
2749         }
2750
2751         if (res == RES_OKAY)
2752                 remove_from_interfaces(interface);
2753
2754         AST_LIST_UNLOCK(&queues);
2755
2756         return res;
2757 }
2758
2759
2760 static int add_to_queue(char *queuename, char *interface, int penalty, int paused, int dump)
2761 {
2762         struct call_queue *q;
2763         struct member *new_member;
2764         int res = RES_NOSUCHQUEUE;
2765
2766         /* \note Ensure the appropriate realtime queue is loaded.  Note that this
2767          * short-circuits if the queue is already in memory. */
2768         if (!(q = load_realtime_queue(queuename)))
2769                 return res;
2770
2771         AST_LIST_LOCK(&queues);
2772
2773         ast_mutex_lock(&q->lock);
2774         if (interface_exists(q, interface) == NULL) {
2775                 add_to_interfaces(interface);
2776                 if ((new_member = create_queue_member(interface, penalty, paused))) {
2777                         new_member->dynamic = 1;
2778                         new_member->next = q->members;
2779                         q->members = new_member;
2780                         manager_event(EVENT_FLAG_AGENT, "QueueMemberAdded",
2781                                 "Queue: %s\r\n"
2782                                 "Location: %s\r\n"
2783                                 "Membership: %s\r\n"
2784                                 "Penalty: %d\r\n"
2785                                 "CallsTaken: %d\r\n"
2786                                 "LastCall: %d\r\n"
2787                                 "Status: %d\r\n"
2788                                 "Paused: %d\r\n",
2789                                 q->name, new_member->interface, new_member->dynamic ? "dynamic" : "static",
2790                                 new_member->penalty, new_member->calls, (int) new_member->lastcall,
2791                                 new_member->status, new_member->paused);
2792                         
2793                         if (dump)
2794                                 dump_queue_members(q);
2795                         
2796                         res = RES_OKAY;
2797                 } else {
2798                         res = RES_OUTOFMEMORY;
2799                 }
2800         } else {
2801                 res = RES_EXISTS;
2802         }
2803         ast_mutex_unlock(&q->lock);
2804         AST_LIST_UNLOCK(&queues);
2805
2806         return res;
2807 }
2808
2809 static int set_member_paused(char *queuename, char *interface, int paused)
2810 {
2811         int found = 0;
2812         struct call_queue *q;
2813         struct member *mem;
2814
2815         /* Special event for when all queues are paused - individual events still generated */
2816
2817         if (ast_strlen_zero(queuename))
2818                 ast_queue_log("NONE", "NONE", interface, (paused ? "PAUSEALL" : "UNPAUSEALL"), "%s", "");
2819
2820         AST_LIST_LOCK(&queues);
2821         AST_LIST_TRAVERSE(&queues, q, list) {
2822                 ast_mutex_lock(&q->lock);
2823                 if (ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename)) {
2824                         if ((mem = interface_exists(q, interface))) {
2825                                 found++;
2826                                 if (mem->paused == paused)
2827                                         ast_log(LOG_DEBUG, "%spausing already-%spaused queue member %s:%s\n", (paused ? "" : "un"), (paused ? "" : "un"), q->name, interface);
2828                                 mem->paused = paused;
2829
2830                                 if (queue_persistent_members)
2831                                         dump_queue_members(q);
2832
2833                                 ast_queue_log(q->name, "NONE", interface, (paused ? "PAUSE" : "UNPAUSE"), "%s", "");
2834
2835                                 manager_event(EVENT_FLAG_AGENT, "QueueMemberPaused",
2836                                         "Queue: %s\r\n"
2837                                         "Location: %s\r\n"
2838                                         "Paused: %d\r\n",
2839                                                 q->name, mem->interface, paused);
2840                         }
2841                 }
2842                 ast_mutex_unlock(&q->lock);
2843         }
2844         AST_LIST_UNLOCK(&queues);
2845
2846         return found ? RESULT_SUCCESS : RESULT_FAILURE;
2847 }
2848
2849 /* Reload dynamic queue members persisted into the astdb */
2850 static void reload_queue_members(void)
2851 {
2852         char *cur_ptr;  
2853         char *queue_name;
2854         char *member;
2855         char *interface;
2856         char *penalty_tok;
2857         int penalty = 0;
2858         char *paused_tok;
2859         int paused = 0;
2860         struct ast_db_entry *db_tree;
2861         struct ast_db_entry *entry;
2862         struct call_queue *cur_queue;
2863         char queue_data[PM_MAX_LEN];
2864
2865         AST_LIST_LOCK(&queues);
2866
2867         /* Each key in 'pm_family' is the name of a queue */
2868         db_tree = ast_db_gettree(pm_family, NULL);
2869         for (entry = db_tree; entry; entry = entry->next) {
2870
2871                 queue_name = entry->key + strlen(pm_family) + 2;
2872
2873                 AST_LIST_TRAVERSE(&queues, cur_queue, list) {
2874                         ast_mutex_lock(&cur_queue->lock);
2875                         if (!strcmp(queue_name, cur_queue->name))
2876                                 break;
2877                         ast_mutex_unlock(&cur_queue->lock);
2878                 }
2879
2880                 if (!cur_queue) {
2881                         /* If the queue no longer exists, remove it from the
2882                          * database */
2883                         ast_db_del(pm_family, queue_name);
2884                         continue;
2885                 } else
2886                         ast_mutex_unlock(&cur_queue->lock);
2887
2888                 if (ast_db_get(pm_family, queue_name, queue_data, PM_MAX_LEN))
2889                         continue;
2890
2891                 cur_ptr = queue_data;
2892                 while ((member = strsep(&cur_ptr, "|"))) {
2893                         if (ast_strlen_zero(member))
2894                                 continue;
2895
2896                         interface = strsep(&member, ";");
2897                         penalty_tok = strsep(&member, ";");
2898                         paused_tok = strsep(&member, ";");
2899
2900                         if (!penalty_tok) {
2901                                 ast_log(LOG_WARNING, "Error parsing persistent member string for '%s' (penalty)\n", queue_name);
2902                                 break;
2903                         }
2904                         penalty = strtol(penalty_tok, NULL, 10);
2905                         if (errno == ERANGE) {
2906                                 ast_log(LOG_WARNING, "Error converting penalty: %s: Out of range.\n", penalty_tok);
2907           &nbs