Exemple #1
0
/* 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);
}
Exemple #2
0
/* shell around imc_idle_select */
void imc_idle(int s, int us)
{
  fd_set read, write, exc;
  int maxfd;
  struct timeval timeout;
  int i;

  FD_ZERO(&read);
  FD_ZERO(&write);
  FD_ZERO(&exc);

  maxfd=imc_fill_fdsets(0, &read, &write, &exc);
  timeout.tv_sec = s;
  timeout.tv_usec = us;

  if (maxfd)
    while ((i=select(maxfd+1, &read, &write, &exc, &timeout)) < 0 &&
	   errno == EINTR)	/* loop, ignoring signals */
      ;
  else
    while ((i=select(0, NULL, NULL, NULL, &timeout)) < 0 &&
	   errno == EINTR)
      ;
    

  if (i<0)
  {
    imc_lerror("imc_idle: select");
    imc_shutdown_network();
    return;
  }

  imc_idle_select(&read, &write, &exc, time(NULL));
}
Exemple #3
0
/* write to descriptor */
static void do_write(imc_connect *c)
{
  int size, w;

  if (c->state==IMC_CONNECTING)
  {
    /* Wait for server password */
    c->state=IMC_WAIT2;
    return;
  }

  size = strlen(c->outbuf);
  if (!size)			/* nothing to write */
    return;

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

  if (w<0)			/* EAGAIN */
    return;

  /* throw away data we wrote */
//  memmove(c->outbuf, c->outbuf+w, size-w+1);
  strcpy(c->outbuf,c->outbuf+w);

  imc_stats.tx_bytes += w;
}
Exemple #4
0
/* save_idlist: save idlist */
static void save_idlist(void)
{
  FILE *out;
  imc_mailid *p;
  char name[200];

  imc_sncpy(name, imc_prefix, 191);
  strcat(name, "mail-ids");

  out=fopen(name, "w");
  if (!out)
  {
    imc_lerror("save_idlist: fopen");
    return;
  }

  for (p=imc_idlist->next; p; p=p->next)
    write_mailid(p, out);

  fclose(out);
}
Exemple #5
0
/* save mailqueue */
static void save_mq(void)
{
  FILE *out;
  imc_qnode *p;
  char name[200];

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

  out=fopen(name, "w");
  if (!out)
  {
    imc_lerror("save_mq: fopen");
    return;
  }

  for (p=imc_mq_head->next; p; p=p->next)
    write_qnode(p, out);

  fclose(out);
}
Exemple #6
0
/* save_ml: save maillist */
static void save_ml(void)
{
  FILE *out;
  imc_mail *p;
  char name[200];

  imc_sncpy(name, imc_prefix, 190);
  strcat(name, "mail-list");

  out=fopen(name, "w");
  if (!out)
  {
    imc_lerror("save_ml: fopen");
    return;
  }

  for (p=imc_ml_head->next; p; p=p->next)
    write_mail(p, out);

  fclose(out);
}
Exemple #7
0
static int lock_prefix(void)
{
  char lockfile[1000];

  sprintf(lockfile, "%slock", imc_prefix);
  imc_lock_file=open(lockfile, O_CREAT|O_EXCL|O_RDWR, 0644);
  if (imc_lock_file<0)
    imc_lock_file=open(lockfile, O_RDWR, 0644);
  if (imc_lock_file<0)
  {
    imc_lerror("lock_prefix: open %s", lockfile);
    return 0;
  }

  //if (lockf(imc_lock_file, F_TLOCK, 1)<0)
  if (imc_lock_file<0) {
    close(imc_lock_file);
    imc_lock_file=-1;
    return 0;
  }

  return 1;
}
Exemple #8
0
/* 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;
}
Exemple #9
0
/* 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;
}
Exemple #10
0
/* start up listening port */
void imc_startup_port(void)
{
  int i;
  struct sockaddr_in sa;

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

  if (imc_port==0)
  {
    imc_logerror("imc_startup_port: called with imc_port=0");
    return;
  }
  
  imc_logstring("binding port %d for incoming connections", imc_port);
      
  control = socket(AF_INET, SOCK_STREAM, 0);
  if (control<0)
  {
    imc_lerror("imc_startup_port: socket");
    return;
  }
    
  i=1;
  if (setsockopt(control, SOL_SOCKET, SO_REUSEADDR, (void *)&i,
		 sizeof(i))<0)
  {
    imc_lerror("imc_startup_port: SO_REUSEADDR");
    close(control);
    return;
  }
  
  if ((i=fcntl(control, F_GETFL, 0))<0)
  {
    imc_lerror("imc_startup_port: fcntl(F_GETFL)");
    close(control);
    return;
  }

  if (fcntl(control, F_SETFL, i | O_NONBLOCK)<0)
  {
    imc_lerror("imc_startup_port: fcntl(F_SETFL)");
    close(control);
    return;
  }

  sa.sin_family      = AF_INET;
  sa.sin_port        = htons(imc_port);
  sa.sin_addr.s_addr = imc_bind; /* already in network order */
  
  if (bind(control, (struct sockaddr *)&sa, sizeof(sa))<0)
  {
    imc_lerror("imc_startup_port: bind");
    close(control);
    return;
  }
  
  if (listen(control, 1)<0)
  {
    imc_lerror("imc_startup_port: listen");
    close(control);
    return;
  }
  
  imc_active=IA_LISTENING;
}