Skip to content
ssh.c 71.1 KiB
Newer Older
            failf(data, "Syntax error: chgrp gid not a number");
            return CURLE_FTP_QUOTE_ERROR;
          }
        }
        else if (curl_strnequal(item->data, "chmod", 5)) {
          attrs.permissions = strtol(path1, NULL, 8);/* permissions are octal */
          if (attrs.permissions == 0 && !ISDIGIT(path1[0])) {
            free(path1);
            free(path2);
            failf(data, "Syntax error: chmod permissions not a number");
            return CURLE_FTP_QUOTE_ERROR;
          }
        }
        else if (curl_strnequal(item->data, "chown", 5)) {
          attrs.uid = strtol(path1, NULL, 10);
          if (attrs.uid == 0 && !ISDIGIT(path1[0])) {
            free(path1);
            free(path2);
            failf(data, "Syntax error: chown uid not a number");
            return CURLE_FTP_QUOTE_ERROR;
          }
        }

        /* Now send the completed structure... */
#if (LIBSSH2_APINO >= 200706012030)
        while ((ret = libssh2_sftp_setstat(sftp_session, path2, &attrs)) ==
               LIBSSH2_ERROR_EAGAIN);
        if (ret != 0) {
          err = libssh2_sftp_last_error(sftp_session);
          free(path1);
          free(path2);
          failf(data, "Attempt to set SFTP stats failed: %s",
                sftp_libssh2_strerror(err));
          return CURLE_FTP_QUOTE_ERROR;
        }
#else /* !(LIBSSH2_APINO >= 200706012030) */
        if (libssh2_sftp_setstat(sftp_session, path2, &attrs) != 0) {
          err = libssh2_sftp_last_error(sftp_session);
          free(path1);
          free(path2);
          failf(data, "Attempt to set SFTP stats failed: %s",
                sftp_libssh2_strerror(err));
          return CURLE_FTP_QUOTE_ERROR;
        }
