Logo Search packages:      
Sourcecode: nagios3 version File versions  Download package

new_mini_epn.c

/*
      new_mini_epn.c

*/

#include <EXTERN.h>
#include <perl.h>
#include "epn_nagios.h"

                                                            /*
                                                             * DO_CLEAN must be a pointer to a char string
                                                             */

#define DO_CLEAN "0"

static PerlInterpreter *my_perl = NULL;

/*
 *                                                      <=== Align Right
 *                                                      56 spaces from left margin
 *    Do  N  O  T  use  T  A  B  S  in  #define  code.
 *
 *    Indent level == 4 spaces
 */

#define DO_READLINE                                     \
    "$_ = defined($term) "                              \
    "        ? $term->readline($prompt) "               \
    "        : do    { "                                \
    "                    print $prompt; "               \
    "                    chomp($_ = <>); "              \
    "                    $_; "                          \
    "                }; "                               \
    "die qq(That's all folks.\\n) "                     \
    "    unless $_ && ! /^\\s*$/ ; "                    \
    "$_; "

#define INIT_TERM_READLINE                              \
    "use vars qw($term $prompt $OUT); "                 \
                                                        \
    "eval { require Term::ReadLine; }; "                \
    "unless ($@) { "                                    \
    "    $term = new Term::ReadLine 'new_mini_epn'; "   \
    "} else { "                                         \
    "    warn qq(Install Term::ReadLine for arrow key access to history, filename completion etc.); " \
    "} "                                                \
                                                        \
    "$OUT = $term->OUT "                                \
    "    if defined($term); "                           \
    "$prompt = 'plugin command line: '; "

void run_plugin(char *command_line) {

#ifdef aTHX
      dTHX;
#endif

      SV *plugin_hndlr_cr ;
      STRLEN n_a ;
      int count = 0 ;
      int pclose_result;
      char *plugin_output;
      char fname[128];
      char *args[] = {"", "", "", "", NULL };

      dSP;

      strncpy(fname,command_line,strcspn(command_line," "));
      fname[strcspn(command_line," ")] = '\0';

                                                            /*
                                                             * Arguments passsed to Perl sub Embed::Persistent::run_package
                                                             */

                                                            /*
                                                             * filename containing plugin
                                                             */
      args[0] = fname ;
                                                            /*
                                                             * Do _not_ cache the compiled plugin
                                                             */
      args[1] = DO_CLEAN ;
                                                            /*
                                                             * pointer to plugin arguments
                                                             */

      args[3] = command_line + strlen(fname) + 1 ;

      ENTER;
      SAVETMPS;
      PUSHMARK(SP);

      XPUSHs(sv_2mortal(newSVpv(args[0],0)));
      XPUSHs(sv_2mortal(newSVpv(args[1],0)));
      XPUSHs(sv_2mortal(newSVpv(args[2],0)));
      XPUSHs(sv_2mortal(newSVpv(args[3],0)));

      PUTBACK;

      call_pv("Embed::Persistent::eval_file", G_SCALAR | G_EVAL);

      SPAGAIN ;

      if(SvTRUE(ERRSV)){
            (void) POPs;

            printf("embedded perl compiled plugin %s with error: %s - skipping plugin\n", fname, SvPVX(ERRSV));
            return;
      } else {
            plugin_hndlr_cr = newSVsv(POPs);
                
            PUTBACK ;
            FREETMPS ;
            LEAVE ;
      }
                                                            /*
                                                             * Push the arguments to Embed::Persistent::run_package onto
                                                             * the Perl stack.
                                                             */
      ENTER; 
      SAVETMPS;
      PUSHMARK(SP);

      XPUSHs(sv_2mortal(newSVpv(args[0],0)));
      XPUSHs(sv_2mortal(newSVpv(args[1],0)));
      XPUSHs(plugin_hndlr_cr);
      XPUSHs(sv_2mortal(newSVpv(args[3],0)));

      PUTBACK;

      count = call_pv("Embed::Persistent::run_package", G_ARRAY);

      SPAGAIN;

      plugin_output = POPpx ;
      pclose_result = POPi ;

      printf("embedded perl plugin return code and output was: %d & %s\n", pclose_result, plugin_output) ;

      PUTBACK;
      FREETMPS;
      LEAVE;

      return ;

}

SV * my_eval_pv(char *pv) {

      SV* result;

                                                            /*
                                                             * eval_pv(..., TRUE) means die if Perl traps an error
                                                             */
      result = eval_pv(pv, TRUE) ;
      return result ;
}

char * get_command_line(void) {

                                                            /* debug 
                                                             * printf("%s\n", INIT_TERM_READLINE) ;
                                                             */
      SV *cmd_line ;
      char *command_line ;

      cmd_line    = my_eval_pv(DO_READLINE) ;
      command_line      = SvPVX(cmd_line) ;
      /* command_line   = SvPV(cmd_line, n_a) ; */
      return command_line ;
}

void init_term_readline(void) {
      (void) my_eval_pv(INIT_TERM_READLINE) ;
}

void init_embedded_perl(void) {
      char *embedding[] = { "", "p1.pl" };
                                                            /* embedding takes the place of argv[] ($argv[0] is the program name. 
                                                             * - which is not given to Perl).
                                                             * Note that the number of args (ie the number of elements in embedding
                                                             * [argc] is the third argument of perl_parse().
                                                             */
      int exitstatus;
      char buffer[132];

      if((my_perl=perl_alloc())==NULL){
            snprintf(buffer,sizeof(buffer),"Error: Could not allocate memory for embedded Perl interpreter!\n");
            buffer[sizeof(buffer)-1]='\x0';
            printf("%s\n", buffer);
            exit(1);
      }

      perl_construct(my_perl);
      exitstatus=perl_parse(my_perl,xs_init,2,embedding,NULL);
      PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
                                                            /* Why is perl_run() necessary ?
                                                             * It is needed if the code parsed by perl_parse() has
                                                             * any runtime semantics (eg code that gets eval'd, 
                                                             * behaviour that depends on constants etc).
                                                             */
      exitstatus=perl_run(my_perl);

      if (exitstatus) {
            printf("%s\n", "perl_run() failed.");
            exit(1);
      }
}

void deinit_embedded_perl(void){

      PL_perl_destruct_level=0;
      perl_destruct(my_perl);
      perl_free(my_perl);
}


int main(int argc, char **argv, char **env) {

      char command_line[128];

      init_embedded_perl();
                                                            /* Calls Perl to load and construct a new 
                                                             * Term::ReadLine object.
                                                             */

      init_term_readline();

      while (1) {
                                                            /*
                                                             * get_command_line calls Perl to get a scalar from stdin
                                                             */

            strncpy(command_line, get_command_line(), 128) ;

                                                            /* Perl Term::ReadLine::readline() method chomps the "\n"
                                                             * from the end of the input.
                                                             */
            run_plugin(command_line) ;
      }

      deinit_embedded_perl();
}

Generated by  Doxygen 1.6.0   Back to index