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

Defines

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

Functions

int ast_add_profile (const char *, uint64_t scale)
 allocates a counter with a given name and scale.
int64_t ast_mark (int, int start1_stop0)
int64_t ast_profile (int, int64_t)
void ast_register_file_version (const char *file, const char *version)
 Register the version of a source code file with the core.
void ast_unregister_file_version (const char *file)
 Unregister a source code file from the core.
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 event events []
static struct ast_mansession session
static newtComponent showform


Define Documentation

#define _NEWT_CAST   (void *)

Definition at line 63 of file astman.c.

Referenced by get_user_input(), and manager_login().

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

Definition at line 50 of file astman.c.

#define DEFAULT_MANAGER_PORT   5038

Definition at line 65 of file astman.c.

#define MAX_HEADERS   80

Definition at line 54 of file astman.c.

Referenced by input_check().

#define MAX_LEN   256

Definition at line 55 of file astman.c.


Function Documentation

int ast_add_profile ( const char *  x,
uint64_t  scale 
)

allocates a counter with a given name and scale.

support for event profiling

Returns:
Returns the identifier of the counter.
allocates a counter with a given name and scale.

(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 877 of file asterisk.c.

References ast_calloc, ast_realloc, ast_strdup, profile_data::e, profile_data::entries, profile_entry::events, profile_entry::mark, profile_data::max_size, profile_entry::name, NULL, prof_data, profile_entry::scale, and profile_entry::value.

00878 {
00879    int l = sizeof(struct profile_data);
00880    int n = 10; /* default entries */
00881 
00882    if (prof_data == NULL) {
00883       prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
00884       if (prof_data == NULL)
00885          return -1;
00886       prof_data->entries = 0;
00887       prof_data->max_size = n;
00888    }
00889    if (prof_data->entries >= prof_data->max_size) {
00890       void *p;
00891       n = prof_data->max_size + 20;
00892       p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
00893       if (p == NULL)
00894          return -1;
00895       prof_data = p;
00896       prof_data->max_size = n;
00897    }
00898    n = prof_data->entries++;
00899    prof_data->e[n].name = ast_strdup(name);
00900    prof_data->e[n].value = 0;
00901    prof_data->e[n].events = 0;
00902    prof_data->e[n].mark = 0;
00903    prof_data->e[n].scale = scale;
00904    return n;
00905 }

int64_t ast_mark ( int  key,
int  start1_stop0 
)

Definition at line 942 of file asterisk.c.

References profile_data::e, profile_data::entries, profile_entry::events, profile_entry::mark, prof_data, rdtsc(), profile_entry::scale, and profile_entry::value.

00943 {
00944    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00945       return 0;
00946    if (startstop == 1)
00947       prof_data->e[i].mark = rdtsc();
00948    else {
00949       prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
00950       if (prof_data->e[i].scale > 1)
00951          prof_data->e[i].mark /= prof_data->e[i].scale;
00952       prof_data->e[i].value += prof_data->e[i].mark;
00953       prof_data->e[i].events++;
00954    }
00955    return prof_data->e[i].mark;
00956 }

int64_t ast_profile ( int  key,
int64_t  val 
)

Definition at line 907 of file asterisk.c.

References profile_data::e, profile_data::entries, profile_entry::events, prof_data, profile_entry::scale, and profile_entry::value.

00908 {
00909    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00910       return 0;
00911    if (prof_data->e[i].scale > 1)
00912       delta /= prof_data->e[i].scale;
00913    prof_data->e[i].value += delta;
00914    prof_data->e[i].events++;
00915    return prof_data->e[i].value;
00916 }

void ast_register_file_version ( const char *  file,
const char *  version 
)

Register the version of a source code file with the core.

Parameters:
file the source file name
version the version string (typically a SVN revision keyword string)
Returns:
nothing
This function should not be called directly, but instead the ASTERISK_FILE_VERSION macro should be used to register a file with the core.

Definition at line 486 of file asterisk.c.

00487 {
00488    struct file_version *new;
00489    char *work;
00490    size_t version_length;
00491 
00492    work = ast_strdupa(version);
00493    work = ast_strip(ast_strip_quoted(work, "$", "$"));
00494    version_length = strlen(work) + 1;
00495 
00496    if (!(new = ast_calloc(1, sizeof(*new) + version_length)))
00497       return;
00498 
00499    new->file = file;
00500    new->version = (char *) new + sizeof(*new);
00501    memcpy(new->version, work, version_length);
00502    AST_RWLIST_WRLOCK(&file_versions);
00503    AST_RWLIST_INSERT_HEAD(&file_versions, new, list);
00504    AST_RWLIST_UNLOCK(&file_versions);
00505 }

void ast_unregister_file_version ( const char *  file  ) 

Unregister a source code file from the core.

Parameters:
file the source file name
Returns:
nothing
This function should not be called directly, but instead the ASTERISK_FILE_VERSION macro should be used to automatically unregister the file when the module is unloaded.

Definition at line 507 of file asterisk.c.

00508 {
00509    struct file_version *find;
00510 
00511    AST_RWLIST_WRLOCK(&file_versions);
00512    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) {
00513       if (!strcasecmp(find->file, file)) {
00514          AST_RWLIST_REMOVE_CURRENT(list);
00515          break;
00516       }
00517    }
00518    AST_RWLIST_TRAVERSE_SAFE_END;
00519    AST_RWLIST_UNLOCK(&file_versions);
00520 
00521    if (find)
00522       ast_free(find);
00523 }

