Might work better with the files :)))

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23321 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol
2008-01-09 18:51:55 +00:00
parent 718140546e
commit 42b2e5d59a
4 changed files with 492 additions and 0 deletions
+223
View File
@@ -0,0 +1,223 @@
#include <String.h>
#include <unistd.h>
#include "SftpClient.h"
SftpClient::SftpClient()
: SpawningUploadClient()
{
}
SftpClient::~SftpClient()
{
if (OutputPipe() >= 0)
SendCommand("quit\n");
}
bool
SftpClient::ChangeDir(const string& dir)
{
bool rc = false;
int len;
BString cmd("cd");
BString reply;
cmd << " " << dir.c_str() << "\n";
SendCommand(cmd.String());
if ((len = ReadReply(&reply)) < 0) {
fprintf(stderr, "read: %s\n", len);
return false;
}
fprintf(stderr, "reply: '%s'\n", reply.String());
if (reply.FindFirst("sftp>") < 0)
return false;
rc = true;
return rc;
}
bool
SftpClient::ListDirContents(string& listing)
{
bool rc = false;
int len;
SendCommand("ls\n");
BString reply;
do {
if ((len = ReadReply(&reply)) < 0) {
fprintf(stderr, "read: %s\n", len);
return false;
}
fprintf(stderr, "reply: '%s'\n", reply.String());
printf("%s", reply.String());
if (reply.FindFirst("sftp>") == 0)
return true;
} while (true);
return rc;
}
bool
SftpClient::PrintWorkingDir(string& dir)
{
bool rc = false;
int len;
SendCommand("pwd\n");
BString reply;
return rc;
}
bool
SftpClient::Connect(const string& server, const string& login, const string& passwd)
{
bool rc = false;
BString cmd("sftp ");
cmd << login.c_str();
cmd << "@" << server.c_str();
SetCommandLine(cmd.String());
rc = SpawningUploadClient::Connect(server, login, passwd);
BString reply;
ssize_t len;
if ((len = ReadReply(&reply)) < 0) {
fprintf(stderr, "read: %d\n", len);
return false;
}
fprintf(stderr, "reply: '%s'\n", reply.String());
if (reply.FindFirst("Connecting to ") != 0)
return false;
if ((len = ReadReply(&reply)) < 0) {
fprintf(stderr, "read: %s\n", len);
return false;
}
fprintf(stderr, "reply: '%s'\n", reply.String());
if (reply.FindFirst("password:") < 0)
return false;
write(OutputPipe(), passwd.c_str(), strlen(passwd.c_str()));
write(OutputPipe(), "\n", 1);
if ((len = ReadReply(&reply)) < 0) {
fprintf(stderr, "read: %s\n", len);
return false;
}
fprintf(stderr, "reply: '%s'\n", reply.String());
if (reply != "\n")
return false;
if ((len = ReadReply(&reply)) < 0) {
fprintf(stderr, "read: %s\n", len);
return false;
}
fprintf(stderr, "reply: '%s'\n", reply.String());
if (reply.FindFirst("sftp>") < 0)
return false;
return rc;
}
bool
SftpClient::PutFile(const string& local, const string& remote, ftp_mode mode)
{
bool rc = false;
int len;
//XXX: handle mode ?
BString cmd("put");
cmd << " " << local.c_str() << " " << remote.c_str() << "\n";
SendCommand(cmd.String());
BString reply;
if ((len = ReadReply(&reply)) < 0) {
fprintf(stderr, "read: %s\n", len);
return false;
}
fprintf(stderr, "reply: '%s'\n", reply.String());
if (reply.FindFirst("Uploading") < 0)
return false;
if ((len = ReadReply(&reply)) < 0) {
fprintf(stderr, "read: %s\n", len);
return false;
}
fprintf(stderr, "reply: '%s'\n", reply.String());
if (reply.FindFirst("sftp>") < 0)
return false;
rc = true;
return rc;
}
bool
SftpClient::GetFile(const string& remote, const string& local, ftp_mode mode)
{
bool rc = false;
//XXX
return rc;
}
// Note: this only works for local remote moves, cross filesystem moves
// will not work
bool
SftpClient::MoveFile(const string& oldPath, const string& newPath)
{
bool rc = false;
int len;
BString cmd("rename");
cmd << " " << oldPath.c_str() << " " << newPath.c_str() << "\n";
SendCommand(cmd.String());
BString reply;
if ((len = ReadReply(&reply)) < 0) {
fprintf(stderr, "read: %s\n", len);
return false;
}
fprintf(stderr, "reply: '%s'\n", reply.String());
if (reply.FindFirst("sftp>") < 0)
return false;
rc = true;
return rc;
}
bool
SftpClient::Chmod(const string& path, const string& mod)
{
bool rc = false;
int len;
//XXX: handle mode ?
BString cmd("chmod");
cmd << " " << mod.c_str() << " " << path.c_str() << "\n";
SendCommand(cmd.String());
BString reply;
if ((len = ReadReply(&reply)) < 0) {
fprintf(stderr, "read: %s\n", len);
return false;
}
fprintf(stderr, "reply: '%s'\n", reply.String());
if (reply.FindFirst("Changing") < 0)
return false;
if ((len = ReadReply(&reply)) < 0) {
fprintf(stderr, "read: %s\n", len);
return false;
}
fprintf(stderr, "reply: '%s'\n", reply.String());
if (reply.FindFirst("sftp>") < 0)
return false;
rc = true;
return rc;
}
void
SftpClient::SetPassive(bool on)
{
}
+40
View File
@@ -0,0 +1,40 @@
#ifndef SFTP_CLIENT_H
#define SFTP_CLIENT_H
#include <stdio.h>
#include <string>
#include <File.h>
#include "SpawningUploadClient.h"
using std::string;
class SftpClient : public SpawningUploadClient {
public:
SftpClient();
~SftpClient();
virtual bool Connect(const string& server, const string& login,
const string& passwd);
bool PutFile(const string& local, const string& remote,
ftp_mode mode = binary_mode);
bool GetFile(const string& remote, const string& local,
ftp_mode mode = binary_mode);
bool MoveFile(const string& oldPath, const string& newPath);
bool ChangeDir(const string& dir);
bool PrintWorkingDir(string& dir);
bool ListDirContents(string& listing);
bool Chmod(const string& path, const string& mod);
void SetPassive(bool on);
protected:
};
#endif // SFTP_CLIENT_H
+180
View File
@@ -0,0 +1,180 @@
#include <image.h>
#include <unistd.h>
#include <signal.h>
#include <String.h>
#include "SpawningUploadClient.h"
SpawningUploadClient::SpawningUploadClient()
: FileUploadClient()
, fCommand()
, fCommandPid(-1)
, fPty(-1)
{
}
SpawningUploadClient::~SpawningUploadClient()
{
close(fPty);
kill(fCommandPid, SIGTERM);
kill(fCommandPid, SIGKILL);
status_t ret;
wait_for_thread(fCommandPid, &ret);
}
bool
SpawningUploadClient::Connect(const string& server, const string& login, const string& passwd)
{
bool rc = false;
// fCommand += " ";
// fCommand += server;
rc = SpawnCommand();
return rc;
}
bool
SpawningUploadClient::SpawnCommand()
{
//XXX: should use a system-provided TerminalCommand class
BString shellcmd = "exec";
const char *args[] = { "/bin/sh", "-c", NULL, NULL };
char path[20];
int pty;
for (pty = 0; pty < 0x50; pty++) {
int fd;
sprintf(path, "/dev/pt/%c%1x", 'p' + pty / 16, pty & 0x0f);
printf("trying %s\n", path);
fd = open(path, O_RDWR);
if (fd < 0)
continue;
fPty = fd;
break;
}
if (fPty < 0)
return false;
sprintf(path, "/dev/tt/%c%1x", 'p' + pty / 16, pty & 0x0f);
shellcmd << " 0<" << path;
shellcmd << " 1>" << path;
shellcmd += " 2>&1";
shellcmd << " ; ";
shellcmd << "export TTY=" << path << "; "; // BeOS hack
shellcmd << "export LC_ALL=C; export LANG=C; ";
shellcmd << "exec ";
shellcmd << fCommand.c_str();
printf("spawning: '%s'\n", shellcmd.String());
args[2] = shellcmd.String();
fCommandPid = load_image(3, args, (const char **)environ);
if (fCommandPid < 0)
return false;
resume_thread(fCommandPid);
return true;
}
status_t
SpawningUploadClient::SetCommandLine(const char *command)
{
fCommand = command;
return B_OK;
}
ssize_t
SpawningUploadClient::SendCommand(const char *cmd)
{
return write(InputPipe(), cmd, strlen(cmd));
}
ssize_t
SpawningUploadClient::ReadReply(BString *to)
{
char buff[1024];
ssize_t len;
to->Truncate(0);
len = read(OutputPipe(), buff, 1024);
if (len < 0)
return errno;
to->Append(buff, len);
return len;
}
status_t
SpawningUploadClient::ParseReply()
{
return B_ERROR;
}
/* the rest is empty */
bool
SpawningUploadClient::ChangeDir(const string& dir)
{
bool rc = false;
return rc;
}
bool
SpawningUploadClient::ListDirContents(string& listing)
{
bool rc = false;
return rc;
}
bool
SpawningUploadClient::PrintWorkingDir(string& dir)
{
bool rc = false;
return rc;
}
bool
SpawningUploadClient::PutFile(const string& local, const string& remote, ftp_mode mode)
{
bool rc = false;
return rc;
}
bool
SpawningUploadClient::GetFile(const string& remote, const string& local, ftp_mode mode)
{
bool rc = false;
return rc;
}
// Note: this only works for local remote moves, cross filesystem moves
// will not work
bool
SpawningUploadClient::MoveFile(const string& oldPath, const string& newPath)
{
bool rc = false;
return rc;
}
bool
SpawningUploadClient::Chmod(const string& path, const string& mod)
{
bool rc = false;
return rc;
}
void
SpawningUploadClient::SetPassive(bool on)
{
}
+49
View File
@@ -0,0 +1,49 @@
#ifndef SPAWNING_UPLOAD_CLIENT_H
#define SPAWNING_UPLOAD_CLIENT_H
#include "FileUploadClient.h"
#include <OS.h>
#include <stdio.h>
#include <string>
class SpawningUploadClient : public FileUploadClient {
public:
SpawningUploadClient();
virtual ~SpawningUploadClient();
virtual bool Connect(const string& server, const string& login,
const string& passwd);
virtual bool PutFile(const string& local, const string& remote,
ftp_mode mode = binary_mode);
virtual bool GetFile(const string& remote, const string& local,
ftp_mode mode = binary_mode);
virtual bool MoveFile(const string& oldPath, const string& newPath);
virtual bool ChangeDir(const string& dir);
virtual bool PrintWorkingDir(string& dir);
virtual bool ListDirContents(string& listing);
virtual bool Chmod(const string& path, const string& mod);
virtual void SetPassive(bool on);
protected:
status_t SetCommandLine(const char *command);
ssize_t SendCommand(const char *cmd);
ssize_t ReadReply(BString *to);
virtual status_t ParseReply();
int InputPipe() const { return fPty; };
int OutputPipe() const { return fPty; };
private:
bool SpawnCommand();
string fCommand;
pid_t fCommandPid;
int fPty;
};
#endif // SPAWNING_UPLOAD_CLIENT_H