Example #1
0
/*
 * add_accept()
 *
 * input	- pointer to clients accept list to add to
 * 		- pointer to client to add
 * output	- none
 * side effects - target is added to clients list
 */
static void add_accept(struct Client *source_p, 
                       struct Client *target_p)
{
  dlink_node *m;

  m = make_dlink_node();
  dlinkAdd(target_p, m, &source_p->allow_list);

  m = make_dlink_node()
  dlinkAdd(source_p, m, &target_p->on_allow_list);
}
Example #2
0
/*
 * check for public repeating and keep/replace appropriate last phrase
 *													-demond
 */
static int check_repeat(struct Client *source_p,
						struct Channel *chptr,
						char *text)
{
	dlink_node *ptr;
	struct Repeat *repeatptr;

	for (ptr = source_p->user->repeat.head; ptr; ptr = ptr->next) {
		repeatptr = ptr->data;
		if (repeatptr->chptr == chptr)
			if (!strcmp(repeatptr->text, text)) {
				return 1;
			} else {
				MyFree(repeatptr->text);
				DupString(repeatptr->text, text);
				repeatptr->lastphrase = CurrentTime;
				return 0;
			}
	}

	repeatptr = (struct Repeat *)MyMalloc(sizeof(struct Repeat));
	repeatptr->chptr = chptr;
	DupString(repeatptr->text, text);
	repeatptr->lastphrase = CurrentTime;

	ptr = make_dlink_node();
	dlinkAdd(repeatptr, ptr, &source_p->user->repeat);

	return 0;
}
Example #3
0
/*
 * dead_link - Adds client to a list of clients that need an exit_client()
 *
 */
void dead_link(struct Client *client_p)
{
  dlink_node *m;
  const char *notice;
  if(IsClosing(client_p))
    return;

  linebuf_donebuf(&client_p->localClient->buf_recvq);
  linebuf_donebuf(&client_p->localClient->buf_sendq);
  
  if(client_p->flags & FLAGS_SENDQEX)
    notice = "Max SendQ exceeded";
  else
    notice = "Dead link";
    	
  if (!IsPerson(client_p) && !IsUnknown(client_p) && !IsClosing(client_p))
  {
    sendto_realops_flags(FLAGS_ALL, L_ADMIN,
                         notice, get_client_name(client_p, HIDE_IP));
    sendto_realops_flags(FLAGS_ALL, L_OPER,
                         notice, get_client_name(client_p, MASK_IP));
  }
  Debug((DEBUG_ERROR, notice, get_client_name(to, HIDE_IP)));
  assert(dlinkFind(&abort_list, client_p) == NULL);
  m = make_dlink_node();
  dlinkAdd(client_p, m, &abort_list);
  SetDead(client_p); /* You are dead my friend */
}
Example #4
0
/*
 * linebuf_new_line
 *
 * Create a new line, and link it to the given linebuf.
 * It will be initially empty.
 */
static buf_line_t *
linebuf_new_line(buf_head_t * bufhead)
{
	buf_line_t *bufline;
	dlink_node *node;

	bufline = linebuf_allocate();
	if(bufline == NULL)
		return NULL;
	++bufline_count;


	node = make_dlink_node();

	bufline->len = 0;
	bufline->terminated = 0;
	bufline->flushing = 0;
	bufline->raw = 0;

	/* Stick it at the end of the buf list */
	dlinkAddTail(bufline, node, &bufhead->list);
	bufline->refcount++;

	/* And finally, update the allocated size */
	bufhead->alloclen++;
	bufhead->numlines++;

	return bufline;
}
Example #5
0
File: dbuf.c Project: mdharris/ircd
static struct dbuf_block *
dbuf_alloc(struct dbuf_queue *qptr)
{
  struct dbuf_block *block = BlockHeapAlloc(dbuf_heap);

  dlinkAddTail(block, make_dlink_node(), &qptr->blocks);
  return block;
}
Example #6
0
static struct dbuf_block *
dbuf_alloc(struct dbuf_queue *qptr)
{
  struct dbuf_block *block = mp_pool_get(dbuf_pool);

  memset(block, 0, sizeof(*block));
  dlinkAddTail(block, make_dlink_node(), &qptr->blocks);
  return block;
}
Example #7
0
/*
 * make_client - create a new Client struct and set it to initial state.
 *
 *      from == NULL,   create local client (a client connected
 *                      to a socket).
 *
 *      from,   create remote client (behind a socket
 *                      associated with the client defined by
 *                      'from'). ('from' is a local client!!).
 */
