"Fossies" - the Fresh Open Source Software Archive

Member "bayonne-1.2.16/server/dso.cpp" (27 Feb 2003, 15131 Bytes) of package /linux/misc/old/bayonne-1.2.16.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "dso.cpp" see the Fossies "Dox" file reference documentation.

    1 // Copyright (C) 2000-2001 Open Source Telecom Corporation.
    2 //  
    3 // This program is free software; you can redistribute it and/or modify
    4 // it under the terms of the GNU General Public License as published by
    5 // the Free Software Foundation; either version 2 of the License, or
    6 // (at your option) any later version.
    7 // 
    8 // This program is distributed in the hope that it will be useful,
    9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
   10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11 // GNU General Public License for more details.
   12 // 
   13 // You should have received a copy of the GNU General Public License
   14 // along with this program; if not, write to the Free Software 
   15 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   16 
   17 #include "server.h"
   18 #include "ivrconfig.h"
   19 
   20 #ifdef  CCXX_NAMESPACES
   21 namespace ost {
   22 using namespace std;
   23 #endif
   24 
   25 Server *Server::first = NULL;
   26 Audit *Audit::first = NULL;
   27 Auditdata Audit::keys;
   28 Translator *Translator::first = NULL;
   29 TGI *TGI::first = NULL;
   30 Module *Module::modFirst = NULL;
   31 Module *Module::sesFirst = NULL;
   32 Module *Module::cmdFirst = NULL;
   33 Module *Module::urlFirst = NULL;
   34 Module *Module::reqFirst = NULL;
   35 Module *Module::netFirst = NULL;
   36 Module *Module::symFirst = NULL;
   37 Module *Module::modImport = NULL;
   38 Sync *Sync::first = NULL;
   39 
   40 Auditdata::Auditdata()
   41 {
   42     load("/bayonne/audit");
   43     load("~bayonne/audit");
   44 }
   45 
   46 Audit::Audit() :
   47 Mutex()
   48 {
   49     next = first;
   50     first = this;
   51 }
   52 
   53 TTS::TTS()
   54 {
   55     tts = this;
   56 }
   57 
   58 Driver::Driver() :
   59 aaScript()
   60 {
   61     active = false;
   62     if(driver)
   63         throw(this);
   64 
   65     groups = NULL;
   66     driver = this;
   67     status = NULL;
   68 
   69     portCount = downCount = idleCount = 0;
   70     extCount = trkCount = tieCount = 0;
   71     numCount = 0;
   72 
   73     extIndex = NULL;
   74 
   75     memset(spans, 0, sizeof(spans));
   76     memset(cards, 0, sizeof(cards));
   77     memset(stacards, 0, sizeof(cards));
   78 }
   79 
   80 bool Driver::setExtNumbering(unsigned count)
   81 {
   82     unsigned port;
   83     Trunk *trk;
   84     if(extIndex)
   85     {
   86         for(port = 0; port < (unsigned)getTrunkCount(); ++port)
   87         {
   88             trk = getTrunkPort(port);
   89             if(trk)
   90                 trk->extNumber[0] = 0;
   91         }
   92 
   93         delete extIndex;
   94     }
   95 
   96     extIndex = NULL;
   97     numCount = 0;
   98 
   99     if(!extCount)
  100         return false;
  101 
  102     switch(count)
  103     {
  104     case 0:
  105         slog(Slog::levelInfo) << "server: clearing station dialing" << endl;
  106         getImage();
  107         return true;
  108     case 1:
  109         numCount = 1;
  110         count = 8;
  111         break;
  112     case 2:
  113         numCount = 2;
  114         count = 60;
  115         break;
  116     case 3:
  117         numCount = 3;
  118         count = 600;
  119         break;
  120     default:
  121         slog(Slog::levelError) << "server: invalid station dialing plan" << endl;
  122         numCount = 0;
  123         return false;
  124     }
  125 
  126     slog(Slog::levelInfo) << "server: setting " << numCount << " digit station dialing" << endl;
  127 
  128     extIndex = new Trunk *[count];
  129     memset(extIndex, 0, sizeof(Trunk *) * count);
  130     getImage();
  131     return true;
  132 }
  133 
  134 Trunk **Driver::getExtIndex(const char *num)
  135 {
  136     unsigned ext = atoi(num);
  137 
  138     if(!numCount)
  139         return NULL;
  140 
  141     if(strlen(num) != numCount)
  142         return NULL;
  143 
  144     switch(numCount)
  145     {
  146     case 1:
  147         if(ext > 9 && ext < 18)
  148             ext -= 10;
  149 
  150         if(ext > 7)
  151             return NULL;
  152 
  153         break;
  154     case 2:
  155         if(!ext)
  156             ext = 10;
  157         if(ext < 10 || ext > 69)
  158             return NULL;
  159         ext -= 10;
  160         break;
  161     case 3:
  162         if(!ext)
  163             ext = 100;
  164         if(ext < 100 || ext > 699)
  165             return NULL;
  166         ext -= 100;
  167         break;
  168     }
  169     return extIndex + ext;
  170 }
  171 
  172 Trunk *Driver::getExtNumber(const char *num)
  173 {
  174     Trunk *trunk;
  175     Trunk **idx;
  176     const char *cp;
  177     
  178     if(!num)
  179         return NULL;
  180 
  181     cp = strchr(num, '-');
  182     if(cp)
  183     {
  184         trunk = driver->getTrunkPort(atoi(++cp));
  185         if(!trunk)
  186             return NULL;
  187 
  188         if(!trunk->extNumber[0])
  189             return NULL;
  190 
  191         num = trunk->extNumber;     
  192     }
  193 
  194     idx = getExtIndex(num);
  195 
  196     if(!idx)
  197         return NULL;
  198 
  199     return *idx;
  200 }
  201 
  202 bool Driver::clrExtNumber(const char *num)
  203 {
  204     char namebuf[16];
  205     Trunk **idx = getExtIndex(num);
  206     Script::Symbol *sym;
  207     ScriptSymbol *globals = Trunk::getGlobals();
  208 
  209     if(!idx)
  210         return false;
  211 
  212     if(*idx)
  213     {
  214         (*idx)->getName(namebuf);
  215         slog(Slog::levelDebug) << namebuf << ": clearing from extension " << num << endl;
  216         if(!stricmp( (*idx)->extNumber, num))
  217             (*idx)->extNumber[0] = 0;
  218         snprintf(namebuf, sizeof(namebuf), "%s.type", num);
  219         sym = globals->getEntry(namebuf, 0);
  220         if(sym)
  221             snprintf(sym->data, sym->flags.size + 1, "user");
  222         snprintf(namebuf, sizeof(namebuf), "%s.port", num);
  223         sym = globals->getEntry(namebuf, 0);
  224         if(sym)
  225             sym->data[0] = 0;
  226     }
  227 
  228     *idx = NULL;
  229     return true;
  230 }
  231 
  232 bool Driver::setExtNumber(unsigned id, const char *ext)
  233 {
  234     char namebuf[24];
  235     Trunk **idx = getExtIndex(ext);
  236     Trunk *trk = getTrunkPort(id);
  237     ScriptSymbol *globals = Trunk::getGlobals();
  238     Script::Symbol *def, *sym;
  239 
  240     if(!idx || ! trk || !(trk->getCapabilities() & TRUNK_CAP_STATION))
  241     {
  242         snprintf(namebuf, sizeof(namebuf), "%s.type", ext);
  243         sym = globals->getEntry(namebuf, 0);
  244         if(sym)
  245             snprintf(sym->data, sym->flags.size + 1, "user");
  246         snprintf(namebuf, sizeof(namebuf), "%s.port", ext);
  247         sym = globals->getEntry(namebuf, 0);
  248         if(sym)
  249             sym->data[0] = 0;
  250         return false;
  251     }
  252 
  253     if(*idx == trk)     // already is set to us, set type
  254     {
  255 
  256         if(!stricmp(trk->extNumber, ext))
  257             return true;    // already station type
  258 
  259         snprintf(namebuf, sizeof(namebuf), "%s.type", trk->extNumber);
  260         sym = globals->getEntry(namebuf, 0);
  261         if(sym)
  262             snprintf(sym->data, sym->flags.size + 1, "virtual");
  263 
  264         snprintf(namebuf, sizeof(namebuf), "%s.type", ext);
  265         sym = globals->getEntry(namebuf, 0);
  266         if(sym)
  267             snprintf(sym->data, sym->flags.size + 1, "station");
  268         strcpy(trk->extNumber, ext);
  269         return true;
  270     }
  271 
  272     clrExtNumber(ext);
  273 
  274     trk->getName(namebuf);
  275     slog(Slog::levelDebug) << namebuf << ": assigning to extension " << ext << endl;
  276     strcpy(trk->extNumber, ext);
  277     snprintf(namebuf, sizeof(namebuf), "%s.password", ext);
  278     *idx = trk;
  279 
  280     def = globals->getEntry("default.password", 0);
  281     if(!def)
  282         return true;
  283 
  284     sym = globals->getEntry(namebuf, def->flags.size);
  285     if(!sym)
  286         return true;
  287 
  288     if(!sym->flags.readonly)
  289         strcpy(sym->data, "new");
  290     sym->flags.initial = false;
  291     sym->flags.readonly = true;
  292 
  293     def = globals->getEntry("default.type", 8);
  294     if(!def)
  295         return true;
  296 
  297     if(def->flags.initial)
  298         def->flags.initial = false;
  299 
  300     snprintf(namebuf, sizeof(namebuf), "%s.type", ext);
  301     sym = globals->getEntry(namebuf, def->flags.size);
  302     if(!sym)
  303         return true;
  304 
  305     snprintf(sym->data, sym->flags.size + 1, "%s", "station");
  306     sym->flags.initial = false;
  307     sym->flags.readonly = true;
  308 
  309     def = globals->getEntry("default.port", 3);
  310     if(!def)
  311         return true;
  312 
  313     if(def->flags.initial)
  314         def->flags.initial = false;
  315 
  316     snprintf(namebuf, sizeof(namebuf), "%s.port", ext);
  317     sym = globals->getEntry(namebuf, def->flags.size);
  318     if(!sym)
  319         return true;
  320 
  321     snprintf(sym->data, sym->flags.size + 1, "%d", id);
  322     sym->flags.initial = false;
  323     sym->flags.readonly = true;
  324 
  325     return true;
  326 }
  327 
  328 bool Driver::setExtVirtual(unsigned id, const char *ext)
  329 {
  330     char namebuf[24];
  331     Trunk **idx = getExtIndex(ext);
  332     Trunk *trk = getTrunkPort(id);
  333     ScriptSymbol *globals = Trunk::getGlobals();
  334     Script::Symbol *def, *sym;
  335 
  336     if(!idx || !trk)
  337     {
  338         snprintf(namebuf, sizeof(namebuf), "%s.type", ext);
  339         sym = globals->getEntry(namebuf, 0);
  340         if(sym)
  341             snprintf(sym->data, sym->flags.size + 1, "user");
  342         snprintf(namebuf, sizeof(namebuf), "%s.port", ext);
  343         sym = globals->getEntry(namebuf, 0);
  344         if(sym)
  345             sym->data[0] = 0;
  346         return false;
  347     }
  348 
  349     if(*idx == trk)     // already is set to us, set type
  350     {
  351         if(stricmp(trk->extNumber, ext))
  352             return true;    // already virtual type
  353 
  354         trk->extNumber[0] = 0;
  355         snprintf(namebuf, sizeof(namebuf), "%s.type", ext);
  356         sym = globals->getEntry(namebuf, 0);
  357         if(sym)
  358             snprintf(sym->data, sym->flags.size + 1, "virtual");
  359         return true;
  360     }
  361 
  362     clrExtNumber(ext);
  363 
  364     trk->getName(namebuf);
  365     slog(Slog::levelDebug) << namebuf << ": assigning virtual " << ext << endl;
  366     snprintf(namebuf, sizeof(namebuf), "%s.password", ext);
  367     *idx = trk;
  368 
  369     def = globals->getEntry("default.password", 0);
  370     if(!def)
  371         return true;
  372 
  373     sym = globals->getEntry(namebuf, def->flags.size);
  374     if(!sym)
  375         return true;
  376 
  377     if(!sym->flags.readonly)
  378         strcpy(sym->data, "new");
  379 
  380     sym->flags.initial = false;
  381     sym->flags.readonly = true;
  382 
  383     def = globals->getEntry("default.type", 8);
  384     if(!def)
  385         return true;
  386 
  387     if(def->flags.initial)
  388         def->flags.initial = false;
  389 
  390     snprintf(namebuf, sizeof(namebuf), "%s.type", ext);
  391     sym = globals->getEntry(namebuf, def->flags.size);
  392     if(!sym)
  393         return true;
  394 
  395     snprintf(sym->data, sym->flags.size + 1, "virtual");
  396     sym->flags.initial = false;
  397     sym->flags.readonly = true;
  398 
  399     def = globals->getEntry("default.port", 3);
  400     if(!def)
  401         return true;
  402 
  403     if(def->flags.initial)
  404         def->flags.initial = false;
  405 
  406     snprintf(namebuf, sizeof(namebuf), "%s.port", ext);
  407     sym = globals->getEntry(namebuf, def->flags.size);
  408     if(!sym)
  409         return true;
  410 
  411     snprintf(sym->data, sym->flags.size + 1, "%d", id);
  412     sym->flags.initial = false;
  413     sym->flags.readonly = true;
  414 
  415     return true;
  416 }
  417 
  418 bool Driver::isIdle(void)
  419 {
  420     if(portCount - idleCount)
  421         return false;
  422 
  423     return true;
  424 }
  425 
  426 bool Driver::isDown(void)
  427 {
  428     if(portCount - downCount)
  429         return false;
  430 
  431     return true;
  432 }
  433 
  434 bool Driver::spanEvent(unsigned span, TrunkEvent *evt)
  435 {
  436     unsigned port;
  437     unsigned rtn = false;
  438     Trunk *trunk;
  439 
  440     if(!span)
  441         return false;
  442 
  443     for(port = 0; port < (unsigned)getTrunkCount(); ++port)
  444     {
  445         TrunkEvent ev = *evt;
  446         trunk = getTrunkPort(port);
  447         if(!trunk)
  448             continue;
  449 
  450         if(trunk->span != span)
  451             continue;
  452 
  453         rtn = true;
  454         trunk->postEvent(&ev);
  455     }
  456     return rtn;
  457 }
  458     
  459 aaImage *Driver::getImage(void)
  460 {
  461     return new aaImage((aaScript *)this);
  462 }
  463 
  464 Trunk *Driver::getTrunkId(const char *id)
  465 {
  466     Trunk *trk, *ret;
  467     char *cp;
  468 
  469     if(!id)
  470         return NULL;
  471 
  472     cp = strchr(id, '-');
  473     if(!cp)
  474         return getTrunkPort(atoi(id));
  475 
  476     trk = ret = getTrunkPort(atoi(++cp));
  477     if(!trk)
  478         return NULL;
  479 
  480     trk->enterMutex();
  481     cp = trk->getSymbol(SYM_GID);
  482     if(!cp)
  483         cp = "";
  484 
  485     if(*id == '-')
  486         cp = strchr(cp, '-');
  487     if(!cp)
  488         cp = "";
  489 
  490     if(strcmp(cp, id))  
  491         ret = NULL;
  492 
  493     trk->leaveMutex();
  494     return ret;
  495 }
  496 
  497 void Driver::secTick(void)
  498 {
  499     unsigned id, max = getTrunkCount();
  500     Trunk *trunk;
  501     TrunkEvent event;
  502     time_t now;
  503 
  504     time(&now);
  505 
  506     for(id = 0; id < max; ++ id)
  507     {
  508         trunk = getTrunkPort(id);
  509         if(!trunk)
  510             continue;
  511 
  512         if(!trunk->exittimer && !trunk->synctimer)
  513             continue;
  514 
  515         if(now >= trunk->exittimer)
  516         {
  517             event.id = TRUNK_TIMER_EXIT;
  518             trunk->postEvent(&event);
  519             trunk->exittimer = 0;
  520         }
  521 
  522         if(now >= trunk->synctimer)
  523         {
  524             event.id = TRUNK_TIMER_SYNC;
  525             trunk->postEvent(&event);
  526             trunk->synctimer = 0;
  527         }
  528     }
  529 }
  530 
  531 void Driver::setTrunkGroup(int id, int card, int span)
  532 {
  533     if(id < 0 || id > getTrunkCount())
  534         slog(Slog::levelError) << "server: setTrumkGroup; invalid" << endl;
  535 
  536     TrunkGroup *grp = getTrunkGroup(id);
  537     if(grp != getGroup(NULL))
  538         return;
  539 
  540     if(!grp)
  541         return;
  542 
  543     if(spans[span])
  544         grp = spans[span];
  545     else if(cards[card])
  546         grp = cards[card];
  547 
  548     groups[id] = grp;
  549 }
  550 
  551 int Driver::getTrunkMember(TrunkGroup *group, unsigned member)
  552 {
  553     int id, count = getTrunkCount();
  554     Trunk *trunk;
  555 
  556     for(id = 0; id < count; ++id)
  557     {
  558         if(groups[id] != group)
  559             continue;
  560 
  561         trunk = getTrunkPort(id);
  562         if(trunk->getMemberId() == member)
  563             return id;
  564     }
  565     return -1;
  566 }
  567 
  568 void Driver::getStatus(char *buffer)
  569 {
  570     if(!status) {
  571         buffer[0] = 0;
  572         return;
  573     }
  574     memcpy(buffer, status, getTrunkCount());
  575 }
  576 
  577 void alog(Trunk *trunk, char *detail)
  578 {
  579     Audit *au = Audit::first;
  580 
  581     while(au)
  582     {
  583         au->reportAudit(trunk, detail);
  584         au = au->next;
  585     }
  586 }
  587 
  588 void audit(Trunk *trunk, char *detail)
  589 {
  590     Audit *au = Audit::first;
  591 
  592     while(au)
  593     {
  594         au->reportCDR(trunk, detail);
  595         au = au->next;
  596     }
  597 }
  598 
  599 Debug::Debug() :
  600 Mutex()
  601 {
  602     if(debug)
  603         throw this;
  604 
  605     debug = this;
  606 }
  607 
  608 Monitor::Monitor() :
  609 Mutex()
  610 {
  611     if(monitor)
  612         throw this;
  613 
  614     monitor = this;
  615 }
  616 
  617 Translator::Translator(const char *conf) :
  618 Keydata(conf)
  619 {
  620     char keypath[33];
  621 
  622     next = first;
  623     first = this;
  624 
  625     strcpy(keypath, conf);
  626     *keypath = '~';
  627     load(keypath);
  628 }
  629 
  630 char *Translator::getPlayBuffer(Trunk *trunk)
  631 {
  632     char *pbuf;
  633     
  634     pbuf = trunk->data.play.list;
  635     trunk->data.play.name = pbuf;
  636     trunk->data.play.limit = trunk->data.play.offset = 0;
  637     *pbuf = 0;
  638     return pbuf;
  639 }
  640 
  641 Translator *getTranslator(const char *name)
  642 {
  643     Translator *trans = Translator::first;
  644 
  645     while(trans)
  646     {
  647         if(!stricmp(name, trans->getName()))
  648             return trans;
  649         trans = trans->next;
  650     }
  651     return NULL;
  652 }
  653 
  654 Sync::Sync()
  655 {
  656     next = first;
  657     first = this;
  658     time(&runtime);
  659 }
  660 
  661 Server::Server(int pri) :
  662 #ifdef  COMMON_OST_NAMESPACE
  663 Thread(pri, keythreads.getStack())
  664 #else
  665 Thread(NULL, pri, keythreads.getStack())
  666 #endif
  667 {
  668     next = first;
  669     first = this;
  670 }
  671 
  672 void startServers(void)
  673 {
  674     Server *server = Server::first;
  675 
  676     while(server)
  677     {
  678         server->start();
  679         server = server->next;
  680     }
  681 }
  682 
  683 void stopServers(void)
  684 {
  685     Server *server = Server::first;
  686 
  687     while(server)
  688     {
  689         server->stop();
  690         server = server->next;
  691     }
  692 }
  693 
  694 TGI::TGI()
  695 {
  696     next = first;
  697     first = this;
  698 }
  699 
  700 TGI *getInterp(char *cmd)
  701 {
  702     TGI *tgi = TGI::first;
  703     char *ext;
  704     char buffer[512];
  705     strcpy(buffer, cmd);
  706     cmd = strtok_r(buffer, " \t\n", &ext);
  707     ext = strrchr(cmd, '.');
  708     
  709     while(tgi)
  710     {
  711         if(tgi->getExtension(ext))
  712             return tgi;
  713         tgi = tgi->next;
  714     }
  715     return NULL;
  716 }
  717 
  718 void getInterp(char *cmd, char **args)
  719 {
  720     TGI *tgi = TGI::first;
  721 
  722     while(tgi)
  723     {
  724         tgi->script(cmd, args);
  725         tgi = tgi->next;
  726     }
  727 }
  728 
  729 Module::Module()
  730 {
  731     modNext = modFirst;
  732     modFirst = this;
  733     prior = NULL;
  734 }
  735 
  736 void Module::addSymbols(void)
  737 {
  738     symNext = symFirst;
  739     symFirst = this;
  740 }
  741 
  742 void Module::addSession(void)
  743 {
  744     sesNext = sesFirst;
  745     sesFirst = this;
  746 }
  747 
  748 void Module::addNetwork(void)
  749 {
  750     netNext = netFirst;
  751     netFirst = this;
  752 }
  753 
  754 void Module::addRequest(void)
  755 {
  756     reqNext = reqFirst;
  757     reqFirst = this;
  758 }
  759 
  760 void Module::setThread(Trunk *trunk, Service *svc)
  761 {
  762     if(trunk->thread)
  763         trunk->stopServices();
  764     trunk->thread = svc;
  765 }
  766 
  767 void Module::addCommand(void)
  768 {
  769     cmdNext = cmdFirst;
  770     cmdFirst = this;
  771 }
  772 
  773 void Module::addPrompts(void)
  774 {
  775     urlNext = urlFirst;
  776     urlFirst = this;
  777 }
  778 
  779 void detachModules(Trunk *trunk)
  780 {
  781     Module *mod = Module::sesFirst;
  782 
  783     while(mod)
  784     {
  785         mod->detach(trunk);
  786         mod = mod->sesNext;
  787     }
  788 }
  789 
  790 void attachModules(Trunk *trunk)
  791 {
  792 
  793     Module *mod = Module::sesFirst;
  794 
  795     while(mod)
  796     {
  797         mod->attach(trunk);
  798         mod = mod->sesNext;
  799     }
  800 }
  801 
  802 Module *getModule(modtype_t mtype, const char *name)
  803 {
  804     Module *mod = Module::modFirst;
  805 
  806     while(mod)
  807     {
  808         if(mod->getType() == mtype || mtype == MODULE_ANY)
  809         {
  810             if(!name)
  811                 return mod;
  812 
  813             if(!stricmp(name, mod->getName()))
  814                 return mod;
  815         }
  816         mod = mod->modNext;
  817     }
  818     return NULL;
  819 }
  820 
  821 #ifdef  HAVE_EXECINFO_H
  822 
  823 #include <execinfo.h>
  824 
  825 void    Debug::stackTrace(int signo)
  826 {
  827         const int maxTrace = 1000;
  828         void* buffer[maxTrace];
  829         int nTrace = backtrace ( buffer, maxTrace );
  830         char** trace = backtrace_symbols ( buffer, nTrace );
  831 
  832         slog(Slog::levelDebug) << "trace: pid=" << pthread_self()
  833                 << " reason=" << signo << endl;
  834 
  835 
  836         if ( trace ) {
  837                 for ( int i = 0; i < nTrace; ++i ) {
  838                 slog(Slog::levelDebug) << "trace(" << i << "): "
  839                         << trace[i] << endl;
  840                 }
  841         }
  842         // free memory
  843         free( trace );
  844 }
  845 
  846 #else
  847 void    Debug::stackTrace(int signo) {}
  848 #endif
  849 
  850 
  851 Debug *debug = NULL;
  852 Monitor *monitor = NULL;
  853 Driver *driver = NULL;
  854 TTS *tts = NULL;
  855 
  856 #ifdef  CCXX_NAMESPACES
  857 };
  858 #endif