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