xref: /haiku/src/apps/codycam/SftpClient.cpp (revision 6a739773fceb43d72a2314eafb465d301ae36310)
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