home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ldapsdk.zip / libraries / libldap / abandon.c next >
C/C++ Source or Header  |  2001-07-22  |  5KB  |  233 lines

  1. /* $OpenLDAP: pkg/ldap/libraries/libldap/abandon.c,v 1.15.6.8 2001/07/21 19:01:39 kurt Exp $ */
  2. /*
  3.  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  4.  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  5.  */
  6. /*  Portions
  7.  *  Copyright (c) 1990 Regents of the University of Michigan.
  8.  *  All rights reserved.
  9.  *
  10.  *  abandon.c
  11.  */
  12.  
  13. /*
  14.  * An abandon request looks like this:
  15.  *    AbandonRequest ::= MessageID
  16.  */
  17.  
  18. #include "portable.h"
  19.  
  20. #include <stdio.h>
  21.  
  22. #include <ac/stdlib.h>
  23.  
  24. #include <ac/socket.h>
  25. #include <ac/string.h>
  26. #include <ac/time.h>
  27.  
  28. #include "ldap-int.h"
  29.  
  30. static int do_abandon LDAP_P((
  31.     LDAP *ld,
  32.     ber_int_t origid,
  33.     ber_int_t msgid,
  34.     LDAPControl **sctrls,
  35.     LDAPControl **cctrls));
  36.  
  37. /*
  38.  * ldap_abandon_ext - perform an ldap extended abandon operation.
  39.  *
  40.  * Parameters:
  41.  *    ld            LDAP descriptor
  42.  *    msgid        The message id of the operation to abandon
  43.  *    scntrls        Server Controls
  44.  *    ccntrls        Client Controls
  45.  *
  46.  * ldap_abandon_ext returns a LDAP error code.
  47.  *        (LDAP_SUCCESS if everything went ok)
  48.  *
  49.  * Example:
  50.  *    ldap_abandon_ext( ld, msgid, scntrls, ccntrls );
  51.  */
  52. int
  53. ldap_abandon_ext(
  54.     LDAP *ld,
  55.     int msgid,
  56.     LDAPControl **sctrls,
  57.     LDAPControl **cctrls )
  58. {
  59.     int rc;
  60.     Debug( LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0 );
  61.  
  62.     /* check client controls */
  63.     rc = ldap_int_client_controls( ld, cctrls );
  64.     if( rc != LDAP_SUCCESS ) return rc;
  65.  
  66.     return do_abandon( ld, msgid, msgid, sctrls, cctrls );
  67. }
  68.  
  69.  
  70. /*
  71.  * ldap_abandon - perform an ldap abandon operation. Parameters:
  72.  *
  73.  *    ld        LDAP descriptor
  74.  *    msgid        The message id of the operation to abandon
  75.  *
  76.  * ldap_abandon returns 0 if everything went ok, -1 otherwise.
  77.  *
  78.  * Example:
  79.  *    ldap_abandon( ld, msgid );
  80.  */
  81. int
  82. ldap_abandon( LDAP *ld, int msgid )
  83. {
  84.     Debug( LDAP_DEBUG_TRACE, "ldap_abandon %d\n", msgid, 0, 0 );
  85.     return ldap_abandon_ext( ld, msgid, NULL, NULL ) == LDAP_SUCCESS
  86.         ? 0 : -1;
  87. }
  88.  
  89.  
  90. static int
  91. do_abandon(
  92.     LDAP *ld,
  93.     ber_int_t origid,
  94.     ber_int_t msgid,
  95.     LDAPControl **sctrls,
  96.     LDAPControl **cctrls)
  97. {
  98.     BerElement    *ber;
  99.     int        i, err, sendabandon;
  100.     ber_int_t *old_abandon;
  101.     Sockbuf        *sb;
  102.     LDAPRequest    *lr;
  103.  
  104.     Debug( LDAP_DEBUG_TRACE, "do_abandon origid %d, msgid %d\n",
  105.         origid, msgid, 0 );
  106.  
  107.     sendabandon = 1;
  108.  
  109.     /* find the request that we are abandoning */
  110.     for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
  111.         if ( lr->lr_msgid == msgid ) {    /* this message */
  112.             break;
  113.         }
  114.         if ( lr->lr_origid == msgid ) {/* child:  abandon it */
  115.             (void) do_abandon( ld,
  116.                 msgid, lr->lr_msgid, sctrls, cctrls );
  117.         }
  118.     }
  119.  
  120.     if ( lr != NULL ) {
  121.         if ( origid == msgid && lr->lr_parent != NULL ) {
  122.             /* don't let caller abandon child requests! */
  123.             ld->ld_errno = LDAP_PARAM_ERROR;
  124.             return( LDAP_PARAM_ERROR );
  125.         }
  126.         if ( lr->lr_status != LDAP_REQST_INPROGRESS ) {
  127.             /* no need to send abandon message */
  128.             sendabandon = 0;
  129.         }
  130.     }
  131.  
  132.     if ( ldap_msgdelete( ld, msgid ) == 0 ) {
  133.         ld->ld_errno = LDAP_SUCCESS;
  134.         return LDAP_SUCCESS;
  135.     }
  136.  
  137.     err = 0;
  138.     if ( sendabandon ) {
  139.         if( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
  140.             /* not connected */
  141.             err = -1;
  142.             ld->ld_errno = LDAP_SERVER_DOWN;
  143.  
  144.         } else if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
  145.             /* BER element alocation failed */
  146.             err = -1;
  147.             ld->ld_errno = LDAP_NO_MEMORY;
  148.  
  149.         } else {
  150.             /* create a message to send */
  151.             err = ber_printf( ber, "{iti",  /* '}' */
  152.                 ++ld->ld_msgid,
  153.                 LDAP_REQ_ABANDON, msgid );
  154.  
  155.             if( err == -1 ) {
  156.                 /* encoding error */
  157.                 ld->ld_errno = LDAP_ENCODING_ERROR;
  158.  
  159.             } else {
  160.                 /* Put Server Controls */
  161.                 if ( ldap_int_put_controls( ld, sctrls, ber )
  162.                     != LDAP_SUCCESS )
  163.                 {
  164.                     err = -1;
  165.  
  166.                 } else {
  167.                     /* close '{' */
  168.                     err = ber_printf( ber, /*{*/ "N}" );
  169.  
  170.                     if( err == -1 ) {
  171.                         /* encoding error */
  172.                         ld->ld_errno = LDAP_ENCODING_ERROR;
  173.                     }
  174.                 }
  175.             }
  176.  
  177.             if ( err == -1 ) {
  178.                 ber_free( ber, 1 );
  179.  
  180.             } else {
  181.                 /* send the message */
  182.                 if ( lr != NULL ) {
  183.                     sb = lr->lr_conn->lconn_sb;
  184.                 } else {
  185.                     sb = ld->ld_sb;
  186.                 }
  187.  
  188.                 if ( ber_flush( sb, ber, 1 ) != 0 ) {
  189.                     ld->ld_errno = LDAP_SERVER_DOWN;
  190.                     err = -1;
  191.                 } else {
  192.                     err = 0;
  193.                 }
  194.             }
  195.         }
  196.     }
  197.  
  198.     if ( lr != NULL ) {
  199.         if ( sendabandon ) {
  200.             ldap_free_connection( ld, lr->lr_conn, 0, 1 );
  201.         }
  202.         if ( origid == msgid ) {
  203.             ldap_free_request( ld, lr );
  204.         }
  205.     }
  206.  
  207.     i = 0;
  208.     if ( ld->ld_abandoned != NULL ) {
  209.         for ( ; ld->ld_abandoned[i] != -1; i++ )
  210.             ;    /* NULL */
  211.     }
  212.  
  213.     old_abandon = ld->ld_abandoned;
  214.  
  215.     ld->ld_abandoned = (ber_int_t *) LDAP_REALLOC( (char *)
  216.         ld->ld_abandoned, (i + 2) * sizeof(ber_int_t) );
  217.         
  218.     if ( ld->ld_abandoned == NULL ) {
  219.         ld->ld_abandoned = old_abandon;
  220.         ld->ld_errno = LDAP_NO_MEMORY;
  221.         return( ld->ld_errno );
  222.     }
  223.  
  224.     ld->ld_abandoned[i] = msgid;
  225.     ld->ld_abandoned[i + 1] = -1;
  226.  
  227.     if ( err != -1 ) {
  228.         ld->ld_errno = LDAP_SUCCESS;
  229.     }
  230.  
  231.     return( ld->ld_errno );
  232. }
  233.