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