Exemple #1
0
/* find /root [patterns] */
static void cmd_find(struct watchman_client *client, json_t *args)
{
    w_root_t *root;
    w_query *query;
    char *errmsg = NULL;
    struct w_query_field_list field_list;
    w_query_res res;
    json_t *response;
    json_t *file_list;
    char clockbuf[128];

    /* resolve the root */
    if (json_array_size(args) < 2) {
        send_error_response(client, "not enough arguments for 'find'");
        return;
    }

    root = resolve_root_or_err(client, args, 1, false);
    if (!root) {
        return;
    }

    query = w_query_parse_legacy(root, args, &errmsg, 2, NULL, NULL, NULL);
    if (errmsg) {
        send_error_response(client, "%s", errmsg);
        free(errmsg);
        w_root_delref(root);
        return;
    }

    w_query_legacy_field_list(&field_list);

    if (client->client_mode) {
        query->sync_timeout = 0;
    }

    if (!w_query_execute(query, root, &res, NULL, NULL)) {
        send_error_response(client, "query failed: %s", res.errmsg);
        w_query_result_free(&res);
        w_root_delref(root);
        w_query_delref(query);
        return;
    }

    w_query_delref(query);

    file_list = w_query_results_to_json(&field_list,
                                        res.num_results, res.results);
    w_query_result_free(&res);

    response = make_response();
    if (clock_id_string(res.root_number, res.ticks, clockbuf, sizeof(clockbuf))) {
        set_prop(response, "clock", json_string_nocheck(clockbuf));
    }
    set_prop(response, "files", file_list);

    send_and_dispose_response(client, response);
    w_root_delref(root);
}
Exemple #2
0
static void delete_subscription(w_ht_val_t val)
{
  struct watchman_client_subscription *sub = w_ht_val_ptr(val);

  w_string_delref(sub->name);
  w_query_delref(sub->query);
  free(sub);
}
Exemple #3
0
w_query *w_query_parse(w_root_t *root, json_t *query, char **errmsg)
{
  w_query *res;

  *errmsg = NULL;

  res = calloc(1, sizeof(*res));
  if (!res) {
    *errmsg = strdup("out of memory");
    goto error;
  }
  res->refcnt = 1;
  res->case_sensitive = root->case_sensitive;

  if (!parse_sync(res, query)) {
    goto error;
  }

  if (!parse_relative_root(root, res, query)) {
    goto error;
  }

  if (!parse_empty_on_fresh_instance(res, query)) {
    goto error;
  }

  /* Look for path generators */
  if (!parse_paths(res, query)) {
    goto error;
  }

  /* Look for suffix generators */
  if (!parse_suffixes(res, query)) {
    goto error;
  }

  /* Look for since generator */
  if (!parse_since(res, query)) {
    goto error;
  }

  if (!parse_query_expression(res, query)) {
    goto error;
  }

  return res;
error:
  if (res) {
    *errmsg = res->errmsg;
    res->errmsg = NULL;
    w_query_delref(res);
  }
  if (!*errmsg) {
    *errmsg = strdup("unspecified error");
  }

  return NULL;
}
Exemple #4
0
static json_t *build_legacy_trigger(
  w_root_t *root,
  struct watchman_client *client,
  json_t *args)
{
  json_t *trig, *expr;
  json_t *command;
  char *errmsg;
  uint32_t next_arg = 0;
  uint32_t i;
  size_t n;
  w_query *query;

  trig = json_pack("{s:O, s:b, s:[s, s, s, s, s]}",
    "name", json_array_get(args, 2),
    "append_files", true,
    "stdin",
      // [
      "name", "exists", "new", "size", "mode"
      // ]
  );

  query = w_query_parse_legacy(root, args, &errmsg, 3, &next_arg, NULL, &expr);
  if (!query) {
    send_error_response(client, "invalid rule spec: %s", errmsg);
    free(errmsg);
    json_decref(trig);
    return NULL;
  }
  w_query_delref(query);

  json_object_set(trig, "expression", json_object_get(expr, "expression"));
  json_decref(expr);

  if (next_arg >= json_array_size(args)) {
    send_error_response(client, "no command was specified");
    json_decref(trig);
    return NULL;
  }

  n = json_array_size(args) - next_arg;
  command = json_array_of_size(n);
  for (i = 0; i < n; i++) {
    json_t *ele = json_array_get(args, i + next_arg);
    if (!json_is_string(ele)) {
      send_error_response(client, "expected argument %d to be a string", i);
      json_decref(trig);
      return NULL;
    }
    json_array_append(command, ele);
  }
  json_object_set_new(trig, "command", command);

  return trig;
}
Exemple #5
0
void w_trigger_command_free(struct watchman_trigger_command *cmd)
{
  if (cmd->triggername) {
    w_string_delref(cmd->triggername);
  }

  if (cmd->command) {
    json_decref(cmd->command);
  }

  if (cmd->definition) {
    json_decref(cmd->definition);
  }

  if (cmd->query) {
    w_query_delref(cmd->query);
  }

  if (cmd->envht) {
    w_ht_free(cmd->envht);
  }

  free(cmd);
}
Exemple #6
0
/* query /root {query} */
static void cmd_query(struct watchman_client *client, json_t *args)
{
  w_root_t *root;
  w_query *query;
  json_t *query_spec;
  char *errmsg = NULL;
  w_query_res res;
  json_t *response;
  json_t *file_list, *jfield_list;
  char clockbuf[128];
  struct w_query_field_list field_list;

  if (json_array_size(args) != 3) {
    send_error_response(client, "wrong number of arguments for 'query'");
    return;
  }

  root = resolve_root_or_err(client, args, 1, false);
  if (!root) {
    return;
  }

  query_spec = json_array_get(args, 2);

  jfield_list = json_object_get(query_spec, "fields");
  if (!parse_field_list(jfield_list, &field_list, &errmsg)) {
    send_error_response(client, "invalid field list: %s", errmsg);
    free(errmsg);
    w_root_delref(root);
    return;
  }

  query = w_query_parse(root, query_spec, &errmsg);
  if (!query) {
    send_error_response(client, "failed to parse query: %s", errmsg);
    free(errmsg);
    w_root_delref(root);
    return;
  }

  if (client->client_mode) {
    query->sync_timeout = 0;
  }

  if (!w_query_execute(query, root, &res, NULL, NULL)) {
    send_error_response(client, "query failed: %s", res.errmsg);
    w_query_result_free(&res);
    w_root_delref(root);
    w_query_delref(query);
    return;
  }

  w_query_delref(query);

  file_list = w_query_results_to_json(&field_list,
                res.num_results, res.results);
  w_query_result_free(&res);

  response = make_response();
  if (clock_id_string(res.root_number, res.ticks, clockbuf, sizeof(clockbuf))) {
    set_prop(response, "clock", json_string_nocheck(clockbuf));
  }
  set_prop(response, "is_fresh_instance",
           json_pack("b", res.is_fresh_instance));
  set_prop(response, "files", file_list);

  send_and_dispose_response(client, response);
  w_root_delref(root);
}
Exemple #7
0
/* since /root <timestamp> [patterns] */
static void cmd_since(struct watchman_client *client, json_t *args)
{
  const char *clockspec;
  w_root_t *root;
  w_query *query;
  char *errmsg = NULL;
  struct w_query_field_list field_list;
  w_query_res res;
  json_t *response, *clock_ele;
  json_t *file_list;
  char clockbuf[128];

  /* resolve the root */
  if (json_array_size(args) < 3) {
    send_error_response(client, "not enough arguments for 'since'");
    return;
  }

  root = resolve_root_or_err(client, args, 1, false);
  if (!root) {
    return;
  }

  clock_ele = json_array_get(args, 2);
  clockspec = json_string_value(clock_ele);
  if (!clockspec) {
    send_error_response(client,
        "expected argument 2 to be a valid clockspec");
    w_root_delref(root);
    return;
  }

  query = w_query_parse_legacy(args, &errmsg, 3, NULL, clockspec, NULL);
  if (errmsg) {
    send_error_response(client, "%s", errmsg);
    free(errmsg);
    w_root_delref(root);
    return;
  }

  w_query_legacy_field_list(&field_list);

  if (!w_query_execute(query, root, &res, NULL, NULL)) {
    send_error_response(client, "query failed: %s", res.errmsg);
    w_query_result_free(&res);
    w_root_delref(root);
    w_query_delref(query);
    return;
  }

  w_query_delref(query);

  file_list = w_query_results_to_json(&field_list,
                res.num_results, res.results);
  w_query_result_free(&res);

  response = make_response();
  if (clock_id_string(res.root_number, res.ticks, clockbuf, sizeof(clockbuf))) {
    set_prop(response, "clock", json_string_nocheck(clockbuf));
  }
  set_prop(response, "is_fresh_instance",
           json_pack("b", res.is_fresh_instance));
  set_prop(response, "files", file_list);

  send_and_dispose_response(client, response);
  w_root_delref(root);
}