Beispiel #1
0
void
vstat_init(struct agent_core_t *core)
{
	struct agent_plugin_t *plug;
	struct vstat_priv_t *priv;

	ALLOC_OBJ(priv);
	plug = plugin_find(core,"vstat");
	vstat_init_ctx(core,&priv->http);
	vstat_init_ctx(core,&priv->timer);

	plug->data = priv;
	plug->start = vstat_start;

	pthread_rwlock_init(&priv->lck, NULL);

	http_register_path(core, "/stats", M_GET, vstat_reply, core);
	http_register_path(core, "/push/test/stats", M_PUT, vstat_push_test, core);
	http_register_path(core, "/push/url/stats", M_PUT, vstat_push_url, core);
}
Beispiel #2
0
void
vcl_init(struct agent_core_t *core)
{
	struct agent_plugin_t *plug;
	struct vcl_priv_t *priv;

	ALLOC_OBJ(priv);
	plug = plugin_find(core,"vcl");
	priv->logger = ipc_register(core,"logger");
	priv->vadmin = ipc_register(core,"vadmin");
	plug->data = (void *)priv;
	mk_help(core, priv);
	http_register_path(core, "/vcljson", M_GET, vcl_json, core);
	http_register_path(core, "/vcl", M_GET, vcl_listshow, core);
	http_register_path(core, "/vcl", M_PUT | M_POST, vcl_push, core);
	http_register_path(core, "/vcl", M_DELETE, vcl_delete, core);
	http_register_path(core, "/vclactive", M_GET , vcl_active, core);
	http_register_path(core, "/vcldeploy", M_PUT , vcl_deploy, core);
	http_register_path(core, "/help/vcl", M_GET, help_reply, priv->help);
}
Beispiel #3
0
int plugin_register(ddns_system_t *plugin)
{
	if (!plugin) {
		errno = EINVAL;
		return 1;
	}

	if (!plugin->name) {
		char *dli_fname = NULL;
#ifdef __CYGWIN__
		char posix_path[MAX_PATH];
		char path[MAX_PATH];
		MEMORY_BASIC_INFORMATION mbi;

		VirtualQuery((void*)&plugin, &mbi, sizeof(mbi));
		GetModuleFileNameA((HINSTANCE)mbi.AllocationBase, path, MAX_PATH);
		cygwin_conv_path(CCP_WIN_A_TO_POSIX | CCP_RELATIVE, path, posix_path, MAX_PATH);
		dli_fname = posix_path;
#else
		Dl_info info;

		if (dladdr(plugin, &info))
			dli_fname = (char *)info.dli_fname;
#endif

		if (!dli_fname)
			plugin->name = "unknown";
		else
			plugin->name = (char *)dli_fname;
	}

	/* Already registered? */
	if (plugin_find(plugin->name)) {
		logit(LOG_DEBUG, "... %s already loaded.", plugin->name);
		return 0;
	}

	TAILQ_INSERT_TAIL(&plugins, plugin, link);

	return 0;
}
Beispiel #4
0
int http_register_url(struct agent_core_t *core, const char *url,
		       unsigned int method,
		       unsigned int (*cb)(struct http_request *request,
		       void *data), void *data)
{
	struct http_listener *listener = malloc(sizeof(struct http_listener));
	struct agent_plugin_t *plug = plugin_find(core,"http");
	struct http_priv_t *http = plug->data;
	assert(listener);
	assert(plug);
	assert(http);
	listener->url = strdup(url);
	assert(listener->url);
	assert(cb);
	listener->method = method;
	listener->cb = cb;
	listener->data = data;
	listener->next = http->listener;
	http->listener = listener;
	return 1;
}
Beispiel #5
0
EXPORTNOT session_t *remote_session_add(const char *uid, const char *plugin) {
	session_t *s;
	plugin_t *pl;

	if (!(pl = plugin_find(plugin))) {
		debug_error("remote_session_add() plugin == NULL\n");
		return NULL;
	}
		
	s = xmalloc(sizeof(session_t));
	s->uid		= xstrdup(uid);
	s->status	= EKG_STATUS_NA;
	s->plugin	= pl;

	sessions_add(s);

	/* XXX, session_var_default() */

	query_emit_id(NULL, SESSION_ADDED, &(s->uid));
	return s;
}
Beispiel #6
0
/*
 * NOTE: options_init and options_destroy are a bit weird, because their
 * invocation is not completely symmetric:
 *
 *   - init is called from driver init (e.g. affile_sd_init),
 *   - destroy is called from driver free method (e.g. affile_sd_free, NOT affile_sd_deinit)
 *
 * The reason:
 *   - when initializing the reloaded configuration fails for some reason,
 *     we have to fall back to the old configuration, thus we cannot dump
 *     the information stored in the Options structure.
 *
 * For the reasons above, init and destroy behave the following way:
 *
 *   - init is idempotent, it can be called multiple times without leaking
 *     memory, and without loss of information
 *   - destroy is only called once, when the options are indeed to be destroyed
 *
 * As init allocates memory, it has to take care about freeing memory
 * allocated by the previous init call (or it has to reuse those).
 *
 */
