Icinga-core 1.4.0
next gen monitoring
contrib/new_mini_epn.c
Go to the documentation of this file.
00001 /*
00002         new_mini_epn.c
00003 
00004 */
00005 
00006 #include <EXTERN.h>
00007 #include <perl.h>
00008 #include "epn_icinga.h"
00009 
00010                                                                                 /*
00011                                                                                  * DO_CLEAN must be a pointer to a char string
00012                                                                                  */
00013 
00014 #define DO_CLEAN "0"
00015 #define MAX_INPUT_CHARS 1024
00016 
00017 static PerlInterpreter *my_perl = NULL;
00018 
00019 /*
00020  *                                                      <=== Align Right
00021  *                                                      56 spaces from left margin
00022  *    Do  N  O  T  use  T  A  B  S  in  #define  code.
00023  *
00024  *    Indent level == 4 spaces
00025  */
00026 
00027 #define DO_READLINE                                     \
00028     "$_ = defined($term) "                              \
00029     "        ? $term->readline($prompt) "               \
00030     "        : do    { "                                \
00031     "                    print $prompt; "               \
00032     "                    chomp($_ = <>); "              \
00033     "                    $_; "                          \
00034     "                }; "                               \
00035     "die qq(That's all folks.\\n) "                     \
00036     "    unless $_ && ! /^\\s*$/ ; "                    \
00037     "$_; "
00038 
00039 #define INIT_TERM_READLINE                              \
00040     "use vars qw($term $prompt $OUT); "                 \
00041                                                         \
00042     "eval { require Term::ReadLine; }; "                \
00043     "unless ($@) { "                                    \
00044     "    $term = new Term::ReadLine 'new_mini_epn'; "   \
00045     "} else { "                                         \
00046     "    warn qq(Install Term::ReadLine for arrow key access to history, filename completion etc.); " \
00047     "} "                                                \
00048                                                         \
00049     "$OUT = $term->OUT "                                \
00050     "    if defined($term); "                           \
00051     "$prompt = 'plugin command line: '; "
00052 
00053 void run_plugin(char *command_line) {
00054 
00055 #ifdef aTHX
00056         dTHX;
00057 #endif
00058 
00059         SV *plugin_hndlr_cr ;
00060         STRLEN n_a ;
00061         int count = 0 ;
00062         int pclose_result;
00063         char *plugin_output;
00064         char fname[MAX_INPUT_CHARS];
00065         char *args[] = {"", "", "", "", NULL };
00066 
00067         dSP;
00068 
00069         strncpy(fname,command_line,strcspn(command_line," "));
00070         fname[strcspn(command_line," ")] = '\0';
00071 
00072                                                                                 /*
00073                                                                                  * Arguments passsed to Perl sub Embed::Persistent::run_package
00074                                                                                  */
00075 
00076                                                                                 /*
00077                                                                                  * filename containing plugin
00078                                                                                  */
00079         args[0] = fname ;
00080                                                                                 /*
00081                                                                                  * Do _not_ cache the compiled plugin
00082                                                                                  */
00083         args[1] = DO_CLEAN ;
00084                                                                                 /*
00085                                                                                  * pointer to plugin arguments
00086                                                                                  */
00087 
00088         args[3] = command_line + strlen(fname) + 1 ;
00089 
00090         ENTER;
00091         SAVETMPS;
00092         PUSHMARK(SP);
00093 
00094         XPUSHs(sv_2mortal(newSVpv(args[0],0)));
00095         XPUSHs(sv_2mortal(newSVpv(args[1],0)));
00096         XPUSHs(sv_2mortal(newSVpv(args[2],0)));
00097         XPUSHs(sv_2mortal(newSVpv(args[3],0)));
00098 
00099         PUTBACK;
00100 
00101         call_pv("Embed::Persistent::eval_file", G_SCALAR | G_EVAL);
00102 
00103         SPAGAIN ;
00104 
00105         if(SvTRUE(ERRSV)){
00106                 (void) POPs;
00107 
00108                 printf("embedded perl compiled plugin %s with error: %s - skipping plugin\n", fname, SvPVX(ERRSV));
00109                 return;
00110         } else {
00111                 plugin_hndlr_cr = newSVsv(POPs);
00112 
00113                 PUTBACK ;
00114                 FREETMPS ;
00115                 LEAVE ;
00116         }
00117                                                                                 /*
00118                                                                                  * Push the arguments to Embed::Persistent::run_package onto
00119                                                                                  * the Perl stack.
00120                                                                                  */
00121         ENTER;
00122         SAVETMPS;
00123         PUSHMARK(SP);
00124 
00125         XPUSHs(sv_2mortal(newSVpv(args[0],0)));
00126         XPUSHs(sv_2mortal(newSVpv(args[1],0)));
00127         XPUSHs(plugin_hndlr_cr);
00128         XPUSHs(sv_2mortal(newSVpv(args[3],0)));
00129 
00130         PUTBACK;
00131 
00132         count = call_pv("Embed::Persistent::run_package", G_ARRAY);
00133 
00134         SPAGAIN;
00135 
00136         plugin_output = POPpx ;
00137         pclose_result = POPi ;
00138 
00139         printf("embedded perl plugin return code and output was: %d & %s\n", pclose_result, plugin_output) ;
00140 
00141         PUTBACK;
00142         FREETMPS;
00143         LEAVE;
00144 
00145         return ;
00146 
00147 }
00148 
00149 SV * my_eval_pv(char *pv) {
00150 
00151         SV* result;
00152 
00153                                                                                 /*
00154                                                                                  * eval_pv(..., TRUE) means die if Perl traps an error
00155                                                                                  */
00156         result = eval_pv(pv, TRUE) ;
00157         return result ;
00158 }
00159 
00160 char * get_command_line(void) {
00161 
00162                                                                                 /* debug
00163                                                                                  * printf("%s\n", INIT_TERM_READLINE) ;
00164                                                                                  */
00165         SV *cmd_line ;
00166         char *command_line ;
00167 
00168         cmd_line        = my_eval_pv(DO_READLINE) ;
00169         command_line    = SvPVX(cmd_line) ;
00170         /* command_line = SvPV(cmd_line, n_a) ; */
00171         return command_line ;
00172 }
00173 
00174 void init_term_readline(void) {
00175         (void) my_eval_pv(INIT_TERM_READLINE) ;
00176 }
00177 
00178 void init_embedded_perl(void) {
00179         char *embedding[] = { "", "p1.pl" };
00180                                                                                 /* embedding takes the place of argv[] ($argv[0] is the program name.
00181                                                                                  * - which is not given to Perl).
00182                                                                                  * Note that the number of args (ie the number of elements in embedding
00183                                                                                  * [argc] is the third argument of perl_parse().
00184                                                                                  */
00185         int exitstatus;
00186         char buffer[132];
00187 
00188         if((my_perl=perl_alloc())==NULL){
00189                 snprintf(buffer,sizeof(buffer),"Error: Could not allocate memory for embedded Perl interpreter!\n");
00190                 buffer[sizeof(buffer)-1]='\x0';
00191                 printf("%s\n", buffer);
00192                 exit(1);
00193         }
00194 
00195         perl_construct(my_perl);
00196         exitstatus=perl_parse(my_perl,xs_init,2,embedding,NULL);
00197         PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
00198                                                                                 /* Why is perl_run() necessary ?
00199                                                                                  * It is needed if the code parsed by perl_parse() has
00200                                                                                  * any runtime semantics (eg code that gets eval'd,
00201                                                                                  * behaviour that depends on constants etc).
00202                                                                                  */
00203         exitstatus=perl_run(my_perl);
00204 
00205         if (exitstatus) {
00206                 printf("%s\n", "perl_run() failed.");
00207                 exit(1);
00208         }
00209 }
00210 
00211 void deinit_embedded_perl(void){
00212 
00213         PL_perl_destruct_level=0;
00214         perl_destruct(my_perl);
00215         perl_free(my_perl);
00216 }
00217 
00218 
00219 int main(int argc, char **argv, char **env) {
00220         char *cmd,*end;
00221 
00222         init_embedded_perl();
00223                                                                                 /* Calls Perl to load and construct a new
00224                                                                                  * Term::ReadLine object.
00225                                                                                  */
00226 
00227         init_term_readline();
00228 
00229         while (1) {
00230                                                                                 /*
00231                                                                                  * get_command_line calls Perl to get a scalar from stdin
00232                                                                                  */
00233 
00234                                                                                 /* Perl Term::ReadLine::readline() method chomps the "\n"
00235                                                                                  * from the end of the input.
00236                                                                                  */
00237 
00238                 /* Allow any length command line */
00239                 cmd = (get_command_line ()) ;
00240 
00241                 /* trim leading whitespace */
00242                 while (isspace (*cmd)) cmd++;
00243 
00244                 /* trim trailing whitespace */
00245                 end = cmd + strlen (cmd) - 1;
00246                 while (end > cmd && isspace (*end)) end--;
00247 
00248                 /* write new null terminator */
00249                 *(end+1) = 0;
00250 
00251                 run_plugin (cmd) ;
00252 
00253         }
00254 
00255         deinit_embedded_perl();
00256 }
 All Data Structures Files Functions Variables Typedefs Defines