Net2/usr/src/contrib/isode/dsap/net/dapinvoke.c

/* dapinvoke.c - DAP : Invoke DAP operations */

#ifndef	lint
static char *rcsid = "$Header: /f/osi/dsap/net/RCS/dapinvoke.c,v 7.2 91/02/22 09:20:57 mrose Interim $";
#endif

/* 
 * $Header: /f/osi/dsap/net/RCS/dapinvoke.c,v 7.2 91/02/22 09:20:57 mrose Interim $
 *
 *
 * $Log:	dapinvoke.c,v $
 * Revision 7.2  91/02/22  09:20:57  mrose
 * Interim 6.8
 * 
 * Revision 7.1  90/10/17  11:43:18  mrose
 * sync
 * 
 * Revision 7.0  90/07/26  14:45:21  mrose
 * *** empty log message ***
 * 
 */

/*
 *                                NOTICE
 *
 *    Acquisition, use, and distribution of this module and related
 *    materials are subject to the restrictions of a license agreement.
 *    Consult the Preface in the User's Manual for the full terms of
 *    this agreement.
 *
 */


/* LINTLIBRARY */

#include <stdio.h>
#include "logger.h"
#include "quipu/util.h"
#include "quipu/dap2.h"
#include "../x500as/DAS-types.h"
#include "../x500as/Quipu-types.h"

extern  LLog    * log_dsap;
extern	void	  ros_log();

#ifdef PDU_DUMP
#define DUMP_ARG 	"arg"
#define DUMP_RES 	"res"
#define DUMP_ERR 	"err"
#endif

int	  DapInvokeReqAux (sd, id, op, pe, di, asyn)
int			  sd;
int			  id;
int			  op;
PE			  pe;
struct DAPindication	* di;
int			  asyn;
{

#ifdef PDU_DUMP
    pdu_dump (pe,DUMP_ARG,op);
#endif

#ifdef HEAVY_DEBUG
    pdu_arg_log (pe, op);
#endif

	switch (asyn)
	{
	case ROS_SYNC:
		return (DapSyncInvokeRequest (sd, id, op, pe, di));

	case ROS_INTR:
		return (DapIntrInvokeRequest (sd, id, op, pe, di));

	case ROS_ASYNC:
		return (DapAsynInvokeRequest (sd, id, op, pe, di));

	default:
		LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapInvokeReqAux(): asyn has unknown value: %d", asyn));
		return (daplose (di, DP_INVOKE, NULLCP, "Unknown synchronicity"));
	}
}

int	  DapSyncInvokeRequest (sd, id, op, pe, di)
int			  sd;
int			  id;
int			  op;
PE			  pe;
struct DAPindication	* di;
{
    int				  result;
    struct RoSAPindication	  roi_s;
    struct RoSAPindication	* roi = &(roi_s);
    struct RoSAPpreject		* rop = &(roi->roi_preject);

    DLOG (log_dsap,LLOG_TRACE,( "DapSyncInvokeRequest()"));

    result = RoInvokeRequest (sd, op, ROS_SYNC, pe,
				id, NULLIP, ROS_NOPRIO, roi);

    if (result != OK)
    {
	if (roi->roi_type != ROI_PREJECT)
	{
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapSyncInvokeRequest(): Failed without rejection"));
	    return (daplose (di, DP_INVOKE, NULLCP, "RoInvokeRequest inconsistent result"));
	}

	if (ROS_FATAL (rop->rop_reason) || (rop->rop_reason == ROS_PARAMETER))
	{
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapSyncInvokeRequest(): Fatal rejection"));
	    return (daplose (di, DP_INVOKE, NULLCP, "RoInvokeRequest failed"));
	}
	else
	{
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapSyncInvokeRequest(): Non-Fatal rejection"));
	    return (dapreject (di, DP_INVOKE, id, NULLCP, "RoInvokeRequest failed"));
	}
    }

