Exemplo n.º 1
0
bool dispatch_command(struct watchman_client *client, json_t *args)
{
  watchman_command_func func;
  const char *cmd_name;
  w_string_t *cmd;

  if (!json_array_size(args)) {
    send_error_response(client,
        "invalid command (expected an array with some elements!)");
    return false;
  }

  cmd_name = json_string_value(json_array_get(args, 0));
  if (!cmd_name) {
    send_error_response(client,
        "invalid command: expected element 0 to be the command name");
    return false;
  }
  cmd = w_string_new(cmd_name);
  func = (watchman_command_func)w_ht_get(command_funcs, (w_ht_val_t)cmd);
  w_string_delref(cmd);

  if (func) {
    func(client, args);
    return true;
  }
  send_error_response(client, "unknown command %s", cmd_name);

  return false;
}
Exemplo n.º 2
0
static void handle_flush(const char *req, int *req_index)
{
    char dirstr[MAXATOMLEN];
    if (ei_decode_atom(req, req_index, dirstr) < 0) {
        send_error_response("einval");
        return;
    }

    enum uart_direction direction;
    if (strcmp(dirstr, "receive") == 0)
        direction = UART_DIRECTION_RECEIVE;
    else if (strcmp(dirstr, "transmit") == 0)
        direction = UART_DIRECTION_TRANSMIT;
    else if (strcmp(dirstr, "both") == 0)
        direction = UART_DIRECTION_BOTH;
    else {
        send_error_response("einval");
        return;
    }

    if (!uart_is_open(uart)) {
        send_error_response("ebadf");
        return;
    }

    if (uart_flush(uart, direction) >= 0)
        send_ok_response();
    else
        send_error_response(uart_last_error());
}
Exemplo n.º 3
0
/* since /root <timestamp> [patterns] */
static void cmd_since(struct watchman_client* client, const json_ref& args) {
  const char *clockspec;

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

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

  auto 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");
    return;
  }

  auto query = w_query_parse_legacy(root, args, 3, nullptr, clockspec, nullptr);

  auto res = w_query_execute(query.get(), root, nullptr);
  auto response = make_response();
  response.set({{"is_fresh_instance", json_boolean(res.is_fresh_instance)},
                {"clock", res.clockAtStartOfQuery.toJson()},
                {"files", std::move(res.resultsArray)}});

  add_root_warnings_to_response(response, root);
  send_and_dispose_response(client, std::move(response));
}
Exemplo n.º 4
0
static void handle_signals(const char *req, int *req_index)
{
    // No arguments
    (void) req;
    (void) req_index;

    if (!uart_is_open(uart)) {
        send_error_response("ebadf");
        return;
    }

    struct uart_signals sig;
    if (uart_get_signals(uart, &sig) >= 0) {
        char resp[128];
        int resp_index = sizeof(uint16_t);
        resp[resp_index++] = response_id;
        ei_encode_version(resp, &resp_index);
        ei_encode_tuple_header(resp, &resp_index, 2);
        ei_encode_atom(resp, &resp_index, "ok");
        ei_encode_map_header(resp, &resp_index, 8);
        encode_kv_bool(resp, &resp_index, "dsr", sig.dsr);
        encode_kv_bool(resp, &resp_index, "dtr", sig.dtr);
        encode_kv_bool(resp, &resp_index, "rts", sig.rts);
        encode_kv_bool(resp, &resp_index, "st", sig.st);
        encode_kv_bool(resp, &resp_index, "sr", sig.sr);
        encode_kv_bool(resp, &resp_index, "cts", sig.cts);
        encode_kv_bool(resp, &resp_index, "cd", sig.cd);
        encode_kv_bool(resp, &resp_index, "rng", sig.rng);
        erlcmd_send(resp, resp_index);
    } else
        send_error_response(uart_last_error());
}
Exemplo n.º 5
0
/*!
 * \brief Handles the SOAP requests to querry the state variables.
 * This functionality has been deprecated in the UPnP V1.0 architecture.
 */
