
/****************************************************************************/
/*                                                                          */
/*      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: /tmp_mnt/r/jove_staff3/mogul/alpha/code/NNstat/RCS/remote.c,v 1.3 1993/08/31 23:49:57 mogul Exp $";
 
/*     This file contains the semantic routines for collect to execute 
 *     remote attaches.  It replaces attach.c and analyze.c in rspy.
 *
 *     The following action routines, called from the command parser in 
 *     cmds.c, create corresponding XDR encoding:
 * 
 *            doInvoke()
 *            doIf(), doSymIf(), doCase(), doSelect()
 *            doAppend(), doNull()
 *            doAnd(), doOr()
 *            Init_attach(), Install_It()
 *            CleanUp()
 *            Detach_SOBJ(), Read_SOBJ(), Clear_SOBJ(), Show_Fields(), Do_Subnet()
 *
 */

/*
 * CHANGES:
 *    17Oct89 AKS/RTB: Add Do_Subnet()
 *    25Oct89 ISI: Change some names
 *      Rel 3.0:
 *    ISI: Support language extensions: Boolean expressions, symif, and select.
 *    ISI: Replace Attach_SOBJ() with doInvoke().
 *      Rel 3.2:
 *    ISI: Fix subnet command
 *    Aug93/DECWRL: XDR is a pointer type!
 */ 
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <rpc/rpc.h>
#include "stat.h"
#include "sobj.h" 

extern XDR W_XDR, R_XDR;
extern char *SOBJ_error;
int   Flush();
char  out[256];

/*   boolean doInvoke(Record/IfInvoke/NotIfInv/SelInv, struct invokes *)
 *
 */
boolean doInvoke(code, invokesp)
    int code;
    struct invokes *invokesp;
    {    
    if (!xdr_int(&W_XDR,  &code)||
        !xdr_invoke(&W_XDR, invokesp)) {
        printf("Conn failed...\n");
        return(FALSE);
    };
    return(TRUE);       
}

/*              boolean doIf(), doSymIf()
 *
 *   Put a postfix IF/IFNOT operator into the XDR stream.
 *
 *   There are three implicit operands, all previously sent: the IF
 *   invocation, the TRUE alternative list, and the FALSE alternative
 *   list.  Returns TRUE if OK, else FALSE.
 *
 */
boolean doIf(isnot) 
    int  isnot; /* Note: This parm included for compatibility with earlier
                       versions */
    {
    int op = (isnot)? Ifnot:If;
    return(xdr_int(&W_XDR, &op));
}

boolean doSymIf()
    {    
    int op = SymIf;
    return(xdr_int(&W_XDR, &op));
}


/*         doCase()
 *
 */
boolean doCase(caseno, invokesp)
    int caseno;
    struct invokes *invokesp;
    {
    int code = Case; 
    int C = caseno;   
    
    if (!xdr_int(&W_XDR,  &code)||
        !xdr_case(&W_XDR, &C, invokesp)) {
        printf("Conn failed...\n");
        return(FALSE);
    };
    return(TRUE); 
}

/*         doSelect()
 *
 */
boolean doSelect()
    {
    int op = Select;
    return(xdr_int(&W_XDR, &op));
}


/*         doAppend()
 *
 *  Put an AppendList operator into the stream.
 */
boolean doAppend()
    {
    int op = AppendList;    
    return(xdr_int(&W_XDR, &op));
} 
  
/*
 *    boolean doAnd(), doOr()
 *
 */
boolean doAnd()
    {
    int op = And;    
    return(xdr_int(&W_XDR, &op));
}

boolean doOr()
    {
    int op = Or;    
    return(xdr_int(&W_XDR, &op));
}

/*
 *         Start new list.
 */
boolean doNull()
    {
    int op = StartList;
    return(xdr_int(&W_XDR, &op));
}


/*
 *         Initialize for new ATTACH
 */
boolean Init_attach()
    {
    int op = ATTACH_op;
    if (!Rconnect()) return(FALSE);
    return(xdr_int(&W_XDR, &op));   
}


/*
 *  Completion of ATTACH
 */
