LCOV - code coverage report
Current view: top level - src - run_script.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 60 82 73.2 %
Date: 2019-03-02 00:16:58 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           2 :         const int maxcmd = sizeof(cmd) / sizeof(cmd[0]);
     131             :         struct strlist *sl;
     132             : #ifndef HAVE_WIN32
     133           2 :         struct cntr *cntr=NULL;
     134           2 :         int s=0;
     135             : #endif
     136           2 :         if(!args || !args[0]) return 0;
     137             : 
     138           1 :         for(a=0; args[a] && l < (maxcmd - 1); a++) cmd[l++]=(char *)args[a];
     139           0 :         for(sl=userargs; sl && l < (maxcmd - 1); sl=sl->next) cmd[l++]=sl->path;
     140           1 :         cmd[l++]=NULL;
     141             : 
     142             : #ifndef HAVE_WIN32
     143           1 :         setup_signal(SIGCHLD, run_script_sigchld_handler);
     144             : #endif
     145             : 
     146           1 :         fflush(stdout); fflush(stderr);
     147           1 :         if(do_wait)
     148             :         {
     149           1 :                 if((p=forkchild(NULL,
     150           1 :                         &sout, &serr, cmd[0], cmd))==-1) return -1;
     151             :         }
     152             :         else
     153             :         {
     154           0 :                 if((p=forkchild_no_wait(NULL,
     155           0 :                         &sout, &serr, cmd[0], cmd))==-1) return -1;
     156           0 :                 return 0;
     157             :         }
     158             : #ifdef HAVE_WIN32
     159             :         // My windows forkchild currently just executes, then returns.
     160             :         return 0;
     161             : #else
     162           1 :         s=run_script_select(asfd, &sout, &serr,
     163             :                 confs, do_logp, log_remote, logbuf);
     164             : 
     165             :         // Set SIGCHLD back to default.
     166           1 :         setup_signal(SIGCHLD, SIG_DFL);
     167             : 
     168           1 :         if(s) return -1;
     169             : 
     170           1 :         if(confs) cntr=get_cntr(confs);
     171             : 
     172           1 :         if(WIFEXITED(run_script_status))
     173             :         {
     174           1 :                 int ret=WEXITSTATUS(run_script_status);
     175           1 :                 logp("%s returned: %d\n", cmd[0], ret);
     176           1 :                 if(log_remote && confs && ret)
     177           0 :                         logw(asfd, cntr, "%s returned: %d\n", cmd[0], ret);
     178             :                 return ret;
     179             :         }
     180           0 :         else if(WIFSIGNALED(run_script_status))
     181             :         {
     182           0 :                 logp("%s terminated on signal %d\n",
     183             :                         cmd[0], WTERMSIG(run_script_status));
     184           0 :                 if(log_remote && confs)
     185           0 :                         logw(asfd, cntr, "%s terminated on signal %d\n",
     186             :                                 cmd[0], WTERMSIG(run_script_status));
     187             :         }
     188             :         else
     189             :         {
     190           0 :                 logp("Strange return when trying to run %s\n", cmd[0]);
     191           0 :                 if(log_remote && confs) logw(asfd, cntr,
     192             :                         "Strange return when trying to run %s\n", cmd[0]);
     193             :         }
     194             :         return -1;
     195             : #endif
     196             : }
     197             : 
     198           2 : int run_script(struct asfd *asfd, const char **args, struct strlist *userargs,
     199             :         struct conf **confs, int do_wait, int do_logp, int log_remote)
     200             : {
     201           2 :         return run_script_to_buf(asfd, args, userargs, confs, do_wait,
     202             :                 do_logp, log_remote, NULL /* do not save output to buffer */);
     203             : }

Generated by: LCOV version 1.13