static void del_chan ( char *  name  )  [static]

Definition at line 139 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().

00140 {
00141    struct ast_chan *chan;
00142 
00143    AST_LIST_TRAVERSE_SAFE_BEGIN(&chans, chan, list) {
00144       if (!strcmp(name, chan->name)) {
00145          AST_LIST_REMOVE_CURRENT(list);
00146          free(chan);
00147          return;
00148       }
00149    }
00150    AST_LIST_TRAVERSE_SAFE_END;
00151 }

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

Definition at line 217 of file astman.c.

References del_chan(), and get_header().

00218 {
00219    del_chan(get_header(m, "Channel"));
00220    return 0;
00221 }

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

Definition at line 223 of file astman.c.

00224 {
00225    return 0;
00226 }

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

Definition at line 196 of file astman.c.

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

00197 {
00198    struct ast_chan *chan;
00199    chan = find_chan(get_header(m, "Channel"));
00200    strncpy(chan->state, get_header(m, "State"), sizeof(chan->state) - 1);
00201    strncpy(chan->callerid, get_header(m, "Callerid"), sizeof(chan->callerid) - 1);
00202    return 0;
00203 }

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

Definition at line 186 of file astman.c.

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

00187 {
00188    struct ast_chan *chan;
00189    chan = find_chan(get_header(m, "Channel"));
00190    strncpy(chan->exten, get_header(m, "Extension"), sizeof(chan->exten) - 1);
00191    strncpy(chan->context, get_header(m, "Context"), sizeof(chan->context) - 1);
00192    strncpy(chan->priority, get_header(m, "Priority"), sizeof(chan->priority) - 1);
00193    return 0;
00194 }

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

Definition at line 178 of file astman.c.

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

00179 {
00180    struct ast_chan *chan;
00181    chan = find_chan(get_header(m, "Channel"));
00182    strncpy(chan->state, get_header(m, "State"), sizeof(chan->state) - 1);
00183    return 0;
00184 }

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

Definition at line 228 of file astman.c.

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

00229 {
00230    struct ast_chan *chan;
00231    chan = find_chan(get_header(m, "Oldname"));
00232    strncpy(chan->name, get_header(m, "Newname"), sizeof(chan->name) - 1);
00233    return 0;
00234 }

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

Definition at line 205 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.

