Exemple #1
0
void
module_register_init(const void *arg)
{
    const moduledata_t* data = (const moduledata_t*) arg;
    int error;
    module_t mod;

    mod = module_lookupbyname(data->name);
    if (mod == NULL) {
#if 0
	panic("module_register_init: module named %s not found", data->name);
#else
	/* temporary kludge until kernel `file' attachment registers modules */
	error = module_register(data, linker_kernel_file);
	if (error)
	    panic("module_register_init: register of module failed! %d", error);
	mod = module_lookupbyname(data->name);
	if (mod == NULL)
	    panic("module_register_init: module STILL not found!");
#endif
    }
    error = MOD_EVENT(mod, MOD_LOAD);
    if (error) {
	module_unload(mod);	/* ignore error */
	module_release(mod);
	kprintf("module_register_init: MOD_LOAD (%s, %lx, %p) error %d\n",
	       data->name, (u_long)(uintfptr_t)data->evhand, data->priv, error);
    }
}
Exemple #2
0
/* SYNTAX: UNLOAD <module> [<submodule>] */
static void cmd_unload(const char *data)
{
    MODULE_REC *module;
    MODULE_FILE_REC *file;
    char *rootmodule, *submodule;
    void *free_arg;

    g_return_if_fail(data != NULL);

    if (!cmd_get_params(data, &free_arg, 2 , &rootmodule, &submodule))
        return;
    if (*rootmodule == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

    module = module_find(rootmodule);
    if (module != NULL) {
        if (*submodule == '\0')
            module_unload(module);
        else {
            file = module_file_find(module, submodule);
            if (file != NULL)
                module_file_unload(file);
            else
                module = NULL;
        }
    }

    if (module == NULL) {
        printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
                    TXT_MODULE_NOT_LOADED, rootmodule, submodule);
    }

    cmd_params_free(free_arg);
}
Exemple #3
0
int mprepare(struct mprepare_state *s, block_t heap, mfile f)
/* Effects: Start processing module f:
     - unload f
     - load required modules
     - change status of variables of f (defines, writes)
     - setup information for mrecall/massign/mexecute

     Sends error/warning messages.
   Returns: TRUE if compilation can proceed
*/
{
  if (f->name)
    {
      if (!module_unload(s->ccontext->gstate, f->name))
	return FALSE;
      module_set(s->ccontext->gstate, f->name, module_loading);
    }

  s->f = f;
  s->heap = heap;
  s->all_loaded = TRUE;
  s->lmodules = NULL;
  s->modules = f->imports;

  return TRUE;
}
Exemple #4
0
static void textui_deinit(void)
{
	quitting = TRUE;
	signal(SIGINT, SIG_DFL);

	while (modules != NULL)
		module_unload(modules->data);

	signal_remove("gui exit", (SIGNAL_FUNC) sig_exit);
	gui_textwidget_deinit();
	gui_special_vars_deinit();
	statusbar_deinit();
	gui_printtext_deinit();
	gui_readline_deinit();
	gui_windows_deinit();
	mainwindow_activity_deinit();
	mainwindows_deinit();
	gui_entry_deinit();
	deinit_screen();

#ifdef HAVE_STATIC_PERL
        perl_deinit();
#endif

	theme_unregister();

	fe_common_irc_deinit();
	fe_common_core_deinit();
	irc_deinit();
	core_deinit();
}
Exemple #5
0
int
linker_file_unload(linker_file_t file)
{
    module_t mod, next;
    struct common_symbol* cp;
    int error = 0;
    int i;

    KLD_DPF(FILE, ("linker_file_unload: lf->refs=%d\n", file->refs));
    lockmgr(&lock, LK_EXCLUSIVE|LK_RETRY, 0, curproc);
    if (file->refs == 1) {
	KLD_DPF(FILE, ("linker_file_unload: file is unloading, informing modules\n"));
	/*
	 * Inform any modules associated with this file.
	 */
	for (mod = TAILQ_FIRST(&file->modules); mod; mod = next) {
	    next = module_getfnext(mod);

	    /*
	     * Give the module a chance to veto the unload.
	     */
	    if (error = module_unload(mod)) {
		KLD_DPF(FILE, ("linker_file_unload: module %x vetoes unload\n",
			       mod));
		lockmgr(&lock, LK_RELEASE, 0, curproc);
		goto out;
	    }

	    module_release(mod);
	}
    }

    file->refs--;
    if (file->refs > 0) {
	lockmgr(&lock, LK_RELEASE, 0, curproc);
	goto out;
    }

    linker_file_sysuninit(file);

    TAILQ_REMOVE(&files, file, link);
    lockmgr(&lock, LK_RELEASE, 0, curproc);

    for (i = 0; i < file->ndeps; i++)
	linker_file_unload(file->deps[i]);
    free(file->deps, M_LINKER);

    for (cp = STAILQ_FIRST(&file->common); cp;
	 cp = STAILQ_FIRST(&file->common)) {
	STAILQ_REMOVE(&file->common, cp, common_symbol, link);
	free(cp, M_LINKER);
    }

    file->ops->unload(file);
    free(file, M_LINKER);

out:
    return error;
}
Exemple #6
0
void free_server()
{
	/* freeing loaded config entries */
	config_free_entries();

	/* unloading server modules */
	module_unload();
}
Exemple #7
0
int module_reload(const char *modules_path)
{
	if (module_unload() == 0)
	{
		return module_load(modules_path);
	}
	
	return -1;
}
Exemple #8
0
void gr_module_term()
{
    gr_module_t * module = (gr_module_t *)g_ghost_rocket_global.module;
    if ( NULL != module ) {
        module_unload( module );

        gr_free( module );
        g_ghost_rocket_global.module = NULL;
    }
}
Exemple #9
0
static void
module_glist_unload (GtkWidget * wid, struct session *sess)
{
	int row;
	char *modname;

	row = gtkutil_clist_selection (modclist);
	if (row == -1)
		return;
	gtk_clist_get_text (GTK_CLIST (modclist), row, 0, &modname);
	module_unload (modname, sess);
}
Exemple #10
0
void module_set_script_lang(const char* script_file)
{
    char* lang_names[] = { MODULE_NAME_UNK, MODULE_NAME_UBASIC, MODULE_NAME_LUA };

    int lang_id = script_lang_id(script_file);

    if (lang_id != current_lang_id)
    {
        module_unload(h_script.name);
        current_lang_id = lang_id;
        h_script.name = lang_names[lang_id];
    }
}
Exemple #11
0
void module_end( GList *list) { // unload all the modules
  GList* l;
  MODULE_ENTRY* entry;
  l = list;
  while  ( l ) {
    entry = (MODULE_ENTRY*)l->data;
    module_unload (entry);
    g_free( entry->name );
    g_free( entry->description );
    g_free( entry->functions );
    g_free( l->data );
    l = g_list_next ( l );
  }
  g_list_free( list );
}
Exemple #12
0
static int _module_load(module_handler_t* hMod)
{
    int idx;

    // Check if module loaded
    idx = module_find(hMod->name);
    if ( idx>=0 )
        return idx;

    // Find empty slot   
    for ( idx=0; idx<MAX_NUM_LOADED_MODULES && modules[idx].hdr; idx++ );

    if  ( idx == MAX_NUM_LOADED_MODULES )
    {
        moduleload_error("%d already loaded",MAX_NUM_LOADED_MODULES);
        return -1;
    }

    if (module_preload(hMod->name, hMod->version) != 0)
    {
        // Module is valid. Finalize binding
        modules[idx].hdr = flat_buf;

        // store runtime params
        flat_module_name_make(modules[idx].modulename, module_filename);
        modules[idx].hMod = hMod;

        int bind_err = bind_module( hMod, flat_buf->_module_info->lib );

        if ( flat_buf->_module_info->lib->loader )
        {
            uint32_t x = flat_buf->_module_info->lib->loader();
            bind_err = bind_err || x;
        }

        if ( bind_err )
        {
            module_unload(module_filename);
            moduleload_error("chdk mismatch",0);
            return -1;
        }

        return idx;
    }

    return -1;
}
Exemple #13
0
void free_module(struct obs_module *mod)
{
	if (!mod)
		return;

	if (mod->module) {
		void (*module_unload)(void);

		module_unload = os_dlsym(mod->module, "module_unload");
		if (module_unload)
			module_unload();

		os_dlclose(mod->module);
	}

	bfree(mod->name);
}
Exemple #14
0
static void os_cmd_modunload(sourceinfo_t *si, int parc, char *parv[])
{
	char *module;
	int i;
	module_t *m;

	if (parc < 1)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "MODUNLOAD");
		command_fail(si, fault_needmoreparams, _("Syntax: MODUNLOAD <module...>"));
		return;
	}
	i = 0;
	while (i < parc)
	{
		module = parv[i++];
		m = module_find_published(module);

		if (!m)
		{
			command_fail(si, fault_nosuch_target, _("\2%s\2 is not loaded; it cannot be unloaded."), module);
			continue;
		}

		if (m->can_unload != MODULE_UNLOAD_CAPABILITY_OK)
		{
			slog(LG_INFO, "\2%s\2 tried to unload a permanent module",
				get_oper_name(si));
			command_fail(si, fault_noprivs, _("\2%s\2 is a permanent module; it cannot be unloaded."), module);
			continue;
		}

		if (!strcmp(m->name, "operserv/main") || !strcmp(m->name, "operserv/modload") || !strcmp(m->name, "operserv/modunload"))
		{
			command_fail(si, fault_noprivs, _("Refusing to unload \2%s\2."),
					module);
			continue;
		}

		logcommand(si, CMDLOG_ADMIN, "MODUNLOAD: \2%s\2", module);

		module_unload(m, MODULE_UNLOAD_INTENT_PERM);

		command_success_nodata(si, _("Module \2%s\2 unloaded."), module);
	}
}
Exemple #15
0
static void textui_deinit(void)
{
	signal(SIGINT, SIG_DFL);

        term_refresh_freeze();
	while (modules != NULL)
		module_unload(modules->data);

#ifdef HAVE_STATIC_PERL
	perl_core_deinit();
	fe_perl_deinit();
#endif

#ifdef HAVE_STATIC_OTR
	otr_core_deinit();
#endif

	dirty_check(); /* one last time to print any quit messages */
	signal_remove("settings userinfo changed", (SIGNAL_FUNC) sig_settings_userinfo_changed);
	signal_remove("gui exit", (SIGNAL_FUNC) sig_exit);

	lastlog_deinit();
	statusbar_deinit();
	gui_entry_deinit();
	gui_printtext_deinit();
	gui_readline_deinit();
	gui_windows_deinit();
	mainwindows_layout_deinit();
	mainwindow_activity_deinit();
	mainwindows_deinit();
	gui_expandos_deinit();
	textbuffer_commands_deinit();
	textbuffer_view_deinit();
	textbuffer_deinit();

	term_refresh_thaw();
	term_deinit();

	theme_unregister();

	fe_common_irc_deinit();
	fe_common_core_deinit();
	irc_deinit();
	core_deinit();
}
Exemple #16
0
static int handle_keyboard_input(irc_connection *con)
{
    char msg[512];
    int retval = 0;
    char *ret = fgets(msg, 511, stdin);
    if (!ret) return -1;
    if (strlen(ret) < 2) return 0;

    char *parse = strdup(msg);
    char *cmd = strtok(parse, " \n");

    if (Is_cmd("q")) {
        /* user input "q" quits the whole application. */
        retval = -2;
    }
    else if (Is_cmd("load")) {
        char *modname = strtok(NULL, " \n");
        printf("Loading module %15s ... ", modname);

        int mod_ret = module_load(con, conf, modname);
        if (!mod_ret) printf("OK!\n");
        else	      printf("Error (%d)!\n", mod_ret);
    }
    else if (Is_cmd("unload")) {
        char *modname = strtok(NULL, " \n");
        printf("Unloading module %15s ... ", modname);

        int mod_ret = module_unload(con, modname);
        if (!mod_ret) printf("OK!\n");
        else	      printf("Error (%d)!\n", mod_ret);
    }
    else if (Is_cmd("modules")) {
        printf("Currently loaded modules:\n");
        char **modules = module_loaded_modules(con);
        int i;
        for (i=0; modules[i]; i++)
            printf(" - %15s\n", modules[i]);
        free(modules);
    }
    else
        retval = irc_send_raw_msg(con, msg);

    free(parse);
    return retval;
}
Exemple #17
0
int module_shutdown(void)
{
	int unloaded;
	module_list_t *entry, *next;

	do {
		unloaded = 0;
		for (entry = module_list_head; entry; entry = next) {
			next = entry->next;
			if (!module_unload(entry->modinfo.name, MODULE_RESTART)) unloaded = 1;
		}
	} while (unloaded);

	bind_table_del(BT_load);
	bind_table_del(BT_unload);

	garbage_run();
	return (0);
}
Exemple #18
0
/**
 * Release all resources associated to dynamic modules
 *
 * \return 0 on success, negative error code on failure
 */
