home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / MXMS_160.LZH / QWK.DOC < prev    next >
Text File  |  1991-04-25  |  15KB  |  316 lines

  1.                         The Mysterious QWK-File Format
  2.  
  3.                                       by
  4.  
  5.                                   Jeffery Foy
  6.  
  7.  
  8.          It would be safe to assume that if you're reading this
  9.          article, you use or have used a QWK-compatible offline mail
  10.          reader. The QWK format has emerged as the format of choice
  11.          due to the relatively small size of QWK mail packets as
  12.          compared to an equivalent ASCII text file.
  13.  
  14.          As most users of offline mail readers know, the QWK format
  15.          was designed by Mark Herring (Sparky) of Sparkware. While Mr.
  16.          Herring did design the format, he only gave very sketchy
  17.          details as to the specifics of the format. This is quite
  18.          understandable as he is a very busy person. That is the
  19.          reason why I'm writing this article.
  20.  
  21.          In it's most basic form, a QWK file is simply a compressed
  22.          file. In almost all cases, the QWK file has been compressed
  23.          with PKZIP from PKWARE. With most mail doors, you can usually
  24.          choose your favorite archiver so your QWK file may not be in
  25.          PKZIP format.
  26.  
  27.          Within the compressed QWK file are quite a number of other
  28.          component files. We'll start with the one called CONTROL.DAT
  29.          since it is the easiest to describe. It is an ASCII text file
  30.          so if you have one handy, you can follow along.
  31.  
  32.          Generic BBS            ; Line # 1
  33.          Seattle, WA            ; Line # 2
  34.          206-555-1212           ; Line # 3
  35.          Joe Sysop, Sysop       ; Line # 4
  36.          00000,GENBBS           ; Line # 5
  37.          01-01-1991,00:00:00    ; Line # 6
  38.          MARY USER              ; Line # 7
  39.          MENU                   ; Line # 8
  40.          0                      ; Line # 9
  41.          0                      ; Line #10
  42.          254                    ; Line #11
  43.          0                      ; Line #12
  44.          Main Conf              ; Line #13
  45.          ...                    ; Line # x
  46.          254                    ; Line # x
  47.          Last Conf              ; Line # x
  48.          HELLO
  49.          NEWS
  50.          GOODBYE
  51.  
  52.          Line # 1 - This is the BBS name where you got your mail
  53.                     packet.
  54.          Line # 2 - This is the city and state where the BBS is
  55.                     located.
  56.          Line # 3 - This is the BBS phone number.
  57.          Line # 4 - This is the sysop's name.
  58.          Line # 5 - This line contains first the serial number of the
  59.                     mail door followed by the BBS ID. Note the BBS ID
  60.                     as it will be used later in this article.
  61.          Line # 6 - This is the time and date of the packet.
  62.          Line # 7 - This is the uppercase name of the user for which
  63.                     this packet was prepared.
  64.          Line # 8 - This line contains the name of the menu file for
  65.                     those who use the Qmail reader/door. Almost all
  66.                     other mail doors leave this line blank.
  67.          Line # 9 - No one seems to know what this line is meant for.
  68.          Line #10 - No one seems to know what this line is meant for.
  69.                     (Note: Both of these ALWAYS seem to be 0)
  70.          Line #11 - This line is the maximum number of conferences
  71.                     MINUS 1.
  72.          Line #12 - This line is the first conference's number. It is
  73.                     usually 0 but not always.
  74.          Line #13 - This line is the name of the first conference. It
  75.                     is 10 characters or less.
  76.  
  77.          Lines 12 and 13 are repeated for as many conferences as
  78.          listed in line 11.
  79.  
  80.          Anything you see after the last conference name can be
  81.          ignored as that information isn't usually provided by mail
  82.          doors. One exception to this is the Markmail door.
  83.  
  84.  
  85.          Now we'll talk about the message file itself. If you haven't
  86.          guess by now, it is the MESSAGES.DAT file. This is, quite
  87.          obviously, the largest file in the .QWK packet.
  88.  
  89.          MESSAGES.DAT is organized very specifically into 128-byte
  90.          records. The first record is the Sparkware copyright notice.
  91.          The rest of the record after the copyright notice is filled
  92.          with blanks (spaces). To maintain compatibility with Sparky's
  93.          Qmail Door, all mail doors reproduce the copyright notice
  94.          exactly.
  95.  
  96.          Following the first record begins the "meat" of the message
  97.          file. Each message included in the file consists of a header
  98.          followed directly by the message text itself. First we will
  99.          describe the header:
  100.  
  101.           Header    Field
  102.          Position   Length   Description
  103.          --------   ------   ----------------------------------------
  104.          1          1        Message status byte
  105.                                 ' ' = public message which hasn't been
  106.                                       read
  107.                                 '-' = public and already read
  108.                                 '*' = private message
  109.                                 '~' = comment to sysop which hasn't
  110.                                       been read by the sysop
  111.                                 '`' = comment to sysop which HAS been
  112.                                       read by the sysop
  113.                                 '%' = password protected message that
  114.                                       hasn't been read (protected by
  115.                                       sender of message)
  116.                                 '^' = password protected message that
  117.                                       HAS been read (protected by
  118.                                       sender of message)
  119.                                 '!' = password protected message that
  120.                                       hasn't been read (protected by
  121.                                       group password)
  122.                                 '#' = password protected message that
  123.                                       HAS been read (protected by
  124.                                       group password)
  125.                                 '$' = password protected message that
  126.                                       is addressed to ALL (protected
  127.                                       by group password)
  128.          2         7         Message number coded in ASCII
  129.          9         8         Date coded in ASCII (MM-DD-YY)
  130.          17        5         Time coded in ASCII (HH:MM) 24 hour
  131.                              format
  132.          22        25        Uppercase name of person message is TO
  133.          47        25        Uppercase name of person message is FROM
  134.          72        25        Subject of message
  135.          97        12        Message password. Usually not anything
  136.                              but spaces (to denote no password)
  137.          109       8         Message # this message refers to (coded
  138.                              in ASCII)
  139.          117       6         Number of 128-byte chunks in the actual
  140.                              message (includes header and is coded in
  141.                              ASCII)
  142.          123       1         Determines whethere a message is live
  143.                              (active) or killed. 90% of the time you
  144.                              won't see a killed message in a packet.
  145.                                  'a' = Message is active/alive (0xE1)
  146.                                  'b' = Message is killed/dead  (0xE2)
  147.          124       1         Least significant byte of conference
  148.                              number.
  149.          125       1         Most significant byte of conference
  150.                              number. NOTE: This isn't in the original
  151.                              .QWK format but has become the standard
  152.                              due to conference numbers greater than
  153.                              255. In the original format, this byte
  154.                              was space-filled.
  155.          126       3         Filler bytes for future expansion.
  156.                              Space-filled and usually ignored.
  157.  
  158.          Following the header record comes the message text itself.
  159.          The message text is simply the body of the message. To save
  160.          space, the return/linefeed combination is translated to the
  161.          pi character 'c' (0xE3). Note that the last line of the
  162.          message is padded with spaces to fill out the 128-byte
  163.          record.
  164.  
  165.  
  166.          Now we'll talk about the *.NDX files that are included in the
  167.          packet. Each .NDX file is formatted into records of 5-bytes
  168.          each. The bytes in each record are formatted thusly:
  169.  
  170.          Start  Field
  171.          Byte   Length   Description
  172.          ----   ------   --------------------------------------------
  173.          1      4        This is a floating point number in the MSBIN
  174.                          format. This number is the record number of
  175.                          the message header in MESSAGES.DAT that
  176.                          corresponds to this message.
  177.          5      1        This byte is the conferece number of this
  178.                          message. This byte can (and should) be
  179.                          ignored as it is duplicated in the message
  180.                          header in MESSAGES.DAT. This is especially
  181.                          important for conferences numbered higher
  182.                          than 255.
  183.  
  184.          Let's stray just a moment to talk about the MSBIN floating
  185.          point format. This is the format used by the older Microsoft
  186.          Basic compilers and interpreters. Most compiler manufacturers
  187.          have switched to the more efficient IEEE floating point
  188.          format. Therefore, we must have a method of converting to and
  189.          from MSBIN format. Included at the end of this article are
  190.          two routines in C that accomplish this quite easily.
  191.  
  192.  
  193.  
  194.          Ok, let's talk about the format of the .REP (reply) packet.
  195.          Like the .QWK packet it is usually compressed. Inside the
  196.          compressed archive is a file whose extension is .MSG. The
  197.          filename itself is the same as line #5 of CONTROL.DAT. This
  198.          is the BBSID. So, for example, if the BBSID is GENERIC, the
  199.          complete filename in the .REP packet would be GENERIC.MSG.
  200.  
  201.          The format of the .MSG file is almost exactly the same as the
  202.          MESSAGES.DAT file with three differences:
  203.  
  204.          1). In the first record, rather than a copyright notice, the
  205.          first eight bytes are the BBSID as described above. The rest
  206.          of the record is filled with spaces.
  207.  
  208.          2). In the message header, rather than the ASCII-coded
  209.          message number, we have the ASCII-coded conference number
  210.  
  211.          3). Also in the message header, the conference number field
  212.          (byte offset 124 & 125) may be filled with spaces *OR* the
  213.          conference number.
  214.  
  215.  
  216.          In recent months a new file, DOOR.ID, has been added to the
  217.          .QWK packet. I know very little about it but will attempt to
  218.          explain it as best as I can.
  219.  
  220.          DOOR.ID seems to be a method for individual doors to let the
  221.          mail reader know how to add and drop conferences. It is a
  222.          good idea and I hope more doors and readers can be made to
  223.          cooperate with it.
  224.  
  225.          Usually there are only five lines in this file. Here is a
  226.          sample from one of my recent .QWK packets:
  227.  
  228.          DOOR = TomCat!                       Line #1
  229.          VERSION = 2.9                        Line #2
  230.          SYSTEM = Wildcat! 2.x                Line #3
  231.          CONTROLNAME = TOMCAT                 Line #4
  232.          CONTROLTYPE = ADD                    Line #5
  233.          CONTROLTYPE = DROP                   Line #6
  234.  
  235.          Line #1 - This is the mail door's name.
  236.          Line #2 - This is the mail door's version number.
  237.          Line #3 - This is the BBS software used and version number.
  238.          Line #4 - This is the control name (TO:) where to send
  239.                    requests for conference changes.
  240.          Line #5 - This is the command the door expects to see to add
  241.                    a conference to the user's current list.
  242.          Line #6 - This is the command the door expects to see to drop
  243.                    a conference from the user's current list.
  244.  
  245.  
  246.          Here are the routines I use to convert to and from the MSBIN
  247.          format. You may use them as you see fit - they are not
  248.          copyrighted by me.
  249.  
  250.          /***  MSBIN conversion routines ***/
  251.  
  252.          union Converter
  253.                {
  254.                 unsigned char uc[10];
  255.                 unsigned int  ui[5];
  256.                 unsigned long ul[2];
  257.                 float          f[2];
  258.                 double         d[1];
  259.                }
  260.  
  261.          /* MSBINToIEEE - Converts an MSBIN floating point number */
  262.          /*               to IEEE floating point format           */
  263.          /*                                                       */
  264.          /*  Input: f - floating point number in MSBIN format     */
  265.          /* Output: Same number in IEEE format                    */
  266.  
  267.          float MSBINToIEEE(float f)
  268.          {
  269.             union Converter t;
  270.             int sign, exp;       /* sign and exponent */
  271.  
  272.             t.f[0] = f;
  273.  
  274.          /* extract the sign & move exponent bias from 0x81 to 0x7f */
  275.  
  276.             sign = t.uc[2] / 0x80;
  277.             exp  = (t.uc[3] - 0x81 + 0x7f) & 0xff;
  278.  
  279.          /* reassemble them in IEEE 4 byte real number format */
  280.  
  281.             t.ui[1] = (t.ui[1] & 0x7f) | (exp << 7) | (sign << 15);
  282.             return t.f[0];
  283.          } /* End of MSBINToIEEE */
  284.  
  285.  
  286.          /* IEEEToMSBIN - Converts an IEEE floating point number  */
  287.          /*               to MSBIN floating point format          */
  288.          /*                                                       */
  289.          /*  Input: f - floating point number in IEEE format      */
  290.          /* Output: Same number in MSBIN format                   */
  291.  
  292.          float IEEEToMSBIN(float f)
  293.          {
  294.             union Converter t;
  295.             int sign, exp;       /* sign and exponent */
  296.  
  297.             t.f[0] = f;
  298.  
  299.          /* extract sign & change exponent bias from 0x7f to 0x81 */
  300.  
  301.             sign = t.uc[3] / 0x80;
  302.             exp  = ((t.ui[1] >> 7) - 0x7f + 0x81) & 0xff;
  303.  
  304.          /* reassemble them in MSBIN format */
  305.  
  306.             t.ui[1] = (t.ui[1] & 0x7f) | (sign << 7) | (exp << 8);
  307.             return t.f[0];
  308.          } /* End of IEEEToMSBIN */
  309.  
  310.  
  311.          Well, that is all there is to it! I hope this article has
  312.          shed some light on the so-called "mysterious" .QWK format.
  313.  
  314.  
  315.                                              Jeffery Foy, April 1991
  316.