Logo Search packages:      
Sourcecode: jabberd2 version File versions  Download package

sm.h

Go to the documentation of this file.
/*
 * jabberd - Jabber Open Source Server
 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
 *                    Ryan Eatmon, Robert Norris
 *
 * This program is free software; you can redistribute it and/or drvify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
 */

/** @file sm/sm.h
  * @brief data structures and prototypes for the session manager
  * @author Jeremie Miller
  * @author Robert Norris
  * $Date: 2005/09/09 05:34:54 $
  * $Revision: 1.53.2.9 $
  */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "sx/sx.h"
#include "sx/sasl.h"
#include "sx/ssl.h"
#include "mio/mio.h"
#include "util/util.h"

#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif

/* forward declarations */
typedef struct sm_st        *sm_t;
typedef struct user_st      *user_t;
typedef struct sess_st      *sess_t;
typedef struct aci_st       *aci_t;
typedef struct storage_st   *storage_t;
typedef struct mm_st        *mm_t;

/* namespace uri strings */
#define uri_AUTH        "jabber:iq:auth"
#define uri_REGISTER    "jabber:iq:register"
#define uri_ROSTER      "jabber:iq:roster"
#define uri_AGENTS      "jabber:iq:agents"
#define uri_DELAY       "jabber:x:delay"
#define uri_VERSION     "jabber:iq:version"
#define uri_TIME        "jabber:iq:time"
#define uri_VCARD       "vcard-temp"
#define uri_PRIVATE     "jabber:iq:private"
#define uri_BROWSE      "jabber:iq:browse"
#define uri_EVENT       "jabber:x:event"
#define uri_GATEWAY     "jabber:iq:gateway"
#define uri_LAST        "jabber:iq:last"
#define uri_EXPIRE      "jabber:x:expire"
#define uri_PRIVACY     "jabber:iq:privacy"
#define uri_SEARCH      "jabber:iq:search"
#define uri_DISCO       "http://jabber.org/protocol/disco"
#define uri_DISCO_ITEMS "http://jabber.org/protocol/disco#items"
#define uri_DISCO_INFO  "http://jabber.org/protocol/disco#info"
#define uri_VACATION    "http://jabber.org/protocol/vacation"

/* indexed known namespace values */
#define ns_AUTH         (1)
#define ns_REGISTER     (2)
#define ns_ROSTER       (3)
#define ns_AGENTS       (4)
#define ns_DELAY        (5)
#define ns_VERSION      (6)
#define ns_TIME         (7)
#define ns_VCARD        (8)
#define ns_PRIVATE      (9)
#define ns_BROWSE       (10)
#define ns_EVENT        (11)
#define ns_GATEWAY      (12)
#define ns_LAST         (13)
#define ns_EXPIRE       (14)
#define ns_PRIVACY      (15)
#define ns_SEARCH       (16)
#define ns_DISCO        (17)
#define ns_DISCO_ITEMS  (18)
#define ns_DISCO_INFO   (19)
#define ns_VACATION     (20)

/** packet types */
00099 typedef enum { 
00100     pkt_NONE = 0x00,            /**< no packet */
00101     pkt_MESSAGE = 0x10,         /**< message */
00102     pkt_PRESENCE = 0x20,        /**< presence */
00103     pkt_PRESENCE_UN = 0x21,     /**< presence (unavailable) */
00104     pkt_PRESENCE_INVIS = 0x22,  /**< presence (invisible) */
00105     pkt_PRESENCE_PROBE = 0x24,  /**< presence (probe) */
00106     pkt_S10N = 0x40,            /**< subscribe request */
00107     pkt_S10N_ED = 0x41,         /**< subscribed response */
00108     pkt_S10N_UN = 0x42,         /**< unsubscribe request */
00109     pkt_S10N_UNED = 0x44,       /**< unsubscribed response */
00110     pkt_IQ = 0x80,              /**< info/query (get) */
00111     pkt_IQ_SET = 0x81,          /**< info/query (set) */
00112     pkt_IQ_RESULT = 0x82,       /**< info/query (result) */
00113     pkt_SESS = 0x100,           /**< session start request */
00114     pkt_SESS_END = 0x101,       /**< session end request */
00115     pkt_SESS_CREATE = 0x102,    /**< session create request */
00116     pkt_SESS_DELETE = 0x104,    /**< session delete request */
00117     pkt_SESS_FAILED = 0x08,     /**< session request failed (mask) */
00118     pkt_SESS_MASK = 0x10f,      /**< session request (mask) */
00119     pkt_ERROR = 0x200           /**< packet error */
} pkt_type_t;

