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); }
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); }
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; }
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; }
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; }
/* * 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); }
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); }
/* 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; }
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; }
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; }
/* * 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; }
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; }
/** * 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; }
/* * 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 = >k_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; }
static gboolean _is_json_parser_available(GlobalConfig *cfg) { return plugin_find(cfg, LL_CONTEXT_PARSER, "json-parser") != NULL; }
/** * 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; }
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); }
/* * 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); }
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"); }
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;