struct Client* make_client(struct Client* from)
{
  struct Client* client_p = NULL;
  struct LocalUser *localClient;
  dlink_node *m;

  client_p = BlockHeapAlloc(client_heap);
  memset(client_p, 0, sizeof(struct Client)); 
  if (from == NULL)
    {
      client_p->from  = client_p; /* 'from' of local client is self! */
      client_p->since = client_p->lasttime = client_p->firsttime = CurrentTime;

      localClient = (struct LocalUser *)BlockHeapAlloc(lclient_heap);
      memset(localClient, 0, sizeof(struct LocalUser));

      client_p->localClient = localClient;
       
      client_p->localClient->fd = -1;
      client_p->localClient->ctrlfd = -1;
#ifndef HAVE_SOCKETPAIR
      client_p->localClient->fd_r = -1;
      client_p->localClient->ctrlfd_r = -1;
#endif      
      /* as good a place as any... */
      m = make_dlink_node();
      dlinkAdd(client_p, m, &unknown_list);
      ++local_client_count;
    }
  else
    { /* from is not NULL */
      client_p->localClient = NULL;
      client_p->from = from; /* 'from' of local client is self! */
      ++remote_client_count;
    }

  client_p->status = STAT_UNKNOWN;
  strcpy(client_p->username, "unknown");
#if 0
  client_p->name[0] = '\0';
  client_p->flags   = 0;
  client_p->next    = NULL;
  client_p->prev    = NULL;
  client_p->hnext   = NULL;
  client_p->lnext   = NULL;
  client_p->lprev   = NULL;
  client_p->user    = NULL;
  client_p->serv    = NULL;
  client_p->servptr = NULL;
  client_p->whowas  = NULL;
  client_p->allow_list.head = NULL;
  client_p->allow_list.tail = NULL;
  client_p->on_allow_list.head = NULL;
  client_p->on_allow_list.tail = NULL;
#endif
  return client_p;
}
Example #8
0
/*! \brief Blindly opers up given source_p, using conf info.
 *         All checks on passwords have already been done.
 * \param source_p Pointer to given client to oper
 * \param conf operator {} configuration record
 */