static UPNP_INLINE void handle_query_variable(
	IN SOCKINFO *info,
	IN http_message_t *request,
	IN IXML_Document *xml_doc)
{
	UpnpStateVarRequest *variable = UpnpStateVarRequest_new();
	Upnp_FunPtr soap_event_callback;
	void *cookie;
	char var_name[LINE_SIZE];
	const char *err_str;
	int err_code;

	if (get_var_name(xml_doc, var_name) != 0) {
		send_error_response(info, SOAP_INVALID_VAR,
				    Soap_Invalid_Var, request);
		return;
	}
	/* get info for event */
	err_code = get_device_info(request, 1, xml_doc,
		info->foreign_sockaddr.ss_family,
		(UpnpString *)UpnpStateVarRequest_get_DevUDN(variable),
		(UpnpString *)UpnpStateVarRequest_get_ServiceID(variable),
		&soap_event_callback, &cookie);
	if (err_code != 0) {
		send_error_response(info, SOAP_INVALID_VAR,
				    Soap_Invalid_Var, request);
		return;
	}
	UpnpStateVarRequest_set_ErrCode(variable, UPNP_E_SUCCESS);
	UpnpStateVarRequest_strcpy_StateVarName(variable, var_name);
	UpnpStateVarRequest_set_CtrlPtIPAddr(variable, &info->foreign_sockaddr);
	/* send event */
	soap_event_callback(UPNP_CONTROL_GET_VAR_REQUEST, variable, cookie);
	UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__,
		"Return from callback for var request\n");
	/* validate, and handle result */
	if (UpnpStateVarRequest_get_CurrentVal(variable) == NULL) {
		err_code = SOAP_ACTION_FAILED;
		err_str = Soap_Action_Failed;
		send_error_response(info, SOAP_INVALID_VAR, Soap_Invalid_Var,
				    request);
		return;
	}
	if (UpnpStateVarRequest_get_ErrCode(variable) != UPNP_E_SUCCESS) {
		if (UpnpString_get_Length(UpnpStateVarRequest_get_ErrStr(variable)) > 0) {
			err_code = SOAP_INVALID_VAR;
			err_str = Soap_Invalid_Var;
		} else {
			err_code = UpnpStateVarRequest_get_ErrCode(variable);
			err_str = UpnpStateVarRequest_get_ErrStr_cstr(variable);
		}
		send_error_response(info, err_code, err_str, request);

		return;
	}
	/* send response */
	send_var_query_response(info, UpnpStateVarRequest_get_CurrentVal(variable), request);
	UpnpStateVarRequest_delete(variable);
}
Exemplo n.º 6
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);
}
Exemplo n.º 7
0
/* trigger /root triggername [watch patterns] -- cmd to run
 * Sets up a trigger so that we can execute a command when a change
 * is detected */
