diff --git a/src/apps/codycam/SftpClient.cpp b/src/apps/codycam/SftpClient.cpp new file mode 100644 index 0000000000..69b2038640 --- /dev/null +++ b/src/apps/codycam/SftpClient.cpp @@ -0,0 +1,223 @@ +#include +#include + +#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) +{ +} + + diff --git a/src/apps/codycam/SftpClient.h b/src/apps/codycam/SftpClient.h new file mode 100644 index 0000000000..7376019bb4 --- /dev/null +++ b/src/apps/codycam/SftpClient.h @@ -0,0 +1,40 @@ +#ifndef SFTP_CLIENT_H +#define SFTP_CLIENT_H + + +#include +#include + +#include +#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 diff --git a/src/apps/codycam/SpawningUploadClient.cpp b/src/apps/codycam/SpawningUploadClient.cpp new file mode 100644 index 0000000000..03b2365334 --- /dev/null +++ b/src/apps/codycam/SpawningUploadClient.cpp @@ -0,0 +1,180 @@ +#include +#include +#include + +#include + +#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) +{ +} + + diff --git a/src/apps/codycam/SpawningUploadClient.h b/src/apps/codycam/SpawningUploadClient.h new file mode 100644 index 0000000000..bf083b3e39 --- /dev/null +++ b/src/apps/codycam/SpawningUploadClient.h @@ -0,0 +1,49 @@ +#ifndef SPAWNING_UPLOAD_CLIENT_H +#define SPAWNING_UPLOAD_CLIENT_H + +#include "FileUploadClient.h" + +#include +#include +#include + + +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