/** route types */
00123 typedef enum {
00124     route_NONE = 0x00,          /**< no route */
00125     route_UNICAST = 0x10,       /**< unicast */
00126     route_BROADCAST = 0x11,     /**< broadcast */
00127     route_ADV = 0x20,           /**< advertisement (available) */
00128     route_ADV_UN = 0x21,        /**< advertisement (unavailable) */
00129     route_ERROR = 0x40          /**< route error */
} route_type_t;

/** packet summary data wrapper */
typedef struct pkt_st {
00134     sm_t                sm;         /**< sm context */

00136     sess_t              source;     /**< session this packet came from */

00138     jid_t               rto, rfrom; /**< addressing of enclosing route */

00140     route_type_t        rtype;      /**< type of enclosing route */

00142     pkt_type_t          type;       /**< packet type */

    jid_t               to, from;   /**< packet addressing (not used for routing) */

00146     int                 ns;         /**< iq sub-namespace */

00148     int                 pri;        /**< presence priority */

    nad_t               nad;        /**< nad of the entire packet */
} *pkt_t;

/** roster items */
00154 typedef struct item_st {
00155     jid_t               jid;        /**< id of this item */

00157     char                *name;      /**< display name */

00159     char                **groups;   /**< groups this item is in */

00161     int                 ngroups;    /**< number of groups in groups array */

00163     int                 to, from;   /**< subscription to this item (they get presence FROM us, they send presence TO us) */

00165     int                 ask;        /**< pending subscription (0 == none, 1 == subscribe, 2 == unsubscribe) */
} *item_t;

/** session manager global context */
00169 struct sm_st {
00170     char                *id;                /**< component id (hostname) */

00172     char                *router_ip;         /**< ip to connect to the router at */
00173     int                 router_port;        /**< port to connect to the router at */
00174     char                *router_user;       /**< username to authenticate to the router as */
00175     char                *router_pass;       /**< password to authenticate to the router with */
00176     char                *router_pemfile;    /**< name of file containing a SSL certificate &
                                                 key for channel to the router */

00179     mio_t               mio;                /**< mio context */

00181     sx_env_t            sx_env;             /**< SX environment */
00182     sx_plugin_t         sx_sasl;            /**< SX SASL plugin */ 
00183     sx_plugin_t         sx_ssl;             /**< SX SSL plugin */

00185     sx_t                router;             /**< SX of router connection */
00186     int                 fd;                 /**< file descriptor of router connection */

00188     xht                 users;              /**< pointers to currently loaded users (key is user@@domain) */

00190     xht                 sessions;           /**< pointers to all connected sessions (key is random sm id) */

00192     xht                 xmlns;              /**< index of common namespaces (for iq sub-namespace in pkt_t) */

00194     xht                 features;           /**< feature index (key is feature string */

00196     config_t            config;             /**< config context */

00198     log_t               log;                /**< log context */

00200     log_type_t          log_type;           /**< log type */
00201     char                *log_facility;      /**< syslog facility (local0 - local7) */
00202     char                *log_ident;         /**< log identifier */

00204     int                 retry_init;         /**< number of times to try connecting to the router at startup */
00205     int                 retry_lost;         /**< number of times to try reconnecting to the router if the connection drops */
00206     int                 retry_sleep;        /**< sleep interval between retries */
00207     int                 retry_left;         /**< number of tries left before failure */

00209     prep_cache_t        pc;                 /**< cache of stringprep'd ids */

00211     storage_t           st;                 /**< storage subsystem */

00213     mm_t                mm;                 /**< module subsystem */

00215     xht                 acls;               /**< access control lists (key is list name, value is jid_t list) */

00217     char                signature[2048];    /**< server signature */
00218     int                 siglen;             /**< length of signature */

00220     int                 started;            /**< true if we've connected to the router at least once */

00222     int                 online;             /**< true if we're currently bound in the router */
};