00206 {
00207    struct ast_chan *chan;
00208    chan = find_chan(get_header(m, "Channel"));
00209    strncpy(chan->state, get_header(m, "State"), sizeof(chan->state) - 1);
00210    strncpy(chan->callerid, get_header(m, "Callerid"), sizeof(chan->callerid) - 1);
00211    strncpy(chan->exten, get_header(m, "Extension"), sizeof(chan->exten) - 1);
00212    strncpy(chan->context, get_header(m, "Context"), sizeof(chan->context) - 1);
00213    strncpy(chan->priority, get_header(m, "Priority"), sizeof(chan->priority) - 1);
00214    return 0;
00215 }

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

Definition at line 154 of file astman.c.

References errno.

Referenced by manager_action().

00155 {
00156    char stuff[4096];
00157    va_list ap;
00158 
00159    va_start(ap, fmt);
00160    vsnprintf(stuff, sizeof(stuff), fmt, ap);
00161    va_end(ap);
00162    if (write(fd, stuff, strlen(stuff)) < 0) {
00163       fprintf(stderr, "write() failed: %s\n", strerror(errno));
00164    }
00165 }

static struct ast_chan* find_chan ( char *  name  )  [static, read]

Definition at line 123 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().

00124 {
00125    struct ast_chan *chan;
00126    AST_LIST_TRAVERSE(&chans, chan, list) {
00127       if (!strcmp(name, chan->name))
00128          return chan;
00129    }
00130    chan = malloc(sizeof(struct ast_chan));
00131    if (chan) {
00132       memset(chan, 0, sizeof(struct ast_chan));
00133       strncpy(chan->name, name, sizeof(chan->name) - 1);
00134       AST_LIST_INSERT_TAIL(&chans, chan, list);
00135    }
00136    return chan;
00137 }

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

Definition at line 167 of file astman.c.

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

00168 {
00169    char cmp[80];
00170    int x;
00171    snprintf(cmp, sizeof(cmp), "%s: ", var);
00172    for (x=0;x<m->hdrcount;x++)
00173       if (!strncasecmp(cmp, m->headers[x], strlen(cmp)))
00174          return m->headers[x] + strlen(cmp);
00175    return "";
00176 }

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

Definition at line 323 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.

00324 {
00325    /* output must have at least sizeof(s->inbuf) space */
00326    int res;
00327    int x;
00328    struct timeval tv = {0, 0};
00329    fd_set fds;
00330    for (x=1;x<s->inlen;x++) {
00331       if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) {
00332          /* Copy output data up to and including \r\n */
00333          memcpy(output, s->inbuf, x + 1);
00334          /* Add trailing \0 */
00335          output[x+1] = '\0';
00336          /* Move remaining data back to the front */
00337          memmove(s->inbuf, s->inbuf + x + 1, s->inlen - x);
00338          s->inlen -= (x + 1);
00339          return 1;
00340       }
00341    } 
00342    if (s->inlen >= sizeof(s->inbuf) - 1) {
00343       fprintf(stderr, "Dumping long line with no return from %s: %s\n", inet_ntoa(s->sin.sin_addr), s->inbuf);
00344       s->inlen = 0;
00345    }
00346    FD_ZERO(&fds);
00347    FD_SET(s->fd, &fds);
00348    res = select(s->fd + 1, &fds, NULL, NULL, &tv);
00349    if (res < 0) {
00350       fprintf(stderr, "Select returned error: %s\n", strerror(errno));
00351    } else if (res > 0) {
00352       res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen);
00353       if (res < 1)
00354          return -1;
00355       s->inlen += res;
00356       s->inbuf[s->inlen] = '\0';
00357    } else {
00358       return 2;
00359    }
00360    return 0;
00361 }

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

Definition at line 513 of file astman.c.

References _NEWT_CAST, input(), and NULL.

Referenced by try_redirect().

