ScpClient can't create directories
I'm playing with both SFTP and SCP modes of writing from .NET to a Linux box. The SftpClient supports creating a directory. I don't see similar functionality for SCP. If I pass a remote path to Upload where directories are missing the operation fails with a path not found error.
If you use ScpClient.Upload(DirectoryInfo directoryInfo, String path) to perform a recursive upload, then the (remote) path will be created.
The ScpClient.Upload(FileInfo fileInfo, String path) and ScpClient.Upload(Stream source, String path) overloads expect the path argument to be a file path.
Let me know if that answers your question.
I run into the following error when attempting to use the scp function to upload as you described. When invoking it the following way I get the following error
using (ScpClient scpClient = new ScpClient(connectionInfo)) {
scpClient.Connect();
scpClient.Upload(new DirectoryInfo("Build/Linux/Arena"), "/home/arena");
scpClient.Disconnect();
Debug.Log("Server Upload Complete");
}
ScpException: scp: /home/arena/./Arena: Is a directory
All files in the top level directory are coipied. It appears to have that issue when it attempts to recurse. There is a single folder in that top level folder (with many folders in it) called Arena_Data. I have also renamed it to ArenaData to try and rule out any strange regex stuff but I get the same issue.
@drieseng - Hello, I use the ScrpClient to update firmware on the Linux client of my device. I ran into the same problem as described above.
You said: "expect the path argument to be a file path"
So I am create my filespath:
string fileName = "/var/www/" + file.Replace(folder+ "\\", "").Replace("\\", "/");
Output:
/var/www/images/logo-2c2bfd916363d66b803aade196c16d03651bfe05d0799bbf63713e625592d721.png
And upload:
scpClient.UploadFile(file, fileName);
But still crashes - message:
scp: /var/www/images: No such file or directory
The filesystem on Linux does not have the folder "images".
Any solutions or suggestions on this?
any update on this ?
I'm getting the same problem, if the folder does not exist it is not created, I need to create it first, and specify that new location so the content of the directory is copied into that destination. I wonder if it is because of the -d server-side parameter https://github.com/sshnet/SSH.NET/blob/develop/src/Renci.SshNet/ScpClient.cs#L377
Hmm, yes it seems to be
Suppose path="/tmp/dir"
Right now it sends scp -r -p -d -t /tmp/dir then sends the inner file and directory messages.
I have a tentative fix: to send scp -r -p -t /tmp and then the directory message D0755 0 dir. But I'm wondering if that's going to change the permissions on dir when it already exists. Not sure if this is the way to do it.
Would it make sense to have one overload where the content goes into the targeted directory and another one where the path should be created or make it a flag with a default of checking if the target is a directory that can be changed like in the SCP code https://github.com/openssh/openssh-portable/blob/606077ee1e77af5908431d003fb28461ef7be092/scp.c#L560 ?
right now the only other option to upload a file is to run a mkdir command before uploading.
Yeah, adding something like Upload(DirectoryInfo directoryInfo, string path, bool create) where create switches on -d vs D0755 is probably easiest. Then it's kind of on the user if they pass create = true with a pre-existing directory in case the permissions change (not checked if they do yet)
from what I understand from reading this a C or E would be needed based on this https://web.archive.org/web/20170215184048/https://blogs.oracle.com/janp/entry/how_the_scp_protocol_works
Any testing I could do to help get a fox for this?
Sorry, I pushed the branch I was testing on locally to https://github.com/sshnet/SSH.NET/compare/develop...Rob-Hague:SSH.NET:scpuploaddir but I've not gotten round to implementing the changes (but it is on my list)