Beispiel #1
0
bool w_ser_write_pdu(enum w_pdu_type pdu_type,
    w_jbuffer_t *jr, w_stm_t stm, json_t *json)
{
  switch (pdu_type) {
    case is_json_compact:
      return w_json_buffer_write(jr, stm, json, JSON_COMPACT);
    case is_json_pretty:
      return w_json_buffer_write(jr, stm, json, JSON_INDENT(4));
    case is_bser:
      return w_json_buffer_write_bser(jr, stm, json);
    case need_data:
    default:
      return false;
  }
}
Beispiel #2
0
bool w_state_save(void)
{
  json_t *state;
  w_jbuffer_t buffer;
  int fd = -1;
  char tmpname[WATCHMAN_NAME_MAX];
  bool result = false;

  if (dont_save_state) {
    return true;
  }

  pthread_mutex_lock(&state_lock);

  state = json_object();

  if (!w_json_buffer_init(&buffer)) {
    w_log(W_LOG_ERR, "save_state: failed to init json buffer\n");
    goto out;
  }

  snprintf(tmpname, sizeof(tmpname), "%sXXXXXX",
      watchman_state_file);
  fd = w_mkstemp(tmpname);
  if (fd == -1) {
    w_log(W_LOG_ERR, "save_state: unable to create temporary file: %s\n",
        strerror(errno));
    goto out;
  }

  json_object_set_new(state, "version", json_string(PACKAGE_VERSION));

  /* now ask the different subsystems to fill out the state */
  if (!w_root_save_state(state)) {
    goto out;
  }

  /* we've prepared what we're going to save, so write it out */
  w_json_buffer_write(&buffer, fd, state, JSON_INDENT(4));

  /* atomically replace the old contents */
  result = rename(tmpname, watchman_state_file) == 0;

out:
  if (state) {
    json_decref(state);
  }
  w_json_buffer_free(&buffer);
  if (fd != -1) {
    if (!result) {
      // If we didn't succeed, remove our temporary file
      unlink(tmpname);
    }
    close(fd);
  }

  pthread_mutex_unlock(&state_lock);

  return result;
}
Beispiel #3
0
static bool try_command(json_t *cmd, int timeout)
{
  int fd;
  int res;
  int tries;
  w_jbuffer_t buffer;

  fd = socket(PF_LOCAL, SOCK_STREAM, 0);
  if (fd == -1) {
    perror("socket");
    return false;
  }

  tries = 0;
  do {
    res = connect(fd, (struct sockaddr*)&un, sizeof(un));
    if (res == 0) {
      break;
    }

    if (timeout && tries < timeout && should_start(errno)) {
      // Wait for socket to come up
      sleep(1);
      continue;
    }

  } while (++tries < timeout);

  if (res) {
    close(fd);
    return false;
  }

  if (!cmd) {
    close(fd);
    return true;
  }

  w_json_buffer_init(&buffer);

  // Send command
  w_json_buffer_write(&buffer, fd, cmd, JSON_COMPACT);

  do {
    if (!read_response(&buffer, fd)) {
      w_json_buffer_free(&buffer);
      close(fd);
      return false;
    }
  } while (persistent);
  w_json_buffer_free(&buffer);
  close(fd);

  return true;
}
Beispiel #4
0
static int prepare_stdin(
  struct watchman_trigger_command *cmd,
  w_query_res *res)
{
  uint32_t n_files;
  char stdin_file_name[WATCHMAN_NAME_MAX];
  int stdin_fd = -1;

  if (cmd->stdin_style == input_dev_null) {
    return open("/dev/null", O_RDONLY|O_CLOEXEC);
  }

  n_files = res->num_results;

  if (cmd->max_files_stdin > 0) {
    n_files = MIN(cmd->max_files_stdin, n_files);
  }

  /* prepare the input stream for the child process */
  snprintf(stdin_file_name, sizeof(stdin_file_name), "%s/wmanXXXXXX",
      watchman_tmp_dir);
  stdin_fd = w_mkstemp(stdin_file_name);
  if (stdin_fd == -1) {
    w_log(W_LOG_ERR, "unable to create a temporary file: %s\n",
        strerror(errno));
    return -1;
  }

  /* unlink the file, we don't need it in the filesystem;
   * we'll pass the fd on to the child as stdin */
  unlink(stdin_file_name);

  switch (cmd->stdin_style) {
    case input_json:
      {
        w_jbuffer_t buffer;
        json_t *file_list;

        if (!w_json_buffer_init(&buffer)) {
          w_log(W_LOG_ERR, "failed to init json buffer\n");
          close(stdin_fd);
          return -1;
        }

        file_list = w_query_results_to_json(&cmd->field_list,
            n_files, res->results);
        w_json_buffer_write(&buffer, stdin_fd, file_list, 0);
        w_json_buffer_free(&buffer);
        json_decref(file_list);
        break;
      }
    case input_name_list:
      {
        struct iovec iov[2];
        uint32_t i;

        iov[1].iov_base = "\n";
        iov[1].iov_len = 1;

        for (i = 0; i < n_files; i++) {
          iov[0].iov_base = (void*)res->results[i].relname->buf;
          iov[0].iov_len = res->results[i].relname->len;
          if (writev(stdin_fd, iov, 2) != (ssize_t)iov[0].iov_len + 1) {
            w_log(W_LOG_ERR,
              "write failure while producing trigger stdin: %s\n",
              strerror(errno));
            close(stdin_fd);
            return -1;
          }
        }
        break;
      }
    case input_dev_null:
      // already handled above
      break;
  }

  lseek(stdin_fd, 0, SEEK_SET);
  return stdin_fd;
}
Beispiel #5
0
static w_stm_t prepare_stdin(
  struct watchman_trigger_command *cmd,
  w_query_res *res)
{
  uint32_t n_files;
  char stdin_file_name[WATCHMAN_NAME_MAX];
  w_stm_t stdin_file = NULL;

  if (cmd->stdin_style == input_dev_null) {
    return w_stm_open("/dev/null", O_RDONLY|O_CLOEXEC);
  }

  n_files = res->num_results;

  if (cmd->max_files_stdin > 0) {
    n_files = MIN(cmd->max_files_stdin, n_files);
  }

  /* prepare the input stream for the child process */
  snprintf(stdin_file_name, sizeof(stdin_file_name), "%s%cwmanXXXXXX",
      watchman_tmp_dir, WATCHMAN_DIR_SEP);
  stdin_file = w_mkstemp(stdin_file_name);
  if (!stdin_file) {
    w_log(W_LOG_ERR, "unable to create a temporary file: %s %s\n",
        stdin_file_name, strerror(errno));
    return NULL;
  }

  /* unlink the file, we don't need it in the filesystem;
   * we'll pass the fd on to the child as stdin */
  unlink(stdin_file_name); // FIXME: windows path translation

  switch (cmd->stdin_style) {
    case input_json:
      {
        w_jbuffer_t buffer;
        json_t *file_list;

        if (!w_json_buffer_init(&buffer)) {
          w_log(W_LOG_ERR, "failed to init json buffer\n");
          w_stm_close(stdin_file);
          return NULL;
        }

        file_list = w_query_results_to_json(&cmd->field_list,
            n_files, res->results);
        w_log(W_LOG_ERR, "input_json: sending json object to stm\n");
        if (!w_json_buffer_write(&buffer, stdin_file, file_list, 0)) {
          w_log(W_LOG_ERR,
              "input_json: failed to write json data to stream: %s\n",
              strerror(errno));
          w_stm_close(stdin_file);
          return NULL;
        }
        w_json_buffer_free(&buffer);
        json_decref(file_list);
        break;
      }
    case input_name_list:
      {
        uint32_t i;

        for (i = 0; i < n_files; i++) {
          if (w_stm_write(stdin_file, res->results[i].relname->buf,
              res->results[i].relname->len) != (int)res->results[i].relname->len
              || w_stm_write(stdin_file, "\n", 1) != 1) {
            w_log(W_LOG_ERR,
              "write failure while producing trigger stdin: %s\n",
              strerror(errno));
            w_stm_close(stdin_file);
            return NULL;
          }
        }
        break;
      }
    case input_dev_null:
      // already handled above
      break;
  }

  w_stm_rewind(stdin_file);
  return stdin_file;
}