boolean Install_it()
    {
    int op = EndofReq;
    if (!xdr_int(&W_XDR, &op)) return(FALSE);
    Flush(&W_XDR);
    return(Get_reply(&R_XDR, NULL));    
    }

/*
 *  Routine to cleanup after Attach error.
 *
 *  Detach all invocations in each of
 *     n lists popped from top of stack.  If n is zero, clear entire stack.
 */
CleanUp(n)
    int n;
    {
    int op = Error ;    
    xdr_int(&W_XDR, &op);
    Flush(&W_XDR);
}

      
        
/*        Detach_SOBJ(fh, objspec)
 */
boolean Detach_SOBJ(xdrs, objspec)
    XDR  *xdrs;
    char *objspec;
    {
    int code = DETACH_op;
    
    if (!Rconnect())  {
        printf("%s\n", SOBJ_error);
        return(FALSE);
    }
    if (!xdr_int(xdrs, &code) ||
        !xdr_string(xdrs, &objspec, MAX_OBJNAME)) {
        printf("Conn failed...\n");
        return(FALSE);
    }
    Flush(xdrs);
    return(Get_reply(&R_XDR, NULL));
}


/*        Read_SOBJ(fh, objspec, isclear)
 */
boolean Read_SOBJ(xdrs, objspec, isclear)
    XDR  *xdrs;
    char *objspec;
    int   isclear;
    {
    int code = (isclear)? READCL_op:READ_op;

    if (!Rconnect())  {
        printf("%s\n", SOBJ_error);
        return(FALSE);
    }
    if (!xdr_int(xdrs, &code) ||
        !xdr_string(xdrs, &objspec, MAX_OBJNAME)) {
        printf("Conn failed...\n");
        return(FALSE);
    }
    Flush(xdrs);
    return(Get_reply(&R_XDR, NULL));
}


/*        Clear_SOBJ(fh, objspec)
 */
boolean Clear_SOBJ(xdrs, objspec)
    XDR *xdrs;
    char *objspec;
    {
    int code = CLEAR_op;
    
    if (!Rconnect())  {
        printf("%s\n", SOBJ_error);
        return(FALSE);
    }
    if (!xdr_int(xdrs, &code) ||
        !xdr_string(xdrs, &objspec, MAX_OBJNAME)) {
        printf("Conn failed...\n");
        return(FALSE);
    };
    Flush(xdrs);
    return(Get_reply(&R_XDR, NULL));
}


/*        Show_Fields(fh, fldspec)
 */
boolean Show_Fields(xdrs, fldspec)
    XDR *xdrs;
    char *fldspec;
    {
    int code = SHOW_op;
    
    if (!Rconnect())  {
        printf("%s\n", SOBJ_error);
        return(FALSE);
    }
    if (!xdr_int(xdrs, &code) ||
        !xdr_string(xdrs, &fldspec, MAX_OBJNAME)) {
        printf("Conn failed...\n");
        return(FALSE);
    };
    Flush(xdrs);
    return(Get_reply(&R_XDR, NULL));
}


/*        Do_Subnet(fh, parm)
 */
boolean Do_Subnet(xdrs, Sparm)
    XDR *xdrs;
    struct subnet_parm Sparm;
    {
    int code = SUBNET_op;
    int len = sizeof(struct subnet_parm);
    char *Sparm_p = (char *) &Sparm;
    
    if (!Rconnect())  {
        printf("%s\n", SOBJ_error);
        return(FALSE);
    }
    if (!xdr_int(xdrs, &code) ||
        !xdr_bytes(xdrs, (char **)&Sparm_p, &len, sizeof(struct subnet_parm))){
        printf("Conn failed...\n");
        return(FALSE);
    };
    Flush(xdrs);
    return(Get_reply(&R_XDR, NULL));
} /* Do_Subnet */
    
    /***********************************************************
     *
     *   UTILITY ROUTINES
     *
     ***********************************************************/   

Flush(fh)
XDR *fh;
    {
    extern FILE *noutfp;
    
    if (fh == NULL) {
        printf("\n");
        fflush(stdout);
    }
    else    
        fflush(noutfp);
}