00514 {
00515    newtComponent form;
00516    newtComponent ok;
00517    newtComponent cancel;
00518    newtComponent inpfield;
00519    const char *input;
00520    int res = -1;
00521    struct newtExitStruct es;
00522 
00523    newtCenteredWindow(60,7, msg);
00524 
00525    inpfield = newtEntry(5, 2, "", 50, _NEWT_CAST &input, 0);
00526    ok = newtButton(22, 3, "OK");
00527    cancel = newtButton(32, 3, "Cancel");
00528    form = newtForm(NULL, NULL, 0);
00529    newtFormAddComponents(form, inpfield, ok, cancel, NULL);
00530    newtFormRun(form, &es);
00531    strncpy(buf, input, buflen - 1);
00532    if (es.u.co == ok) 
00533       res = 0;
00534    else
00535       res = -1;
00536    newtPopWindow();
00537    newtFormDestroy(form);
00538    return res;
00539 }

static int has_input ( struct ast_mansession s  )  [static]

Definition at line 314 of file astman.c.

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

Referenced by manage_calls().

00315 {
00316    int x;
00317    for (x=1;x<s->inlen;x++) 
00318       if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) 
00319          return 1;
00320    return 0;
00321 }

static int hide_doing ( void   )  [static]

Definition at line 475 of file astman.c.

References showform.

Referenced by manage_calls(), and manager_login().

00476 {
00477    newtPopWindow();
00478    newtFormDestroy(showform);
00479    return 0;
00480 }

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

Definition at line 363 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().

00364 {
00365    static struct message m;
00366    int res;
00367 
00368    if (mout)
00369       *mout = NULL;
00370 
00371    for(;;) {
00372       res = get_input(s, m.headers[m.hdrcount]);
00373       if (res == 1) {
00374 #if 0
00375          fprintf(stderr, "Got header: %s", m.headers[m.hdrcount]);
00376          fgetc(stdin);
00377 #endif
00378          /* Strip trailing \r\n */
00379          if (strlen(m.headers[m.hdrcount]) < 2)
00380             continue;
00381          m.headers[m.hdrcount][strlen(m.headers[m.hdrcount]) - 2] = '\0';
00382          if (!strlen(m.headers[m.hdrcount])) {
00383             if (mout && strlen(get_header(&m, "Response"))) {
00384                *mout = &m;
00385                return 0;
00386             }
00387             if (process_message(s, &m))
00388                break;
00389             memset(&m, 0, sizeof(m));
00390          } else if (m.hdrcount < MAX_HEADERS - 1)
00391             m.hdrcount++;
00392       } else if (res < 0) {
00393          return -1;
00394       } else if (res == 2)
00395          return 0;
00396    }
00397    return -1;
00398 }

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

Definition at line 760 of file astman.c.

References manage_calls(), and manager_login().

00761 {
00762    if (argc < 2) {
00763       fprintf(stderr, "Usage: astman <host>\n");
00764       exit(1);
00765    }
00766    newtInit();
00767    newtCls();
00768    newtDrawRootText(0, 0, "Asterisk Manager (C)2002, Linux Support Services, Inc.");
00769    newtPushHelpLine("Welcome to the Asterisk Manager!");
00770    if (manager_login(argv[1])) {
00771       newtFinished();
00772       exit(1);
00773    }
00774    manage_calls(argv[1]);
00775    newtFinished();
00776    return 0;
00777 }

static int manage_calls ( char *  host  )  [static]

Definition at line 573 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().

