Exemple #1
0
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);
}
Exemple #2
0
/*
 * 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;
  }
Exemple #3
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;
}
Exemple #7
0
/**
 * 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;
}