29#define ASTMM_LIBC ASTMM_IGNORE
36#include <netinet/in.h>
38#include <sys/socket.h>
39#include <sys/select.h>
49#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
62#define _NEWT_CAST (void *)
64#define DEFAULT_MANAGER_PORT 5038
72 struct sockaddr_in
sin;
102int64_t
ast_mark(
int,
int start1_stop0);
119 memset(chan, 0,
sizeof(
struct ast_chan));
141static void __attribute__((format(printf, 2, 3)))
fdprintf(
int fd,
char *fmt, ...)
147 vsnprintf(stuff,
sizeof(stuff), fmt, ap);
149 if (write(fd, stuff, strlen(stuff)) < 0) {
150 fprintf(stderr,
"write() failed: %s\n", strerror(
errno));
158 snprintf(cmp,
sizeof(cmp),
"%s: ",
var);
160 if (!strncasecmp(cmp, m->
headers[x], strlen(cmp)))
161 return m->
headers[x] + strlen(cmp);
254 if (!strlen(
event)) {
255 fprintf(stderr,
"Missing event in request");
266 fprintf(stderr,
"Ignoring unknown event '%s'",
event);
269 printf(
"Header: %s\n", m->
headers[x]);
279 char tmpn[
sizeof(chan->
name) +
sizeof(chan->
callerid) + 3 - 1];
282 prev = newtListboxGetCurrent(
c);
285 snprintf(tmpn,
sizeof(tmpn),
"%s (%s)", chan->
name, chan->
callerid);
286 if (strlen(chan->
exten))
287 snprintf(
tmp,
sizeof(
tmp),
"%-30s %8s -> %s@%s:%s",
291 snprintf(
tmp,
sizeof(
tmp),
"%-30s %8s",
293 newtListboxAppendEntry(
c,
tmp, chan);
297 newtListboxAppendEntry(
c,
" << No Active Channels >> ",
NULL);
298 newtListboxSetCurrentByKey(
c, prev);
304 for (x=1;x<s->
inlen;x++)
305 if ((s->
inbuf[x] ==
'\n') && (s->
inbuf[x-1] ==
'\r'))
315 struct timeval tv = {0, 0};
317 for (x=1;x<s->
inlen;x++) {
318 if ((s->
inbuf[x] ==
'\n') && (s->
inbuf[x-1] ==
'\r')) {
320 memcpy(output, s->
inbuf, x + 1);
330 fprintf(stderr,
"Dumping long line with no return from %s: %s\n",
inet_ntoa(s->
sin.sin_addr), s->
inbuf);
335 res = select(s->
fd + 1, &fds,
NULL,
NULL, &tv);
337 fprintf(stderr,
"Select returned error: %s\n", strerror(
errno));
338 }
else if (res > 0) {
370 if (mout && strlen(
get_header(&m,
"Response"))) {
376 memset(&m, 0,
sizeof(m));
379 }
else if (res < 0) {
394 tv.tv_sec = timeout / 1000;
395 tv.tv_usec = (timeout % 1000) * 1000;
410static int __attribute__((format(printf, 2, 3)))
manager_action(
char *action,
char *fmt, ...)
420 vsnprintf(
tmp,
sizeof(
tmp), fmt, ap);
422 if ((res = write(s->
fd,
tmp, strlen(
tmp))) < 0) {
423 fprintf(stderr,
"write() failed: %s\n", strerror(
errno));
434 struct newtExitStruct es;
436 newtCenteredWindow(60,7, title);
438 label = newtLabel(4,1,msg);
439 ok = newtButton(27, 3,
"OK");
441 newtFormAddComponents(form, label, ok,
NULL);
442 newtFormRun(form, &es);
444 newtFormDestroy(form);
451 struct newtExitStruct es;
454 newtCenteredWindow(70,4, title);
455 label = newtLabel(3,1,
tmp);
475 show_message(
"Status Failed",
"Timeout waiting for response");
476 }
else if (strcasecmp(
get_header(m,
"Response"),
"Success")) {
487 chan = newtListboxGetCurrent(
c);
492 show_message(
"Hangup Failed",
"Timeout waiting for response");
493 }
else if (strcasecmp(
get_header(m,
"Response"),
"Success")) {
504 newtComponent cancel;
505 newtComponent inpfield;
508 struct newtExitStruct es;
510 newtCenteredWindow(60,7, msg);
513 ok = newtButton(22, 3,
"OK");
514 cancel = newtButton(32, 3,
"Cancel");
516 newtFormAddComponents(form, inpfield, ok, cancel,
NULL);
517 newtFormRun(form, &es);
524 newtFormDestroy(form);
533 static const char tmp_prefix[] =
"Enter new extension for ";
535 char tmp[
sizeof(tmp_prefix) +
sizeof(channame)];
538 chan = newtListboxGetCurrent(
c);
540 snprintf(channame,
sizeof(channame),
"%s", chan->
name);
541 snprintf(
tmp,
sizeof(
tmp),
"%s%s", tmp_prefix, channame);
544 if ((
context = strchr(dest,
'@'))) {
549 manager_action(
"Redirect",
"Channel: %s\r\nExten: %s\r\nPriority: 1\r\n", chan->
name, dest);
553 show_message(
"Hangup Failed",
"Timeout waiting for response");
554 }
else if (strcasecmp(
get_header(m,
"Response"),
"Success")) {
566 newtComponent redirect;
568 struct newtExitStruct es;
591 snprintf(
tmp,
sizeof(
tmp),
"Asterisk Manager at %s", host);
592 newtCenteredWindow(74, 20,
tmp);
594 newtFormWatchFd(form,
session.
fd, NEWT_FD_READ);
595 newtFormSetTimer(form, 100);
596 quit = newtButton(62, 16,
"Quit");
597 redirect = newtButton(35, 16,
"Redirect");
598 hangup = newtButton(50, 16,
"Hangup");
599 channels = newtListbox(1,1,14, NEWT_FLAG_SCROLL);
603 show_doing(
"Getting Status",
"Retrieving system status...");
608 newtFormRun(form, &es);
611 show_message(
"Disconnected",
"Disconnected from remote host");
614 }
else if (es.reason == NEWT_EXIT_COMPONENT) {
619 }
else if (es.u.co == redirect) {
625 newtFormDestroy(form);
632 newtComponent cancel;
634 newtComponent username;
635 newtComponent password;
637 newtComponent ulabel;
638 newtComponent plabel;
642 struct newtExitStruct es;
647 session.
fd = socket(AF_INET, SOCK_STREAM, 0);
649 snprintf(
tmp,
sizeof(
tmp),
"socket() failed: %s\n", strerror(
errno));
680 login = newtButton(5, 6,
"Login");
681 cancel = newtButton(25, 6,
"Cancel");
682 newtCenteredWindow(40, 10,
"Asterisk Manager Login");
684 label = newtLabel(4,1,
tmp);
686 ulabel = newtLabel(4,2,
"Username:");
687 plabel = newtLabel(4,3,
"Password:");
690 password = newtEntry(14, 3,
"", 20,
_NEWT_CAST &
pass, NEWT_FLAG_HIDDEN);
693 newtFormAddComponents(form, username, password, login, cancel, label, ulabel, plabel,
NULL);
694 newtFormRun(form, &es);
695 if (es.reason == NEWT_EXIT_COMPONENT) {
696 if (es.u.co == login) {
697 snprintf(
tmp,
sizeof(
tmp),
"Logging in '%s'...",
user);
702 if (m && !strcasecmp(
get_header(m,
"Response"),
"Success")) {
706 char md5key[256] =
"";
708 unsigned char digest[16];
714 len += sprintf(md5key +
len,
"%02hhx", digest[x]);
722 if (!strcasecmp(
get_header(m,
"Response"),
"Success")) {
735 if (!strcasecmp(
get_header(m,
"Response"),
"Success")) {
744 newtFormDestroy(form);
748int main(
int argc,
char *argv[])
751 fprintf(stderr,
"Usage: astman <host>\n");
756 newtDrawRootText(0, 0,
"Asterisk Manager (C)2002, Linux Support Services, Inc.");
757 newtPushHelpLine(
"Welcome to the Asterisk Manager!");
static int input(yyscan_t yyscanner)
Asterisk main include file. File version handling, generic pbx functions.
int ast_add_profile(const char *, uint64_t scale)
support for event profiling
static int event_newstate(struct ast_mansession *s, struct message *m)
int main(int argc, char *argv[])
static int get_input(struct ast_mansession *s, char *output)
static int event_newchannel(struct ast_mansession *s, struct message *m)
static struct event events[]
static struct ast_mansession session
static int hide_doing(void)
static int event_ignore(struct ast_mansession *s, struct message *m)
static int event_status(struct ast_mansession *s, struct message *m)
static int show_message(char *title, char *msg)
static int get_user_input(char *msg, char *buf, int buflen)
static int event_hangup(struct ast_mansession *s, struct message *m)
static int event_newexten(struct ast_mansession *s, struct message *m)
static int process_message(struct ast_mansession *s, struct message *m)
static struct ast_chan * find_chan(char *name)
static int manager_action(char *action, char *fmt,...)
static int event_rename(struct ast_mansession *s, struct message *m)
static int has_input(struct ast_mansession *s)
static void try_status(void)
static struct message * wait_for_response(int timeout)
int64_t ast_mark(int, int start1_stop0)
int64_t ast_profile(int, int64_t)
static void try_hangup(newtComponent c)
#define DEFAULT_MANAGER_PORT
static void del_chan(char *name)
static int show_doing(char *title, char *tmp)
static int manager_login(char *hostname)
static void fdprintf(int fd, char *fmt,...)
static char * get_header(struct message *m, char *var)
static void try_redirect(newtComponent c)
static void rebuild_channels(newtComponent c)
static int input_check(struct ast_mansession *s, struct message **mout)
static int manage_calls(char *host)
static newtComponent showform
static int hangup(void *data)
static struct channel_usage channels
static int md5(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
A set of macros to manage forward-linked lists.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_HEAD_NOLOCK_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
static char hostname[MAXHOSTNAMELEN]
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
void MD5Init(struct MD5Context *context)
void MD5Final(unsigned char digest[16], struct MD5Context *context)
static void challenge(const char *realm, pjsip_tx_data *tdata, const pjsip_rx_data *rdata, int is_stale)
astobj2 callback for adding digest challenges to responses
struct ast_chan::@505 list
int(* func)(struct ast_mansession *s, struct message *m)
const char * headers[AST_MAX_MANHEADERS]
structure to hold users read from users.conf