00574 {
00575    newtComponent form;
00576    newtComponent quit;
00577    newtComponent hangup;
00578    newtComponent redirect;
00579    newtComponent channels;
00580    struct newtExitStruct es;
00581    char tmp[80];
00582 
00583    /* Mark: If there's one thing you learn from this code, it is this...
00584       Never, ever fly Air France.  Their customer service is absolutely
00585       the worst.  I've never heard the words "That's not my problem" as 
00586       many times as I have from their staff -- It should, without doubt
00587       be their corporate motto if it isn't already.  Don't bother giving 
00588       them business because you're just a pain in their side and they
00589       will be sure to let you know the first time you speak to them.
00590       
00591       If you ever want to make me happy just tell me that you, too, will
00592       never fly Air France again either (in spite of their excellent
00593       cuisine). 
00594    
00595       Update by oej: The merger with KLM has transferred this
00596       behaviour to KLM as well. 
00597       Don't bother giving them business either...
00598 
00599       Only if you want to travel randomly without luggage, you
00600       might pick either of them.
00601       
00602    */
00603    snprintf(tmp, sizeof(tmp), "Asterisk Manager at %s", host);
00604    newtCenteredWindow(74, 20, tmp);
00605    form = newtForm(NULL, NULL, 0);
00606    newtFormWatchFd(form, session.fd, NEWT_FD_READ);
00607    newtFormSetTimer(form, 100);
00608    quit = newtButton(62, 16, "Quit");
00609    redirect = newtButton(35, 16, "Redirect");
00610    hangup = newtButton(50, 16, "Hangup");
00611    channels = newtListbox(1,1,14, NEWT_FLAG_SCROLL);
00612    newtFormAddComponents(form, channels, redirect, hangup, quit, NULL);
00613    newtListboxSetWidth(channels, 72);
00614    
00615    show_doing("Getting Status", "Retrieving system status...");
00616    try_status();
00617    hide_doing();
00618 
00619    for(;;) {
00620       newtFormRun(form, &es);
00621       if (has_input(&session) || (es.reason == NEWT_EXIT_FDREADY)) {
00622          if (input_check(&session, NULL)) {
00623             show_message("Disconnected", "Disconnected from remote host");
00624             break;
00625          }
00626       } else if (es.reason == NEWT_EXIT_COMPONENT) {
00627          if (es.u.co == quit)
00628             break;
00629          if (es.u.co == hangup) {
00630             try_hangup(channels);
00631          } else if (es.u.co == redirect) {
00632             try_redirect(channels);
00633          }
00634       }
00635       rebuild_channels(channels);
00636    }
00637    newtFormDestroy(form);
00638    return 0;
00639 }

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

Definition at line 423 of file astman.c.

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

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

00424 {
00425    struct ast_mansession *s;
00426    char tmp[4096];
00427    va_list ap;
00428    int res;
00429 
00430    s = &session;
00431    fdprintf(s->fd, "Action: %s\r\n", action);
00432    va_start(ap, fmt);
00433    vsnprintf(tmp, sizeof(tmp), fmt, ap);
00434    va_end(ap);
00435    if ((res = write(s->fd, tmp, strlen(tmp))) < 0) {
00436       fprintf(stderr, "write() failed: %s\n", strerror(errno));
00437    }
00438    fdprintf(s->fd, "\r\n");
00439    return 0;
00440 }

static int manager_login ( char *  hostname  )  [static]

Definition at line 641 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(), and wait_for_response().

Referenced by main().

