예제 #1
0
파일: imc.c 프로젝트: bkero/Smaug
/* accept a connection on the control port */
static void do_accept(void)
{
  int d;
  imc_connect *c;
  struct sockaddr_in sa;
  int size = sizeof(sa);
  int r;

  d=accept(control, (struct sockaddr *) &sa, &size);
  if (d<0)
  {
    imc_lerror("accept");
    return;
  }

  r=fcntl(d, F_GETFL, 0);
  if (r<0 || fcntl(d, F_SETFL, O_NONBLOCK | r)<0)
  {
    imc_lerror("do_accept: fcntl");
    close(d);
    return;
  }

  c=imc_new_connect();
  c->state    = IMC_WAIT1;
  c->desc     = d;

  imc_add_event(IMC_LOGIN_TIMEOUT, ev_login_timeout, c, 1);
  imc_logstring("connection from %s:%d on descriptor %d",
		inet_ntoa(sa.sin_addr), ntohs(sa.sin_port), d);
}
예제 #2
0
파일: imc-mail.c 프로젝트: bhyvex/cosMUD
/* 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);
}
예제 #3
0
/* global init */
void icec_init(void) {
    imc_logstring("ICE client starting.");
    icec_recv_chain = imc_recv_hook;
    imc_recv_hook = icec_recv;
    imc_add_event(60, ev_icec_firstrefresh, NULL, 1);
    icec_load_channels();
}
예제 #4
0
파일: imc-mail.c 프로젝트: bhyvex/cosMUD
/* load mailqueue, assumes init_mq done */
static void load_mq(void)
{
  FILE *in;
  imc_qnode *p;
  char name[200];
  int when=10;

  imc_sncpy(name, imc_prefix, 189);
  strcat(name, "mail-queue");

  in=fopen(name, "r");
  if (!in)
    return;

  p=read_qnode(in);
  while (!feof(in) && !ferror(in))
  {
    if (p)
    {
      add_mq(p);
      imc_add_event(when, ev_qnode_send, p, 1);
      when += rand()%30+30;
    }
    p=read_qnode(in);
  }

  fclose(in);
}
예제 #5
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);
}
예제 #6
0
파일: imc-mail.c 프로젝트: bhyvex/cosMUD
/* imc_mail_startup: start up the mail subsystem */
void imc_mail_startup(void)
{
  init_mq();
  init_ml();
  init_idlist();

  /* order is important here: we need the maillist to resolve the ID refs in
   * the mailqueue
   */

  load_ml();
  load_mq();
  load_idlist();

  /* queue an expiry event */

  imc_add_event(24*3600, ev_mailid_expire, NULL, 0);
}
예제 #7
0
파일: imc-interp.c 프로젝트: bkero/Smaug
/* 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);
}
예제 #8
0
파일: imc.c 프로젝트: bkero/Smaug
/* put a line onto descriptors output buffer */
static void do_send(imc_connect *c, const char *line)
{
  int len;
  char *newbuf;
  int newsize=c->outsize;

  if (c->state==IMC_CLOSED)
    return;

//  imc_debug(c, 1, line);	/* log outgoing traffic */

  if (!c->outbuf[0])
    c->newoutput=1;

  len=strlen(c->outbuf)+strlen(line)+3;

  if (len > c->outsize)
  {

#ifdef SHOW_OVERFLOW
	/* not an error anymore, expected and handled - shogar */
    if (len > IMC_MAXBUF)
    {
      if (!c->info || !(c->info->flags & IMC_QUIET))
      imc_logerror("%s: output buffer overflow", imc_getconnectname(c));
      imc_logerror("%d: was allocated", c->outsize);
//      imc_logerror("current buf: %s", c->outbuf);
//    do_close(c);
//      imc_free(c->outbuf,c->outsize);
//      c->outsize=IMC_MINBUF;
//      c->outbuf= imc_malloc(c->outsize);
//      len=strlen(line)+3;
//    return;
  }
#endif
    while(newsize < len)
      newsize*=2;

    newbuf=imc_malloc(newsize);
    strcpy(newbuf, c->outbuf);
    imc_free(c->outbuf, c->outsize);
    c->outbuf=newbuf;
    c->outsize=newsize;
  }
  if (len<c->outsize/2 && len >= IMC_MINBUF)
  {
    newsize=c->outsize/2;

    newbuf=imc_malloc(newsize);
    strcpy(newbuf, c->outbuf);
    imc_free(c->outbuf, c->outsize);
    c->outbuf=newbuf;
    c->outsize=newsize;
  }

  strcat(c->outbuf, line);
  strcat(c->outbuf, "\n\r");

  if (strlen(c->outbuf)>=c->outsize/2)
  {
    imc_cancel_event(ev_shrink_output, c);
    imc_add_event(IMC_SHRINKTIME, ev_shrink_output, c, 0);
  }
}
예제 #9
0
파일: imc.c 프로젝트: bkero/Smaug
/* read waiting data from descriptor.
 * read to a temp buffer to avoid repeated allocations
 */
