Exemple #1
0
static void cmd_debug_show_cursors(struct watchman_client *client, json_t *args)
{
    w_root_t *root;
    json_t *resp, *cursors;
    w_ht_iter_t i;

    /* resolve the root */
    if (json_array_size(args) != 2) {
        send_error_response(client,
                            "wrong number of arguments for 'debug-show-cursors'");
        return;
    }

    root = resolve_root_or_err(client, args, 1, false);

    if (!root) {
        return;
    }

    resp = make_response();

    w_root_lock(root);
    cursors = json_object_of_size(w_ht_size(root->cursors));
    if (w_ht_first(root->cursors, &i)) do {
            w_string_t *name = w_ht_val_ptr(i.key);
            set_prop(cursors, name->buf, json_integer(i.value));
        } while (w_ht_next(root->cursors, &i));
    w_root_unlock(root);

    set_prop(resp, "cursors", cursors);
    send_and_dispose_response(client, resp);
    w_root_delref(root);
}
Exemple #2
0
static void cmd_debug_show_cursors(
    struct watchman_client* client,
    const json_ref& args) {
  json_ref cursors;

  /* resolve the root */
  if (json_array_size(args) != 2) {
    send_error_response(client,
                        "wrong number of arguments for 'debug-show-cursors'");
    return;
  }

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

  auto resp = make_response();

  {
    auto map = root->inner.cursors.rlock();
    cursors = json_object_of_size(map->size());
    for (const auto& it : *map) {
      const auto& name = it.first;
      const auto& ticks = it.second;
      cursors.set(name.c_str(), json_integer(ticks));
    }
  }

  resp.set("cursors", std::move(cursors));
  send_and_dispose_response(client, std::move(resp));
}
Exemple #3
0
json_ref file_result_to_json(
    const w_query_field_list& fieldList,
    const watchman_rule_match& match) {
  if (fieldList.size() == 1) {
    return fieldList.front()->make(&match);
  }
  auto value = json_object_of_size(fieldList.size());

  for (auto& f : fieldList) {
    auto ele = f->make(&match);
    value.set(f->name, std::move(ele));
  }
  return value;
}
Exemple #4
0
json_t *w_query_results_to_json(
    struct w_query_field_list *field_list,
    uint32_t num_results,
    struct watchman_rule_match *results)
{
  json_t *file_list = json_array_of_size(num_results);
  uint32_t i, f;

  // build a template for the serializer
  if (num_results && field_list->num_fields > 1) {
    json_t *templ = json_array_of_size(field_list->num_fields);

    for (f = 0; f < field_list->num_fields; f++) {
      json_array_append_new(templ,
          json_string_nocheck(field_list->fields[f]->name));
    }

    json_array_set_template_new(file_list, templ);
  }

  for (i = 0; i < num_results; i++) {
    json_t *value, *ele;

    if (field_list->num_fields == 1) {
      value = field_list->fields[0]->make(&results[i]);
    } else {
      value = json_object_of_size(field_list->num_fields);

      for (f = 0; f < field_list->num_fields; f++) {
        ele = field_list->fields[f]->make(&results[i]);
        set_prop(value, field_list->fields[f]->name, ele);
      }
    }
    json_array_append_new(file_list, value);
  }
  return file_list;
}
Exemple #5
0
/* version */
static void cmd_version(struct watchman_client* client, const json_ref& args) {
  auto resp = make_response();

#ifdef WATCHMAN_BUILD_INFO
  resp.set(
      "buildinfo", typed_string_to_json(WATCHMAN_BUILD_INFO, W_STRING_UNICODE));
#endif

  /* ["version"]
   *    -> just returns the basic version information.
   * ["version", {"required": ["foo"], "optional": ["bar"]}]
   *    -> includes capability matching information
   */

  if (json_array_size(args) == 2) {
    const auto& arg_obj = args.at(1);

    auto req_cap = arg_obj.get_default("required");
    auto opt_cap = arg_obj.get_default("optional");

    auto cap_res = json_object_of_size(
        (opt_cap ? json_array_size(opt_cap) : 0) +
        (req_cap ? json_array_size(req_cap) : 0));

    if (opt_cap && opt_cap.isArray()) {
      query_caps(resp, cap_res, opt_cap, false);
    }
    if (req_cap && req_cap.isArray()) {
      query_caps(resp, cap_res, req_cap, true);
    }

    resp.set("capabilities", std::move(cap_res));
  }

  send_and_dispose_response(client, std::move(resp));
}
Exemple #6
0
json_t *w_match_results_to_json(
    uint32_t num_matches,
    struct watchman_rule_match *matches)
{
  json_t *file_list = json_array_of_size(num_matches);
  uint32_t i;