00642 {
00643    newtComponent form;
00644    newtComponent cancel;
00645    newtComponent login;
00646    newtComponent username;
00647    newtComponent password;
00648    newtComponent label;
00649    newtComponent ulabel;
00650    newtComponent plabel;
00651    const char *user;
00652    const char *pass;
00653    struct message *m;
00654    struct newtExitStruct es;
00655    char tmp[55];
00656    struct hostent *hp;
00657    int res = -1;
00658    
00659    session.fd = socket(AF_INET, SOCK_STREAM, 0);
00660    if (session.fd < 0) {
00661       snprintf(tmp, sizeof(tmp), "socket() failed: %s\n", strerror(errno));
00662       show_message("Socket failed", tmp);
00663       return -1;
00664    }
00665    
00666    snprintf(tmp, sizeof(tmp), "Looking up %s\n", hostname);
00667    show_doing("Connecting....", tmp);
00668    
00669    
00670    hp = gethostbyname(hostname);
00671    if (!hp) {
00672       snprintf(tmp, sizeof(tmp), "No such address: %s\n", hostname);
00673       show_message("Host lookup failed", tmp);
00674       return -1;
00675    }
00676    hide_doing();
00677    snprintf(tmp, sizeof(tmp), "Connecting to %s", hostname);
00678    show_doing("Connecting...", tmp);
00679 
00680    session.sin.sin_family = AF_INET;
00681    session.sin.sin_port = htons(DEFAULT_MANAGER_PORT);
00682    memcpy(&session.sin.sin_addr, hp->h_addr, sizeof(session.sin.sin_addr));
00683 
00684    if (connect(session.fd,(struct sockaddr*)&session.sin, sizeof(session.sin))) {
00685       snprintf(tmp, sizeof(tmp), "%s failed: %s\n", hostname, strerror(errno));
00686       show_message("Connect Failed", tmp);
00687       return -1;
00688    }
00689    
00690    hide_doing();
00691    
00692    login = newtButton(5, 6, "Login");
00693    cancel = newtButton(25, 6, "Cancel");
00694    newtCenteredWindow(40, 10, "Asterisk Manager Login");
00695    snprintf(tmp, sizeof(tmp), "Host:     %s", hostname);
00696    label = newtLabel(4,1, tmp);
00697    
00698    ulabel = newtLabel(4,2,"Username:");
00699    plabel = newtLabel(4,3,"Password:");
00700    
00701    username = newtEntry(14, 2, "", 20, _NEWT_CAST &user, 0);
00702    password = newtEntry(14, 3, "", 20, _NEWT_CAST &pass, NEWT_FLAG_HIDDEN);
00703    
00704    form = newtForm(NULL, NULL, 0);
00705    newtFormAddComponents(form, username, password, login, cancel, label, ulabel, plabel,NULL);
00706    newtFormRun(form, &es);
00707    if (es.reason == NEWT_EXIT_COMPONENT) {
00708       if (es.u.co == login) {
00709          snprintf(tmp, sizeof(tmp), "Logging in '%s'...", user);
00710          show_doing("Logging in", tmp);
00711          /* Check to see if the remote host supports MD5 Authentication */
00712          manager_action("Challenge", "AuthType: MD5\r\n");
00713          m = wait_for_response(10000);
00714          if (m && !strcasecmp(get_header(m, "Response"), "Success")) {
00715             char *challenge = get_header(m, "Challenge");
00716             int x;
00717             int len = 0;
00718             char md5key[256] = "";
00719             struct MD5Context md5;
00720             unsigned char digest[16];
00721             MD5Init(&md5);
00722             MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
00723             MD5Update(&md5, (unsigned char *)pass, strlen(pass));
00724             MD5Final(digest, &md5);
00725             for (x=0; x<16; x++)
00726                len += sprintf(md5key + len, "%02hhx", digest[x]);
00727             manager_action("Login",
00728                   "AuthType: MD5\r\n"
00729                   "Username: %s\r\n"
00730                   "Key: %s\r\n",
00731                   user, md5key);
00732             m = wait_for_response(10000);
00733             hide_doing();
00734             if (!strcasecmp(get_header(m, "Response"), "Success")) {
00735                res = 0;
00736             } else {
00737                show_message("Login Failed", get_header(m, "Message"));
00738             }
00739          } else {
00740             manager_action("Login", 
00741                "Username: %s\r\n"
00742                "Secret: %s\r\n",
00743                   user, pass);
00744             m = wait_for_response(10000);
00745             hide_doing();
00746             if (m) {
00747                if (!strcasecmp(get_header(m, "Response"), "Success")) {
00748                   res = 0;
00749                } else {
00750                   show_message("Login Failed", get_header(m, "Message"));
00751                }
00752             }
00753          }
00754       }
00755    }
00756    newtFormDestroy(form);
00757    return res;
00758 }

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

Definition at line 262 of file astman.c.

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

