xref: /haiku/src/apps/codycam/SftpClient.cpp (revision 323b65468e5836bb27a5e373b14027d902349437)
1 #include <String.h>
2 #include <unistd.h>
3 
4 #include "SftpClient.h"
5 
6 SftpClient::SftpClient()
7 	: SpawningUploadClient()
8 {
9 }
10 
11 
12 SftpClient::~SftpClient()
13 {
14 	if (OutputPipe() >= 0)
15 		SendCommand("quit\n");
16 }
17 
18 
19 bool
20 SftpClient::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 
40 bool
41 SftpClient::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 
61 bool
62 SftpClient::PrintWorkingDir(string& dir)
63 {
64 	bool rc = false;
65 	SendCommand("pwd\n");
66 	BString reply;
67 	return rc;
68 }
69 
70 
71 bool
72 SftpClient::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 
130 bool
131 SftpClient::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 
162 bool
163 SftpClient::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
173 bool
174 SftpClient::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 
218 bool
219 SftpClient::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 
250 void
251 SftpClient::SetPassive(bool on)
252 {
253 }
254 
255 
256 const char*
257 SftpClient::_GetLongReadText() const
258 {
259 	return B_TRANSLATE("read: %ld\n");
260 }
261 
262 
263 const char*
264 SftpClient::_GetReadText() const
265 {
266 	return B_TRANSLATE("read: %d\n");
267 }
268 
269 
270 const char*
271 SftpClient::_GetReplyText() const
272 {
273 	return B_TRANSLATE("reply: '%s'\n");
274 }
275 
276 
277