![]() |
Icinga-core 1.4.0
next gen monitoring
|
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 }