void
msg_format_options_init(MsgFormatOptions *options, GlobalConfig *cfg)
{
  gchar *recv_time_zone, *format;
  TimeZoneInfo *recv_time_zone_info;
  MsgFormatHandler *format_handler;
  Plugin *p;

  recv_time_zone = options->recv_time_zone;
  options->recv_time_zone = NULL;
  recv_time_zone_info = options->recv_time_zone_info;
  options->recv_time_zone_info = NULL;
  format = options->format;
  options->format = NULL;
  format_handler = options->format_handler;
  options->format_handler = NULL;

  msg_format_options_destroy(options);

  options->format = format;
  options->format_handler = format_handler;
  options->recv_time_zone = recv_time_zone;
  options->recv_time_zone_info = recv_time_zone_info;

  if (cfg->bad_hostname_compiled)
    options->bad_hostname = &cfg->bad_hostname;
  if (options->recv_time_zone == NULL)
    options->recv_time_zone = g_strdup(cfg->recv_time_zone);
  if (options->recv_time_zone_info == NULL)
    options->recv_time_zone_info = time_zone_info_new(options->recv_time_zone);

  if (!options->format)
    options->format = g_strdup("syslog");

  p = plugin_find(cfg, LL_CONTEXT_FORMAT, options->format);
  if (p)
    options->format_handler = plugin_construct(p, cfg, LL_CONTEXT_FORMAT, options->format);
}
Beispiel #7
0
void
echo_init(struct agent_core_t *core)
{
	struct echo_priv_t *priv;
	struct agent_plugin_t *plug;

	/*
	 * Allocate the private data structure we'll keep using.
	 */
	ALLOC_OBJ(priv);

	/*
	 * Find our pre-allocated data structure. This is only used to
	 * define start-functions (which we don't have), module-specific
	 * private data and an IPC for the module (which we don't use).
	 */
	plug = plugin_find(core, "echo");

	/*
	 * Register with the logger.
	 */
	priv->logger = ipc_register(core, "logger");

	/*
	 * Store our private data somewhere we can reach it, and set our
	 * start function to NULL since echo is only triggered by HTTP
	 * requests.
	 */
	plug->data = (void *)priv;

	/*
	 * Register the url /echo for the methods POST, PUT and GET. When a
	 * request like that is encountered, the echo_reply function will
	 * be called with "priv" as the last argument.
	 */
	http_register_path(core, "/echo", M_POST | M_PUT | M_GET,
	    echo_reply, priv);
}
Beispiel #8
0
/* NOTE: _init needs to be idempotent when called multiple times w/o invoking _destroy */
void
msg_format_options_init(MsgFormatOptions *options, GlobalConfig *cfg)
{
  Plugin *p;

  if (options->initialized)
    return;

  if (cfg->bad_hostname_compiled)
    options->bad_hostname = &cfg->bad_hostname;
  if (options->recv_time_zone == NULL)
    options->recv_time_zone = g_strdup(cfg->recv_time_zone);
  if (options->recv_time_zone_info == NULL)
    options->recv_time_zone_info = time_zone_info_new(options->recv_time_zone);

  if (!options->format)
    options->format = g_strdup("syslog");

  p = plugin_find(cfg, LL_CONTEXT_FORMAT, options->format);
  if (p)
    options->format_handler = plugin_construct(p, cfg, LL_CONTEXT_FORMAT, options->format);
  options->initialized = TRUE;
}
Beispiel #9
0
PyObject *ekg_plugin_load(ekg_pluginObj * self, PyObject *args)
{
	int prio;

	if (!PyArg_ParseTuple(args, "i", &prio))
		return NULL;

	debug("[python] Loading plugin '%s' with prio %i\n", self->name, prio);

	if (plugin_find(self->name)) {
		PyErr_SetString(PyExc_RuntimeError, "Plugin already loaded");
		return NULL;
	}
	if (plugin_load(self->name, prio, 0) == -1) {
		Py_RETURN_FALSE;
	} else {
		self->loaded = 1;
		Py_RETURN_TRUE;
	}

	Py_INCREF(Py_None);
	return Py_None;
}
Beispiel #10
0
int plugin_register(plugin_t *plugin)
{
	if (!plugin) {
		errno = EINVAL;
		return 1;
	}

	/* Setup default name if none is provided */
	if (!plugin->name) {
#ifndef ENABLE_STATIC
		Dl_info info;

		if (dladdr(plugin, &info) && info.dli_fname)
			plugin->name = basename(info.dli_fname);
#endif
		if (!plugin->name)
			plugin->name = "unknown";
	}
	plugin->name = trim_ext(strdup(plugin->name));

	/* Already registered? */
	if (plugin_find(plugin->name)) {
		_d("... %s already loaded", plugin->name);
		free(plugin->name);

		return 0;
	}

#ifndef ENABLE_STATIC
	/* Resolve plugin dependencies */
	check_plugin_depends(plugin);
#endif

	TAILQ_INSERT_TAIL(&plugins, plugin, link);

	return 0;
}
Beispiel #11
0
/*
 * Pings the varnish server every Nth second. First vadmin-plugin written,
 * not sure if it still has value.
 */
