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

Generated by: LCOV version 1.10