Reputation: 47
I want to add some lines to \etc\ssh\sshd_config
using ssh.net, I have tried this method
SFTPCLient.WriteAllLines(string path, string[] content)
but it adds the content
at the beginning of the file after deleting the same number of lines. In the documentation I've found this It is not first truncated to zero bytes.
what does it mean?
I've tried also this method public abstract void Write(byte[] buffer, int offset, int count);
with another file, because I didn't want to risque deleting other lines, BUT it doesn't work, can anyone explain the values that the offset and the count must take?
string[] config = {"Match user Fadwa", "ChrootDirectory /fadwa/dhifi/test",
"ForceCommand internal-sftp -d /fadwa"};
byte[] bconfig = config.SelectMany(s =>Encoding.UTF8.GetBytes(s +
Environment.NewLine)).ToArray();
Renci.SshNet.Sftp.SftpFileStream stream = sftpClient.OpenWrite("/sftp/dhifi/test.txt");
if (stream.CanWrite)
{
stream.Write(bconfig,0,bconfig.Length);
}
else Console.WriteLine("Can't Write right now ! ");
Else, any other solution is welcome, thanks in advance!
Upvotes: 1
Views: 951
Reputation: 16612
SftpClient.OpenWrite()
creates a Stream
positioned at the beginning of the file. "It is not first truncated to zero bytes" means that Stream
will not be writing into what is effectively an empty file, but instead overwriting the existing bytes of the file. Thus, if the existing file is longer than the content
parameter of SftpFileStream.Write()
, the resulting file will consist of content
followed by the remainder of the existing file, which is exactly what you observed.
Looking at the documentation I see a few solutions:
SftpClient.AppendAllLines()
:
sftpClient.AppendAllLines("/sftp/dhifi/test.txt", config);
SftpClient.AppendText()
:
using (StreamWriter writer = sftpClient.AppendText("/sftp/dhifi/test.txt"))
foreach (string line in config)
writer.WriteLine(line);
Since you want to start writing at the end of the file, instead of SftpClient.OpenWrite()
you can call SftpClient.Open()
, which allows you to specify a FileMode
of Append
:
using (SftpFileStream stream = sftpClient.Open("/sftp/dhifi/test.txt", FileMode.Open | FileMode.Append))
stream.Write(bconfig, 0, bconfig.Length);
I don't believe your check of CanWrite
is necessary because the Stream
should fail to open in the first place if FileAccess.Write
could not be granted.
If FileMode.Append
for some reason doesn't work with SSH.NET (and it looks like it does since that's what AppendText()
uses) you could instead use @jdweng's suggestion and seek to the end of the file before writing to it:
using (SftpFileStream stream = sftpClient.OpenWrite("/sftp/dhifi/test.txt"))
{
stream.Seek(0, SeekOrigin.End);
stream.Write(bconfig, 0, bconfig.Length);
}
As an aside, another way to inject NewLine
s between your config
lines would be...
byte[] bconfig = Encoding.UTF8.GetBytes(
string.Join(Environment.NewLine, config)
);
That's a little shorter and more efficient since it reduces the number of intermediate string
s and byte[]
s.
Upvotes: 1