static void *vping_run(void *data)
{
	struct agent_core_t *core = (struct agent_core_t *)data;
	struct agent_plugin_t *plug;
	struct vping_priv_t *ping;
	struct ipc_ret_t vret;

	plug = plugin_find(core,"vping");
	ping = (struct vping_priv_t *) plug->data;

	while (1) {
		sleep(30);
		ipc_run(ping->vadmin_sock, &vret, "ping");
		if (vret.status != 200)
			logger(ping->logger, "Ping failed. %d ", vret.status);
		free(vret.answer);

		ipc_run(ping->vadmin_sock, &vret, "status");
		if (vret.status != 200 || strcmp(vret.answer,"Child in state running"))
			logger(ping->logger, "%d %s", vret.status, vret.answer);
		free(vret.answer);
	}
	return NULL;
}
Beispiel #12
0
int plugin_register(plugin_t *plugin)
{
	int i, inuse = 0;

	if (!plugin) {
		errno = EINVAL;
		return 1;
	}

	if (!plugin->name) {
		Dl_info info;

		if (!dladdr(plugin, &info) || !info.dli_fname)
			plugin->name = "unknown";
		else
			plugin->name = (char *)info.dli_fname;
	}

	/* Already registered? */
	if (plugin_find(plugin->name)) {
		_d("... %s already loaded.", plugin->name);
		return 0;
	}

	check_plugin_depends(plugin);

	if (is_io_plugin(plugin)) {
		if (num_fds + 1 >= MAX_NUM_FDS) {
			num_fds = MAX_NUM_SVC;
			errno = ENOMEM;
			return 1;
		}
		num_fds++;
		inuse++;
	}

	if (plugin->svc.cb) {
		svc_t *svc = svc_find(plugin->name);

		if (svc) {
			inuse++;
			svc->cb           = plugin->svc.cb;
			svc->dynamic      = plugin->svc.dynamic;
			svc->dynamic_stop = plugin->svc.dynamic_stop;
		}
	}

	for (i = 0; i < HOOK_MAX_NUM; i++) {
		if (plugin->hook[i].cb)
			inuse++;
	}

	if (!inuse) {
		_d("No service \"%s\" loaded, and no I/O or finit hooks, skipping plugin.", basename(plugin->name));
		return 1;
	}

	TAILQ_INSERT_TAIL(&plugins, plugin, link);

	return 0;
}
Beispiel #13
0
/**
 * svc_register - Register service, task or run commands
 * @type:     %SVC_CMD_SERVICE(0), %SVC_CMD_TASK(1), %SVC_CMD_RUN(2)
 * @line:     A complete command line with -- separated description text
 * @username: Optional username to run service as, or %NULL to run as root
 *
 * This function is used to register commands to be run on different
 * system runlevels with optional username.  The @type argument details
 * if it's service to bo monitored/respawned (daemon), a one-shot task
 * or a command that must run in sequence and not in parallell, like
 * service and task commands do.
 *
 * The @line can optionally start with a username, denoted by an @
 * character. Like this:
 *
 *   "service @username [!0-6,S] /path/to/daemon arg -- Description text"
 *   "task @username [!0-6,S] /path/to/task arg -- Description text"
 *   "run  @username [!0-6,S] /path/to/cmd arg -- Description text"
 *   "inetd tcp/ssh nowait [2345] @root:root /usr/sbin/sshd -i -- Description"
 *
 * If the username is left out the command is started as root.
 * Inetd services, launched on demand (SVC_CMD_INETD)
 * The [] brackets are there to denote the allowed runlevels. Allowed
 * runlevels mimic that of SysV init with the addition of the 'S'
 * runlevel, which is only run once at startup. It can be seen as the
 * system bootstrap. If a task or run command is listed in more than the
 * [S] runlevel they will be called when changing runlevel.
 *
 * Returns:
 * POSIX OK(0) on success, or non-zero errno exit status on failure.
 */
int svc_register(int type, char *line, char *username)
{
	int i = 0;
#ifndef INETD_DISABLED
	int forking = 0;
#endif
	char *service = NULL, *proto = NULL, *iface = NULL, *port = NULL;
	char *cmd, *desc, *runlevels = NULL;
	svc_t *svc;
	plugin_t *plugin = NULL;

	if (!line) {
		_e("Invalid input argument.");
		return errno = EINVAL;
	}

	desc = strstr(line, "-- ");
	if (desc)
		*desc = 0;

	cmd = strtok(line, " ");
	if (!cmd) {
	incomplete:
		_e("Incomplete service, cannot register.");
		return errno = ENOENT;
	}

	while (cmd) {
		if (cmd[0] != '/' && strchr(cmd, '/'))
			service = cmd;   /* inetd service/proto */
#ifndef INETD_DISABLED
		else if (!strncasecmp(cmd, "nowait", 6))
			forking = 1;
		else if (!strncasecmp(cmd, "wait", 4))
			forking = 0;
#endif
		else if (cmd[0] == '@')	/* @username[:group] */
			username = &cmd[1];
		else if (cmd[0] == '[')	/* [runlevels] */
			runlevels = &cmd[0];
		else
			break;

		/* Check if valid command follows... */
		cmd = strtok(NULL, " ");
		if (!cmd)
			goto incomplete;
	}

	/* Example: inetd ssh@eth0:222/tcp */
	if (service) {
		proto = strchr(service, '/');
		if (!proto)
			goto incomplete;
		*proto++ = 0;

		port = strchr(service, ':');
		if (port)
			*port++ = 0;

		iface = strchr(service, '@');
		if (iface)
			*iface++ = 0;
	}

#ifndef INETD_DISABLED
	/* Find plugin that provides a callback for this inetd service */
	if (type == SVC_CMD_INETD && !strncasecmp(cmd, "internal", 8)) {
		plugin = plugin_find(service);
		if (!plugin || !plugin->inetd.cmd) {
			_e("Inetd service %s has no internal plugin, skipping.", service);
			return errno = ENOENT;
		}
	}

	/* Check if known inetd, then add ifname for filtering only. */
	svc = svc_find_inetd(cmd, service, proto, port);
	if (svc)
		return inetd_allow(&svc->inetd, iface);
#endif

	svc = svc_new();
	if (!svc) {
		_e("Out of memory, cannot register service %s", cmd);
		return errno = ENOMEM;
	}

	svc->type = type;

	if (desc)
		strlcpy(svc->desc, desc + 3, sizeof(svc->desc));

	if (username) {
		char *ptr = strchr(username, ':');

		if (ptr) {
			*ptr++ = 0;
			strlcpy(svc->group, ptr, sizeof(svc->group));
		}
		strlcpy(svc->username, username, sizeof(svc->username));
	}

#ifndef INETD_DISABLED
	if (svc->type == SVC_CMD_INETD) {
		int result;

		result  = inetd_new(&svc->inetd, service, proto, forking);
		result += inetd_init(&svc->inetd, svc, iface, port);

		if (result) {
			_e("Failed registering new inetd service %s.", service);
			inetd_del(&svc->inetd);
			return svc_del(svc);
		}
	}
#endif

	if (plugin) {
		/* Internal plugin provides this service */
		svc->inetd.cmd = plugin->inetd.cmd;
	} else {
		/* External program to call */
		strlcpy(svc->cmd, cmd, sizeof(svc->cmd));

		strlcpy(svc->args[i++], cmd, sizeof(svc->args[0]));
		while ((cmd = strtok(NULL, " ")))
			strlcpy(svc->args[i++], cmd, sizeof(svc->args[0]));
		svc->args[i][0] = 0;

		plugin = plugin_find(svc->cmd);
		if (plugin && plugin->svc.cb) {
			svc->cb           = plugin->svc.cb;
			svc->dynamic      = plugin->svc.dynamic;
			svc->dynamic_stop = plugin->svc.dynamic_stop;
		}
	}

	svc->runlevels = parse_runlevels(runlevels);
	_d("Service %s runlevel 0x%2x", svc->cmd, svc->runlevels);

	return 0;
}
Beispiel #14
0
/*
 * plugin_load()
 *
 * ³aduje wtyczkê o podanej nazwie.
 * 
 * 0/-1
 */
