[This is preliminary documentation
and subject to change.]
Updated: September 8, 2000
FAwk does for Fidonet message bases what good old Unix awk utility does for text files, that is allows processing of the messages according to the C-like scripts. Existing FAwk version supports FTS-001 (aka *.msg), Squish, JAM and Pkt message bases. It is Win32 console application which can be run on Window 9x, Windows NT and Windows 2000 platforms.
With FAwk one can easily create various mail scanners, robots, bouncers, carbon copiers, etc. tailored to your specific needs without chores of real programming. Full set of message, area, string, time and file management functions is available. In addition, you can define custom functions to use in your scripts.
FAwk also supports for RFC822 and MIME messages, POP3/SMTP server access and Fidonet/Internet messages gating.
Future FAwk releases may include:
· NNTP support to allow Internet news processing.
· External .DLL support to allow custom functions.
Unpack the FAwk archive and tweak the configuration file to you needs. Also it's a good idea to check http://www.kvitek.com/fido for the most recent version available. For editing scripts basic knowledge of C language syntax is helpful. Some understanding of general operation of Fidonet is assumed.
By default, FAwk reads its configuration from the file FAwk.cfg found in the current directory. Alternate configuration file name can be specified using /C command line switch.
Detailed description of configuration file keywords can be found in sample configuration file FAwk.cfg and is not included in this document.
FAwk allows selective configuration by means of conditional Include keywords: optional Include keyword parameters specify grep-like masks which are checked against command line parameters and the included file is processed only if one of the command line parameters matches any of the specified masks.
The list of supported command line options is displayed when you run FAwk with /? command line switch. All unrecognized command line options and parameters can be accessed with CmdLineParam function or used in conditional Include keywords. This allows selective configuration using custom command line parameters.
All areas which can be processed by FAwk are defined by Area keyword or imported from Squish configuration or standard Areas.Bbs files using SquishCfg and AreasBbs keywords respectively.
Each area has the following attributes:
· Area tag used to identify the area
· Area type: NetMail, EchoMail, GroupMail and LocalMail. Except for the GroupMail, these attributes have no special meaning for FAwk. GroupMail areas are special in that when the messages are copied into them from another area, the ^aAREA: kludge specifying the original area is automatically added.
· Base path specifies message base path.
· Base type specifies message base type. Current FAwk version supports FTS-001 (*.msg), Squish, JAM and Pkt message bases.
· Default network address. If not specified, primary network address is assumed. Internally it is used to make up the address kludges in FTS-001 areas, but you can also use it in your scripts as the origination address when sending messages.
Following is the Area keyword syntax:
Area <areatag> <areapath> <areatype> [default address]
Example:
Area NETMAIL
c:\Fido\Mail\NetMail FN
Area NETMAIL.Z77
c:\Fido\Mail\NetMail.z77 FN 77:123/6
Area PK.MADMED c:\Fido\Mail\PKMadMed SE
Area PK.SQAFIX
c:\Fido\Mail\PKSqaFix JE
Area GROUPMAIL
c:\Fido\Mail\GroupMail SG
Area JUNKMAIL
c:\Fido\Mail\JunkMail SL
Scan's are specified by the Scan keyword and describe FAwk activity when scanning area matching a set of area masks. Following is the Scan keyword syntax:
Scan areamask […] { script statements }
FAwk processes scans in the order they are defined in the configuration file. For every scan, FAwk goes through the list of known areas looking for the ones which match any of the scan's area masks and if match found, opens the area and executes scan's script for every message in the area.
Example:
Scan NETMAIL {
if (IsMyMail()) ForwardToMe();
if (IsOldMail()) MoveToJunk();
}
Scan PK.* SU.* RU.* {
if (Match(Text(),
"*kvitek", matchNoCase)) ForwardToMe();
}
FAwk returns one of the following exit codes:
· 0 -- normal exit, no errors or warnings.
· 1 -- some warnings reported.
· 2 -- some errors reported.
· -1 -- fatal error.
FAwk script syntax is a subset of the C programming language syntax. Following is formal syntax definition:
statement:
expression-statement
compound-statement
selection-statement
iteration-statement
jump-statement
expression-statement:
[expression];
compound-statement:
{[statement-list]}
statement-list:
statement
statement-list statement
selection-statement:
if (expression) statement [else
statement]
iteration-statement:
while (expression) statement
do statement while(expression);
for
([init-expr];[cond-expr];[loop-expr]) statement
jump-statement
break;
continue;
If the break or continue statement is encountered in the script outside of any iteration statement, it is applied to the message scan loop, that is break stops processing messages in the current area and proceeds to the next area, while continue stops processing of the current message and proceeds to the next message.
FAwk scripts support numeric and string variables. There are no specific means to specify variable type: it's defined by last the assigned value.
Variable names are case sensitive.
Variables and predefined constants share the same name space. This means that you can't have variable with the same name as the predefined constant.
Variables are not explicitly declared and are defined as soon as they're encountered in the script. Initially variables have numeric type and the value of zero.
Variables are subject to scope: variable defined in { } block is visible in it and in all its nested { } blocks. Variable instance is lost as soon as it goes out of scope.
So watch for situations like this:
for (i = 0; i < 10; i++) {
if (i == 5) str = "Fifth
element";
}
StdOut("str=%d\n", str); ; another instance of str!
In the example above, variable str goes out of scope before it's value is displayed. You can fix the problem by declaring str outside of the for loop statement, like in the following example:
str = "";
for (i = 0; i < 10; i++) {
if (i == 5) str = "Fifth
element";
}
StdOut("str=%d\n", str);
You could also fix the problem by replacing for loop compound statement with the simple statement:
for (i = 0; i < 10; i++)
if (i == 5) str = "Fifth
element";
StdOut("str=%d\n", str);
FAwk scripts support numeric, character and string constants and set of predefined constants.
These are integers specified as decimal or hexadecimal values.
Example:
x = 1; y = 12; z = 0x0ff;
These are integers specified as ASCII characters, hexadecimal values or character escape sequences.
Example:
ch1 = 'A'; ch2 = '\xFF'; ch3 = '\n';
Following character escape sequences are supported:
|
Sequence |
Description |
|
\a |
Bell (alert) |
|
\b |
Backspace |
|
\f |
Form feed |
|
\n |
New line |
|
\r |
Carriage return |
|
\t |
Horizontal tab |
|
\v |
Vertical tab |
|
\\ |
Backslash |
|
\'' |
Double quote |
|
\' |
Single quote |
|
\? |
Question mark |
These are strings of ASCII characters or escape sequences enclosed in double quotas.
Example:
str = "Hello, Fidonet world\n";
String constants can be concatenated across the white space. For example, the following string specifications are the same as the one above:
str = "Hello, " "Fidonet "
"world\n";
str = "Hello, "
"Fidonet "
"world"
"\n";
Predefined constants look like variables but you can't assign value to them.
Predefined constant names are case sensitive.
Predefined constant share the name spaces with the variables so you can’t have variable with the same name as predefined constant.
Message attribute constants (use with Attr and SetAttr):
|
Constant |
Description |
|
Local |
Message was created locally |
|
InTransit |
Message is in-transit |
|
Private |
Private message |
|
Read |
Message was read by addressee |
|
Sent |
Message was sent to remote system |
|
KillSent |
Message will be deleted when sent |
|
ArchiveSent |
Message will be archived when sent |
|
Hold |
Message is on hold for pick-up by addressee |
|
Crash |
Message is crash |
|
Immediate |
Send message now, ignore restrictions |
|
Direct |
Send directly to destination |
|
Gate |
Send via gateway |
|
FileRequest |
Message contains file request |
|
FileAttach |
Message contains attached file(s) |
|
TruncFile |
Attached files are to be truncated when sent |
|
KillFile |
Attached files are to be deleted when sent |
|
ReceiptReq |
Return receipt requested |
|
ConfirmReq |
Confirmation receipt requested |
|
Orphan |
Message destination is unknown |
|
Encrypt |
Message text is encrypted |
|
Compress |
Message text is compressed |
|
Escaped |
Message text is seven bit ASCII |
|
ForcePickup |
Force pickup |
|
TypeLocal |
Message is for local use only (not for export) |
|
TypeEcho |
Message is for conference distribution |
|
TypeNet |
Message is direct network mail |
|
Scanned |
Message is scanned (squish) |
|
FileUpdateReq |
Message contains file update request |
|
AuditRequest |
Audit request |
|
NoDisplay |
Message may not be displayed to user |
|
Locked |
Message is locked, no editing possible |
|
Deleted |
Message is deleted |
File open mode constants (use with OpenFile):
|
Constant |
Description |
|
modeRead |
Opens the file for reading only. |
|
modeWrite |
Opens the file for writing only. |
|
modeReadWrite |
Opens the file for reading and writing. |
|
shareExclusive |
Opens the file with exclusive mode, denying other processes both read and write access to the file. Open fails if the file has been opened in any other mode for read or write access, even by the current process. |
|
shareDenyWrite |
Opens the file and denies other processes write access to the file. Open fails if the file has been opened in compatibility mode or for write access by any other process. |
|
shareDenyRead |
Opens the file and denies other processes read access to the file. Open fails if the file has been opened in compatibility mode or for read access by any other process. |
|
shareDenyNone |
Opens the file without denying other processes read or write access to the file. Open fails if the file has been opened in compatibility mode by any other process. |
|
modeNoInherit |
Prevents the file from being inherited by child processes. |
|
modeCreate |
Create a new file. If the file exists already, it is truncated to 0 length. |
|
modeNoTruncate |
Combine this value with modeCreate. If the file being created already exists, it is not truncated to 0 length. Thus the file is guaranteed to open, either as a newly created file or as an existing file. This might be useful, for example, when opening a settings file that may or may not exist already. |
|
typeText |
Sets text mode with special processing for carriage return–linefeed pairs. |
|
typeBinary |
Sets binary mode. |
File positioning constants (use with SeekFile):
|
Constant |
Description |
|
seekBegin |
Seek from beginning of the file. |
|
seekCurrent |
Seek from current position. |
|
seekEnd |
Seek from end of the file. |
File attribute constants (use with Get/SetFileAttr):
|
Constant |
Description |
|
fileArchive |
The file or directory is an archive file or directory |
|
fileCompressed |
The file or directory is compressed |
|
fileDirectory |
Specifies directory |
|
fileEncrypted |
The file or directory is encrypted |
|
fileHidden |
The file or directory is hidden |
|
fileNormal |
The file or directory has no other attributes set. This
attribute is valid only if used alone. |
|
fileOffline |
The data of the file is not immediately available |
|
fileReadOnly |
The file or directory is read-only |
|
fileReparsePoint |
The file has an associated reparse point |
|
fileSparseFile |
The file is a sparse file |
|
fileSystem |
The file or directory is part of, or is used exclusively
by, the operating system |
|
fileTemporary |
The file is being used for temporary storage |
Log level constants (use with Log):
|
Constant |
Description |
|
logError |
Log errors only. |
|
logWarning |
Log warnings and above. |
|
logAction |
Log actions and above. |
|
logDetail |
Log action details and above. |
|
logDebug |
Log function results, execution trace, etc. |
Pattern match constants (use with Match):
|
Constant |
Description |
|
matchNoCase |
No case sensitive match. |
|
matchCase |
Case sensitive match. |
Nodelist info constants (use with GetNodeInfo):
|
Constant |
Description |
|
nodeLine |
Return entire nodelist line for the given node |
|
nodeStatus |
Return node status (Zone, Region, Hub, Point, etc.) |
|
nodeSystem |
Return system name |
|
nodePlace |
Return system location |
|
nodeSysop |
Return sysop name |
|
nodePhone |
Return phone number |
|
nodeFlags |
Return node flags |
Gating constants (use with RfcToFtn and FtnToRfc):
|
Constant |
Description |
|
gateMinInfo |
Gate minimum info |
|
gateMaxInfo |
Gate maximum info |
|
gateNoFileAtt |
Don't gate file attachments |
|
gateAddVia |
Add FAwk via kludge |
Miscellaneous constants:
|
Constant |
Description |
|
NULL |
equals to 0 |
|
FALSE |
equals to 0 |
|
TRUE |
equals to 1 |
FAwk supports large set of predefined functions as well as user defined functions.
Most of these functions are trivial, and more detailed information on some of them can be found in the subsequent chapters. Also, demonstration of many predefined functions can be found in FAwkDemo.cfg.
To get better understanding of area and message related functions you can download Fidonet Mail Access toolkit at http://www.kvitek.com/fido and read its documentation.
Those of you who are familiar with Microsoft Visual C++ and Win32 programming will no doubt recognize that most of string functions come from MFC's CString class, while many file oriented functions have direct Win32 counterparts, so feel free to use appropriate documentation if you have access to it.
Area functions:
|
Function |
Description |
|
Area() |
Returns area name |
|
AreaType() |
Returns area type (NetMail, EchoMail, GroupMail, LocalMail) |
|
AreaAddr() |
Returns area default network address |
|
BaseType() |
Returns area message base type (Fts,JAM,Squish,Pkt) |
|
BasePath() |
Returns area message base path |
|
BasePathExt() |
Returns area message base path extension |
|
cMsg() |
Returns number of messages in an area |
|
SetLastReadMsg() |
Set last read message unique id for the given user id |
|
GetLastReadMsg() |
Get last read message unique id for the given user id |
|
SetNextMsg(umsg) |
Set next message unique id to process in the Scan loop |
Message functions:
|
Function |
Description |
|
FromName() |
Returns message From name |
|
FromAddr() |
Returns message From address |
|
ToName() |
Returns message To name |
|
ToAddr() |
Returns message To address |
|
Subj() |
Returns message subject |
|
Text() |
Returns message text |
|
Attr() |
Returns message attributes as number |
|
AttrString() |
Returns message attributes as string |
|
TimeWritten() |
Returns time when message has been written |
|
TimeReceived() |
Returns time when message has been received |
|
TimeProcessed() |
Returns time when message has been processed |
|
Kludge(kludge,n) |
Returns n'th instance of the specified kludge. If no kludge specified (""), returns n'th kludge in a message |
|
iMsg() |
Returns message index |
|
nMsg() |
Returns message number |
|
uMsg() |
Returns message unique identifier |
|
SetFromName(s) |
Sets message From name |
|
SetFromAddr(s) |
Sets message From address |
|
SetToName(s) |
Sets message To name |
|
SetToAddr(s) |
Sets message To address |
|
SetSubj(s) |
Sets message subject |
|
SetText(s) |
Sets message text |
|
SetAttr(attr) |
Sets message attributes as number |
|
SetTimeWritten(t) |
Sets time when message has been written |
|
SetTimeReceived |
Sets time when message has been received |
|
SetTimeProcessed |
Sets time when message has been processed |
|
DelKludge(kl,n) |
Deletes n'th instance of the specified kludge. If no kludge specified (""), deletes n'th kludge in a message |
|
AddKludge(kludge) |
Adds specified kludge |
|
AddEomKludge(kl) |
Adds specified end-of-message kludge |
|
CopyMsg(area) |
Copies message to specified area |
|
MoveMsg(area) |
Moves message to specified area |
|
DeleteMsg() |
Deletes message |
|
SaveMsg() |
Saves message |
|
SendMsg(...) |
Sends message, parameters are: (area,from,to,subj,attr,text) |
String functions: