Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
astman.c File Reference
#include "asterisk.h"
#include <newt.h>
#include <stdio.h>
#include <sys/time.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include "asterisk/md5.h"
#include "asterisk/linkedlists.h"
Include dependency graph for astman.c:

Go to the source code of this file.

Data Structures

struct  ast_chan
 
struct  ast_mansession
 
struct  chans
 
struct  event
 
struct  message
 

Macros

#define _NEWT_CAST   (void *)
 
#define ARRAY_LEN(a)   (sizeof(a) / sizeof(a[0]))
 
#define ASTMM_LIBC   ASTMM_IGNORE
 
#define DEFAULT_MANAGER_PORT   5038
 
#define MAX_HEADERS   80
 
#define MAX_LEN   256
 

Functions

int ast_add_profile (const char *, uint64_t scale)
 support for event profiling More...
 
int64_t ast_mark (int, int start1_stop0)
 
int64_t ast_profile (int, int64_t)
 
static void del_chan (char *name)
 
static int event_hangup (struct ast_mansession *s, struct message *m)
 
static int event_ignore (struct ast_mansession *s, struct message *m)
 
static int event_newchannel (struct ast_mansession *s, struct message *m)
 
static int event_newexten (struct ast_mansession *s, struct message *m)
 
static int event_newstate (struct ast_mansession *s, struct message *m)
 
static int event_rename (struct ast_mansession *s, struct message *m)
 
static int event_status (struct ast_mansession *s, struct message *m)
 
static void fdprintf (int fd, char *fmt,...)
 
static struct ast_chanfind_chan (char *name)
 
static char * get_header (struct message *m, char *var)
 
static int get_input (struct ast_mansession *s, char *output)
 
static int get_user_input (char *msg, char *buf, int buflen)
 
static int has_input (struct ast_mansession *s)
 
static int hide_doing (void)
 
static int input_check (struct ast_mansession *s, struct message **mout)
 
int main (int argc, char *argv[])
 
static int manage_calls (char *host)
 
static int manager_action (char *action, char *fmt,...)
 
static int manager_login (char *hostname)
 
static int process_message (struct ast_mansession *s, struct message *m)
 
static void rebuild_channels (newtComponent c)
 
static int show_doing (char *title, char *tmp)
 
static int show_message (char *title, char *msg)
 
static void try_hangup (newtComponent c)
 
static void try_redirect (newtComponent c)
 
static void try_status (void)
 
static struct messagewait_for_response (int timeout)
 

Variables

static struct chans chans = { .first = NULL, .last = NULL, }
 
static struct event events []
 
static struct ast_mansession session
 
static newtComponent showform
 

Macro Definition Documentation

◆ _NEWT_CAST

#define _NEWT_CAST   (void *)

Definition at line 62 of file astman.c.

Referenced by get_user_input(), and manager_login().

◆ ARRAY_LEN

#define ARRAY_LEN (   a)    (sizeof(a) / sizeof(a[0]))

Definition at line 49 of file astman.c.

Referenced by process_message().

◆ ASTMM_LIBC

#define ASTMM_LIBC   ASTMM_IGNORE

Definition at line 29 of file astman.c.

◆ DEFAULT_MANAGER_PORT

#define DEFAULT_MANAGER_PORT   5038

Definition at line 64 of file astman.c.

Referenced by manager_login().

◆ MAX_HEADERS

#define MAX_HEADERS   80

Definition at line 53 of file astman.c.

Referenced by input_check().

◆ MAX_LEN

#define MAX_LEN   256

Definition at line 54 of file astman.c.

Function Documentation

◆ ast_add_profile()

int ast_add_profile ( const char *  s,
uint64_t  scale 
)

support for event profiling

(note, this must be documented a lot more) ast_add_profile allocates a generic 'counter' with a given name, which can be shown with the command 'core show profile <name>'

The counter accumulates positive or negative values supplied by

See also
ast_add_profile(), dividing them by the 'scale' value passed in the create call, and also counts the number of 'events'. Values can also be taked by the TSC counter on ia32 architectures, in which case you can mark the start of an event calling ast_mark(id, 1) and then the end of the event with ast_mark(id, 0). For non-i386 architectures, these two calls return 0.

support for event profiling

Returns
Returns the identifier of the counter.

Definition at line 92 of file astman.c.

References ast_profile().

93 {
94  return -1;
95 }

◆ ast_mark()

int64_t ast_mark ( int  key,
int  start1_stop0 
)

Definition at line 103 of file astman.c.

Referenced by __ast_pthread_mutex_lock(), ao2_weakproxy_unsubscribe(), ast_profile(), and extension_match_core().

104 {
105  return 0;
106 }

◆ ast_profile()

int64_t ast_profile ( int  key,
int64_t  val 
)

Definition at line 98 of file astman.c.

References ast_mark().

Referenced by ast_add_profile().

99 {
100  return 0;
101 }

◆ del_chan()

static void del_chan ( char *  name)
static

Definition at line 126 of file astman.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, free(), ast_chan::list, and ast_chan::name.

Referenced by event_hangup().

