/* 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); }
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); }
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; }
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; }
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); }
/* 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); }
/* 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); }