/*
** Copyright (C) 2001-2011 by Carnegie Mellon University.
**
** @OPENSOURCE_HEADER_START@
**
** Use of the SILK system and related source code is subject to the terms
** of the following licenses:
**
** GNU Public License (GPL) Rights pursuant to Version 2, June 1991
** Government Purpose License Rights (GPLR) pursuant to DFARS 252.227.7013
**
** NO WARRANTY
**
** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER
** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY
** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN
** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT
** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE,
** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE
** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT,
** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY
** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF
** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES.
** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF
** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON
** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE
** DELIVERABLES UNDER THIS LICENSE.
**
** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie
** Mellon University, its trustees, officers, employees, and agents from
** all claims or demands made against them (and any related losses,
** expenses, or attorney's fees) arising out of, or relating to Licensee's
** and/or its sub licensees' negligent use or willful misuse of or
** negligent conduct or willful misconduct regarding the Software,
** facilities, or other rights or assistance granted by Carnegie Mellon
** University under this License, including, but not limited to, any
** claims of product liability, personal injury, death, damage to
** property, or violation of any laws or regulations.
**
** Carnegie Mellon University Software Engineering Institute authored
** documents are sponsored by the U.S. Department of Defense under
** Contract FA8721-05-C-0003. Carnegie Mellon University retains
** copyrights in all material produced under this contract. The U.S.
** Government retains a non-exclusive, royalty-free license to publish or
** reproduce these documents, or allow others to do so, for U.S.
** Government purposes only pursuant to the copyright license under the
** contract clause at 252.227.7013.
**
** @OPENSOURCE_HEADER_END@
*/
#ifndef _DYNLIB_H
#define _DYNLIB_H

#include <silk/silk.h>

RCSIDENTVAR(rcsID_DYNLIB_H, "$SiLK: dynlib.h 16752 2011-02-24 17:41:51Z mthomas $");

#include <silk/utils.h>
#include <silk/skplugin.h>


/*
 *    Each plug-in should define a dynlib_api_version() routine that
 *    returns this value.  This allows the application to skip an old
 *    plug-in without a SEGV.
 */
#define DYNLIB_API_VERSION  5


/*
 *    The plug-in's setup() method should return on of these values,
 *    as explained below.
 */
#define DYNLIB_FAILED       1
#define DYNLIB_WILLPROCESS  2
#define DYNLIB_WONTPROCESS  3


