/* $Id: jp.c,v 1.1 1999/08/23 16:18:34 naamato Exp $ */
/*
 * Copyright(c) 1998 by Hitachi.Ltd All rights reserved.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include "pim_def.h"

#define IF_NAME_SIZE 8

void parse_file();
void timer();

char usage[] = "Usage: jp [-i interface] [-s src_addr] [-d dst_addr] [-h holdtime] [-f list ] [-C count] -n up_nbr\n";

int time_expire;

main(argc, argv)
int argc;
char **argv;
{
    char opt;
    extern char *optarg;
    u_long src,dst,nbr_addr;
    u_short holdtime;
    FILE *fp;
    char *if_name;
    int num,count;
#ifndef SOLARIS
    struct sigvec sigv;
#endif

    src = dst = nbr_addr = 0;
    if_name = NULL;
    fp = NULL;
    num = 0;
    count = 1;

    while((opt = getopt(argc,argv,"i:d:s:f:h:n:C:")) != -1) {
        switch(opt) {
	case 'i' : if_name = malloc(IF_NAME_SIZE);
	           strcpy(if_name,optarg);
	           break;
	case 'd' : dst = inet_stoa(optarg);
	           break;
	case 'h' : holdtime = (u_short)atoi(optarg);
	           break;
	case 'f' : if(!(fp = fopen(optarg,"r")))
	               printf(" %s open error \n",optarg);
	           break;
	case 's' : src = inet_stoa(optarg);
	           break;
	case 'n' : nbr_addr = inet_stoa(optarg);
	           break;
	case 'C' : count = atoi(optarg);
	           break;
	default:   fprintf(stderr,usage);
	           exit(1);
	}
    }

    if(!nbr_addr) {
        fprintf(stderr,usage);
	exit(1);
    }

    interface_init();

    pim_init();
    if(fp) parse_file(fp);

#ifdef SOLARIS
    sighold(SIGALRM);
    sigset(SIGALRM,timer);
#else
    bzero((char *)&sigv, sizeof(sigv));
    sigv.sv_flags = 0;
    sigv.sv_handler = timer;
    sigv.sv_mask = 0;
    sigvec(SIGALRM, &sigv, (struct sigvec *)NULL);
#endif

    time_expire = 1;
    add_jp_list_nbr(0,nbr_addr,holdtime);
    while(count) {
        if(time_expire) {
	    pimsm_jp_send2(if_name,src,dst,nbr_addr,holdtime,0);
            time_expire = 0;
            count--;
            alarm(PIM_JOIN_PRUNE_PERIOD);
        }
    }
}

void parse_file(fp)
FILE *fp;
{
    char c,buf[256],*bufp;
    u_long addr,mask;
    u_long grp;
    int holdtime;
    int g_flag,j_flag,p_flag;
    u_char flags;

    bufp = buf;
    addr = mask = grp = 0;
    g_flag = j_flag = p_flag = 0;
    flags = 0;
    while((c=getc(fp)) != EOF) {
        switch (c) {
	case 'g' : g_flag = 1;
	           break;
	case 'j' : j_flag = 1;
	           break;
	case 'p' : p_flag = 1;
	           break;
        case '\n' : *bufp = '\0';
	             prefix_parse(buf,&addr,&mask);
	             if(g_flag) {
			  grp = addr;
#if 0
			  add_jp_entry(grp,mask);
#endif
			  add_jp_list(0,grp,mask);
			  g_flag = 0;
		     }
	             else if(j_flag) {
#if 0
			  add_jp_join_list(grp,addr,mask,flags);
#endif
			  add_jp_join_list2(0,grp,addr,mask,flags);
			  j_flag = 0;
		     }
		     else if(p_flag) {
#if 0
			  add_jp_prune_list(grp,addr,mask,flags);
#endif
			  add_jp_prune_list2(0,grp,addr,mask,flags);
			  p_flag = 0;
		     }
	             bzero(buf,256);
	             bufp = buf;
	             flags = 0;
	             break;
	case 'r' : flags |= USADDR_RP_BIT;
	           break;
	case 'w' : flags |= USADDR_WC_BIT;
	           break;
	case 's' : flags |= USADDR_S_BIT;
	           break;
	case ' ' : break;
	default :  *bufp++ = c;
	           break;
	}
    }
	
}

void timer()
{
    time_expire = 1;
}