  if (num_matches) {
    // Build a template for the serializer
    json_t *templ = json_array_of_size(15);
    static const char *field_list[] = {
      "name", "exists", "size", "mode", "uid", "gid",
      "mtime", "ctime", "ino", "dev", "nlink", "new",
      "oclock", "cclock",
    };

    for (i = 0; i < sizeof(field_list)/sizeof(field_list[0]); i++) {
      json_array_append_new(templ, json_string_nocheck(field_list[i]));
    }

    json_array_set_template_new(file_list, templ);
  }

  for (i = 0; i < num_matches; i++) {
    struct watchman_file *file = matches[i].file;
    w_string_t *relname = matches[i].relname;
    char buf[128];

    json_t *record = json_object_of_size(15);

    set_prop(record, "name", json_string_nocheck(relname->buf));
    set_prop(record, "exists", json_boolean(file->exists));
    // Only report stat data if we think this file exists.  If it doesn't,
    // we probably have stale data cached in file->st which is useless to
    // report on.
    if (file->exists) {
      // Note: our JSON library supports 64-bit integers, but this may
      // pose a compatibility issue for others.  We'll see if anyone
      // runs into an issue and deal with it then...
      set_prop(record, "size", json_integer(file->st.st_size));
      set_prop(record, "mode", json_integer(file->st.st_mode));
      set_prop(record, "uid", json_integer(file->st.st_uid));
      set_prop(record, "gid", json_integer(file->st.st_gid));
      set_prop(record, "mtime", json_integer(file->st.st_mtime));
      set_prop(record, "ctime", json_integer(file->st.st_ctime));
      set_prop(record, "ino", json_integer(file->st.st_ino));
      set_prop(record, "dev", json_integer(file->st.st_dev));
      set_prop(record, "nlink", json_integer(file->st.st_nlink));
      set_prop(record, "new", json_boolean(matches[i].is_new));

      if (clock_id_string(matches[i].root_number, file->ctime.ticks, buf,
                          sizeof(buf))) {
        set_prop(record, "cclock", json_string_nocheck(buf));
      }
    }
    if (clock_id_string(matches[i].root_number, file->otime.ticks, buf,
                        sizeof(buf))) {
      set_prop(record, "oclock", json_string_nocheck(buf));
    }

    json_array_append_new(file_list, record);
  }

  return file_list;
}
Exemple #7
0
static json_t *bunser_template(const char *buf, const char *end,
    json_int_t *used, json_error_t *jerr)
{
  json_int_t needed = 0;
  json_int_t total = 0;
  json_int_t i, nelems;
  json_int_t ip, np;
  json_t *templ = NULL, *arrval, *ret = NULL;

  buf++;
  total++;

  if (*buf != BSER_ARRAY) {
    snprintf(jerr->text, sizeof(jerr->text),
        "Expected array encoding, but found 0x%02x", *buf);
    *used = total;
    return NULL;
  }

  // Load in the property names template
  templ = bunser_array(buf, end, &needed, jerr);
  if (!templ) {
    *used = needed + total;
    goto bail;
  }
  total += needed;
  buf += needed;

  // And the number of objects
  needed = 0;
  if (!bunser_int(buf, end - buf, &needed, &nelems)) {
    *used = needed + total;
    snprintf(jerr->text, sizeof(jerr->text),
        "invalid object number encoding (needed %d but have %d)",
        (int)needed, (int)(end - buf));
    goto bail;
  }
  total += needed;
  buf += needed;

  np = json_array_size(templ);

  // Now load up the array with object values
  arrval = json_array_of_size((size_t)nelems);
  for (i = 0; i < nelems; i++) {
    json_t *item, *val;

    item = json_object_of_size((size_t)np);
    for (ip = 0; ip < np; ip++) {
      if (*buf == BSER_SKIP) {
        buf++;
        total++;
        continue;
      }

      needed = 0;
      val = bunser(buf, end, &needed, jerr);
      if (!val) {
        *used = needed + total;
        goto bail;
      }
      buf += needed;
      total += needed;

      json_object_set_new_nocheck(item,
          json_string_value(json_array_get(templ, (size_t)ip)),
          val);
    }

    json_array_append_new(arrval, item);
  }

  *used = total;
  ret = arrval;
 bail:
  json_decref(templ);
  return ret;
}
Exemple #8
0
json_t *json_object(void)
{
    return json_object_of_size(0);
}