Exemplo n.º 1
0
/* send a keepalive request to everyone - shogar */
void imc_request_keepalive(void)
{
  imc_packet out;
/*
  if (imc_active<IA_UP)
    return;
*/

  if(!time_of_last_salive)
  {
	time_of_last_salive=time(NULL);
  }
  else
  {
        time_since_last_salive = time(NULL) - time_of_last_salive;
	time_of_last_salive =time(NULL);
  }
  imc_initdata(&out.data);
  strcpy(out.type, "keepalive-request");
  strcpy(out.from, "*");
  strcpy(out.to, "*@*");
  imc_addkey(&out.data, "versionid", IMC_VERSIONID);
  if (imc_siteinfo.flags[0])
    imc_addkey(&out.data, "flags", imc_siteinfo.flags);

  imc_send(&out);
  imc_freedata(&out.data);
}
Exemplo n.º 2
0
const char *icec_command(const char *from, const char *arg) {
    char cmd[IMC_NAME_LENGTH];
    char chan[IMC_NAME_LENGTH];
    char data[IMC_DATA_LENGTH];
    const char *p;
    imc_packet out;
    ice_channel *c;
    p = imc_getarg(arg, cmd, IMC_NAME_LENGTH);
    p = imc_getarg(p, chan, IMC_NAME_LENGTH);
    strcpy(data, p);
    if(!cmd[0] || !chan[0]) {
        return "Syntax: icommand <command> <node:channel> [<data..>]";
    }
    p = strchr(chan, ':');
    if(!p) {
        c = icec_findlchannel(chan);
        if(c) {
            strcpy(chan, c->name);
        }
    }
    sprintf(out.to, "ICE@%s", ice_mudof(chan));
    strcpy(out.type, "ice-cmd");
    strcpy(out.from, from);
    imc_initdata(&out.data);
    imc_addkey(&out.data, "channel", chan);
    imc_addkey(&out.data, "command", cmd);
    imc_addkey(&out.data, "data", data);
    imc_send(&out);
    imc_freedata(&out.data);
    return "Command sent.";
}
Exemplo n.º 3
0
void imc_send_direct(const imc_char_data *from, int channel,
					 const char *argument, const char *to) {
	/* This sends a message out only to those MUDs directly connected to the one running this code.
	Added 12/26/98 to cut down on UCMM IMC network traffic -- Scion */
	imc_packet out;
  char tobuf[IMC_MNAME_LENGTH];
    imc_connect *c;

  if (imc_active<IA_UP)
    return;

  setdata(&out, from);

  strcpy(out.type, "chat"); /* emulate a broadcast packet so we don't have to add a imc_recv_direct() */
  strcpy(out.to, "*@!direct!"); /* But we're not sending to *@* this time. */
  imc_addkey(&out.data, "text", argument);
  imc_addkeyi(&out.data, "channel", channel);

  for (c=imc_connect_list; c; c=c->next) /* Go through the list of direct connections */
      if (c->state==IMC_CONNECTED) {
		  strcpy(tobuf, c->info->name);
		  strcpy(out.to, "*@");
		  strcat(out.to, tobuf);
          imc_send(&out); /* And send them what they think is a broadcast packet. */
	  }  

  imc_freedata(&out.data);
}
Exemplo n.º 4
0
/* send an emote out on a channel */
void imc_send_emote(const imc_char_data *from, int channel,
		    const char *argument, const char *to)
{
  imc_packet out;
  char tobuf[IMC_MNAME_LENGTH];

  if (imc_active<IA_UP)
    return;

  setdata(&out, from);

  strcpy(out.type, "emote");
  imc_addkeyi(&out.data, "channel", channel);
  imc_addkey(&out.data, "text", argument);

  to=imc_getarg(to, tobuf, IMC_MNAME_LENGTH);
  while (tobuf[0])
  {
    if (!strcmp(tobuf, "*") || !strcasecmp(tobuf, imc_name) ||
	imc_find_reminfo(tobuf, 0))
    {
      strcpy(out.to, "*@");
      strcat(out.to, tobuf);
      imc_send(&out);
    }

    to=imc_getarg(to, tobuf, IMC_MNAME_LENGTH);
  }

  imc_freedata(&out.data);
}
Exemplo n.º 5
0
/* send a keepalive to everyone */
void imc_send_keepalive(void)
{
  imc_packet out;

  if (imc_active<IA_UP)
    return;

  imc_initdata(&out.data);
  strcpy(out.type, "is-alive");
  strcpy(out.from, "*");
  strcpy(out.to, "*@*");
  imc_addkey(&out.data, "versionid", IMC_VERSIONID);
  if (imc_siteinfo.flags[0])
    imc_addkey(&out.data, "flags", imc_siteinfo.flags);

  imc_send(&out);
  imc_freedata(&out.data);
  imc_add_event(ICED_REFRESH_TIME, ev_iced_refresh, NULL, 1);
}
Exemplo n.º 6
0
/* send connection info to new hub for optimization */
void imc_send_autoconnect(const char *to)
{
  imc_packet out;
  imc_info *i;
  char no_port[IMC_MNAME_LENGTH];

  int a=0,b=0;

  if (imc_active<IA_UP)
    return;

  i=imc_getinfo(to);
  if(i && i == imc_info_list && i->connection) /* not if primary hub - shogar */
    return;

     /* Send all this info: -- Scion 
	 imc set <mudname> all <host> <port> <clientpw> <serverpw> <rcvstamp> <noforward> <flags>
		*/
  imc_initdata(&out.data);
  strcpy(out.type, "imc-switch");
  strcpy(out.from, "*");
  strcpy(out.to, "*@");
  imc_sncpy(out.to+2, to, IMC_MNAME_LENGTH-2);

  /* 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';
  }
  imc_addkey(&out.data, "host", no_port);
  imc_addkeyi(&out.data, "port", (int)imc_port);
  
  if(i) /* don't assign new ones, if we have passwords */
  {
  	imc_addkey(&out.data, "clientpw", i->clientpw);
  	imc_addkey(&out.data, "serverpw", i->serverpw);
  }
  else 
  {
  	imc_addkey(&out.data, "clientpw", imc_make_password());/* these are random */
  	imc_addkey(&out.data, "serverpw", imc_make_password());
  }
  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);
  imc_logstring("Autoconnect sent to %s", to);
}
Exemplo n.º 7
0
/* try sending a qnode */
void ev_qnode_send(void *data)
{
  imc_qnode *p=(imc_qnode *)data;
  imc_packet out;

  save_ml();
  save_mq();

  /* send it.. */

  imc_initdata(&out.data);

  sprintf(out.to, "Mail-daemon@%s", p->tomud);
  strcpy(out.from, "Mail-daemon");
  strcpy(out.type, "mail");

  imc_addkey(&out.data, "to", p->data->to);
  imc_addkey(&out.data, "from", p->data->from);
  imc_addkey(&out.data, "subject", p->data->subject);
  imc_addkey(&out.data, "date", p->data->date);
  imc_addkey(&out.data, "text", p->data->text);
  imc_addkey(&out.data, "id", p->data->id);

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

  /* try resending it in an hour */

  imc_add_event(3600, ev_qnode_send, data, 1);
}
Exemplo n.º 8
0
void icec_sendmessage(ice_channel *c, const char *name, const char *text, int emote) {
    imc_packet out;
    strcpy(out.from, name);
    imc_initdata(&out.data);
    imc_addkey(&out.data, "channel", c->name);
    imc_addkey(&out.data, "text", text);
    imc_addkeyi(&out.data, "emote", emote);
    /* send a message out on a channel */
    if(c->policy == ICE_PRIVATE) {
        /* send to the daemon to distribute */
        /* send locally */
        icec_showchannel(c, imc_makename(name, imc_name), text, emote);
        sprintf(out.to, "ICE@%s", ice_mudof(c->name));
        strcpy(out.type, "ice-msg-p");
    } else {
        /* broadcast */
        strcpy(out.type, "ice-msg-b");
        strcpy(out.to, "*@*");
    }
    imc_send(&out);
    imc_freedata(&out.data);
}
Exemplo n.º 9
0
void ev_icec_firstrefresh(void *dummy) {
    imc_packet out;
    if(imc_active < IA_UP) {
        return;
    }
    strcpy(out.from, "*");
    strcpy(out.to, "ICE@*");
    strcpy(out.type, "ice-refresh");
    imc_initdata(&out.data);
    imc_addkey(&out.data, "channel", "*");
    imc_send(&out);
    imc_freedata(&out.data);
}
Exemplo n.º 10
0
Arquivo: imc.c Projeto: bkero/Smaug
/* notify everyone of the closure - shogar */
void imc_close_notify(const char *host)
{
  imc_packet out;
  char shorthost[80];

  if (imc_active<IA_UP)
    return;

  strcpy(shorthost,host);
  if(strchr(shorthost,'['))
    *(strchr(shorthost,'['))=0;

  imc_initdata(&out.data);
  strcpy(out.type, "close-notify");
  strcpy(out.from, "*");
  strcpy(out.to, "*@*");
  imc_addkey(&out.data, "versionid", IMC_VERSIONID);
  if (imc_siteinfo.flags[0])
    imc_addkey(&out.data, "flags", imc_siteinfo.flags);
  imc_addkey(&out.data, "host", shorthost);
  imc_send(&out);
  imc_freedata(&out.data);
}
Exemplo n.º 11
0
 /* This function was rendered useless when everything was packed into
 rquery, and the rquery info command returned that dumb little #define instead
 of this info. I swapped this with the rquery info function, and now I'm salvaging
 this function to use for something entirely different. 1/5/99 -- Scion
 */
