Exemplo n.º 1
0
/** Initialize the features subsystem. */
void
feature_init(void)
{
    int i;

    for (i = 0; features[i].type; i++) {
        switch (features[i].flags & FEAT_MASK) {
        case FEAT_NONE: /* you're on your own */
            break;

        case FEAT_INT:  /* Integers or Booleans... */
        case FEAT_BOOL:
            features[i].v_int = features[i].def_int;
            break;

        case FEAT_STR:  /* Strings */
            features[i].v_str = features[i].def_str;
            assert(features[i].def_str || (features[i].flags & FEAT_NULL));
            break;
        }
    }

    cli_magic(&his) = CLIENT_MAGIC;
    cli_status(&his) = STAT_SERVER;
    feature_notify_servername();
    feature_notify_serverinfo();
}
Exemplo n.º 2
0
/** used to initialize the features subsystem */
void
feature_init(void)
{
  int i;

  for (i = 0; features[i].type; i++) {
    struct FeatureDesc *feat = &features[i];

    switch (feat_type(&features[i])) {
    case FEAT_NONE: /* you're on your own */
      break;

    case FEAT_INT:  /* Integers or Booleans... */
    case FEAT_UINT:
    case FEAT_BOOL:
      feat->v_int = feat->def_int;
      break;

    case FEAT_STR:  /* Strings */
      feat->v_str = feat->def_str;
      assert(feat->def_str || (feat->flags & FEAT_NULL));
      break;
    }

    if (feat->notify)
     (*feat->notify)();
 } 	  

  cli_magic(&his) = CLIENT_MAGIC;
  cli_status(&his) = STAT_SERVER;
}
Exemplo n.º 3
0
/*
 * Create a new struct Client structure and set it to initial state.
 *
 *   from == NULL,   create local client (a client connected to a socket).
 *
 *   from != NULL,   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, int status)
{
  struct Client* cptr = 0;
  struct Connection* con = 0;

  assert(!from || cli_verify(from));

  cptr = alloc_client();

  assert(0 != cptr);
  assert(!cli_magic(cptr));
  assert(0 == from || 0 != cli_connect(from));

  if (!from) { /* local client, allocate a struct Connection */
    con = alloc_connection();

    assert(0 != con);
    assert(!con_magic(con));

    con_magic(con) = CONNECTION_MAGIC;
    con_fd(con) = -1; /* initialize struct Connection */
    con_freeflag(con) = 0;
    con_nextnick(con) = CurrentTime - NICK_DELAY;
    con_nexttarget(con) = CurrentTime - (TARGET_DELAY * (STARTTARGETS - 1));
    con_handler(con) = UNREGISTERED_HANDLER;
    con_client(con) = cptr;

    cli_local(cptr) = 1; /* Set certain fields of the struct Client */
    cli_since(cptr) = cli_lasttime(cptr) = cli_firsttime(cptr) = CurrentTime;
    cli_lastnick(cptr) = TStime();
  } else
    con = cli_connect(from); /* use 'from's connection */

  assert(0 != con);
  assert(con_verify(con));

  cli_magic(cptr) = CLIENT_MAGIC;
  cli_connect(cptr) = con; /* set the connection and other fields */
  cli_status(cptr) = status;
  cli_hnext(cptr) = cptr;
  strcpy(cli_username(cptr), "unknown");

  return cptr;
}
Exemplo n.º 4
0
/** Release a Client structure by prepending it to #clientFreeList.
 * @param[in] cptr Client that is no longer being used.
 */
static void dealloc_client(struct Client* cptr)
{
  assert(cli_verify(cptr));
  assert(0 == cli_connect(cptr));

  --clients.inuse;

  cli_next(cptr) = clientFreeList;
  clientFreeList = cptr;

  cli_magic(cptr) = 0;
}
Exemplo n.º 5
0
/** Run the daemon.
 * @param[in] argc Number of arguments in \a argv.
 * @param[in] argv Arguments to program execution.
 */
