static int is_symlink_path(pool *p, const char *path, size_t pathlen) {
  int res, xerrno = 0;
  struct stat st;
  char *ptr;

  if (pathlen == 0) {
    return 0;
  }

  pr_fs_clear_cache2(path);
  res = pr_fsio_lstat(path, &st);
  if (res < 0) {
    xerrno = errno;

    pr_log_pri(PR_LOG_WARNING, "error: unable to check %s: %s", path,
      strerror(xerrno));

    errno = xerrno;
    return -1;
  }

  if (S_ISLNK(st.st_mode)) {
    errno = EPERM;
    return -1;
  }

  /* To handle the case where a component further up the path might be a
   * symlink (which lstat(2) will NOT handle), we walk the path backwards,
   * calling ourselves recursively.
   */

  ptr = strrchr(path, '/');
  if (ptr != NULL) {
    char *new_path;
    size_t new_pathlen;

    pr_signals_handle();

    new_pathlen = ptr - path;
    new_path = pstrndup(p, path, new_pathlen);

    pr_log_debug(DEBUG10,
      "AllowChrootSymlink: path '%s' not a symlink, checking '%s'", path,
      new_path);
    res = is_symlink_path(p, new_path, new_pathlen);
    if (res < 0) {
      return -1;
    }
  }

  return 0;
}
static int is_symlink_path(pool *p, const char *path, size_t pathlen) {
  int res, xerrno = 0;
  struct stat st;
  char *ptr;

  if (pathlen == 0) {
    return 0;
  }

  pr_fs_clear_cache2(path);
  res = pr_fsio_lstat(path, &st);
  if (res < 0) {
    xerrno = errno;

    pr_log_pri(PR_LOG_WARNING, "error: unable to check %s: %s", path,
      strerror(xerrno));

    errno = xerrno;
    return -1;
  }

  if (S_ISLNK(st.st_mode)) {
    errno = EPERM;
    return -1;
  }

   

  ptr = strrchr(path, '/');
  if (ptr != NULL) {
    char *new_path;
    size_t new_pathlen;

    pr_signals_handle();

    new_pathlen = ptr - path;
    new_path = pstrndup(p, path, new_pathlen);

    pr_log_debug(DEBUG10,
      "AllowChrootSymlink: path '%s' not a symlink, checking '%s'", path,
      new_path);
    res = is_symlink_path(p, new_path, new_pathlen);
    if (res < 0) {
      return -1;
    }
  }

  return 0;
}