/*
 *  dynlib provides an interface to C-plug-ins---dynamic libraries
 *  loaded at run time.
 *
 *  TO USE A PLUG-IN:
 *
 *  The application that wants to use a plug-in does the following:
 *
 *  1. Calls dynlibCreate(appType) where 'appType' is one of the
 *  symbols listed in the 'dynlibSymbolId' enumeration and describes
 *  the type of the application; this function will return an
 *  interface pointer, 'dlISP'.
 *
 *  2. Calls dynlibLoad(dlISP, path) where 'path' is the path to the
 *  dynamic library.  If 'path' does not contain a slash, dynlibLoad()
 *  will first look for the plug-in
 *  $SILK_PATH/SILK_SUBDIR_PLUGINS/path.  If that fails (or if 'path'
 *  contains a slash), 'path' is handed to dlopen() unaltered.
 *  dlopen() may consult LD_LIBRARY_PATH (or similar).  If dlopen()
 *  fails, DYNLIB_FAILED is returned.
 *
 *  If dlopen() succeeds, dynlibLoad() will verify that the plug-in's
 *  version matches the DYNLIB_API_VERSION given above and that the
 *  plug-in has all the required subroutines.  If it does not,
 *  DYNLIB_FAILED is returned.  Finally, dynlibLoad() will call the
 *  plug-in's setup() method and the result of that method is returned
 *  to the caller.  The details of the setup() method are described
 *  below.
 *
 *  2a. Should the application desire to print any options associated
 *  with the plug-in, it may call dynlibOptionsUsage(dlISP) which will
 *  call the plug-in's optionsUage() method, if it exists.
 *
 *  3. Some plug-ins may require additional configuration prior to
 *  options handling.  The dynlibConfigure() method will call the
 *  plug-in's configure() method, if it exists.
 *
 *  4. Once the application has called the options parser, it can use
 *  dynlibCheckActive(dlISP) to see if the plug-in should be called as
 *  part of the application's processing--some applications only
 *  become active when the user specifies an option related to the
 *  plug-in.  Some applications may have to explicitly initialize and
 *  activate the plug-in by calling the dynlibInitialize() method.
 *
 *  5. If the plug-in is active, dynlibGetRWProcessor(dlISP) returns a
 *  pointer to the function that the application should call.  For a
 *  filtering application, dynlibGetRWProcessor() returns a pointer to
 *  the plug-in's filter() subroutine.
 *
 *  6. Once processing is completed, the application should call
 *  dynlibTeardown(dlISP) which will free the dlISP data structure and
 *  call teardown() on the plug-in.
 *
 *
 *
 *  TO BE A PLUG-IN:
 *
 *  The code that expects to by used by the dynlib interface must
 *  provide the following C subroutines:
 *
 *  - int setup(dynlibInfoStruct_t *dlISP, dynlibSymbolId appType);
 *
 *    This subroutine should set up the plug-in; if the plug-in has its
 *    own options, they can to be registered now.  setup() should
 *    return one of:
 *
 *      DYNLIB_FAILED - if processing fails
 *      DYNLIB_WONTPROCESS - if application should do normal output
 *      DYNLIB_WILLPROCESS - if this plug-in takes over output
 *
 *  - void teardown(dynlibSymbolId appType);
 *
 *    Any cleanup the plug-in requires should happen in this
 *    subroutine.
 *
 *  In addition, the following subroutines MAY exist in the plug-in:
 *
 *  - int dynlib_api_version(void) { return DYNLIB_API_VERSION; }
 *
 *    This subroutine, if it exists, is called first to verify that
 *    the plug-in and application are using a common API.  If it does
 *    not exist, the application will assume the APIs are correct.
 *
 *  - int configure(dynlibInfoStruct_t *dlISP, void *data);
 *
 *    This subroutine is optional.  It provides a way to pass
 *    arbitrary data between the plug-in and the application.  It is
 *    often used as an alternate way to configure the options.  The
 *    exact purpose of this routine will depend on the application and
 *    the plug-in.
 *
 *  - int initialize(dynlibInfoStruct_t *dlISP, dynlibSymbolId appType);
 *
 *    This subroutine should do any "expensive" initialization
 *    required by the plug-in in preparation for calling one of the
 *    interface subroutines listed below.
 *
 *  - void optionsUsage(dynlibSymbolId appType, FILE *fh);
 *
 *    If the plug-in has registered options, this subroutine should
 *    print a them and a short usage message to the given file handle.
 *
 *  To be used by an application type, the plug-in must provide the
 *  necessary interface subroutine.  The interface routine depends on
 *  the 'appType' that is specified in the dynlibCreate() call that
 *  the application makes:
 *
 *  DYNLIB_SHAR_FILTER: used by rwfilter
 *    int filter(rwRec *rwRec);
 *
 *    This subroutine works in tadem with the standard filtering rules
 *    of rwfilter (and other shared filter plug-ins) to determine
 *    whether the rwRec should pass the filter.  This subroutine may
 *    not see all rwRec records since they may be filtered by one of
 *    the standard rules before reaching this plug-in.  The subroutine
 *    should return 0 if the rwRec passes the filter; 1 otherwise.
 *
 *    The dynlib plug-in code will call this filter() routine ONCE per
 *    SiLK Flow record.  If a single plug-in provides multiple
 *    filtering switches, the plug-in must pass the record through all
 *    of the applicable filtering tests before returning.
 *
 *    If the filter() function is not present, the check() function
 *    will be used instead if available.  This is to support older
 *    plug-ins, and this functionality should not be relied upon.
 *
 *  DYNLIB_EXCL_FILTER: used by rwfilter
 *    int check(rwRec *rwRec);
 *
 *    Obsolete.  Has the same functionality as DYNLIB_SHAR_FILTER.
 *
 *  DYNLIB_CUT: used by rwcut
 *    int cut(unsigned int f, char *out, size_t len_out, rwRec *rwrec)
 *
 *  Arguments:
 *      f:       which field to output (indexed from 1)
 *      out:     a string buffer to hold the output
 *      len_out: the length of the string buffer 'out'
 *      rwrec:   a SiLK flow record
 *  Returns:
 *      when 'f' is zero
 *        => the number of supported fields
 *      when 'f' is non-zero
 *        when 'out' is NULL and 'len_out' has any value
 *          when 'rwrec' is NULL
 *            => the size of buffer needed to hold the complete title
 *              of field 'f'
 *          when 'rwrec' is non-NULL
 *            => the size of buffer needed to hold the longest
 *               possible (textual) value of field 'f'
 *        when 'out' is non-NULL
 *          when 'rwrec' is NULL
 *            => length of buffer necessary to hold full title; writes
 *               the first 'len_out'-1 bytes of the title of field 'f'
 *               into 'out'
 *          when 'rwrec' is non-NULL
 *            => length of buffer necessary to hold full textual
 *               value; writes the first 'len_out'-1 bytes of the
 *               textual value of field 'f' into 'out'
 *
 *
 *  DYNLIB_SORT: used by rwsort
 *    int sort(unsigned int f, uint8_t *bin_val, const rwRec *rec)
 *
 *  Arguments:
 *      f:        field to get the binary or textual value of
 *      bin_val:  buffer to fill with a binary value that rwsort will
 *                use for sorting; rwsort will not ask the plug-in for
 *                more data; this value should be everything rwsort
 *                needs to know.  rwsort will use memcmp() to compare
 *                values; the values should be in big-endian byte
 *                order.  THIS BUFFER MAY NOT BE WORD ALIGNED.
 *      rec:      SiLK flow record
 *  Returns:
 *      when 'f' is zero
 *        => the number of supported fields
 *      when 'f' is non-zero
 *        when 'bin_val' or 'rec' is NULL
 *          => the number of bytes required to hold the binary value
 *             of field 'f'
 *        when 'bin_val' and 'rec' are non-NULL
 *          => length of the binary value; uses 'rec' to compute the
 *             value of field 'f' and writes that binary value into
 *             'bin_val'.  ASSUMES 'bin_val' IS BIG ENOUGH!
 *
 *
 *  DYNLIB_UNIQ: used by rwuniq
 *    int uniq(unsigned int f, uint8_t *bin_val, char *text_val, size_t text_len, rwRec *rec)
 *
 *  Arguments:
 *      f:        field to get the binary or textual value of
 *      bin_val:  when reading SiLK records, this is an output buffer
 *                that this function fills with the binary value
 *                representing field 'f'; during output, rwuniq will
 *                use this parameter to pass a value into the function
 *                which the function should convert to text.  THIS
 *                BUFFER MAY NOT BE WORD ALIGNED.
 *      text_val: buffer to fill with the textual value
 *      text_len: length of the buffer 'text_val'
 *      rec:      SiLK flow record
 *  Returns:
 *      when 'f' is zero
 *        => the number of supported fields
 *      when 'f' is non-zero
 *        when 'bin_val' is NULL
 *          => the result of running cut(f, text_val, text_len, rwrec)
 *        when 'bin_val' is non-NULL
 *          when 'text_val' is non-NULL and 'rec' has any value
 *            => length of buffer necessary to hold the complete
 *               textual value; fills 'text_val' with the first
 *               'text_len'-1 bytes of converting the binary value in
 *               'bin_val', corresponding to field 'f', to text.
 *          when 'text_val' is NULL and 'text_len' has any value
 *            when 'rec' is non-NULL
 *              => length of the binary value; uses 'rec' to compute
 *                 the value of field 'f' and writes that binary value
 *                 into 'bin_val'.  ASSUMES 'bin_val' IS BIG ENOUGH!
 *             when 'rec' is NULL
 *               => the number of bytes required to hold the binary
 *                  value of field 'f'
 *
 *
 *  DYNLIB_PTOFLOW: used by rwptoflow
 *    int ptoflow(rwRec *a, void *pktsrc)
 *
 *  Arguments:
 *      the flow record to generate from packet data
 *      the packet source, packet header, and packet data
 *  Returns:
 *      0 to output the flow record but the application should check
 *        any additional dynamic libraries as well.
 *      1 to immediately output the flow record, bypassing any
 *        additional dynamic libraries
 *      2 to immediately output the packet into the 'packet reject'
 *        file, bypassing any additional dynamic libraries
 *      3 to immediately ignore the packet, outputing neither the flow
 *        record nor the packet, bypassing any additional dynamic
 *        libraries
 *  Side Effects:
 *      May modify the record to obfuscate the data it contains.
 *
 */


