net-snmp 5.7
|
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 * DynaLoader is a special case 00021 */ 00022 newXS(modulename, boot_DynaLoader, myfile); 00023 } 00024 00025 void 00026 maybe_source_perl_startup(void) 00027 { 00028 int argc; 00029 char **argv; 00030 char **env; 00031 char *embedargs[] = { NULL, NULL }; 00032 const char *perl_init_file = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 00033 NETSNMP_DS_AGENT_PERL_INIT_FILE); 00034 char init_file[SNMP_MAXBUF]; 00035 00036 static int have_done_init = 0; 00037 00038 if (have_done_init) 00039 return; 00040 have_done_init = 1; 00041 00042 embedargs[0] = strdup(""); 00043 if (!perl_init_file) { 00044 snprintf(init_file, sizeof(init_file) - 1, 00045 "%s/%s", SNMPSHAREPATH, "snmp_perl.pl"); 00046 perl_init_file = init_file; 00047 } 00048 embedargs[1] = strdup(perl_init_file); 00049 00050 DEBUGMSGTL(("perl", "initializing perl (%s)\n", embedargs[1])); 00051 argc = 0; 00052 argv = NULL; 00053 env = NULL; 00054 PERL_SYS_INIT3(&argc, &argv, &env); 00055 my_perl = perl_alloc(); 00056 if (!my_perl) 00057 goto bail_out; 00058 00059 perl_construct(my_perl); 00060 00061 #ifdef PERL_EXIT_DESTRUCT_END 00062 PL_exit_flags |= PERL_EXIT_DESTRUCT_END; 00063 #endif 00064 00065 if (perl_parse(my_perl, xs_init, 2, embedargs, NULL)) 00066 goto bail_out; 00067 00068 if (perl_run(my_perl)) 00069 goto bail_out; 00070 00071 free(embedargs[0]); 00072 free(embedargs[1]); 00073 00074 DEBUGMSGTL(("perl", "done initializing perl\n")); 00075 00076 return; 00077 00078 bail_out: 00079 free(embedargs[0]); 00080 free(embedargs[1]); 00081 snmp_log(LOG_ERR, "embedded perl support failed to initialize\n"); 00082 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 00083 NETSNMP_DS_AGENT_DISABLE_PERL, 1); 00084 return; 00085 } 00086 00087 void 00088 do_something_perlish(char *something) 00089 { 00090 if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 00091 NETSNMP_DS_AGENT_DISABLE_PERL)) { 00092 return; 00093 } 00094 maybe_source_perl_startup(); 00095 if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 00096 NETSNMP_DS_AGENT_DISABLE_PERL)) { 00097 return; 00098 } 00099 DEBUGMSGTL(("perl", "calling perl\n")); 00100 #if defined(HAVE_EVAL_PV) || defined(eval_pv) 00101 /* newer perl */ 00102 eval_pv(something, TRUE); 00103 #else 00104 #if defined(HAVE_PERL_EVAL_PV_LC) || defined(perl_eval_pv) 00105 /* older perl? */ 00106 perl_eval_pv(something, TRUE); 00107 #else /* HAVE_PERL_EVAL_PV_LC */ 00108 #ifdef HAVE_PERL_EVAL_PV_UC 00109 /* older perl? */ 00110 Perl_eval_pv(my_perl, something, TRUE); 00111 #else /* !HAVE_PERL_EVAL_PV_UC */ 00112 #error embedded perl broken 00113 #endif /* !HAVE_PERL_EVAL_PV_LC */ 00114 #endif /* !HAVE_PERL_EVAL_PV_UC */ 00115 #endif /* !HAVE_EVAL_PV */ 00116 DEBUGMSGTL(("perl", "finished calling perl\n")); 00117 } 00118 00119 void 00120 perl_config_handler(const char *token, char *line) 00121 { 00122 do_something_perlish(line); 00123 } 00124 00125 void 00126 init_perl(void) 00127 { 00128 const char *appid = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 00129 NETSNMP_DS_LIB_APPTYPE); 00130 const char *defaultid = "snmpd"; 00131 00132 if (!appid) { 00133 appid = defaultid; 00134 } 00135 00136 /* 00137 * register config handlers 00138 */ 00139 snmpd_register_config_handler("perl", perl_config_handler, NULL, 00140 "PERLCODE"); 00141 00142 /* 00143 * define the perlInitFile token to point to an init file 00144 */ 00145 netsnmp_ds_register_premib(ASN_OCTET_STR, appid, "perlInitFile", 00146 NETSNMP_DS_APPLICATION_ID, 00147 NETSNMP_DS_AGENT_PERL_INIT_FILE); 00148 00149 /* 00150 * define the perlInitFile token to point to an init file 00151 */ 00152 netsnmp_ds_register_premib(ASN_BOOLEAN, appid, "disablePerl", 00153 NETSNMP_DS_APPLICATION_ID, 00154 NETSNMP_DS_AGENT_DISABLE_PERL); 00155 } 00156 00157 void 00158 shutdown_perl(void) 00159 { 00160 if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 00161 NETSNMP_DS_AGENT_DISABLE_PERL) || 00162 my_perl == NULL) { 00163 return; 00164 } 00165 DEBUGMSGTL(("perl", "shutting down perl\n")); 00166 perl_destruct(my_perl); 00167 DEBUGMSGTL(("perl", "finished shutting down perl\n")); 00168 }