                          BudgieSoft DoorLib v1.12               1st June 1996
                          ~~~~~~~~~~~~~~~~~~~~~~~~

The 'et cetera' stuff:
~~~~~~~~~~~~~~~~~~~~~~
   DoorLib and TestDoor are copyright  (C) 1996 Richard Murray [BudgieSoft].
   No liability is assumed if DoorLib craps on your system or stiffs the
   machine. Blah blah blah...

   This version of DoorLib is split into little bits so that you need only
   link the bits you use. Also included is this file (in case you lose the
   archive!). Use !LibFile to extract.



Purpose:
~~~~~~~~
   To provide door interface functions that will make life easier for door
   writers. :-)

   Why? Because I needed some concise routines to Auremia. I *had* considered
   a DoorLib module, but a linkable library seemed a much neater solution - I
   am sure you'll agree.

   I have tried to cover the reasonable stuff here with lots of functions I
   think useful. I'd be happy to hear about other ideas.


    - Don't bother asking for routines like 'doors_cls()' and 'doors_fgbg()'.
       It is, IMHO, easier to do a 'doors_txf(port,"%c[2J",27);' than waste
       memory making a routine to do it for you...


Dependencies:
~~~~~~~~~~~~~
   DoorLib requires:
      * 1 function called 'poll_the_wimp()' which will do a single WIMP poll
        and return. Used when sending large amounts of data to ports if
        buffer gets full.
        Simply call your usual Event_Poll or whatever. From the example code
        you can see how this was hacked to work with DeskLib.
      * 2 global variables...
           Firstly, 'int port_in_use'. You can call this whatever you want,
           and it is not used internally by DoorLib - but you'll need it for
           every call so it knows where to send/get the data. :-)
           Secondly, 'int doors_connectedokay'. This is TRUE when door
           connection is established and active, otherwise FALSE.
      * _kernel_swi (in kernel.h).

      * Note: No function in DoorLib calls 'exit()', you must take action
              yourself depending upon the results of the functions.

        All other memory/variables are allocated within the functions.
        Internal variables all begin with "bs_".


