From 87b9abc892ff976733026d90e637cb243bc8d358 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Fri, 5 Jan 2007 22:43:18 +0000 Subject: Merged revisions 49676 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r49676 | kpfleming | 2007-01-05 16:16:33 -0600 (Fri, 05 Jan 2007) | 2 lines reduce stack consumption for AMI and AMI/HTTP requests by nearly 20K in most cases ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@49678 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- main/config.c | 1 - main/db.c | 18 ++-- main/manager.c | 329 +++++++++++++++++++++++++++++---------------------------- main/pbx.c | 14 +-- 4 files changed, 186 insertions(+), 176 deletions(-) (limited to 'main') diff --git a/main/config.c b/main/config.c index 7d72e0a4e..15f5064de 100644 --- a/main/config.c +++ b/main/config.c @@ -855,7 +855,6 @@ static struct ast_config *config_text_file_load(const char *database, const char lineno++; if (fgets(buf, sizeof(buf), f)) { if ( withcomments ) { - ast_log(LOG_NOTICE, "moo\n"); CB_ADD(lline_buffer); /* add the current lline buffer to the comment buffer */ lline_buffer[0] = 0; /* erase the lline buffer */ } diff --git a/main/db.c b/main/db.c index 735c93db1..84fe2cd0a 100644 --- a/main/db.c +++ b/main/db.c @@ -522,11 +522,11 @@ struct ast_cli_entry cli_database[] = { database_deltree_usage }, }; -static int manager_dbput(struct mansession *s, struct message *m) +static int manager_dbput(struct mansession *s, const struct message *m) { - char *family = astman_get_header(m, "Family"); - char *key = astman_get_header(m, "Key"); - char *val = astman_get_header(m, "Val"); + const char *family = astman_get_header(m, "Family"); + const char *key = astman_get_header(m, "Key"); + const char *val = astman_get_header(m, "Val"); int res; if (ast_strlen_zero(family)) { @@ -542,7 +542,7 @@ static int manager_dbput(struct mansession *s, struct message *m) return 0; } - res = ast_db_put(family, key, val); + res = ast_db_put(family, key, (char *) val); if (res) { astman_send_error(s, m, "Failed to update entry"); } else { @@ -551,12 +551,12 @@ static int manager_dbput(struct mansession *s, struct message *m) return 0; } -static int manager_dbget(struct mansession *s, struct message *m) +static int manager_dbget(struct mansession *s, const struct message *m) { - char *id = astman_get_header(m,"ActionID"); + const char *id = astman_get_header(m,"ActionID"); char idText[256] = ""; - char *family = astman_get_header(m, "Family"); - char *key = astman_get_header(m, "Key"); + const char *family = astman_get_header(m, "Family"); + const char *key = astman_get_header(m, "Key"); char tmp[256]; int res; diff --git a/main/manager.c b/main/manager.c index 8f6ad5d7e..345a94eca 100644 --- a/main/manager.c +++ b/main/manager.c @@ -138,8 +138,8 @@ struct mansession { int authenticated; /*!< Authentication status */ int readperm; /*!< Authorization for reading */ int writeperm; /*!< Authorization for writing */ - char inbuf[AST_MAX_MANHEADER_LEN+1]; /*!< Buffer */ - /* we use the extra byte to add a '\0' and simplify parsing */ + char inbuf[1025]; /*!< Buffer */ + /* we use the extra byte to add a '\0' and simplify parsing */ int inlen; /*!< number of buffered bytes */ int send_events; /*!< XXX what ? */ struct eventqent *last_ev; /*!< last event processed. */ @@ -356,7 +356,7 @@ static int get_perm(const char *instr) * A number returns itself, false returns 0, true returns all flags, * other strings return the flags that are set. */ -static int ast_strings_to_mask(const char *string) +static int strings_to_mask(const char *string) { const char *p; @@ -671,12 +671,12 @@ static void destroy_session(struct mansession *s) free_session(s); } -char *astman_get_header(struct message *m, char *var) +const char *astman_get_header(const struct message *m, char *var) { int x, l = strlen(var); for (x = 0; x < m->hdrcount; x++) { - char *h = m->headers[x]; + const char *h = m->headers[x]; if (!strncasecmp(var, h, l) && h[l] == ':' && h[l+1] == ' ') return h + l + 2; } @@ -684,7 +684,7 @@ char *astman_get_header(struct message *m, char *var) return ""; } -struct ast_variable *astman_get_variables(struct message *m) +struct ast_variable *astman_get_variables(const struct message *m) { int varlen, x, y; struct ast_variable *head = NULL, *cur; @@ -795,9 +795,9 @@ void astman_append(struct mansession *s, const char *fmt, ...) * XXX MSG_MOREDATA should go to a header file. */ #define MSG_MOREDATA ((char *)astman_send_response) -static void astman_send_response_full(struct mansession *s, struct message *m, char *resp, char *msg, char *listflag) +static void astman_send_response_full(struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag) { - char *id = astman_get_header(m,"ActionID"); + const char *id = astman_get_header(m,"ActionID"); astman_append(s, "Response: %s\r\n", resp); if (!ast_strlen_zero(id)) @@ -812,40 +812,39 @@ static void astman_send_response_full(struct mansession *s, struct message *m, c astman_append(s, "\r\n"); } -void astman_send_response(struct mansession *s, struct message *m, char *resp, char *msg) +void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg) { astman_send_response_full(s, m, resp, msg, NULL); } -void astman_send_error(struct mansession *s, struct message *m, char *error) +void astman_send_error(struct mansession *s, const struct message *m, char *error) { astman_send_response_full(s, m, "Error", error, NULL); } -void astman_send_ack(struct mansession *s, struct message *m, char *msg) +void astman_send_ack(struct mansession *s, const struct message *m, char *msg) { astman_send_response_full(s, m, "Success", msg, NULL); } -static void astman_start_ack(struct mansession *s, struct message *m) +static void astman_start_ack(struct mansession *s, const struct message *m) { astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL); } -void astman_send_listack(struct mansession *s, struct message *m, char *msg, char *listflag) +void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag) { astman_send_response_full(s, m, "Success", msg, listflag); } - /*! \brief Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm */ -static int set_eventmask(struct mansession *s, char *eventmask) +static int set_eventmask(struct mansession *s, const char *eventmask) { - int maskint = ast_strings_to_mask(eventmask); + int maskint = strings_to_mask(eventmask); ast_mutex_lock(&s->__lock); if (maskint >= 0) @@ -862,9 +861,9 @@ static int set_eventmask(struct mansession *s, char *eventmask) */ /* helper function for action_login() */ -static int authenticate(struct mansession *s, struct message *m) +static int authenticate(struct mansession *s, const struct message *m) { - char *user = astman_get_header(m, "Username"); + const char *user = astman_get_header(m, "Username"); int error = -1; struct ast_ha *ha = NULL; char *password = NULL; @@ -928,7 +927,7 @@ static int authenticate(struct mansession *s, struct message *m) } } if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) { - char *key = astman_get_header(m, "Key"); + const char *key = astman_get_header(m, "Key"); if (!ast_strlen_zero(key) && !ast_strlen_zero(s->challenge)) { int x; int len = 0; @@ -946,7 +945,7 @@ static int authenticate(struct mansession *s, struct message *m) error = 0; } } else if (password) { - char *pass = astman_get_header(m, "Secret"); + const char *pass = astman_get_header(m, "Secret"); if (!strcmp(password, pass)) error = 0; } @@ -967,7 +966,7 @@ static char mandescr_ping[] = " manager connection open.\n" "Variables: NONE\n"; -static int action_ping(struct mansession *s, struct message *m) +static int action_ping(struct mansession *s, const struct message *m) { astman_send_response(s, m, "Pong", NULL); return 0; @@ -979,10 +978,10 @@ static char mandescr_getconfig[] = "Variables:\n" " Filename: Configuration filename (e.g. foo.conf)\n"; -static int action_getconfig(struct mansession *s, struct message *m) +static int action_getconfig(struct mansession *s, const struct message *m) { struct ast_config *cfg; - char *fn = astman_get_header(m, "Filename"); + const char *fn = astman_get_header(m, "Filename"); int catcount = 0; int lineno = 0; char *category=NULL; @@ -1011,11 +1010,11 @@ static int action_getconfig(struct mansession *s, struct message *m) } /* helper function for action_updateconfig */ -static void handle_updates(struct mansession *s, struct message *m, struct ast_config *cfg) +static void handle_updates(struct mansession *s, const struct message *m, struct ast_config *cfg) { int x; char hdr[40]; - char *action, *cat, *var, *value, *match; + const char *action, *cat, *var, *value, *match; struct ast_category *category; struct ast_variable *v; @@ -1047,13 +1046,13 @@ static void handle_updates(struct mansession *s, struct message *m, struct ast_c } } else if (!strcasecmp(action, "delcat")) { if (!ast_strlen_zero(cat)) - ast_category_delete(cfg, cat); + ast_category_delete(cfg, (char *) cat); } else if (!strcasecmp(action, "update")) { if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat))) - ast_variable_update(category, var, value, match); + ast_variable_update(category, (char *) var, (char *) value, (char *) match); } else if (!strcasecmp(action, "delete")) { if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat))) - ast_variable_delete(category, var, match); + ast_variable_delete(category, (char *) var, (char *) match); } else if (!strcasecmp(action, "append")) { if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat)) && @@ -1079,13 +1078,13 @@ static char mandescr_updateconfig[] = " Value-XXXXXX: Value to work on\n" " Match-XXXXXX: Extra match required to match line\n"; -static int action_updateconfig(struct mansession *s, struct message *m) +static int action_updateconfig(struct mansession *s, const struct message *m) { struct ast_config *cfg; - char *sfn = astman_get_header(m, "SrcFilename"); - char *dfn = astman_get_header(m, "DstFilename"); + const char *sfn = astman_get_header(m, "SrcFilename"); + const char *dfn = astman_get_header(m, "DstFilename"); int res; - char *rld = astman_get_header(m, "Reload"); + const char *rld = astman_get_header(m, "Reload"); if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) { astman_send_error(s, m, "Filename not specified"); @@ -1119,13 +1118,13 @@ static char mandescr_waitevent[] = "Variables: \n" " Timeout: Maximum time (in seconds) to wait for events, -1 means forever.\n"; -static int action_waitevent(struct mansession *s, struct message *m) +static int action_waitevent(struct mansession *s, const struct message *m) { - char *timeouts = astman_get_header(m, "Timeout"); + const char *timeouts = astman_get_header(m, "Timeout"); int timeout = -1; int x; int needexit = 0; - char *id = astman_get_header(m,"ActionID"); + const char *id = astman_get_header(m,"ActionID"); char idText[256] = ""; if (!ast_strlen_zero(id)) @@ -1219,7 +1218,7 @@ static char mandescr_listcommands[] = " action that is available to the user\n" "Variables: NONE\n"; -static int action_listcommands(struct mansession *s, struct message *m) +static int action_listcommands(struct mansession *s, const struct message *m) { struct manager_action *cur; struct ast_str *temp = ast_str_alloca(BUFSIZ); /* XXX very large ? */ @@ -1245,9 +1244,9 @@ static char mandescr_events[] = " 'off' if no events should be sent,\n" " 'system,call,log' to select which flags events should have to be sent.\n"; -static int action_events(struct mansession *s, struct message *m) +static int action_events(struct mansession *s, const struct message *m) { - char *mask = astman_get_header(m, "EventMask"); + const char *mask = astman_get_header(m, "EventMask"); int res; res = set_eventmask(s, mask); @@ -1263,13 +1262,13 @@ static char mandescr_logoff[] = "Description: Logoff this manager session\n" "Variables: NONE\n"; -static int action_logoff(struct mansession *s, struct message *m) +static int action_logoff(struct mansession *s, const struct message *m) { astman_send_response(s, m, "Goodbye", "Thanks for all the fish."); return -1; } -static int action_login(struct mansession *s, struct message *m) +static int action_login(struct mansession *s, const struct message *m) { if (authenticate(s, m)) { sleep(1); @@ -1287,9 +1286,9 @@ static int action_login(struct mansession *s, struct message *m) return 0; } -static int action_challenge(struct mansession *s, struct message *m) +static int action_challenge(struct mansession *s, const struct message *m) { - char *authtype = astman_get_header(m, "AuthType"); + const char *authtype = astman_get_header(m, "AuthType"); if (!strcasecmp(authtype, "MD5")) { if (ast_strlen_zero(s->challenge)) @@ -1309,10 +1308,10 @@ static char mandescr_hangup[] = "Variables: \n" " Channel: The channel name to be hungup\n"; -static int action_hangup(struct mansession *s, struct message *m) +static int action_hangup(struct mansession *s, const struct message *m) { struct ast_channel *c = NULL; - char *name = astman_get_header(m, "Channel"); + const char *name = astman_get_header(m, "Channel"); if (ast_strlen_zero(name)) { astman_send_error(s, m, "No channel specified"); return 0; @@ -1335,12 +1334,12 @@ static char mandescr_setvar[] = " *Variable: Variable name\n" " *Value: Value\n"; -static int action_setvar(struct mansession *s, struct message *m) +static int action_setvar(struct mansession *s, const struct message *m) { struct ast_channel *c = NULL; - char *name = astman_get_header(m, "Channel"); - char *varname = astman_get_header(m, "Variable"); - char *varval = astman_get_header(m, "Value"); + const char *name = astman_get_header(m, "Channel"); + const char *varname = astman_get_header(m, "Variable"); + const char *varval = astman_get_header(m, "Value"); if (ast_strlen_zero(varname)) { astman_send_error(s, m, "No variable specified"); @@ -1377,11 +1376,11 @@ static char mandescr_getvar[] = " *Variable: Variable name\n" " ActionID: Optional Action id for message matching.\n"; -static int action_getvar(struct mansession *s, struct message *m) +static int action_getvar(struct mansession *s, const struct message *m) { struct ast_channel *c = NULL; - char *name = astman_get_header(m, "Channel"); - char *varname = astman_get_header(m, "Variable"); + const char *name = astman_get_header(m, "Channel"); + const char *varname = astman_get_header(m, "Variable"); char *varval; char workspace[1024]; @@ -1399,7 +1398,7 @@ static int action_getvar(struct mansession *s, struct message *m) } if (varname[strlen(varname) - 1] == ')') { - ast_func_read(c, varname, workspace, sizeof(workspace)); + ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); } else { pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); } @@ -1415,15 +1414,15 @@ static int action_getvar(struct mansession *s, struct message *m) /*! \brief Manager "status" command to show channels */ /* Needs documentation... */ -static int action_status(struct mansession *s, struct message *m) +static int action_status(struct mansession *s, const struct message *m) { - char *name = astman_get_header(m,"Channel"); + const char *name = astman_get_header(m,"Channel"); struct ast_channel *c; char bridge[256]; struct timeval now = ast_tvnow(); long elapsed_seconds = 0; int all = ast_strlen_zero(name); /* set if we want all channels */ - char *id = astman_get_header(m,"ActionID"); + const char *id = astman_get_header(m,"ActionID"); char idText[256] = ""; if (!ast_strlen_zero(id)) @@ -1509,11 +1508,11 @@ static char mandescr_sendtext[] = " *Message: Message to send\n" " ActionID: Optional Action id for message matching.\n"; -static int action_sendtext(struct mansession *s, struct message *m) +static int action_sendtext(struct mansession *s, const struct message *m) { struct ast_channel *c = NULL; - char *name = astman_get_header(m, "Channel"); - char *textmsg = astman_get_header(m, "Message"); + const char *name = astman_get_header(m, "Channel"); + const char *textmsg = astman_get_header(m, "Message"); int res = 0; if (ast_strlen_zero(name)) { @@ -1554,13 +1553,13 @@ static char mandescr_redirect[] = " ActionID: Optional Action id for message matching.\n"; /*! \brief action_redirect: The redirect manager command */ -static int action_redirect(struct mansession *s, struct message *m) +static int action_redirect(struct mansession *s, const struct message *m) { - char *name = astman_get_header(m, "Channel"); - char *name2 = astman_get_header(m, "ExtraChannel"); - char *exten = astman_get_header(m, "Exten"); - char *context = astman_get_header(m, "Context"); - char *priority = astman_get_header(m, "Priority"); + const char *name = astman_get_header(m, "Channel"); + const char *name2 = astman_get_header(m, "ExtraChannel"); + const char *exten = astman_get_header(m, "Exten"); + const char *context = astman_get_header(m, "Context"); + const char *priority = astman_get_header(m, "Priority"); struct ast_channel *chan, *chan2 = NULL; int pi = 0; int res; @@ -1614,10 +1613,10 @@ static char mandescr_command[] = " ActionID: Optional Action id for message matching.\n"; /*! \brief Manager command "command" - execute CLI command */ -static int action_command(struct mansession *s, struct message *m) +static int action_command(struct mansession *s, const struct message *m) { - char *cmd = astman_get_header(m, "Command"); - char *id = astman_get_header(m, "ActionID"); + const char *cmd = astman_get_header(m, "Command"); + const char *id = astman_get_header(m, "ActionID"); char *buf; char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ int fd = mkstemp(template); @@ -1642,16 +1641,16 @@ static int action_command(struct mansession *s, struct message *m) /* helper function for originate */ struct fast_originate_helper { - char tech[AST_MAX_MANHEADER_LEN]; - char data[AST_MAX_MANHEADER_LEN]; + char tech[AST_MAX_EXTENSION]; + char data[AST_MAX_EXTENSION]; int timeout; char app[AST_MAX_APP]; - char appdata[AST_MAX_MANHEADER_LEN]; - char cid_name[AST_MAX_MANHEADER_LEN]; - char cid_num[AST_MAX_MANHEADER_LEN]; + char appdata[AST_MAX_EXTENSION]; + char cid_name[AST_MAX_EXTENSION]; + char cid_num[AST_MAX_EXTENSION]; char context[AST_MAX_CONTEXT]; char exten[AST_MAX_EXTENSION]; - char idtext[AST_MAX_MANHEADER_LEN]; + char idtext[AST_MAX_EXTENSION]; char account[AST_MAX_ACCOUNT_CODE]; int priority; struct ast_variable *vars; @@ -1719,19 +1718,19 @@ static char mandescr_originate[] = " Account: Account code\n" " Async: Set to 'true' for fast origination\n"; -static int action_originate(struct mansession *s, struct message *m) -{ - char *name = astman_get_header(m, "Channel"); - char *exten = astman_get_header(m, "Exten"); - char *context = astman_get_header(m, "Context"); - char *priority = astman_get_header(m, "Priority"); - char *timeout = astman_get_header(m, "Timeout"); - char *callerid = astman_get_header(m, "CallerID"); - char *account = astman_get_header(m, "Account"); - char *app = astman_get_header(m, "Application"); - char *appdata = astman_get_header(m, "Data"); - char *async = astman_get_header(m, "Async"); - char *id = astman_get_header(m, "ActionID"); +static int action_originate(struct mansession *s, const struct message *m) +{ + const char *name = astman_get_header(m, "Channel"); + const char *exten = astman_get_header(m, "Exten"); + const char *context = astman_get_header(m, "Context"); + const char *priority = astman_get_header(m, "Priority"); + const char *timeout = astman_get_header(m, "Timeout"); + const char *callerid = astman_get_header(m, "CallerID"); + const char *account = astman_get_header(m, "Account"); + const char *app = astman_get_header(m, "Application"); + const char *appdata = astman_get_header(m, "Data"); + const char *async = astman_get_header(m, "Async"); + const char *id = astman_get_header(m, "ActionID"); struct ast_variable *vars = astman_get_variables(m); char *tech, *data; char *l = NULL, *n = NULL; @@ -1836,9 +1835,9 @@ static char mandescr_mailboxstatus[] = " Waiting: \n" "\n"; -static int action_mailboxstatus(struct mansession *s, struct message *m) +static int action_mailboxstatus(struct mansession *s, const struct message *m) { - char *mailbox = astman_get_header(m, "Mailbox"); + const char *mailbox = astman_get_header(m, "Mailbox"); int ret; if (ast_strlen_zero(mailbox)) { @@ -1864,9 +1863,9 @@ static char mandescr_mailboxcount[] = " NewMessages: \n" " OldMessages: \n" "\n"; -static int action_mailboxcount(struct mansession *s, struct message *m) +static int action_mailboxcount(struct mansession *s, const struct message *m) { - char *mailbox = astman_get_header(m, "Mailbox"); + const char *mailbox = astman_get_header(m, "Mailbox"); int newmsgs = 0, oldmsgs = 0; if (ast_strlen_zero(mailbox)) { @@ -1895,10 +1894,10 @@ static char mandescr_extensionstate[] = "Will return an \"Extension Status\" message.\n" "The response will include the hint for the extension and the status.\n"; -static int action_extensionstate(struct mansession *s, struct message *m) +static int action_extensionstate(struct mansession *s, const struct message *m) { - char *exten = astman_get_header(m, "Exten"); - char *context = astman_get_header(m, "Context"); + const char *exten = astman_get_header(m, "Exten"); + const char *context = astman_get_header(m, "Context"); char hint[256] = ""; int status; if (ast_strlen_zero(exten)) { @@ -1926,10 +1925,10 @@ static char mandescr_timeout[] = " *Timeout: Maximum duration of the call (sec)\n" "Acknowledges set time with 'Timeout Set' message\n"; -static int action_timeout(struct mansession *s, struct message *m) +static int action_timeout(struct mansession *s, const struct message *m) { struct ast_channel *c; - char *name = astman_get_header(m, "Channel"); + const char *name = astman_get_header(m, "Channel"); int timeout = atoi(astman_get_header(m, "Timeout")); if (ast_strlen_zero(name)) { @@ -1986,9 +1985,9 @@ static char mandescr_userevent[] = " Header1: Content1\n" " HeaderN: ContentN\n"; -static int action_userevent(struct mansession *s, struct message *m) +static int action_userevent(struct mansession *s, const struct message *m) { - char *event = astman_get_header(m, "UserEvent"); + const char *event = astman_get_header(m, "UserEvent"); char body[2048] = ""; int x, bodylen = 0; for (x = 0; x < m->hdrcount; x++) { @@ -2017,7 +2016,7 @@ static int action_userevent(struct mansession *s, struct message *m) * Process an AMI message, performing desired action. * Return 0 on success, -1 on error that require the session to be destroyed. */ -static int process_message(struct mansession *s, struct message *m) +static int process_message(struct mansession *s, const struct message *m) { char action[80] = ""; int ret = 0; @@ -2128,6 +2127,29 @@ static int get_input(struct mansession *s, char *output) return res; } +static int do_message(struct mansession *s) +{ + struct message m = { 0 }; + char header_buf[sizeof(s->inbuf)] = { '\0' }; + int res; + + for (;;) { + res = get_input(s, header_buf); + if (res > 0) { + /* Strip trailing \r\n */ + if (strlen(header_buf) < 2) + continue; + header_buf[strlen(header_buf) - 2] = '\0'; + if (ast_strlen_zero(header_buf)) + return process_message(s, &m) ? -1 : 0; + else if (m.hdrcount < (AST_MAX_MANHEADERS - 1)) + m.headers[m.hdrcount++] = ast_strdupa(header_buf); + } else { + return res; + } + } +} + /*! \brief The body of the individual manager session. * Call get_input() to read one line at a time * (or be woken up on new events), collect the lines in a @@ -2138,10 +2160,10 @@ static int get_input(struct mansession *s, char *output) */ static void *session_do(void *data) { - struct message m; /* XXX watch out, this is 20k of memory! */ struct server_instance *ser = data; struct mansession *s = ast_calloc(1, sizeof(*s)); int flags; + int res; if (s == NULL) goto done; @@ -2173,19 +2195,11 @@ static void *session_do(void *data) s->f = ser->f; astman_append(s, "Asterisk Call Manager/1.0\r\n"); /* welcome prompt */ ast_mutex_unlock(&s->__lock); - memset(&m, 0, sizeof(m)); for (;;) { - char *buf = m.headers[m.hdrcount]; - int res = get_input(s, buf); - if (res < 0) /* error */ - break; - if (res > 0) { /* got one line */ - if (ast_strlen_zero(buf)) { /* empty line, terminator */ - if (process_message(s, &m)) - break; - memset(&m, 0, sizeof(m)); - } else if (m.hdrcount < AST_MAX_MANHEADERS - 1) - m.hdrcount++; + res = do_message(s); + + if (res == 0) { + continue; } else if (process_events(s)) break; } @@ -2393,7 +2407,7 @@ static int ast_manager_register_struct(struct manager_action *act) /*! \brief register a new command with manager, including online help. This is the preferred way to register a manager command */ -int ast_manager_register2(const char *action, int auth, int (*func)(struct mansession *s, struct message *m), const char *synopsis, const char *description) +int ast_manager_register2(const char *action, int auth, int (*func)(struct mansession *s, const struct message *m), const char *synopsis, const char *description) { struct manager_action *cur; @@ -2465,17 +2479,6 @@ static struct mansession *find_session(unsigned long ident) return s; } -static void vars2msg(struct message *m, struct ast_variable *vars) -{ - int x; - for (x = 0; vars && (x < AST_MAX_MANHEADERS); x++, vars = vars->next) { - if (!vars) - break; - m->hdrcount = x + 1; - snprintf(m->headers[x], sizeof(m->headers[x]), "%s: %s", vars->name, vars->value); - } -} - /* * convert to xml with various conversion: * mode & 1 -> lowercase; @@ -2661,17 +2664,19 @@ static void xml_translate(struct ast_str **out, char *in, struct ast_variable *v } static struct ast_str *generic_http_callback(enum output_format format, - struct sockaddr_in *requestor, const char *uri, - struct ast_variable *params, int *status, - char **title, int *contentlength) + struct sockaddr_in *requestor, const char *uri, + struct ast_variable *params, int *status, + char **title, int *contentlength) { struct mansession *s = NULL; unsigned long ident = 0; /* invalid, so find_session will fail if not set through the cookie */ int blastaway = 0; - struct message m; struct ast_variable *v; char template[] = "/tmp/ast-http-XXXXXX"; /* template for temporary file */ struct ast_str *out = NULL; + struct message m = { 0 }; + unsigned int x; + size_t hdrlen; for (v = params; v; v = v->next) { if (!strcasecmp(v->name, "mansession_id")) { @@ -2705,23 +2710,49 @@ static struct ast_str *generic_http_callback(enum output_format format, ast_mutex_unlock(&s->__lock); - out = ast_str_create(1024); - if (out == NULL) { + if (!(out = ast_str_create(1024))) { *status = 500; goto generic_callback_out; } - memset(&m, 0, sizeof(m)); + + s->fd = mkstemp(template); /* create a temporary file for command output */ + unlink(template); + s->f = fdopen(s->fd, "w+"); + + for (x = 0; params && (x < AST_MAX_MANHEADERS); x++, params = params->next) { + hdrlen = strlen(params->name) + strlen(params->value) + 3; + m.headers[m.hdrcount] = alloca(hdrlen); + snprintf((char *) m.headers[m.hdrcount], hdrlen, "%s: %s", params->name, params->value); + m.hdrcount = x + 1; + } + + if (process_message(s, &m)) { + if (s->authenticated) { + if (option_verbose > 1) { + if (displayconnects) + ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); + } + ast_log(LOG_EVENT, "HTTP Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); + } else { + if (option_verbose > 1) { + if (displayconnects) + ast_verbose(VERBOSE_PREFIX_2 "HTTP Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr)); + } + ast_log(LOG_EVENT, "HTTP Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr)); + } + s->needdestroy = 1; + } + ast_str_append(&out, 0, - "Content-type: text/%s\r\n" - "Cache-Control: no-cache;\r\n" - "Set-Cookie: mansession_id=\"%08lx\"; Version=\"1\"; Max-Age=%d\r\n" - "\r\n", + "Content-type: text/%s\r\n" + "Cache-Control: no-cache;\r\n" + "Set-Cookie: mansession_id=\"%08lx\"; Version=\"1\"; Max-Age=%d\r\n" + "\r\n", contenttype[format], s->managerid, httptimeout); if (format == FORMAT_HTML) - ast_str_append(&out, 0, "Asterisk™ Manager Test Interface"); - vars2msg(&m, params); + ast_str_append(&out, 0, "Asterisk™ Manager Interface"); if (format == FORMAT_XML) { ast_str_append(&out, 0, "\n"); @@ -2738,31 +2769,12 @@ static struct ast_str *generic_http_callback(enum output_format format, ast_str_append(&out, 0, ROW_FMT, TEST_STRING); } - s->fd = mkstemp(template); /* create a temporary file for command output */ - s->f = fdopen(s->fd, "w+"); - - if (process_message(s, &m)) { - if (s->authenticated) { - if (option_verbose > 1) { - if (displayconnects) - ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); - } - ast_log(LOG_EVENT, "HTTP Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); - } else { - if (option_verbose > 1) { - if (displayconnects) - ast_verbose(VERBOSE_PREFIX_2 "HTTP Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr)); - } - ast_log(LOG_EVENT, "HTTP Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr)); - } - s->needdestroy = 1; - } if (s->f != NULL) { /* have temporary output */ char *buf; int l = ftell(s->f); /* always return something even if len == 0 */ - if ((buf = ast_calloc(1, l+1))) { + if ((buf = ast_calloc(1, l + 1))) { if (l > 0) { fseek(s->f, 0, SEEK_SET); fread(buf, 1, l, s->f); @@ -2774,7 +2786,6 @@ static struct ast_str *generic_http_callback(enum output_format format, fclose(s->f); s->f = NULL; s->fd = -1; - unlink(template); } /* Still okay because c would safely be pointing to workspace even @@ -2787,9 +2798,7 @@ static struct ast_str *generic_http_callback(enum output_format format, ast_mutex_lock(&s->__lock); /* Reset HTTP timeout. If we're not authenticated, keep it extremely short */ s->sessiontimeout = time(NULL) + ((s->authenticated || httptimeout < 5) ? httptimeout : 5); - if (0) - ast_verbose("die in %d seconds\n", - (int)(s->sessiontimeout - time(NULL)) ); + if (s->needdestroy) { if (s->inuse == 1) { if (option_debug) diff --git a/main/pbx.c b/main/pbx.c index 946395304..8d8d1899d 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -3422,7 +3422,7 @@ static int handle_show_dialplan(int fd, int argc, char *argv[]) } /*! \brief Send ack once */ -static void manager_dpsendack(struct mansession *s, struct message *m) +static void manager_dpsendack(struct mansession *s, const struct message *m) { astman_send_listack(s, m, "DialPlan list will follow", "start"); } @@ -3431,8 +3431,10 @@ static void manager_dpsendack(struct mansession *s, struct message *m) * XXX this function is similar but not exactly the same as the CLI's * show dialplan. Must check whether the difference is intentional or not. */ -static int manager_show_dialplan_helper(struct mansession *s, struct message *m, - const char *actionidtext, const char *context, char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude) +static int manager_show_dialplan_helper(struct mansession *s, const struct message *m, + const char *actionidtext, const char *context, + const char *exten, struct dialplan_counters *dpc, + struct ast_include *rinclude) { struct ast_context *c; int res=0, old_total_exten = dpc->total_exten; @@ -3574,10 +3576,10 @@ static int manager_show_dialplan_helper(struct mansession *s, struct message *m, } /*! \brief Manager listing of dial plan */ -static int manager_show_dialplan(struct mansession *s, struct message *m) +static int manager_show_dialplan(struct mansession *s, const struct message *m) { - char *exten = NULL, *context = NULL; - char *id = astman_get_header(m, "ActionID"); + const char *exten, *context; + const char *id = astman_get_header(m, "ActionID"); char idtext[256]; int res; -- cgit v1.2.3