
struct AsfrontenD and its functions provide in the role of a frontend client
easy access to an AsagenT server via TCP/IP. See  sagent -help  for more
information about AsagenT communications.

For convenient use of AsfrontenD an application should provide an interpreter
function and an application object which get involved when a reply message
has completely arrived. (see below for details)

AsfrontenD is made out of these modules (see also makefile of stic) :
  asfrontend asvmsg sregex sfile stcp stunnel sblowfish sconn saccess smem

All operations are accessible by int functions. There should be no need
to include any specific headers in the application code.

Elementary steps to establish and later shut down a frontend connection :

  Asfrontend_new() 
       creates a frontend object and connects to the server.
       It needs an application object pointer (NULL=itself),
       a pointer to an interpreter function for incoming replies,
       the hostname of the server,
       the portnumber of the server,
       the username (""=unencrypted anonymous)

  Asfrontend_send_initial()
       establishes a backchannel at the server side via -add_view. Without
       such a backchannel the server will execute commands but not reply
       anything. (see sagent -help for information about -add_view)

  Asfrontend_destroy()
       closes the connection and removes the frontend object from memory.


Usage of an established connection:

  Asfrontend_get_fd()
       obtain the file descriptor of the connection. It may be needed by the
       application, e.g. for use with select() .

  Asfrontend_send()
       sends a command line to the server.

  Asfrontend_callback()
       should be called whenever availability of data has been detected at
       the connection's file descriptor. This function calls the interpreter
       function with every single incoming reply message as soon as it is
       completly received. It does not block if no data are available at
       the file descriptor.
       This function is modest in grabbing processor time because it will
       only read a limited number of bytes before returning. Any unprocessed
       input data will be pending at the file descriptor and not at internal
       buffers of AsfrontenD or its helpers. Thus select() will detect them
       and Asfrontend_callback() may be invoked again.

  Asfrontend_synchronize()
       receives all replies and only returns after the end mark of the
       most recent command has been received. This function calls the
       interpreter function with every single incoming reply message as
       soon it is completly received.


Constraints of application object and interpreter function:

  The above functions call the interpreter function in the following way:

    char *application_object_pointer;
    struct AsfrontenD *frontend;
    int flag = 0;
    int ret;
    ret= Interpreter(application_object_pointer,frontend,flag);

  The application_object_pointer therefore should lead to all data necessary
  to react properly to possible replies in the context of the application.

  The return value may be:
     -1=failure, abort receiving
      0=failure, continue receiving
      1=all went well
      2=all went well, more data expected (currently no difference to 1)
      3=all went well, end receiving

  An example of an interpreter function is:

  Asfrontend_print_interpreter()
       it gets the frontend pointer two times since frontend serves as
       application object too.
       In main() of this program Asfrontend_print_interpreter() is used
       as argument of Asfrontend_new() together with a NULL pointer for
       the application object.

  Another example of handling a received message can be seen in 
  Asfrontend_check_reply() .

AsfrontenD provides a struct AsviewmsG which contains the parsed components
of a message: type, fieldcount, fields . About the structure of notification
messages see  sagent -help , Appendix B : Format of Notification Messages.
An interpreter function may access the AsviewmsG via the following methods :

  Asfrontend_get_vmsg()
       obtains a pointer to the current message object.

  Asviewmsg_is_complete()
       confirms that the message has been received completely.

  Asviewmsg_fetch_type()
       obtains a pointer to a string containing the message type

  Asviewmsg_fetch_field()
       obtains via fieldname the bytecount and a pointer to the databytes.

  Asviewmsg_get_fieldcount()
       returns the number of fields in the message

  Asviewmsg_fetch_field_idx()
       obtains via fieldnumber pointers to fieldname, bytes and their count.


Examples and documentation:

  main()
       implements a primitive client which requests input lines and shows
       the reply messages. Demonstrates the complete lifecycle of a 
       AsfrontenD object.
       Define macro Asfrontend_without_maiN to suppress the main() function.

  Asfrontend_input_loop()
       the primitive synchronous request-reply loop used by main().
       This function calls Asfrontend_synchronize() and thus the interpreter.

  Asfrontend_helptext()
       replies this text in a malloced string.

  and all the other functions in this sourcecode.


More primitive methods which do not require an application object or
an interpreter function:

  Asfrontend_fetch_vmsg()
       fetches a message respectively the available part of a message into
       the message buffer of the frontend object. This function is modest
       in grabbing processor time because it will only read a limited number
       of bytes before returning. Therefore repeated calls may be necessary.
       select() can not detect possibly buffered data.
       Therefore use Asfrontend_has_data() to determine wether you are done.

  Asfrontend_vmsg_is_valid()
       returns 1 if the frontend object has got a valid current reply
       message. returns 0 else.

  Asfrontend_has_data()
       returns 1 if there are data pending in the buffers or at the file
       descriptor. returns 0 else.


Supporting functions which hardly will be called by applications:

  Asfrontend_check_reply()
       employed by Asfrontend_fetch_vmsg() to keep track of messages
       interesting to the AsfrontenD object. E.g. command mark for
       synchronization or end mark for end of connection.

  Asfrontend_show_conn_messages()
       reads the messages of lower i/o layers and puts them to stdout/stderr.

  Asfrontend_open()
       is called by Asfrontend_new() to establish the TCP/IP connection.

  Asfrontend_set_user()
       is called by Asfrontend_new() to set the user id for the connection.

This software is copyright 2001, Thomas Schmitt stic-source@gmx.net and
provided to you without any warranty under an open source BSD license.
(see file COPYING)

