*** curl-7.16.3-20070601/lib/ssh.c	2007-05-15 04:00:02.000000000 +0200
--- curl-7.16.3-20070601.new/lib/ssh.c	2007-06-04 09:42:44.000000000 +0200
***************
*** 161,166 ****
--- 161,167 ----
  static const char *sftp_libssh2_strerror(unsigned long err);
  static CURLcode sftp_sendquote(struct connectdata *conn,
                                 struct curl_slist *quote);
+ static CURLcode sftp_create_dirs(struct connectdata *conn);
  
  static LIBSSH2_ALLOC_FUNC(libssh2_malloc);
  static LIBSSH2_REALLOC_FUNC(libssh2_realloc);
***************
*** 711,717 ****
    curl_off_t bytecount = 0;
    char *buf = data->state.buffer;
    unsigned long err = 0;
! 
    *done = TRUE; /* unconditionally */
  
    /* Send any quote commands */
--- 712,719 ----
    curl_off_t bytecount = 0;
    char *buf = data->state.buffer;
    unsigned long err = 0;
!   char *slash_pos = 0;
!   unsigned int sftp_err = 0;
    *done = TRUE; /* unconditionally */
  
    /* Send any quote commands */
***************
*** 735,744 ****
                          LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
                          LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
      if (!sftp->sftp_handle) {
!       err = libssh2_sftp_last_error(sftp->sftp_session);
!       failf(conn->data, "Could not open remote file for writing: %s",
              sftp_libssh2_strerror(err));
!       return sftp_libssh2_error_to_CURLE(err);
      }
  
      /* upload data */
--- 737,764 ----
                          LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
                          LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
      if (!sftp->sftp_handle) {
!       sftp_err = libssh2_sftp_last_error(sftp->sftp_session);
!       if (sftp_err == LIBSSH2_FX_NO_SUCH_FILE 
!           || sftp_err == LIBSSH2_FX_FAILURE 
!           || sftp_err == LIBSSH2_FX_NO_SUCH_PATH) {
!         if (conn->data->set.ftp_create_missing_dirs && strlen(sftp->path) > 1) { 
!           /* try to create the path remotely */
!           res = sftp_create_dirs(conn);
!           if (res == 0) {
!             sftp->sftp_handle =
!               libssh2_sftp_open(sftp->sftp_session, sftp->path,
!                   LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
!                   LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
!                   LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
!           }
!         }
!       }
!       if (!sftp->sftp_handle) {
!         err = libssh2_sftp_last_error(sftp->sftp_session);
!         failf(conn->data, "Could not open remote file for writing: %s",
              sftp_libssh2_strerror(err));
!         return sftp_libssh2_error_to_CURLE(err);
!       }
      }
  
      /* upload data */
***************
*** 1392,1395 ****
--- 1412,1449 ----
    return nread;
  }
  
+ /*
+  * Create the path sftp->path on the remote site
+  * returns CURL_OK on success, -1 on failure
+  */
+ static CURLcode sftp_create_dirs(struct connectdata *conn) {
+   CURLcode res = -1;
+   unsigned int sftp_err = 0;
+   struct SSHPROTO *sftp = conn->data->reqdata.proto.ssh;
+   if (strlen(sftp->path) > 1) {
+     char *slash_pos = sftp->path + 1; /* ignore the leading '/' */
+     while((slash_pos = index(slash_pos, '/')) != 0) {
+       *slash_pos = 0;
+       infof(conn->data, "Creating directory '%s'\n", sftp->path);
+       /* 'mode' - parameter is preliminary - I'm not sure how to treat it */
+       res = libssh2_sftp_mkdir(sftp->sftp_session, sftp->path, 
+           LIBSSH2_SFTP_S_IRWXU | LIBSSH2_SFTP_S_IRWXG);
+       *slash_pos = '/';
+       ++slash_pos;
+       if (res == -1) { 
+         /* abort if failure wasn't that the dir already exists or the
+          * permission was denied (creation might succeed further 
+          * down the path) - retry on unspecific FAILURE also
+          */
+         sftp_err = libssh2_sftp_last_error(sftp->sftp_session);
+         if (sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS 
+             && sftp_err != LIBSSH2_FX_FAILURE 
+             && sftp_err != LIBSSH2_FX_PERMISSION_DENIED) {
+           break;
+         }
+       }
+     }
+   }
+   return res;
+ }
  #endif /* USE_LIBSSH2 */