int module_unload_all(void)
{
    int i;
    int rc;
    int rc_save = 0;

    assert(mod_count >= 0);

    for (i = 0; i < mod_count; i++) {
        rc = module_unload(&mod_list[i]);
        if (rc != 0 && rc_save == 0)
            rc_save = rc;
    }

    free(mod_list);
    mod_count = 0;

    return rc_save;
}
Exemple #19
0
/* SYNTAX: UNLOAD <module> [<submodule>] */
static void cmd_unload(const char *data)
{
	MODULE_REC *module;
        MODULE_FILE_REC *file;
        char *rootmodule, *submodule;
	void *free_arg;
	GSList *tmp;
	int all_dynamic;

	g_return_if_fail(data != NULL);

	if (!cmd_get_params(data, &free_arg, 2 , &rootmodule, &submodule))
		return;
	if (*rootmodule == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	module = module_find(rootmodule);
	if (module != NULL) {
		if (*submodule == '\0') {
			all_dynamic = 1;
			for (tmp = module->files; tmp != NULL; tmp = tmp->next)
				all_dynamic &= !MODULE_IS_STATIC((MODULE_FILE_REC*) tmp->data);
			if (all_dynamic)
				module_unload(module);
		}
		else {
			file = module_file_find(module, submodule);
			if (file != NULL) {
				if (!MODULE_IS_STATIC(file))
					module_file_unload(file);
			}
			else
				module = NULL;
		}
	}

	if (module == NULL) {
		printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
                            TXT_MODULE_NOT_LOADED, rootmodule, submodule);
	}

	cmd_params_free(free_arg);
}
Exemple #20
0
static void module_command(client c) {
	if (!strcasecmp(c->argv[1], "load")) {
		/* FIXME */
		if (module_load("/var/lib/xcb", c->argv[2]) != MODULE_LOAD_SUCCESS)
			add_reply_error_format(c, "module '%s' loaded NOT OK", c->argv[2]);
		else
			add_reply_string_format(c, "module '%s' loaded OK\r\n", c->argv[2]);
	} else if (!strcasecmp(c->argv[1], "unload")) {
		if (module_unload(c->argv[2]) != MODULE_LOAD_SUCCESS)
			add_reply_error_format(c, "module '%s' unloaded NOT OK", c->argv[2]);
		else
			add_reply_string_format(c, "module '%s' unloaded OK\r\n", c->argv[2]);
	} else if (!strcasecmp(c->argv[1], "reload")) {
		if (module_reload(c->argv[2]) != MODULE_RELOAD_SUCCESS)
			add_reply_error_format(c, "module '%s' reloaded NOT OK", c->argv[2]);
		else
			add_reply_string_format(c, "module '%s' reloaded OK\r\n", c->argv[2]);
	} else
		add_reply_error_format(c, "unknown action '%s'", c->argv[1]);
	add_reply_string(c, "\r\n", 2);
}
Exemple #21
0
/**
 * Kill the second X server if any, turn card off if requested.
 */