    switch(roi->roi_type)
    {
	case ROI_INVOKE:
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapSyncInvokeRequest: Invocation received"));
	    DRejectRequest (sd, ROS_IP_UNRECOG, roi->roi_invoke.rox_id);
	    return (daplose (di, DP_ROS, NULLCP, "DAP initiator cannot accept invokes"));

	case ROI_RESULT:
	    return (DapDecodeResult (sd, &(roi->roi_result), di));

	case ROI_ERROR:
	    return (DapDecodeError (sd, &(roi->roi_error), di));

	case ROI_UREJECT:
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapSyncInvokeRequest: Operation (%d) user rejected (%d)", roi->roi_ureject.rou_id, roi->roi_ureject.rou_reason));
		return (ros2dapreject (di, "ROI_UREJECT", &(roi->roi_ureject)));

	case ROI_PREJECT:
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapSyncInvokeRequest: Operation (%d) provider rejected", roi->roi_preject.rop_id));
	    return (ros2daplose (di, "ROI_PREJECT", &(roi->roi_preject)));

	case ROI_FINISH:
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapSyncInvokeRequest: Unbind request received"));
	    return (daplose (di, DP_ROS, NULLCP, "DAP initiator cannot accept unbind requests"));

	default:
	    LLOG (log_dsap,LLOG_EXCEPTIONS,( "Unknown indication type : %d", roi->roi_type));
	    break;
    }

    return (OK);
}

int	  DapIntrInvokeRequest (sd, id, op, pe, di)
int			  sd;
int			  id;
int			  op;
PE			  pe;
struct DAPindication	* di;
{
    int				  result;
    struct RoSAPindication	  roi_s;
    struct RoSAPindication	* roi = &(roi_s);
    struct RoSAPpreject		* rop = &(roi->roi_preject);

    DLOG (log_dsap,LLOG_TRACE,( "DapIntrInvokeRequest()"));

    result = RoIntrRequest (sd, op, pe, id, NULLIP, ROS_NOPRIO, roi);

    if (result != OK)
    {
	if (roi->roi_type != ROI_PREJECT)
	{
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapIntrInvokeRequest(): Failed without rejection"));
	    return (daplose (di, DP_INVOKE, NULLCP, "RoInvokeRequest inconsistent result"));
	}

	if (rop->rop_reason == ROS_INTERRUPTED)
	{
	     return (DapInterrupt(sd, id, op, di));
	}

	if (ROS_FATAL (rop->rop_reason) || (rop->rop_reason == ROS_PARAMETER))
	{
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapIntrInvokeRequest(): Fatal rejection"));
	    return (daplose (di, DP_INVOKE, NULLCP, "RoInvokeRequest failed"));
	}
	else
	{
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapIntrInvokeRequest(): Non-Fatal rejection"));
	    return (dapreject (di, DP_INVOKE, id, NULLCP, "RoInvokeRequest failed"));
	}
    }

    switch(roi->roi_type)
    {
	case ROI_INVOKE:
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapIntrInvokeRequest: Invocation received"));
	    DRejectRequest (sd, ROS_IP_UNRECOG, roi->roi_invoke.rox_id);
	    return (daplose (di, DP_ROS, NULLCP, "DAP initiator cannot accept invokes"));

	case ROI_RESULT:
	    return (DapDecodeResult (sd, &(roi->roi_result), di));

	case ROI_ERROR:
	    return (DapDecodeError (sd, &(roi->roi_error), di));

	case ROI_UREJECT:
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapIntrInvokeRequest: Operation (%d) user rejected (%d)", roi->roi_ureject.rou_id, roi->roi_ureject.rou_reason));
		return (ros2dapreject (di, "ROI_UREJECT", &(roi->roi_ureject)));

	case ROI_PREJECT:
		LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapIntrInvokeRequest: Operation (%d) provider rejected", roi->roi_preject.rop_id));
		return (ros2daplose (di, "ROI_PREJECT", &(roi->roi_preject)));

	case ROI_FINISH:
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapIntrInvokeRequest: Unbind request received"));
	    return (daplose (di, DP_ROS, NULLCP, "DAP initiator cannot accept unbind requests"));

	default:
	    LLOG (log_dsap,LLOG_EXCEPTIONS,( "Unknown indication type : %d", roi->roi_type));
	    break;
    }

    return (OK);
}

int	  DapAsynInvokeRequest (sd, id, op, pe, di)
int			  sd;
int			  id;
int			  op;
PE			  pe;
struct DAPindication	* di;
{
    int				  result;
    struct RoSAPindication	  roi_s;
    struct RoSAPindication	* roi = &(roi_s);
    struct RoSAPpreject		* rop = &(roi->roi_preject);

