コード例 #1
0
ファイル: imc.c プロジェクト: bkero/Smaug
/* handle a password response from a server */
static void serverpassword(imc_connect *c, const char *argument)
{
  char arg1[3], name[IMC_MNAME_LENGTH], pw[IMC_PW_LENGTH], version[20];
  imc_info *i;

  argument=imc_getarg(argument, arg1, 4);	/* has to be PW */
  argument=imc_getarg(argument, name, IMC_MNAME_LENGTH);
  argument=imc_getarg(argument, pw, IMC_PW_LENGTH);
  argument=imc_getarg(argument, version, 20);

  if (strcasecmp(arg1, "PW"))
  {
    imc_logstring("%s: non-PW password packet", imc_getconnectname(c));
    do_close(c);
    return;
  }

  i=imc_getinfo(name);
  if (!i || strcmp(i->serverpw, pw) ||
      i != c->info)
  {
    if ((!i || !(i->flags & IMC_QUIET)) && !(c->info->flags & IMC_QUIET))
    imc_logstring("%s: password failure for %s", imc_getconnectname(c), name);
    do_close(c);
    return;
  }

  if (i->connection)	/* kill old connections */
    do_close(i->connection);

  i->connection         = c;

  c->state              = IMC_CONNECTED;
  c->spamcounter1       = 0;
  c->spamcounter2       = 0;

  /* check for a version string (assume version 0 if not present) */
  if (sscanf(version, "version=%hu", &c->version)!=1)
    c->version=0;

  /* check for generator/interpreter */
  if (!imc_vinfo[c->version].generate ||
      !imc_vinfo[c->version].interpret)
  {
    if (!(i->flags & IMC_QUIET))
      imc_logstring("%s: unsupported version %d",
		    imc_getconnectname(c), c->version);
    do_close(c);
    return;
  }

  if (!(i->flags & IMC_QUIET))
    imc_logstring("%s: connected (version %d)",
		  imc_getconnectname(c), c->version);
  c->info->timer_duration=IMC_MIN_RECONNECT_TIME;
  c->info->last_connected=imc_now;
  imc_cancel_event(ev_login_timeout, c);
  imc_cancel_event(ev_reconnect, c->info);
}
コード例 #2
0
ファイル: imc.c プロジェクト: bkero/Smaug
void imc_delete_info(imc_info *i)
{
  imc_connect *c;
  imc_info *last;

  for (c=imc_connect_list; c; c=c->next)
    if (c->info==i)
      do_close(c);

  if (i==imc_info_list)
    imc_info_list=i->next;
  else
  {
    for (last=imc_info_list; last && last->next!=i; last=last->next)
      ;

    if (!last)
      imc_logerror("imc_delete_info: not in list");
    else
      last->next=i->next;
  }

  if (i->name)
    imc_strfree(i->name);
  if (i->host)
    imc_strfree(i->host);
  if (i->clientpw)
    imc_strfree(i->clientpw);
  if (i->serverpw)
    imc_strfree(i->serverpw);

  imc_cancel_event(NULL, i);

  imc_free(i, sizeof(*i));
}
コード例 #3
0
ファイル: imc.c プロジェクト: bkero/Smaug
/*  free buffers and extract 'c' from imc_connect_list
 *  called from imc_idle_select when we're done with a connection with
 *  c->state==IMC_CLOSED
 */
