Пример #1
0
/*
 * call-seq:
 *   io.getpass(prompt=nil)       -> string
 *
 * See IO#getpass.
 */
static VALUE
io_getpass(int argc, VALUE *argv, VALUE io)
{
    VALUE str;

    rb_check_arity(argc, 0, 1);
    prompt(argc, argv, io);
    str = str_chomp(rb_funcallv(io, id_gets, 0, 0));
    puts_call(io);
    return str;
}
Пример #2
0
/*
 * call-seq:
 *   io.getpass(prompt=nil)       -> string
 *
 * Reads and returns a line without echo back.
 * Prints +prompt+ unless it is +nil+.
 *
 * You must require 'io/console' to use this method.
 */
static VALUE
console_getpass(int argc, VALUE *argv, VALUE io)
{
    VALUE str, wio;

    rb_check_arity(argc, 0, 1);
    wio = rb_io_get_write_io(io);
    if (wio == io && io == rb_stdin) wio = rb_stderr;
    prompt(argc, argv, wio);
    str = rb_ensure(getpass_call, io, puts_call, wio);
    return str_chomp(str);
}
Пример #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)
{
  // 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;
  }
}
Пример #4
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;
  }
}
Пример #5
0
static int ipkg_conf_parse_file(ipkg_conf_t *conf, const char *filename,
				pkg_src_list_t *pkg_src_list,
				nv_pair_list_t *tmp_dest_nv_pair_list,
				char **lists_dir)
{
     int err;
     ipkg_option_t * options;
     FILE *file = fopen(filename, "r");
     regex_t valid_line_re, comment_re;
#define regmatch_size 12
     regmatch_t regmatch[regmatch_size];

     if (ipkg_init_options_array(conf, &options)<0)
        return ENOMEM;

     if (file == NULL) {
	  fprintf(stderr, "%s: failed to open %s: %s\n",
		  __FUNCTION__, filename, strerror(errno));
	  free(options);
	  return errno;
     }
     ipkg_message(conf, IPKG_NOTICE, "loading conf file %s\n", filename);

     err = xregcomp(&comment_re, 
		    "^[[:space:]]*(#.*|[[:space:]]*)$",
		    REG_EXTENDED);
     if (err) {
	  free(options);
	  return err;
     }
     err = xregcomp(&valid_line_re, "^[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))([[:space:]]+([^[:space:]]+))?[[:space:]]*$", REG_EXTENDED);
     if (err) {
	  free(options);
	  return err;
     }

     while(1) {
	  int line_num = 0;
	  char *line;
	  char *type, *name, *value, *extra;

	  line = file_read_line_alloc(file);
	  line_num++;
	  if (line == NULL) {
	       break;
	  }

	  str_chomp(line);

	  if (regexec(&comment_re, line, 0, 0, 0) == 0) {
	       goto NEXT_LINE;
	  }

	  if (regexec(&valid_line_re, line, regmatch_size, regmatch, 0) == REG_NOMATCH) {
	       str_chomp(line);
	       fprintf(stderr, "%s:%d: Ignoring invalid line: `%s'\n",
		       filename, line_num, line);
	       goto NEXT_LINE;
	  }

	  /* This has to be so ugly to deal with optional quotation marks */
	  if (regmatch[2].rm_so > 0) {
	       type = strndup(line + regmatch[2].rm_so,
			      regmatch[2].rm_eo - regmatch[2].rm_so);
	  } else {
	       type = strndup(line + regmatch[3].rm_so,
			      regmatch[3].rm_eo - regmatch[3].rm_so);
	  }
	  if (regmatch[5].rm_so > 0) {
	       name = strndup(line + regmatch[5].rm_so,
			      regmatch[5].rm_eo - regmatch[5].rm_so);
	  } else {
	       name = strndup(line + regmatch[6].rm_so,
			      regmatch[6].rm_eo - regmatch[6].rm_so);
	  }
	  if (regmatch[8].rm_so > 0) {
	       value = strndup(line + regmatch[8].rm_so,
			       regmatch[8].rm_eo - regmatch[8].rm_so);
	  } else {
	       value = strndup(line + regmatch[9].rm_so,
			       regmatch[9].rm_eo - regmatch[9].rm_so);
	  }
	  extra = NULL;
	  if (regmatch[11].rm_so > 0) {
	       extra = strndup (line + regmatch[11].rm_so,
				regmatch[11].rm_eo - regmatch[11].rm_so);
	  }

	  /* We use the tmp_dest_nv_pair_list below instead of
	     conf->pkg_dest_list because we might encounter an
	     offline_root option later and that would invalidate the
	     directories we would have computed in
	     pkg_dest_list_init. (We do a similar thing with
	     tmp_src_nv_pair_list for sake of symmetry.) */
	  if (strcmp(type, "option") == 0) {
	       ipkg_conf_set_option(options, name, value);
	  } else if (strcmp(type, "src") == 0) {
	       if (!nv_pair_list_find(pkg_src_list, name)) {
		    pkg_src_list_append (pkg_src_list, name, value, extra, 0);
	       } else {
		    ipkg_message(conf, IPKG_ERROR, "ERROR: duplicate src declaration.  Skipping:\n\t src %s %s\n",
				 name, value);
	       }
	  } else if (strcmp(type, "src/gz") == 0) {
	       if (!nv_pair_list_find(pkg_src_list, name)) {
		    pkg_src_list_append (pkg_src_list, name, value, extra, 1);
	       } else {
		    ipkg_message(conf, IPKG_ERROR, "ERROR: duplicate src declaration.  Skipping:\n\t src %s %s\n",
				 name, value);
	       }
	  } else if (strcmp(type, "dest") == 0) {
	       nv_pair_list_append(tmp_dest_nv_pair_list, name, value);
	  } else if (strcmp(type, "lists_dir") == 0) {
	       *lists_dir = realloc(*lists_dir,strlen(value)+1);
               if (*lists_dir == NULL) {
		    ipkg_message(conf, IPKG_ERROR, "ERROR: Not enough memory\n");
	            free(options);
	            return EINVAL;
               }
               sprintf (*lists_dir,"%s",value);
	  } else if (strcmp(type, "arch") == 0) {
	       ipkg_message(conf, IPKG_INFO, "supported arch %s priority (%s)\n", name, value);
	       if (!value) {
		    ipkg_message(conf, IPKG_NOTICE, "defaulting architecture %s priority to 10\n", name);
		    value = strdup("10");
	       }
	       nv_pair_list_append(&conf->arch_list, strdup(name), strdup(value));
	  } else {
	       fprintf(stderr, "WARNING: Ignoring unknown configuration "
		       "parameter: %s %s %s\n", type, name, value);
	       free(options);
	       return EINVAL;
	  }

	  free(type);
	  free(name);
	  free(value);
	  if (extra)
	       free (extra);

     NEXT_LINE:
	  free(line);
     }

     free(options);
     regfree(&comment_re);
     regfree(&valid_line_re);
     fclose(file);

     return 0;
}