Exemple #1
0
static bool subscription_generator(
    w_query *query,
    w_root_t *root,
    struct w_query_ctx *ctx,
    void *gendata)
{
  struct watchman_file *f;
  struct watchman_client_subscription *sub = gendata;

  w_log(W_LOG_DBG, "running subscription %s %p\n",
      sub->name->buf, sub);

  // Walk back in time until we hit the boundary
  for (f = root->latest_file; f; f = f->next) {
    if (ctx->since.is_timestamp &&
        w_timeval_compare(f->otime.tv, ctx->since.timestamp) < 0) {
      break;
    }
    if (!ctx->since.is_timestamp &&
        f->otime.ticks <= ctx->since.clock.ticks) {
      break;
    }

    if (!w_query_process_file(query, ctx, f)) {
      return false;
    }
  }

  return true;
}
Exemple #2
0
static bool trigger_generator(
    w_query *query,
    w_root_t *root,
    struct w_query_ctx *ctx,
    void *gendata)
{
  struct watchman_file *f;
  struct watchman_trigger_command *cmd = gendata;

  w_log(W_LOG_DBG, "assessing trigger %s %p\n",
      cmd->triggername->buf, cmd);

  // Walk back in time until we hit the boundary
  for (f = root->latest_file; f; f = f->next) {
    if (ctx->since.is_timestamp &&
        w_timeval_compare(f->otime.tv, ctx->since.timestamp) < 0) {
      break;
    }
    if (!ctx->since.is_timestamp &&
        f->otime.ticks <= ctx->since.clock.ticks) {
      break;
    }

    if (!w_query_file_matches_relative_root(ctx, f)) {
      continue;
    }

    if (!w_query_process_file(query, ctx, f)) {
      return false;
    }
  }

  return true;
}
Exemple #3
0
static bool time_generator(
    w_query *query,
    w_root_t *root,
    struct w_query_ctx *ctx)
{
  struct watchman_file *f;

  // Walk back in time until we hit the boundary
  for (f = root->latest_file; f; f = f->next) {
    if (ctx->since.is_timestamp &&
        w_timeval_compare(f->otime.tv, ctx->since.timestamp) < 0) {
      break;
    }
    if (!ctx->since.is_timestamp &&
        f->otime.ticks < ctx->since.clock.ticks) {
      break;
    }

    if (!w_query_process_file(query, ctx, f)) {
      return false;
    }
  }

  return true;
}
Exemple #4
0
static bool eval_since(struct w_query_ctx *ctx,
    struct watchman_file *file,
    void *data)
{
  struct since_term *term = data;
  w_clock_t clock;
  struct w_query_since since;
  time_t tval = 0;

  w_clockspec_eval(ctx->root, term->spec, &since);

  switch (term->field) {
    case SINCE_OCLOCK:
    case SINCE_CCLOCK:
      clock = (term->field == SINCE_OCLOCK) ? file->otime : file->ctime;
      if (since.is_timestamp) {
        return w_timeval_compare(since.timestamp, clock.tv) > 0;
      }
      if (since.clock.is_fresh_instance) {
        return file->exists;
      }
      return clock.ticks > since.clock.ticks;
    case SINCE_MTIME:
      tval = file->st.st_mtime;
      break;
    case SINCE_CTIME:
      tval = file->st.st_ctime;
      break;
  }

  assert(since.is_timestamp);
  return tval > since.timestamp.tv_sec;
}
Exemple #5
0
static bool eval_since(struct w_query_ctx *ctx,
    struct watchman_file *file,
    void *data)
{
  struct since_term *term = data;
  w_clock_t clock;
  time_t tval = 0;

  unused_parameter(ctx);

  switch (term->field) {
    case SINCE_OCLOCK:
    case SINCE_CCLOCK:
      clock = (term->field == SINCE_OCLOCK) ? file->otime : file->ctime;
      if (term->spec.is_timestamp) {
        return w_timeval_compare(term->spec.tv, clock.tv) > 0;
      }
      return clock.ticks > term->spec.ticks;
    case SINCE_ATIME:
      tval = file->st.st_atime;
      break;
    case SINCE_MTIME:
      tval = file->st.st_mtime;
      break;
    case SINCE_CTIME:
      tval = file->st.st_ctime;
      break;
  }

  return tval > term->spec.tv.tv_sec;
}
Exemple #6
0
bool w_query_process_file(
    w_query *query,
    struct w_query_ctx *ctx,
    struct watchman_file *file)
{
  struct watchman_rule_match *m;

  if (ctx->wholename) {
    w_string_delref(ctx->wholename);
    ctx->wholename = NULL;
  }
  ctx->file = file;

  // For fresh instances, only return files that currently exist.
  if (!ctx->since.is_timestamp && ctx->since.clock.is_fresh_instance &&
      !file->exists) {
    return true;
  }

  // We produce an output for this file if there is no expression,
  // or if the expression matched.
  if (query->expr && !w_query_expr_evaluate(query->expr, ctx, file)) {
    // No matched
    return true;
  }

  // Need more room?
  if (ctx->num_results + 1 > ctx->num_allocd) {
    uint32_t new_num = ctx->num_allocd ? ctx->num_allocd * 2 : 64;
    struct watchman_rule_match *res;

    res = realloc(ctx->results, new_num * sizeof(*res));
    if (!res) {
      w_log(W_LOG_ERR, "out of memory while capturing matches!\n");
      return false;
    }

    ctx->results = res;
    ctx->num_allocd = new_num;
  }

  m = &ctx->results[ctx->num_results++];

  m->root_number = ctx->root->number;
  m->relname = w_query_ctx_get_wholename(ctx);
  if (!m->relname) {
    w_log(W_LOG_ERR, "out of memory while capturing matches!\n");
    return false;
  }
  w_string_addref(m->relname);

  m->file = file;
  if (ctx->since.is_timestamp) {
    m->is_new = w_timeval_compare(ctx->since.timestamp, file->ctime.tv) > 0;
  } else if (ctx->since.clock.is_fresh_instance) {
    m->is_new = true;
  } else {
    m->is_new = file->ctime.ticks > ctx->since.clock.ticks;
  }

  return true;
}