Exemplo n.º 1
0
static HRESULT process_hook_section(install_ctx_t *ctx, const WCHAR *sect_name)
{
    WCHAR buf[2048], val[2*MAX_PATH];
    const WCHAR *key;
    DWORD len;
    HRESULT hres;

    static const WCHAR runW[] = {'r','u','n',0};

    len = GetPrivateProfileStringW(sect_name, NULL, NULL, buf, sizeof(buf)/sizeof(*buf), ctx->install_file);
    if(!len)
        return S_OK;

    for(key = buf; *key; key += strlenW(key)+1) {
        if(!strcmpiW(key, runW)) {
            WCHAR *cmd;
            size_t size;

            len = GetPrivateProfileStringW(sect_name, runW, NULL, val, sizeof(val)/sizeof(*val), ctx->install_file);

            TRACE("Run %s\n", debugstr_w(val));

            expand_command(ctx, val, NULL, &size);

            cmd = heap_alloc(size*sizeof(WCHAR));
            if(!cmd)
                heap_free(cmd);

            expand_command(ctx, val, cmd, &size);
            hres = RunSetupCommandW(ctx->hwnd, cmd, NULL, ctx->tmp_dir, NULL, NULL, 0, NULL);
            heap_free(cmd);
            if(FAILED(hres))
                return hres;
        }else {
            FIXME("Unsupported hook %s\n", debugstr_w(key));
            return E_NOTIMPL;
        }
    }

    return S_OK;
}
Exemplo n.º 2
0
/**
* pm_execute
* @params
*   int should_wait - Indicates if this execute should be inline or asynchronous
*   const char* command - The command to run
*   const char* cd - Run in this directory unless it's a NULL pointer
*   int nice - Special nice level
*   const char** env - Environment variables to run in the shell
* @output
    pid_t pid - output pid of the new process
**/
pid_t pm_execute(int should_wait, const char* command, const char *cd, int nice, const char** env)
{
  // Setup execution
  char **command_argv = {0};
  int command_argc = 0;
  int running_script = 0;
  
  if (expand_command((const char*)str_chomp(command), &command_argc, &command_argv, &running_script)) ;
  
  command_argv[command_argc] = 0;
  
  // Now actually RUN it!
  pid_t pid;
  if (should_wait)
    pid = vfork();
  else
    pid = fork();
  
  switch (pid) {
  case -1: 
    return -1;
  case 0: {
    pm_setup_signal_handlers();
    if (cd != NULL && cd[0] != '\0')
      chdir(cd);
    else
      chdir("/tmp");
    
    if (execve((const char*)command_argv[0], command_argv, (char* const*) env) < 0) {
      printf("execve failed because: %s\n", strerror(errno));      
      exit(-1);
    }
  }
  default:
    // In parent process
    if (nice != INT_MAX && setpriority(PRIO_PROCESS, pid, nice) < 0) 
      ;
    return pid;
  }
}
Exemplo n.º 3
0
/**
* pm_execute
* @params
*   int should_wait - Indicates if this execute should be inline or asynchronous
*   const char* command - The command to run
*   const char* cd - Run in this directory unless it's a NULL pointer
*   int nice - Special nice level
*   const char** env - Environment variables to run in the shell
* @output
    pid_t pid - output pid of the new process
**/
pid_t pm_execute(
  int should_wait, const char* command, const char *cd, int nice, const char** env, int *child_stdin, const char* p_stdout, const char *p_stderr
) {
  // Setup execution
  char **command_argv = {0};
  int command_argc = 0;
  int running_script = 0;
  int countdown = 200;
  
  // If there is nothing here, don't run anything :)
  if (strlen(command) == 0) return -1;
  
  char* chomped_string = str_chomp(command);
  char* safe_chomped_string = str_safe_quote(chomped_string);
  if (expand_command((const char*)safe_chomped_string, &command_argc, &command_argv, &running_script, env)) ;
  command_argv[command_argc] = 0;
      
  // Now actually RUN it!
  pid_t pid;
  
#if USE_PIPES

  int child_fd[2];
  if ( pipe(child_fd) < 0 ) {// Create a pipe to the child (do we need this? I doubt it)
    perror("pipe failed");
  }
  // Setup the stdin so the parent can communicate!
  (*child_stdin) = child_fd[0];
#endif

    // Let's name it so we can get to it later
  int child_dev_null;
  
#if DEBUG
  if ((child_dev_null = open("debug.log", O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
    syslog(LOG_ERR, "babysitter (fatal): Could not open debug.log: errno: %d\n", errno);
  };
#else
  if ((child_dev_null = open("/dev/null", O_RDWR)) < 0) {
    syslog(LOG_ERR, "babysitter (fatal): Could not open /dev/null: errno: %d\n", errno);
  };
#endif
    
  // Setup fork
  pm_setup_fork();
  
  if (should_wait)
    pid = vfork();
  else
    pid = fork();
    
  switch (pid) {
  case -1: 
    return -1;
  case 0: {
    // Child process
    pm_setup_child();
    
    if (cd != NULL && cd[0] != '\0')
      safe_chdir(cd);
    else
      safe_chdir("/tmp");
        
    int child_stdout, child_stderr;
    // Set everything to dev/null first
    child_stdout = child_stderr = child_dev_null;
    
    // If we've passed in a stdout filename, then open it
    if(p_stdout)
      if ((child_stdout = open(p_stdout, O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
        perror("child stdout");
        child_stdout = child_dev_null;
      }
    // If we've been passed a stderr filename, then open that
    if(p_stderr)
      if ((child_stderr = open(p_stderr, O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
        perror("child stderr");
        child_stderr = child_dev_null;
      }
    
    // Parent doesn't write anything to the child, so just close this right away
    // REDIRECT TO DEV/NULL
    // Replace the stdout/stderr with the child_write fd
#if USE_PIPES
    if (dup2(child_fd[0], STDIN_FILENO) < 0)       FATAL_ERROR("could not dup STDIN_FILENO", -1);
    close(child_fd[1]); // We are using a different stdout
#endif

#if DEBUG
#else
    // Setup the different stdout/stderr
    if (dup2(child_stdout, STDOUT_FILENO) < 0)  FATAL_ERROR("could not dup STDOUT_FILENO", -1);
    if (dup2(child_stderr, STDERR_FILENO) < 0)  FATAL_ERROR("could not dup STDERR_FILENO", -1);

    if (child_stdout != child_dev_null) close(child_stdout);
    if (child_stderr != child_dev_null) close(child_stderr);
#endif

    if (execve((const char*)command_argv[0], command_argv, (char* const*) env) < 0) {
      perror("execve");
      exit(-1);
    }
  }
  default:
    // In parent process
    // set the stdout back
    close(child_dev_null); // Child write never gets used outside the child
  
#if USE_PIPES
    if (dup2(child_fd[1], STDOUT_FILENO) < 0)
      perror("dup2");
    
    close(child_fd[0]);
#endif
    
    if (nice != INT_MAX && setpriority(PRIO_PROCESS, pid, nice) < 0) 
      ;
    if (running_script) {
      while (countdown > 0) {
        if (kill(pid, 0) != 0) break;
        usleep(100);
        countdown--;
      }
      struct stat buffer;
      if (stat(command_argv[0], &buffer) != 0) {
        printf("file doesn't exist when it should because: %s\n", strerror(errno));
      }
      if( unlink( command_argv[0] ) != 0 ) perror( "Error deleting file" );
    }
    // These are free'd later, anyway
    // if (chomped_string) free(chomped_string); 
    // if (safe_chomped_string) free(safe_chomped_string);
    return pid;
  }
}