/* utils.c */
/******************************************************************************
      IMM version 2.4
      Written by Winston Dang <wkd@hawaii.edu>
 
 * Copyright (c) University of Hawaii 1993. All rights reserved.
 *  
 * License is granted to copy, to use, and to make and to use derivative
 * works for research, educational, government or evaluation purposes, provided
 * that the University of Hawaii is acknowledged in all documentation pertaining
 * to any such copy or derivative work. University of Hawaii grants no other 
 * licenses expressed or implied. The University of Hawaii trade name should 
 * not be used in any advertising without its written  permission.
 *  
 * UNIVERSITY OF HAWAII MAKES NO REPRESENTATIONS CONCERNING EITHER THE
 * MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE
 * FOR ANY PARTICULAR PURPOSE.  The software is provided "as is" without
 * express or implied warranty of any kind.
 *  
 * These notices must be retained in any copies of any part of this software.
 ******************************************************************************/
#include <stdio.h>
#include <varargs.h>
#include <stdlib.h>
#include <string.h>
#ifdef __NetBSD__
#include <unistd.h>
#endif

extern int debug;
extern int seed;
char mailer[] = "/bin/mail";
char *mailprog = mailer;
char *whome = NULL;

#ifdef ERROR_TEST
int err_in_block=0;
int err_block_size=100; /* default for 100 packet block size for error test */
#endif

/*----------------------------------------------------------------------------*/

void warn( va_alist )
va_dcl
{
    va_list args;
    char *fmt;

    va_start( args );
    fmt = va_arg( args, char * );
    fprintf( stderr, "Warning: " );
    vfprintf( stderr, fmt, args );
    va_end( args );
}

/*----------------------------------------------------------------------------*/

void die( va_alist )
va_dcl
{
    va_list args;
    char *fmt;

    va_start( args );
    fmt = va_arg( args, char * );
    fprintf( stderr, "Error: " );
    vfprintf( stderr, fmt, args );
    exit( 1 );
}

/*----------------------------------------------------------------------------*/

void fatal( va_alist )
va_dcl
{
    va_list args;
    char *fmt;

    va_start( args );
    fmt = va_arg( args, char * );
    fprintf( stderr, "Internal Error: " );
    vfprintf( stderr, fmt, args );
    exit( 2 );
}

/*----------------------------------------------------------------------------*/

unsigned uihash( ui )
unsigned ui;
{
    unsigned sum = 0;
    int i;
    
    for( i = 0; i < 4; i += 1 ){
	sum ^= ui << ( i * 8 );
	sum += ui >> i;
    }
    return( sum );
}

/*----------------------------------------------------------------------------*/

unsigned stringhash( str )
char *str;
{
    unsigned sum = 0;
    int i = 0;
    char *cp;

    for( cp = &str[ 0 ]; *cp != '\0'; cp += 1 ){
	sum ^= *cp << ( i++ % 4 );
	sum += *cp;
    }

    return( sum );
}
int checkpath(filename)
char * filename;
{
    char *token;
    char *pathptr;
    char *pathlist;
    static char tokensep[] = " \t,:";
    char cmdline[180];
    pathptr = getenv ("PATH");
    pathlist = malloc(strlen(pathptr) + 1);
    strcpy(pathlist, pathptr);
    /* Call strtok once to get first token and intialize it */
    token = strtok(pathlist,tokensep);
    while (token != NULL) {
	sprintf(cmdline,"%s/%s",token,filename);
	if (debug > 1) fprintf(stderr,"%s\n",cmdline);
	if (access(cmdline,0) == 0) {
	    free(pathlist);
	    return 1;
	}
	token = strtok(NULL,tokensep);
    }
    free(pathlist);
    return 0;
}
    
/*----------------------------------------------------------------------------*/

void mailmessage( va_alist )
va_dcl
{
    va_list args;
    char *fmt;
    FILE *popen(), *fp;
    char cmdline[80];
     if (whome == NULL) whome = getlogin();
	sprintf(cmdline,"%s %s",mailprog,whome);
	fp = popen(cmdline,"w");
    va_start( args );
    fmt = va_arg( args, char * );
    fprintf( fp, "MNM Warning: " );
    vfprintf( fp, fmt, args );
    va_end( args );
    pclose(fp);
}

/*****************************************************************************/
#ifdef ERROR_TEST
/* PACKET_DROP procedure to emulate random packet drops at the source */
int random_drop(error_block_size,error_per_block)
int error_block_size,error_per_block;

{
    unsigned int temp;
#ifdef SOLARIS
    temp = error_block_size * (rand_r(&seed) >> 5) / 1023;
#else
#ifdef hpux
    temp = error_block_size * (rand() >> 5) / 1023);	
#else
    temp = error_block_size * (random()&1023)/1023;
#endif
#endif
     if (temp >= error_per_block)
	 return(0); /* transmit packet */
     else
	 return(1); /* drop packet */
}
#endif /* ERROR_TEST */
