1
2 %{
3
4 /*
5 * RNtrack - FTN message tracker/router
6 *
7 * cfg.(y|hpp|cpp) - Config file parser
8 *
9 * Copyright (c) 2003-2005 Alex Soukhotine, 2:5030/1157
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * $Id: cfg.y,v 1.6 2005/06/22 22:18:14 ph0enix Exp $
17 */
18
19 #define YYDEBUG 0
20 /* #define YYERROR_VERBOSE */
21 #ifdef HAVE_CONFIG_H
22 # include "aconfig.h"
23 #endif
24
25 #include <stdlib.h>
26 #ifdef HAVE_MALLOC_H
27 #include <malloc.h>
28 #endif
29 #include "msg.hpp"
30 #include "outbound.hpp"
31 #include "fidoaddr.hpp"
32 #include "vars.hpp"
33 #include "configure.hpp"
34 #include "constant.hpp"
35 #include "log.hpp"
36 #include "aka.hpp"
37 #include "age.hpp"
38 #include "scandir.hpp"
39 #include "attach.hpp"
40 #include "badpkt.hpp"
41 #include "badmsg.hpp"
42 #include "domain.hpp"
43 #include "filebox.hpp"
44 #include "passwd.hpp"
45 #include "nodelist.hpp"
46 #include "script.hpp"
47
48 #undef YYSTYPE /* Perl also uses bison? damn! */
49
50 extern int DetectError;
51 extern bool NoTokensF;
52
53 extern FA cffa;
54 extern FA cffa1;
55 extern FA cffa2;
56
57 static int brf = FALSE, arf = FALSE, renumberf = FALSE, unpackf = FALSE, freshf = FALSE;
58 static ScanDir *wsd = NULL;
59 static char *FileName = NULL;
60 static char *BPktDir = NULL;
61 static char *ScriptBefore = NULL;
62 static char *ScriptAfter = NULL;
63 static tTimes *tt;
64 static IndBiList<tTimes> *_TTimes;
65 static MSGBASE *mbase;
66 static Mask *msk = NULL;
67 static int MaskMode;
68 static int rc;
69 static int FlagMode = 0;
70 static Action *act = NULL;
71
CheckETTime(void)72 static void CheckETTime(void) {
73 time_t tmt;
74 if (tt->_ETime != 0 && tt->_ETime < tt->_STime) {
75 tmt = tt->_ETime;
76 tt->_ETime = (23*60*60)+(59*60)+59;
77 tt->_ETime += TimeOfBeginOfDay(-1);
78 _TTimes->AddToEnd(tt);
79 tt = new tTimes;
80 tt->_STime = TimeOfBeginOfDay(-1);
81 tt->_ETime = tmt;
82 }
83 }
84
PrepareMask(Mask & m)85 static int PrepareMask(Mask &m) {
86 ScanDir *sd;
87 char ErrMess[128];
88
89 CHP = 23700;
90 sd = ScanDirs.GetLast();
91 if (sd == NULL) {
92 strcpy(ErrMess,"'");
93 strcat(ErrMess,m.MaskName());
94 strcat(ErrMess,":' without 'ScanDir:'");
95 yyerror(ErrMess);
96 return -1;
97 }
98 m.sd = sd;
99 return 0;
100 }
101
AddReadyMask(Mask & m)102 static void AddReadyMask(Mask &m) {
103 ScanDir *sd;
104
105 switch (PrevMask) {
106 case 0: // first mask.
107 case 1: // after action.
108 LastDo = new DoList();
109 sd = ScanDirs.GetLast();
110 sd->_DoLists.AddToEnd(LastDo);
111 PrevMask = 2;
112 break;
113 case 2: // after MASK.
114 break;
115 }
116 LastDo->AddMask(m);
117 }
118
119
CheckMaskMode(char * f)120 static int CheckMaskMode(char *f) {
121 char Buff[128];
122 if (MaskMode != 0) {
123 strcpy(Buff,"You can use '");
124 strcat(Buff,f);
125 strcat(Buff,"' flag only in 'Mask:'.");
126 yyerror(Buff);
127 return -1;
128 }
129 return 0;
130 }
131
132
ctoi(char * s)133 static int ctoi(char *s) {
134 char *foo;
135 int res = 0;
136
137 res = strtoul(s, &foo, 0);
138 if (*foo) /* parse error */
139 return 0;
140 return res;
141 }
142
143
144
145 %}
146
147 %union {
148 int in;
149 char *ch;
150 long ln;
151 KillModeT kmode;
152 CheckPointsT pmode;
153 tBadMsgMode bmode;
154 tBadMsgMode bpmode;
155 fileboxType fbtype;
156 time_t t;
157 PKTMode pktmode;
158 };
159
160
161
162 %token _LOGFILE _LOGLEVEL _NODELIST _INDEXFILE _NODELISTPATH
163 _ADDRESS _SYSOPNAME _USEOWNZONE _FORCEINTL _LOOPSTR
164 _SCANDIR _MASK _SMASK _PMASK _BODYMASK
165 _SBODYMASK _PBODYMASK _KLUDGEMASK _SKLUDGEMASK _PKLUDGEMASK
166 _ACTION _MAXAGE _BADMESSAGES _NOLOGIGNORE _AKA
167 _SKIPHIDDENFILES _FILEINBOUND _OUTBOUND _ADDTONULLPKT _TEMPMAIL
168 _TRAFFICLOG _PASSWORD _UTC _ORIGIN _TEARLINE
169 _INCLUDE _APKTDIR _CHECKPOINTS _SETVIAALWAYS _FRESH
170 _CREATEMISSINGBASE _USENEWVIA _SCRIPTMASK _SSCRIPTMASK _PSCRIPTMASK
171 _MAXATTACHSIZE _SEMAPHORE _SCRIPTFILE _USEASO _USEBRAKE _FILEBOXDIR
172 _KILLROUTEDMESSAGE _IGNOREBSY _AFTERSCRIPT _BEFORESCRIPT _AGEFROMVIA
173 _MAXNODELISTAGE _USEFILEBOXES _FILEBOXTYPE _LONG _TMLONG _TMSHORT _BRAKE
174 _SOFTCHECKINNODELIST _BADPACKETS _IGNOREATTACHPATH _MAXPKTSIZE _MAXMSGSIZE
175 _TIMESTAMPFILE _DOMAIN_ _FILEBOX
176 _TRAFFICLOGTEMPLATE
177 _STRIPPATHINPKT
178
179 _CRLF _SKIP _DELETE _EXIT _MOVE __EOF
180 _STRING _BEFOREROUTE _AFTERROUTE
181 _DIGIT_
182 _RENUMBER _UNPACK _DAILY _WEEKLY _FLAG
183 _NEVER _HARD _SOFT _ALWAYS
184 /* Actions */
185 _ADDNOTE _COPY _REWRITE _IGNORE _DISPLAY _DELFILE _NEWMSG _WRITEFILE
186 _APPENDTOFILE _CALL _ROUTE _ROUTEFBOX _ROUTEHUB _POLL _DELETEATTACH _CHANGEPATH _MOVEATTACH
187 _ASCRIPT _TOLOWERPATH _TOUPPERPATH _COPYATTACHFBOX _MOVEATTACHFBOX
188 _COPYATTACH _SPLIT _RECODE _ADDKLUDGE _HOLD _CRASH _DIRECT _NORMAL _IMMEDIATE
189 LEXERR
190
191 %start Conf
192
193 %%
194
195 Conf : /* empty */
196 | Conf ConfLine
197 ;
198
199
200 ConfLine : Action _CRLF
201 | IncludeF _CRLF {
202 if (SetInclude($<ch>1) != 0) {
203 YYABORT;
204 }
205 }
206 | TimeStampFile _CRLF
207 | Address _CRLF
208 | _ADDTONULLPKT _CRLF
209 {
210 if (SetAddToNullPkt() != 0) {
211 YYABORT;
212 }
213 }
214 | Aka _CRLF
215 | APktDir _CRLF
216 | BodyMask _CRLF
217 | SBodyMask _CRLF
218 | PBodyMask _CRLF
219 | CheckPoints _CRLF
220 | _CREATEMISSINGBASE _CRLF
221 {
222 if (SetCreateMissingBase() != 0) {
223 YYABORT;
224 }
225 }
226 | FileInbound _CRLF
227 | _FORCEINTL _CRLF
228 {
229 if (SetForceINTL() != 0) {
230 YYABORT;
231 }
232 }
233 | Origin _CRLF
234 | IndexFile _CRLF
235 | KillRoutedMessage _CRLF
236 | KludgeMask _CRLF
237 | SKludgeMask _CRLF
238 | PKludgeMask _CRLF
239 | LogFile _CRLF
240 | LogLevel _CRLF
241 | LoopStr _CRLF
242 | Mask _CRLF
243 | SMask _CRLF
244 | PMask _CRLF
245 | MaxAge _CRLF
246 | MaxAttachSize _CRLF
247 | MaxMsgSize _CRLF
248 | MaxPktSize _CRLF
249 | MaxNodelistAge _CRLF
250 | Nodelist _CRLF
251 | NodelistPath _CRLF
252 | _NOLOGIGNORE _CRLF
253 {
254 if (SetNoLogIgnore() != 0) {
255 YYABORT;
256 }
257 }
258 | Outbound _CRLF
259 | Password _CRLF
260 | Domain _CRLF
261 | FileBox _CRLF
262 | ScriptMask _CRLF
263 | SScriptMask _CRLF
264 | PScriptMask _CRLF
265 | _IGNOREBSY _CRLF
266 {
267 if (SetIgnoreBSY() != 0) {
268 YYABORT;
269 }
270 }
271 | _IGNOREATTACHPATH _CRLF
272 {
273 if (SetIgnoreAttachPath() != 0) {
274 YYABORT;
275 }
276 }
277 | _SETVIAALWAYS _CRLF
278 {
279 if (SetSetViaAlways() != 0) {
280 YYABORT;
281 }
282 }
283 | _SKIPHIDDENFILES _CRLF
284 {
285 if (SetSkipHiddenFiles() != 0) {
286 YYABORT;
287 }
288 }
289 | _SOFTCHECKINNODELIST _CRLF
290 {
291 if (SetSoftCheckInNodelists() != 0) {
292 YYABORT;
293 }
294 }
295 | SysopName _CRLF
296 | TearLine _CRLF
297 | _USENEWVIA _CRLF
298 {
299 if (SetNewVia() != 0) {
300 YYABORT;
301 }
302 }
303 | _USEOWNZONE _CRLF
304 {
305 if (SetUseOwnZone() != 0) {
306 YYABORT;
307 }
308 }
309 | _USEASO _CRLF
310 {
311 if (SetUseASO() != 0) {
312 YYABORT;
313 }
314 }
315 | _USEBRAKE _CRLF
316 {
317 if (SetUseBrake() != 0) {
318 YYABORT;
319 }
320 }
321 | _USEFILEBOXES _CRLF
322 {
323 if (SetUseFileBoxes() != 0) {
324 YYABORT;
325 }
326 }
327 | _STRIPPATHINPKT _CRLF
328 {
329 if (SetStripPathInPkt() != 0) {
330 YYABORT;
331 }
332 }
333 | _AGEFROMVIA _CRLF
334 {
335 if (SetAgeFromVia() != 0) {
336 YYABORT;
337 }
338 }
339 | Utc _CRLF
340 | TempMail _CRLF
341 | TrafficLog _CRLF
342 | BadMessages _CRLF
343 | BadPackets _CRLF
344 | ScanDir _CRLF
345 | Semaphore _CRLF
346 | TrafficLogTemplate _CRLF
347 | ScriptFile _CRLF
348 | FileBoxDir _CRLF
349 | FileBoxType _CRLF
350 | error _CRLF { YYABORT; }
351 { DetectError = TRUE;
352 }
353 | _CRLF
354 {
355 avail = 0;
356 }
357 ;
358
359 ScriptFile : _SCRIPTFILE _STRING {
360 if (LoadScriptFile($<ch>2) != 0) {
361 YYABORT;
362 }
363 }
364 ;
365
366 FileBoxDir : _FILEBOXDIR _STRING {
367 if (SetFileBoxDir($<ch>2) != 0) {
368 YYABORT;
369 }
370 }
371 ;
372
373 FileBoxType: _FILEBOXTYPE FBOXTYPE
374 {
375 if (SetFileBoxType($<fbtype>2) != 0) {
376 YYABORT;
377 }
378 }
379 ;
380 FBOXTYPE : _LONG { $<fbtype>$ = FILEBOXLONG}
381 | _TMLONG { $<fbtype>$ = FILEBOXTMLONG }
382 | _TMSHORT { $<fbtype>$ = FILEBOXTMSHORT }
383 | _BRAKE { $<fbtype>$ = FILEBOXBRAKE }
384 ;
385
386
387 TrafficLogTemplate : _TRAFFICLOGTEMPLATE _STRING {
388 if (SetTrafficLogTemplate($<ch>2) != 0) {
389 YYABORT;
390 }
391 }
392 ;
393
394 Semaphore : _SEMAPHORE _DIGIT_ _STRING {
395 if (SetSemaphoreName($<ch>3, $<ln>2) != 0) {
396 YYABORT;
397 }
398 }
399 ;
400
401
402 IncludeF : _INCLUDE _STRING { $<ch>$ = $<ch>2; }
403 ;
404
405 Aka : _AKA { cffa.Clean(); } faddress { cffa1 = cffa; cffa.Clean(); } faddress
406 {
407 if (SetAka(cffa1, cffa) != 0) {
408 YYABORT;
409 }
410 cffa.Clean();
411 cffa1.Clean();
412 }
413 ;
414
415 TimeStampFile : _TIMESTAMPFILE _STRING
416 {
417 if (SetTimeStampFile($<ch>2) != 0) {
418 YYABORT;
419 }
420 }
421 ;
422
423 APktDir : _APKTDIR _STRING
424 {
425 if (SetAPktDir($<ch>2) != 0) {
426 YYABORT;
427 }
428 }
429 ;
430
431 Address : _ADDRESS { cffa.Clean(); } faddress
432 {
433 if (SetMyAddr(cffa) != 0) {
434 YYABORT;
435 }
436 cffa.Clean();
437 }
438 ;
439
440 CheckPoints : _CHECKPOINTS ChkPntMode { SetCheckPoints($<pmode>2); }
441 ;
442
443 ChkPntMode : _NEVER { $<pmode>$ = CHECKPNT_NEVER; }
444 | _HARD { $<pmode>$ = CHECKPNT_HARD; }
445 | _SOFT { $<pmode>$ = CHECKPNT_SOFT; }
446 ;
447
448 KillRoutedMessage : _KILLROUTEDMESSAGE KillRMode { SetKillRoutedMessages($<kmode>2); }
449 ;
450
451 KillRMode : _ALWAYS { $<kmode>$ = KILL_ALWAYS; }
452 | _NEVER { $<kmode>$ = KILL_NEVER; }
453 | _FLAG { $<kmode>$ = KILL_FLAG; }
454 ;
455
456 SysopName: _SYSOPNAME _STRING
457 {
458 if (SetSysopName($<ch>2) != 0) {
459 YYABORT;
460 }
461 }
462 ;
463
464 TearLine : _TEARLINE _STRING
465 {
466 if (SetTearline($<ch>2) != 0) {
467 YYABORT;
468 }
469 }
470 ;
471
472 LogFile : _LOGFILE _STRING
473 {
474 if (SetLogFile($<ch>2) != 0) {
475 YYABORT;
476 }
477 }
478 ;
479
480 LogLevel : _LOGLEVEL _DIGIT_
481 {
482 if (SetLogLevel($<ln>2) != 0) {
483 YYABORT;
484 }
485 }
486 ;
487
488 Origin : _ORIGIN _STRING
489 {
490 if (SetOrigin($<ch>2) != 0) {
491 YYABORT;
492 }
493 }
494 ;
495
496 Nodelist : _NODELIST _STRING NdlZone
497 {
498 if (SetNodelist($<ch>2,$<ln>3) != 0) {
499 YYABORT;
500 }
501 }
502 ;
503
504 NdlZone : { $<ln>$ = -3; }
505 | _DIGIT_ { $<ln>$ = $<ln>1; }
506 ;
507
508 NodelistPath : _NODELISTPATH _STRING
509 {
510 if (SetNodelistPath($<ch>2) != 0) {
511 YYABORT;
512 }
513 }
514 ;
515
516 IndexFile: _INDEXFILE _STRING
517 {
518 if (SetIndexFile($<ch>2) != 0) {
519 YYABORT;
520 }
521 }
522 ;
523
524 LoopStr : _LOOPSTR _STRING
525 {
526 if (SetLoopStr($<ch>2) != 0) {
527 YYABORT;
528 }
529 }
530 ;
531
532 MaxAttachSize : _MAXATTACHSIZE _DIGIT_
533 {
534 if (SetMaxAttach($<ln>2) != 0) {
535 YYABORT;
536 }
537 }
538 ;
539
540 MaxNodelistAge : _MAXNODELISTAGE _DIGIT_
541 {
542 if (SetMaxNodelistAge($<ln>2) != 0) {
543 YYABORT;
544 }
545 }
546 ;
547
548 Outbound : _OUTBOUND _STRING
549 {
550 if (SetOutbound($<ch>2) != 0) {
551 YYABORT;
552 }
553 }
554 ;
555
556 TempMail : _TEMPMAIL _STRING
557 {
558 if (SetTempMail($<ch>2) != 0) {
559 YYABORT;
560 }
561 }
562 ;
563
564 TrafficLog : _TRAFFICLOG _STRING
565 {
566 if (SetTrafficLog($<ch>2) != 0) {
567 YYABORT;
568 }
569 }
570 ;
571
572 FileInbound : _FILEINBOUND _STRING
573 {
574 if (SetFileInbound($<ch>2) != 0) {
575 YYABORT;
576 }
577 }
578 ;
579
580 MaxAge : _MAXAGE _DIGIT_
581 {
582 if (SetMaxAge($<ln>2) != 0) {
583 YYABORT;
584 }
585 cffa.Clean();
586 }
587 ;
588
589 MaxMsgSize : _MAXMSGSIZE _DIGIT_
590 {
591 if (SetMaxMsgSize($<ln>2) != 0) {
592 YYABORT;
593 }
594 cffa.Clean();
595 }
596 ;
597
598 MaxPktSize : _MAXPKTSIZE _DIGIT_
599 {
600 if (SetMaxPktSize($<ln>2) != 0) {
601 YYABORT;
602 }
603 cffa.Clean();
604 }
605 ;
606
607 Password : _PASSWORD _STRING
608 {
609 if (strlen($<ch>2) > 8){
610 yyerror("Password too long. Max password length is a 8 characters.");
611 YYABORT;
612 }
613 cffa.Clean();
614 }
615 faddress
616 {
617 if (SetPasswd(cffa, $<ch>2) != 0) {
618 YYABORT;
619 }
620 cffa.Clean();
621 }
622 ;
623
624 Domain : _DOMAIN_ _STRING
625 {
626 if (strlen($<ch>2) > 10){
627 yyerror("Domain too long. Max domain length is a 10 characters.");
628 YYABORT;
629 }
630 cffa.Clean();
631 }
632 faddress
633 {
634 if (SetDomain(cffa, $<ch>2) != 0) {
635 YYABORT;
636 }
637 cffa.Clean();
638 }
639 ;
640
641 FileBox : _FILEBOX _STRING
642 {
643 if (strlen($<ch>2) > 100){
644 yyerror("Path too long. Max path length is a 100 characters.");
645 YYABORT;
646 }
647 cffa.Clean();
648 }
649 faddress
650 {
651 if (SetFilebox(cffa, $<ch>2) != 0) {
652 YYABORT;
653 }
654 cffa.Clean();
655 }
656 ;
657
658
659 BadMessages : _BADMESSAGES BadMsgMode
660 {
661 if (SetBadMode($<bmode>2,FileName) != 0) {
662 YYABORT;
663 }
664 FileName = NULL;
665 }
666 ;
667 BadMsgMode : _SKIP { $<bmode>$ = SKIP; FileName = NULL;}
668 | _EXIT { $<bmode>$ = EXIT; FileName = NULL;}
669 | _DELETE { $<bmode>$ = REMOVE; FileName = NULL;}
670 | _MOVE _STRING { $<bmode>$ = MOVE; FileName = $<ch>2;}
671 ;
672
673 BadPackets : _BADPACKETS BadPktMode
674 {
675 if (SetBadPktMode($<bpmode>2,BPktDir) != 0) {
676 YYABORT;
677 }
678 BPktDir = NULL;
679 }
680 ;
681 BadPktMode : _SKIP { $<bpmode>$ = SKIP; BPktDir = NULL;}
682 | _EXIT { $<bpmode>$ = EXIT; BPktDir = NULL;}
683 | _DELETE { $<bpmode>$ = REMOVE; BPktDir = NULL;}
684 | _MOVE _STRING { $<bpmode>$ = MOVE; BPktDir = $<ch>2;}
685 ;
686
687 Utc : _UTC UtcOffs
688 {
689 if (SetUTC($<ln>2) != 0) {
690 YYABORT;
691 }
692 }
693 ;
694
695 UtcOffs : _DIGIT_ { $<ln>$ = $<ln>1; }
696 | '+' _DIGIT_ { $<ln>$ = $<ln>2; }
697 | '-' _DIGIT_ { $<ln>$ = -$<ln>2; }
698 ;
699
700 /* ScanDir --------- */
701
702 ScanDir : _SCANDIR
703 {
704 wsd = new ScanDir();
705 CheckMem((char *)wsd);
706 renumberf = FALSE;
707 unpackf = FALSE;
708 freshf = FALSE;
709 arf = FALSE;
710 brf = FALSE;
711 _TTimes = &wsd->_Times;
712 mbase = NULL;
713 PrevMask = 0;
714 ScriptBefore = NULL;
715 ScriptAfter = NULL;
716 FileName = NULL;
717 }
718 SDType
719 {
720 wsd->SetBase(mbase);
721 wsd->_Renumber = renumberf;
722 wsd->_Unpack = unpackf;
723 wsd->_Fresh = freshf;
724 wsd->_FlagFile = FileName;
725 wsd->_ScriptBefore = ScriptBefore;
726 wsd->_ScriptAfter = ScriptAfter;
727 ScanDirs.AddToEnd(wsd);
728 if (brf) BeforeRoute = wsd;
729 if (arf) AfterRoute = wsd;
730 }
731 ;
732
733 SDType : BeforeAfter Flag
734 | _STRING
735 {
736 mbase = MakeBase($<ch>1);
737 if (mbase == NULL) {
738 YYABORT;
739 }
740 if (!mbase->Set($<ch>1,BASE_IN)) {
741 delete mbase;
742 mbase = NULL;
743 yyerror("Unable to open message base.");
744 YYABORT;
745 }
746 if (!mbase->CheckIn()) {
747 delete mbase;
748 YYABORT;
749 }
750 }
751 AddSdParam Flag
752 ;
753
754 BeforeAfter : _BEFOREROUTE { brf = TRUE; }
755 | _AFTERROUTE { arf = TRUE; }
756 ;
757
758 AddSdParam :
759 | AddSdParam SdParam
760 ;
761
762 SdParam : _RENUMBER
763 {
764 if (renumberf == TRUE) {
765 yyerror("Renumber for this base already set.");
766 YYABORT;
767 } else {
768 renumberf = TRUE;
769 }
770 }
771 | _BEFORESCRIPT _STRING
772 {
773 if (!ScriptWordExists($<ch>2)) {
774 yyerror("Script function not found.");
775 YYABORT;
776 }
777 ScriptBefore = strdup($<ch>2);
778 }
779 | _AFTERSCRIPT _STRING
780 {
781 if (!ScriptWordExists($<ch>2)) {
782 yyerror("Script function not found.");
783 YYABORT;
784 }
785 ScriptAfter = strdup($<ch>2);
786 }
787 | _FRESH
788 {
789 if (freshf == TRUE) {
790 yyerror("Fresh scripts for this base already set.");
791 YYABORT;
792 } else {
793 freshf = TRUE;
794 }
795 }
796 | _UNPACK
797 {
798 if (unpackf == TRUE) {
799 yyerror("Unpack for this base already set.");
800 YYABORT;
801 } else {
802 unpackf = TRUE;
803 }
804 if (Outbound == NULL) {
805 yyerror("Outbound directory not specified.");
806 YYABORT;
807 }
808 }
809 | STime
810 {
811 if (TimeStampFile == NULL) {
812 yyerror("You can't set scanning time without Timestamp File.");
813 YYABORT;
814 }
815
816 }
817 ;
818
819 STime : _DAILY
820 {
821 tt = new tTimes;
822 tt->_STime = TimeOfBeginOfDay(-1);
823 tt->_ETime = 0;
824 }
825 DaySTime
826 {
827 if (tt->_STime != 0) {
828 CheckETTime();
829 _TTimes->AddToEnd(tt);
830 }
831 }
832 | _WEEKLY
833 {
834 tt = new tTimes;
835 tt->_STime = TimeOfBeginOfDay(0);
836 tt->_ETime = 0;
837 }
838 WeekSTime
839 {
840 if (tt->_STime != 0) {
841 CheckETTime();
842 _TTimes->AddToEnd(tt);
843 }
844 }
845 ;
846
847 DaySTime :
848 | DaySTime DaySSTime
849 {
850 if (tt->_STime != 0) {
851 CheckETTime();
852 _TTimes->AddToEnd(tt);
853 tt = new tTimes;
854 }
855 }
856 ;
857
858 DaySSTime : Time
859 {
860 tt->_STime = $<t>1 + TimeOfBeginOfDay(-1);
861 }
862 | Time '-' Time
863 {
864 tt->_STime = $<t>1 + TimeOfBeginOfDay(-1);
865 tt->_ETime = $<t>3 + TimeOfBeginOfDay(-1) + 59;
866 }
867 | AnyP '.' Time {
868 time_t i_time;
869 time_t b_time;
870 if ($<t>3 == (time_t) 0) {
871 yyerror("Time of pereodical event should be between 00:01 and 23:59");
872 YYABORT;
873 }
874 tt->_STime = TimeOfBeginOfDay(-1);
875 b_time = tt->_STime;
876 do {
877 i_time = tt->_STime;
878 CheckETTime();
879 _TTimes->AddToEnd(tt);
880 tt = new tTimes;
881 tt->_ETime = 0;
882 tt->_STime = i_time + $<t>3;
883 } while (tt->_STime < (b_time + (23*60*60)+(59*60)+60));
884 tt->_STime = 0;
885 }
886 ;
887
888 AnyP : 'p'
889 | 'P'
890 ;
891
892 Time : _DIGIT_
893 {
894 if ($<ln>1 < 0 || $<ln>1 > 23) {
895 yyerror("Hour should be between 00 and 23");
896 YYABORT;
897 } else {
898 $<t>$ = (time_t) ($<ln>1 * 60);
899 }
900 }
901 ':' _DIGIT_
902 {
903 if ($<ln>4 < 0 || $<ln>4 > 59 || $<t>2 == (time_t) -1) {
904 $<t>$ = (time_t)-1;
905 yyerror("Minutes should be between 00 and 59");
906 YYABORT;
907 } else {
908 $<t>$ = $<t>2 + (time_t) $<ln>4;
909 $<t>$ *= 60;
910 }
911 }
912 ;
913
914 WeekSTime :
915 | WeekSTime WeekSSTime
916 {
917 CheckETTime();
918 _TTimes->AddToEnd(tt);
919 tt = new tTimes;
920 }
921 ;
922
923 WeekSSTime : _DIGIT_
924 {
925 if ($<ln>1 < 0 || $<ln>1 > 6) {
926 yyerror("Day of week should be between 0 and 6");
927 YYABORT;
928 } else {
929 tt->_STime = TimeOfBeginOfDay($<ln>1);
930 }
931 }
932 | _DIGIT_ '-' _DIGIT_
933 {
934 if ($<ln>1 < 0 || $<ln>1 > 6 || $<ln>3 < 0 || $<ln>3 > 6) {
935 yyerror("Day of week should be between 0 and 6");
936 YYABORT;
937 } else {
938 tt->_STime = TimeOfBeginOfDay($<ln>1);
939 tt->_ETime = TimeOfBeginOfDay($<ln>3) + (23*60*60)+(59*60)+59;
940 }
941 }
942 ;
943
944 Flag : { FileName = NULL; }
945 | AFlag { FileName = strdup($<ch>1); }
946 ;
947
948 /* -------------- */
949
950 Mask : _MASK { MaskMode = 0; } MParam {
951 msk->_Type = MASK_NORMAL;
952 AddReadyMask(*(NormalMask *)msk);
953 }
954 ;
955
956 SMask : _SMASK { MaskMode = 0; } MParam {
957 msk->_Type = MASK_SKIP;
958 AddReadyMask(*(NormalMask *)msk);
959 }
960 ;
961
962 PMask : _PMASK { MaskMode = 0; } MParam {
963 msk->_Type = MASK_ADD;
964 AddReadyMask(*(NormalMask *)msk);
965 }
966 ;
967
968 MParam : {
969 msk = new NormalMask();
970 CheckMem((char *)msk);
971 msk->_Type = MASK_NORMAL;
972 if (PrepareMask(*msk) != 0) {
973 YYABORT;
974 }
975 }
976 SyName {
977 ((NormalMask *)msk)->_FromName = strdup($<ch>2);
978 cffa.Clean();
979 }
980 faddress {
981 ((NormalMask *)msk)->_FromAddr = cffa;
982 if (MaskMode == 0) {
983 rc = ((NormalMask *)msk)->_FromAddr.MaskValid();
984 } else {
985 rc = ((NormalMask *)msk)->_FromAddr.ActValid();
986 }
987 if (!rc) {
988 yyerror("Invalid 'From' Address.");
989 YYABORT;
990 }
991 }
992 SyName {
993 ((NormalMask *)msk)->_ToName = strdup($<ch>6);
994 cffa.Clean();
995 }
996 faddress {
997 ((NormalMask *)msk)->_ToAddr = cffa;
998 if (MaskMode == 0) {
999 rc = ((NormalMask *)msk)->_ToAddr.MaskValid();
1000 } else {
1001 rc = ((NormalMask *)msk)->_ToAddr.ActValid();
1002 }
1003 if (!rc) {
1004 yyerror("Invalid 'To' Address.");
1005 YYABORT;
1006 }
1007 if ((((NormalMask *)msk)->_ToAddr.Zone() & (FA_LSTMASK|FA_HOLDMASK|FA_DOWNMASK|FA_PVTMASK|FA_HUBMASK)) && (!Ndl.Enabled())) {
1008 yyerror("You can't use '#','H','D','U' or 'P' mask without nodelist.");
1009 YYABORT;
1010 }
1011 if ((((NormalMask *)msk)->_ToAddr.Point() & FA_SUBMASK) && (!Ndl.Enabled())) {
1012 yyerror("You can't use '&' mask without nodelist.");
1013 YYABORT;
1014 }
1015 }
1016 MString {
1017 ((NormalMask *)msk)->_Subject = strdup($<ch>10);
1018 NoTokensF = TRUE;
1019 }
1020 MsgAttr {
1021 NoTokensF = FALSE;
1022 }
1023 ;
1024
1025 SyName : _STRING
1026 | '$' { $<ch>$ = "$"; }
1027 | '*' { $<ch>$ = "*"; }
1028 | '%' { $<ch>$ = "%"; }
1029 ;
1030
1031 MString : _STRING
1032 | '*' { $<ch>$ = "*"; }
1033 ;
1034
1035 MDigit : MNot _DIGIT_ {
1036 if ($<ln>2 > 65535) {
1037 yyerror("Parameter shoul be less that 65535");
1038 YYABORT;
1039 }
1040 $<ln>$ = $<ln>1 | $<ln>2;
1041 }
1042 | '*' { $<ln>$ = -1; }
1043 ;
1044
1045 MNot : { $<ln>$ = 0; }
1046 | '!' { $<ln>$ = 0x08000000; }
1047 ;
1048
1049 MsgAttr : '*'
1050 | { FlagMode = 1; } MsgFAttr
1051 ;
1052 MsgFAttr : FlagsMode
1053 | MsgFAttr FlagsMode
1054 ;
1055
1056 FlagsMode : FlagsChar
1057 | '+' { FlagMode = 1; } FlagsChar
1058 | '-' { FlagMode = 2; } FlagsChar
1059 ;
1060
1061 FlagsChar : 'a' { ((NormalMask *)msk)->fFileAttach = (FlagMode == 2) ? 2 : 1; }
1062 | 'A' { /* Check MaxAttach size*/
1063 if (CheckMaskMode("A") != 0) {
1064 YYABORT;
1065 }
1066 if (((NormalMask *)msk)->sd->_MaxAttachSize == 0 && MaxAttachSize == 0) {
1067 yyerror("Not one (global or local) MaxAttachSize is not defined.");
1068 YYABORT;
1069 }
1070 ((NormalMask *)msk)->fMaxAttach = (FlagMode == 2) ? 2 : 1;
1071 }
1072 | 'M' { /* Check MaxMsg size*/
1073 if (CheckMaskMode("M") != 0) {
1074 YYABORT;
1075 }
1076 if (((NormalMask *)msk)->sd->_MaxMsgSize == 0 && MaxMsgSize == 0) {
1077 yyerror("Not one (global or local) MaxMsgSize is not defined.");
1078 YYABORT;
1079 }
1080 ((NormalMask *)msk)->fMaxMsg = (FlagMode == 2) ? 2 : 1;
1081 }
1082 | 'b' { ((NormalMask *)msk)->fARQ = (FlagMode == 2) ? 2 : 1; }
1083 | 'c' { ((NormalMask *)msk)->fCrash = (FlagMode == 2) ? 2 : 1; }
1084 | 'd' { ((NormalMask *)msk)->fDIR = (FlagMode == 2) ? 2 : 1; }
1085 | 'e' { /* Empty message */
1086 if (CheckMaskMode("e") != 0) {
1087 YYABORT;
1088 }
1089 ((NormalMask *)msk)->fEmpty = (FlagMode == 2) ? 2 : 1;
1090 }
1091 | 'E' { /* Check echomail */
1092 if (CheckMaskMode("E") != 0) {
1093 YYABORT;
1094 }
1095 ((NormalMask *)msk)->fEchomail = (FlagMode == 2) ? 2 : 1;
1096 }
1097 | 'f' { ((NormalMask *)msk)->fFileRequest = (FlagMode == 2) ? 2 : 1; }
1098 | 'g' { /* Check age */
1099 if (CheckMaskMode("g") != 0) {
1100 YYABORT;
1101 }
1102 if (((NormalMask *)msk)->sd->_MaxAge == 0 && MaxAge == 0) {
1103 yyerror("Not one (global or local) MaxAge is not defined.");
1104 YYABORT;
1105 }
1106 ((NormalMask *)msk)->fMaxAge = (FlagMode == 2) ? 2 : 1;
1107 }
1108 | 'h' { ((NormalMask *)msk)->fHold = (FlagMode == 2) ? 2 : 1; }
1109 | 'i' { ((NormalMask *)msk)->fTransit = (FlagMode == 2) ? 2 : 1; }
1110 | 'j' { ((NormalMask *)msk)->fKFS = (FlagMode == 2) ? 2 : 1; }
1111 | 'k' { ((NormalMask *)msk)->fKillSend = (FlagMode == 2) ? 2 : 1; }
1112 | 'l' { ((NormalMask *)msk)->fLocal = (FlagMode == 2) ? 2 : 1; }
1113 | 'L' { ((NormalMask *)msk)->fLok = (FlagMode == 2) ? 2 : 1; }
1114 | 'm' { ((NormalMask *)msk)->fIMM = (FlagMode == 2) ? 2 : 1; }
1115 | 'n' { ((NormalMask *)msk)->fCFM = (FlagMode == 2) ? 2 : 1; }
1116 | 'o' { ((NormalMask *)msk)->fOrphan = (FlagMode == 2) ? 2 : 1; }
1117 | 'p' { ((NormalMask *)msk)->fPrivate = (FlagMode == 2) ? 2 : 1; }
1118 | 'q' { ((NormalMask *)msk)->fRRQ = (FlagMode == 2) ? 2 : 1; }
1119 | 'r' { ((NormalMask *)msk)->fReceived = (FlagMode == 2) ? 2 : 1; }
1120 | 's' { ((NormalMask *)msk)->fSend = (FlagMode == 2) ? 2 : 1; }
1121 | 'S' { ((NormalMask *)msk)->fAS = (FlagMode == 2) ? 2 : 1; }
1122 | 't' { ((NormalMask *)msk)->fTFS = (FlagMode == 2) ? 2 : 1; }
1123 | 'u' { ((NormalMask *)msk)->fFURQ = (FlagMode == 2) ? 2 : 1; }
1124 | 'v' { ((NormalMask *)msk)->fScanned = (FlagMode == 2) ? 2 : 1; }
1125 | 'x' { /* Check existing attach */
1126 if (CheckMaskMode("x") != 0) {
1127 YYABORT;
1128 }
1129 ((NormalMask *)msk)->fAttExists = (FlagMode == 2) ? 2 : 1;
1130 }
1131 | 'y' { ((NormalMask *)msk)->fIRR = (FlagMode == 2) ? 2 : 1; }
1132 | _DIGIT_ {
1133 if (CheckMaskMode("loop flag") != 0) {
1134 YYABORT;
1135 }
1136 ((NormalMask *)msk)->fLoop = (FlagMode == 2) ? 2 : 1;
1137 if (((NormalMask *)msk)->Loops != (unsigned int)-1) {
1138 yyerror("Only one loop count should be in mask.");
1139 YYABORT;
1140 }
1141 ((NormalMask *)msk)->Loops = $<ln>1;
1142 }
1143 ;
1144
1145 /* -------------- */
1146
1147 KludgeMask : _KLUDGEMASK KMParam {
1148 msk->_Type = MASK_NORMAL;
1149 AddReadyMask(*(KludgeMask *)msk);
1150 }
1151 ;
1152
1153 SKludgeMask : _SKLUDGEMASK KMParam {
1154 msk->_Type = MASK_SKIP;
1155 AddReadyMask(*(KludgeMask *)msk);
1156 }
1157 ;
1158
1159 PKludgeMask : _PKLUDGEMASK KMParam {
1160 msk->_Type = MASK_ADD;
1161 AddReadyMask(*(KludgeMask *)msk);
1162 }
1163 ;
1164
1165 KMParam : {
1166 msk = new KludgeMask();
1167 CheckMem((char *)msk);
1168 msk->_Type = MASK_NORMAL;
1169 if (PrepareMask(*msk) != 0) {
1170 YYABORT;
1171 }
1172 }
1173 MString MString MDigit {
1174 ((KludgeMask *)msk)-> _KludgeName = strdup($<ch>2);
1175 ((KludgeMask *)msk)-> _KludgeBody = strdup($<ch>3);
1176 ((KludgeMask *)msk)-> _Times = $<ln>4;
1177 }
1178 ;
1179
1180 /* -------------- */
1181
1182 BodyMask : _BODYMASK BMParam {
1183 msk->_Type = MASK_NORMAL;
1184 AddReadyMask(*(BodyMask *)msk);
1185 }
1186 ;
1187
1188 SBodyMask : _SBODYMASK BMParam {
1189 msk->_Type = MASK_SKIP;
1190 AddReadyMask(*(BodyMask *)msk);
1191 }
1192 ;
1193
1194 PBodyMask : _PBODYMASK BMParam {
1195 msk->_Type = MASK_ADD;
1196 AddReadyMask(*(BodyMask *)msk);
1197 }
1198 ;
1199
1200 BMParam : {
1201 msk = new BodyMask();
1202 CheckMem((char *)msk);
1203 msk->_Type = MASK_NORMAL;
1204 if (PrepareMask(*msk) != 0) {
1205 YYABORT;
1206 }
1207 }
1208 MString MDigit MDigit {
1209 ((BodyMask *)msk)-> _Body = strdup($<ch>2);
1210 ((BodyMask *)msk)-> _Lines = $<ln>3;
1211 ((BodyMask *)msk)-> _Bytes = $<ln>4;
1212 }
1213 ;
1214
1215
1216 /* -------------- */
1217
1218 ScriptMask : _SCRIPTMASK SCRMParam {
1219 msk->_Type = MASK_NORMAL;
1220 AddReadyMask(*(ScriptMask *)msk);
1221 }
1222 ;
1223
1224 SScriptMask : _SSCRIPTMASK SCRMParam {
1225 msk->_Type = MASK_SKIP;
1226 AddReadyMask(*(ScriptMask *)msk);
1227 }
1228 ;
1229
1230 PScriptMask : _PSCRIPTMASK SCRMParam {
1231 msk->_Type = MASK_ADD;
1232 AddReadyMask(*(ScriptMask *)msk);
1233 }
1234 ;
1235
1236 SCRMParam : {
1237 msk = new ScriptMask();
1238 CheckMem((char *)msk);
1239 msk->_Type = MASK_NORMAL;
1240 if (PrepareMask(*msk) != 0) {
1241 YYABORT;
1242 }
1243 }
1244 _STRING {
1245 ((ScriptMask *)msk)->_ScriptName = strdup($<ch>2);
1246 if (!ScriptWordExists($<ch>2)) {
1247 yyerror("Subroutine not found in scripts.");
1248 YYABORT;
1249 }
1250 }
1251 ;
1252
1253 /* -------------- */
1254
1255 Action : _ACTION {
1256 if (PrevMask == 0) {
1257 yyerror("Action without Mask.");
1258 YYABORT;
1259 }
1260 wsd = ScanDirs.GetLast();
1261 PrevMask = 1;
1262 act = new Action();
1263 act->sd = wsd;
1264 act->Before = BeforeRoute;
1265 act->After = AfterRoute;
1266 _TTimes = &act->_Times;
1267 }
1268 ActionCmd {
1269 LastDo->AddAction(*act);
1270 }
1271 MayBeActTime
1272 ;
1273
1274 MayBeActTime :
1275 | '[' STime ']'
1276 ;
1277
1278 ActionCmd : AAddNote
1279 | _DELETE { act->_Act = ACT_DELETE; }
1280 | AMove
1281 | ACopy
1282 | ARewrite
1283 | _IGNORE { act->_Act = ACT_IGNORE; }
1284 | ADisplay
1285 | AAFlag
1286 | ADelFile
1287 | ANewMsg
1288 | AWriteFile
1289 | AAppendToFile
1290 | ACall
1291 | ARoute
1292 | ARouteFbox
1293 | ARouteHub
1294 | APoll
1295 | _DELETEATTACH { act->_Act = ACT_DELETEATTACH; }
1296 | AChangePath
1297 | AToLowerPath
1298 | AToUpperPath
1299 | AMoveAttach
1300 | AMoveAttachFbox
1301 | ACopyAttach
1302 | ACopyAttachFbox
1303 | ASplit
1304 | ARecode
1305 | AScript
1306 | AAddKludge
1307 ;
1308
1309 AAddNote : _ADDNOTE _STRING {
1310 act->_Act = ACT_ADDNOTE;
1311 act->_Tpl = new Template();
1312 if (!act->_Tpl->Set($<ch>2)) {
1313 yyerror("Template file is not accesible.");
1314 delete act->_Tpl;
1315 act->_Tpl = NULL;
1316 YYABORT;
1317 }
1318 act->_Tpl->sd = ScanDirs.GetLast();
1319 }
1320 ;
1321
1322 AMove : _MOVE _STRING {
1323 act->_Act = ACT_MOVE;
1324 act->_Base = MakeBase($<ch>2);
1325 if (act->_Base == NULL) {
1326 YYABORT;
1327 }
1328 if (!act->_Base->Set($<ch>2,BASE_OUT)) {
1329 yyerror("Invalid message base name.");
1330 delete act->_Base;
1331 act->_Base = NULL;
1332 YYABORT;
1333 }
1334 if (!act->_Base->CheckOut()) {
1335 delete act->_Base;
1336 act->_Base = NULL;
1337 YYABORT;
1338 }
1339 act->_Base->Rewind();
1340 }
1341 ;
1342
1343 ACopy : _COPY _STRING {
1344 act->_Act = ACT_COPY;
1345 act->_Base = MakeBase($<ch>2);
1346 if (act->_Base == NULL) {
1347 YYABORT;
1348 }
1349 if (!act->_Base->Set($<ch>2,BASE_OUT)) {
1350 yyerror("Invalid message base name.");
1351 delete act->_Base;
1352 act->_Base = NULL;
1353 YYABORT;
1354 }
1355 if (!act->_Base->CheckOut()) {
1356 delete act->_Base;
1357 act->_Base = NULL;
1358 YYABORT;
1359 }
1360 act->_Base->Rewind();
1361 }
1362 ;
1363
1364 ARewrite : _REWRITE {
1365 MaskMode = 1;
1366 act->_Act = ACT_REWRITE;
1367 }
1368 MParam {
1369 act->_Mask = msk;
1370 }
1371 ;
1372
1373 ADisplay : _DISPLAY _STRING {
1374 act->_Act = ACT_DISPLAY;
1375 act->_TplName = strdup($<ch>2);
1376 }
1377 ;
1378
1379 AScript : _ASCRIPT _STRING {
1380 act->_Act = ACT_SCRIPT;
1381 if (!ScriptWordExists($<ch>2)) {
1382 yyerror("Script function not found.");
1383 YYABORT;
1384 }
1385 act->_TplName = strdup($<ch>2);
1386 }
1387 ;
1388
1389 AAFlag : AFlag {
1390 act->_Act = ACT_FLAG;
1391 act->_OutDir = strdup($<ch>1);
1392 }
1393 ;
1394
1395 AFlag : _FLAG _STRING { $<ch>$ = $<ch>2; }
1396 ;
1397
1398 ADelFile : _DELFILE _STRING {
1399 act->_Act = ACT_DELFILE;
1400 act->_OutDir = strdup($<ch>2);
1401 }
1402 ;
1403
1404 ANewMsg : _NEWMSG {
1405 MaskMode = 1;
1406 act->_Act = ACT_NEWMSG;
1407 }
1408 _STRING _STRING MParam {
1409 act->_Tpl = new Template();
1410 if (!act->_Tpl->Set($<ch>3)) {
1411 yyerror("Template file is not accesible.");
1412 delete act->_Tpl;
1413 act->_Tpl = NULL;
1414 delete msk;
1415 msk = NULL;
1416 YYABORT;
1417 }
1418 act->_Tpl->sd = ScanDirs.GetLast();
1419 act->_Base = MakeBase($<ch>4);
1420 if (act->_Base == NULL || !act->_Base->Set($<ch>4,BASE_OUT)) {
1421 yyerror("Invalid message base name.");
1422 delete act->_Tpl;
1423 act->_Tpl = NULL;
1424 delete msk;
1425 msk = NULL;
1426 delete act->_Base;
1427 act->_Base = NULL;
1428 YYABORT;
1429 }
1430 if (!act->_Base->CheckOut()) {
1431 delete act->_Tpl;
1432 act->_Tpl = NULL;
1433 delete msk;
1434 msk = NULL;
1435 delete act->_Base;
1436 act->_Base = NULL;
1437 YYABORT;
1438 }
1439 act->_Base->Rewind();
1440 act->_Mask = msk;
1441
1442 }
1443 ;
1444
1445 AWriteFile : _WRITEFILE _STRING _STRING {
1446 act->_Act = ACT_WRITEFILE;
1447 act->_Tpl = new Template();
1448 if (!act->_Tpl->Set($<ch>2)) {
1449 yyerror("Template file is not accesible.");
1450 delete act->_Tpl;
1451 act->_Tpl = NULL;
1452 YYABORT;
1453 }
1454 act->_Tpl->sd = ScanDirs.GetLast();
1455 act->_OutDir = strdup($<ch>3);
1456 }
1457 ;
1458
1459 AAppendToFile : _APPENDTOFILE _STRING _STRING {
1460 act->_Act = ACT_ADDFILE;
1461 act->_Tpl = new Template();
1462 if (!act->_Tpl->Set($<ch>2)) {
1463 yyerror("Template file is not accesible.");
1464 delete act->_Tpl;
1465 act->_Tpl = NULL;
1466 YYABORT;
1467 }
1468 act->_Tpl->sd = ScanDirs.GetLast();
1469 act->_OutDir = strdup($<ch>3);
1470 }
1471 ;
1472
1473 ACall : _CALL _STRING _STRING _STRING {
1474 act->_Act = ACT_CALL;
1475 act->_Tpl = new Template();
1476 if (!act->_Tpl->Set($<ch>2)) {
1477 yyerror("Template file is not accesible.");
1478 delete act->_Tpl;
1479 act->_Tpl = NULL;
1480 YYABORT;
1481 }
1482 act->_Tpl->sd = ScanDirs.GetLast();
1483 act->_OutDir = strdup($<ch>3);
1484 act->_TplName = strdup($<ch>4);
1485 }
1486 | _CALL _STRING {
1487 act->_Act = ACT_CALL;
1488 act->_TplName = strdup($<ch>2);
1489 }
1490 ;
1491
1492 ARoute : _ROUTE RouMode { cffa.Clean(); } faddress {
1493 act->_Act = ACT_ROUTE;
1494 if (act->sd == act->Before|| act->sd == act->After) {
1495 yyerror("You can not use the Action Route in 'ScanDir: @AfterRoute|@BeforeRoute'");
1496 YYABORT;
1497 }
1498 act->_Flav = $<pktmode>2;
1499 act->_f = cffa;
1500 if (act->_f.Point() & FA_NOTDEF) {
1501 act->_f.Point(0);
1502 }
1503 if (!act->_f.RouValid()) {
1504 yyerror("Invalid routing address.");
1505 YYABORT;
1506 }
1507 }
1508 ;
1509
1510 ARouteFbox : _ROUTEFBOX RouMode { cffa.Clean(); } faddress {
1511 act->_Act = ACT_ROUTEFBOX;
1512 if (FileBoxDir == NULL)
1513 {
1514 yyerror("You must define FileBoxDir before using Action: RouteFilebox.");
1515 YYABORT;
1516 }
1517 if (act->sd == act->Before|| act->sd == act->After) {
1518 yyerror("You can not use the Action RouteFilebox in 'ScanDir: @AfterRoute|@BeforeRoute'");
1519 YYABORT;
1520 }
1521 act->_Flav = $<pktmode>2;
1522 act->_f = cffa;
1523 if (act->_f.Point() & FA_NOTDEF) {
1524 act->_f.Point(0);
1525 }
1526 if (!act->_f.RouValid()) {
1527 yyerror("Invalid routing address.");
1528 YYABORT;
1529 }
1530 }
1531 ;
1532
1533 ARouteHub : _ROUTEHUB RouMode { cffa.Clean(); } {
1534 act->_Act = ACT_ROUTEHUB;
1535 if (act->sd == act->Before|| act->sd == act->After) {
1536 yyerror("You can not use the Action RouteHub in 'ScanDir: @AfterRoute|@BeforeRoute'");
1537 YYABORT;
1538 }
1539 act->_Flav = $<pktmode>2;
1540 }
1541 ;
1542
1543
1544 ACopyAttachFbox : _COPYATTACHFBOX RouMode { cffa.Clean(); } faddress {
1545 act->_Act = ACT_COPYATTACHFBOX;
1546 if (FileBoxDir == NULL)
1547 {
1548 yyerror("You must define FileBoxDir before using Action: CopyAttachFilebox.");
1549 YYABORT;
1550 }
1551 act->_Flav = $<pktmode>2;
1552 act->_f = cffa;
1553 }
1554 ;
1555
1556 AMoveAttachFbox : _MOVEATTACHFBOX RouMode { cffa.Clean(); } faddress {
1557 act->_Act = ACT_MOVEATTACHFBOX;
1558 if (FileBoxDir == NULL)
1559 {
1560 yyerror("You must define FileBoxDir before using Action: MoveAttachFilebox.");
1561 YYABORT;
1562 }
1563 act->_Flav = $<pktmode>2;
1564 act->_f = cffa;
1565 }
1566 ;
1567
1568 RouMode : _HOLD { $<pktmode>$ = F_HOLD; }
1569 | _CRASH { $<pktmode>$ = F_CRASH; }
1570 | _DIRECT { $<pktmode>$ = F_DIRECT; }
1571 | _NORMAL { $<pktmode>$ = F_NORMAL; }
1572 | _IMMEDIATE{ $<pktmode>$ = F_IMMEDIATE; }
1573 ;
1574
1575 APoll : _POLL RouMode { cffa.Clean(); } faddress {
1576 act->_Act = ACT_POLL;
1577 act->_Flav = $<pktmode>2;
1578 act->_f = cffa;
1579 if (act->_f.Point() & FA_NOTDEF) {
1580 act->_f.Point(0);
1581 }
1582 if (!act->_f.RouValid()) {
1583 yyerror("Invalid poll address.");
1584 YYABORT;
1585 }
1586 }
1587 ;
1588
1589 AChangePath : _CHANGEPATH _STRING {
1590 act->_Act = ACT_CHANGEPATH;
1591 if (strlen($<ch>2) > 72) {
1592 yyerror("New path too long");
1593 YYABORT;
1594 }
1595 act->_OutDir = strdup($<ch>2);
1596 }
1597 ;
1598
1599 AToLowerPath : _TOLOWERPATH {
1600 act->_Act = ACT_TOLOWERPATH;
1601 }
1602 ;
1603
1604
1605 AToUpperPath : _TOUPPERPATH {
1606 act->_Act = ACT_TOUPPERPATH;
1607 }
1608 ;
1609
1610 AAddKludge : _ADDKLUDGE _STRING _STRING {
1611 act->_Act = ACT_ADDKLUDGE;
1612 act->_OutDir = strdup($<ch>2);
1613 act->_TplName = strdup($<ch>3);
1614 }
1615 ;
1616
1617
1618 AMoveAttach : _MOVEATTACH _STRING {
1619 act->_Act = ACT_MOVEATTACH;
1620 if (!DirExists($<ch>2)) {
1621 Log.Level(LOGE) << "Target directory '" << $<ch>2 << "' not found." << EOL;
1622 }
1623 if (strlen($<ch>2) > 72) {
1624 yyerror("New path too long");
1625 YYABORT;
1626 }
1627 act->_OutDir = strdup($<ch>2);
1628 }
1629 ;
1630
1631 ACopyAttach : _COPYATTACH _STRING {
1632 act->_Act = ACT_COPYATTACH;
1633 if (!DirExists($<ch>2)) {
1634 Log.Level(LOGE) << "Target directory '" << $<ch>2 << "' not found." << EOL;
1635 }
1636 if (strlen($<ch>2) > 72) {
1637 yyerror("New path too long");
1638 YYABORT;
1639 }
1640 act->_OutDir = strdup($<ch>2);
1641 }
1642 ;
1643
1644 ASplit : _SPLIT _DIGIT_ {
1645 act->_Act = ACT_SPLIT;
1646 if ($<ln>2 < 1 || $<ln>2 > 65535) {
1647 yyerror("Parameter 'Lines' should be positive integer between 1 and 65535");
1648 YYABORT;
1649 }
1650 act->_Lines = $<ln>2;
1651 }
1652 ;
1653
1654 ARecode : _RECODE _STRING {
1655 FILE *fp = NULL;
1656 char buf[512],*p,*q;
1657 int in,on,count;
1658 int line = 0;
1659
1660 act->_Act = ACT_RECODE;
1661 fp = fopen($<ch>2,"r");
1662 if (fp == NULL) {
1663 yyerror("Unable to open file");
1664 YYABORT;
1665 }
1666 act->_TplName = (char *)malloc(256);
1667 CheckMem(act->_TplName);
1668 for (count = 0; count < 256; count++) act->_TplName[count] = (char) count;
1669 count = 0;
1670 line = 0;
1671
1672 while (fgets((char*)buf,sizeof(buf),fp)) {
1673 line++;
1674 p = strtok((char*)buf," \t\n#");
1675 q = strtok(NULL," \t\n#");
1676 if (p != NULL && q != NULL) {
1677 in = ctoi((char *)p);
1678 if (in > 255) {
1679 sprintf(buf, "%s: Error in line %d.", $<ch>2, line);
1680 yyerror(buf);
1681 fclose(fp);
1682 free(act->_TplName);
1683 YYABORT;
1684 }
1685 on=ctoi((char *)q);
1686 if (in != 0 && on != 0) {
1687 if (count++ < 256 ) {
1688 act->_TplName[in]=on;
1689 } else {
1690 sprintf(buf,"Char map table \"%s\" is big",$<ch>2);
1691 yyerror(buf);
1692 fclose(fp);
1693 free(act->_TplName);
1694 YYABORT;
1695 }
1696 }
1697 } /* if */
1698 } /* While */
1699 fclose(fp);
1700 }
1701 ;
1702
1703
1704 /* -------------- */
1705
1706 faddress : FullFtnAddr
1707 | '!' FullFtnAddr { cffa.Zone(cffa.Zone() | FA_NOTMASK); }
1708 ;
1709
1710 FullFtnAddr : nodeaddr
1711 | pointaddr
1712 | '*'
1713 {
1714 cffa.Zone(FA_ANYMASK);
1715 cffa.Net(FA_ANYMASK);
1716 cffa.Node(FA_ANYMASK);
1717 cffa.Point(FA_ANYMASK);
1718 }
1719 | '#'
1720 {
1721 cffa.Zone(FA_LSTMASK);
1722 cffa.Net(FA_LSTMASK);
1723 cffa.Node(FA_LSTMASK);
1724 cffa.Point(FA_LSTMASK);
1725 }
1726 | 'H'
1727 {
1728 cffa.Zone(FA_HOLDMASK);
1729 cffa.Net(FA_HOLDMASK);
1730 cffa.Node(FA_HOLDMASK);
1731 cffa.Point(FA_HOLDMASK);
1732 }
1733 | 'U'
1734 {
1735 cffa.Zone(FA_HUBMASK);
1736 cffa.Net(FA_HUBMASK);
1737 cffa.Node(FA_HUBMASK);
1738 cffa.Point(FA_HUBMASK);
1739 }
1740 | 'D'
1741 {
1742 cffa.Zone(FA_DOWNMASK);
1743 cffa.Net(FA_DOWNMASK);
1744 cffa.Node(FA_DOWNMASK);
1745 cffa.Point(FA_DOWNMASK);
1746 }
1747 | 'P'
1748 {
1749 cffa.Zone(FA_PVTMASK);
1750 cffa.Net(FA_PVTMASK);
1751 cffa.Node(FA_PVTMASK);
1752 cffa.Point(FA_PVTMASK);
1753 }
1754 | '@'
1755 {
1756 cffa.Zone(FA_OURMASK);
1757 cffa.Net(FA_OURMASK);
1758 cffa.Node(FA_OURMASK);
1759 cffa.Point(FA_OURMASK);
1760 }
1761 | '$'
1762 {
1763 cffa.Zone(FA_FROMMASK);
1764 cffa.Net(FA_FROMMASK);
1765 cffa.Node(FA_FROMMASK);
1766 cffa.Point(FA_FROMMASK);
1767 }
1768 | '%'
1769 {
1770 cffa.Zone(FA_TOMASK);
1771 cffa.Net(FA_TOMASK);
1772 cffa.Node(FA_TOMASK);
1773 cffa.Point(FA_TOMASK);
1774 }
1775 | '%' '.' _DIGIT_
1776 {
1777 if ($<ln>3 != 0) {
1778 yyerror("parse error");
1779 YYABORT;
1780 }
1781 cffa.Zone(FA_TOMASK);
1782 cffa.Net(FA_TOMASK);
1783 cffa.Node(FA_TOMASK);
1784 cffa.Point(0);
1785 }
1786 ;
1787
1788 pointaddr: nodeaddr '.' PntAddr
1789 ;
1790
1791 PntAddr : dw { cffa.Point($<ln>1); }
1792 | '&' { cffa.Point(FA_SUBMASK); }
1793 ;
1794
1795 nodeaddr : dw ':' dw '/' dw
1796 {
1797 cffa.Zone($<ln>1);
1798 cffa.Net($<ln>3);
1799 cffa.Node($<ln>5);
1800 cffa.Point(0);
1801 }
1802 ;
1803
1804 dw : _DIGIT_ { $<ln>$ = $<ln>1; }
1805 | '*' { $<ln>$ = FA_ANYMASK; }
1806 ;
1807
1808
1809 %%
1810
1811
1812