diff --git a/src/Makefile.am b/src/Makefile.am index c8726592a..9b59824d7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,13 +5,13 @@ task_SOURCES = API.cpp Att.cpp Cmd.cpp Color.cpp Config.cpp Context.cpp \ Grid.cpp Hooks.cpp Keymap.cpp Location.cpp Nibbler.cpp \ Path.cpp Permission.cpp Record.cpp Sequence.cpp \ StringTable.cpp Subst.cpp TDB.cpp Table.cpp Task.cpp \ - Taskmod.cpp Timer.cpp command.cpp custom.cpp dependency.cpp \ + Taskmod.cpp Transport.cpp TransportSSH.cpp Timer.cpp \ + command.cpp custom.cpp dependency.cpp \ edit.cpp export.cpp import.cpp interactive.cpp main.cpp \ recur.cpp report.cpp rules.cpp rx.cpp text.cpp util.cpp \ API.h Att.h Cmd.h Color.h Config.h Context.h Date.h \ Directory.h Duration.h File.h Filter.h Grid.h Hooks.h Keymap.h \ Location.h Nibbler.h Path.h Permission.h Record.h Sequence.h \ - StringTable.h Subst.h TDB.h Table.h Task.h Taskmod.h Timer.h \ - i18n.h main.h text.h util.h rx.h + StringTable.h Subst.h TDB.h Table.h Task.h Taskmod.h Timer.h \ Transport.h TransportSSH.h i18n.h main.h text.h util.h rx.h task_CPPFLAGS=$(LUA_CFLAGS) task_LDFLAGS=$(LUA_LFLAGS) diff --git a/src/Transport.cpp b/src/Transport.cpp new file mode 100644 index 000000000..389bdc62b --- /dev/null +++ b/src/Transport.cpp @@ -0,0 +1,154 @@ +//////////////////////////////////////////////////////////////////////////////// +// taskwarrior - a command line task list manager. +// +// Copyright 2006 - 2010, Paul Beckingham, Johannes Schlatow. +// All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation; either version 2 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the +// +// Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, +// Boston, MA +// 02110-1301 +// USA +// +//////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include "Transport.h" +#include "TransportSSH.h" + +//////////////////////////////////////////////////////////////////////////////// +Transport::Transport (const std::string& host, const std::string& path, const std::string& user="", const std::string& port="") +{ + executable = ""; + this->host = host; + this->path = path; + this->user = user; + this->port = port; +} + +//////////////////////////////////////////////////////////////////////////////// +Transport::Transport (const std::string& uri) +{ + executable = ""; + + parseUri(uri); +} + +//////////////////////////////////////////////////////////////////////////////// +Transport::~Transport () +{ +} + +//////////////////////////////////////////////////////////////////////////////// +void Transport::parseUri(std::string uri) +{ + std::string::size_type pos; + std::string uripart; + + user = ""; + port = ""; + + // skip ^.*:// + if ((pos = uri.find ("://")) != std::string::npos) + { + uri = uri.substr (pos+3); + } + + // get host part + if ((pos = uri.find ("/")) != std::string::npos) + { + host = uri.substr (0, pos); + path = uri.substr (pos+1); + } + else + { + throw std::string ("Could not parse \""+uri+"\""); + } + + // parse host + if ((pos = host.find ("@")) != std::string::npos) + { + user = host.substr (0, pos); + host = host.substr (pos+1); + } + + if ((pos = host.find (":")) != std::string::npos) + { + port = host.substr (pos+1); + host = host.substr (0,pos); + } +} + +//////////////////////////////////////////////////////////////////////////////// +Transport* Transport::getTransport(const std::string& uri) +{ + if (uri.find("ssh://") == 0) { + return new TransportSSH(uri); + } + + return NULL; +} + +//////////////////////////////////////////////////////////////////////////////// +int Transport::execute() +{ + if (executable == "") + return -1; + + pid_t child_pid = fork(); + + if (child_pid == 0) + { + // this is done by the child process + char shell[] = "sh"; + char opt[] = "-c"; + + std::string cmdline = executable; + + std::vector ::iterator it; + for (it = arguments.begin(); it != arguments.end(); ++it) + { + std::string tmp = *it; + cmdline += " " + tmp; + } + + char** argv = new char*[4]; + argv[0] = shell; // sh + argv[1] = opt; // -c + argv[2] = (char*)cmdline.c_str(); // e.g. scp undo.data user@host:.task/ + argv[3] = NULL; // required by execv + + int ret = execvp("sh", argv); + delete[] argv; + + exit(ret); + } + else + { + // this is done by the parent process + int child_status; + + pid_t pid = waitpid(child_pid, &child_status, 0); + + if (pid == -1) + return -1; + else + return child_status; + } +} \ No newline at end of file diff --git a/src/Transport.h b/src/Transport.h new file mode 100644 index 000000000..e03b5cd63 --- /dev/null +++ b/src/Transport.h @@ -0,0 +1,58 @@ +//////////////////////////////////////////////////////////////////////////////// +// taskwarrior - a command line task list manager. +// +// Copyright 2006 - 2010, Paul Beckingham, Johannes Schlatow. +// All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation; either version 2 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the +// +// Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, +// Boston, MA +// 02110-1301 +// USA +// +//////////////////////////////////////////////////////////////////////////////// +#ifndef INCLUDED_TRANSPORT +#define INCLUDED_TRANSPORT + +#include +#include + +class Transport { +public: + Transport (const std::string&, const std::string&, const std::string&, const std::string&); + Transport (const std::string&); + ~Transport (); + + static Transport* getTransport(const std::string&); + + void parseUri (std::string); + virtual void send (const std::string&) = 0; + virtual void recv (std::string) = 0; + +protected: + std::string executable; + std::vector arguments; + + std::string host; + std::string path; + std::string port; + std::string user; + + int execute(); +}; + +#endif + diff --git a/src/TransportSSH.cpp b/src/TransportSSH.cpp new file mode 100644 index 000000000..98b90d697 --- /dev/null +++ b/src/TransportSSH.cpp @@ -0,0 +1,130 @@ +//////////////////////////////////////////////////////////////////////////////// +// taskwarrior - a command line task list manager. +// +// Copyright 2006 - 2010, Paul Beckingham, Johannes Schlatow. +// All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation; either version 2 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the +// +// Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, +// Boston, MA +// 02110-1301 +// USA +// +//////////////////////////////////////////////////////////////////////////////// + +#include "TransportSSH.h" + +//////////////////////////////////////////////////////////////////////////////// +TransportSSH::TransportSSH(const std::string& uri) : Transport(uri) +{ + executable = "scp"; +} + +//////////////////////////////////////////////////////////////////////////////// +TransportSSH::TransportSSH( + const std::string& host, + const std::string& path, + const std::string& user, + const std::string& port) : Transport (host,path,user,port) +{ + executable = "scp"; +} + +//////////////////////////////////////////////////////////////////////////////// +void TransportSSH::send(const std::string& source) +{ + if (host == "") { + throw std::string ("Hostname is empty"); + } + + // Is there more than one file to transfer? + // Then path has to end with a '/' + if ( (source.find ("*") != std::string::npos) + || (source.find ("?") != std::string::npos) + || (source.find (" ") != std::string::npos) ) + { + std::string::size_type pos; + + pos = path.find_last_of ("/"); + if (pos != path.length()-1) + { + path = path.substr (0, pos+1); + } + } + + // cmd line is: scp [-p port] [user@]host:path + if (port != "") + { + arguments.push_back ("-P"); + arguments.push_back (port); + } + + arguments.push_back (source); + + if (user != "") + { + arguments.push_back (user + "@" + host + ":" + path); + } + else + { + arguments.push_back (host + ":" + path); + } + + if (execute()) + throw std::string ("Failed to run scp!"); +} + +//////////////////////////////////////////////////////////////////////////////// +void TransportSSH::recv(std::string target) +{ + if (host == "") { + throw std::string ("Hostname is empty"); + } + + // Is there more than one file to transfer? + // Then target has to end with a '/' + if ( (path.find ("*") != std::string::npos) + || (path.find ("?") != std::string::npos) ) + { + std::string::size_type pos; + pos = target.find_last_of ("/"); + if (pos != target.length()-1) + { + target = target.substr( 0, pos+1); + } + } + + // cmd line is: scp [-p port] [user@]host:path + if (port != "") + { + arguments.push_back ("-P"); + arguments.push_back (port); + } + + if (user != "") + { + arguments.push_back (user + "@" + host + ":" + path); + } + else + { + arguments.push_back (host + ":" + path); + } + + arguments.push_back (target); + + if (execute()) + throw std::string ("Failed to run scp!"); +} \ No newline at end of file diff --git a/src/TransportSSH.h b/src/TransportSSH.h new file mode 100644 index 000000000..c10afab62 --- /dev/null +++ b/src/TransportSSH.h @@ -0,0 +1,44 @@ +//////////////////////////////////////////////////////////////////////////////// +// taskwarrior - a command line task list manager. +// +// Copyright 2006 - 2010, Paul Beckingham, Johannes Schlatow. +// All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation; either version 2 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the +// +// Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, +// Boston, MA +// 02110-1301 +// USA +// +//////////////////////////////////////////////////////////////////////////////// +#ifndef INCLUDED_TRANSPORTSSH +#define INCLUDED_TRANSPORTSSH + +#include +#include + +class TransportSSH : public Transport { +public: + TransportSSH (const std::string&); + TransportSSH (const std::string&, const std::string&, const std::string&, const std::string&); + + virtual void send (const std::string&); + virtual void recv (std::string); + +}; + +#endif + diff --git a/src/tests/Makefile b/src/tests/Makefile index e8d947295..3e215f126 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -11,7 +11,8 @@ OBJECTS = ../t-TDB.o ../t-Task.o ../t-text.o ../t-Date.o ../t-Table.o \ ../t-Grid.o ../t-Color.o ../t-rules.o ../t-recur.o ../t-custom.o \ ../t-export.o ../t-import.o ../t-edit.o ../t-Timer.o \ ../t-Permission.o ../t-Path.o ../t-File.o ../t-Directory.o \ - ../t-Hooks.o ../t-API.o ../t-rx.o ../t-Taskmod.o ../t-dependency.o + ../t-Hooks.o ../t-API.o ../t-rx.o ../t-Taskmod.o ../t-dependency.o \ + ../t-Transport.o ../t-TransportSSH.o all: $(PROJECT)