Feature #462: url support
- added uri class for proper uri and path handling
This commit is contained in:
@@ -15,7 +15,7 @@ task_SOURCES = API.cpp API.h Att.cpp Att.h Cmd.cpp Cmd.h Color.cpp Color.h \
|
|||||||
TransportCurl.cpp TransportCurl.h Tree.cpp Tree.h command.cpp \
|
TransportCurl.cpp TransportCurl.h Tree.cpp Tree.h command.cpp \
|
||||||
custom.cpp dependency.cpp edit.cpp export.cpp i18n.h import.cpp \
|
custom.cpp dependency.cpp edit.cpp export.cpp i18n.h import.cpp \
|
||||||
interactive.cpp main.cpp main.h recur.cpp report.cpp rules.cpp \
|
interactive.cpp main.cpp main.h recur.cpp report.cpp rules.cpp \
|
||||||
rx.cpp rx.h text.cpp text.h util.cpp util.h
|
rx.cpp rx.h text.cpp text.h util.cpp util.h Uri.cpp Uri.h
|
||||||
task_CPPFLAGS=$(LUA_CFLAGS)
|
task_CPPFLAGS=$(LUA_CFLAGS)
|
||||||
task_LDFLAGS=$(LUA_LFLAGS)
|
task_LDFLAGS=$(LUA_LFLAGS)
|
||||||
|
|
||||||
|
|||||||
@@ -35,21 +35,10 @@
|
|||||||
#include "TransportCurl.h"
|
#include "TransportCurl.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Transport::Transport (const std::string& host, const std::string& path, const std::string& user="", const std::string& port="")
|
Transport::Transport (const Uri& uri)
|
||||||
{
|
{
|
||||||
executable = "";
|
executable = "";
|
||||||
this->host = host;
|
this->uri = uri;
|
||||||
this->path = path;
|
|
||||||
this->user = user;
|
|
||||||
this->port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Transport::Transport (const std::string& uri)
|
|
||||||
{
|
|
||||||
executable = "";
|
|
||||||
|
|
||||||
parseUri(uri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -58,79 +47,22 @@ Transport::~Transport ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void Transport::parseUri(std::string uri)
|
Transport* Transport::getTransport(const Uri& uri)
|
||||||
{
|
{
|
||||||
std::string::size_type pos;
|
if (uri.protocol == "ssh")
|
||||||
std::string uripart;
|
|
||||||
std::string pathDelimiter = "/";
|
|
||||||
|
|
||||||
user = "";
|
|
||||||
port = "";
|
|
||||||
|
|
||||||
// skip ^.*://
|
|
||||||
if ((pos = uri.find ("://")) != std::string::npos)
|
|
||||||
{
|
|
||||||
protocol = uri.substr(0, pos);
|
|
||||||
uri = uri.substr (pos+3);
|
|
||||||
// standard syntax: protocol://[user@]host.xz[:port]/path/to/undo.data
|
|
||||||
pathDelimiter = "/";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
protocol = "ssh";
|
|
||||||
// scp-like syntax: [user@]host.xz:path/to/undo.data
|
|
||||||
pathDelimiter = ":";
|
|
||||||
}
|
|
||||||
|
|
||||||
// get host part
|
|
||||||
if ((pos = uri.find (pathDelimiter)) != 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remark: this find() will never be != npos for scp-like syntax
|
|
||||||
// because we found pathDelimiter, which is ":", before
|
|
||||||
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 new TransportSSH(uri);
|
||||||
}
|
}
|
||||||
else if (uri.find("rsync://") == 0)
|
else if (uri.protocol == "rsync")
|
||||||
{
|
{
|
||||||
return new TransportRSYNC(uri);
|
return new TransportRSYNC(uri);
|
||||||
}
|
}
|
||||||
else if ( (uri.find("http://") == 0)
|
else if ( (uri.protocol == "http")
|
||||||
|| (uri.find("https://") == 0)
|
|| (uri.protocol == "https")
|
||||||
|| (uri.find("ftp://") == 0) )
|
|| (uri.protocol == "ftp") )
|
||||||
{
|
{
|
||||||
return new TransportCurl(uri);
|
return new TransportCurl(uri);
|
||||||
}
|
}
|
||||||
else if ( (uri.find(":") != std::string::npos)
|
|
||||||
&& (uri.find("://") == std::string::npos) )
|
|
||||||
{
|
|
||||||
return new TransportSSH(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,28 +29,23 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "Uri.h"
|
||||||
|
|
||||||
class Transport {
|
class Transport {
|
||||||
public:
|
public:
|
||||||
Transport (const std::string&, const std::string&, const std::string&, const std::string&);
|
Transport (const Uri&);
|
||||||
Transport (const std::string&);
|
|
||||||
~Transport ();
|
~Transport ();
|
||||||
|
|
||||||
static Transport* getTransport(const std::string&);
|
static Transport* getTransport(const Uri&);
|
||||||
|
|
||||||
void parseUri (std::string);
|
|
||||||
virtual void send (const std::string&) = 0;
|
virtual void send (const std::string&) = 0;
|
||||||
virtual void recv (std::string) = 0;
|
virtual void recv (std::string) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string executable;
|
std::string executable;
|
||||||
std::string protocol;
|
|
||||||
std::vector<std::string> arguments;
|
std::vector<std::string> arguments;
|
||||||
|
|
||||||
std::string host;
|
Uri uri;
|
||||||
std::string path;
|
|
||||||
std::string port;
|
|
||||||
std::string user;
|
|
||||||
|
|
||||||
int execute();
|
int execute();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,31 +28,15 @@
|
|||||||
#include "TransportCurl.h"
|
#include "TransportCurl.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
TransportCurl::TransportCurl(const std::string& uri) : Transport(uri)
|
TransportCurl::TransportCurl(const Uri& uri) : Transport(uri)
|
||||||
{
|
{
|
||||||
executable = "curl";
|
executable = "curl";
|
||||||
|
|
||||||
if (protocol == "")
|
|
||||||
protocol = "http";
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
TransportCurl::TransportCurl(
|
|
||||||
const std::string& host,
|
|
||||||
const std::string& path,
|
|
||||||
const std::string& user,
|
|
||||||
const std::string& port) : Transport (host,path,user,port)
|
|
||||||
{
|
|
||||||
executable = "curl";
|
|
||||||
|
|
||||||
if (protocol == "")
|
|
||||||
protocol = "http";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void TransportCurl::send(const std::string& source)
|
void TransportCurl::send(const std::string& source)
|
||||||
{
|
{
|
||||||
if (host == "") {
|
if (uri.host == "") {
|
||||||
throw std::string ("Hostname is empty");
|
throw std::string ("Hostname is empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,13 +51,13 @@ void TransportCurl::send(const std::string& source)
|
|||||||
arguments.push_back ("-T");
|
arguments.push_back ("-T");
|
||||||
arguments.push_back (source);
|
arguments.push_back (source);
|
||||||
|
|
||||||
if (port != "")
|
if (uri.port != "")
|
||||||
{
|
{
|
||||||
arguments.push_back (protocol + "://" + host + ":" + port + "/" + path);
|
arguments.push_back (uri.protocol + "://" + uri.host + ":" + uri.port + "/" + uri.path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arguments.push_back (protocol + "://" + host + "/" + path);
|
arguments.push_back (uri.protocol + "://" + uri.host + "/" + uri.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (execute())
|
if (execute())
|
||||||
@@ -83,25 +67,25 @@ void TransportCurl::send(const std::string& source)
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void TransportCurl::recv(std::string target)
|
void TransportCurl::recv(std::string target)
|
||||||
{
|
{
|
||||||
if (host == "") {
|
if (uri.host == "") {
|
||||||
throw std::string ("Hostname is empty");
|
throw std::string ("Hostname is empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wildcards arent supported
|
// Wildcards arent supported
|
||||||
if ( (path.find ("*") != std::string::npos)
|
if ( (uri.path.find ("*") != std::string::npos)
|
||||||
|| (path.find ("?") != std::string::npos) )
|
|| (uri.path.find ("?") != std::string::npos) )
|
||||||
{
|
{
|
||||||
throw std::string ("Failed to use curl with wildcards!");
|
throw std::string ("Failed to use curl with wildcards!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// cmd line is: curl protocol://host:port/path/to/source/file -o path/to/target/file
|
// cmd line is: curl protocol://host:port/path/to/source/file -o path/to/target/file
|
||||||
if (port != "")
|
if (uri.port != "")
|
||||||
{
|
{
|
||||||
arguments.push_back (protocol + "://" + host + ":" + port + "/" + path);
|
arguments.push_back (uri.protocol + "://" + uri.host + ":" + uri.port + "/" + uri.path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arguments.push_back (protocol + "://" + host + "/" + path);
|
arguments.push_back (uri.protocol + "://" + uri.host + "/" + uri.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
arguments.push_back ("-o");
|
arguments.push_back ("-o");
|
||||||
|
|||||||
@@ -32,8 +32,7 @@
|
|||||||
|
|
||||||
class TransportCurl : public Transport {
|
class TransportCurl : public Transport {
|
||||||
public:
|
public:
|
||||||
TransportCurl (const std::string&);
|
TransportCurl (const Uri&);
|
||||||
TransportCurl (const std::string&, const std::string&, const std::string&, const std::string&);
|
|
||||||
|
|
||||||
virtual void send (const std::string&);
|
virtual void send (const std::string&);
|
||||||
virtual void recv (std::string);
|
virtual void recv (std::string);
|
||||||
|
|||||||
@@ -28,17 +28,7 @@
|
|||||||
#include "TransportRSYNC.h"
|
#include "TransportRSYNC.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
TransportRSYNC::TransportRSYNC(const std::string& uri) : Transport(uri)
|
TransportRSYNC::TransportRSYNC(const Uri& uri) : Transport(uri)
|
||||||
{
|
|
||||||
executable = "rsync";
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
TransportRSYNC::TransportRSYNC(
|
|
||||||
const std::string& host,
|
|
||||||
const std::string& path,
|
|
||||||
const std::string& user,
|
|
||||||
const std::string& port) : Transport (host,path,user,port)
|
|
||||||
{
|
{
|
||||||
executable = "rsync";
|
executable = "rsync";
|
||||||
}
|
}
|
||||||
@@ -46,7 +36,7 @@ TransportRSYNC::TransportRSYNC(
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void TransportRSYNC::send(const std::string& source)
|
void TransportRSYNC::send(const std::string& source)
|
||||||
{
|
{
|
||||||
if (host == "") {
|
if (uri.host == "") {
|
||||||
throw std::string ("Hostname is empty");
|
throw std::string ("Hostname is empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,28 +48,28 @@ void TransportRSYNC::send(const std::string& source)
|
|||||||
{
|
{
|
||||||
std::string::size_type pos;
|
std::string::size_type pos;
|
||||||
|
|
||||||
pos = path.find_last_of ("/");
|
pos = uri.path.find_last_of ("/");
|
||||||
if (pos != path.length()-1)
|
if (pos != uri.path.length()-1)
|
||||||
{
|
{
|
||||||
path = path.substr (0, pos+1);
|
uri.path = uri.path.substr (0, pos+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// cmd line is: rsync [--port=PORT] source [user@]host::path
|
// cmd line is: rsync [--port=PORT] source [user@]host::path
|
||||||
if (port != "")
|
if (uri.port != "")
|
||||||
{
|
{
|
||||||
arguments.push_back ("--port=" + port);
|
arguments.push_back ("--port=" + uri.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
arguments.push_back (source);
|
arguments.push_back (source);
|
||||||
|
|
||||||
if (user != "")
|
if (uri.user != "")
|
||||||
{
|
{
|
||||||
arguments.push_back (user + "@" + host + "::" + path);
|
arguments.push_back (uri.user + "@" + uri.host + "::" + uri.path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arguments.push_back (host + "::" + path);
|
arguments.push_back (uri.host + "::" + uri.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (execute())
|
if (execute())
|
||||||
@@ -89,14 +79,14 @@ void TransportRSYNC::send(const std::string& source)
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void TransportRSYNC::recv(std::string target)
|
void TransportRSYNC::recv(std::string target)
|
||||||
{
|
{
|
||||||
if (host == "") {
|
if (uri.host == "") {
|
||||||
throw std::string ("Hostname is empty");
|
throw std::string ("Hostname is empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is there more than one file to transfer?
|
// Is there more than one file to transfer?
|
||||||
// Then target has to end with a '/'
|
// Then target has to end with a '/'
|
||||||
if ( (path.find ("*") != std::string::npos)
|
if ( (uri.path.find ("*") != std::string::npos)
|
||||||
|| (path.find ("?") != std::string::npos) )
|
|| (uri.path.find ("?") != std::string::npos) )
|
||||||
{
|
{
|
||||||
std::string::size_type pos;
|
std::string::size_type pos;
|
||||||
pos = target.find_last_of ("/");
|
pos = target.find_last_of ("/");
|
||||||
@@ -107,18 +97,18 @@ void TransportRSYNC::recv(std::string target)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cmd line is: rsync [--port=PORT] [user@]host::path target
|
// cmd line is: rsync [--port=PORT] [user@]host::path target
|
||||||
if (port != "")
|
if (uri.port != "")
|
||||||
{
|
{
|
||||||
arguments.push_back ("--port=" + port);
|
arguments.push_back ("--port=" + uri.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user != "")
|
if (uri.user != "")
|
||||||
{
|
{
|
||||||
arguments.push_back (user + "@" + host + "::" + path);
|
arguments.push_back (uri.user + "@" + uri.host + "::" + uri.path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arguments.push_back (host + "::" + path);
|
arguments.push_back (uri.host + "::" + uri.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
arguments.push_back (target);
|
arguments.push_back (target);
|
||||||
|
|||||||
@@ -32,8 +32,7 @@
|
|||||||
|
|
||||||
class TransportRSYNC : public Transport {
|
class TransportRSYNC : public Transport {
|
||||||
public:
|
public:
|
||||||
TransportRSYNC (const std::string&);
|
TransportRSYNC (const Uri&);
|
||||||
TransportRSYNC (const std::string&, const std::string&, const std::string&, const std::string&);
|
|
||||||
|
|
||||||
virtual void send (const std::string&);
|
virtual void send (const std::string&);
|
||||||
virtual void recv (std::string);
|
virtual void recv (std::string);
|
||||||
|
|||||||
@@ -28,17 +28,7 @@
|
|||||||
#include "TransportSSH.h"
|
#include "TransportSSH.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
TransportSSH::TransportSSH(const std::string& uri) : Transport(uri)
|
TransportSSH::TransportSSH(const Uri& 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";
|
executable = "scp";
|
||||||
}
|
}
|
||||||
@@ -46,7 +36,7 @@ TransportSSH::TransportSSH(
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void TransportSSH::send(const std::string& source)
|
void TransportSSH::send(const std::string& source)
|
||||||
{
|
{
|
||||||
if (host == "") {
|
if (uri.host == "") {
|
||||||
throw std::string ("Hostname is empty");
|
throw std::string ("Hostname is empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,29 +48,29 @@ void TransportSSH::send(const std::string& source)
|
|||||||
{
|
{
|
||||||
std::string::size_type pos;
|
std::string::size_type pos;
|
||||||
|
|
||||||
pos = path.find_last_of ("/");
|
pos = uri.path.find_last_of ("/");
|
||||||
if (pos != path.length()-1)
|
if (pos != uri.path.length()-1)
|
||||||
{
|
{
|
||||||
path = path.substr (0, pos+1);
|
uri.path = uri.path.substr (0, pos+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// cmd line is: scp [-p port] [user@]host:path
|
// cmd line is: scp [-p port] [user@]host:path
|
||||||
if (port != "")
|
if (uri.port != "")
|
||||||
{
|
{
|
||||||
arguments.push_back ("-P");
|
arguments.push_back ("-P");
|
||||||
arguments.push_back (port);
|
arguments.push_back (uri.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
arguments.push_back (source);
|
arguments.push_back (source);
|
||||||
|
|
||||||
if (user != "")
|
if (uri.user != "")
|
||||||
{
|
{
|
||||||
arguments.push_back (user + "@" + host + ":" + path);
|
arguments.push_back (uri.user + "@" + uri.host + ":" + uri.path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arguments.push_back (host + ":" + path);
|
arguments.push_back (uri.host + ":" + uri.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (execute())
|
if (execute())
|
||||||
@@ -90,14 +80,14 @@ void TransportSSH::send(const std::string& source)
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void TransportSSH::recv(std::string target)
|
void TransportSSH::recv(std::string target)
|
||||||
{
|
{
|
||||||
if (host == "") {
|
if (uri.host == "") {
|
||||||
throw std::string ("Hostname is empty");
|
throw std::string ("Hostname is empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is there more than one file to transfer?
|
// Is there more than one file to transfer?
|
||||||
// Then target has to end with a '/'
|
// Then target has to end with a '/'
|
||||||
if ( (path.find ("*") != std::string::npos)
|
if ( (uri.path.find ("*") != std::string::npos)
|
||||||
|| (path.find ("?") != std::string::npos) )
|
|| (uri.path.find ("?") != std::string::npos) )
|
||||||
{
|
{
|
||||||
std::string::size_type pos;
|
std::string::size_type pos;
|
||||||
pos = target.find_last_of ("/");
|
pos = target.find_last_of ("/");
|
||||||
@@ -108,19 +98,19 @@ void TransportSSH::recv(std::string target)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cmd line is: scp [-p port] [user@]host:path
|
// cmd line is: scp [-p port] [user@]host:path
|
||||||
if (port != "")
|
if (uri.port != "")
|
||||||
{
|
{
|
||||||
arguments.push_back ("-P");
|
arguments.push_back ("-P");
|
||||||
arguments.push_back (port);
|
arguments.push_back (uri.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user != "")
|
if (uri.user != "")
|
||||||
{
|
{
|
||||||
arguments.push_back (user + "@" + host + ":" + path);
|
arguments.push_back (uri.user + "@" + uri.host + ":" + uri.path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arguments.push_back (host + ":" + path);
|
arguments.push_back (uri.host + ":" + uri.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
arguments.push_back (target);
|
arguments.push_back (target);
|
||||||
|
|||||||
@@ -32,8 +32,7 @@
|
|||||||
|
|
||||||
class TransportSSH : public Transport {
|
class TransportSSH : public Transport {
|
||||||
public:
|
public:
|
||||||
TransportSSH (const std::string&);
|
TransportSSH (const Uri&);
|
||||||
TransportSSH (const std::string&, const std::string&, const std::string&, const std::string&);
|
|
||||||
|
|
||||||
virtual void send (const std::string&);
|
virtual void send (const std::string&);
|
||||||
virtual void recv (std::string);
|
virtual void recv (std::string);
|
||||||
|
|||||||
235
src/Uri.cpp
Normal file
235
src/Uri.cpp
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// taskwarrior - a command line task list manager.
|
||||||
|
//
|
||||||
|
// Copyright 2010, 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 "Context.h"
|
||||||
|
#include "Uri.h"
|
||||||
|
|
||||||
|
extern Context context;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Uri::Uri ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Uri::Uri (const Uri& other)
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
{
|
||||||
|
data = other.data;
|
||||||
|
host = other.host;
|
||||||
|
path = other.path;
|
||||||
|
user = other.user;
|
||||||
|
port = other.port;
|
||||||
|
protocol = other.protocol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Uri::Uri (const std::string& in, const std::string& configPrefix)
|
||||||
|
{
|
||||||
|
data = in;
|
||||||
|
if (configPrefix != "")
|
||||||
|
expand(configPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Uri::~Uri ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Uri& Uri::operator= (const Uri& other)
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
{
|
||||||
|
this->data = other.data;
|
||||||
|
this->host = other.host;
|
||||||
|
this->path = other.path;
|
||||||
|
this->user = other.user;
|
||||||
|
this->port = other.port;
|
||||||
|
this->protocol = other.protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Uri::operator std::string () const
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
std::string Uri::name () const
|
||||||
|
{
|
||||||
|
if (path.length ())
|
||||||
|
{
|
||||||
|
std::string::size_type slash = path.rfind ('/');
|
||||||
|
if (slash != std::string::npos)
|
||||||
|
return path.substr (slash + 1, std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
std::string Uri::parent () const
|
||||||
|
{
|
||||||
|
if (path.length ())
|
||||||
|
{
|
||||||
|
std::string::size_type slash = path.rfind ('/');
|
||||||
|
if (slash != std::string::npos)
|
||||||
|
return path.substr (0, slash);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
std::string Uri::extension () const
|
||||||
|
{
|
||||||
|
if (path.length ())
|
||||||
|
{
|
||||||
|
std::string::size_type dot = path.rfind ('.');
|
||||||
|
if (dot != std::string::npos)
|
||||||
|
return path.substr (dot + 1, std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool Uri::is_directory () const
|
||||||
|
{
|
||||||
|
return (path == ".")
|
||||||
|
|| (path == "")
|
||||||
|
|| (path[path.length()-1] == '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool Uri::is_local () const
|
||||||
|
{
|
||||||
|
return ( (data.find("://") == std::string::npos)
|
||||||
|
&& (data.find(":") == std::string::npos) );
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool Uri::append (const std::string& path)
|
||||||
|
{
|
||||||
|
if (is_directory ())
|
||||||
|
{
|
||||||
|
this->path += path;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool Uri::expand (const std::string& configPrefix )
|
||||||
|
{
|
||||||
|
std::string tmp;
|
||||||
|
if (data.length ())
|
||||||
|
{
|
||||||
|
// try to replace argument with uri from config
|
||||||
|
tmp = context.config.get (configPrefix + "." + data + ".uri");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// get default target from config
|
||||||
|
tmp = context.config.get (configPrefix + ".default.uri");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp != "")
|
||||||
|
{
|
||||||
|
data = tmp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void Uri::parse ()
|
||||||
|
{
|
||||||
|
if (is_local ())
|
||||||
|
{
|
||||||
|
path = data;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string::size_type pos;
|
||||||
|
std::string uripart;
|
||||||
|
std::string pathDelimiter = "/";
|
||||||
|
|
||||||
|
user = "";
|
||||||
|
port = "";
|
||||||
|
|
||||||
|
// skip ^.*://
|
||||||
|
if ((pos = data.find ("://")) != std::string::npos)
|
||||||
|
{
|
||||||
|
protocol = data.substr(0, pos);
|
||||||
|
data = data.substr (pos+3);
|
||||||
|
// standard syntax: protocol://[user@]host.xz[:port]/path/to/undo.data
|
||||||
|
pathDelimiter = "/";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
protocol = "ssh";
|
||||||
|
// scp-like syntax: [user@]host.xz:path/to/undo.data
|
||||||
|
pathDelimiter = ":";
|
||||||
|
}
|
||||||
|
|
||||||
|
// get host part
|
||||||
|
if ((pos = data.find (pathDelimiter)) != std::string::npos)
|
||||||
|
{
|
||||||
|
host = data.substr (0, pos);
|
||||||
|
path = data.substr (pos+1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::string ("Could not parse \""+data+"\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse host
|
||||||
|
if ((pos = host.find ("@")) != std::string::npos)
|
||||||
|
{
|
||||||
|
user = host.substr (0, pos);
|
||||||
|
host = host.substr (pos+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remark: this find() will never be != npos for scp-like syntax
|
||||||
|
// because we found pathDelimiter, which is ":", before
|
||||||
|
if ((pos = host.find (":")) != std::string::npos)
|
||||||
|
{
|
||||||
|
port = host.substr (pos+1);
|
||||||
|
host = host.substr (0,pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
68
src/Uri.h
Normal file
68
src/Uri.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// taskwarrior - a command line task list manager.
|
||||||
|
//
|
||||||
|
// Copyright 2010, 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_URI
|
||||||
|
#define INCLUDED_URI
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// supports the following syntaxes:
|
||||||
|
// protocol://[user@]host.tld[:port]/path
|
||||||
|
// [user@]host:path
|
||||||
|
// path/to/local/file.ext
|
||||||
|
// alias (e.g. merge.alias.uri)
|
||||||
|
class Uri
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Uri ();
|
||||||
|
Uri (const Uri&);
|
||||||
|
Uri (const std::string&, const std::string& configPrefix="");
|
||||||
|
virtual ~Uri ();
|
||||||
|
|
||||||
|
Uri& operator= (const Uri&);
|
||||||
|
operator std::string () const;
|
||||||
|
|
||||||
|
std::string name () const;
|
||||||
|
std::string parent () const;
|
||||||
|
std::string extension () const;
|
||||||
|
bool is_directory () const;
|
||||||
|
bool is_local () const;
|
||||||
|
bool append (const std::string&);
|
||||||
|
bool expand (const std::string&);
|
||||||
|
void parse ();
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string data;
|
||||||
|
std::string path;
|
||||||
|
std::string host;
|
||||||
|
std::string port;
|
||||||
|
std::string user;
|
||||||
|
std::string protocol;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -588,42 +588,26 @@ void handleMerge (std::string& outs)
|
|||||||
|
|
||||||
std::string sAutopush = context.config.get ("merge.autopush");
|
std::string sAutopush = context.config.get ("merge.autopush");
|
||||||
bool bAutopush = context.config.getBoolean("merge.autopush");
|
bool bAutopush = context.config.getBoolean("merge.autopush");
|
||||||
|
|
||||||
if (file.length () == 0)
|
Uri uri (file, "merge");
|
||||||
|
uri.parse();
|
||||||
|
|
||||||
|
if (sAutopush == "ask")
|
||||||
{
|
{
|
||||||
// get default target from config
|
// expand uri
|
||||||
file = context.config.get ("merge.default.uri");
|
Uri push (file, "push");
|
||||||
|
pushfile = push.data;
|
||||||
if (sAutopush == "ask")
|
|
||||||
pushfile = context.config.get ("push.default.uri");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// replace argument with uri from config
|
|
||||||
std::string tmp = context.config.get ("merge." + file + ".uri");
|
|
||||||
|
|
||||||
if (sAutopush == "ask")
|
|
||||||
pushfile = context.config.get ("push." + file + ".uri");
|
|
||||||
|
|
||||||
if (tmp != "")
|
|
||||||
file = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file.length () > 0)
|
if (uri.data.length ())
|
||||||
{
|
{
|
||||||
Directory location (context.config.get ("data.location"));
|
Directory location (context.config.get ("data.location"));
|
||||||
|
|
||||||
// add undo.data to path if necessary
|
// be sure that uri points to a file
|
||||||
if (file.find ("undo.data") == std::string::npos)
|
uri.append("undo.data");
|
||||||
{
|
|
||||||
if (file[file.length()-1] != '/')
|
|
||||||
file += "/";
|
|
||||||
|
|
||||||
file += "undo.data";
|
|
||||||
}
|
|
||||||
|
|
||||||
Transport* transport;
|
Transport* transport;
|
||||||
if ((transport = Transport::getTransport (file)) != NULL )
|
if ((transport = Transport::getTransport (uri)) != NULL )
|
||||||
{
|
{
|
||||||
tmpfile = location.data + "/undo_remote.data";
|
tmpfile = location.data + "/undo_remote.data";
|
||||||
transport->recv (tmpfile);
|
transport->recv (tmpfile);
|
||||||
@@ -631,6 +615,8 @@ void handleMerge (std::string& outs)
|
|||||||
|
|
||||||
file = tmpfile;
|
file = tmpfile;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
file = uri.path;
|
||||||
|
|
||||||
context.tdb.lock (context.config.getBoolean ("locking"));
|
context.tdb.lock (context.config.getBoolean ("locking"));
|
||||||
context.tdb.merge (file);
|
context.tdb.merge (file);
|
||||||
@@ -641,7 +627,7 @@ void handleMerge (std::string& outs)
|
|||||||
if (tmpfile != "")
|
if (tmpfile != "")
|
||||||
{
|
{
|
||||||
remove (tmpfile.c_str());
|
remove (tmpfile.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ((sAutopush == "ask") && (confirm ("Do you want to push the changes to \'" + pushfile + "\'?")) )
|
if ( ((sAutopush == "ask") && (confirm ("Do you want to push the changes to \'" + pushfile + "\'?")) )
|
||||||
|| (bAutopush) )
|
|| (bAutopush) )
|
||||||
@@ -662,28 +648,18 @@ void handlePush (std::string& outs)
|
|||||||
if (context.hooks.trigger ("pre-push-command"))
|
if (context.hooks.trigger ("pre-push-command"))
|
||||||
{
|
{
|
||||||
std::string file = trim (context.task.get ("description"));
|
std::string file = trim (context.task.get ("description"));
|
||||||
|
|
||||||
|
Uri uri (file, "push");
|
||||||
|
uri.parse ();
|
||||||
|
|
||||||
if (file.length () == 0)
|
if (uri.data.length ())
|
||||||
{
|
|
||||||
// get default target from config
|
|
||||||
file = context.config.get ("push.default.uri");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// try to replace argument with uri from config
|
|
||||||
std::string tmp = context.config.get ("push." + file + ".uri");
|
|
||||||
|
|
||||||
if (tmp != "")
|
|
||||||
file = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.length () > 0)
|
|
||||||
{
|
{
|
||||||
Directory location (context.config.get ("data.location"));
|
Directory location (context.config.get ("data.location"));
|
||||||
|
|
||||||
Transport* transport;
|
Transport* transport;
|
||||||
if ((transport = Transport::getTransport (file)) != NULL )
|
if ((transport = Transport::getTransport (uri)) != NULL )
|
||||||
{
|
{
|
||||||
|
// TODO specify data files
|
||||||
transport->send (location.data + "/*.data");
|
transport->send (location.data + "/*.data");
|
||||||
delete transport;
|
delete transport;
|
||||||
}
|
}
|
||||||
@@ -709,42 +685,25 @@ void handlePull (std::string& outs)
|
|||||||
if (context.hooks.trigger ("pre-pull-command"))
|
if (context.hooks.trigger ("pre-pull-command"))
|
||||||
{
|
{
|
||||||
std::string file = trim (context.task.get ("description"));
|
std::string file = trim (context.task.get ("description"));
|
||||||
|
|
||||||
|
Uri uri (file, "pull");
|
||||||
|
uri.parse ();
|
||||||
|
|
||||||
if (file.length () == 0)
|
if (uri.data.length ())
|
||||||
{
|
|
||||||
// get default target from config
|
|
||||||
file = context.config.get ("pull.default.uri");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// replace argument with uri from config
|
|
||||||
std::string tmp = context.config.get ("pull." + file + ".uri");
|
|
||||||
|
|
||||||
if (tmp != "")
|
|
||||||
file = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.length () > 0)
|
|
||||||
{
|
{
|
||||||
Directory location (context.config.get ("data.location"));
|
Directory location (context.config.get ("data.location"));
|
||||||
|
|
||||||
// add *.data to path if necessary
|
uri.append ("*.data");
|
||||||
if (file.find ("*.data") == std::string::npos)
|
|
||||||
{
|
|
||||||
if (file[file.length()-1] != '/')
|
|
||||||
file += "/";
|
|
||||||
|
|
||||||
file += "*.data";
|
|
||||||
}
|
|
||||||
|
|
||||||
Transport* transport;
|
Transport* transport;
|
||||||
if ((transport = Transport::getTransport (file)) != NULL )
|
if ((transport = Transport::getTransport (uri)) != NULL )
|
||||||
{
|
{
|
||||||
transport->recv (location.data + "/");
|
transport->recv (location.data + "/");
|
||||||
delete transport;
|
delete transport;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// TODO copy files
|
||||||
throw std::string ("Pull failed");
|
throw std::string ("Pull failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1267,8 +1267,11 @@ int handleImport (std::string &outs)
|
|||||||
|
|
||||||
#if FEATURE_URL > 0
|
#if FEATURE_URL > 0
|
||||||
std::string tmpfile = "";
|
std::string tmpfile = "";
|
||||||
|
Uri uri (file);
|
||||||
|
uri.parse ();
|
||||||
|
|
||||||
Transport* transport;
|
Transport* transport;
|
||||||
if ((transport = Transport::getTransport (file)) != NULL )
|
if ((transport = Transport::getTransport (uri)) != NULL )
|
||||||
{
|
{
|
||||||
std::string location (context.config.get ("data.location"));
|
std::string location (context.config.get ("data.location"));
|
||||||
tmpfile = location + "/import.data";
|
tmpfile = location + "/import.data";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
PROJECT = t.t tdb.t date.t duration.t t.benchmark.t text.t autocomplete.t \
|
PROJECT = t.t tdb.t date.t duration.t t.benchmark.t text.t autocomplete.t \
|
||||||
config.t seq.t att.t stringtable.t record.t nibbler.t subst.t filt.t \
|
config.t seq.t att.t stringtable.t record.t nibbler.t subst.t filt.t \
|
||||||
cmd.t util.t color.t list.t path.t file.t directory.t grid.t rx.t \
|
cmd.t util.t color.t list.t path.t file.t directory.t grid.t rx.t \
|
||||||
taskmod.t sensor.t rectangle.t tree.t tree2.t lisp.t transport.t
|
taskmod.t sensor.t rectangle.t tree.t tree2.t lisp.t uri.t
|
||||||
CFLAGS = -I. -I.. -I../.. -Wall -pedantic -ggdb3 -fno-rtti
|
CFLAGS = -I. -I.. -I../.. -Wall -pedantic -ggdb3 -fno-rtti
|
||||||
LFLAGS = -L/usr/local/lib -lpthread -lncurses -llua
|
LFLAGS = -L/usr/local/lib -lpthread -lncurses -llua
|
||||||
OBJECTS = ../t-TDB.o ../t-Task.o ../t-text.o ../t-Date.o ../t-Table.o \
|
OBJECTS = ../t-TDB.o ../t-Task.o ../t-text.o ../t-Date.o ../t-Table.o \
|
||||||
@@ -15,7 +15,7 @@ OBJECTS = ../t-TDB.o ../t-Task.o ../t-text.o ../t-Date.o ../t-Table.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 ../t-Sensor.o ../t-Thread.o \
|
../t-Transport.o ../t-TransportSSH.o ../t-Sensor.o ../t-Thread.o \
|
||||||
../t-Lisp.o ../t-Rectangle.o ../t-Tree.o ../t-TransportRSYNC.o \
|
../t-Lisp.o ../t-Rectangle.o ../t-Tree.o ../t-TransportRSYNC.o \
|
||||||
../t-TransportCurl.o
|
../t-TransportCurl.o ../t-Uri.o
|
||||||
|
|
||||||
all: $(PROJECT)
|
all: $(PROJECT)
|
||||||
|
|
||||||
@@ -106,9 +106,6 @@ rx.t: rx.t.o $(OBJECTS) test.o
|
|||||||
taskmod.t: taskmod.t.o $(OBJECTS) test.o
|
taskmod.t: taskmod.t.o $(OBJECTS) test.o
|
||||||
g++ taskmod.t.o $(OBJECTS) test.o $(LFLAGS) -o taskmod.t
|
g++ taskmod.t.o $(OBJECTS) test.o $(LFLAGS) -o taskmod.t
|
||||||
|
|
||||||
transport.t: transport.t.o $(OBJECTS) test.o
|
|
||||||
g++ transport.t.o $(OBJECTS) test.o $(LFLAGS) -o transport.t
|
|
||||||
|
|
||||||
lisp.t: lisp.t.o $(OBJECTS) test.o
|
lisp.t: lisp.t.o $(OBJECTS) test.o
|
||||||
g++ lisp.t.o $(OBJECTS) test.o $(LFLAGS) -o lisp.t
|
g++ lisp.t.o $(OBJECTS) test.o $(LFLAGS) -o lisp.t
|
||||||
|
|
||||||
@@ -124,3 +121,6 @@ tree.t: tree.t.o $(OBJECTS) test.o
|
|||||||
tree2.t: tree2.t.o $(OBJECTS) test.o
|
tree2.t: tree2.t.o $(OBJECTS) test.o
|
||||||
g++ tree2.t.o $(OBJECTS) test.o $(LFLAGS) -o tree2.t
|
g++ tree2.t.o $(OBJECTS) test.o $(LFLAGS) -o tree2.t
|
||||||
|
|
||||||
|
uri.t: uri.t.o $(OBJECTS) test.o
|
||||||
|
g++ uri.t.o $(OBJECTS) test.o $(LFLAGS) -o uri.t
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use Test::More tests => 42;
|
use Test::More tests => 43;
|
||||||
use File::Copy;
|
use File::Copy;
|
||||||
|
|
||||||
use constant false => 0;
|
use constant false => 0;
|
||||||
@@ -137,8 +137,7 @@ qx{../task rc:remote.rc 4 +gym}; # right_newer
|
|||||||
|
|
||||||
# merge remote into local
|
# merge remote into local
|
||||||
copy("local/undo.data", "local/undo.save") or fail("copy local/undo.data to local/undo.save");
|
copy("local/undo.data", "local/undo.save") or fail("copy local/undo.data to local/undo.save");
|
||||||
my $output_l = qx{../task rc:local.rc merge remote/undo.data};
|
my $output_l = qx{../task rc:local.rc merge remote/};
|
||||||
rename("local/undo.save", "local/undo.data") or fail("rename local/undo.save in local/undo.data");
|
|
||||||
|
|
||||||
#check output
|
#check output
|
||||||
like ($output_l, qr/Running redo/, "local-merge finished");
|
like ($output_l, qr/Running redo/, "local-merge finished");
|
||||||
@@ -146,7 +145,7 @@ unlike ($output_l, qr/Missing/, "local-merge: no missing entry");
|
|||||||
unlike ($output_l, qr/Not adding duplicate/, "local-merge: no duplicates");
|
unlike ($output_l, qr/Not adding duplicate/, "local-merge: no duplicates");
|
||||||
|
|
||||||
# merge local into remote
|
# merge local into remote
|
||||||
my $output_r = qx{../task rc:remote.rc merge local/undo.data};
|
my $output_r = qx{../task rc:remote.rc merge local/undo.save};
|
||||||
|
|
||||||
# check output
|
# check output
|
||||||
like ($output_r, qr/Running redo/, "remote-merge finished");
|
like ($output_r, qr/Running redo/, "remote-merge finished");
|
||||||
@@ -240,6 +239,9 @@ ok (!-r 'local/completed.data', 'Removed local/completed.data');
|
|||||||
unlink 'local/undo.data';
|
unlink 'local/undo.data';
|
||||||
ok (!-r 'local/undo.data', 'Removed local/undo.data');
|
ok (!-r 'local/undo.data', 'Removed local/undo.data');
|
||||||
|
|
||||||
|
unlink 'local/undo.save';
|
||||||
|
ok (!-r 'local/undo.save', 'Removed local/undo.save');
|
||||||
|
|
||||||
unlink 'local.rc';
|
unlink 'local.rc';
|
||||||
ok (!-r 'local.rc', 'Removed local.rc');
|
ok (!-r 'local.rc', 'Removed local.rc');
|
||||||
|
|
||||||
|
|||||||
@@ -1,87 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// taskwarrior - a command line task list manager.
|
|
||||||
//
|
|
||||||
// Copyright 2006 - 2010, Paul Beckingham.
|
|
||||||
// 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 <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <Context.h>
|
|
||||||
//#include <Att.h>
|
|
||||||
#include <Transport.h>
|
|
||||||
#include <test.h>
|
|
||||||
|
|
||||||
Context context;
|
|
||||||
|
|
||||||
class TransportTest : public Transport
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TransportTest (const std::string& uri) : Transport (uri) {};
|
|
||||||
|
|
||||||
std::string getHost() { return host; };
|
|
||||||
std::string getPath() { return path; };
|
|
||||||
std::string getUser() { return user; };
|
|
||||||
std::string getPort() { return port; };
|
|
||||||
std::string getProt() { return protocol; };
|
|
||||||
|
|
||||||
virtual void recv(std::string) {};
|
|
||||||
virtual void send(const std::string&) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int main (int argc, char** argv)
|
|
||||||
{
|
|
||||||
UnitTest t (20);
|
|
||||||
|
|
||||||
TransportTest tport1 ("asfd://user@host/folder/");
|
|
||||||
t.is (tport1.getUser (), "user", "Transport::parseUri() : asfd://user@host/folder/");
|
|
||||||
t.is (tport1.getHost (), "host", "Transport::parseUri() : asfd://user@host/folder/");
|
|
||||||
t.is (tport1.getPort (), "", "Transport::parseUri() : asfd://user@host/folder/");
|
|
||||||
t.is (tport1.getPath (), "folder/", "Transport::parseUri() : asfd://user@host/folder/");
|
|
||||||
t.is (tport1.getProt (), "asfd", "Transport::parseUri() : asfd://user@host/folder/");
|
|
||||||
|
|
||||||
TransportTest tport2 ("user@host:folder/file.test");
|
|
||||||
t.is (tport2.getUser (), "user", "Transport::parseUri() : user@host:22/folder/file.test");
|
|
||||||
t.is (tport2.getHost (), "host", "Transport::parseUri() : user@host:22/folder/file.test");
|
|
||||||
t.is (tport2.getPort (), "", "Transport::parseUri() : user@host:22/folder/file.test");
|
|
||||||
t.is (tport2.getPath (), "folder/file.test", "Transport::parseUri() : user@host:22/folder/file.test");
|
|
||||||
t.is (tport2.getProt (), "ssh", "Transport::parseUri() : user@host:22/folder/file.test");
|
|
||||||
|
|
||||||
TransportTest tport3 ("rsync://hostname.abc.de:1234/file.test");
|
|
||||||
t.is (tport3.getUser (), "", "Transport::parseUri() : hostname.abc.de/file.test");
|
|
||||||
t.is (tport3.getHost (), "hostname.abc.de", "Transport::parseUri() : hostname.abc.de/file.test");
|
|
||||||
t.is (tport3.getPort (), "1234", "Transport::parseUri() : hostname.abc.de/file.test");
|
|
||||||
t.is (tport3.getPath (), "file.test", "Transport::parseUri() : hostname.abc.de/file.test");
|
|
||||||
t.is (tport3.getProt (), "rsync", "Transport::parseUri() : hostname.abc.de/file.test");
|
|
||||||
|
|
||||||
TransportTest tport4 ("hostname:");
|
|
||||||
t.is (tport4.getUser (), "", "Transport::parseUri() : hostname/");
|
|
||||||
t.is (tport4.getHost (), "hostname", "Transport::parseUri() : hostname/");
|
|
||||||
t.is (tport4.getPort (), "", "Transport::parseUri() : hostname/");
|
|
||||||
t.is (tport4.getPath (), "", "Transport::parseUri() : hostname/");
|
|
||||||
t.is (tport4.getProt (), "ssh", "Transport::parseUri() : hostname/");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
94
src/tests/uri.t.cpp
Normal file
94
src/tests/uri.t.cpp
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// taskwarrior - a command line task list manager.
|
||||||
|
//
|
||||||
|
// Copyright 2010, 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 <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <Context.h>
|
||||||
|
#include <Uri.h>
|
||||||
|
#include <test.h>
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
int main (int argc, char** argv)
|
||||||
|
{
|
||||||
|
UnitTest t (30);
|
||||||
|
|
||||||
|
Uri uri1 ("asfd://user@host/folder/");
|
||||||
|
uri1.parse ();
|
||||||
|
t.is (uri1.user, "user", "Uri::parse() : asdf://user@host/folder/");
|
||||||
|
t.is (uri1.host, "host", "Uri::parse() : asdf://user@host/folder/");
|
||||||
|
t.is (uri1.port, "", "Uri::parse() : asdf://user@host/folder/");
|
||||||
|
t.is (uri1.path, "folder/", "Uri::parse() : asdf://user@host/folder/");
|
||||||
|
t.is (uri1.protocol, "asfd", "Uri::parse() : asdf://user@host/folder/");
|
||||||
|
t.ok (uri1.append ("file.test"), "Uri::append() to path");
|
||||||
|
t.is (uri1.path, "folder/file.test", "Uri::append() ok");
|
||||||
|
|
||||||
|
Uri uri2 ("user@host:folder/file.test");
|
||||||
|
uri2.parse ();
|
||||||
|
t.is (uri2.user, "user", "Uri::parse() : user@host:folder/file.test");
|
||||||
|
t.is (uri2.host, "host", "Uri::parse() : user@host:folder/file.test");
|
||||||
|
t.is (uri2.port, "", "Uri::parse() : user@host/folder/file.test");
|
||||||
|
t.is (uri2.path, "folder/file.test", "Uri::parse() : user@host/folder/file.test");
|
||||||
|
t.is (uri2.protocol, "ssh", "Uri::parse() : user@host/folder/file.test");
|
||||||
|
t.notok (uri2.append ("test.dat"), "Uri::append() to file");
|
||||||
|
|
||||||
|
Uri uri3 ("rsync://hostname.abc.de:1234//abs/path");
|
||||||
|
uri3.parse ();
|
||||||
|
t.is (uri3.user, "", "Uri::parse() : rsync://hostname.abc.de:1234//abs/path");
|
||||||
|
t.is (uri3.host, "hostname.abc.de", "Uri::parse() : rsync://hostname.abc.de:1234//abs/path");
|
||||||
|
t.is (uri3.port, "1234", "Uri::parse() : rsync://hostname.abc.de:1234//abs/path");
|
||||||
|
t.is (uri3.path, "/abs/path", "Uri::parse() : rsync://hostname.abc.de:1234//abs/path");
|
||||||
|
t.is (uri3.protocol, "rsync", "Uri::parse() : rsync://hostname.abc.de:1234//abs/path");
|
||||||
|
|
||||||
|
Uri uri4 ("hostname:");
|
||||||
|
uri4.parse ();
|
||||||
|
t.is (uri4.user, "", "Uri::parse() : hostname:");
|
||||||
|
t.is (uri4.host, "hostname", "Uri::parse() : hostname:");
|
||||||
|
t.is (uri4.port, "", "Uri::parse() : hostname:");
|
||||||
|
t.is (uri4.path, "", "Uri::parse() : hostname:");
|
||||||
|
t.is (uri4.protocol, "ssh", "Uri::parse() : hostname:");
|
||||||
|
t.notok (uri4.is_local (), "Uri::is_local() : hostname:");
|
||||||
|
t.ok (uri4.append ("file.test"), "Uri::append() : hostname:");
|
||||||
|
t.is (uri4.path, "file.test","Uri::append() : ok");
|
||||||
|
|
||||||
|
context.config.set ("merge.default.uri", "../folder/");
|
||||||
|
context.config.set ("push.test.uri", "/home/user/.task/");
|
||||||
|
|
||||||
|
Uri uri5 ("", "merge");
|
||||||
|
t.ok (uri5.is_local (), "Uri::is_local() : ../server/");
|
||||||
|
uri5.parse ();
|
||||||
|
t.is (uri5.path, "../folder/", "Uri::expand() default");
|
||||||
|
|
||||||
|
Uri uri6 ("test", "push");
|
||||||
|
t.ok (uri6.is_local(), "Uri::is_local() : /home/user/.task/");
|
||||||
|
uri6.parse ();
|
||||||
|
t.is (uri6.path, "/home/user/.task/", "Uri::expand() test");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Reference in New Issue
Block a user