    result = RoInvokeRequest (sd, op, ROS_ASYNC, pe,
				id, NULLIP, ROS_NOPRIO, roi);

    if (result != OK)
    {
	if (roi->roi_type != ROI_PREJECT)
	{
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapAsynInvokeRequest(): Failed without rejection"));
	    return (daplose (di, DP_INVOKE, NULLCP, "RoInvokeRequest inconsistent result"));
	}

	if (ROS_FATAL (rop->rop_reason) || (rop->rop_reason == ROS_PARAMETER))
	{
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapAsynInvokeRequest(): Fatal rejection"));
	    return (daplose (di, DP_INVOKE, NULLCP, "RoInvokeRequest failed"));
	}
	else
	{
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapAsynInvokeRequest(): Non-Fatal rejection"));
	    return (dapreject (di, DP_INVOKE, id, NULLCP, "RoInvokeRequest failed"));
	}
    }

    return (OK);
}

int	  DapInterrupt(sd, id, op, di)
int			  sd;
int			  id;
int			  op;
struct DAPindication	* di;
{
    /*
    * Abandoning. Trickier than it looks!
    * Need to RoInvoke an abandon op, which will receive
    * One of the following:
    *    Result/Error for op being abandoned sent before
    *	this abandon arrived at the DSA;
    *    Abandoned error for op being abandoned;
    *    Result for abandon op which has overtaken the
    *	abandoned error for previous op between DSA and DUA
    *    Error for abandon because DSA has screwed up.
    *
    * Unless something goes wrong there should be 2 Ro events to
    * collect before returning. 
    */

    /* abandon operation */
    struct ds_abandon_arg	  ab_arg;
    struct DSError		  ab_err;
    PE				  ab_req_pe;
    int				  old_id;
    int				  new_id;
    int				  ret1;
    int				  ret2;
    struct RoSAPindication	  roi1_s;
    struct RoSAPindication	* roi1 = &(roi1_s);
    struct RoSAPpreject		* rop1 = &(roi1->roi_preject);
    struct RoSAPindication	  roi2_s;
    struct RoSAPindication	* roi2 = &(roi2_s);
    struct RoSAPpreject		* rop2 = &(roi2->roi_preject);
    struct RoSAPindication	* result_roi;

    ab_arg.aba_invokeid = old_id = id;
    new_id = ++id;

