Sun Java System Directory Server Enterprise Edition 6.1 Developer's Guide

Internal Search

For an internal search, use callbacks to retrieve what the server finds. The callbacks allow you to retrieve the info that would be sent back to a client application were the operation initiated by an external request: LDAP result codes, entries found, and referrals.

You set up the callback data that you want to retrieve. You also write the function that is called back by the server.


Example 8–4 Search Callback (internal.c)

This code shows how the example plug-in internal.c uses a callback to retrieve an LDIF representation of the first entry that is found. The entry is found during an internal search with slapi_entry2str() as the callback function.

#include "slapi-plugin.h"

struct cb_data {                       /* Data returned from search     */
    char * e_str;                      /* Entry as LDIF                 */
    int    e_len;                      /* Length of LDIF                */
};

int
test_internal_entry_callback(Slapi_Entry * entry, void * callback_data)
{
    struct cb_data * data;
    int              len;

    /* This callback could do something more interesting with the
     * data such as build an array of entries returned by the search.
     * Here, simply log the result.                                     */
    data        = (struct cb_data *)callback_data;
    data->e_str = slapi_entry2str(entry, &len);
    data->e_len = len;
    slapi_log_info_ex(
        SLAPI_LOG_INFO_AREA_PLUGIN,
        SLAPI_LOG_INFO_LEVEL_DEFAULT,
        SLAPI_LOG_NO_MSGID,
        SLAPI_LOG_NO_CONNID,
        SLAPI_LOG_NO_OPID,
        "test_internal_entry_callback in test-internal plug-in",
        "\nFound entry: %sLength: %d\n", data->e_str, data->e_len
    );
    return (-1);                       /* Stop at the first entry.      */
}                                      /* To continue, return 0.        */

This callback stops the search at the first entry. Your plug-in might have to deal with more than one entry being returned by the search. Therefore, consider how you want to allocate space for your data depending on what your plug-in does.

With the callback data and function implemented, you are ready to process the internal search. First, allocate space for the parameter block and your callback data, and set up the parameter block with slapi_search_internal_pb_set(). Next, invoke the search with slapi_search_internal_pb(), and also set up the callback with slapi_search_internal_callback_pb(). When you are finished, free the space that you have allocated.



Example 8–5 Internal Search Operation (internal.c)

#include "slapi-plugin.h"

static Slapi_ComponentId * plugin_id     = NULL;

int
test_internal()
{
    Slapi_PBlock   * pb;               /* PBlock for internal ops       */
    char           * srch_attrs[] =    /* Attr. to get during search    */
                       {LDAP_ALL_USER_ATTRS, NULL};
    struct cb_data   callback_data;    /* Data returned from search     */
    int              rc;               /* Return code; 0 means success. */

    slapi_log_info_ex(
        SLAPI_LOG_INFO_AREA_PLUGIN,
        SLAPI_LOG_INFO_LEVEL_DEFAULT,
        SLAPI_LOG_NO_MSGID,
        SLAPI_LOG_NO_CONNID,
        SLAPI_LOG_NO_OPID,
        "test_internal in test-internal plug-in",
        "\nSearching with base DN %s, filter %s...\n",
        "dc=example,dc=com", "(uid=fcubbins)"
    );

    pb = slapi_pblock_new();           /* Set up a PBlock...            */
    rc = slapi_search_internal_set_pb(
        pb,
        "dc=example,dc=com",           /* Base DN for search            */
        LDAP_SCOPE_SUBTREE,            /* Scope                         */
        "(uid=fcubbins)",              /* Filter                        */
        srch_attrs,                    /* Set to get all user attrs.    */
        0,                             /* Return attrs. and values      */
        NULL,                          /* No controls                   */
        NULL,                          /* DN rather than unique ID      */
        plugin_id,
        SLAPI_OP_FLAG_NEVER_CHAIN      /* Never chain this operation.   */
    );

    if (rc != LDAP_SUCCESS) {
        slapi_pblock_destroy(pb);
        return (-1);
    }

    /* Internal search puts results into the PBlock, but uses callbacks
     * to get at the data as it is turned up by the search. In this case,
     * what you want to get is the entry found by the search.           */
    rc  = slapi_search_internal_pb(pb);
    rc |= slapi_search_internal_callback_pb(
        pb,
        &callback_data,
        NULL,                          /* No result callback            */
        test_internal_entry_callback,
        NULL                           /* No referral callback          */
    );

                                       /* ... get status ...            */
    slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
    if (rc != LDAP_SUCCESS) {
        slapi_pblock_destroy(pb);
        return -1;
    }
                                       /* Free the search results when
                                        * finished with them.           */
    slapi_free_search_results_internal(pb);
    slapi_pblock_destroy(pb);          /* ... done cleaning up.         */

    return (0);
}

Here, you allocate and free callback_data locally. You can manage memory differently if you pass the data to another plug-in function.