/** data for a single user */
00226 struct user_st {
00227     pool                p;                  /**< memory pool this user is allocated off */

00229     sm_t                sm;                 /**< sm context */

00231     jid_t               jid;                /**< user jid (user@@host) */

00233     xht                 roster;             /**< roster for this user (key is full jid of item, value is item_t) */

00235     sess_t              sessions;           /**< list of action sessions */
00236     sess_t              top;                /**< top priority session */

00238     time_t              active;             /**< time that user first logged in (ever) */

00240     void                **module_data;      /**< per-user module data */
};

/** data for a single session */
struct sess_st {
00245     pool                p;                  /**< memory pool this session is allocated off */

00247     user_t              user;               /**< user this session belongs to */

    jid_t               jid;                /**< session jid (user@@host/res) */

00251     char                c2s[1024];           /**< id of c2s that is handling their connection */

    char                sm_id[41];          /**< local id (for session control) */
    char                c2s_id[10];         /**< remote id (for session control) */

00256     pkt_t               pres;               /**< copy of the last presence packet we received */

00258     int                 available;          /**< true if this session is available */
00259     int                 invisible;          /**< true if this session is invisible */
00260     int                 pri;                /**< current priority of this session */

00262     jid_t               A;                  /**< list of jids that this session has sent directed presence to */
00263     jid_t               E;                  /**< list of jids that bounced presence updates we sent them */

00265     void                **module_data;      /**< per-session module data */

00267     sess_t              next;               /**< next session (in a list of sessions) */
};

extern sig_atomic_t sm_lost_router;

/* functions */
xht             aci_load(sm_t sm);
int             aci_check(xht acls, char *type, jid_t jid);
void            aci_unload(xht acls);

int             sm_sx_callback(sx_t s, sx_event_t e, void *data, void *arg);
int             sm_mio_callback(mio_t m, mio_action_t a, int fd, void *data, void *arg);
void            sm_timestamp(time_t t, char timestamp[18]);
void            sm_c2s_action(sess_t dest, char *action, char *target);
void            sm_signature(sm_t sm, char *str);

void            dispatch(sm_t sm, pkt_t pkt);

pkt_t           pkt_error(pkt_t pkt, int err);
pkt_t           pkt_tofrom(pkt_t pkt);
pkt_t           pkt_dup(pkt_t pkt, const char *to, const char *from);
pkt_t           pkt_new(sm_t sm, nad_t nad);
void            pkt_free(pkt_t pkt);
pkt_t           pkt_create(sm_t sm, const char *elem, const char *type, const char *to, const char *from);
void            pkt_id(pkt_t src, pkt_t dest);
void            pkt_id_new(pkt_t pkt);
void            pkt_delay(pkt_t pkt, time_t t, const char *from);

void            pkt_router(pkt_t pkt);
void            pkt_sess(pkt_t pkt, sess_t sess);

int             pres_trust(user_t user, jid_t jid);
void            pres_roster(sess_t sess, item_t item);
void            pres_update(sess_t sess, pkt_t pres);
void            pres_error(sess_t sess, jid_t jid);
void            pres_deliver(sess_t sess, pkt_t pres);
void            pres_in(user_t user, pkt_t pres);
void            pres_probe(user_t user);

void            sess_route(sess_t sess, pkt_t pkt);
sess_t          sess_start(sm_t sm, jid_t jid);
void            sess_end(sess_t sess);
sess_t          sess_match(user_t user, char *resource);

user_t          user_load(sm_t sm, jid_t jid);
void            user_free(user_t user);
int             user_create(sm_t sm, jid_t jid);
void            user_delete(sm_t sm, jid_t jid);

void            feature_register(sm_t sm, char *feature);
void            feature_unregister(sm_t sm, char *feature);


/* driver module manager */

/** module return values */
00323 typedef enum {
00324     mod_HANDLED,                /**< packet was handled (and freed) */
00325     mod_PASS                    /**< packet was unhandled, should be passed to the next module */
} mod_ret_t;

