Example #1
0
END_TEST

START_TEST (dir_best_path_test) {
  char *res;
  const char *path;

  res = dir_best_path(NULL, NULL);
  fail_unless(res == NULL, "Failed to handle null arguments");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
    strerror(errno), errno);

  res = dir_best_path(p, NULL);
  fail_unless(res == NULL, "Failed to handle null path");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
    strerror(errno), errno);

  mark_point();
  path = "/foo";
  res = dir_best_path(p, path);
  fail_unless(path != NULL, "Failed to get best path for '%s': %s", path,
    strerror(errno));
  fail_unless(strcmp(res, path) == 0, "Expected '%s', got '%s'", path, res);
}
/* Handles the DELE, RNFR, and RNTO commands. */
MODRET counter_alter(cmd_rec *cmd) {
  config_rec *c;
  int res;
  pr_fh_t *fh;
  const char *path;

  if (counter_engine == FALSE) {
    return PR_DECLINED(cmd);
  }

  c = find_config(CURRENT_CONF, CONF_PARAM, "CounterMaxWriters", FALSE);
  counter_max_writers = c ? *((int *) c->argv[0]) : COUNTER_DEFAULT_MAX_WRITERS;

  if (counter_max_writers == 0) {
    return PR_DECLINED(cmd);
  }

  path = pr_fs_decode_path(cmd->tmp_pool, cmd->arg);

  if (!exists((char *) path)) {
    return PR_DECLINED(cmd);
  }

  /* The semaphores operate using dir_best_path(). */
  path = dir_best_path(cmd->tmp_pool, path);
  if (path == NULL) {
    return PR_DECLINED(cmd);
  }

  counter_curr_path = path;

  fh = counter_get_fh(cmd->tmp_pool, counter_curr_path);
  if (fh == NULL) {
    (void) pr_log_writefile(counter_logfd, MOD_COUNTER_VERSION,
      "%s: no CounterFile found for path '%s'", (char *) cmd->argv[0],
      counter_curr_path);

    /* No CounterFile configured/available for this path. */
    return PR_DECLINED(cmd);
  }

  counter_curr_semid = counter_get_sem(fh, counter_curr_path);
  if (counter_curr_semid < 0) {
    (void) pr_log_writefile(counter_logfd, MOD_COUNTER_VERSION,
      "unable to get semaphore for '%s': %s", counter_curr_path,
      strerror(errno));
    return PR_DECLINED(cmd);
  }

  /* Add a writer to this file by decrementing the writer counter value.
   * This functions as a sort of "lock".
   */
  res = counter_add_writer(counter_curr_semid);
  if (res < 0 &&
      errno == EAGAIN) {
  
    /* The lock acquisition failed, which means the file is busy.
     * The upload should be failed.
     */
    (void) pr_log_writefile(counter_logfd, MOD_COUNTER_VERSION,
      "%s: max number of writers (%d) reached for '%s'", (char *) cmd->argv[0],
      counter_max_writers, counter_curr_path);
    pr_response_add_err(R_450, _("%s: File busy"), cmd->arg);
    return PR_ERROR(cmd);
  }

  counter_pending |= COUNTER_HAVE_WRITER;
  (void) pr_log_writefile(counter_logfd, MOD_COUNTER_VERSION,
    "%s: added writer counter for '%s' (semaphore ID %d)",
    (char *) cmd->argv[0], counter_curr_path, counter_curr_semid);

  return PR_DECLINED(cmd);
}