static void do_read(imc_connect *c)
{
  int size;
  int r;
  char temp[IMC_MAXBUF];
  char *newbuf;
  int newsize;

  r=read(c->desc, temp, IMC_MAXBUF-1);
  if (!r || (r<0 && errno != EAGAIN && errno != EWOULDBLOCK))
  {
    if (!c->info || !(c->info->flags & IMC_QUIET))
    {
      if (r<0)                    /* read error */
      {
        imc_lerror("%s: read", imc_getconnectname(c));
      }
      else                        /* socket was closed */
      {
        imc_logerror("%s: read: EOF", imc_getconnectname(c));
      }
    }
    do_close(c);
    return;
  }
  
  if (r<0)			/* EAGAIN error */
    return;

  temp[r]=0;

  size=strlen(c->inbuf)+r+1;

  if (size>=c->insize)
  {

#ifdef SHOW_OVERFLOW
	/* not an error anymore, expected and handled - shogar */
    if (size>IMC_MAXBUF)
    {
        imc_logerror("%s: input buffer overflow", imc_getconnectname(c));
        imc_logerror("%d: was allocated", c->insize);
//      do_close(c);
//      imc_free(c->inbuf,c->insize);
//      c->insize=IMC_MINBUF;
//      c->inbuf= imc_malloc(c->insize);
//      size = r + 1;
//      return;
    }
      
#endif
    newsize=c->insize;
    while(newsize<size)
      newsize*=2;

    newbuf=imc_malloc(newsize);
    strcpy(newbuf, c->inbuf);
    imc_free(c->inbuf, c->insize);
    c->inbuf=newbuf;
    c->insize=newsize;
  }
  
  if (size>c->insize/2)
  {
    imc_cancel_event(ev_shrink_input, c);
    imc_add_event(IMC_SHRINKTIME, ev_shrink_input, c, 0);
  }
  if (size<c->insize/2 && size >= IMC_MINBUF)
  {
    newsize=c->insize;
    newsize/=2;

    newbuf=imc_malloc(newsize);
    strcpy(newbuf, c->inbuf);
    imc_free(c->inbuf, c->insize);
    c->inbuf=newbuf;
    c->insize=newsize;
  }

  strcat(c->inbuf, temp);

  imc_stats.rx_bytes += r;
}
예제 #10
0
파일: imc.c 프로젝트: bkero/Smaug
/* close given connection */
static void do_close(imc_connect *c)
{
  const char *name;
  imc_reminfo *r;

  if (c->info) /* if our switched hub, get a new one right away - shogar */
  {
    if (!imc_is_router && (c->info->flags & IMC_NEW_HUB) && c->info == imc_info_list)
    {
	imc_cancel_event(ev_imc_pollforhub,NULL);
	imc_cancel_event(ev_imc_optimize,NULL);
  	imc_add_event(10, ev_imc_pollforhub, NULL, 1);
  	imc_add_event(70, ev_imc_optimize, NULL, 1);
    }
  }
  
  if (c->state==IMC_CLOSED)
    return;

  name=imc_getconnectname(c);
  if(name && c->state == IMC_CONNECTED) /* dont send if never connected */
  {
  	imc_close_notify(name);
        close(c->desc); /* dont close if closed */
  }
  if (c->state == IMC_CONNECTED)
    c->info->connection=NULL;

  /* handle reconnects */
  if (c->info)
    if ((c->info->flags & IMC_RECONNECT) &&
	!(c->info->flags & IMC_DENY) &&
	!(c->info->flags & IMC_CLIENT))
    {
      imc_setup_reconnect(c->info);
    }

  c->state=IMC_CLOSED;

  /* only log after we've set the state, in case imc_logstring
   * sends packets itself (problems with eg. output buffer overflow).
   */
  if (!c->info || !(c->info->flags & IMC_QUIET))
  {
  	name=imc_getconnectname(c);
    	if(name) imc_logstring("%s: closing link", name);
  }

  if (c->info)
  {
    r=imc_find_reminfo(c->info->name, 1);
    if (r)
      imc_delete_reminfo(r);
  }
  if(c->desc)
	close(c->desc);
  c->desc=0;
  c->inbuf[0]=0;
  c->outbuf[0]=0;
  
}
예제 #11
0
파일: imc.c 프로젝트: bkero/Smaug
/* connect to given mud */
int imc_connect_to(const char *mud)
{
  imc_info *i;
  imc_connect *c;
  int desc;
  struct sockaddr_in sa;
  char buf[IMC_DATA_LENGTH];
  int r;

  if (imc_active == IA_NONE)
  {
    imc_qerror("IMC is not active");
    return 0;
  }
    
  i=imc_getinfo(mud);
  if (!i)
  {
    imc_qerror("%s: unknown mud name", mud);
    return 0;
  }

  if (i->connection)
  {
    imc_qerror("%s: already connected", mud);
    return 0;
  }

  if (i->flags & IMC_CLIENT)
  {
    imc_qerror("%s: client-only flag is set", mud);
    return 0;
  }

  if (i->flags & IMC_DENY)
  {
    imc_qerror("%s: deny flag is set", mud);
    return 0;
  }

  if (!(i->flags & IMC_QUIET))
    imc_logstring("connect to %s", mud);

  /*  warning: this blocks. It would be better to farm the query out to
   *  another process, but that is difficult to do without lots of changes
   *  to the core mud code. You may want to change this code if you have an
   *  existing resolver process running.
   */

  if ((sa.sin_addr.s_addr=inet_addr(i->host)) == -1UL)
  {
    struct hostent *hostinfo;

    if (NULL == (hostinfo=gethostbyname(i->host)))
    {
      imc_logerror("imc_connect: couldn't resolve hostname");
      return 0;
    }

    sa.sin_addr.s_addr = *(unsigned long *) hostinfo->h_addr;
  }

  sa.sin_port   = htons(i->port);
  sa.sin_family = AF_INET;

  desc=socket(AF_INET, SOCK_STREAM, 0);
  if (desc<0)
  {
    imc_lerror("socket");
    return 0;
  }

  r=fcntl(desc, F_GETFL, 0);
  if (r<0 || fcntl(desc, F_SETFL, O_NONBLOCK | r)<0)
  {
    imc_lerror("imc_connect: fcntl");
    close(desc);
    return 0;
  }

  if (connect(desc, (struct sockaddr *)&sa, sizeof(sa))<0)
    if (errno != EINPROGRESS)
    {
      imc_lerror("connect");
      close(desc);
      return 0;
    }

  c=imc_new_connect();

  c->desc     = desc;
  c->state    = IMC_CONNECTING;
  c->info     = i;

  imc_add_event(IMC_LOGIN_TIMEOUT, ev_login_timeout, c, 1);

  sprintf(buf, "PW %s %s version=%d",
	  imc_name,
	  i->clientpw,
	  IMC_VERSION);
  do_send(c, buf);

  return 1;
}
예제 #12
0
파일: imc.c 프로젝트: bkero/Smaug
/* low-level idle function: read/write buffers as needed, etc */
void imc_idle_select(fd_set *read, fd_set *write, fd_set *exc, time_t now)
{
  const char *command;
  imc_packet *p;
  imc_connect *c, *c_next ;

  if (imc_active<IA_CONFIG1)
    return;

  if (imc_lock)
  {
    imc_logerror("imc_idle_select: recursive call");
    return;
  }

  imc_lock=1;

  if (imc_sequencenumber < (unsigned long)imc_now)
    imc_sequencenumber=(unsigned long)imc_now;

  imc_run_events(now);

  if (imc_active<IA_UP)
  {
    imc_lock=0;
    return;
  }

  /* handle results of the select */

  if (imc_active >= IA_LISTENING &&
      FD_ISSET(control, read))
    do_accept();

  for (c=imc_connect_list; c; c=c_next)
  {
    c_next=c->next;

    if (c->state!=IMC_CLOSED && FD_ISSET(c->desc, exc))
      do_close(c);

    if (c->state!=IMC_CLOSED && FD_ISSET(c->desc, read))
      do_read(c);

    while (c->state!=IMC_CLOSED &&
//	   (c->spamtime1>=0 || c->spamcounter1<=IMC_SPAM1MAX) &&
//	   (c->spamtime2>=0 || c->spamcounter2<=IMC_SPAM2MAX) &&
	   (command = get_one_line(c->inbuf)) != NULL)
    {
      if (strlen(command) > imc_stats.max_pkt)
	imc_stats.max_pkt=strlen(command);

//      imc_debug(c, 0, command);	/* log incoming packets */

      switch (c->state)
      {
      case IMC_CLOSED:
	break;
      case IMC_WAIT1:
	clientpassword(c, command);
	break;
      case IMC_WAIT2:
	serverpassword(c, command);
	break;
      case IMC_CONNECTED:
	p = do_interpret_packet(c, command);
	if (p)
	{
#ifdef IMC_PARANOIA
	  /* paranoia: check the last entry in the path is the same as the
	   * sending mud. Also check the first entry to see that it matches
	   * the sender.
	   */

	  imc_stats.rx_pkts++;

	  if (strcasecmp(c->info->name,
			 imc_lastinpath(p->i.path)))
	    imc_logerror("PARANOIA: packet from %s allegedly from %s",
			 c->info->name,
			 imc_lastinpath(p->i.path));
	  else if (strcasecmp(imc_mudof(p->i.from), imc_firstinpath(p->i.path)))
	    imc_logerror("PARANOIA: packet from %s has firstinpath %s",
			 p->i.from,
			 imc_firstinpath(p->i.path));
	  else
	    forward(p);		/* only forward if its a valid packet! */
#else
	  imc_stats.rx_pkts++;
	  forward(p);
#endif
#ifdef SPAMPROT
  if (!strcasecmp(p->type, "chat") ||
      !strcasecmp(p->type, "tell") ||
      !strcasecmp(p->type, "emote") || 1)
  {
      if (!c->spamcounter1 && !c->spamtime1)
	imc_add_event(IMC_SPAM1INTERVAL, ev_spam1, c, 0);
      c->spamcounter1++;

      if (!c->spamcounter2 && !c->spamtime2)
	imc_add_event(IMC_SPAM2INTERVAL, ev_spam2, c, 0);
      c->spamcounter2++;
  }
#endif
	  imc_freedata(&p->data);
	}
	break;
      }
    }
  }

  for (c=imc_connect_list; c; c=c_next)
  {
    c_next=c->next;
    
    if (c->state!=IMC_CLOSED &&
	(FD_ISSET(c->desc, write) || c->newoutput))
    {
//      c->newoutput=0;
      do_write(c);
      c->newoutput=c->outbuf[0];
    }
  }

  for (c=imc_connect_list; c; c=c_next)
  {
    c_next=c->next;

    if (c->state==IMC_CLOSED)
      imc_extract_connect(c);
  }

  imc_lock=0;
}
예제 #13
0
파일: imc.c 프로젝트: bkero/Smaug
/* start up IMC */
void imc_startup_network(void)
{
    imc_info *info;
	int toggle=0; /* This is to tell after we've done reconnects if we've connected to a hub or not -- Scion */

  if (imc_active != IA_CONFIG2)
  {
    imc_logerror("imc_startup_network: called with imc_active==%d",
		 imc_active);
    return;
  }

  if (!imc_siteinfo.name[0])
  {
    imc_logerror("InfoName not set, not initializing");
    return;
  }

  if (!imc_siteinfo.email[0])
  {
    imc_logerror("InfoEmail not set, not initializing");
    return;
  }
  
  imc_logstring("network initializing");

  imc_active=IA_UP;

  control=-1;

  if (imc_port)
    imc_startup_port();
  imc_stats.start    = imc_now;
  imc_stats.rx_pkts  = 0;
  imc_stats.tx_pkts  = 0;
  imc_stats.rx_bytes = 0;
  imc_stats.tx_bytes = 0;
  imc_stats.sequence_drops = 0;

  imc_add_event(20, ev_keepalive, NULL, 1);
  /* fill my imclist please - shogar */
  imc_add_event(30, ev_request_keepalive, NULL, 1);

  imc_mail_startup();		/* start up the mailer */

  if (!lock_prefix())
  {
    imc_logstring("another process is using the same config prefix, not autoconnecting.");
    return;
  }

  /* do autoconnects */
  for (info=imc_info_list; info; info=info->next)
    if (!(info->flags & IMC_NOAUTO) && !(info->flags & IMC_CLIENT) 
		&& !(info->flags & IMC_DENY) 
 /*               && !(info->flags & IMC_OLD_HUB)  not used anymore - shogar
                && !(info->flags & IMC_DEAD_HUB)
*/
		&& !(info->flags & IMC_HUB)) {
      if (imc_connect_to(info->name) && ((info->flags & IMC_MAIN_HUB) || (info->flags & IMC_HUB)))
		  toggle=1;
	}

  
	/* Setup optimization to run, it won't if we're a hub -- Scion */
   if(imc_hubswitch && !imc_is_router)
   {
   	imc_add_event(360, ev_imc_pollforhub, NULL, 1);
   	imc_add_event(420, ev_imc_optimize, NULL, 1);

   	imc_logstring("Setting auto-optimize to run in 6 minutes.");
   }

   /* Are we connected to any hubs, btw? -- Scion */

   if (!toggle) { /* No hubs connected! */
	   for (info=imc_info_list; info; info=info->next)
		   if ((info->flags & IMC_HUB) && (!toggle))
			   if (imc_connect_to(info->name))
				   toggle=0;
   }
   /* We're out of ideas, notify the admins -- Scion */
/*
   if (!toggle)
	   imc_logstring("No hubs connected! Check the configuration!");
*/
}
예제 #14
0
파일: imc-mail.c 프로젝트: bhyvex/cosMUD
/* expire old entries in the mailid list; called once an hour */
void ev_mailid_expire(void *data)
{
  flush_idlist(imc_now + 24*3600);
  imc_add_event(3600, ev_mailid_expire, NULL, 1);
}
예제 #15
0
파일: imc-mail.c 프로젝트: bhyvex/cosMUD
/* 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();
}