xref: /haiku/src/apps/codycam/SftpClient.cpp (revision b671e9bbdbd10268a042b4f4cc4317ccd03d105e)
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, "read: %d\n", len);
30 		return false;
31 	}
32 	fprintf(stderr, "reply: '%s'\n", 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, "read: %d\n", len);
50 			return false;
51 		}
52 		fprintf(stderr, "reply: '%s'\n", 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, const string& passwd)
73 {
74 	bool rc = false;
75 	BString cmd("sftp ");
76 	BString host(server.c_str());
77 	BString port;
78 	if (host.FindFirst(':'))
79 		host.MoveInto(port, host.FindFirst(':'), host.Length());
80 	port.RemoveAll(":");
81 	if (port.Length())
82 		cmd << "-oPort=" << port << " ";
83 	cmd << login.c_str();
84 	cmd << "@" << host.String();
85 	printf("COMMAND: '%s'\n", cmd.String());
86 	SetCommandLine(cmd.String());
87 	rc = SpawningUploadClient::Connect(server, login, passwd);
88 	BString reply;
89 	ssize_t len;
90 
91 	if ((len = ReadReply(&reply)) < 0) {
92 		fprintf(stderr, "read: %ld\n", len);
93 		return false;
94 	}
95 	fprintf(stderr, "reply: '%s'\n", reply.String());
96 	if (reply.FindFirst("Connecting to ") != 0)
97 		return false;
98 
99 	if ((len = ReadReply(&reply)) < 0) {
100 		fprintf(stderr, "read: %ld\n", len);
101 		return false;
102 	}
103 	fprintf(stderr, "reply: '%s'\n", reply.String());
104 	if (reply.FindFirst(/*[pP]*/"assword:") < 0)
105 		return false;
106 
107 	write(OutputPipe(), passwd.c_str(), strlen(passwd.c_str()));
108 	write(OutputPipe(), "\n", 1);
109 
110 	if ((len = ReadReply(&reply)) < 0) {
111 		fprintf(stderr, "read: %ld\n", len);
112 		return false;
113 	}
114 	fprintf(stderr, "reply: '%s'\n", reply.String());
115 	if (reply != "\n")
116 		return false;
117 
118 	if ((len = ReadReply(&reply)) < 0) {
119 		fprintf(stderr, "read: %ld\n", len);
120 		return false;
121 	}
122 	fprintf(stderr, "reply: '%s'\n", reply.String());
123 	if (reply.FindFirst("sftp>") < 0)
124 		return false;
125 	return rc;
126 }
127 
128 
129 bool
130 SftpClient::PutFile(const string& local, const string& remote, ftp_mode mode)
131 {
132 	bool rc = false;
133 	int len;
134 	//XXX: handle mode ?
135 	BString cmd("put");
136 	cmd << " " << local.c_str() << " " << remote.c_str() << "\n";
137 	SendCommand(cmd.String());
138 	BString reply;
139 
140 	if ((len = ReadReply(&reply)) < 0) {
141 		fprintf(stderr, "read: %d\n", len);
142 		return false;
143 	}
144 	fprintf(stderr, "reply: '%s'\n", reply.String());
145 	if (reply.FindFirst("Uploading") < 0)
146 		return false;
147 
148 	if ((len = ReadReply(&reply)) < 0) {
149 		fprintf(stderr, "read: %d\n", len);
150 		return false;
151 	}
152 	fprintf(stderr, "reply: '%s'\n", reply.String());
153 	if (reply.FindFirst("sftp>") < 0)
154 		return false;
155 
156 	rc = true;
157 	return rc;
158 }
159 
160 
161 bool
162 SftpClient::GetFile(const string& remote, const string& local, ftp_mode mode)
163 {
164 	bool rc = false;
165 	//XXX
166 	return rc;
167 }
168 
169 
170 // Note: this only works for local remote moves, cross filesystem moves
171 // will not work
172 bool
173 SftpClient::MoveFile(const string& oldPath, const string& newPath)
174 {
175 	bool rc = false;
176 	int len;
177 
178 	// sftpd can't rename to an existing file...
179 	BString cmd("rm");
180 	cmd << " " << newPath.c_str() << "\n";
181 	fprintf(stderr, "CMD: '%s'\n", cmd.String());
182 	SendCommand(cmd.String());
183 	BString reply;
184 
185 	if ((len = ReadReply(&reply)) < 0) {
186 		fprintf(stderr, "read: %d\n", len);
187 		return false;
188 	}
189 	fprintf(stderr, "reply: '%s'\n", reply.String());
190 	// we don't care if it worked or not.
191 	//if (reply.FindFirst("Removing") != 0 && reply.FindFirst("Couldn't") )
192 	//	return false;
193 
194 	if ((len = ReadReply(&reply)) < 0) {
195 		fprintf(stderr, "read: %d\n", len);
196 		return false;
197 	}
198 	fprintf(stderr, "reply: '%s'\n", reply.String());
199 	if (reply.FindFirst("sftp>") < 0)
200 		return false;
201 
202 	cmd = "rename";
203 	cmd << " " << oldPath.c_str() << " " << newPath.c_str() << "\n";
204 	SendCommand(cmd.String());
205 	if ((len = ReadReply(&reply)) < 0) {
206 		fprintf(stderr, "read: %d\n", len);
207 		return false;
208 	}
209 	fprintf(stderr, "reply: '%s'\n", reply.String());
210 	if (reply.FindFirst("sftp>") < 0)
211 		return false;
212 	rc = true;
213 	return rc;
214 }
215 
216 
217 bool
218 SftpClient::Chmod(const string& path, const string& mod)
219 {
220 	bool rc = false;
221 	int len;
222 	//XXX: handle mode ?
223 	BString cmd("chmod");
224 	cmd << " " << mod.c_str() << " " << path.c_str() << "\n";
225 	SendCommand(cmd.String());
226 	BString reply;
227 
228 	if ((len = ReadReply(&reply)) < 0) {
229 		fprintf(stderr, "read: %d\n", len);
230 		return false;
231 	}
232 	fprintf(stderr, "reply: '%s'\n", reply.String());
233 	if (reply.FindFirst("Changing") < 0)
234 		return false;
235 
236 	if ((len = ReadReply(&reply)) < 0) {
237 		fprintf(stderr, "read: %d\n", len);
238 		return false;
239 	}
240 	fprintf(stderr, "reply: '%s'\n", reply.String());
241 	if (reply.FindFirst("sftp>") < 0)
242 		return false;
243 
244 	rc = true;
245 	return rc;
246 }
247 
248 
249 void
250 SftpClient::SetPassive(bool on)
251 {
252 }
253 
254 
255