📄 trunkmap.cpp
字号:
// Copyright (C) 1999-2000 Open Source Telecom Corporation.// // This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// As a special exception to the GNU General Public License, permission is// granted for additional uses of the text contained in its release// of ACS as noted here.//// This exception is that permission is hereby granted to link ACS with// the Pika MonteCarlo static libraries to produce a executable image// without requiring MonteCarlo itself to be supplied in source form so// long as each source file so linked contains this exclusion.//// This exception does not however invalidate any other reasons why// the resulting executable file might be covered by the GNU General// public license or invalidate the licensing requirements of any// other component or library.//// This exception applies only to the code released by OST under the// name ACS. If you copy code from other releases into a copy of// ACS, as the General Public License permits, the exception does not// apply to the code that you add in this way. To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own to ACS, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice, at which// point the terms of your modification would be covered under the GPL// as explicitly stated in "COPYING".#include <config.h>#include <debug.h>#include <stdlib.h>#include <ctype.h>#include <sym.h>#include <cc++/thread.h>#include <cc++/file.h>#include "trunkmap.h"#include "script.h"#include "shell.h"//#include "portmap.h"#include "module.h"#include "database.h"#include "vocab.h"char Trunkmap::dtmfkeys[] = "0123456789*#ABCD";Trunkmap *Trunkmap::firstmap = NULL;Trunkmap *Trunkmap::lastmap = NULL;int Trunkmap::active = 0;Trunkmap::Trunkmap(Runmap *map, char *scr){ runmap = map; dtmf = listflag = offhook = idle = trap = false; timer = 0; rings = 0; digits = 0; digit[0] = 0; cid[0] = 0; dnid[0] = 0; ani[0] = 0; volume = 0x5050;// portmap = NULL; script = NULL; mailbox = NULL; strcpy(lang, "UsEngM"); vocab = getVocabulary(lang);// if(getPortmaps())// portmap = new Trunkmap*[getPortmaps()]; if(!firstmap) { firstmap = lastmap = this; nextmap = NULL; } else { lastmap->nextmap = this; lastmap = this; nextmap = NULL; } yield(); clrSchedule(); setCurrent("Starting..."); if(!scr) setSchedule(SCHED_RESET, "default"); else setSchedule(SCHED_OVERRIDE, scr); id = ++active;}Trunkmap::~Trunkmap(){ if(script) detach(script);// if(portmap)// delete[] portmap; setCurrent("DOWN"); --active;}void Trunkmap::setcid(void){ struct tm *dt; dt = localtime(&ringtime); sprintf(cid, "time=%02d:%02d:%02d&date=%04d%02d%02d", dt->tm_hour, dt->tm_min, dt->tm_sec, dt->tm_year + 1900, dt->tm_mon + 1, dt->tm_mday);}void Trunkmap::setCurrent(char *str){ yield(); memset(runmap->current, 0, 32); strncpy(runmap->current, str, 31); }void Trunkmap::setSchedule(int sc, char *scr){ switch(sc) { case SCHED_DAILY: case SCHED_RESET: if(sched == SCHED_OVERRIDE) return; } yield(); memset(runmap->schedule, 0, 32); strncpy(runmap->schedule, scr, 31); sched = sc;}void Trunkmap::scrErrorStep(char *errmsg){ strncpy(error, errmsg, 16); error[16] = 0; debug(1, "%s(%d): error handler", errmsg, id); if(menu->ERR == menu->first || (cmd[stack]->mask & ERROR_MASK)) scrStep(); else { cmd[stack] = menu->ERR; scrExecute(); }}void Trunkmap::scrExists(void){ char *path = getOption(NULL); struct stat ino; if(!path) return scrErrorStep("missing-arg"); if(!stat(path, &ino)) { scrGoto(); return; } scrStep();}void Trunkmap::scrErase(void){ char *target = getOption(NULL); if(target) { if(*target != '/') { if(remove(target)) return scrErrorStep("remove-failed"); } else return scrErrorStep("invalid-path"); } else return scrErrorStep("missing-arg"); scrStep();}void Trunkmap::scrMove(void){ char *source = getOption(NULL); char *target = getOption(NULL); if(source && target) { if(*source != '/' && *target != '/') { if(!link(source, target)) { if(remove(source)) return scrErrorStep("remove-failed"); } else return scrErrorStep("move-failed"); } else return scrErrorStep("invalid-path"); } else return scrErrorStep("missing-arg"); scrStep();}void Trunkmap::scrLink(void){ char *src = getOption(NULL); char *target; while(NULL != (target = getOption(NULL))) { if(*src != '/' && *target != '/') { if(link(src, target)) return scrErrorStep("link-failed"); } else return scrErrorStep("invalid-path"); } scrStep();}void Trunkmap::scrIf(void){ int l1, l2; char *op1 = getOption(NULL); char *op = getOption(NULL); char *op2 = getOption(NULL); if(!op1 || !op || !op2) return scrErrorStep("missing-arg"); if(!stricmp(op, "=")) { if(atol(op1) == atol(op2)) return scrGoto(); } if(!stricmp(op, "<>")) { if(atol(op1) != atol(op2)) return scrGoto(); } if(!stricmp(op, "==")) { if(!stricmp(op1, op2)) return scrGoto(); } if(!stricmp(op, "!=")) { if(stricmp(op1, op2)) return scrGoto(); } if(!stricmp(op, "$")) { if(strstr(op2, op1)) return scrGoto(); } if(!stricmp(op, "$<") || !stricmp(op, "$+")) { if(!strnicmp(op1, op2, strlen(op1))) return scrGoto(); } if(!stricmp(op, "$>") || !stricmp(op, "$-")) { l1 = strlen(op1); l2 = strlen(op2); if(l1 <= l2) if(!strnicmp(op1, op2 + l2 - l1, l1)) return scrGoto(); } if(!stricmp(op, ">")) { if(atol(op1) > atol(op2)) return scrGoto(); } if(!stricmp(op, "<")) { if(atol(op1) < atol(op2)) return scrGoto(); } if(!stricmp(op, "<=") || !stricmp(op, "=<")) { if(atol(op1) <= atol(op2)) return scrGoto(); } if(!stricmp(op, ">=") || !stricmp(op, "=>")) { if(atol(op1) >= atol(op2)) return scrGoto(); } scrStep();}void Trunkmap::scrPrefix(void){ char *target = getOption(NULL); char *value; if(!target) return scrErrorStep("missing-arg"); while(NULL != (value = getOption(NULL))) { if(!strnicmp(value, target, strlen(value))) return scrGoto(); getOption(NULL); } scrStep();}void Trunkmap::scrTrace(void){ char *opt = getOption("on"); if(!stricmp(opt, "off")) listflag = false; else listflag = true; scrStep();}void Trunkmap::scrSelect(void){ char *target = getOption(NULL); char *value; if(!target) return scrErrorStep("missing-arg"); while(NULL != (value = getOption(NULL))) { if(!stricmp(value, target)) return scrGoto(); getOption(NULL); // skip to next entry } scrStep();}void Trunkmap::scrPop(void){ if(stack) { cmd[stack - 1] = cmd[stack]; --stack; } else return scrErrorStep("stack-empty"); scrStep();}void Trunkmap::scrReturn(void){ if(stack) --stack; else return scrErrorStep("stack-empty"); scrStep();}void Trunkmap::scrCall(void){ if(stack < (MAX_STACK - 1)) { cmd[stack + 1] = cmd[stack]; ++stack; } else return scrErrorStep("stack-full"); return scrGoto();}void Trunkmap::scrTrap(void){ char *opt; if(trap) return scrGoto(); opt = getOption(NULL); if(opt) menu->TRAP = cmd[stack]; else menu->TRAP = NULL;}bool Trunkmap::exeTrap(void){ if(trap) return true; if(!offhook || !menu->TRAP) return false; trap = true; debug(2, "trap(%d): invoking trap script", id); stack = 0; cmd[stack] = menu->TRAP; menu->TRAP = NULL; scrExecute();}void Trunkmap::scrGoto(void){ char buf[32]; Menu *start = NULL; int dig; char *opt = getOption(getSchedule(buf)); if(!*opt) return scrErrorStep("missing-arg"); if(*opt == '#') { dig = opt[1] - '0'; if(dig > -1 && dig < 10) { cmd[stack] = menu->L[dig]; debug(3, "branching %s(%d)", opt, id); scrExecute(); return; } else return scrErrorStep("invalid-arg"); } if(*opt == '^') { for(dig = 0; dig < 16; ++dig) if(opt[1] == dtmfkeys[dig]) break; if(dig == 16) { dig = -1; switch(opt[1]) { case 't': case 'T': cmd[stack] = menu->TO; debug(3, "branching timeout(%d)", id); scrExecute(); return; case 'e': case 'E': cmd[stack] = menu->ERR; debug(3, "branching error(%d)", id); scrExecute(); return; } } if(dig >= 0) { debug(3, "branching digit-%d(%d)", dig, id); cmd[stack] = menu->D[dig]; scrExecute(); return; } else return scrErrorStep("invalid-arg"); } start = lookup(script, opt); if(!start) { syslog(LOG_WARNING, "%s: cannot start", opt); return scrErrorStep("missing-script"); } menu = start; menu->TRAP = NULL; debug(2, "starting %s(%d)", opt, id); offset = 0l; cmd[stack] = menu->first; setCurrent(menu->name); scrExecute();}void Trunkmap::scrAttach(char *scr){ char schedule[33]; if(!script) script = attach(); if(scr) strcpy(schedule, scr); else getSchedule(schedule); menu = lookup(script, schedule); menu->TRAP = NULL; if(!menu) { syslog(LOG_WARNING, "%s: cannot start", schedule); return; } debug(1, "scheduling %s(%d)", schedule, id); offset = 0l; stack = 0; trap = listflag = false; time(&starttime); cmd[stack] = menu->first; setCurrent(menu->name); scrExecute();}void Trunkmap::scrDetach(void){ if(script) { detach(script); script = NULL; }};void Trunkmap::scrExecute(void){ argc = 0; temps = 0; if(listflag) { syslog(LOG_DEBUG, "%03d %s(%d) %s, mask=%08x", cmd[stack]->line, menu->name, id, cmd[stack]->cmd, cmd[stack]->mask); } (this->*(cmd[stack]->scrHandler))();}void Trunkmap::scrTimeout(void){ if(menu->TO != menu->first) cmd[stack] = menu->TO; else cmd[stack] = cmd[stack]->next; scrStop();}void Trunkmap::scrError(char *err){ strcpy(error, err); if(menu->ERR != menu->first && !(cmd[stack]->mask & ERROR_MASK)) cmd[stack] = menu->ERR; else cmd[stack] = cmd[stack]->next; scrStop();}void Trunkmap::scrDigit(int trap){ if(menu->D[trap] != menu->first && !cmd[stack]->mask) { digits = 1; digit[0] = dtmfkeys[trap]; digit[1] = 0; cmd[stack] = menu->D[trap]; scrStop(); return; } if(digits > 32) return; digit[digits++] = dtmfkeys[trap]; digit[digits] = 0;}void Trunkmap::scrLog(void){ char buf[256]; char *opt; sprintf(buf, "%s(%02d):", menu->name, id); while(NULL != (opt = getOption(NULL))) { strcat(buf, " "); strcat(buf, opt); } syslog(LOG_INFO, "%s", buf); scrStep();}void Trunkmap::scrTrim(void){ char *opt = getOption(NULL); int l1; int c; if(!opt) return scrErrorStep("missing-arg"); l1 = strlen(opt); if(*opt == '-') { ++opt; --l1; if(l1 <= digits) { if(!strcmp(opt, digit + digits - l1)) { digits -= l1; digit[digits] = 0; } } scrStep(); return; } if(!strnicmp(digit, opt, l1)) { for(c = l1; c <= digits; ++c) digit[c - l1] = digit[c]; digits -= l1; } scrStep();}void Trunkmap::scrAdd(void){ char *opt = getOption(NULL); int l1; int c; if(!opt) return scrErrorStep("missing-arg"); if(*opt == '-') { ++opt; strncat(digit, opt, 32 - digits); digit[32] = 0; digits = strlen(digit); scrStep(); return; } l1 = strlen(opt); if(l1 + digits > 32) { scrStep(); return; } for(c = digits; c >= 0; --c) digit[c + l1] = digit[c]; strncpy(digit, opt, l1); digits += l1; scrStep();}void Trunkmap::scrDrop(void){ if(!mailbox) return scrErrorStep("no-mailbox"); mailbox->Drop(); scrStep();}void Trunkmap::scrSave(void){ if(!mailbox) return scrErrorStep("no-mailbox"); mailbox->Save(); scrStep();}void Trunkmap::scrSkip(void){ if(!mailbox) return scrErrorStep("no-mailbox"); mailbox->Skip(getOption("next")); scrStep();}void Trunkmap::scrMessages(void){ if(!mailbox) return scrErrorStep("no-mailbox"); mailbox->setMessages(getOption("new")); scrStep();}void Trunkmap::scrClear(void){ char *opt = getOption(NULL); int count = 0; int pos = 0; if(opt) { if(*opt == '-') count = -atoi(++opt); else count = atoi(opt); } if(count > 0 && count < digits) { digit[digits] = 0; for(;;) { digit[pos] = digit[pos + count]; if(!digit[pos]) break; ++pos; } digits = strlen(digit); } else if(count < 0 && -count < digits) { digits += count; digit[digits] = 0; } else { digits = 0; digit[0] = 0; } scrStep();}void Trunkmap::scrTGI(bool wait, bool detach){ char buf[128]; char *p; char *q; int cnt = 0; int args = 0; strcpy(buf, getOption(NULL)); for(;;) { q = cmd[stack]->argv[argc]; if(NULL == (p = getOption(NULL))) break; if(!(cnt++)) strcat(buf, " query="); else strcat(buf, "&"); if(*q == '%' || *q == '@') ++q; else { sprintf(buf, "value%d", ++args); q = buf; } strcat(buf, q); strcat(buf, "="); strcat(buf, p); } if(digits > 0) { digit[digits] = 0; strcat(buf, " digits="); strcat(buf, digit); } if(cid[0]) { strcat(buf, " cid="); strcat(buf, cid); } if(ani[0]) { strcat(buf, " ani="); strcat(buf, ani); } if(dnid[0]) { strcat(buf, " dnid="); strcat(buf, dnid); } waitpid = 0; exstatus = -1; if(detach) execute(0, buf); else execute(id, buf); if(wait) { argc = 0; scrExWait(); } else scrStep();}void Trunkmap::scrLibexec(void){ char *timeout = getOption(NULL); if(timeout) { if(!stricmp(timeout, "trap")) { menu->TRAP = NULL; scrTGI(false, true); } else if(!stricmp(timeout, "detach")) { scrTGI(false, true); } else if(!stricmp(timeout, "start")) { scrTGI(false, false); } else if(!stricmp(timeout, "wait") || !stricmp(timeout, "exit")) { scrExWait(); } else if(!stricmp(timeout, "kill")) { if(waitpid) { kill(waitpid, SIGINT); waitpid = 0; } scrStep(); } else scrTGI(true, false); } else scrErrorStep("missing-arg");}void Trunkmap::scrList(void){ char env[256]; char *target = getOption(NULL); char *e; if(!target) return scrErrorStep("missing-arg"); env[0] = 0; while(NULL != (e = getOption(NULL))) { if(env[0]) strcat(env, ":"); strcat(env, e); } setsym(target, env, id); item = 0; scrStep();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -