static int action_setcdruserfield(struct mansession *s, struct message *m) { struct cw_channel *c = NULL; char *userfield = astman_get_header(m, "UserField"); char *channel = astman_get_header(m, "Channel"); char *append = astman_get_header(m, "Append"); if (cw_strlen_zero(channel)) { astman_send_error(s, m, "No Channel specified"); return 0; } if (cw_strlen_zero(userfield)) { astman_send_error(s, m, "No UserField specified"); return 0; } c = cw_get_channel_by_name_locked(channel); if (!c) { astman_send_error(s, m, "No such channel"); return 0; } if (cw_true(append)) cw_cdr_appenduserfield(c, userfield); else cw_cdr_setuserfield(c, userfield); cw_mutex_unlock(&c->lock); astman_send_ack(s, m, "CDR Userfield Set"); return 0; }
static int manager_dbput(struct mansession *s, struct message *m) { char *family = astman_get_header(m, "Family"); char *key = astman_get_header(m, "Key"); char *val = astman_get_header(m, "Val"); int res; if (ast_strlen_zero(family)) { astman_send_error(s, m, "No family specified"); return 0; } if (ast_strlen_zero(key)) { astman_send_error(s, m, "No key specified"); return 0; } if (ast_strlen_zero(val)) { astman_send_error(s, m, "No val specified"); return 0; } res = ast_db_put(family, key, val); if (res) { astman_send_error(s, m, "Failed to update entry"); } else { astman_send_ack(s, m, "Updated database successfully"); } return 0; }
static int manager_dbdeltree(struct mansession *s, const struct message *m) { const char *family = astman_get_header(m, "Family"); const char *key = astman_get_header(m, "Key"); int num_deleted; if (ast_strlen_zero(family)) { astman_send_error(s, m, "No family specified."); return 0; } if (!ast_strlen_zero(key)) { num_deleted = ast_db_deltree(family, key); } else { num_deleted = ast_db_deltree(family, NULL); } if (num_deleted < 0) { astman_send_error(s, m, "Database unavailable"); } else if (num_deleted == 0) { astman_send_error(s, m, "Database entry not found"); } else { astman_send_ack(s, m, "Key tree deleted successfully"); } return 0; }
static int change_monitor_action(struct mansession *s, struct message *m) { struct ast_channel *c = NULL; char *name = astman_get_header(m, "Channel"); char *fname = astman_get_header(m, "File"); if (ast_strlen_zero(name)) { astman_send_error(s, m, "No channel specified"); return 0; } if (ast_strlen_zero(fname)) { astman_send_error(s, m, "No filename specified"); return 0; } c = ast_get_channel_by_name_locked(name); if (!c) { astman_send_error(s, m, "No such channel"); return 0; } if (ast_monitor_change_fname(c, fname, 1)) { astman_send_error(s, m, "Could not change monitored filename of channel"); ast_channel_unlock(c); return 0; } ast_channel_unlock(c); astman_send_ack(s, m, "Changed monitor filename"); return 0; }
void *ProxyLogin(struct mansession *s, struct message *m) { struct message mo; struct proxy_user *pu; char *user, *secret, *key, *actionid; user = astman_get_header(m, "Username"); secret = astman_get_header(m, "Secret"); key = astman_get_header(m, "Key"); actionid = astman_get_header(m, "ActionID"); memset(&mo, 0, sizeof(struct message)); if( debug ) debugmsg("Login attempt as: %s/%s", user, secret); pthread_mutex_lock(&userslock); pu = pc.userlist; while( pu ) { if ( !strcmp(user, pu->username) ) { if (!AuthMD5(key, s->challenge, pu->secret) || !strcmp(secret, pu->secret) ) { AddHeader(&mo, "Response: Success"); AddHeader(&mo, "Message: Authentication accepted"); if( actionid && strlen(actionid) > 0 ) AddHeader(&mo, "ActionID: %s", actionid); s->output->write(s, &mo); FreeHeaders(&mo); pthread_mutex_lock(&s->lock); s->authenticated = 1; strcpy(s->user.channel, pu->channel); strcpy(s->user.icontext, pu->icontext); strcpy(s->user.ocontext, pu->ocontext); strcpy(s->user.account, pu->account); strcpy(s->user.server, pu->server); strcpy(s->user.more_events, pu->more_events); s->user.filter_bits = pu->filter_bits; pthread_mutex_unlock(&s->lock); if( debug ) debugmsg("Login as: %s", user); break; } } pu = pu->next; } pthread_mutex_unlock(&userslock); if( !pu ) { SendError(s, "Authentication failed", actionid); pthread_mutex_lock(&s->lock); s->authenticated = 0; pthread_mutex_unlock(&s->lock); if( debug ) debugmsg("Login failed as: %s/%s", user, secret); } return 0; }
static int manager_park(struct mansession *s, const struct message *m) { const char *channel = astman_get_header(m, "Channel"); const char *timeout_channel = S_OR(astman_get_header(m, "TimeoutChannel"), astman_get_header(m, "Channel2")); const char *timeout = astman_get_header(m, "Timeout"); const char *parkinglot = astman_get_header(m, "Parkinglot"); char buf[BUFSIZ]; int timeout_override = -1; RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup); RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup); if (ast_strlen_zero(channel)) { astman_send_error(s, m, "Channel not specified"); return 0; } if (!ast_strlen_zero(timeout)) { if (sscanf(timeout, "%30d", &timeout_override) != 1 || timeout < 0) { astman_send_error(s, m, "Invalid Timeout value."); return 0; } if (timeout_override > 0) { /* If greater than zero, convert to seconds for internal use. Must be >= 1 second. */ timeout_override = MAX(1, timeout_override / 1000); } } if (!(chan = ast_channel_get_by_name(channel))) { snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel); astman_send_error(s, m, buf); return 0; } ast_channel_lock(chan); if (!ast_strlen_zero(timeout_channel)) { pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", timeout_channel); } ast_channel_unlock(chan); if (!(parking_bridge = park_common_setup(chan, chan, parkinglot, NULL, 0, 0, timeout_override, 0))) { astman_send_error(s, m, "Park action failed\n"); return 0; } if (ast_bridge_add_channel(parking_bridge, chan, NULL, 0, NULL)) { astman_send_error(s, m, "Park action failed\n"); return 0; } astman_send_ack(s, m, "Park successful\n"); return 0; }
static int manager_bridge_info(struct mansession *s, const struct message *m) { const char *id = astman_get_header(m, "ActionID"); const char *bridge_uniqueid = astman_get_header(m, "BridgeUniqueid"); RAII_VAR(struct ast_str *, id_text, ast_str_create(128), ast_free); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); RAII_VAR(struct ast_str *, bridge_info, NULL, ast_free); struct ast_bridge_snapshot *snapshot; struct bridge_list_data list_data; if (!id_text) { astman_send_error(s, m, "Internal error"); return -1; } if (ast_strlen_zero(bridge_uniqueid)) { astman_send_error(s, m, "BridgeUniqueid must be provided"); return 0; } if (!ast_strlen_zero(id)) { ast_str_set(&id_text, 0, "ActionID: %s\r\n", id); } msg = stasis_cache_get(ast_bridge_cache(), ast_bridge_snapshot_type(), bridge_uniqueid); if (!msg) { astman_send_error(s, m, "Specified BridgeUniqueid not found"); return 0; } snapshot = stasis_message_data(msg); bridge_info = ast_manager_build_bridge_state_string(snapshot); if (!bridge_info) { astman_send_error(s, m, "Internal error"); return -1; } astman_send_listack(s, m, "Bridge channel listing will follow", "start"); list_data.id_text = ast_str_buffer(id_text); list_data.count = 0; ao2_callback_data(snapshot->channels, OBJ_NODATA, send_bridge_info_item_cb, s, &list_data); astman_send_list_complete_start(s, m, "BridgeInfoComplete", list_data.count); if (!ast_strlen_zero(ast_str_buffer(bridge_info))) { astman_append(s, "%s", ast_str_buffer(bridge_info)); } astman_send_list_complete_end(s); return 0; }
static int start_monitor_action(struct mansession *s, struct message *m) { struct ast_channel *c = NULL; char *name = astman_get_header(m, "Channel"); char *fname = astman_get_header(m, "File"); char *format = astman_get_header(m, "Format"); char *mix = astman_get_header(m, "Mix"); char *d; if (ast_strlen_zero(name)) { astman_send_error(s, m, "No channel specified"); return 0; } c = ast_get_channel_by_name_locked(name); if (!c) { astman_send_error(s, m, "No such channel"); return 0; } if (ast_strlen_zero(fname)) { /* No filename base specified, default to channel name as per CLI */ fname = malloc (FILENAME_MAX); if (!fname) { astman_send_error(s, m, "Could not start monitoring channel"); ast_mutex_unlock(&c->lock); return 0; } memset(fname, 0, FILENAME_MAX); ast_copy_string(fname, c->name, FILENAME_MAX); /* Channels have the format technology/channel_name - have to replace that / */ if ((d=strchr(fname, '/'))) *d='-'; } if (ast_monitor_start(c, format, fname, 1)) { if (ast_monitor_change_fname(c, fname, 1)) { astman_send_error(s, m, "Could not start monitoring channel"); ast_mutex_unlock(&c->lock); return 0; } } if (ast_true(mix)) { ast_monitor_setjoinfiles(c, 1); } ast_mutex_unlock(&c->lock); astman_send_ack(s, m, "Started monitoring channel"); return 0; }
/*! * \internal * \brief Update the specified mailbox. * \since 12.1.0 * * \param s AMI session. * \param m AMI message. * * \retval 0 to keep AMI connection. * \retval -1 to disconnect AMI connection. */ static int mwi_mailbox_update(struct mansession *s, const struct message *m) { const char *mailbox_id = astman_get_header(m, "Mailbox"); const char *msgs_old = astman_get_header(m, "OldMessages"); const char *msgs_new = astman_get_header(m, "NewMessages"); struct ast_mwi_mailbox_object *mailbox; unsigned int num_old; unsigned int num_new; if (ast_strlen_zero(mailbox_id)) { astman_send_error(s, m, "Missing mailbox parameter in request"); return 0; } num_old = 0; if (!ast_strlen_zero(msgs_old)) { if (sscanf(msgs_old, "%u", &num_old) != 1) { astman_send_error_va(s, m, "Invalid OldMessages: %s", msgs_old); return 0; } } num_new = 0; if (!ast_strlen_zero(msgs_new)) { if (sscanf(msgs_new, "%u", &num_new) != 1) { astman_send_error_va(s, m, "Invalid NewMessages: %s", msgs_new); return 0; } } mailbox = ast_mwi_mailbox_alloc(mailbox_id); if (!mailbox) { astman_send_error(s, m, "Mailbox object creation failure"); return 0; } /* Update external mailbox. */ ast_mwi_mailbox_set_msgs_old(mailbox, num_old); ast_mwi_mailbox_set_msgs_new(mailbox, num_new); if (ast_mwi_mailbox_update(mailbox)) { astman_send_error(s, m, "Update attempt failed"); } else { astman_send_ack(s, m, NULL); } ast_mwi_mailbox_unref(mailbox); return 0; }
/* DelFromStack - Removes an item from the stack based on the UniqueID field. */ void DelFromStack(struct message *m, struct mansession *s) { char *uniqueid; struct mstack *prev; struct mstack *t; uniqueid = astman_get_header(m, "Uniqueid"); if( uniqueid[0] == '\0' ) return; pthread_mutex_lock(&s->lock); prev = NULL; t = s->stack; while( t ) { if( !strncmp( t->uniqueid, uniqueid, sizeof(t->uniqueid) ) ) { if( t->message ) free( t->message ); if( prev ) prev->next = t->next; else s->stack = t->next; free( t ); s->depth--; if( debug ) debugmsg("Removed uniqueid: %s from stack", uniqueid); break; } prev = t; t = t->next; } pthread_mutex_unlock(&s->lock); }
int ProxyDropServer(struct mansession *s, struct message *m) { struct message mo; struct mansession *srv; char *value; int res; memset(&mo, 0, sizeof(struct message)); value = astman_get_header(m, "Server"); pthread_rwlock_rdlock(&sessionlock); srv = sessions; while (*value && srv) { if (srv->server && !strcmp(srv->server->ast_host, value)) break; srv = srv->next; } pthread_rwlock_unlock(&sessionlock); if (srv) { destroy_session(srv); debugmsg("Dropping Server %s", value); AddHeader(&mo, "ProxyResponse: Success"); AddHeader(&mo, "Message: Dropped %s", value); res = 0; } else { debugmsg("Failed to Drop Server %s -- not found", value); AddHeader(&mo, "ProxyResponse: Failure"); AddHeader(&mo, "Message: Cannot Drop Server %s, Does Not Exist", value); res = 1; } s->output->write(s, &mo); FreeHeaders(&mo); return res; }
void *ProxySetAutoFilter(struct mansession *s, struct message *m) { struct message mo; char *value; int i; value = astman_get_header(m, "AutoFilter"); if ( !strcasecmp(value, "on") ) i = 1; else if ( !strcasecmp(value, "unique") ) i = 2; else i = 0; pthread_mutex_lock(&s->lock); s->autofilter = i; if( i == 2 ) snprintf(s->actionid, MAX_LEN - 20, "amp%d-", s->fd); else s->actionid[0] = '\0'; pthread_mutex_unlock(&s->lock); memset(&mo, 0, sizeof(struct message)); AddHeader(&mo, "ProxyResponse: Success"); AddHeader(&mo, "AutoFilter: %d", s->autofilter); s->output->write(s, &mo); FreeHeaders(&mo); return 0; }
static int manager_parking_lot_list(struct mansession *s, const struct message *m) { const char *id = astman_get_header(m, "ActionID"); struct ao2_container *lot_container; char id_text[256]; struct park_list_data list_data; id_text[0] = '\0'; if (!ast_strlen_zero(id)) { snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id); } lot_container = get_parking_lot_container(); if (!lot_container) { ast_log(LOG_ERROR, "Failed to obtain parking lot list. Action canceled.\n"); astman_send_error(s, m, "Could not create parking lot list"); return 0; } astman_send_listack(s, m, "Parking lots will follow", "start"); list_data.id_text = id_text; list_data.count = 0; ao2_callback_data(lot_container, OBJ_MULTIPLE | OBJ_NODATA, manager_append_event_parking_lot_data_cb, s, &list_data); astman_send_list_complete_start(s, m, "ParkinglotsComplete", list_data.count); astman_send_list_complete_end(s); return 0; }
static int do_pause_or_unpause(struct mansession *s, struct message *m, int action) { struct ast_channel *c = NULL; char *name = astman_get_header(m, "Channel"); if (IS_NULL_STRING(name)) { astman_send_error(s, m, "No channel specified"); return -1; } c = ast_get_channel_by_name_locked(name); if (!c) { astman_send_error(s, m, "No such channel"); return -1; } if (action == MONITOR_ACTION_PAUSE) ast_monitor_pause(c); else ast_monitor_unpause(c); ast_channel_unlock(c); astman_send_ack(s, m, "Paused monitoring of the channel"); return 0; }
static int manager_optimize_away(struct mansession *s, const struct message *m) { const char *channel; struct local_pvt *p; struct local_pvt *found; struct ast_channel *chan; channel = astman_get_header(m, "Channel"); if (ast_strlen_zero(channel)) { astman_send_error(s, m, "'Channel' not specified."); return 0; } chan = ast_channel_get_by_name(channel); if (!chan) { astman_send_error(s, m, "Channel does not exist."); return 0; } p = ast_channel_tech_pvt(chan); ast_channel_unref(chan); found = p ? ao2_find(locals, p, 0) : NULL; if (found) { ao2_lock(found); ast_clear_flag(&found->base, AST_UNREAL_NO_OPTIMIZATION); ao2_unlock(found); ao2_ref(found, -1); astman_send_ack(s, m, "Queued channel to be optimized away"); } else { astman_send_error(s, m, "Unable to find channel"); } return 0; }
static int manager_parking_lot_list(struct mansession *s, const struct message *m) { const char *id = astman_get_header(m, "ActionID"); char id_text[256] = ""; struct ao2_container *lot_container; if (!ast_strlen_zero(id)) { snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id); } lot_container = get_parking_lot_container(); if (!lot_container) { ast_log(LOG_ERROR, "Failed to obtain parking lot list. Action canceled.\n"); astman_send_error(s, m, "Could not create parking lot list"); return -1; } astman_send_ack(s, m, "Parking lots will follow"); ao2_callback_data(lot_container, OBJ_MULTIPLE | OBJ_NODATA, manager_append_event_parking_lot_data_cb, s, id_text); astman_append(s, "Event: ParkinglotsComplete\r\n" "%s" "\r\n",id_text); return RESULT_SUCCESS; }
/*! * \internal * \brief Delete the requested mailboxes. * \since 12.1.0 * * \param s AMI session. * \param m AMI message. * * \retval 0 to keep AMI connection. * \retval -1 to disconnect AMI connection. */ static int mwi_mailbox_delete(struct mansession *s, const struct message *m) { const char *mailbox_id = astman_get_header(m, "Mailbox"); if (ast_strlen_zero(mailbox_id)) { astman_send_error(s, m, "Missing mailbox parameter in request"); return 0; } if (*mailbox_id == '/') { struct ast_str *regex_string; regex_string = ast_str_create(strlen(mailbox_id) + 1); if (!regex_string) { astman_send_error(s, m, "Memory Allocation Failure"); return 0; } /* Make "/regex/" into "regex" */ if (ast_regex_string_to_regex_pattern(mailbox_id, ®ex_string) != 0) { astman_send_error_va(s, m, "Mailbox regex format invalid in: %s", mailbox_id); ast_free(regex_string); return 0; } ast_mwi_mailbox_delete_by_regex(ast_str_buffer(regex_string)); ast_free(regex_string); } else { ast_mwi_mailbox_delete(mailbox_id); } astman_send_ack(s, m, NULL); return 0; }
static int manager_mutestream(struct mansession *s, const struct message *m) { const char *channel = astman_get_header(m, "Channel"); const char *id = astman_get_header(m,"ActionID"); const char *state = astman_get_header(m,"State"); const char *direction = astman_get_header(m,"Direction"); char id_text[256]; struct ast_channel *c = NULL; if (ast_strlen_zero(channel)) { astman_send_error(s, m, "Channel not specified"); return 0; } if (ast_strlen_zero(state)) { astman_send_error(s, m, "State not specified"); return 0; } if (ast_strlen_zero(direction)) { astman_send_error(s, m, "Direction not specified"); return 0; } /* Ok, we have everything */ c = ast_channel_get_by_name(channel); if (!c) { astman_send_error(s, m, "No such channel"); return 0; } if (mute_channel(c, direction, ast_true(state))) { astman_send_error(s, m, "Failed to mute/unmute stream"); ast_channel_unref(c); return 0; } ast_channel_unref(c); if (!ast_strlen_zero(id)) { snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id); } else { id_text[0] = '\0'; } astman_append(s, "Response: Success\r\n" "%s" "\r\n", id_text); return 0; }
int AddToStack(struct message *m, struct mansession *s, int withbody) { char *uniqueid; int ret, absent; ret=0; absent=0; uniqueid = astman_get_header(m, "Uniqueid"); if( uniqueid[0] != '\0' ) { if( do_AddToStack(uniqueid, m, s, withbody) ) ret |= ATS_UNIQUE; } else absent++; uniqueid = astman_get_header(m, "SrcUniqueID"); if( uniqueid[0] != '\0' ) { if( do_AddToStack(uniqueid, m, s, withbody) ) ret |= ATS_SRCUNIQUE; } else { uniqueid = astman_get_header(m, "Uniqueid1"); if( uniqueid[0] != '\0' ) { if( do_AddToStack(uniqueid, m, s, withbody) ) ret |= ATS_SRCUNIQUE; } else absent++; } uniqueid = astman_get_header(m, "DestUniqueID"); if( uniqueid[0] != '\0' ) { if( do_AddToStack(uniqueid, m, s, withbody) ) ret |= ATS_DSTUNIQUE; } else { uniqueid = astman_get_header(m, "Uniqueid2"); if( uniqueid[0] != '\0' ) { if( do_AddToStack(uniqueid, m, s, withbody) ) ret |= ATS_DSTUNIQUE; } else absent++; } if( s->user.more_events[0] != '\0' && absent == 3 ) ret = 1; // Want more/anonymous events if (debug > 4 ) debugmsg("AddToStack for fd: %d returning: %d", s->fd, ret); return ret; }
static int manager_parking_status(struct mansession *s, const struct message *m) { const char *id = astman_get_header(m, "ActionID"); const char *lot_name = astman_get_header(m, "ParkingLot"); char id_text[256] = ""; if (!ast_strlen_zero(id)) { snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id); } if (!ast_strlen_zero(lot_name)) { return manager_parking_status_single_lot(s, m, id_text, lot_name); } return manager_parking_status_all_lots(s, m, id_text); }
/*! * \internal * \brief AMI entry point to send a SIP notify to an endpoint. */ static int manager_notify(struct mansession *s, const struct message *m) { const char *endpoint_name = astman_get_header(m, "Endpoint"); const char *uri = astman_get_header(m, "URI"); if (!ast_strlen_zero(endpoint_name) && !ast_strlen_zero(uri)) { astman_send_error(s, m, "PJSIPNotify action can not handle a request specifying " "both 'URI' and 'Endpoint'. You must use only one of the two.\n"); } else if (!ast_strlen_zero(endpoint_name)) { manager_notify_endpoint(s, m, endpoint_name); } else if (!ast_strlen_zero(uri)) { manager_notify_uri(s, m, uri); } else { astman_send_error(s, m, "PJSIPNotify requires either an endpoint name or a SIP URI."); } return 0; }
static int manager_bridge_kick(struct mansession *s, const struct message *m) { const char *bridge_uniqueid = astman_get_header(m, "BridgeUniqueid"); const char *channel_name = astman_get_header(m, "Channel"); RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup); RAII_VAR(struct ast_channel *, channel, NULL, ao2_cleanup); if (ast_strlen_zero(channel_name)) { astman_send_error(s, m, "Channel must be provided"); return 0; } channel = ast_channel_get_by_name(channel_name); if (!channel) { astman_send_error(s, m, "Channel does not exist"); return 0; } if (ast_strlen_zero(bridge_uniqueid)) { /* get the bridge from the channel */ ast_channel_lock(channel); bridge = ast_channel_get_bridge(channel); ast_channel_unlock(channel); if (!bridge) { astman_send_error(s, m, "Channel is not in a bridge"); return 0; } } else { bridge = ast_bridge_find_by_id(bridge_uniqueid); if (!bridge) { astman_send_error(s, m, "Bridge not found"); return 0; } } if (ast_bridge_kick(bridge, channel)) { astman_send_error(s, m, "Channel kick from bridge failed"); return 0; } astman_send_ack(s, m, "Channel has been kicked"); return 0; }
static int manager_bridges_list(struct mansession *s, const struct message *m) { const char *id = astman_get_header(m, "ActionID"); const char *type_filter = astman_get_header(m, "BridgeType"); RAII_VAR(struct ast_str *, id_text, ast_str_create(128), ast_free); RAII_VAR(struct ao2_container *, bridges, NULL, ao2_cleanup); struct bridge_list_data list_data; if (!id_text) { astman_send_error(s, m, "Internal error"); return -1; } if (!ast_strlen_zero(id)) { ast_str_set(&id_text, 0, "ActionID: %s\r\n", id); } bridges = stasis_cache_dump(ast_bridge_cache(), ast_bridge_snapshot_type()); if (!bridges) { astman_send_error(s, m, "Internal error"); return -1; } astman_send_listack(s, m, "Bridge listing will follow", "start"); if (!ast_strlen_zero(type_filter)) { char *type_filter_dup = ast_strdupa(type_filter); ao2_callback(bridges, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK, filter_bridge_type_cb, type_filter_dup); } list_data.id_text = ast_str_buffer(id_text); list_data.count = 0; ao2_callback_data(bridges, OBJ_NODATA, send_bridge_list_item_cb, s, &list_data); astman_send_list_complete_start(s, m, "BridgeListComplete", list_data.count); astman_send_list_complete_end(s); return 0; }
int ProxyAddServer(struct mansession *s, struct message *m) { struct message mo; struct ast_server *srv; int res = 0; /* malloc ourselves a server credentials structure */ srv = malloc(sizeof(struct ast_server)); if ( !srv ) { fprintf(stderr, "Failed to allocate server credentials: %s\n", strerror(errno)); exit(1); } memset(srv, 0, sizeof(struct ast_server) ); memset(&mo, 0, sizeof(struct message)); strcpy(srv->ast_host, astman_get_header(m, "Server")); strcpy(srv->ast_user, astman_get_header(m, "Username")); strcpy(srv->ast_pass, astman_get_header(m, "Secret")); strcpy(srv->ast_port, astman_get_header(m, "Port")); strcpy(srv->ast_events, astman_get_header(m, "Events")); if (*srv->ast_host && *srv->ast_user && *srv->ast_pass && *srv->ast_port && *srv->ast_events) { pthread_mutex_lock(&serverlock); srv->next = pc.serverlist; pc.serverlist = srv; pthread_mutex_unlock(&serverlock); res = StartServer(srv); } else res = 1; if (res) { AddHeader(&mo, "ProxyResponse: Failure"); AddHeader(&mo, "Message: Could not add %s", srv->ast_host); } else { AddHeader(&mo, "ProxyResponse: Success"); AddHeader(&mo, "Message: Added %s", srv->ast_host); } s->output->write(s, &mo); FreeHeaders(&mo); return 0; }
static int manager_dbget(struct mansession *s, const struct message *m) { const char *id = astman_get_header(m,"ActionID"); char idText[256] = ""; const char *family = astman_get_header(m, "Family"); const char *key = astman_get_header(m, "Key"); char tmp[MAX_DB_FIELD]; int res; if (ast_strlen_zero(family)) { astman_send_error(s, m, "No family specified."); return 0; } if (ast_strlen_zero(key)) { astman_send_error(s, m, "No key specified."); return 0; } if (!ast_strlen_zero(id)) snprintf(idText, sizeof(idText) ,"ActionID: %s\r\n", id); res = ast_db_get(family, key, tmp, sizeof(tmp)); if (res) { astman_send_error(s, m, "Database entry not found"); } else { astman_send_ack(s, m, "Result will follow"); astman_append(s, "Event: DBGetResponse\r\n" "Family: %s\r\n" "Key: %s\r\n" "Val: %s\r\n" "%s" "\r\n", family, key, tmp, idText); astman_append(s, "Event: DBGetComplete\r\n" "%s" "\r\n", idText); } return 0; }
int ProxyChallenge(struct mansession *s, struct message *m) { struct message mo; char *actionid; actionid = astman_get_header(m, "ActionID"); if ( strcasecmp("MD5", astman_get_header(m, "AuthType")) ) { SendError(s, "Must specify AuthType", actionid); return 1; } if (!*s->challenge) snprintf(s->challenge, sizeof(s->challenge), "%d", rand()); memset(&mo, 0, sizeof(struct message)); AddHeader(&mo, "Response: Success"); AddHeader(&mo, "Challenge: %s", s->challenge); if( actionid && strlen(actionid) ) AddHeader(&mo, "ActionID: %s", actionid); s->output->write(s, &mo); FreeHeaders(&mo); return 0; }
static int manager_play_dtmf(struct mansession *s, const struct message *m) { const char *channel = astman_get_header(m, "Channel"); const char *digit = astman_get_header(m, "Digit"); struct ast_channel *chan = ast_get_channel_by_name_locked(channel); if (!chan) { astman_send_error(s, m, "Channel not specified"); return 0; } if (ast_strlen_zero(digit)) { astman_send_error(s, m, "No digit specified"); ast_mutex_unlock(&chan->lock); return 0; } ast_senddigit(chan, *digit); ast_mutex_unlock(&chan->lock); astman_send_ack(s, m, "DTMF successfully queued"); return 0; }
void *ProxySetOutputFormat(struct mansession *s, struct message *m) { struct message mo; char *value; value = astman_get_header(m, "OutputFormat"); SetIOHandlers(s, s->input->formatname, value); memset(&mo, 0, sizeof(struct message)); AddHeader(&mo, "ProxyResponse: Success"); AddHeader(&mo, "OutputFormat: %s", s->output->formatname ); s->output->write(s, &mo); FreeHeaders(&mo); return 0; }
static int manager_dbdel(struct mansession *s, const struct message *m) { const char *family = astman_get_header(m, "Family"); const char *key = astman_get_header(m, "Key"); int res; if (ast_strlen_zero(family)) { astman_send_error(s, m, "No family specified."); return 0; } if (ast_strlen_zero(key)) { astman_send_error(s, m, "No key specified."); return 0; } res = ast_db_del(family, key); if (res) astman_send_error(s, m, "Database entry not found"); else astman_send_ack(s, m, "Key deleted successfully"); return 0; }
static int ami_sip_qualify(struct mansession *s, const struct message *m) { const char *endpoint_name = astman_get_header(m, "Endpoint"); RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup); char *aors; char *aor_name; if (ast_strlen_zero(endpoint_name)) { astman_send_error(s, m, "Endpoint parameter missing."); return 0; } endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", endpoint_name); if (!endpoint) { astman_send_error(s, m, "Unable to retrieve endpoint\n"); return 0; } /* send a qualify for all contacts registered with the endpoint */ if (ast_strlen_zero(endpoint->aors)) { astman_send_error(s, m, "No AoRs configured for endpoint\n"); return 0; } aors = ast_strdupa(endpoint->aors); while ((aor_name = strsep(&aors, ","))) { struct ast_sip_aor *aor; struct ao2_container *contacts; aor = ast_sip_location_retrieve_aor(aor_name); if (!aor) { continue; } contacts = ast_sip_location_retrieve_aor_contacts(aor); if (contacts) { ao2_callback(contacts, OBJ_NODATA, ami_contact_cb, NULL); ao2_ref(contacts, -1); } ao2_ref(aor, -1); } astman_send_ack(s, m, "Endpoint found, will qualify"); return 0; }