static int dso_unload_module(module *m) { int res; char *name; /* Some modules cannot be unloaded. */ if (strcmp(m->name, "dso") == 0) { errno = EPERM; return -1; } name = pstrdup(dso_pool, m->name); pr_trace_msg(trace_channel, 5, "unloading module 'mod_%s.c'", name); res = pr_module_unload(m); if (res < 0) { pr_log_debug(DEBUG1, MOD_DSO_VERSION ": error unloading module 'mod_%s.c': %s", m->name, strerror(errno)); pr_trace_msg(trace_channel, 1, "error unloading module 'mod_%s.c': %s", m->name, strerror(errno)); } if (lt_dlclose(m->handle) < 0) { pr_log_debug(DEBUG1, MOD_DSO_VERSION ": error closing '%s': %s", name, lt_dlerror()); return -1; } pr_trace_msg(trace_channel, 8, "module 'mod_%s.c' successfully unloaded", name); return 0; }
END_TEST START_TEST (module_load_cmdtab_test) { int res; module m; cmdtable cmdtab[] = { { CMD, C_RETR, G_READ, NULL, TRUE, FALSE, CL_READ }, { HOOK, "foo", G_READ, NULL, FALSE, FALSE }, { 0, NULL } }; res = pr_module_load_cmdtab(NULL); fail_unless(res < 0, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL, strerror(errno), errno); memset(&m, 0, sizeof(m)); res = pr_module_load_cmdtab(&m); fail_unless(res < 0, "Failed to handle null module name"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL, strerror(errno), errno); m.name = "testsuite"; res = pr_module_load_cmdtab(&m); fail_unless(res == 0, "Failed to load module cmdtab: %s", strerror(errno)); pr_module_unload(&m); fail_unless(res == 0, "Failed to unload module: %s", strerror(errno)); m.name = "testsuite"; m.cmdtable = cmdtab; res = pr_module_load_cmdtab(&m); fail_unless(res == 0, "Failed to load module cmdtab: %s", strerror(errno)); pr_module_unload(&m); fail_unless(res == 0, "Failed to unload module: %s", strerror(errno)); }
END_TEST START_TEST (module_unload_test) { int res; module m; authtable authtab[] = { { 0, "setpwent", NULL }, { 0, NULL, NULL } }; cmdtable cmdtab[] = { { CMD, C_RETR, G_READ, NULL, TRUE, FALSE, CL_READ }, { HOOK, "foo", G_READ, NULL, FALSE, FALSE }, { 0, NULL } }; conftable conftab[] = { { "TestSuite", NULL, NULL }, { NULL } }; res = pr_module_unload(NULL); fail_unless(res < 0, "Failed to handle null argument"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL, strerror(errno), errno); memset(&m, 0, sizeof(m)); res = pr_module_unload(&m); fail_unless(res < 0, "Failed to handle null module name"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL, strerror(errno), errno); m.name = "bar"; res = pr_module_unload(&m); fail_unless(res < 0, "Failed to handle nonexistent module"); fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT, strerror(errno), errno); loaded_modules = &m; res = pr_module_unload(&m); fail_unless(res == 0, "Failed to unload module: %s", strerror(errno)); res = pr_module_unload(&m); fail_unless(res < 0, "Failed to handle nonexistent module"); fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT, strerror(errno), errno); m.authtable = authtab; m.cmdtable = cmdtab; m.conftable = conftab; loaded_modules = &m; res = pr_module_unload(&m); fail_unless(res == 0, "Failed to unload module: %s", strerror(errno)); loaded_modules = NULL; }
END_TEST START_TEST (module_load_conftab_test) { int res; module m; conftable conftab[] = { { "TestSuite", NULL, NULL }, { NULL } }; res = pr_module_load_conftab(NULL); fail_unless(res < 0, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL, strerror(errno), errno); memset(&m, 0, sizeof(m)); res = pr_module_load_conftab(&m); fail_unless(res < 0, "Failed to handle null module name"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL, strerror(errno), errno); m.name = "testsuite"; res = pr_module_load_conftab(&m); fail_unless(res == 0, "Failed to load module conftab: %s", strerror(errno)); pr_module_unload(&m); fail_unless(res == 0, "Failed to unload module: %s", strerror(errno)); m.conftable = conftab; res = pr_module_load_conftab(&m); fail_unless(res == 0, "Failed to load module conftab: %s", strerror(errno)); pr_module_unload(&m); fail_unless(res == 0, "Failed to unload module: %s", strerror(errno)); }
/* usage: ModuleOrder mod1 mod2 ... modN */ MODRET set_moduleorder(cmd_rec *cmd) { register unsigned int i; module *m, *mn, *module_list = NULL; if (cmd->argc-1 < 1) CONF_ERROR(cmd, "wrong number of parameters"); CHECK_CONF(cmd, CONF_ROOT); /* What about duplicate names in the list? * * What if the given list is longer than the one already in loaded_modules? * This will be caught by the existence check. Otherwise, the only way for * the list to be longer is if there are duplicates, which will be caught * by the duplicate check. */ /* Make sure the given module names exist. */ for (i = 1; i < cmd->argc; i++) { if (pr_module_get(cmd->argv[i]) == NULL) CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "no such module '", cmd->argv[i], "' loaded", NULL)); } /* Make sure there are no duplicate module names in the list. */ for (i = 1; i < cmd->argc; i++) { register unsigned int j; for (j = i + 1; j < cmd->argc; j++) { if (strcmp(cmd->argv[i], cmd->argv[j]) == 0) { char ibuf[4], jbuf[4]; snprintf(ibuf, sizeof(ibuf), "%u", i); ibuf[sizeof(ibuf)-1] = '\0'; snprintf(jbuf, sizeof(jbuf), "%u", j); jbuf[sizeof(jbuf)-1] = '\0'; CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "duplicate module name '", cmd->argv[i], "' as parameters ", ibuf, " and ", jbuf, NULL)); } } } pr_log_debug(DEBUG4, "%s: reordering modules", cmd->argv[0]); for (i = 1; i < cmd->argc; i++) { m = pr_module_get(cmd->argv[i]); if (module_list) { m->next = module_list; module_list->prev = m; module_list = m; } else module_list = m; } /* Now, unload all the modules in the loaded_modules list, then load * the modules in our module_list. */ for (m = loaded_modules; m;) { mn = m->next; if (pr_module_unload(m) < 0) { pr_log_debug(DEBUG0, "%s: error unloading module 'mod_%s.c': %s", cmd->argv[0], m->name, strerror(errno)); } m = mn; } for (m = module_list; m; m = m->next) { if (pr_module_load(m) < 0) { pr_log_debug(DEBUG0, "%s: error loading module 'mod_%s.c': %s", cmd->argv[0], m->name, strerror(errno)); exit(1); } } pr_log_pri(PR_LOG_NOTICE, "module order is now:"); for (m = loaded_modules; m; m = m->next) { pr_log_pri(PR_LOG_NOTICE, " mod_%s.c", m->name); } return PR_HANDLED(cmd); }