00263 {
00264    int x;
00265    char event[80] = "";
00266    strncpy(event, get_header(m, "Event"), sizeof(event) - 1);
00267    if (!strlen(event)) {
00268       fprintf(stderr, "Missing event in request");
00269       return 0;
00270    }
00271    for (x = 0; x < ARRAY_LEN(events); x++) {
00272       if (!strcasecmp(event, events[x].event)) {
00273          if (events[x].func(s, m))
00274             return -1;
00275          break;
00276       }
00277    }
00278    if (x >= ARRAY_LEN(events))
00279       fprintf(stderr, "Ignoring unknown event '%s'", event);
00280 #if 0
00281    for (x=0;x<m->hdrcount;x++) {
00282       printf("Header: %s\n", m->headers[x]);
00283    }
00284 #endif   
00285    return 0;
00286 }

static void rebuild_channels ( newtComponent  c  )  [static]

Definition at line 288 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().

00289 {
00290    void *prev = NULL;
00291    struct ast_chan *chan;
00292    char tmpn[42];
00293    char tmp[256];
00294    int x=0;
00295    prev = newtListboxGetCurrent(c);
00296    newtListboxClear(c);
00297    AST_LIST_TRAVERSE(&chans, chan, list) {
00298       snprintf(tmpn, sizeof(tmpn), "%s (%s)", chan->name, chan->callerid);
00299       if (strlen(chan->exten)) 
00300          snprintf(tmp, sizeof(tmp), "%-30s %8s -> %s@%s:%s", 
00301             tmpn, chan->state,
00302             chan->exten, chan->context, chan->priority);
00303       else
00304          snprintf(tmp, sizeof(tmp), "%-30s %8s",
00305             tmpn, chan->state);
00306       newtListboxAppendEntry(c, tmp, chan);
00307       x++;
00308    }
00309    if (!x)
00310       newtListboxAppendEntry(c, " << No Active Channels >> ", NULL);
00311    newtListboxSetCurrentByKey(c, prev);
00312 }

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

Definition at line 462 of file astman.c.

References NULL, and showform.

Referenced by manage_calls(), and manager_login().

00463 {
00464    struct newtExitStruct es;
00465    newtComponent label;
00466    showform = newtForm(NULL, NULL, 0);
00467    newtCenteredWindow(70,4, title);
00468    label = newtLabel(3,1,tmp);
00469    newtFormAddComponents(showform,label, NULL);
00470    newtFormSetTimer(showform, 200);
00471    newtFormRun(showform, &es);
00472    return 0;
00473 }

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

Definition at line 442 of file astman.c.

References NULL.

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

00443 {
00444    newtComponent form;
00445    newtComponent label;
00446    newtComponent ok;
00447    struct newtExitStruct es;
00448 
00449    newtCenteredWindow(60,7, title);
00450 
00451    label = newtLabel(4,1,msg);
00452    ok = newtButton(27, 3, "OK");
00453    form = newtForm(NULL, NULL, 0);
00454    newtFormAddComponents(form, label, ok, NULL);
00455    newtFormRun(form, &es);
00456    newtPopWindow();
00457    newtFormDestroy(form);
00458    return 0;
00459 }

static void try_hangup ( newtComponent  c  )  [static]

Definition at line 495 of file astman.c.

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

Referenced by manage_calls().

00496 {
00497    struct ast_chan *chan;
00498    struct message *m;
00499 
00500    chan = newtListboxGetCurrent(c);
00501    if (chan) {
00502       manager_action("Hangup", "Channel: %s\r\n", chan->name);
00503       m = wait_for_response(10000);
00504       if (!m) {
00505          show_message("Hangup Failed", "Timeout waiting for response");
00506       } else if (strcasecmp(get_header(m, "Response"), "Success"))  {
00507          show_message("Hangup Failed", get_header(m, "Message"));
00508       }
00509    }
00510    
00511 }

static void try_redirect ( newtComponent  c  )  [static]

Definition at line 541 of file astman.c.

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

Referenced by manage_calls().

