%{ #define YYDEBUG 0 /* #define YYERROR_VERBOSE */ #include #ifdef __WATCOMC__ #include #endif #include "msg.hpp" #include "outbound.hpp" #include "fidoaddr.h" #include "vars.hpp" #include "configure.hpp" #include "constant.hpp" #include "log.hpp" #include "aka.hpp" #include "age.hpp" #include "scandir.hpp" #include "attach.hpp" #include "badmsg.hpp" #include "passwd.hpp" #include "nodelist.hpp" #include "script.hpp" #undef YYSTYPE /* Perl also use bison? damn! */ extern int DetectError; extern int NoTokensF; extern FA cffa; extern FA cffa1; extern FA cffa2; static int brf = FALSE, arf = FALSE, renumberf = FALSE, unpackf = FALSE, freshf = FALSE; static ScanDir *wsd = NULL; static char *FileName = NULL; static char *ScriptBefore = NULL; static char *ScriptAfter = NULL; static tTimes *tt; static IndBiList *_TTimes; static MSGBASE *mbase; static Mask *msk = NULL; static int MaskMode; static int rc; static int FlagMode = 0; static Action *act = NULL; static void CheckETTime(void) { time_t tmt; if (tt->_ETime != 0 && tt->_ETime < tt->_STime) { tmt = tt->_ETime; tt->_ETime = (23*60*60)+(59*60)+59; tt->_ETime += TimeOfBeginOfDay(-1); _TTimes->AddToEnd(tt); tt = new tTimes; tt->_STime = TimeOfBeginOfDay(-1); tt->_ETime = tmt; } } static int PrepareMask(Mask &m) { ScanDir *sd; char ErrMess[128]; CHP = 23700; sd = ScanDirs.GetLast(); if (sd == NULL) { strcpy(ErrMess,"'"); strcat(ErrMess,m.MaskName()); strcat(ErrMess,":' without 'ScanDir:'"); yyerror(ErrMess); return -1; } m.sd = sd; return 0; } static void AddReadyMask(Mask &m) { ScanDir *sd; switch (PrevMask) { case 0: // first mask. case 1: // after action. LastDo = new DoList(); sd = ScanDirs.GetLast(); sd->_DoLists.AddToEnd(LastDo); PrevMask = 2; break; case 2: // after MASK. break; } LastDo->AddMask(m); } static int CheckMaskMode(char *f) { char Buff[128]; if (MaskMode != 0) { strcpy(Buff,"You can use '"); strcat(Buff,f); strcat(Buff,"' flag only in 'Mask:'."); yyerror(Buff); return -1; } return 0; } static int ctoi(char *s) { char *foo; int res = 0; res = strtoul(s, &foo, 0); if (*foo) /* parse error */ return 0; return res; } %} %union { int in; char *ch; long ln; KillModeT kmode; CheckPointsT pmode; tBadMsgMode bmode; time_t t; PKTMode pktmode; }; %token _LOGFILE _LOGLEVEL _NODELIST _INDEXFILE _NODELISTPATH _ADDRESS _SYSOPNAME _USEOWNZONE _FORCEINTL _LOOPSTR _SCANDIR _MASK _SMASK _PMASK _BODYMASK _SBODYMASK _PBODYMASK _KLUDGEMASK _SKLUDGEMASK _PKLUDGEMASK _ACTION _MAXAGE _BADMESSAGES _NOLOGIGNORE _AKA _SKIPHIDDENFILES _FILEINBOUND _OUTBOUND _ADDTONULLPKT _TEMPMAIL _TRAFFICLOG _PASSWORD _UTC _ORIGIN _TEARLINE _INCLUDE _APKTDIR _CHECKPOINTS _SETVIAALWAYS _FRESH _CREATEMISSINGBASE _USENEWVIA _SCRIPTMASK _SSCRIPTMASK _PSCRIPTMASK _MAXATTACHSIZE _SEMAPHORE _SCRIPTFILE _USEASO _KILLROUTEDMESSAGE _IGNOREBSY _AFTERSCRIPT _BEFORESCRIPT _MAXNODELISTAGE _SOFTCHECKINNODELIST _TIMESTAMPFILE _TRAFFICLOGTEMPLATE _STRIPPATHINPKT _CRLF _SKIP _DELETE _EXIT _MOVE __EOF _STRING _BEFOREROUTE _AFTERROUTE _DIGIT_ _RENUMBER _UNPACK _DAILY _WEEKLY _FLAG _NEVER _HARD _SOFT _ALWAYS /* Actions */ _ADDNOTE _COPY _REWRITE _IGNORE _DISPLAY _DELFILE _NEWMSG _WRITEFILE _APPENDTOFILE _CALL _ROUTE _POLL _DELETEATTACH _CHANGEPATH _MOVEATTACH _ASCRIPT _COPYATTACH _SPLIT _RECODE _HOLD _CRASH _DIRECT _NORMAL LEXERR %start Conf %% Conf : /* empty */ | Conf ConfLine ; ConfLine : Action _CRLF | IncludeF _CRLF ={ if (SetInclude($1) != 0) { YYABORT; } } | TimeStampFile _CRLF | Address _CRLF | _ADDTONULLPKT _CRLF = { if (SetAddToNullPkt() != 0) { YYABORT; } } | Aka _CRLF | APktDir _CRLF | BodyMask _CRLF | SBodyMask _CRLF | PBodyMask _CRLF | CheckPoints _CRLF | _CREATEMISSINGBASE _CRLF = { if (SetCreateMissingBase() != 0) { YYABORT; } } | FileInbound _CRLF | _FORCEINTL _CRLF = { if (SetForceINTL() != 0) { YYABORT; } } | Origin _CRLF | IndexFile _CRLF | KillRoutedMessage _CRLF | KludgeMask _CRLF | SKludgeMask _CRLF | PKludgeMask _CRLF | LogFile _CRLF | LogLevel _CRLF | LoopStr _CRLF | Mask _CRLF | SMask _CRLF | PMask _CRLF | MaxAge _CRLF | MaxAttachSize _CRLF | MaxNodelistAge _CRLF | Nodelist _CRLF | NodelistPath _CRLF | _NOLOGIGNORE _CRLF = { if (SetNoLogIgnore() != 0) { YYABORT; } } | Outbound _CRLF | Password _CRLF | ScriptMask _CRLF | SScriptMask _CRLF | PScriptMask _CRLF | _IGNOREBSY _CRLF = { if (SetIgnoreBSY() != 0) { YYABORT; } } | _SETVIAALWAYS _CRLF = { if (SetSetViaAlways() != 0) { YYABORT; } } | _SKIPHIDDENFILES _CRLF = { if (SetSkipHiddenFiles() != 0) { YYABORT; } } | _SOFTCHECKINNODELIST _CRLF = { if (SetSoftCheckInNodelists() != 0) { YYABORT; } } | SysopName _CRLF | TearLine _CRLF | _USENEWVIA _CRLF = { if (SetNewVia() != 0) { YYABORT; } } | _USEOWNZONE _CRLF = { if (SetUseOwnZone() != 0) { YYABORT; } } | _USEASO _CRLF = { if (SetUseASO() != 0) { YYABORT; } } | _STRIPPATHINPKT _CRLF = { if (SetStripPathInPkt() != 0) { YYABORT; } } | Utc _CRLF | TempMail _CRLF | TrafficLog _CRLF | BadMessages _CRLF | ScanDir _CRLF | Semaphore _CRLF | TrafficLogTemplate _CRLF | ScriptFile _CRLF | error _CRLF ={ YYABORT; } = { DetectError = TRUE; } | _CRLF = { avail = 0; } ; ScriptFile : _SCRIPTFILE _STRING ={ if (LoadScriptFile($2) != 0) { YYABORT; } } ; TrafficLogTemplate : _TRAFFICLOGTEMPLATE _STRING ={ if (SetTrafficLogTemplate($2) != 0) { YYABORT; } } ; Semaphore : _SEMAPHORE _DIGIT_ _STRING ={ if (SetSemaphoreName($3, $2) != 0) { YYABORT; } } ; IncludeF : _INCLUDE _STRING ={ $$ = $2; } ; Aka : _AKA ={ cffa.Clean(); } faddress = { cffa1 = cffa; cffa.Clean(); } faddress = { if (SetAka(cffa1, cffa) != 0) { YYABORT; } cffa.Clean(); cffa1.Clean(); } ; TimeStampFile : _TIMESTAMPFILE _STRING = { if (SetTimeStampFile($2) != 0) { YYABORT; } } ; APktDir : _APKTDIR _STRING = { if (SetAPktDir($2) != 0) { YYABORT; } } ; Address : _ADDRESS ={ cffa.Clean(); } faddress = { if (SetMyAddr(cffa) != 0) { YYABORT; } cffa.Clean(); } ; CheckPoints : _CHECKPOINTS ChkPntMode = { SetCheckPoints($2); } ; ChkPntMode : _NEVER ={ $$ = CHECKPNT_NEVER; } | _HARD ={ $$ = CHECKPNT_HARD; } | _SOFT ={ $$ = CHECKPNT_SOFT; } ; KillRoutedMessage : _KILLROUTEDMESSAGE KillRMode = { SetKillRoutedMessages($2); } ; KillRMode : _ALWAYS = { $$ = KILL_ALWAYS; } | _NEVER = { $$ = KILL_NEVER; } | _FLAG = { $$ = KILL_FLAG; } ; SysopName: _SYSOPNAME _STRING = { if (SetSysopName($2) != 0) { YYABORT; } } ; TearLine : _TEARLINE _STRING = { if (SetTearline($2) != 0) { YYABORT; } } ; LogFile : _LOGFILE _STRING = { if (SetLogFile($2) != 0) { YYABORT; } } ; LogLevel : _LOGLEVEL _DIGIT_ = { if (SetLogLevel($2) != 0) { YYABORT; } } ; Origin : _ORIGIN _STRING = { if (SetOrigin($2) != 0) { YYABORT; } } ; Nodelist : _NODELIST _STRING NdlZone = { if (SetNodelist($2,$3) != 0) { YYABORT; } } ; NdlZone : ={ $$ = -3; } | _DIGIT_ ={ $$ = $1; } ; NodelistPath : _NODELISTPATH _STRING = { if (SetNodelistPath($2) != 0) { YYABORT; } } ; IndexFile: _INDEXFILE _STRING = { if (SetIndexFile($2) != 0) { YYABORT; } } ; LoopStr : _LOOPSTR _STRING = { if (SetLoopStr($2) != 0) { YYABORT; } } ; MaxAttachSize : _MAXATTACHSIZE _DIGIT_ = { if (SetMaxAttach($2) != 0) { YYABORT; } } ; MaxNodelistAge : _MAXNODELISTAGE _DIGIT_ = { if (SetMaxNodelistAge($2) != 0) { YYABORT; } } ; Outbound : _OUTBOUND _STRING = { if (SetOutbound($2) != 0) { YYABORT; } } ; TempMail : _TEMPMAIL _STRING = { if (SetTempMail($2) != 0) { YYABORT; } } ; TrafficLog : _TRAFFICLOG _STRING = { if (SetTrafficLog($2) != 0) { YYABORT; } } ; FileInbound : _FILEINBOUND _STRING = { if (SetFileInbound($2) != 0) { YYABORT; } } ; MaxAge : _MAXAGE _DIGIT_ = { if (SetMaxAge($2) != 0) { YYABORT; } cffa.Clean(); } ; Password : _PASSWORD _STRING = { if (strlen($2) > 8){ yyerror("Password too long. Max password length is a 8 characters."); YYABORT; } cffa.Clean(); } faddress = { if (SetPasswd(cffa, $2) != 0) { YYABORT; } cffa.Clean(); } ; BadMessages : _BADMESSAGES BadMsgMode ={ if (SetBadMode($2,FileName) != 0) { YYABORT; } FileName = NULL; } ; BadMsgMode : _SKIP ={ $$ = SKIP; FileName = NULL;} | _EXIT ={ $$ = EXIT; FileName = NULL;} | _DELETE ={ $$ = REMOVE; FileName = NULL;} | _MOVE _STRING ={ $$ = MOVE; FileName = $2;} ; Utc : _UTC UtcOffs ={ if (SetUTC($2) != 0) { YYABORT; } } ; UtcOffs : _DIGIT_ ={ $$ = $1; } | '+' _DIGIT_ ={ $$ = $2; } | '-' _DIGIT_ ={ $$ = -$2; } ; /* ScanDir --------- */ ScanDir : _SCANDIR = { wsd = new ScanDir(); CheckMem((char *)wsd); renumberf = FALSE; unpackf = FALSE; freshf = FALSE; arf = FALSE; brf = FALSE; _TTimes = &wsd->_Times; mbase = NULL; PrevMask = 0; ScriptBefore = NULL; ScriptAfter = NULL; FileName = NULL; } SDType = { wsd->SetBase(mbase); wsd->_Renumber = renumberf; wsd->_Unpack = unpackf; wsd->_Fresh = freshf; wsd->_FlagFile = FileName; wsd->_ScriptBefore = ScriptBefore; wsd->_ScriptAfter = ScriptAfter; ScanDirs.AddToEnd(wsd); if (brf) BeforeRoute = wsd; if (arf) AfterRoute = wsd; } ; SDType : BeforeAfter Flag | _STRING = { mbase = MakeBase($1); if (mbase == NULL) { YYABORT; } if (!mbase->Set($1,BASE_IN)) { delete mbase; mbase = NULL; yyerror("Unable to open message base."); YYABORT; } if (!mbase->CheckIn()) { delete mbase; YYABORT; } } AddSdParam Flag ; BeforeAfter : _BEFOREROUTE = { brf = TRUE; } | _AFTERROUTE = { arf = TRUE; } ; AddSdParam : | AddSdParam SdParam ; SdParam : _RENUMBER = { if (renumberf == TRUE) { yyerror("Renumber for this base already set."); YYABORT; } else { renumberf = TRUE; } } | _BEFORESCRIPT _STRING = { if (ScriptWordExists($2) == FALSE) { yyerror("Script function not found."); YYABORT; } ScriptBefore = strdup($2); } | _AFTERSCRIPT _STRING = { if (ScriptWordExists($2) == FALSE) { yyerror("Script function not found."); YYABORT; } ScriptAfter = strdup($2); } | _FRESH = { if (freshf == TRUE) { yyerror("Fresh scripts for this base already set."); YYABORT; } else { freshf = TRUE; } } | _UNPACK = { if (unpackf == TRUE) { yyerror("Unpack for this base already set."); YYABORT; } else { unpackf = TRUE; } if (Outbound == NULL) { yyerror("Outbound directory not specified."); YYABORT; } } | STime = { if (TimeStampFile == NULL) { yyerror("You can't set scanning time without Timestamp File."); YYABORT; } } ; STime : _DAILY = { tt = new tTimes; tt->_STime = TimeOfBeginOfDay(-1); tt->_ETime = 0; } DaySTime = { if (tt->_STime != 0) { CheckETTime(); _TTimes->AddToEnd(tt); } } | _WEEKLY = { tt = new tTimes; tt->_STime = TimeOfBeginOfDay(0); tt->_ETime = 0; } WeekSTime = { if (tt->_STime != 0) { CheckETTime(); _TTimes->AddToEnd(tt); } } ; DaySTime : | DaySTime DaySSTime = { if (tt->_STime != 0) { CheckETTime(); _TTimes->AddToEnd(tt); tt = new tTimes; } } ; DaySSTime : Time = { tt->_STime = $1 + TimeOfBeginOfDay(-1); } | Time '-' Time = { tt->_STime = $1 + TimeOfBeginOfDay(-1); tt->_ETime = $3 + TimeOfBeginOfDay(-1) + 59; } | AnyP '.' Time ={ time_t i_time; time_t b_time; if ($3 == (time_t) 0) { yyerror("Time of pereodical event should be between 00:01 and 23:59"); YYABORT; } tt->_STime = TimeOfBeginOfDay(-1); b_time = tt->_STime; do { i_time = tt->_STime; CheckETTime(); _TTimes->AddToEnd(tt); tt = new tTimes; tt->_ETime = 0; tt->_STime = i_time + $3; } while (tt->_STime < (b_time + (23*60*60)+(59*60)+60)); tt->_STime = 0; } ; AnyP : 'p' | 'P' ; Time : _DIGIT_ = { if ($1 < 0 || $1 > 23) { yyerror("Hour should be between 00 and 23"); YYABORT; } else { $$ = (time_t) ($1 * 60); } } ':' _DIGIT_ = { if ($4 < 0 || $4 > 59 || $2 == (time_t) -1) { $$ = (time_t)-1; yyerror("Minutes should be between 00 and 59"); YYABORT; } else { $$ = $2 + (time_t) $4; $$ *= 60; } } ; WeekSTime : | WeekSTime WeekSSTime = { CheckETTime(); _TTimes->AddToEnd(tt); tt = new tTimes; } ; WeekSSTime : _DIGIT_ = { if ($1 < 0 || $1 > 6) { yyerror("Day of week should be between 0 and 6"); YYABORT; } else { tt->_STime = TimeOfBeginOfDay($1); } } | _DIGIT_ '-' _DIGIT_ = { if ($1 < 0 || $1 > 6 || $3 < 0 || $3 > 6) { yyerror("Day of week should be between 0 and 6"); YYABORT; } else { tt->_STime = TimeOfBeginOfDay($1); tt->_ETime = TimeOfBeginOfDay($3) + (23*60*60)+(59*60)+59; } } ; Flag : = { FileName = NULL; } | AFlag = { FileName = strdup($1); } ; /* -------------- */ Mask : _MASK ={ MaskMode = 0; } MParam ={ msk->_Type = MASK_NORMAL; AddReadyMask(*(NormalMask *)msk); } ; SMask : _SMASK ={ MaskMode = 0; } MParam ={ msk->_Type = MASK_SKIP; AddReadyMask(*(NormalMask *)msk); } ; PMask : _PMASK ={ MaskMode = 0; } MParam ={ msk->_Type = MASK_ADD; AddReadyMask(*(NormalMask *)msk); } ; MParam : ={ msk = new NormalMask(); CheckMem((char *)msk); msk->_Type = MASK_NORMAL; if (PrepareMask(*msk) != 0) { YYABORT; } } SyName ={ ((NormalMask *)msk)->_FromName = strdup($2); cffa.Clean(); } faddress ={ ((NormalMask *)msk)->_FromAddr = cffa; if (MaskMode == 0) { rc = ((NormalMask *)msk)->_FromAddr.MaskValid(); } else { rc = ((NormalMask *)msk)->_FromAddr.ActValid(); } if (!rc) { yyerror("Invalid 'From' Address."); YYABORT; } } SyName ={ ((NormalMask *)msk)->_ToName = strdup($6); cffa.Clean(); } faddress ={ ((NormalMask *)msk)->_ToAddr = cffa; if (MaskMode == 0) { rc = ((NormalMask *)msk)->_ToAddr.MaskValid(); } else { rc = ((NormalMask *)msk)->_ToAddr.ActValid(); } if (!rc) { yyerror("Invalid 'To' Address."); YYABORT; } if ((((NormalMask *)msk)->_ToAddr.Zone() & (FA_LSTMASK|FA_HOLDMASK|FA_DOWNMASK|FA_PVTMASK|FA_HUBMASK)) && (!Ndl.Enabled())) { yyerror("You can't use '#','H','D','U' or 'P' mask without nodelist."); YYABORT; } if ((((NormalMask *)msk)->_ToAddr.Point() & FA_SUBMASK) && (!Ndl.Enabled())) { yyerror("You can't use '&' mask without nodelist."); YYABORT; } } MString ={ ((NormalMask *)msk)->_Subject = strdup($10); NoTokensF = TRUE; } MsgAttr ={ NoTokensF = FALSE; } ; SyName : _STRING | '$' ={ $$ = "$"; } | '*' ={ $$ = "*"; } | '%' ={ $$ = "%"; } ; MString : _STRING | '*' ={ $$ = "*"; } ; MDigit : MNot _DIGIT_ ={ if ($2 > 65535) { yyerror("Parameter shoul be less that 65535"); YYABORT; } $$ = $1 | $2; } | '*' ={ $$ = -1; } ; MNot : ={ $$ = 0; } | '!' ={ $$ = 0x08000000; } ; MsgAttr : '*' | ={ FlagMode = 1; } MsgFAttr ; MsgFAttr : FlagsMode | MsgFAttr FlagsMode ; FlagsMode : FlagsChar | '+' ={ FlagMode = 1; } FlagsChar | '-' ={ FlagMode = 2; } FlagsChar ; FlagsChar : 'a' ={ ((NormalMask *)msk)->fFileAttach = (FlagMode == 2) ? 2 : 1; } | 'A' ={ /* CheckMaxAttach size*/ if (CheckMaskMode("A") != 0) { YYABORT; } if (((NormalMask *)msk)->sd->_MaxAttachSize == 0 && MaxAttachSize == 0) { yyerror("Not one (global or local) MaxAttachSize is not defined."); YYABORT; } ((NormalMask *)msk)->fMaxAttach = (FlagMode == 2) ? 2 : 1; } | 'b' ={ ((NormalMask *)msk)->fARQ = (FlagMode == 2) ? 2 : 1; } | 'c' ={ ((NormalMask *)msk)->fCrash = (FlagMode == 2) ? 2 : 1; } | 'd' ={ ((NormalMask *)msk)->fDIR = (FlagMode == 2) ? 2 : 1; } | 'e' ={ /* Empty message */ if (CheckMaskMode("e") != 0) { YYABORT; } ((NormalMask *)msk)->fEmpty = (FlagMode == 2) ? 2 : 1; } | 'E' ={ /* Check echomail */ if (CheckMaskMode("E") != 0) { YYABORT; } ((NormalMask *)msk)->fEchomail = (FlagMode == 2) ? 2 : 1; } | 'f' ={ ((NormalMask *)msk)->fFileRequest = (FlagMode == 2) ? 2 : 1; } | 'g' ={ /* Check age */ if (CheckMaskMode("g") != 0) { YYABORT; } if (((NormalMask *)msk)->sd->_MaxAge == 0 && MaxAge == 0) { yyerror("Not one (global or local) MaxAge is not defined."); YYABORT; } ((NormalMask *)msk)->fMaxAge = (FlagMode == 2) ? 2 : 1; } | 'h' ={ ((NormalMask *)msk)->fHold = (FlagMode == 2) ? 2 : 1; } | 'i' ={ ((NormalMask *)msk)->fTransit = (FlagMode == 2) ? 2 : 1; } | 'j' ={ ((NormalMask *)msk)->fKFS = (FlagMode == 2) ? 2 : 1; } | 'k' ={ ((NormalMask *)msk)->fKillSend = (FlagMode == 2) ? 2 : 1; } | 'l' ={ ((NormalMask *)msk)->fLocal = (FlagMode == 2) ? 2 : 1; } | 'L' ={ ((NormalMask *)msk)->fLok = (FlagMode == 2) ? 2 : 1; } | 'm' ={ ((NormalMask *)msk)->fIMM = (FlagMode == 2) ? 2 : 1; } | 'n' ={ ((NormalMask *)msk)->fCFM = (FlagMode == 2) ? 2 : 1; } | 'o' ={ ((NormalMask *)msk)->fOrphan = (FlagMode == 2) ? 2 : 1; } | 'p' ={ ((NormalMask *)msk)->fPrivate = (FlagMode == 2) ? 2 : 1; } | 'q' ={ ((NormalMask *)msk)->fRRQ = (FlagMode == 2) ? 2 : 1; } | 'r' ={ ((NormalMask *)msk)->fReceived = (FlagMode == 2) ? 2 : 1; } | 's' ={ ((NormalMask *)msk)->fSend = (FlagMode == 2) ? 2 : 1; } | 'S' ={ ((NormalMask *)msk)->fAS = (FlagMode == 2) ? 2 : 1; } | 't' ={ ((NormalMask *)msk)->fTFS = (FlagMode == 2) ? 2 : 1; } | 'u' ={ ((NormalMask *)msk)->fFURQ = (FlagMode == 2) ? 2 : 1; } | 'v' ={ ((NormalMask *)msk)->fScanned = (FlagMode == 2) ? 2 : 1; } | 'x' ={ /* Check existing attach */ if (CheckMaskMode("x") != 0) { YYABORT; } ((NormalMask *)msk)->fAttExists = (FlagMode == 2) ? 2 : 1; } | 'y' ={ ((NormalMask *)msk)->fIRR = (FlagMode == 2) ? 2 : 1; } | _DIGIT_ = { if (CheckMaskMode("loop flag") != 0) { YYABORT; } ((NormalMask *)msk)->fLoop = (FlagMode == 2) ? 2 : 1; if (((NormalMask *)msk)->Loops != (unsigned int)-1) { yyerror("Only one loop count should be in mask."); YYABORT; } ((NormalMask *)msk)->Loops = $1; } ; /* -------------- */ KludgeMask : _KLUDGEMASK KMParam ={ msk->_Type = MASK_NORMAL; AddReadyMask(*(KludgeMask *)msk); } ; SKludgeMask : _SKLUDGEMASK KMParam ={ msk->_Type = MASK_SKIP; AddReadyMask(*(KludgeMask *)msk); } ; PKludgeMask : _PKLUDGEMASK KMParam ={ msk->_Type = MASK_ADD; AddReadyMask(*(KludgeMask *)msk); } ; KMParam : ={ msk = new KludgeMask(); CheckMem((char *)msk); msk->_Type = MASK_NORMAL; if (PrepareMask(*msk) != 0) { YYABORT; } } MString MString MDigit ={ ((KludgeMask *)msk)-> _KludgeName = strdup($2); ((KludgeMask *)msk)-> _KludgeBody = strdup($3); ((KludgeMask *)msk)-> _Times = $4; } ; /* -------------- */ BodyMask : _BODYMASK BMParam ={ msk->_Type = MASK_NORMAL; AddReadyMask(*(BodyMask *)msk); } ; SBodyMask : _SBODYMASK BMParam ={ msk->_Type = MASK_SKIP; AddReadyMask(*(BodyMask *)msk); } ; PBodyMask : _PBODYMASK BMParam ={ msk->_Type = MASK_ADD; AddReadyMask(*(BodyMask *)msk); } ; BMParam : ={ msk = new BodyMask(); CheckMem((char *)msk); msk->_Type = MASK_NORMAL; if (PrepareMask(*msk) != 0) { YYABORT; } } MString MDigit MDigit ={ ((BodyMask *)msk)-> _Body = strdup($2); ((BodyMask *)msk)-> _Lines = $3; ((BodyMask *)msk)-> _Bytes = $4; } ; /* -------------- */ ScriptMask : _SCRIPTMASK SCRMParam ={ msk->_Type = MASK_NORMAL; AddReadyMask(*(ScriptMask *)msk); } ; SScriptMask : _SSCRIPTMASK SCRMParam ={ msk->_Type = MASK_SKIP; AddReadyMask(*(ScriptMask *)msk); } ; PScriptMask : _PSCRIPTMASK SCRMParam ={ msk->_Type = MASK_ADD; AddReadyMask(*(ScriptMask *)msk); } ; SCRMParam : ={ msk = new ScriptMask(); CheckMem((char *)msk); msk->_Type = MASK_NORMAL; if (PrepareMask(*msk) != 0) { YYABORT; } } _STRING ={ ((ScriptMask *)msk)->_ScriptName = strdup($2); if (ScriptWordExists($2) != TRUE) { yyerror("Subroutine not found in scripts."); YYABORT; } } ; /* -------------- */ Action : _ACTION ={ if (PrevMask == 0) { yyerror("Action without Mask."); YYABORT; } wsd = ScanDirs.GetLast(); PrevMask = 1; act = new Action(); act->sd = wsd; act->Before = BeforeRoute; act->After = AfterRoute; _TTimes = &act->_Times; } ActionCmd ={ LastDo->AddAction(*act); } MayBeActTime ; MayBeActTime : | '[' STime ']' ; ActionCmd : AAddNote | _DELETE ={ act->_Act = ACT_DELETE; } | AMove | ACopy | ARewrite | _IGNORE ={ act->_Act = ACT_IGNORE; } | ADisplay | AAFlag | ADelFile | ANewMsg | AWriteFile | AAppendToFile | ACall | ARoute | APoll | _DELETEATTACH ={ act->_Act = ACT_DELETEATTACH; } | AChangePath | AMoveAttach | ACopyAttach | ASplit | ARecode | AScript ; AAddNote : _ADDNOTE _STRING ={ act->_Act = ACT_ADDNOTE; act->_Tpl = new Template(); if (!act->_Tpl->Set($2)) { yyerror("Template file is not accesible."); delete act->_Tpl; act->_Tpl = NULL; YYABORT; } act->_Tpl->sd = ScanDirs.GetLast(); } ; AMove : _MOVE _STRING ={ act->_Act = ACT_MOVE; act->_Base = MakeBase($2); if (act->_Base == NULL) { YYABORT; } if (!act->_Base->Set($2,BASE_OUT)) { yyerror("Invalid message base name."); delete act->_Base; act->_Base = NULL; YYABORT; } if (!act->_Base->CheckOut()) { delete act->_Base; act->_Base = NULL; YYABORT; } act->_Base->Rewind(); } ; ACopy : _COPY _STRING ={ act->_Act = ACT_COPY; act->_Base = MakeBase($2); if (act->_Base == NULL) { YYABORT; } if (!act->_Base->Set($2,BASE_OUT)) { yyerror("Invalid message base name."); delete act->_Base; act->_Base = NULL; YYABORT; } if (!act->_Base->CheckOut()) { delete act->_Base; act->_Base = NULL; YYABORT; } act->_Base->Rewind(); } ; ARewrite : _REWRITE ={ MaskMode = 1; act->_Act = ACT_REWRITE; } MParam ={ act->_Mask = msk; } ; ADisplay : _DISPLAY _STRING ={ act->_Act = ACT_DISPLAY; act->_TplName = strdup($2); } ; AScript : _ASCRIPT _STRING ={ act->_Act = ACT_SCRIPT; if (ScriptWordExists($2) == FALSE) { yyerror("Script function not found."); YYABORT; } act->_TplName = strdup($2); } ; AAFlag : AFlag ={ act->_Act = ACT_FLAG; act->_OutDir = strdup($1); } ; AFlag : _FLAG _STRING = { $$ = $2; } ; ADelFile : _DELFILE _STRING ={ act->_Act = ACT_DELFILE; act->_OutDir = strdup($2); } ; ANewMsg : _NEWMSG ={ MaskMode = 1; act->_Act = ACT_NEWMSG; } _STRING _STRING MParam ={ act->_Tpl = new Template(); if (!act->_Tpl->Set($3)) { yyerror("Template file is not accesible."); delete act->_Tpl; act->_Tpl = NULL; delete msk; msk = NULL; YYABORT; } act->_Tpl->sd = ScanDirs.GetLast(); act->_Base = MakeBase($4); if (act->_Base == NULL || !act->_Base->Set($4,BASE_OUT)) { yyerror("Invalid message base name."); delete act->_Tpl; act->_Tpl = NULL; delete msk; msk = NULL; delete act->_Base; act->_Base = NULL; YYABORT; } if (!act->_Base->CheckOut()) { delete act->_Tpl; act->_Tpl = NULL; delete msk; msk = NULL; delete act->_Base; act->_Base = NULL; YYABORT; } act->_Base->Rewind(); act->_Mask = msk; } ; AWriteFile : _WRITEFILE _STRING _STRING ={ act->_Act = ACT_WRITEFILE; act->_Tpl = new Template(); if (!act->_Tpl->Set($2)) { yyerror("Template file is not accesible."); delete act->_Tpl; act->_Tpl = NULL; YYABORT; } act->_Tpl->sd = ScanDirs.GetLast(); act->_OutDir = strdup($3); } ; AAppendToFile : _APPENDTOFILE _STRING _STRING ={ act->_Act = ACT_ADDFILE; act->_Tpl = new Template(); if (!act->_Tpl->Set($2)) { yyerror("Template file is not accesible."); delete act->_Tpl; act->_Tpl = NULL; YYABORT; } act->_Tpl->sd = ScanDirs.GetLast(); act->_OutDir = strdup($3); } ; ACall : _CALL _STRING _STRING _STRING ={ act->_Act = ACT_CALL; act->_Tpl = new Template(); if (!act->_Tpl->Set($2)) { yyerror("Template file is not accesible."); delete act->_Tpl; act->_Tpl = NULL; YYABORT; } act->_Tpl->sd = ScanDirs.GetLast(); act->_OutDir = strdup($3); act->_TplName = strdup($4); } | _CALL _STRING ={ act->_Act = ACT_CALL; act->_TplName = strdup($2); } ; ARoute : _ROUTE RouMode ={ cffa.Clean(); } faddress ={ act->_Act = ACT_ROUTE; if (act->sd == act->Before|| act->sd == act->After) { yyerror("You can not use the Action Route in 'ScanDir: @AfterRoute|@BeforeRoute'"); YYABORT; } act->_Flav = $2; act->_f = cffa; if (act->_f.Point() & FA_NOTDEF) { act->_f.Point(0); } if (!act->_f.RouValid()) { yyerror("Invalid routing address."); YYABORT; } } ; RouMode : _HOLD ={ $$ = F_HOLD; } | _CRASH ={ $$ = F_CRASH; } | _DIRECT ={ $$ = F_DIRECT; } | _NORMAL ={ $$ = F_NORMAL; } ; APoll : _POLL RouMode ={ cffa.Clean(); } faddress ={ act->_Act = ACT_POLL; act->_Flav = $2; act->_f = cffa; if (act->_f.Point() & FA_NOTDEF) { act->_f.Point(0); } if (!act->_f.RouValid()) { yyerror("Invalid poll address."); YYABORT; } } ; AChangePath : _CHANGEPATH _STRING ={ act->_Act = ACT_CHANGEPATH; if (strlen($2) > 72) { yyerror("New path too long"); YYABORT; } act->_OutDir = strdup($2); } ; AMoveAttach : _MOVEATTACH _STRING ={ act->_Act = ACT_MOVEATTACH; if (!DirExists($2)) { yyerror("Target directory not found."); YYABORT; } if (strlen($2) > 72) { yyerror("New path too long"); YYABORT; } act->_OutDir = strdup($2); } ; ACopyAttach : _COPYATTACH _STRING ={ act->_Act = ACT_COPYATTACH; if (!DirExists($2)) { yyerror("Target directory not found."); YYABORT; } act->_OutDir = strdup($2); } ; ASplit : _SPLIT _DIGIT_ ={ act->_Act = ACT_SPLIT; if ($2 < 1 || $2 > 65535) { yyerror("Parameter 'Lines' should be positive integer between 1 and 65535"); YYABORT; } act->_Lines = $2; } ; ARecode : _RECODE _STRING ={ FILE *fp = NULL; char buf[512],*p,*q; int in,on,count; int line = 0; act->_Act = ACT_RECODE; fp = fopen($2,"r"); if (fp == NULL) { yyerror("Unable to open file"); YYABORT; } act->_TplName = (char *)malloc(256); CheckMem(act->_TplName); for (count = 0; count < 256; count++) act->_TplName[count] = (char) count; count = 0; line = 0; while (fgets((char*)buf,sizeof(buf),fp)) { line++; p = strtok((char*)buf," \t\n#"); q = strtok(NULL," \t\n#"); if (p != NULL && q != NULL) { in = ctoi((char *)p); if (in > 255) { sprintf(buf, "%s: Error in line %d.", $2, line); yyerror(buf); fclose(fp); free(act->_TplName); YYABORT; } on=ctoi((char *)q); if (in != 0 && on != 0) { if (count++ < 256 ) { act->_TplName[in]=on; } else { sprintf(buf,"Char map table \"%s\" is big",$2); yyerror(buf); fclose(fp); free(act->_TplName); YYABORT; } } } /* if */ } /* While */ fclose(fp); } ; /* -------------- */ faddress : FullFtnAddr | '!' FullFtnAddr = { cffa.Zone(cffa.Zone() | FA_NOTMASK); } ; FullFtnAddr : nodeaddr | pointaddr | '*' = { cffa.Zone(FA_ANYMASK); cffa.Net(FA_ANYMASK); cffa.Node(FA_ANYMASK); cffa.Point(FA_ANYMASK); } | '#' = { cffa.Zone(FA_LSTMASK); cffa.Net(FA_LSTMASK); cffa.Node(FA_LSTMASK); cffa.Point(FA_LSTMASK); } | 'H' = { cffa.Zone(FA_HOLDMASK); cffa.Net(FA_HOLDMASK); cffa.Node(FA_HOLDMASK); cffa.Point(FA_HOLDMASK); } | 'U' = { cffa.Zone(FA_HUBMASK); cffa.Net(FA_HUBMASK); cffa.Node(FA_HUBMASK); cffa.Point(FA_HUBMASK); } | 'D' = { cffa.Zone(FA_DOWNMASK); cffa.Net(FA_DOWNMASK); cffa.Node(FA_DOWNMASK); cffa.Point(FA_DOWNMASK); } | 'P' = { cffa.Zone(FA_PVTMASK); cffa.Net(FA_PVTMASK); cffa.Node(FA_PVTMASK); cffa.Point(FA_PVTMASK); } | '@' = { cffa.Zone(FA_OURMASK); cffa.Net(FA_OURMASK); cffa.Node(FA_OURMASK); cffa.Point(FA_OURMASK); } | '$' = { cffa.Zone(FA_FROMMASK); cffa.Net(FA_FROMMASK); cffa.Node(FA_FROMMASK); cffa.Point(FA_FROMMASK); } | '%' = { cffa.Zone(FA_TOMASK); cffa.Net(FA_TOMASK); cffa.Node(FA_TOMASK); cffa.Point(FA_TOMASK); } | '%' '.' _DIGIT_ = { if ($3 != 0) { yyerror("parse error"); YYABORT; } cffa.Zone(FA_TOMASK); cffa.Net(FA_TOMASK); cffa.Node(FA_TOMASK); cffa.Point(0); } ; pointaddr: nodeaddr '.' PntAddr ; PntAddr : dw = { cffa.Point($1); } | '&' = { cffa.Point(FA_SUBMASK); } ; nodeaddr : dw ':' dw '/' dw = { cffa.Zone($1); cffa.Net($3); cffa.Node($5); cffa.Point(0); } ; dw : _DIGIT_ = { $$ = $1; } | '*' = { $$ = FA_ANYMASK; } ; %%