/** module chain types */
00329 typedef enum {
00330     chain_SESS_START,           /**< session start, load per-session data */
00331     chain_SESS_END,             /**< session ended, save & free per-session data */
00332     chain_IN_SESS,              /**< packet from an active session */
00333     chain_IN_ROUTER,            /**< packet from the router */
00334     chain_OUT_SESS,             /**< packet to an active session */
00335     chain_OUT_ROUTER,           /**< packet to a router */
00336     chain_PKT_SM,               /**< packet for the sm itself */
00337     chain_PKT_USER,             /**< packet for a user */
00338     chain_PKT_ROUTER,           /**< packet from the router (special purpose) */
00339     chain_USER_LOAD,            /**< user loaded, load per-user data */
00340     chain_USER_CREATE,          /**< user creation, generate and save per-user data */
00341     chain_USER_DELETE           /**< user deletion, delete saved per-user data */
} mod_chain_t;

typedef struct module_st *module_t;
typedef struct mod_instance_st *mod_instance_t;

/** module manager date */
00348 struct mm_st {
00349     sm_t                sm;         /**< sm context */

00351     xht                 modules;    /**< pointers to module data (key is module name) */

00353     int                 nindex;     /**< counter for module instance sequence (!!! should be local to mm_new) */

    /** sess-start chain */
00356     mod_instance_t      *sess_start;    int nsess_start;
    /** sess-end chain */
00358     mod_instance_t      *sess_end;      int nsess_end;
    /** in-sess chain */
00360     mod_instance_t      *in_sess;       int nin_sess;
    /** in-router chain */
00362     mod_instance_t      *in_router;     int nin_router;
    /** out-sess chain */
00364     mod_instance_t      *out_sess;      int nout_sess;
    /** out-router chain */
00366     mod_instance_t      *out_router;    int nout_router;
    /** pkt-sm chain */
00368     mod_instance_t      *pkt_sm;        int npkt_sm;
    /** pkt-user chain */
00370     mod_instance_t      *pkt_user;      int npkt_user;
    /** pkt-router chain */
00372     mod_instance_t      *pkt_router;    int npkt_router;
    /** user-load chain */
00374     mod_instance_t      *user_load;     int nuser_load;
    /** user-create chain */
00376     mod_instance_t      *user_create;   int nuser_create;
    /** user-delete chain */
00378     mod_instance_t      *user_delete;   int nuser_delete;
};

/** data for a single module */
00382 struct module_st {
00383     mm_t                mm;         /**< module manager */

00385     char                *name;      /**< name of module */

00387     int                 index;      /**< module index. this is the index into user->module_data and
                                         sess->module_data where the module can store its own
                                         per-user/per-session data */

00391     int                 init;       /**< number of times the module intialiser has been called */

00393     void                *private;   /**< module private data */

    int                 (*sess_start)(mod_instance_t mi, sess_t sess);              /**< sess-start handler */
    void                (*sess_end)(mod_instance_t mi, sess_t sess);                /**< sess-end handler */

    mod_ret_t           (*in_sess)(mod_instance_t mi, sess_t sess, pkt_t pkt);      /**< in-sess handler */
    mod_ret_t           (*in_router)(mod_instance_t mi, pkt_t pkt);                 /**< in-router handler */

    mod_ret_t           (*out_sess)(mod_instance_t mi, sess_t sess, pkt_t pkt);     /**< out-sess handler */
    mod_ret_t           (*out_router)(mod_instance_t mi, pkt_t pkt);                /**< out-router handler */

    mod_ret_t           (*pkt_sm)(mod_instance_t mi, pkt_t pkt);                    /**< pkt-sm handler */
    mod_ret_t           (*pkt_user)(mod_instance_t mi, user_t user, pkt_t pkt);     /**< pkt-user handler */

    mod_ret_t           (*pkt_router)(mod_instance_t mi, pkt_t pkt);                /**< pkt-router handler */

    int                 (*user_load)(mod_instance_t mi, user_t user);               /**< user-load handler */

    int                 (*user_create)(mod_instance_t mi, jid_t jid);               /**< user-create handler */
    void                (*user_delete)(mod_instance_t mi, jid_t jid);               /**< user-delete handler */

    void                (*free)(module_t mod);                                      /**< called when module is freed */
};

/** single instance of a module in a chain */
00418 struct mod_instance_st {
00419     sm_t                sm;         /**< sm context */

00421     module_t            mod;        /**< module that this is an instance of */

00423     int                 seq;        /**< number of this instance */

00425     mod_chain_t         chain;      /**< chain this instance is in */

00427     char                *arg;       /**< option arg that this instance was started with */
};

