harglists.h
上传用户:tjescc
上传日期:2021-02-23
资源大小:419k
文件大小:59k
源码类别:

Telnet服务器

开发平台:

Unix_Linux

  1. /*
  2.  *  Copyright (c) Nessus Consulting S.A.R.L., 2000 - 2001
  3.  *  Email: office@nessus.com
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License 
  16.  *  along with this library; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  $Id: harglists.h,v 1.20 2003/12/15 15:54:39 renaud Exp $
  20.  *
  21.  * Author: Jordan Hrycaj <jordan@mjh.teddy-net.com>
  22.  *
  23.  * Jordan re-wrote Renauds idea of an arglists management on top
  24.  * of the hash list manager
  25.  *
  26.  * --------------------------------------------------------------------
  27.  *
  28.  * There is a generic interface to symbolic run time variable managemet.
  29.  * Althoug opaque variable types are supported, the idea is to let the
  30.  * C language use type defs for checking data types as far a possible.
  31.  *
  32.  *
  33.  * 1. Basic data types supported:
  34.  * ==============================
  35.  *
  36.  * ANY:     It means no particular data type at all and is used in special
  37.  *          cases, only. HARG_ANY is frequently used when it is to be
  38.  *          expressed, that the access key for addressing the data is a ''
  39.  *          terminated chatacter string.
  40.  *
  41.  * STRING:  Such a data type is stored as a '' terminated character string
  42.  *        . It handled similar to a HARG_BLOB data type, but without need to
  43.  *          explicitely state the data length. The storage space for that
  44.  *          kind of data is fully handled by the system but can be mofified,
  45.  *          freely by a user. Once passed anc copied to the data storage of
  46.  *          the system, the '' termination character will not be used,
  47.  *          anymore.
  48.  *
  49.  * NSTRING: Not a real data type but rather data of STRING type with
  50.  *          predefined length. Internally, a '' terminator will be
  51.  *          appended logically ending up with data of type HARG_STRING.
  52.  *
  53.  * BLOB:    Considered similar as HARG_STRING but without the terminating
  54.  *          '', this data type is seen as a Binary Large OBject of bytes
  55.  *          without knowing an internal data structure. The storage space
  56.  *          for that kind of data is fully handled by the system but can be
  57.  *          mofified, freely by a user.
  58.  *
  59.  * PTR      This is a scalar data type and is stored as a (var*)pointer.
  60.  *
  61.  * INT      This is a scalar data type and is stored as a integer.
  62.  *
  63.  * HARG     This type of data is stored similar to a HARG_PTR.  Addressing
  64.  *          such a data record always implies the whole data tree rooted by
  65.  *          this particular data record.
  66.  *
  67.  * These data types above are indexed by a '' terminated character string,
  68.  * which pretty much refers to the notion of a variable name. There is
  69.  * another set of data types describing the same contents as stated abuve.
  70.  *
  71.  * The difference is, that these data types are addressed by a reference
  72.  * to a (void*)pointer, rather than a variable name. Formally, you use
  73.  * the same key argument when addressing such a variable. By using other
  74.  * data types the software knows when to process pointer reference rather
  75.  * than a '' terminated character string, 
  76.  *
  77.  * PANY     no data type, stands for any data type using a (void*)key type
  78.  *
  79.  * PSTRING  like STRING, but using a (void*)key type
  80.  *
  81.  * PNSTRING like NSTRING, but using a (void*)key type
  82.  *
  83.  * PPTR     like PTR, but using a (void*)key type
  84.  *
  85.  * PINT     like INT, but using a (void*)key type
  86.  *
  87.  * PBLOB    like BLOB, but using a (void*)key type
  88.  *
  89.  * PHARG    like HARG, but using a (void*)key type
  90.  *
  91.  *
  92.  * 1.1 Posix thread support:
  93.  * -------------------------
  94.  *
  95.  * There is no thread support other than running different lists on each
  96.  * thread.  The same harg list descriptor must not e used concurrently.
  97.  * Using the concept remote lists (see chapter 3), there are several
  98.  * models of, how to share and optimize access to a remote list.
  99.  *
  100.  * A remote list can be run locally, so the remoteness is rather virtual
  101.  * than really on another process, but you do not need to know really as
  102.  * the only difference is the response time when accessing data.
  103.  *
  104.  * Running a remote harg list locallly is available without any furher
  105.  * maintenance and actions (see the directive harg_attach() on chapter 14.)
  106.  *
  107.  *
  108.  *
  109.  *
  110.  * 2. Standard error codes
  111.  * =======================
  112.  *
  113.  * When an error is detectes, the global variable errno is set to some
  114.  * error code. While most specific error codes are application dependent,
  115.  * there are some standard codes explained here.
  116.  *
  117.  * 2.1 common error codes:
  118.  * - - - - - - - - - - - -
  119.  *
  120.  *    ENOENT    There was no such record found matching the particular key,
  121.  *              or index..
  122.  * 
  123.  *    EPERM     Although a record matched the particular key, or index it
  124.  *              must not be used due to a failed type check.
  125.  *
  126.  *    EEXISTS   The record could not be created as it was present,
  127.  *              already, eg. when creating exclusively.
  128.  *
  129.  *    EINVAL    Illegal function arguments, as a NULL list descriptor etc.
  130.  *
  131.  *    ELOOP     Recursion to deep when doing some action, eg. on lists
  132.  *              having sublists where a sublist has the root list as a
  133.  *              sublist, see the symbol HLST_MAX_RDEPTH, below.
  134.  *
  135.  *    EAGAIN    Some condition that is considerd impossible, as being unable
  136.  *              to create a new list entry despite the fact, that such an
  137.  *              entry does not exist, yet--try again or abort.
  138.  *
  139.  *    ENOEXEC   Some internal function was called with invalid arguments
  140.  *              (see also ENOEXEC on section 2.2, below)
  141.  *
  142.  * 2.2 error codes with remote lists:
  143.  * - - - - - - - - - - - - - - - - -
  144.  *
  145.  *    EIDRM     The record was marked tainted and is not allowed to be
  146.  *              used in this list.
  147.  *
  148.  *    ENOEXEC   Some call back function on the server was called with
  149.  *              invalid arguments (internal, will be logged on the server)
  150.  *
  151.  *    EBADF     The remote list does not exist (somebody removed it?,
  152.  *              error will be logged on the server)
  153.  *
  154.  *    EBADSLT   The current slot for remote list is currupt and will be
  155.  *              removed (internal error, will be logged on the server)
  156.  *
  157.  *    EFAULT    Bad data record on the remote server (internal error,
  158.  *              should be logged on the server)
  159.  *
  160.  *    EIO       Unspeciefied communication or server error when refering
  161.  *              to the remote archive (will be logged, if detailed
  162.  *              information is available)
  163.  *
  164.  *
  165.  *
  166.  *
  167.  * 3. Remote behavior/cache strategies:
  168.  * ===================================
  169.  *
  170.  * Accessing data on a list declared remote depends on the cache strategy,
  171.  * currently used.
  172.  *
  173.  * 3.4.1 transparent write (H_sWRTHRU):
  174.  * - - - - - - - - -  - - - - - - - - -
  175.  *
  176.  * On adding, deleting, or modifying a single record, the action always
  177.  * takes place remotely and the local list is updated, afrewards. Unless
  178.  * otherwise noted, an action on a single record (not of type HARG, or 
  179.  * PHARG refering to a sublist) on a reomte list is always atomic. 
  180.  *
  181.  * 3.4.2 remote defaults (neither transparent read or write):
  182.  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  183.  *
  184.  * The local list is updated from the remote list only if there was
  185.  * no record present, locally. After that, local modification takes
  186.  * place without remote update.
  187.  *
  188.  * Even on deleting when there is no local record, present an update
  189.  * from the remote list might be necessary when type checking is required
  190.  * (which is a weird operation in that context, anyway.)
  191.  *
  192.  *
  193.  *
  194.  *
  195.  * 4. List construction/destruction:
  196.  * =================================
  197.  *
  198.  * harglst*   harg_create              (unsigned estimated_size);
  199.  * harglst*   harg_dup       (harglst*, unsigned estimated_size);
  200.  * void       harg_close     (harglst*);
  201.  * void       harg_close_all (harglst*);
  202.  * void       harg_purge     (harglst*);
  203.  * void       harg_purge_all (harglst*);
  204.  *
  205.  * Both, harg_create() and harg_dup() create new variable lists, the latter
  206.  * function copies the access tree for that list, recursively (see 
  207.  * HARG_HARGLST, above.)
  208.  *
  209.  * The functions harg_close()/harg_close_all() destroy lists locally,
  210.  * the function harg_close_all() destroys all sublists, recursively.
  211.  *
  212.  * The functions harg_purge()/harg_purge_all() act locally the same way as
  213.  * the harg_close()/harg_close_all(), if applied on a remote list, it is
  214.  * destroyed, as well.
  215.  *
  216.  *
  217.  * 4.1 Return value
  218.  * ----------------
  219.  *
  220.  * The return value for harg_create() and harg_dup() are new list pointers,
  221.  * The function harg_create() never returns NULL, but harg_dup() may do
  222.  * when an error occurs while the variable errno is set to some error code.
  223.  *
  224.  * 4.1.1 error codes:
  225.  * - - - - - - - - - 
  226.  *
  227.  *    ELOOP     Recursion to deep when copying the list
  228.  *
  229.  *    see also chapter 2.
  230.  *
  231.  *
  232.  * 4.2 Remote lists
  233.  * ----------------
  234.  *
  235.  * Even if applied on a remote list, the result of harg_dup() is a local
  236.  * list.  And the result of harg_create() is always a local list.
  237.  *
  238.  * 
  239.  *
  240.  *
  241.  * 5. Adding data:
  242.  * ===============
  243.  *
  244.  * hargkey_t *harg_add_string          (harglst*,hargkey_t*,          char*);
  245.  * hargkey_t *harg_add_nstring         (harglst*,hargkey_t*, unsigned,char*);
  246.  * hargkey_t *harg_add_blob            (harglst*,hargkey_t*, unsigned,void*);
  247.  * hargkey_t *harg_add_ptr             (harglst*,hargkey_t*, void*);
  248.  * hargkey_t *harg_add_int             (harglst*,hargkey_t*  int);
  249.  * hargkey_t *harg_add_harg            (harglst*,hargkey_t*  harglst*)
  250.  *
  251.  * hargkey_t *harg_add_pstring         (harglst*,     void*,          char*);
  252.  * hargkey_t *harg_add_pnstring        (harglst*,     void*, unsigned,char*);
  253.  * hargkey_t *harg_add_pblob           (harglst*,     void*, unsigned,void*);
  254.  * hargkey_t *harg_add_pptr            (harglst*,     void*, void*);
  255.  * hargkey_t *harg_add_pint            (harglst*,     void*, int);
  256.  * hargkey_t *harg_add_pharg           (harglst*,     void*, harglst*)
  257.  *
  258.  * hargkey_t *harg_add_default_string  (harglst*,hargkey_t*,          char*);
  259.  * hargkey_t *harg_add_default_nstring (harglst*,hargkey_t*, unsigned,char*);
  260.  * hargkey_t *harg_add_default_blob    (harglst*,hargkey_t*, unsigned,void*);
  261.  * hargkey_t *harg_add_default_ptr     (harglst*,hargkey_t*, void*);
  262.  * hargkey_t *harg_add_default_int     (harglst*,hargkey_t*  int);
  263.  * hargkey_t *harg_add_default_harg    (harglst*,hargkey_t*  harglst*)
  264.  *
  265.  * hargkey_t *harg_add_default_pstring (harglst*,     void*,          char*);
  266.  * hargkey_t *harg_add_default_pnstring(harglst*,     void*, unsigned,char*);
  267.  * hargkey_t *harg_add_default_pblob   (harglst*,     void*, unsigned,void*);
  268.  * hargkey_t *harg_add_default_pptr    (harglst*,     void*, void*);
  269.  * hargkey_t *harg_add_default_pint    (harglst*,     void*  int);
  270.  * hargkey_t *harg_add_default_pharg   (harglst*,     void*  harglst*)
  271.  *
  272.  * Using these functions, some typed data entry is added to the list. The
  273.  * arguments to these fuctions are all similar
  274.  *
  275.  *    <active-list>, <key>, <data ...>
  276.  *
  277.  * where the key type and the data argumments depend on the function name
  278.  * assembled as
  279.  *
  280.  *    "harg_" <action-to-be-performed> "_" <lower-case-data-type>
  281.  *
  282.  * For an explanation of the data types and the particular key format,
  283.  * see chapter 1.
  284.  *
  285.  * As a particular feature, a string with given length (nstring) or a blob
  286.  * might be passed with a NULL pointer.  In this case, a zero data block of
  287.  * the corresponding length is assumed.
  288.  *
  289.  *
  290.  * 4.1 <action-to-be-performed> == "add_default"
  291.  * ---------------------------------------------
  292.  *
  293.  * If an entry with the given key exists, already, the harg_add_default_*()
  294.  * directive will have no effect. Othewise the data specified with the last
  295.  * arguments are stored as defined in chapter 1.
  296.  *
  297.  *
  298.  * 4.2 <action-to-be-performed> == "add"
  299.  * -------------------------------------
  300.  *
  301.  * These functions always overwrite any exixting entry and will store the data
  302.  * specified with the last as defined in chapter 1.
  303.  *
  304.  *
  305.  * 4.3 Return value
  306.  * ----------------
  307.  *
  308.  * The return value is always a pointer to a copy of the second argument,
  309.  * which is the access key which is guaranteed to exists on the same memory
  310.  * location provided:
  311.  * 
  312.  *   + the table entry exists without being overwitten or removed
  313.  *   + the list is not declared remote with cache flushing, enabled.
  314.  *
  315.  * There is no way to check, whether data record has been overwritten other
  316.  * than testing it before it is added.
  317.  *
  318.  * Upon error NULL is returned variable errno is set to some error code.
  319.  *
  320.  *
  321.  *
  322.  *
  323.  * 6. Deleting symbolically accessed data:
  324.  * =======================================
  325.  *
  326.  * int harg_remove         (harglst*,hargkey_t*);
  327.  *
  328.  * int harg_remove_string  (harglst*,hargkey_t*);
  329.  * int harg_remove_blob    (harglst*,hargkey_t*);
  330.  * int harg_remove_ptr     (harglst*,hargkey_t*);
  331.  * int harg_remove_int     (harglst*,hargkey_t*);
  332.  * int harg_remove_harg    (harglst*,hargkey_t*);
  333.  * int harg_remove_any     (harglst*,hargkey_t*);
  334.  *
  335.  * int harg_remove_pstring (harglst*,hargkey_t*);
  336.  * int harg_remove_pblob   (harglst*,hargkey_t*);
  337.  * int harg_remove_pptr    (harglst*,hargkey_t*);
  338.  * int harg_remove_pint    (harglst*,hargkey_t*);
  339.  * int harg_remove_pharg   (harglst*,hargkey_t*);
  340.  * int harg_remove_pany    (harglst*,hargkey_t*);
  341.  *
  342.  * Using these functions, some typed data entry is removed from the list. 
  343.  * The arguments to these fuctions are all similar
  344.  *
  345.  *    <active-list>, <key>
  346.  *
  347.  * where the key type and the data argumments depend on the function name
  348.  * assembled as
  349.  *
  350.  *    "harg_remove_" <lower-case-data-type>
  351.  *
  352.  * For an explanation of the data types and the particular key format,
  353.  * see chapter 1.
  354.  *
  355.  * The particular function harg_remove() is a shortcut for the function
  356.  * harg_remove_any(). If the function matches type and key in the list,
  357.  * the entry is removed.
  358.  *
  359.  *
  360.  * 6.1 Return value
  361.  * ----------------
  362.  *
  363.  * The return value is always a 0, if an entry could be deleted and
  364.  * -1, otherwise while the variable errno is set to some error code.
  365.  *
  366.  *
  367.  * 6.2 Remark
  368.  * ----------
  369.  *
  370.  * Using either function harg_remove_type() or harg_remove_pany() is
  371.  * generally more efficient than the other functions.  This is because
  372.  * no spacufic data type must be compared.
  373.  *
  374.  *
  375.  *
  376.  *
  377.  * 7. Modifying the data contents:
  378.  * ===============================
  379.  *
  380.  * int harg_set_string   (harglst*,hargkey_t*,          char*);
  381.  * int harg_set_nstring  (harglst*,hargkey_t*, unsigned,char*);
  382.  * int harg_set_blob     (harglst*,hargkey_t*, unsigned,void*);
  383.  * int harg_set_ptr      (harglst*,hargkey_t*, void*);
  384.  * int harg_set_int      (harglst*,hargkey_t*, int);
  385.  * int harg_set_harg     (harglst*,hargkey_t*, harglst*);
  386.  *
  387.  * int harg_set_pstring  (harglst*,hargkey_t*,          char*);
  388.  * int harg_set_pnstring (harglst*,hargkey_t*, unsigned,char*);
  389.  * int harg_set_pblob    (harglst*,hargkey_t*, unsigned,void*);
  390.  * int harg_set_pptr     (harglst*,hargkey_t*, void*);
  391.  * int harg_set_pint     (harglst*,hargkey_t*, int);
  392.  * int harg_set_pharg    (harglst*,hargkey_t*, harglst*);
  393.  *
  394.  * An existing table entry is assigned a new value.  The directive
  395.  * will not do some type checking against the internal data type.
  396.  *
  397.  * The arguments to these fuctions are all similar
  398.  *
  399.  *    <active-list>, <key>, <data ...>
  400.  *
  401.  * where the key type and the data argumments depend on the function name
  402.  * assembled as
  403.  *
  404.  *    "harg_set_" <lower-case-data-type>
  405.  *
  406.  * For an explanation of the data types and the particular key format,
  407.  * see chapter 1.
  408.  *
  409.  * As a particular feature, a string with given length (nstring) or a blob
  410.  * might be passed with a NULL pointer.  In this case, a zero data block of
  411.  * the corresponding length is assumed.
  412.  *
  413.  *
  414.  * 7.1 Return value
  415.  * ----------------
  416.  *
  417.  * The return value is always a 0, if an entry could be changed and
  418.  * -1, otherwise while the variable errno is set to some error code.
  419.  *
  420.  *
  421.  *
  422.  *
  423.  * 8. Modifying the data type:
  424.  * ===========================
  425.  *
  426.  * int harg_name_set_string  (harglst*,hargkey_t*,hargkey_t*);
  427.  * int harg_name_set_blob    (harglst*,hargkey_t*,hargkey_t*);
  428.  * int harg_name_set_ptr     (harglst*,hargkey_t*,hargkey_t*);
  429.  * int harg_name_set_int     (harglst*,hargkey_t*,hargkey_t*);
  430.  * int harg_name_set_harg    (harglst*,hargkey_t*,hargkey_t*);
  431.  * int harg_name_set_any     (harglst*,hargkey_t*,hargkey_t*);
  432.  *
  433.  * int harg_name_set_pstring (harglst*,hargkey_t*,hargkey_t*);
  434.  * int harg_name_set_pblob   (harglst*,hargkey_t*,hargkey_t*);
  435.  * int harg_name_set_pptr    (harglst*,hargkey_t*,hargkey_t*);
  436.  * int harg_name_set_pint    (harglst*,hargkey_t*,hargkey_t*);
  437.  * int harg_name_set_pharg   (harglst*,hargkey_t*,hargkey_t*);
  438.  * int harg_name_set_pany    (harglst*,hargkey_t*,hargkey_t*);
  439.  *
  440.  * int harg_type_set_string  (harglst*,hargkey_t*);
  441.  * int harg_type_set_blob    (harglst*,hargkey_t*);
  442.  * int harg_type_set_ptr     (harglst*,hargkey_t*);
  443.  * int harg_type_set_int     (harglst*,hargkey_t*);
  444.  * int harg_type_set_harg    (harglst*,hargkey_t*);
  445.  *
  446.  * int harg_type_set_pstring (harglst*,hargkey_t*);
  447.  * int harg_type_set_pblob   (harglst*,hargkey_t*);
  448.  * int harg_type_set_pptr    (harglst*,hargkey_t*);
  449.  * int harg_type_set_pint    (harglst*,hargkey_t*);
  450.  * int harg_type_set_pharg   (harglst*,hargkey_t*);
  451.  *
  452.  * These functions redefine an existing type of a table entry to a new data
  453.  * type. It only works among the same type groups scalar (ptr, harg, and int)
  454.  * or object (blob and string.)  This means for example, you  can change a
  455.  * blob to a string type and vice versa, but not to a ptr or int type.
  456.  * 
  457.  * The arguments to these fuctions are all similar
  458.  *
  459.  *    <active-list>, <key>
  460.  *
  461.  * where the key type depends on the function name assembled as
  462.  *
  463.  *    "harg_type_set_" <lower-case-data-type>
  464.  *
  465.  * For an explanation of the data types and the particular key format,
  466.  * see chapter 1.
  467.  *
  468.  *
  469.  * 8.1 Return value
  470.  * ----------------
  471.  *
  472.  * The return value is always a 0, if an entry could be changed and
  473.  * -1, otherwise while the variable errno is set to some error code.
  474.  *
  475.  *
  476.  *
  477.  *
  478.  * 9. Increment and decrement operations:
  479.  * ======================================
  480.  *
  481.  * int harg_inc    (harglst*,hargkey_t*);
  482.  * int harg_dec    (harglst*,hargkey_t*);
  483.  * int harg_inc0   (harglst*,hargkey_t*);
  484.  * int harg_dec0   (harglst*,hargkey_t*);
  485.  * int harg_inc1   (harglst*,hargkey_t*);
  486.  * int harg_dec1   (harglst*,hargkey_t*);
  487.  *
  488.  * int harg_pinc   (harglst*,hargkey_t*);
  489.  * int harg_pdec   (harglst*,hargkey_t*);
  490.  * int harg_pinc0  (harglst*,hargkey_t*);
  491.  * int harg_pdec0  (harglst*,hargkey_t*);
  492.  * int harg_pinc1  (harglst*,hargkey_t*);
  493.  * int harg_pdec1  (harglst*,hargkey_t*);
  494.  *
  495.  * int harg_incn   (harglst*,hargkey_t*, int);
  496.  * int harg_decn   (harglst*,hargkey_t*, int);
  497.  * int harg_inc0n  (harglst*,hargkey_t*, int);
  498.  * int harg_dec0n  (harglst*,hargkey_t*, int);
  499.  * int harg_inc1n  (harglst*,hargkey_t*, int);
  500.  * int harg_dec1n  (harglst*,hargkey_t*, int);
  501.  *
  502.  * int harg_pincn  (harglst*,hargkey_t*, int);
  503.  * int harg_pdecn  (harglst*,hargkey_t*, int);
  504.  * int harg_pinc0n (harglst*,hargkey_t*, int);
  505.  * int harg_pdec0n (harglst*,hargkey_t*, int);
  506.  * int harg_pinc1n (harglst*,hargkey_t*, int);
  507.  * int harg_pdec1n (harglst*,hargkey_t*, int);
  508.  *
  509.  * These operationa act upon integer data types, only. The arguments to 
  510.  * these fuctions are all similar
  511.  *
  512.  *    <active-list>, <key>, [ <increment> ]
  513.  *
  514.  * where the key type and the data argumments depend on the function name
  515.  * assembled as
  516.  *
  517.  *    "harg_" <key-type> <modification-type> <special-action> <offset>
  518.  *
  519.  * where
  520.  *
  521.  *    <key-type>           ::=    "" | "p"
  522.  *    <modification-type>  ::= "inc" | "dec"
  523.  *    <special-action>     ::=    "" | "0"   | "1"
  524.  *    <offset>             ::=    "" | "n" 
  525.  *
  526.  * If the <key-type> is "p", a (void*)  pointer argument key type is
  527.  * expected, 
  528.  *
  529.  * On <modification-type> "inc", the data are to be incremented, on
  530.  * "dec" the data are to be decremented.
  531.  *
  532.  * If the <offset> is "n", an extra integer argument with the increment
  533.  * or decrement distance is expected.  Otherwise this value is assumed 1.
  534.  *
  535.  * If the <special-action> is "", nothing particular happens but the
  536.  * value of the data record will be inremented, or decrement.
  537.  *
  538.  * If the <special-action> is "0", a data record will be created
  539.  * automatically upon incementing if it is missing, and deleted 
  540.  * automatically if the result of the decrement would be smaller or
  541.  * equal zero.
  542.  *
  543.  * If the <special-action> is "1", a data record will be created 
  544.  * automatically upon incementing when it is missing, but it is an error
  545.  * if a record it exists and has non-zero value.  Upon decrementing, the
  546.  * data record will be deleted when it becomes zero, but it is an error 
  547.  * if the decrement operation would become smaller zero.
  548.  *
  549.  *
  550.  * 9.1 Return value
  551.  * ----------------
  552.  *
  553.  * The return value is always a integer value of the data record after
  554.  * the increment or decrement operation if no error occurs. If an error
  555.  * occurs, -1 is returned while the global variable errno is set to a
  556.  * non-zero error code.
  557.  *
  558.  *
  559.  *
  560.  *
  561.  *
  562.  * 10. Retrieving data:
  563.  * ====================
  564.  *
  565.  * void      *harg_get         (harglst*, hargkey_t*);
  566.  *
  567.  * char      *harg_get_string  (harglst*, hargkey_t*);
  568.  * void      *harg_get_blob    (harglst*, hargkey_t*);
  569.  * void      *harg_get_ptr     (harglst*, hargkey_t*);
  570.  * int        harg_get_int     (harglst*, hargkey_t*);
  571.  * harglst   *harg_get_harg    (harglst*, hargkey_t*);
  572.  * void      *harg_get_any     (harglst*, hargkey_t*);
  573.  *
  574.  * char      *harg_get_string  (harglst*, hargkey_t*);
  575.  * void      *harg_get_blob    (harglst*, hargkey_t*);
  576.  * void      *harg_get_ptr     (harglst*, hargkey_t*);
  577.  * int        harg_get_int     (harglst*, hargkey_t*);
  578.  * harglst   *harg_get_harg    (harglst*, hargkey_t*);
  579.  * void      *harg_get_pany    (harglst*, hargkey_t*);
  580.  *
  581.  * These functions realize access to the tata contents.  The arguments to
  582.  * these fuctions are all similar
  583.  *
  584.  *    <active-list>, <key>
  585.  *
  586.  * where the key type depends on the function name assembled as
  587.  *
  588.  *    "harg_type_get_" <lower-case-data-type>
  589.  *
  590.  * For an explanation of the data types and the particular key format,
  591.  * see chapter 1.
  592.  *
  593.  * If the function matches type and key in the list, an entry is returned.
  594.  *
  595.  * The particular function harg_get() is a shortcut for the function
  596.  * harg_get_any().
  597.  *
  598.  *
  599.  * 10.1 Return value
  600.  * ----------------
  601.  *
  602.  * The return value is the appropriate data value as indicated by the last
  603.  * part of the function name. With the particular functions  harg_get_any()
  604.  * and  harg_get_pany(), a generic data type is returned to be casted,
  605.  * appropriately.
  606.  *
  607.  * If an error occurs, NULL of 0 is returned while the global variable
  608.  * errno is set to some non-zero error code.
  609.  *
  610.  *
  611.  *
  612.  *
  613.  * 11. Retrieving meta data:
  614.  * ========================
  615.  *
  616.  * unsigned   harg_get_size     (harglst*,hargkey_t*);
  617.  * hargtype_t harg_get_type     (harglst*,hargkey_t*);
  618.  * int        harg_get_origin   (harglst*,hargkey_t*);
  619.  *
  620.  * unsigned   harg_get_psize    (harglst*,hargkey_t*);
  621.  * hargtype_t harg_get_ptype    (harglst*,hargkey_t*);
  622.  * int        harg_get_porigin  (harglst*,hargkey_t*);
  623.  *
  624.  * Internally, these functions work similar to the harg_get_any() and 
  625.  * harg_get_pany() functions described in chapter 8, only that meta 
  626.  * information retrieved rather than the data records themselves.
  627.  *
  628.  * The harg_get_size()/harg_get_psize() functions return the size of the
  629.  * internal data areea, for a scalar type, this is always sizeof (void*).
  630.  *
  631.  *
  632.  * The harg_get_type()/harg_get_ptype() functions return the data type.
  633.  *
  634.  * The harg_get_origin()/harg_get_porigin() functions return some
  635.  * internal flags, for a remoete record an 0 when the data are local,
  636.  * supported flags are
  637.  *
  638.  *    H_sREMOTE  -- record is from a remote list
  639.  *    H_sTAINTED -- tainted record eg.loaded from a server dump
  640.  *    H_sSTICKY  -- record cannot be flushed with the cache 
  641.  *    H_sWRTHRU  -- write through (and cache locally) 
  642.  *
  643.  *
  644.  *
  645.  *
  646.  * 12. Retrieving sorted records:
  647.  * ==============================
  648.  *
  649.  * hargkey_t *harg_get_nth         (harglst*,unsigned);
  650.  *
  651.  * hargkey_t *harg_get_nth_string  (harglst*,unsigned);
  652.  * hargkey_t *harg_get_nth_blob    (harglst*,unsigned);
  653.  * hargkey_t *harg_get_nth_ptr     (harglst*,unsigned);
  654.  * hargkey_t *harg_get_nth_int     (harglst*,unsigned);
  655.  * hargkey_t *harg_get_nth_harg    (harglst*,unsigned);
  656.  * hargkey_t *harg_get_nth_any     (harglst*,unsigned);
  657.  *
  658.  * hargkey_t *harg_get_nth_pstring (harglst*,unsigned);
  659.  * hargkey_t *harg_get_nth_pblob   (harglst*,unsigned);
  660.  * hargkey_t *harg_get_nth_pptr    (harglst*,unsigned);
  661.  * hargkey_t *harg_get_nth_pint    (harglst*,unsigned);
  662.  * hargkey_t *harg_get_nth_pharg   (harglst*,unsigned);
  663.  * hargkey_t *harg_get_nth_pany    (harglst*,unsigned);
  664.  *
  665.  * int harg_csort (harglst*, 
  666.  *                 int (*cmp_cb) (void *desc, harglst*
  667.  *                                hargkey_t *lKey, hargtype_t lType,
  668.  *                                hargkey_t *rKey, hargtype_t rType),
  669.  *                 void *desc);
  670.  *                              
  671.  * The harg_get_nth-functions treat the argument list (first argument)
  672.  * as an ordered one and retrieve the item with the order index given
  673.  * as second argument. The first index is 0.
  674.  *
  675.  * The returned key type depends on the function name assembled as
  676.  *
  677.  *    "harg_get_nth_" <lower-case-data-type>
  678.  *
  679.  * For an explanation of the data types and the particular key format,
  680.  * see chapter 1.
  681.  *
  682.  * If the function matches type and key in the list, an entry is returned.
  683.  *
  684.  * The particular function harg_get_nth() is a shortcut for the function
  685.  * harg_get_nth_any().
  686.  *
  687.  * Key sorting is usually done lexically upon the ASCII strings of a key.
  688.  * For a (void*)key type this is not unique as it depends on the big/little
  689.  * endian way of storing a pointer in memory.
  690.  *
  691.  * For custom sorting, a call back function might be installed using the
  692.  * harg_csort() request. This function only applies to the current list
  693.  * and will not be inherited to sublists.  The default behavior of the
  694.  + sorting will be equibalent to the following call back function:
  695.  *
  696.  * int cmp_cb (void *unused, harglst *not_used,
  697.  *             hargkey_t *lKey, hargtype_t lType,
  698.  *             hargkey_t *rKey, hargtype_t rType) {
  699.  *
  700.  *   // is ptr type key? see hargtype_t definition
  701.  *   int lLen = (lType & 0x1000) ? 4 : strlen (lKey) ;
  702.  *   int rLen = (rType & 0x1000) ? 4 : strlen (rKey) ;
  703.  *
  704.  *   // get the minimum length
  705.  *   int min  = (lLen > rLen) ? lLen : rLen ;
  706.  *
  707.  *   // compare leftmost characters
  708.  *   int test = memcmp (lKey, rKey, min);
  709.  *
  710.  *   // evaluate
  711.  *   return test ? test : (lLen - rLen) ;
  712.  * }
  713.  *
  714.  * Use a NULL entry for the second argument cmp_cb in harg_csort () in
  715.  * order to reinstall the default value.
  716.  *
  717.  *
  718.  * 12.1 Return value
  719.  * --_--------------
  720.  *
  721.  * The return value is always a key pointer, either to a '' terminated
  722.  * character string or to a (void*) pointer depending on the argument
  723.  * type.  Upn error, NULL is returned while the variable errno is set to
  724.  * some error code.
  725.  *
  726.  *
  727.  * 12.2 Remark:
  728.  * ------------
  729.  *
  730.  * This function sort the list when it is necessary. So using these
  731.  * functions while adding and deleting records should be handled carefully
  732.  * as either action will cause the list to be resorted befor indexing with
  733.  * the functions above.
  734.  *
  735.  *
  736.  *
  737.  * 
  738.  * 13. Acting on all records of a list
  739.  * ===================================
  740.  *
  741.  * int        harg_do         (harglst*, int(*call_back)(), void*state);
  742.  * where:     int (*call_back) 
  743.  *              (void*state,void*,hargtype_t,unsigned,hargkey_t*);
  744.  *
  745.  * hargwalk  *harg_walk_init  (harglst*);
  746.  * hargkey_t *harg_walk_next  (hargwalk*);
  747.  * hargkey_t *harg_walk_nextT (hargwalk*,hargtype_t*);
  748.  * void       harg_walk_stop  (hargwalk*);
  749.  *
  750.  * You can cycle thtough all records of a given list recurseively with
  751.  * cal back function, or iteratively. 
  752.  *
  753.  * Doing it recursively call harg_do() passing the list to be considered
  754.  * as first argument, a call back function as second one and a generic
  755.  * state pointer als last one.  For each record of the list, the call back
  756.  * function will be called passing the parameters
  757.  *
  758.  *   <generic-state-pointer> <data-value> <data-type> <key> <key-length>
  759.  *
  760.  * so this function may act upon the data contents.
  761.  *
  762.  * Doing it iteratively, using harg_walk_init() you open a walk upon the
  763.  * list given as argument.  The return value from this routine serves as
  764.  * descriptor argument for subsequent calls.  Getting the next list element
  765.  * can be done either with harg_walk_next() or with harg_walk_nextT(), where
  766.  * the latter function optionally passes bach the type of the next function
  767.  * to the variable pointed, to by the second argument (setting it NULL, this
  768.  * variable is ignored.)
  769.  *
  770.  * The return value from harg_walk_next()/harg_walk_nextT() is a key that
  771.  * may be used for other operations. It returns NULL when all list elements
  772.  * are visited, already.
  773.  *
  774.  * With the directive harg_walk_stop() the list walk is closed and the
  775.  * walk decriptor must not be used, anymore.
  776.  *
  777.  *
  778.  * 13.1 Return value
  779.  * --=--------------
  780.  *
  781.  * Doing it recursively, a 0 value is returned upon successful cycling through
  782.  * all list records, a positve value indicates, that not all records have been
  783.  * visited, and -1 indicates an error while the global error variable errno
  784.  * will be set to some error code.  If the call back function returned a
  785.  * non-zero value (negative upon error, positive upon stop request) cycling
  786.  * through the list is immediately stopped and the value returned as result.
  787.  *
  788.  * Doing it iteratively, walk_init() returns a non-zero descriptor, or
  789.  * NULL upon error (with errno set.)  The functions harg_walk_next() or
  790.  * harg_walk_nextT() return character string or to a (void*) pointer
  791.  * depending on the key type, or NULL when all list elements have been
  792.  * visited, while error ins set to 0. On error, also NULL is returned but
  793.  * the variable errno is set to some error code.
  794.  *
  795.   * 13.1.1 particular error codes:
  796.  * - - - - - - - - - - - - - - -
  797.  *
  798.  *    ENOENT    There list has been flushed so the walk was disabled.
  799.  *
  800.  *
  801.  *
  802.  *
  803.  * 14. Attaching/detaching to/from a remote list:
  804.  * ==============================================
  805.  *
  806.  * int harg_attach (int fd, harglst*,
  807.  *                  harglst* lst, const char* remote_name, 
  808.  *                  int(*drain)(void*), void*, int timeout,
  809.  *                  int);
  810.  * int harg_rstrategy            (harglst*,int);
  811.  * int harg_detach               (harglst*,int);
  812.  *
  813.  * The harg_attach() command is used to run a remote list. As a prerequisite,
  814.  * a remote list server must exist, either uaing a communication socket to
  815.  * another process (see harg_lstserver(), below), or running the remote
  816.  * list server locally. With the directive harg_rstrategy(), the overall
  817.  * cache strategy can be controlled as well as whether to reject tainted
  818.  * data records from the remote list.
  819.  *
  820.  *
  821.  * 14.1 Attaching to a remote archive:
  822.  * -----------------------------------
  823.  *
  824.  * Running the remote list server locally usually applies to posix threads
  825.  * and is available without any furher maintenance and actions, to be taken.
  826.  * Also, using this model is the only way to run a harg list thread save
  827.  * when every thread has its own list descriptor attached to the same remote
  828.  * list. The function arguments to the harg_attach() command are
  829.  *
  830.  *    <fd>, <harg-server>, <harg-to-be-attached>, <list-name>, <flags>
  831.  *
  832.  * where the first two arguments <fd>, <harg-server> describe the connection
  833.  * to the remote harg list server, the argument <harg-to-be-attached> is
  834.  * any local harg (e.g. see harg_create() on chapter 4) to be made or
  835.  * attached remotely, <list-name> is (a '' terminated character string and)
  836.  * the logic name of the archibe to connect to, and <flags> is the way how to
  837.  * to open and run that list.
  838.  *
  839.  * A for any remote list server run locally, the argument <fd> must be
  840.  * H_fLOCALQ while <harg-server> is any harg list dedicatged to hold the
  841.  * data of the remote list server.
  842.  *
  843.  * For any other connection, <fd> is the TCP socket, or stream id to be used
  844.  * with read/write (or probably send/recv.) The underlying read/write
  845.  * command are provided as call backs from another software layer (though
  846.  * there is no way to change these call backs, currently.)
  847.  *
  848.  * The argument <harg-to-be-attached> is the harg list descriptor that
  849.  * represents the list to be run, remotely. The name of this list is given
  850.  * as <list-name> and is used to uniquely identify the remote list.
  851.  *
  852.  * With the last argument <flags> the open and cache strategy is determined.
  853.  * The <flags> argument is a bit vector, the following bit options are
  854.  * supported:
  855.  *
  856.  * 14.1.1.open procedure flags
  857.  * - - - - - - - - - - - - - -
  858.  *
  859.  *   H_oCREATE  -- create new data base (must not exist) 
  860.  *   H_oTRUNC   -- create unless existing, empty data base
  861.  *   H_oOPEN    -- list does not need to exist when creating 
  862.  *
  863.  * Only one of there symbols is effective at a time. The flag H_oCREATE
  864.  + has precedence over both H_oOPEN and H_oTRUNC, the flag H_oTRUNC implies
  865.  * the actions of the flag H_oOPEN.
  866.  *
  867.  * 14.1.2.data initialization flags
  868.  * - - - - - - - - - - - - - - - - 
  869.  *
  870.  *   H_oCOPY    -- copy local data to the server 
  871.  *   H_oMOVE    -- move local data to the server (delete the local data)
  872.  *   H_oOWRITE  -- overwrite data on the server 
  873.  *
  874.  * The flag H_oMOVE has precedence ofer the flag H_oCOPY. The flag
  875.  * H_oOWRITE makes sense in combination of any flag H_oCOPY and H_oMOVE
  876.  * but is meaningless when set, alone.
  877.  * 
  878.  * 14.1.3.cache strategy flags
  879.  * - - - - - - - - - - - - - -
  880.  *
  881.  *   H_sSTICKY  -- disable flushing the cache
  882.  *   H_sWRTHRU  -- write through (and cache locally) 
  883.  *
  884.  * These bits affect the behaviour after the open phase.  The flag 
  885.  * H_sSTICKY will prevent flushing any local data from the cache (see also 
  886.  * harg_rsrtategy(), below), tha flag H_sWRTHRU will put the local cache
  887.  * in transparent write through mode which directly reflects the remote
  888.  * harg list, on line.
  889.  *
  890.  * 14.1.4.other flags
  891.  * - - - - - -  - - -
  892.  *
  893.  *   H_sTAINTED -- filter out tainted records 
  894.  *
  895.  * Setting this bit, all remote data that are marked insecure are rejected
  896.  * causing an EIDRM error when accessed. 
  897.  *
  898.  * ===============================
  899.  *
  900.  *
  901.  * Operations on a remote archive
  902.  * ------------------------------
  903.  *
  904.  *
  905.  *
  906.  *
  907.  * int harg_rstrategy  (harglst*, int flags);
  908.  * int harg_get_origin (harglst*,hargkey_t*);
  909.  * const char *harg_datadir (const char *); 
  910.  *
  911.  * harg_ddump  (list, filename)
  912.  * harg_store  (list, filename)
  913.  * harg_undump (list, filename)
  914.  * harg_load   (list, filename)
  915.  * harg_merge  (list, filename)
  916.  *
  917.  * ENOSYS     This package has not been compiled with remote list
  918.  *            suppoer
  919.  */
  920. #ifndef __HARGLIST_H__
  921. #define __HARGLIST_H__
  922. #ifdef _CYGWIN_
  923. #undef _WIN32
  924. #endif
  925. typedef
  926. enum _hargtype_t {
  927.   /* bits: 0..7 (0x00ff) is non-null for specific data types
  928.               8 (0x0100) unused
  929.               9 (0x0200) harg list data type
  930.              10 (0x0400) blob/string data type
  931.              11 (0x0800) scalar data type as int, ptr etc.
  932.              13 (0x1000) data type with (void*) key, otherwise char string
  933.              14 (0x2000) remote data type, usually a remote list
  934.   */
  935.   /* ----------------------------------------------------------------------- *
  936.    *         standard data types addressed by a string type key, a           *
  937.    *                -terminated character string                           *
  938.    * ----------------------------------------------------------------------- */
  939.   HARG_ANY       = 0x0000,
  940.   HARG_HARG      = 0x0201,
  941.   HARG_STRING    = 0x0401,
  942.   HARG_BLOB,
  943.   /* blob data types follow ... */
  944.   HARG_PTR       = 0x0801,
  945.   HARG_INT,
  946.   /* scalar data types follow ... */
  947. # ifdef ARG_ARGLIST
  948.   HARG_ARGLIST,
  949. # endif
  950.   /* ----------------------------------------------------------------------- *
  951.    *        data types addressed by a (void*) type key, an array of          *
  952.    *    sizeof(void*) bytes -- all types following have the 8th bit set      *
  953.    * ----------------------------------------------------------------------- */
  954.   HARG_PANY      = 0x1000,
  955.   HARG_PHARG     = 0x1201,
  956.   HARG_PSTRING   = 0x1401,
  957.   HARG_PBLOB,
  958.   /* data types follow (same order as above) ... */
  959.   HARG_PPTR      = 0x1801,
  960.   HARG_PINT,
  961.  /* data types follow (same order as above) ... */
  962. # ifdef ARG_ARGLIST
  963.   HARG_PARGLIST,
  964. # endif
  965.   /* ----------------------------------------------------------------------- *
  966.    *              remote data types -- not directly accessible               *
  967.    * ----------------------------------------------------------------------- */
  968.   
  969.   RHARG_ANY      = 0x2000,
  970.   RHARG_HARG     = 0x2201,
  971.   RHARG_PANY     = 0x3000,
  972.   RHARG_PHARG    = 0x3201
  973. } hargtype_t ;
  974. #ifdef __HARG_INTERNAL__
  975. /* data type qualifiers */
  976. #define is_specific_type(t) ((t) & 0x00ff) /* eg. is not HARG_PANY */
  977. #define is_harglst_type(t)  ((t) & 0x0200)
  978. #define is_blob_type(t)     ((t) & 0x0400)
  979. #define is_scalar_type(t)   ((t) & 0x0800)
  980. #define is_ptrkey_type(t)   ((t) & 0x1000)
  981. #define is_remote_type(t)   ((t) & 0x2000)
  982. #define get_local_type(t)   ((t) & 0xDfff) /* off remote bits */
  983. #define get_yekrtp_type(t)  ((t) & 0xEfff) /* off ptr key bits */ 
  984. #define get_simple_type(t)  ((t) & 0xCfff) /* off remote and ptr key bits */ 
  985. #define make_remote_type(t) ((t) | 0x2000) /* set the remote bit */
  986. #endif /* __HARG_INTERNAL__ */
  987. /* ------------------------------------------------------------------------- *
  988.  *                  mode arguments to harg_inct()                            *
  989.  * ------------------------------------------------------------------------- */
  990. typedef  
  991. enum _incmode_t {
  992.   /* bits: 4 (0x0100) increment, otherwise decrement
  993.    5 (0x0200) data record will be created
  994.    6 (0x0400) non-zero data record must not exist
  995.    7 (0x0800) destroy when zero
  996.    8 (0x1000) record must not become negative
  997.    9 (0x2000) record must not remain positive
  998.   */
  999.   HARG_INC_OP  = 0x0101, /* normal increment and decrement */
  1000.   HARG_DEC_OP  = 0x0001,
  1001.   
  1002.   HARG_INC0_OP = 0x0301, /* automatically create if necessary */
  1003.   HARG_DEC0_OP = 0x0801, /* automatically destroy when smaller or equal 0 */
  1004.   HARG_INC1_OP = 0x0701, /* Automatically create if necessary. In
  1005.     addition to that, it is an error if the
  1006.     entry exists and is non-zero */
  1007.   HARG_DEC1_OP = 0x1801, /* Automatically destroy, when 0. In addition
  1008.     to that, it is an error if the entry would
  1009.     become negative.*/
  1010.   HARG_DEC2_OP = 0x3801 /* Automatically destroy, when 0. In addition
  1011.     to that, it is an error if the entry would
  1012.     remain non-zero.*/
  1013. } incmode_t ;
  1014. #ifdef __HARG_INTERNAL__
  1015. # define inc_op_increments_record(x) ((x) & 0x0100)
  1016. # define inc_op_creates_record(x)    ((x) & 0x0200)
  1017. # define inc_op_wants_0_record(x)    ((x) & 0x0400)
  1018. # define inc_op_destroy0_record(x)   ((x) & 0x0800)
  1019. # define inc_op_notnegtv_record(x)   ((x) & 0x1000)
  1020. # define inc_op_notpostv_record(x)   ((x) & 0x2000)
  1021. #endif /* __HARG_INTERNAL__ */
  1022. /* ------------------------------------------------------------------------- *
  1023.  *                 descriptors, contants, typedefs                           *
  1024.  * ------------------------------------------------------------------------- */
  1025. typedef const char hargkey_t ;
  1026. #ifdef __HARG_INTERNAL__
  1027. typedef 
  1028. struct _harglst {
  1029.   hlst           *x ;
  1030.   short destroy_mode ;
  1031.   short       rflags ;  /* open/mode flags for remote processing */
  1032.   void       *sorter ;  /* custom sorting defs */
  1033. } harglst;
  1034. #else
  1035. typedef struct _harglst  {char opaq;} harglst;
  1036. #endif /* __HARG_INTERNAL__ */
  1037. typedef struct _hargwalk {char opaq;} hargwalk;
  1038. /* recusion depth, tree walk */
  1039. #ifndef HLST_MAX_RDEPTH
  1040. #define HLST_MAX_RDEPTH 20
  1041. #endif
  1042. /* ------------------------------------------------------------------------- *
  1043.  *                stategy flags for remote lists and records                 *
  1044.  * ------------------------------------------------------------------------- */
  1045. #define H_sTAINTED  0x0100 /* filter out tainted records */
  1046. #define H_sSTICKY   0x0200 /* cannot be flushed with the cache */
  1047. #define H_sREMOTE   0x0800 /* NOOP, indicates remote processing or origin */
  1048. #define H_sWRTHRU   0x1000 /* write through (and cache locally) */
  1049. #define H_sRECURSE  0x2000 /* apply to all, eg. harg_close_any() */
  1050. /* remote open mode/initialization flags */
  1051. #define H_oCREATE   0x0002 /* create new data base (must not exist) */
  1052. #define H_oOPEN     0x0004 /* data base need not exist when creating */
  1053. #define H_oTRUNC    0x0008 /* empty data base */
  1054. #define H_oCOPY     0x0010 /* copy data to/from the server */
  1055. #define H_oMOVE     0x0020 /* move data to/from the server */
  1056. #define H_oOWRITE   0x0040 /* overwrite data on the server */
  1057. /* other flags */
  1058. #define H_fLOCALQ   0x8000 /* local queue instead of io stream */
  1059. /* ------------------------------------------------------------------------- *
  1060.  *                         functional interface                              *
  1061.  * ------------------------------------------------------------------------- */
  1062. extern harglst*    harg_create               (unsigned estimated_size);
  1063. extern harglst*    harg_dup        (harglst*, unsigned estimated_size);
  1064. extern void        harg_close_any  (harglst*,int);
  1065. extern hargkey_t  *harg_addt       (harglst*,hargkey_t*,hargtype_t,int,unsigned,void*);
  1066. extern int         harg_inct       (harglst*,hargkey_t*,hargtype_t,incmode_t,int);
  1067. extern int         harg_removet    (harglst*,hargkey_t*,hargtype_t);
  1068. extern int         harg_renamet    (harglst*,hargkey_t*,hargtype_t,hargkey_t*,hargtype_t);
  1069. extern int         harg_set_valuet (harglst*,hargkey_t*,hargtype_t,unsigned,void*);
  1070. extern void       *harg_get_valuet (harglst*,hargkey_t*,hargtype_t);
  1071. extern hargkey_t  *harg_get_ntht   (harglst*,unsigned,  hargtype_t);
  1072. extern int         harg_csort      (harglst*,int(*)(void*,harglst*,hargkey_t*,hargtype_t,hargkey_t*,hargtype_t),void*);
  1073. extern hargtype_t  harg_get_typet  (harglst*,hargkey_t*,hargtype_t);
  1074. extern unsigned    harg_get_sizet  (harglst*,hargkey_t*,hargtype_t);
  1075. extern hargwalk   *harg_walk_init  (harglst*);
  1076. extern hargkey_t  *harg_walk_nextT (hargwalk*,hargtype_t*);
  1077. extern void        harg_walk_stop  (hargwalk*);
  1078. extern void harg_sort(harglst*);
  1079. extern int         harg_do         (harglst*, 
  1080.    int(*)(void*state,void*data,hargtype_t,unsigned size,hargkey_t*),
  1081.    void *state) ;
  1082. extern void        harg_dump       (harglst*);
  1083. extern void        harg_tracker_flush (void);
  1084. extern void        harg_tracker_dump (void);
  1085. extern void (*harg_logger(void(*f)(const char *, ...)))(const char *, ...);
  1086. extern int    harg_debuglevel (int level); /* set HARG_DEBUG to enable */
  1087. /* ------------------------------------------------------------------------- *
  1088.  *           remote extensions for the functional interface                  *
  1089.  * ------------------------------------------------------------------------- */
  1090. extern int         harg_attach     (int fd, harglst* localserver, harglst* lst, const char *name, int (*drain)(void*),void*,int tmo, int flags);
  1091. extern int         harg_detach     (harglst*, int flags);
  1092. extern int         harg_rstrategy  (harglst*, int flags);
  1093. extern int         harg_get_origint(harglst*,hargkey_t*,hargtype_t);
  1094. extern int         harg_runserver  (harglst*,int,int (*cb)(void*),void*);
  1095. extern void        harg_addacceptor(harglst*,int,void (*cb)(void*,int,int),void*);
  1096. extern const char *harg_datadir    (const char *); /* see hlstio_datadir () */
  1097. extern int         harg_rdump      (harglst*, const char *fname, int open_flags,   int open_mode);
  1098. extern int         harg_rload      (harglst*, const char *fname, int flush_server, int overwrite);
  1099. /* ------------------------------------------------------------------------- *
  1100.  *                             convenience macros                            *
  1101.  * ------------------------------------------------------------------------- */
  1102. #define harg_close(               d)              harg_close_any   ((d),                    0)
  1103. #define harg_close_all(           d)              harg_close_any   ((d),           H_sRECURSE)
  1104. #define harg_purge(               d)              harg_close_any   ((d), H_sWRTHRU)
  1105. #define harg_purge_all(           d)              harg_close_any   ((d), H_sWRTHRU|H_sRECURSE)
  1106. #define harg_walk_next(           w)              harg_walk_nextT  ((w),0) 
  1107. #define harg_ddump(               d,f)            harg_rdump       ((d),(f),O_TRUNC|O_CREAT,0600) /* overwrite file */
  1108. #define harg_store(               d,f)            harg_rdump       ((d),(f),        O_CREAT,0600)
  1109. #define harg_undump(              d,f)            harg_rload       ((d),(f),              1,   1) /* flush list */
  1110. #define harg_load(                d,f)            harg_rload       ((d),(f),              0,   1) /* overwrite list */
  1111. #define harg_merge(               d,f)            harg_rload       ((d),(f),              0,   0)
  1112. #define harg_add_string(          d,k,  s)        harg_addt        ((d),             (k),HARG_STRING,  1, 0, (void*)(s))
  1113. #define harg_add_nstring(         d,k,n,s)        harg_addt        ((d),             (k),HARG_STRING,  1,(n),(void*)(s))
  1114. #define harg_add_ptr(             d,k,  q)        harg_addt        ((d),             (k),HARG_PTR,     1, 0,        (q))
  1115. #define harg_add_harg(            d,k,  t)        harg_addt        ((d),             (k),HARG_HARGLST, 1, 0,        (t))
  1116. #define harg_add_blob(            d,k,l,q)        harg_addt        ((d),             (k),HARG_BLOB,    1,(l),       (q))
  1117. #define harg_add_int(             d,k,  n)        harg_addt        ((d),             (k),HARG_INT,     1, 0, (void*)(n))
  1118. #define harg_add_pstring(         d,p,  s)        harg_addt        ((d),(hargkey_t*)&(p),HARG_PSTRING, 1, 0, (void*)(s))
  1119. #define harg_add_pnstring(        d,p,n,s)        harg_addt        ((d),(hargkey_t*)&(p),HARG_PSTRING, 1,(n),(void*)(s))
  1120. #define harg_add_pptr(            d,p,  q)        harg_addt        ((d),(hargkey_t*)&(p),HARG_PPTR,    1, 0,        (q))
  1121. #define harg_add_pharg(           d,p,  t)        harg_addt        ((d),(hargkey_t*)&(p),HARG_PHARGLST,1, 0,        (t))
  1122. #define harg_add_pblob(           d,p,l,q)        harg_addt        ((d),(hargkey_t*)&(p),HARG_PBLOB,   1,(l),       (q))
  1123. #define harg_add_pint(            d,p,  n)        harg_addt        ((d),(hargkey_t*)&(p),HARG_PINT,    1, 0, (void*)(n))
  1124. #define harg_add_default_string(  d,k,  s)        harg_addt        ((d),             (k),HARG_STRING,  0, 0, (void*)(s))
  1125. #define harg_add_default_nstring( d,k,n,s)        harg_addt        ((d),             (k),HARG_STRING,  0,(n),(void*)(s))
  1126. #define harg_add_default_ptr(     d,k,  q)        harg_addt        ((d),             (k),HARG_PTR,     0, 0,        (q))
  1127. #define harg_add_default_harg(    d,k,  t)        harg_addt        ((d),             (k),HARG_HARGLST, 0, 0,        (t))
  1128. #define harg_add_default_blob(    d,k,l,q)        harg_addt        ((d),             (k),HARG_BLOB,    0,(l),       (q))
  1129. #define harg_add_default_int(     d,k,  n)        harg_addt        ((d),             (k),HARG_INT,     0, 0, (void*)(n))
  1130. #define harg_add_default_pstring( d,p,  s)        harg_addt        ((d),(hargkey_t*)&(p),HARG_PSTRING, 0, 0, (void*)(s))
  1131. #define harg_add_default_pnstring(d,p,n,s)        harg_addt        ((d),(hargkey_t*)&(p),HARG_PSTRING, 0,(n),(void*)(s))
  1132. #define harg_add_default_pptr(    d,p,  q)        harg_addt        ((d),(hargkey_t*)&(p),HARG_PPTR,    0, 0,        (q))
  1133. #define harg_add_default_pharg(   d,p,  t)        harg_addt        ((d),(hargkey_t*)&(p),HARG_PHARGLST,0, 0,        (t))
  1134. #define harg_add_default_pblob(   d,p,l,q)        harg_addt        ((d),(hargkey_t*)&(p),HARG_PBLOB,   0,(l),       (q))
  1135. #define harg_add_default_pint(    d,p,  n)        harg_addt        ((d),(hargkey_t*)&(p),HARG_PINT,    0, 0, (void*)(n))
  1136. #define harg_set_string(          d,k,  s)        harg_set_valuet  ((d),             (k),HARG_STRING,     0,        (s))
  1137. #define harg_set_nstring(         d,k,n,s)        harg_set_valuet  ((d),             (k),HARG_STRING,    (n),       (s))
  1138. #define harg_set_ptr(             d,k,  q)        harg_set_valuet  ((d),             (k),HARG_PTR,        0,        (q))
  1139. #define harg_set_harg(            d,k,  t)        harg_set_valuet  ((d),             (k),HARG_HARGLST,    0,        (t))
  1140. #define harg_set_blob(            d,k,l,q)        harg_set_valuet  ((d),             (k),HARG_BLOB,      (l),       (q))
  1141. #define harg_set_int(             d,k,  n)        harg_set_valuet  ((d),             (k),HARG_INT,        0, (void*)(n))
  1142. #define harg_set_pstring(         d,p,  s)        harg_set_valuet  ((d),(hargkey_t*)&(p),HARG_PSTRING,    0,        (s))
  1143. #define harg_set_pnstring(        d,p,n,s)        harg_set_valuet  ((d),(hargkey_t*)&(p),HARG_PSTRING,   (n),       (s))
  1144. #define harg_set_pptr(            d,p,  q)        harg_set_valuet  ((d),(hargkey_t*)&(p),HARG_PPTR,       0,        (q))
  1145. #define harg_set_pharg(           d,p,  t)        harg_set_valuet  ((d),(hargkey_t*)&(p),HARG_PHARGLST,   0,        (t))
  1146. #define harg_set_pblob(           d,p,l,q)        harg_set_valuet  ((d),(hargkey_t*)&(p),HARG_PBLOB,     (l),       (q))
  1147. #define harg_set_pint(            d,p,  n)        harg_set_valuet  ((d),(hargkey_t*)&(p),HARG_PINT,       0, (void*)(n))
  1148. #define harg_inc(                 d,k)            harg_inct        ((d),             (k),HARG_INT,  HARG_INC_OP,     1 )
  1149. #define harg_dec(                 d,k)            harg_inct        ((d),             (k),HARG_INT,  HARG_DEC_OP,     1 )
  1150. #define harg_inc0(                d,k)            harg_inct        ((d),             (k),HARG_INT,  HARG_INC0_OP,    1 )
  1151. #define harg_dec0(                d,k)            harg_inct        ((d),             (k),HARG_INT,  HARG_DEC0_OP     1 )
  1152. #define harg_inc1(                d,k)            harg_inct        ((d),             (k),HARG_INT,  HARG_INC1_OP,    1 )
  1153. #define harg_dec1(                d,k)            harg_inct        ((d),             (k),HARG_INT,  HARG_DEC1_OP,    1 )
  1154. #define harg_pinc(                d,p)            harg_inct        ((d),(hargkey_t*)&(p),HARG_PINT, HARG_INC_OP,     1 )
  1155. #define harg_pdec(                d,p)            harg_inct        ((d),(hargkey_t*)&(p),HARG_PINT, HARG_DEC_OP,     1 )
  1156. #define harg_pinc0(               d,p)            harg_inct        ((d),(hargkey_t*)&(p),HARG_PINT, HARG_INC0_OP,    1 )
  1157. #define harg_pdec0(               d,p)            harg_inct        ((d),(hargkey_t*)&(p),HARG_PINT, HARG_DEC0_OP     1 )
  1158. #define harg_pinc1(               d,p)            harg_inct        ((d),(hargkey_t*)&(p),HARG_PINT, HARG_INC1_OP,    1 )
  1159. #define harg_pdec1(               d,p)            harg_inct        ((d),(hargkey_t*)&(p),HARG_PINT, HARG_DEC1_OP,    1 )
  1160. #define harg_incn(                d,k,n)          harg_inct        ((d),             (k),HARG_INT,  HARG_INC_OP,    (n))
  1161. #define harg_decn(                d,k,n)          harg_inct        ((d),             (k),HARG_INT,  HARG_DEC_OP,    (n))
  1162. #define harg_inc0n(               d,k,n)          harg_inct        ((d),             (k),HARG_INT,  HARG_INC0_OP,   (n))
  1163. #define harg_dec0n(               d,k,n)          harg_inct        ((d),             (k),HARG_INT,  HARG_DEC0_OP    (n))
  1164. #define harg_inc1n(               d,k,n)          harg_inct        ((d),             (k),HARG_INT,  HARG_INC1_OP,   (n))
  1165. #define harg_dec1n(               d,k,n)          harg_inct        ((d),             (k),HARG_INT,  HARG_DEC1_OP,   (n))
  1166. #define harg_pincn(               d,p,n)          harg_inct        ((d),(hargkey_t*)&(p),HARG_PINT, HARG_INC_OP,    (n))
  1167. #define harg_pdecn(               d,p,n)          harg_inct        ((d),(hargkey_t*)&(p),HARG_PINT, HARG_DEC_OP,    (n))
  1168. #define harg_pinc0n(              d,p,n)          harg_inct        ((d),(hargkey_t*)&(p),HARG_PINT, HARG_INC0_OP,   (n))
  1169. #define harg_pdec0n(              d,p,n)          harg_inct        ((d),(hargkey_t*)&(p),HARG_PINT, HARG_DEC0_OP    (n))
  1170. #define harg_pinc1n(              d,p,n)          harg_inct        ((d),(hargkey_t*)&(p),HARG_PINT, HARG_INC1_OP,   (n))
  1171. #define harg_pdec1n(              d,p,n)          harg_inct        ((d),(hargkey_t*)&(p),HARG_PINT, HARG_DEC1_OP,   (n))
  1172. #define harg_get_string(          d,k)    ((char*)harg_get_valuet  ((d),             (k),HARG_STRING))
  1173. #define harg_get_ptr(             d,k)    ((void*)harg_get_valuet  ((d),             (k),HARG_PTR))
  1174. #define harg_get_harg(            d,k) ((harglst*)harg_get_valuet  ((d),             (k),HARG_HARGLST))
  1175. #define harg_get_blob(            d,k)    ((void*)harg_get_valuet  ((d),             (k),HARG_BLOB))
  1176. #define harg_get_int(             d,k)      ((int)harg_get_valuet  ((d),             (k),HARG_INT))
  1177. #define harg_get_any(             d,k)            harg_get_valuet  ((d),             (k),HARG_ANY)
  1178. #define harg_get(                 d,k)            harg_get_any (d,k)
  1179. #define harg_get_pstring(         d,p)    ((char*)harg_get_valuet  ((d),(hargkey_t*)&(p),HARG_PSTRING))
  1180. #define harg_get_pptr(            d,p)    ((void*)harg_get_valuet  ((d),(hargkey_t*)&(p),HARG_PPTR))
  1181. #define harg_get_pharg(           d,p) ((harglst*)harg_get_valuet  ((d),(hargkey_t*)&(p),HARG_PHARGLST))
  1182. #define harg_get_pblob(           d,p)    ((void*)harg_get_valuet  ((d),(hargkey_t*)&(p),HARG_PBLOB))
  1183. #define harg_get_pint(            d,p)      ((int)harg_get_valuet  ((d),(hargkey_t*)&(p),HARG_PINT))
  1184. #define harg_get_pany(            d,p)            harg_get_valuet  ((d),(hargkey_t*)&(p),HARG_PANY)
  1185. #define harg_get_nth_string(      d,n)            harg_get_ntht    ((d),             (n),HARG_STRING)
  1186. #define harg_get_nth_ptr(         d,n)            harg_get_ntht    ((d),             (n),HARG_PTR)
  1187. #define harg_get_nth_harg(        d,n)            harg_get_ntht    ((d),             (n),HARG_HARGLST)
  1188. #define harg_get_nth_blob(        d,n)            harg_get_ntht    ((d),             (n),HARG_BLOB)
  1189. #define harg_get_nth_int(         d,n)            harg_get_ntht    ((d),             (n),HARG_INT)
  1190. #define harg_get_nth_any(         d,n)            harg_get_ntht    ((d),             (n),HARG_ANY)
  1191. #define harg_get_nth(             d,n)            harg_get_nth_any (d,n)
  1192. #define harg_get_nth_pstring(     d,n)            harg_get_ntht    ((d),             (n),HARG_PSTRING)
  1193. #define harg_get_nth_pptr(        d,n)            harg_get_ntht    ((d),             (n),HARG_PPTR)
  1194. #define harg_get_nth_pharg(       d,n)            harg_get_ntht    ((d),             (n),HARG_PHARGLST)
  1195. #define harg_get_nth_pblob(       d,n)            harg_get_ntht    ((d),             (n),HARG_PBLOB)
  1196. #define harg_get_nth_pint(        d,n)            harg_get_ntht    ((d),             (n),HARG_PINT)
  1197. #define harg_get_nth_pany(        d,n)            harg_get_ntht    ((d),             (n),HARG_PANY)
  1198. #define harg_get_origin(          d,k)            harg_get_origint ((d),             (k),HARG_ANY)
  1199. #define harg_get_size(            d,k)            harg_get_sizet   ((d),             (k),HARG_ANY)
  1200. #define harg_get_type(            d,k)            harg_get_typet   ((d),             (k),HARG_ANY)
  1201. #define harg_get_porigin(         d,p)            harg_get_origint ((d),(hargkey_t*)&(p),HARG_PANY)
  1202. #define harg_get_psize(           d,p)            harg_get_sizet   ((d),(hargkey_t*)&(p),HARG_PANY)
  1203. #define harg_get_ptype(           d,p)            harg_get_typet   ((d),(hargkey_t*)&(p),HARG_PANY)
  1204. #define harg_remove_string(       d,k)            harg_removet     ((d),             (k),HARG_STRING)
  1205. #define harg_remove_ptr(          d,k)            harg_removet     ((d),             (k),HARG_PTR)
  1206. #define harg_remove_harg(         d,k)            harg_removet     ((d),             (k),HARG_HARGLST)
  1207. #define harg_remove_blob(         d,k)            harg_removet     ((d),             (k),HARG_BLOB)
  1208. #define harg_remove_int(          d,k)            harg_removet     ((d),             (k),HARG_INT)
  1209. #define harg_remove_any(          d,k)            harg_removet     ((d),             (k),HARG_ANY)
  1210. #define harg_remove(              d,k)            harg_remove_any (d,k)
  1211. #define harg_remove_pstring(      d,p)            harg_removet     ((d),(hargkey_t*)&(p),HARG_PSTRING)
  1212. #define harg_remove_pptr(         d,p)            harg_removet     ((d),(hargkey_t*)&(p),HARG_PPTR)
  1213. #define harg_remove_pharg(        d,p)            harg_removet     ((d),(hargkey_t*)&(p),HARG_PHARGLST)
  1214. #define harg_remove_pblob(        d,p)            harg_removet     ((d),(hargkey_t*)&(p),HARG_PBLOB)
  1215. #define harg_remove_pint(         d,p)            harg_removet     ((d),(hargkey_t*)&(p),HARG_PINT)
  1216. #define harg_remove_pany(         d,p)            harg_removet     ((d),(hargkey_t*)&(p),HARG_PANY)
  1217. #define harg_name_set_string(     d,k,l)          harg_renamet     ((d),             (k),HARG_ANY,(l),HARG_STRING)
  1218. #define harg_name_set_ptr(        d,k,l)          harg_renamet     ((d),             (k),HARG_ANY,(l),HARG_PTR)
  1219. #define harg_name_set_harg(       d,k,l)          harg_renamet     ((d),             (k),HARG_ANY,(l),HARG_HARGLST) 
  1220. #define harg_name_set_blob(       d,k,l)          harg_renamet     ((d),             (k),HARG_ANY,(l),HARG_BLOB)
  1221. #define harg_name_set_int(        d,k,l)          harg_renamet     ((d),             (k),HARG_ANY,(l),HARG_INT)
  1222. #define harg_name_set_any(        d,k,l)          harg_renamet     ((d),             (k),HARG_ANY,(l),HARG_INT)
  1223. #define harg_name_set_pstring(    d,p,q)          harg_renamet     ((d),(hargkey_t*)&(p),HARG_PANY,(hargkey_t*)&(q),HARG_PSTRING)
  1224. #define harg_name_set_pptr(       d,p,q)          harg_renamet     ((d),(hargkey_t*)&(p),HARG_PANY,(hargkey_t*)&(q),HARG_PPTR)
  1225. #define harg_name_set_pharg(      d,p,q)          harg_renamet     ((d),(hargkey_t*)&(p),HARG_PANY,(hargkey_t*)&(q),HARG_PHARGLST) 
  1226. #define harg_name_set_pblob(      d,p,q)          harg_renamet     ((d),(hargkey_t*)&(p),HARG_PANY,(hargkey_t*)&(q),HARG_PBLOB)
  1227. #define harg_name_set_pint(       d,p,q)          harg_renamet     ((d),(hargkey_t*)&(p),HARG_PANY,(hargkey_t*)&(q),HARG_PINT)
  1228. #define harg_name_set_pany(       d,p,q)          harg_renamet     ((d),(hargkey_t*)&(p),HARG_PANY,(hargkey_t*)&(q),HARG_PINT)
  1229. #define harg_type_set_string(     d,k)            harg_name_set_string  (d,k,0)
  1230. #define harg_type_set_ptr(        d,k)            harg_name_set_ptr     (d,k,0)
  1231. #define harg_type_set_harg(       d,k)            harg_name_set_harg    (d,k,0)
  1232. #define harg_type_set_blob(       d,k)            harg_name_set_blob    (d,k,0)
  1233. #define harg_type_set_int(        d,k)            harg_name_set_int     (d,k,0)
  1234. #define harg_type_set_pstring(    d,p)            harg_name_set_pstring (d,p,0)
  1235. #define harg_type_set_pptr(       d,p)            harg_name_set_pptr    (d,p,0)
  1236. #define harg_type_set_pharg(      d,p)            harg_name_set_pharg   (d,p,0)
  1237. #define harg_type_set_pblob(      d,p)            harg_name_set_pblob   (d,p,0)
  1238. #define harg_type_set_pint(       d,p)            harg_name_set_pint    (d,p,0)
  1239. /* ------------------------------------------------------------------------- *
  1240.  *                Renaud special & old name compat                           *
  1241.  * ------------------------------------------------------------------------- */
  1242. #define harg_ptr_add_ptr(     d,p)   harg_add_pptr     (d,p,p)
  1243. #define harg_ptr_get_ptr(     d,p)   harg_get_pptr     (d,p)
  1244. #define harg_ptr_remove_ptr(  d,p)   harg_remove_pany  (d,p)
  1245. #define harg_get_value(       d,k)   harg_get          (d,k)
  1246. #define HARG_HARGLST                 HARG_HARG
  1247. #endif /* __HARGLIST_H__ */