static void
oper_up(struct Client *source_p, const struct MaskItem *conf)
{
  const unsigned int old = source_p->umodes;

  ++Count.oper;
  SetOper(source_p);

  if (conf->modes)
    AddUMode(source_p, conf->modes);
  else if (ConfigGeneral.oper_umodes)
    AddUMode(source_p, ConfigGeneral.oper_umodes);

  if (!(old & UMODE_INVISIBLE) && HasUMode(source_p, UMODE_INVISIBLE))
    ++Count.invisi;
  else if ((old & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE))
    --Count.invisi;

  assert(dlinkFind(&oper_list, source_p) == NULL);
  dlinkAdd(source_p, make_dlink_node(), &oper_list);

  AddOFlag(source_p, conf->port);

  if (HasOFlag(source_p, OPER_FLAG_ADMIN))
    AddUMode(source_p, UMODE_ADMIN);

  if (!EmptyString(conf->whois))
  {
    svstag_attach(&source_p->svstags, RPL_WHOISOPERATOR, "+", conf->whois);
    sendto_server(NULL, 0, 0, ":%s SVSTAG %s %ju %u + :%s",
                  me.id, source_p->id, source_p->tsinfo,
                  RPL_WHOISOPERATOR, conf->whois);
  }

  ilog(LOG_TYPE_OPER, "OPER %s by %s!%s@%s", conf->name, source_p->name,
       source_p->username, source_p->host);
  sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE, "%s is now an operator",
                       get_oper_name(source_p));
  sendto_server(NULL, 0, 0, ":%s GLOBOPS :%s is now an operator",
                me.id, get_oper_name(source_p));

  send_umode_out(source_p, old);
  sendto_one_numeric(source_p, &me, RPL_YOUREOPER);
}
Example #9
0
static void
do_list(struct Client *source_p, char *arg)
{
  struct ListTask *lt = NULL;
  int no_masked_channels = 1;

  if (source_p->connection->list_task)
  {
    free_list_task(source_p);
    sendto_one_numeric(source_p, &me, RPL_LISTEND);
    return;
  }

  lt = MyCalloc(sizeof(struct ListTask));
  lt->users_max = UINT_MAX;
  lt->created_max = UINT_MAX;
  lt->topicts_max = UINT_MAX;
  source_p->connection->list_task = lt;

  if (!EmptyString(arg))
  {
    char *opt, *save = NULL;
    dlink_list *list = NULL;
    int i = 0, errors = 0;

    for (opt = strtoken(&save,  arg, ","); opt;
         opt = strtoken(&save, NULL, ","))
    {
      switch (*opt)
      {
        case '<':
          if ((i = atoi(opt + 1)) > 0)
            lt->users_max = (unsigned int)i - 1;
          else
            errors = 1;
          break;
        case '>':
          if ((i = atoi(opt + 1)) >= 0)
            lt->users_min = (unsigned int)i + 1;
          else
            errors = 1;
          break;
        case 'C':
        case 'c':
          switch (*++opt)
          {
            case '<':
              if ((i = atoi(opt + 1)) >= 0)
                lt->created_max = (unsigned int)(CurrentTime - 60 * i);
              else
                errors = 1;
              break;
            case '>':
              if ((i = atoi(opt + 1)) >= 0)
                lt->created_min = (unsigned int)(CurrentTime - 60 * i);
              else
                errors = 1;
              break;
            default:
              errors = 1;
          }

          break;

        case 'T':
        case 't':
          switch (*++opt)
          {
            case '<':
              if ((i = atoi(opt + 1)) >= 0)
                lt->topicts_min = (unsigned int)(CurrentTime - 60 * i);
              else
                errors = 1;
              break;
            case '>':
              if ((i = atoi(opt + 1)) >= 0)
                lt->topicts_max = (unsigned int)(CurrentTime - 60 * i);
              else
                errors = 1;
              break;
            case ':':
              if (strlcpy(lt->topic, opt + 1, sizeof(lt->topic)) == 0)
                errors = 1;
              break;
            default:
              errors = 1;
          }

          break;

        default:
          if (*opt == '!')
          {
            list = &lt->hide_mask;
            opt++;
          }
          else
            list = &lt->show_mask;

          if (has_wildcards(opt + !!IsChanPrefix(*opt)))
          {
            if (list == &lt->show_mask)
              no_masked_channels = 0;
          }
          else if (!IsChanPrefix(*opt))
            errors = 1;

          if (!errors)
            dlinkAdd(xstrdup(opt), make_dlink_node(), list);
      }
    }

    if (errors)
    {
      free_list_task(source_p);
      sendto_one_numeric(source_p, &me, ERR_LISTSYNTAX);
      return;
    }
  }

  dlinkAdd(source_p, &lt->node, &listing_client_list);

  sendto_one_numeric(source_p, &me, RPL_LISTSTART);
  safe_list_channels(source_p, no_masked_channels && lt->show_mask.head != NULL);
}
Example #10
0
int
main(int argc, char *argv[])
{
  /* Check to see if the user is running us as root, which is a nono */
  if (!geteuid())
  {
    fprintf(stderr, "ERROR: This server won't run as root/superuser\n");
    return -1;
  }

  /* Setup corefile size immediately after boot -kre */
  setup_corefile();

  /* Save server boot time right away, so getrusage works correctly */
  set_time();

  /* It's not random, but it ought to be a little harder to guess */
  init_genrand(SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid() << 20)));

  dlinkAdd(&me, &me.node, &global_client_list);

  ConfigGeneral.dpath      = DPATH;
  ConfigGeneral.spath      = SPATH;
  ConfigGeneral.mpath      = MPATH;
  ConfigGeneral.configfile = CPATH;    /* Server configuration file */
  ConfigGeneral.klinefile  = KPATH;    /* Server kline file         */
  ConfigGeneral.glinefile  = GPATH;    /* Server gline file         */
  ConfigGeneral.xlinefile  = XPATH;    /* Server xline file         */
  ConfigGeneral.dlinefile  = DLPATH;   /* dline file                */
  ConfigGeneral.resvfile   = RESVPATH; /* resv file                 */

  myargv = argv;
  umask(077);  /* umask 077: u=rwx,g=,o= */

  parseargs(&argc, &argv, myopts);

  if (printVersion)
  {
    printf("ircd: version %s(%s)\n", ircd_version, serno);
    exit(EXIT_SUCCESS);
  }

  if (chdir(ConfigGeneral.dpath))
  {
    perror("chdir");
    exit(EXIT_FAILURE);
  }

  ssl_init();

  if (!server_state.foreground)
  {
    make_daemon();
    close_standard_fds(); /* this needs to be before init_netio()! */
  }
  else
    print_startup(getpid());

  setup_signals();

  /* We need this to initialise the fd array before anything else */
  fdlist_init();
  log_set_file(LOG_TYPE_IRCD, 0, logFileName);

  init_netio();         /* This needs to be setup early ! -- adrian */

  /* Check if there is pidfile and daemon already running */
  check_pidfile(pidFileName);

  mp_pool_init();
  init_dlink_nodes();
  init_isupport();
  dbuf_init();
  hash_init();
  ipcache_init();
  client_init();
  class_init();
  whowas_init();
  watch_init();
  auth_init();          /* Initialise the auth code */
  init_resolver();      /* Needs to be setup before the io loop */
  modules_init();
  read_conf_files(1);   /* cold start init conf files */
  init_uid();
  initialize_server_capabs();   /* Set up default_server_capabs */
  initialize_global_set_options();  /* Has to be called after read_conf_files() */
  channel_init();
  read_links_file();
  motd_init();
  user_usermodes_init();