#if 0
/* THESE ARE HERE FOR REFERENCE ONLY.
 * skplugin.h defines these */
/*
 *  A list of application types.  One of these should be passed to
 *  dynlibCreate().
 */
typedef enum dynlibSymbolId_en {
    DYNLIB_SETUP,               /* internal use -- must be first*/
    DYNLIB_TEARDOWN,            /* internal use */
    DYNLIB_VERSION,             /* internal use */
    DYNLIB_CONFIGURE,           /* internal use */
    DYNLIB_INITIALIZE,          /* internal use */
    DYNLIB_OPT_USAGE,           /* internal use */
    DYNLIB_SUPPORTS_THREADS,    /* internal use */
    DYNLIB_EXCL_FILTER,         /* rwfilter: augment other filter rules */
    DYNLIB_SHAR_FILTER,         /* rwfilter: augment other filter rules */
    DYNLIB_CUT,                 /* rwcut: output of data */
    DYNLIB_SORT,                /* rwsort: orders records by attributes */
    DYNLIB_UNIQ,                /* rwuniq: bin records by attribute(s) */
    DYNLIB_PTOFLOW,             /* rwptoflow: create flow from packet data */
    DYNLIB_VOID                 /* internal use -- must be last */
} dynlibSymbolId;

/*
 *    Loads the plugin represented by the filename 'name' using the
 *    skplugin infrastructure.  Will handle legacy dynlib-style
 *    plugins. If complain_on_error is non-zero, error messages will
 *    be written to the error stream.
 */