void cmd_trigger(struct watchman_client *client, json_t *args)
{
  w_root_t *root;
  struct watchman_trigger_command *cmd;
  json_t *resp;
  json_t *trig;
  char *errmsg = NULL;

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

  if (json_array_size(args) < 3) {
    send_error_response(client, "not enough arguments");
    goto done;
  }

  trig = json_array_get(args, 2);
  if (json_is_string(trig)) {
    trig = build_legacy_trigger(client, args);
    if (!trig) {
      goto done;
    }
  } else {
    // Add a ref so that we don't need to conditionally decref later
    // for the legacy case later
    json_incref(trig);
  }

  cmd = w_build_trigger_from_def(root, trig, &errmsg);
  json_decref(trig);

  if (!cmd) {
    send_error_response(client, "%s", errmsg);
    goto done;
  }

  w_root_lock(root);
  w_ht_replace(root->commands, w_ht_ptr_val(cmd->triggername),
      w_ht_ptr_val(cmd));
  w_root_unlock(root);

  w_state_save();

  resp = make_response();
  set_prop(resp, "triggerid", json_string_nocheck(cmd->triggername->buf));
  send_and_dispose_response(client, resp);

done:
  if (errmsg) {
    free(errmsg);
  }
  w_root_delref(root);
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
0
bool dispatch_command(struct watchman_client *client, json_t *args, int mode)
{
  struct watchman_command_handler_def *def;
  char *errmsg = NULL;
  bool result = false;
  char sample_name[128];

  // Stash a reference to the current command to make it easier to log
  // the command context in some of the error paths
  client->current_command = args;
  json_incref(client->current_command);

  def = lookup(args, &errmsg, mode);

  if (!def) {
    send_error_response(client, "%s", errmsg);
    goto done;
  }

  if (poisoned_reason && (def->flags & CMD_POISON_IMMUNE) == 0) {
    send_error_response(client, "%s", poisoned_reason);
    goto done;
  }

  if (!client->client_is_owner && (def->flags & CMD_ALLOW_ANY_USER) == 0) {
    send_error_response(client, "you must be the process owner to execute '%s'",
                        def->name);
    return false;
  }

  w_log(W_LOG_DBG, "dispatch_command: %s\n", def->name);
  snprintf(sample_name, sizeof(sample_name), "dispatch_command:%s", def->name);
  w_perf_start(&client->perf_sample, sample_name);
  w_perf_set_wall_time_thresh(
      &client->perf_sample,
      cfg_get_double(NULL, "slow_command_log_threshold_seconds", 1.0));

  result = true;
  def->func(client, args);

  if (w_perf_finish(&client->perf_sample)) {
    json_incref(args);
    w_perf_add_meta(&client->perf_sample, "args", args);
    w_perf_log(&client->perf_sample);
  } else {
    w_log(W_LOG_DBG, "dispatch_command: %s (completed)\n", def->name);
  }

done:
  free(errmsg);
  json_decref(client->current_command);
  client->current_command = NULL;
  w_perf_destroy(&client->perf_sample);
  return result;
}
Exemplo n.º 10
0
static void handle_drain(const char *req, int *req_index)
{
    (void) req;
    (void) req_index;
    if (!uart_is_open(uart)) {
        send_error_response("ebadf");
        return;
    }

    if (uart_drain(uart) >= 0)
        send_ok_response();
    else
        send_error_response(uart_last_error());
}
Exemplo n.º 11
0
static void handle_configure(const char *req, int *req_index)
{
    struct uart_config config = current_config;
    if (parse_option_list(req, req_index, &config) < 0) {
        send_error_response("einval");
        return;
    }

    if (uart_configure(uart, &config) >= 0) {
        current_config = config;
        send_ok_response();
    } else {
        send_error_response(uart_last_error());
    }
}
Exemplo n.º 12
0
/* unsubscribe /root subname
 * Cancels a subscription */
static void cmd_unsubscribe(
    struct watchman_client* clientbase,
    const json_ref& args) {
  const char *name;
  bool deleted{false};
  struct watchman_user_client *client =
      (struct watchman_user_client *)clientbase;

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

  auto jstr = json_array_get(args, 2);
  name = json_string_value(jstr);
  if (!name) {
    send_error_response(
        client, "expected 2nd parameter to be subscription name");
    return;
  }

  auto sname = json_to_w_string(jstr);
  deleted = client->unsubByName(sname);

  auto resp = make_response();
  resp.set({{"unsubscribe", typed_string_to_json(name)},
            {"deleted", json_boolean(deleted)}});

  send_and_dispose_response(client, std::move(resp));
}
Exemplo n.º 13
0
/* debug-ageout */
static void cmd_debug_ageout(
    struct watchman_client* client,
    const json_ref& args) {

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

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

  std::chrono::seconds min_age(json_integer_value(json_array_get(args, 2)));

  auto resp = make_response();

  root->performAgeOut(min_age);

  resp.set("ageout", json_true());
  send_and_dispose_response(client, std::move(resp));
}
Exemplo n.º 14
0
/* find /root [patterns] */
static void cmd_find(struct watchman_client* client, const json_ref& args) {

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

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

  auto query = w_query_parse_legacy(root, args, 2, nullptr, nullptr, nullptr);
  if (client->client_mode) {
    query->sync_timeout = std::chrono::milliseconds(0);
  }

  auto res = w_query_execute(query.get(), root, nullptr);
  auto response = make_response();
  response.set({{"clock", res.clockAtStartOfQuery.toJson()},
                {"files", std::move(res.resultsArray)}});

  send_and_dispose_response(client, std::move(response));
}
Exemplo n.º 15
0
/* watch /root */
static void cmd_watch(struct watchman_client *client, json_t *args)
{
  w_root_t *root;
  json_t *resp;

  /* resolve the root */
  if (json_array_size(args) != 2) {
    send_error_response(client, "wrong number of arguments to 'watch'");
    return;
  }

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

  resp = make_response();

  w_root_lock(root);
  if (root->failure_reason) {
    set_prop(resp, "error", json_string_nocheck(root->failure_reason->buf));
  } else if (root->cancelled) {
    set_prop(resp, "error", json_string_nocheck("root was cancelled"));
  } else {
    set_prop(resp, "watch", json_string_nocheck(root->root_path->buf));
  }
  send_and_dispose_response(client, resp);
  w_root_unlock(root);
  w_root_delref(root);
}
Exemplo n.º 16
0
/* debug-ageout */
static void cmd_debug_ageout(struct watchman_client *client, json_t *args)
{
    w_root_t *root;
    json_t *resp;
    int min_age;

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

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

    if (!root) {
        return;
    }

    min_age = json_integer_value(json_array_get(args, 2));

    resp = make_response();

    w_root_lock(root);
    w_root_perform_age_out(root, min_age);
    w_root_unlock(root);

    set_prop(resp, "ageout", json_true());
    send_and_dispose_response(client, resp);
    w_root_delref(root);
}
Exemplo n.º 17
0
static void cmd_debug_recrawl(struct watchman_client *client, json_t *args)
{
    w_root_t *root;
    json_t *resp;

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

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

    if (!root) {
        return;
    }

    resp = make_response();

    w_root_lock(root);
    w_root_schedule_recrawl(root, "debug-recrawl");
    w_root_unlock(root);

    set_prop(resp, "recrawl", json_true());
    send_and_dispose_response(client, resp);
    w_root_delref(root);
}
Exemplo n.º 18
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);
}
Exemplo n.º 19
0
static void
printfile(const char *path, pConnInfo conn_info)
{
    char *mod_time_str ;
    char *file_mod_time = get_file_time(path);
    if((mod_time_str = get_header_param("If-Modified-Since", conn_info->request_header))) {
        if(!is_expire(mod_time_str, file_mod_time)) {
            conn_info->status_code = 304;
            send_error_response(conn_info);
            return;
        }
    }

    FILE* file = fopen(path, "r");
    fseek(file, 0, SEEK_END);
    header_body.content_len = ftell(file);
    rewind(file);

    add_header_param("Last-Modified", file_mod_time, conn_info->response_header);
    uws_free(file_mod_time);

    header_body.content = (char*) uws_malloc (header_body.content_len * sizeof(char));
    size_t read_size = fread(header_body.content, sizeof(char), header_body.content_len, file);
    fclose(file);

}
Exemplo n.º 20
0
static void handle_write(const char *req, int *req_index)
{
    if (!uart_is_open(uart)) {
        send_error_response("ebadf");
        return;
    }

    int term_size;
    if (ei_decode_tuple_header(req, req_index, &term_size) < 0 ||
            term_size != 2)
        errx(EXIT_FAILURE, "expecting {data, timeout}");

    int term_type;
    if (ei_get_type(req, req_index, &term_type, &term_size) < 0 ||
            term_type != ERL_BINARY_EXT)
        errx(EXIT_FAILURE, "expecting data as a binary");

    uint8_t *to_write = malloc(term_size);
    long amount_to_write;
    if (ei_decode_binary(req, req_index, to_write, &amount_to_write) < 0)
        errx(EXIT_FAILURE, "decode binary error?");

    long timeout;
    if (ei_decode_long(req, req_index, &timeout) < 0)
        errx(EXIT_FAILURE, "expecting timeout");

    // uart_write always invokes a callback when it completes (error or no error).
    uart_write(uart, to_write, amount_to_write, timeout);
}
Exemplo n.º 21
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));
}
Exemplo n.º 22
0
w_root_t *resolve_root_or_err(struct watchman_client *client, json_t *args,
                              int root_index, bool create) {
  w_root_t *root;
  const char *root_name;
  char *errmsg = NULL;
  json_t *ele;

  ele = json_array_get(args, root_index);
  if (!ele) {
    send_error_response(client, "wrong number of arguments");
    return NULL;
  }

  root_name = json_string_value(ele);
  if (!root_name) {
    send_error_response(client, "invalid value for argument %d, expected "
                                "a string naming the root dir",
                        root_index);
    return NULL;
  }

  if (client->client_mode) {
    root = w_root_resolve_for_client_mode(root_name, &errmsg);
  } else {
    if (!client->client_is_owner) {
      // Only the owner is allowed to create watches
      create = false;
    }
    root = w_root_resolve(root_name, create, &errmsg);
  }

  if (!root) {
    if (!client->client_is_owner) {
      send_error_response(client, "unable to resolve root %s: %s (this may be "
                                  "because you are not the process owner)",
                          root_name, errmsg);
    } else {
      send_error_response(client, "unable to resolve root %s: %s", root_name,
                          errmsg);
    }
    free(errmsg);
  } else {
    w_perf_add_root_meta(&client->perf_sample, root);
  }

  return root;
}
Exemplo n.º 23
0
static void handle_set_break(const char *req, int *req_index)
{
    int val;
    if (ei_decode_boolean(req, req_index, &val) < 0) {
        send_error_response("einval");
        return;
    }

    if (!uart_is_open(uart)) {
        send_error_response("ebadf");
        return;
    }

    if (uart_set_break(uart, !!val) >= 0)
        send_ok_response();
    else
        send_error_response(uart_last_error());
}
Exemplo n.º 24
0
static void handle_write_completed(int rc, const uint8_t *data)
{
    free((uint8_t *) data);

    if (rc == 0)
        send_ok_response();
    else
        send_error_response(uart_last_error());
}
Exemplo n.º 25
0
/* trigger-del /root triggername
 * Delete a trigger from a root
 */