#ifdef HAVE_LIBGEOIP
  geoip_ctx = GeoIP_new(GEOIP_MEMORY_CACHE);
#endif

  if (EmptyString(ConfigServerInfo.sid))
  {
    ilog(LOG_TYPE_IRCD, "ERROR: No server id specified in serverinfo block.");
    exit(EXIT_FAILURE);
  }

  strlcpy(me.id, ConfigServerInfo.sid, sizeof(me.id));

  if (EmptyString(ConfigServerInfo.name))
  {
    ilog(LOG_TYPE_IRCD, "ERROR: No server name specified in serverinfo block.");
    exit(EXIT_FAILURE);
  }

  strlcpy(me.name, ConfigServerInfo.name, sizeof(me.name));

  /* serverinfo{} description must exist.  If not, error out.*/
  if (EmptyString(ConfigServerInfo.description))
  {
    ilog(LOG_TYPE_IRCD, "ERROR: No server description specified in serverinfo block.");
    exit(EXIT_FAILURE);
  }

  strlcpy(me.info, ConfigServerInfo.description, sizeof(me.info));

  me.from = &me;
  me.servptr = &me;
  me.connection->lasttime = CurrentTime;
  me.connection->since = CurrentTime;
  me.connection->firsttime = CurrentTime;

  SetMe(&me);
  make_server(&me);

  hash_add_id(&me);
  hash_add_client(&me);

  dlinkAdd(&me, make_dlink_node(), &global_server_list);

  load_kline_database();
  load_dline_database();
  load_gline_database();
  load_xline_database();
  load_resv_database();

  load_all_modules(1);
  load_conf_modules();
  load_core_modules(1);

  write_pidfile(pidFileName);

  ilog(LOG_TYPE_IRCD, "Server Ready");

  event_addish(&event_cleanup_glines, NULL);
  event_addish(&event_cleanup_tklines, NULL);

  /* We want try_connections to be called as soon as possible now! -- adrian */
  /* No, 'cause after a restart it would cause all sorts of nick collides */
  event_addish(&event_try_connections, NULL);

  /* Setup the timeout check. I'll shift it later :)  -- adrian */
  event_add(&event_comm_checktimeouts, NULL);

  event_addish(&event_save_all_databases, NULL);

  if (ConfigServerHide.links_delay > 0)
  {
    event_write_links_file.when = ConfigServerHide.links_delay;
    event_addish(&event_write_links_file, NULL);
  }
  else
    ConfigServerHide.links_disabled = 1;

  if (splitmode)
    event_addish(&splitmode_event, NULL);

  io_loop();
  return 0;
}
Example #11
0
static void
do_list(struct Client *source_p, int parc, char *parv[])
{
  struct ListTask *lt;
  int no_masked_channels;

  if (MyConnect(source_p))
  {
    if (source_p->localClient->list_task != NULL)
    {
      free_list_task(source_p->localClient->list_task, source_p);
      sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
      return;
    }
  }

  lt = (struct ListTask *) MyMalloc(sizeof(struct ListTask));
  lt->users_max = UINT_MAX;
  lt->created_max = UINT_MAX;
  lt->topicts_max = UINT_MAX;
  if (MyConnect(source_p))
    source_p->localClient->list_task = lt;
  no_masked_channels = 1;

  if (parc > 1)
  {
    char *opt, *save;
    dlink_list *list;
    int i, errors = 0;

    for (opt = strtoken(&save, parv[1], ","); opt != NULL;
         opt = strtoken(&save, NULL, ","))
      switch (*opt)
      {
        case '<': if ((i = atoi(opt + 1)) > 0)
		    lt->users_max = (unsigned int) i - 1;
                  else
		    errors = 1;
		  break;
        case '>': if ((i = atoi(opt + 1)) >= 0)
		    lt->users_min = (unsigned int) i + 1;
		  else
		    errors = 1;
		  break;
        case '-': break;
        case 'C':
	case 'c': switch (*++opt)
	          {
		    case '<': if ((i = atoi(opt + 1)) >= 0)
		                lt->created_max = (unsigned int) (CurrentTime
				                  - 60 * i);
			      else
			        errors = 1;
			      break;
		    case '>': if ((i = atoi(opt + 1)) >= 0)
		                lt->created_min = (unsigned int) (CurrentTime
				                  - 60 * i);
			      else
			        errors = 1;
			      break;
		    default: errors = 1;
		  }
		  break;
	case 'T':
	case 't': switch (*++opt)
	          {
		    case '<': if ((i = atoi(opt + 1)) >= 0)
		                lt->topicts_min = (unsigned int) (CurrentTime
				                  - 60 * i);
			      else
			        errors = 1;
			      break;
		    case '>': if ((i = atoi(opt + 1)) >= 0)
		                lt->topicts_max = (unsigned int) (CurrentTime
				                  - 60 * i);
			      else
			        errors = 1;
			      break;
		    default: errors = 1;
		  }
		  break;
        default: if (*opt == '!')
	         {
		   list = &lt->hide_mask;
		   opt++;
		 }
		 else list = &lt->show_mask;

		 if (has_wildcards(opt + !!IsChanPrefix(*opt)))
		 {
		   if (list == &lt->show_mask)
		     no_masked_channels = 0;
		 }
		 else if (!IsChanPrefix(*opt))
		   errors = 1;
		 if (!errors)
		 {
                   char *s;
		   DupString(s, opt);
		   dlinkAdd(s, make_dlink_node(), list);
		 }
      }
    if (errors)
    {
      free_list_task(lt, source_p);
      sendto_one(source_p, form_str(ERR_LISTSYNTAX),
                 MyConnect(source_p) ? me.name : ID(&me),
                 MyConnect(source_p) ? source_p->name : ID(source_p));
      return;
    }
  }


  if (MyConnect(source_p))
    dlinkAdd(source_p, make_dlink_node(), &listing_client_list);
  sendto_one(source_p, form_str(RPL_LISTSTART),
             MyConnect(source_p) ? me.name : ID(&me),
             MyConnect(source_p) ? source_p->name : ID(source_p));
  safe_list_channels(source_p, lt, no_masked_channels &&
                     lt->show_mask.head != NULL, !MyConnect(source_p));
}
Example #12
0
/*
** Exit one client, local or remote. Assuming all dependents have
** been already removed, and socket closed for local client.
*/
static void exit_one_client(struct Client *client_p,
                            struct Client *source_p,
                            struct Client *from, const char *comment)
{
  struct Client* target_p;
  dlink_node *lp;
  dlink_node *next_lp;