int plugin_load(const char *name, int prio, int quiet)
{
#ifdef SHARED_LIBS
	char lib[PATH_MAX];
	char *env_ekg_plugins_path = NULL;
	char *init = NULL;
#endif

	plugin_t *pl;
	void *plugin = NULL;
	int (*plugin_init)() = NULL;

	if (!name)
		return -1;

	if (plugin_find(name)) {
		printq("plugin_already_loaded", name); 
		return -1;
	}
#ifdef SHARED_LIBS
#ifndef NO_POSIX_SYSTEM
#ifdef SCONS
#	define DOTLIBS "" 
#else
#	define DOTLIBS ".libs/"
#endif
	if ((env_ekg_plugins_path = getenv("EKG_PLUGINS_PATH"))) {
		if (snprintf(lib, sizeof(lib), "%s/%s.so", env_ekg_plugins_path, name) < sizeof(lib))
			plugin = ekg2_dlopen(lib);
		if (!plugin && (snprintf(lib, sizeof(lib), "%s/%s/" DOTLIBS "%s.so", env_ekg_plugins_path, name, name) < sizeof(lib)))
				plugin = ekg2_dlopen(lib);
	}

#ifndef SKIP_RELATIVE_PLUGINS_DIR
	/* The following lets ekg2 load plugins when it is run directly from
	 * the source tree, without installation. This can be beneficial when
	 * developing the program, or for less knowlegeable users, who don't
	 * know how to or cannot for some other reason use installation prefix
	 * to install in their home directory. However this impses a security
	 * risk if the program installed in the system directory is run in
	 * untrusted $CWD or when $CWD/../plugins is untrusted.
	 *
	 * TODO(porridge,darkjames): This can be fixed by having a wrapper
	 * script in the source tree to run ekg/.libs/ekg2 with
	 * EKG_PLUGINS_PATH set appropriately.
	 */
	if (!plugin) {
		if (snprintf(lib, sizeof(lib), "plugins/%s/" DOTLIBS "%s.so", name, name) < sizeof(lib))
			plugin = ekg2_dlopen(lib);
	}

	if (!plugin) {
		if (snprintf(lib, sizeof(lib), "../plugins/%s/" DOTLIBS "%s.so", name, name) < sizeof(lib))
			plugin = ekg2_dlopen(lib);
	}
#endif

	if (!plugin) {
		if (snprintf(lib, sizeof(lib), "%s/%s.so", PLUGINDIR, name) < sizeof(lib))
			plugin = ekg2_dlopen(lib);
	}
#else	/* NO_POSIX_SYSTEM */
	if (!plugin) {
		if (snprintf(lib, sizeof(lib), "c:\\ekg2\\plugins\\%s.dll", name) < sizeof(lib))
			plugin = ekg2_dlopen(lib);
	}
#endif /* SHARED_LIBS */
	if (!plugin) {
		printq("plugin_doesnt_exist", name);
		return -1;
	}
#endif

#ifdef STATIC_LIBS
#ifndef SCONS
/* first let's try to load static plugin... */
	extern int jabber_plugin_init(int prio);
	extern int irc_plugin_init(int prio);
	extern int gtk_plugin_init(int prio);

	debug("searching for name: %s in STATICLIBS: %s\n", name, STATIC_LIBS);

	if (!xstrcmp(name, "jabber")) plugin_init = &jabber_plugin_init;
	if (!xstrcmp(name, "irc")) plugin_init = &irc_plugin_init;
	if (!xstrcmp(name, "gtk")) plugin_init = &gtk_plugin_init;
//	if (!xstrcmp(name, "miranda")) plugin_init = &miranda_plugin_init;
#else
	debug_function("plugin_load(), trying to find static plugin '%s'\n", name);
	void *plugin_load_static(const char *name); /* autogenerated by scons */
	plugin_init = plugin_load_static(name);
#endif
#endif

#ifdef SHARED_LIBS
	if (!plugin_init) {
# ifdef EKG2_WIN32_HELPERS
		void (*plugin_preinit)(void *);
		char *preinit = saprintf("win32_plugin_init");
		if (!(plugin_preinit = ekg2_dlsym(plugin, preinit))) {
			debug("NO_POSIX_SYSTEM, PLUGIN:%s NOT COMPILATED WITH EKG2_WIN32_SHARED_LIB?!\n", name);
			printq("plugin_incorrect", name);
			xfree(preinit);
			return -1;
		}
		xfree(preinit);
		plugin_preinit(&win32_helper);
# endif
/* than if we don't have static plugin... let's try to load it dynamicly */
		init = saprintf("%s_plugin_init", name);

		if (!(plugin_init = ekg2_dlsym(plugin, init))) {
			printq("plugin_incorrect", name);
			ekg2_dlclose(plugin);
			xfree(init);
			return -1;
		}
		xfree(init);
	}
#endif
	if (!plugin_init) {
		printq("plugin_doesnt_exist", name);
		return -1;
	}

	if (plugin_init(prio) == -1) {
		printq("plugin_not_initialized", name);
		ekg2_dlclose(plugin);
		return -1;
	}

	if ((pl = plugin_find(name))) {
		pl->dl = plugin;
	} else {
		debug_error("plugin_load() plugin_find(%s) not found.\n", name);
		/* It's FATAL */
	}

	query_emit_id(pl, SET_VARS_DEFAULT);

	printq("plugin_loaded", name);

	if (!in_autoexec) {
		const char *tmp;

		in_autoexec = 1;
		if ((tmp = prepare_pathf("config-%s", name)))
			config_read(tmp);
		if ((pl->pclass == PLUGIN_PROTOCOL) && (tmp = prepare_pathf("sessions-%s", name)))
			session_read(tmp);

		if (pl)
			query_emit_id(pl, CONFIG_POSTINIT);

		in_autoexec = 0;
		config_changed = 1;
	}
	return 0;
}
Beispiel #15
0
static gboolean
_is_json_parser_available(GlobalConfig *cfg)
{
  return plugin_find(cfg, LL_CONTEXT_PARSER, "json-parser") != NULL;
}
Beispiel #16
0
/**
 * service_register - Register service, task or run commands
 * @type:     %SVC_TYPE_SERVICE(0), %SVC_TYPE_TASK(1), %SVC_TYPE_RUN(2)
 * @line:     A complete command line with -- separated description text
 * @mtime:    The modification time if service is loaded from /etc/finit.d
 * @username: Optional username to run service as, or %NULL to run as root
 *
 * This function is used to register commands to be run on different
 * system runlevels with optional username.  The @type argument details
 * if it's service to bo monitored/respawned (daemon), a one-shot task
 * or a command that must run in sequence and not in parallell, like
 * service and task commands do.
 *
 * The @line can optionally start with a username, denoted by an @
 * character. Like this:
 *
 *     service @username [!0-6,S] <!EV> /path/to/daemon arg -- Description
 *     task @username [!0-6,S] /path/to/task arg            -- Description
 *     run  @username [!0-6,S] /path/to/cmd arg             -- Description
 *     inetd tcp/ssh nowait [2345] @root:root /sbin/sshd -i -- Description
 *
 * If the username is left out the command is started as root.  The []
 * brackets denote the allowed runlevels, if left out the default for a
 * service is set to [2-5].  Allowed runlevels mimic that of SysV init
 * with the addition of the 'S' runlevel, which is only run once at
 * startup.  It can be seen as the system bootstrap.  If a task or run
 * command is listed in more than the [S] runlevel they will be called
 * when changing runlevel.
 *
 * Services (daemons, not inetd services) also support an optional <!EV>
 * argument.  This is for services that, e.g., require a system gateway
 * or interface to be up before they are started.  Or restarted, or even
 * SIGHUP'ed, when the gateway changes or interfaces come and go.  The
 * special case when a service is declared with <!> means it does not
 * support SIGHUP but must be STOP/START'ed at system reconfiguration.
 *
 * Supported service events are: GW, IFUP[:ifname], IFDN[:ifname], where
 * the interface name (:ifname) is optional.  Actully, the check with a
 * service event declaration is string based, so 'IFUP:ppp' will match
 * any of "IFUP:ppp0" or "IFUP:pppoe1" sent by the netlink.so plugin.
 *
 * For multiple instances of the same command, e.g. multiple DHCP
 * clients, the user must enter an ID, using the :ID syntax.
 *
 *     service :1 /sbin/udhcpc -i eth1
 *     service :2 /sbin/udhcpc -i eth2
 *
 * Without the :ID syntax Finit will overwrite the first service line
 * with the contents of the second.  The :ID must be [1,MAXINT].
 *
 * Returns:
 * POSIX OK(0) on success, or non-zero errno exit status on failure.
 */