    if(encode_DAS_AbandonArgument(&ab_req_pe,1,0,NULLCP,&ab_arg) != OK)
    {
	LLOG(log_dsap, LLOG_EXCEPTIONS, ("Failed to encode an abandon operation"));
	/* Go on listening for result or dump out ?? */
	return(dapreject (di, DP_INVOKE, old_id, NULLCP, "DapInterrupt: Abandon argument encoding failed"));
    }
    else
    {
	DLOG(log_dsap, LLOG_DEBUG, ("Abandon invoke request"));

    	ret1 = RoInvokeRequest(sd,OP_ABANDON,ROS_SYNC,ab_req_pe,new_id,NULLIP,ROS_NOPRIO,roi1);

	DLOG(log_dsap, LLOG_DEBUG, ("Abandon RoInvoke returns: %d", ret1));

	if (ab_req_pe != NULLPE)
	    pe_free(ab_req_pe);

	switch(ret1)
	{
	    case OK:
		/* What have we got? */
		switch(roi1->roi_type)
		{
		    case ROI_RESULT:
		        if(roi1->roi_result.ror_id == old_id)
		        {
			    /* Ferret result away for later */
			    result_roi = roi1;
		        }
		        else if(roi1->roi_result.ror_id == (old_id + 1))
		        {
			    RORFREE (&(roi1->roi_result));
		        }
		        else
		        {
			    LLOG(log_dsap, LLOG_EXCEPTIONS, ("ARRGH! Abandon sent: event for neither op nor abandon op returned!!"));
			    return(dapreject (di, DP_INVOKE, roi1->roi_result.ror_id, NULLCP, "Unexpected operation identifier"));
		        }
		        break;

		    case ROI_ERROR:
#ifdef PDU_DUMP
	    pdu_dump (roi1->roi_error.roe_param,DUMP_ERR,op);
#endif

		        if(roi1->roi_error.roe_id == old_id)
		        {
			    /* Ferret error away for later */
			    result_roi = roi1;
		        }
		        else if(roi1->roi_error.roe_id == (old_id + 1))
		        {
			    if (roi1->roi_error.roe_error != DSE_ABANDON_FAILED)
			    {
				LLOG(log_dsap, LLOG_EXCEPTIONS, ("Failed to abandon correctly"));
				return(dapreject (di, DP_INVOKE, roi1->roi_error.roe_id, NULLCP, "Error mistyped for abandon"));
			    }
			    else
			    {
				struct DSE_abandon_fail * af;
			        if(decode_DAS_AbandonFailedParm (roi1->roi_error.roe_param, 1, NULLIP, NULLVP, &af) != OK)
				{
				    LLOG(log_dsap, LLOG_EXCEPTIONS, ("Failed to decode abandonFailed"));
				    return(dapreject (di, DP_INVOKE, old_id, NULLCP, "Abandon error decoding failed"));
				}
				else
				{
				    LLOG(log_dsap, LLOG_NOTICE, ("Abandon failed error!!!"));
				    ab_err.dse_un.dse_un_abandon_fail = *af; /* struct copy */
				    free ((char *)af);
				    ab_err.dse_type = DSE_ABANDON_FAILED;
				    log_ds_error(&ab_err);
				    ds_error_free(&ab_err);
				}
			    }
		        }
		        else
		        {
			    LLOG(log_dsap, LLOG_EXCEPTIONS, ("Abandon sent : event for neither op nor abandon op returned!!"));
			    return(dapreject (di, DP_INVOKE, roi1->roi_error.roe_id, NULLCP, "Unrecognised op id"));
		        }
		        break;

		    default:
		        LLOG(log_dsap, LLOG_FATAL, ("Unexpected roi_type : %d", roi1->roi_type));
		        return(dapreject (di, DP_INVOKE, -1, NULLCP, "Unrecognised event"));
		}
	        break;

	    case NOTOK:
		ros_log(rop1, "RO-INVOKE.REQUEST");
		if (ROS_FATAL (rop2->rop_reason))
		{
		    return (ros2daplose (di, "DapInterrupt", rop2));
		}
		else
		{
		    return (dapreject (di, DP_ROS, -1, NULLCP, "DapInterrupt: Non-fatal reject"));
		}

	    case DONE:
		LLOG(log_dsap, LLOG_EXCEPTIONS, ("Responder has sent Finish!"));
		return(daplose (di, DP_ROS, NULLCP, "Received Finish"));

            default:
		LLOG(log_dsap, LLOG_FATAL, ("Unknown return from RoInvokeRequest : %d", ret1));
		return(daplose (di, DP_ROS, NULLCP, "RoInvokeRequest error"));
        }

	ret2 = RoWaitRequest(sd, NOTOK, roi2);

	DLOG(log_dsap, LLOG_DEBUG, ("Abandon RoInvoke returns: %d", ret1));

	switch(ret2)
	{
	    case OK:
	    /* What have we got? */
		switch(roi2->roi_type)
		{
		    case ROI_RESULT:
		        if(roi2->roi_result.ror_id == old_id)
		        {
			    /* Ferret result away for later */
			    result_roi = roi2;
		        }
		        else if(roi2->roi_result.ror_id == (old_id + 1))
		        {
			    RORFREE (&(roi2->roi_result));
		        }
		        else
		        {
			    LLOG(log_dsap, LLOG_EXCEPTIONS, ("ARRGH! Abandon sent and event for neither op nor abandon op returned!!"));
			    return(dapreject (di, DP_INVOKE, roi1->roi_result.ror_id, NULLCP, "Unexpected operation identifier"));
		        }
		        break;

		    case ROI_ERROR:
#ifdef PDU_DUMP
	    pdu_dump (roi1->roi_error.roe_param,DUMP_ERR,op);
#endif

		        if(roi2->roi_error.roe_id == old_id)
		        {
			    /* Ferret error away for later */
			    result_roi = roi2;
		        }
		        else if(roi2->roi_error.roe_id == (old_id + 1))
		        {
			    if (roi2->roi_error.roe_error != DSE_ABANDON_FAILED)
			    {
				LLOG(log_dsap, LLOG_EXCEPTIONS, ("Failed to abandon correctly"));
				return(dapreject (di, DP_INVOKE, roi2->roi_error.roe_id, NULLCP, "Error mistyped for abandon"));
			    }
			    else
			    {
				
				struct DSE_abandon_fail * af;
			        if(decode_DAS_AbandonFailedParm (roi2->roi_error.roe_param, 1, NULLIP, NULLVP, &af) != OK)
				{
				    LLOG(log_dsap, LLOG_EXCEPTIONS, ("Failed to decode abandonFailed"));
				    return(dapreject (di, DP_INVOKE, old_id, NULLCP, "Abandon error decoding failed"));
				}
				else
				{
				    LLOG(log_dsap, LLOG_NOTICE, ("Abandon failed error!!!"));
				    ab_err.dse_un.dse_un_abandon_fail = *af; /*struct copy */
				    free ((char *) af);
				    ab_err.dse_type = DSE_ABANDON_FAILED;
				    log_ds_error(&ab_err);
				    ds_error_free(&ab_err);
				}
			    }
		        }
		        else
		        {
			    LLOG(log_dsap, LLOG_EXCEPTIONS, ("Abandon sent : event for neither op nor abandon op returned!!"));
			    return(dapreject (di, DP_INVOKE, roi1->roi_error.roe_id, NULLCP, "Unrecognised op id"));
		        }
		        break;

		    default:
		        LLOG(log_dsap, LLOG_FATAL, ("Unexpected roi_type : %d", roi2->roi_type));
		        return(dapreject (di, DP_INVOKE, -1, NULLCP, "Unrecognised event"));
		}
		break;

	    case NOTOK:
		ros_log(rop2, "RO-WAIT.REQUEST (Abandon)");
		if (ROS_FATAL (rop1->rop_reason))
		{
		    return (ros2daplose (di, "DapInterrupt", rop2));
		}
		else
		{
		    return (dapreject (di, DP_ROS, -1, NULLCP, "DapInterrupt: Non-fatal reject"));
		}

	    case DONE:
		LLOG(log_dsap, LLOG_EXCEPTIONS, ("Responder has sent Finish!"));
		return(daplose (di, DP_ROS, NULLCP, "Received Finish"));

            default:
		LLOG(log_dsap, LLOG_FATAL, ("Unknown return from RoInvokeRequest : %d", ret2));
		return(daplose (di, DP_ROS, NULLCP, "RoInvokeRequest error"));
        }
    }