  if (IsServer(source_p))
    {
      if (source_p->servptr && source_p->servptr->serv)
        del_client_from_llist(&(source_p->servptr->serv->servers),
                                    source_p);
      else
        ts_warn("server %s without servptr!", source_p->name);

      if(!IsMe(source_p))
        remove_server_from_list(source_p);
    }
  else if (source_p->servptr && source_p->servptr->serv)
    {
      del_client_from_llist(&(source_p->servptr->serv->users), source_p);
    }
  /* there are clients w/o a servptr: unregistered ones */

  /*
  **  For a server or user quitting, propogate the information to
  **  other servers (except to the one where is came from (client_p))
  */
  if (IsMe(source_p))
    {
      sendto_realops_flags(FLAGS_ALL, L_ALL,
			   "ERROR: tried to exit me! : %s", comment);
      return;        /* ...must *never* exit self!! */
    }
  else if (IsServer(source_p))
    {
      /*
      ** Old sendto_serv_but_one() call removed because we now
      ** need to send different names to different servers
      ** (domain name matching)
      */
      /*
      ** The bulk of this is done in remove_dependents now, all
      ** we have left to do is send the SQUIT upstream.  -orabidoo
      */
      if (source_p->localClient)
      {
	if(source_p->localClient->ctrlfd > -1)
	{
          fd_close(source_p->localClient->ctrlfd);
	  source_p->localClient->ctrlfd = -1;

#ifndef HAVE_SOCKETPAIR
          fd_close(source_p->localClient->ctrlfd_r);
	  fd_close(source_p->localClient->fd_r);
	  
	  source_p->localClient->ctrlfd_r = -1;
	  source_p->localClient->fd_r = -1;
#endif
	}
      }

      target_p = source_p->from;
      if (target_p && IsServer(target_p) && target_p != client_p && !IsMe(target_p) &&
          (source_p->flags & FLAGS_KILLED) == 0)
        sendto_one(target_p, ":%s SQUIT %s :%s", from->name, source_p->name, comment);
    }
  else if (source_p->name[0]) /* ...just clean all others with QUIT... */
    {
      /*
      ** If this exit is generated from "m_kill", then there
      ** is no sense in sending the QUIT--KILL's have been
      ** sent instead.
      */
      if ((source_p->flags & FLAGS_KILLED) == 0)
        {
          sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS,
                        NOFLAGS, ":%s QUIT :%s", source_p->name, comment);
        }
      /*
      ** If a person is on a channel, send a QUIT notice
      ** to every client (person) on the same channel (so
      ** that the client can show the "**signoff" message).
      ** (Note: The notice is to the local clients *only*)
      */
      if (source_p->user)
        {
          sendto_common_channels_local(source_p, ":%s!%s@%s QUIT :%s",
				       source_p->name,
				       source_p->username,
				       source_p->host,
				       comment);

          for (lp = source_p->user->channel.head; lp; lp = next_lp)
	    {
	      next_lp = lp->next;
	      remove_user_from_channel(lp->data, source_p);
	    }
          /* Should not be in any channels now */
          assert(source_p->user->channel.head == NULL);
          
          /* Clean up invitefield */
          for (lp = source_p->user->invited.head; lp; lp = next_lp)
           {
              next_lp = lp->next;
              del_invite(lp->data, source_p);
           }

          /* Clean up allow lists */
          del_all_accepts(source_p);

	  add_history(source_p, 0);
	  off_history(source_p);

	  if (HasID(source_p))
	    del_from_id_hash_table(source_p->user->id, source_p);
  
          /* again, this is all that is needed */
        }
    }
  
  /* 
   * Remove source_p from the client lists
   */
  del_from_client_hash_table(source_p->name, source_p);

  /* remove from global client list */
  remove_client_from_list(source_p);

  /* Check to see if the client isn't already on the dead list */
  assert(dlinkFind(&dead_list, source_p) == NULL);
  /* add to dead client dlist */
  lp = make_dlink_node();
  SetDead(source_p);
  dlinkAdd(source_p, lp, &dead_list);
}
Example #13
0
 * linebuf_attach
 *
 * attach the lines in a buf_head_t to another buf_head_t
 * without copying the data (using refcounts).
 */