int main(int argc, char **argv) {
  CurrentTime = time(NULL);

  thisServer.argc = argc;
  thisServer.argv = argv;
  thisServer.uid  = getuid();
  thisServer.euid = geteuid();

#ifdef MDEBUG
  mem_dbg_initialise();
#endif

#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_CORE)
  set_core_limit();
#endif

  umask(077);                   /* better safe than sorry --SRB */
  memset(&me, 0, sizeof(me));
  memset(&me_con, 0, sizeof(me_con));
  cli_connect(&me) = &me_con;
  cli_fd(&me) = -1;

  parse_command_line(argc, argv);

  if (chdir(dpath)) {
    fprintf(stderr, "Fail: Cannot chdir(%s): %s, check DPATH\n", dpath, strerror(errno));
    return 2;
  }

  if (!set_userid_if_needed())
    return 3;

  /* Check paths for accessibility */
  if (!check_file_access(SPATH, 'S', X_OK) ||
      !check_file_access(configfile, 'C', R_OK))
    return 4;

  if (!init_connection_limits())
    return 9;

  close_connections(!(thisServer.bootopt & (BOOT_DEBUG | BOOT_TTY | BOOT_CHKCONF)));

  /* daemon_init() must be before event_init() because kqueue() FDs
   * are, perversely, not inherited across fork().
   */
  daemon_init(thisServer.bootopt & BOOT_TTY);

#ifdef DEBUGMODE
  /* Must reserve fd 2... */
  if (debuglevel >= 0 && !(thisServer.bootopt & BOOT_TTY)) {
    int fd;
    if ((fd = open("/dev/null", O_WRONLY)) < 0) {
      fprintf(stderr, "Unable to open /dev/null (to reserve fd 2): %s\n",
	      strerror(errno));
      return 8;
    }
    if (fd != 2 && dup2(fd, 2) < 0) {
      fprintf(stderr, "Unable to reserve fd 2; dup2 said: %s\n",
	      strerror(errno));
      return 8;
    }
  }
#endif

  event_init(MAXCONNECTIONS);

  setup_signals();
  feature_init(); /* initialize features... */
  log_init(*argv);
  set_nomem_handler(outofmemory);

  initload();
  init_list();
  init_hash();
  init_class();
  initwhowas();
  initmsgtree();
  initstats();

  /* we need this for now, when we're modular this 
     should be removed -- hikari */
  ircd_crypt_init();

  motd_init();

  if (!init_conf()) {
    log_write(LS_SYSTEM, L_CRIT, 0, "Failed to read configuration file %s",
	      configfile);
    return 7;
  }

  if (thisServer.bootopt & BOOT_CHKCONF) {
    if (dbg_client)
      conf_debug_iline(dbg_client);
    fprintf(stderr, "Configuration file %s checked okay.\n", configfile);
    return 0;
  }

  debug_init(thisServer.bootopt & BOOT_TTY);
  if (check_pid()) {
    Debug((DEBUG_FATAL, "Failed to acquire PID file lock after fork"));
    exit(2);
  }

  init_server_identity();

  uping_init();

  stats_init();

  IPcheck_init();
  timer_add(timer_init(&connect_timer), try_connections, 0, TT_RELATIVE, 1);
  timer_add(timer_init(&ping_timer), check_pings, 0, TT_RELATIVE, 1);
  timer_add(timer_init(&destruct_event_timer), exec_expired_destruct_events, 0, TT_PERIODIC, 60);
  timer_add(timer_init(&mute_timer), check_expired_mutes, 0, TT_PERIODIC, 30);

  CurrentTime = time(NULL);

  SetMe(&me);
  cli_magic(&me) = CLIENT_MAGIC;
  cli_from(&me) = &me;
  make_server(&me);

  cli_serv(&me)->timestamp = TStime();  /* Abuse own link timestamp as start TS */
  cli_serv(&me)->prot      = atoi(MAJOR_PROTOCOL);
  cli_serv(&me)->up        = &me;
  cli_serv(&me)->down      = NULL;
  cli_handler(&me)         = SERVER_HANDLER;

  SetYXXCapacity(&me, MAXCLIENTS);

  cli_lasttime(&me) = cli_since(&me) = cli_firsttime(&me) = CurrentTime;

  hAddClient(&me);

  write_pidfile();
  init_counters();

  Debug((DEBUG_NOTICE, "Server ready..."));
  log_write(LS_SYSTEM, L_NOTICE, 0, "Server Ready");

  event_loop();

  return 0;
}