#endif /* !(LIBSSH2_APINO >= 200706012030) */
      }
      else if (curl_strnequal(item->data, "ln ", 3) ||
               curl_strnequal(item->data, "symlink ", 8)) {
        /* symbolic linking */
        /* path1 is the source */
        err = get_pathname(&cp, &path2);  /* get the destination */
        if (err) {
          if (err == CURLE_OUT_OF_MEMORY)
            failf(data, "Out of memory");
          else
            failf(data,
                  "Syntax error in ln/symlink: Bad second parameter");
          free(path1);
          return err;
        }
#if (LIBSSH2_APINO >= 200706012030)
        while ((ret = libssh2_sftp_symlink(sftp_session, path1, path2)) ==
               LIBSSH2_ERROR_EAGAIN);
        if (ret != 0) {
          err = libssh2_sftp_last_error(sftp_session);
          free(path1);
          free(path2);
          failf(data, "symlink command failed: %s",
                sftp_libssh2_strerror(err));
          return CURLE_FTP_QUOTE_ERROR;
        }
#else /* !(LIBSSH2_APINO >= 200706012030) */
        if (libssh2_sftp_symlink(sftp_session, path1, path2) != 0) {
          err = libssh2_sftp_last_error(sftp_session);
          free(path1);
          free(path2);
          failf(data, "symlink command failed: %s",
                sftp_libssh2_strerror(err));
          return CURLE_FTP_QUOTE_ERROR;
        }
#endif /* !(LIBSSH2_APINO >= 200706012030) */
      }
      else if (curl_strnequal(item->data, "mkdir ", 6)) { /* create dir */
#if (LIBSSH2_APINO >= 200706012030)
        while ((ret = libssh2_sftp_mkdir(sftp_session, path1, 0744)) ==
               LIBSSH2_ERROR_EAGAIN);
        if (ret != 0) {
          err = libssh2_sftp_last_error(sftp_session);
          free(path1);
          failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
          return CURLE_FTP_QUOTE_ERROR;
        }
#else /* !(LIBSSH2_APINO >= 200706012030) */
        if (libssh2_sftp_mkdir(sftp_session, path1, 0744) != 0) {
          err = libssh2_sftp_last_error(sftp_session);
          free(path1);
          failf(data, "mkdir command failed: %s",
                sftp_libssh2_strerror(err));
          return CURLE_FTP_QUOTE_ERROR;
        }
#endif /* !(LIBSSH2_APINO >= 200706012030) */
      }
      else if (curl_strnequal(item->data, "rename ", 7)) { /* rename file */
        /* first param is the source path */
        err = get_pathname(&cp, &path2);  /* second param is the dest. path */
        if (err) {
          if (err == CURLE_OUT_OF_MEMORY)
            failf(data, "Out of memory");
          else
            failf(data,
                  "Syntax error in rename: Bad second parameter");
          free(path1);
          return err;
        }
#if (LIBSSH2_APINO >= 200706012030)
        while ((ret = libssh2_sftp_rename(sftp_session, path1, path2)) ==
               LIBSSH2_ERROR_EAGAIN);
        if (ret != 0) {
          err = libssh2_sftp_last_error(sftp_session);
          free(path1);
          free(path2);
          failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
          return CURLE_FTP_QUOTE_ERROR;
        }
#else /* !(LIBSSH2_APINO >= 200706012030) */
        if (libssh2_sftp_rename(sftp_session,
                                path1, path2) != 0) {
          err = libssh2_sftp_last_error(sftp_session);
          free(path1);
          free(path2);
          failf(data, "rename command failed: %s",
                sftp_libssh2_strerror(err));
          return CURLE_FTP_QUOTE_ERROR;
        }
#endif /* !(LIBSSH2_APINO >= 200706012030) */
      }
      else if (curl_strnequal(item->data, "rmdir ", 6)) { /* delete dir */
#if (LIBSSH2_APINO >= 200706012030)
        while ((ret = libssh2_sftp_rmdir(sftp_session, path1)) ==
               LIBSSH2_ERROR_EAGAIN);
        if (ret != 0) {
          err = libssh2_sftp_last_error(sftp_session);
          free(path1);
          failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
          return CURLE_FTP_QUOTE_ERROR;
        }
#else /* !(LIBSSH2_APINO >= 200706012030) */
        if (libssh2_sftp_rmdir(sftp_session,
                               path1) != 0) {
          err = libssh2_sftp_last_error(sftp_session);
          free(path1);
          failf(data, "rmdir command failed: %s",
                sftp_libssh2_strerror(err));
          return CURLE_FTP_QUOTE_ERROR;
        }
#endif /* !(LIBSSH2_APINO >= 200706012030) */
      }
      else if (curl_strnequal(item->data, "rm ", 3)) { /* delete file */
#if (LIBSSH2_APINO >= 200706012030)
        while ((ret = libssh2_sftp_unlink(sftp_session, path1)) ==
               LIBSSH2_ERROR_EAGAIN);
        if (ret != 0) {
          err = libssh2_sftp_last_error(sftp_session);
          free(path1);
          failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
          return CURLE_FTP_QUOTE_ERROR;
        }
#else /* !(LIBSSH2_APINO >= 200706012030) */
        if (libssh2_sftp_unlink(sftp_session, path1) != 0) {
          err = libssh2_sftp_last_error(sftp_session);
          free(path1);
          failf(data, "rm command failed: %s",
                sftp_libssh2_strerror(err));
          return CURLE_FTP_QUOTE_ERROR;
        }
#endif /* !(LIBSSH2_APINO >= 200706012030) */
      }

      if (path1)
        free(path1);
      if (path2)
        free(path2);
    }
    item = item->next;
  }
  (void)ret;    /* possibly unused */

/*
 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
 * a regular CURLcode value.
 */
ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
  (void)sockindex;

  /* libssh2_sftp_read() returns size_t !*/

#if defined(LIBSSH2SFTP_EAGAIN) && (LIBSSH2_APINO < 200706012030)
  /* we prefer the non-blocking API but that didn't exist previously */
  nread = (ssize_t)
    libssh2_sftp_readnb(conn->data->reqdata.proto.ssh->sftp_handle, mem, len);
#else
  nread = (ssize_t)
    libssh2_sftp_read(conn->data->reqdata.proto.ssh->sftp_handle, mem, len);
  return nread;
}

#endif /* USE_LIBSSH2 */