void
linebuf_attach(buf_head_t * bufhead, buf_head_t * new)
{
	dlink_node *new_node;
	dlink_node *node;
	buf_line_t *line;

	DLINK_FOREACH(node, new->list.head)
	{
		line = (buf_line_t *) node->data;
		new_node = make_dlink_node();
		dlinkAddTail(line, new_node, &bufhead->list);

		/* Update the allocated size */
		bufhead->alloclen++;
		bufhead->len += line->len;
		bufhead->numlines++;

		line->refcount++;
	}
}

/*
 * linebuf_putmsg
 *
 * Similar to linebuf_put, but designed for use by send.c.
Example #14
0
int
main (int argc, char *argv[])
{
  /* Check to see if the user is running
   * us as root, which is a nono
   */
  if (geteuid () == 0)
    {
      fprintf (stderr, "Don't run ircd as root!!!\n");
      return (-1);
    }

  /* save server boot time right away, so getrusage works correctly */
  set_time ();

  /* Setup corefile size immediately after boot -kre */
  setup_corefile ();

  /* set initialVMTop before we allocate any memory */
  initialVMTop = get_vm_top ();

  ServerRunning = 0;

  /* It ain't random, but it ought to be a little harder to guess */
  srand (SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid () << 20)));
  memset (&me, 0, sizeof (me));
  memset (&meLocalUser, 0, sizeof (meLocalUser));
  me.localClient = &meLocalUser;
  dlinkAdd (&me, &me.node, &global_client_list);	/* Pointer to beginning
							   of Client list */

  memset (&ServerInfo, 0, sizeof (ServerInfo));

  /* Initialise the channel capability usage counts... */
  init_chcap_usage_counts ();

  ConfigFileEntry.dpath = DPATH;
  ConfigFileEntry.configfile = CPATH;	/* Server configuration file */
  ConfigFileEntry.klinefile = KPATH;	/* Server kline file         */
  ConfigFileEntry.xlinefile = XPATH;	/* Server xline file         */
  ConfigFileEntry.dlinefile = DLPATH;	/* dline file                */
  ConfigFileEntry.cresvfile = CRESVPATH;	/* channel resv file      */
  ConfigFileEntry.nresvfile = NRESVPATH;	/* nick resv file         */
  myargv = argv;
  umask (077);			/* better safe than sorry --SRB */

  parseargs (&argc, &argv, myopts);

  build_version ();

  if (printVersion)
    {
      printf ("ircd: version %s\n", ircd_version);
      exit (EXIT_SUCCESS);
    }

  if (chdir (ConfigFileEntry.dpath))
    {
      perror ("chdir");
      exit (EXIT_FAILURE);
    }

  if (!server_state.foreground)
    make_daemon ();
  else
    print_startup (getpid ());

