Esempio n. 1
0
/* Command code for the various _*STAT calls.  rc is the return value
 * from *stat() and SB is the buffer. */
static uint32_t sftp_v456_stat_core(struct sftpjob *job, int rc,
                                    const struct stat *sb, const char *path) {
  struct sftpattr attrs;
  uint32_t flags;

  if(!rc) {
    pcheck(sftp_parse_uint32(job, &flags));
    sftp_stat_to_attrs(job->a, sb, &attrs, flags, path);
    sftp_send_begin(job->worker);
    sftp_send_uint8(job->worker, SSH_FXP_ATTRS);
    sftp_send_uint32(job->worker, job->id);
    protocol->sendattrs(job, &attrs);
    sftp_send_end(job->worker);
    return HANDLER_RESPONDED;
  } else
    return HANDLER_ERRNO;
}
Esempio n. 2
0
uint32_t sftp_v6_realpath(struct sftpjob *job) {
  char *path, *compose, *resolvedpath;
  uint8_t control_byte = SSH_FXP_REALPATH_NO_CHECK;
  unsigned rpflags = 0;
  struct stat sb;
  struct sftpattr attrs;

  pcheck(sftp_parse_path(job, &path));
  if(job->left) {
    pcheck(sftp_parse_uint8(job, &control_byte));
    while(job->left) {
      pcheck(sftp_parse_path(job, &compose));
      if(compose[0] == '/')
        path = compose;
      else {
        char *newpath = sftp_alloc(job->a, strlen(path) + strlen(compose) + 2);

        strcpy(newpath, path);
        strcat(newpath, "/");
        strcat(newpath, compose);
        path = newpath;
      }
    }
  }
  D(("sftp_v6_realpath %s %#x", path, control_byte));
  switch(control_byte) {
  case SSH_FXP_REALPATH_NO_CHECK:
    /* Don't follow links and don't fail if the path doesn't exist */
    rpflags = 0;
    break;
  case SSH_FXP_REALPATH_STAT_IF:
    /* Follow links but don't fail if the path doesn't exist */
    rpflags = RP_READLINK;
    break;
  case SSH_FXP_REALPATH_STAT_ALWAYS:
    /* Follow links and fail if the path doesn't exist */
    rpflags = RP_READLINK|RP_MUST_EXIST;
    break;
  default:
    return SSH_FX_BAD_MESSAGE;
  }
  if(!(resolvedpath = sftp_find_realpath(job->a, path, rpflags)))
    return HANDLER_ERRNO;
  D(("...real path is %s", resolvedpath));
  switch(control_byte) {
  case SSH_FXP_REALPATH_NO_CHECK:
    /* Don't stat, send dummy attributes */
    memset(&attrs, 0, sizeof attrs);
    attrs.name = resolvedpath;
    break;
  case SSH_FXP_REALPATH_STAT_IF:
    /* stat as hard as we can but accept failure if it's just not there */
    if(stat(resolvedpath, &sb) >= 0 || lstat(resolvedpath, &sb) >= 0)
      sftp_stat_to_attrs(job->a, &sb, &attrs, 0xFFFFFFFF, resolvedpath);
    else {
      memset(&attrs, 0, sizeof attrs);
      attrs.name = resolvedpath;
    }
    break;
  case SSH_FXP_REALPATH_STAT_ALWAYS:
    /* stat and error on failure */
    if(stat(resolvedpath, &sb) >= 0 || lstat(resolvedpath, &sb) >= 0)
      sftp_stat_to_attrs(job->a, &sb, &attrs, 0xFFFFFFFF, resolvedpath);
    else
      /* Can only happen if path is deleted between realpath call and stat */
      return HANDLER_ERRNO;
    break;
  }
  sftp_send_begin(job->worker);
  sftp_send_uint8(job->worker, SSH_FXP_NAME);
  sftp_send_uint32(job->worker, job->id);
  protocol->sendnames(job, 1, &attrs);
  sftp_send_end(job->worker);
  return HANDLER_RESPONDED;
}