Blame agent/snmp_perl.c

Packit Service b38f0b
#if defined(_WIN32) && !defined(_WIN32_WINNT)
Packit Service b38f0b
#define _WIN32_WINNT 0x501
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#include <EXTERN.h>
Packit Service b38f0b
#include "perl.h"
Packit Service b38f0b
Packit Service b38f0b
#include <net-snmp/net-snmp-config.h>
Packit Service b38f0b
#include <net-snmp/net-snmp-includes.h>
Packit Service b38f0b
#include <net-snmp/agent/net-snmp-agent-includes.h>
Packit Service b38f0b
Packit Service b38f0b
#include "snmp_perl.h"
Packit Service b38f0b
Packit Service b38f0b
static PerlInterpreter *my_perl;
Packit Service b38f0b
Packit Service b38f0b
void            boot_DynaLoader(pTHX_ CV * cv);
Packit Service b38f0b
Packit Service b38f0b
void
Packit Service b38f0b
xs_init(pTHX)
Packit Service b38f0b
{
Packit Service b38f0b
    char            myfile[] = __FILE__;
Packit Service b38f0b
    char            modulename[] = "DynaLoader::boot_DynaLoader";
Packit Service b38f0b
    /*
Packit Service b38f0b
     * DynaLoader is a special case 
Packit Service b38f0b
     */
Packit Service b38f0b
    newXS(modulename, boot_DynaLoader, myfile);
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
void
Packit Service b38f0b
maybe_source_perl_startup(void)
Packit Service b38f0b
{
Packit Service b38f0b
    int             argc;
Packit Service b38f0b
    char          **argv;
Packit Service b38f0b
    char          **env;
Packit Service b38f0b
    char           *embedargs[] = { NULL, NULL };
Packit Service b38f0b
    const char     *perl_init_file = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
Packit Service b38f0b
							   NETSNMP_DS_AGENT_PERL_INIT_FILE);
Packit Service b38f0b
    char            init_file[SNMP_MAXBUF];
Packit Service b38f0b
    int             res;
Packit Service b38f0b
Packit Service b38f0b
    static int      have_done_init = 0;
Packit Service b38f0b
Packit Service b38f0b
    if (have_done_init)
Packit Service b38f0b
        return;
Packit Service b38f0b
    have_done_init = 1;
Packit Service b38f0b
Packit Service b38f0b
    embedargs[0] = strdup("");
Packit Service b38f0b
    if (!perl_init_file) {
Packit Service b38f0b
        snprintf(init_file, sizeof(init_file) - 1,
Packit Service b38f0b
                 "%s/%s", SNMPSHAREPATH, "snmp_perl.pl");
Packit Service b38f0b
        perl_init_file = init_file;
Packit Service b38f0b
    }
Packit Service b38f0b
    embedargs[1] = strdup(perl_init_file);
Packit Service b38f0b
Packit Service b38f0b
    DEBUGMSGTL(("perl", "initializing perl (%s)\n", embedargs[1]));
Packit Service b38f0b
    argc = 0;
Packit Service b38f0b
    argv = NULL;
Packit Service b38f0b
    env = NULL;
Packit Service b38f0b
    PERL_SYS_INIT3(&argc, &argv, &env;;
Packit Service b38f0b
    my_perl = perl_alloc();
Packit Service b38f0b
    if (!my_perl) {
Packit Service b38f0b
        snmp_log(LOG_ERR,
Packit Service b38f0b
                 "embedded perl support failed to initialize (perl_alloc())\n");
Packit Service b38f0b
        goto bail_out;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    perl_construct(my_perl);
Packit Service b38f0b
Packit Service b38f0b
#ifdef PERL_EXIT_DESTRUCT_END
Packit Service b38f0b
    PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
    res = perl_parse(my_perl, xs_init, 2, embedargs, NULL);
Packit Service b38f0b
    if (res) {
Packit Service b38f0b
        snmp_log(LOG_ERR,
Packit Service b38f0b
                 "embedded perl support failed to initialize (perl_parse(%s)"
Packit Service b38f0b
                 " returned %d)\n", embedargs[1], res);
Packit Service b38f0b
        goto bail_out;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    res = perl_run(my_perl);
Packit Service b38f0b
    if (res) {
Packit Service b38f0b
        snmp_log(LOG_ERR,
Packit Service b38f0b
                 "embedded perl support failed to initialize (perl_run()"
Packit Service b38f0b
                 " returned %d)\n", res);
Packit Service b38f0b
        goto bail_out;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    free(embedargs[0]);
Packit Service b38f0b
    free(embedargs[1]);
Packit Service b38f0b
Packit Service b38f0b
    DEBUGMSGTL(("perl", "done initializing perl\n"));
Packit Service b38f0b
Packit Service b38f0b
    return;
Packit Service b38f0b
Packit Service b38f0b
  bail_out:
Packit Service b38f0b
    free(embedargs[0]);
Packit Service b38f0b
    free(embedargs[1]);
Packit Service b38f0b
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit Service b38f0b
			   NETSNMP_DS_AGENT_DISABLE_PERL, 1);
Packit Service b38f0b
    return;
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
void
Packit Service b38f0b
do_something_perlish(char *something)
Packit Service b38f0b
{
Packit Service b38f0b
    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit Service b38f0b
			       NETSNMP_DS_AGENT_DISABLE_PERL)) {
Packit Service b38f0b
        return;
Packit Service b38f0b
    }
Packit Service b38f0b
    maybe_source_perl_startup();
Packit Service b38f0b
    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit Service b38f0b
			       NETSNMP_DS_AGENT_DISABLE_PERL)) {
Packit Service b38f0b
        return;
Packit Service b38f0b
    }
Packit Service b38f0b
    DEBUGMSGTL(("perl", "calling perl\n"));
Packit Service b38f0b
#if defined(HAVE_EVAL_PV) || defined(eval_pv)
Packit Service b38f0b
    /* newer perl */
Packit Service b38f0b
    eval_pv(something, TRUE);
Packit Service b38f0b
#else
Packit Service b38f0b
#if defined(HAVE_PERL_EVAL_PV_LC) || defined(perl_eval_pv)
Packit Service b38f0b
    /* older perl? */
Packit Service b38f0b
    perl_eval_pv(something, TRUE);
Packit Service b38f0b
#else /* HAVE_PERL_EVAL_PV_LC */
Packit Service b38f0b
#ifdef HAVE_PERL_EVAL_PV_UC
Packit Service b38f0b
    /* older perl? */
Packit Service b38f0b
    Perl_eval_pv(my_perl, something, TRUE);
Packit Service b38f0b
#else /* !HAVE_PERL_EVAL_PV_UC */
Packit Service b38f0b
#error embedded perl broken 
Packit Service b38f0b
#endif /* !HAVE_PERL_EVAL_PV_LC */
Packit Service b38f0b
#endif /* !HAVE_PERL_EVAL_PV_UC */
Packit Service b38f0b
#endif /* !HAVE_EVAL_PV */
Packit Service b38f0b
    DEBUGMSGTL(("perl", "finished calling perl\n"));
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
void
Packit Service b38f0b
perl_config_handler(const char *token, char *line)
Packit Service b38f0b
{
Packit Service b38f0b
    do_something_perlish(line);
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
void
Packit Service b38f0b
init_perl(void)
Packit Service b38f0b
{
Packit Service b38f0b
    const char     *appid = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
Packit Service b38f0b
						  NETSNMP_DS_LIB_APPTYPE);
Packit Service b38f0b
    const char     *defaultid = "snmpd";
Packit Service b38f0b
Packit Service b38f0b
    if (!appid) {
Packit Service b38f0b
        appid = defaultid;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * register config handlers 
Packit Service b38f0b
     */
Packit Service b38f0b
    snmpd_register_config_handler("perl", perl_config_handler, NULL,
Packit Service b38f0b
                                  "PERLCODE");
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * define the perlInitFile token to point to an init file 
Packit Service b38f0b
     */
Packit Service b38f0b
    netsnmp_ds_register_premib(ASN_OCTET_STR, appid, "perlInitFile",
Packit Service b38f0b
			       NETSNMP_DS_APPLICATION_ID, 
Packit Service b38f0b
			       NETSNMP_DS_AGENT_PERL_INIT_FILE);
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * define the perlInitFile token to point to an init file 
Packit Service b38f0b
     */
Packit Service b38f0b
    netsnmp_ds_register_premib(ASN_BOOLEAN, appid, "disablePerl",
Packit Service b38f0b
			       NETSNMP_DS_APPLICATION_ID,
Packit Service b38f0b
			       NETSNMP_DS_AGENT_DISABLE_PERL);
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
void
Packit Service b38f0b
shutdown_perl(void)
Packit Service b38f0b
{
Packit Service b38f0b
    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit Service b38f0b
			       NETSNMP_DS_AGENT_DISABLE_PERL) ||
Packit Service b38f0b
        my_perl == NULL) {
Packit Service b38f0b
        return;
Packit Service b38f0b
    }
Packit Service b38f0b
    DEBUGMSGTL(("perl", "shutting down perl\n"));
Packit Service b38f0b
    perl_destruct(my_perl);
Packit Service b38f0b
    my_perl = NULL;
Packit Service b38f0b
    DEBUGMSGTL(("perl", "finished shutting down perl\n"));
Packit Service b38f0b
}