void stop_secondary() {
  char driver[BUFFER_SIZE];
  // kill X if it is running
  if (bb_is_running(bb_status.x_pid)) {
    bb_log(LOG_INFO, "Stopping X server\n");
    bb_stop_wait(bb_status.x_pid);
  }

  if (bb_config.pm_method == PM_DISABLED && bb_status.runmode != BB_RUN_EXIT) {
    /* do not disable the card if PM is disabled unless exiting */
    return;
  }

  //if card is on and can be switched, switch it off
  if (switcher) {
    if (switcher->need_driver_unloaded) {
      /* do not unload the drivers nor disable the card if the card is not on */
      if (switcher->status() != SWITCH_ON) {
        return;
      }
      if (pci_config_save(pci_bus_id_discrete, &pci_config_state_discrete)) {
        bb_log(LOG_WARNING, "Could not save PCI configuration space: %s\n",
                strerror(errno));
      }
      /* unload the driver loaded by the graphica card */
      if (pci_get_driver(driver, pci_bus_id_discrete, sizeof driver)) {
        module_unload(driver);
      }

      //only turn card off if no drivers are loaded
      if (pci_get_driver(NULL, pci_bus_id_discrete, 0)) {
        bb_log(LOG_DEBUG, "Drivers are still loaded, unable to disable card\n");
        return;
      }
    }
    if (switch_off() != SWITCH_OFF) {
      bb_log(LOG_WARNING, "Unable to disable discrete card.");
    }
  }
}//stop_secondary
Exemple #22
0
void module_file_unload(MODULE_FILE_REC *file)
{
	MODULE_REC *root;
  
        root = file->root;
	root->files = g_slist_remove(root->files, file);

        if (file->initialized)
		signal_emit("module unloaded", 2, file->root, file);

#ifdef HAVE_GMODULE
	if (file->gmodule != NULL)
                module_file_deinit_gmodule(file);
#endif

	g_free(file->name);
	g_free(file->defined_module_name);
	g_free(file);

	if (root->files == NULL && g_slist_find(modules, root) != NULL)
                module_unload(root);
}
Exemple #23
0
static_inline
int module_load(
    gr_module_t * module,
    const char * path,
    bool is_absolute
)
{
    if ( NULL != module->dll ) {
        return GR_ERR_WRONG_CALL_ORDER;
    }

    if ( is_absolute ) {
        module->dll = gr_dll_open_absolute( path );
    } else {
        module->dll = gr_dll_open( path );
    }
    if ( NULL== module->dll ) {
        return GR_ERR_INIT_MODULE_FAILED;
    }

    module->version = (gr_version_t)gr_dll_symbol( module->dll, GR_VERSION_NAME );
    module->init = (gr_init_t)gr_dll_symbol( module->dll, GR_INIT_NAME );
    module->term = (gr_term_t)gr_dll_symbol( module->dll, GR_TERM_NAME );
    module->tcp_accept = (gr_tcp_accept_t)gr_dll_symbol( module->dll, GR_TCP_ACCEPT_NAME );
    module->tcp_close = (gr_tcp_close_t)gr_dll_symbol( module->dll, GR_TCP_CLOSE_NAME );
    module->chk_binary = (gr_check_t)gr_dll_symbol( module->dll, GR_CHECK_NAME );
    module->proc_binary = (gr_proc_t)gr_dll_symbol( module->dll, GR_PROC_NAME );
    module->proc_http = (gr_proc_http_t)gr_dll_symbol( module->dll, GR_PROC_HTTP_NAME );

    if ( NULL == module->version || ( NULL == module->proc_binary && NULL == module->proc_http ) ) {
        gr_fatal( "[init](%s) gr_proc_http & gr_proc both not found", path );
        module_unload( module );
        return GR_ERR_INVALID_PARAMS;
    }

    gr_info( "[init]module '%s' loadded", path );
    return 0;
}
Exemple #24
0
void on_modules_cell_toggle_callback(GtkCellRenderer * cell,
             gchar * path, gpointer model)
{
  GtkTreeIter iter;
  gboolean *on;
  gchar *name;
  MODULE_ENTRY *entry;
  GList *l;

  gtk_tree_model_get_iter_from_string(model, &iter, path);
  gtk_tree_model_get(model, &iter, COL_ENABLE, &on, COL_NAME, &name,
         -1);
  if (on) {
    entry = module_get_by_name(config->modules, name);
    GtkWidget *menubar;
    GtkWidget *toolbar;
    // reset menu for any existing window
    if (entry->functions) {
      l = config->windows;
      while (l) {
        menubar =
            interface_get_widget(GTK_WIDGET
               (l->data),
               "menubar_main");
        if (menubar)
          if (entry->functions->menu_reset)
            entry->functions->
                menu_reset((gpointer)
                     menubar);

        toolbar =
            interface_get_widget(GTK_WIDGET
               (l->data),
               "toolbar_main");
        if (toolbar)
          if (entry->functions->
              toolbar_reset)
            entry->functions->
                toolbar_reset((gpointer) toolbar);
        l = g_list_next(l);
      }

      // call session_open for all existing sessions
      if (entry->functions->session_close) {
        l = config->sessions;
        while (l) {
          entry->functions->session_close(l->
                  data);
          l = g_list_next(l);
        }
      }
    }
    if (module_unload(entry)) {
      gtk_list_store_set(model, &iter, COL_ENABLE, FALSE,
             -1);
      // change the menu 
    } else {
      char *message;
      message =
          g_strdup_printf
          (" Module \"%s\" can't be unloaded !", name);
      interface_display_message(message);
      g_free(message);
    }
  } else {
    if (module_load
        ((entry =
          module_get_by_name(config->modules, name)))) {
      GtkWidget *menubar;
      GtkWidget *toolbar;
      if (entry->functions) {
        // modify menu for any existing window
        l = config->windows;
        while (l) {
          menubar =
              interface_get_widget(GTK_WIDGET
                 (l->data),
                 "menubar_main");
          if (menubar)
            if (entry->functions->
                menu_modify)
              entry->functions->
                  menu_modify((gpointer) menubar);
          toolbar =
              interface_get_widget(GTK_WIDGET
                 (l->data),
                 "toolbar_main");
          if (toolbar)
            if (entry->functions->
                toolbar_modify)
              entry->functions->
                  toolbar_modify((gpointer) toolbar);
          l = g_list_next(l);
        }
        // call session_open for all existing sessions
        if (entry->functions->session_open) {
          l = config->sessions;
          while (l) {
            entry->functions->
                session_open(l->data);
            l = g_list_next(l);
          }
        }
      }
      gtk_list_store_set(model, &iter, COL_ENABLE, TRUE,
             -1);
    } else {
      char *message;
      message =
          g_strdup_printf
          (" Module \"%s\" can't be loaded !", name);
      interface_display_message(message);
      g_free(message);
    }
  }
  g_free(name);
}
Exemple #25
0
/**
 * Start the X server by fork-exec, turn card on and load driver if needed.
 * If after this method finishes X is running, it was successfull.
 * If it somehow fails, X should not be running after this method finishes.
 */