127 {
128  struct ast_chan *chan;
129 
131  if (!strcmp(name, chan->name)) {
133  free(chan);
134  return;
135  }
136  }
138 }
struct ast_chan::@514 list
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
void free()
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
char name[80]
Definition: astman.c:79
static const char name[]
Definition: cdr_mysql.c:74
Definition: astman.c:88
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528

◆ event_hangup()

static int event_hangup ( struct ast_mansession s,
struct message m 
)
static

Definition at line 204 of file astman.c.

References del_chan(), and get_header().

205 {
206  del_chan(get_header(m, "Channel"));
207  return 0;
208 }
static char * get_header(struct message *m, char *var)
Definition: astman.c:154
static void del_chan(char *name)
Definition: astman.c:126

◆ event_ignore()

static int event_ignore ( struct ast_mansession s,
struct message m 
)
static

Definition at line 210 of file astman.c.

211 {
212  return 0;
213 }

◆ event_newchannel()

static int event_newchannel ( struct ast_mansession s,
struct message m 
)
static

Definition at line 183 of file astman.c.

References ast_chan::callerid, find_chan(), get_header(), and ast_chan::state.

184 {
185  struct ast_chan *chan;
186  chan = find_chan(get_header(m, "Channel"));
187  strncpy(chan->state, get_header(m, "State"), sizeof(chan->state) - 1);
188  strncpy(chan->callerid, get_header(m, "Callerid"), sizeof(chan->callerid) - 1);
189  return 0;
190 }
static char * get_header(struct message *m, char *var)
Definition: astman.c:154
static struct ast_chan * find_chan(char *name)
Definition: astman.c:110
char callerid[40]
Definition: astman.c:83
char state[10]
Definition: astman.c:84

◆ event_newexten()

static int event_newexten ( struct ast_mansession s,
struct message m 
)
static

Definition at line 173 of file astman.c.

References ast_chan::context, ast_chan::exten, find_chan(), get_header(), and ast_chan::priority.

174 {
175  struct ast_chan *chan;
176  chan = find_chan(get_header(m, "Channel"));
177  strncpy(chan->exten, get_header(m, "Extension"), sizeof(chan->exten) - 1);
178  strncpy(chan->context, get_header(m, "Context"), sizeof(chan->context) - 1);
179  strncpy(chan->priority, get_header(m, "Priority"), sizeof(chan->priority) - 1);
180  return 0;
181 }
static char * get_header(struct message *m, char *var)
Definition: astman.c:154
static struct ast_chan * find_chan(char *name)
Definition: astman.c:110
char priority[20]
Definition: astman.c:82
char exten[20]
Definition: astman.c:80
char context[20]
Definition: astman.c:81

◆ event_newstate()

static int event_newstate ( struct ast_mansession s,
struct message m 
)
static

Definition at line 165 of file astman.c.

References find_chan(), get_header(), and ast_chan::state.

166 {
167  struct ast_chan *chan;
168  chan = find_chan(get_header(m, "Channel"));
169  strncpy(chan->state, get_header(m, "State"), sizeof(chan->state) - 1);
170  return 0;
171 }
static char * get_header(struct message *m, char *var)
Definition: astman.c:154
static struct ast_chan * find_chan(char *name)
Definition: astman.c:110
char state[10]
Definition: astman.c:84

◆ event_rename()

static int event_rename ( struct ast_mansession s,
struct message m 
)
static

Definition at line 215 of file astman.c.

References find_chan(), get_header(), and ast_chan::name.

216 {
217  struct ast_chan *chan;
218  chan = find_chan(get_header(m, "Oldname"));
219  strncpy(chan->name, get_header(m, "Newname"), sizeof(chan->name) - 1);
220  return 0;
221 }
static char * get_header(struct message *m, char *var)
Definition: astman.c:154
static struct ast_chan * find_chan(char *name)
Definition: astman.c:110
char name[80]
Definition: astman.c:79

◆ event_status()

static int event_status ( struct ast_mansession s,
struct message m 
)
static

Definition at line 192 of file astman.c.

References ast_chan::callerid, ast_chan::context, ast_chan::exten, find_chan(), get_header(), ast_chan::priority, and ast_chan::state.

193 {
194  struct ast_chan *chan;
195  chan = find_chan(get_header(m, "Channel"));
196  strncpy(chan->state, get_header(m, "State"), sizeof(chan->state) - 1);
197  strncpy(chan->callerid, get_header(m, "Callerid"), sizeof(chan->callerid) - 1);
198  strncpy(chan->exten, get_header(m, "Extension"), sizeof(chan->exten) - 1);
199  strncpy(chan->context, get_header(m, "Context"), sizeof(chan->context) - 1);
200  strncpy(chan->priority, get_header(m, "Priority"), sizeof(chan->priority) - 1);
201  return 0;
202 }
static char * get_header(struct message *m, char *var)
Definition: astman.c:154
static struct ast_chan * find_chan(char *name)
Definition: astman.c:110
char priority[20]
Definition: astman.c:82
char exten[20]
Definition: astman.c:80
char context[20]
Definition: astman.c:81
char callerid[40]
Definition: astman.c:83
char state[10]
Definition: astman.c:84

◆ fdprintf()

static void fdprintf ( int  fd,
char *  fmt,
  ... 
)
static

Definition at line 141 of file astman.c.

References errno.