    switch(result_roi->roi_type)
    {
	case ROI_RESULT:
	    return (DapDecodeResult (sd, &(result_roi->roi_result), di));

	case ROI_ERROR:
	    return (DapDecodeError (sd, &(result_roi->roi_error), di));

	default:
	    return (dapreject (di, DP_ROS, old_id, NULLCP, "DapInterrupt erroneous"));
    }
}

#ifdef PDU_DUMP

static int pdu_count = -1;
static char * pdu_dir = NULLCP;

pdu_dump_init (dir)
char * dir;
{
	pdu_count = 0;
	pdu_dir = strdup (dir);
	LLOG (log_dsap, LLOG_NOTICE, ("PDU Tracing enabled - %s",dir));
	
	(void) mkdir (pdu_dir,0755);
}

pdu_dump (pe,type,op)
PE pe;
char * type;
int op;
{
char filename [BUFSIZE];
char * oper;
PS ps;
FILE * fptr;

	if ( pdu_count == -1)
		return;

	if (strcmp (type,DUMP_ARG) == 0)
		pdu_count++;

	switch (op) {
		case OP_READ:
			oper = "read";
			break;
		case OP_COMPARE:
			oper = "compare";
			break;
		case OP_ABANDON:	/* Humm ... */
			oper = "abandon";
			break;
		case OP_LIST:
			oper = "list";
			break;
		case OP_SEARCH:
			oper = "search";
			break;
		case OP_ADDENTRY:
			oper = "add";
			break;
		case OP_REMOVEENTRY:
			oper = "remove";
			break;
		case OP_MODIFYENTRY:
			oper = "modify";
			break;
		case OP_MODIFYRDN:
			oper = "modifyrdn";
			break;
		case OP_GETEDB:
			oper = "getedb";
			break;
		case 100:	/* special case for bind */
			oper = "bind";
			break;
	}

	if (strcmp (type,DUMP_ERR) == 0)
		oper = "oper";

	(void) sprintf (filename, "%s/%s_%s.%d",pdu_dir,oper,type,pdu_count);
	DLOG (log_dsap,LLOG_DEBUG,("Writing PDU to file %s",filename));

	if ((fptr = fopen (filename,"w")) == (FILE *) NULL) {
		LLOG(log_dsap,LLOG_EXCEPTIONS,("Cant open PDU file %s",filename));
		return;
	}

	ps = ps_alloc (std_open);
	if (std_setup (ps,fptr) != OK) {
		(void) fclose (fptr);
		return;
	}
		
	(void) pe2pl (ps,pe);

	(void) fclose (fptr);
	ps_free (ps);

}
#endif

