home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / flink11.zip / FrexxLink.doc < prev    next >
Text File  |  1995-09-14  |  78KB  |  2,355 lines

  1.                          FrexxLink Documentation
  2.  
  3.                                   by
  4.  
  5.                              Björn Stenberg
  6.  
  7.                                   for
  8.  
  9.                               Version 1.1
  10.  
  11.  
  12.   COPYRIGHT
  13.  
  14.   FrexxLink is Copyright (C) 1995 Björn Stenberg
  15.  
  16.   Permission to use, copy, and distribute this software and its
  17.   documentation is hereby granted without fee, provided that the above
  18.   copyright notice appear in all copies and that the copyright notice
  19.   and this permission notice appear in supporting documentation.
  20.  
  21.  
  22.   NO WARRANTY
  23.  
  24.     BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
  25.   FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
  26.   OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
  27.   PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
  28.   OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  29.   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
  30.   TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
  31.   PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
  32.   REPAIR OR CORRECTION.
  33.  
  34.     IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  35.   WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
  36.   REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
  37.   INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
  38.   OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
  39.   TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
  40.   YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
  41.   PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
  42.   POSSIBILITY OF SUCH DAMAGES.
  43.  
  44.  
  45.  
  46.   CONTACT INFORMATION
  47.  
  48.   If you wish to contact me, I can be reached at the following addresses:
  49.  
  50.   FidoNet:       2:201/328 (BBS phone: +46-8-6121258 V34,CM)
  51.   AmigaNet:     39:164/102
  52.   Email:        Bjorn.Stenberg@sth.frontec.se
  53.   Paper mail:   Björn Stenberg
  54.                 Birger Jarlsgatan 93 B
  55.                 113 56 Stockholm
  56.             Sweden
  57.  
  58.  
  59.  
  60.   GENERAL DESCRIPTION
  61.  
  62.   FrexxLink is not actually a BBS system in the usual sense. A more accurate
  63.   description is to call it an FPL interpreter with a lot of built-in functions
  64.   useful for BBS system operators.
  65.  
  66.   A FrexxLink BBS system consists of a number of FPL scripts, interpreted by
  67.   FrexxLink. Whatever you want your system to do you must write down in FPL
  68.   files.
  69.  
  70.   I have designed FrexxLink not as the most easy-to-use or -setup system
  71.   available, but instead with ultimate flexibility as my primary goal.
  72.   Therefore, the functions available are pretty low-level and a lot of
  73.   work is required of the sysop/FPL programmer in order to get a fully
  74.   functional BBS system.
  75.   The benefit of this is, of course, that you can make yourself a truly
  76.   unique BBS. It's all up to you.
  77.  
  78.   There are many function calls being mentioned in this text. For a full
  79.   documentation of all functions, see the end of this file.
  80.  
  81.  
  82.  
  83.   EXE/DLL FILE DESCRIPTIONS
  84.  
  85.   FrexxLink.exe   The main exe file, containing all of the BBS specific code
  86.                   except for the Squish stuff.
  87.   BjornEd.exe     A simple full-screen message editor.
  88.   Fwrap.exe       A word-wrap program for wrapping messages into neat quotable
  89.                   text buffers.
  90.   Max2Flink.exe   A multi-purpose conversion utility, able to convert the
  91.                   Maximus/2 2.x USER.BBS file, the FILES.BBS files and to 
  92.                   create sample message and file area arrays from Max's 
  93.                   FILEAREA.CTL and MSGAREA.CTL files.
  94.   FPL.DLL         Frexx Programming Language. The FPL interpreter by Daniel 
  95.                   Stenberg.
  96.   DDE4SBS.DLL     The shared Standard C library for IBMs C/Set compiler. Used
  97.                   by FrexxLink, BjornEd and Fwrap to keep their exe size down.
  98.   MSGAPI32.DLL    The Squish message base API by Scott Dudley. Routines for
  99.                   handling most of the message area stuff.
  100.   P.DLL           A protocol stack by Jyrki Salmi for Z- ,X- and Ymodem etc.
  101.   P.exe           Frontend for P.DLL. I like this better than using P.DLL
  102.                   directly from within the FrexxLink executable. It allows
  103.                   you to use something completely different, should you want
  104.                   to.
  105.  
  106.  
  107.  
  108.   THE TALE OF CREATION
  109.  
  110.   The first script controlled BBS I used was a system called WOP, created
  111.   by Magnus Nilsbo. It was a pretty "normal" system, but it had more advanced
  112.   screen codes than many other systems. It also allowed conditional
  113.   execution based on arbitrary variables, which was way more than anything
  114.   else I'd seen BBS software do (this was around 1988-89, I think). I used
  115.   it passionately for some years but when I changed to OS/2 in the beginning
  116.   of the 90's, I really didn't want to run a DOS system for my BBS. So I did
  117.   like everyone else, I ran the only thing available: Maximus/2. Now don't
  118.   get me wrong, Max is not a bad system. But it's a real bore when you're
  119.   used to WOP like I was.
  120.  
  121.   In the meantime, my brother Daniel was starting to develop this text editor
  122.   for the Amiga, called FrexxEd, with some friends. They wanted something
  123.   more powerful than ARexx to control the editor, something like the GNU Emacs
  124.   LISP system, only more modern. It quickly became obvious that C was the
  125.   best language to use, simply because no other language is better known
  126.   throughout the computer world. So Daniel started programming a script
  127.   interpreter based on the C syntax and semantics, calling it the 'Frexx
  128.   Programming Language', or FPL. In the beginning there were quite a lot of
  129.   differences between FPL and C, but over the years FPL has adapted more and
  130.   more of the 'real' C language. Today I'd say it is pretty close to the real
  131.   thing.
  132.  
  133.   In the end of 1993, I was getting increasingly irritated by the feeling of
  134.   having my arms tied behind my back by Maximus. The idea of creating my
  135.   own system, using Daniel's FPL interpreter, started to form in my mind.
  136.   I philosiphied a lot about it and Daniel and I talked quite a bit about
  137.   how the system 'ought' to be. Finally, in the spring of 1994, I sat down
  138.   and started to hack out the basics of the system. I ported FPL (done in
  139.   a few minutes, that piece of code is one heck of a portable thing!) and
  140.   set it up, I created the user file system and a lot of the basic function
  141.   calls like getstring(), printf() and the support system for different
  142.   character sets (which was something WOP had and I really really missed in
  143.   Maximus), the file description field system and some other things.
  144.  
  145.   Then I started to look into the Squish API (because I didn't want to have
  146.   to make my own tosser, scanner etc) and that was when I ran into this
  147.   huge brick wall. I somehow never managed to get the 16-bit MSGAPI working
  148.   properly with the rest of my 32-bit code. I worked for weeks, but eventually
  149.   I ran out of ideas and found that I COULD NOT make it work.
  150.   So the summer of 1994 became a summer of much sun and little code for me.
  151.   I simply gave up, having tried everything I could think of and having asked
  152.   everyone I could imagine having a clue. I put the whole thing on ice.
  153.  
  154.   Some months later (I don't know exactly when) Scott (the author of Squish)
  155.   released a 32-bit version of the MSGAPI.DLL. I was quite put off by my
  156.   previous poor experience with the thing, though, so I didn't try it out
  157.   until around christmas time 1994. It was with extreme delight I found my
  158.   test code was actually working with the new DLL.
  159.  
  160.   That was when FrexxLink really started to take form. I sat, nights at an
  161.   end, programming. I had spent months that autumn, thinking how I would
  162.   want the system to be "if just that **** API code would work for me". Now
  163.   that it did work, I had merely to convert all my ideas and strategies into
  164.   code and FPL scripts.
  165.   I started with making a carbon-copy of the Maximus system I had running,
  166.   so I'd know I had all the basic functionality and to make sure I didn't
  167.   forget anything vital. That was completed in the middle of February '95
  168.   and after some extra tuning and (a lot of) FPL script hacking I finally
  169.   converted my Maximus USER.BBS to FrexxLink user files on March 10, 1995.
  170.   From that date on, I'm quite proud to say, FrexxLink has been running
  171.   around the clock on my two-node system.
  172.  
  173.  
  174.  
  175.   FILES and DIRECTORIES
  176.  
  177.   FrexxLink never changes it's current directory. Therefore, all references to
  178.   files and directories can always depend on the current directory being
  179.   where FrexxLink was originally started.
  180.  
  181.   Here are descriptions of some notable files and directories used by
  182.   FrexxLink:
  183.  
  184.   Users/ (directory)
  185.         This is where all the user files are stored. Each file in this
  186.         directory contains the information for one user.
  187.  
  188.   Users/xxxxx xxxxx (files)
  189.         The user files are (as all FrexxLink files) simple text files, editable
  190.         with any normal text editor. The file has the name of the user whose
  191.         data is stored within the file. (i.e. user "Max Headroom" is stored in
  192.         the file "Users/Max Headroom")
  193.         Each line in a user file contains a variable, with the name of the
  194.         variable as the first word and the value as the rest of the line, in
  195.         the following format:
  196.         "Password       thisisme,reallyreally"
  197.         Meaning that the string 'thisisme,reallyreally' is stored in a
  198.         variable called 'Password'. The variable name cannot contain spaces
  199.         or tabs, since those are used as delimiters.
  200.  
  201.   MsgMap/ (directory)
  202.         This directory stores the message maps of all users. Each file in this
  203.         directory contains the message maps of one user. The file has the
  204.         same name as the user whose data it contains.
  205.  
  206.   MsgMap/Xxxxx Xxxxxx (files)
  207.         This file contains a number of lines, one line for each message area
  208.         the user has read messages in. The line consists of the area
  209.         tag, a colon, and a list of the unique message id numbers of
  210.         the messages in that area that have been read.
  211.         Example:
  212.         ----
  213.         FREXXLINK:2983,2999-3100,3123
  214.         *LOCALCHAT:202-302,305,308,312
  215.         ----
  216.         This file is loaded the first time a gotomarea() call is issued. It is
  217.         created (and updated) each time the user leaves FrexxLink. It can also
  218.         be updated at an earlier time by the calling the savemsgmap() function.
  219.  
  220.         The asterix (*) first on the line means that the user is a member of
  221.         the area.
  222.  
  223.   .Files (file)
  224.         This is the file description list for a file area. Actually, this name
  225.         is not defined anywhere in FrexxLink, it's just the one I chose for 
  226.         the BBS I'm sending with the package as an example. You may call it 
  227.         anything you like.
  228.         The description file contains one line for each file in the area, as 
  229.         this example shows:
  230.         ---
  231.         Filename for the masses.txt,UL:John Doe,DL:23,TX:Neat text thingy!
  232.         FrexxLink.Zip,UL:Björn Stenberg,DA:19980923,TX:FrexxLink, VR version.
  233.         ---
  234.         Every line is divided into several 'fields'. A field consists of a
  235.         two-character identifier, a colon, a string and a trailing comma. Ex:
  236.         'UL:Björn Stenberg,'. A field can therefore never contain a comma sign.
  237.         The maximum line length is defined by your system memory.
  238.  
  239.         A few field identifiers are hard-coded into FrexxLink:
  240.         'TX:' is the file description displayed in file lists. This field
  241.               must exist on all files in the file list or an error will occur.
  242.               It may be empty, but it must exist.
  243.         'DA:' is an optional field specifying the file date in the format
  244.               'YYYYMMDD' (ex: '19950502' for 2 May 1995). If this field
  245.               exists, it will override the file's creation date stamp as the
  246.               date showed in the file lists. Also, if this field exists,
  247.               newscan() will not have to examine the disk file for it's file
  248.               date, thus speeding up the search for new files substantially.
  249.  
  250.         There are some exceptions to the file field rules, however:
  251.          * To save some space, the filename field has no identifier and no 
  252.            colon. Instead it must always be the FIRST field on a line.
  253.          * The 'TX:' field CAN contain comma signs, to allow file descriptions
  254.            containing pretty much anything. To enable this, the TX field must
  255.            always be the LAST field on every line. This means that everything
  256.            put after the 'TX:' is considered part of the file description.
  257.  
  258.         Empty lines and lines beginning with a whitespace character are
  259.         displayed as they are, with no parsing or interpretation whatsoever.
  260.  
  261.         In addition to those hard-coded fields above, I use some fields in
  262.         my enclosed example BBS. These are just my choices and nothing
  263.         enforced by FrexxLink. You may do however you like with these:
  264.         'DL:' is the number of times the file has been downloaded.
  265.         'UL:' is the name of the user who uploaded the file.
  266.  
  267.   FplErr.log (file)
  268.         This file is created in the current directory whenever FrexxLink
  269.         encounters a FPL script error. It is a simple log file, containing
  270.         one error per line. If the file already exists when an error occurs,
  271.         FrexxLink simply appends the new error line to the existing file.
  272.  
  273.         Lines with an asterix (*) between the time and the log message means
  274.         the the error occured when running in "safe" mode.
  275.  
  276.   Several other files and directories are used by the enclosed example BBS
  277.   system. However those are not required or at all known of by FrexxLink but
  278.   are used by the FPL code. Examples are the Signatures/ directory,
  279.   containing up to five signatures per user, or the OneLiners/ directory,
  280.   containing one-line logon notes between users.
  281.  
  282.  
  283.  
  284.   CHARACTER SETS
  285.  
  286.   (This section is mainly aimed at non-english speaking countries like
  287.    Sweden which has several major charsets for their national characters.)
  288.  
  289.   FrexxLink has internal support for four separate character sets. They are
  290.   ISO 8859-1, IBM CodePage 437, IBM CodePage 850 and SIS-11 (7-bit ASCII
  291.   with Swedish national chars where {[]}\| is).
  292.   FrexxLink assumes all local data (FPL scripts, file descriptions etc.) are
  293.   stored in CodePage 850. The reason for this is that CP850 contains all
  294.   characters found in ISO 8859-1, only in scrambled order. Therefore CP850 is
  295.   able to contain without distortion all ISO 8859-1 chars. And since ISO
  296.   is the world-wide standard, that is not an altogether bad thing.
  297.   This means that you must enter all text in FPL scripts and file descriptions
  298.   as CP850 if you want your users to be able to read it properly after
  299.   charset conversion.
  300.  
  301.   To cope with the problem of users with different charsets, you can set up
  302.   FrexxLink to convert the user input and output. Also, you can alter
  303.   FrexxLink's CP850 assumptions a bit, for example when you wish to display
  304.   a message or a text file with another character set. Both these conversion
  305.   settings are done with the charset() function call.
  306.   FrexxLink also supplies a translate() function, allowing translation of
  307.   strings from one charset to another.
  308.  
  309.  
  310.  
  311.   USER SYSTEM
  312.  
  313.   FrexxLink keeps data of one user in memory at a time. To load the user into
  314.   memory, you use the loaduser() function. After that, you can access the
  315.   user data with the functions getuservar() and setuservar(). To save any
  316.   altered information or new user variables into the user file, use the
  317.   saveuser() function.
  318.   The first time a new user logs on, there is no file to load with his data
  319.   in. In that case, clear the internal buffers using the inituser() function
  320.   before starting to add variables.
  321.  
  322.  
  323.  
  324.   FILE AREA SYSTEM
  325.  
  326.   FrexxLink remembers only one file area at a time. You tell FrexxLink where
  327.   the current areas file list is and what it's called, plus you tell it in 
  328.   what directory the actual files can be found. For this, you use the 
  329.   gotofarea() function call.
  330.   After you've defined where the current area is, you can list all or a
  331.   subset of the files using the filelist() function, you can search for
  332.   files by date, using newfiles(), you can alter and read file fields, using
  333.   setffield() and getffield(), you can remove a file from the file list,
  334.   using fkill(), move a file to another list, using fmove() and so on.
  335.   When you want to change file area, you simply issue another gotofarea()
  336.   call.
  337.  
  338.   The upload/download system in the examle system depends on the protocol
  339.   handler creating a log file in DSZ format. A dszfield() function is
  340.   supplied by FrexxLink to facilitate the interpretation of such log files.
  341.  
  342.   All files listed, either using filelist() or newfiles() get a file tag,
  343.   a number from 1 to 99. For each file listed, the tag is increased one step.
  344.   At 99, the number starts at 1 again and continues upwards.
  345.   The idea with this system is that the last 99 files listed by the user
  346.   can always be accessed by a number rather than having to enter the full
  347.   filename. You obtain what file a specific tag represents to by using the
  348.   getftag() function. If you wish to reset the tag counter to 1 (I like to do
  349.   that at the start of a new list, for example), use the clrftags() function.
  350.  
  351.  
  352.  
  353.   MESSAGE SYSTEM
  354.  
  355.   Currently, only the Squish message format is supported. JAM is suggested
  356.   and will probably be implemented sometime soon.
  357.  
  358.   The message system concept is just like with the file areas. FrexxLink
  359.   knows of one message area, set with gotomarea(). The difference is that
  360.   with the message area, you tell FrexxLink the Squish base name for the
  361.   area and the tagname for it. Note now that ALL areas in a FrexxLink system
  362.   must have a tagname, including local and netmail areas. The reason for
  363.   this is that the tagname is used in the MsgMap files to identify the area.
  364.   Without a tag, FrexxLink would be unable to remember what messages has
  365.   been read in what areas.
  366.  
  367.   The getmarea() function obtains information about the area, such as the
  368.   number of messages etc. Message areas always start with message #1.
  369.  
  370.   The getmsg() function obtains part of a message, such as the subject, body
  371.   text, creation date etc. Using this function with printf() and printmsg()
  372.   (which displays a message body, wrapped and with coloured quotes) will
  373.   allow you to read messages.
  374.  
  375.   The messages in Squish areas are stored in the order of tossing. However,
  376.   using MSGID/REPLY linking, there is the possibility of linking message
  377.   threads together to achieve threaded reading. The nextmsg() function is
  378.   used to locate messages in thread order.
  379.  
  380.   FrexxLink keeps a message map of each area, consisting of one flag for
  381.   every message in the area. This map is used to find out exactly which
  382.   messages the user has read and which are still unread. The function
  383.   markmsg() is used to modify this map and savemsgmap() can be used to store
  384.   all the message maps to disk. If you do not use the savemsgmap() function,
  385.   or if any message map is modified after your last savemsgmap() call,
  386.   FrexxLink will save the message map file when exiting.
  387.   In order to know the filename of the MsgMap file to read and write, you
  388.   must supply the username (or whatever filename you wish to use) in the
  389.   setuid() function before entering any message areas.
  390.  
  391.   A concept of area membership is supported by FrexxLink. The function
  392.   msgmember() is used both to set and check area membership.
  393.  
  394.   Creating messages is one major thing about BBSing. The FrexxLink way of
  395.   doing this is to first clear the internal message buffer using createmsg().
  396.   After that, you add parts of the message using putmsg() and putmsgflag()
  397.   until you are satisfied, at which point you call sendmsg() to write the
  398.   message to the Squish area. If you at any point wish to abort the message
  399.   or start again, simply call the createmsg() function again and the buffer
  400.   will be cleared. delmsg() removes a written message from the area.
  401.   Currently, there are no functions for modifying an existing message. I
  402.   intend to implement that soon, though.
  403.  
  404.   One of the message parts you may wish to put into the messages you send
  405.   is the "control" part, containing kludges like MSGID and such. The only
  406.   control information created by FrexxLink is a PID kludge, looking like
  407.   "\1PID: FrexxLink X.X", where X.X is the current version. All other
  408.   kludges you wish your system to send, you must put into the message
  409.   yourself using 'putmsg("control",kludges)'.
  410.   One of the more useful kludges is the MSGID kludge. It requires a uniqe
  411.   number from the originating system. Therefore, a msgid() function is
  412.   supplied by FrexxLink.
  413.  
  414.  
  415.  
  416.   EXCEPTION HANDLING
  417.  
  418.   There are some special occations that do not follow the normal flow of
  419.   execution in the FPL files. These are handled using "callback functions"
  420.   which basically are small FPL programs stored in FrexxLink for usage when
  421.   required.
  422.   Currently, two such exceptions exist. They are the more prompt at the end
  423.   of the screen and something called the timeleft function, which is called
  424.   every minute to let you check the user's time status and warn him, kick him
  425.   out or whatever you wish to do. For the user time, a function called
  426.   setusertime() makes life a little easier.
  427.  
  428.  
  429.  
  430.   FUNCTION REFERENCE
  431.  
  432. ==============================================================================
  433.                              FPL Functions
  434. ==============================================================================
  435.    FPL contains a number of internal functions that FrexxLink has no doing
  436.    with, such as the strcmp(), the substr(), strstr() and so on. These
  437.    functions are fully described in the FPLUser.doc document.
  438.  
  439. ==============================================================================
  440.                             System Variables
  441. ==============================================================================
  442.  
  443.  NAME
  444.     errno -- standard error variable
  445.  
  446.  TYPE
  447.     int
  448.  
  449.  DESCRIPTION
  450.     Holds the current error code. The possible error codes are:
  451.        0   No error. All is fine.
  452.       -1   The user provided no input to a getstring() or getint() prompt,
  453.            but hit enter right away.
  454.       -2   A file related function failed to locate a requested file.
  455.  
  456. ------------------------------------------------------------------------------
  457.  
  458.  NAME
  459.     sys_local -- is this a local logon?
  460.  
  461.  TYPE
  462.     int
  463.  
  464.  DESCRIPTION
  465.     Contains 1 if the current process is local only, or 0 if the serial
  466.     communication is active.
  467.  
  468. ------------------------------------------------------------------------------
  469.  
  470.  NAME
  471.     sys_comhandle -- what com handle is in use?
  472.  
  473.  TYPE
  474.     int
  475.  
  476.  DESCRIPTION
  477.     Holds the currently used com port handle.
  478.  
  479. ------------------------------------------------------------------------------
  480.  
  481.  NAME
  482.     sys_timeleft -- how much time is there left?
  483.  
  484.  TYPE
  485.     int
  486.  
  487.  DESCRIPTION
  488.     Holds the number of seconds until the user time is up.
  489.  
  490.  SEE ALSO
  491.     setusertime()
  492.  
  493. ------------------------------------------------------------------------------
  494.  
  495.  NAME
  496.     sys_version -- the version number of FrexxLink
  497.  
  498.  TYPE
  499.     string
  500.  
  501.  DESCRIPTION
  502.     Holds the version number of the FrexxLink being run. The string is in
  503.     format "version.revision", ex "1.0".
  504.  
  505.  
  506. ------------------------------------------------------------------------------
  507.  
  508.  NAME
  509.     fpl_version -- the version number of FPL.DLL
  510.  
  511.  TYPE
  512.     string
  513.  
  514.  DESCRIPTION
  515.     Holds the version number of the FPL.DLL being used. The string is in
  516.     format "version.revision", ex "13.2".
  517.  
  518. ------------------------------------------------------------------------------
  519.  
  520.  NAME
  521.     sys_safemode -- are we running in "safe" mode?
  522.  
  523.  TYPE
  524.     int
  525.  
  526.  DESCRIPTION
  527.     Contains 1 if running in "safe" mode, or 0 if running in normal mode.
  528.  
  529.  SEE ALSO
  530.     runsafe()
  531.  
  532. ==============================================================================
  533.                           Programming Functions
  534. ==============================================================================
  535.  
  536.  NAME
  537.     getstring -- Retreive a string from user
  538.  
  539.  SYNTAX
  540.     string getstring( [ string Prompt ], [ int Display ] );
  541.  
  542.  DESCRIPTION
  543.     Retrieves a string from the user, allowing primitive command line
  544.     editing using BACKSPACE.
  545.  
  546.  PARAMETERS
  547.     If Prompt is supplied, it will be displayed before the user can enter any
  548.     input.
  549.  
  550.     If Display is supplied, it controls what will be echoed back from the
  551.     user's keypresses. A value of 0 will inhibit any echoing. A value of
  552.     -1 will echo the actual input characters and any other value will be
  553.     used as the echo eharacter. If the Display parameter is omitted, -1 is
  554.     assumed.
  555.  
  556.     You cannot supply Display without also supplying Prompt. If you wish
  557.     to alter the display mode without displaying a prompt, use "" for the
  558.     Prompt parameter.
  559.  
  560.  RETURNS
  561.     The string entered by the user. If the user entered nothing, errno will
  562.     be set to -1.
  563.  
  564.  SEE ALSO
  565.     getint(), getchar(), getkey()
  566.  
  567. ------------------------------------------------------------------------------
  568.  
  569.  NAME
  570.     getint -- Retreive an integer from user
  571.  
  572.  SYNTAX
  573.     int getint( [ string Prompt ], [ int Display ] );
  574.  
  575.  DESCRIPTION
  576.     Retrieves an integer from the user, allowing primitive command line
  577.     editing using BACKSPACE.
  578.  
  579.  PARAMETERS
  580.     If Prompt is supplied, it will be printed before the user can enter
  581.     anything.
  582.  
  583.     If Display is supplied, it controls what will be echoed back from the
  584.     user's keypresses. A value of 0 will inhibit any echoing. A value of
  585.     -1 will echo the actual input characters and any other value will be
  586.     used as the echo eharacter. If the Display parameter is omitted, -1 is
  587.     assumed.
  588.  
  589.  RETURNS
  590.     The integer entered by the user. If the user entered nothing, errno will
  591.     be set to -1.
  592.  
  593.  SEE ALSO
  594.     getstring(), getchar(), getkey()
  595.  
  596. ------------------------------------------------------------------------------
  597.  
  598.  NAME
  599.     getchar -- Retreive a character from user
  600.  
  601.  SYNTAX
  602.     int getchar( [ string Prompt ], [ int Display ] );
  603.  
  604.  DESCRIPTION
  605.     Retrieves a character from the user.
  606.  
  607.  PARAMETERS
  608.     If Prompt is supplied, it will be printed before the user can enter
  609.     anything.
  610.  
  611.     If Display is supplied, it controls what will be echoed back from the
  612.     user's keypresses. A value of 0 will inhibit any echoing. A value of
  613.     -1 will echo the actual input characters and any other value will be
  614.     used as the echo eharacter. If the Display parameter is omitted, -1 is
  615.     assumed.
  616.  
  617.  RETURNS
  618.     The value of the character pressed by the user.
  619.  
  620.  SEE ALSO
  621.     getstring(), getint(), getkey()
  622.  
  623. ------------------------------------------------------------------------------
  624.  
  625.  NAME
  626.     getkey -- Retreive a character from the input queue
  627.  
  628.  SYNTAX
  629.     int getkey( void );
  630.  
  631.  DESCRIPTION
  632.     Retrieves a character from the input queue without waiting for input.
  633.  
  634.  RETURNS
  635.     The first character in the input queue, or -1 if the input queue is empty.
  636.  
  637.  SEE ALSO
  638.     getstring(), getint(), getchar()
  639.  
  640. ------------------------------------------------------------------------------
  641.  
  642.  NAME
  643.     loadstring -- load a text file into a string
  644.  
  645.  SYNTAX
  646.     string loadstring( string File );
  647.  
  648.  PARAMETERS
  649.     File must be a fully qualified filename, reachable and readable by the
  650.     current process.
  651.  
  652.  SAFE MODE
  653.     In "safe" mode, any path specified in the filename is ignored. The file is
  654.     loaded from the directory specified by runsafe().
  655.  
  656.  RETURNS
  657.     The created string. If the file could not be found, the string is set
  658.     to "" and errno is set to -2.
  659.  
  660.  SEE ALSO
  661.     savestring()
  662.  
  663. ------------------------------------------------------------------------------
  664.  
  665.  NAME
  666.     savestring -- save a string as a text file
  667.  
  668.  SYNTAX
  669.     void savestring( string String, string File [, int Mode] );
  670.  
  671.  PARAMETERS
  672.     String  is the string to be written
  673.     File    must be a fully qualified filename, reachable and writable by the
  674.             current process.
  675.     Mode    is the "write mode", which is:
  676.             0 for normal, nonfiltered writing, which is the default
  677.             1 for "message filter mode", which does two things:
  678.               a) Replaces all LF chars with SPACE (0x20)
  679.               b) Truncates the message at the first occurence of "SEEN-BY: "
  680.  
  681.  SAFE MODE
  682.     In "safe" mode, any path specified in the filename is ignored. The file is
  683.     saved to the directory specified by runsafe().
  684.  
  685.   NOTES
  686.     If String is 0 bytes long, the File is removed.
  687.  
  688.   SEE ALSO
  689.     loadstring(), fappend(), fprepend()
  690.  
  691. ------------------------------------------------------------------------------
  692.  
  693.  NAME
  694.     loadarray -- load a text file into an array of strings, one string per line
  695.  
  696.  SYNTAX
  697.     int loadarray( string File, string& Array[] );
  698.  
  699.  PARAMETERS
  700.     File     must be a fully qualified filename, reachable and readable by the
  701.              current process.
  702.     Array    must be a reference to a string array. The size of the array does
  703.              not matter, since FrexxLink will expand the array enough to hold
  704.              the file. 
  705.  
  706.  SAFE MODE
  707.     In "safe" mode, any path specified in the filename is ignored. The file is
  708.     loaded from the directory specified by runsafe().
  709.  
  710.  RETURNS
  711.     The size (number of elements) of the expanded string array, or -1 if the
  712.     file was not found.
  713.  
  714.  SEE ALSO
  715.     loadstring()
  716.  
  717. ------------------------------------------------------------------------------
  718.  
  719.  NAME
  720.     savearray -- save am array of strings as a text file
  721.  
  722.  SYNTAX
  723.     void savearray( string& Array[], string File, [ int Elements ] );
  724.  
  725.  PARAMETERS
  726.     Array    is a reference to an array of strings to be saved
  727.     File     must be a fully qualified filename, reachable and writable by the
  728.              current process.
  729.     Elements is an optional number of elements to write. If this parameter is
  730.              omitted, all elements in the array are written.
  731.  
  732.  SAFE MODE
  733.     In "safe" mode, any path specified in the filename is ignored. The file is
  734.     saved to the directory specified by runsafe().
  735.  
  736.   SEE ALSO
  737.     loadarray(), savestring(), loadstring(), fappend(), fprepend()
  738.  
  739. ------------------------------------------------------------------------------
  740.  
  741.  NAME
  742.     toupper -- Convert a character to uppercase
  743.  
  744.  SYNTAX
  745.     int toupper( int Char );
  746.  
  747.  DESCRIPTION
  748.     Converts a character to uppercase. If Char is not a letter, no change
  749.     will be made. Unlike the standard C equivalence, this function also
  750.     converts 8-bit local characters properly.
  751.  
  752.  RETURNS
  753.     The value of the converted character.
  754.  
  755. ------------------------------------------------------------------------------
  756.  
  757.  NAME
  758.     runfile -- Executes an FPL file.
  759.  
  760.  SYNTAX
  761.     void runfile( string Filename );
  762.  
  763.  DESCRIPTION
  764.     Executes an FPL file.
  765.  
  766.  RETURNS
  767.     Nothing
  768.  
  769.  SEE ALSO
  770.     runsafe()
  771.  
  772. ------------------------------------------------------------------------------
  773.  
  774.  NAME
  775.     runsafe -- Executes an FPL file in "safe" mode.
  776.  
  777.  SYNTAX
  778.     void runsafe( string Filename, string UserPath );
  779.  
  780.  DESCRIPTION
  781.     Executes an FPL file with all potentially "dangerous" functions disabled
  782.     in the FPL interpreter. Calling the disabled functions is still possible,
  783.     but the functions will not do anything.
  784.  
  785.     Disabled functions are:
  786.     fappend, fprepend, ffindfirst, ffindnext, fmove, fkill, fdelete, frename, 
  787.     getffield, setffield, gotofarea, newfiles, filelist, typefile, dszfield,
  788.     inituser, loaduser, saveuser, setuservar, setsysvar, setuid, runfile, 
  789.     runsafe, setfunc, gotomarea, getmarea, delmsg, getmsg, printmsg, nextmsg, 
  790.     savemsgmap, msgmember, markmsg, createmsg, sendmsg, putmsgflag,
  791.     getmsgflag, setmareasize, putmsg, setusertime, settimeout, charset, 
  792.     system, bye
  793.  
  794.     In addition to these disabled functions, some functions are functionally
  795.     limited when called in "safe" mode.
  796.  
  797.     UserPath is where all calls to load/savestring and load/savearray will
  798.     read/write their files. It should be a fully qualified path WITHOUT
  799.     trailing backslash.
  800.  
  801.  RETURNS
  802.     Nothing
  803.  
  804.  SEE ALSO
  805.     runfile(), sys_safemode
  806.  
  807. ------------------------------------------------------------------------------
  808.  
  809.  NAME
  810.     printf -- formatted output
  811.  
  812.  SYNTAX
  813.     void printf( string Format, [ ... ] );
  814.  
  815.  DESCRIPTION
  816.     printf() produces formatted output. It behaves pretty much exactly like
  817.     the C printf() function, except that floating point numbers aren't
  818.     supported. (This description is not complete, but just explains the
  819.     basic aspects of printf().)
  820.  
  821.     To take it short, printf() checks the Format string for percent signs
  822.     (%). Everywhere there's a % char, printf will output something special.
  823.     What, and how to output it depends on the characters immediately
  824.     following the %:
  825.  
  826.     %d   print an integer in base 10
  827.     %s   print a string
  828.     %x   print an integer in base 16 (hexadecimal)
  829.     %%   print a percent sign
  830.  
  831.     Also, there are some flags and parameters that can be used to define how
  832.     to format the field:
  833.  
  834.     %5s  print the string to at least 5 characters length. If the string is
  835.          shorter, the output will be padded with space to the left of the
  836.          string. (right justified)
  837.     %-5s same as above, but put the padding spaces to the right of the string.
  838.          (left justified)
  839.     %5d  print an integer to at least 5 characters length, left justified
  840.     %05d print an integer to at least 5 characters length, right justified
  841.          but padded with zeros instead of spaces.
  842.  
  843.     Example: printf( "%d %s were printed at %02d:%02d\n",5,"dots",10,3)
  844.     will output the string '5 dots were printed at 10:03\n'.
  845.  
  846.  RETURNS
  847.     1 if a MorePrompt() was answered negatively, i.e the user wants the output
  848.     to stop. 0 in all other cases.
  849.  
  850.  SEE ALSO
  851.     lprintf(), sprintf()
  852.  
  853. ------------------------------------------------------------------------------
  854.  
  855.  NAME
  856.     lprintf -- local formatted output
  857.  
  858.  SYNTAX
  859.     void printf( string Format, [ ... ] );
  860.  
  861.  DESCRIPTION
  862.     lprintf() produces formatted output on the local console only. It works
  863.     just like printf() in all other aspects.
  864.  
  865.  RETURNS
  866.     Nothing
  867.  
  868.  SEE ALSO
  869.     printf(), sprintf()
  870.  
  871. ------------------------------------------------------------------------------
  872.  
  873.  NAME
  874.     sprintf -- formatted string
  875.  
  876.  SYNTAX
  877.     string sprintf( string Format, [ ... ] );
  878.  
  879.  DESCRIPTION
  880.     sprintf() is exactly like printf(), except that it returns the
  881.     resulting string to FPL instead of displaying it on the user screen.
  882.  
  883.  RETURNS
  884.     The created string
  885.  
  886.  SEE ALSO
  887.     printf(), lprintf()
  888.  
  889. ------------------------------------------------------------------------------
  890.  NAME
  891.     setfunc -- set system function
  892.  
  893.  SYNTAX
  894.     void setfunc( string FuncId, string Code );
  895.  
  896.  DESCRIPTION
  897.     Defines the action of the predefined system functions
  898.  
  899.  PARAMETERS
  900.     FuncId is one of the following functions:
  901.        "moreprompt"  When the screen is filled with scrolling text, a "More?
  902.                      (Y/n)" prompt is generally appreciated by the average
  903.                      user. This function defines what that prompt should do.
  904.  
  905.        "timeleft"    is called once every minute. Use it to keep track of the
  906.                      user's time, warn him when it's running short and to
  907.                      kick him out when time is up etc.
  908.  
  909.     Code   is a complete FPL statement to execute as the function. It is
  910.            recommended to use a function call here, rather than a complicated
  911.            routine.
  912.  
  913.     IMPORTANT: All functions called from within these system FPL functions
  914.     must be 'export' declared!
  915.  
  916.  RETURNS
  917.     Nothing
  918.  
  919.  SEE ALSO
  920.     sys_timeleft, screenlen()
  921.  
  922. ------------------------------------------------------------------------------
  923.  
  924.  NAME
  925.     clear -- clear line counter
  926.  
  927.  SYNTAX
  928.     void clear( [ int ClearScreen ] );
  929.  
  930.  DESCRIPTION
  931.     In order to know when to execute the more prompt, a line counter is
  932.     maintained internally by FrexxLink. This function clears that counter,
  933.     so that it will take a screenfull of lines to trigger the more prompt
  934.     again.
  935.  
  936.  PARAMETERS
  937.     If ClearScreen is 1, the screen clear escape code will be sent.
  938.  
  939.  RETURNS
  940.     Nothing
  941.  
  942.  SEE ALSO
  943.     screenlen(), setfunc()
  944.  
  945. ------------------------------------------------------------------------------
  946.  
  947.  NAME
  948.     colour -- obtain the escape sequence to change text color
  949.  
  950.  SYNTAX
  951.     string colour( string Colour );
  952.  
  953.  DESCRIPTION
  954.     Returns the ANSI standard escape sequence needed to change the text colour.
  955.  
  956.  PARAMETERS
  957.     Colour   A string describing which colour is desired. The string must be
  958.              one of the following (case insensitive): black, red, green,
  959.              brown, blue, magenta, cyan, gray, dgray, lred, lgreen, yellow,
  960.              lblue, lmagenta, lcyan, white.
  961.              The 'l' in 'lblue' etc means light and the 'd' in 'dgray' means 
  962.              dark.
  963.  
  964.  RETURNS
  965.     The escape sequence
  966.  
  967.  SEE ALSO
  968.     gotoxy()
  969.  
  970. ------------------------------------------------------------------------------
  971.  
  972.  NAME
  973.     gotoxy -- position cursor on the screen
  974.  
  975.  SYNTAX
  976.     void gotoxy( int Xpos, int Ypos );
  977.  
  978.  DESCRIPTION
  979.     Sends the ANSI standard escape sequence to position the cursor on screen.
  980.  
  981.  PARAMETERS
  982.     Xpos   the column on which the cursor is desired. The leftmost column on
  983.            the screen is number 0.
  984.     Ypos   the line on which the cursor is desired. The topmost line on the
  985.            screen is number 0.
  986.  
  987.  RETURNS
  988.     Nothing
  989.  
  990.  SEE ALSO
  991.     colour()
  992.  
  993. ------------------------------------------------------------------------------
  994.  
  995.  NAME
  996.     system -- execute external command
  997.  
  998.  SYNTAX
  999.     int system( string CmdLine );
  1000.  
  1001.  DESCRIPTION
  1002.     Executes an external command such as an editor, protocol handler etc.
  1003.  
  1004.  PARAMETERS
  1005.     CmdLine is the command line to be executed.
  1006.  
  1007.  RETURNS
  1008.     The returncode of the executed command
  1009.  
  1010. ------------------------------------------------------------------------------
  1011.  
  1012.  NAME
  1013.     translate -- translate string from one charset to another
  1014.  
  1015.  SYNTAX
  1016.     string translate( string Str, int FromSet, int ToSet );
  1017.  
  1018.  PARAMETERS
  1019.     Str     is the string to be translated
  1020.     FromSet is the charset to convert from
  1021.     ToSet   is the charset to convert to
  1022.               1 = CodePage 850
  1023.               2 = CodePage 437
  1024.               3 = ISO 8859-1
  1025.               4 = Swedish ASCII
  1026.  
  1027.  RETURNS
  1028.     The translated string
  1029.  
  1030.  SEE ALSO
  1031.     charset()
  1032.  
  1033. ------------------------------------------------------------------------------
  1034.  
  1035.  NAME
  1036.     fappend -- append string to a file
  1037.  
  1038.  SYNTAX
  1039.     void fappend( string File, string Str );
  1040.  
  1041.  DESCRIPTION
  1042.     Appends a string to a file. It does not add a newline to the string,
  1043.     so if you want one you must include it in the string.
  1044.  
  1045.  PARAMETERS
  1046.     File    the path+name of the file to modify
  1047.     Str     the string to append to the file
  1048.  
  1049.  RETURNS
  1050.     Nothing
  1051.  
  1052.  SEE ALSO
  1053.     savestring(), fprepend()
  1054.  
  1055. ------------------------------------------------------------------------------
  1056.  
  1057.  NAME
  1058.     fprepend -- prepend string to a file
  1059.  
  1060.  SYNTAX
  1061.     void fprepend( string File, string Str );
  1062.  
  1063.  DESCRIPTION
  1064.     Prepends a string to a file. I.e it works just like fappend() only it
  1065.     puts the line at the top of the file instead of at the bottom.
  1066.  
  1067.  PARAMETERS
  1068.     File    the path+name of the file to modify
  1069.     Str     the string to append to the file
  1070.  
  1071.  RETURNS
  1072.     Nothing
  1073.  
  1074.  SEE ALSO
  1075.     savestring(), fappend()
  1076.  
  1077. ------------------------------------------------------------------------------
  1078.  
  1079.  NAME
  1080.     fexists -- check if a file exists
  1081.  
  1082.  SYNTAX
  1083.     int fexists( string File );
  1084.  
  1085.  PARAMETERS
  1086.     File the filename to look for.
  1087.  
  1088.  RETURNS
  1089.     1 if the file exists. 0 if it doesn't.
  1090.  
  1091. ------------------------------------------------------------------------------
  1092.  
  1093.  NAME
  1094.     ffindfirst -- find the first directory entry matching a pattern
  1095.  
  1096.  SYNTAX
  1097.     string ffindfirst( string Pattern, [ string Attribs ] );
  1098.  
  1099.  PARAMETERS
  1100.     Pattern   is the file pattern to look for. Ex: "C:\\FrexxLink\\*.exe".
  1101.     Attribs   is a string describing what kind of files you wish to find.
  1102.               Each character in the string represents one flag:
  1103.                 'h' include hidden files in the search
  1104.                 's' include system files in the search
  1105.                 'd' include directory entries in the search
  1106.                 'H' search for hidden files only
  1107.                 'S' search for system files only
  1108.                 'D' search for directory entries only
  1109.                 'A' search for archive files only
  1110.                 'R' search for read-only files only
  1111.  
  1112.  RETURNS
  1113.     The name of the found file, or "" if no matching file was found.
  1114.  
  1115.  SEE ALSO
  1116.     ffindnext()
  1117.  
  1118. ------------------------------------------------------------------------------
  1119.  
  1120.  NAME
  1121.     ffindnext -- find the next directory entry matching a pattern
  1122.  
  1123.  SYNTAX
  1124.     string ffindnext();
  1125.  
  1126.  PARAMETERS
  1127.     None
  1128.  
  1129.  RETURNS
  1130.     The name of the found file, or "" if no more matching files could be found.
  1131.  
  1132.  SEE ALSO
  1133.     ffindfirst()
  1134.  
  1135. ------------------------------------------------------------------------------
  1136.  
  1137.  NAME
  1138.     fdelete -- delete a file from disk
  1139.  
  1140.  SYNTAX
  1141.     void fdelete( string Filename );
  1142.  
  1143.  PARAMETERS
  1144.     Filename    the name of the file to be deleted
  1145.  
  1146.  RETURNS
  1147.     Nothing
  1148.  
  1149.  SEE ALSO
  1150.     fkill(), frename(), fmove()
  1151.  
  1152. ------------------------------------------------------------------------------
  1153.  
  1154.  NAME
  1155.     frename -- rename a file to a new name
  1156.  
  1157.  SYNTAX
  1158.     void frename( string Oldname, string Newname );
  1159.  
  1160.  PARAMETERS
  1161.     Oldname    the name of the file to be renamed
  1162.     Newname    the new name of the file
  1163.  
  1164.  RETURNS
  1165.     Nothing
  1166.  
  1167.  NOTES
  1168.     Supplying a path with the new filename will move the file to a new
  1169.     directory. This will only occur if the assigned directory is on the same
  1170.     disk/partition as the old file.
  1171.  
  1172.  SEE ALSO
  1173.     fmove()
  1174.  
  1175. ------------------------------------------------------------------------------
  1176.  
  1177.  NAME
  1178.     getenv -- get environment variable
  1179.  
  1180.  SYNTAX
  1181.     string getenv( string Variable );
  1182.  
  1183.  DESCRIPTION
  1184.     Obtains an environment variable from the parent shell. (The 'SET'
  1185.     variables in an OS/2 CMD session.)
  1186.  
  1187.  PARAMETERS
  1188.     Variable is the name of the variable to get
  1189.  
  1190.  RETURNS
  1191.     The value of the variable if it exists, or "" if it doesn't.
  1192.  
  1193.  SEE ALSO
  1194.     getuservar()
  1195.  
  1196. ------------------------------------------------------------------------------
  1197.  
  1198.  NAME
  1199.     tokstr -- tokenize string
  1200.  
  1201.  SYNTAX
  1202.     string tokstr( string Source, int PartNo [, string Delimiters ] );
  1203.  
  1204.  DESCRIPTION
  1205.     Copies part of the source string, based on the delimiters and PartNo.
  1206.  
  1207.  PARAMETERS
  1208.     Source      the source string from which to copy the substrings
  1209.     PartNo      the ordinal number of the part to copy. The first part is
  1210.                 number 1.
  1211.     Delimiters  a string containing the delimiter chars used in Source to
  1212.                 separate the parts. The default is ";".
  1213.  
  1214.  RETURNS
  1215.     The copied string, or "" (null length string) if no part was found.
  1216.  
  1217. ------------------------------------------------------------------------------
  1218.  
  1219.  NAME
  1220.     sort -- sort an array of strings
  1221.  
  1222.  SYNTAX
  1223.     void sort( string& Array[] );
  1224.  
  1225.  DESCRIPTION
  1226.     Sorts the array in ASCII order.
  1227.  
  1228.  PARAMETERS
  1229.     Array       a reference to the array of strings to sort. 
  1230.  
  1231.  RETURNS
  1232.     Nothing
  1233.  
  1234. ------------------------------------------------------------------------------
  1235.  
  1236.  NAME
  1237.     parsecmnd -- parse a command line in KOM-style fashion
  1238.  
  1239.  SYNTAX
  1240.     string parsecmnd( string Line, string& Commands[] );
  1241.  
  1242.  DESCRIPTION
  1243.     Parses a command line, looking to match the line to a single command, as
  1244.     given in the Commands array. 
  1245.     The string matching is done character by character, until either the 
  1246.     command ends or a space is encountered. Given the commands "search new 
  1247.     files" and "search next file", the string "s n f" will match both commands
  1248.     while the string "s nex f" only will match the second.
  1249.  
  1250.  PARAMETERS
  1251.     Line        The command line to be parsed.
  1252.     Commands    A reference to an array of accepted commands.
  1253.  
  1254.  RETURNS
  1255.     A string containing the index numbers of the matching commands separated by
  1256.     commas, or "" if no string matched.
  1257.  
  1258.  EXAMPLE 1 (short)
  1259.  
  1260.     string commands[2] = { "go home","go back" };
  1261.     string index;
  1262.  
  1263.     /* this is how you call parsecmnd(): */
  1264.     index = parsecmnd("go",&commands);
  1265.  
  1266.     /* index will now contain the string "0,1,", since both "go back" 
  1267.        and "go home" are matched by the string "go". */
  1268.  
  1269.     index = parsecmnd("g b",&commands);
  1270.  
  1271.     /* index will now contain the string "1,", since only "go back" is 
  1272.        matched by the string "g b".
  1273.        Note how the word 'go' is prematurely terminated using a space
  1274.        character. Had there been a command in the array starting with, say,
  1275.        'get' the 'g b' string would have been ambigous since 'g ' could have
  1276.        meant either 'go' or 'get'. */
  1277.  
  1278.  
  1279.  EXAMPLE 2 (long)
  1280.  
  1281.     /* declare variables */
  1282.     string commands[5] = { "go home","go back","loot","lurk","sleep" };
  1283.     string input,index;
  1284.  
  1285.     /* ask user for string */
  1286.     input = getstring("Enter command: ");
  1287.  
  1288.     /* parse string and match it to the commands */
  1289.     index = parsecmnd(input,&commands);
  1290.  
  1291.     /* did user enter any known command? */
  1292.     if(!strlen(index))
  1293.     printf("\nUnknown command '%s'.\n",input);
  1294.     else {
  1295.         /* did we match more than one command?        */
  1296.         /* (check for a second value in index string) */
  1297.         if (atoi(tokstr(index,2,','))){
  1298.             int i;
  1299.             string s;
  1300.             printf("\nAmbigous input '%s' matches the following:\n",input);
  1301.             for(i=1;;i++){
  1302.                 s=tokstr(index,i,',');
  1303.                 /* if s=="" then we're out of indexes */
  1304.                 if(!strlen(s))
  1305.                     break;
  1306.                 printf("%s\n",commands[atoi(s)]);
  1307.             }
  1308.         }
  1309.         else {
  1310.             switch(command[atoi(index)]){
  1311.                 case "go home": printf("Go home!\n"); break;
  1312.                 case "go back": printf("Go back!\n"); break;
  1313.                 default: printf("Not implemented! :-)\n"); break;
  1314.             }
  1315.         }
  1316.     }
  1317.  
  1318. ------------------------------------------------------------------------------
  1319.  
  1320.  NAME
  1321.     bye -- quit frexxlink
  1322.  
  1323.  SYNTAX
  1324.     void bye( void );
  1325.  
  1326.  DESCRIPTION
  1327.     Quits FrexxLink immediately. Using the keyword 'exit' only stops the
  1328.     current FPL file, which does not always exit FrexxLink. The timeout 
  1329.     function, for example, runs as a separate FPL session and issuing an
  1330.     'exit' in there only exits the timeout function, and does not exit
  1331.     FrexxLink. Use bye() instead to achieve a complete exit.
  1332.  
  1333.  RETURNS
  1334.     It doesn't return. FrexxLink exits.
  1335.  
  1336. ------------------------------------------------------------------------------
  1337.  
  1338.  NAME
  1339.     random -- get a random value
  1340.  
  1341.  SYNTAX
  1342.     int random( void );
  1343.  
  1344.  DESCRIPTION
  1345.     Creates a properly randomized value between 0 and 999. This function is
  1346.     seeded when FrexxLink is started, using the system's millisecond counter
  1347.     as seed. The proper spread of values can be checked with the supplied
  1348.     FPL test program 'RandomTest.FPL'.
  1349.  
  1350.  RETURNS
  1351.     The random value
  1352.  
  1353. ------------------------------------------------------------------------------
  1354.  
  1355.  NAME
  1356.     sleep -- suspend execution for a certain amount of time
  1357.  
  1358.  SYNTAX
  1359.     void sleep( int Milliseconds );
  1360.  
  1361.  DESCRIPTION
  1362.     Suspends the system for the specified number of milliseconds. If this
  1363.     function is called in "safe" mode, the maximum allowed sleep time is 10
  1364.     seconds (10000 milliseconds).
  1365.  
  1366.  RETURNS
  1367.     Nothing
  1368.  
  1369.  
  1370. ==============================================================================
  1371.                              User Functions
  1372. ==============================================================================
  1373.  
  1374.  NAME
  1375.     inituser -- create a new user
  1376.  
  1377.  SYNTAX
  1378.     void inituser( void );
  1379.  
  1380.  DESCRIPTION
  1381.     This function clears all internal structures of any previous user and
  1382.     sets up the basis for a new user.
  1383.  
  1384.  RETURNS
  1385.     Nothing
  1386.  
  1387.  SEE ALSO
  1388.     loaduser(), saveuser()
  1389.  
  1390. ------------------------------------------------------------------------------
  1391.  
  1392.  NAME
  1393.     loaduser -- load a user file from disk
  1394.  
  1395.  SYNTAX
  1396.     int loaduser( string Username );
  1397.  
  1398.  DESCRIPTION
  1399.     Loads a user file from the "Users" directory.
  1400.  
  1401.  PARAMETERS
  1402.     Username is the username (and filename) of the user to load. It is not
  1403.     case sensitive.
  1404.  
  1405.  RETURNS
  1406.     0 if the user was found, or -1 if it wasn't.
  1407.  
  1408.  SEE ALSO
  1409.     inituser(), saveuser()
  1410.  
  1411. ------------------------------------------------------------------------------
  1412.  
  1413.  NAME
  1414.     saveuser -- save a user file to disk
  1415.  
  1416.  SYNTAX
  1417.     int saveuser( String Username );
  1418.  
  1419.  DESCRIPTION
  1420.     Saves a user to disk in the "Users" directory.
  1421.  
  1422.  PARAMETERS
  1423.     Username is the name of the user to save. It is not case sensitive.
  1424.  
  1425.  RETURNS
  1426.     0 if the user was saved correctly, or -1 if the file could not be created.
  1427.  
  1428.  SEE ALSO
  1429.     inituser(), loaduser()
  1430.  
  1431. ------------------------------------------------------------------------------
  1432.  
  1433.  NAME
  1434.     setuid -- set user identification string
  1435.  
  1436.  SYNTAX
  1437.     void setuid( string Username );
  1438.  
  1439.  PARAMETERS
  1440.     Username is the name of the user, or whatever string is desired to use for
  1441.     identifying which file in the MsgMap/ directory thath should be used as
  1442.     data file for which messages has been read.
  1443.  
  1444.  RETURNS
  1445.     Nothing
  1446.  
  1447.  SEE ALSO
  1448.     getuid(), markmsg()
  1449.  
  1450. ------------------------------------------------------------------------------
  1451.  
  1452.  NAME
  1453.     getuid -- get user identification string
  1454.  
  1455.  SYNTAX
  1456.     string getuid( void );
  1457.  
  1458.  RETURNS
  1459.     The string sent with setuid(), or "" if no calls to setuid() has been made.
  1460.  
  1461.  SEE ALSO
  1462.     setuid()
  1463.  
  1464. ------------------------------------------------------------------------------
  1465.  
  1466.  NAME
  1467.     getuservar -- get user variable
  1468.  
  1469.  SYNTAX
  1470.     string getuservar( string VarName );
  1471.  
  1472.  PARAMETERS
  1473.     VarName is the name of the user variable. It is not case sensitive.
  1474.  
  1475.  RETURNS
  1476.     The string
  1477.  
  1478.  SEE ALSO
  1479.     setuservar(), getenv(), getuid()
  1480.  
  1481. ------------------------------------------------------------------------------
  1482.  
  1483.  NAME
  1484.     setuservar -- set user variable
  1485.  
  1486.  SYNTAX
  1487.     void setuservar( string VarName, string Value );
  1488.  
  1489.  PARAMETERS
  1490.     VarName is the name of the user variable. It is not case sensitive.
  1491.     Value   is what the user variable is assigned. Case is preserved.
  1492.  
  1493.  RETURNS
  1494.     Nothing
  1495.  
  1496.  SEE ALSO
  1497.     getuservar(), setuid()
  1498.  
  1499. ------------------------------------------------------------------------------
  1500.  
  1501.  NAME
  1502.     charset -- set charset conversion
  1503.  
  1504.  SYNTAX
  1505.     void charset( int UserSet, int DataSet );
  1506.  
  1507.  DESCRIPTION
  1508.     Internally, FrexxLink handles all text as CodePage 850. In order to
  1509.     supply proper charset conversion for things like messages and such,
  1510.     it is necessary set the charset used.
  1511.  
  1512.  PARAMETER
  1513.     UserSet specifies the user's charset.
  1514.     DataSet specifies the charset used in the current message area.
  1515.  
  1516.  RETURNS
  1517.     Nothing
  1518.  
  1519.  SEE ALSO
  1520.     translate()
  1521.  
  1522. ------------------------------------------------------------------------------
  1523.  
  1524.  NAME
  1525.     screenlen -- get/set user screen length
  1526.  
  1527.  SYNTAX
  1528.     int screenlen( [ int Lines ] );
  1529.  
  1530.  PARAMETERS
  1531.     Lines is the number of lines on the user's screen. By supplying this
  1532.     parameter, the previous value will be overwritten. However, altering the 
  1533.     screen length is not allowed in "safe" mode.
  1534.  
  1535.  RETURNS
  1536.     The number of lines per screen.
  1537.  
  1538.  SEE ALSO
  1539.     setfunc(), clear()
  1540.  
  1541. ------------------------------------------------------------------------------
  1542.  
  1543.  NAME
  1544.     setusertime -- set the amount of user time left
  1545.  
  1546.  SYNTAX
  1547.     void setusertime( int Seconds );
  1548.  
  1549.  DESCRIPTION
  1550.     This functions sets the amount of time for the current user. Every time
  1551.     the minute count "clicks" down, the system FPL function "timeleft" is
  1552.     called.
  1553.  
  1554.  PARAMETERS
  1555.     Seconds is the number of seconds until the user time is up.
  1556.  
  1557.  RETURNS
  1558.     Nothing
  1559.  
  1560.  SEE ALSO
  1561.     setfunc(), sys_timeleft
  1562.  
  1563.  
  1564. ==============================================================================
  1565.                          Message Area Functions
  1566. ==============================================================================
  1567.  
  1568.  NAME
  1569.     gotomarea -- set current message area
  1570.  
  1571.  SYNTAX
  1572.     int gotomarea( string Tag, string Path );
  1573.  
  1574.  DESCRIPTION
  1575.     Sets the internal "cursor" to the specified area. All subsequent message
  1576.     functions are applied to this area.
  1577.  
  1578.  PARAMETERS
  1579.     Tag is the area tag, used in the MsgMap file for marking read messages.
  1580.     Path is the path+base filename to the squish data files for this area.
  1581.  
  1582.  RETURNS
  1583.     -1 if the call failed. 0 otherwise.
  1584.  
  1585. ------------------------------------------------------------------------------
  1586.  
  1587.  NAME
  1588.     getmarea -- get information about current message area 
  1589.  
  1590.  SYNTAX
  1591.     int getmarea( string Id );
  1592.  
  1593.  PARAMETERS
  1594.     Id  is the information identifier:
  1595.        "total"    the total number of messages in the area.
  1596.        "unread"   the number of unread messages in the area.
  1597.        "highest"  the number of the highest message in the area.
  1598.  
  1599.  RETURNS
  1600.   SEE above.
  1601.  
  1602. ------------------------------------------------------------------------------
  1603.  
  1604.  NAME
  1605.     getmsg -- get a subpart of a message
  1606.  
  1607.  SYNTAX
  1608.     string getmsg( int MsgNo, string PartId [, int ReplyNo] );
  1609.  
  1610.  PARAMETERS
  1611.     MsgNo specifies which message to read from.
  1612.     PartId specifies which part of the message to fetch:
  1613.       "body"     - the message body, truncated below the first occurence of
  1614.                    " * Origin: ".
  1615.       "from"     - the 'From' field
  1616.       "to"       - the 'To'   field
  1617.       "subject"  - the 'Subject' field
  1618.       "origaddr" - the originating 4D address (Zone:Net/Node.Point)
  1619.       "destaddr" - the destination 4D address (Zone:Net/Node.Point)
  1620.       "date"     - the creation date of the message (YY-MM-DD HH:MM)
  1621.       "replyto"  - the message number this message is a reply to, or 0 if this
  1622.                    message isn't a reply
  1623.       "control"  - the ^A kludges of the message. Each SOH (0x01) is replaced
  1624.                    with a newline character.
  1625.       "replies"  - the message number(s) of the replies to this message. This
  1626.                    is where the ReplyNo parameter comes in. It specifies which
  1627.                    reply to check for, starting with #1. There can be a
  1628.                    maximum of 10 replies to every message. This function
  1629.                  RETurns "0" if there is no reply with the specified number.
  1630.                    Replies are always stored 1->10, so once you find a 0 it's
  1631.                    no use checking the rest of the replies.
  1632.  
  1633.  RETURNS
  1634.     See above
  1635.  
  1636. ------------------------------------------------------------------------------
  1637.  
  1638.  NAME
  1639.     printmsg -- display message body with quote colouring and word wrapping
  1640.  
  1641.  SYNTAX
  1642.     void printmsg( string Body, string QuoteCol, string TextCol );
  1643.  
  1644.  DESCRIPTION
  1645.     FidoNet messages can be somewhat messy to handle, so here's a function that
  1646.     does all that neat formatting and colouring stuff for you.
  1647.     It replaces all LF (0x0a) characters whith SPACE (0x20) and then outputs
  1648.     each paragraph (i.e. lines separated with CR (0x0d)) neatly wrapped.
  1649.     All paragraphs having a '>' character in the first 10 characters are
  1650.     considered quoted and are thus prefixed with the QuoteCol string.
  1651.     All "normal" text paragraphs immediately following a quote are prefixed
  1652.     with the TextCol string.
  1653.  
  1654.  PARAMETERS
  1655.     Body     - The body of a message
  1656.     QuoteCol - The escape sequence (or whatever) for the quoted lines colour
  1657.     TextCol  - The escape sequence for normal lines
  1658.  
  1659.  RETURNS
  1660.     Nothing
  1661.  
  1662. ------------------------------------------------------------------------------
  1663.  
  1664.  NAME
  1665.     nextmsg -- Find next unread message in thread
  1666.  
  1667.  SYNTAX
  1668.     int nextmsg( int Message );
  1669.  
  1670.  DESCRIPTION
  1671.     Finds the next unread message.
  1672.  
  1673.  PARAMETERS
  1674.     If Message is a valid message number, nextmsg() will scan Message's
  1675.     thread for an unread reply. If Message is -1, nextmsg() will scan
  1676.     for the first unread message in the area.
  1677.  
  1678.  RETURNS
  1679.     Next unread message number. If the thread is exhausted, nextmsg()
  1680.   RETurns -1. If the area is exhausted, nextmsg() returns 0.
  1681.  
  1682. ------------------------------------------------------------------------------
  1683.  
  1684.  NAME
  1685.     markmsg -- check read mark for message
  1686.  
  1687.  SYNTAX
  1688.     int msgmsg( int MsgNo [, int Set ] );
  1689.  
  1690.  PARAMETERS
  1691.     MsgNo is the number of the message to check
  1692.     Set   is an optional flag which changes the value of the mark:
  1693.            0 marks the message as unread
  1694.            1 marks the message as read
  1695.           -1 does not modify the mark (default)
  1696.  
  1697.  RETURNS
  1698.     0 if the message is marked as unread, otherwise 1.
  1699.  
  1700. ------------------------------------------------------------------------------
  1701.  
  1702.  NAME
  1703.     savemsgmap -- store map of read messages
  1704.  
  1705.  SYNTAX
  1706.     void savemsgmap( void );
  1707.  
  1708.  DESCRIPTION
  1709.     Stores a map of read messages in the "MsgMap" directory, in a filename
  1710.     as set by the setuid() function.
  1711.  
  1712.  RETURNS
  1713.     Nothing
  1714.  
  1715. ------------------------------------------------------------------------------
  1716.  
  1717.  NAME
  1718.     createmsg -- clear all internal message structures
  1719.  
  1720.  SYNTAX
  1721.     void createmsg( void );
  1722.  
  1723.  DESCRIPTION
  1724.     Clears all stuff internally used for sending messages. Use this before
  1725.     putmsg()ing stuff.
  1726.  
  1727.  RETURNS
  1728.     Nothing
  1729.  
  1730. ------------------------------------------------------------------------------
  1731.  
  1732.  NAME
  1733.     putmsg -- assign message part value
  1734.  
  1735.  SYNTAX
  1736.     void putmsg( string PartId, string Value );
  1737.  
  1738.  DESCRIPTION
  1739.     Adds part of a message to the internal message buffer.
  1740.  
  1741.  PARAMETERS
  1742.     PartId is the part which is to be assigned:
  1743.       "body"     - the message body
  1744.       "from"     - the 'From' field
  1745.       "to"       - the 'To'   field
  1746.       "subject"  - the 'Subject' field
  1747.       "origaddr" - the originating 4D address (Zone:Net/Node.Point)
  1748.       "destaddr" - the destination 4D address (Zone:Net/Node.Point)
  1749.       "control"  - the ^A kludges of the message, with SOH (0x01) characters
  1750.                    positioned correctly. FrexxLink does not alter this field
  1751.                    in any way before sending it, so it's all up to you!
  1752.  
  1753.     Value is the value to set.
  1754.  
  1755.  RETURNS
  1756.     Nothing
  1757.  
  1758. ------------------------------------------------------------------------------
  1759.  
  1760.  NAME
  1761.     putmsgflag -- set message flags
  1762.  
  1763.  SYNTAX
  1764.     void putmsgflag( string FlagId, int Value );
  1765.  
  1766.  PARAMETERS
  1767.     FlagId is the flag identifier:
  1768.       "private",
  1769.       "crash",
  1770.       "read",
  1771.       "sent",
  1772.       "file",
  1773.       "forward",
  1774.       "orphan",
  1775.       "kill",
  1776.       "local",
  1777.       "hold",
  1778.       "freq",
  1779.       "rreq",
  1780.       "receipt",
  1781.       "ureq",
  1782.       "scanned",
  1783.       "uid",
  1784.     Value is 0 if the flag is to be cleared, or 1 if the flag should be set.
  1785.  
  1786.  RETURNS
  1787.     Nothing
  1788.  
  1789. ------------------------------------------------------------------------------
  1790.  
  1791.  NAME
  1792.     getmsgflag -- get message flags
  1793.  
  1794.  SYNTAX
  1795.     int getmsgflag( int MsgNo, string FlagId );
  1796.  
  1797.  DESCRIPTION
  1798.     Checks if a message contains a specific flag.
  1799.  
  1800.  PARAMETERS
  1801.     MsgNo  is the number of the message to be examined
  1802.  
  1803.     FlagId is the flag identifier:
  1804.       "private",
  1805.       "crash",
  1806.       "read",
  1807.       "sent",
  1808.       "file",
  1809.       "forward",
  1810.       "orphan",
  1811.       "kill",
  1812.       "local",
  1813.       "hold",
  1814.       "freq",
  1815.       "rreq",
  1816.       "receipt",
  1817.       "ureq",
  1818.       "scanned",
  1819.       "uid",
  1820.  
  1821.  RETURNS
  1822.     1 if the flag is set. 0 otherwise.
  1823.  
  1824.  
  1825. ------------------------------------------------------------------------------
  1826.  
  1827.  NAME
  1828.     sendmsg -- write message to message base
  1829.  
  1830.  SYNTAX
  1831.     void sendmsg( void );
  1832.  
  1833.  RETURNS
  1834.     Nothing
  1835.  
  1836. ------------------------------------------------------------------------------
  1837.  
  1838.  NAME
  1839.     msgid -- create new MSGID
  1840.  
  1841.  SYNTAX
  1842.     int msgid( void );
  1843.  
  1844.  DESCRIPTION
  1845.     This function creates a new message ID of the type you are required to put
  1846.     into your FidoNet messages. The FTS-09 document specifies that no two
  1847.     messages from a system may contain the same MSGID for at least three years.
  1848.     I have solved this by counting the time passed since the last 5-year
  1849.     shift, in 1/10th of seconds. That means that my counter reset last time
  1850.     1995-01-01 00:00 and is increasing constantly at a speed of 864000 clicks
  1851.     per day. Even with this speed, the counter will not wrap for about 13
  1852.     years, so I think we're on the safe side.
  1853.  
  1854.  RETURNS
  1855.     The message id.
  1856.  
  1857. ------------------------------------------------------------------------------
  1858.  
  1859.  NAME
  1860.     msgmember -- check area membership
  1861.  
  1862.  SYNTAX
  1863.     int msgmember( [ int Flag ] );
  1864.  
  1865.  DESCRIPTION
  1866.     FrexxLink supports the concept or area membership. This function controls
  1867.     whether the current user (as specified with setuid()) is a member of the
  1868.     current area (as specified with gotomarea()) or not.
  1869.  
  1870.  PARAMETERS
  1871.     Flag is an optional parameter, changing the state of membership:
  1872.       0 clears the member flag
  1873.       1 sets the member flag
  1874.      -1 does not modify the member flag (default)
  1875.  
  1876.  RETURNS
  1877.     The state of membership for the area.
  1878.  
  1879. ------------------------------------------------------------------------------
  1880.  
  1881.  NAME
  1882.     delmsg -- delete a message
  1883.  
  1884.  SYNTAX
  1885.     void delmsg( int MsgNo );
  1886.  
  1887.  DESCRIPTION
  1888.     Deletes a message from the message base.
  1889.  
  1890.  PARAMETERS
  1891.     MsgNo is the number of the message to delete.
  1892.  
  1893.  RETURNS
  1894.     Nothing
  1895.  
  1896. ------------------------------------------------------------------------------
  1897.  
  1898.  NAME
  1899.     setmareasize -- define maiximum size of a message area
  1900.  
  1901.  SYNTAX
  1902.     void setmareasize( int MaxSize );
  1903.  
  1904.  DESCRIPTION
  1905.     Sets the maximum size of the current message area. The tosser will
  1906.     start throwing away old messages when this number is reached.
  1907.     You only need to call this function when you wish to modify the maximum
  1908.     size of the area.
  1909.  
  1910.  PARAMETERS
  1911.     MaxSize  is the maximum number of messages in the area.
  1912.  
  1913.  RETURNS
  1914.     Nothing
  1915.  
  1916.  
  1917. ==============================================================================
  1918.                            File Area Functions
  1919. ==============================================================================
  1920.  
  1921.  NAME
  1922.     gotofarea -- set current file area
  1923.  
  1924.  SYNTAX
  1925.     void gotofarea( string ListPath, string FilePath );
  1926.  
  1927.  DESCRIPTION
  1928.     Defines the current file area. All subsequent file area functions will use
  1929.     this setting
  1930.  
  1931.  PARAMETERS
  1932.     ListPath is the path and filename to the list file for this area.
  1933.     FilePath is the path to where the actual files of this area are stored.
  1934.  
  1935.  RETURNS
  1936.     Nothing
  1937.  
  1938. ------------------------------------------------------------------------------
  1939.  
  1940.  NAME
  1941.     filelist -- list files in current file area
  1942.  
  1943.  SYNTAX
  1944.     int filelist( [ string Type ], [ string Field ], [ string Key ] );
  1945.  
  1946.  DESCRIPTION
  1947.     Lists files in the current directory, all or a selected few. If searching
  1948.     is enabled, this function will output two newlines before the first file
  1949.     match is printed.
  1950.  
  1951.  PARAMETERS
  1952.     If no parameters are supplied, this function will list all files as they
  1953.     are listed in the list file, including comments and separator lines.
  1954.  
  1955.     Type   controls what kind of searching is to be done. Possible parameters
  1956.            are "string" and "date". If Type is set to "date", the Field
  1957.        and Key parameters are not required.
  1958.  
  1959.     Field  if "string" is chosen as search type, this field is used to define
  1960.            which string field is to be searched for matching text. Setting this
  1961.          PARAMeter to "TX" will actually search both the "TX" field and the
  1962.        filename. This parameter is case sensitive.
  1963.  
  1964.     Key    is the string to search for in the field specified by Field. It
  1965.            is not case sensitive.
  1966.  
  1967.  RETURNS
  1968.     1 if the user has pressed Ctrl-C. 0 otherwise.
  1969.  
  1970. ------------------------------------------------------------------------------
  1971.  
  1972.  NAME
  1973.     newfiles -- search for files newer than a specific date
  1974.  
  1975.  SYNTAX
  1976.     int newfiles( int Date );
  1977.  
  1978.  DESCRIPTION
  1979.     Scans current file area looking for files not older than Date. If there
  1980.     exists a field 'DA' on a file description line, newscan() uses the date
  1981.     specified in that field. Otherwise, newscan() examines the file on the
  1982.     disk and obtains the creation date.
  1983.  
  1984.  PARAMETERS
  1985.     Date   the time in integer format, i.e. seconds from 1970.
  1986.  
  1987.  RETURNS
  1988.     1 if the user has pressed Ctrl-C. 0 otherwise.
  1989.  
  1990. ------------------------------------------------------------------------------
  1991.  
  1992.  NAME
  1993.     typefile -- display a text file onscreen
  1994.  
  1995.  SYNTAX
  1996.     int typefile( string Filename ); 
  1997.  
  1998.  PARAMETERS
  1999.     Filename   the path+filename of the file to display.
  2000.  
  2001.  RETURNS
  2002.     -1 if the file was not found. 0 if all is fine.
  2003.  
  2004. ------------------------------------------------------------------------------
  2005.  
  2006.  NAME
  2007.     fileinfo -- get specifics about a disk file
  2008.  
  2009.  SYNTAX
  2010.     int fileinfo( string Filename, string Field );
  2011.  
  2012.  PARAMETERS
  2013.     Filename   the path+filename of the file to examine.
  2014.  
  2015.     Field      a string describing what information is requested:
  2016.         "size"   the size of the file in bytes.
  2017.         "time"   the creation time of the file, as an integer.
  2018.  
  2019.  RETURNS
  2020.     The result examination, or -1 if the file was not found.
  2021.  
  2022. ------------------------------------------------------------------------------
  2023.  
  2024.  NAME
  2025.     dszfield -- parse a dszlog type file
  2026.  
  2027.  SYNTAX
  2028.     string dszfield( string DszLog, int Line, string Field );
  2029.  
  2030.  DESCRIPTION
  2031.     Many transfer protocols produce a result log in the format defined by
  2032.     the DSZ software. This is a convenience function to decipher such a log
  2033.     file.
  2034.  
  2035.  PARAMETERS
  2036.     DszLog    the path+filename of the DSZ-style log file
  2037.     Line    the line number to examine. Each file transfered in a batch
  2038.                 gets a line of its own, so this parameter simply says which
  2039.                 file in order you wish to examine.
  2040.  
  2041.     Field    the information field requested:
  2042.            "protocol"   a one character string describing the protocol used
  2043.                         in transfer. An upper case character means upload,
  2044.                         lower case download.
  2045.                         'z' and 'Z' are used for Zmodem.
  2046.                         'x' and 'X' are used for Xmodem.
  2047.                         'e' and 'E' are used to signal that the transfer was
  2048.                         unsuccessful (a fatal error occured).
  2049.            "fsize"      the size of the transfered file in bytes
  2050.            "dte"    the dte (computer to modem) speed
  2051.            "cps"    the achieved transfer speed i bytes per second
  2052.            "errors"    the number of non-fatal errors during the transfer
  2053.            "stops"    the number of transfer stops occured
  2054.            "psize"    the packet size used (for Xmodem and other packet
  2055.                         oriented protocols. Zmodem does not use packets).
  2056.            "file"    the (path and) name of the file transferred
  2057.            "serial"    the serial number of the remote protocol handler
  2058.  
  2059.  RETURNS
  2060.     The requested field.
  2061.  
  2062.    NOTES
  2063.     Use the protocol field to check the number of lines. If the protocol is
  2064.     "" (zero length string) that means there are no more files in the log.
  2065.  
  2066. ------------------------------------------------------------------------------
  2067.  
  2068.  NAME
  2069.     splitpath -- split a path+file string into path and filename
  2070.  
  2071.  SYNTAX
  2072.     string splitpath( string FullName, string Field );
  2073.  
  2074.  DESCRIPTION
  2075.     Copies either the path or the filename out of a full path+filename string.
  2076.     The algorithm used is to locate the last '\' character in the string and
  2077.     consider the filename to begin at the next character. Everything before
  2078.     that is the path.
  2079.  
  2080.  PARAMETERS
  2081.     FullName    the path to be split. ex: "C:\FrexxLink\Top.FPL"
  2082.     Field       the part requested:
  2083.            "path"   the path, WITHOUT trailing backslash
  2084.            "file"   the filename
  2085.  
  2086.  RETURNS
  2087.     The requested field.
  2088.  
  2089. ------------------------------------------------------------------------------
  2090.  
  2091.  NAME
  2092.     clrftags -- clear file tags
  2093.  
  2094.  SYNTAX
  2095.     void clrftags( void );
  2096.  
  2097.  DESCRIPTION
  2098.     Clears the internal file tags and resets the tag counter to 1.
  2099.  
  2100.  PARAMETERS
  2101.     None
  2102.  
  2103.  RETURNS
  2104.     Nothing
  2105.  
  2106. ------------------------------------------------------------------------------
  2107.  
  2108.  NAME
  2109.     getftag -- get a file tag
  2110.  
  2111.  SYNTAX
  2112.     string getftag( int TagNo );
  2113.  
  2114.  DESCRIPTION
  2115.     The tag list FrexxLink keeps consists of 99 path+file strings,
  2116.     containing the last 99 files listed using filelist() and newfiles().
  2117.     getftag() copies one of those tag strings.
  2118.  
  2119.  PARAMETERS
  2120.     TagNo    the number of the tag you wish to get.
  2121.  
  2122.  RETURNS
  2123.     The tag string, if TagNo is the number of a tag that actually exists.
  2124.     Otherwise, an empty string ("") is returned.
  2125.  
  2126.  SEE ALSO
  2127.     clrftags()
  2128.  
  2129. ------------------------------------------------------------------------------
  2130.  
  2131.  NAME
  2132.     getffield -- get file description field
  2133.  
  2134.  SYNTAX
  2135.     string getffield( string Filename, string Field );
  2136.  
  2137.  DESCRIPTION
  2138.     Every file description line consists of several file fields. getffield()
  2139.   RETurns the value of a field for a specific file.
  2140.     The description file used is the one specified with gotofarea().
  2141.  
  2142.  PARAMETERS
  2143.     Filename  the name of the file whose description contains the field
  2144.     Field     the two-character field name to look for, case sensitive
  2145.  
  2146.  RETURNS
  2147.     The contents of the file field, or "" if no such field exists for the
  2148.     specified file.
  2149.  
  2150.  SEE ALSO
  2151.     gotofarea(), setffield()
  2152.  
  2153. ------------------------------------------------------------------------------
  2154.  
  2155.  NAME
  2156.     setffield -- set file description field
  2157.  
  2158.  SYNTAX
  2159.     void setffield( string Filename, string Field, string Contents );
  2160.  
  2161.  DESCRIPTION
  2162.     Sets the contents of a file description field. If no such field exists
  2163.     for the specified file, it will be created.
  2164.  
  2165.  PARAMETERS
  2166.     Filename  the name of the file whose field should be set
  2167.     Field     the two-character field name to set, case sensitive
  2168.     Contents  the new contents of the description field
  2169.  
  2170.  RETURNS
  2171.     Nothing
  2172.  
  2173.  SEE ALSO
  2174.     gotofarea(), getffield()
  2175.  
  2176. ------------------------------------------------------------------------------
  2177.  
  2178.  NAME
  2179.     fkill -- remove a file description line
  2180.  
  2181.  SYNTAX
  2182.     void fkill( string Filename );
  2183.  
  2184.  DESCRIPTION
  2185.     Removes the description line for Filename from the description file.
  2186.     The first line encountered describing the specified filename is simply
  2187.     removed from the list file. If the list file contains several entries
  2188.     for the same filename, only the first one is removed.
  2189.  
  2190.  PARAMETERS
  2191.     Filename   the name of the file whose description line should be removed
  2192.  
  2193.  RETURNS
  2194.     Nothing
  2195.  
  2196. ------------------------------------------------------------------------------
  2197.  
  2198.  NAME
  2199.     fmove -- move a file description line
  2200.  
  2201.  SYNTAX
  2202.     void fmove( string Filename, string NewList );
  2203.  
  2204.  DESCRIPTION
  2205.     Moves the description line for Filename from the current description file
  2206.     to the top of another file.
  2207.  
  2208.  PARAMETERS
  2209.     Filename   the name of the file whose description line should be moved
  2210.     NewList    the path+filename of the description file to where the line
  2211.                should be moved
  2212.  
  2213.  RETURNS
  2214.     Nothing
  2215.  
  2216. ------------------------------------------------------------------------------
  2217.  
  2218.  NAME
  2219.     setdatestr -- set file date display strings
  2220.  
  2221.  SYNTAX
  2222.     void setdatestr( string& Days[3], string& Months[12] );
  2223.  
  2224.  DESCRIPTION
  2225.     In the file list, the file date can be displayed in varying ways. The
  2226.     default is the following:
  2227.     If the file date is "today", the string "Today" is displayed instead of
  2228.     the file date. The same goes for yesterday. For all dates other than today,
  2229.     yesterday and the day before yesterday, but in the same year as today, the
  2230.     format "DD Month" is used. For all other dates (other years) the format
  2231.     YY-MM-DD is used.
  2232.     setdatestr() defines the strings displayed when the YY-MM-DD format is NOT
  2233.     used. That is, it defines the relative day names and the month names.
  2234.  
  2235.  PARAMETERS
  2236.     Days    A reference to an array of three (3) strings with a maximum
  2237.             length of eight characters each.
  2238.             The first string should contain the string to be displayed for
  2239.             dates being the current day. Default: "Today"
  2240.             The second string should contain the string to be displayed for
  2241.             dates being one day prior to the current day. Default: "Yestrday"
  2242.             The third string is for dates being TWO days prior to the current
  2243.             day. Default: "" (no string).
  2244.  
  2245.     Months  A reference to an array of twelve (12) strings with a maximum
  2246.             length of five characters each.
  2247.             The strings should be the month names. Default: Jan,Febr,March,
  2248.             April,May,June,July,Aug,Sept,Oct,Nov,Dec
  2249.  
  2250.  
  2251.     If you wish to inhibit the use of one or more of these strings, use an
  2252.     empty string ("") in place of a month or day name. Supplying only empty
  2253.     day names inhibits the use of relative days and supplying only empty
  2254.     month names inhibits the current-year display variant.
  2255.  
  2256.  RETURNS
  2257.     Nothing
  2258.  
  2259.  EXAMPLE
  2260.     /* Set all three day strings */
  2261.     string Days[3] = {"Todei","Jestrday","DayBfore"};
  2262.  
  2263.     /* Use strings for all months, except july, august and september, */
  2264.     /*  where the YY-MM-DD format will be displayed.                  */
  2265.     string Months[12] = { "Yan","Fbrrr","March","April","May","June",
  2266.                           "","","","Oct","Nov","Dec" };
  2267.     setdatestr(&Days,&Months);
  2268.  
  2269.  
  2270. ==============================================================================
  2271.                              Time Functions
  2272. ==============================================================================
  2273.  
  2274.  
  2275.  NAME
  2276.     nowtime -- find out current system time
  2277.  
  2278.  SYNTAX
  2279.     int nowtime( void );
  2280.  
  2281.  DESCRIPTION
  2282.     notime() returns the current system time in the number of seconds
  2283.     since 1970.
  2284.  
  2285.  PARAMETERS
  2286.     None
  2287.  
  2288.  RETURNS
  2289.     The time.
  2290.  
  2291. ------------------------------------------------------------------------------
  2292.  
  2293.  NAME
  2294.     timepart -- get part of a time (better description wanted!)
  2295.  
  2296.  SYNTAX
  2297.     int timepart( int Time, string Field );
  2298.  
  2299.  DESCRIPTION
  2300.     This function allows you to extract a single part from a time, such
  2301.     as the year, the month number or the minute.
  2302.  
  2303.  PARAMETERS
  2304.     Time    the time to use, in seconds from 1970.
  2305.     Field   the time part to return:
  2306.         "year"     the year, 1970-
  2307.         "month"    the month, 1-12
  2308.         "day"      the day of the month, 1-31
  2309.         "wday"     the day of the week, 0-6 (0=Monday)
  2310.         "hour"     the hour, 0-23
  2311.         "minute"   the minute, 0-59
  2312.         "second"   the second, 0-59
  2313.  
  2314.  RETURNS
  2315.     The time part requested.
  2316.  
  2317. ------------------------------------------------------------------------------
  2318.  
  2319.  NAME
  2320.     time2str -- convert an integer to a time string
  2321.  
  2322.  SYNTAX
  2323.     string time2str( int Time );
  2324.  
  2325.  DESCRIPTION
  2326.     Converts an integer representing the number of seconds from 1970 into
  2327.     a string in the format "YYYY-MM-DD,HH:MM:SS"
  2328.  
  2329.  PARAMETERS
  2330.     Time   the time to convert
  2331.  
  2332.  RETURNS
  2333.     The time, as a string.
  2334.  
  2335. ------------------------------------------------------------------------------
  2336.  
  2337.  NAME
  2338.     str2time -- convert a time string into an integer
  2339.  
  2340.  SYNTAX
  2341.     int str2time( string Time );
  2342.  
  2343.  DESCRIPTION
  2344.     Converts a string in the format "YYYY-MM-DD,HH:MM:SS" into an integer
  2345.     representing the number of seconds since 1970.
  2346.     Actually, the time format is "YYYY.MM.DD.HH.MM.SS" where the '.' chars
  2347.     can be any character at all.
  2348.  
  2349.  PARAMETERS
  2350.     Time   the time string to convert
  2351.  
  2352.  RETURNS
  2353.     The time, as an integer.
  2354.  
  2355.