Referenced by manager_action().

142 {
143  char stuff[4096];
144  va_list ap;
145 
146  va_start(ap, fmt);
147  vsnprintf(stuff, sizeof(stuff), fmt, ap);
148  va_end(ap);
149  if (write(fd, stuff, strlen(stuff)) < 0) {
150  fprintf(stderr, "write() failed: %s\n", strerror(errno));
151  }
152 }
int errno

◆ find_chan()

static struct ast_chan* find_chan ( char *  name)
static

Definition at line 110 of file astman.c.

References AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_chan::list, malloc(), and ast_chan::name.

Referenced by event_newchannel(), event_newexten(), event_newstate(), event_rename(), and event_status().

111 {
112  struct ast_chan *chan;
113  AST_LIST_TRAVERSE(&chans, chan, list) {
114  if (!strcmp(name, chan->name))
115  return chan;
116  }
117  chan = malloc(sizeof(struct ast_chan));
118  if (chan) {
119  memset(chan, 0, sizeof(struct ast_chan));
120  strncpy(chan->name, name, sizeof(chan->name) - 1);
122  }
123  return chan;
124 }
struct ast_chan::@514 list
char * malloc()
char name[80]
Definition: astman.c:79
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char name[]
Definition: cdr_mysql.c:74
Definition: astman.c:88

◆ get_header()

static char* get_header ( struct message m,
char *  var 
)
static

Definition at line 154 of file astman.c.

References message::hdrcount, and message::headers.

Referenced by event_hangup(), event_newchannel(), event_newexten(), event_newstate(), event_rename(), event_status(), input_check(), manager_login(), process_message(), try_hangup(), try_redirect(), and try_status().

155 {
156  char cmp[80];
157  int x;
158  snprintf(cmp, sizeof(cmp), "%s: ", var);
159  for (x=0;x<m->hdrcount;x++)
160  if (!strncasecmp(cmp, m->headers[x], strlen(cmp)))
161  return m->headers[x] + strlen(cmp);
162  return "";
163 }
#define var
Definition: ast_expr2f.c:614
const char * headers[AST_MAX_MANHEADERS]
Definition: manager.h:146
unsigned int hdrcount
Definition: manager.h:145

◆ get_input()

static int get_input ( struct ast_mansession s,
char *  output 
)
static

Definition at line 310 of file astman.c.

References errno, ast_mansession::fd, FD_SET, FD_ZERO, ast_mansession::inbuf, inet_ntoa, ast_mansession::inlen, NULL, and ast_mansession::sin.

Referenced by input_check().

311 {
312  /* output must have at least sizeof(s->inbuf) space */
313  int res;
314  int x;
315  struct timeval tv = {0, 0};
316  fd_set fds;
317  for (x=1;x<s->inlen;x++) {
318  if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) {
319  /* Copy output data up to and including \r\n */
320  memcpy(output, s->inbuf, x + 1);
321  /* Add trailing \0 */
322  output[x+1] = '\0';
323  /* Move remaining data back to the front */
324  memmove(s->inbuf, s->inbuf + x + 1, s->inlen - x);
325  s->inlen -= (x + 1);
326  return 1;
327  }
328  }
329  if (s->inlen >= sizeof(s->inbuf) - 1) {
330  fprintf(stderr, "Dumping long line with no return from %s: %s\n", inet_ntoa(s->sin.sin_addr), s->inbuf);
331  s->inlen = 0;
332  }
333  FD_ZERO(&fds);
334  FD_SET(s->fd, &fds);
335  res = select(s->fd + 1, &fds, NULL, NULL, &tv);
336  if (res < 0) {
337  fprintf(stderr, "Select returned error: %s\n", strerror(errno));
338  } else if (res > 0) {
339  res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen);
340  if (res < 1)
341  return -1;
342  s->inlen += res;
343  s->inbuf[s->inlen] = '\0';
344  } else {
345  return 2;
346  }
347  return 0;
348 }
char inbuf[MAX_LEN]
Definition: astman.c:74
#define NULL
Definition: resample.c:96
#define FD_ZERO(a)
Definition: select.h:49
#define FD_SET(fd, fds)
Definition: select.h:58
#define inet_ntoa
Definition: network.h:87
int errno
struct sockaddr_in sin
Definition: astman.c:72

◆ get_user_input()

static int get_user_input ( char *  msg,
char *  buf,
int  buflen 
)
static

Definition at line 500 of file astman.c.

References _NEWT_CAST, input(), and NULL.

Referenced by try_redirect().

