// -------------------------------------------------------------------- // S c r i p t . c p p // // Layer for FICL. // -------------------------------------------------------------------- // Copyright (c) 1998-2000 by Fyodor Ustinov // FIDONet 2:5020/79 // // All rights reserved. // -------------------------------------------------------------------- // // If you want to compile FTrack without script subsystem // // Check points 60* #include "ficl.h" #include "script.hpp" #include "constant.hpp" #include "vars.hpp" #include "configure.hpp" static cMSG *m = NULL; void stackPushCStr(char *c) { if (c == NULL) { stackPushPtr(pVM->pStack,NULL); stackPushUNS(pVM->pStack,0); } else { stackPushPtr(pVM->pStack,c); stackPushUNS(pVM->pStack,strlen(c)); } } // -------------------------------------------------------------------- // Work with MSG // -------------------------------------------------------------------- void CheckM(void) { if (m == NULL) { Log.Level(LOGE) << "Attempt of use of words like MSG.* in script before scandir." << EOL; exit(-1); } } static void fMsgFromAddr(FICL_VM *pVM) { CheckM(); stackPushUNS(pVM->pStack, (UNS32)m->_FromAddr.Point()); stackPushUNS(pVM->pStack, (UNS32)m->_FromAddr.Node()); stackPushUNS(pVM->pStack, (UNS32)m->_FromAddr.Net()); stackPushUNS(pVM->pStack, (UNS32)m->_FromAddr.Zone()); return; } static void fMsgFromAddrA(FICL_VM *pVM) { CheckM(); stackPushUNS(pVM->pStack, (UNS32)&m->_FromAddr); return; } static void fMsgToAddr(FICL_VM *pVM) { CheckM(); stackPushUNS(pVM->pStack, (UNS32)m->_ToAddr.Point()); stackPushUNS(pVM->pStack, (UNS32)m->_ToAddr.Node()); stackPushUNS(pVM->pStack, (UNS32)m->_ToAddr.Net()); stackPushUNS(pVM->pStack, (UNS32)m->_ToAddr.Zone()); return; } static void fMsgToAddrA(FICL_VM *pVM) { CheckM(); stackPushUNS(pVM->pStack, (UNS32)&m->_ToAddr); return; } static void fMsgFromName(FICL_VM *pVM) { CheckM(); stackPushPtr(pVM->pStack,m->_FromName); stackPushUNS(pVM->pStack,strlen(m->_FromName)); return; } static void fMsgToName(FICL_VM *pVM) { CheckM(); stackPushPtr(pVM->pStack,m->_ToName); stackPushUNS(pVM->pStack,strlen(m->_ToName)); return; } static void fMsgSubject(FICL_VM *pVM) { CheckM(); stackPushPtr(pVM->pStack,m->_Subject); stackPushUNS(pVM->pStack,strlen(m->_Subject)); return; } static void fMsgBody(FICL_VM *pVM) { CheckM(); stackPushPtr(pVM->pStack,m->_Body); stackPushUNS(pVM->pStack,strlen(m->_Body)); return; } static void fMsgLines(FICL_VM *pVM) { CheckM(); stackPushUNS(pVM->pStack,m->Lines()); return; } static void fMsgBytes(FICL_VM *pVM) { CheckM(); stackPushUNS(pVM->pStack,m->Bytes()); return; } static void fMsgKludgeBody(FICL_VM *pVM) { IndBiList<Kludge>::ElemPtr Klu; int KluNumber; CheckM(); KluNumber = stackPopINT(pVM->pStack); Klu = m->_Klu.GetFirst(); while (Klu != NULL && KluNumber != 0) { Klu++; KluNumber--; } if (Klu == NULL) { stackPushPtr(pVM->pStack,NULL); stackPushUNS(pVM->pStack,0); } else { stackPushCStr(Klu->Body()); } return; } static void fMsgKludgeName(FICL_VM *pVM) { IndBiList<Kludge>::ElemPtr Klu; int KluNumber; CheckM(); KluNumber = stackPopINT(pVM->pStack); Klu = m->_Klu.GetFirst(); while (Klu != NULL && KluNumber != 0) { Klu++; KluNumber--; } if (Klu == NULL) { stackPushPtr(pVM->pStack,NULL); stackPushUNS(pVM->pStack,0); } else { stackPushCStr(Klu->Name()); } return; } static void fMsgKludgeDelete(FICL_VM *pVM) { IndBiList<Kludge>::ElemPtr Klu; int KluNumber; CheckM(); KluNumber = stackPopINT(pVM->pStack); Klu = m->_Klu.GetFirst(); while (Klu != NULL && KluNumber != 0) { Klu++; KluNumber--; } if (Klu == NULL) { vmThrow(pVM,FTR_OUTOFRANGE); } else { m->_Klu.Remove(Klu); } return; } static void fMsgKludges(FICL_VM *pVM) { CheckM(); stackPushUNS(pVM->pStack,m->_Klu.ElemCount()); return; } static void fMsgLoopCount(FICL_VM *pVM) { FICL_UNS count = stackPopUNS(pVM->pStack); char *cp = (char *)stackPopPtr(pVM->pStack); char *tmt; CheckM(); if (count == 0) { stackPushUNS(pVM->pStack,0); return; } tmt = (char *) malloc(count+1); CheckMem(tmt); strncpy(tmt,cp,count); tmt[count] = '\0'; stackPushUNS(pVM->pStack,m->LoopCount(tmt)); free(tmt); return; } static void fMsgAttachSize(FICL_VM *pVM) { CheckM(); stackPushUNS(pVM->pStack,m->AttachSize()); return; } static void fMsgWrite(FICL_VM *pVM) { CheckM(); stackPushUNS(pVM->pStack,m->AttachSize()); return; } int ScriptWordExists(char *word) { FICL_WORD *WordExec; WordExec = ficlLookup(word); if (WordExec != NULL) return TRUE; else return FALSE; } // -------------------------------------------------------------------- // Scandirs... // -------------------------------------------------------------------- ScrRet DoThisWordRc(char *word) { return DoThisWord(word); } ScrRet DoThisWord(char *word) { FICL_WORD *WordExec; int i; if (LogLevel >= 5) { Log.Level(LOGD) << "DoThisWord(\"" << word << "\");" << EOL; } WordExec = ficlLookup(word); if (WordExec != NULL) { if ((i = ficlExecXT(pVM,WordExec)) != VM_INNEREXIT) { Log.Level(LOGE) << "Error execution word '" << word << "' rc == " << i << EOL; return SS_ERROR; } else { return SS_OK; } } else { return SS_ERROR; } } void PrepareMsgForScript(cMSG &sm) { m = &sm; } void buildAddonsToFICL(void) { ficlBuild("MSG.FromAddr", fMsgFromAddr, FW_DEFAULT); ficlBuild("MSG.FromAddrA", fMsgFromAddrA, FW_DEFAULT); ficlBuild("MSG.ToAddr", fMsgToAddr, FW_DEFAULT); ficlBuild("MSG.ToAddrA", fMsgToAddrA, FW_DEFAULT); ficlBuild("MSG.FromName", fMsgFromName, FW_DEFAULT); ficlBuild("MSG.ToName", fMsgToName, FW_DEFAULT); ficlBuild("MSG.Subject", fMsgSubject, FW_DEFAULT); ficlBuild("MSG.Body", fMsgBody, FW_DEFAULT); ficlBuild("MSG.Lines", fMsgLines, FW_DEFAULT); ficlBuild("MSG.Bytes", fMsgBytes, FW_DEFAULT); ficlBuild("MSG.Kludge.Name", fMsgKludgeName, FW_DEFAULT); ficlBuild("MSG.Kludge.Body", fMsgKludgeBody, FW_DEFAULT); ficlBuild("MSG.Kludge.Delete", fMsgKludgeDelete, FW_DEFAULT); ficlBuild("MSG.Kludges", fMsgKludges, FW_DEFAULT); ficlBuild("MSG.LoopCount", fMsgLoopCount, FW_DEFAULT); ficlBuild("MSG.AttachSize", fMsgAttachSize, FW_DEFAULT); ficlBuild("MSG.Write", fMsgWrite, FW_DEFAULT); return; } int InitScriptSystem(void) { ficlInitSystem(FICL_SIZE); pVM = ficlNewVM(); buildAddonsToFICL(); return TRUE; } int StopScriptSystem(void) { ficlTermSystem(); return TRUE; } int InitScriptValues(void) { return TRUE; } ScrRet DoSomeWord(char *word) { if (ScriptWordExists(word)) { return DoThisWord(word); } return SS_NOTDEF; } ScrRet DoSomeWordRc(char *word) { if (ScriptWordExists(word)) { return DoThisWordRc(word); } return SS_NOTDEF; } int _LoadScriptFile(char *fname) { char Buff[MAXCFGLINE]; FILE *fh; int LineNum; char *tmt; LineNum = 0; Log.Level(LOGI) << "Load script file: '" << fname << "'." << EOL; fh = fopen(fname,"r"); if (fh == NULL) { yyerror("Unable to open script file."); return (-1); } while(fgets(Buff,MAXCFGLINE,fh)) { LineNum++; while ((tmt = strrchr(Buff,'\n')) != NULL) *tmt = '\0'; while ((tmt = strrchr(Buff,'\r')) != NULL) *tmt = '\0'; if (strlen(Buff) == 0) continue; if (ficlExec(pVM, Buff) != VM_OUTOFTEXT) { sprintf(Buff,"Unable parsing script in line %d",LineNum); yyerror(Buff); fclose(fh); return (-1); } } ficlExec(pVM, ""); fclose(fh); return 0; }