skplugin_err_t skPluginLoadPluginOrDynlib(
    const char     *name,
    dynlibSymbolId  appType,
    int             complain_on_error);
#endif  /* 0 */


/*
 *  Pointer to function returning int---the actual argument list
 *  varies by function.  We store an array of these in the
 *  dynlibInfoStruct_t, and it is the return type of
 *  dynlibGetRWProcessor().
 */
typedef int (*dynlib_fn_t)();


/*
 *  The structure that holds information about the plug-in.
 */
struct dynlibInfoStruct_st;
typedef struct dynlibInfoStruct_st dynlibInfoStruct_t;
typedef dynlibInfoStruct_t * dynlibInfoStructPtr;
#define dynlibInfoStruct dynlibInfoStruct_t


/*
 *  dynlibCreate:
 *      get space and initialize struct
 *  Inputs:
 *      The type of application
 *  Outputs:
 *      dynlibInfoStruct_t *dlISP;
 */
dynlibInfoStruct_t *dynlibCreate(dynlibSymbolId appType);


/*
 *  dynlibLoad:
 *      check all stuff about potential dynamic lib: load the library
 *      and check that it has the necessary functions.  To find Call
 *      the dynamic library's setup() subroutine which may register
 *      options
 *  Input:
 *      dynlibInfoStruct_t *dlISP
 *      path to dyn lib
 *  Output:
 *      0 if ok; 1 else
 *  Side Effects:
 *      struct dlISP filled.
 */
int dynlibLoad(dynlibInfoStruct_t *dlISP, const char *dlPath);


/*
 *  dynlibConfigure
 *
 *      Do any additional setup/configuration by calling the plug-in's
 *      configure() method.  This function returns 0 if the plug-in
 *      has a configure() method, and 1 otherwise.  The return status
 *      of the confiugre() method is returned in *out_status.
 */
int dynlibConfigure(dynlibInfoStruct_t *dlISP, void *data);


/*
 *  dynlibInitialize:
 *      Call the dynamic library's initalize() subroutine.  The idea
 *      is to put expensive initialization code in the initialize()
 *      routine, and only call it once the application knows the
 *      dynamic library will be used.
 *
 *      Once the initialize() routine returns 0, this wrapper will not
 *      call it again; if you must call initialize() multiple times,
 *      use the dynlibClearInitialized() macro to clear the
 *      'initialized()-was-called' flag.
 *  Input:
 *      dynlibInfoStruct_t *dlISP
 *  Output:
 *      Returns 0 if
 *        -- initialized() does not exist, or
 *        -- initialized() returns 0, or
 *        -- initialized() previously returned 0
 *      Otherwise returns status of call to initialize()
 *  Side Effects:
 *      Depends on shared library
 */
int dynlibInitialize(dynlibInfoStruct_t *dlISP);