int service_register(int type, char *line, time_t mtime, char *username)
{
	int i = 0;
	int id = 1;		/* Default to ID:1 */
#ifndef INETD_DISABLED
	int forking = 0;
#endif
	char *service = NULL, *proto = NULL, *ifaces = NULL;
	char *cmd, *desc, *runlevels = NULL, *events = NULL;
	svc_t *svc;
	plugin_t *plugin = NULL;

	if (!line) {
		_e("Invalid input argument.");
		return errno = EINVAL;
	}

	desc = strstr(line, "-- ");
	if (desc)
		*desc = 0;

	cmd = strtok(line, " ");
	if (!cmd) {
	incomplete:
		_e("Incomplete service, cannot register.");
		return errno = ENOENT;
	}

	while (cmd) {
		if (cmd[0] != '/' && strchr(cmd, '/'))
			service = cmd;   /* inetd service/proto */
#ifndef INETD_DISABLED
		else if (!strncasecmp(cmd, "nowait", 6))
			forking = 1;
		else if (!strncasecmp(cmd, "wait", 4))
			forking = 0;
#endif
		else if (cmd[0] == '@')	/* @username[:group] */
			username = &cmd[1];
		else if (cmd[0] == '[')	/* [runlevels] */
			runlevels = &cmd[0];
		else if (cmd[0] == '<')	/* [!ev] */
			events = &cmd[1];
		else if (cmd[0] == ':')	/* :ID */
			id = atoi(&cmd[1]);
		else
			break;

		/* Check if valid command follows... */
		cmd = strtok(NULL, " ");
		if (!cmd)
			goto incomplete;
	}

	/* Example: inetd ssh/tcp@eth0,eth1 or 222/tcp@eth2 */
	if (service) {
		ifaces = strchr(service, '@');
		if (ifaces)
			*ifaces++ = 0;

		proto = strchr(service, '/');
		if (!proto)
			goto incomplete;
		*proto++ = 0;
	}

#ifndef INETD_DISABLED
	/* Find plugin that provides a callback for this inetd service */
	if (type == SVC_TYPE_INETD) {
		if (!strncasecmp(cmd, "internal", 8)) {
			char *ptr, *ps = service;

			/* internal.service */
			ptr = strchr(cmd, '.');
			if (ptr) {
				*ptr++ = 0;
				ps = ptr;
			}

			plugin = plugin_find(ps);
			if (!plugin || !plugin->inetd.cmd) {
				_e("Inetd service %s has no internal plugin, skipping.", service);
				return errno = ENOENT;
			}
		}

		/* Check if known inetd, then add ifnames for filtering only. */
		svc = find_inetd_svc(cmd, service, proto);
		if (svc)
			goto inetd_setup;

		id = svc_next_id(cmd);
	}
#endif

	svc = svc_find(cmd, id);
	if (!svc) {
		_d("Creating new svc for %s id #%d type %d", cmd, id, type);
		svc = svc_new(cmd, id, type);
		if (!svc) {
			_e("Out of memory, cannot register service %s", cmd);
			return errno = ENOMEM;
		}
	}

	/* New, recently modified or unchanged ... used on reload. */
	svc_check_dirty(svc, mtime);

	if (desc)
		strlcpy(svc->desc, desc + 3, sizeof(svc->desc));

	if (username) {
		char *ptr = strchr(username, ':');

		if (ptr) {
			*ptr++ = 0;
			strlcpy(svc->group, ptr, sizeof(svc->group));
		}
		strlcpy(svc->username, username, sizeof(svc->username));
	}

	if (plugin) {
		/* Internal plugin provides this service */
		svc->inetd.cmd = plugin->inetd.cmd;
	} else {
		strlcpy(svc->args[i++], cmd, sizeof(svc->args[0]));
		while ((cmd = strtok(NULL, " ")))
			strlcpy(svc->args[i++], cmd, sizeof(svc->args[0]));
		svc->args[i][0] = 0;

		plugin = plugin_find(svc->cmd);
		if (plugin && plugin->svc.cb) {
			svc->cb           = plugin->svc.cb;
			svc->dynamic      = plugin->svc.dynamic;
			svc->dynamic_stop = plugin->svc.dynamic_stop;
		}
	}

	svc->runlevels = conf_parse_runlevels(runlevels);
	_d("Service %s runlevel 0x%2x", svc->cmd, svc->runlevels);

	if (type == SVC_TYPE_SERVICE)
		conf_parse_events(svc, events);

#ifndef INETD_DISABLED
	if (svc_is_inetd(svc)) {
		char *iface, *name = service;

		if (svc->inetd.cmd && plugin)
			name = plugin->name;

		if (inetd_new(&svc->inetd, name, service, proto, forking, svc)) {
			_e("Failed registering new inetd service %s.", service);
			inetd_del(&svc->inetd);
			return svc_del(svc);
		}

	inetd_setup:
		if (!ifaces) {
			_d("No specific iface listed for %s, allowing ANY.", service);
			return inetd_allow(&svc->inetd, NULL);
		}

		for (iface = strtok(ifaces, ","); iface; iface = strtok(NULL, ",")) {
			if (iface[0] == '!')
				inetd_deny(&svc->inetd, &iface[1]);
			else
				inetd_allow(&svc->inetd, iface);
		}
	}
#endif

	return 0;
}
Beispiel #17
0
static unsigned int vlog_reply(struct http_request *request, void *data)
{
	struct vlog_req_priv vrp = { .limit = 10 };
	int disp_status;
	char *p;
	char *tag = NULL;
	char *tag_re = NULL;
	struct VSL_data *vsl = NULL;
	struct VSLQ *vslq = NULL;
	struct VSL_cursor *c = NULL;
	enum VSL_grouping_e grouping = VSL_g_request;
	struct agent_core_t *core = data;

	p = next_slash(request->url + 1);
	if (p) {
		char *lim = strdup(p);
		assert(lim);
		char *tmp2 = strchr(lim, '/');
		if (tmp2 && *tmp2) *tmp2 = '\0';

		int j = sscanf(lim, "%u", &vrp.limit);
		if(j != 1) {
			free(lim);
			http_reply(request->connection, 500, "Not a number");
			return 0;
		}

		free(lim);
		p = next_slash(p);
	}

	if (p) {
		tag = strdup(p);
		char *tmp2 = strchr(tag,'/');
		if (tmp2 && *tmp2) *tmp2 = '\0';
		p = next_slash(p);
	}

	if (p) {
		tag_re = strdup(p);
		char *tmp2 = strchr(tag_re, '/');
		if (tmp2 && *tmp2) *tmp2 = '\0';
		p = next_slash(p);
	}
	
	vrp.answer = VSB_new_auto();
	assert(vrp.answer != NULL);

	vrp.vsm = VSM_New();
	assert(vrp.vsm);
	if (!VSM_n_Arg(vrp.vsm, core->config->n_arg)) {
		VSB_printf(vrp.answer, "Error in creating shmlog: %s",
		    VSM_Error(vrp.vsm));
		VSB_finish(vrp.answer);
		http_reply(request->connection, 500, VSB_data(vrp.answer));
		goto cleanup;
	}

	if (VSM_Open(vrp.vsm) != 0) {
		VSB_printf(vrp.answer, "Error in opening shmlog: %s",
		    VSM_Error(vrp.vsm));
		VSB_finish(vrp.answer);
		http_reply(request->connection, 500, VSB_data(vrp.answer));
		goto cleanup;
	}
	
	vsl = VSL_New();
	assert(vsl);

	if (tag) {
		grouping = VSL_g_raw;
		
		if (VSL_Arg(vsl, 'i', tag) < 0) {
			VSB_printf(vrp.answer, "Unable to specify tag '%s': %s",
			    tag, VSL_Error(vsl));
			VSB_finish(vrp.answer);
			http_reply(request->connection, 500, VSB_data(vrp.answer));
			goto cleanup;
		}
		if (tag_re) {
			VSL_Arg(vsl,'I', tag_re);
		}
	}

	c = VSL_CursorVSM(vsl, vrp.vsm,
	    VSL_COPT_BATCH | VSL_COPT_TAILSTOP);
	if (c == NULL) {
		VSB_printf(vrp.answer, "Can't open log (%s)",
		    VSL_Error(vsl));
		VSB_finish(vrp.answer);
		http_reply(request->connection, 500, VSB_data(vrp.answer));
		goto cleanup;
	}

	
	vslq = VSLQ_New(vsl, &c, grouping, NULL);
	if (vslq == NULL) {
		VSB_clear(vrp.answer);
		VSB_printf(vrp.answer, "Error in creating query: %s",
		    VSL_Error(vsl));
		http_reply(request->connection, 500, VSB_data(vrp.answer));
		goto cleanup;
	}

	VSB_printf(vrp.answer, "{ \"log\": [");

	do {
		disp_status = VSLQ_Dispatch(vslq, vlog_cb_func, &vrp);
	} while (disp_status == 1 && vrp.entries < vrp.limit);

	VSB_printf(vrp.answer, "\n] }\n");

	assert(VSB_finish(vrp.answer) == 0);
	if (VSB_len(vrp.answer) > 1) {
		struct http_response *resp = http_mkresp(request->connection, 200, NULL);
		resp->data = VSB_data(vrp.answer);
		resp->ndata = VSB_len(vrp.answer);
		http_add_header(resp,"Content-Type","application/json");
		send_response(resp);
		http_free_resp(resp);
	} else {
		http_reply(request->connection, 500, "FAIL");
	}

 cleanup:
	free(tag);
	free(tag_re);
	VSB_delete(vrp.answer);
	if (vslq)
		VSLQ_Delete(&vslq);
	if (vsl)
		VSL_Delete(vsl);
	if (vrp.vsm)
		VSM_Delete(vrp.vsm);
	vrp.answer = NULL;
	return 0;
}