void imc_extract_connect(imc_connect *c)
{
  imc_connect *c_find;

  if (c->state!=IMC_CLOSED)
  {
    imc_logerror("imc_extract_connect: non-closed connection");
    return;
  }
  
  imc_free(c->inbuf, c->insize);
  imc_free(c->outbuf, c->outsize);

  if (c==imc_connect_list)
    imc_connect_list=c->next;
  else
  {
    for (c_find=imc_connect_list; c_find && c_find->next!=c;
	 c_find=c_find->next)
      ;
    
    if (!c_find)
      imc_logerror("imc_extract_connect: not in imc_connect_list");
    else
      c_find->next=c->next;
  }

  imc_cancel_event(NULL, c);

  imc_free(c, sizeof(*c));
}
コード例 #4
0
ファイル: imc-mail.c プロジェクト: bhyvex/cosMUD
/* free_mail: free a mail structure */
static void free_mail(imc_mail *p)
{
  if (!p)
  {
    imc_logerror("BUG: free_mail: freeing NULL pointer");
    return;
  }

  if (p->usage)
  {
    imc_logerror("BUG: free_mail: freeing mail at %p with usage=%d",
		 p, p->usage);
    return;
  }

  if (p->from)
    imc_strfree(p->from);
  if (p->to)
    imc_strfree(p->to);
  if (p->id)
    imc_strfree(p->id);
  if (p->text)
    imc_strfree(p->text);
  if (p->subject)
    imc_strfree(p->subject);
  if (p->date)
    imc_strfree(p->date);

  imc_cancel_event(NULL, p);

  imc_free(p, sizeof(*p));
}
コード例 #5
0
ファイル: imc-mail.c プロジェクト: bhyvex/cosMUD
/* imc_mail_shutdown: shut down the mailer */
void imc_mail_shutdown(void)
{
  save_mq();
  save_ml();
  save_idlist();

  free_mq();
  free_ml();
  free_idlist();

  imc_cancel_event(ev_mailid_expire, NULL);
}
コード例 #6
0
ファイル: icec.c プロジェクト: benjamin-small/GodWars
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);
}
コード例 #7
0
ファイル: imc-mail.c プロジェクト: bhyvex/cosMUD
/* free_mailid: free a mailid */
static void free_mailid(imc_mailid *p)
{
  if (!p)
  {
    imc_logerror("BUG: free_mailid: freeing NULL pointer");
    return;
  }

  if (p->id)
    imc_strfree(p->id);

  imc_cancel_event(NULL, p);

  imc_free(p, sizeof(*p));
}
コード例 #8
0
ファイル: imc-mail.c プロジェクト: bhyvex/cosMUD
/* free_qnode: free a qnode */
static void free_qnode(imc_qnode *q)
{
  if (!q)
  {
    imc_logerror("BUG: free_qnode: freeing NULL pointer");
    return;
  }

  if (q->tomud)
    imc_strfree(q->tomud);

  if (q->data && !--q->data->usage)
    delete_ml(q->data);

  imc_cancel_event(NULL, q);

  imc_free(q, sizeof(*q));
}
コード例 #9
0
ファイル: imc.c プロジェクト: bkero/Smaug
/* handle a password from a client */
static void clientpassword(imc_connect *c, const char *argument)
{
  char arg1[3], name[IMC_MNAME_LENGTH], pw[IMC_PW_LENGTH], version[20];
  imc_info *i;
  char response[IMC_PACKET_LENGTH];

  argument=imc_getarg(argument, arg1, 4);      /* packet type (has to be PW) */
  argument=imc_getarg(argument, name, IMC_MNAME_LENGTH);  /* remote mud name */
  argument=imc_getarg(argument, pw, IMC_PW_LENGTH);	         /* password */
  argument=imc_getarg(argument, version, 20);	/* optional version=n string */

  if (strcasecmp(arg1, "PW"))
  {
    imc_logstring("%s: non-PW password packet", imc_getconnectname(c));
    do_close(c);
    return;
  }

  /* do we know them, and do they have the right password? */
  i=imc_getinfo(name);
  if (!i || strcmp(i->clientpw, pw))
  {
    if (!i || !(i->flags & IMC_QUIET))
    imc_logstring("%s: password failure for %s", imc_getconnectname(c), name);
    do_close(c);
    return;
  }

  /* deny access if deny flag is set (good for eg. muds that start crashing
   * on rwho)
   */
  if (i->flags & IMC_DENY)
  {
    if (!(i->flags & IMC_QUIET))
      imc_logstring("%s: denying connection", name);
    do_close(c);
    return;
  }

  if (i->connection)	                      /* kill old connections */
    do_close(i->connection);

  /* register them */
  i->connection     = c;

  c->state          = IMC_CONNECTED;
  c->info           = i;
  c->spamcounter1   = 0;
  c->spamcounter2   = 0;

  /* check for a version string (assume version 0 if not present) */
  if (sscanf(version, "version=%hu", &c->version)!=1)
    c->version=0;

  /* check for generator/interpreter */
  if (!imc_vinfo[c->version].generate ||
      !imc_vinfo[c->version].interpret)
  {
    if (!(i->flags & IMC_QUIET))
    imc_logstring("%s: unsupported version %d",
		  imc_getconnectname(c), c->version);
    do_close(c);
    return;
  }

  /* send our response */

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

  if (!(i->flags & IMC_QUIET))
    imc_logstring("%s: connected (version %d)",
		  imc_getconnectname(c), c->version);

  c->info->timer_duration=IMC_MIN_RECONNECT_TIME;
  c->info->last_connected=imc_now;
  imc_cancel_event(ev_login_timeout, c);
  imc_cancel_event(ev_reconnect, c->info);
}
コード例 #10
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);
  }
}
コード例 #11
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;
}
コード例 #12
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;
  
}