Back to index

lightning-sunbird  0.9+nobinonly
psearch.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla Communicator client code, released
00015  * March 31, 1998.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /*
00039  * Use a Persistent Search to monitor the directory server for changes to
00040  * all people entries whose surname (last name) is "Jensen".
00041  *
00042  */
00043 
00044 #include "examples.h"
00045 
00046 static char *changetype_num2string( int chgtype );
00047 
00048 int
00049 main( int argc, char **argv )
00050 {
00051     LDAP             *ld;
00052     LDAPMessage             *result, *e;
00053     BerElement              *ber;
00054     char             *a, *dn;
00055     char             **vals;
00056     int                     i;
00057     int                     rc;
00058     int                     finished;
00059     int                     msgid;
00060     int                     num_entries = 0;
00061     int                     version = LDAP_VERSION3;
00062     LDAPControl             *ctrls[2], *psctrl, **ectrls;
00063 
00064     /* arrange to use LDAP version 3 */
00065     if ( ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version ) != 0 ) {
00066        perror( "ldap_set_option" );
00067        return( 1 );
00068     }
00069 
00070     /* get a handle to an LDAP connection */
00071     if ( (ld = ldap_init( MY_HOST, MY_PORT )) == NULL ) {
00072        perror( "ldap_init" );
00073        return( 1 );
00074     }
00075 
00076     /* authenticate to the directory as nobody */
00077     if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
00078        ldap_perror( ld, "ldap_simple_bind_s" );
00079        ldap_unbind( ld );
00080        return( 1 );
00081     }
00082 
00083     /* construct the Persistent Search control */
00084     if ( ldap_create_persistentsearch_control( ld, LDAP_CHANGETYPE_ANY,
00085               1 /* changesOnly */, 1 /* request entry change controls */,
00086               1 /* critical */, &psctrl ) != LDAP_SUCCESS ) {
00087        ldap_perror( ld, "ldap_create_persistentsearch_control" );
00088        ldap_unbind( ld );
00089        return( 1 );
00090     }
00091     ctrls[0] = psctrl;
00092     ctrls[1] = NULL;
00093 
00094     /* issue a persistent search for all entries with surname of Jensen */
00095     if ( LDAP_SUCCESS != ldap_search_ext( ld, MY_SEARCHBASE,
00096            LDAP_SCOPE_SUBTREE, MY_FILTER, NULL /* all attrs */,
00097            0 /* get attrs and values */, ctrls, NULL /* no client ctrls */,
00098            NULL /* no timeout */, 0 /* no sizelimit */, &msgid )) {
00099        ldap_perror( ld, "ldap_search_ext" );
00100        ldap_unbind( ld );
00101        return( 1 );
00102     }
00103 
00104     ldap_control_free( psctrl );   /* no longer needed */
00105 
00106     /*
00107      * Loop, polling for results until finished.
00108      * Since this is a persistent search, this loop won't end until the
00109      * server shuts down or we lose the connection for some other reason.
00110      * We could abandon the persistent search or close the connection of
00111      * course, but we don't in this example.
00112      */
00113     finished = 0;
00114     while ( !finished ) {
00115        /*
00116         * Poll for results.   We call ldap_result with the "all" argument
00117         * set to LDAP_MSG_ONE.  This causes ldap_result() to return exactly one
00118         * entry if at least one entry is available.  This allows us to
00119         * display the entries as they are received.
00120         */
00121        result = NULL;
00122        rc = ldap_result( ld, msgid, LDAP_MSG_ONE, NULL /* no timeout */, &result );
00123        switch ( rc ) {
00124        case -1:
00125            /* some error occurred */
00126            ldap_perror( ld, "ldap_result" );
00127            ldap_unbind( ld );
00128            return( 1 );
00129        case 0:
00130            /* Timeout was exceeded.  No entries are ready for retrieval. */
00131            if ( result != NULL ) {
00132               ldap_msgfree( result );
00133            }
00134            break;
00135        default:
00136            /*
00137             * Either an entry is ready for retrieval, or all entries have
00138             * been retrieved.
00139             */
00140            if (( e = ldap_first_entry( ld, result )) == NULL ) {
00141               /* All done */
00142               finished = 1;
00143               if ( result != NULL ) {
00144                   ldap_msgfree( result );
00145               }
00146               continue;
00147            }
00148            num_entries++;
00149 
00150            /* for each entry print out name */
00151            if (( dn = ldap_get_dn( ld, e )) != NULL ) {
00152               printf( "dn: %s\n", dn );
00153               ldap_memfree( dn );
00154            }
00155 
00156            /* print entry change info. if it was returned */
00157            if ( LDAP_SUCCESS == ldap_get_entry_controls( ld, e, &ectrls )) {
00158               int    chgtype, chgnumpresent;
00159               long   chgnum;
00160               char   *prevdn;
00161 
00162               if ( LDAP_SUCCESS == ldap_parse_entrychange_control( ld,
00163                      ectrls, &chgtype, &prevdn, &chgnumpresent, &chgnum )) {
00164                   printf( "changeType: %s\n",
00165                          changetype_num2string( chgtype ));
00166                   if ( prevdn != NULL ) {
00167                      printf( "previousDN: %s\n", prevdn );
00168                      ldap_memfree( prevdn );
00169                   }
00170                   if ( chgnumpresent ) {
00171                      printf( "changeNumber: %d\n", chgnum );
00172                   }
00173                   ldap_controls_free( ectrls );
00174               }
00175            }
00176 
00177            /* print out all attrs and values */
00178            for ( a = ldap_first_attribute( ld, e, &ber );
00179                   a != NULL; a = ldap_next_attribute( ld, e, ber ) ) {
00180               if (( vals = ldap_get_values( ld, e, a )) != NULL ) {
00181                   for ( i = 0; vals[ i ] != NULL; i++ ) {
00182                      printf( "%s: %s\n", a, vals[ i ] );
00183                   }
00184                   ldap_value_free( vals );
00185               }
00186               ldap_memfree( a );
00187            }
00188            if ( ber != NULL ) {
00189               ber_free( ber, 0 );
00190            }
00191            printf( "\n" );
00192            ldap_msgfree( result );
00193        }
00194     }
00195 
00196     /* All done.  Print a summary. */
00197     printf( "%d entries retrieved.\n", num_entries );
00198     ldap_unbind( ld );
00199     return( 0 );
00200 }
00201 
00202 
00203 static char *
00204 changetype_num2string( int chgtype )
00205 {
00206     static char buf[ 25 ];
00207     char      *s;
00208 
00209     switch( chgtype ) {
00210     case LDAP_CHANGETYPE_ADD:
00211        s = "add";
00212        break;
00213     case LDAP_CHANGETYPE_DELETE:
00214        s = "delete";
00215        break;
00216     case LDAP_CHANGETYPE_MODIFY:
00217        s = "modify";
00218        break;
00219     case LDAP_CHANGETYPE_MODDN:
00220        s = "moddn";
00221        break;
00222     default:
00223        sprintf( s, "unknown (%d)", chgtype );
00224     }
00225 
00226     return( s );
00227 }