void start_secondary(void) {
  char driver[BUFFER_SIZE] = {0};
  /* enable card if the switcher is available */
  if (switcher) {
    if (switch_on() != SWITCH_ON) {
      set_bb_error("Could not enable discrete graphics card");
      return;
    }
    if (pci_config_restore(pci_bus_id_discrete, &pci_config_state_discrete)) {
      bb_log(LOG_WARNING, "Could not restore PCI configuration space: %s\n",
              strerror(errno));
    }
  }

  //if runmode is BB_RUN_EXIT, do not start X, we are shutting down.
  if (bb_status.runmode == BB_RUN_EXIT) {
    return;
  }

  if (pci_get_driver(driver, pci_bus_id_discrete, sizeof driver)) {
    /* if the loaded driver does not equal the driver from config, unload it */
    if (strcasecmp(bb_config.driver, driver)) {
      if (!module_unload(driver)) {
        /* driver failed to unload, aborting */
        return;
      }
    }
  }

  /* load the driver if none was loaded or if the loaded driver did not match
   * the configured one */
  if (strcasecmp(bb_config.driver, driver)) {
    char *module_name = bb_config.module_name;
    char *driver_name = bb_config.driver;
    if (!module_load(module_name, driver_name)) {
      set_bb_error("Could not load GPU driver");
      return;
    }
  }

  //no problems, start X if not started yet
  if (!bb_is_running(bb_status.x_pid)) {
    char pci_id[12];
    static char *x_conf_file;
    snprintf(pci_id, 12, "PCI:%02x:%02x:%o", pci_bus_id_discrete->bus,
            pci_bus_id_discrete->slot, pci_bus_id_discrete->func);
    if (!x_conf_file) {
      x_conf_file = xorg_path_w_driver(bb_config.x_conf_file, bb_config.driver);
    }

    bb_log(LOG_INFO, "Starting X server on display %s.\n", bb_config.x_display);
    char *x_argv[] = {
      XORG_BINARY,
      bb_config.x_display,
      "-config", x_conf_file,
      "-sharevts",
      "-nolisten", "tcp",
      "-noreset",
      "-verbose", "3",
      "-isolateDevice", pci_id,
      "-modulepath",
      bb_config.mod_path,
      NULL
    };
    if (!*bb_config.mod_path) {
      x_argv[12] = 0; //remove -modulepath if not set
    }
    //close any previous pipe, if it (still) exists
    if (bb_status.x_pipe[0] != -1){close(bb_status.x_pipe[0]); bb_status.x_pipe[0] = -1;}
    if (bb_status.x_pipe[1] != -1){close(bb_status.x_pipe[1]); bb_status.x_pipe[1] = -1;}
    //create a new pipe
    if (pipe2(bb_status.x_pipe, O_NONBLOCK)){
      set_bb_error("Could not create output pipe for X");
      return;
    }
    bb_status.x_pid = bb_run_fork_ld_redirect(x_argv, bb_config.ld_path, bb_status.x_pipe[1]);
    //close the end of the pipe that is not ours
    if (bb_status.x_pipe[1] != -1){close(bb_status.x_pipe[1]); bb_status.x_pipe[1] = -1;}
  }

  //check if X is available, for maximum 10 seconds.
  time_t xtimer = time(0);
  Display * xdisp = 0;
  while ((time(0) - xtimer <= 10) && bb_is_running(bb_status.x_pid)) {
    xdisp = XOpenDisplay(bb_config.x_display);
    if (xdisp != 0) {
      break;
    }
    check_xorg_pipe();//make sure Xorg errors come in smoothly
    usleep(100000); //don't retry too fast
  }
  check_xorg_pipe();//make sure Xorg errors come in smoothly

  //check if X is available
  if (xdisp == 0) {
    //X not available
    /// \todo Maybe check X exit status and/or messages?
    if (bb_is_running(bb_status.x_pid)) {
      //X active, but not accepting connections
      set_bb_error("X unresponsive after 10 seconds - aborting");
      bb_stop(bb_status.x_pid);
    } else {
      //X terminated itself
      set_bb_error("X did not start properly");
    }
  } else {
    //X accepted the connetion - we assume it works
    XCloseDisplay(xdisp); //close connection to X again
    bb_log(LOG_INFO, "X successfully started in %i seconds\n", time(0) - xtimer);
    //reset errors, if any
    set_bb_error(0);
  }
}//start_secondary
Exemple #26
0
int mainloop(int toplevel)
{
  static int socket_cleanup = 0;
  int xx, i, eggbusy = 1, tclbusy = 0;
  char buf[520];

  /* Lets move some of this here, reducing the numer of actual
   * calls to periodic_timers
   */
  now = time(NULL);
  /*
   * FIXME: Get rid of this, it's ugly and wastes lots of cpu.
   *
   * pre-1.3.0 Eggdrop had random() in the once a second block below.
   *
   * This attempts to keep random() more random by constantly
   * calling random() and updating the state information.
   */
  random();                /* Woop, lets really jumble things */

  /* If we want to restart, we have to unwind to the toplevel.
   * Tcl will Panic if we kill the interp with Tcl_Eval in progress.
   * This is done by returning -1 in tickle_WaitForEvent.
   */
  if (do_restart && do_restart != -2 && !toplevel)
    return -1;

  /* Once a second */
  if (now != then) {
    call_hook(HOOK_SECONDLY);
    then = now;
  }

  /* Only do this every so often. */
  if (!socket_cleanup) {
    socket_cleanup = 5;

    /* Remove dead dcc entries. */
    dcc_remove_lost();

    /* Check for server or dcc activity. */
    dequeue_sockets();
  } else
    socket_cleanup--;

  /* Free unused structures. */
  garbage_collect();

  xx = sockgets(buf, &i);
  if (xx >= 0) {              /* Non-error */
    int idx;

    for (idx = 0; idx < dcc_total; idx++)
      if (dcc[idx].sock == xx) {
        if (dcc[idx].type && dcc[idx].type->activity) {
          /* Traffic stats */
          if (dcc[idx].type->name) {
            if (!strncmp(dcc[idx].type->name, "BOT", 3))
              itraffic_bn_today += strlen(buf) + 1;
            else if (!strcmp(dcc[idx].type->name, "SERVER"))
              itraffic_irc_today += strlen(buf) + 1;
            else if (!strncmp(dcc[idx].type->name, "CHAT", 4))
              itraffic_dcc_today += strlen(buf) + 1;
            else if (!strncmp(dcc[idx].type->name, "FILES", 5))
              itraffic_dcc_today += strlen(buf) + 1;
            else if (!strcmp(dcc[idx].type->name, "SEND"))
              itraffic_trans_today += strlen(buf) + 1;
            else if (!strncmp(dcc[idx].type->name, "GET", 3))
              itraffic_trans_today += strlen(buf) + 1;
            else
              itraffic_unknown_today += strlen(buf) + 1;
          }
          dcc[idx].type->activity(idx, buf, i);
        } else
          putlog(LOG_MISC, "*",
                 "!!! untrapped dcc activity: type %s, sock %d",
                 dcc[idx].type->name, dcc[idx].sock);
        break;
      }
  } else if (xx == -1) {        /* EOF from someone */
    int idx;

    if (i == STDOUT && !backgrd)
      fatal("END OF FILE ON TERMINAL", 0);
    for (idx = 0; idx < dcc_total; idx++)
      if (dcc[idx].sock == i) {
        if (dcc[idx].type && dcc[idx].type->eof)
          dcc[idx].type->eof(idx);
        else {
          putlog(LOG_MISC, "*",
                 "*** ATTENTION: DEAD SOCKET (%d) OF TYPE %s UNTRAPPED",
                 i, dcc[idx].type ? dcc[idx].type->name : "*UNKNOWN*");
          killsock(i);
          lostdcc(idx);
        }
        idx = dcc_total + 1;
      }
    if (idx == dcc_total) {
      putlog(LOG_MISC, "*",
             "(@) EOF socket %d, not a dcc socket, not anything.", i);
      close(i);
      killsock(i);
    }
  } else if (xx == -2 && errno != EINTR) {      /* select() error */
    putlog(LOG_MISC, "*", "* Socket error #%d; recovering.", errno);
    for (i = 0; i < dcc_total; i++) {
      if ((fcntl(dcc[i].sock, F_GETFD, 0) == -1) && (errno == EBADF)) {
        putlog(LOG_MISC, "*",
               "DCC socket %d (type %d, name '%s') expired -- pfft",
               dcc[i].sock, dcc[i].type, dcc[i].nick);
        killsock(dcc[i].sock);
        lostdcc(i);
        i--;
      }
    }
  } else if (xx == -3) {
    call_hook(HOOK_IDLE);
    socket_cleanup = 0;       /* If we've been idle, cleanup & flush */
    eggbusy = 0;
  } else if (xx == -5) {
    eggbusy = 0;
    tclbusy = 1;
  }

  if (do_restart) {
    if (do_restart == -2)
      rehash();
    else if (!toplevel)
      return -1; /* Unwind to toplevel before restarting */
    else {
      /* Unload as many modules as possible */
      int f = 1;
      module_entry *p;
      Function startfunc;
      char name[256];

      /* oops, I guess we should call this event before tcl is restarted */
      check_tcl_event("prerestart");

      while (f) {
        f = 0;
        for (p = module_list; p != NULL; p = p->next) {
          dependancy *d = dependancy_list;
          int ok = 1;

          while (ok && d) {
            if (d->needed == p)
              ok = 0;
            d = d->next;
          }
          if (ok) {
            strcpy(name, p->name);
            if (module_unload(name, botnetnick) == NULL) {
              f = 1;
              break;
            }
          }
        }
      }

      /* Make sure we don't have any modules left hanging around other than
       * "eggdrop" and the two that are supposed to be.
       */
      for (f = 0, p = module_list; p; p = p->next) {
        if (strcmp(p->name, "eggdrop") && strcmp(p->name, "encryption") &&
            strcmp(p->name, "uptime")) {
          f++;
        }
      }
      if (f != 0) {
        putlog(LOG_MISC, "*", MOD_STAGNANT);
      }

      flushlogs();
      kill_tcl();
      init_tcl(argc, argv);
      init_language(0);

      /* this resets our modules which we didn't unload (encryption and uptime) */
      for (p = module_list; p; p = p->next) {
        if (p->funcs) {
          startfunc = p->funcs[MODCALL_START];
          startfunc(NULL);
        }
      }

      rehash();
#ifdef TLS
      ssl_cleanup();
      ssl_init();
#endif
      restart_chons();
      call_hook(HOOK_LOADED);
    }
    eggbusy = 1;
    do_restart = 0;
  }

#ifdef USE_TCL_EVENTS
  if (!eggbusy) {
/* Process all pending tcl events */
#  ifdef REPLACE_NOTIFIER
    if (Tcl_ServiceAll())
      tclbusy = 1;
#  else
    while (Tcl_DoOneEvent(TCL_DONT_WAIT | TCL_ALL_EVENTS))
      tclbusy = 1;
#  endif /* REPLACE_NOTIFIER */
#endif   /* USE_TCL_EVENTS   */
  }

  return (eggbusy || tclbusy);
}
Exemple #27
0
int gr_module_init(
    gr_version_t    version,
    gr_init_t       init,
    gr_term_t       term,
    gr_tcp_accept_t tcp_accept,
    gr_tcp_close_t  tcp_close,
    gr_check_t      chk_binary,
    gr_proc_t       proc_binary,
    gr_proc_http_t  proc_http)
{
    gr_module_t *   module;
    int             r;

    if ( NULL != g_ghost_rocket_global.module ) {
        gr_fatal( "[init]gr_module_init already called" );
        return GR_ERR_WRONG_CALL_ORDER;
    }

    module = (gr_module_t *)gr_calloc( 1, sizeof( gr_module_t ) );
    if ( NULL == module ) {
        gr_fatal( "[init]malloc %d bytes failed, errno=%d,%s",
                  (int)sizeof(gr_module_t), errno, strerror( errno ) );
        return GR_ERR_BAD_ALLOC;
    }

    module->version     = version;
    module->init        = init;
    module->term        = term;
    module->tcp_accept  = tcp_accept;
    module->tcp_close   = tcp_close;
    module->chk_binary  = chk_binary;
    module->proc_binary = proc_binary;
    module->proc_http   = proc_http;

    r = 0;

    do {

        if (   NULL == module->init
                && NULL == module->term
                && NULL == module->tcp_accept
                && NULL == module->tcp_close
                && NULL == module->chk_binary
                && NULL == module->proc_binary
                && NULL == module->proc_http
           )
        {
            // 没指定用户函数,要装载模块
            char path[ MAX_PATH ] = "";
            bool is_absolute;
            gr_config_get_module_path( path, sizeof( path ), & is_absolute );

            if ( '\0' != path[ 0 ] ) {
                r = module_load( module, path, is_absolute );
                if ( 0 != r ) {
                    gr_fatal( "[init]module_load( %s ) failed, return %d", path, r );
                    break;
                }
            }
        } else {
            if ( NULL == module->version ) {
                gr_fatal( "[init]module->version is NULL" );
                r = GR_ERR_INVALID_PARAMS;
                break;
            }
        }

        if ( ! check_version( module ) ) {
            gr_fatal( "[init]check_version failed" );
            r = GR_ERR_WRONG_VERSION;
            break;
        }

    } while ( false );

    if ( GR_OK != r ) {
        module_unload( module );
        gr_free( module );
        return r;
    }

    g_ghost_rocket_global.module = module;
    return GR_OK;
}
Exemple #28
0
/* export { */
struct module *module_load(const char *filename, getsym_t getsym_fun,
    void *getsym_arg) {
  FILE* elf_file = NULL;
  Elf32_Shdr *section_headers = NULL;
  struct module *mod = NULL;

  TRY_PTR(mod = malloc(sizeof(struct module)));
  module_init(mod);

  TRY_PTR(elf_file = fopen(filename, "rb"));

  Elf32_Ehdr elf_header;
  TRY_TRUE(fread(&elf_header, sizeof(Elf32_Ehdr), 1, elf_file) == 1);

  TRY_TRUE(elf_header.e_ident[EI_MAG0] == ELFMAG0
      && elf_header.e_ident[EI_MAG1] == ELFMAG1
      && elf_header.e_ident[EI_MAG2] == ELFMAG2
      && elf_header.e_ident[EI_MAG3] == ELFMAG3);
  TRY_TRUE(elf_header.e_ident[EI_CLASS] == ELFCLASS32);
  TRY_TRUE(elf_header.e_ident[EI_DATA] == ELFDATA2LSB);
  TRY_TRUE(elf_header.e_type == ET_REL);
  TRY_TRUE(elf_header.e_machine == EM_386);

  TRY_PTR(elf_header.e_shoff);
  TRY_TRUE(fseek(elf_file, elf_header.e_shoff, SEEK_SET) == 0);
  TRY_TRUE(elf_header.e_shentsize == sizeof(Elf32_Shdr));

  // If the number of sections is greater than or equal to SHN_LORESERVE
  // (0xff00), e_shnum has the value SHN_UNDEF (0) and the actual number of
  // section header table entries is contained in the sh_size field of the
  // section header at index 0
  // We do not handle this extension
  TRY_TRUE(elf_header.e_shnum != SHN_UNDEF);
  TRY_TRUE(elf_header.e_shnum < SHN_LORESERVE);

  TRY_PTR(section_headers = malloc(sizeof(Elf32_Shdr) * elf_header.e_shnum));
  TRY_TRUE(fread(section_headers, elf_header.e_shentsize, elf_header.e_shnum,
        elf_file) == elf_header.e_shnum);
  // Count and create sections
  mod->sections_sz = elf_header.e_shnum;
  TRY_PTR(mod->sections = malloc(sizeof(struct section) * mod->sections_sz));
  memset(mod->sections, 0, sizeof(struct section) * mod->sections_sz);
  // Not actually first global but we will treat all of them as global
  size_t global_sym_idx = 0;
  size_t symtab_idx = 0;
  // Load sections
  for (size_t idx = 0; idx < elf_header.e_shnum; idx++) {
    Elf32_Shdr *shdr = section_headers + idx;
    struct section *section;
    TRY_PTR(section = module_get_section(mod, idx));
    switch (shdr->sh_type) {
      case SHT_NULL:
      case SHT_STRTAB:
        // We will read appropriate strings table with symbols table
      case SHT_REL:
        // We will perform relocations later on
        break;
      case SHT_SYMTAB:
        TRY_TRUE(symtab_idx == 0);
        symtab_idx = idx;
        TRY_SYS(module_read_symbols(mod, shdr, elf_file));
        global_sym_idx = shdr->sh_info;
        // Field sh_link contains section header index of associated string table
        TRY_TRUE(IS_VALID_SHNDX(shdr->sh_link) && shdr->sh_link < elf_header.e_shnum);
        TRY_SYS(module_read_strings(mod, section_headers + shdr->sh_link, elf_file));
        break;
      case SHT_NOBITS:
        if ((shdr->sh_flags & SHF_ALLOC) && shdr->sh_size > 0) {
          TRY_SYS(section_alloc(section, shdr));
          memset((void *) section->addr, 0, shdr->sh_size);
        }
        break;
      case SHT_PROGBITS:
      default:
        if ((shdr->sh_flags & SHF_ALLOC) && shdr->sh_size > 0) {
          TRY_SYS(section_alloc(section, shdr));
          TRY_TRUE(fseek(elf_file, shdr->sh_offset, SEEK_SET) == 0);
          TRY_TRUE(fread((void *) section->addr, shdr->sh_size, 1, elf_file) == 1);
        }
        break;
    }
  }
  // An empty string table section is permitted.
  // TRY_PTR(mod->strings);
  TRY_PTR(mod->symbols);

  // Perform relocations
  for (size_t idx = 0; idx < elf_header.e_shnum; idx++) {
    Elf32_Shdr *shdr = section_headers + idx;
    if (shdr->sh_type == SHT_REL && shdr->sh_link == symtab_idx) {
      // mising (shdr->sh_flags & SHF_INFO_LINK)
      TRY_TRUE(fseek(elf_file, shdr->sh_offset, SEEK_SET) == 0);
      TRY_TRUE(sizeof(Elf32_Rel) == shdr->sh_entsize);
      size_t rel_num = shdr->sh_size / shdr->sh_entsize;
      TRY_TRUE(shdr->sh_size == rel_num * shdr->sh_entsize);

      struct section *dest_section;
      TRY_PTR(dest_section = module_get_section(mod, shdr->sh_info));
      if (section_is_alloc(dest_section)) {
        for (size_t idx = 0; idx < rel_num; idx++) {
          Elf32_Rel relocation;
          TRY_TRUE(fread(&relocation, sizeof(Elf32_Rel), 1, elf_file) == 1);
          TRY_SYS(do_relocation(mod, dest_section, &relocation, getsym_fun,
              getsym_arg));
        }
      }
    }
  }

  // Compress symbol table (remove local symbols after relocations)
  TRY_TRUE(global_sym_idx < mod->symbols_sz);
  mod->symbols_sz -= global_sym_idx;
  memmove(mod->symbols, mod->symbols + global_sym_idx,
      mod->symbols_sz * sizeof(symbol_t));
  TRY_PTR(mod->symbols = realloc(mod->symbols,
        mod->symbols_sz * sizeof(symbol_t)));

  // Set-up sections protection
  for (size_t idx = 0; idx < elf_header.e_shnum; idx++) {
    struct section *section;
    TRY_PTR(section = module_get_section(mod, idx));
    if (section_is_alloc(section)) {
      TRY_SYS(mprotect((void *) section->mmap_start, section->mmap_length,
            section->mmap_prot));
    }
  }

  free(section_headers);
  fclose(elf_file);
  return mod;
CATCH:
  free(section_headers);
  if (elf_file) {
    fclose(elf_file);
  }
  module_unload(mod);
  return NULL;
}
Exemple #29
0
static int tcc_compile_and_run(char* filename)
{
    console_printf("Compiling script %s...\n", filename);

    void* tcc = NULL;
    TCCState * script_state = NULL;
    void* script_buf = NULL;
    
    tcc = module_load("ML/MODULES/tcc.mo");
    if (!tcc)
    {
        console_printf("Could not load TCC compiler.\n");
        goto err;
    }
    
    script_state = (void*) module_exec(tcc, "tcc_new", 0);
    if (!script_state)
    {
        console_printf("Could not initialize TCC compiler.\n");
        goto err;
    }

    module_exec(tcc, "tcc_set_options", 2, script_state, "-nostdlib");
    module_exec(tcc, "tcc_set_options", 2, script_state, "-Wall");
    module_exec(tcc, "tcc_set_options", 2, script_state, "-IML/scripts");
    module_exec(tcc, "tcc_set_output_type", 2, script_state, TCC_OUTPUT_MEMORY);

    int ret_compile = module_exec(tcc, "tcc_add_file", 2, script_state, filename);
    if (ret_compile < 0)
    {
        console_printf("Compilation error.\n");
        goto err;
    }

    script_load_symbols(tcc, script_state, "ML/modules/5D3_113.sym");

    int size = module_exec(tcc, "tcc_relocate", 2, script_state, NULL);
    if (size <= 0)
    {
        console_printf("Linking error.\n");
        goto err;
    }

    script_buf = (void*) tcc_malloc(size);
    if (!script_buf)
    {
        console_printf("Malloc error.\n");
        goto err;
    }
    
    int ret_link = module_exec(tcc, "tcc_relocate", 2, script_state, script_buf);
    if (ret_link < 0)
    {
        console_printf("Relocate error.\n");
        goto err;
    }
        
    void (*script_main)() = (void*) module_exec(tcc, "tcc_get_symbol", 2, script_state, "main");
    if (!script_main)
    {
        console_printf("Your script should have a main function.\n");
        goto err;
    }

    script_define_param_variables(tcc, script_state);

    module_exec(tcc, "tcc_delete", 1, script_state); script_state = NULL;
    module_unload(tcc); tcc = NULL;

    console_printf("Running script %s...\n", filename);

    /* http://repo.or.cz/w/tinycc.git/commit/6ed6a36a51065060bd5e9bb516b85ff796e05f30 */
    sync_caches();

    script_main();

    tcc_free(script_buf); script_buf = NULL;
    return 0;

err:
    if (script_buf) tcc_free(script_buf);
    if (script_state) module_exec(tcc, "tcc_delete", 1, script_state);
    if (tcc) module_unload(tcc);
    return 1;
}
Exemple #30
0
int main(int argc, char **argv)
{
  int xx, i;
#ifdef STOP_UAC
  int nvpair[2];
#endif
  char buf[520], s[25];
  FILE *f;
#ifndef ENABLE_STRIP
  struct rlimit cdlim;
#endif

  /* Don't allow Eggdrop to run as root. */
  if (((int) getuid() == 0) || ((int) geteuid() == 0))
    fatal("ERROR: Eggdrop will not run as root!", 0);

#ifndef ENABLE_STRIP
  cdlim.rlim_cur = RLIM_INFINITY;
  cdlim.rlim_max = RLIM_INFINITY;
  setrlimit(RLIMIT_CORE, &cdlim);
#endif

#include "patch.h"
  /* Version info! */
  egg_snprintf(ver, sizeof ver, "eggdrop v%s", egg_version);
  egg_snprintf(version, sizeof version,
               "Eggdrop v%s (C) 1997 Robey Pointer (C) 2005 Eggheads",
               egg_version);
  /* Now add on the patchlevel (for Tcl) */
  sprintf(&egg_version[strlen(egg_version)], " %u", egg_numver);
  strcat(egg_version, egg_xtra);

#ifdef STOP_UAC
  nvpair[0] = SSIN_UACPROC;
  nvpair[1] = UAC_NOPRINT;
  setsysinfo(SSI_NVPAIRS, (char *) nvpair, 1, NULL, 0);
#endif

  /* Set up error / signal traps. */
  setup_signal_traps();

  /* Initialize a few variables before main loop. */
  cache_miss = 0;
  cache_hit  = 0;
  chanset    = NULL;
  now        = time(NULL);

  egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm));
  lastmin = nowtm.tm_min;

  /* Initialize random number generator. */
  srandom((unsigned int) (now % (getpid() + getppid())));

  init_mem();
  init_language(1);

  /* Process command line arguments. */
  process_args(argc, argv);

  printf("\n%s\n", version);

  init_dcc_max();
  init_userent();
  logfile_init(0);
  init_bots();
  init_net();
  init_modules();

  if (backgrd)
    bg_prepare_split();

  init_tcl(argc, argv);
  init_language(0);
  help_init();
  traffic_init();
  logfile_init(1);