void vlog_init(struct agent_core_t *core)
{
	struct agent_plugin_t *plug;
	struct vlog_priv_t *priv;

	ALLOC_OBJ(priv);
	plug = plugin_find(core,"vlog");
	plug->data = priv;

	http_register_url(core, "/log", M_GET, vlog_reply, core);
}
Beispiel #18
0
/*
 * plugin_load()
 *
 * ³aduje wtyczkê o podanej nazwie.
 * 
 * 0/-1
 */
int plugin_load(const char *name, int prio, int quiet)
{
#ifdef SHARED_LIBS
	const gchar *env_ekg_plugins_path = NULL;
	char *init = NULL;
	gchar *lib;
	gchar *libname;
	GModule *plugin = NULL;
#endif

	plugin_t *pl;
	int (*plugin_init)() = NULL;

	g_assert(name);
	if (plugin_find(name)) {
		printq("plugin_already_loaded", name); 
		return -1;
	}

#ifdef SHARED_LIBS
	libname = g_strdup_printf("%s.la", name);
	if ((env_ekg_plugins_path = g_getenv("EKG_PLUGINS_PATH"))) {
		lib = g_build_filename(env_ekg_plugins_path, libname, NULL);
		plugin = ekg2_dlopen(lib);
		g_free(lib);

		if (!plugin) {
			lib = g_build_filename(env_ekg_plugins_path, name, libname, NULL);
			plugin = ekg2_dlopen(lib);
			g_free(lib);
		}
	}

	/* The following lets ekg2 load plugins when it is run directly from
	 * the source tree, without installation. This can be beneficial when
	 * developing the program, or for less knowlegeable users, who don't
	 * know how to or cannot for some other reason use installation prefix
	 * to install in their home directory. It might be also useful
	 * for win32-style installs.
	 */
	if (!plugin && rel_plugin_dir) {
		lib = g_build_filename(rel_plugin_dir, "plugins", name, libname, NULL);
		plugin = ekg2_dlopen(lib);
		g_free(lib);
	}

	if (!plugin) {
		lib = g_build_filename(PLUGINDIR, libname, NULL);
		plugin = ekg2_dlopen(lib);
		g_free(lib);
	}

	g_free(libname);
	/* prefer shared plugins */
	if (plugin) {
		init = g_strdup_printf("%s_plugin_init", name);
		plugin_init = ekg2_dlsym(plugin, init);
		g_free(init);
	}
#endif /* SHARED_LIBS */

#ifdef STATIC_LIBS
	/* if no shared plugin, fallback to the static one */
	if (!plugin_init) {
		STATIC_PLUGIN_DECLS
		STATIC_PLUGIN_CALLS

		if (plugin_init)
			debug_ok("[plugin] statically compiled in: %s\n", name);
	}
Beispiel #19
0
static int answer_to_connection (void *cls, struct MHD_Connection *connection,
                      const char *url, const char *method,
                      const char *version, const char *upload_data,
                      size_t *upload_data_size, void **con_cls)
{
	struct agent_core_t *core = (struct agent_core_t *)cls;
	struct http_priv_t *http;
	struct agent_plugin_t *plug;
	struct http_request request;
	struct connection_info_struct *con_info = NULL;
	int ret;

	(void)version;
	plug = plugin_find(core,"http");
	http = (struct http_priv_t *) plug->data;
	assert(plug);
	assert(http);


	if (NULL == *con_cls) {
		con_info = malloc (sizeof (struct connection_info_struct));
		assert(con_info);
		con_info->answerstring[0] = '\0';
		con_info->progress = 0;
		con_info->authed = 0;
		*con_cls = con_info;
		return MHD_YES;
	}
	con_info = *con_cls;
	assert(core->config->userpass);

	log_request(connection, http, method, url);

	if (0 == strcmp (method, "GET") || !strcmp(method, "HEAD") || !strcmp(method,"DELETE")) {
		ret = check_auth(connection, core, con_info);
		if (ret == 1)
			return MHD_YES;
		if (!strcmp(method,"DELETE")) {
			request.method = M_DELETE;
		} else {
			request.method = M_GET;
		}
		request.connection = connection;
		request.url = url;
		request.ndata = 0;
		if (find_listener(&request, http))
			return MHD_YES;
	}


	if (!strcmp(method, "POST") || !strcmp(method, "PUT")) {

		if (*upload_data_size != 0) {
			if (*upload_data_size + con_info->progress >= RCV_BUFFER) {
				warnlog(http->logger, "Client input exceeded buffer size of %u bytes. Dropping client.", RCV_BUFFER);

				 return MHD_NO;
			}
			memcpy(con_info->answerstring + con_info->progress,
				upload_data, *upload_data_size);
			con_info->progress += *upload_data_size;
			*upload_data_size = 0;

			return MHD_YES;
		} else if (NULL != con_info->answerstring){
			ret = check_auth(connection, core, con_info);
			if (ret == 1)
				return MHD_YES;
			if (!strcmp(method,"POST")) {
				request.method = M_POST;
			} else {
				request.method = M_PUT;
			}
			request.connection = connection;
			request.url = url;
			request.ndata = con_info->progress;
			request.data = con_info->answerstring;
			/*
			 * FIXME
			 */
			((char *)request.data)[con_info->progress] = '\0';
			if (find_listener(&request, http))
				return MHD_YES;
		}
	}
	if (request.method == M_GET && !strcmp(url, "/")) {
		if (http->help_page == NULL)
			http->help_page = make_help(http);
		assert (http->help_page);
		return send_response_ok(connection, http->help_page);
	}


	return send_response_fail (connection, "Failed\n");
}
Beispiel #20
0
		ret->answer = strdup("Varnishd disconnected");
		vadmin->state = 0;
		return;
	}
	logger(vadmin->logger, "Running %s",cmd);
	(void)VCLI_ReadResult(sock, &ret->status, &ret->answer, 2000);
	logger(vadmin->logger, "Got: %d ",ret->status, ret->answer);
}

static void
read_cmd(void *private, char *msg, struct ipc_ret_t *ret)
{
	struct agent_core_t *core = private;
	struct agent_plugin_t *plug;
	struct vadmin_config_t *vadmin;
	plug = plugin_find(core,"vadmin");
	vadmin = plug->data;
	if (vadmin->state == 0)
		cli_sock(vadmin, core);
	vadmin_run(vadmin, msg, ret);
}


void
vadmin_init(struct agent_core_t *core)
{
	struct vadmin_config_t *vadmin;
	struct agent_plugin_t *v;

	v  = plugin_find(core, "vadmin");
	v->ipc->cb = read_cmd;