static void cmd_trigger_delete(struct watchman_client *client, json_t *args)
{
    w_root_t *root;
    json_t *resp;
    json_t *jname;
    w_string_t *tname;
    bool res;

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

    if (json_array_size(args) != 3) {
        send_error_response(client, "wrong number of arguments");
        w_root_delref(root);
        return;
    }
    jname = json_array_get(args, 2);
    if (!json_is_string(jname)) {
        send_error_response(client, "expected 2nd parameter to be trigger name");
        w_root_delref(root);
        return;
    }
    tname = json_to_w_string_incref(jname);

    w_root_lock(root, "trigger-del");
    res = w_ht_del(root->commands, w_ht_ptr_val(tname));
    w_root_unlock(root);

    if (res) {
        w_state_save();
    }

    w_string_delref(tname);

    resp = make_response();
    set_prop(resp, "deleted", json_boolean(res));
    json_incref(jname);
    set_prop(resp, "trigger", jname);
    send_and_dispose_response(client, resp);
    w_root_delref(root);
}
Exemplo n.º 26
0
static void cmd_debug_set_subscriptions_paused(
    struct watchman_client* clientbase,
    const json_ref& args) {
  auto client = (struct watchman_user_client*)clientbase;

  const auto& paused = args.at(1);
  auto& paused_map = paused.object();
  for (auto& it : paused_map) {
    auto sub_iter = client->subscriptions.find(it.first);
    if (sub_iter == client->subscriptions.end()) {
      send_error_response(
          client,
          "this client does not have a subscription named '%s'",
          it.first.c_str());
      return;
    }
    if (!json_is_boolean(it.second)) {
      send_error_response(
          client,
          "new value for subscription '%s' not a boolean",
          it.first.c_str());
      return;
    }
  }

  auto states = json_object();

  for (auto& it : paused_map) {
    auto sub_iter = client->subscriptions.find(it.first);
    bool old_paused = sub_iter->second->debug_paused;
    bool new_paused = json_is_true(it.second);
    sub_iter->second->debug_paused = new_paused;
    states.set(
        it.first,
        json_object({{"old", json_boolean(old_paused)}, {"new", it.second}}));
  }

  auto resp = make_response();
  resp.set("paused", std::move(states));
  send_and_dispose_response(clientbase, std::move(resp));
}
Exemplo n.º 27
0
bool dispatch_command(struct watchman_client *client, json_t *args, int mode)
{
  struct watchman_command_handler_def *def;
  char *errmsg = NULL;

  def = lookup(args, &errmsg, mode);

  if (!def) {
    send_error_response(client, "%s", errmsg);
    free(errmsg);
    return false;
  }

  if (poisoned_reason && (def->flags & CMD_POISON_IMMUNE) == 0) {
    send_error_response(client, "%s", poisoned_reason);
    return false;
  }

  def->func(client, args);
  return true;
}
Exemplo n.º 28
0
w_root_t *resolve_root_or_err(
    struct watchman_client *client,
    json_t *args,
    int root_index,
    bool create)
{
  w_root_t *root;
  const char *root_name;
  char *errmsg = NULL;
  json_t *ele;

  ele = json_array_get(args, root_index);
  if (!ele) {
    send_error_response(client, "wrong number of arguments");
    return NULL;
  }

  root_name = json_string_value(ele);
  if (!root_name) {
    send_error_response(client,
        "invalid value for argument %d, expected "
        "a string naming the root dir",
        root_index);
    return NULL;
  }

  if (client->client_mode) {
    root = w_root_resolve_for_client_mode(root_name, &errmsg);
  } else {
    root = w_root_resolve(root_name, create, &errmsg);
  }

  if (!root) {
    send_error_response(client,
        "unable to resolve root %s: %s",
        root_name, errmsg);
    free(errmsg);
  }
  return root;
}
Exemplo n.º 29
0
/* trigger-del /root triggername
 * Delete a trigger from a root
 */
