00001 #include <EXTERN.h>
00002 #include "perl.h"
00003
00004 #include <net-snmp/net-snmp-config.h>
00005 #include <net-snmp/net-snmp-includes.h>
00006 #include <net-snmp/agent/net-snmp-agent-includes.h>
00007
00008 #include "snmp_perl.h"
00009
00010 static PerlInterpreter *my_perl;
00011
00012 void boot_DynaLoader(pTHX_ CV * cv);
00013
00014 void
00015 xs_init(pTHX)
00016 {
00017 char myfile[] = __FILE__;
00018 char modulename[] = "DynaLoader::boot_DynaLoader";
00019
00020
00021
00022 newXS(modulename, boot_DynaLoader, myfile);
00023 }
00024
00025 void
00026 maybe_source_perl_startup(void)
00027 {
00028 const char *embedargs[] = { "", "" };
00029 const char *perl_init_file = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
00030 NETSNMP_DS_AGENT_PERL_INIT_FILE);
00031 char init_file[SNMP_MAXBUF];
00032
00033 static int have_done_init = 0;
00034
00035 if (have_done_init)
00036 return;
00037 have_done_init = 1;
00038
00039 if (!perl_init_file) {
00040 snprintf(init_file, sizeof(init_file) - 1,
00041 "%s/%s", SNMPSHAREPATH, "snmp_perl.pl");
00042 perl_init_file = init_file;
00043 }
00044 embedargs[1] = perl_init_file;
00045
00046 DEBUGMSGTL(("perl", "initializing perl (%s)\n", embedargs[1]));
00047 my_perl = perl_alloc();
00048 if (!my_perl)
00049 goto bail_out;
00050
00051 perl_construct(my_perl);
00052
00053 #ifdef PERL_EXIT_DESTRUCT_END
00054 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
00055 #endif
00056
00057 if (perl_parse(my_perl, xs_init, 2, (char **) embedargs, NULL))
00058 goto bail_out;
00059
00060 if (perl_run(my_perl))
00061 goto bail_out;
00062
00063 DEBUGMSGTL(("perl", "done initializing perl\n"));
00064
00065 return;
00066
00067 bail_out:
00068 snmp_log(LOG_ERR, "embedded perl support failed to initialize\n");
00069 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
00070 NETSNMP_DS_AGENT_DISABLE_PERL, 1);
00071 return;
00072 }
00073
00074 void
00075 do_something_perlish(char *something)
00076 {
00077 if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
00078 NETSNMP_DS_AGENT_DISABLE_PERL)) {
00079 return;
00080 }
00081 maybe_source_perl_startup();
00082 if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
00083 NETSNMP_DS_AGENT_DISABLE_PERL)) {
00084 return;
00085 }
00086 DEBUGMSGTL(("perl", "calling perl\n"));
00087 #if defined(HAVE_EVAL_PV) || defined(eval_pv)
00088
00089 eval_pv(something, TRUE);
00090 #else
00091 #if defined(HAVE_PERL_EVAL_PV_LC) || defined(perl_eval_pv)
00092
00093 perl_eval_pv(something, TRUE);
00094 #else
00095 #ifdef HAVE_PERL_EVAL_PV_UC
00096
00097 Perl_eval_pv(my_perl, something, TRUE);
00098 #else
00099 #error embedded perl broken
00100 #endif
00101 #endif
00102 #endif
00103 DEBUGMSGTL(("perl", "finished calling perl\n"));
00104 }
00105
00106 void
00107 perl_config_handler(const char *token, char *line)
00108 {
00109 do_something_perlish(line);
00110 }
00111
00112 void
00113 init_perl(void)
00114 {
00115 const char *appid = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
00116 NETSNMP_DS_LIB_APPTYPE);
00117 const char *defaultid = "snmpd";
00118
00119 if (!appid) {
00120 appid = defaultid;
00121 }
00122
00123
00124
00125
00126 snmpd_register_config_handler("perl", perl_config_handler, NULL,
00127 "PERLCODE");
00128
00129
00130
00131
00132 netsnmp_ds_register_premib(ASN_OCTET_STR, appid, "perlInitFile",
00133 NETSNMP_DS_APPLICATION_ID,
00134 NETSNMP_DS_AGENT_PERL_INIT_FILE);
00135
00136
00137
00138
00139 netsnmp_ds_register_premib(ASN_BOOLEAN, appid, "disablePerl",
00140 NETSNMP_DS_APPLICATION_ID,
00141 NETSNMP_DS_AGENT_DISABLE_PERL);
00142 }
00143
00144 void
00145 shutdown_perl(void)
00146 {
00147 if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
00148 NETSNMP_DS_AGENT_DISABLE_PERL) ||
00149 my_perl == NULL) {
00150 return;
00151 }
00152 DEBUGMSGTL(("perl", "shutting down perl\n"));
00153 perl_destruct(my_perl);
00154 perl_free(my_perl);
00155 DEBUGMSGTL(("perl", "finished shutting down perl\n"));
00156 }