Source: Document: FTS-0001
Version: 016
Date: 30-Sep-95
A Basic FidoNet(r) Technical Standard
| Revision 16
Formerly known as FSC001, FSC-0001
| Randy Bush, Pacific Systems Group
| September 30, 1995
B. Application Layer : the System from the User's View
The application layer is outside the domain of a FidoNet standard, as it
is the layer that the user's application sees as opposed to what FidoNet
sees. In recent months, there has been sufficient confusion and
discussion about the format of data at this level to warrant the
description of the data structure, the message as it is stored by Fido,
SEAdog, and Rover.
Perfectly valid FidoNet systems may be implemented whose stored messages
differ greatly from this format.
1. Application Layer Data Definition : a Stored Message
Stored Message
Offset
dec hex
.-----------------------------------------------.
0 0 | |
~ fromUserName ~
| 36 bytes |
+-----------------------+-----------------------+
36 24 | |
~ toUserName ~
| 36 bytes |
+-----------------------+-----------------------+
72 48 | |
~ subject ~
| 72 bytes |
+-----------------------+-----------------------+
144 90 | |
~ DateTime ~
| 20 bytes |
+-----------------------+-----------------------+
164 A4 | timesRead (low order) | timesRead (high order)|
+-----------------------+-----------------------+
166 A6 | destNode (low order) | destNode (high order) |
+-----------------------+-----------------------+
168 A8 | origNode (low order) | origNode (high order) |
+-----------------------+-----------------------+
170 AA | cost (low order) | cost (high order) |
+-----------------------+-----------------------+
172 AC | origNet (low order) | origNet (high order) |
+-----------------------+-----------------------+
174 AE | destNet (low order) | destNet (high order) |
+-----------------------+-----------------------+
176 B0 | destZone (optional) | destZone (optional) |
+-----------------------+-----------------------+
178 B2 | origZone (optional) | origZone (optional) |
+-----------------------+-----------------------+
180 B4 | destPoint(optional) | destPoint(optional) |
+-----------------------+-----------------------+
182 B6 | origPoint(optional) | origPoint(optional) |
+-----------------------+-----------------------+
184 B8 | replyTo (low order) | replyTo (high order) |
+-----------------------+-----------------------+
186 BA | Attribute (low order) | Attribute (high order)|
+-----------------------+-----------------------+
188 BC | nextReply (low order) | nextReply (high order)|
+-----------------------+-----------------------+
190 BE | text |
~ unbounded ~
| null terminated |
`-----------------------------------------------'
Message = fromUserName(36) (* Null terminated *)
toUserName(36) (* Null terminated *)
subject(72) (* see FileList below *)
DateTime (* message body was last edited *)
timesRead (* number of times msg has been read *)
destNode (* of message *)
origNode (* of message *)
cost (* in lowest unit of originator's
currency *)
origNet (* of message *)
destNet (* of message *)
destZone (* of message *)
origZone (* of message *)
destPoint (* of message *)
origPoint (* of message *)
replyTo (* msg to which this replies *)
AttributeWord
nextReply (* msg which replies to this *)
text(unbounded) (* Null terminated *)
DateTime = (* a character string 20 characters long *)
(* 01 Jan 86 02:34:56 *)
DayOfMonth " " Month " " Year " "
" " HH ":" MM ":" SS
Null
DayOfMonth = "01" | "02" | "03" | ... | "31" (* Fido 0 fills *)
Month = "Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" |
"Jul" | "Aug" | "Sep" | "Oct" | "Nov" | "Dec"
Year = "01" | "02" | .. | "85" | "86" | ... | "99" | "00"
HH = "00" | .. | "23"
MM = "00" | .. | "59"
SS = "00" | .. | "59"
AttributeWord bit meaning
--- --------------------
0 + Private
1 + s Crash
2 Recd
3 Sent
4 + FileAttached
5 InTransit
6 Orphan
7 KillSent
8 Local
9 s HoldForPickup
10 + unused
11 s FileRequest
12 + s ReturnReceiptRequest
13 + s IsReturnReceipt
14 + s AuditRequest
15 s FileUpdateReq
s - need not be recognized, but it's ok
+ - not zeroed before packeting
Bits numbers ascend with arithmetic significance of bit position.
Message Text
Message text is unbounded and null terminated (note exception below).
A 'hard' carriage return, 0DH, marks the end of a paragraph, and must
be preserved.
So called 'soft' carriage returns, 8DH, may mark a previous
processor's automatic line wrap, and should be ignored. Beware that
they may be followed by linefeeds, or may not.
All linefeeds, 0AH, should be ignored. Systems which display message
text should wrap long lines to suit their application.
If the first character of a physical line (e.g. the first character of
the message text, or the character immediately after a hard carriage
return (ignoring any linefeeds)) is a ^A (<control-A>, 01H), then that
line is not displayed as it contains control information. The
convention for such control lines is:
o They begin with ^A
o They end at the end of the physical line (i.e. ignore soft <cr>s).
o They begin with a keyword followed by a colon.
o The keywords are uniquely assigned to applications.
o They keyword/colon pair is followed by application specific data.
Current ^A keyword assignments are:
| o TOPT <pt no> - destination point address
o FMPT <pt no> - origin point address
o INTL <dest z:n/n> <orig z:n/n> - used for inter-zone address
File Specifications
If one or more of FileAttached, FileRequest, or FileUpdateReq are
asserted in an AttributeWord, the subject{72} field is interpreted as
a list of file specifications which may include wildcards and other
system-dependent data. This list is of the form
FileList = [ FileSpec { Sep FileSpec } ] Null
FileSpec = (* implementation dependent file specification. may
not contain Null or any of the characters in Sep. *)
Sep = ( " " | "," ) { " " }
There are deviations from and additions to these specifications
1 - Fido does not necessarily terminate the message text with a Null,
but uses an empty line (0DH 0AH 0DH 0AH). Some Fido utilities
use an EOF (1AH).
2 - SEAdog zeros the message cost field when building a message.
4 - SEAdog uses a different format for dates, e.g.
DateTime = (* a character string 20 characters long *)
(* SEAdog format Mon 1 Jan 86 02:34 *)
DayOfWk " " DayOfMo " " Month " " Year " " HH ":" MM Null
DayOfWk = "Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | "Sun"
DayOfMo = " 1" | " 2" | " 3" | ... | "31" (* blank fill *)