#ifdef	HEAVY_DEBUG
pdu_arg_log (pe,op)
PE pe;
int op;
{
    /* PDU Level Logging */
    switch (op) {
	case OP_READ:
	    PLOG (log_dsap, print_DAS_ReadArgument, pe, "Read", 0);
	    break;
	case OP_COMPARE:
	    PLOG (log_dsap, print_DAS_CompareArgument, pe, "Compare", 0);
	    break;
	case OP_ABANDON:
	    PLOG (log_dsap, print_DAS_AbandonArgument, pe, "Abandon", 0);
	    break;
	case OP_LIST:
	    PLOG (log_dsap, print_DAS_ListArgument, pe, "List", 0);
	    break;
	case OP_SEARCH:
	    PLOG (log_dsap, print_DAS_SearchArgument, pe, "Search", 0);
	    break;
	case OP_ADDENTRY:
	    PLOG (log_dsap, print_DAS_AddEntryArgument, pe, "AddEntry", 0);
	    break;
	case OP_REMOVEENTRY:
	    PLOG (log_dsap, print_DAS_RemoveEntryArgument, pe, "RemoveEntry", 0);
	    break;
	case OP_MODIFYENTRY:
	    PLOG (log_dsap, print_DAS_ModifyEntryArgument, pe, "ModifyEntry", 0);
	    break;
	case OP_MODIFYRDN:
	    PLOG (log_dsap, print_DAS_ModifyRDNArgument, pe, "ModifyRDN", 0);
	    break;
	case OP_GETEDB:
	    PLOG (log_dsap, print_Quipu_GetEntryDataBlockArgument, pe, "GetEDB", 0);
	    break;
	default:
		LLOG (log_dsap, LLOG_PDUS, ("Unknown operation (%d) - no argument PDU logged",op));
    }
}

pdu_res_log (pe, op)
PE	  pe;
int	  op;
{
    /* PDU Level Logging */
    switch (op)
    {
	case OP_READ:
	    PLOG (log_dsap, print_DAS_ReadResult, pe, "Read", 1);
	    break;

	case OP_COMPARE:
	    PLOG (log_dsap, print_DAS_CompareResult, pe, "Compare", 1);
	    break;
	case OP_ABANDON:
	    PLOG (log_dsap, print_DAS_AbandonResult, pe, "Abandon", 1);
	    break;
	case OP_LIST:
	    PLOG (log_dsap, print_DAS_ListResult, pe, "List", 1);
	    break;
	case OP_SEARCH:
	    PLOG (log_dsap, print_DAS_SearchResult, pe, "Search", 1);
	    break;
	case OP_ADDENTRY:
	    PLOG (log_dsap, print_DAS_AddEntryResult, pe, "AddEntry", 1);
	    break;
	case OP_REMOVEENTRY:
	    PLOG (log_dsap, print_DAS_RemoveEntryResult, pe, "RemoveEntry",1);
	    break;
	case OP_MODIFYENTRY:
	    PLOG (log_dsap, print_DAS_ModifyEntryResult, pe, "ModifyEntry",1);
	    break;
	case OP_MODIFYRDN:
	    PLOG (log_dsap, print_DAS_ModifyRDNResult, pe, "ModifyRDN", 1);
	    break;
	case OP_GETEDB:
	    PLOG (log_dsap, print_Quipu_GetEntryDataBlockResult, pe, "GetEDB", 1);
	    break;
	default:
	    LLOG (log_dsap, LLOG_PDUS, ("Unknown operation (%d) - no result PDU logged",op));
    }
}
#endif