/** allocate a module manager instance, and loads the modules */
mm_t                    mm_new(sm_t sm);
/** free a mm instance */
void                    mm_free(mm_t mm);

/** fire sess-start chain */
int                     mm_sess_start(mm_t mm, sess_t sess);
/** fire sess-end chain */
void                    mm_sess_end(mm_t mm, sess_t sess);

/** fire in-sess chain */
mod_ret_t               mm_in_sess(mm_t mm, sess_t sess, pkt_t pkt);
/** fire in-router chain */
mod_ret_t               mm_in_router(mm_t mm, pkt_t pkt);

/** fire out-sess chain */
mod_ret_t               mm_out_sess(mm_t mm, sess_t sess, pkt_t pkt);
/** fire out-router chain */
mod_ret_t               mm_out_router(mm_t mm, pkt_t pkt);

/** fire pkt-sm chain */
mod_ret_t               mm_pkt_sm(mm_t mm, pkt_t pkt);
/** fire pkt-user chain */
mod_ret_t               mm_pkt_user(mm_t mm, user_t user, pkt_t pkt);

/** fire pkt-router chain */
mod_ret_t               mm_pkt_router(mm_t mm, pkt_t pkt);

/** fire user-load chain */
int                     mm_user_load(mm_t mm, user_t user);

/** fire user-create chain */
int                     mm_user_create(mm_t mm, jid_t jid);
/** fire user-delete chain */
void                    mm_user_delete(mm_t mm, jid_t jid);

/** type for the module init function */
00467 typedef int (*module_init_fn)(mod_instance_t);


/* object sets */

/** object types */
00473 typedef enum {
00474     os_type_BOOLEAN,            /**< boolean (0 or 1) */
00475     os_type_INTEGER,            /**< integer */
00476     os_type_STRING,             /**< string */
00477     os_type_NAD,                /**< XML */
00478     os_type_UNKNOWN             /**< unknown */
} os_type_t;

/** a single tuple (value) within an object */ 
00482 typedef struct os_field_st {
00483     char        *key;           /**< field name */
00484     void        *val;           /**< field value */
00485     os_type_t   type;           /**< field type */
} *os_field_t;

typedef struct os_st        *os_t;
typedef struct os_object_st *os_object_t;

/** object set (ie group of several objects) */
00492 struct os_st {
00493     pool        p;              /**< pool the objects are allocated from */

00495     os_object_t head;           /**< first object in the list */
00496     os_object_t tail;           /**< last object in the list */

00498     int         count;          /**< number of objects in this set */

00500     os_object_t iter;           /**< pointer for iteration */
};

/** an object */
00504 struct os_object_st {
    /** object set this object is part of */
00506     os_t        os;

    /** fields (key is field name) */
00509     xht         hash;

00511     os_object_t next;           /**< next object in the list */
00512     os_object_t prev;           /**< previous object in the list */
};

/** create a new object set */
os_t        os_new(void);
/** free an object set */
void        os_free(os_t os);

/** number of objects in a set */
int         os_count(os_t os);

/** set iterator to first object (1 = exists, 0 = doesn't exist) */
int         os_iter_first(os_t os);

/** set iterator to next object (1 = exists, 0 = doesn't exist) */
int         os_iter_next(os_t os);

/** get the object currently under the iterator */
os_object_t os_iter_object(os_t os);

/** create a new object in this set */
os_object_t os_object_new(os_t os);
/** free an object (remove it from its set) */
void        os_object_free(os_object_t o);

/** add a field to the object */
void        os_object_put(os_object_t o, const char *key, const void *val, os_type_t type);

/** get a field from the object of type type (result in val), ret 0 == not found */
int         os_object_get(os_t os, os_object_t o, const char *key, void **val, os_type_t type, os_type_t *ot);

/** wrappers for os_object_get to avoid breaking strict-aliasing rules in gcc3 */
int         os_object_get_nad(os_t os, os_object_t o, const char *key, nad_t *val);
int         os_object_get_str(os_t os, os_object_t o, const char *key, char **val);
int         os_object_get_int(os_t os, os_object_t o, const char *key, int *val);
int         os_object_get_bool(os_t os, os_object_t o, const char *key, int *val);
int         os_object_get_time(os_t os, os_object_t o, const char *key, time_t *val);

