LCOV - code coverage report
Current view: top level - src - run_script.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 59 81 72.8 %
Date: 2018-09-29 15:42:53 Functions: 5 5 100.0 %

          Line data    Source code
       1             : #include "burp.h"
       2             : #include "alloc.h"
       3             : #include "asfd.h"
       4             : #include "conf.h"
       5             : #include "fzp.h"
       6             : #include "forkchild.h"
       7             : #include "handy.h"
       8             : #include "log.h"
       9             : #include "strlist.h"
      10             : #include "run_script.h"
      11             : 
      12             : #ifndef HAVE_WIN32
      13             : 
      14           2 : static int log_script_output(struct asfd *asfd, struct fzp **fzp,
      15             :         struct conf **confs,
      16             :         int do_logp, int log_remote, int is_stderr, char **logbuf)
      17             : {
      18           2 :         char buf[256]="";
      19           2 :         if(!fzp || !*fzp) return 0;
      20           2 :         if(fzp_gets(*fzp, buf, sizeof(buf)))
      21             :         {
      22           0 :                 if(logbuf && astrcat(logbuf, buf, __func__)) return -1;
      23           0 :                 if(log_remote)
      24             :                 {
      25             :                         // logm and low will also log to stdout.
      26           0 :                         if(is_stderr) logw(asfd, confs?get_cntr(confs):NULL,
      27             :                                 "%s", buf);
      28             :                         else
      29           0 :                                 logm(asfd, confs, "%s", buf);
      30             :                 }
      31             :                 else
      32             :                 {
      33           0 :                         if(do_logp)
      34             :                         {
      35           0 :                                 if(is_stderr)
      36           0 :                                         logp("WARNING: %s", buf);
      37             :                                 else
      38           0 :                                         logp("MESSAGE: %s", buf);
      39             :                         }
      40             :                         else
      41             :                         {
      42             :                                 // logc does not print a prefix
      43           0 :                                 logc("%s", buf);
      44             :                         }
      45             :                 }
      46             :         }
      47           2 :         if(fzp_eof(*fzp)) fzp_close(fzp);
      48             :         return 0;
      49             : }
      50             : 
      51             : static int got_sigchld=0;
      52             : static int run_script_status=-1;
      53             : 
      54           1 : static void run_script_sigchld_handler(__attribute__ ((unused)) int sig)
      55             : {
      56             :         //printf("in run_script_sigchld_handler\n");
      57           1 :         got_sigchld=1;
      58           1 :         run_script_status=-1;
      59           1 :         waitpid(-1, &run_script_status, 0);
      60           1 : }
      61             : 
      62           1 : static int run_script_select(struct asfd *asfd,
      63             :         struct fzp **sout, struct fzp **serr,
      64             :         struct conf **confs, int do_logp, int log_remote, char **logbuf)
      65             : {
      66           1 :         int mfd=-1;
      67             :         fd_set fsr;
      68             :         struct timeval tval;
      69           1 :         int soutfd=fzp_fileno(*sout);
      70           1 :         int serrfd=fzp_fileno(*serr);
      71             :         // FIX THIS: convert to asfd?
      72           1 :         fzp_setlinebuf(*sout);
      73           1 :         fzp_setlinebuf(*serr);
      74           1 :         set_non_blocking(soutfd);
      75           1 :         set_non_blocking(serrfd);
      76             : 
      77             :         while(1)
      78             :         {
      79           3 :                 mfd=-1;
      80           3 :                 FD_ZERO(&fsr);
      81           3 :                 if(*sout) add_fd_to_sets(soutfd, &fsr, NULL, NULL, &mfd);
      82           3 :                 if(*serr) add_fd_to_sets(serrfd, &fsr, NULL, NULL, &mfd);
      83           3 :                 tval.tv_sec=1;
      84           3 :                 tval.tv_usec=0;
      85           3 :                 if(select(mfd+1, &fsr, NULL, NULL, &tval)<0)
      86             :                 {
      87           1 :                         if(errno!=EAGAIN && errno!=EINTR)
      88             :                         {
      89           0 :                                 logp("%s error: %s\n", __func__,
      90             :                                         strerror(errno));
      91           0 :                                 return -1;
      92             :                         }
      93             :                 }
      94           3 :                 if(FD_ISSET(soutfd, &fsr))
      95             :                 {
      96           1 :                         if(log_script_output(asfd, sout, confs,
      97             :                                 do_logp, log_remote, 0, logbuf)) return -1;
      98             :                 }
      99           3 :                 if(FD_ISSET(serrfd, &fsr))
     100             :                 {
     101           1 :                         if(log_script_output(asfd, serr, confs,
     102             :                                 do_logp, log_remote, 1, logbuf)) return -1;
     103             :                 }
     104             : 
     105           3 :                 if(!*sout && !*serr && got_sigchld)
     106             :                 {
     107             :                         //fclose(*sout); *sout=NULL;
     108             :                         //fclose(*serr); *serr=NULL;
     109           1 :                         got_sigchld=0;
     110           1 :                         return 0;
     111             :                 }
     112             :         }
     113             : 
     114             :         // Never get here.
     115             :         return -1;
     116             : }
     117             : 
     118             : #endif
     119             : 
     120           2 : int run_script_to_buf(struct asfd *asfd,
     121             :         const char **args, struct strlist *userargs, struct conf **confs,
     122             :         int do_wait, int do_logp, int log_remote, char **logbuf)
     123             : {
     124           2 :         int a=0;
     125           2 :         int l=0;
     126             :         pid_t p;
     127           2 :         struct fzp *serr=NULL;
     128           2 :         struct fzp *sout=NULL;
     129           2 :         char *cmd[64]={ NULL };
     130             :         struct strlist *sl;
     131             : #ifndef HAVE_WIN32
     132           2 :         struct cntr *cntr=NULL;
     133           2 :         int s=0;
     134             : #endif
     135           2 :         if(!args || !args[0]) return 0;
     136             : 
     137           1 :         for(a=0; args[a]; a++) cmd[l++]=(char *)args[a];
     138           0 :         for(sl=userargs; sl; sl=sl->next) cmd[l++]=sl->path;
     139           1 :         cmd[l++]=NULL;
     140             : 
     141             : #ifndef HAVE_WIN32
     142           1 :         setup_signal(SIGCHLD, run_script_sigchld_handler);
     143             : #endif
     144             : 
     145           1 :         fflush(stdout); fflush(stderr);
     146           1 :         if(do_wait)
     147             :         {
     148           1 :                 if((p=forkchild(NULL,
     149           1 :                         &sout, &serr, cmd[0], cmd))==-1) return -1;
     150             :         }
     151             :         else
     152             :         {
     153           0 :                 if((p=forkchild_no_wait(NULL,
     154           0 :                         &sout, &serr, cmd[0], cmd))==-1) return -1;
     155           0 :                 return 0;
     156             :         }
     157             : #ifdef HAVE_WIN32
     158             :         // My windows forkchild currently just executes, then returns.
     159             :         return 0;
     160             : #else
     161           1 :         s=run_script_select(asfd, &sout, &serr,
     162             :                 confs, do_logp, log_remote, logbuf);
     163             : 
     164             :         // Set SIGCHLD back to default.
     165           1 :         setup_signal(SIGCHLD, SIG_DFL);
     166             : 
     167           1 :         if(s) return -1;
     168             : 
     169           1 :         if(confs) cntr=get_cntr(confs);
     170             : 
     171           1 :         if(WIFEXITED(run_script_status))
     172             :         {
     173           1 :                 int ret=WEXITSTATUS(run_script_status);
     174           1 :                 logp("%s returned: %d\n", cmd[0], ret);
     175           1 :                 if(log_remote && confs && ret)
     176           0 :                         logw(asfd, cntr, "%s returned: %d\n", cmd[0], ret);
     177             :                 return ret;
     178             :         }
     179           0 :         else if(WIFSIGNALED(run_script_status))
     180             :         {
     181           0 :                 logp("%s terminated on signal %d\n",
     182             :                         cmd[0], WTERMSIG(run_script_status));
     183           0 :                 if(log_remote && confs)
     184           0 :                         logw(asfd, cntr, "%s terminated on signal %d\n",
     185             :                                 cmd[0], WTERMSIG(run_script_status));
     186             :         }
     187             :         else
     188             :         {
     189           0 :                 logp("Strange return when trying to run %s\n", cmd[0]);
     190           0 :                 if(log_remote && confs) logw(asfd, cntr,
     191             :                         "Strange return when trying to run %s\n", cmd[0]);
     192             :         }
     193             :         return -1;
     194             : #endif
     195             : }
     196             : 
     197           2 : int run_script(struct asfd *asfd, const char **args, struct strlist *userargs,
     198             :         struct conf **confs, int do_wait, int do_logp, int log_remote)
     199             : {
     200           2 :         return run_script_to_buf(asfd, args, userargs, confs, do_wait,
     201             :                 do_logp, log_remote, NULL /* do not save output to buffer */);
     202             : }

Generated by: LCOV version 1.13