home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / C / MBLIB10 / MB_LIB.DOC < prev    next >
Text File  |  1993-03-07  |  122KB  |  3,157 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.             =============================================================
  14.  
  15.                                      MB_lib V1.0
  16.  
  17.                 Hudson and Opus message base interface library for C
  18.  
  19.                           (c) F.W. van Wensveen 1992, 1993
  20.  
  21.                                  All Rights Reserved
  22.  
  23.             =============================================================
  24.  
  25.  
  26.                 The author of this software can be reached via E-mail
  27.                   as Frank Van.wensveen at the following addresses:
  28.  
  29.                                 2:285/504@fidonet.org
  30.                                27:1331/703@signet.org
  31.                                 310/902 GT Power net
  32.                    frank.van.wensveen@p0.f504.n285.z2.fidonet.org
  33.  
  34.                                  BBS: +31-10-4717477
  35.                  (V21, V22, V22b, V23, V32b, V42b, MNP2..5 - 24h/day
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.                     Abstract
  50.  
  51.                     MB_lib is a message library for use with C (calling the
  52.                     routines  from  other  languages  is,  of  course, also
  53.                     possible). It provides a full set of services needed to
  54.                     interface your applications with both Hudson and *.MSG-
  55.                     style message bases quite easily.
  56.  
  57.                     This document only contains flat ASCII.
  58.  
  59.  
  60.           ============================================================
  61.           1. INTRODUCTION
  62.           ============================================================
  63.  
  64.           Why MB_lib?
  65.           -----------
  66.  
  67.           One of  the most important features BBSes and mail systems is the
  68.           ability to handle electronic mail. This  enables people  from all
  69.           over the world to communicate with each other against hardly more
  70.           than the cost of (usually) local phone calls. Initially, messages
  71.           were stored  by the  BBS and/or mailer software in separate files
  72.           for each message (the well-known *.MSG files).
  73.           Since this proved a very inefficient way of using disk space, the
  74.           Hudson message  base was  developed. This message base stores all
  75.           messages in only five files, one of which contains the total text
  76.           of all messages in the system, while the other files act as index
  77.           files. This  system uses  the available  more efficiently. Today,
  78.           the  Hudson  message  base  is  used by many popular BBS and mail
  79.           programs like  Remote  Access,  SuperBBS,  Quick  BBS, FrontDoor,
  80.           TosScan, Fmail, and lots, lots more.
  81.  
  82.           The Hudson  message base  however has the disadvantage that it is
  83.           quite complicated to access when  compared  with  a  simple *.MSG
  84.           file. Therefore,  programmers have had more difficulty developing
  85.           software to interface with  the Hudson  message base,  since they
  86.           would  have  to  write  their  own,  often complicated, interface
  87.           routines  first,  before  getting  down  to  the  meat  of  their
  88.           applications.
  89.           This library  intends to  remedy that  by providing a full set of
  90.           functions that allow you to interface with both  Hudson and *.MSG
  91.           message bases  in a  very simple  way. If  you're a C programmer,
  92.           this is what you've been waiting for.
  93.           MB_lib is a library intended for use with C. It was written using
  94.           Borland Turbo  C 2.01.  and Turbo Assembler 1.5. It may also work
  95.           with other compilers than Borland's. Of course you  can also call
  96.           the functions  from other  languages like  Assembly, provided you
  97.           know how. I intend to  release  a  version  for  Borland  C++ for
  98.           Windows, but  at the time this document was written, this version
  99.           isn't finished yet. As far as  I know  this is  the first library
  100.           offering these services to the C community.
  101.  
  102.  
  103.           A WORD TO THOSE WHO'D RATHER USE PASCAL
  104.           ---------------------------------------
  105.  
  106.           For those  with Pascal  experience the story might begin to sound
  107.           familiar. For Turbo Pascal there already  is a  unit with message
  108.           base  routines  available.  This  is MSGBASE by Richard Faasen of
  109.           Sliedrecht,  The  Netherlands,  SysOp  of  InFase  BBS (+31-1840-
  110.           21818). So  if you're  a Pascal programmer, you can either switch
  111.           to C (why not?) or contact Richard.
  112.           This library is based upon Richards original Pascal  source code.
  113.           (See also the credits at the end of this document.)
  114.  
  115.  
  116.  
  117.  
  118.  
  119.                                                 2
  120.  
  121.  
  122.           FEATURES
  123.           --------
  124.  
  125.           The  most  important  features  of  MB_lib  include  (but are not
  126.           limited to):
  127.           *    All you need to  read, write,  search for  or kill messages.
  128.                Writing a new message is as easy as msg_write_new ()!
  129.           *    Dynamic  use  of  memory.  Message text can have *any* size,
  130.                the only restriction being  actual  memory  limits.  Text is
  131.                manipulated using a 'text handle'.
  132.           *    Flexible,  well-behaved,  and  stable.  With flexible I mean
  133.                that MB_lib won't get in the way of whatever you're doing in
  134.                your  applications   (you  can,  for  example,  call  MB_lib
  135.                routines when in  graphics  mode  without  problems). MB_lib
  136.                interfaces with your operating system in a decent way.
  137.           *    Powerful yet flexible error trapping and -handling.
  138.           *    Fully supports  the Remote  Access 1.11 message base locking
  139.                technique. This means  you  can  write  programs  suited for
  140.                multi-tasking environments,  as required by applications for
  141.                Remote Access on multi-line systems.
  142.           *    Written with portability in mind. I haven't tried it as yet,
  143.                but porting  MB_lib to other platforms than MS-DOS should be
  144.                relatively easy.  The only  system-dependent code  is in the
  145.                locking mechanism, which other OSes might not need.
  146.           *    No-nonsense programming  style. No  effort has  been made to
  147.                dress up the software or to provide flashy effects. Instead,
  148.                the code is flexible and well-behaved enough so that you may
  149.                do  that  yourself  if  you  wish.  MB_lib  concentrates  on
  150.                providing  fast,   stable  and  efficient  services  without
  151.                unwanted overhead (Unix people will get the idea).
  152.  
  153.  
  154.           FILES IN THE PACKAGE
  155.           --------------------
  156.  
  157.           The distribution package of  MB_lib should  contain the following
  158.           files:
  159.  
  160.           MB_LIB.DOC     The file you are currently reading
  161.           MB_LIB.H       The header file for MB_lib
  162.           MB_LIBT.LIB    Message base library file, Tiny model
  163.           MB_LIBS.LIB    Message base library file, Small model
  164.           MB_LIBC.LIB    Message base library file, Compact model
  165.           MB_LIBM.LIB    Message base library file, Medium model
  166.           MB_LIBL.LIB    Message base library file, Large model
  167.           MB_LIBH.LIB    Message base library file, Huge model
  168.           *.C            Example programs.  Look here  for tips & tricks on
  169.                          how to use the library functions in your programs.
  170.           RALCK003.DOC   The Remote Access Locking Specification version 3,
  171.                          contains details on message base locking.
  172.  
  173.           If you receive a version with any of these files missing, you can
  174.           obtain a complete and  uncorrupted  version  of  MB_lib  from the
  175.           author.
  176.  
  177.  
  178.  
  179.  
  180.  
  181.                                                 3
  182.  
  183.  
  184.           ABOUT THIS MANUAL
  185.           -----------------
  186.  
  187.           Like the  code, this  manual is very straightforward. It provides
  188.           brief insights on how  the Hudson  message base  stores messages,
  189.           how  MB_lib  handles  things,  and  than proceeds to describe the
  190.           library functions. In other words,  this  document  is  meant for
  191.           people familiar  with C.  It is  beyond the scope of this text to
  192.           explain how functions are called  or  how  pointers  are  used to
  193.           handle data.
  194.           The function  descriptions should look familiar to anyone who has
  195.           ever seen a C reference guide  or used  a man  command on  a Unix
  196.           system. Basic  knowledge about  echomail is  assumed. It wouldn't
  197.           hurt to be familiar with FTS-0001, either.
  198.           Sometimes examples are given in the  reference section. Sometimes
  199.           these  examples  are  complete  programs, sometimes not. The only
  200.           purpose of these examples is to illustrate how a certain function
  201.           works, so do not regard them as complete and functional programs.
  202.           Example source code is included in  the distribution  package. It
  203.           might really be a good idea to have a look at it.
  204.  
  205.  
  206.           CREDITS
  207.           -------
  208.  
  209.           Special thanks to the following people:
  210.  
  211.           *    Richard  Faasen,  who  wrote  the  original  Pascal  version
  212.                (MsgBase 1.0) and gave me the Pascal source to have  a go at
  213.                it in  C. Never mind the fact that he tried to convert me to
  214.                C++ just before the beta version was finished. <grin>
  215.           *    The beta team: Feico de Boer, Olaf Westrik, Arnoud de Jonge,
  216.                Richard Faasen,  plus lots  of people  who made suggestions,
  217.                offered advice, or just gave moral support.
  218.           *    John Lots for many tips and pieces of advice that (sometimes
  219.                unintended and without his knowledge) finally ended up here.
  220.           *    Brian Pirie  of Ottawa,  Ontario, who  knows how  to write a
  221.                hashing algorithm.
  222.           *    Everyone who replied to  my questions  in the  FIDOnet C and
  223.                Assembly conferences.
  224.  
  225.           Thank you, guys! You were all most helpful.
  226.  
  227.  
  228.           DISTRIBUTION, LICENCING AND LEGALESE
  229.           ------------------------------------
  230.  
  231.           The latest  version of  MB_lib is  always available on my BBS, or
  232.           you can request it from one of my E-mail addresses. See the front
  233.           page  of  this  document  for  details. For support, bug reports,
  234.           etc., you can also contact me at the adresses on the front page.
  235.           If you've written programs using this library, I'd really like to
  236.           see them,  and, if  you want  me to,  I'll be happy to comment on
  237.           them, and distribute the via my BBS.
  238.  
  239.           You may (and in fact, are  encourage to)  copy this  software and
  240.           distribute those copies. However, YOU MAY NOT:
  241.  
  242.  
  243.                                                 4
  244.  
  245.  
  246.           -    Alter or  remove any  portion of the package, including this
  247.                document, in any way.
  248.           -    Distribute it  on  a  commercial  basis.  You  may, however,
  249.                charge a  nominal fee not to exceed the cost of floppy disks
  250.                and mailing costs.
  251.           -    Distribute  program's  you've   written   and   compiled  an
  252.                unregistered version of MB_lib.
  253.  
  254.           Disclaimer:  The  author  of  this  software  does not accept any
  255.           responsibility for any damage, direct or indirect, including, but
  256.           not limited to, lost profits, lost savings, or loss or corruption
  257.           of data, resulting from the use of, or the inability to use, this
  258.           software. 
  259.           The software  is provided 'as is', without any guarantee whatsoe-
  260.           ver. If it works for you, fine. If it does  not, too  bad. If you
  261.           try this  program and your system goes to pieces, I'm not obliged
  262.           to provide you with a tube of glue. It is the users responsibili-
  263.           ty  to  make  backups  of  important data, to carefully check out
  264.           untested software, and to take precautions in general.  So if you
  265.           like to live dangerously, on your own head be it.
  266.  
  267.           The author  retains the copyright to this software. This software
  268.           is NOT in the public domain. Source code  is not  available, and,
  269.           by previous agreement to other parties, it won't become available
  270.           in the future.
  271.  
  272.           As to licencing: THIS IS NOT  FREE  SOFTWARE!  I  know,  for many
  273.           people this part is a giggle, but bear with me for a moment.
  274.           You  may  try  this  software  for  30 days. If you decide not to
  275.           continue using it after  the trial  period of  30 days,  you must
  276.           stop using  it, and  you must destroy (== delete) all executables
  277.           containing linked code from MB_lib.
  278.           If you decide that the stuff  is worth  the disk  space, you must
  279.           register  MB_lib.  See  the  file  REGISTER.TXT, included in this
  280.           package, for conditions and full details on how to register.
  281.  
  282.  
  283.           A note about the shareware concept
  284.           ----------------------------------
  285.  
  286.           Just to make your conscience uneasy,  consider this.  In the past
  287.           I've written stuff on a write-it-when-I-need-it basis. Sometimes,
  288.           when a piece of software came in particularly handy, I decided to
  289.           distribute it. I granted permission to anyone to use the software
  290.           absolutely free, but I asked to  be  sent  a  netmail  message, a
  291.           postcard, or whatever, when someone decided to use my stuff.
  292.           Since then, I've seen my programs popping up in the most unlikely
  293.           places. So people actually use it,  which gives  me a  real kick.
  294.           But the  number of  reactions I  got was very disappointing. This
  295.           may be  due  to  the  fact  that  I  never  crippled distribution
  296.           versions. This sounds ridiculous, and, if true, it is.
  297.           So, when  people will use my software (in which, by the way, I've
  298.           invested a considerable amount of time), but consider it too much
  299.           trouble to  even drop me a netmail message, this may very well be
  300.           the last program from me. This time it's  really going  to depend
  301.           on user response. If I don't get any - again - then I won't spend
  302.           too much time at the keyboard next time. On the  other hand, any-
  303.            and I  mean *any*  - reaction  is an  impulse for me to continue
  304.  
  305.                                                 5
  306.  
  307.  
  308.           with projects like these. I'm sorry to put  it this  bluntly, but
  309.           that's the way it is. It's all in your hands now. 
  310.           If you  don't use the stuff, fine. But at least drop me a line to
  311.           let me know what you think  of it.  If you're  experimenting with
  312.           this,  the  odds  are  that  you  know  how  to send me a netmail
  313.           message. If not, ask the nearest SysOp, he'll be more  than happy
  314.           to instruct you.
  315.           If, on  the other  hand, you  decide to  use it, even better! But
  316.           register the stuff. It's  cheap,  and  it  will  keep  me  at the
  317.           keyboard to write something even better.
  318.  
  319.           OK -  some have hinted that I didn't get any reactions because my
  320.           documentation intro's tend to get long-winded... so let's  get on
  321.           with it!
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.                                                 6
  368.  
  369.  
  370.           ============================================================
  371.           2. TECHNICAL BACKGROUND INFORMATION
  372.           ============================================================
  373.  
  374.  
  375.           A BRIEF OVERVIEW OF THE HUDSON MESSAGE BASE
  376.           -------------------------------------------
  377.  
  378.           It is beyond the scope of this text to explain the Hudson message
  379.           base in detail. For those who want to know more, see the original
  380.           specifications, if you can find 'em.
  381.  
  382.           The  Hudson  message  base  consists  of  five  files.  Each file
  383.           consists of one or more records, the format of which you can find
  384.           in the MB_lib header file. A short description follows:
  385.  
  386.                MSGINFO.BBS    This file  is the only one with a fixed size.
  387.                               It contains  a single  record specifying info
  388.                               regarding the entire message base: the number
  389.                               of  messages  in  the  base,  the  lowest and
  390.                               highest number, and the amount of messages in
  391.                               each board.
  392.                MSGIDX.BBS     Index file. This file  contains a  record for
  393.                               each  message   in  the   base.  This  record
  394.                               specifies the message number and the board it
  395.                               can be  found in.  This file  can be used for
  396.                               searching for messages in a certain board.
  397.                MSGTOIDX.BBS   Index file. This file  contains a  record for
  398.                               each message in the base. The record contains
  399.                               the  who_to  field  from   the  corresponding
  400.                               message  header,  if  the message hasn't been
  401.                               received  by  the  user  yet.  (Mail  readers
  402.                               should overwrite  this record  when a message
  403.                               has been read.) This  file  can  be  used for
  404.                               searching  for  unread  messages to a certain
  405.                               user.
  406.                MSGHDR.BBS     Index file. This file  contains a  record for
  407.                               each message in the base. The records contain
  408.                               the header of the  corresponding message. Two
  409.                               fields in  this header  specify the number of
  410.                               the first text block of the  message, and the
  411.                               number of text blocks.
  412.                MSGTEXT.BBS    Ah,  this  is  the  one.  This  file contains
  413.                               blocks  of  text,  that  make  up  the actual
  414.                               message  text   body.  Start   en  length  of
  415.                               messages  are  specified  by  fields  in  the
  416.                               message header.
  417.  
  418.           The files  marked as  'Index file' have indeed an index function.
  419.           That means that record  n  in  one  index  file  corresponds with
  420.           record n  in another  index file. In other words, if a search for
  421.           unread mail  in MSGTOIDX.BBS  results in  a search  hit at record
  422.           100,  you  should  examine  record  100 in MSGIDX.BBS to find the
  423.           message number and board number, read record 100 in MSGHDR.BBS to
  424.           get  the  message  header,  and  examine this header to determine
  425.           which records to read from  MSGTEXT.BBS  to  dig  up  the message
  426.           text. But  you needn't worry about this - MB_lib will do that for
  427.           you.
  428.  
  429.                                                 7
  430.  
  431.  
  432.           Obviously, if one of  the index  files should  be corrupted, this
  433.           could mean loss of all messages in the base. Panic!
  434.           Well,  it's  not  as  bad  as  that.  If the files MSGHDR.BBS and
  435.           MSGTXT.BBS are  uncorrupted, the  other files  can be regenerated
  436.           from these by many message base maintenance utilities.
  437.  
  438.  
  439.           INTRODUCTION TO FILE LOCKING
  440.           ----------------------------
  441.  
  442.           In an  multi-tasking environment  where two or more processes are
  443.           sharing a single database or file, steps must be taken to prevent
  444.           file or database corruption when writing.
  445.           Picture this:  we read  a message  header, update  the reply link
  446.           pointers, and write it back. Nothing wrong so far. Now  try this:
  447.           we  read  a  file  header.  While  we're modifying the reply link
  448.           pointers, another  process  (like  another  instance  of  the BBS
  449.           program handling  another line)  also reads  the header. We write
  450.           our modified header back, after which the other  process does the
  451.           same, THEREBY  OVERWRITING THE MODIFICATIONS WE JUST MADE. Voila:
  452.           one corrupt message base.
  453.           To prevent all this, we use file locking. Before modifying one of
  454.           the files, we lock the message base. That is: we indicate then no
  455.           other process may write to the  files  at  this  moment.  Then we
  456.           read  and  modify  our  records,  write them back, and proceed to
  457.           unlock the message  base.  Other  operating  systems  than MS-DOS
  458.           (Unix for example) handle this for us, but if we're using MS-DOS,
  459.           we must do it ourselves. Thanks a bundle, MicroSoft.
  460.           MB_lib meets the official  Remote  Access  Locking Specification.
  461.           That means  that we  don't use  file locking in the normal sense,
  462.           relying on SHARE to provide the  services that  plain DOS doesn't
  463.           offer. Instead,  the files  are locked  outside their boundaries,
  464.           while RA checks for a lock just there. In the  meantime, a 0-byte
  465.           file  in  RA's  semaphore  file  directory  can indicate that the
  466.           message base must be unlocked NOW. So, as  I said,  it's not real
  467.           record  locking  in  the  normal  (OS)  sense. See the RA locking
  468.           specification for details.
  469.           Should you use file  locking when  writing a  program? YES!!! You
  470.           may not  be running  a multi-line  BBS, but somebody else may, so
  471.           that your program would corrupt the  message base  of that system
  472.           if you didn't use file locking.
  473.           MB_lib provides  two functions for easy locking and unlocking the
  474.           message base, so that you won't  have much  trouble handling this
  475.           properly.
  476.           Since  other  processes  can't  write while we've got the message
  477.           base locked,  we  should  unlock  it  regularly.  When performing
  478.           several write operations at a time, for example while changing an
  479.           entire message, you should use the following locking  / unlocking
  480.           sequences:
  481.           Changing a message header:
  482.                - Lock the message base
  483.                - Read the message header
  484.                - Modify it
  485.                - Write it back
  486.                - Unlock the message base
  487.           Writing new message text when the message header exists:
  488.                - Create message text
  489.                - Lock the message base
  490.  
  491.                                                 8
  492.  
  493.  
  494.                - Read the header
  495.                - Write message text
  496.                - Modify header
  497.                - Write back header
  498.                - Unlock message base
  499.           The same  goes for  *any* write  operation (create, modify, kill,
  500.           whatever) to  the message  base. Lock  the message  base, do your
  501.           modification,  unlock,  lock,  do  another  modification, unlock.
  502.           Always lock as short as possible. If you should need  to lock the
  503.           message base  for more  than 15  seconds at a time, you must take
  504.           some special precautions. See the document  RALCK003, enclosed in
  505.           this package, for details.
  506.  
  507.  
  508.           HOW TEXT IS STORED IN MEMORY
  509.           ----------------------------
  510.  
  511.           The size  of a  message text  body is unknown. The Hudson message
  512.           base allows - in theory - for  a  maximum  text  size  of  16 Mb,
  513.           though  many  BBS  and  mail processor packages can't handle more
  514.           than 8 or 16 kb. Therefore  it  is  wise  not  to  write messages
  515.           larger than 8 kb.
  516.           Anyway, we  can't allocate a fixed data space for a message text.
  517.           Therefore, text space is dynamically allocated.
  518.           Text  is  manipulated  with  a  so-called  text  handle.  For the
  519.           technically inclined:  this text  handle is actually a pointer to
  520.           the beginning of a linked list of records, consisting of pointers
  521.           to text blocks and pointers to the next record in the chain.
  522.           Text handles  are variables  of type  M_TEXT. You  declare a text
  523.           handle as follows:
  524.  
  525.           M_TEXT msgtxt;      /* Text handle to manipulate message text */
  526.  
  527.           That's all! Text  handles  are  returned  by  functions  like the
  528.           msg_read_text () and txt_new () functions. For example:
  529.  
  530.           msgtxt = msg_read_text (& header);  /* Read message text */
  531.  
  532.           To dump  this text  to, say,  the screen,  you use  the same text
  533.           handle:
  534.  
  535.           txt_dump (msgtxt, printline, margin, NOKLUDGES);
  536.  
  537.           It's a simple as that!
  538.  
  539.  
  540.           HOW MB_LIB HANDLES ERROR TRAPPING
  541.           ---------------------------------
  542.  
  543.           This may be news  to some  programmers... <grin>  but many things
  544.           can go  wrong while a program is running, and it is wise to check
  545.           for errors, so that when (not  if) an  error occurs,  the program
  546.           can gracefully  exit. Many  programs, especially those written in
  547.           Pascal for some reason, lack  airtight  error  trapping,  so that
  548.           they sometimes  exit with  the highly informative message RUNTIME
  549.           ERROR AT 1234:ABCD (or some other address). Anyway,  I've labored
  550.           to make error trapping in MB_lib as foolproof as possible.
  551.  
  552.  
  553.                                                 9
  554.  
  555.  
  556.           Since library  code never  should get  in the way of whatever the
  557.           application is  doing, error  trapping is  very flexible. Library
  558.           routines do  not exit to the OS. Library codes do not print error
  559.           messages. Nor  do  they  generate  beeps  or  anything  else. The
  560.           application programmer can do all this if desired.
  561.           Every  library  function  that  can  encounter an error returns a
  562.           completion code. This code usually is zero to indicate error-free
  563.           completion,  or  non-zero  if  an  error  was  encountered.  When
  564.           functions are supposed to return  a  number  (like  a  message or
  565.           record number),  the error completion code is -1, otherwise it is
  566.           an integer indication the nature of the error. For example:
  567.  
  568.           if (msg_open ("C:\\MSGBASE"))
  569.             error ();    /* Invoke programmer-supplied error handler */
  570.  
  571.           The programmer has two global variables  at his/her  disposal, to
  572.           determine the  nature of  the error.  When an error occurs, these
  573.           variables are automatically set to indicate what went  wrong, and
  574.           can be used in an error handler.
  575.           First,  there  is  the  int errortype variable. This variable can
  576.           have the following values:
  577.  
  578.           NOT_ERR (0x00)   /* No error                         */
  579.           MEM_ERR (0x01)   /* Memory error - out of memory     */
  580.           FRD_ERR (0x02)   /* File read error                  */
  581.           FWR_ERR (0x03)   /* File write error                 */
  582.           FCR_ERR (0x04)   /* File create error                */
  583.           MNO_ERR (0x05)   /* Message base not open error      */
  584.           IRN_ERR (0x06)   /* Invalid record no., out of bound */
  585.           MBC_ERR (0x07)   /* Msg base corrupt                 */
  586.  
  587.           THIS  VALUE  ALSO  APPLIES  TO  THE  FUNCTION  COMPLETION  CODES!
  588.           Examining either  the completion  code or  the errortype variable
  589.           can be used to trap errors.
  590.           Then there is the  char errorstring  [] variable.  This string is
  591.           filled  with  a  message  telling  the  user  what went wrong, in
  592.           readable text. 
  593.  
  594.           Using these two variables, an error handler could look like this:
  595.  
  596.           void error_exit (void) {
  597.             printf ("%cError %d accessing message base:\n%s\n",
  598.                      BELL, errortype, errorstring);
  599.             exit (1);
  600.           }
  601.  
  602.           Because MB_lib routines do not exit to the OS or  print anything,
  603.           you won't  get problems  when, for example, an error occurs while
  604.           in graphics mode. On the other  hand, if  you always  remember to
  605.           check completion  codes, you  will be  able to handle any kind of
  606.           error, critical or non-critical.
  607.  
  608.  
  609.           USE OF THE REGISTRATION KEY
  610.           ---------------------------
  611.  
  612.           Users who register their copy of MB_lib will  receive a registra-
  613.           tion key.  This key  is a  small file, that should be included in
  614.  
  615.                                                10
  616.  
  617.  
  618.           the program at the top of the source listing. Typically you would
  619.           add a     include "mb_lib.key"    statement to your program along
  620.           with the include statements for, say, the stdio.h file.
  621.           That  is  all!  The  registration  key  does  not  take  up extra
  622.           code/data space  in the  compiled executables. The only thing you
  623.           will notice is that the compiled  program no  longer displays the
  624.           'unregistered' message when running.
  625.           With the key, you can recompile your programs for distribution.
  626.  
  627.  
  628.           HOW MB_LIB IS DIVIDED INTO SEGMENTS
  629.           -----------------------------------
  630.  
  631.           Because the  whole library  is a large chunk of code, it would be
  632.           difficult to handle at  once. Therefore,  the library  is divided
  633.           into  segments.  This  provides  a  reasonable compromise between
  634.           efficiency and code size. If a  segment  isn't  used,  it  is not
  635.           linked to your executable.
  636.           The  functions  in  each  segment  are  discussed  in  a separate
  637.           chapter. The segments have the following functions:
  638.  
  639.           TEXT      Functions to handle text
  640.           ACCESS    Functions to access the message base
  641.           LOCK      Functions to  take  care  of  message  base  locking to
  642.                     enable  your  programs  to  run  in  a multi-tasking or
  643.                     multi-line BBS environment
  644.           MANIP     Message manipulation functions
  645.           READ      Functions to read records and messages
  646.           WRITE     Functions to write records and messages
  647.           SEARCH    Functions to search for messages
  648.           NETMAIL   This segment contains all functions to  handle messages
  649.                     in the  *.MSG format  (like netmail  messages with most
  650.                     mailers).
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676.  
  677.                                                11
  678.  
  679.  
  680.           ============================================================
  681.           3. TYPES, VARIABLES AND DEFINES
  682.           ============================================================
  683.  
  684.           =======================
  685.           M_TEXT
  686.           =======================
  687.  
  688.           Name           M_TEXT - text handle type
  689.  
  690.           Usage          M_TEXT <handlename>
  691.  
  692.           Description    As explained  above,  a  text  handle  is  used to
  693.                          manipulate message  text. A  variable of this type
  694.                          is returned by functions like txt_new ().
  695.  
  696.           See also       The background information  given  above,  and the
  697.                          reference  section  on  the txt_new () (and other)
  698.                          functions.
  699.  
  700.           Example        M_TEXT msgtext;   /* Text handle */
  701.  
  702.  
  703.           =======================
  704.           msginfo
  705.           =======================
  706.  
  707.           Name           msginfo - a global MSGINFO.BBS record  for various
  708.                          purposes
  709.  
  710.           Usage          MSGINFO_RECORD msginfo;
  711.  
  712.           Description    Since MSGINFO.BBS  contains only one record, which
  713.                          can have only one value, it makes sense  to define
  714.                          one  global  record  in which this information can
  715.                          be stored.  Instead of  reading the  file over and
  716.                          over  again  to  a  locally  defined  record, this
  717.                          variable provides one record which can be referred
  718.                          to  when   MSGINFO.BBS  data  is  needed  for  any
  719.                          purpose.
  720.  
  721.           See also       msg_read_info ();
  722.  
  723.  
  724.           ========================
  725.           errortype
  726.           ========================
  727.  
  728.           Name           errortype - indicate what went wrong
  729.  
  730.           Usage          int errortype;
  731.  
  732.           Description    The  errortype  variable   is   set   when  MB_lib
  733.                          encounters  an  error.  It  can have the following
  734.                          values:
  735.  
  736.                          NOT_ERR        No error
  737.                          MEM_ERR        Memory error (out of memory)
  738.  
  739.                                                12
  740.  
  741.  
  742.                          FRD_ERR        File read error
  743.                          FWR_ERR        File write error
  744.                          FCR_ERR        File creation error
  745.                          MNO_ERR        Message  base   not  opened  before
  746.                                         accessing it
  747.                          IRN_ERR        Invalid record number specified for
  748.                                         read or  write,  attempt  to access
  749.                                         files outside boundaries
  750.                          MBC_ERR        Message   base   corrupt  -  header
  751.                                         specifies non-existent records
  752.  
  753.           Remarks        These values also apply  to  the  completion codes
  754.                          returned by  the functions  which do  not return a
  755.                          record or message number.  It  is  set  when *any*
  756.                          function encounters an error. Checking it is up to
  757.                          you. However, errortype may  have  been  set  by a
  758.                          previous function after which you didn't check. In
  759.                          general, using completion codes to trap  errors is
  760.                          the most reliable way.
  761.  
  762.           See also       errorstring
  763.  
  764.           Example        See errorstring
  765.  
  766.  
  767.           ========================
  768.           errorstring
  769.           ========================
  770.  
  771.           Name           errorstring - tell the user what went wrong
  772.  
  773.           Usage          char errorstring []
  774.  
  775.           Description    The  errorstring  variable  is  set  whenever  the
  776.                          errortype variable is set.  It  contains  a string
  777.                          telling you  in readable text what went wrong. The
  778.                          string is not \n terminated.
  779.  
  780.           Remarks        See errortype
  781.  
  782.           See also       errortype
  783.  
  784.           Example        void errorexit (void) {    /* Exit with error */
  785.                            putchar (BELL);
  786.                            printf ("MB_lib error %d: %s\n", errortype,
  787.                            errorstring);
  788.                            exit (1);
  789.                          }
  790.  
  791.  
  792.           =======================
  793.           Various defines
  794.           =======================
  795.  
  796.           For your convenience, the following values  have been  defined in
  797.           MB_lib.h:
  798.  
  799.  
  800.  
  801.                                                13
  802.  
  803.  
  804.                     HCR       Hard carriage  return to  indicate the end of
  805.                               a paragraph in messages
  806.                     SCR       Soft carriage  return, may  be reformatted by
  807.                               message readers
  808.                     LF        Line feed
  809.                     KLUDGE    The  kludge  delimiter.  If this is the first
  810.                               character on a line, the rest of that line up
  811.                               to the first HCR will be used as a kludge.
  812.                     BELL      The bell character
  813.                     KLUDGES   Indicates  that   the  txt_dump  ()  function
  814.                               should dump kludges
  815.                     NOKLUDGES Indicates  that  the  txt_dump   ()  function
  816.                               should not  dump kludges. See txt_dump () for
  817.                               details.
  818.  
  819.  
  820.           =======================
  821.           Message attributes
  822.           =======================
  823.  
  824.  
  825.           #define MA_DELETED      0x01    /* Message attributes               */
  826.           #define MA_UNSENT       0X02
  827.           #define MA_NETMAIL      0X04
  828.           #define MA_PRIVATE      0X08
  829.           #define MA_RECEIVED     0X10
  830.           #define MA_UNMOVED      0X20
  831.           #define MA_LOCAL        0X40
  832.  
  833.           #define NA_KILL         0X01    /* Hudson netmail attributes        */
  834.           #define NA_SENT         0X02
  835.           #define NA_FILE         0X04
  836.           #define NA_CRASH        0X08
  837.           #define NA_RECEIPT      0X10
  838.           #define NA_AUDIT        0X20
  839.           #define NA_RETURN       0X40
  840.  
  841.           #define NM_PRIVATE      0X0001  /* Opus (*.MSG) Netmail attributes  */
  842.           #define NM_CRASH        0x0002
  843.           #define NM_RECEIVED     0x0004
  844.           #define NM_SENT         0x0008
  845.           #define NM_FILE         0x0010
  846.           #define NM_TRANSIT      0x0020
  847.           #define NM_ORPHAN       0x0040
  848.           #define NM_KILL         0x0080
  849.           #define NM_LOCAL        0x0100
  850.           #define NM_HOLD         0x0200
  851.           #define NM_UNUSED       0x4000
  852.           #define NM_REQUEST      0x0800
  853.           #define NM_RECEIPT      0x1000
  854.           #define NM_ISRECEIPT    0x2000
  855.           #define NM_AUDIT        0x4000
  856.           #define NM_UPDATEREQ    0x8000
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  
  863.                                                14
  864.  
  865.  
  866.           =======================
  867.           Record structures
  868.           =======================
  869.  
  870.           The following structures make up the message base file records. BEWARE!
  871.           Since the strings in the Hudson message base are Pascal-format strings,
  872.           you should NEVER read  or  write  message  base  records  yourself, but
  873.           instead  use  the  functions  provided  in  MB_lib,  so that the proper
  874.           conversion can be performed.
  875.           These structures all use C-style  strings  -  you  needn't  worry about
  876.           formats here.  Just remember  to use  the MB_lib  functions for message
  877.           base I/O. That's what they're for, anyway, so why would you want  to do
  878.           otherwise?
  879.  
  880.           typedef struct {               /* MSGINFO.BBS structure definition */
  881.             unsigned int low_msg;        /* Lowest msg # in message base     */
  882.             unsigned int high_msg;       /* Highest msg # in message base    */
  883.             unsigned int total_msgs;     /* Total # of messages in base      */
  884.             unsigned int total_on_board [200];   /* Number of msgs / board   */
  885.           } MSGINFO_RECORD;
  886.  
  887.           typedef struct {               /* MSGIDX.BBS structure definition  */
  888.             int msg_num;                 /* Message #                        */
  889.             unsigned char board;         /* Board # where msg is stored      */
  890.           } MSGIDX_RECORD;
  891.  
  892.           typedef char MSGTOIDX_RECORD [36];  /* MSGTOIDX.BBS structure def. */
  893.  
  894.           typedef struct {               /* MSGHDR.BBS structure definition  */
  895.             int msgnum;                  /* Message number                   */
  896.             unsigned int prev_reply;     /* Msg # of previous reply, 0 if no */
  897.             unsigned int next_reply;     /* Msg # of next reply, 0 if none   */
  898.             unsigned int times_read;     /* # of times msg was read, UNUSED  */
  899.             unsigned int start_block;    /* Record # of msg in MSGTXT.BBS    */
  900.             unsigned int num_blocks;     /* # of records in MSGTXT.BBS       */
  901.             unsigned int dest_net;       /* Destination net                  */
  902.             unsigned int dest_node;      /* Destination node                 */
  903.             unsigned int orig_net;       /* Origin net                       */
  904.             unsigned int orig_node;      /* Origin node                      */
  905.             unsigned char dest_zone;     /* Destination zone                 */
  906.             unsigned char orig_zone;     /* Origin zone                      */
  907.             unsigned int cost;           /* Cost (Netmail)                   */
  908.             unsigned char msg_attr;      /* Msg attributes. Bits as follows: */
  909.                                          /* 0 : Deleted                      */
  910.                                          /* 1 : Unsent                       */
  911.                                          /* 2 : Netmail                      */
  912.                                          /* 3 : Private                      */
  913.                                          /* 4 : Received                     */
  914.                                          /* 5 : Unmoved outgoing echo        */
  915.                                          /* 6 : Local                        */
  916.                                          /* 7 : RESERVED                     */
  917.             unsigned char net_attr;      /* Netmail attributes. Bits follow: */
  918.                                          /* 0 : Kill/Sent                    */
  919.                                          /* 1 : Sent                         */
  920.                                          /* 2 : File attach                  */
  921.                                          /* 3 : Crash                        */
  922.                                          /* 4 : Receipt request              */
  923.                                          /* 5 : Audit request                */
  924.  
  925.                                                15
  926.  
  927.  
  928.                                          /* 6 : Is a return receipt          */
  929.                                          /* 7 : RESERVED                     */
  930.             unsigned char board;         /* Message board #                  */
  931.             char post_time [6];          /* Time message was posted          */
  932.             char post_date [9];          /* Date message was posted          */
  933.             char who_to [36];            /* Recipient to whom msg is sent    */
  934.             char who_from [36];          /* Sender who posted message        */
  935.             char subject [73];           /* Subject line of message          */
  936.           } MSGHDR_RECORD;
  937.  
  938.           typedef struct {               /* MSGTXT.BBS structure definition  */
  939.             unsigned char str_len;       /* This string is stored in memory  */
  940.             char str_txt [255];          /*  in Pascal format to reduce      */
  941.           } MSGTXT_RECORD;               /*  overhead, so take care!         */
  942.  
  943.  
  944.           /* The strings in the *.MSG file header (Opus style) aren't Pascal */
  945.           /* type strings but have the 'normal' ASCIIZ  format.              */
  946.  
  947.           typedef struct {               /* OPUS-style (*.MSG) msg format    */
  948.             char who_from [36];          /* Sender who posted message        */
  949.             char who_to [36];            /* Recipient  to whom msg is sent   */
  950.             char subject [72];           /* Subject line of message          */
  951.             char datetime [20];          /* Date/time msg was last edited    */
  952.             unsigned int times_read;     /* # of times message was read      */
  953.             unsigned int dest_node;      /* Destination node                 */
  954.             unsigned int orig_node;      /* Origin node                      */
  955.             unsigned int cost;           /* Cost to send netmail msg         */
  956.             unsigned int orig_net;       /* Origin net                       */
  957.             unsigned int dest_net;       /* Destination net                  */
  958.             unsigned int dest_zone;      /* Destination zone  (These fields) */
  959.             unsigned int orig_zone;      /* Origin zone       (were padded ) */
  960.             unsigned int dest_point;     /* Destination point (with 8 0's  ) */
  961.             unsigned int orig_point;     /* Origin point      (in FSC-0001 ) */
  962.             unsigned int reply_to;       /* Msg # to which this one replies  */
  963.             unsigned int attribute;      /* Msg attributes. Bits as follows: */
  964.                                          /* 0  : Private                     */
  965.                                          /* 1  : Crash                       */
  966.                                          /* 2  : Received                    */
  967.                                          /* 3  : Sent                        */
  968.                                          /* 4  : File attached               */
  969.                                          /* 5  : In transit                  */
  970.                                          /* 6  : Orphan                      */
  971.                                          /* 7  : Kill when sent              */
  972.                                          /* 8  : Local                       */
  973.                                          /* 9  : Hold for pickup             */
  974.                                          /* 10 : UNUSED                      */
  975.                                          /* 11 : File request                */
  976.                                          /* 12 : Return receipt request      */
  977.                                          /* 13 : Is a return receipt         */
  978.                                          /* 14 : Audit request               */
  979.                                          /* 15 : File update request         */
  980.             unsigned int next_reply;     /* Next msg in reply chain          */
  981.           } NET_RECORD;
  982.  
  983.  
  984.  
  985.  
  986.  
  987.                                                16
  988.  
  989.  
  990.           ============================================================
  991.           4. TEXT SERVICES
  992.           ============================================================
  993.  
  994.           =======================
  995.           txt_new ()
  996.           =======================
  997.  
  998.           Name           txt_new - create a new message text body
  999.  
  1000.           Usage          M_TEXT txt_new (char * string);
  1001.  
  1002.           Description    The txt_new () function creates a new message text
  1003.                          body. This is typically the first function to call
  1004.                          when starting with a new message text. It requires
  1005.                          that you have defined  a  text  handle previously.
  1006.                          This  function  also  initializes the text handle.
  1007.                          The string argument may  either be  the first line
  1008.                          of the  new message text body, or may be a pointer
  1009.                          to a complete null-terminated block of text.
  1010.  
  1011.           Return value   Text handle, NULL if error. In case of  error, the
  1012.                          errortype  and  errorstring  variables  are set to
  1013.                          indicate the type of error.
  1014.  
  1015.           Remarks        The \n character is  not  translated  and  will be
  1016.                          placed  in  the  message  text body as a line feed
  1017.                          (LF).  It  will  be  ignored  by  message readers,
  1018.                          according  to  specifications  in FTS-0001. The \r
  1019.                          character generates a Hard Carriage Return (HCR).
  1020.  
  1021.           See also       txt_add (), txt_dispose ()
  1022.  
  1023.           Example        See txt_add ()
  1024.  
  1025.  
  1026.           =======================
  1027.           txt_add ()
  1028.           =======================
  1029.  
  1030.           Name           txt_add - add new text to an existing message text
  1031.                          body.
  1032.  
  1033.           Usage          int txt_add (M_TEXT texthandle, char * string);
  1034.  
  1035.           Description    The txt_add  () function  adds text to an existing
  1036.                          message text body.  When  starting  a  new message
  1037.                          text body, you MUST call txt_new () first in order
  1038.                          to initialize your text handle.
  1039.  
  1040.           Return value   Zero to indicate success, non-zero to  indicate an
  1041.                          error. See  the 'variables' section for completion
  1042.                          codes.
  1043.  
  1044.           Remarks        See txt_new ()
  1045.  
  1046.           See also       txt_new ()
  1047.  
  1048.  
  1049.                                                17
  1050.  
  1051.  
  1052.           Example        #include "mblib.h"
  1053.  
  1054.                          M_TEXT msgtext;
  1055.  
  1056.                          msgtext = txt_new ("This is line one. \n");
  1057.                          if (msgtext == NULL) {     /* ERROR! */
  1058.                            printf ("%s\n", errorstring);
  1059.                            exit (1);
  1060.                          }
  1061.                          if (txt_add (msgtext, "This is line two!\r"))
  1062.                            printf ("%s\n", errorstring);
  1063.  
  1064.  
  1065.           ========================
  1066.           txt_dispose
  1067.           ========================
  1068.  
  1069.           Name           txt_dispose - dispose of a message text body
  1070.  
  1071.           Usage          void txt_dispose (M_TEXT texthandle);
  1072.  
  1073.           Description    The txt_dispose () function is used  to dispose of
  1074.                          a block  of text. It releases the memory allocated
  1075.                          for the text body. Call this function after you've
  1076.                          finished with  a text  body (after processing it),
  1077.                          to free memory and the text handle for future use.
  1078.  
  1079.           Return value   None.
  1080.  
  1081.           See also       txt_new ()
  1082.  
  1083.  
  1084.           ========================
  1085.           txt_dump
  1086.           ========================
  1087.  
  1088.           Name           txt_dump - dump a message text to an output device
  1089.  
  1090.           Usage          int txt_dump (M_TEXT texthandle,
  1091.                          int (* output) (char *), unsigned char margin,
  1092.                          unsigned char kludges);
  1093.  
  1094.           Description    The txt_dump () function  is used  for all dumping
  1095.                          and printing  of message text. It is very flexible
  1096.                          and can be  used  to  print  message  text  to the
  1097.                          screen,  to  send  it  to  *any*  device, file, or
  1098.                          whatever, or to manipulate individual text lines.
  1099.                          It does so by  dividing text  into separate lines,
  1100.                          and  then  calling  a  programmer  supplied output
  1101.                          routine to process that  line. Because  you supply
  1102.                          the  output  routine  yourself,  you have complete
  1103.                          control over what happens to the text.
  1104.                          Text is wrapped to  a  specified  line  width (the
  1105.                          margin   parameter),   while  kludges  are  either
  1106.                          printed  or  not  printed,  as  specified  by  the
  1107.                          kludges parameter.
  1108.                          Because the  syntax is a bit complicated, here's a
  1109.                          list summarizing the accepted parameters:
  1110.  
  1111.                                                18
  1112.  
  1113.  
  1114.                            M_TEXT texthandle - this is the  text handle for
  1115.                          the text body you want to dump.
  1116.                            int (* output) (char *) - this looks complex but
  1117.                          it isn't. This parameter  is the  NAME (!)  of the
  1118.                          programmer  supplied  function  to  process a text
  1119.                          line. This function  should  accept  a  pointer to
  1120.                          char,  and  return  an  integer. This return value
  1121.                          should be zero to  indicate success  or nonzero to
  1122.                          indicate an error. See example below.
  1123.                            unsigned  char  margin  -  this is the number of
  1124.                          characters you want the text to be wrapped to
  1125.                            unsigned char kludges -  this  is  a  flag which
  1126.                          indicates whether  to print kludges or not. It can
  1127.                          have  the  value  KLUDGES  to  print  kludges,  or
  1128.                          NOKLUDGES to print no kludges.
  1129.  
  1130.           Return value   0 if success, -1 if the output routine encountered
  1131.                          an error (or at least returned a non-zero value).
  1132.  
  1133.           Remarks        WARNING: Because the actual output is  not handled
  1134.                          by  MB_lib,  an  error  encountered  by the output
  1135.                          routine will not set the errortype and errorstring
  1136.                          variables!   Error   handling  within  the  output
  1137.                          routine must be handled by the programmer.
  1138.                          The line passed to the output routine is not \n or
  1139.                          \r terminated.
  1140.  
  1141.           Example        #include "mblib.h"
  1142.                          #include <stdio.h>
  1143.  
  1144.                          int printline (char *);  /* Always prototype */
  1145.                          int saveline (char *);   /* these functions! */
  1146.  
  1147.                          M_TEXT msgtext;
  1148.                          FILE * savefile;
  1149.  
  1150.                          void main (void) {
  1151.                            msgtext = txt_new ("This is line one. \n");
  1152.                            if (msgtext == NULL) {     /* ERROR! */
  1153.                              printf ("%s\n", errorstring);
  1154.                              exit (1);
  1155.                            }
  1156.                            if (txt_add (msgtext, "This is line two!\r")) {
  1157.                              printf ("%s\n", errorstring);
  1158.                              exit (1);
  1159.                            }
  1160.                            txt_dump (msgtext, printline, 70, NOKLUDGES);
  1161.                              /* Print text to screen, margin 70 */
  1162.                            if ((savefile = fopen ("TEST", "w")) == NULL)
  1163.                              exit (1);
  1164.                            txt_dump (msgtext, saveline, 80, KLUDGES);
  1165.                              /* Save text to file, margin 80 + kludges */
  1166.                            txt_dispose (msgtext);
  1167.                            puts ("Done.");
  1168.                            fclose (savefile);
  1169.                          } /* main */
  1170.  
  1171.                          /* The following functions each output text */
  1172.  
  1173.                                                19
  1174.  
  1175.  
  1176.                          /* one line at a time                       */
  1177.  
  1178.                          int printline (char * line) {
  1179.                            puts (line);
  1180.                            return (0);    /* This always works */
  1181.                          } /* printline */
  1182.  
  1183.                          int saveline (char * line) {
  1184.                            if (!fprintf (savefile, "%s\n", line)) {
  1185.                              puts ("Error saving text!");
  1186.                              return (-1);    /* Error writing file */
  1187.                            }
  1188.                            else
  1189.                              return (0);
  1190.                          } /* saveline */
  1191.  
  1192.  
  1193.  
  1194.  
  1195.  
  1196.  
  1197.  
  1198.  
  1199.  
  1200.  
  1201.  
  1202.  
  1203.  
  1204.  
  1205.  
  1206.  
  1207.  
  1208.  
  1209.  
  1210.  
  1211.  
  1212.  
  1213.  
  1214.  
  1215.  
  1216.  
  1217.  
  1218.  
  1219.  
  1220.  
  1221.  
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.  
  1228.  
  1229.  
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.                                                20
  1236.  
  1237.  
  1238.           ============================================================
  1239.           5: MESSAGE BASE ACCESS SERVICES
  1240.           ============================================================
  1241.  
  1242.           ========================
  1243.           msg_open
  1244.           ========================
  1245.  
  1246.           Name           msg_open - open the message base
  1247.  
  1248.           Usage          int msg_open (char * msgbasepath);
  1249.  
  1250.           Description    Before you  can access  the message base, you MUST
  1251.                          call this  function to  open the  message base and
  1252.                          initialize the  message base I/O system. If you do
  1253.                          not, any attempts to access the  message base will
  1254.                          result in a MNO_ERR return value.
  1255.                          MB_lib tries  to locate  the message base files in
  1256.                          the path you supply.  If  the  files  don't exist,
  1257.                          msg_open () will create them.
  1258.  
  1259.           Return value   0 if  success, non-zero  if error. See the 'varia-
  1260.                          bles' section for completion codes.
  1261.  
  1262.           Remarks        Attempts to  open  the  message  base  when  it is
  1263.                          already open can't do any harm. MB_lib keeps track
  1264.                          of these things, just in case you do not. :-)
  1265.                          The message  base  path  may  be  terminated  by a
  1266.                          backslash, or not.
  1267.  
  1268.           See also       msg_close ()
  1269.  
  1270.           Example        if (msg_open ("C:\\MSGBASE"))
  1271.                            exit (1);   /* Error opening message base */
  1272.                          /* Your message handling goes here */
  1273.                          msg_close (); 
  1274.  
  1275.  
  1276.           ========================
  1277.           msg_close
  1278.           ========================
  1279.  
  1280.           Name           msg_close - close the message base
  1281.  
  1282.           Usage          void msg_close (void);
  1283.  
  1284.           Description    msg_close  closes  the  message  base  files after
  1285.                          you're done with them.  Closing  the  message base
  1286.                          when  it  isn't  open  can't  do any harm - MB_lib
  1287.                          checks first.
  1288.  
  1289.           Remarks        You don't rally need  to call  msg_close () before
  1290.                          exiting  your  program.  When  you have opened the
  1291.                          message  base,  MB_lib  checks  to  see  if you've
  1292.                          closed them again before exiting. So if you forget
  1293.                          to call  msg_close (),  there's no  harm done. But
  1294.                          from a  puristic point  of view, it's bad habit to
  1295.  
  1296.  
  1297.                                                21
  1298.  
  1299.  
  1300.                          rely on such mechanisms, it's neater  to close the
  1301.                          message base yourself.
  1302.  
  1303.           See also       msg_open ()
  1304.  
  1305.           Example        See msg_open ()
  1306.  
  1307.  
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.  
  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.  
  1354.  
  1355.  
  1356.  
  1357.  
  1358.  
  1359.                                                22
  1360.  
  1361.  
  1362.           ============================================================
  1363.           6: MESSAGE BASE LOCKING SERVICES
  1364.           ============================================================
  1365.  
  1366.           ========================
  1367.           msg_lock
  1368.           ========================
  1369.  
  1370.           Name           msg_lock - lock the message base to prevent writes
  1371.                          by other processes
  1372.  
  1373.           Usage          int msglock (char * semapath);
  1374.  
  1375.           Description    In a  multi-tasking  environment  (like multi-line
  1376.                          BBS'es) we  must take  precautions to prevent file
  1377.                          corruption.  The  details  on  this  are described
  1378.                          above (see Introduction to file locking).
  1379.                          The  semapath  string  must  specify the directory
  1380.                          that  is  used  by  Remote  Access  to  keep  it's
  1381.                          semaphore files in.
  1382.  
  1383.           Return value   -1 if  the there was a problem locking the message
  1384.                          base, otherwise 0.
  1385.  
  1386.           Remarks        If SHARE is not loaded before  locking the message
  1387.                          base, this  won't cause  an error.  I guess that's
  1388.                          the whole point for the rather exotic (and,  to my
  1389.                          taste, a little inelegant) RA locking method.
  1390.                          Since msg_lock  () allows for a 15 second timeout,
  1391.                          locking your message base could take this long.
  1392.  
  1393.           See also       msg_unlock ()
  1394.  
  1395.           Example        #include "mb_lib.h"
  1396.  
  1397.                          if (msg_lock == -1)
  1398.                            puts ("Error locking message base");
  1399.                          /* Or you could put a few retries here... */
  1400.                          else {
  1401.                            msg_write_new (& msgheader, msgtext);
  1402.                          /* msgheader and msgtext previously inited */
  1403.                          msg_unlock ();
  1404.  
  1405.  
  1406.           ========================
  1407.           msg_unlock
  1408.           ========================
  1409.  
  1410.           Name           msg_unlock  -   unlock  the   message  base  after
  1411.                          modifying it
  1412.  
  1413.           Usage          void msg_unlock (void);
  1414.  
  1415.           Description    Use  msg_unlock  ()  to  release file locks on the
  1416.                          message base, thereby enabling  other processes to
  1417.                          perform their write operations again.
  1418.  
  1419.           Remarks        See msg_lock ()
  1420.  
  1421.                                                23
  1422.  
  1423.  
  1424.  
  1425.           See also       msg_lock ()
  1426.  
  1427.           Example        See msg_lock ()
  1428.  
  1429.  
  1430.  
  1431.  
  1432.  
  1433.  
  1434.  
  1435.  
  1436.  
  1437.  
  1438.  
  1439.  
  1440.  
  1441.  
  1442.  
  1443.  
  1444.  
  1445.  
  1446.  
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455.  
  1456.  
  1457.  
  1458.  
  1459.  
  1460.  
  1461.  
  1462.  
  1463.  
  1464.  
  1465.  
  1466.  
  1467.  
  1468.  
  1469.  
  1470.  
  1471.  
  1472.  
  1473.  
  1474.  
  1475.  
  1476.  
  1477.  
  1478.  
  1479.  
  1480.  
  1481.  
  1482.  
  1483.                                                24
  1484.  
  1485.  
  1486.           ============================================================
  1487.           7: MESSAGE MANIPULATION SERVICES
  1488.           ============================================================
  1489.  
  1490.           ========================
  1491.           msg_msgnr2recnr
  1492.           ========================
  1493.  
  1494.           Name           msg_msgnr2recnr - convert message number to record
  1495.                          number.
  1496.  
  1497.           Usage          long msg_msgnr2recnr (unsigned int msgnr);
  1498.  
  1499.           Description    Message numbers are not related to  record numbers
  1500.                          on  a  1:1  basis.  Since  messages  may have been
  1501.                          deleted from the message  base,  the  message base
  1502.                          records 0,  1, and  2 could,  for example, contain
  1503.                          the messages  100,  294  and  1583.  This function
  1504.                          converts  a  record  number  to  the corresponding
  1505.                          message number.
  1506.  
  1507.           Return value   The record number of  the message  we're searching
  1508.                          for, -1  if the  message was not found or an error
  1509.                          occurred. In the  latter  case  the  errortype and
  1510.                          errorstring variables are set.
  1511.  
  1512.           Remarks        If the message base contains message numbers which
  1513.                          have been set to  -1  (some  programs  do  this to
  1514.                          indicate   that   a   message  has  been  killed),
  1515.                          msg_msgnr2recnr () switches to  a different search
  1516.                          algorithm,  resulting  in  a    slight decrease in
  1517.                          performance.
  1518.  
  1519.           See also       msg_recnr2msgnr ();
  1520.  
  1521.           Example        #include "mb_lib.h"
  1522.  
  1523.                          long recnr;
  1524.                          int msgnr;
  1525.  
  1526.                          printf ("Enter message number: ");
  1527.                          scanf ("%d", & msgnr);
  1528.                          if ((recnr = msg_msgnr2recnr (msgnr)) == -1)
  1529.                            puts ("Message not found.");
  1530.                          else
  1531.                            printf ("Record nr. %l\n", recnr);
  1532.  
  1533.  
  1534.           ========================
  1535.           msg_recnr2msgnr
  1536.           ========================
  1537.  
  1538.           Name           msg_recnr2msgnr - convert record number to message
  1539.                          number.
  1540.  
  1541.           Usage          unsigned int msg_recnr2msgnr (long recnr);
  1542.  
  1543.  
  1544.  
  1545.                                                25
  1546.  
  1547.  
  1548.           Description    This  function  does  exactly  the opposite of the
  1549.                          msg_msgnr2recnr  ()  function:  it  retrieves  the
  1550.                          message  number  that  corresponds  with a certain
  1551.                          record number.
  1552.  
  1553.           Return value   The message number  of  the  message corresponding
  1554.                          with  the   specified  record,   -1  if  an  error
  1555.                          occurred. In this  case  the  errortype  an error-
  1556.                          string variables are set.
  1557.  
  1558.           See also       msg_msgnr2recnr ()
  1559.  
  1560.           Example        #include "mb_lib.h"
  1561.  
  1562.                          long recnr;
  1563.  
  1564.                          puts ("Message nr: 10");
  1565.                          if ((recnr = msg_recnr2msgnr (recnr)) == -1)
  1566.                            puts ("Error accessing message base");
  1567.                          else
  1568.                            printf ("Record nr: %l\n", recnr);
  1569.  
  1570.  
  1571.           ========================
  1572.           msg_hdr_clear
  1573.           ========================
  1574.  
  1575.           Name           msg_hdr_clear  -  clear  a  message header record,
  1576.                          e.g. set all fields in the header to zero.
  1577.  
  1578.           Usage          void msg_hdr_clear (MSGHDR_RECORD * hdr);
  1579.  
  1580.           Description    A message header record contains many fields, many
  1581.                          of which  should be  set to  0 when creating a new
  1582.                          message. Because the  fields  in  an uninitialized
  1583.                          header contain unknown values, we should initiali-
  1584.                          zed each field  before  using  this  header. Since
  1585.                          this  is  very  cumbersome, this function does the
  1586.                          job for you.
  1587.  
  1588.           Remarks        This  function   should  always   be  called  when
  1589.                          creating a new message header, otherwise unpredic-
  1590.                          table effects will occur.
  1591.  
  1592.           Example        #include "mb_lib.h"
  1593.  
  1594.                          MSGHDR_RECORD hdr;
  1595.  
  1596.                          msg_hdr_clear (& hdr);
  1597.                          strcpy (hdr.who_from, "Frank Van.wensveen");
  1598.                          strcpy (hdr.who_to, "All");
  1599.                          strcpy (hdr.subject, "Test");  /* That's all! */
  1600.  
  1601.           ========================
  1602.           msg_fixup4d
  1603.           ========================
  1604.  
  1605.  
  1606.  
  1607.                                                26
  1608.  
  1609.  
  1610.           Name           msg_fixup4d - convert the zone fields in a netmail
  1611.                          header to  an INTL kludge to overcome the FSC-0001
  1612.                          compliance problem.
  1613.  
  1614.           Usage          int msg_fixup4d (MSGHDR_RECORD * hdr, M_TEXT txt);
  1615.  
  1616.           Description    FSC-0001 describes the  format  of  a  basic *.MSG
  1617.                          netmail message  header. Since this document dates
  1618.                          from the time that  only 2D  addressing (net/node)
  1619.                          was used,  the definition had not defined any zone
  1620.                          and point address fields, but instead contains a 8
  1621.                          byte 'padding area'.
  1622.                          The header  used in this message base library is a
  1623.                          variant  that  is  widely  used  by  a  number  of
  1624.                          popular  software  packages,  but not supported by
  1625.                          all programs. This leads to problems. For example,
  1626.                          a  message  entered  in Remote Access addressed to
  1627.                          zone 3, will be  sent to  the zone  defined as the
  1628.                          mailers primary address instead.
  1629.                          To overcome  this incompatibility,  the INTL, FMPT
  1630.                          and TOPT kludges have been defined.  These kludges
  1631.                          are added  to the message text, usually at the top
  1632.                          of the message, although  at the  bottom they work
  1633.                          just as well. They have the following functions:
  1634.                               INTL 27:1331/703 2:285/504
  1635.                          indicates a message to 27:1331/703 from 2:285/504,
  1636.                               FMPT 2
  1637.                          indicates a message from point 2, and
  1638.                               TOPT 6
  1639.                          indicates a message to point 6.
  1640.                          So,   a   message   from,  say,  27:1331/703.5  to
  1641.                          2:285/504.2 will contain the following kludges:
  1642.                               INTL 2:285/504 27:1331/703
  1643.                               FMPT 5
  1644.                               TOPT 2
  1645.                          while the header has  to contain  only 1331/703 as
  1646.                          the origin address, and 285/504 as the destination
  1647.                          address. It  may contain  more, but  if the mailer
  1648.                          (or  any   other  software  used  to  process  the
  1649.                          message) doesn't support use of those  fields, the
  1650.                          extra header information is ignored. Software that
  1651.                          doesn't support these kludges simply ignores them,
  1652.                          as with all other kludges.
  1653.                          The  msg_fixup4d  function  allows  you  to easily
  1654.                          write messages  that  are  processed  correctly by
  1655.                          FSC-0001  compliant   software.  It  converts  the
  1656.                          undocumented zone  fields  in  the  Hudson netmail
  1657.                          header  into  a  INTL  kludge,  while  the related
  1658.                          net_fixup4d () function converts  the undocumented
  1659.                          zone  and  point  fields  in the *.MSG header into
  1660.                          INTL, FMPT and TOPT  kludges. If  these fields are
  1661.                          zero, however, the kludges are omitted.
  1662.  
  1663.           Return value   Zero on success, nonzero on error.
  1664.  
  1665.           Remarks        CAUTION:  The  fixup  functions  add  text  to the
  1666.                          specified  text  handle.  The  text  handle *MUST*
  1667.                          therefore be initialized, otherwise "unpredictable
  1668.  
  1669.                                                27
  1670.  
  1671.  
  1672.                          results"  (an  euphemism  for   a  total  screwup,
  1673.                          usually)  will   occur.  You  *must*  have  called
  1674.                          txt_new () previous to  calling msg_fixup4d  () or
  1675.                          net_fixup4d ().
  1676.  
  1677.           See also       net_fixup4d ()
  1678.  
  1679.           Example        #include "mb_lib.h"
  1680.  
  1681.                          MSGHDR_RECORD hdr;
  1682.                          M_TEXT msgtxt;
  1683.  
  1684.                          msg_hdr_clear (& hdr);
  1685.                          strcpy (hdr.who_from, "Frank Van.wensveen");
  1686.                          strcpy (hdr.who_to, "Sysop");
  1687.                          strcpy (hdr.subject, "Kludges");
  1688.                          hdr.dest_zone = 27;
  1689.                          hdr.orig_zone = 2;
  1690.                          hdr.dest_net = 1331;
  1691.                          hdr.orig_net = 285;
  1692.                          hdr.dest_node = 703;
  1693.                          hdr.orig_node = 504;
  1694.  
  1695.                          /* Now we have two possibilities. The first: */
  1696.                          msgtxt = txt_new ("");  /* THIS IS VITAL!! */
  1697.                          msg_fixup4d (& hdr, msgtxt);  /* Add kludges */
  1698.                          txt_add ("This message now contains kludges.\r");
  1699.  
  1700.                          /* The second: */
  1701.                          msgtxt = txt_new ("This message is kludgy!\r");
  1702.                          msg_fixup4d (& hdr, msgtxt); /* Add kludges */
  1703.                          /* Note the \r after the last message text! */
  1704.                          /* Without it, the kludge will be ignored!  */
  1705.  
  1706.                          msg_write_new (& hdr, msgtxt);   /* Save it */
  1707.  
  1708.  
  1709.  
  1710.  
  1711.  
  1712.  
  1713.  
  1714.  
  1715.  
  1716.  
  1717.  
  1718.  
  1719.  
  1720.  
  1721.  
  1722.  
  1723.  
  1724.  
  1725.  
  1726.  
  1727.  
  1728.  
  1729.  
  1730.  
  1731.                                                28
  1732.  
  1733.  
  1734.           ============================================================
  1735.           8: MESSAGE READING SERVICES
  1736.           ============================================================
  1737.  
  1738.           ========================
  1739.           msg_read_info
  1740.           ========================
  1741.  
  1742.           Name           msg_read_info -  read MSGINFO.BBS  into the global
  1743.                          msginfo record
  1744.  
  1745.           Usage          void msg_read_info (void);
  1746.  
  1747.           Description    MSGINFO.BBS does not contain multiple records, but
  1748.                          instead has  a fixed length, and contains only one
  1749.                          structure that can have only one value at  a time.
  1750.                          Therefore it  makes sense  not to read MSGINFO.BBS
  1751.                          over and over again to locally defined structures,
  1752.                          but  instead  use  a  global structure that can be
  1753.                          used  for  multiple  purposes.  This  structure is
  1754.                          msginfo. See the variables section for details.
  1755.  
  1756.           Return value   Zero  on   success,  a  nonzero  value  on  error,
  1757.                          indicating  the  nature  of  the  error.  See  the
  1758.                          section on error handling for result codes.
  1759.  
  1760.           See also       msg_write_info ();
  1761.  
  1762.           Example        #include "mb_lib.h"
  1763.  
  1764.                          /* Message base is supposed to be open */
  1765.                          if (msg_read_info ())
  1766.                            exit (1);   /* Read error */
  1767.                          printf ("Number of messages in base: ");
  1768.                          printf ("%u\n", msginfo.total_msgs);
  1769.  
  1770.  
  1771.           ========================
  1772.           msg_read_hdr
  1773.           ========================
  1774.  
  1775.           Name           msg_read_hdr  -  read  a  message  header  from  a
  1776.                          specified record in MSGHDR.BBS.
  1777.  
  1778.           Usage          int msg_read_hdr (long recnr, 
  1779.                                            MSGHDR_RECORD * hdr);
  1780.  
  1781.           Description    This function  is used  to read  a message header.
  1782.                          Prior to  reading the header, the record number of
  1783.                          the message must  be  known.  This  number  can be
  1784.                          obtained from one of the search functions.
  1785.  
  1786.           Return value   Zero  on   success,  a  nonzero  value  on  error,
  1787.                          indicating  the  nature  of  the  error.  See  the
  1788.                          section on error handling for result codes.
  1789.  
  1790.           See also       msg_write_hdr ()
  1791.  
  1792.  
  1793.                                                29
  1794.  
  1795.  
  1796.           Example        #include "mblib.h"
  1797.                          MSGHDR_RECORD myheader;
  1798.  
  1799.                          /* Reading the header in record 100: */
  1800.                          if (msg_read_hdr (100, & myheader))
  1801.                            exit (1);    /* Read error */
  1802.                          printf ("Subject: %s\n", myhdr.subject);
  1803.  
  1804.  
  1805.           ========================
  1806.           msg_read_idx
  1807.           ========================
  1808.  
  1809.           Name           msg_read_idx  -  read  a  message  header  from  a
  1810.                          specified record in MSGIDX.BBS.
  1811.  
  1812.           Usage          int msg_read_idx (long recnr, 
  1813.                                            MSGIDX_RECORD * idx);
  1814.  
  1815.           Description    This function is  used  to  read  a  message index
  1816.                          record. This  record specifies  the message number
  1817.                          and the board number of  a  message  in  a certain
  1818.                          record.  Prior  to  reading the record, the record
  1819.                          number of the message  must be  known. This number
  1820.                          can be obtained from one of the search functions.
  1821.  
  1822.           Return value   Zero  on   success,  a  nonzero  value  on  error,
  1823.                          indicating  the  nature  of  the  error.  See  the
  1824.                          section on error handling for result codes.
  1825.  
  1826.  
  1827.           See also       msg_write_idx ()
  1828.  
  1829.           Example        #include "mblib.h"
  1830.                          MSGIDX_RECORD myidx;
  1831.  
  1832.                          /* Reading the index in record 100: */
  1833.                          if (msg_read_idx (100, & myidx))
  1834.                            exit (1);    /* Read error */
  1835.                          printf ("Msg nr: %d, board nr: %d",
  1836.                                  myidx.msg_num, myidx.board);
  1837.  
  1838.  
  1839.           ========================
  1840.           msg_read_toidx
  1841.           ========================
  1842.  
  1843.           Name           msg_read_toidx  -  read  a record from a specified
  1844.                          record in MSGTOIDX.BBS. 
  1845.  
  1846.           Usage          int msg_read_toidx (long recnr, 
  1847.                                              MSGTOIDX_RECORD * idx);
  1848.  
  1849.           Description    This  function  is  used  to  read  a MSGTOIDX.BBS
  1850.                          record.  Prior  to  reading the header, the record
  1851.                          number of the message  must be  known. This number
  1852.                          can be obtained from one of the search functions.
  1853.  
  1854.  
  1855.                                                30
  1856.  
  1857.  
  1858.                          The  obtained  record  specifies the user name the
  1859.                          message is sent to.  After  the  message  has been
  1860.                          received, this record should be overwritten by the
  1861.                          message reader. As a result, the MSGTOIDX file can
  1862.                          be searched for unreceived mail to a certain user.
  1863.  
  1864.           Return value   Zero  on   success,  a  nonzero  value  on  error,
  1865.                          indicating  the  nature  of  the  error.  See  the
  1866.                          section on error handling for result codes.
  1867.  
  1868.           See also       msg_write_toidx ()
  1869.  
  1870.           Example        #include "mblib.h"
  1871.                          MSGTOIDX_RECORD addressee;
  1872.  
  1873.                          /* Reading addressee from record 100: */
  1874.                          if (msg_read_toidx (100, & addressee))
  1875.                            exit (1);    /* Read error */
  1876.                          printf ("To: %s\n", addressee);
  1877.  
  1878.  
  1879.           ========================
  1880.           msg_read_text
  1881.           ========================
  1882.  
  1883.           Name           msg_read_text -  read the  text of  a message, the
  1884.                          header of which is known.
  1885.  
  1886.           Usage          M_TEXT msg_read_text (MSGHDR_RECORD * hdr);
  1887.  
  1888.           Description    This function  is  used  to  read  the  text  of a
  1889.                          certain message. Because text is not just a single
  1890.                          record, more information than just a record number
  1891.                          is needed.  Therefore, the  message header must be
  1892.                          read prior to calling this function, and a pointer
  1893.                          to the  corresponding message  header is passed to
  1894.                          this read function.
  1895.  
  1896.           Return value   The text handle to be used  for the  text, NULL if
  1897.                          an error  occurred. In this case the errortype and
  1898.                          errorstring variables are set.
  1899.  
  1900.           See also       msg_write_text (), txt_dump ()
  1901.  
  1902.           Example        #include "mb_lib.h"
  1903.                          MSGHDR_RECORD msghdr;    /* Header      */
  1904.                          M_TEXT msgtxt;           /* Text handle */
  1905.  
  1906.                          /* Reading message in record 100 */
  1907.                          if (msg_read_hdr (100, & msghdr))
  1908.                            exit (1);    /* Read error */
  1909.                          msgtxt = msg_read_text (& msghdr);
  1910.                          if (msgtxt == NULL)
  1911.                            exit (1);    /* Read error */
  1912.                          printf ("Message %d:\n", msghdr.msgnum);
  1913.                          printf ("By: %s\nTo:%s\nRe:%s\n\n",
  1914.                                   msghdr.who_from, msghdr.who_to,
  1915.                                   msghdr.subject);
  1916.  
  1917.                                                31
  1918.  
  1919.  
  1920.                          txt_dump (msgtxt, printline, 70, NOKLUDGES);
  1921.                          /* Printline function defined elsewhere */
  1922.  
  1923.  
  1924.  
  1925.  
  1926.  
  1927.  
  1928.  
  1929.  
  1930.  
  1931.  
  1932.  
  1933.  
  1934.  
  1935.  
  1936.  
  1937.  
  1938.  
  1939.  
  1940.  
  1941.  
  1942.  
  1943.  
  1944.  
  1945.  
  1946.  
  1947.  
  1948.  
  1949.  
  1950.  
  1951.  
  1952.  
  1953.  
  1954.  
  1955.  
  1956.  
  1957.  
  1958.  
  1959.  
  1960.  
  1961.  
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.  
  1978.  
  1979.                                                32
  1980.  
  1981.  
  1982.           ============================================================
  1983.           9: MESSAGE WRITING SERVICES
  1984.           ============================================================
  1985.  
  1986.           ========================
  1987.           msg_write_info
  1988.           ========================
  1989.  
  1990.           Name           msg_write_info -  write the  global msginfo record
  1991.                          to MSGINFO.BBS
  1992.  
  1993.           Usage          void msg_write_info (void);
  1994.  
  1995.           Description    This function  is much  like msg_read_info, except
  1996.                          that it writes the global MSGINFO.BBS record back,
  1997.                          for example after it has been modified.
  1998.  
  1999.           Return value   Zero  on   success,  a  nonzero  value  on  error,
  2000.                          indicating  the  nature  of  the  error.  See  the
  2001.                          section on error handling for result codes.
  2002.  
  2003.           See also       msg_read_info ();
  2004.  
  2005.           Example        #include "mb_lib.h"
  2006.  
  2007.                          /* Message base is supposed to be open */
  2008.                          if (msg_read_info ())
  2009.                            exit (1);   /* Read error */
  2010.                          /* The msginfo record is modified here */
  2011.                          if (msg_write_info ())
  2012.                            exit (1);   /* Write error */
  2013.  
  2014.  
  2015.           ========================
  2016.           msg_write_hdr
  2017.           ========================
  2018.  
  2019.           Name           msg_read_hdr  -   write  a  message  header  to  a
  2020.                          specified record in MSGHDR.BBS.
  2021.  
  2022.           Usage          int msg_write_hdr (long recnr, 
  2023.                                            MSGHDR_RECORD * hdr);
  2024.  
  2025.           Description    This function is used  to write  a message header.
  2026.                          Prior to  writing the header, the record number of
  2027.                          the message must  be  known.  This  number  can be
  2028.                          obtained  from  one  of  the search functions, or,
  2029.                          when  modifying  a  header,  it  is  usually known
  2030.                          before you need this function.
  2031.  
  2032.           Return value   Zero  on   success,  a  nonzero  value  on  error,
  2033.                          indicating  the  nature  of  the  error.  See  the
  2034.                          section on error handling for result codes.
  2035.  
  2036.           See also       msg_read_hdr ()
  2037.  
  2038.           Example        #include "mblib.h"
  2039.                          MSGHDR_RECORD myheader;
  2040.  
  2041.                                                33
  2042.  
  2043.  
  2044.  
  2045.                          /* Modify the header in record 100: */
  2046.                          if (msg_read_hdr (100, & myheader))
  2047.                            exit (1);    /* Read error */
  2048.                          myheader.times_read ++;  /* Read once more */
  2049.                          if (msg_write_hdr (100, & myheader))
  2050.                            exit (1);    /* Write error */
  2051.  
  2052.  
  2053.           ========================
  2054.           msg_write_idx
  2055.           ========================
  2056.  
  2057.           Name           msg_write_idx  -  write  a  message  header  to  a
  2058.                          specified record in MSGIDX.BBS.
  2059.  
  2060.           Usage          int msg_write_idx (long recnr, 
  2061.                                            MSGIDX_RECORD * idx);
  2062.  
  2063.           Description    This function is much like msg_read_idx (), except
  2064.                          that it writes a record to MSGIDX.BBS.
  2065.  
  2066.           Return value   Zero  on   success,  a  nonzero  value  on  error,
  2067.                          indicating  the  nature  of  the  error.  See  the
  2068.                          section on error handling for result codes.
  2069.  
  2070.           See also       msg_read_idx ()
  2071.  
  2072.           Example        #include "mblib.h"
  2073.                          MSGIDX_RECORD myidx;  /* Supposed to be inited */
  2074.  
  2075.                          /* Writing the index to record 100: */
  2076.                          if (msg_to_idx (100, & myidx))
  2077.                            exit (1);    /* Read error */
  2078.  
  2079.  
  2080.           ========================
  2081.           msg_write_toidx
  2082.           ========================
  2083.  
  2084.           Name           msg_write_toidx  -  write  a record to a specified
  2085.                          record in MSGTOIDX.BBS. 
  2086.  
  2087.           Usage          int msg_write_toidx (long recnr, 
  2088.                                              MSGTOIDX_RECORD * idx);
  2089.  
  2090.           Description    This  function  is  much  like  msg_read_toidx (),
  2091.                          except that  it writes a record to MSGIDX.BBS, for
  2092.                          example after modifying it.
  2093.  
  2094.           Return value   Zero  on  success,  a  nonzero  value   on  error,
  2095.                          indicating  the  nature  of  the  error.  See  the
  2096.                          section on error handling for result codes.
  2097.  
  2098.           See also       msg_read_toidx ()
  2099.  
  2100.           Example        #include "mblib.h"
  2101.                          MSGTOIDX_RECORD addressee;
  2102.  
  2103.                                                34
  2104.  
  2105.  
  2106.  
  2107.                          /* Reading addressee from record 100: */
  2108.                          if (msg_read_toidx (100, & addressee))
  2109.                            exit (1);    /* Read error */
  2110.                          printf ("To: %s\n", addressee);
  2111.                          strcpy (addressee, "* Received *");
  2112.                          /* Since the msg is no longer unreceived, */
  2113.                          /* mark it as such                        */
  2114.                          if (msg_write_toidx (100, & addressee)
  2115.                            exit (1);    /* Write error */
  2116.  
  2117.  
  2118.           ========================
  2119.           msg_write_text
  2120.           ========================
  2121.  
  2122.           Name           msg_write_text - write text  to a  message, either
  2123.                          modifying old text or creating new text.
  2124.  
  2125.           Usage          int msg_write_text (MSGHDR_RECORD * hdr,
  2126.                                              M_TEXT txt);
  2127.  
  2128.           Description    This function is typically used to modify existing
  2129.                          message text, or to add new  text to  a previously
  2130.                          written new  message header.  To create entire new
  2131.                          messages  from  scratch,  you'd   better  use  the
  2132.                          msg_write_new () function.
  2133.                          Whether the  text is  used as  a replacement or as
  2134.                          new  text  is  determined  by  the  message header
  2135.                          passed  to  the  function.  If the start_block and
  2136.                          num_blocks field in the  message header  are zero,
  2137.                          the  text  is  treated  as  new  text (since there
  2138.                          obviously isn't  any  old  text  with  these field
  2139.                          containing  zero).  Otherwise,  previous  text  is
  2140.                          replaced.
  2141.  
  2142.           Return value   Zero  on  success,  a  nonzero  value   on  error,
  2143.                          indicating  the  nature  of  the  error.  See  the
  2144.                          section on error handling for result codes.
  2145.  
  2146.           Remarks        Replaced  message  text  blocks  are  not actually
  2147.                          removed from  the message  base. You  need to pack
  2148.                          the message base  with  an  external  message base
  2149.                          maintenance utility to do this.
  2150.  
  2151.           See also       msg_read_text (), msg_write_new ()
  2152.  
  2153.           Example        #include "mb_lib.h"
  2154.                          MSGHDR_RECORD msghdr;    /* Header      */
  2155.                          M_TEXT msgtxt;           /* Text handle */
  2156.  
  2157.                          /* Reading message in record 100 */
  2158.                          if (msg_read_hdr (100, & msghdr))
  2159.                            exit (1);    /* Read error */
  2160.                          /* Now read text, add line, write it back */
  2161.                          msgtxt = msg_read_text (& msghdr);
  2162.                          if (msgtxt == NULL)
  2163.                            exit (1);    /* Read error */
  2164.  
  2165.                                                35
  2166.  
  2167.  
  2168.                          if (txt_add (msgtxt, "One more line..."))
  2169.                            exit (1);    /* Memory error */
  2170.                          if (msg_write_txt (& msghdr, msgtxt))
  2171.                            exit (1);    /* Error writing new text */
  2172.  
  2173.  
  2174.           ========================
  2175.           msg_write_new
  2176.           ========================
  2177.  
  2178.           Name           msg_write_new - write a new message to the message
  2179.                          base
  2180.  
  2181.           Usage          int msg_write_new (MSGHDR_RECORD * hdr,
  2182.                                             M_TEXT txt);
  2183.  
  2184.           Description    Ah - this is the one!  This function  is typically
  2185.                          used to  write a  new message to the message base.
  2186.                          Before calling this function you need to construct
  2187.                          a message  header and fill in the source, destina-
  2188.                          tion and subject fields (in case  of netmail, node
  2189.                          numbers  as  well),  fill  in the board number and
  2190.                          set the desired message attributes. You  also need
  2191.                          to create  a message  text. When you've got header
  2192.                          and text handy, all you need is call this function
  2193.                          (which will  set the other header fields for you).
  2194.  
  2195.           Return value   Zero  on  success,  a  nonzero  value   on  error,
  2196.                          indicating  the  nature  of  the  error.  See  the
  2197.                          section on error handling for result codes.
  2198.  
  2199.           Remarks        You must set unused  header fields  to zero  - the
  2200.                          msg_hdr_clear () function can be used for this. If
  2201.                          you  don't,  unpredicted  results  (this  being an
  2202.                          euphemism for a complete screwup) could occur.
  2203.  
  2204.           See also       msg_write_text (), msg_kill ()
  2205.  
  2206.           Example        #include "mb_lib.h"
  2207.                          MSGHDR_RECORD msghdr;
  2208.                          M_TEXT msgtxt;
  2209.  
  2210.                          /* Error checking left out to keep it short! */
  2211.                          /* In other words, this is quick and dirty.  */
  2212.                          main () {
  2213.                            msg_open ("C:\\MSGBASE");
  2214.                            msg_hdr_clear (& msghdr);
  2215.                            strcpy (msghdr.who_from, "Frank Van.wensveen");
  2216.                            strcpy (msghdr.who_to, "All");
  2217.                            strcpy (msghdr.subject, "See how easy it is?");
  2218.                            msghdr.board = 6; /* My local echomail board */
  2219.                            msghdr.msg_attr = MA_LOCAL;
  2220.                            msgtxt = txt_new ("See? Writing a message is ");
  2221.                            txt_add (msgtxt, "easy! Even I could do it!\r");
  2222.                            msg_lock ("C:\\SEMAFORE");
  2223.                            msg_write_new (& msghdr, msgtxt);
  2224.                            msg_unlock ();
  2225.                            msg_close ();
  2226.  
  2227.                                                36
  2228.  
  2229.  
  2230.                          }
  2231.  
  2232.  
  2233.           ========================
  2234.           msg_kill
  2235.           ========================
  2236.  
  2237.           Name           msg_kill - kill a message
  2238.  
  2239.           Usage          int msg_kill (long recnr);
  2240.  
  2241.           Description    The  msg_kill  ()  function  is  used  to  kill  a
  2242.                          message, the record number of which is specified.
  2243.  
  2244.           Return value   Zero  on  success,  a  nonzero  value   on  error,
  2245.                          indicating  the  nature  of  the  error.  See  the
  2246.                          section on error handling for result codes.
  2247.  
  2248.           Remarks        A killed message is not actually  removed from the
  2249.                          message  base.  To  do  this, you need to pack the
  2250.                          message  base   with  an   external  message  base
  2251.                          maintenance utility.
  2252.  
  2253.           Example        #include "mb_lib.h"
  2254.                          long recnr;
  2255.  
  2256.                          /* Killing message nr. 100 */
  2257.                          recnr = msg_msgnr2recnr (100);
  2258.                          if (recnr != -1)
  2259.                            msg_kill (recnr);
  2260.                          /* Error checking left out */
  2261.  
  2262.  
  2263.  
  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.                                                37
  2290.  
  2291.  
  2292.           ============================================================
  2293.           10: MESSAGE SEARCH SERVICES
  2294.           ============================================================
  2295.  
  2296.           ========================
  2297.           msg_firstinboard
  2298.           ========================
  2299.  
  2300.           Name           msg_firstinboard -  find the  first message in the
  2301.                          specified board
  2302.  
  2303.           Usage          long msg_firstinboard (unsigned char board);
  2304.  
  2305.           Description    This message is used to find the RECORD  NUMBER of
  2306.                          the first  message in a certain board. You'll need
  2307.                          things like  this when  reading all  messages in a
  2308.                          certain  board  from  first  to  last or something
  2309.                          like that.
  2310.  
  2311.           Return value   The RECORD number  of  the  first  message  in the
  2312.                          specified board,  -1 if not found or error. In the
  2313.                          latter   case   the   errortype   and  errorstring
  2314.                          variables are set.
  2315.  
  2316.           See also       msg_lastinboard (), msg_nextinboard (),
  2317.                          msg_previnboard ()
  2318.  
  2319.           Example        See msg_nextinboard ();
  2320.  
  2321.  
  2322.           ========================
  2323.           msg_nextinboard
  2324.           ========================
  2325.  
  2326.           Name           msg_nextinboard  -  find  the  next message in the
  2327.                          same board as the message we've just read is in.
  2328.  
  2329.           Usage          long msg_nextinboard (long recnr);
  2330.  
  2331.           Description    After  calling  msg_firstinboard,  we've  got  the
  2332.                          record number  of the first message in that board.
  2333.                          This  function  finds  the  next  message  in that
  2334.                          board, using  the record  number of the previously
  2335.                          processed message as a starting point.
  2336.  
  2337.           Return value   The RECORD  number  of  the  next  message  in the
  2338.                          specified board,  -1 if not found or error. In the
  2339.                          latter   case   the   errortype   and  errorstring
  2340.                          variables are set.
  2341.  
  2342.           See also       msg_firstinboard (), msg_lastinboard (),
  2343.                          msg_previnboard ();
  2344.  
  2345.           Example        #include "mb_lib.h"
  2346.                          long recnr;
  2347.  
  2348.                          /* Listing messages in board 1 */
  2349.                          recnr = msg_firstinboard (1);
  2350.  
  2351.                                                38
  2352.  
  2353.  
  2354.                          while (recnr != -1) {
  2355.                            printf ("Message number:%d\n",
  2356.                                     msg_recnr2msgnr (recnr);
  2357.                            recnr = msg_nextinboard (recnr);
  2358.                          }
  2359.  
  2360.  
  2361.           ========================
  2362.           msg_lastinboard
  2363.           ========================
  2364.  
  2365.           Name           msg_lastinboard  -  find  the  last message in the
  2366.                          specified board.
  2367.  
  2368.           Usage          long msg_lastinboard (unsigned char board);
  2369.  
  2370.           Description    This message is identical to msg_firstinboard, but
  2371.                          returns the  number of the last message instead of
  2372.                          the first.
  2373.  
  2374.           Return value   The RECORD  number  of  the  last  message  in the
  2375.                          specified board,  -1 if not found or error. In the
  2376.                          latter   case   the   errortype   and  errorstring
  2377.                          variables are set.
  2378.  
  2379.           See also       msg_firstinboard (), msg_nextinboard (),
  2380.                          msg_previnboard ();
  2381.  
  2382.           Example        See msg_previnboard ();
  2383.  
  2384.  
  2385.           ========================
  2386.           msg_previnboard
  2387.           ========================
  2388.  
  2389.           Name           msg_previnboard - find the previous message in the
  2390.                          same board as the message we've just read is in.
  2391.  
  2392.           Usage          long msg_previnboard (long recnr);
  2393.  
  2394.           Description    This function is identical  to msg_nextinboard (),
  2395.                          except that it searches backwards.
  2396.  
  2397.           Return value   The RECORD  number of  the previous message in the
  2398.                          specified board, -1 if not found or error.  In the
  2399.                          latter   case   the   errortype   and  errorstring
  2400.                          variables are set.
  2401.  
  2402.           See also       msg_next_inboard, msg_lastinboard (),
  2403.                          msg_previnboard ();
  2404.  
  2405.           Example        #include "mb_lib.h"
  2406.                          long recnr;
  2407.  
  2408.                          /* Backward listing messages in board 1 */
  2409.                          recnr = msg_lastinboard (1);
  2410.                          while (recnr != -1) {
  2411.                            printf ("Message number:%d\n",
  2412.  
  2413.                                                39
  2414.  
  2415.  
  2416.                                     msg_recnr2msgnr (recnr);
  2417.                            recnr = msg_previnboard (recnr);
  2418.                          }
  2419.  
  2420.  
  2421.           ========================
  2422.           msg_firstto
  2423.           ========================
  2424.  
  2425.           Name           msg_firstto - find the first unreceived message to
  2426.                          a certain user
  2427.  
  2428.           Usage          long msg_firstto (MSGTOIDX_RECORD * idx);
  2429.  
  2430.           Description    This message  can be used to scan the message base
  2431.                          for unreceived  mail to  a certain  user. It scans
  2432.                          MSGTOIDX.BBS for  the user's  name and returns the
  2433.                          record number associated with  a  search  hit. You
  2434.                          can  then  proceed  to  read  the  message in this
  2435.                          record.
  2436.                          Software used for reading  the unreceived messages
  2437.                          should  overwrite   the  corresponding  record  in
  2438.                          MSGTOIDX.BBS to prevent the message from remaining
  2439.                          marked  as  unreceived.  Functions in MB_lib don't
  2440.                          take care of this, the programmer must do it.
  2441.  
  2442.           Return value   The RECORD number  of  the  first  message  to the
  2443.                          specified user,  -1 if  not found or error. In the
  2444.                          latter   case   the   errortype   and  errorstring
  2445.                          variables are set.
  2446.  
  2447.           See also       msg_nextto (), msg_lastto (), msg_prevto ()
  2448.  
  2449.           Example        See msg_nextto ()
  2450.  
  2451.  
  2452.           ========================
  2453.           msg_nextto
  2454.           ========================
  2455.  
  2456.           Name           msg_nextto  -  find  the  next message to the same
  2457.                          user as the one we just read was addressed to
  2458.  
  2459.           Usage          long msg_nextto (long recnr);
  2460.  
  2461.           Description    After calling msg_firstto,  we've  got  the record
  2462.                          number  of  the  first  message to a certain user.
  2463.                          This  function  finds  the  next  message  to that
  2464.                          user,  using  the  record number of the previously
  2465.                          processed message as a starting point.
  2466.  
  2467.           Return value   The RECORD  number  of  the  next  message  to the
  2468.                          specified user,  -1 if  not found or error. In the
  2469.                          latter   case   the   errortype   and  errorstring
  2470.                          variables are set.
  2471.  
  2472.           See also       msg_firstto (), msg_lastto (), msg_prevto ()
  2473.  
  2474.  
  2475.                                                40
  2476.  
  2477.  
  2478.           Example        #include "mb_lib.h"
  2479.                          long recnr;
  2480.                          MSGTOIDX_RECORD toidx;
  2481.  
  2482.                          strcpy (toidx, "Frank Van.wensveen");
  2483.                          recnr = msg_firstto (toidx);
  2484.                          puts ("Mail waiting for you:");
  2485.                          while (recnr != -1) {
  2486.                            printf ("Message number: %d\n",
  2487.                                     msg_recnr2msgnr (recnr);
  2488.                            recnr = msg_nextto (recnr);
  2489.                          }
  2490.  
  2491.  
  2492.           ========================
  2493.           msg_lastto
  2494.           ========================
  2495.  
  2496.           Name           msg_lastto - find the last unreceived message to a
  2497.                          certain user.
  2498.  
  2499.           Usage          long msg_lastto (MSGTOIDX_RECORD * toidx);
  2500.  
  2501.           Description    This  function  is  identical  to  msg_firstto (),
  2502.                          except  that  it  searches  for  the  last message
  2503.                          instead of the first.
  2504.  
  2505.           Return value   The RECORD  number  of  the  last  message  to the
  2506.                          specified user,  -1 if  not found or error. In the
  2507.                          latter   case   the   errortype   and  errorstring
  2508.                          variables are set.
  2509.  
  2510.           See also       msg_firstto (), msg_nextto (), msg_prevto ()
  2511.  
  2512.           Example        See msg_prevto ()
  2513.  
  2514.  
  2515.           ========================
  2516.           msg_prevto
  2517.           ========================
  2518.  
  2519.           Name           msg_prevto - find the previous message to the same
  2520.                          user as the one we just read was addressed to
  2521.  
  2522.           Usage          long msg_nextto (long recnr);
  2523.  
  2524.           Description    This message is identical to msg_nextto (), except
  2525.                          that it searches backwards.
  2526.  
  2527.           Return value   The RECORD  number of  the previous message to the
  2528.                          specified user, -1 if not found  or error.  In the
  2529.                          latter   case   the   errortype   and  errorstring
  2530.                          variables are set.
  2531.  
  2532.           See also       msg_firstto (), msg_lastto (), msg_nextto ()
  2533.  
  2534.           Example        #include "mb_lib.h"
  2535.                          long recnr;
  2536.  
  2537.                                                41
  2538.  
  2539.  
  2540.                          MSGTOIDX_RECORD toidx;
  2541.  
  2542.                          strcpy (toidx, "Frank Van.wensveen");
  2543.                          recnr = msg_lastto (toidx);
  2544.                          puts ("Mail waiting for you:");
  2545.                          puts ("Listed last to first")
  2546.                          while (recnr != -1) {
  2547.                            printf ("Message number: %d\n",
  2548.                                     msg_recnr2msgnr (recnr);
  2549.                            recnr = msg_prevto (recnr);
  2550.                          }
  2551.  
  2552.  
  2553.  
  2554.  
  2555.  
  2556.  
  2557.  
  2558.  
  2559.  
  2560.  
  2561.  
  2562.  
  2563.  
  2564.  
  2565.  
  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.  
  2593.  
  2594.  
  2595.  
  2596.  
  2597.  
  2598.  
  2599.                                                42
  2600.  
  2601.  
  2602.           ============================================================
  2603.           11: NETMAIL (*.MSG) SERVICES
  2604.           ============================================================
  2605.           The following routines make up the  net_ family.  These functions
  2606.           are typically  used for  netmail support.  But in  fact any *.MSG
  2607.           base is supported, no  matter  what  type  of  mail  it contains.
  2608.           (Fmail for example uses *.MSG type files to store personal mail.)
  2609.  
  2610.           WARNING: though  the netmail  header defined in MB_LIB.H contains
  2611.           both a Zone and a Point field, these fields are  not supported by
  2612.           FSC-0001. Correct  interpretation of these fields by all software
  2613.           is NOT guaranteed. In fact, some  programs have  been verified to
  2614.           use  these  fields  for  other  data. FSC-0001 (sec) specified 2D
  2615.           addressing only.
  2616.           In order to use 4D addresses which will be processed correctly by
  2617.           all software,  it is  recommended that  you use the FMPT/TOPT and
  2618.           INTL kludges instead.
  2619.  
  2620.  
  2621.  
  2622.  
  2623.  
  2624.  
  2625.  
  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.  
  2652.  
  2653.  
  2654.  
  2655.  
  2656.  
  2657.  
  2658.  
  2659.  
  2660.  
  2661.                                                43
  2662.  
  2663.  
  2664.           ========================
  2665.           net_first
  2666.           ========================
  2667.  
  2668.           Name           net_first -  get the  number of  the first netmail
  2669.                          message in a directory.
  2670.  
  2671.           Usage          int net_first (char * msgpath);
  2672.  
  2673.           Description    This  function  is  used  to get the number of the
  2674.                          first  message  in  a  *.MSG  (Opus-style) message
  2675.                          base. The  path to the directory holding the *.MSG
  2676.                          files is specified.
  2677.  
  2678.           Return value   The number of the first message  in the directory,
  2679.                          0 if  error or no messages found. In this case the
  2680.                          errortype and errorstring variables are set.
  2681.  
  2682.           Remarks        The specified  directory  is  supposed  to contain
  2683.                          *.MSG  files.  These  message  need not be netmail
  2684.                          messages.
  2685.  
  2686.           See also       net_last (), net_next (), net_prev ()
  2687.  
  2688.           Example        See net_next ()
  2689.  
  2690.  
  2691.           ========================
  2692.           net_next
  2693.           ========================
  2694.  
  2695.           Name           net_next - return the  number of  the message next
  2696.                          to the specified one.
  2697.  
  2698.           Usage          int net_next (char * msgpath, int nr);
  2699.  
  2700.           Description    While net_first  () return the number of the first
  2701.                          message in the specified  directory, this function
  2702.                          returns  the  number  of  the  message next to the
  2703.                          specified one. Typically you'd  call net_first (),
  2704.                          and  use  the  number  obtained  to  find the next
  2705.                          message until you run out of mail.
  2706.  
  2707.           Return value   The number of the message in the directory next to
  2708.                          the specified  number, 0  if error  or no messages
  2709.                          found. In this case the errortype  and errorstring
  2710.                          variables are set.
  2711.  
  2712.           See also       net_first (), net_last (), net_prev ()
  2713.  
  2714.           Example        #include "mb_lib.h"
  2715.                          int msgnum;
  2716.  
  2717.                          msgnum = net_first ("C:\\NETMAIL");
  2718.                          puts ("Netmail:");
  2719.                          while (msgnum != 0) {
  2720.                            printf ("%d\n", msgnum);
  2721.                            msgnum = net_next (msgnum);
  2722.  
  2723.                                                44
  2724.  
  2725.  
  2726.                          }
  2727.  
  2728.  
  2729.           ========================
  2730.           net_last
  2731.           ========================
  2732.  
  2733.           Name           net_last  -  get  the  number  of the last netmail
  2734.                          message in a directory.
  2735.  
  2736.           Usage          int net_last (char * msgpath);
  2737.  
  2738.           Description    This function is used to  get  the  number  of the
  2739.                          last  message  in  a  *.MSG  (Opus-style)  message
  2740.                          base. The path to the directory  holding the *.MSG
  2741.                          files is specified.
  2742.  
  2743.           Return value   The number  of the  last message in the directory,
  2744.                          0 if error or no messages found. In  this case the
  2745.                          errortype and errorstring variables are set.
  2746.  
  2747.           Remarks        The  specified  directory  is  supposed to contain
  2748.                          *.MSG files. These  message  need  not  be netmail
  2749.                          messages.
  2750.  
  2751.           See also       net_first (), net_next (), net_prev ()
  2752.  
  2753.           Example        See net_prev ()
  2754.  
  2755.  
  2756.           ========================
  2757.           net_prev
  2758.           ========================
  2759.  
  2760.           Name           net_prev  -  return  the  number  of  the  message
  2761.                          previous to the specified one.
  2762.  
  2763.           Usage          int net_prev (char * msgpath, int nr);
  2764.  
  2765.           Description    While net_last () returns  the number  of the last
  2766.                          message in  the specified directory, this function
  2767.                          returns the number of the message  previous to the
  2768.                          specified one.  Typically you'd  call net_last (),
  2769.                          and use the number  obtained to  find the previous
  2770.                          message until you run out of mail.
  2771.  
  2772.           Return value   The  number   of  the  message  in  the  directory
  2773.                          previous to  the specified  number, 0  if error or
  2774.                          no messages  found. In this case the errortype and
  2775.                          errorstring variables are set.
  2776.  
  2777.           See also       net_first (), net_last (), net_next ()
  2778.  
  2779.           Example        #include "mb_lib.h"
  2780.                          int msgnum;
  2781.  
  2782.                          msgnum = net_last ("C:\\NETMAIL");
  2783.                          puts ("Netmail listed backwards:");
  2784.  
  2785.                                                45
  2786.  
  2787.  
  2788.                          while (msgnum != 0) {
  2789.                            printf ("%d\n", msgnum);
  2790.                            msgnum = net_prev (msgnum);
  2791.                          }
  2792.  
  2793.  
  2794.           ========================
  2795.           net_hdr_clear
  2796.           ========================
  2797.  
  2798.           Name           net_hdr_clear -  clear  a  netmail  header record,
  2799.                          e.g. set all fields in the header to zero.
  2800.  
  2801.           Usage          void net_hdr_clear (NET_RECORD * hdr);
  2802.  
  2803.           Description    A netmail header record contains many fields, many
  2804.                          of which should be  set to  0 when  creating a new
  2805.                          message.  Because  the  fields in an uninitialized
  2806.                          header contain unknown values, we should initiali-
  2807.                          zed  each  field  before  using this header. Since
  2808.                          this is very cumbersome,  this  function  does the
  2809.                          job for you.
  2810.  
  2811.           Remarks        This  function   should  always   be  called  when
  2812.                          creating a new netmail header, otherwise unpredic-
  2813.                          table effects will occur.
  2814.  
  2815.           Example        #include "mb_lib.h"
  2816.  
  2817.                          NET_RECORD hdr;
  2818.  
  2819.                          net_hdr_clear (& hdr);
  2820.                          strcpy (hdr.who_from, "Frank Van.wensveen");
  2821.                          strcpy (hdr.who_to, "All");
  2822.                          strcpy (hdr.subject, "Test");
  2823.                          /* The header is now fully initialized! */
  2824.  
  2825.  
  2826.           ========================
  2827.           net_getlastread
  2828.           ========================
  2829.  
  2830.           Name           net_getlastread - get the lastread pointer for the
  2831.                          specified *.msg folder.
  2832.  
  2833.           Usage          int net_getlastread (char * msgpath);
  2834.  
  2835.           Description    To keep track of  what message  has been  read the
  2836.                          last time,  most message  readers /  editors use a
  2837.                          lastread pointer. This is a small  file located in
  2838.                          the message  directory, which  contains the number
  2839.                          of the message that was read last. 
  2840.                          This function is used to read the lastread pointer
  2841.                          for a specified message directory.
  2842.  
  2843.           Return value   The number of the message that was read last or -1
  2844.                          if an error  was  encountered.  In  that  case the
  2845.                          errortype and errorstring variables are set.
  2846.  
  2847.                                                46
  2848.  
  2849.  
  2850.  
  2851.           See also       net_setlastread ()
  2852.  
  2853.  
  2854.           ========================
  2855.           net_setlastread
  2856.           ========================
  2857.  
  2858.           Name           net_setlastread - set the lastread pointer for the
  2859.                          specified *.msg folder
  2860.  
  2861.           Usage          int setlastread (char * msgpath, int lastread);
  2862.  
  2863.           Description    This function is used to set  the lastread pointer
  2864.                          for the specified message directory to a specified
  2865.                          value.
  2866.  
  2867.           Return value   Zero  if  success,  non-zero   if  an   error  was
  2868.                          encountered.  In   this  case  the  errortype  and
  2869.                          errorstring variables are set.
  2870.  
  2871.           See also       net_getlastread
  2872.  
  2873.  
  2874.           ========================
  2875.           net_read_hdr
  2876.           ========================
  2877.  
  2878.           Name           net_read_hdr - read a netmail header
  2879.  
  2880.           Usage          int net_read_hdr (char * msgpath, int msgnr,
  2881.                                            NET_RECORD * hdr);
  2882.  
  2883.           Description    This function is much  like msg_read_hdr,  in that
  2884.                          it is used to read a message header.
  2885.  
  2886.           Return value   Zero  if   success,  non-zero   if  an  error  was
  2887.                          encountered.
  2888.  
  2889.           See also       msg_read_hdr (), net_read_text ()
  2890.  
  2891.           Example        See net_read_text ()
  2892.  
  2893.  
  2894.           ========================
  2895.           net_read_text
  2896.           ========================
  2897.  
  2898.           Name           net_read_text -  read the  text body  of a netmail
  2899.                          message.
  2900.  
  2901.           Usage          M_TEXT net_read_text (char * msgpath, int msgnum);
  2902.  
  2903.           Description    This function  is much like msg_read_text, in that
  2904.                          it is  used to  read the  text body  of a message.
  2905.                          Combined with the net_read_hdr () function, it can
  2906.                          be used for all  kinds of  netmail message reading
  2907.                          jobs. Because  text is returned by means of a text
  2908.  
  2909.                                                47
  2910.  
  2911.  
  2912.                          handle,  all  possibilities  with  regard  to text
  2913.                          manipulation apply.
  2914.  
  2915.           Return value   Text  handle,  NULL  on  error.  In  this case the
  2916.                          errortype and errorstring variables are set.
  2917.  
  2918.           See also       msg_read_text (), net_read_hdr ()
  2919.  
  2920.           Example        #include "mb_lib.h"
  2921.  
  2922.                          M_TEXT txt;
  2923.                          NET_RECORD hdr;
  2924.  
  2925.                          /* Reading message nr. 10        */
  2926.                          if (net_read_hdr ("C:\\NETMAIL", 10, & hdr))
  2927.                            exit (1);
  2928.                          txt = net_read_text ("C:\\NETMAIL, 10);
  2929.                          if (txt == NULL)
  2930.                            exit (1);
  2931.                          txt_dump (txt, printline, 70, NOKLUDGES);
  2932.  
  2933.  
  2934.           ========================
  2935.           net_write
  2936.           ========================
  2937.  
  2938.           Name           net_write - write a (netmail) message into a *.MSG
  2939.                          base.
  2940.  
  2941.           Usage          int net_write (char * msgpath, int msgnr,
  2942.                                         NET_RECORD * hdr, M_TEXT txt);
  2943.  
  2944.           Description    This  function  is  all  you need to write a *.MSG
  2945.                          message. Before calling the net_write () function,
  2946.                          you need  to determine the desired message number.
  2947.                          For new messages you  typically do  something like
  2948.                          msg_nr = net_last ("C:\\NETMAIL") + 1;.
  2949.                          You also  need to  create a message text, the text
  2950.                          handle of which  is  passed  to  the  net_write ()
  2951.                          function.
  2952.                          Unused fields in the message header must be set to
  2953.                          zero, or  unpredictable  results  will  occur. The
  2954.                          net_hdr_clear  ()  function  can be used for that.
  2955.                          The datetime field in the message  header does not
  2956.                          need to  be initialized, net_write () will do that
  2957.                          for you.
  2958.  
  2959.           Return value   Zero  on  success,  non-zero  when  an   error  is
  2960.                          encountered.  In   this  case  the  errortype  and
  2961.                          errorstring variables are set.
  2962.  
  2963.           See also       msg_write_new ();
  2964.  
  2965.           Example        #include "mb_lib.h"
  2966.                          NET_RECORD msghdr;
  2967.                          M_TEXT msgtxt;
  2968.  
  2969.                          /* Error checking left out to keep it short! */
  2970.  
  2971.                                                48
  2972.  
  2973.  
  2974.                          /* In other words, this is quick and dirty.  */
  2975.                          main () {
  2976.                            net_hdr_clear (& msghdr);
  2977.                            strcpy (msghdr.who_from, "Frank Van.wensveen");
  2978.                            strcpy (msghdr.who_to, "SysOp");
  2979.                            strcpy (msghdr.subject, "See how easy it is?");
  2980.                            msghdr.msg_attr = NM_LOCAL;
  2981.                            msgtxt = txt_new ("See? Writing a netmail is ");
  2982.                            txt_add (msgtxt, "easy! Even I could do it!\r");
  2983.                            net_write ("C:\\NETMAIL", 
  2984.                                        net_last ("C:\\NETMAIL") + 1, 
  2985.                                        & msghdr, msgtxt);
  2986.                          }
  2987.  
  2988.  
  2989.           ========================
  2990.           net_kill
  2991.           ========================
  2992.  
  2993.           Name           net_kill - kill a *.MSG message.
  2994.  
  2995.           Usage          int net_kill (char * msgpath, int msgnr);
  2996.  
  2997.           Description    This function is used  to kill  (delete) a message
  2998.                          in  a  *.MSG  base.  Unlike messages in the Hudson
  2999.                          message  base,  *.MSG   messages   are  physically
  3000.                          deleted when killed.
  3001.  
  3002.           Return value   Zero  on   success,  non-zero   if  an  error  was
  3003.                          encountered.  In  this  case   the  errortype  and
  3004.                          errorstring variables are set.
  3005.  
  3006.  
  3007.           ========================
  3008.           net_fixup4d
  3009.           ========================
  3010.  
  3011.           Name           net_fixup4d - convert the zone and point fields in
  3012.                          a *.MSG netmail  header  into  INTL  and FMPT/TOPT
  3013.                          kludges   to   overcome  the  FSC-0001  compliance
  3014.                          problem.
  3015.  
  3016.           Usage          int net_fixup4d (NET_RECORD * hdr, M_TEXT txt);
  3017.  
  3018.           Description    See  msg_fixup4d.  The  difference  between Hudson
  3019.                          netmail  headers  and  *.MSG  headers  is that the
  3020.                          latter also contain unsupported  point fields. The
  3021.                          Hudson  netmail  header  does  not  support  point
  3022.                          addresses.
  3023.  
  3024.           Return value   Zero on success, non-zero on error.
  3025.  
  3026.           Remarks        CAUTION:  The  fixup  functions  add  text  to the
  3027.                          specified  text  handle.  The  text  handle *MUST*
  3028.                          therefore be initialized, otherwise "unpredictable
  3029.                          results"  (an   euphemism  for  a  total  screwup,
  3030.                          usually)  will  occur.  You   *must*  have  called
  3031.  
  3032.  
  3033.                                                49
  3034.  
  3035.  
  3036.                          txt_new ()  previous to  calling msg_fixup4d () or
  3037.                          net_fixup4d ().
  3038.  
  3039.           See also       msg_fixup4d ()
  3040.  
  3041.           Example        see msg_fixup4d (). 
  3042.  
  3043.  
  3044.  
  3045.  
  3046.  
  3047.  
  3048.  
  3049.  
  3050.  
  3051.  
  3052.  
  3053.  
  3054.  
  3055.  
  3056.  
  3057.  
  3058.  
  3059.  
  3060.  
  3061.  
  3062.  
  3063.  
  3064.  
  3065.  
  3066.  
  3067.  
  3068.  
  3069.  
  3070.  
  3071.  
  3072.  
  3073.  
  3074.  
  3075.  
  3076.  
  3077.  
  3078.  
  3079.  
  3080.  
  3081.  
  3082.  
  3083.  
  3084.  
  3085.  
  3086.  
  3087.  
  3088.  
  3089.  
  3090.  
  3091.  
  3092.  
  3093.  
  3094.  
  3095.                                                50
  3096.  
  3097.  
  3098.  
  3099.  
  3100.  
  3101.  
  3102.                          This page intentionally left blank.
  3103.  
  3104.  
  3105.  
  3106.  
  3107.  
  3108.  
  3109.  
  3110.  
  3111.  
  3112.  
  3113.  
  3114.  
  3115.  
  3116.  
  3117.  
  3118.  
  3119.  
  3120.  
  3121.  
  3122.  
  3123.  
  3124.  
  3125.  
  3126.  
  3127.  
  3128.  
  3129.  
  3130.  
  3131.  
  3132.  
  3133.  
  3134.  
  3135.  
  3136.  
  3137.  
  3138.  
  3139.  
  3140.  
  3141.  
  3142.  
  3143.  
  3144.  
  3145.  
  3146.  
  3147.  
  3148.  
  3149.  
  3150.  
  3151.  
  3152.  
  3153.  
  3154.  
  3155.  
  3156.  
  3157.                                                51