/** wrappers for os_object_put to avoid breaking strict-aliasing rules in gcc3 */
void        os_object_put_time(os_object_t o, const char *key, const time_t *val);

/** set field iterator to first field (1 = exists, 0 = doesn't exist) */
int         os_object_iter_first(os_object_t o);
/** set field iterator to next field (1 = exists, 0 = doesn't exist) */
int         os_object_iter_next(os_object_t o);
/** extract field values from field currently under the iterator */
void        os_object_iter_get(os_object_t o, char **key, void **val, os_type_t *type);


/* storage manager */

/** storage driver return values */
00564 typedef enum {
00565     st_SUCCESS,                 /**< call completed successful */
00566     st_FAILED,                  /**< call failed (driver internal error) */
00567     st_NOTFOUND,                /**< no matching objects were found */
00568     st_NOTIMPL                  /**< call not implemented */
} st_ret_t;

typedef struct st_driver_st *st_driver_t;

/** storage manager data */
00574 struct storage_st {
00575     sm_t        sm;             /**< sm context */

00577     xht         drivers;        /**< pointers to drivers (key is driver name) */
00578     xht         types;          /**< pointers to drivers (key is type name) */

00580     st_driver_t default_drv;    /**< default driver (used when there is no module
                                     explicitly registered for a type) */
};

/** data for a single storage driver */
00585 struct st_driver_st {
00586     storage_t   st;             /**< storage manager context */ 

00588     char        *name;          /**< name of driver */

00590     void        *private;       /**< driver private data */

    /** called to find out if this driver can handle a particular type */
    st_ret_t    (*add_type)(st_driver_t drv, const char *type);

    /** put handler */
    st_ret_t    (*put)(st_driver_t drv, const char *type, const char *owner, os_t os);
    /** get handler */
    st_ret_t    (*get)(st_driver_t drv, const char *type, const char *owner, const char *filter, os_t *os);
    /** delete handler */
    st_ret_t    (*delete)(st_driver_t drv, const char *type, const char *owner, const char *filter);
    /** replace handler */
    st_ret_t    (*replace)(st_driver_t drv, const char *type, const char *owner, const char *filter, os_t os);

    /** called when driver is freed */
    void        (*free)(st_driver_t drv);
};

/** allocate a storage manager instance */
storage_t       storage_new(sm_t sm);
/** free a storage manager instance */
void            storage_free(storage_t st);

/** associate this data type with this driver */
st_ret_t        storage_add_type(storage_t st, const char *driver, const char *type);

/** store objects in this set */
st_ret_t        storage_put(storage_t st, const char *type, const char *owner, os_t os);
/** get objects matching this filter */
st_ret_t        storage_get(storage_t st, const char *type, const char *owner, const char *filter, os_t *os);
/** delete objects matching this filter */
st_ret_t        storage_delete(storage_t st, const char *type, const char *owner, const char *filter);
/** replace objects matching this filter with objects in this set (atomic delete + get) */
st_ret_t        storage_replace(storage_t st, const char *type, const char *owner, const char *filter, os_t os);

/** type for the driver init function */
00626 typedef st_ret_t (*st_driver_init_fn)(st_driver_t);


/** storage filter types */
00630 typedef enum {
00631     st_filter_type_PAIR,        /**< key=value pair */
00632     st_filter_type_AND,         /**< and operator */
00633     st_filter_type_OR,          /**< or operator */
00634     st_filter_type_NOT          /**< not operator */
} st_filter_type_t;

typedef struct st_filter_st *st_filter_t;
/** filter abstraction */
00639 struct st_filter_st {
00640     pool                p;      /**< pool that filter is allocated from */

00642     st_filter_type_t    type;   /**< type of this filter */

00644     char                *key;   /**< key for PAIR filters */
00645     char                *val;   /**< value for PAIR filters */

00647     st_filter_t         sub;    /**< sub-filter for operator filters */

00649     st_filter_t         next;   /**< next filter in a group */
};

/** create a filter abstraction from a LDAP-like filter string */
st_filter_t     storage_filter(const char *filter);

/** see if the object matches the filter */
int             storage_match(st_filter_t filter, os_object_t o, os_t os);

Generated by  Doxygen 1.6.0   Back to index