#ifdef HAVE_LIBCRYPTO
  dh_init();
  fprintf(stderr, "SSL: Initialize\n");

  SSL_load_error_strings();
  SSLeay_add_ssl_algorithms();
  ServerInfo.ctx = SSL_CTX_new(SSLv23_server_method());

  if (!ServerInfo.ctx) {
       ERR_print_errors_fp(stderr);
       return 0;
  }

  fprintf(stderr, "SSL: Client based SSL connections are enabled.\n");
#endif

  setup_signals ();
  /* We need this to initialise the fd array before anything else */
  fdlist_init ();

  if (!server_state.foreground)
    close_all_connections ();	/* this needs to be before init_netio()! */
  else
    check_can_use_v6 ();	/* Done in close_all_connections normally */

  init_log (logFileName);
  init_netio ();		/* This needs to be setup early ! -- adrian */
  /* Check if there is pidfile and daemon already running */
  check_pidfile (pidFileName);
  /* Init the event subsystem */
  eventInit ();
  init_sys ();

#ifndef NOBALLOC
  initBlockHeap ();
#endif
  init_dlink_nodes ();
  init_slink_nodes ();
  initialize_message_files ();
  dbuf_init ();
  init_hash ();
  init_ip_hash_table ();	/* client host ip hash table */
  init_host_hash ();		/* Host-hashtable. */
  clear_hash_parse ();
  init_client ();
  init_user ();
  init_channels ();
  init_class ();
  init_whowas ();
  init_stats ();
  init_hooks ();
  read_conf_files (1);		/* cold start init conf files */
  initServerMask ();
  init_uid ();
  init_auth ();			/* Initialise the auth code */
  init_resolver ();		/* Needs to be setup before the io loop */
  init_reject ();               /* Set up the reject code. */
  init_umodes ();               /* Set up the usermode system. */

  initialize_foundation_signals(); /* register things that modules need */

