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