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