static int pickup_exec(struct ast_channel *chan, void *data)
{
	int res = 0;
	struct localuser *u = NULL;
	struct ast_channel *origin = NULL, *target = NULL;
	char *tmp = NULL, *exten = NULL, *context = NULL, *rest=data;
	char workspace[256] = "";
	const char *tmp2 = NULL;

	if (ast_strlen_zero(data)) {
		ast_log(LOG_WARNING, "Pickup requires an argument (extension) !\n");
		return -1;	
	}

	LOCAL_USER_ADD(u);
	
	while (!target && (exten = rest) ) {
		res = 0;
		rest = strchr(exten, '&');
		if (rest)
			*rest++ = 0;

		/* Get the extension and context if present */
		context = strchr(exten, '@');
		if (context)
			*context++ = '\0';

		/* If the context is the pickup mark, iterate through all channels finding the right origin one */
		if (!strcmp(context, PICKUPMARK)) {
			while ((origin = ast_channel_walk_locked(origin))) {
				if (origin) {
					tmp2 = pbx_builtin_getvar_helper(origin, PICKUPMARK);
					if (tmp2 && !strcmp(tmp2, exten))
						break;
					ast_mutex_unlock(&origin->lock);
				}
			}
		} else {
			/* Use the classic mode of searching */
			origin = ast_get_channel_by_exten_locked(exten, context);
		}

		if (origin) {
			ast_cdr_getvar(origin->cdr, "dstchannel", &tmp, workspace,
					sizeof(workspace), 0, 0);
			if (tmp) {
				/* We have a possible channel... now we need to find it! */
				target = ast_get_channel_by_name_locked(tmp);
			} else {
				ast_log(LOG_NOTICE, "No target channel found for %s.\n", exten);
				res = -1;
			}
			ast_mutex_unlock(&origin->lock);

		} else {
			ast_log(LOG_DEBUG, "No originating channel found.\n");
		}

		if (res)
			continue;

		if (target && (!target->pbx) && ((target->_state == AST_STATE_RINGING) || (target->_state == AST_STATE_RING) ) ) {
			ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n", target->name,
					chan->name);
			res = ast_answer(chan);
			if (res) {
				ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
				res = -1;
				break;
			}
			res = ast_queue_control(chan, AST_CONTROL_ANSWER);
			if (res) {
				ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n",
						chan->name);
				res = -1;
				break;
			}
			res = ast_channel_masquerade(target, chan);
			if (res) {
				ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name);
				res = -1;
				break;
			}
		} else {
			ast_log(LOG_NOTICE, "No call pickup possible for %s...\n", exten);
			res = -1;
		}
	}
	if (target) 
		ast_mutex_unlock(&target->lock);
	
	LOCAL_USER_REMOVE(u);

	return res;
}
static int pickup_exec(struct ast_channel *chan, void *data)
{
	int res = 0;
	struct localuser *u = NULL;
	struct ast_channel *origin = NULL, *target = NULL;
	char *tmp = NULL, *exten = NULL, *context = NULL;
	char workspace[256] = "";

	if (ast_strlen_zero(data)) {
		ast_log(LOG_WARNING, "Pickup requires an argument (extension) !\n");
		return -1;	
	}

	LOCAL_USER_ADD(u);
	
	/* Get the extension and context if present */
	exten = data;
	context = strchr(data, '@');
	if (context) {
		*context = '\0';
		context++;
	}

	/* Find a channel to pickup */
	origin = ast_get_channel_by_exten_locked(exten, context);
	if (origin && origin->cdr) {
		ast_cdr_getvar(origin->cdr, "dstchannel", &tmp, workspace,
			       sizeof(workspace), 0);
		if (tmp) {
			/* We have a possible channel... now we need to find it! */
			target = ast_get_channel_by_name_locked(tmp);
		} else {
			ast_log(LOG_DEBUG, "No target channel found.\n");
			res = -1;
		}
		ast_mutex_unlock(&origin->lock);
	} else {
		if (origin)
			ast_mutex_unlock(&origin->lock);
		ast_log(LOG_DEBUG, "No originating channel found.\n");
	}
	
	if (res)
		goto out;

	if (target && (!target->pbx) && ((target->_state == AST_STATE_RINGING) || (target->_state == AST_STATE_RING))) {
		ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n", target->name,
			chan->name);
		res = ast_answer(chan);
		if (res) {
			ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
			res = -1;
			goto out;
		}
		res = ast_queue_control(chan, AST_CONTROL_ANSWER);
		if (res) {
			ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n",
				chan->name);
			res = -1;
			goto out;
		}
		res = ast_channel_masquerade(target, chan);
		if (res) {
			ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name);
			res = -1;
			goto out;
		}
	} else {
		ast_log(LOG_DEBUG, "No call pickup possible...\n");
		res = -1;
	}
	/* Done */
 out:
	if (target) 
		ast_mutex_unlock(&target->lock);
	
	LOCAL_USER_REMOVE(u);

	return res;
}