Functions (arranged in subcomponent order):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   doorlib112 - core functions:
   ----------------------------

   int doors_scanconnect(int)
      Scans for a connection to the doors interface.

      ENTRY: Parameter 1 - The required door number in the range 1 to 254.
      EXIT : The port connected to.


   int doors_scanconnecttimed(int, int)
      Scans for a connection to the doors interface with timeout.

      ENTRY: Parameter 1 - The required door number in the range 1 to 254.
             Parameter 2 - The timeout delay in seconds.
      EXIT : The port connected or '-1' if timed-out.


   int doors_getbyte(int)
      Gets the next byte and returns its ASCII code.

      ENTRY: Parameter 1 - The port number.
      EXIT : The next byte's ASCII code or '-1' if no next byte.


   int doors_getbytef(int, int)
      Gets the next byte and returns it. Will loop until timed out (if active)
      or a byte is received.

      ENTRY: Parameter 1 - The port number.
             Parameter 2 - An optional timeout in seconds ('0' to disable).
      EXIT : The next byte's ASCII code or '-1' if timed out.


   int doors_byteswaiting(int)
      Find out how many bytes are WAITING in the input buffer.

      ENTRY: Parameter 1 - The port number.
      EXIT : The number of bytes WAITING in the input buffer.


   int doors_bytesfree(int)
      Find out how many bytes are FREE in the output buffer.

      ENTRY: Parameter 1 - The port number.
      EXIT : The number of bytes FREE in the output buffer.


   int doors_checkactive(int)
      Returns the status of the port. Call in 'poll_the_wimp()'?

      ENTRY: Parameter 1 - The port number.
      EXIT : Returns TRUE if okay and FALSE if user gone or something.


   void doors_tx(int, char *)
      This sends the required string to the port. The input is loose-parsed,
      so you can include "/r/n" in the line, but not '%' type substitutions.

      ENTRY: Parameter 1 - The port number.
             Parameter 2 - The string to send.
      EXIT : 


   void doors_txf(int, char *, ...)
      As 'doors_tx()' but accepts printf style input.

      ENTRY: Parameter 1 - The port number.
             Parameter 2 - The string to send.
             Parameter++ - Variables as required by string. Allows standard
                           printf substitutions ('\n' or '\a' or '%#d' etc).
      EXIT : 


   void doors_txesc(int, char *)
      As 'doors_tx()' but converts every '~' found into an escape code.
      Therefore you can read ANSI escapes from messages files and suchlike...

      ENTRY: Parameter 1 - The port number.
             Parameter 2 - The string to send.
      EXIT : 


   void doors_close(int)
      Closes down the door connection and returns the user to the BBS server
      system.

      ENTRY: Parameter 1 - The port number.
      EXIT : 



   drawbox    - box drawing function:
   ----------------------------------

   int doors_drawbox(int, int, int, int, int)
      Draws boxes for you...
      Cursor is returned to start position after box has been drawn.

      ENTRY: Parameter 1 - The port number.
             Parameter 2 - The horizontal start position, 0 to 77.
             Parameter 3 - The vertical start position, 0 to 21.
             Parameter 4 - The width of the box, 3 to (77 - horiz_start).
             Parameter 5 - The height of the box, 3 to (22 - vert_start).
                           The height extends downwards, not upwards.
      EXIT : Returns 0 if okay, or an error code:
             20 - Horizontal start position out of range.
             21 - Vertical start position out of range.
             22 - Width out of range.
             23 - Height out of range.
             25 - Height computation overruns screen.
             26 - Width computation overruns screen.



   ftp        - file transfer functions:
   -------------------------------------

   File transfer functions have not been coded at this time. Two routines
   are defined. Both will return '-1' (ftp failure). Do not rely on the
   presence or absence of routines in 'ftp', or the parameter ordering.

   int doors_xmodem1tx(char *, char *)
   int doors_xmodem1rx(char *)



   typetextf  - text file output function:
   ---------------------------------------

   int doors_typetextfile(int, int, char *)
      Types a textfile to the port. User gets the ArcBBS style "More?
      [Return] continues, [N]onstop, [Ctrl+C] to abort..." prompting. Once
      nonstop has been selected, there is no way to un-nonstop.

      ENTRY: Parameter 1 - The port number.
             Parameter 2 - Unused.
             Parameter 3 - Filename.

      EXIT : Returns TRUE if okay, FALSE if file can't be opened.



   userdata   - user data functions:
   ---------------------------------

   "userdata" is a set of functions new to DoorLib 1.12. Simply, these return
   useful user-related data. Or if you want something more techie, you can get
   access to the user information directly.

   int doors_isportavailable(int)
      This is a little routine I'm playing around with. It currently doesn't
      work as far as I could suss out. Feel free to play.

      ENTRY: Parameter 1 - The port number.

      EXIT : Should return '1' if port contactable or '0' if not loaded, no
             user, user in door or user ftping.

   int doors_checkchatirq(int)
      This routine returns the status of the NO_CHAT_REQUESTS flag. It returns
      0 if you have no chat requests set, or 1. Note that this is backwards
      to the way you would expect! :-)

      ENTRY: Parameter 1 - The port number.

      EXIT : 0, NO_CHAT_REQUESTS set; 1, unset.


   char *doors_getusername(int)
      This returns a pointer to the users username string.

      ENTRY: Parameter 1 - The port number.

      EXIT : Pointer to username string.


   int doors_gettermtype(int)
      Return the terminal type.

      Under ArcBBS, this returns:
        0 - TTY
        1 - VT52
        2 - VT100
        3 - ANSI

      ArmBBS/NewsFlash *may* return their approximation (0 & 3?). Suck'n'see.

      ENTRY: Parameter 1 - The port number.

      EXIT : Terminal type setting.


   int doors_gettimeleft(int)
      Return the number of seconds of time remaining on-line this call.

      ENTRY: Parameter 1 - The port number.

      EXIT : Seconds remaining. Note, you may get weird values for ArmBBS's
             "unlimited time" option -- I think it is negative.


   int doors_getuserlevel(int)
      Returns the userlevel (hexadecimal value).

      ENTRY: Parameter 1 - The port number.

      EXIT : The user level.


   char *doors_getrealname(int)
      This returns a pointer to the users realname string.

      ENTRY: Parameter 1 - The port number.

      EXIT : Pointer to realname string. ArmBBS should cope with this by
             setting a null string or something. Early days of SysOpChat would
             crash ArmBBS if you asked for the address etc. It's come a long
             way. Again, suck'n'see.


   struct bs_userdatum_type0 *doors_genericfetchdata_typezero(int)
      Not something to be taken lightly! :-)

      ENTRY: Parameter 1 - The port number.

      EXIT : Pointer to type 0 structure containing the following fields
             (defined in doorlib.h):

               struct bs_userdatum_type0
               {
                  int  bs_usernumber;
                  int  bs_firstlogon;
                  int  bs_lastlogon;
                  int  bs_mailwaiting;
                  int  bs_mailstart;
                  int  bs_mailend;
                  int  bs_highestmessage;
                  int  bs_highestfile;
                  int  bs_terminaltype;
                  int  bs_messageflags;
                  int  bs_fileflags;
                  int  bs_userflags;
                  int  bs_updownratio;
                  int  bs_userlevel;
                  int  bs_numberoflogons;
                  int  bs_numberofuploads;
                  int  bs_numberofdownloads;
                  int  bs_timeperday;
                  int  bs_timeusedtoday;
                  int  bs_fidocredit;
                  int  bs_fidoflags;
                  int  bs_messagearea;
                  int  bs_filearea;
                  int  bs_outboxstart;
                  int  bs_outboxend;
                  int  bs_outboxcount;
                  char bs_areasjoined[64];
                  int  bs_timeusedthiscall;
                  int  bs_timeleftthiscall;
                  int  bs_timeallocthiscall;
                  int  bs_connectspeed;
                  char bs_arq[1];
                  char bs_callrate[1];
                  char bs_screenlength[1];
                  char bs_username[31];
                  char bs_remainder[38];
               };

             So you can access the data directly if you require. If there is
             a routine you use a lot that interfaces with this struct, maybe
             you should submit it for inclusion into DoorLib?

             You gotta admit, calling doors_gettermtype() is nicer, even
             though it simply returns 'bs_userdatum_type0.bs_terminaltype'.

             Further information? Read the ArcBBS 'doordox' file or the
             BudgieSoft 'DoorDocs' file version 7.


   struct bs_userdatum_type1 *doors_genericfetchdata_typeone(int)
      Another "Not something to be taken lightly!" thing.

      ENTRY: Parameter 1 - The port number.

      EXIT : Pointer to type 1 structure containing the following fields
             (defined in doorlib.h):

               struct bs_userdatum_type1
               {
                  char bs_username[31];
                  char bs_realname[31];
                  char bs_address1[31];
                  char bs_address2[31];
                  char bs_address3[31];
                  char bs_address4[31];
                  char bs_postcode[11];
                  char bs_telephone[11];
                  char bs_remainder[48];
               };

             I can't say if this works under ArmBBS. Not tested it! So if it
             does, can somebody tell me maybe?

             Further information? Read the ArcBBS 'doordox' file or the
             BudgieSoft 'DoorDocs' file version 7.



   utility    - useful utility functions:
   --------------------------------------

   int doors_yesno(int, int)
      Will respond to 'Y' or 'y' or 'N' or 'n' or 'Ctrl+C' or 'Return'.

      ENTRY: Parameter 1 - The port number.
             Parameter 2 - The value to return if 'Return' is pressed, TRUE
                           (fakes Y) or FALSE (fakes N). If 'Return' value is
                           not either TRUE or FALSE, presses of 'Return' will
                           be ignored.
      EXIT : Returns TRUE if 'Yes' or FALSE if 'No' or '-1' if Ctrl+C.


   int doors_scrollrq(int)
      Allows you to support "More? [Return] continues, [N]onstop, Ctrl+C to 
      abort" things.

      ENTRY: Parameter 1 - The port number.
      EXIT : Returns TRUE if 'Return' (more), FALSE if nonstop and '-1' if
             Ctrl+C.


   char *doors_centretext(char *, int)
      Centres a string.

      ENTRY: Parameter 1 - The string to centre.
             Parameter 2 - The width. A width of 0 implies the default width
                           of 78 characters.
      EXIT : Returns a pointer to the centred string. If the width is less
             than the length of the string, the routine simply returns the
             input string. Input string is NOT altered.


   void doors_strfill(char *, int, int)
      Fills the supplied string with the character defined for a specified
      length. No checks are made to see if the length overruns the string
      size.

      ENTRY: Parameter 1 - The string to fill (can be anything).
             Parameter 2 - The ASCII code to fill with.
             Parameter 3 - The length to fill.
      EXIT : 


   void doors_substr(char *, char *, int, int)
      This moves #a characters from $x to $y, starting at #b. This can, with
      practice, be used much like MID$ or LEFT$ or even RIGHT$. There are no
      checks made to ensure the values passed are correct. The leftmost
      character is character 1. Do not set #b to 0... The input string is
      not altered.

      ENTRY: Parameter 1 - The input string ($x).
             Parameter 2 - The output string ($y).
             Parameter 3 - The starting position (#b).
             Parameter 4 - The number of characters to move (#a).
      EXIT : 


   char *doors_itoa(int)
      This is the reverse of atoi, it takes the number supplied and returns
      it as a string.

      ENTRY: Parameter 1 - The number to convert, as an int.
      EXIT : Returns a pointer to the string converted.


   char *doors_string(int, int)
      This mimics BASICs 'STRING$'. Unlike BASIC, which will accept strings
      as second parameters, this routine will only accept one character. My
      experience has shown this is sufficient...

      ENTRY: Parameter 1 - The number of times to repeat.
             Parameter 2 - The character to repeat.
      EXIT : Returns a pointer to the created string.


   int doors_reset(int)
      Resets the terminal, clears screen et cetera.

      ENTRY: Parameter 1 - The port number.
      EXIT : 


   int doors_flush(int)
      Flushes the input and output buffers.

      ENTRY: Parameter 1 - The port number.
      EXIT : 


   int doors_inputflush(int)
      Flushes the input buffer.

      ENTRY: Parameter 1 - The port number.
      EXIT : 


   int doors_outputflush(int)
      Flushes the output buffer.

      ENTRY: Parameter 1 - The port number.
      EXIT : 





Other functions being hand crafted for DoorLib...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   doors_getttypedirect()   [undecided]
      Will attempt a few 'tests' on the terminal itself to read in its
      compatibilities.
      Returns:  0 - TTY compatible, 1 - VT52 compatible, 3 - VT100/ANSI
      compatible. VT100 and ANSI are treated as equal.

   doors_settimeleft()
      Takes an integer number of seconds and updates the users time remaining.

   doors_typearcbbsfile()   [undecided]
      Like 'doors_typetextfile()', this will read in a textfile and dump it to
      the user. This version will be byte-by-byte with simple wrapping. It
      will attempt to parse {ArcBBS} in-line commands, providing sensible
      answers for all the things it cannot read (like number of ArcBBS tasks).
      This is undecided because it'll be a real SOAB to code...



DoorLib NSFAQ:
~~~~~~~~~~~~~~

Q. Why write DoorLib?
A. Because it saved hoiking the same old crap out of past programs. Where this
   is kinda acceptable in BASIC, C offers the facility to link little chunks
   of code into one big lump. So a linkable library made sense!


Q. Do I have to link in the ftp junk and half a million daft routines in order
   to use the doors_txf() function?
A. Nope! Not any longer. See the next question.


Q. What is this weirdness with DoorLib 1.12? It doesn't look like an object
   file!?
A. It isn't. It is a LIBRARY file with several object files inside it. Use the
   !LibFile DDE tool to find out more. In this way all the bits are in one
   lump (nicer for you) and you now link the bits you need, not all of
   DoorLib (nicer for you II - the sequel).


Q. Hacking into DoorLib, I've uncovered bits like "doors_doorlib_identify".
   What are you hiding in here!?
A. Call doors_doorlib_identify() in a door. Pass parameter 1 as the port you
   are using. It does exactly what it says.

   The other hidden things are doors_includeX0 thru doors_includeX5. These
   routines printf() the name of the associated bit (like
   "BUDGIESOFT DOORLIB :: USERDATA"). This should not be called, but is a
   little bit hardcoded into the library files so I can tell whether or not
   the right bits are being linked in.

   The reason why these are not defined in the header file is basically there
   is no point. Nobody is going to call the identify routine, and the others
   aren't designed to be called. Just ignore them. They won't fry your
   harddisc or anything. Link to something and browse in !Zap if you don't
   believe me. :-) :-)


Q. Must I have a poll_the_wimp() function?
A. Yes. You must. Each standard library has different names for this one
   thing, so the easiest answer is to expect a certain function. It isn't
   hard to handle. See TestDoor sources.