#ifdef STATIC
  link_statics();
#endif

  strncpyz(s, ctime(&now), sizeof s);
  strcpy(&s[11], &s[20]);
  putlog(LOG_ALL, "*", "--- Loading %s (%s)", ver, s);

  /* Read configuration data. */
  readconfig();

  /* Check for encryption module. */
  if (!encrypt_pass) {
    printf(MOD_NOCRYPT);
    bg_send_quit(BG_ABORT);
    exit(1);
  }

  putlog(LOG_MISC, "*", "=== %s: %d channels, %d users.", botnetnick,
         count_channels(), count_users(userlist));

  if (!pid_file[0])
    egg_snprintf(pid_file, sizeof pid_file, "pid.%s", botnetnick);

  /* Check for pre-existing eggdrop! */
  f = fopen(pid_file, "r");
  if (f != NULL) {
    fgets(s, 10, f);
    xx = atoi(s);
    kill(xx, SIGCHLD); /* Meaningless kill to determine if PID is used. */
    if (errno != ESRCH) {
      printf(EGG_RUNNING1, botnetnick);
      printf(EGG_RUNNING2, pid_file);
      bg_send_quit(BG_ABORT);
      exit(1);
    }
  }

  /* Move into background? */
  if (backgrd) {
#ifndef CYGWIN_HACKS
    bg_do_split();
  }
  else {
#endif
    xx = getpid();
    if (xx != 0) {
      FILE *fp;

      /* Write PID to file. */
      unlink(pid_file);
      fp = fopen(pid_file, "w");
      if (fp != NULL) {
        fprintf(fp, "%u\n", xx);
        if (fflush(fp)) {
          /* Let the bot live since this doesn't appear to be a botchk. */
          printf("Cannot not write to '%s' (PID file).\n", pid_file);
          fclose(fp);
          unlink(pid_file);
        }
        else
          fclose(fp);
      }
      else
        printf("Cannot not write to '%s' (PID file).\n", pid_file);
#ifdef CYGWIN_HACKS
      printf("Launched into the background (PID: %d)\n\n", xx);
#endif
    }
  }

  use_stderr = 0;               /* Stop writing to stderr now */
  if (backgrd) {
    /* Ok, try to disassociate from controlling terminal (finger cross) */
#if defined(HAVE_SETPGID) && !defined(CYGWIN_HACKS)
    setpgid(0, 0);
#endif

    /* Tcl wants the stdin, stdout and stderr file handles kept open. */
    freopen("/dev/null", "r", stdin);
    freopen("/dev/null", "w", stdout);
    freopen("/dev/null", "w", stderr);

#ifdef CYGWIN_HACKS
    FreeConsole();
#endif
  }

  /* Terminal emulating dcc chat */
  if (!backgrd && term_z) {
    int n = new_dcc(&DCC_CHAT, sizeof(struct chat_info));

    dcc[n].addr = iptolong(getmyip());
    dcc[n].sock = STDOUT;
    dcc[n].timeval = now;
    dcc[n].u.chat->con_flags = conmask;
    dcc[n].u.chat->strip_flags = STRIP_ALL;
    dcc[n].status = STAT_ECHO;
    strcpy(dcc[n].nick, "HQ");
    strcpy(dcc[n].host, "llama@console");
    /* HACK: Workaround not to pass literal "HQ" as a non-const arg */
    dcc[n].user = get_user_by_handle(userlist, dcc[n].nick);
    /* Make sure there's an innocuous HQ user if needed */
    if (!dcc[n].user) {
      userlist = adduser(userlist, dcc[n].nick, "none", "-", USER_PARTY);
      dcc[n].user = get_user_by_handle(userlist, dcc[n].nick);
    }
    setsock(STDOUT, 0); /* Entry in net table */
    dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n");
    dcc_chatter(n);
  }

  then = now;
  online_since = now;
  autolink_cycle(NULL); /* Hurry and connect to tandem bots. */
  add_help_reference("cmds1.help");
  add_help_reference("cmds2.help");
  add_help_reference("core.help");

  /* Create hooks. */
  add_hook(HOOK_SECONDLY, (Function) core_secondly);
  add_hook(HOOK_MINUTELY, (Function) core_minutely);
  add_hook(HOOK_HOURLY, (Function) core_hourly);
  add_hook(HOOK_REHASH, (Function) event_rehash);
  add_hook(HOOK_PRE_REHASH, (Function) event_prerehash);
  add_hook(HOOK_USERFILE, (Function) event_save);
  add_hook(HOOK_BACKUP, (Function) backupuserfile);
  add_hook(HOOK_DAILY, (Function) event_logfile);
  add_hook(HOOK_DAILY, (Function) traffic_reset);
  add_hook(HOOK_LOADED, (Function) event_loaded);

  call_hook(HOOK_LOADED);

  debug0("main: entering loop");
  while (1) {
    int socket_cleanup = 0;

#ifdef USE_TCL_EVENTS
    /* Process a single Tcl event. */
    Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
#endif

    now = time(NULL);
    random();

    /* Every second... */
    if (now != then) {
      call_hook(HOOK_SECONDLY);
      then = now;
    }

    /* Only do this every so often. */
    if (!socket_cleanup) {
      socket_cleanup = 5;

      /* Remove dead dcc entries. */
      dcc_remove_lost();

      /* Check for server or dcc activity. */
      dequeue_sockets();
    }
    else {
      socket_cleanup--;
    }

    /* Free unused structures. */
    garbage_collect();

    xx = sockgets(buf, &i);
    if (xx >= 0) { /* Non-error */
      int idx;

      for (idx = 0; idx < dcc_total; idx++) {
        if (dcc[idx].sock != xx)
          continue;

        if (dcc[idx].type && dcc[idx].type->activity) {
          traffic_update_in(dcc[idx].type, (strlen(buf) + 1)); /* Traffic stats. */
          dcc[idx].type->activity(idx, buf, i);
        }
        else {
          putlog(LOG_MISC, "*", "!!! untrapped dcc activity: type %s, sock %d",
                 dcc[idx].type->name, dcc[idx].sock);
        }

        break;
      }
    }
    else if (xx == -1) { /* EOF */
      int idx;

      if (i == STDOUT && !backgrd)
        fatal("END OF FILE ON TERMINAL", 0);

      for (idx = 0; idx < dcc_total; idx++) {
        if (dcc[idx].sock != i)
          continue;

        if (dcc[idx].type && dcc[idx].type->eof) {
          dcc[idx].type->eof(idx);
        }
        else {
          putlog(LOG_MISC, "*",
                 "*** ATTENTION: DEAD SOCKET (%d) OF TYPE %s UNTRAPPED",
                 i, dcc[idx].type ? dcc[idx].type->name : "*UNKNOWN*");
          killsock(i);
          lostdcc(idx);
        }

        idx = dcc_total + 1;
      }

      if (idx == dcc_total) {
        putlog(LOG_MISC, "*",
               "(@) EOF socket %d, not a dcc socket, not anything.", i);
        close(i);
        killsock(i);
      }
    }
    else if (xx == -2 && errno != EINTR) { /* select() error */
      putlog(LOG_MISC, "*", "* Socket error #%d; recovering.", errno);
      for (i = 0; i < dcc_total; i++) {
        if ((fcntl(dcc[i].sock, F_GETFD, 0) == -1) && (errno == EBADF)) {
          putlog(LOG_MISC, "*",
                 "DCC socket %d (type %d, name '%s') expired -- pfft",
                 dcc[i].sock, dcc[i].type, dcc[i].nick);
          killsock(dcc[i].sock);
          lostdcc(i);
          i--;
        }
      }
    }
    else if (xx == -3) {
      call_hook(HOOK_IDLE);
      socket_cleanup = 0;       /* If we've been idle, cleanup & flush */
    }

    if (do_restart) {
      if (do_restart == -2) {
        rehash();
      }
      else {
        int f = 1;
        module_entry *p;
        Function startfunc;
        char name[256];


        check_tcl_event("prerestart");

        /* Unload as many modules as possible */
        while (f) {
          f = 0;

          for (p = module_list; p != NULL; p = p->next) {
            dependancy *d = dependancy_list;
            int ok = 1;

            while (ok && d) {
              if (d->needed == p)
                ok = 0;

              d = d->next;
            }
            if (ok) {
              strcpy(name, p->name);

              if (module_unload(name, botnetnick) == NULL) {
                f = 1;
                break;
              }
            }
          }
        }

        /* Make sure we don't have any modules left hanging around other than
         * "eggdrop" and the two that are supposed to be.
         */
        for (f = 0, p = module_list; p; p = p->next) {
          if (strcmp(p->name, "eggdrop") && strcmp(p->name, "encryption") &&
              strcmp(p->name, "uptime")) {
            f++;
          }
        }
        if (f != 0) {
          putlog(LOG_MISC, "*", MOD_STAGNANT);
        }

        /* Flush log files to disk. */
        flushlogs();

        /* Clean up Tcl stuff. */
        kill_tcl();

        /* Initialize stuff again. */
        init_tcl(argc, argv);
        init_language(0);
        help_init();
        traffic_init();
        logfile_init(1);

        /* This resets our modules which we didn't unload (encryption and uptime). */
        for (p = module_list; p; p = p->next) {
          if (p->funcs) {
            startfunc = p->funcs[MODCALL_START];
            startfunc(NULL);
          }
        }

        rehash();
        restart_chons();
        call_hook(HOOK_LOADED);
      }

      do_restart = 0;
    }
  }
}