void plugins_init(const char *path) { char *plugins_path; lt_dladvise advise; if (path && !strcmp(path, "none")) { return; } if (!(plugins_path = path ? xstrdup(path) : xstrdup(ovs_pluginsdir()))) { VLOG_ERR("Failed to allocate plugins path"); return; } if (lt_dlinit() || lt_dlsetsearchpath(plugins_path) || lt_dladvise_init(&advise)) { VLOG_ERR("ltdl initializations: %s", lt_dlerror()); goto err_init; } if (!(interface_id = lt_dlinterface_register("ovs-plugin", NULL))) { VLOG_ERR("lt_dlinterface_register: %s", lt_dlerror()); goto err_interface_register; } if (lt_dladvise_global(&advise) || lt_dladvise_ext (&advise) || lt_dlforeachfile(lt_dlgetsearchpath(), &plugins_open_plugin, &advise)) { VLOG_ERR("ltdl setting advise: %s", lt_dlerror()); goto err_set_advise; } VLOG_INFO("Successfully initialized all plugins"); return; err_set_advise: lt_dlinterface_free(interface_id); err_interface_register: if (lt_dladvise_destroy(&advise)) { VLOG_ERR("destroying ltdl advise%s", lt_dlerror()); return; } err_init: free(plugins_path); }
/* * Load all available modules. Return nonzero on failure. */ int stp_module_load(void) { /* initialise libltdl */ #ifdef USE_LTDL static int ltdl_is_initialised = 0; /* Is libltdl initialised? */ #endif static int module_list_is_initialised = 0; /* Is the module list initialised? */ #if defined(USE_LTDL) || defined(USE_DLOPEN) stp_list_t *dir_list; /* List of directories to scan */ stp_list_t *file_list; /* List of modules to open */ stp_list_item_t *file; /* Pointer to current module */ #endif #ifdef USE_LTDL if (!ltdl_is_initialised) { if (lt_dlinit()) { stp_erprintf("Error initialising libltdl: %s\n", DLERROR()); return 1; } ltdl_is_initialised = 1; } /* set default search paths */ lt_dladdsearchdir(PKGMODULEDIR); #endif /* initialise module_list */ if (!module_list_is_initialised) { if (!(module_list = stp_list_create())) return 1; stp_list_set_freefunc(module_list, module_list_freefunc); module_list_is_initialised = 1; } /* search for available modules */ #if defined (USE_LTDL) || defined (USE_DLOPEN) if (!(dir_list = stp_list_create())) return 1; stp_list_set_freefunc(dir_list, stp_list_node_free_data); if (getenv("STP_MODULE_PATH")) { stp_path_split(dir_list, getenv("STP_MODULE_PATH")); } else { #ifdef USE_LTDL stp_path_split(dir_list, getenv("LTDL_LIBRARY_PATH")); stp_path_split(dir_list, lt_dlgetsearchpath()); #else stp_path_split(dir_list, PKGMODULEDIR); #endif } #ifdef USE_LTDL file_list = stp_path_search(dir_list, ".la"); #else file_list = stp_path_search(dir_list, ".so"); #endif stp_list_destroy(dir_list); /* load modules */ file = stp_list_get_start(file_list); while (file) { stp_module_open((const char *) stp_list_item_get_data(file)); file = stp_list_item_next(file); } stp_list_destroy(file_list); #else /* use a static module list */ { int i=0; while (static_modules[i]) { stp_module_register(static_modules[i]); i++; } } #endif return 0; }
/* * Parse the module config sections, and load * and call each module's init() function. * * Libtool makes your life a LOT easier, especially with libltdl. * see: http://www.gnu.org/software/libtool/ */ int setup_modules(void) { int comp; CONF_SECTION *cs; /* * FIXME: This should be pulled from somewhere else. */ const char *filename="radiusd.conf"; /* * No current list of modules: Go initialize libltdl. */ if (!module_list) { /* * Set the default list of preloaded symbols. * This is used to initialize libltdl's list of * preloaded modules. * * i.e. Static modules. */ LTDL_SET_PRELOADED_SYMBOLS(); if (lt_dlinit() != 0) { radlog(L_ERR|L_CONS, "Failed to initialize libraries: %s\n", lt_dlerror()); exit(1); /* FIXME */ } /* * Set the search path to ONLY our library directory. * This prevents the modules from being found from * any location on the disk. */ lt_dlsetsearchpath(radlib_dir); DEBUG2("Module: Library search path is %s", lt_dlgetsearchpath()); /* * Initialize the components. */ for (comp = 0; comp < RLM_COMPONENT_COUNT; comp++) { components[comp] = NULL; } } else { detach_modules(); } /* * Create any DICT_VALUE's for the types. See * 'doc/configurable_failover' for examples of 'authtype' * used to create new Auth-Type values. In order to * let the user create new names, we've got to look for * those names, and create DICT_VALUE's for them. */ for (comp = 0; section_type_value[comp].section != NULL; comp++) { const char *name2; DICT_ATTR *dattr; DICT_VALUE *dval; CONF_SECTION *sub, *next; CONF_PAIR *cp; /* * Big-time YUCK */ static int my_value = 32767; cs = cf_section_find(section_type_value[comp].section); if (!cs) continue; sub = NULL; do { /* * See if there's a sub-section by that * name. */ next = cf_subsection_find_next(cs, sub, section_type_value[comp].typename); /* * Allow some old names, too. */ if (!next && (comp <= 4)) { next = cf_subsection_find_next(cs, sub, old_section_type_value[comp].typename); } sub = next; /* * If so, look for it to define a new * value. */ name2 = cf_section_name2(sub); if (!name2) continue; /* * If the value already exists, don't * create it again. */ dval = dict_valbyname(section_type_value[comp].attr, name2); if (dval) continue; /* * Find the attribute for the value. */ dattr = dict_attrbyvalue(section_type_value[comp].attr); if (!dattr) continue; /* * Finally, create the new attribute. */ if (dict_addvalue(name2, dattr->name, my_value++) < 0) { radlog(L_ERR, "%s", librad_errstr); exit(1); } } while (sub != NULL); /* * Loop over the non-sub-sections, too. */ cp = NULL; do { /* * See if there's a conf-pair by that * name. */ cp = cf_pair_find_next(cs, cp, NULL); if (!cp) break; /* * If the value already exists, don't * create it again. */ name2 = cf_pair_attr(cp); dval = dict_valbyname(section_type_value[comp].attr, name2); if (dval) continue; /* * Find the attribute for the value. */ dattr = dict_attrbyvalue(section_type_value[comp].attr); if (!dattr) continue; /* * Finally, create the new attribute. */ if (dict_addvalue(name2, dattr->name, my_value++) < 0) { radlog(L_ERR, "%s", librad_errstr); exit(1); } } while (cp != NULL); } /* over the sections which can have redundent sub-sections */
int pa__init(pa_module*m) { struct userdata *u; pa_sample_spec ss; pa_channel_map map; pa_modargs *ma; char *t; pa_sink *master; pa_sink_input_new_data sink_input_data; pa_sink_new_data sink_data; const char *plugin, *label, *input_ladspaport_map, *output_ladspaport_map; LADSPA_Descriptor_Function descriptor_func; unsigned long input_ladspaport[PA_CHANNELS_MAX], output_ladspaport[PA_CHANNELS_MAX]; const char *e, *cdata; const LADSPA_Descriptor *d; unsigned long p, h, j, n_control, c; pa_bool_t *use_default = NULL; pa_assert(m); pa_assert_cc(sizeof(LADSPA_Data) == sizeof(float)); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments."); goto fail; } if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SINK))) { pa_log("Master sink not found"); goto fail; } ss = master->sample_spec; ss.format = PA_SAMPLE_FLOAT32; map = master->channel_map; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { pa_log("Invalid sample format specification or channel map"); goto fail; } if (!(plugin = pa_modargs_get_value(ma, "plugin", NULL))) { pa_log("Missing LADSPA plugin name"); goto fail; } if (!(label = pa_modargs_get_value(ma, "label", NULL))) { pa_log("Missing LADSPA plugin label"); goto fail; } if (!(input_ladspaport_map = pa_modargs_get_value(ma, "input_ladspaport_map", NULL))) pa_log_debug("Using default input ladspa port mapping"); if (!(output_ladspaport_map = pa_modargs_get_value(ma, "output_ladspaport_map", NULL))) pa_log_debug("Using default output ladspa port mapping"); cdata = pa_modargs_get_value(ma, "control", NULL); u = pa_xnew0(struct userdata, 1); u->module = m; m->userdata = u; u->memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL); u->max_ladspaport_count = 1; /*to avoid division by zero etc. in pa__done when failing before this value has been set*/ u->channels = 0; u->input = NULL; u->output = NULL; if (!(e = getenv("LADSPA_PATH"))) e = LADSPA_PATH; /* FIXME: This is not exactly thread safe */ t = pa_xstrdup(lt_dlgetsearchpath()); lt_dlsetsearchpath(e); m->dl = lt_dlopenext(plugin); lt_dlsetsearchpath(t); pa_xfree(t); if (!m->dl) { pa_log("Failed to load LADSPA plugin: %s", lt_dlerror()); goto fail; } if (!(descriptor_func = (LADSPA_Descriptor_Function) pa_load_sym(m->dl, NULL, "ladspa_descriptor"))) { pa_log("LADSPA module lacks ladspa_descriptor() symbol."); goto fail; } for (j = 0;; j++) { if (!(d = descriptor_func(j))) { pa_log("Failed to find plugin label '%s' in plugin '%s'.", label, plugin); goto fail; } if (strcmp(d->Label, label) == 0) break; } u->descriptor = d; pa_log_debug("Module: %s", plugin); pa_log_debug("Label: %s", d->Label); pa_log_debug("Unique ID: %lu", d->UniqueID); pa_log_debug("Name: %s", d->Name); pa_log_debug("Maker: %s", d->Maker); pa_log_debug("Copyright: %s", d->Copyright); n_control = 0; u->channels = ss.channels; /* * Enumerate ladspa ports * Default mapping is in order given by the plugin */ for (p = 0; p < d->PortCount; p++) { if (LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p])) { if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p])) { pa_log_debug("Port %lu is input: %s", p, d->PortNames[p]); input_ladspaport[u->input_count] = p; u->input_count++; } else if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p])) { pa_log_debug("Port %lu is output: %s", p, d->PortNames[p]); output_ladspaport[u->output_count] = p; u->output_count++; } } else if (LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p]) && LADSPA_IS_PORT_INPUT(d->PortDescriptors[p])) { pa_log_debug("Port %lu is control: %s", p, d->PortNames[p]); n_control++; } else pa_log_debug("Ignored port %s", d->PortNames[p]); /* XXX: Has anyone ever seen an in-place plugin with non-equal number of input and output ports? */ /* Could be if the plugin is for up-mixing stereo to 5.1 channels */ /* Or if the plugin is down-mixing 5.1 to two channel stereo or binaural encoded signal */ if (u->input_count > u->max_ladspaport_count) u->max_ladspaport_count = u->input_count; else u->max_ladspaport_count = u->output_count; } if (u->channels % u->max_ladspaport_count) { pa_log("Cannot handle non-integral number of plugins required for given number of channels"); goto fail; } pa_log_debug("Will run %lu plugin instances", u->channels / u->max_ladspaport_count); /* Parse data for input ladspa port map */ if (input_ladspaport_map) { const char *state = NULL; char *pname; c = 0; while ((pname = pa_split(input_ladspaport_map, ",", &state))) { if (c == u->input_count) { pa_log("Too many ports in input ladspa port map"); goto fail; } for (p = 0; p < d->PortCount; p++) { if (strcmp(d->PortNames[p], pname) == 0) { if (LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p]) && LADSPA_IS_PORT_INPUT(d->PortDescriptors[p])) { input_ladspaport[c] = p; } else { pa_log("Port %s is not an audio input ladspa port", pname); pa_xfree(pname); goto fail; } } } c++; pa_xfree(pname); } } /* Parse data for output port map */ if (output_ladspaport_map) { const char *state = NULL; char *pname; c = 0; while ((pname = pa_split(output_ladspaport_map, ",", &state))) { if (c == u->output_count) { pa_log("Too many ports in output ladspa port map"); goto fail; } for (p = 0; p < d->PortCount; p++) { if (strcmp(d->PortNames[p], pname) == 0) { if (LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p]) && LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p])) { output_ladspaport[c] = p; } else { pa_log("Port %s is not an output ladspa port", pname); pa_xfree(pname); goto fail; } } } c++; pa_xfree(pname); } } u->block_size = pa_frame_align(pa_mempool_block_size_max(m->core->mempool), &ss); /* Create buffers */ if (LADSPA_IS_INPLACE_BROKEN(d->Properties)) { u->input = (LADSPA_Data**) pa_xnew(LADSPA_Data*, (unsigned) u->input_count); for (c = 0; c < u->input_count; c++) u->input[c] = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size); u->output = (LADSPA_Data**) pa_xnew(LADSPA_Data*, (unsigned) u->output_count); for (c = 0; c < u->output_count; c++) u->output[c] = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size); } else {
int pa__init(pa_module*m) { struct userdata *u; pa_sample_spec ss; pa_channel_map map; pa_modargs *ma; char *t; pa_sink *master; pa_sink_input_new_data sink_input_data; pa_sink_new_data sink_data; const char *plugin, *label; LADSPA_Descriptor_Function descriptor_func; const char *e, *cdata; const LADSPA_Descriptor *d; unsigned long input_port, output_port, p, j, n_control; unsigned c; pa_bool_t *use_default = NULL; pa_assert(m); pa_assert_cc(sizeof(LADSPA_Data) == sizeof(float)); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments."); goto fail; } if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SINK))) { pa_log("Master sink not found"); goto fail; } ss = master->sample_spec; ss.format = PA_SAMPLE_FLOAT32; map = master->channel_map; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { pa_log("Invalid sample format specification or channel map"); goto fail; } if (!(plugin = pa_modargs_get_value(ma, "plugin", NULL))) { pa_log("Missing LADSPA plugin name"); goto fail; } if (!(label = pa_modargs_get_value(ma, "label", NULL))) { pa_log("Missing LADSPA plugin label"); goto fail; } cdata = pa_modargs_get_value(ma, "control", NULL); u = pa_xnew0(struct userdata, 1); u->module = m; m->userdata = u; u->memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL); if (!(e = getenv("LADSPA_PATH"))) e = LADSPA_PATH; /* FIXME: This is not exactly thread safe */ t = pa_xstrdup(lt_dlgetsearchpath()); lt_dlsetsearchpath(e); m->dl = lt_dlopenext(plugin); lt_dlsetsearchpath(t); pa_xfree(t); if (!m->dl) { pa_log("Failed to load LADSPA plugin: %s", lt_dlerror()); goto fail; } if (!(descriptor_func = (LADSPA_Descriptor_Function) pa_load_sym(m->dl, NULL, "ladspa_descriptor"))) { pa_log("LADSPA module lacks ladspa_descriptor() symbol."); goto fail; } for (j = 0;; j++) { if (!(d = descriptor_func(j))) { pa_log("Failed to find plugin label '%s' in plugin '%s'.", label, plugin); goto fail; } if (strcmp(d->Label, label) == 0) break; } u->descriptor = d; pa_log_debug("Module: %s", plugin); pa_log_debug("Label: %s", d->Label); pa_log_debug("Unique ID: %lu", d->UniqueID); pa_log_debug("Name: %s", d->Name); pa_log_debug("Maker: %s", d->Maker); pa_log_debug("Copyright: %s", d->Copyright); input_port = output_port = (unsigned long) -1; n_control = 0; for (p = 0; p < d->PortCount; p++) { if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p])) { if (strcmp(d->PortNames[p], "Input") == 0) { pa_assert(input_port == (unsigned long) -1); input_port = p; } else { pa_log("Found audio input port on plugin we cannot handle: %s", d->PortNames[p]); goto fail; } } else if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p])) { if (strcmp(d->PortNames[p], "Output") == 0) { pa_assert(output_port == (unsigned long) -1); output_port = p; } else { pa_log("Found audio output port on plugin we cannot handle: %s", d->PortNames[p]); goto fail; } } else if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])) n_control++; else { pa_assert(LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])); pa_log_debug("Ignored control output port \"%s\".", d->PortNames[p]); } } if ((input_port == (unsigned long) -1) || (output_port == (unsigned long) -1)) { pa_log("Failed to identify input and output ports. " "Right now this module can only deal with plugins which provide an 'Input' and an 'Output' audio port. " "Patches welcome!"); goto fail; } u->block_size = pa_frame_align(pa_mempool_block_size_max(m->core->mempool), &ss); u->input = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size); if (LADSPA_IS_INPLACE_BROKEN(d->Properties)) u->output = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size); else u->output = u->input; u->channels = ss.channels; for (c = 0; c < ss.channels; c++) { if (!(u->handle[c] = d->instantiate(d, ss.rate))) { pa_log("Failed to instantiate plugin %s with label %s for channel %i", plugin, d->Label, c); goto fail; } d->connect_port(u->handle[c], input_port, u->input); d->connect_port(u->handle[c], output_port, u->output); } if (!cdata && n_control > 0) { pa_log("This plugin requires specification of %lu control parameters.", n_control); goto fail; } if (n_control > 0) { const char *state = NULL; char *k; unsigned long h; u->control = pa_xnew(LADSPA_Data, (unsigned) n_control); use_default = pa_xnew(pa_bool_t, (unsigned) n_control); p = 0; while ((k = pa_split(cdata, ",", &state)) && p < n_control) { double f; if (*k == 0) { use_default[p++] = TRUE; pa_xfree(k); continue; } if (pa_atod(k, &f) < 0) { pa_log("Failed to parse control value '%s'", k); pa_xfree(k); goto fail; } pa_xfree(k); use_default[p] = FALSE; u->control[p++] = (LADSPA_Data) f; } /* The previous loop doesn't take the last control value into account if it is left empty, so we do it here. */ if (*cdata == 0 || cdata[strlen(cdata) - 1] == ',') { if (p < n_control) use_default[p] = TRUE; p++; } if (p > n_control || k) { pa_log("Too many control values passed, %lu expected.", n_control); pa_xfree(k); goto fail; } if (p < n_control) { pa_log("Not enough control values passed, %lu expected, %lu passed.", n_control, p); goto fail; } h = 0; for (p = 0; p < d->PortCount; p++) { LADSPA_PortRangeHintDescriptor hint = d->PortRangeHints[p].HintDescriptor; if (!LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])) continue; if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p])) { for (c = 0; c < ss.channels; c++) d->connect_port(u->handle[c], p, &u->control_out); continue; } pa_assert(h < n_control); if (use_default[h]) { LADSPA_Data lower, upper; if (!LADSPA_IS_HINT_HAS_DEFAULT(hint)) { pa_log("Control port value left empty but plugin defines no default."); goto fail; } lower = d->PortRangeHints[p].LowerBound; upper = d->PortRangeHints[p].UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(hint)) { lower *= (LADSPA_Data) ss.rate; upper *= (LADSPA_Data) ss.rate; } switch (hint & LADSPA_HINT_DEFAULT_MASK) { case LADSPA_HINT_DEFAULT_MINIMUM: u->control[h] = lower; break; case LADSPA_HINT_DEFAULT_MAXIMUM: u->control[h] = upper; break; case LADSPA_HINT_DEFAULT_LOW: if (LADSPA_IS_HINT_LOGARITHMIC(hint)) u->control[h] = (LADSPA_Data) exp(log(lower) * 0.75 + log(upper) * 0.25); else u->control[h] = (LADSPA_Data) (lower * 0.75 + upper * 0.25); break; case LADSPA_HINT_DEFAULT_MIDDLE: if (LADSPA_IS_HINT_LOGARITHMIC(hint)) u->control[h] = (LADSPA_Data) exp(log(lower) * 0.5 + log(upper) * 0.5); else u->control[h] = (LADSPA_Data) (lower * 0.5 + upper * 0.5); break; case LADSPA_HINT_DEFAULT_HIGH: if (LADSPA_IS_HINT_LOGARITHMIC(hint)) u->control[h] = (LADSPA_Data) exp(log(lower) * 0.25 + log(upper) * 0.75); else u->control[h] = (LADSPA_Data) (lower * 0.25 + upper * 0.75); break; case LADSPA_HINT_DEFAULT_0: u->control[h] = 0; break; case LADSPA_HINT_DEFAULT_1: u->control[h] = 1; break; case LADSPA_HINT_DEFAULT_100: u->control[h] = 100; break; case LADSPA_HINT_DEFAULT_440: u->control[h] = 440; break; default: pa_assert_not_reached(); } } if (LADSPA_IS_HINT_INTEGER(hint)) u->control[h] = roundf(u->control[h]); pa_log_debug("Binding %f to port %s", u->control[h], d->PortNames[p]); for (c = 0; c < ss.channels; c++) d->connect_port(u->handle[c], p, &u->control[h]); h++; } pa_assert(h == n_control); } if (d->activate) for (c = 0; c < u->channels; c++) d->activate(u->handle[c]); /* Create sink */ pa_sink_new_data_init(&sink_data); sink_data.driver = __FILE__; sink_data.module = m; if (!(sink_data.name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", NULL)))) sink_data.name = pa_sprintf_malloc("%s.ladspa", master->name); pa_sink_new_data_set_sample_spec(&sink_data, &ss); pa_sink_new_data_set_channel_map(&sink_data, &map); pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name); pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter"); pa_proplist_sets(sink_data.proplist, "device.ladspa.module", plugin); pa_proplist_sets(sink_data.proplist, "device.ladspa.label", d->Label); pa_proplist_sets(sink_data.proplist, "device.ladspa.name", d->Name); pa_proplist_sets(sink_data.proplist, "device.ladspa.maker", d->Maker); pa_proplist_sets(sink_data.proplist, "device.ladspa.copyright", d->Copyright); pa_proplist_setf(sink_data.proplist, "device.ladspa.unique_id", "%lu", (unsigned long) d->UniqueID); if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) { pa_log("Invalid properties"); pa_sink_new_data_done(&sink_data); goto fail; } if ((u->auto_desc = !pa_proplist_contains(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) { const char *z; z = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION); pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "LADSPA Plugin %s on %s", d->Name, z ? z : master->name); } u->sink = pa_sink_new(m->core, &sink_data, PA_SINK_HW_MUTE_CTRL|PA_SINK_HW_VOLUME_CTRL|PA_SINK_DECIBEL_VOLUME| (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY))); pa_sink_new_data_done(&sink_data); if (!u->sink) { pa_log("Failed to create sink."); goto fail; } u->sink->parent.process_msg = sink_process_msg_cb; u->sink->set_state = sink_set_state_cb; u->sink->update_requested_latency = sink_update_requested_latency_cb; u->sink->request_rewind = sink_request_rewind_cb; u->sink->set_volume = sink_set_volume_cb; u->sink->set_mute = sink_set_mute_cb; u->sink->userdata = u; pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq); /* Create sink input */ pa_sink_input_new_data_init(&sink_input_data); sink_input_data.driver = __FILE__; sink_input_data.module = m; sink_input_data.sink = master; pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "LADSPA Stream"); pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss); pa_sink_input_new_data_set_channel_map(&sink_input_data, &map); pa_sink_input_new(&u->sink_input, m->core, &sink_input_data); pa_sink_input_new_data_done(&sink_input_data); if (!u->sink_input) goto fail; u->sink_input->pop = sink_input_pop_cb; u->sink_input->process_rewind = sink_input_process_rewind_cb; u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb; u->sink_input->update_max_request = sink_input_update_max_request_cb; u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb; u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb; u->sink_input->kill = sink_input_kill_cb; u->sink_input->attach = sink_input_attach_cb; u->sink_input->detach = sink_input_detach_cb; u->sink_input->state_change = sink_input_state_change_cb; u->sink_input->may_move_to = sink_input_may_move_to_cb; u->sink_input->moving = sink_input_moving_cb; u->sink_input->volume_changed = sink_input_volume_changed_cb; u->sink_input->mute_changed = sink_input_mute_changed_cb; u->sink_input->userdata = u; pa_sink_put(u->sink); pa_sink_input_put(u->sink_input); pa_modargs_free(ma); pa_xfree(use_default); return 0; fail: if (ma) pa_modargs_free(ma); pa_xfree(use_default); pa__done(m); return -1; }
static globus_result_t globus_l_extension_dlopen( const char * name, lt_dlhandle * handle) { char library[1024]; lt_dlhandle dlhandle; char * path; char * basename; char * search_path = NULL; char * save_path = NULL; globus_result_t result = GLOBUS_SUCCESS; GlobusFuncName(globus_l_extension_dlopen); path = globus_libc_strdup(name); if(path && (basename = strrchr(path, '/'))) { *basename = 0; if(basename == path) { /* ignore root dir */ name = path + 1; } else if(*(basename + 1) == 0) { /* ignore trailing slashes */ name = path; } else { name = basename + 1; if(globus_l_globus_location) { /* if globus_location is not set, then it's likely I won't * find the library */ search_path = globus_common_create_string( "%s/%s", globus_l_globus_location, path); } } } globus_l_libtool_mutex_lock(); if(search_path || globus_l_globus_location) { if((save_path = (char *) lt_dlgetsearchpath())) { /* libtool frees this pointer before setting the next one */ save_path = globus_libc_strdup(save_path); } lt_dlsetsearchpath( search_path ? search_path : globus_l_globus_location); } snprintf(library, 1024, "lib%s", name); library[1023] = 0; dlhandle = lt_dlopenext(library); if(!dlhandle) { /* older libtools dont search the extensions correctly */ snprintf(library, 1024, "lib%s" MY_LIB_EXT, name); library[1023] = 0; dlhandle = lt_dlopenext(library); } #if USE_SYMBOL_LABELS if (!dlhandle) { snprintf(library, 1024, "lib%s_%s", name, (sizeof(long) == 8) ? "gcc64pthr" : "gcc32pthr"); library[1023] = 0; dlhandle = lt_dlopenext(library); if(!dlhandle) { /* older libtools dont search the extensions correctly */ snprintf(library, 1024, "lib%s_%s" MY_LIB_EXT, name, (sizeof(long) == 8) ? "gcc64pthr" : "gcc32pthr"); library[1023] = 0; dlhandle = lt_dlopenext(library); } } #endif if(!dlhandle) { const char * error; error = lt_dlerror(); GlobusExtensionDebugPrintf( GLOBUS_L_EXTENSION_DEBUG_DLL, (_GCSL("[%s] Couldn't dlopen %s in %s (or LD_LIBRARY_PATH): %s\n"), _globus_func_name, library, search_path ? search_path : globus_l_globus_location ? globus_l_globus_location : "(default)", error ? error : "(null)")); result = globus_error_put( globus_error_construct_error( GLOBUS_EXTENSION_MODULE, NULL, GLOBUS_EXTENSION_ERROR_OPEN_FAILED, __FILE__, _globus_func_name, __LINE__, "Couldn't dlopen %s in %s (or LD_LIBRARY_PATH): %s\n", library, (search_path ? search_path : (globus_l_globus_location ? globus_l_globus_location : "(default)")), error ? error : "(null)")); } if(search_path || globus_l_globus_location) { lt_dlsetsearchpath(save_path); if(save_path) { globus_free(save_path); } } globus_l_libtool_mutex_unlock(); if(search_path) { globus_free(search_path); } if(path) { globus_free(path); } *handle = dlhandle; return result; }
/** * initializeScanRules * * this reads in the rules definition file for identifying the playload. * It compiles the regular * expressions and loads in the dynamic libraries as defined for later use * * @param scriptFile a file pointer to the rule definition file * */ gboolean ycInitializeScanRules ( FILE * scriptFile, GError ** err) { /* // for every rule that is "imagined" can be returned on a single call to pcre_exec, you need to multiply that number by 6 for the correct number of "vector" entries (and because of pcre limitation should be a multiple of 3) */ #define NUM_SUBSTRING_VECTS 60 const char *errorString; int errorPos; char eString[ESTRING_SIZE]; pcre *ruleScanner; pcre *pluginScanner; pcre *commentScanner; pcre *pluginArgScanner; pcre *signatureScanner; const char commentScannerExp[] = "^\\s*#[^\\n]*\\n"; const char pluginScannerExp[] = "^[[:space:]]*label[[:space:]]+([[:digit:]]+)" "[[:space:]]+plugin[[:space:]]*([^[:space:]\\n].*)\\n"; const char ruleScannerExp[] = "^[[:space:]]*label[[:space:]]+([[:digit:]]+)" "[[:space:]]+regex[[:space:]]*([^\\n].*)\\n"; const char signatureScannerExp[] = "^[[:space:]]*label[[:space:]]+([[:digit:]]+)" "[[:space:]]+signature[[:space:]]*([^\\n].*)\\n"; const char pluginArgScannerExp[] = "[[:word:]]"; int rc; int substringVects[NUM_SUBSTRING_VECTS]; char lineBuffer[LINE_BUF_SIZE]; int readLength; char *captString; unsigned int bufferOffset = 0; int currentStartPos = 0; int loop; char *ltdl_lib_path = NULL; /* first mark all plugin entries as empty, just in case */ for (loop = 0; loop < MAX_PAYLOAD_RULES; loop++) { ruleTable[loop].ruleType = EMPTY; } /* initialize the hash table */ ycPortHashInitialize(); /* initialize the dynamic loader library */ rc = lt_dlinit(); if (0 != rc) { *err = g_error_new (YAF_ERROR_DOMAIN, YAF_ERROR_IMPL, "error initializing the dynamic loader library: \"%s\"", lt_dlerror ()); return FALSE; } /* if LTDL_LIBRARY_PATH is set - add this one first */ ltdl_lib_path = getenv("LTDL_LIBRARY_PATH"); if (ltdl_lib_path) { lt_dladdsearchdir(ltdl_lib_path); } #ifdef YAF_APPLABEL_PATH /* add the applabel path based on libdir at build time */ lt_dladdsearchdir(YAF_APPLABEL_PATH); #else /* add /usr/local/lib/yaf to path since libtool can never find it */ lt_dladdsearchdir(YAF_SEARCH_PATH); lt_dladdsearchdir(ALT_SEARCH_PATH); lt_dladdsearchdir(ALT_SEARCH_PATH64); #endif /* create the hash table for library modules to library handle names */ if (!hcreate ((MAX_PAYLOAD_RULES * 20) / 100)) { *err = g_error_new (YAF_ERROR_DOMAIN, YAF_ERROR_IMPL, "couldn't create load module hash table (%d)", errno); return FALSE; } /* * take all of the rules needed to parse the rule file and compile * them into a form that // the regular expression engine can deal with */ ruleScanner = pcre_compile(ruleScannerExp, PCRE_MULTILINE, &errorString, &errorPos, NULL); if (NULL == ruleScanner) { ycDisplayScannerRuleError(eString, ESTRING_SIZE, "couldn't build the rule scanner", errorString, ruleScannerExp, errorPos); *err = g_error_new(YAF_ERROR_DOMAIN,YAF_ERROR_INTERNAL, "%s", eString); return FALSE; } pluginScanner = pcre_compile(pluginScannerExp, PCRE_MULTILINE, &errorString, &errorPos, NULL); if (NULL == pluginScanner) { ycDisplayScannerRuleError(eString, ESTRING_SIZE, "couldn't build the plugin scanner", errorString, pluginScannerExp, errorPos); *err = g_error_new(YAF_ERROR_DOMAIN,YAF_ERROR_INTERNAL, "%s", eString); return FALSE; } commentScanner = pcre_compile(commentScannerExp, PCRE_MULTILINE, &errorString, &errorPos, NULL); if (NULL == commentScanner) { ycDisplayScannerRuleError (eString, ESTRING_SIZE, "couldn't build the comment scanner", errorString, commentScannerExp, errorPos); *err = g_error_new(YAF_ERROR_DOMAIN,YAF_ERROR_INTERNAL, "%s", eString); return FALSE; } pluginArgScanner = pcre_compile(pluginArgScannerExp, PCRE_MULTILINE, &errorString, &errorPos, NULL); if (NULL == pluginArgScanner) { ycDisplayScannerRuleError(eString, ESTRING_SIZE, "couldn't build the plugin argument scanner", errorString, pluginArgScannerExp, errorPos); *err = g_error_new(YAF_ERROR_DOMAIN,YAF_ERROR_INTERNAL, "%s", eString); return FALSE; } signatureScanner = pcre_compile(signatureScannerExp, PCRE_MULTILINE, &errorString, &errorPos, NULL); if (NULL == signatureScanner) { ycDisplayScannerRuleError (eString, ESTRING_SIZE, "couldn't build the signature scanner", errorString, signatureScannerExp, errorPos); *err = g_error_new(YAF_ERROR_DOMAIN,YAF_ERROR_INTERNAL, "%s", eString); return FALSE; } /* * this is the loop that does the lion's share of the rule file * processing first read a hunk of the rule file, (this may include * multiple lines of stuff) this gets a little bit ugly, there are a * number of issues that have to handled; first, because there may be * multiple lines (which is in fact likely) it has to be able to work * its way through the buffer, a single pass of the buffer through the * pcre engine simply won't cut it; at the end, it is possible // to have * part of line, when this happens, it needs to copy the leftover part * of the read into the front of the buffer, and then read again to fill in * the rest of line. (this detail limits a single line to * LINE_BUF_SIZE size) */ do { readLength = fread (lineBuffer + bufferOffset, 1, LINE_BUF_SIZE - 1 -bufferOffset, scriptFile); if (0 == readLength) { if (ferror (scriptFile)) { *err = g_error_new(YAF_ERROR_DOMAIN, YAF_ERROR_IO, "couldn't read the rule file: %s", strerror (errno)); return FALSE; } break; } /* fread only returns how much it read from the file - need to add extra we put in the buffer from last read, if any */ readLength += bufferOffset; /* * substringVects is used by the pcre library to indicate where the * matched substrings are in the input string, but [1] points to * the very end of the total match, we use this to iterate through * the readBuffer, always reset it after a read */ substringVects[0] = 0; substringVects[1] = 0; /* parse as much of the input buffer as possible */ while (substringVects[1] < readLength) { #if YFDEBUG_APPLABEL g_debug("readLength %d startPosition %d\n", readLength, substringVects[1]); for (loop=0; loop < 10; loop++) { if (loop+substringVects[1] > readLength) { break; } char curChar = *(lineBuffer + substringVects[1] + loop); if (iscntrl(curChar)) { g_debug("."); continue; } if (isprint(curChar)) { g_debug("%c", curChar); } else { g_debug("."); } } g_debug("\n"); #endif /* get rid of CR's and LF's at the begging, use the simple manual * method, they gum up the regex works */ if ('\n' == *(lineBuffer + substringVects[1]) || '\r' == *(lineBuffer + substringVects[1])) { substringVects[1]++; continue; } /* first check for comments, and eliminate them */ currentStartPos = substringVects[1]; /* need to store the current offset, if we fail to match, we get -1 in [1] */ rc = pcre_exec (commentScanner, NULL, lineBuffer, readLength, substringVects[1], PCRE_ANCHORED, substringVects, NUM_SUBSTRING_VECTS); if (rc > 0) { #if YFDEBUG_APPLABEL g_debug("comment match pos %d to pos %d\n", substringVects[0], substringVects[1]); pcre_get_substring(lineBuffer, substringVects, rc, 0, (const char**)&captString); g_debug("comment line is \"%s\"\n", captString); pcre_free(captString); #endif continue; } substringVects[1] = currentStartPos; /* scan the line to see if it is a regex statement, and get the * arguments if it is */ rc = pcre_exec (ruleScanner, NULL, lineBuffer, readLength, substringVects[1], PCRE_ANCHORED, substringVects, NUM_SUBSTRING_VECTS); if (rc > 0) { pcre *newRule; pcre_extra *newExtra; /* get the first matched field from the regex rule expression * (the label value) */ pcre_get_substring (lineBuffer, substringVects, rc, 1, (const char **) &captString); ruleTable[numPayloadRules].payloadLabelValue = strtoul (captString, NULL, 10); #if YFDEBUG_APPLABEL g_debug("regex: rule # %u, label value %lu ", numPayloadRules, strtoul(captString, NULL, 10)); #endif pcre_free (captString); /* get the second matched field from the regex rule expression * (should be the regex) */ pcre_get_substring(lineBuffer, substringVects, rc, 2, (const char **) &captString); #if YF_DEBUG_APPLABEL g_debug(" regex \"%s\"\n", captString); #endif newRule = pcre_compile(captString, 0, &errorString, &errorPos, NULL); if (NULL == newRule) { ycDisplayScannerRuleError(eString, ESTRING_SIZE, "error in regex application labeler rule", errorString, captString, errorPos); } else { newExtra = pcre_study (newRule, 0, &errorString); ruleTable[numPayloadRules].ruleArgs.regexFields. scannerExpression = newRule; ruleTable[numPayloadRules].ruleArgs.regexFields. scannerExtra = newExtra; ruleTable[numPayloadRules].ruleType = REGEX; ycPortHashInsert(ruleTable[numPayloadRules].payloadLabelValue, numPayloadRules); numPayloadRules++; } pcre_free (captString); if (MAX_PAYLOAD_RULES == numPayloadRules) { *err = g_error_new (YAF_ERROR_DOMAIN, YAF_ERROR_LIMIT, "maximum number of application labeler" " rules has been reached"); return FALSE; } continue; } substringVects[1] = currentStartPos; /* scan the line to see if it is a plugin statement, and handle the * arguments if it is */ rc = pcre_exec (pluginScanner, NULL, lineBuffer, readLength, substringVects[1], PCRE_ANCHORED, substringVects, NUM_SUBSTRING_VECTS); if (rc > 0) { int numArgs; char **argStrings; /* get the first matched field from the regex rule expression * (the lable value) */ pcre_get_substring (lineBuffer, substringVects, rc, 1, (const char **) &captString); ruleTable[numPayloadRules].payloadLabelValue = strtoul (captString, NULL, 10); #if YFDEBUG_APPLABEL g_debug("plugin: rule # %u, label value %lu ", numPayloadRules, strtoul(captString, NULL, 10)); #endif pcre_free (captString); /* * get the second matched field, which should be the plugin * name and all of its arguments, now we need to chunk that * into an array of strings, ala argc, argv */ pcre_get_substring(lineBuffer, substringVects, rc, 2, (const char **) &captString); ycChunkString(captString, &numArgs, &argStrings); if (numArgs < 2) { g_critical("error: not enough arguments to load and call " "a plugin, at least a library name and function" " name are needed\n"); pcre_free(captString); pcre_get_substring(lineBuffer, substringVects, rc, 0, (const char **) &captString); g_critical("input line: \"%s\"\n", captString); } else { ENTRY newItem; ENTRY *foundItem; lt_dlhandle modHandle; lt_ptr funcPtr; ruleTable[numPayloadRules].ruleType = PLUGIN; ruleTable[numPayloadRules].ruleArgs.pluginArgs.numArgs = numArgs; ruleTable[numPayloadRules].ruleArgs.pluginArgs.pluginArgs = argStrings; newItem.key = strdup(argStrings[0]); if (NULL == newItem.key) { g_error("out of memory error\n"); for (loop = 0; loop < numArgs; loop++) { free ((char *) (argStrings[loop])); } free(argStrings); return FALSE; } newItem.data = NULL; foundItem = hsearch(newItem, FIND); if (NULL == foundItem) { modHandle = lt_dlopenext(newItem.key); if (NULL == modHandle) { g_critical("Couldn't open library \"%s\": %s", argStrings[0], lt_dlerror()); g_critical("Search path set to %s", lt_dlgetsearchpath()); g_critical("Set LTDL_LIBRARY_PATH to correct" " location."); for (loop = 0; loop < numArgs; loop++) { free((char *) (argStrings[loop])); } free(argStrings); pcre_free(captString); continue; } else { #if YFDEBUG_APPLABEL const lt_dlinfo *info = lt_dlgetinfo(modHandle); g_debug("Loading %s plugin from %s", info->name, info->filename); #endif } newItem.data = (void *)modHandle; hsearch(newItem, ENTER); } else { modHandle = (lt_dlhandle)foundItem->data; } funcPtr = lt_dlsym(modHandle, argStrings[1]); if (NULL == funcPtr) { g_critical("couldn't find function \"%s\" in library" " \"%s\"\n", argStrings[1], argStrings[0]); for (loop = 0; loop < numArgs; loop++) { free ((char *) (argStrings[loop])); } free (argStrings); pcre_free (captString); continue; } ruleTable[numPayloadRules].ruleArgs.pluginArgs.func = (ycScannerPlugin_fn) funcPtr; ycPortHashInsert(ruleTable[numPayloadRules].payloadLabelValue, numPayloadRules); numPayloadRules++; } pcre_free(captString); if (MAX_PAYLOAD_RULES == numPayloadRules) { g_warning ("maximum number of rules has been reached\n"); return TRUE; } continue; } substringVects[1] = currentStartPos; /* scan the line to see if it is a signature, and get the * arguments if it is */ rc = pcre_exec(signatureScanner, NULL, lineBuffer, readLength, substringVects[1], PCRE_ANCHORED, substringVects, NUM_SUBSTRING_VECTS); if (rc > 0) { pcre *newRule; pcre_extra *newExtra; /* get the first matched field from the regex rule expression * (the label value) */ pcre_get_substring(lineBuffer, substringVects, rc, 1, (const char **) &captString); sigTable[numSigRules].payloadLabelValue = strtoul(captString, NULL, 10); #if YFDEBUG_APPLABEL g_debug("signature: rule # %u, label value %lu ", numSigRules, strtoul(captString, NULL, 10)); #endif pcre_free (captString); /* get the second matched field from the regex rule expression * (should be the regex) */ pcre_get_substring(lineBuffer, substringVects, rc, 2, (const char **) &captString); #if YFDEBUG_APPLABEL g_debug(" signature \"%s\"\n", captString); #endif newRule = pcre_compile(captString, 0, &errorString, &errorPos, NULL); if (NULL == newRule) { ycDisplayScannerRuleError (eString, ESTRING_SIZE, "error in signature application " "labeler rule", errorString, captString, errorPos); } else { newExtra = pcre_study (newRule, 0, &errorString); sigTable[numSigRules].ruleArgs.regexFields. scannerExpression = newRule; sigTable[numSigRules].ruleArgs.regexFields. scannerExtra = newExtra; sigTable[numSigRules].ruleType = SIGNATURE; numSigRules++; } pcre_free(captString); if (MAX_PAYLOAD_RULES == numSigRules) { *err = g_error_new(YAF_ERROR_DOMAIN, YAF_ERROR_LIMIT, "maximum number of signature rules has " "been reached"); return FALSE; } continue; } substringVects[1] = currentStartPos; /* pcre_free (captString);*/ #if YFDEBUG_APPLABEL g_debug("plugin args: "); for (loop = 0; loop < numArgs; loop++) { g_debug("\"%s\" ", (*argStrings)[loop]); } g_debug("\n"); #endif /* * check to see if we have partial text left over at the end of * the read buffer, if we copy it to the front of the read * buffer, and on the next read, read a little less to * compensate for the left over amount */ if ((PCRE_ERROR_NOMATCH == rc) && (substringVects[1] < readLength) && !feof (scriptFile)) { memmove (lineBuffer, lineBuffer + substringVects[1], readLength - substringVects[1]); bufferOffset = readLength - substringVects[1]; break; } else if (PCRE_ERROR_NOMATCH == rc && feof (scriptFile)) { /* this is an error, we have crap left over at the end of the * file that we can't parse! */ g_critical("unparsed text at the end of the application labeler" " rule file!\n"); break; } } } while (!ferror (scriptFile) && !feof (scriptFile)); /* * get rid of the module handle lookup hash; this creates a mem leak of * the module handles, they can't be freed any longer (although this is a * crappy hash, and iterating the hash is not possible....) */ hdestroy(); g_debug("Application Labeler accepted %d rules.", numPayloadRules); g_debug("Application Labeler accepted %d signatures.", numSigRules); pcre_free(ruleScanner); pcre_free(pluginScanner); pcre_free(commentScanner); pcre_free(pluginArgScanner); pcre_free(signatureScanner); /* debug */ return TRUE; }