17 #include <sipwitch-config.h>
18 #include <ucommon/ucommon.h>
19 #include <ucommon/export.h>
31 #define RUNLEVELS (sizeof(callback::runlevels) / sizeof(LinkedObject *))
65 static struct sockaddr_storage peering;
66 static time_t started = 0l;
67 static time_t periodic = 0l;
69 static size_t xmldecode(
char *out,
size_t limit,
const char *src)
77 if(*src ==
'\'' || *src ==
'\"')
79 while(src && limit-- > 1 && !strchr(
"<\'\">", *src)) {
80 if(!strncmp(src,
"&", 5)) {
84 else if(!strncmp(src,
"<", 4)) {
88 else if(!strncmp(src,
">", 4)) {
92 else if(!strncmp(src,
""", 6)) {
96 else if(!strncmp(src,
"'", 6)) {
120 assert(
id != NULL && *
id != 0);
146 crit(rl < (
int)
RUNLEVELS,
"service runlevel invalid");
149 crit(rl > 0,
"service runlevel invalid");
159 LinkedObject::delist(&runlevels[runlevel]);
167 if(eq(uri,
"sip:", 4) || eq(uri,
"sip"))
170 if(eq(uri,
"sips:", 5) || eq(uri,
"sips"))
173 if(eq(uri,
"tcp:", 4) || eq(uri,
"tcp"))
176 if(eq(uri,
"udp:", 4) || eq(uri,
"udp"))
221 if(strchr(addr,
':'))
222 sip_family = AF_INET6;
225 if(eq(addr,
":::") || eq(addr,
"::0") || eq(addr,
"::*") || eq(addr,
"*") || eq(addr,
"0.0.0.0") || !*addr)
245 enlistTail(&trunk->Child);
251 assert(name != NULL && *name != 0);
253 root.setId((
char *)name);
254 root.setPointer(NULL);
268 reset_unsafe<keynode>(
root);
274 Socket::address resolver;
275 const struct sockaddr *host;
278 memset(&peering, 0,
sizeof(peering));
283 resolver.set(addr, i);
284 host = resolver.getAddr();
290 Socket::store(&peering, host);
297 memcpy(peer, &peering,
sizeof(peering));
307 return (
long)(now - started);
312 assert(
id != NULL && *
id != 0);
322 assert(
id != NULL && *
id != 0);
331 return node->getFirst();
337 assert(
id != NULL && *
id != 0);
339 linked_pointer<keymap>
map;
350 if(!stricmp(map->id,
id))
362 assert(
id != NULL && *
id != 0);
378 assert(path != NULL && *path != 0);
384 return base->getFirst();
402 assert(
id != NULL && *
id != 0);
409 while(
id && *
id && node) {
410 String::set(buf,
sizeof(buf),
id);
411 ep = strchr(buf,
'.');
414 np = strchr(
id,
'.');
419 child = node->getChild(buf);
421 child =
addNode(node, buf, NULL);
429 assert(base != NULL);
430 assert(
id != NULL && *
id != 0);
436 mp = memalloc::alloc(
sizeof(
keynode));
438 node =
new(mp)
keynode(base, cp);
440 node->setPointer(dup(value));
442 node->setPointer(NULL);
448 assert(node != NULL);
449 assert(
id != NULL && *
id != 0);
451 node = node->getChild(
id);
455 return node->getPointer();
460 assert(base != NULL);
461 assert(defs != NULL);
471 if(node->getChild(defs->
key))
480 assert(base != NULL);
481 assert(
id != NULL && *
id != 0);
482 assert(attr != NULL);
483 assert(value != NULL);
485 linked_pointer<keynode> node = base->getFirst();
490 if(!strcmp(
id, node->getId())) {
491 leaf = node->getLeaf(attr);
493 cp = leaf->getPointer();
494 if(cp && !stricmp(cp, value))
505 assert(base != NULL);
506 assert(
id != NULL && *
id != 0);
507 assert(text != NULL && *text != 0);
509 linked_pointer<keynode> node = base->getFirst();
513 if(!strcmp(
id, node->getId())) {
514 cp = node->getPointer();
515 if(cp && !stricmp(cp, text))
525 assert(node != NULL);
526 assert(attr != NULL);
532 while(attr && *attr && *attr !=
'>') {
533 while(isspace(*attr))
536 if(!*attr || *attr ==
'>')
540 while(*attr && *attr !=
'=' && *attr !=
'>')
547 id = String::trim(
id,
" \t\r\n");
548 while(isspace(*attr))
552 ep = strchr(++attr, *qt);
558 qt = (
char *)memalloc::alloc(len + 1);
559 xmldecode(qt, len + 1, attr);
569 char *cp, *ep, *bp, *id;
572 bool document =
false, empty;
580 top = node->getParent();
589 if(
buffer.len() < 1024 - 5) {
590 len = fread(cp, 1, 1024 -
buffer.len() - 1, fp);
604 while(node != top && cp && *cp)
606 cp = String::trim(cp,
" \t\r\n");
608 if(cp && *cp && !node)
611 bp = strchr(cp,
'<');
612 if(bp == cp && String::equal(bp,
"<!--", 4)) {
613 ep = strstr(cp,
"-->");
620 ep = strchr(cp,
'>');
624 cp = cp + strlen(cp);
628 if(node->getPointer() != NULL)
632 cp = String::chop(cp,
" \r\n\t");
634 ep = (
char *)memalloc::alloc(len + 1);
635 xmldecode(ep, len + 1, cp);
636 node->setPointer(ep);
644 if(*(ep - 1) ==
'/') {
650 if(!strncmp(bp,
"</", 2)) {
651 if(strcmp(bp + 2, node->getId())) {
652 shell::log(shell::ERR,
"%s: %s\n",
653 _TEXT(
"No matching opening token found for"), node->getId());
657 node = node->getParent();
675 while(
id && *
id && isspace(*
id))
679 if(strcmp(node->getId(), bp))
685 node =
addNode(node, bp, NULL);
689 node = node->getParent();
702 linked_pointer<callback> sp;
704 memset(&peering, 0,
sizeof(peering));
706 shell::log(shell::NOTIFY,
"startup");
721 linked_pointer<callback> sp;
738 assert(root != NULL);
741 const char *id, *
value;
743 linked_pointer<service::keynode> node =
root;
746 value = node->getPointer();
747 child = node->getFirst();
751 if(child && value &&
id)
752 fprintf(fp,
"%s(%s):\n",
id, value);
754 fprintf(fp,
"%s:\n",
id);
756 fprintf(fp,
"%s=%s\n",
id, value);
758 fprintf(fp,
"%s\n",
id);
760 dump(fp, child, level + 2);
769 fprintf(fp,
"Config ");
778 shell::log(shell::ERR,
"%s\n",
779 _TEXT(
"dump cannot access file"));
783 shell::log(
DEBUG1,
"%s\n",
784 _TEXT(
"dumping config"));
787 cfg->service::dump(fp);
797 const char *addr = (
const char *)vaddr;
802 if(!addr || eq(addr,
"*")) {
803 #ifdef HAVE_GETHOSTNAME
804 static char hostbuf[256] = {0};
805 gethostname(hostbuf,
sizeof(hostbuf));
816 if(port && port != 5060) {
817 if(strchr(addr,
':'))
818 uri = str(
"sip:[") + addr +
"]:" + str(port);
820 uri = str(
"sip:") + addr +
":" + str(port);
823 uri = str(
"sip:") + addr;
836 next = ((periodic / slice) + 1l) * slice;
840 next = (now / slice) * slice;
845 DateTimeString dt(periodic);
846 fprintf(fp,
"%s %ld\n", (
const char *)dt, (
long)(next - periodic));
863 linked_pointer<callback> cb;
868 shell::log(shell::ERR,
"%s\n",
869 _TEXT(
"snapshot; cannot access file"));
873 shell::log(
DEBUG1,
"%s\n", _TEXT(
"snapshot started"));
887 shell::log(
DEBUG1,
"%s\n", _TEXT(
"snapshot completed"));
896 linked_pointer<callback> cb;
902 while(rtn && is(cb)) {
913 linked_pointer<callback> cb;
956 assert(digits != NULL);
957 assert(match != NULL);
959 unsigned len = strlen(match);
962 const char *d = digits;
968 while(*d && dlen <
sizeof(dbuf) - 1) {
969 if(isdigit(*d) || *d ==
'*' || *d ==
'#') {
970 dbuf[dlen++] = *(d++);
974 if(*d ==
' ' || *d ==
',') {
982 if(!stricmp(digits, match))
999 digits += (len - dlen);
1002 while(*match && *digits) {
1007 if(!isdigit(*digits))
1012 if(*digits < '2' || *digits >
'9')
1017 if(*digits && *digits !=
'1')
1022 if(*digits < '1' || *digits >
'9')
1030 if(*digits != *match)
1037 if(*match && !*digits)
1040 if(*match && *digits)
Used for definitions of plugin modules.
Some convenience methods for manipulating SIP uri's.
static volatile char * sip_publish
virtual void snapshot(FILE *fp)
static void release(keynode *node)
void addAttributes(keynode *node, char *attrib)
Add attributes in a XML entity as child nodes of the xml node.
static voip::context_t udp_context
static volatile char * sip_contact
virtual void stop(service *cfg)
static voip::context_t tls_context
static volatile dialmode_t dialmode
static const char * getInterface(void)
static void start(void)
Start cdr subsystem and que dispatch thread.
static void startup(void)
void operator=(keynode *node)
virtual void start(service *cfg)
static keynode * getUser(const char *uid)
Used to splice new chains onto an existing xml tree.
keynode * getList(const char *path)
static unsigned sip_prefix
static void snapshot(void)
static void publish(const char *addr)
Set and publish public "appearing" address of the server.
service(const char *name, size_t s=0)
virtual void publish(service *cfg)
static void bind(unsigned short port)
static LinkedObject * getModules(void)
static void publish(const char *address)
Update publish address...
static void dumpfile(void)
static voip::context_t tcp_context
static const char * sip_iface
Keyword and value pair definition lists.
static void dump(FILE *fp, keynode *node, unsigned level)
static LinkedObject * runlevels[4]
static const char * sip_realm
bool load(FILE *file, keynode *node=NULL)
Load xml file into xml tree.
static void notice(const char *reason)
Send notice to user.
static void shutdown(void)
static condlock_t locking
keynode * addNode(keynode *base, define *defs)
Stream events to local clients.
static void reload(void)
Refresh clients with any config events...
static void published(struct sockaddr_storage *peer)
static bool static FILE * output(const char *id)
Used to open an output session for returning control data.
static char session_uuid[40]
static bool match(const char *digits, const char *pattern, bool partial)
static keynode * path(const char *p)
void splice(keyclone *trunk)
static unsigned short getPort(void)
static const char * sip_tlskey
static const char * sip_domain
static const char * sip_tlsdh
static string_t getContact(void)
static keynode * list(const char *p)
static void stop(void)
Stop cdr subsystem.
static const char * sip_tlsca
voip::context_t getContext(const char *uri)
virtual void errlog(shell::loglevel_t level, const char *text)
A pointer to a subtree in the xml configuration tree.
static bool period(long slice)
Service configuration and component callbacks.
static voip::context_t out_context
dialmode_t
Dialing mode supported.
keynode * getNode(keynode *base, const char *id, const char *value)
static const char * sip_tlsdev
static const char * sip_tlscert
System configuration instance and service functions.
Manage control interface.
static unsigned short sip_port
static keynode * get(void)
Interface class for call detail records.
static unsigned sip_range
static const char * getValue(keynode *base, const char *id)
static const char * sip_tlspwd
keynode * getPath(const char *path)
static const char * env(const char *id)
Return the value of a server environment variable.
treemap< char * > keynode
Definition of a xml node.
static keynode * getProtected(const char *path)
virtual void cdrlog(cdr *call)
virtual void confirm(void)
virtual void reload(service *cfg)