/*
 *  dynlibOptionsUsage:
 *      Calls the dynamic library's optionsUsage() subroutine
 *  Input:
 *      dynlibInfoStruct_t *dlISP
 *      FILE *fh
 *  Output:
 *      none
 *  Side Effects:
 *      Depends on shared library
 */
void dynlibOptionsUsage(dynlibInfoStruct_t *dlISP, FILE *fh);


/*
 *  dynlibSupportsThreads:
 *      Calls the dynamic library's supportsThreads() subroutine if it
 *      exists.
 *  Input:
 *      dynlibInfoStruct_t *dlISP
 *  Output:
 *      1 if threads are supported, 0 if they are not, -1 if the
 *      function does not provide that subroutine.
 *  Side Effects:
 *      Depends on shared library
 */
int dynlibSupportsThreads(dynlibInfoStruct_t *dlISP);


/*
 *  dynlibGetRWProcessor:
 *      Returns a pointer to the function applicable to this app-type;
 *      e.g., for DYNLIB_CUT returns a pointer to cut().  The
 *      existence of the function was checked in dynlibLoad
 *  Input:
 *      dynlibInfoStruct_t *dlISP
 *  Output:
 *      function ptr
 *  Side Effects:
 *      None.
 */
dynlib_fn_t dynlibGetRWProcessor(dynlibInfoStruct_t *dlISP);


/*
 *  dynlibTeardown:
 *      close and free mem
 *  Inputs:
 *      dynlibInfoStruct_t *dlISP
 *  Outputs:
 *      None
 */
void dynlibTeardown(dynlibInfoStruct_t *dlISP);


/*
 *  dynlibGetPath
 *      Return the path to the dynamic library
 *  Inputs:
 *      dynlibInfoStruct_t *dlISP
 *  Outputs:
 *      A \0 terminated string.  String should be considered
 *      read-only.  Returns the path passed to dlopen to open
 *      the dynamic library.
 *  Side Effects:
 *      None.
 */
const char *dynlibGetPath(const dynlibInfoStruct_t *dlIPS);


/*
 *  dynlibCheckLoaded
 *      Returns status of loading and checking the plug-in
 *  Inputs:
 *      dynlibInfoStruct_t *dlISP
 *  Outputs:
 *      Return 1 if the plug-in was successfully loaded and checked, 0
 *      otherwise.
 *  Side Effects:
 *      None.
 *  Notes:
 *      dlISP may be NULL
 */
int dynlibCheckLoaded(const dynlibInfoStruct_t *dlISP);


/*
 *  dynlibGetAppType
 *      Returns the application type as set in dynlibCreate()
 *  Inputs:
 *      dynlibInfoStruct_t *dlISP
 *  Outputs:
 *      The dynlibSymbolId for this application
 *  Side Effects:
 *      None.
 */
dynlibSymbolId dynlibGetAppType(const dynlibInfoStruct_t *dlISP);


/*
 *  dynlibGetStatus
 *      Return the status of the call to dynlibLoad()
 *  Inputs:
 *      dynlibInfoStruct_t *dlISP
 *  Outputs:
 *      An integer value of:
 *
 *      DYNLIB_FAILED - if processing fails
 *      DYNLIB_WONTPROCESS - if application should do normal output
 *      DYNLIB_WILLPROCESS - if this plug-in takes over output
 *  Side Effects:
 *      None.
 */
int dynlibGetStatus(const dynlibInfoStruct_t *dlISP);


/*
 *  dynlibGetAppContext
 *      Return the application context: a pointer to a struct
 *      containing the application's name and its options
 *
 *      Plug-ins should call skAppContextSet() with the value returned
 *      by this macro in their setup() routines.  This will ensure
 *      that the plug-in's options are in the application's main
 *      options structure.
 *
 *  Inputs:
 *      dynlibInfoStruct_t *dlISP
 *  Outputs:
 *      The global application context object, skAppContext_t*
 *  Side Effects:
 *      None.
 */
skAppContext_t *dynlibGetAppContext(const dynlibInfoStruct_t *dlISP);


/*
 *  dynlibCheckActive
 *      Return non-zero if this plug-in will be processing the
 *      rwRecPtr's and thus should be called.
 *  Inputs:
 *      dynlibInfoStruct_t *dlISP
 *  Outputs:
 *      The state of the active flag
 *  Side Effects:
 *      None.
 *  Notes:
 *      dlISP may be NULL
 */
int dynlibCheckActive(const dynlibInfoStruct_t *dlISP);


