struct oh_handler *new_handler(GHashTable *handler_config) { struct oh_plugin_config *p_config; struct oh_handler *handler; handler = malloc(sizeof(*handler)); if (!handler) { dbg("Out of Memory!"); goto err; } memset(handler, '\0', sizeof(*handler)); if(plugin_refcount((char *)g_hash_table_lookup(handler_config, "plugin")) < 1) { dbg("Attempt to create handler for unknown plugin %s", (char *)g_hash_table_lookup(handler_config, "plugin")); goto err; } p_config = plugin_config((char *)g_hash_table_lookup(handler_config, "plugin")); if(p_config == NULL) { dbg("No such plugin config"); goto err; } handler->abi = p_config->abi; handler->config = handler_config; /* this should be done elsewhere. if 0 it for now to make it easier to migrate */ handler->hnd = handler->abi->open(handler->config); if (!handler->hnd) { dbg("The plugin can not work"); goto err; } return handler; err: free(handler); return NULL; }
int main (int argc, char *argv[]) { int c; int option_index; int help = 0, version = 0; tls_init (); for (;;) { c = getopt_long (argc, argv, short_options, long_options, &option_index); if (c == -1) break; switch (c) { case 0: /* options which are long only */ if (strcmp (long_options[option_index].name, "dump-config") == 0) { dump_config (); exit (EXIT_SUCCESS); } else if (strcmp (long_options[option_index].name, "run") == 0) { run = optarg; foreground = 1; } else { fprintf (stderr, "%s: unknown long option: %s (%d)\n", program_name, long_options[option_index].name, option_index); exit (EXIT_FAILURE); } break; case 'f': foreground = 1; break; case 'g': group = optarg; break; case 'i': ipaddr = optarg; break; case 'n': newstyle = 1; break; case 'o': /* XXX When we add support for exportnames, we will need to * ensure that the user does not use -o + --export. */ newstyle = 0; break; case 'P': pidfile = nbdkit_absolute_path (optarg); if (pidfile == NULL) exit (EXIT_FAILURE); break; case 'p': port = optarg; break; case 'r': readonly = 1; break; case 's': listen_stdin = 1; break; case 'U': if (strcmp (optarg, "-") == 0) unixsocket = make_random_fifo (); else unixsocket = nbdkit_absolute_path (optarg); if (unixsocket == NULL) exit (EXIT_FAILURE); break; case 'u': user = optarg; break; case 'v': verbose = 1; break; case 'V': version = 1; break; case HELP_OPTION: help = 1; break; default: usage (); exit (EXIT_FAILURE); } } /* No extra parameters. */ if (optind >= argc) { if (help) { usage (); exit (EXIT_SUCCESS); } if (version) { display_version (); exit (EXIT_SUCCESS); } /* Otherwise this is an error. */ fprintf (stderr, "%s: no plugins given on the command line.\nRead nbdkit(1) for documentation.\n", program_name); exit (EXIT_FAILURE); } /* Remaining command line arguments define the plugins and plugin * configuration. If --help or --version was specified, we still * partially parse these in order that we can display the per-plugin * help/version information. In future (when the new protocol and * export names are permitted) we will allow multiple plugins to be * given, but at the moment only one plugin is allowed. */ while (optind < argc) { const char *filename = argv[optind]; char *p; open_plugin_so (filename); /* Find key=value configuration parameters for this plugin. */ ++optind; while (optind < argc && (p = strchr (argv[optind], '=')) != NULL) { if (help || version) continue; *p = '\0'; plugin_config (argv[optind], p+1); ++optind; } if (help) { usage (); printf ("\n%s:\n\n", filename); plugin_usage (); exit (EXIT_SUCCESS); } if (version) { display_version (); plugin_version (); exit (EXIT_SUCCESS); } plugin_config_complete (); /* If we supported export names, then we'd continue in the loop * here, but at the moment only one plugin may be used per server * so exit if there are any more. */ ++optind; if (optind < argc) { fprintf (stderr, "%s: this server only supports a single plugin\n", program_name); exit (EXIT_FAILURE); } } start_serving (); plugin_cleanup (); free (unixsocket); free (pidfile); if (random_fifo) { unlink (random_fifo); free (random_fifo); } if (random_fifo_dir) { rmdir (random_fifo_dir); free (random_fifo_dir); } exit (EXIT_SUCCESS); }
int config_plugin(char *plugin_name) { int (*plugin_config)(); void (*plugin_init)(); void (*plugin_unload)(); Plugin *last_plugin, *new_plugin; /* allocate memory for new plugin and attach it to the plugin list */ if ((new_plugin = (Plugin *) malloc(sizeof(Plugin))) == NULL) { fprintf(stderr, " Error - Unable to allocate memory: %m.\n"); return(-1); } else { new_plugin->handle = NULL; new_plugin->name = NULL; new_plugin->version = NULL; new_plugin->next = NULL; new_plugin->filename = NULL; } if (plugin_name == NULL) { fprintf(stderr, " Error loading plugin - No name given.\n"); return(-1); } else { if ((new_plugin->handle = (void *) malloc(sizeof(int))) == NULL) { fprintf(stderr, " Error loading plugin - Unable to allocate memory: %m.\n"); free(new_plugin); return(-1); } else new_plugin->filename = (char *) strdup(plugin_name); } dlerror(); /* Clear any existing error */ if (((new_plugin->handle = dlopen(new_plugin->filename, RTLD_NOW)) == NULL) && ((plugin_error_str = (char *) dlerror()) != NULL)) { fprintf(stderr, " Unable to initialize plugin: %s\n", plugin_error_str); unload_on_err(new_plugin); exit(EXIT_FAILURE); } /* determin internal module name and version string */ if (((new_plugin->name = (char *) dlsym(new_plugin->handle, "module_name")) == NULL) && ((plugin_error_str = (char *) dlerror()) != NULL)) { /* handle error, the symbol wasn't found */ fprintf(stderr, " Unable to initialize plugin: %s\n", plugin_error_str); fprintf(stderr, " %s seems not to be a honeytrap plugin.\n", new_plugin->filename); unload_on_err(new_plugin); return(-1); } if (((new_plugin->version = (char *) dlsym(new_plugin->handle, "module_version")) == NULL) && ((plugin_error_str = (char *) dlerror()) != NULL)) { /* handle error, the symbol wasn't found */ fprintf(stderr, " Unable to initialize plugin %s: %s\n", new_plugin->name, plugin_error_str); fprintf(stderr, " %s seems not to be a honeytrap plugin.\n", new_plugin->filename); unload_on_err(new_plugin); return(-1); } fprintf(stdout, " Loading plugin %s v%s\n", new_plugin->name, new_plugin->version); DEBUG_FPRINTF(stdout, " Configuring plugin %s.\n", new_plugin->name); /* resolve module's unload function and add it to unload hook */ if (((plugin_unload = dlsym(new_plugin->handle, "plugin_unload")) == NULL) && ((plugin_error_str = (char *) dlerror()) != NULL)) { /* handle error, the symbol wasn't found */ fprintf(stderr, " Unable to initialize plugin %s: %s\n", new_plugin->name, plugin_error_str); fprintf(stderr, " %s seems not to be a honeytrap plugin.\n", new_plugin->filename); unload_on_err(new_plugin); return(-1); } if (!add_unload_func_to_list(new_plugin->name, "plugin_unload", plugin_unload)) { fprintf(stderr, " Unable to register module for hook 'unload_plugins': %s\n", plugin_error_str); unload_on_err(new_plugin); return(-1); } /* resolve and call module's config function */ if (((plugin_config = dlsym(new_plugin->handle, "plugin_config")) == NULL) && ((plugin_error_str = (char *) dlerror()) != NULL)) { /* handle error, the symbol wasn't found */ fprintf(stderr, "\n Unable to resolve symbol 'plugin_config': %s\n", plugin_error_str); return(-1); } plugin_config(); // resolve module's init function and add it to init hook if (((plugin_init = dlsym(new_plugin->handle, "plugin_init")) == NULL) && ((plugin_error_str = (char *) dlerror()) != NULL)) { /* handle error, the symbol wasn't found */ fprintf(stderr, " Unable to initialize plugin %s: %s\n", new_plugin->name, plugin_error_str); fprintf(stderr, " %s seems not to be a honeytrap plugin.\n", new_plugin->filename); unload_on_err(new_plugin); return(-1); } if (!add_init_func_to_list(new_plugin->name, "plugin_init", plugin_init)) { fprintf(stderr, " Unable to register module for hook 'init_plugins': %s\n", plugin_error_str); unload_on_err(new_plugin); return(-1); } /* attach plugin to plugin_list */ if (!plugin_list) plugin_list = new_plugin; else { last_plugin = plugin_list; while(last_plugin->next) last_plugin = last_plugin->next; last_plugin->next = new_plugin; } return(1); }