#ifdef HAVE_LIBCRYPTO
  bio_spare_fd = save_spare_fd ("SSL private key validation");
#endif /* HAVE_LIBCRYPTO */

  initialize_server_capabs ();	/* Set up default_server_capabs */
  initialize_global_set_options ();

  if (ServerInfo.name == NULL)
    {
      fprintf (stderr,
	       "ERROR: No server name specified in serverinfo block.\n");
      ilog (L_CRIT, "No server name specified in serverinfo block.");
      exit (EXIT_FAILURE);
    }
  strlcpy (me.name, ServerInfo.name, sizeof (me.name));

  /* serverinfo{} description must exist.  If not, error out. */
  if (ServerInfo.description == NULL)
    {
      fprintf (stderr,
	       "ERROR: No server description specified in serverinfo block.\n");
      ilog (L_CRIT,
	    "ERROR: No server description specified in serverinfo block.");
      exit (EXIT_FAILURE);
    }
  strlcpy (me.info, ServerInfo.description, sizeof (me.info));

  me.from = &me;
  me.servptr = &me;

  SetMe (&me);
  make_server (&me);

  strlcpy (me.serv->up, me.name, sizeof (me.serv->up));
  me.lasttime = me.since = me.firsttime = CurrentTime;
  hash_add_client (&me);

  /* add ourselves to global_serv_list */
  dlinkAdd (&me, make_dlink_node (), &global_serv_list);

  check_class ();

#ifndef STATIC_MODULES
  if (chdir (MODPATH))
    {
      ilog (L_CRIT, "Could not load core modules. Terminating!");
      exit (EXIT_FAILURE);
    }
  mod_set_base ();
  load_all_modules (1);
  load_core_modules (1);
  /* Go back to DPATH after checking to see if we can chdir to MODPATH */
  chdir (ConfigFileEntry.dpath);
#else
  load_all_modules (1);
#endif

  write_pidfile (pidFileName);

  ilog (L_NOTICE, "Server Ready");

  eventAddIsh ("cleanup_tklines", cleanup_tklines, NULL,
	       CLEANUP_TKLINES_TIME);

  /* We want try_connections to be called as soon as possible now! -- adrian */
  /* No, 'cause after a restart it would cause all sorts of nick collides */
  eventAddIsh ("try_connections", try_connections, NULL,
	       STARTUP_CONNECTIONS_TIME);

  eventAddIsh ("collect_zipstats", collect_zipstats, NULL, ZIPSTATS_TIME);

  /* Setup the timeout check. I'll shift it later :)  -- adrian */
  eventAddIsh ("comm_checktimeouts", comm_checktimeouts, NULL, 1);

  if (splitmode)
    eventAddIsh ("check_splitmode", check_splitmode, NULL, 60);

  ServerRunning = 1;
  io_loop ();
  return (0);
}