501 {
502  newtComponent form;
503  newtComponent ok;
504  newtComponent cancel;
505  newtComponent inpfield;
506  const char *input;
507  int res = -1;
508  struct newtExitStruct es;
509 
510  newtCenteredWindow(60,7, msg);
511 
512  inpfield = newtEntry(5, 2, "", 50, _NEWT_CAST &input, 0);
513  ok = newtButton(22, 3, "OK");
514  cancel = newtButton(32, 3, "Cancel");
515  form = newtForm(NULL, NULL, 0);
516  newtFormAddComponents(form, inpfield, ok, cancel, NULL);
517  newtFormRun(form, &es);
518  strncpy(buf, input, buflen - 1);
519  if (es.u.co == ok)
520  res = 0;
521  else
522  res = -1;
523  newtPopWindow();
524  newtFormDestroy(form);
525  return res;
526 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define NULL
Definition: resample.c:96
static int input(yyscan_t yyscanner)
Definition: ast_expr2f.c:1584
#define _NEWT_CAST
Definition: astman.c:62

◆ has_input()

static int has_input ( struct ast_mansession s)
static

Definition at line 301 of file astman.c.

References ast_mansession::inbuf, and ast_mansession::inlen.

Referenced by manage_calls().

302 {
303  int x;
304  for (x=1;x<s->inlen;x++)
305  if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r'))
306  return 1;
307  return 0;
308 }
char inbuf[MAX_LEN]
Definition: astman.c:74

◆ hide_doing()

static int hide_doing ( void  )
static

Definition at line 462 of file astman.c.

Referenced by manage_calls(), and manager_login().

463 {
464  newtPopWindow();
465  newtFormDestroy(showform);
466  return 0;
467 }
static newtComponent showform
Definition: astman.c:448

◆ input_check()

static int input_check ( struct ast_mansession s,
struct message **  mout 
)
static

Definition at line 350 of file astman.c.

References get_header(), get_input(), message::hdrcount, message::headers, MAX_HEADERS, NULL, and process_message().

Referenced by manage_calls(), and wait_for_response().

351 {
352  static struct message m;
353  int res;
354 
355  if (mout)
356  *mout = NULL;
357 
358  for(;;) {
359  res = get_input(s, m.headers[m.hdrcount]);
360  if (res == 1) {
361 #if 0
362  fprintf(stderr, "Got header: %s", m.headers[m.hdrcount]);
363  fgetc(stdin);
364 #endif
365  /* Strip trailing \r\n */
366  if (strlen(m.headers[m.hdrcount]) < 2)
367  continue;
368  m.headers[m.hdrcount][strlen(m.headers[m.hdrcount]) - 2] = '\0';
369  if (!strlen(m.headers[m.hdrcount])) {
370  if (mout && strlen(get_header(&m, "Response"))) {
371  *mout = &m;
372  return 0;
373  }
374  if (process_message(s, &m))
375  break;
376  memset(&m, 0, sizeof(m));
377  } else if (m.hdrcount < MAX_HEADERS - 1)
378  m.hdrcount++;
379  } else if (res < 0) {
380  return -1;
381  } else if (res == 2)
382  return 0;
383  }
384  return -1;
385 }
#define MAX_HEADERS
Definition: astman.c:53
static char * get_header(struct message *m, char *var)
Definition: astman.c:154
#define NULL
Definition: resample.c:96
static int process_message(struct ast_mansession *s, struct message *m)
Definition: astman.c:249
static int get_input(struct ast_mansession *s, char *output)
Definition: astman.c:310

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 748 of file astman.c.

References manage_calls(), and manager_login().

749 {
750  if (argc < 2) {
751  fprintf(stderr, "Usage: astman <host>\n");
752  exit(1);
753  }
754  newtInit();
755  newtCls();
756  newtDrawRootText(0, 0, "Asterisk Manager (C)2002, Linux Support Services, Inc.");
757  newtPushHelpLine("Welcome to the Asterisk Manager!");
758  if (manager_login(argv[1])) {
759  newtFinished();
760  exit(1);
761  }
762  manage_calls(argv[1]);
763  newtFinished();
764  return 0;
765 }
static int manage_calls(char *host)
Definition: astman.c:561
static int manager_login(char *hostname)
Definition: astman.c:629

◆ manage_calls()

static int manage_calls ( char *  host)
static

Definition at line 561 of file astman.c.

References channels, ast_mansession::fd, hangup(), has_input(), hide_doing(), input_check(), NULL, rebuild_channels(), session, show_doing(), show_message(), tmp(), try_hangup(), try_redirect(), and try_status().

Referenced by main().

562 {
563  newtComponent form;
564  newtComponent quit;
565  newtComponent hangup;
566  newtComponent redirect;
567  newtComponent channels;
568  struct newtExitStruct es;
569  char tmp[80];
570 
571  /* Mark: If there's one thing you learn from this code, it is this...
572  Never, ever fly Air France. Their customer service is absolutely
573  the worst. I've never heard the words "That's not my problem" as
574  many times as I have from their staff -- It should, without doubt
575  be their corporate motto if it isn't already. Don't bother giving
576  them business because you're just a pain in their side and they
577  will be sure to let you know the first time you speak to them.
578 
579  If you ever want to make me happy just tell me that you, too, will
580  never fly Air France again either (in spite of their excellent
581  cuisine).
582 
583  Update by oej: The merger with KLM has transferred this
584  behaviour to KLM as well.
585  Don't bother giving them business either...
586 
587  Only if you want to travel randomly without luggage, you
588  might pick either of them.
589 
590  */
591  snprintf(tmp, sizeof(tmp), "Asterisk Manager at %s", host);
592  newtCenteredWindow(74, 20, tmp);
593  form = newtForm(NULL, NULL, 0);
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);
600  newtFormAddComponents(form, channels, redirect, hangup, quit, NULL);
601  newtListboxSetWidth(channels, 72);
602 
603  show_doing("Getting Status", "Retrieving system status...");
604  try_status();
605  hide_doing();
606 
607  for(;;) {
608  newtFormRun(form, &es);
609  if (has_input(&session) || (es.reason == NEWT_EXIT_FDREADY)) {
610  if (input_check(&session, NULL)) {
611  show_message("Disconnected", "Disconnected from remote host");
612  break;
613  }
614  } else if (es.reason == NEWT_EXIT_COMPONENT) {
615  if (es.u.co == quit)
616  break;
617  if (es.u.co == hangup) {
618  try_hangup(channels);
619  } else if (es.u.co == redirect) {
620  try_redirect(channels);
621  }
622  }
623  rebuild_channels(channels);
624  }
625  newtFormDestroy(form);
626  return 0;
627 }
static int tmp()
Definition: bt_open.c:389
static int hangup(void *data)
Definition: chan_pjsip.c:2483
#define NULL
Definition: resample.c:96
static char host[256]
Definition: muted.c:77
static void try_hangup(newtComponent c)
Definition: astman.c:482
static struct ast_mansession session
static void try_redirect(newtComponent c)
Definition: astman.c:528
static struct channel_usage channels
static void try_status(void)
Definition: astman.c:469
static int show_doing(char *title, char *tmp)
Definition: astman.c:449
static int show_message(char *title, char *msg)
Definition: astman.c:429
static void rebuild_channels(newtComponent c)
Definition: astman.c:275
static int hide_doing(void)
Definition: astman.c:462
static int input_check(struct ast_mansession *s, struct message **mout)
Definition: astman.c:350
static int has_input(struct ast_mansession *s)
Definition: astman.c:301

