/* * 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 long err = 0; struct SSHPROTO *sftp = conn->data->reqdata.proto.ssh; char *slash_pos, *slash_posr = 0; LIBSSH2_SFTP_ATTRIBUTES attrs; if (strlen(sftp->path) > 1) { /* we expect a full path - just a '/' isn't enough */ /* determine where in the path to start creation (backwards) */ while((slash_pos = strrchr(sftp->path, '/')) != sftp->path) { /* ignore the leading '/' */ *slash_pos = 0; res = libssh2_sftp_stat(sftp->sftp_session, sftp->path, &attrs); if (slash_posr != 0) *slash_posr = '/'; slash_posr = slash_pos; if (res != -1 ) { if (attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { /* got valid info */ if (attrs.permissions & LIBSSH2_SFTP_S_IFDIR) { /* and it's a dir */ slash_posr = 0; *slash_pos = '/'; ++slash_pos; /* start path creation (below) one step further down */ break; } else { /* bail out, not a directory */ failf(conn->data, "Can't create directory '%s', path element not a directory\n", sftp->path); return -1; } } else { /* bail out, invalid stat-data */ failf(conn->data, "Could not get valid information for the remote directory '%s'\n", sftp->path); return -1; } } else { err = libssh2_sftp_last_error(sftp->sftp_session); /* bail out if error isn't a missing directory */ if (err != LIBSSH2_FX_NO_SUCH_FILE && err != LIBSSH2_FX_NO_SUCH_PATH) { failf(conn->data, "Could not get information for the remote directory '%s': %s (%u)\n", sftp->path, sftp_libssh2_strerror(err), err); return -1; } } } if (slash_posr != 0) *slash_posr = '/'; /* repair / at 0 marker */ /* create the missing part of the path (forward :)*/ while((slash_pos = strchr(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 on every error, as we should be able to create any * missing part */ err = libssh2_sftp_last_error(sftp->sftp_session); failf(conn->data, "Could not create remote directory '%s': %s (%u)\n", sftp->path, sftp_libssh2_strerror(err), err); break; } } } return res; }