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