◆ manager_action()

static int manager_action ( char *  action,
char *  fmt,
  ... 
)
static

Definition at line 410 of file astman.c.

References errno, ast_mansession::fd, fdprintf(), session, and tmp().

Referenced by manager_login(), try_hangup(), try_redirect(), and try_status().

411 {
412  struct ast_mansession *s;
413  char tmp[4096];
414  va_list ap;
415  int res;
416 
417  s = &session;
418  fdprintf(s->fd, "Action: %s\r\n", action);
419  va_start(ap, fmt);
420  vsnprintf(tmp, sizeof(tmp), fmt, ap);
421  va_end(ap);
422  if ((res = write(s->fd, tmp, strlen(tmp))) < 0) {
423  fprintf(stderr, "write() failed: %s\n", strerror(errno));
424  }
425  fdprintf(s->fd, "\r\n");
426  return 0;
427 }
static int tmp()
Definition: bt_open.c:389
static struct ast_mansession session
int errno
static void fdprintf(int fd, char *fmt,...)
Definition: astman.c:141

◆ manager_login()

static int manager_login ( char *  hostname)
static

Definition at line 629 of file astman.c.

References _NEWT_CAST, challenge(), DEFAULT_MANAGER_PORT, errno, ast_mansession::fd, get_header(), gethostbyname, hide_doing(), hp, len(), manager_action(), MD5Final(), MD5Init(), MD5Update(), NULL, pass, password, session, show_doing(), show_message(), ast_mansession::sin, tmp(), user, and wait_for_response().

Referenced by main().

