1 /*
2 * Copyright 1998-1999 Be, Inc. All Rights Reserved.
3 * Copyright 2003-2019 Haiku, Inc. All rights reserved.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8 #include "SftpClient.h"
9
10 #include <unistd.h>
11
12 #include <String.h>
13
14
SftpClient()15 SftpClient::SftpClient()
16 :
17 SpawningUploadClient()
18 {
19 }
20
21
~SftpClient()22 SftpClient::~SftpClient()
23 {
24 if (OutputPipe() >= 0)
25 SendCommand("quit\n");
26 }
27
28
29 bool
ChangeDir(const string & dir)30 SftpClient::ChangeDir(const string& dir)
31 {
32 int len;
33 BString cmd("cd");
34 BString reply;
35
36 cmd << " " << dir.c_str() << "\n";
37 SendCommand(cmd.String());
38
39 len = ReadReply(&reply);
40 if (len < 0) {
41 fprintf(stderr, _GetReadText(), len);
42 return false;
43 }
44
45 fprintf(stderr, _GetReplyText(), reply.String());
46 if (reply.FindFirst("sftp>") < 0)
47 return false;
48
49 return true;
50 }
51
52
53 bool
ListDirContents(string & listing)54 SftpClient::ListDirContents(string& listing)
55 {
56 int len;
57 BString reply;
58
59 SendCommand("ls\n");
60 do {
61 len = ReadReply(&reply);
62 if (len < 0) {
63 fprintf(stderr, _GetReadText(), len);
64 return false;
65 }
66 fprintf(stderr, _GetReplyText(), reply.String());
67 printf("%s", reply.String());
68 if (reply.FindFirst("sftp>") == 0)
69 return true;
70 } while (true);
71
72 return false;
73 }
74
75
76 bool
PrintWorkingDir(string & dir)77 SftpClient::PrintWorkingDir(string& dir)
78 {
79 SendCommand("pwd\n");
80 return false;
81 }
82
83
84 bool
Connect(const string & server,const string & login,const string & passwd)85 SftpClient::Connect(const string& server, const string& login,
86 const string& passwd)
87 {
88 BString cmd("sftp ");
89 BString host(server.c_str());
90 BString port;
91
92 if (host.FindFirst(':'))
93 host.MoveInto(port, host.FindFirst(':'), host.Length());
94 port.RemoveAll(":");
95
96 if (port.Length())
97 cmd << "-oPort=" << port << " ";
98
99 cmd << login.c_str();
100 cmd << "@" << host.String();
101 printf("COMMAND: '%s'\n", cmd.String());
102 SetCommandLine(cmd.String());
103
104 if (!SpawningUploadClient::Connect(server, login, passwd))
105 return false;
106
107 BString reply;
108 ssize_t len;
109
110 len = ReadReply(&reply);
111 if (len < 0) {
112 fprintf(stderr, _GetLongReadText(), len);
113 return false;
114 }
115 fprintf(stderr, _GetReplyText(), reply.String());
116 if (reply.FindFirst("Connecting to ") != 0)
117 return false;
118
119 len = ReadReply(&reply);
120 if (len < 0) {
121 fprintf(stderr, _GetLongReadText(), len);
122 return false;
123 }
124
125 fprintf(stderr, _GetReplyText(), reply.String());
126 if (reply.FindFirst(/*[pP]*/"assword:") < 0)
127 return false;
128
129 write(OutputPipe(), passwd.c_str(), strlen(passwd.c_str()));
130 write(OutputPipe(), "\n", 1);
131
132 len = ReadReply(&reply);
133 if (len < 0) {
134 fprintf(stderr, _GetLongReadText(), len);
135 return false;
136 }
137
138 fprintf(stderr, _GetReplyText(), reply.String());
139 if (reply != "\n")
140 return false;
141
142 len = ReadReply(&reply);
143 if (len < 0) {
144 fprintf(stderr, _GetLongReadText(), len);
145 return false;
146 }
147
148 fprintf(stderr, _GetReplyText(), reply.String());
149 if (reply.FindFirst("sftp>") < 0)
150 return false;
151
152 return true;
153 }
154
155
156 bool
PutFile(const string & local,const string & remote,ftp_mode mode)157 SftpClient::PutFile(const string& local, const string& remote, ftp_mode mode)
158 {
159 int len;
160 //XXX: handle mode ?
161 BString cmd("put");
162 cmd << " " << local.c_str() << " " << remote.c_str() << "\n";
163 SendCommand(cmd.String());
164
165 BString reply;
166
167 len = ReadReply(&reply);
168 if (len < 0) {
169 fprintf(stderr, _GetReadText(), len);
170 return false;
171 }
172
173 fprintf(stderr, _GetReplyText(), reply.String());
174 if (reply.FindFirst("Uploading") < 0)
175 return false;
176
177 len = ReadReply(&reply);
178 if (len < 0) {
179 fprintf(stderr, _GetReadText(), len);
180 return false;
181 }
182
183 fprintf(stderr, _GetReplyText(), reply.String());
184 if (reply.FindFirst("sftp>") < 0)
185 return false;
186
187 return true;
188 }
189
190
191 bool
GetFile(const string & remote,const string & local,ftp_mode mode)192 SftpClient::GetFile(const string& remote, const string& local, ftp_mode mode)
193 {
194 //XXX
195 return false;
196 }
197
198
199 // Note: this only works for local remote moves, cross filesystem moves
200 // will not work
201 bool
MoveFile(const string & oldPath,const string & newPath)202 SftpClient::MoveFile(const string& oldPath, const string& newPath)
203 {
204 int len;
205
206 // sftpd can't rename to an existing file...
207 BString cmd("rm");
208 cmd << " " << newPath.c_str() << "\n";
209 fprintf(stderr, "CMD: '%s'\n", cmd.String());
210 SendCommand(cmd.String());
211 BString reply;
212
213 len = ReadReply(&reply);
214 if (len < 0) {
215 fprintf(stderr, _GetReadText(), len);
216 return false;
217 }
218
219 fprintf(stderr, _GetReplyText(), reply.String());
220 // we don't care if it worked or not.
221 //if (reply.FindFirst("Removing") != 0 && reply.FindFirst("Couldn't") )
222 // return false;
223
224 len = ReadReply(&reply);
225 if (len < 0) {
226 fprintf(stderr, _GetReadText(), len);
227 return false;
228 }
229
230 fprintf(stderr, _GetReplyText(), reply.String());
231 if (reply.FindFirst("sftp>") < 0)
232 return false;
233
234 cmd = "rename";
235 cmd << " " << oldPath.c_str() << " " << newPath.c_str() << "\n";
236 SendCommand(cmd.String());
237
238 len = ReadReply(&reply);
239 if (len < 0) {
240 fprintf(stderr, _GetReadText(), len);
241 return false;
242 }
243
244 fprintf(stderr, _GetReplyText(), reply.String());
245 if (reply.FindFirst("sftp>") < 0)
246 return false;
247
248 return true;
249 }
250
251
252 bool
Chmod(const string & path,const string & mod)253 SftpClient::Chmod(const string& path, const string& mod)
254 {
255 int len;
256 //XXX: handle mode ?
257 BString cmd("chmod");
258 cmd << " " << mod.c_str() << " " << path.c_str() << "\n";
259 SendCommand(cmd.String());
260
261 BString reply;
262
263 len = ReadReply(&reply);
264 if (len < 0) {
265 fprintf(stderr, _GetReadText(), len);
266 return false;
267 }
268
269 fprintf(stderr, _GetReplyText(), reply.String());
270 if (reply.FindFirst("Changing") < 0)
271 return false;
272
273 len = ReadReply(&reply);
274 if (len < 0) {
275 fprintf(stderr, _GetReadText(), len);
276 return false;
277 }
278
279 fprintf(stderr, _GetReplyText(), reply.String());
280 if (reply.FindFirst("sftp>") < 0)
281 return false;
282
283 return true;
284 }
285
286
287 void
SetPassive(bool on)288 SftpClient::SetPassive(bool on)
289 {
290 }
291
292
293 const char*
_GetLongReadText() const294 SftpClient::_GetLongReadText() const
295 {
296 return B_TRANSLATE("read: %ld\n");
297 }
298
299
300 const char*
_GetReadText() const301 SftpClient::_GetReadText() const
302 {
303 return B_TRANSLATE("read: %d\n");
304 }
305
306
307 const char*
_GetReplyText() const308 SftpClient::_GetReplyText() const
309 {
310 return B_TRANSLATE("reply: '%s'\n");
311 }
312