
/****************************************************************************/
/*                                                                          */
/*      NNstat -- Internet Statistics Collection Package                    */
/*                                                                          */
/*            Written by: Bob Braden & Annette DeSchon                      */
/*            USC Information Sciences Institute                            */
/*            Marina del Rey, California                                    */
/*                                                                          */
/*      Copyright (c) 1991 University of Southern California.               */
/*      All rights reserved.                                                */
/*                                                                          */
/*      Redistribution and use in source and binary forms are permitted     */
/*      provided that the above copyright notice and this paragraph are     */
/*      duplicated in all such forms and that any documentation,            */
/*      advertising materials, and other materials related to such          */
/*      distribution and use acknowledge that the software was              */
/*      developed by the University of Southern California, Information     */
/*      Sciences Institute.  The name of the University may not be used     */
/*      to endorse or promote products derived from this software           */
/*      without specific prior written permission.                          */
/*      THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR        */
/*      IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
/*      WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR          */
/*      PURPOSE.                                                            */
/*                                                                          */
/****************************************************************************/

static char rcsid[]=
  "$Header: reply.c,v 1.3 93/08/31 23:51:06 mogul Locked $";

/*
 *	                  reply.c
 *
 *   Routines to format/log XDR replies to commands to remote statspy.
 *   Used by collect and by rspy.
 */

/*
 *  CHANGES:
 *    15Oct89 ISI: Return Boolean: Get_reply()
 *    17Oct89 ISI: Support remote "subnet ?" commmand
 *      Rel 2.4:
 *    01Nov89 ISI: Support MAB, MSB, FAB, FOB object classes; change calling
 *                        sequences for ReadFO(), MA_list(), and FAO_list().
 *
 *      Rel 3.0:
 *    ISI: Add select statement to show_list().
 *    ISI: Move list routines onto individual object transfer vectors.
 *    ISI: Clean up handling of error msgs
 *    Aug93/DECWRL: Alpha/OSF port
 */
 
#include <stdio.h>
#include <rpc/rpc.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/time.h>

#include "collect.h"
#include "sobj.h"

#define endof(x) (x + strlen(x))
#define pad(x,col) while (strlen(x)<col) strcat(x, " ")

extern FILE *tracefp;
extern FILE *logfp;
extern GENERICOP *GenOpPtr[];
char *SOBJ_error;

u_int32 get_long();
OBJ  rsp_obj, *rspP = &rsp_obj;
char out[256];
char  Error_msg[256];

short packetlen;  /* Dummy */

void
show_list(xdrs)
    XDR *xdrs;
    {
    char temp[MAX_FLDNAME];
    int  oper;
    int  level = 0;
    struct invokes Invokes;
    
    if (!SHOWfield(xdrs, temp, 0, 1)) return;
    while (1) {
    
        if (!xdr_int(xdrs, &oper)) return;
        switch (oper) {
    
        case EndofResp:
            return;
            
        case SHOW_op:  /* Start new field */
            if (!SHOWfield(xdrs, temp, 0, 1)) return;
            level = 0;
            break;
        
        case If: 
        case Record:
        case Select:        
            if (!SHOWinv(xdrs, &Invokes, level, oper, 1)) return;
            break;
        
        case StartTsubl:
        case StartFsubl:
        case Case:
        case Default:
            SHOWsublist(NULL, ++level, oper, 1);
            break;
        
        case EndofSubl:
            level--;
            break;
        
        default:
            printf("SHOW op?? %d\n", oper);
            return;
        }
    }
} /* show_list */
               
/* 
 *  Decode reply from XDR and log/print results
 *      xdrs -- XDR * to be decoded.
 *      cptr -- collector * to be passed to Start_Read(cptr, rspH) 
 *			when a Read is to be decoded.
 *  If fails, returns FALSE with SOBJ_error set to reason string.
 */   
boolean
Get_reply(xdrs, cptr) 
    XDR *xdrs;
    struct collector *cptr;
    {
    int Resp_code, Resp_op;
    char *temp = NULL; /* Let XDR malloc areas for strngs... */
    boolean XDR_err();
   
    SOBJ_error = Error_msg;
    *SOBJ_error = '\0';
    if (!xdr_int(xdrs, &Resp_code))
        return(XDR_err());
        
    switch (Resp_code) {
   
    case RESP_ERROR:
        log("Error --", tracefp);
        if (!xdr_string(xdrs, &temp, 256)) 
            return(XDR_err());
	strcpy(SOBJ_error, temp);
        free(temp);
        return(FALSE);
         
    case RESP_OK:
        log("OK.\n", tracefp);
        while (1) {  /* Allow for multiple Response ops (Read) */
            if (!xdr_int(xdrs, &Resp_op)) return(XDR_err());
            switch (Resp_op) {
         
            case EndofResp: 
                /****log("\nEnd of Response\n", tracefp);***/
                return(TRUE);
             
            case CLEAR_op:
            case ATTACH_op:
            case DETACH_op:
            case SHOWnames_op:
            case SUBNET_op:
                if (!xdr_string(xdrs, &temp, 8000)) 
                    return(XDR_err());
                log(temp, tracefp);
                free(temp);
                log("\n", logfp);   /* Need a NL */
                return(TRUE);
                                                      
            case READ_op:
            case READCL_op:
                out[0] = '\0';
                if (!ReadStd(xdrs, out, 256, rspP)) 
                    return(XDR_err());
                if (!Start_Read(cptr, rspP)) {
                    SOBJ_error = "Cannot find/create file"; 
                    return(FALSE); /* used by collect */
                }
                log(out, logfp);
                if (rspP->obj_totlength  - sizeof(struct Obj_state) <= 4)
                    break;  /* Read ? */
            
                     /* Call appropriate List_xx routine via transfer vector */
                (*(GenOpPtr[rspP->obj_class-1]->list_xx))(xdrs, rspP);

                End_Read();
                break;  /* Back for another READ segment, or EndofResp */
            
            case SHOW_op:
                show_list(xdrs); 
                return(TRUE);   

             default: 
                if (tracefp) fprintf(tracefp,"op = %xx??\n\n",Resp_op);
                return(TRUE);
            }  /* End of while(1) loop */
        }  /* End switch on Resp_op */
        break;
            
    default:
        if (tracefp) fprintf(tracefp,"code = %xx\??n",Resp_code);
        return(FALSE);
    } /* End switch on Resp_code */
} /* Get_reply */



/*  Define some dangling statspy routines for rspy & collect */

attach_error(msgp, namep)
    char *msgp, *namep;
    {
    sprintf(SOBJ_error = Error_msg, "ATTACH error -- %s: %s", 
           msgp, namep);
}
    
boolean XDR_err()
    {
    strcat(SOBJ_error, "...XDR conn closed ");
    return(FALSE);
}


SOBJ *Get_SOBJ(Classno, objname, parmlistp, nparms, datalen, datalen2)
    char *objname;
    u_int32 *parmlistp ;
    int Classno, datalen, datalen2, nparms;
    {
    /* Stub ... function unneeded */
}


Unget_SOBJ(sobjp)
    SOBJ *sobjp;
    {
    /* Stub ... function unneeded */
}
    