/*
 *  dynlibMakeActive
 *      Mark the plug-in as being active: i.e., the plug-in will be
 *      processing the rwRecPtr's
 *  Inputs:
 *      dynlibInfoStruct_t *dlISP
 *  Outputs:
 *      None.
 *  Side Effects:
 *      None.
 */
void dynlibMakeActive(dynlibInfoStruct_t *dlISP);


/*
 *  dynlibClearInitialized
 *      Clear the flag that indicates that the initialize() routine
 *      has been run.  See dynlibInitialize() for details.
 *  Inputs:
 *      dynlibInfoStruct_t *dlISP
 *  Outputs:
 *      None.
 *  Side Effects:
 *      None.
 */
void dynlibClearInitialized(dynlibInfoStruct_t *dlISP);


/*
 *  dynlibSetDoNotClose
 *      Set the do-not-close flag to TRUE.  This will prevent
 *      dlclose() from being called on the plug-in.  We do this do
 *      work around an Oracle problem with unloading libraries.
 *  Inputs:
 *      dynlibInfoStruct_t *dlISP
 *  Outputs:
 *      None.
 *  Side Effects:
 *      None.
 */
void dynlibSetDoNotClose(dynlibInfoStruct_t *dlISP);


/*
 *  dynlibLastError
 *      Return the most recent value from dlerror()
 *  Inputs:
 *      dynlibInfoStruct_t *dlISP
 *  Outputs:
 *      A \0 terminated string.  String should be considered
 *      read-only.  The string only contains a valid error message
 *      immediately after an error occurred.  At other times, the
 *      string may be empty or contain a previous error.
 *  Side Effects:
 *      None.
 */
const char *dynlibLastError(const dynlibInfoStruct_t *dlISP);


/*
 *  dynlibOpenDataInputStream
 *      Create an skstream_t object using the specified 'content_type'
 *      and 'filename', open it, and fill the location pointed to by
 *      'stream' with the object.  If the application has called
 *      dynlibSetOpenInputFunction(), that function will be used if it
 *      is non-null.
 *  Inputs:
 *      location in which to return address of skstream_t object
 *      content_type of the filename
 *      name of file to open
 *  Outputs:
 *      Returns 0 if stream was successfully opened and should be
 *      used.  Returns -1 on error.  Returns 1 if the plug-in should
 *      ignore the file.
 *  Side Effects:
 *      'stream' is filled with address of skstream_t object.
 */
int dynlibOpenDataInputStream(
    skstream_t        **stream,
    skcontent_t         content_type,
    const char         *filename);


#if 0
/*
 *  Type signature of the function that dynlibOpenDataInputStream()
 *  will call.
 */
typedef int (*open_data_input_fn_t)(
    skstream_t        **stream,
    skcontent_t         content_type,
    const char         *filename);
#endif


/*
 *  dynlibSetOpenInputFunction
 *      Sets the function that dynlibOpenDataInputStream() should for
 *      opening data files.  If this function is not called or called
 *      with a NULL parameter, the sequence of functions
 *      skStreamCreate(), skStreamBind(), skStreamOpen() is called.
 *  Inputs:
 *      function pointer to use for opening files
 *  Outputs:
 *      None.
 *  Side Effects:
 *      None.
 */
void dynlibSetOpenInputFunction(open_data_input_fn_t open_fn);


/* These are the functions on the plug-in that this code may call */
int dynlib_api_version(/*(void)*/);
int setup(/*(dynlibInfoStruct_t *dlISP, dynlibSymbolId appType)*/);
int configure(/*(dynlibInfoStruct_t *dlISP, void *data)*/);
void teardown(/*(dynlibSymbolId appType)*/);
void optionsUsage(/*(dynlibSymbolId appType, FILE *fh)*/);
int initialize(/*(dynlibInfoStruct_t *dlISP, dynlibSymbolId appType)*/);
int filter(/*(rwRec *rwrec)*/);
int cut(/*(unsigned int type, char *out, size_t len_out, rwRec *rwrec)*/);
int sort(/*(rwRec *a, rwRec *b)*/);
int uniq(/*(TO BE DECIDED)*/);
int ptoflow(/*(rwRec *rwrec, void *pktsrc)*/);


#endif /*  _DYNLIB_H */

/*
** Local Variables:
** mode:c
** indent-tabs-mode:nil
** c-basic-offset:4
** End:
*/
