Ejemplo n.º 1
0
void imc_autoconnect_reply_accept(const char *from, const char *rhost, int rport, const char *rclientpw, const char *rserverpw, 
						  int rrcvstamp, int rnoforward, const char *rflags, const char *remotename, const char *confirm) {
	/* Wow.. what a function name! This gets the packet that says "connection added"
	in it from the hub, then adds the appropriate connection here. -- Scion */

	imc_info *i,*o;

	imc_logstring("Received autoconnect reply from %s.", remotename);
	if (strcasecmp(confirm, "connection added")) { /* Don't change this, or it won't work. */
		imc_logstring("Confirmation refused: %s", confirm);
		return;
	}

	if (imc_name && !strcasecmp(remotename, imc_name)) {
	  imc_logstring("Autoconnect attempt allegedly from this host! Ignoring.");
      return; /* Hey! That's our name! */
  }
  else if (!strcasecmp(rhost, "!!!")) {
	  imc_logstring("Unknown host name for %s. Aborting.", remotename);
	  return;
  } else {
	/* Setup the new connection... */
  if((o=imc_getinfo(remotename))) /* remove old entries - shogar */
  {
  	i=imc_insert_info();
        i->connection=o->connection;
        i->flags=o->flags; 
        if(i->connection) i->connection->info=i;
  	imc_cancel_info(o); 
  }
  else
  {
  	i=imc_insert_info();
//        i->flags      = imc_flagvalue("hub reconnect new", imc_connection_flags);
        i->flags      = imc_flagvalue("hub new", imc_connection_flags);
  }

      i->name       = imc_strdup(remotename);
      i->host       = imc_strdup(rhost);
      i->port       = (unsigned short)rport;
      i->clientpw   = imc_strdup(rclientpw);
      i->serverpw   = imc_strdup(rserverpw);
      i->rcvstamp   = rrcvstamp;
      i->noforward  = rnoforward;
      i->connect_attempts = 0;

      imc_saveconfig();

	  imc_connect_to(remotename);
	  /* All done! */
	  imc_logstring("Added connection to %s.", remotename);

  }
  imc_send_keepalive();

}
Ejemplo n.º 2
0
void icec_recv_update(const char *from,
                      const char *chan,
                      const char *owner,
                      const char *operators,
                      const char *policy,
                      const char *invited,
                      const char *excluded) {
    ice_channel *c;
    const char *mud;
    mud = imc_mudof(from);
    /* forged? */
    if(!strchr(chan, ':') ||
            strcasecmp(mud, ice_mudof(chan))) {
        return;
    }
    c = icec_findchannel(chan);
    if(!c) {
        c = imc_malloc(sizeof(*c));
        c->name = imc_strdup(chan);
        c->owner = imc_strdup(owner);
        c->operators = imc_strdup(operators);
        c->invited = imc_strdup(invited);
        c->excluded = imc_strdup(excluded);
        c->local = NULL;
        c->active = NULL;
        c->next = icec_channel_list;
        icec_channel_list = c;
    } else {
        imc_strfree(c->owner);
        imc_strfree(c->operators);
        imc_strfree(c->invited);
        imc_strfree(c->excluded);
        c->name = imc_strdup(chan);
        c->owner = imc_strdup(owner);
        c->operators = imc_strdup(operators);
        c->invited = imc_strdup(invited);
        c->excluded = imc_strdup(excluded);
    }
    if(!strcasecmp(policy, "open")) {
        c->policy = ICE_OPEN;
    } else if(!strcasecmp(policy, "closed")) {
        c->policy = ICE_CLOSED;
    } else {
        c->policy = ICE_PRIVATE;
    }
    if(c->local && !ice_audible(c, imc_name)) {
        icec_localfree(c);
    }
    icec_notify_update(c);
    imc_cancel_event(ev_icec_timeout, c);
    imc_add_event(ICEC_TIMEOUT, ev_icec_timeout, c, 0);
}
Ejemplo n.º 3
0
Archivo: imc.c Proyecto: bkero/Smaug
/* update our routing table based on a packet received with path "path" */
static void updateroutes(const char *path)
{
  imc_reminfo *p;
  const char *sender, *last;
  const char *temp;

  /* loop through each item in the path, and update routes to there */

  last = imc_lastinpath(path);
  temp = path;
  while (temp && temp[0])
  {
    sender=imc_firstinpath(temp);

    if (strcasecmp(sender, imc_name))
    {
      /* not from us */
      /* check if its in the list already */

      p = imc_find_reminfo(sender, 1);
      if (!p)			/* not in list yet, create a new entry */
      {
	p=imc_new_reminfo();

	p->name    = imc_strdup(sender);
	p->ping    = 0;
	p->alive   = imc_now;
	p->route   = imc_strdup(last);
	p->version = imc_strdup("unknown");
	p->type    = IMC_REMINFO_NORMAL;
      }
      else
      {				/* already in list, update the entry */
	if (strcasecmp(last, p->route))
	{
	  imc_strfree(p->route);
	  p->route=imc_strdup(last);
	}
	p->alive=imc_now;
	p->type = IMC_REMINFO_NORMAL;
      }
    }

    /* get the next item in the path */

    temp=strchr(temp, '!');
    if (temp)
      temp++;			/* skip to just after the next '!' */
  }
}
Ejemplo n.º 4
0
Archivo: imc.c Proyecto: bkero/Smaug
void imc_startup(const char *prefix)
{
  if (imc_active!=IA_NONE)
  {
    imc_logstring("imc_startup: called with imc_active=%d", imc_active);
    return;
  }

  imc_now=time(NULL);                  /* start our clock */
  imc_boot=imc_now;

  imc_logstring("%s initializing", IMC_VERSIONID);

#ifdef USEIOCTL
  outqsize = getsndbuf();
  imc_logstring("found TIOCOUTQ=%d", outqsize);
#endif

  imc_prefix=imc_strdup(prefix);

  imc_sequencenumber=imc_now;
  strcpy(imc_lasterror, "no error");

  imc_readconfig();
  imc_readignores();

  imc_active = imc_name ? IA_CONFIG2 : IA_CONFIG1;

  if (imc_active==IA_CONFIG2)
    imc_startup_network();
}
Ejemplo n.º 5
0
/* read_qnode: read a qnode from a file */
static imc_qnode *read_qnode(FILE *in)
{
  imc_qnode *p;
  imc_mail *m;
  char line[IMC_DATA_LENGTH];
  char temp1[IMC_DATA_LENGTH], temp2[IMC_DATA_LENGTH];

  fgets(line, IMC_DATA_LENGTH, in);
  if (ferror(in) || feof(in))
    return NULL;

  sscanf(line, "%[^ ] %[^\n]", temp1, temp2);
  m=find_ml(temp1);
  if (!m)
  {
    imc_logerror("read_qnode: ID %s not in mail queue", temp1);
    return NULL;
  }

  p=new_qnode();

  m->usage++;
  p->data  = m;
  p->tomud = imc_strdup(temp2);

  return p;
}
Ejemplo n.º 6
0
/* called when a keepalive has been received */
void imc_recv_keepalive(const char *from, const char *version, const char *flags)
{
  imc_reminfo *p;

  if (!strcasecmp(from, imc_name))
    return;
  
  /*  this should never fail, imc.c should create an
   *  entry if one doesn't exist (in the path update
   *  code)
   */
  p=imc_find_reminfo(from, 0);
  if (!p)		    /* boggle */
    return;

  if(!time_of_last_ralive)
  {
	time_of_last_ralive=time(NULL);
  }
  else
  {
        time_since_last_ralive = time(NULL) - time_of_last_ralive;
	time_of_last_ralive =time(NULL);
  }

  if (imc_hasname(flags, "hide"))
    p->hide=1;
  else
    p->hide=0;
  
  /* lower-level code has already updated p->alive */

  if (strcasecmp(version, p->version))    /* remote version has changed? */
  {
    imc_strfree(p->version);              /* if so, update it */
    p->version=imc_strdup(version);
  }

  /* Only routers should ping - and even then, only directly connected muds */
  /* and only if there is an open connection - shogar */
  if (imc_is_router && imc_getinfo(from) && 
	imc_getinfo(from)->connection && imc_getinfo(from)->connection->state==IMC_CONNECTED)
  {
    struct timeval tv;

    gettimeofday(&tv, NULL);

    imc_send_ping(from, tv.tv_sec, tv.tv_usec);
  }
  /* or muds acting as a hub to another mud - shogar */
  if (!imc_is_router && imc_getinfo(from) && imc_getinfo(from)->connection
    && !(imc_getinfo(from)->flags & IMC_HUB) && mud_has_hub)
  {
    struct timeval tv;

    gettimeofday(&tv, NULL);

    imc_send_ping(from, tv.tv_sec, tv.tv_usec);
  }
}
Ejemplo n.º 7
0
void icec_load_channels(void)
{
  FILE *fp;
  char name[MAX_STRING_LENGTH];
  char buf1[MAX_STRING_LENGTH];
  char buf2[MAX_STRING_LENGTH];
  char buf3[MAX_STRING_LENGTH];
  char buf4[MAX_STRING_LENGTH];
  int l;

  strcpy(name, imc_prefix);
  strcat(name, "icec");

  fp=fopen(name, "r");
  if (!fp)
  {
    imc_logerror("Can't open %s", name);
    return;
  }

  while (fscanf(fp,
		"%s %s %d\n"
		"%[^\n]\n"
		"%[^\n]\n", buf1, buf2, &l, buf3, buf4) == 5)
  {
    ice_channel *c=imc_malloc(sizeof(*c));

    c->local=imc_malloc(sizeof(*c->local));
    
    c->name=imc_strdup(buf1);
    c->local->name=imc_strdup(buf2);
    c->local->format1=imc_strdup(buf3);
    c->local->format2=imc_strdup(buf4);
    c->local->level=l;
    
    c->next=saved_channel_list;
    saved_channel_list=c;

    imc_logstring("ICEc: configured %s as %s",
		  c->name, c->local->name);
  }

  fclose(fp);
}
Ejemplo n.º 8
0
void icec_save_channels(void)
{
  ice_channel *c;
  FILE *fp;
  char name[MAX_STRING_LENGTH];

  strcpy(name, imc_prefix);
  strcat(name, "icec");

  fp=fopen(name, "w");
  if (!fp)
  {
    imc_logerror("Can't write to %s", name);
    return;
  }
  
  for (c=saved_channel_list; c; c=c->next)
  {
    /* update */
    ice_channel *current=icec_findlchannel(c->local->name);
    if (current)
    {
      imc_strfree(c->name);
      imc_strfree(c->local->format1);
      imc_strfree(c->local->format2);

      c->name=imc_strdup(current->name);
      c->local->format1=imc_strdup(current->local->format1);
      c->local->format2=imc_strdup(current->local->format2);
      c->local->level=current->local->level;
    }

    /* save */
    fprintf(fp,
	    "%s %s %d\n"
	    "%s\n"
	    "%s\n",
	    c->name, c->local->name, c->local->level,
	    c->local->format1,
	    c->local->format2);
  }

  fclose(fp);
}
Ejemplo n.º 9
0
void icec_notify_update(ice_channel *c)
{
  if (!c->local)
  {
    /* saved channel? */
    ice_channel *saved;

    for (saved=saved_channel_list; saved; saved=saved->next)
      if (!strcasecmp(saved->name, c->name))
      {
	c->local=imc_malloc(sizeof(icec_lchannel));
	c->local->name=imc_strdup(saved->local->name);
	c->local->format1=imc_strdup(saved->local->format1);
	c->local->format2=imc_strdup(saved->local->format2);
	c->local->level=saved->local->level;

	return;
      }
  }
}
Ejemplo n.º 10
0
/* init_ml: init the maillist */
static void init_ml(void)
{
  imc_ml_head          = new_mail();
  imc_ml_head->to      = imc_strdup("");
  imc_ml_head->from    = imc_strdup("");
  imc_ml_head->date    = imc_strdup("");
  imc_ml_head->subject = imc_strdup("");
  imc_ml_head->text    = imc_strdup("");
  imc_ml_head->id      = imc_strdup("");
}
Ejemplo n.º 11
0
/* read_mailid: read a mailid from a file, NULL on EOF */
static imc_mailid *read_mailid(FILE *in)
{
  imc_mailid *p;
  char line[IMC_DATA_LENGTH];
  char temp[IMC_DATA_LENGTH];
  time_t r;

  fgets(line, IMC_DATA_LENGTH, in);
  if (ferror(in) || feof(in))
    return NULL;

  sscanf(line, "%[^ ] %ld", temp, &r);

  p=new_mailid();

  p->id       = imc_strdup(temp);
  p->received = r;

  return p;
}
Ejemplo n.º 12
0
Archivo: imc.c Proyecto: bkero/Smaug
/* checkrepeat: check for repeats in the memory table */
static int checkrepeat(const char *mud, unsigned long seq)
{
  int i;

  for (i=0; i<IMC_MEMORY; i++)
    if (imc_memory[i].from && 
        !strcasecmp(mud, imc_memory[i].from) &&
        seq == imc_memory[i].sequence)
      return 1;

  /* not a repeat, so log it */

  if (imc_memory[memory_head].from)
    imc_strfree(imc_memory[memory_head].from);

  imc_memory[memory_head].from     = imc_strdup(mud);
  imc_memory[memory_head].sequence = seq;
  
  memory_head++;
  if (memory_head==IMC_MEMORY)
    memory_head=0;

  return 0;
}
Ejemplo n.º 13
0
/* read_mail: read a single mail from a file, NULL on EOF */
static imc_mail *read_mail(FILE *in)
{
  imc_mail *p;
  char line[IMC_DATA_LENGTH];
  char temp[IMC_DATA_LENGTH];

  fgets(line, IMC_DATA_LENGTH, in);
  if (ferror(in) || feof(in))
    return NULL;

  p=new_mail();

  sscanf(line, "From %[^\n]", temp);
  p->from=imc_strdup(unescape(temp));
  fgets(line, IMC_DATA_LENGTH, in);
  sscanf(line, "To %[^\n]", temp);
  p->to=imc_strdup(unescape(temp));
  fgets(line, IMC_DATA_LENGTH, in);
  sscanf(line, "Subject %[^\n]", temp);
  p->subject=imc_strdup(unescape(temp));
  fgets(line, IMC_DATA_LENGTH, in);
  sscanf(line, "Date %[^\n]", temp);
  p->date=imc_strdup(unescape(temp));
  fgets(line, IMC_DATA_LENGTH, in);
  sscanf(line, "Text %[^\n]", temp);
  p->text=imc_strdup(unescape(temp));
  fgets(line, IMC_DATA_LENGTH, in);
  sscanf(line, "ID %[^\n]", temp);
  p->id=imc_strdup(unescape(temp));
  fgets(line, IMC_DATA_LENGTH, in);
  sscanf(line, "Received %ld", &p->received);

  p->usage=0;

  return p;
}
Ejemplo n.º 14
0
/* imc_send_mail: called by the mud to add a piece of mail to the queue */
void imc_send_mail(const char *from, const char *to, const char *date,
		   const char *subject, const char *text)
{
  char temp[IMC_DATA_LENGTH];
  imc_mail *m;
  imc_qnode *qroot, *q;
  char arg[IMC_NAME_LENGTH];
  const char *mud;
  int when=10;

  /* set up the entry for the mail list */

  m=new_mail();

  mudtoaddr(to, temp);		/* qualify local addresses */
  m->to       = imc_strdup(temp);
  sprintf(temp, "%s@%s", from, imc_name);	/* qualify sender */
  m->from     = imc_strdup(temp);
  m->date     = imc_strdup(date);
  m->subject  = imc_strdup(subject);
  m->id       = imc_strdup(generate_mailid());
  m->text     = imc_strdup(text);
  m->received = imc_now;

  qroot=NULL;			/* initialise the local list */
  to=imc_getarg(to, arg, IMC_NAME_LENGTH);

  while (*arg)
  {
    /*  get a mudname and check if we've already added a queue entry for that
     *  mud. If not, add it
     */

    if (strchr(arg, '@') != NULL && (mud = imc_mudof(arg))[0] != 0 &&
	strcasecmp(mud, imc_name))
    {
      if (!strcmp(mud, "*"))
	q=NULL;	                /* catch the @* case - not yet implemented */
      else
	for (q=qroot; q; q=q->next)
	  if (!strcasecmp(q->tomud, mud))
	    break;

      if (!q)			/* not seen yet */
      {				/* add to the top of our mini-queue */
	q=new_qnode();
	q->tomud=imc_strdup(mud);
	q->data=m;
	q->next=qroot;
	m->usage++;
	qroot=q;

	imc_add_event(when, ev_qnode_send, q, 1);
	when += rand()%30+30;
      }
    }

    /* get the next address */

    to=imc_getarg(to, arg, IMC_NAME_LENGTH);
  }

  if (!qroot)			/* boggle, no foreign addresses?? */
  {
    free_mail(m);
    return;
  }

  /* add mail to mail list, add mini-queue to mail queue */

  add_ml(m);
  add_mq(qroot);
  save_ml();
  save_mq();
}
Ejemplo n.º 15
0
void imc_recv_mail(const char *from, const char *to, const char *date,
		   const char *subject, const char *id, const char *text)
{
  imc_mailid *mid;
  imc_packet out;
  char *reason;
  char temp[IMC_DATA_LENGTH];

  /* silently drop broadcast mail */
  if (strchr(to, '*'))
    return;

  imc_initdata(&out.data);
  sprintf(out.to, "Mail-daemon@%s", imc_mudof(from));
  strcpy(out.from, "Mail-daemon");

  /* check if we've already seen it */

  mid=find_id(id);

  if (mid)
  {
    strcpy(out.type, "mail-ok");
    imc_addkey(&out.data, "id", id);

    imc_send(&out);
    imc_freedata(&out.data);

    mid->received = imc_now;

    return;
  }

  /* check for rignores */

  if (imc_isignored(from))
  {
    strcpy(out.type, "mail-reject");
    imc_addkey(&out.data, "id", id);
    imc_addkey(&out.data, "reason", "You are being ignored.");

    imc_send(&out);
    imc_freedata(&out.data);
    return;
  }

  /* forward it to the mud */

  addrtomud(to, temp);

  if ((reason=imc_mail_arrived(from, temp, date, subject, text)) == NULL)
  {
    /* it was OK */

    strcpy(out.type, "mail-ok");
    imc_addkey(&out.data, "id", id);

    imc_send(&out);
    imc_freedata(&out.data);

    mid=new_mailid();
    mid->id=imc_strdup(id);
    mid->received=imc_now;

    add_idlist(mid);
    save_idlist();
    return;
  }

  /* mud rejected the mail */

  strcpy(out.type, "mail-reject");
  imc_addkey(&out.data, "id", id);
  imc_addkey(&out.data, "reason", reason);

  imc_send(&out);
  imc_freedata(&out.data);
}
Ejemplo n.º 16
0
/* add the mud to our list if we're a hub, and reply with our info. -- Scion*/
void imc_recv_autoconnect(const char *to, const char *rhost, int rport, 
	const char *rclientpw, const char *rserverpw, 
  	int rrcvstamp, int rnoforward, const char *rflags, 
	const char *remotename)
{
  imc_packet out;
  char no_port[IMC_MNAME_LENGTH];

  int a=0,b=0;

  imc_info *i,*o;

   if (imc_active<IA_UP)
    return;


  /* Receive all this info: -- Scion 
	 imc set <mudname> all <host> <port> <clientpw> <serverpw> <rcvstamp> <noforward> <flags>
		*/
#ifdef NO_OPTIMIZE
   imc_logstring("Autoconnect refused because NO_OPTIMIZE is defined.");
   return;
#endif
  
  if (imc_name && !strcasecmp(remotename, imc_name)) {
	  imc_logstring("Autoconnect attempt allegedly from this server! Ignoring.");
      return; /* Hey! That's our name! */
  }
	  
  /* Get that pesky port out of the host name */
  for (a=0;a<strlen(imc_siteinfo.host); a++) {
	  if (imc_siteinfo.host[a]==':'
	  || imc_siteinfo.host[a]==' ') 
 	  {
		  break;
	  }
	  no_port[b++]=imc_siteinfo.host[a];
	  no_port[b]='\0';
  }
  /* Send our information back to the MUD */
  imc_initdata(&out.data);
  strcpy(out.type, "switch-reply");
  strcpy(out.from, "*");
  strcpy(out.to, "*@");
  imc_sncpy(out.to+2, remotename, IMC_MNAME_LENGTH-2);
  
  imc_addkey(&out.data, "confirm", "connection added");
  imc_addkey(&out.data, "host", no_port); /* don't put the port number in from imc_siteinfo.host b/c it's the game port */
  imc_addkeyi(&out.data, "port", (int)imc_port);
  imc_addkey(&out.data, "clientpw", rclientpw);
  imc_addkey(&out.data, "serverpw", rserverpw);
  imc_addkeyi(&out.data, "rcvstamp", 0);
  imc_addkeyi(&out.data, "noforward", 0);
  imc_addkey(&out.data, "flags", "none");
  imc_addkey(&out.data, "localname", imc_name);
  
  imc_send(&out);
  
  imc_freedata(&out.data); 
  
  /* Setup the new connection... */
  if((o=imc_getinfo(remotename))) /* remove old entries - shogar */
  {
  	i=imc_insert_info();
        i->connection=o->connection;
        i->flags=o->flags;
        if (i->connection) i->connection->info=i;
  	imc_cancel_info(o); 
  }
  else
  {
  	i=imc_insert_info();
        i->flags = imc_flagvalue("new", imc_connection_flags); /* Hubs don't need specific flags really */
  }


  i->name       = imc_strdup(remotename);
  i->host       = imc_strdup(rhost);
  i->port       = (unsigned short)rport;
  i->clientpw   = imc_strdup(rclientpw);
  i->serverpw   = imc_strdup(rserverpw);
  i->rcvstamp   = rrcvstamp;
  i->noforward  = rnoforward;
  i->connect_attempts = 0;


  imc_saveconfig();
  /* All done! */
  
  imc_logstring("Autoconnect accepted from %s", to);


}
Ejemplo n.º 17
0
void imc_whoreply_start(const char *to)
{
  wr_sequence=0;
  wr_to=imc_strdup(to);
  wr_buf=imc_getsbuf(IMC_DATA_LENGTH);
}
Ejemplo n.º 18
0
/* handle a packet destined for us, or a broadcast */
void imc_recv(const imc_packet *p)
{
  imc_char_data d;
  int bcast;
  imc_reminfo *i;

  bcast=!strcmp(imc_mudof(p->i.to), "*") ? 1 : 0;
  
  getdata(p, &d);

  if(!imc_is_router)
  {
	i=imc_find_reminfo(imc_mudof(p->from),0);
	if(i)
	{
		if(i->path)
			imc_strfree(i->path);
		i->path=imc_strdup(p->i.path);
		i->ping=0;
                i->type=0;
	}
  }
  
  /* chat: message to a channel (broadcast) */
  if (!strcasecmp(p->type, "chat") && !imc_isignored(p->from))
    imc_recv_chat(&d, imc_getkeyi(&p->data, "channel", 0),
		  imc_getkey(&p->data, "text", ""));

  /* emote: emote to a channel (broadcast) */
  else if (!strcasecmp(p->type, "emote") && !imc_isignored(p->from))
    imc_recv_emote(&d, imc_getkeyi(&p->data, "channel", 0),
		   imc_getkey(&p->data, "text", ""));

  /* tell: tell a player here something */
  else if (!strcasecmp(p->type, "tell"))
  {
    if (imc_isignored(p->from))
    {
      imc_sendignore(p->from);
    }
    else
    {
      imc_recv_tell(&d, p->to, imc_getkey(&p->data, "text", ""),
		    imc_getkeyi(&p->data, "isreply", 0));
    }
  }

  /* who-reply: receive a who response */
  else if (!strcasecmp(p->type, "who-reply"))
    imc_recv_whoreply(p->to, imc_getkey(&p->data, "text", ""),
		      imc_getkeyi(&p->data, "sequence", -1));

  /* who: receive a who request */
  else if (!strcasecmp(p->type, "who"))
  {
    if (imc_isignored(p->from))
    {
      imc_sendignore(p->from);
    }
    else
    {
      imc_recv_who(&d, imc_getkey(&p->data, "type", "who"));
    }
  }

  /* whois-reply: receive a whois response */
  else if (!strcasecmp(p->type, "whois-reply"))
    imc_recv_whoisreply(p->to, imc_getkey(&p->data, "text", ""));

  /* whois: receive a whois request */
  else if (!strcasecmp(p->type, "whois"))
    imc_recv_whois(&d, p->to);

  /* beep: beep a player */
  else if (!strcasecmp(p->type, "beep"))
  {
    if (imc_isignored(p->from))
    {
      imc_sendignore(p->from);
    }
    else
    {
      imc_recv_beep(&d, p->to);
    }
  }

  /* is-alive: receive a keepalive (broadcast) */
  else if (!strcasecmp(p->type, "is-alive"))
    imc_recv_keepalive(imc_mudof(p->from),
		       imc_getkey(&p->data, "versionid", "unknown"),
		       imc_getkey(&p->data, "flags", ""));

  /* ping: receive a ping request */
  else if (!strcasecmp(p->type, "ping"))
    imc_recv_ping(imc_mudof(p->from), imc_getkeyi(&p->data, "time-s", 0),
		  imc_getkeyi(&p->data, "time-us", 0), p->i.path);

  /* ping-reply: receive a ping reply */
  else if (!strcasecmp(p->type, "ping-reply"))
    imc_recv_pingreply(imc_mudof(p->from), imc_getkeyi(&p->data, "time-s", 0),
		       imc_getkeyi(&p->data, "time-us", 0),
		       imc_getkey(&p->data, "path", NULL), p->i.path);

  /* mail: mail something to a local player */
  else if (!strcasecmp(p->type, "mail"))
    imc_recv_mail(imc_getkey(&p->data, "from", "error@hell"),
		  imc_getkey(&p->data, "to", "error@hell"),
		  imc_getkey(&p->data, "date", "(IMC error: bad date)"),
		  imc_getkey(&p->data, "subject", "no subject"),
		  imc_getkey(&p->data, "id", "bad_id"),
		  imc_getkey(&p->data, "text", ""));

  /* mail-ok: remote confirmed that they got the mail ok */
  else if (!strcasecmp(p->type, "mail-ok"))
    imc_recv_mailok(p->from, imc_getkey(&p->data, "id", "bad_id"));

  /* mail-reject: remote rejected our mail, bounce it */
  else if (!strcasecmp(p->type, "mail-reject"))
    imc_recv_mailrej(p->from, imc_getkey(&p->data, "id", "bad_id"),
		     imc_getkey(&p->data, "reason",
				"(IMC error: no reason supplied"));

/* handle keepalive requests - shogar */
  else if (!strcasecmp(p->type, "keepalive-request"))
  {
        if(imc_is_router)
        	imc_logstring("Recieved keepalive request from %s", p->from);
	imc_send_keepalive();
  }
/* expire closed hubs - shogar */
  else if (!strcasecmp(p->type, "close-notify"))
  {
        imc_reminfo *r;
	char fake[90];
    	struct timeval tv;

        if(imc_is_router)
  		imc_logstring("%s reports %s closed.", p->from,
        	imc_getkey(&p->data, "host","unknown"));
        if(imc_is_router)
		return;

	r = imc_find_reminfo(imc_getkey(&p->data,"host","unknown"),0);
        if(r)
	{
		r->type = IMC_REMINFO_EXPIRED;
		for(r=imc_reminfo_list;r;r=r->next)
		{
			char *sf;
			sprintf(fake,"!%s",imc_getkey(&p->data,"host","___unknown"));
			if(r->name 
			&& r->path 
			&& (sf=strstr(r->path,fake))
			&& sf 
			&& (*(sf+strlen(fake))=='!' || *(sf+strlen(fake)) == 0) 
			)
			{

//				imc_logstring("Expiring %s",r->path);
				r->type = IMC_REMINFO_EXPIRED;
    				gettimeofday(&tv, NULL);
    				imc_send_ping(r->name, tv.tv_sec, tv.tv_usec);
			}
		}
				
	}
  }

/* These 4 added by me for the auto-hub-swap -- Scion 1/9/99 */
  else if (!strcasecmp(p->type, "inforequest")) /* Request connection info from all 1.00a hubs -- Scion */
    imc_recv_inforequest(p->from); /* Had to use inforequest because 0.10 responds to info-request :) */
  else if (!strcasecmp(p->type, "info-reply")) /* receive the reply from the inforequest :) -- Scion */
	imc_recv_info_reply(p->from, imc_getkey(&p->data, "hub", "no"), imc_getkeyi(&p->data, "direct", -1));
  
  else if (!strcasecmp(p->type, "switch-reply")) /* hub confirmed that it added a connection to us. -- Scion */
	  imc_autoconnect_reply_accept(    /* Add a connection back to the hub */
	  p->from,      
	  imc_getkey(&p->data, "host", "!!!"), 
	  imc_getkeyi(&p->data, "port", -1),
	  imc_getkey(&p->data, "clientpw", "password"), 
	  imc_getkey(&p->data, "serverpw", "password"), 
	  imc_getkeyi(&p->data, "rcvstamp", 0), 
	  imc_getkeyi(&p->data, "noforward", 0), 
	  imc_getkey(&p->data, "flags", "none"),
	  imc_getkey(&p->data, "localname", "!!!"),
	  imc_getkey(&p->data, "confirm", "not accepted")
	  );
  else if (!strcasecmp(p->type, "imc-switch")) /* hub receives request to add a connection -- Scion */
	  imc_recv_autoconnect(
	  p->from, 
	  imc_getkey(&p->data, "host", "!!!"), 
	  imc_getkeyi(&p->data, "port", -1),
	  imc_getkey(&p->data, "clientpw", "password"), 
	  imc_getkey(&p->data, "serverpw", "password"), 
	  imc_getkeyi(&p->data, "rcvstamp", 0), 
	  imc_getkeyi(&p->data, "noforward", 0), 
	  imc_getkey(&p->data, "flags", "none"),
	  imc_getkey(&p->data, "localname", "!!!")
	  );
/* call catch-all fn if present */
  else
  {
    imc_packet out;

	if (imc_recv_hook)
      if ((*imc_recv_hook)(p, bcast))
	return;

    if (bcast || !strcasecmp(p->type, "reject"))
      return;
    
    /* reject packet */
      if (!imc_is_router)
    { 
    strcpy(out.type, "reject");
    strcpy(out.to, p->from);
    strcpy(out.from, p->to);

    imc_clonedata(&p->data, &out.data);
    imc_addkey(&out.data, "old-type", p->type);

    imc_send(&out);
    imc_freedata(&out.data);
    }
  }
}