00542 {
00543    struct ast_chan *chan;
00544    char dest[256];
00545    struct message *m;
00546    char channame[256];
00547    char tmp[80];
00548    char *context;
00549 
00550    chan = newtListboxGetCurrent(c);
00551    if (chan) {
00552       strncpy(channame, chan->name, sizeof(channame) - 1);
00553       snprintf(tmp, sizeof(tmp), "Enter new extension for %s", channame);
00554       if (get_user_input(tmp, dest, sizeof(dest))) 
00555          return;
00556       if ((context = strchr(dest, '@'))) {
00557          *context = '\0';
00558          context++;
00559          manager_action("Redirect", "Channel: %s\r\nContext: %s\r\nExten: %s\r\nPriority: 1\r\n", chan->name,context,dest);
00560       } else {
00561          manager_action("Redirect", "Channel: %s\r\nExten: %s\r\nPriority: 1\r\n", chan->name, dest);
00562       }
00563       m = wait_for_response(10000);
00564       if (!m) {
00565          show_message("Hangup Failed", "Timeout waiting for response");
00566       } else if (strcasecmp(get_header(m, "Response"), "Success"))  {
00567          show_message("Hangup Failed", get_header(m, "Message"));
00568       }
00569    }
00570    
00571 }

static void try_status ( void   )  [static]

Definition at line 482 of file astman.c.

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

Referenced by manage_calls().

00483 {
00484    struct message *m;
00485    manager_action("Status", "%s", "");
00486    m = wait_for_response(10000);
00487    if (!m) {
00488       show_message("Status Failed", "Timeout waiting for response");
00489    } else if (strcasecmp(get_header(m, "Response"), "Success"))  {
00490       show_message("Status Failed Failed", get_header(m, "Message"));
00491    }
00492 }

static struct message* wait_for_response ( int  timeout  )  [static, read]

Definition at line 400 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().

00401 {
00402    struct message *m;
00403    struct timeval tv;
00404    int res;
00405    fd_set fds;
00406    for (;;) {
00407       tv.tv_sec = timeout / 1000;
00408       tv.tv_usec = (timeout % 1000) * 1000;
00409       FD_SET(session.fd, &fds);
00410       res = select(session.fd + 1, &fds, NULL, NULL, &tv);
00411       if (res < 1)
00412          break;
00413       if (input_check(&session, &m) < 0) {
00414          return NULL;
00415       }
00416       if (m)
00417          return m;
00418    }
00419    return NULL;
00420 }


Variable Documentation

struct event events[] [static]

struct ast_mansession session [static]

Referenced by __ast_manager_event_multichan(), add_header(), answer(), app_handler(), assign_uuid(), ast_ari_events_event_websocket_ws_cb(), ast_ari_websocket_events_event_websocket(), ast_ari_websocket_session_create(), astman_is_authed(), astman_verify_session_readpermissions(), astman_verify_session_writepermissions(), auth_http_callback(), call(), chan_pjsip_answer(), chan_pjsip_queryoption(), chan_pjsip_request(), chan_pjsip_set_rtp_peer(), check_manager_session_inuse(), defer_termination_cancel(), find_session(), find_session_by_nonce(), generic_http_callback(), get_manager_sessions_cb(), handle_negotiated_sdp_session_media(), handle_showmanconn(), hangup(), indicate(), 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(), purge_sessions(), rcvfax_exec(), request(), sdp_register(), sdp_search(), send_direct_media_request(), session_create(), session_destroy_fn(), session_destructor(), session_do(), session_dtor(), sndfax_exec(), t38_automatic_reject(), t38_automatic_reject_timer_cb(), transmit_info_dtmf(), transmit_info_with_vidupdate(), transport_read(), unistim_call(), update_completed(), update_connected_line_information(), wait_for_response(), and websocket_session_dtor().

newtComponent showform [static]

Definition at line 461 of file astman.c.

Referenced by hide_doing(), and show_doing().


Generated on Thu Apr 16 06:28:58 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6