Hello, I want to suggest an option for the SFTP that will allow library's client to get information about files in the directory listing in the form of curl_fileinfo structure.
The patch in attachment works well for me, however I would like to know does it suit the Curl "philosophy". I've added DIRLISTFILES and DIRLISTFILES_CALLBACK - one enables new listing behavior, the other sets client's callback which will receive file info. The callback has the following signature: long (*curl_fileinfo_list_callback)(const struct curl_fileinfo *finf, const struct curl_fileinfo *linf, void *userptr); Where: 'finf' contains the next item's properties 'linf' contains the properties of link destination if the file is a link 'userptr' is the user pointer passed via CURLOPT_WRITEDATA I decided that such callback is much better, than parsing raw server listing entry, which is not standardized. To fill the curl_fileinfo I use LIBSSH2_SFTP_ATTRIBUTES. Concerning link files - in our application we need the information about link destination. Current SSH_SFTP_READDIR implementation reads link also. I considered adding new request to get arbitrary file attributes, but for me such an operation seemed to be out of current libcurl architecture as I understood it. Thus I decided to fetch link destination file information during directory listing. Now DIRLISTFILES does not disable normal SSH_SFTP_READDIR implementation, however I think they should be mutually excluding - client either receives textual listing, or listing in the form of curl_fileinfo. Which way is better? I'm not sure that I've done all errors handling and memory management right. Looking forward for the reviews of the patch. During the work on SFTP, I've also added these small changes: /* * ssh_statemach_act() runs the SSH state machine as far as it can without * blocking and without reaching the end. The data the pointer 'block' points @@ -1490,7 +1576,7 @@ failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err)); state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; + sshc->actualcode = sftp_libssh2_error_to_CURLE(err); break; } state(conn, SSH_SFTP_NEXT_QUOTE); @@ -1515,7 +1601,7 @@ failf(data, "rename command failed: %s", sftp_libssh2_strerror(err)); state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; + sshc->actualcode = sftp_libssh2_error_to_CURLE(err); break; } state(conn, SSH_SFTP_NEXT_QUOTE); @@ -1533,7 +1619,7 @@ failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err)); state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; + sshc->actualcode = sftp_libssh2_error_to_CURLE(err); break; } state(conn, SSH_SFTP_NEXT_QUOTE); @@ -1551,7 +1637,7 @@ failf(data, "rm command failed: %s", sftp_libssh2_strerror(err)); state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; + sshc->actualcode = sftp_libssh2_error_to_CURLE(err); break; } state(conn, SSH_SFTP_NEXT_QUOTE); They allow to get better error codes for QUOTE commands. Best Regards, Pavel Shkrabliuk
diff.patch
Description: Binary data
------------------------------------------------------------------- List admin: http://cool.haxx.se/list/listinfo/curl-library Etiquette: http://curl.haxx.se/mail/etiquette.html