home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 September / Chip_2000-09_cd1.bin / sharewar / Slunec / app / 16 / COMM.SWG / 0005_QWK.pas < prev    next >
Pascal/Delphi Source File  |  1996-09-03  |  14KB  |  294 lines

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