Annotation of sbbs/sbbs2/smb/121a/smb.txt, revision 1.1

1.1     ! root        1: 
        !             2: 
        !             3: 
        !             4: 
        !             5: 
        !             6: 
        !             7: 
        !             8: 
        !             9: 
        !            10: 
        !            11: 
        !            12: 
        !            13: 
        !            14: 
        !            15: 
        !            16: 
        !            17: 
        !            18: 
        !            19: 
        !            20:                      Synchronet Message Base Specification
        !            21:                                  Version 1.21
        !            22:                                Updated 08/31/95
        !            23: 
        !            24:                         Copyright 1995 Digital Dynamics
        !            25: 
        !            26:                                   PO Box 501
        !            27:                              Yorba Linda, CA 92686
        !            28: 
        !            29:                  Voice: 714-529-6328   BBS: 714-529-9525 V.32/V.32bis
        !            30:                    FAX: 714-529-9721        714-529-9547 V.FC
        !            31:                   Fido: 1:103/705      ftp: netcom.com /pub/sb/sbbs
        !            32: 
        !            33: 
        !            34: 
        !            35: 
        !            36: 
        !            37: 
        !            38: 
        !            39: 
        !            40: 
        !            41: 
        !            42: 
        !            43: 
        !            44: 
        !            45: 
        !            46: 
        !            47: 
        !            48: 
        !            49: 
        !            50: 
        !            51: 
        !            52: 
        !            53: 
        !            54: 
        !            55: 
        !            56: 
        !            57: 
        !            58: Table of Contents
        !            59: =================
        !            60: 
        !            61: Introduction.............................................................3
        !            62: Implementation Levels....................................................8
        !            63: Definitions.............................................................10
        !            64:         Acronyms........................................................12
        !            65:         Data Types......................................................13
        !            66: File Formats............................................................18
        !            67:         Index.....................(*.SID)...............................18
        !            68:         Header....................(*.SHD)...............................20
        !            69:         Header Allocation.........(*.SHA)...............................30
        !            70:         Data......................(*.SDT)...............................31
        !            71:         Data Allocation...........(*.SDA)...............................32
        !            72:         CRC History...............(*.SCH)...............................33
        !            73: Header Field Types......................................................34
        !            74: Data Field Types........................................................58
        !            75: Messsage Attributes.....................................................60
        !            76: Translation Types.......................................................61
        !            77: Agent Types.............................................................62
        !            78: Network Types...........................................................63
        !            79: Media Types.............................................................64
        !            80: Message Storage Pseudo Code.............................................67
        !            81: Message Retrieval Pseudo Code...........................................69
        !            82: SMBUTIL.................................................................70
        !            83: CHKSMB..................................................................71
        !            84: FIXSMB..................................................................72
        !            85: SMBLIB (C library)......................................................73
        !            86:         Data Types and Constants..(SMBDEFS.H)...........................74
        !            87:         Global Variables..........(SMBVARS.C)...........................75
        !            88:         Function Prototypes.......(SMBLIB.H)............................76
        !            89:         Library Functions.........(SMBLIB.C)............................77
        !            90:         Miscellaneous.............(CRC*.* and LZH.*)....................84
        !            91: SMBLIB Storage Example..................................................86
        !            92: SMBLIB Retrieval Example................................................89
        !            93: SMBLIB Performance Issues...............................................91
        !            94: Bibliography............................................................95
        !            95: Implementations.........................................................96
        !            96: 
        !            97: 
        !            98: 
        !            99: 
        !           100: 
        !           101: 
        !           102: 
        !           103: 
        !           104: 
        !           105: 
        !           106: 
        !           107: 
        !           108: 
        !           109: 
        !           110: 
        !           111: 
        !           112: 
        !           113: _______________________________________________________________________________
        !           114: Synchronet                            2                                Contents
        !           115: 
        !           116: 
        !           117: Introduction
        !           118: ============
        !           119: 
        !           120: Q. What is SMB?
        !           121: 
        !           122: A. SMB (Synchronet Message Base) is a technical specification for the storage
        !           123:    format of electronic mail messages. These e-mail messages may all be
        !           124:    contained in one database, or, more commonly, separated into catagorized
        !           125:    databases. These message databases (or message bases) are also referred to
        !           126:    as "sub-boards", "forums", "conferences", and "SIGs". The messages may be
        !           127:    directed to an individual person, sent to a group of individuals, or sent
        !           128:    to everyone who can read messages in that message base. Messages may be
        !           129:    created and read soley at one physical location, or imported from and
        !           130:    exported to a message network that may span continents. Message bases that
        !           131:    are connected to a message network are often called "echoes".
        !           132: 
        !           133: 
        !           134: Q. Why SMB?
        !           135: 
        !           136: A. The Synchronet Message Base is designed to store high volumes of messages
        !           137:    while maintaining optimum search, retrieval, and creation performance.
        !           138:    These messages are not limited to mere text. In addition to text, SMB
        !           139:    defines the storage of digitized sound, MIDI, graphics, fonts, animation,
        !           140:    as well as other multimedia data and triggers for localized multimedia.
        !           141:    SMB thrives on a multi-user environment where messages are being created,
        !           142:    read, modified, and deleted by multiple tasks simultaneously. With the
        !           143:    large message networks of today being the rule, rather than the exception,
        !           144:    and high volumes of messages being imported on a daily, sometimes hourly
        !           145:    basis, creation and deletion speed is of the utmost importance. This is
        !           146:    where SMB really shines. Being extensible enough to handle message formats
        !           147:    from networks of today and tomorrow, and fast enough to import more messages
        !           148:    that humanly readable, the SMB format will more than meet your message
        !           149:    storage needs.
        !           150: 
        !           151: 
        !           152: Q. Why a specification?
        !           153: 
        !           154: A. Message bases are often accessed and modified by a number of different
        !           155:    programs. Often these programs are developed by individuals or companies
        !           156:    other than the original designer of the message base format. This
        !           157:    specification is an attempt to aid developers in creating programs that
        !           158:    access or modify a message base stored in the SMB format.
        !           159: 
        !           160: 
        !           161: Q. Who can use this specification?
        !           162: 
        !           163: A. Anyone that has interest in the Synchronet Message Base format at either
        !           164:    an educational or professional level. Specifically, software developers
        !           165:    interested or currently involved in the development of message readers,
        !           166:    editors, echomail (toss/scan) programs, message transfer agents (MTAs),
        !           167:    network gateways, and bulletin board systems. Much of the information in
        !           168:    this specification is intended for those with preexisting programming
        !           169:    knowledge, so those with little or no programming experience may find it
        !           170:    hard to comprehend.
        !           171: 
        !           172: _______________________________________________________________________________
        !           173: Synchronet                            3                            Introduction
        !           174: 
        !           175: 
        !           176: 
        !           177: 
        !           178: Q. What does the SMB specification include?
        !           179: 
        !           180: A. The text you are reading is part of the SMB specification: a single text
        !           181:    document that defines the storage format of each of the six files of an
        !           182:    SMB format message base and how they are related to each other.
        !           183: 
        !           184:    Included with this specification is C source code to be used as an example
        !           185:    to programmers of how to access an SMB format message base and public domain
        !           186:    library functions (SMBLIB) that can be compiled and linked into programs
        !           187:    that access an SMB format message base developed by third parties. An SMB
        !           188:    utility program (SMBUTIL) is also included with C source code as an example
        !           189:    of how to use the SMBLIB functions.
        !           190: 
        !           191: 
        !           192: Q. Where did the SMB specification come from?
        !           193: 
        !           194: A. Digital Dynamics (southern California based software development company)
        !           195:    released "Synchronet Multinode BBS Software Version 1a" in June of 1992 as
        !           196:    one of the first BBS packages to be designed from the ground-up to operate
        !           197:    in a multinode environment with incredible speed and reliability, with a
        !           198:    large suite of multinode specific features and design innovations.
        !           199: 
        !           200:    The original message base format was designed with localized messaging and
        !           201:    low volume message networks in mind. By January of 1993, it was clear that
        !           202:    high volume message networks (FidoNet, RelayNet, Usenet, etc.) were the
        !           203:    preference of most BBS users and a new message base format was required to
        !           204:    allow for high volume message storage, improved storage, retrieval, and
        !           205:    maintenance performance, as well as lower storage space requirements.
        !           206: 
        !           207:    Rather than introduce another new message format, Digital Dynamics sought
        !           208:    to implement an existing public specification for a format that would meet
        !           209:    current and future message storage needs. More than a few specifications
        !           210:    were seriously considered at one time or another, but after careful
        !           211:    examination, design flaws and lack of extensibility eliminated them from the
        !           212:    long term plans of Digital Dynamics and Synchronet BBS Software. Thus began
        !           213:    the design of the "Synchronet Message Base" (SMB) format.
        !           214: 
        !           215:    At the request of many message related program developers, Digital Dynamics
        !           216:    created and released the SMB specification before the release of "Synchronet
        !           217:    Version 2.00" to allow lead-time on developing support programs for the new
        !           218:    format.
        !           219: 
        !           220:    Digital Dynamics strongly encourages developers of message related programs
        !           221:    (including software that directly competes with Synchronet or other Digital
        !           222:    Dynamics products) to implement support for SMB. Though this is a public
        !           223:    specification and Digital Dynamics encourages developer suggestions, it will
        !           224:    remain under the sole control of Digital Dynamics unless specifically stated
        !           225:    otherwise in a future revision of this specification.
        !           226: 
        !           227:    Digital Dynamics requests that any organizations that wish to adopt or
        !           228:    ratify this specification, in part or whole, notify Digital Dynamics through
        !           229:    any of the contact methods listed at the beginning of this document.
        !           230: 
        !           231: _______________________________________________________________________________
        !           232: Synchronet                            4                            Introduction
        !           233: 
        !           234: 
        !           235: 
        !           236: 
        !           237: Q. How does SMB store messages?
        !           238: 
        !           239: A. Each message base is stored in a set of binary files. This set consists
        !           240:    of between three and six files depending the storage method used. The base
        !           241:    filename (maximum of eight characters under DOS) is the same for all six
        !           242:    files of the same message base and unique amoung the filenames of other
        !           243:    message bases in the same directory. The six files each have a different
        !           244:    three character extension. The first character of the extension is always
        !           245:    the letter 'S' (for SMB), while the second and third characters define the
        !           246:    contents of the file.
        !           247: 
        !           248:    Two of the six files associated with each message base are not recreatable
        !           249:    and therefore are the most important when considering data integrity. These
        !           250:    two files are the data file (with a .SDT extension) and header file (.SHD
        !           251:    extension). Both of these files use 256 byte blocks and have associated
        !           252:    block allocation tables (stored in .SDA and .SHA respectively) so that
        !           253:    deleted message blocks may be used by new messages without creating odd
        !           254:    sized unused 'holes' in the files. The block allocation table files (.SDA
        !           255:    and .SHA) can be recreated with the information stored in the header (.SHD)
        !           256:    file. When using Hyper Allocation storage method, the allocation files (.SDA
        !           257:    and .SHA) are not used.
        !           258: 
        !           259:    For fast indexing, there is a small fixed length index file (with a .SID
        !           260:    extension). This file allows for the immediate location of message header
        !           261:    records based on sender's name or user number, recipient's name or user
        !           262:    number, subject, message number, or message attributes. This file can be
        !           263:    recreated with the data stored in the header (.SHD) file.
        !           264: 
        !           265:    The last file is an optional CRC history (.SCH) file. It contains 32-bit
        !           266:    CRCs of a configurable number of messages imported or created locally. This
        !           267:    is to help eliminate duplicate messages created by user or program error.
        !           268:    The CRC history file can be recreated with the combination of information
        !           269:    stored in the data (.SDT) and header (.SHD) files.
        !           270: 
        !           271: 
        !           272: 
        !           273: 
        !           274: 
        !           275: 
        !           276: 
        !           277: 
        !           278: 
        !           279: 
        !           280: 
        !           281: 
        !           282: 
        !           283: 
        !           284: 
        !           285: 
        !           286: 
        !           287: 
        !           288: 
        !           289: 
        !           290: _______________________________________________________________________________
        !           291: Synchronet                            5                            Introduction
        !           292: 
        !           293: 
        !           294: Q. How fast do messages import into an SMB message base?
        !           295: 
        !           296: A. This is a very important question for systems for that import large volumes
        !           297:    of messages. Of course, the answer depends on the storage format which you
        !           298:    are importing from, the average length of messages, the design of the
        !           299:    program which is peforming the import process, as well as the hardware and
        !           300:    system software being used. What's important is that SMB will allow the
        !           301:    fastest import process possible with any given combination of the above
        !           302:    factors.
        !           303: 
        !           304:    Since system storage capacity is rarely infinite, neither is the number
        !           305:    of messages which can be stored in a message base. System operators must
        !           306:    define the maximum number of messages to be stored in a message base, the
        !           307:    maximum age of the messages in that message base, or a combination of both.
        !           308:    When using the Self-packing storage method (defined later in this document),
        !           309:    the smaller the number of messages stored in a message base, the faster the
        !           310:    import process. The SMB format is flexible enough to support multiple levels
        !           311:    of import performance based on optimizations for storage space or speed.
        !           312:    Most system operators will almost invariably choose speed over space, but
        !           313:    which choices are available is determined by the importing program. This
        !           314:    specification defines three storage methods, from slowest to fastest:
        !           315:    Self-packing, Fast Allocation, and Hyper Allocation. Other options defined
        !           316:    in this specification may affect storage performance, including duplicate
        !           317:    message checking and message compression/encryption.
        !           318: 
        !           319: 
        !           320: Q. How much storage is required for an SMB message base?
        !           321: 
        !           322: A. The biggest factor in determining storage requirements for a message base
        !           323:    is the maximum number of messages to be stored in the base (defined by the
        !           324:    system operator) and the average size of each message. The minimum required
        !           325:    storage for a message base is 32 bytes plus 532 bytes per message (plus four
        !           326:    bytes per message if duplicate message checking is used and three bytes
        !           327:    per message if Self-packing or Fast Allocation storage methods are used).
        !           328: 
        !           329:    The SMB format was originally designed to be "self-packing", meaning purged
        !           330:    (deleted) message header and data blocks will be used automatically by new
        !           331:    messages. Relying solely on self-packing, an SMB format message base will
        !           332:    never "shrink" in size. This is not to say that it will continually "grow"
        !           333:    in size, but that without specific packing procedures, deleted message
        !           334:    blocks may remain unused for extended periods of time, meanwhile using some
        !           335:    amount of storage space that could be recovered using specific packing
        !           336:    procedures. The Fast Allocation and Hyper Allocation storage methods do not
        !           337:    use deleted message blocks for new messages so specific packing procedures
        !           338:    must be used if any messages are deleted and that storage space is to ever
        !           339:    be recovered.
        !           340: 
        !           341:    Limiting the maximum age of messages in an SMB message base is another way
        !           342:    to control the storage requirements. While maximum message age definition is
        !           343:    optional, the definition of the maximum number of messages is not.
        !           344: 
        !           345: 
        !           346: 
        !           347: 
        !           348: 
        !           349: _______________________________________________________________________________
        !           350: Synchronet                            6                            Introduction
        !           351: 
        !           352: 
        !           353: Q. How many messages can be stored per SMB message base?
        !           354: 
        !           355: A. Without considering storage limitations or message data lengths greater than
        !           356:    256, the theoretical maximum number of messages that can be stored in a
        !           357:    single SMB message base is 16.7 million. Considering the variable length
        !           358:    nature of message and header data, it is suggested that the system operator
        !           359:    allow no more than 1 million messages per base.
        !           360: 
        !           361:    To determine an estimated maximum number of messages for a message base
        !           362:    using the average message data length as a factor, use the following
        !           363:    formula:
        !           364: 
        !           365:    4.2 billion divided by the average message length rounded up to be evenly
        !           366:    divisible by 256.
        !           367: 
        !           368:    If the average message data length is 1500 bytes, the estimated maximum
        !           369:    number of messages would be 2,734,375 (4.2 billion divided by 1536).
        !           370: 
        !           371:    Implementations of this format may be further limited by available system
        !           372:    memory.
        !           373: 
        !           374: 
        !           375: 
        !           376: 
        !           377: 
        !           378: 
        !           379: 
        !           380: 
        !           381: 
        !           382: 
        !           383: 
        !           384: 
        !           385: 
        !           386: 
        !           387: 
        !           388: 
        !           389: 
        !           390: 
        !           391: 
        !           392: 
        !           393: 
        !           394: 
        !           395: 
        !           396: 
        !           397: 
        !           398: 
        !           399: 
        !           400: 
        !           401: 
        !           402: 
        !           403: 
        !           404: 
        !           405: 
        !           406: 
        !           407: 
        !           408: _______________________________________________________________________________
        !           409: Synchronet                            7                            Introduction
        !           410: 
        !           411: 
        !           412: Implementation Levels
        !           413: =====================
        !           414: The SMB format can be implemented to varying degrees between programs without
        !           415: creating compatibilty issues. Rather than have developers specifically state
        !           416: which features they have and have not implemented, we have defined seven levels
        !           417: of implementation (represented by Roman numerals I through VII). For a program
        !           418: or software package to meet an implementation level, it must have all of the
        !           419: features listed for that level and all of those for each level below it. The
        !           420: minimum suggested imlementation is level I. The SMBUTIL program included with
        !           421: this specification is an example of a level I implementation with features
        !           422: from some of the higher implementation levels.
        !           423: 
        !           424: Level I
        !           425: -------
        !           426: The minimum suggested level of implementation. Messages contain merely ASCII
        !           427: text displayable on an ANSI terminal. Messages can be added to the message
        !           428: base and if the maximum number of messages is exceeded, messages are removed
        !           429: or marked for deletion.
        !           430: 
        !           431: Level II
        !           432: --------
        !           433: The addition of file attachments, multiple index/header entries per message
        !           434: (multiple destinations), multiple text bodies for the separation of message
        !           435: text and tag/origin lines (for example), forwarding, threading, and specific
        !           436: FidoNet kludge header field support makes this level of implementation more
        !           437: realistic for bulletin board system and EchoMail software implementation.
        !           438: 
        !           439: Synchronet Multinode BBS Software v2.00 has a level II implementation of this
        !           440: specification.
        !           441: 
        !           442: Level III
        !           443: ---------
        !           444: This implementation adds support for translation strings defined later in this
        !           445: document for data compression, encryption, escaping, and encoding. This level
        !           446: is still limited to basic ASCII text and ANSI escape sequence entry and
        !           447: retrieval.
        !           448: 
        !           449: Synchronet Multinode BBS Software v2.10 has a level III implementation of this
        !           450: specification.
        !           451: 
        !           452: Level IV
        !           453: --------
        !           454: The storage and retrieval of embedded and attached images is added in this
        !           455: level of implementation. Supported images are limited to single binary or text
        !           456: data blocks that can be displayed or transferred to the user (automatically,
        !           457: or by request) if their display and translation protocols define specific
        !           458: support for the image type.
        !           459: 
        !           460: 
        !           461: 
        !           462: 
        !           463: 
        !           464: 
        !           465: 
        !           466: 
        !           467: _______________________________________________________________________________
        !           468: Synchronet                            8                   Implementation Levels
        !           469: 
        !           470: 
        !           471: Level V
        !           472: -------
        !           473: This level of implementation adds support for embedded and attached sound data.
        !           474: This includes digitized sound and MIDI data. Supported sounds are limited to
        !           475: single binary or text data blocks that can be played or transferred to the user
        !           476: (automatically or by request) if their presentation and translation protocols
        !           477: define specific support for the sound type.
        !           478: 
        !           479: Level VI
        !           480: --------
        !           481: Localized sound and image data can be triggered by messages stored and
        !           482: retrieved in an implementation of this level.
        !           483: 
        !           484: Level VII
        !           485: ---------
        !           486: Complete multimedia support is reached in this implementation level with
        !           487: support for embedded and attached animation, sound, and video data.
        !           488: 
        !           489: 
        !           490: 
        !           491: 
        !           492: 
        !           493: 
        !           494: 
        !           495: 
        !           496: 
        !           497: 
        !           498: 
        !           499: 
        !           500: 
        !           501: 
        !           502: 
        !           503: 
        !           504: 
        !           505: 
        !           506: 
        !           507: 
        !           508: 
        !           509: 
        !           510: 
        !           511: 
        !           512: 
        !           513: 
        !           514: 
        !           515: 
        !           516: 
        !           517: 
        !           518: 
        !           519: 
        !           520: 
        !           521: 
        !           522: 
        !           523: 
        !           524: 
        !           525: 
        !           526: _______________________________________________________________________________
        !           527: Synchronet                            9                   Implementation Levels
        !           528: 
        !           529: 
        !           530: Definitions
        !           531: ===========
        !           532: 
        !           533: Control Characters
        !           534: ------------------
        !           535: When specifying control characters (ASCII 1 through 31), the caret symbol "^"
        !           536: or the abreviation "ctrl-" followed by a character will be used to indicate the
        !           537: value. ^A is equivalent to ASCII 1, ^B ASCII 2, etc. The case of the control
        !           538: character is not significant (i.e. ^z and ^Z are equivalent). The control
        !           539: character ^@ (ASCII 0) will be specified as NULL or 0.
        !           540: 
        !           541: 
        !           542: Hexadecimal
        !           543: -----------
        !           544: Base sixteen numbering system which includes the digits 0-9 and A-F.
        !           545: Hexadecimal numbers are represented in this document with a prefix of "0x" or
        !           546: "\x" or a suffix of "h". Hexadecimal letter digits are not case sensitive
        !           547: (i.e. the number 0xff is the same as 0xFF).
        !           548: 
        !           549: 
        !           550: File dump
        !           551: ---------
        !           552: When example file dumps are displayed, the format is similar to that of the
        !           553: output from the DOS DEBUG program. With the exception of the ASCII characters,
        !           554: all numbers are in hexadecimal.
        !           555: 
        !           556: Offset    Byte values                                          ASCII characters
        !           557: 
        !           558: 000000    53 4D 42 1A 10 01 20 00   F4 01 00 00 F4 01 00 00    SMB... .�...�...
        !           559: 000010    20 00 00 00 D0 07 00 00   D0 07 00 00 00 00 00 00     ...�...�.......
        !           560: 
        !           561: 
        !           562: Bit values
        !           563: ----------
        !           564: Bit (or flag) values are represented in C notation as (1<<x) where x is the bit
        !           565: number. (i.e. bit number 7 (1<<7) is the same as 0x80).
        !           566: 
        !           567: 
        !           568: Word storage
        !           569: ------------
        !           570: All words (16-bit) and double words (32-bit) are stored in Intel 80x86 (little
        !           571: endian) format with bytes stored from low to high (reverse of the Motorola
        !           572: 680x0 word storage format).
        !           573: 
        !           574: A 16-bit word with the value 1234h is stored as 34h 12h.
        !           575: 
        !           576: 
        !           577: 
        !           578: 
        !           579: 
        !           580: 
        !           581: 
        !           582: 
        !           583: 
        !           584: 
        !           585: _______________________________________________________________________________
        !           586: Synchronet                           10                             Definitions
        !           587: 
        !           588: 
        !           589: Translation strings
        !           590: -------------------
        !           591: Translation strings (xlat variables) are arrays of words (16-bit) in the order
        !           592: of the original storage translation. The last translation type is followed by a
        !           593: 16-bit zero (defined later as XLAT_NONE). If there are no translations, then
        !           594: the first and only element of the array is XLAT_NONE.
        !           595: 
        !           596: If multiple translations are used, the translation order must be reversed
        !           597: upon retrieval to obtain the proper data.
        !           598: 
        !           599: 
        !           600: Local e-mail
        !           601: ------------
        !           602: When referring to the local e-mail message base of a Synchronet BBS, we are
        !           603: referring specifically the message base with the name "MAIL" stored in the
        !           604: "DATA" directory (e.g. \SBBS\DATA\MAIL).
        !           605: 
        !           606: Messages stored in this message base are different in the following respects:
        !           607: 
        !           608:     The SMB_EMAIL status header attribute is set ON
        !           609:     Hyper Allocation storage method is not supported
        !           610:     The "To" and and "From" fields of the message indexes do NOT contain CRCs
        !           611: 
        !           612: 
        !           613: 
        !           614: 
        !           615: 
        !           616: 
        !           617: 
        !           618: 
        !           619: 
        !           620: 
        !           621: 
        !           622: 
        !           623: 
        !           624: 
        !           625: 
        !           626: 
        !           627: 
        !           628: 
        !           629: 
        !           630: 
        !           631: 
        !           632: 
        !           633: 
        !           634: 
        !           635: 
        !           636: 
        !           637: 
        !           638: 
        !           639: 
        !           640: 
        !           641: 
        !           642: 
        !           643: 
        !           644: _______________________________________________________________________________
        !           645: Synchronet                           11                             Definitions
        !           646: 
        !           647: 
        !           648: Acronyms:
        !           649: ========
        !           650: 
        !           651: ANSI            American National Standards Institute
        !           652: ASCII           American Standard Code for Information Interchange
        !           653: BBS             Bulletin Board System
        !           654: C               The C programming language as defined by ANSI X3.159-1989
        !           655: CR              Carriage Return character (ASCII 13)
        !           656: CRC             Cyclic Redundancy Check
        !           657: CRC-16          Standard 16-bit CRC using 1021h polynomial (seed 0)
        !           658: CRC-32          Standard 32-bit CRC using EDB88320h polynomial (seed -1)
        !           659: CRLF            Carriage Return character followed by a Line Feed character
        !           660: FSC             FidoNet Standards Commitee (FTS proposal)
        !           661: FTN             FidoNet Technology Network
        !           662: FTS             FidoNet Technical Standard
        !           663: LF              Line Feed character (ASCII 10)
        !           664: QWK             Compressed message packet format for message reading/networking
        !           665: RFC             Request for Comments
        !           666: SMB             Synchronet Message Base
        !           667: UT              Universal Time (formerly called "Greenwhich Mean Time")
        !           668: 
        !           669: 
        !           670: 
        !           671: 
        !           672: 
        !           673: 
        !           674: 
        !           675: 
        !           676: 
        !           677: 
        !           678: 
        !           679: 
        !           680: 
        !           681: 
        !           682: 
        !           683: 
        !           684: 
        !           685: 
        !           686: 
        !           687: 
        !           688: 
        !           689: 
        !           690: 
        !           691: 
        !           692: 
        !           693: 
        !           694: 
        !           695: 
        !           696: 
        !           697: 
        !           698: 
        !           699: 
        !           700: 
        !           701: 
        !           702: 
        !           703: _______________________________________________________________________________
        !           704: Synchronet                           12                  Definition of Acronyms
        !           705: 
        !           706: 
        !           707: Data types
        !           708: ==========
        !           709: 
        !           710: uchar           Unsigned 8-bit value (0 through 255).
        !           711:                 C example:
        !           712: 
        !           713:                 #define uchar unsigned char
        !           714: 
        !           715: 
        !           716: short           Signed 16-bit value (-32768 through 32767).
        !           717:                 "short" is a C keyword indicating "short int".
        !           718: 
        !           719: 
        !           720: ushort          Unsigned 16-bit value (0 through 65535).
        !           721:                 C example:
        !           722: 
        !           723:                 #define ushort unsigned short
        !           724: 
        !           725: 
        !           726: ulong           Unsigned 32-bit value (0 through 4294967295).
        !           727:                 C example:
        !           728: 
        !           729:                 #define ulong unsigned long
        !           730: 
        !           731: 
        !           732: time_t          Unsigned 32-bit value.
        !           733:                 Seconds since 00:00 Jan 01 1970 (Unix format).
        !           734:                 Used for all time/date storage in SMB as part of the when_t
        !           735:                 data type. This time format will support dates through the year
        !           736:                 2105.
        !           737:                 time_t is defined by ANSI C as a long (signed) which can
        !           738:                 limit its date support to the year 2038 depending on the
        !           739:                 library routines used.
        !           740: 
        !           741: 
        !           742: ASCII           String (aka character array) of 8-bit ASCII characters.
        !           743:                 Characters with the bit 7 set (80h through FFh) represent
        !           744:                 the IBM PC extended ASCII character set. When data or header
        !           745:                 fields of this type are stored in the header, a NULL
        !           746:                 terminator may or may not be present.
        !           747:                 C example:
        !           748: 
        !           749:                 uchar str[80];
        !           750: 
        !           751: 
        !           752: ASCIIZ          ASCII string with (non-optional) NULL terminator.
        !           753:                 C example:
        !           754: 
        !           755:                 uchar str[81];
        !           756: 
        !           757: 
        !           758: 
        !           759: 
        !           760: 
        !           761: 
        !           762: _______________________________________________________________________________
        !           763: Synchronet                           13                Definition of Data Types
        !           764: 
        !           765: 
        !           766: nulstr          ASCII string immediately terminated by NULL.
        !           767:                 C example:
        !           768: 
        !           769:                 uchar *nulstr="";
        !           770: 
        !           771: 
        !           772: undef           Data buffer with undefined contents.
        !           773:                 C example:
        !           774: 
        !           775:                 uchar buf[BUF_LEN];
        !           776: 
        !           777: when_t          Date/Time stamp including time-zone adjustment information.
        !           778:                 C example:
        !           779: 
        !           780:                 typedef struct {
        !           781: 
        !           782:                     time_t  time;   // Time stamp (in local time)
        !           783:                     short   zone;   // Zone constant or Minutes (+/-) from UT
        !           784: 
        !           785:                     } when_t;
        !           786: 
        !           787:                 time:
        !           788: 
        !           789:                 A time value of 0 is invalid and indicates an uninitialized
        !           790:                 time stamp.
        !           791: 
        !           792:                 Time stamps are always stored in universal time. i.e.
        !           793:                 Regardless of what the local time zone is, Jan 1st 1994 00:00
        !           794:                 will always be stored as 2D24BD00h.
        !           795: 
        !           796:                 zone:
        !           797: 
        !           798:                 If the zone is in the range -720 to +720, it represents the
        !           799:                 number of minutes east or west of UT. Values in this range
        !           800:                 should only be used for time zones not otherwise represented
        !           801:                 here.
        !           802: 
        !           803:                 If the zone is greater than 720 or less than -720, then the
        !           804:                 following bits have special meaning:
        !           805: 
        !           806:                 (1<<12)         // Non-US time zone     (east of UT)
        !           807:                 (1<<13)         // Non-US time zone     (west of UT)
        !           808:                 (1<<14)         // U.S. time zone
        !           809:                 (1<<15)         // Daylight savings
        !           810: 
        !           811:                 The lower 12 bits (0 through 11) contain the number of minutes
        !           812:                 east or west of UT (not accounting for daylight savings).
        !           813: 
        !           814: 
        !           815: 
        !           816: 
        !           817: 
        !           818: 
        !           819: 
        !           820: 
        !           821: _______________________________________________________________________________
        !           822: Synchronet                           14                Definition of Data Types
        !           823: 
        !           824: 
        !           825:                 If the time zone is one specified in the U.S. Uniform Time Act,
        !           826:                 the following values represent the zone:
        !           827: 
        !           828:                 AST 0x40F0      // Atlantic             (-04:00)
        !           829:                 EST 0x412C      // Eastern              (-05:00)
        !           830:                 CST 0x4168      // Central              (-06:00)
        !           831:                 MST 0x41A4      // Mountain             (-07:00)
        !           832:                 PST 0x41E0      // Pacific              (-08:00)
        !           833:                 YST 0x421C      // Yukon                (-09:00)
        !           834:                 HST 0x4258      // Hawaii/Alaska        (-10:00)
        !           835:                 BST 0x4294      // Bering               (-11:00)
        !           836: 
        !           837:                 With bit 15 set, the following values represent the same zone
        !           838:                 with the presence of daylight savings:
        !           839: 
        !           840:                 ADT 0xC0F0      // Atlantic             (-03:00)
        !           841:                 EDT 0xC12C      // Eastern              (-04:00)
        !           842:                 CDT 0xC168      // Central              (-05:00)
        !           843:                 MDT 0xC1A4      // Mountain             (-06:00)
        !           844:                 PDT 0xC1E0      // Pacific              (-07:00)
        !           845:                 YDT 0xC21C      // Yukon                (-08:00)
        !           846:                 HDT 0xC258      // Hawaii/Alaska        (-09:00)
        !           847:                 BDT 0xC294      // Bering               (-10:00)
        !           848: 
        !           849:                 The following non-standard time zone specifications may also be
        !           850:                 used:
        !           851: 
        !           852:                 MID 0x2294      // Midway               (-11:00)
        !           853:                 VAN 0x21E0      // Vancouver            (-08:00)
        !           854:                 EDM 0x21A4      // Edmonton             (-07:00)
        !           855:                 WIN 0x2168      // Winnipeg             (-06:00)
        !           856:                 BOG 0x212C      // Bogota               (-05:00)
        !           857:                 CAR 0x20F0      // Caracas              (-04:00)
        !           858:                 RIO 0x20B4      // Rio de Janeiro       (-03:00)
        !           859:                 FER 0x2078      // Fernando de Noronha  (-02:00)
        !           860:                 AZO 0x203C      // Azores               (-01:00)
        !           861:                 LON 0x1000      // London               (+00:00)
        !           862:                 BER 0x103C      // Berlin               (+01:00)
        !           863:                 ATH 0x1078      // Athens               (+02:00)
        !           864:                 MOS 0x10B4      // Moscow               (+03:00)
        !           865:                 DUB 0x10F0      // Dubai                (+04:00)
        !           866:                 KAB 0x110E      // Kabul                (+04:30)
        !           867:                 KAR 0x112C      // Karachi              (+05:00)
        !           868:                 BOM 0x114A      // Bombay               (+05:30)
        !           869:                 KAT 0x1159      // Kathmandu            (+05:45)
        !           870:                 DHA 0x1168      // Dhaka                (+06:00)
        !           871:                 BAN 0x11A4      // Bangkok              (+07:00)
        !           872:                 HON 0x11E0      // Hong Kong            (+08:00)
        !           873:                 TOK 0x121C      // Tokyo                (+09:00)
        !           874:                 SYD 0x1258      // Sydney               (+10:00)
        !           875:                 NOU 0x1294      // Noumea               (+11:00)
        !           876:                 WEL 0x12D0      // Wellington           (+12:00)
        !           877: 
        !           878: 
        !           879: 
        !           880: _______________________________________________________________________________
        !           881: Synchronet                           15                Definition of Data Types
        !           882: 
        !           883: 
        !           884: fidoaddr_t      FidoNet address stored as four ushorts that represent the zone,
        !           885:                 network, node, and point (in that order).
        !           886:                 C example:
        !           887: 
        !           888:                 typedef struct {
        !           889: 
        !           890:                     ushort zone,
        !           891:                            net,
        !           892:                            node,
        !           893:                            point;
        !           894: 
        !           895:                     } fidoaddr_t;
        !           896: 
        !           897: 
        !           898: typestr_t       ASCIIZ string with ushort type prefix.
        !           899:                 C example:
        !           900: 
        !           901:                 typedef struct {
        !           902: 
        !           903:                     ushort  type;   // Specifier for type of 'str'
        !           904:                     uchar   str[];  // ASCIIZ filename or other string data
        !           905: 
        !           906:                     } typestr_t;
        !           907: 
        !           908: 
        !           909: mattach_t       File attachment information with type prefix, translation
        !           910:                 string, and filename.
        !           911:                 C example:
        !           912: 
        !           913:                 typedef struct {
        !           914: 
        !           915:                     ushort  type;   // Attachment type
        !           916:                     ushort  xlat[]; // Translations of data in attachment
        !           917:                     uchar   str[];  // ASCIIZ filename
        !           918: 
        !           919:                     } mattach_t;
        !           920: 
        !           921: vattach_t       Video file attachment information with type, compression,
        !           922:                 translation string, and filename.
        !           923:                 C example:
        !           924: 
        !           925:                 typedef struct {
        !           926: 
        !           927:                     ushort  type;   // Attachment type
        !           928:                     ushort  comp;   // Compression method
        !           929:                     ushort  xlat[]; // Translations of data in attachment
        !           930:                     uchar   str[];  // ASCIIZ filename
        !           931: 
        !           932:                     } vattach_t;
        !           933: 
        !           934: 
        !           935: 
        !           936: 
        !           937: 
        !           938: 
        !           939: _______________________________________________________________________________
        !           940: Synchronet                           16                Definition of Data Types
        !           941: 
        !           942: 
        !           943: mtext_t         Message text with translation string prefix.
        !           944:                 C example:
        !           945: 
        !           946:                 typedef struct {
        !           947: 
        !           948:                     ushort  xlat[]; // Translations of text
        !           949:                     uchar   text[]; // Actual text data
        !           950: 
        !           951:                     } mtext_t;
        !           952: 
        !           953: 
        !           954: ftext_t         Formatted message text with translation string prefix and
        !           955:                 format type.
        !           956:                 C example:
        !           957: 
        !           958:                 typedef struct {
        !           959: 
        !           960:                     ushort  type;   // See Image Types for valid types
        !           961:                     ushort  xlat[]; // Translations of data
        !           962:                     uchar   data[]; // Actual formatted text data
        !           963: 
        !           964:                     } ftext_t;
        !           965: 
        !           966: 
        !           967: membed_t        Embedded data with type prefix, translation string, and ASCIIZ
        !           968:                 description.
        !           969:                 C example:
        !           970: 
        !           971:                 typedef struct {
        !           972: 
        !           973:                     ushort  type;   // Specifier for type of 'dat'
        !           974:                     ushort  xlat[]; // Translations of embedded data
        !           975:                     uchar   name[]; // ASCIIZ char description of embedded data
        !           976:                     uchar   dat[];  // Binary data
        !           977: 
        !           978:                     } membed_t;
        !           979: 
        !           980: vembed_t        Embedded video data with type, compression method, translation
        !           981:                 string, and ASCIIZ description.
        !           982:                 C example:
        !           983: 
        !           984:                 typedef struct {
        !           985: 
        !           986:                     ushort  type;   // Specifier for type of 'dat'
        !           987:                     ushort  comp;   // Compression method
        !           988:                     ushort  xlat[]; // Translations of embedded data
        !           989:                     uchar   name[]; // ASCIIZ char description of embedded data
        !           990:                     uchar   dat[];  // Binary data
        !           991: 
        !           992:                     } vembed_t;
        !           993: 
        !           994: 
        !           995: 
        !           996: 
        !           997: 
        !           998: _______________________________________________________________________________
        !           999: Synchronet                           17                Definition of Data Types
        !          1000: 
        !          1001: 
        !          1002: File formats
        !          1003: ============
        !          1004: 
        !          1005: Index File (*.SID)
        !          1006: ------------------
        !          1007: The index file for each message base contains one record per message in the
        !          1008: base. Each record is fixed length using the following format:
        !          1009: 
        !          1010: Index Record:
        !          1011: ------------
        !          1012: C example:
        !          1013: 
        !          1014: typedef struct {
        !          1015: 
        !          1016:     ushort  to;     // 16-bit CRC of recipient name (lower case) or user number
        !          1017:     ushort  from;   // 16-bit CRC of sender name (lower case) or user number
        !          1018:     ushort  subj;   // 16-bit CRC of title/subject (lower case)
        !          1019:     ushort  attr;   // attributes (MSG_PRIVATE, MSG_READ, etc. flags)
        !          1020:     ulong   offset; // byte offset of message header in header file
        !          1021:     ulong   number; // message serial number (1 based)
        !          1022:     time_t  time;   // import date/time stamp (Unix format)
        !          1023: 
        !          1024:     } idxrec_t;
        !          1025: 
        !          1026: 
        !          1027: Example file dump (16 messages starting with message number 15):
        !          1028: ---------------------------------------------------------------
        !          1029: 000000    36 4F 13 07 2A 77 00 00   20 00 00 00 0F 00 00 00    6O..*w.. .......
        !          1030: 000010    BE 62 76 2C 36 4F 46 0A   7F B2 00 00 20 01 00 00    �bv,6OF.�.. ...
        !          1031: 000020    10 00 00 00 C7 29 78 2C   36 4F 70 6F 46 FF 00 00    ....�)x,6OpoF�..
        !          1032: 000030    20 02 00 00 11 00 00 00   AD D3 7A 2C 70 6F 13 07     .......��z,po..
        !          1033: 000040    46 FF 00 00 20 03 00 00   12 00 00 00 D6 F8 7F 2C    F�.. .......��,
        !          1034: 000050    36 4F E1 EA E7 E9 00 00   20 04 00 00 13 00 00 00    6O����.. .......
        !          1035: 000060    1E 7B 85 2C 37 0D 2E DF   4D 79 00 00 20 05 00 00    .{�,7..�My.. ...
        !          1036: 000070    14 00 00 00 5C E1 A1 2C   90 54 2D 5A 86 62 00 00    ....\�,�T-Z�b..
        !          1037: 000080    20 06 00 00 15 00 00 00   39 2E A2 2C 70 6F 1A 8B     .......9.�,po.�
        !          1038: 000090    46 FF 00 00 20 07 00 00   16 00 00 00 D0 7B A8 2C    F�.. .......�{�,
        !          1039: 0000A0    2E DF 1A 8B 4D 79 00 00   20 08 00 00 17 00 00 00    .�.�My.. .......
        !          1040: 0000B0    FF 7B A8 2C B4 D9 35 7C   23 B1 00 00 20 09 00 00    �{�,��5|#�.. ...
        !          1041: 0000C0    18 00 00 00 CE D4 BA 2C   36 4F BC D8 B2 E7 00 00    ....�Ժ,6O�ز�..
        !          1042: 0000D0    20 0A 00 00 19 00 00 00   14 5F C3 2C BA A8 4E B0     ........_�,��N�
        !          1043: 0000E0    67 76 00 00 20 0B 00 00   1A 00 00 00 6F 89 C3 2C    gv.. .......o��,
        !          1044: 0000F0    36 4F 0C 01 19 9C 00 00   20 0C 00 00 1B 00 00 00    6O...�.. .......
        !          1045: 000100    F8 30 C6 2C 36 4F FA 48   0E 55 00 00 20 0D 00 00    �0�,6O�H.U.. ...
        !          1046: 000110    1C 00 00 00 6A 94 D3 2C   36 4F F1 CE CF A2 00 00    ....j��,6O��Ϣ..
        !          1047: 000120    20 0E 00 00 1D 00 00 00   53 DB D5 2C 8D A6 21 CE     .......S��,��!�
        !          1048: 000130    F7 AB 00 00 20 0F 00 00   1E 00 00 00 31 29 DC 2C    ��.. .......1)�,
        !          1049: 
        !          1050: 
        !          1051: 
        !          1052: 
        !          1053: 
        !          1054: 
        !          1055: 
        !          1056: 
        !          1057: _______________________________________________________________________________
        !          1058: Synchronet                           18               Index (*.SID) File Format
        !          1059: 
        !          1060: 
        !          1061: Field descriptions:
        !          1062: ------------------
        !          1063: To:
        !          1064: The 'To' field is the CRC-16 of the name of the intended recipient agent of
        !          1065: this message or the intended recipient's user number. If the CRC is stored, the
        !          1066: text must be converted to lower case (A-Z changed to a-z) before the CRC is
        !          1067: calculated. If the message is forwarded to another agent, the original or new
        !          1068: index record must be changed to contain the CRC-16 of the new recipient name or
        !          1069: user number. This field must always contain the recipient user number for local
        !          1070: e-mail on a Synchronet BBS. Outbound netmail stored in the Synchronet local
        !          1071: e-mail message base will contain 0 in this field.
        !          1072: 
        !          1073: From:
        !          1074: This field, similar to the 'To' field, contains the CRC-16 of the name of the
        !          1075: sending agent of this message or the sender's user number. If the CRC is
        !          1076: stored, the text must be converted to lower case (A-Z changed to a-z) before
        !          1077: the CRC is calculated. If the message is forwarded to another agent, the
        !          1078: original or new index record must be changed to contain the CRC-16 of the new
        !          1079: sender name or user number. If the message was imported into the local e-mail
        !          1080: message base on a Synchronet BBS via netmail, this field will contain 0.
        !          1081: 
        !          1082: Subj:
        !          1083: The 'Subj' field contains the CRC-16 of the message's subject. The subject
        !          1084: must be converted to lower case (A-Z changed to a-z) and all preceeding
        !          1085: "re: "'s and "re:"'s removed before calculating the CRC-16.
        !          1086: 
        !          1087: Attr:
        !          1088: This ushort is a bit field of the specific attributes for this message.
        !          1089: It is a clone of the 'attr' element of the msghdr_t structure.
        !          1090: 
        !          1091: Offset:
        !          1092: This ulong is the offset (in bytes) in the header file for this message's
        !          1093: header record.
        !          1094: 
        !          1095: Number:
        !          1096: This ulong is the serial number of this message. Valid values are 1 through
        !          1097: 0xffffffff. No two index records in the same message base may have the same
        !          1098: message number. All index records must have sequential, but not necessarily
        !          1099: consequetive, message numbers.
        !          1100: 
        !          1101: Time:
        !          1102: This field is the date/time stamp the message was imported to or posted in
        !          1103: the message base. It is a clone of the 'when_imported.time' element of the
        !          1104: msghdr_t structure.
        !          1105: 
        !          1106: 
        !          1107: 
        !          1108: 
        !          1109: 
        !          1110: 
        !          1111: 
        !          1112: 
        !          1113: 
        !          1114: 
        !          1115: 
        !          1116: _______________________________________________________________________________
        !          1117: Synchronet                           19               Index (*.SID) File Format
        !          1118: 
        !          1119: 
        !          1120: Header File (*.SHD)
        !          1121: ===================
        !          1122: 
        !          1123: Each SMB header file is made up of two distinct sections: base header records
        !          1124: and message header records (usually the bulk of the file).
        !          1125: 
        !          1126: Base Header Records:
        !          1127: -------------------
        !          1128: Base header records are blocks of data that apply to the entire message base
        !          1129: and are of variable length. This specification defines only one base header
        !          1130: record, the "Status info" (smbstatus_t) record. This status info record must be
        !          1131: the first base header record in the file and must be modified if additional
        !          1132: base header records are added.
        !          1133: 
        !          1134: Additional header records allow other developers to store configuration and
        !          1135: status information particular to their application needs. It also allows for
        !          1136: future header record definitions as part of this specification without causing
        !          1137: backward compatibility issues.
        !          1138: 
        !          1139: Each base header record contains a fixed length portion (smbhdr_t) and an
        !          1140: optional variable length portion.
        !          1141: 
        !          1142: Whenever a base header record is read or updated (written), it must first
        !          1143: be successfully locked and subsequently unlocked.
        !          1144: 
        !          1145: The first base header record (Status Info) is used as a semaphore when writing
        !          1146: to the message index (.SID) file and, when using the Hyper Allocation storage
        !          1147: method, writing to the message data (.SDT) file. This record must be
        !          1148: succesfully locked before writing and subsequently unlocked. This is to insure
        !          1149: that multiple applications simultaneously writing to the same message base
        !          1150: does result in corrrupted data.
        !          1151: 
        !          1152: 
        !          1153: Message Header Records:
        !          1154: ----------------------
        !          1155: Following the last base header record is the first message header record. Each
        !          1156: header record is stored in one or more 256 byte blocks. There must be exactly
        !          1157: one active message header record for every index record in the index file.
        !          1158: (Note: This does not include deleted message headers that have not been
        !          1159: overwritten by a new message header).
        !          1160: 
        !          1161: Each message header record contains a fixed length portion (msghdr_t), a list
        !          1162: of zero or more fixed length data fields (dfield_t), and a list of three or
        !          1163: more variable length header fields (hfield_t).
        !          1164: 
        !          1165: The value of the data stored in the zero or more unused bytes of the last
        !          1166: header record block have an undefined value, though whenever possible
        !          1167: developers should initialize to binary zero for human readability.
        !          1168: 
        !          1169: Whenever a message header record is read or updated (written), it must first
        !          1170: be successfully locked and subsequently unlocked.
        !          1171: 
        !          1172: 
        !          1173: 
        !          1174: 
        !          1175: _______________________________________________________________________________
        !          1176: Synchronet                           20              Header File (*.SHD) Format
        !          1177: 
        !          1178: 
        !          1179: Base Header Record (Fixed Portion):
        !          1180: ----------------------------------
        !          1181: C example:
        !          1182: 
        !          1183: typedef struct {
        !          1184: 
        !          1185:     uchar   id[4];          // text or binary unique hdr ID
        !          1186:     ushort  version;        // version number (initially 100h for 1.00)
        !          1187:     ushort  length;         // length including this struct
        !          1188: 
        !          1189:     } smbhdr_t;
        !          1190: 
        !          1191: 
        !          1192: Base Header Record Field Descriptions:
        !          1193: -------------------------------------
        !          1194: Id:
        !          1195: This is a four byte unique ID identifying the type of the base header record.
        !          1196: The bytes may contain any value, but printable ASCII characters are preferred.
        !          1197: The only ID defined in this specification is "SMB^Z" used by the Status Info
        !          1198: base header record.
        !          1199: 
        !          1200: Version:
        !          1201: This is a version number of the base header record type. Base header records
        !          1202: of different versions may have different formats or contain different
        !          1203: information. This is to aid the application in determining if the record
        !          1204: is pertinent and if so, to what degree. The Status Info base header record
        !          1205: uses this version field to define the version of the format for the entire
        !          1206: message base (currently 0x121 for version 1.21).
        !          1207: 
        !          1208: Length:
        !          1209: This is entire length in bytes of this header record (including both fixed
        !          1210: and variable portions).
        !          1211: 
        !          1212: 
        !          1213: Base Header #1 (Status info) Record (Variable Portion):
        !          1214: ------------------------------------------------------
        !          1215: C example:
        !          1216: 
        !          1217: typedef struct {
        !          1218: 
        !          1219:     ulong   last_msg;       // last message number posted or imported
        !          1220:     ulong   total_msgs;     // total messages currently in message base
        !          1221:     ulong   header_offset;  // byte offset to first header record
        !          1222:     ulong   max_crcs;       // Maximum number of CRCs to keep in history
        !          1223:     ulong   max_msgs;       // Maximum number of messages to keep in base
        !          1224:     ushort  max_age;        // Maximum age of messages (days) to keep in base
        !          1225:     ushort  attr;           // Attribute bits
        !          1226: 
        !          1227:     } smbstatus_t;
        !          1228: 
        !          1229: 
        !          1230: 
        !          1231: 
        !          1232: 
        !          1233: 
        !          1234: _______________________________________________________________________________
        !          1235: Synchronet                           21              Header File (*.SHD) Format
        !          1236: 
        !          1237: 
        !          1238: Base Header #1 (Status Info) Record (Variable Portion) Field Descriptions:
        !          1239: -------------------------------------------------------------------------
        !          1240: Last_msg:
        !          1241: This is the serial number of the last message imported or posted into this
        !          1242: message base. The index, header, and data records for this message may possibly
        !          1243: not exist (due to deletion). This field is used for determining the message
        !          1244: number to give to a new message being imported or posted into this message
        !          1245: base. This field must be updated for every message added to the message base.
        !          1246: 
        !          1247: Total_msgs:
        !          1248: This is the total number of active messages currently in the message base.
        !          1249: This number should match the number of records in the index (.SID) file
        !          1250: and active header records in the header (.SHD) file. This field must be
        !          1251: updated whenever a message is added to or removed from the message base.
        !          1252: 
        !          1253: Header_offset:
        !          1254: This is the byte offset to the first message header record. It is useful
        !          1255: for skipping all the base header records and going directly to the first
        !          1256: message header record.
        !          1257: 
        !          1258: Max_crcs:
        !          1259: This is the maximum number of message CRCs to store in the CRC history (.SCH)
        !          1260: file for duplicate message checking. If this field contains 0, then duplicate
        !          1261: message checking is disabled.
        !          1262: 
        !          1263: Max_msgs:
        !          1264: This is the preferred maximum number of messages to keep in this message
        !          1265: base as specified by the system operator. It is used by maintenance programs
        !          1266: that trim the message base down by removing old messages. This field should
        !          1267: be ignored by applications importing or posting messages allowing them to
        !          1268: exceed this maximum at will.
        !          1269: 
        !          1270: Max_age:
        !          1271: This field is the maximum age (in days) of messages to keep in the message
        !          1272: base. It is used by maintenance programs to purge out-dated messages from
        !          1273: the message base.
        !          1274: 
        !          1275: 
        !          1276: 
        !          1277: 
        !          1278: 
        !          1279: 
        !          1280: 
        !          1281: 
        !          1282: 
        !          1283: 
        !          1284: 
        !          1285: 
        !          1286: 
        !          1287: 
        !          1288: 
        !          1289: 
        !          1290: 
        !          1291: 
        !          1292: 
        !          1293: _______________________________________________________________________________
        !          1294: Synchronet                           22              Header File (*.SHD) Format
        !          1295: 
        !          1296: 
        !          1297: Attr:
        !          1298: This is a bit field containing specific attributes (or flags) that may define
        !          1299: the way messages are stored or retrieved from the this message base. The
        !          1300: following attributes are defined:
        !          1301: 
        !          1302:     SMB_EMAIL       (1<<0)
        !          1303: 
        !          1304:     Indicates the message base is specifically for messages to or from local
        !          1305:     users. When this bit is set, the idxrec.to and idxrec.from fields will
        !          1306:     contain the user numbers (or 0 for non-user destination/source) instead of
        !          1307:     the CRC-16 of the agent name.
        !          1308: 
        !          1309:     SMB_HYPERALLOC  (1<<1)
        !          1310: 
        !          1311:     Indicates the message base uses the Hyper Allocation storage method. This
        !          1312:     bit should not be cleared by an application without first deleting all the
        !          1313:     messages in the message base. This is due to the fact the Hyper Allocation
        !          1314:     is not downward compatible with the Self-packing and Fast Allocation
        !          1315:     storage methods.
        !          1316: 
        !          1317: When used with Synchronet BBS software, a message base must NOT have both of
        !          1318: the above attributes set. The only message base that should have the SMB_EMAIL
        !          1319: attribute set is the DATA\MAIL message base.
        !          1320: 
        !          1321: 
        !          1322: 
        !          1323: 
        !          1324: 
        !          1325: 
        !          1326: 
        !          1327: 
        !          1328: 
        !          1329: 
        !          1330: 
        !          1331: 
        !          1332: 
        !          1333: 
        !          1334: 
        !          1335: 
        !          1336: 
        !          1337: 
        !          1338: 
        !          1339: 
        !          1340: 
        !          1341: 
        !          1342: 
        !          1343: 
        !          1344: 
        !          1345: 
        !          1346: 
        !          1347: 
        !          1348: 
        !          1349: 
        !          1350: 
        !          1351: 
        !          1352: _______________________________________________________________________________
        !          1353: Synchronet                           23              Header File (*.SHD) Format
        !          1354: 
        !          1355: 
        !          1356: Base Header #1 (Status info) Record Contents:
        !          1357: --------------------------------------------
        !          1358: smbhdr.id="SMB\x1a";        // SMB^Z
        !          1359: smbhdr.version=0x121;       // v1.21
        !          1360: smbhdr.length=sizeof(smbhdr_t)+sizeof(smbstatus_t); smbstatus_t status;
        !          1361: 
        !          1362: 
        !          1363: Additional Base Headers:
        !          1364: -----------------------
        !          1365: Additional headers from developers must have initial 8 bytes in smbhdr_t
        !          1366: format, length must include size of smbhdr_t, and header_offset of smbstatus_t
        !          1367: must be changed to include the size of the additional header(s).
        !          1368: 
        !          1369: 
        !          1370: Example file dump (base header portion only):
        !          1371: --------------------------------------------
        !          1372: 000000    53 4D 42 1A 20 01 20 00   F4 01 00 00 F4 01 00 00    SMB. . .�...�...
        !          1373: 000010    20 00 00 00 D0 07 00 00   D0 07 00 00 00 00 00 00     ...�...�.......
        !          1374: 
        !          1375: 
        !          1376: 
        !          1377: 
        !          1378: 
        !          1379: 
        !          1380: 
        !          1381: 
        !          1382: 
        !          1383: 
        !          1384: 
        !          1385: 
        !          1386: 
        !          1387: 
        !          1388: 
        !          1389: 
        !          1390: 
        !          1391: 
        !          1392: 
        !          1393: 
        !          1394: 
        !          1395: 
        !          1396: 
        !          1397: 
        !          1398: 
        !          1399: 
        !          1400: 
        !          1401: 
        !          1402: 
        !          1403: 
        !          1404: 
        !          1405: 
        !          1406: 
        !          1407: 
        !          1408: 
        !          1409: 
        !          1410: 
        !          1411: _______________________________________________________________________________
        !          1412: Synchronet                           24              Header File (*.SHD) Format
        !          1413: 
        !          1414: 
        !          1415: Message Header Record (Fixed portion):
        !          1416: -------------------------------------
        !          1417: C example:
        !          1418: 
        !          1419: typedef struct {
        !          1420: 
        !          1421:     uchar   id[4];          // SHD^Z (same for all types and versions)
        !          1422:     ushort  type;           // Message type (this is the definition of type 0)
        !          1423:     ushort  version;        // Version of type (initially 100h for 1.00)
        !          1424:     ushort  length;         // Total length of fixed portion + all fields
        !          1425:     ushort  attr;           // Attributes (bit field) (duplicated in SID)
        !          1426:     ulong   auxattr;        // Auxillary attributes (bit field)
        !          1427:     ulong   netattr;        // Network attributes (bit field)
        !          1428:     when_t  when_written;   // Date/Time message was originally created
        !          1429:     when_t  when_imported;  // Date/Time message was imported (locally)
        !          1430:     ulong   number;         // Message number (unique, not necessarily seq.)
        !          1431:     ulong   thread_orig;    // Original message number in thread
        !          1432:     ulong   thread_next;    // Next message in thread
        !          1433:     ulong   thread_first;   // Number of first reply to this message
        !          1434:     uchar   reserved[16];   // 16 reserved bytes for future use
        !          1435:     ulong   offset;         // Offset for buffer into data file (0 or mod 256)
        !          1436:     ushort  total_dfields;  // Total number of data fields
        !          1437: 
        !          1438:     } msghdr_t;
        !          1439: 
        !          1440: typedef struct {
        !          1441: 
        !          1442:     ushort  type;           // See "Data Field Types" values
        !          1443:     ulong   offset;         // Offset into buffer 
        !          1444:     ulong   length;         // Length of data field in buffer
        !          1445: 
        !          1446:     } dfield_t;
        !          1447: 
        !          1448: typedef struct {
        !          1449: 
        !          1450:     ushort  type;           // See "Header Field Types" for values
        !          1451:     ushort  length;         // Length of buffer
        !          1452:     uchar   dat[length];
        !          1453: 
        !          1454:     } hfield_t;
        !          1455: 
        !          1456: 
        !          1457: 
        !          1458: 
        !          1459: 
        !          1460: 
        !          1461: 
        !          1462: 
        !          1463: 
        !          1464: 
        !          1465: 
        !          1466: 
        !          1467: 
        !          1468: 
        !          1469: 
        !          1470: _______________________________________________________________________________
        !          1471: Synchronet                           25              Header File (*.SHD) Format
        !          1472: 
        !          1473: 
        !          1474: Example file dump (one header record, both fixed and variable length portions):
        !          1475: ------------------------------------------------------------------------------
        !          1476: 000020    53 48 44 1A 00 00 20 01   F5 00 00 00 00 00 00 00    SHD... .�.......
        !          1477: 000030    00 00 00 00 46 DB F7 2C   00 00 7D D7 29 2D 00 00    ....F��,..}�)-..
        !          1478: 000040    01 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00    ................
        !          1479: 000050    00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00    ................
        !          1480: 000060    00 00 00 00 02 00 00 00   00 00 00 00 4A 01 00 00    ............J...
        !          1481: 000070    02 00 4A 01 00 00 53 00   00 00 00 00 13 00 4D 61    ..J...S.......Ma
        !          1482: 000080    72 69 61 6E 6E 65 20 4D   6F 6E 74 67 6F 6D 65 72    rianne Montgomer
        !          1483: 000090    79 30 00 0C 00 43 61 72   6F 6C 20 47 61 69 73 65    y0...Carol Gaise
        !          1484: 0000A0    72 60 00 07 00 46 61 72   6E 68 61 6D A4 00 14 00    r`...Farnham�...
        !          1485: 0000B0    31 3A 31 33 38 2F 31 30   32 2E 30 20 32 63 66 38    1:138/102.0 2cf8
        !          1486: 0000C0    30 35 37 36 A5 00 14 00   31 3A 33 34 33 2F 31 30    0576�...1:343/10
        !          1487: 0000D0    30 2E 30 20 32 63 66 33   62 39 30 61 A3 00 23 00    0.0 2cf3b90a�.#.
        !          1488: 0000E0    31 33 38 2F 31 30 32 20   31 20 32 37 30 2F 31 30    138/102 1 270/10
        !          1489: 0000F0    31 20 32 30 39 2F 32 30   39 20 31 30 33 2F 30 20    1 209/209 103/0 
        !          1490: 000100    33 35 35 02 00 02 00 02   00 03 00 08 00 01 00 8A    355............�
        !          1491: 000110    00 66 00 00 00 00 00 00   00 00 00 00 00 00 00 00    .f..............
        !          1492: 
        !          1493: 
        !          1494: 
        !          1495: 
        !          1496: 
        !          1497: 
        !          1498: 
        !          1499: 
        !          1500: 
        !          1501: 
        !          1502: 
        !          1503: 
        !          1504: 
        !          1505: 
        !          1506: 
        !          1507: 
        !          1508: 
        !          1509: 
        !          1510: 
        !          1511: 
        !          1512: 
        !          1513: 
        !          1514: 
        !          1515: 
        !          1516: 
        !          1517: 
        !          1518: 
        !          1519: 
        !          1520: 
        !          1521: 
        !          1522: 
        !          1523: 
        !          1524: 
        !          1525: 
        !          1526: 
        !          1527: 
        !          1528: 
        !          1529: _______________________________________________________________________________
        !          1530: Synchronet                           26              Header File (*.SHD) Format
        !          1531: 
        !          1532: 
        !          1533: Contents of example header:
        !          1534: --------------------------
        !          1535: id                   SHD^Z
        !          1536: type                 0000h
        !          1537: version              0120h
        !          1538: length               245
        !          1539: attr                 0000h
        !          1540: auxattr              00000000h
        !          1541: netattr              00000000h
        !          1542: when_written         Sat Nov 27 17:57:10 1993
        !          1543: when_imported        Tue Jan 04 15:54:21 1994
        !          1544: number               1
        !          1545: thread_orig          0
        !          1546: thread_next          0
        !          1547: thread_first         0
        !          1548: reserved[16]         
        !          1549: offset               0
        !          1550: total_dfields        2
        !          1551: 
        !          1552: dfield[0].type       00h
        !          1553: dfield[0].offset     0
        !          1554: dfield[0].length     330
        !          1555: dfield[1].type       02h
        !          1556: dfield[1].offset     330
        !          1557: dfield[1].length     83
        !          1558: 
        !          1559: hfield[0].type       00h
        !          1560: hfield[0].length     19
        !          1561: hfield[0]_dat        Marianne Montgomery
        !          1562: hfield[1].type       30h
        !          1563: hfield[1].length     12
        !          1564: hfield[1]_dat        Carol Gaiser
        !          1565: hfield[2].type       60h
        !          1566: hfield[2].length     7
        !          1567: hfield[2]_dat        Farnham
        !          1568: hfield[3].type       A4h
        !          1569: hfield[3].length     20
        !          1570: hfield[3]_dat        1:138/102.0 2cf80576
        !          1571: hfield[4].type       A5h
        !          1572: hfield[4].length     20
        !          1573: hfield[4]_dat        1:343/100.0 2cf3b90a
        !          1574: hfield[5].type       A3h
        !          1575: hfield[5].length     35
        !          1576: hfield[5]_dat        138/102 1 270/101 209/209 103/0 355
        !          1577: hfield[6].type       02h
        !          1578: hfield[6].length     2
        !          1579: hfield[6]_dat        02 00
        !          1580: hfield[7].type       03h
        !          1581: hfield[7].length     8
        !          1582: hfield[7]_dat        01 00 8A 00 66 00 00 00
        !          1583: 
        !          1584: 
        !          1585: 
        !          1586: 
        !          1587: 
        !          1588: _______________________________________________________________________________
        !          1589: Synchronet                           27              Header File (*.SHD) Format
        !          1590: 
        !          1591: 
        !          1592: Fixed Portion Field descriptions:
        !          1593: --------------------------------
        !          1594: Id:
        !          1595: This field (regardless of the header type or version) must always contain the
        !          1596: the string "SHD^Z". This is to aid in the restoration of a corrupted header
        !          1597: file and give a visual indication of the beginning of a new header record when
        !          1598: viewing dumps of the header file.
        !          1599: 
        !          1600: Type:
        !          1601: This is the message header type. Only one type is currently defined by this
        !          1602: specification (type 0). Any and all future header types will have the first
        !          1603: 4 fields (10 bytes) in the same format of type 0. This allows other types
        !          1604: (with different lengths) to be skipped because the 4th field (length) will
        !          1605: always be in the same position.
        !          1606: 
        !          1607: Version:
        !          1608: This is the version of this header type. This specification defines version
        !          1609: 1.21 of message header type 0 (stored as 121h).
        !          1610: 
        !          1611: Length:
        !          1612: This is the total length of this message header record (including both fixed
        !          1613: and variable length portions, but NOT including unused block space).
        !          1614: 
        !          1615: Attr:
        !          1616: This is a bit field (16-bit) containing basic message attributes (flags) for
        !          1617: this message. An exact duplicate of this field is stored in the index file as
        !          1618: well. They must always match.
        !          1619: 
        !          1620: Auxattr:
        !          1621: This is a bit field (32-bit) containing the auxillary attributes (flags) for
        !          1622: this message. The attributes stored in this variable are more specific in
        !          1623: nature and less critical than those in the Attr field.
        !          1624: 
        !          1625: Netattr:
        !          1626: This is a bit field (32-bit) containing the network attributes (flags) for this
        !          1627: message. The attributes stored in this variable are related solely to message
        !          1628: networking.
        !          1629: 
        !          1630: When_written:
        !          1631: This is the date and time when the message was originally created.
        !          1632: 
        !          1633: When_imported:
        !          1634: This is the date and time when the message was posted on or imported into the
        !          1635: local message system.
        !          1636: 
        !          1637: Number:
        !          1638: This is the message's unique serial number (from 1 to FFFFFFFFh). This field
        !          1639: is duplicated in the index file. They must always match.
        !          1640: 
        !          1641: 
        !          1642: 
        !          1643: 
        !          1644: 
        !          1645: 
        !          1646: 
        !          1647: _______________________________________________________________________________
        !          1648: Synchronet                           28              Header File (*.SHD) Format
        !          1649: 
        !          1650: 
        !          1651: Thread_orig:
        !          1652: If this message is a reply, then this field contains the number of the original
        !          1653: message that was replied to. If this message was not a reply, this field will
        !          1654: contain the value 0.
        !          1655: 
        !          1656: Thread_next:
        !          1657: If this message is a reply, and there are later replies to that message
        !          1658: (the message number contained in the Thread_orig field), then this field will
        !          1659: contain the number of the next reply in the chain. If this message is the only
        !          1660: reply to the orignal message, this field will contain the value 0.
        !          1661: 
        !          1662: Thread_first:
        !          1663: If there are any replies to this message (after it has been posted), this field
        !          1664: will contain the number of the first reply to this message. If there are no
        !          1665: replies to this message, this field will contain the value 0.
        !          1666: 
        !          1667: Reserved:
        !          1668: Unused bytes, reserved for future definition in the message header type 0
        !          1669: specification.
        !          1670: 
        !          1671: Offset:
        !          1672: The byte offset into the data file, specifying the start of the buffer for
        !          1673: all data associated with this message. This value must be either 0 or modula
        !          1674: 256. When retrieving the actual data portion of data fields, the physical
        !          1675: offset into the file will be the offset of the message data buffer (this field)
        !          1676: plus the offset of the individual data field (msghdr_t.offset+dfield_t.offset).
        !          1677: 
        !          1678: Total_dfields:
        !          1679: This field contains the total number of data fields associated with this
        !          1680: message. The value of this field must match the actual number of data fields
        !          1681: stored in the header (dfield_t data types following the fixed portion of the
        !          1682: message header).
        !          1683: 
        !          1684: 
        !          1685: Variable Portion Field descriptions:
        !          1686: -----------------------------------
        !          1687: See the Header Field Type and Data Field Type sections for the descriptions
        !          1688: of the values contained in these fields.
        !          1689: 
        !          1690: 
        !          1691: 
        !          1692: 
        !          1693: 
        !          1694: 
        !          1695: 
        !          1696: 
        !          1697: 
        !          1698: 
        !          1699: 
        !          1700: 
        !          1701: 
        !          1702: 
        !          1703: 
        !          1704: 
        !          1705: 
        !          1706: _______________________________________________________________________________
        !          1707: Synchronet                           29              Header File (*.SHD) Format
        !          1708: 
        !          1709: 
        !          1710: Message Header Block Allocation (*.SHA)
        !          1711: =======================================
        !          1712: 
        !          1713: If this message base uses the Hyper Allocation storage method (the
        !          1714: SMB_HYPERALLOC bit is set in the smbstatus_t.attr field), then this file is
        !          1715: not created or used.
        !          1716: 
        !          1717: This file contains no header or signature data. Each byte (uchar) in the file
        !          1718: specifies the allocation state of the corresponding 256 byte block in the
        !          1719: header (*.SHD) file. A value of 0 indicates a free header block, and a value of
        !          1720: 1 indicates an allocated block. Other non-zero values are undefined.
        !          1721: 
        !          1722: This file must always be opened DENY ALL (non-shareable).
        !          1723: 
        !          1724: 
        !          1725: 
        !          1726: 
        !          1727: 
        !          1728: 
        !          1729: 
        !          1730: 
        !          1731: 
        !          1732: 
        !          1733: 
        !          1734: 
        !          1735: 
        !          1736: 
        !          1737: 
        !          1738: 
        !          1739: 
        !          1740: 
        !          1741: 
        !          1742: 
        !          1743: 
        !          1744: 
        !          1745: 
        !          1746: 
        !          1747: 
        !          1748: 
        !          1749: 
        !          1750: 
        !          1751: 
        !          1752: 
        !          1753: 
        !          1754: 
        !          1755: 
        !          1756: 
        !          1757: 
        !          1758: 
        !          1759: 
        !          1760: 
        !          1761: 
        !          1762: 
        !          1763: 
        !          1764: 
        !          1765: _______________________________________________________________________________
        !          1766: Synchronet                           30   Header Allocation File (*.SHA) Format
        !          1767: 
        !          1768: 
        !          1769: Message Data (*.SDT)
        !          1770: ====================
        !          1771: 
        !          1772: This file contains no header or signature data. It contains the text and other
        !          1773: embedded data for the messages in a single message base. The data for each
        !          1774: message always begins on a 256 byte block boundary. The data in the unused
        !          1775: portion of a data block is undefined, but should be initialized to NULL
        !          1776: whenever possible.
        !          1777: 
        !          1778: This file must always be opened DENY NONE (shareable).
        !          1779: 
        !          1780: Data fields of type TEXT_BODY and TEXT_TAIL must have all trailing white space
        !          1781: and control characters removed (i.e. the last character of the data record
        !          1782: must be in the range 21h to FFh). The only exception to this rule, is if the
        !          1783: TEXT_BODY is terminated with multiple contiguous CRLFs, only the last CRLF
        !          1784: should be removed. A CRLF should always be appended to the text data when it is
        !          1785: displayed.
        !          1786: 
        !          1787: When reading from this file, it is a good idea to make sure the message header
        !          1788: for the data being read is currently locked (though no single message header
        !          1789: should be locked for extended durations of time). This will insure that no
        !          1790: other application will write to this portion of the file while it's being
        !          1791: read (read from disk, not displayed).
        !          1792: 
        !          1793: When using the Hyper Allocation storage method, the Status Info message base
        !          1794: header must be successfully locked before writing to this file and subsequently
        !          1795: unlocked.
        !          1796: 
        !          1797: 
        !          1798: 
        !          1799: 
        !          1800: 
        !          1801: 
        !          1802: 
        !          1803: 
        !          1804: 
        !          1805: 
        !          1806: 
        !          1807: 
        !          1808: 
        !          1809: 
        !          1810: 
        !          1811: 
        !          1812: 
        !          1813: 
        !          1814: 
        !          1815: 
        !          1816: 
        !          1817: 
        !          1818: 
        !          1819: 
        !          1820: 
        !          1821: 
        !          1822: 
        !          1823: 
        !          1824: _______________________________________________________________________________
        !          1825: Synchronet                           31                Data File (*.SDT) Format
        !          1826: 
        !          1827: 
        !          1828: Message Data Block Allocation (*.SDA)
        !          1829: =====================================
        !          1830: 
        !          1831: If this message base uses the Hyper Allocation storage method (the
        !          1832: SMB_HYPERALLOC bit is set in the smbstatus_t.attr field), then this file is
        !          1833: not created or used.
        !          1834: 
        !          1835: This file contains no header or signature data. Each word (ushort) in the file
        !          1836: specifies the allocation state of the corresponding 256 byte block in the data
        !          1837: (*.SDT) file. A value of 0 indicates a free block, and a non-zero value
        !          1838: indicates the number of message header records associated with this message
        !          1839: data (most often 1). Each block can be used by up to 65,535 header records.
        !          1840: 
        !          1841: This file must always be opened DENY ALL (non-shareable).
        !          1842: 
        !          1843: 
        !          1844: 
        !          1845: 
        !          1846: 
        !          1847: 
        !          1848: 
        !          1849: 
        !          1850: 
        !          1851: 
        !          1852: 
        !          1853: 
        !          1854: 
        !          1855: 
        !          1856: 
        !          1857: 
        !          1858: 
        !          1859: 
        !          1860: 
        !          1861: 
        !          1862: 
        !          1863: 
        !          1864: 
        !          1865: 
        !          1866: 
        !          1867: 
        !          1868: 
        !          1869: 
        !          1870: 
        !          1871: 
        !          1872: 
        !          1873: 
        !          1874: 
        !          1875: 
        !          1876: 
        !          1877: 
        !          1878: 
        !          1879: 
        !          1880: 
        !          1881: 
        !          1882: 
        !          1883: _______________________________________________________________________________
        !          1884: Synchronet                           32     Data Allocation File (*.SDA) Format
        !          1885: 
        !          1886: 
        !          1887: CRC history for duplicate message checking (*.SCH)
        !          1888: ==================================================
        !          1889: 
        !          1890: This file is optional and contains no header or signature data. Each long word
        !          1891: (ulong) in the file contains a CRC-32 of previously posted/imported messages.
        !          1892: These CRCs can be used to check a candidate message for posting/import to be
        !          1893: sure the message isn't a duplicate created by human or program error. The
        !          1894: maximum number of CRCs to store is defined in the first message base header
        !          1895: record (smbstatus_t.max_crcs).
        !          1896: 
        !          1897: The CRC is calculated on the first TEXT_BODY data field before any translations
        !          1898: are applied (e.g. encoding, compression, encryption).
        !          1899: 
        !          1900: This file must always be opened DENY ALL (non-shareable).
        !          1901: 
        !          1902: 
        !          1903: 
        !          1904: 
        !          1905: 
        !          1906: 
        !          1907: 
        !          1908: 
        !          1909: 
        !          1910: 
        !          1911: 
        !          1912: 
        !          1913: 
        !          1914: 
        !          1915: 
        !          1916: 
        !          1917: 
        !          1918: 
        !          1919: 
        !          1920: 
        !          1921: 
        !          1922: 
        !          1923: 
        !          1924: 
        !          1925: 
        !          1926: 
        !          1927: 
        !          1928: 
        !          1929: 
        !          1930: 
        !          1931: 
        !          1932: 
        !          1933: 
        !          1934: 
        !          1935: 
        !          1936: 
        !          1937: 
        !          1938: 
        !          1939: 
        !          1940: 
        !          1941: 
        !          1942: _______________________________________________________________________________
        !          1943: Synchronet                           33         CRC History File (*.SCH) Format
        !          1944: 
        !          1945: 
        !          1946: Header Field Types:
        !          1947: ==================
        !          1948: 
        !          1949: These are the defined valid values for hfield_t.type:
        !          1950: 
        !          1951: Name     : SENDER
        !          1952: Value    : 00h
        !          1953: Data     : ASCII
        !          1954: Multiple : Yes, order significant
        !          1955: Required : Yes
        !          1956: Summary  : Name of agent that sent this message
        !          1957: 
        !          1958: If blank (0 length or nulstr), assumed "Anonymous". If multiple SENDER fields
        !          1959: exist, then the message has been forwarded and the order of the fields in the
        !          1960: record must match the forwarding order (chronologically). When forwarding a
        !          1961: message, the original SENDER field should be left intact and new SENDER,
        !          1962: FORWARDED, and RECIPIENT fields added to the end of the record.
        !          1963: 
        !          1964: 
        !          1965: Name     : SENDERAGENT
        !          1966: Value    : 01h
        !          1967: Data     : ushort
        !          1968: Multiple : Yes, order significant
        !          1969: Required : No
        !          1970: Default  : AGENT_PERSON or previous SENDERAGENT if exists
        !          1971: Summary  : Type of agent that sent this message
        !          1972: 
        !          1973: If multiple SENDER fields exist, then the message has been forwarded. If any of the
        !          1974: forwarding agents is of a type other than AGENT_PERSON, then this field must
        !          1975: follow that SENDER field to specify the agent type.
        !          1976: 
        !          1977: Name     : SENDERNETTYPE
        !          1978: Value    : 02h
        !          1979: Data     : ushort
        !          1980: Multiple : Yes, order significant
        !          1981: Required : No
        !          1982: Default  : NET_NONE or previous SENDERNETTYPE if exists
        !          1983: Summary  : Type of network message was sent from
        !          1984: 
        !          1985: If multiple SENDERNETADDR fields are included, a SENDERNETTYPE field should be
        !          1986: included before each to determine what data type the address is stored in.
        !          1987: 
        !          1988: Name     : SENDERNETADDR
        !          1989: Value    : 03h
        !          1990: Data     : undef
        !          1991: Multiple : Yes, order significant
        !          1992: Required : No
        !          1993: Default  : Previous SENDERNETADDR if exists
        !          1994: Summary  : Network address for agent that sent this message
        !          1995: 
        !          1996: The SENDERNETTYPE field indicates the data type of this field. If the
        !          1997: SENDERNETTYPE is of type NET_INTERNET, the local-part of the Internet
        !          1998: address is optional. If the local-part separator character ('@') is omitted,
        !          1999: the SENDER field is assumed to be the local-part of the address.
        !          2000: 
        !          2001: _______________________________________________________________________________
        !          2002: Synchronet                           34                      Header Field Types
        !          2003: 
        !          2004: 
        !          2005: 
        !          2006: Name     : SENDEREXT
        !          2007: Value    : 04h
        !          2008: Data     : ASCII
        !          2009: Multiple : Yes, order significant
        !          2010: Required : No
        !          2011: Default  : Previous SENDEREXT if exists
        !          2012: Summary  : Extension of sending agent
        !          2013: 
        !          2014: This field is useful for storing the sending agent's extension, when the
        !          2015: agent's extension binds more tightly than the agent's name.
        !          2016: 
        !          2017: For example, Synchronet Multinode BBS Software stores local e-mail with the
        !          2018: sending and receiving agent's user numbers stored as their respective
        !          2019: extensions. This is done so that if a user name changes for some reason,
        !          2020: messages will not "disappear" from the user's mail box.
        !          2021: 
        !          2022: If the SMB_EMAIL status header attribute is set, then the "From" field in the
        !          2023: index must contain the binary value of this field rather than the CRC-16 of the
        !          2024: SENDER (name) field.
        !          2025: 
        !          2026: Name     : SENDERPOS
        !          2027: Value    : 05h
        !          2028: Data     : ASCII
        !          2029: Multiple : Yes, order significant
        !          2030: Required : No
        !          2031: Default  : Previous SENDERPOS if exists
        !          2032: Summary  : Position of sending agent
        !          2033: 
        !          2034: Primarily for documentary purposes, this field contains the position of the
        !          2035: sending agent (i.e. President, Sysop, C.E.O., MIS Director, etc).
        !          2036: 
        !          2037: It can also be useful for getting a message or reply to the intended
        !          2038: recipient when the agent name is not located or is unknown, but the position
        !          2039: of the agent is known and specified.
        !          2040: 
        !          2041: Name     : SENDERORG
        !          2042: Value    : 06h
        !          2043: Data     : ASCII
        !          2044: Multiple : Yes, order significant
        !          2045: Required : No
        !          2046: Default  : Previous SENDERORG if exists
        !          2047: Summary  : Organization name of sending agent
        !          2048: 
        !          2049: Primarily for documentary purposes, this field contains the organization to
        !          2050: which the sending agent belongs (i.e. Microsoft, Joe's BBS, SoCal User's Group,
        !          2051: etc).
        !          2052: 
        !          2053: 
        !          2054: 
        !          2055: 
        !          2056: 
        !          2057: 
        !          2058: 
        !          2059: 
        !          2060: _______________________________________________________________________________
        !          2061: Synchronet                           35                      Header Field Types
        !          2062: 
        !          2063: 
        !          2064: Name     : AUTHOR
        !          2065: Value    : 10h
        !          2066: Data     : ASCII
        !          2067: Multiple : Yes
        !          2068: Required : No
        !          2069: Default  : First SENDER
        !          2070: Summary  : Name of agent that created this message
        !          2071: 
        !          2072: This field can only be added by the process that originally creates the
        !          2073: message. It should not be included if same as first SENDER field. If multiple
        !          2074: AUTHOR fields exist, then the message was created by multiple agents and is
        !          2075: considered valid. The order of multiple AUTHOR fields in the record is not
        !          2076: significant.
        !          2077: 
        !          2078: Name     : AUTHORAGENT
        !          2079: Value    : 11h
        !          2080: Data     : ushort
        !          2081: Multiple : Yes, order significant
        !          2082: Required : No
        !          2083: Default  : SENDERAGENT or previous AUTHORAGENT if exists
        !          2084: Summary  : Type of agent that created this message
        !          2085: 
        !          2086: This field can only be added by the process that originally creates the
        !          2087: message. It should not be included if same as first SENDERAGENT field. If
        !          2088: multiple AUTHOR fields exist, then the message was created by multiple agents
        !          2089: and if the agent type for any of the authors is other than AGENT_PERSON, an
        !          2090: AUTHORAGENT field must follow to specify the agent type.
        !          2091: 
        !          2092: Name     : AUTHORNETTYPE
        !          2093: Value    : 12h
        !          2094: Data     : ushort
        !          2095: Multiple : Yes, order significant
        !          2096: Required : No
        !          2097: Default  : SENDERNETTYPE or previous AUTHORNETTYPE if exists
        !          2098: Summary  : Type of network this author is member of
        !          2099: 
        !          2100: Name     : AUTHORNETADDR
        !          2101: Value    : 13h
        !          2102: Data     : undef
        !          2103: Multiple : Yes, order significant
        !          2104: Required : No
        !          2105: Default  : SENDERNETADDR or previous AUTHORNETADDR if exists
        !          2106: Summary  : Network address of this author
        !          2107: 
        !          2108: 
        !          2109: 
        !          2110: 
        !          2111: 
        !          2112: 
        !          2113: 
        !          2114: 
        !          2115: 
        !          2116: 
        !          2117: 
        !          2118: 
        !          2119: _______________________________________________________________________________
        !          2120: Synchronet                           36                      Header Field Types
        !          2121: 
        !          2122: 
        !          2123: Name     : AUTHOREXT
        !          2124: Value    : 14h
        !          2125: Data     : ASCII
        !          2126: Multiple : Yes, order significant
        !          2127: Required : No
        !          2128: Default  : SENDEREXT or previous AUTHOREXT if exists
        !          2129: Summary  : Extension of this author
        !          2130: 
        !          2131: Name     : AUTHORPOS
        !          2132: Value    : 15h
        !          2133: Data     : ASCII
        !          2134: Multiple : Yes, order significant
        !          2135: Required : No
        !          2136: Default  : SENDERPOS or previous AUTHORPOS if exists
        !          2137: Summary  : Position of this author
        !          2138: 
        !          2139: Name     : AUTHORORG
        !          2140: Value    : 16h
        !          2141: Data     : ASCII
        !          2142: Multiple : Yes, order significant
        !          2143: Required : No
        !          2144: Default  : SENDERORG or previous AUTHORORG if exists
        !          2145: Summary  : Organization this author belongs to
        !          2146: 
        !          2147: 
        !          2148: 
        !          2149: 
        !          2150: 
        !          2151: 
        !          2152: 
        !          2153: 
        !          2154: 
        !          2155: 
        !          2156: 
        !          2157: 
        !          2158: 
        !          2159: 
        !          2160: 
        !          2161: 
        !          2162: 
        !          2163: 
        !          2164: 
        !          2165: 
        !          2166: 
        !          2167: 
        !          2168: 
        !          2169: 
        !          2170: 
        !          2171: 
        !          2172: 
        !          2173: 
        !          2174: 
        !          2175: 
        !          2176: 
        !          2177: 
        !          2178: _______________________________________________________________________________
        !          2179: Synchronet                           37                      Header Field Types
        !          2180: 
        !          2181: 
        !          2182: Name     : REPLYTO
        !          2183: Value    : 20h
        !          2184: Data     : ASCII
        !          2185: Multiple : Yes, but only last is valid
        !          2186: Required : No
        !          2187: Default  : SENDER
        !          2188: Summary  : Name of agent that replies should go to
        !          2189: 
        !          2190: Name     : REPLYTOAGENT
        !          2191: Value    : 21h
        !          2192: Data     : ushort
        !          2193: Multiple : Yes, but only last is valid
        !          2194: Required : No
        !          2195: Default  : SENDERAGENT
        !          2196: Summary  : Type of agent that replies should go to
        !          2197: 
        !          2198: Name     : REPLYTONETTYPE
        !          2199: Value    : 22h
        !          2200: Data     : ushort
        !          2201: Multiple : Yes, but only last is valid
        !          2202: Required : No
        !          2203: Default  : SENDERNETTYPE
        !          2204: Summary  : Type of network that replies should go to
        !          2205: 
        !          2206: Name     : REPLYTONETADDR
        !          2207: Value    : 23h
        !          2208: Data     : undef
        !          2209: Multiple : Yes, but only last is valid
        !          2210: Required : No
        !          2211: Default  : SENDERNETADDR
        !          2212: Summary  : Network address that replies should go to
        !          2213: 
        !          2214: 
        !          2215: 
        !          2216: 
        !          2217: 
        !          2218: 
        !          2219: 
        !          2220: 
        !          2221: 
        !          2222: 
        !          2223: 
        !          2224: 
        !          2225: 
        !          2226: 
        !          2227: 
        !          2228: 
        !          2229: 
        !          2230: 
        !          2231: 
        !          2232: 
        !          2233: 
        !          2234: 
        !          2235: 
        !          2236: 
        !          2237: _______________________________________________________________________________
        !          2238: Synchronet                           38                      Header Field Types
        !          2239: 
        !          2240: 
        !          2241: Name     : REPLYTOEXT
        !          2242: Value    : 24h
        !          2243: Data     : ASCII
        !          2244: Multiple : Yes, but only last is valid
        !          2245: Required : No
        !          2246: Default  : SENDEREXT
        !          2247: Summary  : Extension of agent that replies should go to
        !          2248: 
        !          2249: Name     : REPLYTOPOS
        !          2250: Value    : 25h
        !          2251: Data     : ASCII
        !          2252: Multiple : Yes, but only last is valid
        !          2253: Required : No
        !          2254: Default  : SENDERPOS
        !          2255: Summary  : Position of agent that replies should go to
        !          2256: 
        !          2257: Name     : REPLYTOORG
        !          2258: Value    : 26h
        !          2259: Data     : ASCII
        !          2260: Multiple : Yes, but only last is valid
        !          2261: Required : No
        !          2262: Default  : SENDERORG
        !          2263: Summary  : Organization of agent that replies should go to
        !          2264: 
        !          2265: 
        !          2266: 
        !          2267: 
        !          2268: 
        !          2269: 
        !          2270: 
        !          2271: 
        !          2272: 
        !          2273: 
        !          2274: 
        !          2275: 
        !          2276: 
        !          2277: 
        !          2278: 
        !          2279: 
        !          2280: 
        !          2281: 
        !          2282: 
        !          2283: 
        !          2284: 
        !          2285: 
        !          2286: 
        !          2287: 
        !          2288: 
        !          2289: 
        !          2290: 
        !          2291: 
        !          2292: 
        !          2293: 
        !          2294: 
        !          2295: 
        !          2296: _______________________________________________________________________________
        !          2297: Synchronet                           39                      Header Field Types
        !          2298: 
        !          2299: 
        !          2300: Name     : RECIPIENT
        !          2301: Value    : 30h
        !          2302: Data     : ASCII
        !          2303: Multiple : Yes, order significant
        !          2304: Required : Yes
        !          2305: Default  : "All"
        !          2306: Summary  : Name of agent to receive this message
        !          2307: 
        !          2308: If multiple RECIPIENT fields exist, the message has been forwarded and for each
        !          2309: additional RECIPIENT field (after the initial RECIPIENT), there should be a
        !          2310: FORWARDED field. The order of the RECIPIENT fields in the record must match the
        !          2311: order in which the message was sent and forwarded (chronologically).
        !          2312: 
        !          2313: Name     : RECIPIENTAGENT
        !          2314: Value    : 31h
        !          2315: Data     : ushort
        !          2316: Multiple : Yes, order significant
        !          2317: Required : No
        !          2318: Default  : AGENT_PERSON or previous RECIPIENTAGENT if exists
        !          2319: Summary  : Type of agent to receive this message
        !          2320: 
        !          2321: If multiple RECIPIENT fields exist, the message has been forwarded. If any of
        !          2322: the recipient agents are of a type other than AGENT_PERSON, this field must
        !          2323: follow the RECIPIENT field to specify the agent type.
        !          2324: 
        !          2325: Name     : RECIPIENTNETTYPE
        !          2326: Value    : 32h
        !          2327: Data     : ushort
        !          2328: Multiple : Yes, order significant
        !          2329: Required : No
        !          2330: Default  : NET_NONE or previous RECIPIENTNETTYPE if exists
        !          2331: Summary  : Type of network to receive this message
        !          2332: 
        !          2333: Name     : RECIPIENTNETADDR
        !          2334: Value    : 33h
        !          2335: Data     : undef
        !          2336: Multiple : Yes, order significant
        !          2337: Required : No
        !          2338: Default  : Previous RECIPIENTNETADDR if exists
        !          2339: Summary  : Address of network to receive this message
        !          2340: 
        !          2341: 
        !          2342: 
        !          2343: 
        !          2344: 
        !          2345: 
        !          2346: 
        !          2347: 
        !          2348: 
        !          2349: 
        !          2350: 
        !          2351: 
        !          2352: 
        !          2353: 
        !          2354: 
        !          2355: _______________________________________________________________________________
        !          2356: Synchronet                           40                      Header Field Types
        !          2357: 
        !          2358: 
        !          2359: Name     : RECIPIENTEXT
        !          2360: Value    : 34h
        !          2361: Data     : ASCII
        !          2362: Multiple : Yes, order significant
        !          2363: Required : No
        !          2364: Default  : Previous RECIPIENTEXT if exists
        !          2365: Summary  : Extension of agent to receive this message
        !          2366: 
        !          2367: If SMB_EMAIL status header attribute is set, then the "To" field in the index
        !          2368: must contain the binary value of this field rather than the CRC-16 of the
        !          2369: RECIPIENT (name) field. This is the case specifically with the local e-mail
        !          2370: message base on a Synchronet BBS.
        !          2371: 
        !          2372: Name     : RECIPIENTPOS
        !          2373: Value    : 35h
        !          2374: Data     : ASCII
        !          2375: Multiple : Yes, order significant
        !          2376: Required : No
        !          2377: Default  : Previous RECIPIENTPOS if exists
        !          2378: Summary  : Position of agent to receive this message
        !          2379: 
        !          2380: Name     : RECIPIENTORG
        !          2381: Value    : 36h
        !          2382: Data     : ASCII
        !          2383: Multiple : Yes, order significant
        !          2384: Required : No
        !          2385: Default  : Previous RECIPIENTORG if exists
        !          2386: Summary  : Type of agent to receive this message
        !          2387: 
        !          2388: 
        !          2389: 
        !          2390: 
        !          2391: 
        !          2392: 
        !          2393: 
        !          2394: 
        !          2395: 
        !          2396: 
        !          2397: 
        !          2398: 
        !          2399: 
        !          2400: 
        !          2401: 
        !          2402: 
        !          2403: 
        !          2404: 
        !          2405: 
        !          2406: 
        !          2407: 
        !          2408: 
        !          2409: 
        !          2410: 
        !          2411: 
        !          2412: 
        !          2413: 
        !          2414: _______________________________________________________________________________
        !          2415: Synchronet                           41                      Header Field Types
        !          2416: 
        !          2417: 
        !          2418: Name     : FORWARDTO
        !          2419: Value    : 40h
        !          2420: Data     : ASCII
        !          2421: Multiple : Yes, order significant
        !          2422: Required : No
        !          2423: Summary  : Name of agent this message is to be forwarded to
        !          2424: 
        !          2425: Name     : FORWARDTOAGENT
        !          2426: Value    : 41h
        !          2427: Data     : ushort
        !          2428: Multiple : Yes, order significant
        !          2429: Required : No
        !          2430: Default  : RECIPIENTAGENT or previous FORWARDTOAGENT if exists
        !          2431: Summary  : Type of agent this message is to be forwarded to
        !          2432: 
        !          2433: Name     : FORWARDTONETTYPE
        !          2434: Value    : 42h
        !          2435: Data     : ushort
        !          2436: Multiple : Yes, order significant
        !          2437: Required : No
        !          2438: Default  : RECIPIENTNETTYPE or previous FORWARDTONETTYPE if exists
        !          2439: Summary  : Type of network this message is to be forwarded to
        !          2440: 
        !          2441: Name     : FORWARDTONETADDR
        !          2442: Value    : 43h
        !          2443: Data     : undef
        !          2444: Multiple : Yes, order significant
        !          2445: Required : No
        !          2446: Default  : RECIPIENTNETADDR or previous FORWARDTONETADDR if exists
        !          2447: Summary  : Network address this message is to be forwarded to
        !          2448: 
        !          2449: 
        !          2450: 
        !          2451: 
        !          2452: 
        !          2453: 
        !          2454: 
        !          2455: 
        !          2456: 
        !          2457: 
        !          2458: 
        !          2459: 
        !          2460: 
        !          2461: 
        !          2462: 
        !          2463: 
        !          2464: 
        !          2465: 
        !          2466: 
        !          2467: 
        !          2468: 
        !          2469: 
        !          2470: 
        !          2471: 
        !          2472: 
        !          2473: _______________________________________________________________________________
        !          2474: Synchronet                           42                      Header Field Types
        !          2475: 
        !          2476: 
        !          2477: Name     : FORWARDTOEXT
        !          2478: Value    : 44h
        !          2479: Data     : ASCII
        !          2480: Multiple : Yes, order significant
        !          2481: Required : No
        !          2482: Default  : RECIPIENTEXT or previous FORWARDTOEXT if exists
        !          2483: Summary  : Extension of agent this message is to be forwarded to
        !          2484: 
        !          2485: Name     : FORWARDTOPOS
        !          2486: Value    : 45h
        !          2487: Data     : ASCII
        !          2488: Multiple : Yes, order significant
        !          2489: Required : No
        !          2490: Default  : RECIPIENTPOS or previous FORWARDTOPOS if exists
        !          2491: Summary  : Position of agent this message is to be forwarded to
        !          2492: 
        !          2493: Name     : FORWARDTOORG
        !          2494: Value    : 46h
        !          2495: Data     : ASCII
        !          2496: Multiple : Yes, order significant
        !          2497: Required : No
        !          2498: Default  : RECIPIENTORG or previous FORWARDTOORG if exists
        !          2499: Summary  : Organization of agent this message is to be forwarded to
        !          2500: 
        !          2501: Name     : FORWARDED
        !          2502: Value    : 48h
        !          2503: Data     : when_t
        !          2504: Multiple : Yes, order significant
        !          2505: Required : Yes, if forwarded
        !          2506: Summary  : Date/Time this message was forwarded to another agent
        !          2507: 
        !          2508: 
        !          2509: 
        !          2510: 
        !          2511: 
        !          2512: 
        !          2513: 
        !          2514: 
        !          2515: 
        !          2516: 
        !          2517: 
        !          2518: 
        !          2519: 
        !          2520: 
        !          2521: 
        !          2522: 
        !          2523: 
        !          2524: 
        !          2525: 
        !          2526: 
        !          2527: 
        !          2528: 
        !          2529: 
        !          2530: 
        !          2531: 
        !          2532: _______________________________________________________________________________
        !          2533: Synchronet                           43                      Header Field Types
        !          2534: 
        !          2535: 
        !          2536: Name     : RECEIVEDBY
        !          2537: Value    : 50h
        !          2538: Data     : ASCII
        !          2539: Multiple : Yes, order significant
        !          2540: Required : Yes, if receiving agent is other than RECIPIENT
        !          2541: Summary  : Name of agent that received this message
        !          2542: 
        !          2543: Name     : RECEIVEDBYAGENT
        !          2544: Value    : 51h
        !          2545: Data     : ushort
        !          2546: Multiple : Yes, order significant
        !          2547: Required : No
        !          2548: Default  : RECIPIENTAGENT or previous RECEIVEDBYAGENT if exists
        !          2549: Summary  : Type of agent that received this message
        !          2550: 
        !          2551: Name     : RECEIVEDBYNETTYPE
        !          2552: Value    : 52h
        !          2553: Data     : ushort
        !          2554: Multiple : Yes, order significant
        !          2555: Required : No
        !          2556: Default  : RECIPIENTNETTYPE or previous RECEIVEDBYNETTYPE if exists
        !          2557: Summary  : Type of network that received this message
        !          2558: 
        !          2559: Name     : RECEIVEDBYNETADDR
        !          2560: Value    : 53h
        !          2561: Data     : undef
        !          2562: Multiple : Yes, order significant
        !          2563: Required : No
        !          2564: Default  : RECIPIENTNETADDR or previous RECEIVEDBYNETADDR if exists
        !          2565: Summary  : Network address that received this message
        !          2566: 
        !          2567: 
        !          2568: 
        !          2569: 
        !          2570: 
        !          2571: 
        !          2572: 
        !          2573: 
        !          2574: 
        !          2575: 
        !          2576: 
        !          2577: 
        !          2578: 
        !          2579: 
        !          2580: 
        !          2581: 
        !          2582: 
        !          2583: 
        !          2584: 
        !          2585: 
        !          2586: 
        !          2587: 
        !          2588: 
        !          2589: 
        !          2590: 
        !          2591: _______________________________________________________________________________
        !          2592: Synchronet                           44                      Header Field Types
        !          2593: 
        !          2594: 
        !          2595: Name     : RECEIVEDBYEXT
        !          2596: Value    : 54h
        !          2597: Data     : ASCII
        !          2598: Multiple : Yes, order significant
        !          2599: Required : No
        !          2600: Default  : RECIPIENTEXT or previous RECEIVEDBYEXT if exists
        !          2601: Summary  : Extension of agent that received this message
        !          2602: 
        !          2603: Name     : RECEIVEDBYPOS
        !          2604: Value    : 55h
        !          2605: Data     : ASCII
        !          2606: Multiple : Yes, order significant
        !          2607: Required : No
        !          2608: Default  : RECIPIENTPOS or previous RECEIVEDBYPOS if exists
        !          2609: Summary  : Position of agent that received this message
        !          2610: 
        !          2611: Name     : RECEIVEDBYORG
        !          2612: Value    : 56h
        !          2613: Data     : ASCII
        !          2614: Multiple : Yes, order significant
        !          2615: Required : No
        !          2616: Default  : RECIPIENTORG or previous RECEIVEDBYORG if exists
        !          2617: Summary  : Organization of agent that received this message
        !          2618: 
        !          2619: Name     : RECEIVED
        !          2620: Value    : 58h
        !          2621: Data     : when_t
        !          2622: Multiple : Yes, order significant
        !          2623: Required : Yes, if received
        !          2624: Default  : NULL
        !          2625: Summary  : Date/Time this message was received
        !          2626: 
        !          2627: 
        !          2628: 
        !          2629: 
        !          2630: 
        !          2631: 
        !          2632: 
        !          2633: 
        !          2634: 
        !          2635: 
        !          2636: 
        !          2637: 
        !          2638: 
        !          2639: 
        !          2640: 
        !          2641: 
        !          2642: 
        !          2643: 
        !          2644: 
        !          2645: 
        !          2646: 
        !          2647: 
        !          2648: 
        !          2649: 
        !          2650: _______________________________________________________________________________
        !          2651: Synchronet                           45                      Header Field Types
        !          2652: 
        !          2653: 
        !          2654: Name     : SUBJECT
        !          2655: Value    : 60h
        !          2656: Data     : ASCII
        !          2657: Multiple : No
        !          2658: Required : Yes, but may be blank (0 length or nulstr)
        !          2659: Summary  : Subject/title of message
        !          2660: 
        !          2661: Name     : SUMMARY
        !          2662: Value    : 61h
        !          2663: Data     : ASCII
        !          2664: Multiple : No
        !          2665: Required : No
        !          2666: Summary  : Summary of message contents, created by AUTHOR
        !          2667: 
        !          2668: Name     : COMMENT
        !          2669: Value    : 62h
        !          2670: Data     : ASCII
        !          2671: Multiple : Yes
        !          2672: Required : No
        !          2673: Summary  : Comment about this message, created by SENDER
        !          2674: 
        !          2675: This field is useful for adding notes to a message when forwarding to a new
        !          2676: recipient.
        !          2677: 
        !          2678: Name     : CARBONCOPY
        !          2679: Value    : 63h
        !          2680: Data     : ASCII
        !          2681: Multiple : Yes
        !          2682: Required : No
        !          2683: Summary  : List of agents this message was also sent to
        !          2684: 
        !          2685: This field is optional and only for the use of notifying the recipient of who
        !          2686: else received the message.
        !          2687: 
        !          2688: Name     : GROUP
        !          2689: Value    : 64h
        !          2690: Data     : ASCII
        !          2691: Multiple : Yes
        !          2692: Required : No
        !          2693: Summary  : Name of group of users to receive message on recipient system
        !          2694: 
        !          2695: This field is used when sending to a group name across a network, where the
        !          2696: group can be expanded into multiple header records for each agent on the
        !          2697: destination system.
        !          2698: 
        !          2699: Name     : EXPIRATION
        !          2700: Value    : 65h
        !          2701: Data     : when_t
        !          2702: Multiple : No
        !          2703: Required : No
        !          2704: Summary  : Date/Time that this message will expire
        !          2705: 
        !          2706: 
        !          2707: 
        !          2708: 
        !          2709: _______________________________________________________________________________
        !          2710: Synchronet                           46                      Header Field Types
        !          2711: 
        !          2712: 
        !          2713: Name     : PRIORITY
        !          2714: Value    : 66h
        !          2715: Data     : ulong
        !          2716: Multiple : No
        !          2717: Required : No
        !          2718: Default  : 0
        !          2719: Summary  : Message priority (0 is lowest, FFFFFFFFh is highest)
        !          2720: 
        !          2721: 
        !          2722: 
        !          2723: 
        !          2724: 
        !          2725: 
        !          2726: 
        !          2727: 
        !          2728: 
        !          2729: 
        !          2730: 
        !          2731: 
        !          2732: 
        !          2733: 
        !          2734: 
        !          2735: 
        !          2736: 
        !          2737: 
        !          2738: 
        !          2739: 
        !          2740: 
        !          2741: 
        !          2742: 
        !          2743: 
        !          2744: 
        !          2745: 
        !          2746: 
        !          2747: 
        !          2748: 
        !          2749: 
        !          2750: 
        !          2751: 
        !          2752: 
        !          2753: 
        !          2754: 
        !          2755: 
        !          2756: 
        !          2757: 
        !          2758: 
        !          2759: 
        !          2760: 
        !          2761: 
        !          2762: 
        !          2763: 
        !          2764: 
        !          2765: 
        !          2766: 
        !          2767: 
        !          2768: _______________________________________________________________________________
        !          2769: Synchronet                           47                      Header Field Types
        !          2770: 
        !          2771: 
        !          2772: Name     : FILEATTACH
        !          2773: Value    : 70h
        !          2774: Data     : ASCII
        !          2775: Multiple : Yes
        !          2776: Required : No
        !          2777: Summary  : Name/file specification of attached file(s)
        !          2778: 
        !          2779: Name of attached file(s). Wildcards allowed. MSG_FILEATTACH attribute must be
        !          2780: set. If the MSG_FILEATTACH attribute is set but this field is not included,
        !          2781: the SUBJECT field is assumed to be the filename(s).
        !          2782: 
        !          2783: Name     : DESTFILE
        !          2784: Value    : 71h
        !          2785: Data     : ASCII
        !          2786: Multiple : Yes, order significant
        !          2787: Required : No
        !          2788: Summary  : Destination name for attached file(s)
        !          2789: 
        !          2790: Wildcards allowed. FILEATTACH field must also be included.
        !          2791: 
        !          2792: Name     : FILEATTACHLIST
        !          2793: Value    : 72h
        !          2794: Data     : ASCII
        !          2795: Multiple : Yes
        !          2796: Required : No
        !          2797: Summary  : Name of ASCII list of attached filenames
        !          2798: 
        !          2799: Wildcards not allowed in ASCII list filename. Wildcards allowed in ASCII list.
        !          2800: MSG_FILEATTACH attribute must be set.
        !          2801: 
        !          2802: Name     : DESTFILELIST
        !          2803: Value    : 73h
        !          2804: Data     : ASCII
        !          2805: Multiple : Yes, order significant
        !          2806: Required : No
        !          2807: Summary  : Name of ASCII list of destination filenames
        !          2808: 
        !          2809: Wildcards not allowed in ASCII list filename. Wildcards allowed in ASCII list.
        !          2810: 
        !          2811: Name     : FILEREQUEST
        !          2812: Value    : 74h
        !          2813: Data     : ASCII
        !          2814: Multiple : Yes
        !          2815: Required : No
        !          2816: Summary  : Name of requested file
        !          2817: 
        !          2818: Wildcards allowed. MSG_FILEREQUEST attribute must be set
        !          2819: 
        !          2820: Name     : FILEPASSWORD
        !          2821: Value    : 75h
        !          2822: Data     : ASCII
        !          2823: Multiple : Yes, order significant
        !          2824: Required : No
        !          2825: Summary  : Password for FILEREQUEST
        !          2826: 
        !          2827: _______________________________________________________________________________
        !          2828: Synchronet                           48                      Header Field Types
        !          2829: 
        !          2830: 
        !          2831: 
        !          2832: Name     : FILEREQUESTLIST
        !          2833: Value    : 76h
        !          2834: Data     : ASCII
        !          2835: Multiple : Yes
        !          2836: Required : No
        !          2837: Summary  : Name of ASCII list of filenames to request
        !          2838: 
        !          2839: Wildcards allowed.
        !          2840: 
        !          2841: Name     : FILEPASSWORDLIST
        !          2842: Value    : 77h
        !          2843: Data     : ASCII
        !          2844: Multiple : Yes, order significant
        !          2845: Required : No
        !          2846: Summary  : Name of ASCII list of passwords for FILEREQUESTLIST
        !          2847: 
        !          2848: 
        !          2849: 
        !          2850: 
        !          2851: 
        !          2852: 
        !          2853: 
        !          2854: 
        !          2855: 
        !          2856: 
        !          2857: 
        !          2858: 
        !          2859: 
        !          2860: 
        !          2861: 
        !          2862: 
        !          2863: 
        !          2864: 
        !          2865: 
        !          2866: 
        !          2867: 
        !          2868: 
        !          2869: 
        !          2870: 
        !          2871: 
        !          2872: 
        !          2873: 
        !          2874: 
        !          2875: 
        !          2876: 
        !          2877: 
        !          2878: 
        !          2879: 
        !          2880: 
        !          2881: 
        !          2882: 
        !          2883: 
        !          2884: 
        !          2885: 
        !          2886: _______________________________________________________________________________
        !          2887: Synchronet                           49                      Header Field Types
        !          2888: 
        !          2889: 
        !          2890: Name     : IMAGEATTACH
        !          2891: Value    : 80h
        !          2892: Data     : mattach_t
        !          2893: Multiple : Yes, order significant
        !          2894: Required : No
        !          2895: Summary  : Type and filename of attached image file for display
        !          2896: 
        !          2897: MSG_FILEATTACH attribute must be set. See Image Types for valid
        !          2898: mattach_t.type values.
        !          2899: 
        !          2900: Name     : ANIMATTACH
        !          2901: Value    : 81h
        !          2902: Data     : mattach_t
        !          2903: Multiple : Yes, order significant
        !          2904: Required : No
        !          2905: Summary  : Type and filename of attached graphical animation file for display
        !          2906: 
        !          2907: MSG_FILEATTACH attribute must be set. See Animation Types for valid
        !          2908: mattach_t.type values.
        !          2909: 
        !          2910: Name     : FONTATTACH
        !          2911: Value    : 82h
        !          2912: Data     : mattach_t
        !          2913: Multiple : Yes, order significant
        !          2914: Required : No
        !          2915: Summary  : Type and filename of attached font definition file
        !          2916: 
        !          2917: MSG_FILEATTACH attribute must be set. See Font Types for valid mattach_t.type
        !          2918: values.
        !          2919: 
        !          2920: Name     : SOUNDATTACH
        !          2921: Value    : 83h
        !          2922: Data     : mattach_t
        !          2923: Multiple : Yes, order significant
        !          2924: Required : No
        !          2925: Summary  : Type and filename of attached sound file for playback
        !          2926: 
        !          2927: MSG_FILEATTACH attribute must be set. See Sound Types for valid mattach_t.type
        !          2928: values.
        !          2929: 
        !          2930: Name     : PRESENTATTACH
        !          2931: Value    : 84h
        !          2932: Data     : mattach_t
        !          2933: Multiple : Yes, order significant
        !          2934: Required : No
        !          2935: Summary  : Type and filename of attached presentation definition file
        !          2936: 
        !          2937: MSG_FILEATTACH attribute must be set. See Present Types for valid
        !          2938: mattach_t.type values.
        !          2939: 
        !          2940: 
        !          2941: 
        !          2942: 
        !          2943: 
        !          2944: 
        !          2945: _______________________________________________________________________________
        !          2946: Synchronet                           50                      Header Field Types
        !          2947: 
        !          2948: 
        !          2949: Name     : VIDEOATTACH
        !          2950: Value    : 85h
        !          2951: Data     : vattach_t
        !          2952: Multiple : Yes, order significant
        !          2953: Required : No
        !          2954: Summary  : Type and filename of attached interleaved video/sound file
        !          2955: 
        !          2956: MSG_FILEATTACH attribute must be set. See Video Types for valid
        !          2957: vattach_t.type values and Video Compression Types for valid vattach_t.comp
        !          2958: values.
        !          2959: 
        !          2960: Name     : APPDATAATTACH
        !          2961: Value    : 86h
        !          2962: Data     : mattach_t
        !          2963: Multiple : Yes, order significant
        !          2964: Required : No
        !          2965: Summary  : Name of attached application data file for process/display
        !          2966: 
        !          2967: MSG_FILEATTACH attribute must be set. See Application Data Types for valid
        !          2968: mattach_t.type values.
        !          2969: 
        !          2970: 
        !          2971: 
        !          2972: 
        !          2973: 
        !          2974: 
        !          2975: 
        !          2976: 
        !          2977: 
        !          2978: 
        !          2979: 
        !          2980: 
        !          2981: 
        !          2982: 
        !          2983: 
        !          2984: 
        !          2985: 
        !          2986: 
        !          2987: 
        !          2988: 
        !          2989: 
        !          2990: 
        !          2991: 
        !          2992: 
        !          2993: 
        !          2994: 
        !          2995: 
        !          2996: 
        !          2997: 
        !          2998: 
        !          2999: 
        !          3000: 
        !          3001: 
        !          3002: 
        !          3003: 
        !          3004: _______________________________________________________________________________
        !          3005: Synchronet                           51                      Header Field Types
        !          3006: 
        !          3007: 
        !          3008: Name     : IMAGETRIGGER
        !          3009: Value    : 90h
        !          3010: Data     : typestr_t
        !          3011: Multiple : Yes, order significant
        !          3012: Required : No
        !          3013: Summary  : Type and filename of image file to trigger for display
        !          3014: 
        !          3015: See Image Types for valid typestr_t.type values.
        !          3016: 
        !          3017: Name     : ANIMTRIGGER
        !          3018: Value    : 91h
        !          3019: Data     : typestr_t
        !          3020: Multiple : Yes, order significant
        !          3021: Required : No
        !          3022: Summary  : Type and filename of animation file to trigger for display
        !          3023: 
        !          3024: See Animation Types for valid typestr_t.type values.
        !          3025: 
        !          3026: Name     : FONTTRIGGER
        !          3027: Value    : 92h
        !          3028: Data     : typestr_t
        !          3029: Multiple : Yes, order significant
        !          3030: Required : No
        !          3031: Summary  : Type and filename of font definition file to trigger
        !          3032: 
        !          3033: See Font Types for valid typestr_t.type values.
        !          3034: 
        !          3035: Name     : SOUNDTRIGGER
        !          3036: Value    : 93h
        !          3037: Data     : typestr_t
        !          3038: Multiple : Yes, order significant
        !          3039: Required : No
        !          3040: Summary  : Type and filename of sound file to trigger for playback
        !          3041: 
        !          3042: See Sound Types for valid typestr_t.type values.
        !          3043: 
        !          3044: Name     : PRESENTTRIGGER
        !          3045: Value    : 94h
        !          3046: Data     : typestr_t
        !          3047: Multiple : Yes, order significant
        !          3048: Required : No
        !          3049: Summary  : Type and filename of presentation definition file to trigger
        !          3050: 
        !          3051: See Present Types for valid typestr_t.type values.
        !          3052: 
        !          3053: Name     : VIDEOTRIGGER
        !          3054: Value    : 95h
        !          3055: Data     : typestr_t
        !          3056: Multiple : Yes, order significant
        !          3057: Required : No
        !          3058: Summary  : Type and filename of interleaved video/sound file to trigger
        !          3059: 
        !          3060: See Video Types for valid typestr_t.type values.
        !          3061: 
        !          3062: 
        !          3063: _______________________________________________________________________________
        !          3064: Synchronet                           52                      Header Field Types
        !          3065: 
        !          3066: 
        !          3067: Name     : APPDATATRIGGER
        !          3068: Value    : 96h
        !          3069: Data     : typestr_t
        !          3070: Multiple : Yes, order significant
        !          3071: Required : No
        !          3072: Summary  : Type and filename of application data file to trigger
        !          3073: 
        !          3074: See Application Data Types for valid typestr_t.type values.
        !          3075: 
        !          3076: 
        !          3077: 
        !          3078: 
        !          3079: 
        !          3080: 
        !          3081: 
        !          3082: 
        !          3083: 
        !          3084: 
        !          3085: 
        !          3086: 
        !          3087: 
        !          3088: 
        !          3089: 
        !          3090: 
        !          3091: 
        !          3092: 
        !          3093: 
        !          3094: 
        !          3095: 
        !          3096: 
        !          3097: 
        !          3098: 
        !          3099: 
        !          3100: 
        !          3101: 
        !          3102: 
        !          3103: 
        !          3104: 
        !          3105: 
        !          3106: 
        !          3107: 
        !          3108: 
        !          3109: 
        !          3110: 
        !          3111: 
        !          3112: 
        !          3113: 
        !          3114: 
        !          3115: 
        !          3116: 
        !          3117: 
        !          3118: 
        !          3119: 
        !          3120: 
        !          3121: 
        !          3122: _______________________________________________________________________________
        !          3123: Synchronet                           53                      Header Field Types
        !          3124: 
        !          3125: 
        !          3126: Name     : FIDOCTRL
        !          3127: Value    : A0h
        !          3128: Data     : ASCII
        !          3129: Multiple : Yes, order significant
        !          3130: Required : No
        !          3131: Format   : keyword ":" [" "] appdata
        !          3132: Summary  : FTS/FSC-compliant control information line
        !          3133: 
        !          3134: Any FidoNet FTS/FSC-compliant control information ("kludge") line that
        !          3135: does not have an equivalent representation here. All data not unique to the
        !          3136: actual control line, including leading and trailing white space, Ctrl-A (01h)
        !          3137: character and terminating CR must be ommited. Defined in FTS-0001.
        !          3138: 
        !          3139: Name     : FIDOAREA
        !          3140: Value    : A1h
        !          3141: Data     : ASCII
        !          3142: Multiple : No
        !          3143: Required : No
        !          3144: Summary  : FTN EchoMail conference name.
        !          3145: 
        !          3146: Defined in FTS-0004.
        !          3147: 
        !          3148: Name     : FIDOSEENBY
        !          3149: Value    : A2h
        !          3150: Data     : ASCII
        !          3151: Multiple : Yes, order significant
        !          3152: Required : No
        !          3153: Format   : net"/"node [" "[net"/"]node] [...]
        !          3154: Summary  : Used to store two-dimensional (net/node) SEEN-BY information
        !          3155: 
        !          3156: Often used in FTN EchoMail environments. Only the actual SEEN-BY data is stored
        !          3157: and SEEN-BY: is stripped along with any leading and trailing white space
        !          3158: characters. Defined in FTS-0004.
        !          3159: 
        !          3160: Name     : FIDOPATH
        !          3161: Value    : A3h
        !          3162: Data     : ASCII
        !          3163: Multiple : Yes, order significant
        !          3164: Required : No
        !          3165: Format   : net"/"node [" "[net"/"]node] [...]
        !          3166: Summary  : Used to store two-dimensional (net/node)
        !          3167: 
        !          3168: Defined in FTS-0004. ^aPATH: is stripped along with any leading and trailing
        !          3169: white space characters.
        !          3170: 
        !          3171: 
        !          3172: 
        !          3173: 
        !          3174: 
        !          3175: 
        !          3176: 
        !          3177: 
        !          3178: 
        !          3179: 
        !          3180: 
        !          3181: _______________________________________________________________________________
        !          3182: Synchronet                           54                      Header Field Types
        !          3183: 
        !          3184: 
        !          3185: Name     : FIDOMSGID
        !          3186: Value    : A4h
        !          3187: Data     : ASCII
        !          3188: Multiple : No
        !          3189: Required : No
        !          3190: Format   : origaddr " " serialno
        !          3191: Summary  : MSGID field as specified in FTS-0009.
        !          3192: 
        !          3193: Name     : FIDOREPLYID
        !          3194: Value    : A5h
        !          3195: Data     : ASCII
        !          3196: Multiple : No
        !          3197: Required : No
        !          3198: Format   : origaddr " " serialno
        !          3199: Summary  : REPLY field as specified in FTS-0009.
        !          3200: 
        !          3201: Name     : FIDOPID
        !          3202: Value    : A6h
        !          3203: Data     : ASCII
        !          3204: Multiple : No
        !          3205: Required : No
        !          3206: Format   : pID " " version [" "serialno]
        !          3207: Summary  : Indentification string of program that created this message
        !          3208: 
        !          3209: Defined FSC-0046. "^aPID:" and any white space is not included.
        !          3210: 
        !          3211: Name     : FIDOFLAGS
        !          3212: Value    : A7h
        !          3213: Data     : ASCII
        !          3214: Multiple : Yes
        !          3215: Required : No
        !          3216: Summary  : Used to store the FTN FLAGS kludge information
        !          3217: 
        !          3218: Note that all FLAG options that have binary representation in the message
        !          3219: header must be removed from the FLAGS string prior to storing it. Only the
        !          3220: actual flags option string is stored and ^aFLAGS is stripped along with any
        !          3221: leading and trailing white space characters. Defined in FSC-0053.
        !          3222: 
        !          3223: 
        !          3224: 
        !          3225: 
        !          3226: 
        !          3227: 
        !          3228: 
        !          3229: 
        !          3230: 
        !          3231: 
        !          3232: 
        !          3233: 
        !          3234: 
        !          3235: 
        !          3236: 
        !          3237: 
        !          3238: 
        !          3239: 
        !          3240: _______________________________________________________________________________
        !          3241: Synchronet                           55                      Header Field Types
        !          3242: 
        !          3243: 
        !          3244: Name     : RFC822HEADER
        !          3245: Value    : B0h
        !          3246: Data     : ASCII
        !          3247: Multiple : Yes, order significant
        !          3248: Required : No
        !          3249: Format   : field-name ":" [field-body] [CRLF]
        !          3250: Summary  : Undefined RFC-822 header field
        !          3251: 
        !          3252: Internet Message storage format, that does not have an equivalent
        !          3253: representation here. Folded header fields are allowed. Terminating CRLF may be
        !          3254: ommited.
        !          3255: 
        !          3256: Name     : RFC822MSGID
        !          3257: Value    : B1h
        !          3258: Data     : ASCII
        !          3259: Multiple : No
        !          3260: Required : No
        !          3261: Format   : "<" addr-spec ">"
        !          3262: Summary  : Message-ID field as specified in RFC-822.
        !          3263: 
        !          3264: Name     : RFC822REPLYID
        !          3265: Value    : B2h
        !          3266: Data     : ASCII
        !          3267: Multiple : No
        !          3268: Required : No
        !          3269: Format   : "<" addr-spec ">"
        !          3270: Summary  : In-Reply-To field as specified in RFC-822.
        !          3271: 
        !          3272: 
        !          3273: 
        !          3274: 
        !          3275: 
        !          3276: 
        !          3277: 
        !          3278: 
        !          3279: 
        !          3280: 
        !          3281: 
        !          3282: 
        !          3283: 
        !          3284: 
        !          3285: 
        !          3286: 
        !          3287: 
        !          3288: 
        !          3289: 
        !          3290: 
        !          3291: 
        !          3292: 
        !          3293: 
        !          3294: 
        !          3295: 
        !          3296: 
        !          3297: 
        !          3298: 
        !          3299: _______________________________________________________________________________
        !          3300: Synchronet                           56                      Header Field Types
        !          3301: 
        !          3302: 
        !          3303: Name     : UNKNOWN
        !          3304: Value    : F0h
        !          3305: Data     : undef
        !          3306: Multiple : Yes
        !          3307: Required : No
        !          3308: Summary  : Undefined header field of undefined type
        !          3309: 
        !          3310: This field is useful for retaining binary header fields (that do not have an
        !          3311: equivalent representation here) between message storage formats.
        !          3312: 
        !          3313: Name     : UNKNOWNASCII
        !          3314: Value    : F1h
        !          3315: Data     : ASCII
        !          3316: Multiple : Yes
        !          3317: Required : No
        !          3318: Summary  : Undefined header field of type ASCII
        !          3319: 
        !          3320: This field is useful for retaining ASCII header fields (that do not have an
        !          3321: equivalent representation here) between message storage formats.
        !          3322: 
        !          3323: Name     : UNUSED
        !          3324: Value    : FFh
        !          3325: Data     : undef
        !          3326: Multiple : Yes
        !          3327: Required : No
        !          3328: Summary  : Unused (deleted) header field
        !          3329: 
        !          3330: The data contained in this header field is of an unknown type and should not be
        !          3331: processed.
        !          3332: 
        !          3333: 
        !          3334: Note:
        !          3335: ----
        !          3336: Specifically, not defined are the values F000h through FFFFh. These values
        !          3337: are to be used for user or system defined header fields. Digital Dynamics
        !          3338: requests that any developers or organizations that wish to have additional
        !          3339: header fields added to this specification notify Digital Dynamics through any
        !          3340: of the contact methods listed at the beginning of this document.
        !          3341: 
        !          3342: 
        !          3343: 
        !          3344: 
        !          3345: 
        !          3346: 
        !          3347: 
        !          3348: 
        !          3349: 
        !          3350: 
        !          3351: 
        !          3352: 
        !          3353: 
        !          3354: 
        !          3355: 
        !          3356: 
        !          3357: 
        !          3358: _______________________________________________________________________________
        !          3359: Synchronet                           57                      Header Field Types
        !          3360: 
        !          3361: 
        !          3362: Data Field Types:
        !          3363: ================
        !          3364: 
        !          3365: These are the defined valid values for dfield_t.type:
        !          3366: 
        !          3367: 
        !          3368: Val Name                Data        Description
        !          3369: --- ----                ----        -----------
        !          3370: 00h TEXT_BODY           mtext_t     Displayable text (body of message).
        !          3371:                                     Included in duplicate message checking.
        !          3372:                                     All terminating white space and control
        !          3373:                                     characters are to be truncated from data
        !          3374:                                     (except when multiple contiguous CRLFs
        !          3375:                                     terminate the text, only the last CRLF
        !          3376:                                     is removed).
        !          3377: 
        !          3378: 01h TEXT_SOUL           mtext_t     Non-displayed text.
        !          3379:                                     Not normally displayed. Not necessarily
        !          3380:                                     displayable.
        !          3381:                                     Included in duplicate message checking.
        !          3382: 
        !          3383: 02h TEXT_TAIL           mtext_t     Displayable text (tag/tear/origin lines,
        !          3384:                                     etc).
        !          3385:                                     Not included in duplicate message checking.
        !          3386:                                     All terminating white space and control
        !          3387:                                     characters are to be truncated from data.
        !          3388: 
        !          3389: 03h TEXT_WING           mtext_t     Non-displayed text.
        !          3390:                                     Not normally displayed. Not necessarily
        !          3391:                                     displayable.
        !          3392:                                     Not included in duplicate message checking.
        !          3393: 
        !          3394: 10h FTEXT_BODY          ftext_t     Formatted equivalent of TEXT_BODY to be
        !          3395:                                     displayed in place of TEXT_BODY if format
        !          3396:                                     is supported. See Image Types for valid
        !          3397:                                     values of ftext_t.type.
        !          3398: 
        !          3399: 12h FTEXT_TAIL          ftext_t     Formatted equivalent of TEXT_TAIL to be
        !          3400:                                     displayed in place of TEXT_TAIL if format
        !          3401:                                     is supported. See Image Types for valid
        !          3402:                                     values of ftext_t.type.
        !          3403: 
        !          3404: 
        !          3405: 
        !          3406: 
        !          3407: 
        !          3408: 
        !          3409: 
        !          3410: 
        !          3411: 
        !          3412: 
        !          3413: 
        !          3414: 
        !          3415: 
        !          3416: 
        !          3417: _______________________________________________________________________________
        !          3418: Synchronet                           58                        Data Field Types
        !          3419: 
        !          3420: 
        !          3421: 20h IMAGEEMBED          membed_t    Type and data of embedded raster image file
        !          3422:                                     for display.
        !          3423:                                     See Image Types for valid membed.type
        !          3424:                                     values.
        !          3425: 
        !          3426: 21h ANIMEMBED           membed_t    Type and data of embedded graphical
        !          3427:                                     animation file for display.
        !          3428:                                     See Animation Types for valid membed.type
        !          3429:                                     values.
        !          3430: 
        !          3431: 22h FONTEMBED           membed_t    Type and data of embedded font definition
        !          3432:                                     file. See Font Types for valid
        !          3433:                                     membed_t.type values.
        !          3434: 
        !          3435: 23h SOUNDEMBED          membed_t    Type and data of embedded sound file for
        !          3436:                                     playback.
        !          3437:                                     See Sound Types for valid membed_t.type
        !          3438:                                     values.
        !          3439: 
        !          3440: 24h PRESENTEMBED        membed_t    Type and data of embedded presentation
        !          3441:                                     definition file.
        !          3442:                                     See Present Types for valid membed_t.type
        !          3443:                                     values.
        !          3444: 
        !          3445: 25h VIDEOEMBED          vembed_t    Type and data of embedded video/sound file
        !          3446:                                     for playback.
        !          3447:                                     See Video Types for valid vembed_t.type
        !          3448:                                     values.
        !          3449:                                     See Video Compression Types for valid
        !          3450:                                     vembed_t.comp values.
        !          3451: 
        !          3452: 26h APPDATAEMBED        membed_t    Type and data of embedded application data
        !          3453:                                     file for process/display.
        !          3454:                                     See Application Data Types for valid
        !          3455:                                     membed_t.type values.
        !          3456: 
        !          3457: FFh UNUSED              undef       Space allocated for future update/expansion
        !          3458: 
        !          3459: 
        !          3460: Specifically, not defined are the values F000h through FFFFh. These values
        !          3461: are to be used for user or system defined data fields. Digital Dynamics
        !          3462: requests that any developers or organizations that wish to have additional
        !          3463: data fields added to this specification notify Digital Dynamics through any
        !          3464: of the contact methods listed at the beginning of this document.
        !          3465: 
        !          3466: 
        !          3467: 
        !          3468: 
        !          3469: 
        !          3470: 
        !          3471: 
        !          3472: 
        !          3473: 
        !          3474: 
        !          3475: 
        !          3476: _______________________________________________________________________________
        !          3477: Synchronet                           59                        Data Field Types
        !          3478: 
        !          3479: 
        !          3480: Message Attributes:
        !          3481: ------------------
        !          3482: 
        !          3483: These are the bit values for idxrec_t.attr and msghdr_t.attr:
        !          3484: 
        !          3485: MSG_PRIVATE         (1<<0)  // Private
        !          3486: MSG_READ            (1<<1)  // Read by addressee
        !          3487: MSG_PERMANENT       (1<<2)  // Permanent
        !          3488: MSG_LOCKED          (1<<3)  // Msg is locked, no editing possible
        !          3489: MSG_DELETE          (1<<4)  // Msg is marked for deletion
        !          3490: MSG_ANONYMOUS       (1<<5)  // Anonymous author
        !          3491: MSG_KILLREAD        (1<<6)  // Delete message after it has been read
        !          3492: MSG_MODERATED       (1<<7)  // This message must be validated before export
        !          3493: MSG_VALIDATED       (1<<8)  // This message has been validated by a moderator
        !          3494: 
        !          3495: 
        !          3496: Auxillary Attributes:
        !          3497: --------------------
        !          3498: These are the bit values for msghdr_t.auxattr:
        !          3499: 
        !          3500: MSG_FILEREQUEST     (1<<0)  // File request
        !          3501: MSG_FILEATTACH      (1<<1)  // File(s) attached to Msg
        !          3502: MSG_TRUNCFILE       (1<<2)  // Truncate file(s) when sent
        !          3503: MSG_KILLFILE        (1<<3)  // Delete file(s) when sent
        !          3504: MSG_RECEIPTREQ      (1<<4)  // Return receipt requested
        !          3505: MSG_CONFIRMREQ      (1<<5)  // Confirmation receipt requested
        !          3506: MSG_NODISP          (1<<6)  // Msg may not be displayed to user
        !          3507: 
        !          3508: 
        !          3509: Network Attributes:
        !          3510: ------------------
        !          3511: These are the bit values for msghdr_t.netattr:
        !          3512: 
        !          3513: MSG_LOCAL           (1<<0)  // Msg created locally
        !          3514: MSG_INTRANSIT       (1<<1)  // Msg is in-transit
        !          3515: MSG_SENT            (1<<2)  // Sent to remote
        !          3516: MSG_KILLSENT        (1<<3)  // Kill when sent
        !          3517: MSG_ARCHIVESENT     (1<<4)  // Archive when sent
        !          3518: MSG_HOLD            (1<<5)  // Hold for pick-up
        !          3519: MSG_CRASH           (1<<6)  // Crash
        !          3520: MSG_IMMEDIATE       (1<<7)  // Send Msg now, ignore restrictions
        !          3521: MSG_DIRECT          (1<<8)  // Send directly to destination
        !          3522: MSG_GATE            (1<<9)  // Send via gateway
        !          3523: MSG_ORPHAN          (1<<10) // Unknown destination
        !          3524: MSG_FPU             (1<<11) // Force pickup
        !          3525: MSG_TYPELOCAL       (1<<12) // Msg is for local use only
        !          3526: MSG_TYPEECHO        (1<<13) // Msg is for conference distribution
        !          3527: MSG_TYPENET         (1<<14) // Msg is direct network mail
        !          3528: 
        !          3529: 
        !          3530: 
        !          3531: 
        !          3532: 
        !          3533: 
        !          3534: 
        !          3535: _______________________________________________________________________________
        !          3536: Synchronet                           60                      Message Attributes
        !          3537: 
        !          3538: 
        !          3539: Translation Types:
        !          3540: -----------------
        !          3541: 
        !          3542: Definition for values of *.xlat[x]:
        !          3543: 
        !          3544: XLAT_NONE           0       // No translation/End of translation list
        !          3545: XLAT_LF2CRLF        1       // Expand sole LF to CRLF
        !          3546: XLAT_ESCAPED        2       // 7-bit ASCII escaping for ctrl and 8-bit data
        !          3547: XLAT_HUFFMAN        3       // Static and adaptive Huffman coding compression
        !          3548: XLAT_LZW            4       // LZW (Lempel-Ziv-Welch) encoding for compression
        !          3549:                             // Terry Welch, IEEE Computer Vol 17, No 6
        !          3550:                             // June 1984, pp 8-19
        !          3551: XLAT_LZC            5       // LZC (modified LZW) encoding for compression
        !          3552:                             // Unix compress program
        !          3553: XLAT_RLE            6       // Run length encoding compression
        !          3554: XLAT_IMPLODE        7       // Implode compression (PKZIP v1.x)
        !          3555: XLAT_SHRINK         8       // Shrink compression (PKZIP v1.x)
        !          3556: XLAT_LZH            9       // LZH dynamic Huffman coding
        !          3557:                             // Haruyasu Yoshizaki, LHarc
        !          3558:                             // November, 1988
        !          3559: 
        !          3560: 
        !          3561: 
        !          3562: 
        !          3563: 
        !          3564: 
        !          3565: 
        !          3566: 
        !          3567: 
        !          3568: 
        !          3569: 
        !          3570: 
        !          3571: 
        !          3572: 
        !          3573: 
        !          3574: 
        !          3575: 
        !          3576: 
        !          3577: 
        !          3578: 
        !          3579: 
        !          3580: 
        !          3581: 
        !          3582: 
        !          3583: 
        !          3584: 
        !          3585: 
        !          3586: 
        !          3587: 
        !          3588: 
        !          3589: 
        !          3590: 
        !          3591: 
        !          3592: 
        !          3593: 
        !          3594: _______________________________________________________________________________
        !          3595: Synchronet                           61                       Translation Types
        !          3596: 
        !          3597: 
        !          3598: Agent Types:
        !          3599: -----------
        !          3600: 
        !          3601: AGENT_PERSON        0       // To or from person
        !          3602: AGENT_PROCESS       1       // Unknown process, identified by agent name
        !          3603: 
        !          3604: Agent types E000h through EFFFh are reserved for Synchronet process types
        !          3605: (defined specifically by Digital Dynamics).
        !          3606: 
        !          3607: Note:
        !          3608: ----
        !          3609: Specifically not defined are agent types F000h through FFFFh. These values
        !          3610: are to be used for user or system defined agent types. Digital Dynamics
        !          3611: requests that any developers or organizations that wish to have additional
        !          3612: agent types added to this specification notify Digital Dynamics through any
        !          3613: of the contact methods listed at the beginning of this document.
        !          3614: 
        !          3615: 
        !          3616: 
        !          3617: 
        !          3618: 
        !          3619: 
        !          3620: 
        !          3621: 
        !          3622: 
        !          3623: 
        !          3624: 
        !          3625: 
        !          3626: 
        !          3627: 
        !          3628: 
        !          3629: 
        !          3630: 
        !          3631: 
        !          3632: 
        !          3633: 
        !          3634: 
        !          3635: 
        !          3636: 
        !          3637: 
        !          3638: 
        !          3639: 
        !          3640: 
        !          3641: 
        !          3642: 
        !          3643: 
        !          3644: 
        !          3645: 
        !          3646: 
        !          3647: 
        !          3648: 
        !          3649: 
        !          3650: 
        !          3651: 
        !          3652: 
        !          3653: _______________________________________________________________________________
        !          3654: Synchronet                           62                             Agent Types
        !          3655: 
        !          3656: 
        !          3657: Network Types:
        !          3658: -------------
        !          3659: 
        !          3660:                             // Net Type             Address Format
        !          3661:                             // -----------------------------------
        !          3662: NET_NONE            0       // Locally created      none
        !          3663: NET_UNKNOWN         1       // Unknown              undef
        !          3664: NET_FIDO            2       // FTN network          fidoaddr_t
        !          3665: NET_POSTLINK        3       // PostLink network     none
        !          3666: NET_QWK             4       // QWK based network    ASCII
        !          3667: NET_INTERNET        5       // The Internet         ASCII
        !          3668: NET_WWIV            6       // WWIV based network   ulong
        !          3669: NET_MHS             7       // MHS network          ASCII
        !          3670: 
        !          3671: 
        !          3672: 
        !          3673: 
        !          3674: 
        !          3675: 
        !          3676: 
        !          3677: 
        !          3678: 
        !          3679: 
        !          3680: 
        !          3681: 
        !          3682: 
        !          3683: 
        !          3684: 
        !          3685: 
        !          3686: 
        !          3687: 
        !          3688: 
        !          3689: 
        !          3690: 
        !          3691: 
        !          3692: 
        !          3693: 
        !          3694: 
        !          3695: 
        !          3696: 
        !          3697: 
        !          3698: 
        !          3699: 
        !          3700: 
        !          3701: 
        !          3702: 
        !          3703: 
        !          3704: 
        !          3705: 
        !          3706: 
        !          3707: 
        !          3708: 
        !          3709: 
        !          3710: 
        !          3711: 
        !          3712: _______________________________________________________________________________
        !          3713: Synchronet                           63                           Network Types
        !          3714: 
        !          3715: 
        !          3716: Media Types:
        !          3717: ===========
        !          3718: 
        !          3719: Image Types:
        !          3720: -----------
        !          3721: 
        !          3722: IMAGE_UNKNOWN       0x00    // Use image signature header to determine format
        !          3723: IMAGE_ASC           0x01    // ASCII text/IBM extended ASCII graphics
        !          3724: IMAGE_ANS           0x02    // ANSI X3.64 terminal escape sequences
        !          3725: IMAGE_AVT           0x03    // AVATAR terminal escape sequences
        !          3726: IMAGE_LVI           0x04    // LVI terminal escape sequences
        !          3727: IMAGE_GIF           0x05    // Compuserve Graphics Interchange Format (GIF)
        !          3728: IMAGE_TIF           0x06    // Tagged Image Format (AKA TIFF)
        !          3729: IMAGE_JPG           0x07    // Joint Photographers Electronics Group (JPEG)
        !          3730: IMAGE_T16           0x08    // TrueVision 16-bit bitmap (TGA)
        !          3731: IMAGE_T24           0x09    // TrueVision 24-bit bitmap (TGA)
        !          3732: IMAGE_T32           0x0a    // TrueVision 32-bit bitmpa (TGA)
        !          3733: IMAGE_PCX           0x0b    // ZSoft PaintBrush graphics
        !          3734: IMAGE_BMP           0x0c    // Windows bitmap
        !          3735: IMAGE_RLE           0x0d    // Windows bitmap (compressed)
        !          3736: IMAGE_DIB           0x0e    // Display independant bitmap
        !          3737: IMAGE_PCD           0x0f    // Kodak PhotoCD
        !          3738: IMAGE_G3F           0x10    // Group 3 FAX
        !          3739: IMAGE_EPS           0x11    // Ecapsulated PostScript
        !          3740: IMAGE_RTF           0x12    // Rich text format
        !          3741: IMAGE_RIP           0x13    // Remote Imaging Protocol Script (RIPscrip)
        !          3742: IMAGE_NAP           0x14    // NAPLPS
        !          3743: IMAGE_CDR           0x15    // Corel Draw!
        !          3744: IMAGE_CGM           0x16    // Computer graphics metafile
        !          3745: IMAGE_WMF           0x17    // Windows metafile
        !          3746: IMAGE_DFX           0x18    // Autodesk AutoCAD
        !          3747: IMAGE_IFF           0x19    // Amiga Interchange File Format
        !          3748: 
        !          3749: 
        !          3750: Animation Types:
        !          3751: ---------------
        !          3752: 
        !          3753: ANIM_UNKNOWN        0       // Use file signature header to determine format
        !          3754: ANIM_FLI            1       // Autodesk animator
        !          3755: ANIM_FLC            2       // Autodesk
        !          3756: ANIM_GL             3       // Grasprt
        !          3757: ANIM_IFF            4       // Amiga Interchange File Format
        !          3758: 
        !          3759: 
        !          3760: Video Types:
        !          3761: -----------
        !          3762: 
        !          3763: VIDEO_UNKNOWN       0       // Use file signature header to determine format
        !          3764: VIDEO_QTIME         1       // Apple Quick-time
        !          3765: VIDEO_FQTIME        2       // Apple Flattened Quick-time
        !          3766: VIDEO_AVI           3       // Windows Auto/Video Interleave
        !          3767: VIDEO_ULT           4       // OS/2 Ultimotion
        !          3768: 
        !          3769: 
        !          3770: 
        !          3771: _______________________________________________________________________________
        !          3772: Synchronet                           64                             Media Types
        !          3773: 
        !          3774: 
        !          3775: Video Compression Types:
        !          3776: -----------------------
        !          3777: 
        !          3778: VCOMP_UNKNOWN       0       // Use file signature header to determine codec
        !          3779: VCOMP_RLE           1       // Apple animation
        !          3780: VCOMP_SMC           2       // Apple graphics
        !          3781: VCOMP_RPZA          3       // Apple video
        !          3782: VCOMP_KLIC          4       // Captain crunch
        !          3783: VCOMP_CVID          5       // CinePak
        !          3784: VCOMP_RT21          6       // Intel indeo R2
        !          3785: VCOMP_IV31          7       // Intel indeo R3
        !          3786: VCOMP_YVU9          8       // Intel YVU9
        !          3787: VCOMP_JPEG          9       // JPEG
        !          3788: VCOMP_MRLE          10      // Microsoft RLE
        !          3789: VCOMP_MSVC          11      // Microsoft video 1
        !          3790: 
        !          3791: 
        !          3792: Font Types:
        !          3793: ----------
        !          3794: 
        !          3795: FONT_UNKNOWN        0       // Use file signature header to determine format
        !          3796: FONT_TTF            1       // Windows TrueType
        !          3797: FONT_PFB            2       // PostScript Type 1 Font Binary
        !          3798: FONT_PFM            3       // PostScript Type 1 Font Metric
        !          3799: FONT_AMIGA          4       // Amiga Bitmapped
        !          3800: FONT_AGFA           5       // CompuGraphic Fonts
        !          3801: 
        !          3802: 
        !          3803: Sound Types:
        !          3804: -----------
        !          3805: 
        !          3806: SOUND_UNKNOWN       0       // Use file signature header to determine format
        !          3807: SOUND_MOD           1       // MOD format
        !          3808: SOUND_VOC           2       // Sound Blaster VOC format
        !          3809: SOUND_WAV           3       // Windows 3.1 WAV RIFF format
        !          3810: SOUND_MID           4       // MIDI format
        !          3811: SOUND_GMID          5       // General MIDI format (standardized patches)
        !          3812: SOUND_SMP           6       // Turtle Beach SampleVision format
        !          3813: SOUND_SF            7       // IRCAM format
        !          3814: SOUND_AU            8       // Sun Microsystems AU format
        !          3815: SOUND_IFF           9       // Amiga Interchange File Format
        !          3816: 
        !          3817: 
        !          3818: 
        !          3819: 
        !          3820: 
        !          3821: 
        !          3822: 
        !          3823: 
        !          3824: 
        !          3825: 
        !          3826: 
        !          3827: 
        !          3828: 
        !          3829: 
        !          3830: _______________________________________________________________________________
        !          3831: Synchronet                           65                             Media Types
        !          3832: 
        !          3833: 
        !          3834: Application Data Types:
        !          3835: ----------------------
        !          3836: 
        !          3837: APPDATA_UNKNOWN     0       // Use file signature header to determine format
        !          3838: APPDATA_WORDPERFECT 1       // WordPerfect Document
        !          3839: APPDATA_WKS         2       // Lotus 123 Worksheet (?)
        !          3840: APPDATA_WK1         3       // Lotus 123 Worksheet rev 1
        !          3841: APPDATA_WK2         4       // Lotus 123 Worksheet rev 2
        !          3842: APPDATA_WK3         5       // Lotus 123 Worksheet rev 3
        !          3843: APPDATA_DBF         6       // dBase III data file
        !          3844: APPDATA_PDX         7       // Paradox data file
        !          3845: APPDATA_EXCEL       8       // Excel data file
        !          3846: APPDATA_QUATRO      9       // Borland Quatro Pro file
        !          3847: APPDATA_WORD        10      // Microsoft Word
        !          3848: 
        !          3849: 
        !          3850: 
        !          3851: 
        !          3852: 
        !          3853: 
        !          3854: 
        !          3855: 
        !          3856: 
        !          3857: 
        !          3858: 
        !          3859: 
        !          3860: 
        !          3861: 
        !          3862: 
        !          3863: 
        !          3864: 
        !          3865: 
        !          3866: 
        !          3867: 
        !          3868: 
        !          3869: 
        !          3870: 
        !          3871: 
        !          3872: 
        !          3873: 
        !          3874: 
        !          3875: 
        !          3876: 
        !          3877: 
        !          3878: 
        !          3879: 
        !          3880: 
        !          3881: 
        !          3882: 
        !          3883: 
        !          3884: 
        !          3885: 
        !          3886: 
        !          3887: 
        !          3888: 
        !          3889: _______________________________________________________________________________
        !          3890: Synchronet                           66                             Media Types
        !          3891: 
        !          3892: 
        !          3893: Message Storage Pseudo Code
        !          3894: ===========================
        !          3895: 
        !          3896: The following is a "C like" pseudo code listing example of adding a message to
        !          3897: an SMB message base. SMBLIB contains C functions to do most of the following
        !          3898: operations. We are supplying this pseudo code as a general definition of the
        !          3899: order of required operations in writing to the message base. Many details have
        !          3900: been left out to simplify the code and to demonstrate only the basic
        !          3901: principles.
        !          3902: 
        !          3903: shd = open ( MSGBASE.SHD , READ/WRITE/DENY_NONE )
        !          3904: sdt = open ( MSGBASE.SDT , READ/WRITE/DENY_NONE )
        !          3905: sid = open ( MSGBASE.SDT , READ/WRITE/DENY_NONE )
        !          3906: 
        !          3907: lock ( shd , smbhdr )
        !          3908: read ( shd , smbstatus )
        !          3909: 
        !          3910: if ( smbstatus.attr & SMB_HYPERALLOC )
        !          3911:     msg.hdr.offset = filelength ( sdt )
        !          3912: 
        !          3913: else {
        !          3914:     number_of_blocks = length_of_message_data / SDT_BLOCK_LEN
        !          3915:     if ( length_of_message_data % SDT_BLOCK_LEN )   /* unevenly divisible */
        !          3916:         number_of_blocks = number_of_blocks + 1
        !          3917: 
        !          3918:     sda = open ( MSGBASE.SDA , READ/WRITE/DENY_ALL )
        !          3919: 
        !          3920:     if ( fast_allocation_mode )
        !          3921:         seek ( sda , END_OF_FILE )
        !          3922: 
        !          3923:     else {
        !          3924:         seek ( sda , BEGINNING_OF_FILE )
        !          3925:         while ( not end_of_file ( sda ) ) {
        !          3926:             read ( sda , allocated , number_of_blocks * 2 )
        !          3927:             if ( allocated = 0 ) {
        !          3928:                 seek_backwards ( sda , number_of_blocks * 2 )
        !          3929:                 break
        !          3930:             }
        !          3931:         }
        !          3932:     }
        !          3933: 
        !          3934:     msg.hdr.offset = ( current_position ( sda ) / 2 ) * SDT_BLOCK_LEN
        !          3935: 
        !          3936:     allocated = 1
        !          3937: 
        !          3938:     write ( sda , allocated , number_of_blocks * 2 )
        !          3939: 
        !          3940:     close ( sda )
        !          3941: }
        !          3942: 
        !          3943: 
        !          3944: 
        !          3945: 
        !          3946: 
        !          3947: 
        !          3948: _______________________________________________________________________________
        !          3949: Synchronet                           67             Message Storage Pseudo Code
        !          3950: 
        !          3951: 
        !          3952: seek ( sdt , msg.hdr.offset )
        !          3953: 
        !          3954: write ( sdt , message_data )
        !          3955: 
        !          3956: if ( smbstatus.attr & SMB_HYPERALLOC )
        !          3957:     msg.idx.offset = filelength ( shd )
        !          3958: 
        !          3959: else {
        !          3960:     number_of_blocks = length_of_message_header / SHD_BLOCK_LEN
        !          3961:     if ( length_of_message_header % SHD_BLOCK_LEN )   /* unevenly divisible */
        !          3962:         number_of_blocks = number_of_blocks + 1
        !          3963: 
        !          3964:     sha = open ( MSGBASE.SHA , READ/WRITE/DENY_ALL )
        !          3965: 
        !          3966:     if ( fast_allocation_mode )
        !          3967:         seek ( sha , END_OF_FILE )
        !          3968: 
        !          3969:     else {
        !          3970:         seek ( sha , BEGINNING_OF_FILE )
        !          3971:         while ( not end_of_file ( sha ) ) {
        !          3972:             read ( sha , allocated , number_of_blocks )
        !          3973:             if ( allocated = 0 ) {
        !          3974:                 seek_backwards ( sha , number_of_blocks )
        !          3975:                 break
        !          3976:             }
        !          3977:         }
        !          3978:     }
        !          3979: 
        !          3980:     msg.idx.offset = ( current_position ( sha ) * SHD_BLOCK_LEN )
        !          3981:     msg.idx.offset = msg.idx.offset + smbstatus.header_offset
        !          3982: 
        !          3983:     allocated = 1
        !          3984: 
        !          3985:     write ( sha , allocated , number_of_blocks )
        !          3986: 
        !          3987:     close ( sha )
        !          3988: }
        !          3989: 
        !          3990: seek ( shd , msg.idx.offset )
        !          3991: 
        !          3992: msg.hdr.number = smbstatus.last_msg+1
        !          3993: 
        !          3994: write ( shd , msg.hdr )
        !          3995: 
        !          3996: smbstatus.total_msgs = smbstatus.total_msgs + 1
        !          3997: smbstatus.last_msg = msg.hdr.number
        !          3998: 
        !          3999: write ( shd , smbstatus )
        !          4000: 
        !          4001: write ( sid , msg.idx )
        !          4002: 
        !          4003: unlock ( shd , smbstatus )
        !          4004: 
        !          4005: 
        !          4006: 
        !          4007: _______________________________________________________________________________
        !          4008: Synchronet                           68             Message Storage Pseudo Code
        !          4009: 
        !          4010: 
        !          4011: Message Retrieval Pseudo Code
        !          4012: =============================
        !          4013: 
        !          4014: shd = open ( MSGBASE.SHD , READ/WRITE/DENY_NONE )
        !          4015: sdt = open ( MSGBASE.SDT , READ/WRITE/DENY_NONE )
        !          4016: sid = open ( MSGBASE.SDT , READ/WRITE/DENY_NONE )
        !          4017: 
        !          4018: read ( sid , msg.idx )
        !          4019: 
        !          4020: seek ( shd , msg.idx.offset )
        !          4021: 
        !          4022: lock ( shd , msg.hdr )
        !          4023: 
        !          4024: read ( shd , msg.hdr )
        !          4025: 
        !          4026: seek ( sdt , msg.hdr.offset )
        !          4027: 
        !          4028: read ( sdt , msg.hdr.data_length )
        !          4029: 
        !          4030: unlock ( shd , msg.hdr )
        !          4031: 
        !          4032: 
        !          4033: 
        !          4034: 
        !          4035: 
        !          4036: 
        !          4037: 
        !          4038: 
        !          4039: 
        !          4040: 
        !          4041: 
        !          4042: 
        !          4043: 
        !          4044: 
        !          4045: 
        !          4046: 
        !          4047: 
        !          4048: 
        !          4049: 
        !          4050: 
        !          4051: 
        !          4052: 
        !          4053: 
        !          4054: 
        !          4055: 
        !          4056: 
        !          4057: 
        !          4058: 
        !          4059: 
        !          4060: 
        !          4061: 
        !          4062: 
        !          4063: 
        !          4064: 
        !          4065: 
        !          4066: _______________________________________________________________________________
        !          4067: Synchronet                           69           Message Retrieval Pseudo Code
        !          4068: 
        !          4069: 
        !          4070: SMBUTIL
        !          4071: =======
        !          4072: 
        !          4073: SMBUTIL is a utility that can perform various functions on an SMB message base.
        !          4074: The primary purpose of SMBUTIL is as an example to C programmers of how to use
        !          4075: the SMBLIB functions to access and modify an SMB message base. The complete C
        !          4076: source code for SMBUTIL is included and functions from it can be used or
        !          4077: modified by developers at their own discretion. The following files make up
        !          4078: SMBUTIL:
        !          4079: 
        !          4080: SMBUTIL.EXE     Compiled and linked for 16-bit DOS (ready to run)
        !          4081: SMBUTIL.C       C functions
        !          4082: SMBUTIL.H       C definitions and variable prototypes
        !          4083: SMBUTIL.WAT     Makefile for Watcom C/C++ (type wmake -f smbutil.wat)
        !          4084: SMBUTIL.BOR     Makefile for Borland C/C++ (type make -f smbutil.bor)
        !          4085: 
        !          4086: The usage syntax is as follows:
        !          4087: 
        !          4088: SMBUTIL [/opts] cmd smb_filespec.shd
        !          4089: 
        !          4090: where cmd is one or more of the following:
        !          4091: 
        !          4092:        l[n] = list msgs starting at number n
        !          4093:        r[n] = read msgs starting at number n
        !          4094:        v[n] = view msg headers starting at number n
        !          4095:        k[n] = kill (delete) n msgs
        !          4096:        i<f> = import from text file f
        !          4097:        s    = display msg base status
        !          4098:        c    = change msg base status
        !          4099:        m    = maintain msg base - delete old msgs and msgs over max
        !          4100:        p[k] = pack msg base (k specifies minimum packable Kbytes)
        !          4101: 
        !          4102: where opts is one or more of the following:
        !          4103: 
        !          4104:        a    = always (force) packing
        !          4105:        z<n> = set time zone (n=min +/- from UT or 'EST','EDT','CST',etc)
        !          4106: 
        !          4107: and smb_filespec is the base filename or file specification (wildcards) for the
        !          4108: message base. If wildcards are used, the ".SHD" extension must be specified.
        !          4109: 
        !          4110: An example command line:
        !          4111: 
        !          4112: SMBUTIL MP C:\SBBS\DATA\SUBS\*.SHD
        !          4113: 
        !          4114: would maintain and pack all the message bases found in the C:\SBBS\DATA\SUBS
        !          4115: directory.
        !          4116: 
        !          4117: 
        !          4118: 
        !          4119: 
        !          4120: 
        !          4121: 
        !          4122: 
        !          4123: 
        !          4124: 
        !          4125: _______________________________________________________________________________
        !          4126: Synchronet                           70                                 SMBUTIL
        !          4127: 
        !          4128: 
        !          4129: CHKSMB
        !          4130: ======
        !          4131: 
        !          4132: CHKSMB is a utility that performs a comprehensive analysis of a message base
        !          4133: to find any possible errors and calculate the number of packable bytes. It does
        !          4134: not "fix" a message base if any errors are found, it only reports the specific
        !          4135: errors (and exits with a non-zero error level). If any errors are reported,
        !          4136: packing the message base with SMBUTIL may rebuild the damaged files. If that
        !          4137: doesn't work, then use FIXSMB as a last resort.
        !          4138: 
        !          4139: C source code for CHKSMB is also included as an example to programmers of how
        !          4140: to use SMBLIB functions.
        !          4141: 
        !          4142: The usage syntax is as follows:
        !          4143: 
        !          4144: CHKSMB [/opts] smb_filespec.shd
        !          4145: 
        !          4146: where opts is one or more of the following:
        !          4147: 
        !          4148:         q   = quiet mode (no beeps)
        !          4149:         s   = stop after an errored message base (for use with wildcards)
        !          4150:         p   = pause after an errored message base (wait for key press)
        !          4151:         t   = don't check for unsupported translation strings (faster)
        !          4152:         e   = display extended information on corrupted messages
        !          4153: 
        !          4154: An example command line:
        !          4155: 
        !          4156: CHKSMB /QP C:\SBBS\DATA\SUBS\*.SHD
        !          4157: 
        !          4158: would check all the message bases in the C:\SBBS\DATA\SUBS directory, without
        !          4159: beeping on errors, and pausing after an errored message base.
        !          4160: 
        !          4161: 
        !          4162: 
        !          4163: 
        !          4164: 
        !          4165: 
        !          4166: 
        !          4167: 
        !          4168: 
        !          4169: 
        !          4170: 
        !          4171: 
        !          4172: 
        !          4173: 
        !          4174: 
        !          4175: 
        !          4176: 
        !          4177: 
        !          4178: 
        !          4179: 
        !          4180: 
        !          4181: 
        !          4182: 
        !          4183: 
        !          4184: _______________________________________________________________________________
        !          4185: Synchronet                           71                                  CHKSMB
        !          4186: 
        !          4187: 
        !          4188: FIXSMB
        !          4189: ======
        !          4190: 
        !          4191: FIXSMB is a utility that will rebuild the index and allocation files for a
        !          4192: message base. Since the message headers are not necessarily stored
        !          4193: sequentially, the order of the messages in the index may be changed when the
        !          4194: index is rebuilt. Messages are also re-numbered, so only use this program if
        !          4195: the index is corrupted and the messages are extremely important.
        !          4196: 
        !          4197: C source code for FIXSMB is also included as an example to programmers of how
        !          4198: to use SMBLIB functions.
        !          4199: 
        !          4200: The usage syntax is as follows:
        !          4201: 
        !          4202: FIXSMB [/M] smb_file
        !          4203: 
        !          4204: An example command line:
        !          4205: 
        !          4206: FIXSMB \SBBS\DATA\MAIL
        !          4207: 
        !          4208: Only use the "/M" command line switch if fixing an older Synchronet e-mail
        !          4209: message base (created with SBBS v2.1 or earlier). Once the SMB_EMAIL status
        !          4210: attr is set ("SMBUTIL S" will report a status attr of 1), the "/M" is not
        !          4211: required.
        !          4212: 
        !          4213: 
        !          4214: 
        !          4215: 
        !          4216: 
        !          4217: 
        !          4218: 
        !          4219: 
        !          4220: 
        !          4221: 
        !          4222: 
        !          4223: 
        !          4224: 
        !          4225: 
        !          4226: 
        !          4227: 
        !          4228: 
        !          4229: 
        !          4230: 
        !          4231: 
        !          4232: 
        !          4233: 
        !          4234: 
        !          4235: 
        !          4236: 
        !          4237: 
        !          4238: 
        !          4239: 
        !          4240: 
        !          4241: 
        !          4242: 
        !          4243: _______________________________________________________________________________
        !          4244: Synchronet                           72                                  FIXSMB
        !          4245: 
        !          4246: 
        !          4247: SMBLIB
        !          4248: ======
        !          4249: 
        !          4250: SMBLIB is a library of C functions for accessing and storing messages in an
        !          4251: SMB format message base. It can eliminate much of the development time for
        !          4252: developers that wish to use the library in whole or in part, or use the
        !          4253: functions as examples for their own message base function library. The library
        !          4254: consists of the following files:
        !          4255: 
        !          4256: SMBDEFS.H       Constant definitions, macros, and data types
        !          4257: SMBLIB.H        Library constants and function prototypes
        !          4258: SMBLIB.C        Function definitions
        !          4259: SMBVARS.C       Global variable definitions (doubles as declaration file)
        !          4260: 
        !          4261: For developers to use this library with their program, they must include the
        !          4262: "SMBLIB.H" header file at the top of each C file that uses any of the library
        !          4263: functions, global variables, data types, macros, and constants. This can be
        !          4264: done by simply adding the following line to each .C file:
        !          4265: 
        !          4266: #include "smblib.h"
        !          4267: 
        !          4268: If SMBLIB.H is included, there is no need to include SMBDEFS.H or SMBVARS.C.
        !          4269: 
        !          4270: To link the library functions and variables with a main program, the files
        !          4271: SMBVARS.OBJ and SMBLIB.OBJ must be linked with the main program .OBJ files.
        !          4272: If the operating system is DOS, be sure that all .OBJ files are compiled for
        !          4273: the same memory model.
        !          4274: 
        !          4275: Example MAKEFILEs for compiling and linking SMBUTIL with Borland C/C++
        !          4276: (SMBUTIL.BOR) and Watcom C/C++ (SMBUTIL.WAT) are included.
        !          4277: 
        !          4278: 
        !          4279: 
        !          4280: 
        !          4281: 
        !          4282: 
        !          4283: 
        !          4284: 
        !          4285: 
        !          4286: 
        !          4287: 
        !          4288: 
        !          4289: 
        !          4290: 
        !          4291: 
        !          4292: 
        !          4293: 
        !          4294: 
        !          4295: 
        !          4296: 
        !          4297: 
        !          4298: 
        !          4299: 
        !          4300: 
        !          4301: 
        !          4302: _______________________________________________________________________________
        !          4303: Synchronet                           73                                  SMBLIB
        !          4304: 
        !          4305: 
        !          4306: SMBDEFS.H
        !          4307: =========
        !          4308: 
        !          4309: The SMBDEFS.H file contains important constant definitions and data types (also
        !          4310: defined in this document). If ever this document and SMBDEFS.H are inconsistent
        !          4311: with each other, then SMBDEFS.H is to be considered correct and this document
        !          4312: in error. If such a discrepency is found, please notifiy Digital Dynamics so it
        !          4313: can be corrected in a future revision of the specification.
        !          4314: 
        !          4315: Most notable of the data types is a structure called smbmsg_t (not defined
        !          4316: in this document). It contains the fixed and variable portions of a message's
        !          4317: header record as well as convenience pointers to the sender's name
        !          4318: (smbmsg_t.to), recipient's name (smbmsg_t.from), network addresses, and more.
        !          4319: If multiple SENDER header fields are included (for example), then smbmsg_t.to
        !          4320: will point to the last SENDER header field in the header record. Convenience
        !          4321: pointers for other data items work in the same fasion if multiple header fields
        !          4322: of the same type exist in the header record.
        !          4323: 
        !          4324: Variables of the smbmsg_t data type (and pointers to variables of smbmsg_t
        !          4325: type) are used as arguments to many of the SMBLIB functions.
        !          4326: 
        !          4327: 
        !          4328: 
        !          4329: 
        !          4330: 
        !          4331: 
        !          4332: 
        !          4333: 
        !          4334: 
        !          4335: 
        !          4336: 
        !          4337: 
        !          4338: 
        !          4339: 
        !          4340: 
        !          4341: 
        !          4342: 
        !          4343: 
        !          4344: 
        !          4345: 
        !          4346: 
        !          4347: 
        !          4348: 
        !          4349: 
        !          4350: 
        !          4351: 
        !          4352: 
        !          4353: 
        !          4354: 
        !          4355: 
        !          4356: 
        !          4357: 
        !          4358: 
        !          4359: 
        !          4360: 
        !          4361: _______________________________________________________________________________
        !          4362: Synchronet                           74                               SMBDEFS.H
        !          4363: 
        !          4364: 
        !          4365: SMBVARS.C
        !          4366: =========
        !          4367: 
        !          4368: The SMBVARS.C file contains definitions of the global variables used by the
        !          4369: SMBLIB functions. It is a fairly small file since their are a small number of
        !          4370: global variables (by design). This file is used for both definitions and
        !          4371: declarations, so no "extern" declarations need to be made in developers source
        !          4372: code as long as SMBVARS.C or (preferably) SMBLIB.H is included in the source
        !          4373: code.
        !          4374: 
        !          4375: 
        !          4376: 
        !          4377: 
        !          4378: 
        !          4379: 
        !          4380: 
        !          4381: 
        !          4382: 
        !          4383: 
        !          4384: 
        !          4385: 
        !          4386: 
        !          4387: 
        !          4388: 
        !          4389: 
        !          4390: 
        !          4391: 
        !          4392: 
        !          4393: 
        !          4394: 
        !          4395: 
        !          4396: 
        !          4397: 
        !          4398: 
        !          4399: 
        !          4400: 
        !          4401: 
        !          4402: 
        !          4403: 
        !          4404: 
        !          4405: 
        !          4406: 
        !          4407: 
        !          4408: 
        !          4409: 
        !          4410: 
        !          4411: 
        !          4412: 
        !          4413: 
        !          4414: 
        !          4415: 
        !          4416: 
        !          4417: 
        !          4418: 
        !          4419: 
        !          4420: _______________________________________________________________________________
        !          4421: Synchronet                           75                               SMBVARS.C
        !          4422: 
        !          4423: 
        !          4424: SMBLIB.H
        !          4425: =======
        !          4426: 
        !          4427: The SMBLIB.H file contains prototypes of all the functions in the SMBLIB.C
        !          4428: file. It is necessary to include this file in C source code if any of the
        !          4429: SMBLIB functions are used. The following C source line will include this file:
        !          4430: 
        !          4431: #include "smblib.h"
        !          4432: 
        !          4433: and should be placed near the top of all C source files that use SMBLIB
        !          4434: functions, variables, constants, or data types.
        !          4435: 
        !          4436: Function prototypes are necessary for compilers to know the correct calling
        !          4437: syntax of a function and detect incorrect usage. Prototypes are also useful
        !          4438: as a quick reference for programmers as to the correct calling syntax of a
        !          4439: specific function.
        !          4440: 
        !          4441: 
        !          4442: 
        !          4443: 
        !          4444: 
        !          4445: 
        !          4446: 
        !          4447: 
        !          4448: 
        !          4449: 
        !          4450: 
        !          4451: 
        !          4452: 
        !          4453: 
        !          4454: 
        !          4455: 
        !          4456: 
        !          4457: 
        !          4458: 
        !          4459: 
        !          4460: 
        !          4461: 
        !          4462: 
        !          4463: 
        !          4464: 
        !          4465: 
        !          4466: 
        !          4467: 
        !          4468: 
        !          4469: 
        !          4470: 
        !          4471: 
        !          4472: 
        !          4473: 
        !          4474: 
        !          4475: 
        !          4476: 
        !          4477: 
        !          4478: 
        !          4479: _______________________________________________________________________________
        !          4480: Synchronet                           76                                SMBLIB.H
        !          4481: 
        !          4482: 
        !          4483: SMBLIB.C
        !          4484: =======
        !          4485: 
        !          4486: The SMBLIB.C file contains the actual SMBLIB library functions. This source
        !          4487: file is not a stand alone program, but instead must be compiled and linked
        !          4488: with a main source file to create the executable program.
        !          4489: 
        !          4490: The functions in this file are organized in a logical order, but their order
        !          4491: is actually irrelevant to the compiling, linking, and execution of the
        !          4492: resulting program.
        !          4493: 
        !          4494: A comment block preceeds each function, explaining what the function does,
        !          4495: how the passed parameters are used, and what the return code (if any)
        !          4496: indicates. A more detailed explanation of each function is included here:
        !          4497: 
        !          4498: int smb_open(int retry_time)
        !          4499: ----------------------------
        !          4500: The smb_open() function must be called before the message base is accessed
        !          4501: (read from or written to). The parameter, retry_time, is the maximum number
        !          4502: of seconds to wait while retrying to lock the message base header. If
        !          4503: retry_time is 0, then the message base header is not locked or read (this is
        !          4504: called "Fast Open" and should only be used when speed is more important than
        !          4505: checking for compatibility and validity upon opening). The global variable
        !          4506: smb_file must be initialized with the path and base filename of the message
        !          4507: base. This function returns 0 on success, 1 if the .SDT file could not be
        !          4508: opened, 2 if the .SHD file could not be opened, and 3 if the .SID file could
        !          4509: not be opened. If the message base header could not be locked, this function
        !          4510: returns -1. If the message base ID is incorrect, it returns -2. And if the
        !          4511: message base is of an incompatible version, it returns -3.
        !          4512: 
        !          4513: The errno global variable (standard of most C libraries) will most likely
        !          4514: contain the error code for open failure.
        !          4515: 
        !          4516: int smb_open_da(int retry_time)
        !          4517: -------------------------------
        !          4518: The smb_open_da() function is used to open the data block allocation file for
        !          4519: writing messages to a message base. The parameter, retry_time, is the maximum
        !          4520: number of seconds to wait while retrying to open the file. This function
        !          4521: returns 0 on success. -1 is returned if an open error other than "Access
        !          4522: Denied" is returned from the operating system, and the global variable errno
        !          4523: will contain the error code. -2 is returned if the retry_time has been
        !          4524: reached, and -3 is returned if the file descriptor could not be converted to
        !          4525: a stream by the fdopen() function.
        !          4526: 
        !          4527: fclose(sda_fp) should be called immediately after all necessary file access
        !          4528: has been completed.
        !          4529: 
        !          4530: This function is not used with the Hyper Allocation storage method.
        !          4531: 
        !          4532: 
        !          4533: 
        !          4534: 
        !          4535: 
        !          4536: 
        !          4537: 
        !          4538: _______________________________________________________________________________
        !          4539: Synchronet                           77                                SMBLIB.C
        !          4540: 
        !          4541: 
        !          4542: int smb_open_ha(int retry_time)
        !          4543: -------------------------------
        !          4544: The smb_open_ha() function is used to open the header block allocation file for
        !          4545: writing messages to a message base. The parameter, retry_time, is the maximum
        !          4546: number of seconds to wait while retrying to open the file. This function
        !          4547: returns 0 on success. -1 is returned if an open error other than "Access
        !          4548: Denied" is returned from the operating system, and the global variable errno
        !          4549: will contain the error code. -2 is returned if the retry_time has been
        !          4550: reached, and -3 is returned if the file descriptor could not be converted to
        !          4551: a stream by the fdopen() function.
        !          4552: 
        !          4553: fclose(sha_fp) should be called immediately after all necessary file access
        !          4554: has been completed.
        !          4555: 
        !          4556: This function is not used with the Hyper Allocation storage method.
        !          4557: 
        !          4558: int smb_create(ulong max_crcs, ulong max_msgs, ushort max_age, ushort attr
        !          4559:     ,int retry_time)
        !          4560: --------------------------------------------------------------------------
        !          4561: The smb_create() function is used to create a new message base or reset an
        !          4562: existing message base. The parameters max_crcs, max_msgs, max_age, and attr
        !          4563: are used to set the initial status of the message base status header. The
        !          4564: parameter, retry_time is the maximum number of seconds to wait while retrying
        !          4565: to lock the message base header. This functions returns 0 on success or 1 if
        !          4566: the message base header could not be locked.
        !          4567: 
        !          4568: int smb_trunchdr(int retry_time)
        !          4569: --------------------------------
        !          4570: The smb_trunchdr() function is used to truncate the header file when packing
        !          4571: the message base and writing the new header information back to the header
        !          4572: file. The parameter, retry_time is the maximum number of seconds to wait while
        !          4573: retrying to truncate the header file. Returns 0 on success, -1 if error was
        !          4574: other than "Access Denied", or -2 if retry_time reached.
        !          4575: 
        !          4576: int smb_locksmbhdr(int retry_time)
        !          4577: ----------------------------------
        !          4578: The smb_locksmbhdr() function is used to lock the first message base (status)
        !          4579: header. The parameter, retry_time is the number of seconds to wait while
        !          4580: retrying to lock the header. The smb_unlocksmbhdr() function should always be
        !          4581: used to unlock the header after accessing the message base header (usually
        !          4582: with smb_getstatus() and/or smb_putstatus()). Returns 0 if successful, -1 if
        !          4583: unsuccessful.
        !          4584: 
        !          4585: int smb_unlocksmbhdr()
        !          4586: ----------------------
        !          4587: The smb_unlocksmbhdr() function is used to unlock a previously locked message
        !          4588: base header (using smb_lockmsghdr()). Returns 0 on success, non-zero on
        !          4589: failure.
        !          4590: 
        !          4591: int smb_getstatus(smbstatus_t *hdr)
        !          4592: -----------------------------------
        !          4593: The smb_getstatus() function is used to read the status message base header
        !          4594: into the hdr structure. Returns 0 on success, 1 on failure.
        !          4595: 
        !          4596: 
        !          4597: _______________________________________________________________________________
        !          4598: Synchronet                           78                                SMBLIB.C
        !          4599: 
        !          4600: 
        !          4601: int smb_putstatus(smbstatus_t hdr)
        !          4602: ----------------------------------
        !          4603: The smb_putstatus() function is used to write the status information to the
        !          4604: first message base header. The parameter hdr, contains the status information
        !          4605: to be written. Returns 0 on success, 1 on failure.
        !          4606: 
        !          4607: int smb_getmsgidx(smbmsg_t *msg)
        !          4608: --------------------------------
        !          4609: The smb_getmsgidx() function is used to get the byte offset for a specific
        !          4610: message header in the message header file based on the message base index.
        !          4611: 
        !          4612: If msg->hdr.number is non-zero when this function is called, then the index
        !          4613: will be searched for this message number. If the message number is found in
        !          4614: the index, the msg->idx.offset is set to the byte offset of the message header
        !          4615: record in the header file and msg->offset is set to the record offset of the
        !          4616: index record in the index file, and the function returns 0. If the message
        !          4617: number is not found in the index, the function returns 1.
        !          4618: 
        !          4619: If msg->hdr.number is zero, msg->idx.offset and msg->idx.number are obtained
        !          4620: from the index record at record offset msg->offset. If msg->offset is an
        !          4621: invalid record offset when this function is called, the function returns 1.
        !          4622: Otherwise, the function returns 0.
        !          4623: 
        !          4624: int smb_getlastidx(idxrec_t *idx)
        !          4625: ---------------------------------
        !          4626: Reads the last index record of the currently open message base into the
        !          4627: idxrec_t structure pointed to by idx. Returns 0 if successful, -1 if the index
        !          4628: is empty or unopened, or -2 if the record can't be read.
        !          4629: 
        !          4630: int smb_getmsghdrlen(smbmsg_t msg)
        !          4631: ----------------------------------
        !          4632: The smb_getmsghdrlen() function is used to calculate the total length of
        !          4633: message header msg including both fixed and variable length portions. This
        !          4634: function returns the length of the header record in bytes.
        !          4635: 
        !          4636: long smb_getmsgdatlen(smbmsg_t msg)
        !          4637: -----------------------------------
        !          4638: The smb_getmsgdatlen() function is used to calculate the total length of the
        !          4639: data for message msg. This function returns the length of all data fields
        !          4640: combined.
        !          4641: 
        !          4642: int smb_lockmsghdr(smbmsg_t msg, int retry_time)
        !          4643: ------------------------------------------------
        !          4644: The smb_lockmsghdr() function is used to lock the header record for message
        !          4645: msg. The parameter retry_time is the maximum number of seconds to wait while
        !          4646: retrying to lock the header. Returns 0 on success, -1 on failure. The function
        !          4647: smb_unlockmsghdr() should immediately be called after accessing the message
        !          4648: header (usually with smb_getmsghdr() or smb_putmsghdr()).
        !          4649: 
        !          4650: 
        !          4651: 
        !          4652: 
        !          4653: 
        !          4654: 
        !          4655: 
        !          4656: _______________________________________________________________________________
        !          4657: Synchronet                           79                                SMBLIB.C
        !          4658: 
        !          4659: 
        !          4660: int smb_getmsghdr(smbmsg_t *msg)
        !          4661: --------------------------------
        !          4662: The function smb_getmsghdr() is used to read the header record for message
        !          4663: msg. msg->idx.offset must be initialized to the byte offset of the header
        !          4664: record in the header file before this function is called. The function
        !          4665: smb_freemsgmem() must be called to free the memory allocated by this function
        !          4666: for the header and data felds. This function returns 0 on success, -1 if
        !          4667: the fixed portion of the message header record could not be read, -2 if the
        !          4668: message header ID was incorrect, -3 if memory could not be allocated, -4
        !          4669: if a data field could not be read, -5 if the fixed length portion of a header
        !          4670: field could not be read, -6 if the variable length portion of a header field
        !          4671: could not be read, -7 if one or more of the mandatory header fields (SENDER,
        !          4672: RECIPIENT, or SUBJECT) are missing, -8 if total_dfields extends beyond the
        !          4673: end of the header record, or -9 if incompatible header version.
        !          4674: 
        !          4675: Several convenience pointers in the msg structure are initialized by this
        !          4676: function to point to the last occurance of the SENDER (msg->from), RECIPIENT
        !          4677: (msg->to), SUBJECT (msg->subj), etc.
        !          4678: 
        !          4679: int smb_unlockmsghdr(smbmsg_t msg)
        !          4680: ----------------------------------
        !          4681: The smb_unlockmsghdr() function is used to unlock a previously locked message
        !          4682: header (with smb_lockmsghdr()). This function returns 0 on success, non-zero
        !          4683: on failure.
        !          4684: 
        !          4685: int smb_addcrc(ulong max_crcs, ulong crc, int retry_time)
        !          4686: ---------------------------------------------------------
        !          4687: The smb_addcrc() function is used to add a CRC-32 to the CRC history file
        !          4688: for a message base, automatically checking for duplicates. The parameter
        !          4689: max_crcs should be the max_crcs defined in the status header of the message
        !          4690: base. The parameter crc, is the CRC-32 of the TEXT_BODY and TEXT_SOUL data
        !          4691: fields for the message. The parameter retry_time is the maximum number of
        !          4692: seconds to wait when retrying to open the CRC history file.
        !          4693: 
        !          4694: This function returns -1 if there was an open error, -2 if the retry_time
        !          4695: was reached, -3 if there was a memory allocation error, 1 if the CRC already
        !          4696: exists in the CRC history file (indicating a duplicate message), or 0 on
        !          4697: success (and no duplicate).
        !          4698: 
        !          4699: int smb_hfield(smbmsg_t *msg, ushort type, ushort length, void *data)
        !          4700: ---------------------------------------------------------------------
        !          4701: The smb_hfield() function is used to add a header field to the structure msg.
        !          4702: The parameters type, length, and data, must be specified according to the
        !          4703: header field values listed in this specification. This function returns 0
        !          4704: on success, non-zero on memory allocation error. The function smb_freemsgmem()
        !          4705: must be called to free the memory allocated by this function.
        !          4706: 
        !          4707: int smb_dfield(smbmsg_t *msg, ushort type, ulong length)
        !          4708: --------------------------------------------------------
        !          4709: The smb_dfield() function is used to add a data field to the structure msg.
        !          4710: The parameters type and length must be specified according to the data field
        !          4711: values listed in this specification. This function returns 0 on success,
        !          4712: non-zero on memory allocation error. The function smb_freemsgmem() must be
        !          4713: called to free the memory allocated by this function.
        !          4714: 
        !          4715: _______________________________________________________________________________
        !          4716: Synchronet                           80                                SMBLIB.C
        !          4717: 
        !          4718: 
        !          4719: int smb_addmsghdr(smbmsg_t *msg,smbstatus_t *status,int storage,int retry_time)
        !          4720: -------------------------------------------------------------------------------
        !          4721: The smb_addmsghdr() function is used to add a new message header to the message
        !          4722: header file and update the index file. The msg and status structures are
        !          4723: updated to reflect the new total messages, last message number, etc. The
        !          4724: storage parameter is used to indicate the storage method to use (either
        !          4725: SMB_SELFPACK, SMB_FASTALLOC, or SMB_HYPERALLOC). If the storage type is
        !          4726: SMB_SELFPACK, the header block allocation file will be searched for unused
        !          4727: block(s) to store this header. If the storage type is SMB_FASTALLOC or
        !          4728: SMB_HYPERALLOC, the header is stored at the end of the header file. Returns 0
        !          4729: on success, non-zero on failure. The parameter retry_time is the maximum number
        !          4730: of seconds to wait while retrying to lock and open files.
        !          4731: 
        !          4732: int smb_putmsg(smbmsg_t msg)
        !          4733: ----------------------------
        !          4734: The smb_putmsg() function calls both the smb_putmsghdr() and smb_putmsgidx()
        !          4735: functions to write the header and index elements of a message to the
        !          4736: appropriate files. Returns 0 on success, non-zero on failure.
        !          4737: 
        !          4738: int smb_putmsgidx(smbmsg_t msg)
        !          4739: -------------------------------
        !          4740: The smb_putmsgidx() function is used to store a message index in the message
        !          4741: index file. The message index can be for a new message or an existing
        !          4742: message. Returns 0 on success, non-zero on failure.
        !          4743: 
        !          4744: int smb_putmsghdr(smbmsg_t msg)
        !          4745: -------------------------------
        !          4746: The smb_putmsghdr() function is used to store a message header in the message
        !          4747: header file. The message header can be for a new message or an existing
        !          4748: message. Returns 0 on success, non-zero on failure.
        !          4749: 
        !          4750: void smb_freemsgmem(smbmsg_t msg)
        !          4751: ---------------------------------
        !          4752: Frees allocated memory for the header and data fields in the msg structure.
        !          4753: This function must be called to free the memory allocated by the functions
        !          4754: smb_hfield(), smb_dfield(), and smb_getmsghdr().
        !          4755: 
        !          4756: long smb_hdrblocks(ulong length)
        !          4757: --------------------------------
        !          4758: The smb_hdrblocks() function is used to calculate the number of blocks
        !          4759: required to store a message header of length size (in bytes). This function
        !          4760: returns the number of blocks required.
        !          4761: 
        !          4762: long smb_datblocks(ulong length)
        !          4763: --------------------------------
        !          4764: The smb_datblocks() function is used to calculate the number of blocks
        !          4765: required to store message data of length size (in byte). This function returns
        !          4766: the number of blocks required.
        !          4767: 
        !          4768: 
        !          4769: 
        !          4770: 
        !          4771: 
        !          4772: 
        !          4773: 
        !          4774: _______________________________________________________________________________
        !          4775: Synchronet                           81                                SMBLIB.C
        !          4776: 
        !          4777: 
        !          4778: long smb_allochdr(ulong length)
        !          4779: -------------------------------
        !          4780: The smb_allochdr() function is used to search for free blocks to store a
        !          4781: message header of length bytes and mark the free blocks as allocated in the
        !          4782: header allocation file. This function returns the byte offset to the header
        !          4783: record or a negative number on error. The function smb_open_ha() should be
        !          4784: called prior to calling this function and fclose(sha_fp) should be called
        !          4785: after. The function is called from smb_addmsghdr(), so you probably have no
        !          4786: need to call this function directly.
        !          4787: 
        !          4788: long smb_fallochdr(ulong length)
        !          4789: --------------------------------
        !          4790: The smb_fallochdr() function works exactly the same as the smb_allochdr()
        !          4791: function except it is much faster because the header allocation file is not
        !          4792: searched for free blocks. The function is called from smb_addmsghdr(), so you
        !          4793: probably have no need to call this function directly.
        !          4794: 
        !          4795: long smb_hallochdr(ulong header_offset)
        !          4796: ---------------------------------------
        !          4797: This smb_hallochdr() functions works exactly the same as the smb_fallochdr()
        !          4798: function except the status.header_offset is passed as the argument and the
        !          4799: header allocation (.SHA) file is not updated so smb_open_ha() need not be
        !          4800: called. The function is called from smb_addmsghdr(), so you probably have no
        !          4801: need to call this function directly.
        !          4802: 
        !          4803: long smb_allocdat(ulong length, ushort headers)
        !          4804: -----------------------------------------------
        !          4805: The smb_allocdat() function is used to search for free blocks to store length
        !          4806: amount of data for a message. The parameter headers, indicates the number of
        !          4807: message headers that are associated with this data. Normally, the headers
        !          4808: parameter will be 1, unless this message is part of a mass mailing. The offset
        !          4809: to the allocated data blocks is returned, or a negative value on error. The
        !          4810: function smb_open_da() should be called prior to calling this function and
        !          4811: fclose(sda_fp) should be called after.
        !          4812: 
        !          4813: long smb_fallocdat(ulong length, ushort headers)
        !          4814: ------------------------------------------------
        !          4815: The smb_fallocdat() function works exactly the same as the smb_allocdat()
        !          4816: function except it is much faster because the data allocation file is not
        !          4817: searched for free blocks.
        !          4818: 
        !          4819: long smb_hallocdat()
        !          4820: --------------------
        !          4821: The smb_hallocdat() function works exactly the same as the smb_hallocdat()
        !          4822: function except no argument is passed and the data allocation file (.SDA) is
        !          4823: not updated so smb_open_da() need not be called.
        !          4824: 
        !          4825: 
        !          4826: 
        !          4827: 
        !          4828: 
        !          4829: 
        !          4830: 
        !          4831: 
        !          4832: 
        !          4833: _______________________________________________________________________________
        !          4834: Synchronet                           82                                SMBLIB.C
        !          4835: 
        !          4836: 
        !          4837: int smb_incdat(ulong offset, ulong length, ushort headers)
        !          4838: ----------------------------------------------------------
        !          4839: The smb_incdat() function is used to increment the header counter in the data
        !          4840: allocation file for the data starting at the byte offset and length size in
        !          4841: bytes. The parameter headers, indicates the number of headers to add to the
        !          4842: current allocation value in the data allocation file. Returns 0 on success,
        !          4843: non-zero on failure.
        !          4844: 
        !          4845: int smb_freemsg(smbmsg_t msg, smbstatus_t status)
        !          4846: -------------------------------------------------
        !          4847: The smb_freemsg() function is used to free the disk space allocated for the
        !          4848: header and data fields of the message msg. Returns 0 on success, non-zero on
        !          4849: failure. The parameter, status, must be the current status from the message
        !          4850: base header for this message base.
        !          4851: 
        !          4852: int smb_freemsgdat(ulong offset, ulong length, ushort headers)
        !          4853: --------------------------------------------------------------
        !          4854: The smb_freemsgdat() function is used to decrement the data block allocation
        !          4855: records in the data allocation file associated with the data in the data file
        !          4856: by the value of the headers parameter (normally 1). The parameter offset
        !          4857: indicates the byte offset to the beginning of the message data in the data
        !          4858: file and the parameter length is the total length of the message data.
        !          4859: Returns 0 on success, non-zero on failure.
        !          4860: 
        !          4861: int smb_freemsghdr(ulong offset, ulong length)
        !          4862: ----------------------------------------------
        !          4863: The smb_freemsghdr() function is used to set the header block allocation
        !          4864: records in the header allocation file to 0 (indicated non-allocated block).
        !          4865: The parameter offset indicates the byte offset to the beginning of the header
        !          4866: record being freed and the parameter length indicates the total length of the
        !          4867: header record. Returns 0 on success, non-zero on failure.
        !          4868: 
        !          4869: int smb_stack(int op)
        !          4870: ---------------------
        !          4871: The smb_stack() function is used to save and restore message base information
        !          4872: so that multiple message bases can be open simultaneously. The stack can
        !          4873: save up to 4 message bases (allowing 5 simultaneously open message bases).
        !          4874: The stack is a "last in, first out" storage area for open message bases.
        !          4875: If the op parameter is SMB_STACK_PUSH, smb_stack() will save (push) the current
        !          4876: message base onto the stack. Calling smb_stack(SMB_STACK_POP) will restore
        !          4877: (pop) the most recently pushed message base off the stack. Calling
        !          4878: smb_stack(SMB_STACK_XCHNG) will exchange the most recently pushed message base
        !          4879: and the current message base (replacing the top of the stack with the current
        !          4880: message base).
        !          4881: 
        !          4882: void smb_close()
        !          4883: ----------------
        !          4884: Closes the header, data, and index files for the currently open message base.
        !          4885: 
        !          4886: 
        !          4887: 
        !          4888: 
        !          4889: 
        !          4890: 
        !          4891: 
        !          4892: _______________________________________________________________________________
        !          4893: Synchronet                           83                                SMBLIB.C
        !          4894: 
        !          4895: 
        !          4896: Miscellaneous SMBLIB Files
        !          4897: ==========================
        !          4898: 
        !          4899: CRC32.H         C header file for CRC-32 calculations
        !          4900: -----------------------------------------------------
        !          4901: This file contains a static 32-bit CRC table (crc32tbl[]) and a macro (ucrc32)
        !          4902: that uses this table to calculate 32-bit CRCs one byte at a time.
        !          4903: 
        !          4904: Example:
        !          4905: 
        !          4906:     ulong crc=0xffffffff;
        !          4907: 
        !          4908: for(i=0;i<length;i++)
        !          4909:     crc=ucrc32(buf[i],crc);
        !          4910: crc=~crc;
        !          4911: 
        !          4912: 
        !          4913: CRC16.C         C functions for 16-bit CRC calculations
        !          4914: -------------------------------------------------------
        !          4915: This file contains a function (ucrc16), to calculate 16-bit CRCs one byte at a
        !          4916: time and a function (crc16) that uses the ucrc16() function to calculate the
        !          4917: 16-bit CRC of an ASCIIZ character string.
        !          4918: 
        !          4919: Example:
        !          4920: 
        !          4921:     ushort crc;
        !          4922: 
        !          4923: crc=crc16("Text");
        !          4924: 
        !          4925: 
        !          4926: 
        !          4927: 
        !          4928: 
        !          4929: 
        !          4930: 
        !          4931: 
        !          4932: 
        !          4933: 
        !          4934: 
        !          4935: 
        !          4936: 
        !          4937: 
        !          4938: 
        !          4939: 
        !          4940: 
        !          4941: 
        !          4942: 
        !          4943: 
        !          4944: 
        !          4945: 
        !          4946: 
        !          4947: 
        !          4948: 
        !          4949: 
        !          4950: 
        !          4951: _______________________________________________________________________________
        !          4952: Synchronet                           84              Miscellaneous SMBLIB Files
        !          4953: 
        !          4954: 
        !          4955: LZH.H           Function prototypes for LZH.C
        !          4956: ---------------------------------------------
        !          4957: This file contains function prototypes for the two most important functions
        !          4958: in LZH.C, lzh_encode() and lzh_decode().
        !          4959: 
        !          4960: Example:
        !          4961: 
        !          4962:     uchar str[256],lzh[512];
        !          4963:     long length;
        !          4964: 
        !          4965: strcpy(str,"This is a string of text");
        !          4966: length=lzh_encode(str,strlen(str),lzh);
        !          4967: lzh_decode(lzh,length,str);
        !          4968: 
        !          4969: 
        !          4970: LZH.C           C functions for LZH encoding (compression/decompression)
        !          4971: ------------------------------------------------------------------------
        !          4972: This file contains the functions for encoding and decoding LZH compressed
        !          4973: data. If the macro LZH_DYNAMIC_BUF is defined when this file is compiled,
        !          4974: temporary buffers will be dynamically allocated as opposed to static. This
        !          4975: may be slower than the static buffer method, but frees the allocated memory
        !          4976: after encoding or decoding. If free memory for your application is an issue,
        !          4977: then define this macro when compiling this file.
        !          4978: 
        !          4979: Example (Borland C):
        !          4980: 
        !          4981: bcc -c -DLZH_DYNAMIC_BUF lzh
        !          4982: 
        !          4983: Example (Watcom C):
        !          4984: 
        !          4985: wcc -dLZH_DYNAMIC_BUF lzh
        !          4986: 
        !          4987: 
        !          4988: 
        !          4989: 
        !          4990: 
        !          4991: 
        !          4992: 
        !          4993: 
        !          4994: 
        !          4995: 
        !          4996: 
        !          4997: 
        !          4998: 
        !          4999: 
        !          5000: 
        !          5001: 
        !          5002: 
        !          5003: 
        !          5004: 
        !          5005: 
        !          5006: 
        !          5007: 
        !          5008: 
        !          5009: 
        !          5010: _______________________________________________________________________________
        !          5011: Synchronet                           85              Miscellaneous SMBLIB Files
        !          5012: 
        !          5013: 
        !          5014: SMBLIB Storage Example
        !          5015: ======================
        !          5016: 
        !          5017: #include "smblib.h"
        !          5018: #include "crc16.c"
        !          5019: 
        !          5020: int main(void)
        !          5021: {
        !          5022:     char    str[256]                        // General purpose string
        !          5023:            ,*msg_text="Hello, world!"       // Message text
        !          5024:            ,nul_buf[SDT_BLOCK_LEN]={0}      // NULL initialized buffer
        !          5025:            ;
        !          5026:     int     i                               // General purpose integer
        !          5027:            ,storage=SMB_SELFPACK            // Default storage method
        !          5028:            ,retry=10                        // Retry for opening/locking files
        !          5029:            ;
        !          5030:     ushort  max_age=0                       // Default maximum age of messages
        !          5031:            ,xlat=XLAT_NONE                  // Translation string
        !          5032:            ,tzone=PST                       // Time zone
        !          5033:            ,copies=1                        // Number of copies of this msg
        !          5034:            ;
        !          5035:     ulong   max_msgs=500                    // Default max number of msgs
        !          5036:            ,max_crcs=0                      // Default max crcs
        !          5037:            ,length                          // Length of msg text
        !          5038:            ,offset                          // Offset to msg text in data file
        !          5039:            ;
        !          5040:     smbmsg_t    msg;                        // Message structure
        !          5041:     smbstatus_t status;                     // Message base status record
        !          5042: 
        !          5043: strcpy(smb_file,"MSGBASE");                 // We'll use "MSGBASE" for the name
        !          5044: if((i=smb_open(retry))!=0) {                // Can't open!?!
        !          5045:     printf("smb_open returned %d\n",i);
        !          5046:     return(1); }
        !          5047: 
        !          5048: if(!filelength(fileno(shd_fp)))             // Message base not created yet
        !          5049:     smb_create(max_crcs                     // Create with default settings
        !          5050:               ,max_msgs
        !          5051:               ,max_age
        !          5052:               ,storage==SMB_HYPERALLOC
        !          5053:                     ? SMB_HYPERALLOC : 0    // SMB_EMAIL if this was e-mail
        !          5054:               ,retry
        !          5055:               );
        !          5056: 
        !          5057: if((i=smb_locksmbhdr(retry))!=0) {          // Can't lock status base header
        !          5058:     printf("smb_locksmbhdr returned %d\n",i);
        !          5059:     smb_close();
        !          5060:     return(1); }
        !          5061: 
        !          5062: if((i=smb_getstatus(&status))!=0) {         // Can't read status base header
        !          5063:     smb_unlocksmbhdr();
        !          5064:     smb_close();
        !          5065:     printf("smb_getstatus returned %d\n",i);
        !          5066:     return(1); }
        !          5067: 
        !          5068: 
        !          5069: _______________________________________________________________________________
        !          5070: Synchronet                           86                  SMBLIB Storage Example
        !          5071: 
        !          5072: 
        !          5073: if(status.attr&SMB_HYPERALLOC)
        !          5074:     storage=SMB_HYPERALLOC;
        !          5075: else
        !          5076:     storage=SMB_SELFPACK;
        !          5077: 
        !          5078: length=strlen(msg_text);                    // Get length of message
        !          5079: length+=sizeof(xlat);                       // Add length of xlat string
        !          5080: 
        !          5081: if(storage==SMB_HYPERALLOC)                 // Allocate space for message text
        !          5082:     offset=smb_hallocdat();
        !          5083: else {
        !          5084:     if((i=smb_open_da(retry))!=0) {
        !          5085:         smb_unlocksmbhdr();
        !          5086:         printf("smb_open_da returned %d\n",i);
        !          5087:         smb_close();
        !          5088:         return(1); }
        !          5089:     if(storage==SMB_FASTALLOC)
        !          5090:         offset=smb_fallocdat(length,copies);
        !          5091:     else
        !          5092:         offset=smb_allocdat(length,copies);
        !          5093:     fclose(sda_fp); }
        !          5094: 
        !          5095: fseek(sdt_fp,offset,SEEK_SET);              // Seek to beginning of data block
        !          5096: fwrite(&xlat,sizeof(xlat),1,sdt_fp);        // Write xlat string
        !          5097: fwrite(msg_text,strlen(msg_text),1,sdt_fp); // Write message text
        !          5098: fwrite(nul_buf,SDT_BLOCK_LEN-length         // Write NULLs out to end of block
        !          5099:     ,1,sdt_fp);
        !          5100: fflush(sdt_fp);                             // Flush output buffer
        !          5101: smb_unlocksmbhdr();                         // Unlock status base header
        !          5102: 
        !          5103: memset(&msg,0,sizeof(smbmsg_t));            // Initialize header to NULL
        !          5104: memcpy(msg.hdr.id,"SHD\x1a",4);             // Always set to SHD^Z
        !          5105: msg.hdr.version=SMB_VERSION;
        !          5106: msg.hdr.when_written.time=time(NULL);
        !          5107: msg.hdr.when_written.zone=tzone;
        !          5108: msg.hdr.when_imported.time=time(NULL);
        !          5109: msg.hdr.when_imported.zone=tzone;
        !          5110: msg.hdr.offset=offset;
        !          5111: 
        !          5112: strcpy(str,"All");                          // Send message to "All"
        !          5113: if((i=smb_hfield(&msg,RECIPIENT,strlen(str),str))!=0) {
        !          5114:     printf("smb_hfield returned %d\n",i);
        !          5115:     smb_freemsgdat(offset,length,copies);
        !          5116:     smb_close();
        !          5117:     return(1); }
        !          5118: strlwr(str);                                // If this were e-mail, idx.to
        !          5119: msg.idx.to=crc16(str);                      // would be the "to" user number
        !          5120: 
        !          5121: 
        !          5122: 
        !          5123: 
        !          5124: 
        !          5125: 
        !          5126: 
        !          5127: 
        !          5128: _______________________________________________________________________________
        !          5129: Synchronet                           87                  SMBLIB Storage Example
        !          5130: 
        !          5131: 
        !          5132: strcpy(str,"Sysop");                        // Send message from "Sysop"
        !          5133: if((i=smb_hfield(&msg,SENDER,strlen(str),str))!=0) {
        !          5134:     printf("smb_hfield returned %d\n",i);
        !          5135:     smb_freemsgdat(offset,length,copies);
        !          5136:     smb_freemsgmem(msg);
        !          5137:     smb_close();
        !          5138:     return(1); }
        !          5139: strlwr(str);                                // If this were e-mail, idx.from
        !          5140: msg.idx.from=crc16(str);                    // would be the "from" user number
        !          5141: 
        !          5142: strcpy(str,"This is a test");               // Set the message subject/title
        !          5143: if((i=smb_hfield(&msg,SUBJECT,strlen(str),str))!=0) {
        !          5144:     printf("smb_hfield returned %d\n",i);
        !          5145:     smb_freemsgdat(offset,length,copies);
        !          5146:     smb_freemsgmem(msg);
        !          5147:     smb_close();
        !          5148:     return(1); }
        !          5149: strlwr(str);
        !          5150: msg.idx.subj=crc16(str);
        !          5151: 
        !          5152: if((i=smb_dfield(&msg,TEXT_BODY,length))!=0) {
        !          5153:     printf("smb_dfield returned %d\n",i);
        !          5154:     smb_freemsgdat(offset,length,copies);
        !          5155:     smb_freemsgmem(msg);
        !          5156:     smb_close();
        !          5157:     return(1); }
        !          5158: 
        !          5159: if((i=smb_addmsghdr(&msg,&status,storage,retry))!=0) {
        !          5160:     printf("smb_addmsghdr returned %d\n",i);
        !          5161:     smb_freemsgdat(offset,length,copies);
        !          5162:     smb_freemsgmem(msg);
        !          5163:     smb_close();
        !          5164:     return(1); }
        !          5165: 
        !          5166: smb_freemsgmem(msg);                        // Unnecessary if exiting main()
        !          5167: smb_close();                                // Unnecessary if exiting main()
        !          5168: return(0);
        !          5169: }
        !          5170: 
        !          5171: 
        !          5172: 
        !          5173: 
        !          5174: 
        !          5175: 
        !          5176: 
        !          5177: 
        !          5178: 
        !          5179: 
        !          5180: 
        !          5181: 
        !          5182: 
        !          5183: 
        !          5184: 
        !          5185: 
        !          5186: 
        !          5187: _______________________________________________________________________________
        !          5188: Synchronet                           88                  SMBLIB Storage Example
        !          5189: 
        !          5190: 
        !          5191: SMBLIB Retrieval Example
        !          5192: ========================
        !          5193: 
        !          5194: #include "smblib.h"
        !          5195: 
        !          5196: int main(void)
        !          5197: {
        !          5198:     char        ch;                         // General purpose character
        !          5199:     int         i,                          // General purpose integer
        !          5200:                 retry=10;                   // Retry for opening/locking files
        !          5201:     ushort      xlat;                       // Translation string
        !          5202:     ulong       l;                          // General purpose long integer
        !          5203:     smbmsg_t    msg;                        // Message structure
        !          5204: 
        !          5205: strcpy(smb_file,"MSGBASE");                 // We'll use "MSGBASE" for the name
        !          5206: if((i=smb_open(retry))!=0) {                // Can't open!?!
        !          5207:     printf("smb_open returned %d\n",i);
        !          5208:     return(1); }
        !          5209: 
        !          5210: if(!filelength(fileno(shd_fp))) {           // Message base not created yet
        !          5211:     printf("Empty\n");
        !          5212:     smb_close();
        !          5213:     return(0); }
        !          5214: 
        !          5215: for(msg.offset=0;!ferror(sid_fp);msg.offset++) {
        !          5216: 
        !          5217:     fseek(sid_fp,msg.offset*sizeof(idxrec_t),SEEK_SET);
        !          5218:     if(!fread(&msg.idx,1,sizeof(idxrec_t),sid_fp))
        !          5219:         break;
        !          5220: 
        !          5221:     if((i=smb_lockmsghdr(msg,retry))!=0) {
        !          5222:         printf("smb_lockmsghdr returned %d\n",i);
        !          5223:         break; }
        !          5224:     if((i=smb_getmsghdr(&msg))!=0) {
        !          5225:         smb_unlockmsghdr(msg);
        !          5226:         printf("smb_getmsghdr returned %d\n",i);
        !          5227:         break; }
        !          5228:     if((i=smb_unlockmsghdr(msg))!=0) {
        !          5229:         smb_freemsgmem(msg);
        !          5230:         printf("smb_unlockmsghdr returned %d\n",i);
        !          5231:         break; }
        !          5232: 
        !          5233: 
        !          5234: 
        !          5235: 
        !          5236: 
        !          5237: 
        !          5238: 
        !          5239: 
        !          5240: 
        !          5241: 
        !          5242: 
        !          5243: 
        !          5244: 
        !          5245: 
        !          5246: _______________________________________________________________________________
        !          5247: Synchronet                           89                SMBLIB Retrieval Example
        !          5248: 
        !          5249: 
        !          5250:     printf("Subj : %s\n",msg.subj);
        !          5251:     printf("To   : %s\n",msg.to);
        !          5252:     printf("From : %s\n",msg.from);
        !          5253:     printf("Date : %s\n",ctime((time_t *)&msg.hdr.when_written.time));
        !          5254: 
        !          5255:     for(i=0;i<msg.hdr.total_dfields;i++)
        !          5256:         switch(msg.dfield[i].type) {
        !          5257:             case TEXT_BODY:             // Only show BODY and TAIL data fields
        !          5258:             case TEXT_TAIL:
        !          5259:                 fseek(sdt_fp,msg.hdr.offset+msg.dfield[i].offset
        !          5260:                     ,SEEK_SET);
        !          5261:                 fread(&xlat,sizeof(xlat),1,sdt_fp);
        !          5262:                 if(xlat!=XLAT_NONE)     // No translations supported
        !          5263:                     continue;
        !          5264:                 for(l=sizeof(xlat);l<msg.dfield[i].length;l++) {
        !          5265:                     ch=fgetc(sdt_fp);
        !          5266:                     if(ch)
        !          5267:                         putchar(ch); }
        !          5268:                 printf("\n");
        !          5269:                 break; }
        !          5270:     printf("\n");
        !          5271: 
        !          5272:     smb_freemsgmem(msg); }          // Free memory allocated by smb_getmsghdr()
        !          5273: 
        !          5274: smb_close();
        !          5275: return(0);
        !          5276: }
        !          5277: 
        !          5278: 
        !          5279: 
        !          5280: 
        !          5281: 
        !          5282: 
        !          5283: 
        !          5284: 
        !          5285: 
        !          5286: 
        !          5287: 
        !          5288: 
        !          5289: 
        !          5290: 
        !          5291: 
        !          5292: 
        !          5293: 
        !          5294: 
        !          5295: 
        !          5296: 
        !          5297: 
        !          5298: 
        !          5299: 
        !          5300: 
        !          5301: 
        !          5302: 
        !          5303: 
        !          5304: 
        !          5305: _______________________________________________________________________________
        !          5306: Synchronet                           90                SMBLIB Retrieval Example
        !          5307: 
        !          5308: 
        !          5309: SMBLIB Performance Issues
        !          5310: =========================
        !          5311: 
        !          5312: Since importing messages is the usually the most time consuming task likely
        !          5313: undertaken by an SMB application, it is also the most susceptable to design
        !          5314: issues that effect performance.
        !          5315: 
        !          5316: Opening and Closing
        !          5317: -------------------
        !          5318: When importing multiple messages for a single message base, it appears logical
        !          5319: to open the message base, import all the messages, then close it. This indeed
        !          5320: is preferred over opening and closing the message base for each message.
        !          5321: 
        !          5322: When importing multiple messages for possibly non-consecutive message bases,
        !          5323: developers may eaily make the mistake of opening and closing the message base
        !          5324: for each message. This is not necessary and can considerably hinder the
        !          5325: import performance. The easiest solution is to only close the message base and
        !          5326: open a new one if the next message to be imported is not for the same message
        !          5327: base as the previously imported message. Example:
        !          5328: 
        !          5329: smb_file[0]=0;
        !          5330: for(i=0;i<total_messages_to_be_imported;i++) {
        !          5331:     if(stricmp(get_messagebase_for_this_message(i),smb_file)) {
        !          5332:         if(smb_file[0])     /* We've already opened one */
        !          5333:             smb_close();
        !          5334:         strcpy(smb_file,get_messagebase_for_this_message(i));
        !          5335:         smb_open(10); }
        !          5336:     /* Import this message */
        !          5337:     }
        !          5338: if(smb_file[0])
        !          5339:     smb_close();
        !          5340: 
        !          5341: 
        !          5342: 
        !          5343: 
        !          5344: 
        !          5345: 
        !          5346: 
        !          5347: 
        !          5348: 
        !          5349: 
        !          5350: 
        !          5351: 
        !          5352: 
        !          5353: 
        !          5354: 
        !          5355: 
        !          5356: 
        !          5357: 
        !          5358: 
        !          5359: 
        !          5360: 
        !          5361: 
        !          5362: 
        !          5363: 
        !          5364: _______________________________________________________________________________
        !          5365: Synchronet                           91               SMBLIB Performance Issues
        !          5366: 
        !          5367: 
        !          5368: A more advanced method is to keep multiple message bases open at the same time.
        !          5369: Due to the likely limitation of total file handles on the system, it is
        !          5370: suggested to keep the number of simultaneously open message bases at or below
        !          5371: 3. SMBLIB includes the function smb_stack() to easily "push" and "pop" message
        !          5372: bases without closing them (push is the equivalent to "save" and pop is the
        !          5373: equivalent to "restore"). The downside of this function is that you cannot
        !          5374: access message bases on the stack without actually popping them off (in reverse
        !          5375: of the order they were pushed). You can however "exchange" the current message
        !          5376: base with the message base on the top of the stack (most recently pushed).
        !          5377: To intelligently juggle more than two open message bases, the developer should
        !          5378: create their own equivalent of the smb_stack() function so they can access the
        !          5379: message bases on the stack without popping them off. An example of keeping a
        !          5380: maximum of two message bases open using smb_stack():
        !          5381: 
        !          5382:     char last_messagebase[128],new_messagebase[128];
        !          5383: 
        !          5384: smb_file[0]=0;
        !          5385: last_messagebase[0]=0;
        !          5386: for(i=0;i<total_messages_to_be_imported;i++) {
        !          5387:     strcpy(new_messagebase,get_messagebase_for_this_message(i));
        !          5388:     if(stricmp(new_messagebase,smb_file)) {     /* Not current message base */
        !          5389:         if(smb_file[0]) {                       /* We've already opened one */
        !          5390:             if(!stricmp(new_messagebase,last_messagebase)) { /* Same as last */
        !          5391:                 strcpy(last_messagebase,smb_file);
        !          5392:                 smb_stack(SMB_STACK_XCHNG); }       /* Retore previous base */
        !          5393:             else {
        !          5394:                 if(last_messagebase[0]) {
        !          5395:                     smb_stack(SMB_STACK_XCHNG);
        !          5396:                     smb_close();
        !          5397:                     strcpy(last_messagebase,new_messagebase); }
        !          5398:                 else {
        !          5399:                     strcpy(last_messagebase,smb_file);
        !          5400:                     smb_stack(SMB_STACK_PUSH); }    /* Save current base */
        !          5401:                 strcpy(smb_file,new_messagebase);
        !          5402:                 smb_open(10); } }
        !          5403:         else {
        !          5404:             strcpy(smb_file,new_messagebase);
        !          5405:             smb_open(10); } }
        !          5406:     /* Import this message */
        !          5407:     }
        !          5408: if(smb_file[0])
        !          5409:     smb_close();
        !          5410: if(last_messagebase[0]) {
        !          5411:     smb_stack(SMB_STACK_POP);
        !          5412:     smb_close(); }
        !          5413: 
        !          5414: 
        !          5415: 
        !          5416: 
        !          5417: 
        !          5418: 
        !          5419: 
        !          5420: 
        !          5421: 
        !          5422: 
        !          5423: _______________________________________________________________________________
        !          5424: Synchronet                           92               SMBLIB Performance Issues
        !          5425: 
        !          5426: 
        !          5427: The second example would be of negligible performance gain over the first
        !          5428: example (6 open operations versus 7) if the messages to import were in the
        !          5429: following order:
        !          5430: 
        !          5431: msg[0] --> msgbase[0]       // 0 opened
        !          5432: msg[1] --> msgbase[1]       // 0 pushed 1 opened
        !          5433: msg[2] --> msgbase[1]
        !          5434: msg[3] --> msgbase[2]       // 1 closed 0 popped 0 closed 2 opened
        !          5435: msg[4] --> msgbase[0]       // 2 pushed 0 opened
        !          5436: msg[5] --> msgbase[2]       // 0 pushed 2 popped (exchanged)
        !          5437: msg[6] --> msgbase[3]       // 2 closed 0 popped 0 closed 3 opened
        !          5438: msg[7] --> msgbase[0]       // 3 pushed 0 opened
        !          5439: 
        !          5440: The second example would be of significant performance gain over the first
        !          5441: example (4 open operations versus 8) if the messages to import were in the
        !          5442: following order:
        !          5443: 
        !          5444: msg[0] --> msgbase[0]       // 0 opened
        !          5445: msg[1] --> msgbase[1]       // 0 pushed 1 opened
        !          5446: msg[2] --> msgbase[0]       // 1 pushed 0 popped (exchanged)
        !          5447: msg[3] --> msgbase[1]       // 0 pushed 1 popped (exchanged)
        !          5448: msg[4] --> msgbase[0]       // 1 pushed 0 popped (exchanged)
        !          5449: msg[5] --> msgbase[2]       // 0 pushed 1 popped (exchanged) 1 closed 2 opened
        !          5450: msg[6] --> msgbase[3]       // 2 pushed 0 popped (exchanged) 0 closed 3 opened
        !          5451: msg[7] --> msgbase[2]       // 3 pushed 2 popped (exchanged)
        !          5452: 
        !          5453: More advanced use of "stack-like" message base file handle storage can easily
        !          5454: reduce the number of open operations, therefore increasing import performance
        !          5455: under more adverse message base ordering conditions.
        !          5456: 
        !          5457: 
        !          5458: 
        !          5459: 
        !          5460: 
        !          5461: 
        !          5462: 
        !          5463: 
        !          5464: 
        !          5465: 
        !          5466: 
        !          5467: 
        !          5468: 
        !          5469: 
        !          5470: 
        !          5471: 
        !          5472: 
        !          5473: 
        !          5474: 
        !          5475: 
        !          5476: 
        !          5477: 
        !          5478: 
        !          5479: 
        !          5480: 
        !          5481: 
        !          5482: _______________________________________________________________________________
        !          5483: Synchronet                           93               SMBLIB Performance Issues
        !          5484: 
        !          5485: 
        !          5486: Compression
        !          5487: -----------
        !          5488: If any message data compression features are offered by the application, it
        !          5489: is important the the application not unnecessarily compress data that will
        !          5490: not save any storage space. While this may seem an obvious statement, please
        !          5491: review the following pseudo-code example:
        !          5492: 
        !          5493: if ( message_data_length < SDT_BLOCK_LEN )
        !          5494:     // Store uncompressed data
        !          5495: else {
        !          5496:     // Compress data
        !          5497:     if ( ( compressed_data_length / SDT_BLOCK_LEN )
        !          5498:         < ( message_data_length / SDT_BLOCK_LEN ) ) // Saves a block or more
        !          5499:         // Store compressed data
        !          5500:     else
        !          5501:         // Store uncompressed data
        !          5502:     }
        !          5503: 
        !          5504: Since the SMB format stores message data in fixed length blocks, there is no
        !          5505: point in storing a message in compressed format if it requires the same number
        !          5506: of blocks as the uncompressed format (i.e. a message that is two blocks in
        !          5507: length in uncompressed format and only a block and a half in length when
        !          5508: compressed should not be stored in compressed format since it still requires
        !          5509: two full blocks of storage). It is important to note that in the above example,
        !          5510: the length of the data translation string was not taken into account in
        !          5511: determining the number of required blocks. Also, the smb_datblocks() function
        !          5512: is normally used in determing the number of required blocks to store a given
        !          5513: data length and it is a little more involved than simply dividing the length of
        !          5514: the data by SDT_BLOCK_LEN.
        !          5515: 
        !          5516: 
        !          5517: 
        !          5518: 
        !          5519: 
        !          5520: 
        !          5521: 
        !          5522: 
        !          5523: 
        !          5524: 
        !          5525: 
        !          5526: 
        !          5527: 
        !          5528: 
        !          5529: 
        !          5530: 
        !          5531: 
        !          5532: 
        !          5533: 
        !          5534: 
        !          5535: 
        !          5536: 
        !          5537: 
        !          5538: 
        !          5539: 
        !          5540: 
        !          5541: _______________________________________________________________________________
        !          5542: Synchronet                           94               SMBLIB Performance Issues
        !          5543: 
        !          5544: 
        !          5545: Bibliography
        !          5546: ============
        !          5547: 
        !          5548: Title     : The C Programming Language
        !          5549: Publisher : Prentice Hall
        !          5550: Author    : Brian W. Kernighan and Dennis M. Ritchie
        !          5551: 
        !          5552: Document  : ARPANET Request for Comments (RFC) #822
        !          5553: Title     : Standard for the Format of ARPA Internet text messages
        !          5554: Publisher : SRI International
        !          5555: Author    : David H. Crocker, University of Delaware
        !          5556: 
        !          5557: Document  : FTS-0001
        !          5558: Publisher : FSC
        !          5559: Author    : Randy Bush, Pacific Systems Group
        !          5560: 
        !          5561: Document  : FTS-0004
        !          5562: Title     : EchoMail Specification
        !          5563: Publisher : FSC
        !          5564: Author    : Bob Hartman
        !          5565: 
        !          5566: Document  : FTS-0009
        !          5567: Title     : A standard for unique message identifiers and reply chain linkage
        !          5568: Publisher : FSC
        !          5569: Author    : Jim Nutt
        !          5570: 
        !          5571: Document  : FSC-00046
        !          5572: Title     : A Product Idenfifier for FidoNet Message Handlers
        !          5573: Publisher : FSC
        !          5574: Author    : Joaquim H. Homrighausen
        !          5575: 
        !          5576: Document  : FSC-00053
        !          5577: Title     : Specifications for the ^aFLAGS field
        !          5578: Publisher : FSC
        !          5579: Author    : Joaquim H. Homrighausen
        !          5580: 
        !          5581: 
        !          5582: 
        !          5583: 
        !          5584: 
        !          5585: 
        !          5586: 
        !          5587: 
        !          5588: 
        !          5589: 
        !          5590: 
        !          5591: 
        !          5592: 
        !          5593: 
        !          5594: 
        !          5595: 
        !          5596: 
        !          5597: 
        !          5598: 
        !          5599: 
        !          5600: _______________________________________________________________________________
        !          5601: Synchronet                           95                            Bibliography
        !          5602: 
        !          5603: 
        !          5604: Implementations
        !          5605: ===============
        !          5606: 
        !          5607: Product   : Synchronet Multinode BBS Software
        !          5608: Developer : Digital Dynamics
        !          5609: Level     : III
        !          5610: Version   : 2.20
        !          5611: 
        !          5612: Product   : Synchronet/FidoNet Import/Export Utility (SBBSFIDO)
        !          5613: Developer : Digital Dynamics
        !          5614: Level     : III
        !          5615: Version   : 2.23
        !          5616: 
        !          5617: Product   : Synchronet UTI (Universal Text Interface) Driver
        !          5618: Developer : Digital Dynamics
        !          5619: Level     : III
        !          5620: Version   : 2.23
        !          5621: 
        !          5622: Product   : SBBSecho FidoNet Packet Tosser for Synchronet
        !          5623: Developer : Digital Dynamics
        !          5624: Level     : III
        !          5625: Version   : 1.11
        !          5626: 
        !          5627: Product   : NetXpress Internet UUCP for Synchronet
        !          5628: Developer : Merlin Systems
        !          5629: Level     : II
        !          5630: Version   : 1.50
        !          5631: 
        !          5632: Product   : InterEcho FidoNet Packet Tosser
        !          5633: Developer : InterMail Sales Inc
        !          5634: Level     : II
        !          5635: Version   : 1.11
        !          5636: 
        !          5637: 
        !          5638: 
        !          5639: 
        !          5640: 
        !          5641: 
        !          5642: 
        !          5643: 
        !          5644: 
        !          5645: 
        !          5646: 
        !          5647: 
        !          5648: 
        !          5649: 
        !          5650: 
        !          5651: 
        !          5652: 
        !          5653: 
        !          5654: 
        !          5655: 
        !          5656: 
        !          5657: 
        !          5658: _______________________________________________________________________________
        !          5659: Synchronet                           96                                   Index
        !          5660: 
        !          5661: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.