void cmd_trigger_delete(struct watchman_client *client, json_t *args)
{
  w_root_t *root;
  json_t *resp;
  const char *name;
  w_string_t *tname;
  bool res;

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

  if (json_array_size(args) != 3) {
    send_error_response(client, "wrong number of arguments");
    w_root_delref(root);
    return;
  }
  name = json_string_value(json_array_get(args, 2));
  if (!name) {
    send_error_response(client, "expected 2nd parameter to be trigger name");
    w_root_delref(root);
    return;
  }
  tname = w_string_new(name);

  w_root_lock(root);
  res = w_ht_del(root->commands, (w_ht_val_t)tname);
  w_root_unlock(root);

  w_state_save();

  w_string_delref(tname);

  resp = make_response();
  set_prop(resp, "deleted", json_boolean(res));
  set_prop(resp, "trigger", json_string_nocheck(name));
  send_and_dispose_response(client, resp);
  w_root_delref(root);
}
Exemplo n.º 30
0
/*
 * Handle {name, kv_list}
 *
 *    name is the serial port name
 *    kv_list a list of configuration values (speed, parity, etc.)
 */
static void handle_open(const char *req, int *req_index)
{
    int term_type;
    int term_size;

    if (ei_decode_tuple_header(req, req_index, &term_size) < 0 ||
            term_size != 2)
        errx(EXIT_FAILURE, ":open requires a 2-tuple");

    char name[32];
    long binary_len;
    if (ei_get_type(req, req_index, &term_type, &term_size) < 0 ||
            term_type != ERL_BINARY_EXT ||
            term_size >= (int) sizeof(name) ||
            ei_decode_binary(req, req_index, name, &binary_len) < 0) {
        // The name is almost certainly too long, so report that it
        // doesn't exist.
        send_error_response("enoent");
        return;
    }
    name[term_size] = '\0';

    struct uart_config config = current_config;
    if (parse_option_list(req, req_index, &config) < 0) {
        send_error_response("einval");
        return;
    }

    // If the uart was already open, close and open it again
    if (uart_is_open(uart))
        uart_close(uart);

    if (uart_open(uart, name, &config) >= 0) {
        current_config = config;
        send_ok_response();
    } else {
        send_error_response(uart_last_error());
    }
}