630 {
631  newtComponent form;
632  newtComponent cancel;
633  newtComponent login;
634  newtComponent username;
635  newtComponent password;
636  newtComponent label;
637  newtComponent ulabel;
638  newtComponent plabel;
639  const char *user;
640  const char *pass;
641  struct message *m;
642  struct newtExitStruct es;
643  char tmp[55];
644  struct hostent *hp;
645  int res = -1;
646 
647  session.fd = socket(AF_INET, SOCK_STREAM, 0);
648  if (session.fd < 0) {
649  snprintf(tmp, sizeof(tmp), "socket() failed: %s\n", strerror(errno));
650  show_message("Socket failed", tmp);
651  return -1;
652  }
653 
654  snprintf(tmp, sizeof(tmp), "Looking up %s\n", hostname);
655  show_doing("Connecting....", tmp);
656 
657 
658  hp = gethostbyname(hostname);
659  if (!hp) {
660  snprintf(tmp, sizeof(tmp), "No such address: %s\n", hostname);
661  show_message("Host lookup failed", tmp);
662  return -1;
663  }
664  hide_doing();
665  snprintf(tmp, sizeof(tmp), "Connecting to %s", hostname);
666  show_doing("Connecting...", tmp);
667 
668  session.sin.sin_family = AF_INET;
669  session.sin.sin_port = htons(DEFAULT_MANAGER_PORT);
670  memcpy(&session.sin.sin_addr, hp->h_addr, sizeof(session.sin.sin_addr));
671 
672  if (connect(session.fd,(struct sockaddr*)&session.sin, sizeof(session.sin))) {
673  snprintf(tmp, sizeof(tmp), "%s failed: %s\n", hostname, strerror(errno));
674  show_message("Connect Failed", tmp);
675  return -1;
676  }
677 
678  hide_doing();
679 
680  login = newtButton(5, 6, "Login");
681  cancel = newtButton(25, 6, "Cancel");
682  newtCenteredWindow(40, 10, "Asterisk Manager Login");
683  snprintf(tmp, sizeof(tmp), "Host: %s", hostname);
684  label = newtLabel(4,1, tmp);
685 
686  ulabel = newtLabel(4,2,"Username:");
687  plabel = newtLabel(4,3,"Password:");
688 
689  username = newtEntry(14, 2, "", 20, _NEWT_CAST &user, 0);
690  password = newtEntry(14, 3, "", 20, _NEWT_CAST &pass, NEWT_FLAG_HIDDEN);
691 
692  form = newtForm(NULL, NULL, 0);
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);
698  show_doing("Logging in", tmp);
699  /* Check to see if the remote host supports MD5 Authentication */
700  manager_action("Challenge", "AuthType: MD5\r\n");
701  m = wait_for_response(10000);
702  if (m && !strcasecmp(get_header(m, "Response"), "Success")) {
703  char *challenge = get_header(m, "Challenge");
704  int x;
705  int len = 0;
706  char md5key[256] = "";
707  struct MD5Context md5;
708  unsigned char digest[16];
709  MD5Init(&md5);
710  MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
711  MD5Update(&md5, (unsigned char *)pass, strlen(pass));
712  MD5Final(digest, &md5);
713  for (x=0; x<16; x++)
714  len += sprintf(md5key + len, "%02hhx", digest[x]);
715  manager_action("Login",
716  "AuthType: MD5\r\n"
717  "Username: %s\r\n"
718  "Key: %s\r\n",
719  user, md5key);
720  m = wait_for_response(10000);
721  hide_doing();
722  if (!strcasecmp(get_header(m, "Response"), "Success")) {
723  res = 0;
724  } else {
725  show_message("Login Failed", get_header(m, "Message"));
726  }
727  } else {
728  manager_action("Login",
729  "Username: %s\r\n"
730  "Secret: %s\r\n",
731  user, pass);
732  m = wait_for_response(10000);
733  hide_doing();
734  if (m) {
735  if (!strcasecmp(get_header(m, "Response"), "Success")) {
736  res = 0;
737  } else {
738  show_message("Login Failed", get_header(m, "Message"));
739  }
740  }
741  }
742  }
743  }
744  newtFormDestroy(form);
745  return res;
746 }
static char user[512]
static char pass[512]
#define gethostbyname
Definition: lock.h:637
static struct message * wait_for_response(int timeout)
Definition: astman.c:387
static char * get_header(struct message *m, char *var)
Definition: astman.c:154
#define DEFAULT_MANAGER_PORT
Definition: astman.c:64
static int tmp()
Definition: bt_open.c:389
void MD5Final(unsigned char digest[16], struct MD5Context *context)
Definition: md5.c:120
#define NULL
Definition: resample.c:96
static struct ast_str * password
Definition: cdr_mysql.c:77
void MD5Init(struct MD5Context *context)
Definition: md5.c:57
static struct ast_mansession session
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
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
Definition: md5.c:72
static int md5(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_md5.c:52
static int show_doing(char *title, char *tmp)
Definition: astman.c:449
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno
static int show_message(char *title, char *msg)
Definition: astman.c:429
struct sockaddr_in sin
Definition: astman.c:72
Definition: md5.h:26
static int hide_doing(void)
Definition: astman.c:462
#define _NEWT_CAST
Definition: astman.c:62
static struct ast_str * hostname
Definition: cdr_mysql.c:77
static int manager_action(char *action, char *fmt,...)
Definition: astman.c:410
static struct hostent * hp
Definition: chan_skinny.c:1236

◆ process_message()

static int process_message ( struct ast_mansession s,
struct message m 
)
static

Definition at line 249 of file astman.c.

References ARRAY_LEN, events, get_header(), message::hdrcount, and message::headers.

Referenced by input_check().

250 {
251  int x;
252  char event[80] = "";
253  strncpy(event, get_header(m, "Event"), sizeof(event) - 1);
254  if (!strlen(event)) {
255  fprintf(stderr, "Missing event in request");
256  return 0;
257  }
258  for (x = 0; x < ARRAY_LEN(events); x++) {
259  if (!strcasecmp(event, events[x].event)) {
260  if (events[x].func(s, m))
261  return -1;
262  break;
263  }
264  }
265  if (x >= ARRAY_LEN(events))
266  fprintf(stderr, "Ignoring unknown event '%s'", event);
267 #if 0
268  for (x=0;x<m->hdrcount;x++) {
269  printf("Header: %s\n", m->headers[x]);
270  }
271 #endif
272  return 0;
273 }
static char * get_header(struct message *m, char *var)
Definition: astman.c:154
Definition: astman.c:222
static struct event events[]
const char * headers[AST_MAX_MANHEADERS]
Definition: manager.h:146
#define ARRAY_LEN(a)
Definition: astman.c:49
unsigned int hdrcount
Definition: manager.h:145

◆ rebuild_channels()

static void rebuild_channels ( newtComponent  c)
static

Definition at line 275 of file astman.c.

References AST_LIST_TRAVERSE, ast_chan::callerid, ast_chan::context, ast_chan::exten, ast_chan::list, ast_chan::name, NULL, ast_chan::priority, ast_chan::state, and tmp().

Referenced by manage_calls().

276 {
277  void *prev = NULL;
278  struct ast_chan *chan;
279  char tmpn[sizeof(chan->name) + sizeof(chan->callerid) + 3 - 1];
280  char tmp[256];
281  int x=0;
282  prev = newtListboxGetCurrent(c);
283  newtListboxClear(c);
284  AST_LIST_TRAVERSE(&chans, chan, list) {
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",
288  tmpn, chan->state,
289  chan->exten, chan->context, chan->priority);
290  else
291  snprintf(tmp, sizeof(tmp), "%-30s %8s",
292  tmpn, chan->state);
293  newtListboxAppendEntry(c, tmp, chan);
294  x++;
295  }
296  if (!x)
297  newtListboxAppendEntry(c, " << No Active Channels >> ", NULL);
298  newtListboxSetCurrentByKey(c, prev);
299 }
struct ast_chan::@514 list
static int tmp()
Definition: bt_open.c:389
static struct test_val c
char priority[20]
Definition: astman.c:82
#define NULL
Definition: resample.c:96
char name[80]
Definition: astman.c:79
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char exten[20]
Definition: astman.c:80
Definition: astman.c:88
char context[20]
Definition: astman.c:81
char callerid[40]
Definition: astman.c:83
char state[10]
Definition: astman.c:84