void imc_recv_inforequest(const char *from) {
	/* What we're going to do here is to reply to a type of packet
	labelled as "inforequest". We'll reply with two things: 
	1) Are we a hub or not?
	2) The number of direct connections we have.
	
	  What will happen when the MUD receives this info is that it will compare
	  each of the available hubs and find the one with the least number of direct
	  connections. It will then switch its hub connection to the hub with less
	  connections, hopefully averaging the number of connections per hub. You will
	  be able to prevent this auto-swap by #defining NO_OPTIMIZE in imc-config.h -- Scion */
  imc_packet reply;
  int num_direct=0;
  imc_info *i;
  
  extern imc_info *imc_info_list;

  strcpy(reply.to, from);
  strcpy(reply.from, "*");

  imc_initdata(&reply.data);

  if (imc_isignored(from)) /* Don't reply if they're ignored */
  {
    strcpy(reply.type, "info-unavailable");
    imc_send(&reply);
  }
  strcpy(reply.type, "info-reply");
    
  if (imc_is_router) 
  	/* don't even send a reply if we're not a hub -- Scion */
  {
	  imc_addkey(&reply.data, "hub",    "yes");
	  for (i=imc_info_list; i; i=i->next)
              if(i->connection && i->connection->state & IMC_CONNECTED) /* only the live ones - shogar */
			num_direct++;
	  imc_addkeyi(&reply.data, "direct",    
		imc_siteinfo.maxguests - num_direct);
  
        /*  don't send if num_direct exceeds maxguest - shogar */
        if(num_direct <= imc_siteinfo.maxguests)
        {
  		imc_send(&reply);
  		imc_logstring("Sent info-reply to %s.", from);
	}
  }
  imc_freedata(&reply.data);
}
Exemplo n.º 12
0
/* send a pingreply with the given timestamp */
void imc_send_pingreply(const char *to, int time_s, int time_u, const char *path)
{
  imc_packet out;

  if (imc_active<IA_UP)
    return;

  imc_initdata(&out.data);
  strcpy(out.type, "ping-reply");
  strcpy(out.from, "*");
  strcpy(out.to, "*@");
  imc_sncpy(out.to+2, to, IMC_MNAME_LENGTH-2);
  imc_addkeyi(&out.data, "time-s", time_s);
  imc_addkeyi(&out.data, "time-us", time_u);
  imc_addkey(&out.data, "path", path);

  imc_send(&out);
  imc_freedata(&out.data);
}
Exemplo n.º 13
0
/* respond with a whois-reply */
void imc_send_whoisreply(const char *to, const char *data)
{
  imc_packet out;

  if (imc_active<IA_UP)
    return;

  if (!strcmp(imc_mudof(to), "*"))
    return; /* don't let them do this */

  imc_initdata(&out.data);

  imc_sncpy(out.to, to, IMC_NAME_LENGTH);
  strcpy(out.type, "whois-reply");
  strcpy(out.from, "*");
  imc_addkey(&out.data, "text", data);

  imc_send(&out);
  imc_freedata(&out.data);
}
Exemplo n.º 14
0
/* send a who-request to a remote mud */
void imc_send_who(const imc_char_data *from, const char *to, const char *type)
{
  imc_packet out;

  if (imc_active<IA_UP)
    return;

  if (!strcmp(imc_mudof(to), "*"))
    return; /* don't let them do this */

  setdata(&out, from);

  sprintf(out.to, "*@%s", to);
  strcpy(out.type, "who");

  imc_addkey(&out.data, "type", type);

  imc_send(&out);
  imc_freedata(&out.data);
}
Exemplo n.º 15
0
/* send a tell to a remote player */
void imc_send_tell(const imc_char_data *from, const char *to,
		   const char *argument, int isreply)
{
  imc_packet out;

  if (imc_active<IA_UP)
    return;

  if (!strcmp(imc_mudof(to), "*"))
    return; /* don't let them do this */

  setdata(&out, from);

  imc_sncpy(out.to, to, IMC_NAME_LENGTH);
  strcpy(out.type, "tell");
  imc_addkey(&out.data, "text", argument);
  if (isreply)
    imc_addkeyi(&out.data, "isreply", isreply);

  imc_send(&out);
  imc_freedata(&out.data);
}
Exemplo 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);


}
Exemplo n.º 17
0
static void parsekeys(const char *string, imc_data * data) {
    const char *p1;
    char *p2;
    char k[IMC_DATA_LENGTH], v[IMC_DATA_LENGTH];
    int quote;
    p1 = string;
    while(*p1) {
        while(*p1 && isspace(*p1)) {
            p1++;
        }
        p2 = k;
        while(*p1 && *p1 != '=' && p2 - k < IMC_DATA_LENGTH - 1) {
            *p2++ = *p1++;
        }
        *p2 = 0;
        if(!k[0] || !*p1) {	/* no more keys? */
            break;
        }
        p1++;			/* skip the '=' */
        if(*p1 == '"') {
            p1++;
            quote = 1;
        } else {
            quote = 0;
        }
        p2 = v;
        while(*p1 && (!quote || *p1 != '"') && (quote || *p1 != ' ') &&
                p2 - v < IMC_DATA_LENGTH + 1) {
            if(*p1 == '\\') {
                switch(*(++p1)) {
                case '\\':
                    *p2++ = '\\';
                    break;
                case 'n':
                    *p2++ = '\n';
                    break;
                case 'r':
                    *p2++ = '\r';
                    break;
                case '"':
                    *p2++ = '"';
                    break;
                default:
                    *p2++ = *p1;
                    break;
                }
                if(*p1) {
                    p1++;
                }
            } else {
                *p2++ = *p1++;
            }
        }
        *p2 = 0;
        if(!v[0]) {
            continue;
        }
        imc_addkey(data, k, v);
        if(quote && *p1) {
            p1++;
        }
    }
}
Exemplo n.º 18
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);
}
Exemplo n.º 19
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);
    }
  }
}