◆ show_doing()

static int show_doing ( char *  title,
char *  tmp 
)
static

Definition at line 449 of file astman.c.

References NULL.

Referenced by manage_calls(), and manager_login().

450 {
451  struct newtExitStruct es;
452  newtComponent label;
453  showform = newtForm(NULL, NULL, 0);
454  newtCenteredWindow(70,4, title);
455  label = newtLabel(3,1,tmp);
456  newtFormAddComponents(showform,label, NULL);
457  newtFormSetTimer(showform, 200);
458  newtFormRun(showform, &es);
459  return 0;
460 }
static newtComponent showform
Definition: astman.c:448
static int tmp()
Definition: bt_open.c:389
#define NULL
Definition: resample.c:96

◆ show_message()

static int show_message ( char *  title,
char *  msg 
)
static

Definition at line 429 of file astman.c.

References NULL.

Referenced by manage_calls(), manager_login(), try_hangup(), try_redirect(), and try_status().

430 {
431  newtComponent form;
432  newtComponent label;
433  newtComponent ok;
434  struct newtExitStruct es;
435 
436  newtCenteredWindow(60,7, title);
437 
438  label = newtLabel(4,1,msg);
439  ok = newtButton(27, 3, "OK");
440  form = newtForm(NULL, NULL, 0);
441  newtFormAddComponents(form, label, ok, NULL);
442  newtFormRun(form, &es);
443  newtPopWindow();
444  newtFormDestroy(form);
445  return 0;
446 }
#define NULL
Definition: resample.c:96

◆ try_hangup()

static void try_hangup ( newtComponent  c)
static

Definition at line 482 of file astman.c.

References get_header(), manager_action(), ast_chan::name, show_message(), and wait_for_response().

Referenced by manage_calls().

483 {
484  struct ast_chan *chan;
485  struct message *m;
486 
487  chan = newtListboxGetCurrent(c);
488  if (chan) {
489  manager_action("Hangup", "Channel: %s\r\n", chan->name);
490  m = wait_for_response(10000);
491  if (!m) {
492  show_message("Hangup Failed", "Timeout waiting for response");
493  } else if (strcasecmp(get_header(m, "Response"), "Success")) {
494  show_message("Hangup Failed", get_header(m, "Message"));
495  }
496  }
497 
498 }
static struct message * wait_for_response(int timeout)
Definition: astman.c:387
static char * get_header(struct message *m, char *var)
Definition: astman.c:154
static struct test_val c
char name[80]
Definition: astman.c:79
static int show_message(char *title, char *msg)
Definition: astman.c:429
static int manager_action(char *action, char *fmt,...)
Definition: astman.c:410

◆ try_redirect()

static void try_redirect ( newtComponent  c)
static

Definition at line 528 of file astman.c.

References context, get_header(), get_user_input(), manager_action(), ast_chan::name, show_message(), tmp(), and wait_for_response().

Referenced by manage_calls().

529 {
530  struct ast_chan *chan;
531  char dest[256];
532  struct message *m;
533  static const char tmp_prefix[] = "Enter new extension for ";
534  char channame[256];
535  char tmp[sizeof(tmp_prefix) + sizeof(channame)];
536  char *context;
537 
538  chan = newtListboxGetCurrent(c);
539  if (chan) {
540  snprintf(channame, sizeof(channame), "%s", chan->name);
541  snprintf(tmp, sizeof(tmp), "%s%s", tmp_prefix, channame);
542  if (get_user_input(tmp, dest, sizeof(dest)))
543  return;
544  if ((context = strchr(dest, '@'))) {
545  *context = '\0';
546  context++;
547  manager_action("Redirect", "Channel: %s\r\nContext: %s\r\nExten: %s\r\nPriority: 1\r\n", chan->name,context,dest);
548  } else {
549  manager_action("Redirect", "Channel: %s\r\nExten: %s\r\nPriority: 1\r\n", chan->name, dest);
550  }
551  m = wait_for_response(10000);
552  if (!m) {
553  show_message("Hangup Failed", "Timeout waiting for response");
554  } else if (strcasecmp(get_header(m, "Response"), "Success")) {
555  show_message("Hangup Failed", get_header(m, "Message"));
556  }
557  }
558 
559 }
static struct message * wait_for_response(int timeout)
Definition: astman.c:387
static char * get_header(struct message *m, char *var)
Definition: astman.c:154
static int tmp()
Definition: bt_open.c:389
static struct test_val c
char name[80]
Definition: astman.c:79
static int show_message(char *title, char *msg)
Definition: astman.c:429
static int get_user_input(char *msg, char *buf, int buflen)
Definition: astman.c:500
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
static int manager_action(char *action, char *fmt,...)
Definition: astman.c:410

◆ try_status()

static void try_status ( void  )
static

Definition at line 469 of file astman.c.

References get_header(), manager_action(), show_message(), and wait_for_response().

Referenced by manage_calls().

470 {
471  struct message *m;
472  manager_action("Status", "%s", "");
473  m = wait_for_response(10000);
474  if (!m) {
475  show_message("Status Failed", "Timeout waiting for response");
476  } else if (strcasecmp(get_header(m, "Response"), "Success")) {
477  show_message("Status Failed Failed", get_header(m, "Message"));
478  }
479 }
static struct message * wait_for_response(int timeout)
Definition: astman.c:387
static char * get_header(struct message *m, char *var)
Definition: astman.c:154
static int show_message(char *title, char *msg)
Definition: astman.c:429
static int manager_action(char *action, char *fmt,...)
Definition: astman.c:410

◆ wait_for_response()

static struct message* wait_for_response ( int  timeout)
static

Definition at line 387 of file astman.c.

References ast_mansession::fd, FD_SET, input_check(), NULL, and session.

Referenced by manager_login(), try_hangup(), try_redirect(), and try_status().

388 {
389  struct message *m;
390  struct timeval tv;
391  int res;
392  fd_set fds;
393  for (;;) {
394  tv.tv_sec = timeout / 1000;
395  tv.tv_usec = (timeout % 1000) * 1000;
396  FD_SET(session.fd, &fds);
397  res = select(session.fd + 1, &fds, NULL, NULL, &tv);
398  if (res < 1)
399  break;
400  if (input_check(&session, &m) < 0) {
401  return NULL;
402  }
403  if (m)
404  return m;
405  }
406  return NULL;
407 }
static int timeout
Definition: cdr_mysql.c:86
#define NULL
Definition: resample.c:96
#define FD_SET(fd, fds)
Definition: select.h:58
static struct ast_mansession session
static int input_check(struct ast_mansession *s, struct message **mout)
Definition: astman.c:350

Variable Documentation

◆ chans

struct chans chans = { .first = NULL, .last = NULL, }
static

◆ events

struct event events[]
static

Referenced by process_message().

◆ session

struct ast_mansession session
static

Referenced by __manager_event_sessions_va(), add_header(), assign_uuid(), ast_ari_events_event_websocket_ws_established_cb(), ast_ari_websocket_events_event_websocket_established(), ast_ari_websocket_session_create(), ast_sip_channel_pvt_alloc(), ast_sip_dialog_get_session(), ast_sip_session_alloc(), ast_sip_session_create_outgoing(), ast_websocket_uri_cb(), astman_is_authed(), astman_verify_session_readpermissions(), astman_verify_session_writepermissions(), auth_http_callback(), channel_read_rtcp(), channel_read_rtp(), check_manager_session_inuse(), cli_channelstats_print_body(), defer_termination_cancel_task(), destroy_session(), event_session_alloc(), event_session_dtor(), event_session_hash(), find_session(), find_session_by_nonce(), generic_http_callback(), get_manager_sessions_cb(), handle_new_invite_request(), handle_showmanconn(), invite_collision_timeout(), invite_proceeding(), invite_terminated(), jingle_action_hook(), jingle_alloc(), jingle_answer(), jingle_call(), jingle_digit_begin(), jingle_digit_end(), jingle_fixup(), jingle_get_rtp_peer(), jingle_hangup(), jingle_indicate(), jingle_outgoing_hook(), jingle_read(), jingle_request(), jingle_sendtext(), jingle_session_destructor(), jingle_session_hash(), jingle_write(), manage_calls(), manager_action(), manager_fax_session(), manager_fax_sessions(), manager_login(), notify_ami_channel_data_create(), outbound_invite_auth(), pjsip_logger_session_alloc(), pjsip_logger_session_destroy(), purge_sessions(), push_notify_channel(), rcvfax_exec(), sdp_register(), sdp_search(), session_destroy_fn(), session_destructor(), session_do(), session_end_if_deferred_task(), session_end_if_disconnected(), session_inv_on_redirected(), sip_websocket_callback(), sndfax_exec(), stasis_app_message_handler(), t38_automatic_reject(), t38_automatic_reject_timer_cb(), t38_parameters_task_data_alloc(), transport_read(), unistim_call(), update_completed(), wait_for_response(), websocket_cb(), and websocket_session_dtor().

◆ showform

newtComponent showform
static

Definition at line 448 of file astman.c.