Cleanup rdef
Rewrote url parsing (unfinished) Added several url types. Now it handles: ftp, sftp, telnet, ssh, finger, sh, file, beshare (to BeShare), mms, rtp, rtsp (to VLC). Some make probably more sense to add to the respective apps (BeShare, VLC...) but it's still handy for now. Now please everyone go fix your apps to use generic url support instead of hardcoding http: :) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20048 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
998579b2e1
commit
44c1a9db62
@ -1,3 +1,4 @@
|
||||
#include <Alert.h>
|
||||
#include <Application.h>
|
||||
#include <AppFileInfo.h>
|
||||
#include <Mime.h>
|
||||
@ -8,33 +9,164 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define PROTO "telnet"
|
||||
#define HANDLE_FILE
|
||||
#define HANDLE_SH
|
||||
#define HANDLE_BESHARE
|
||||
//#define HANDLE_IM
|
||||
#define HANDLE_VLC
|
||||
|
||||
class TWApp : public BApplication
|
||||
const char *kAppSig = "application/x-vnd.haiku.urlwrapper";
|
||||
|
||||
#ifdef __HAIKU__
|
||||
const char *kTerminalSig = "application/x-vnd.Haiku-Terminal";
|
||||
#else
|
||||
const char *kTerminalSig = "application/x-vnd.Be-SHEL";
|
||||
#endif
|
||||
|
||||
#ifdef HANDLE_FILE
|
||||
const char *kTrackerSig = "application/x-vnd.Be-TRAK";
|
||||
#endif
|
||||
|
||||
#ifdef HANDLE_BESHARE
|
||||
const char *kBeShareSig = "application/x-vnd.Sugoi-BeShare";
|
||||
#endif
|
||||
|
||||
#ifdef HANDLE_IM
|
||||
const char *kIMSig = "application/x-vnd.m_eiman.sample_im_client";
|
||||
#endif
|
||||
|
||||
#ifdef HANDLE_VLC
|
||||
const char *kVLCSig = "application/x-vnd.videolan-vlc";
|
||||
#endif
|
||||
|
||||
// TODO: make a Url class
|
||||
class Url : public BString {
|
||||
public:
|
||||
Url(const char *url) : BString(url) { fStatus = ParseAndSplit(); };
|
||||
~Url() {};
|
||||
status_t InitCheck() const { return fStatus; };
|
||||
status_t ParseAndSplit();
|
||||
|
||||
bool HasHost() const { return host.Length(); };
|
||||
bool HasPort() const { return port.Length(); };
|
||||
bool HasUser() const { return user.Length(); };
|
||||
bool HasPass() const { return pass.Length(); };
|
||||
bool HasPath() const { return path.Length(); };
|
||||
BString Proto() const { return BString(proto); };
|
||||
BString Host() const { return BString(host); };
|
||||
BString Port() const { return BString(port); };
|
||||
BString User() const { return BString(user); };
|
||||
BString Pass() const { return BString(pass); };
|
||||
|
||||
BString proto;
|
||||
BString host;
|
||||
BString port;
|
||||
BString user;
|
||||
BString pass;
|
||||
BString path;
|
||||
private:
|
||||
status_t fStatus;
|
||||
};
|
||||
|
||||
class UrlWrapperApp : public BApplication
|
||||
{
|
||||
public:
|
||||
TWApp();
|
||||
~TWApp();
|
||||
status_t SplitUrlHostUserPass(const char *url, BString &host, BString &user, BString &pass);
|
||||
UrlWrapperApp();
|
||||
~UrlWrapperApp();
|
||||
status_t SplitUrl(const char *url, BString &host, BString &port, BString &user, BString &pass, BString &path);
|
||||
status_t UnurlString(BString &s);
|
||||
status_t Warn(const char *url);
|
||||
virtual void ArgvReceived(int32 argc, char **argv);
|
||||
virtual void ReadyToRun(void);
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
const char *app_mime = "application/x-vnd.mmu_man.telnetwrapper";
|
||||
//const char *url_mime = "application/x-vnd.Be.URL.telnet";
|
||||
const char *url_mime = B_URL_TELNET;
|
||||
const char *terminal_sig = "application/x-vnd.Be-SHEL";
|
||||
|
||||
TWApp::TWApp() : BApplication(app_mime)
|
||||
// TODO: handle ":port" as well
|
||||
// TODO: handle "/path" as well
|
||||
// proto:[//]user:pass@host:port/path
|
||||
status_t Url::ParseAndSplit()
|
||||
{
|
||||
BMimeType mt(url_mime);
|
||||
int32 v;
|
||||
//host = *this;
|
||||
BString left;
|
||||
printf("s:%s\n", String());
|
||||
|
||||
v = FindFirst(":");
|
||||
if (v < 0)
|
||||
return EINVAL;
|
||||
|
||||
CopyInto(proto, 0, v);
|
||||
CopyInto(left, v + 1, Length() - v);
|
||||
if (left.FindFirst("//") == 0)
|
||||
left.RemoveFirst("//");
|
||||
|
||||
// path part
|
||||
v = left.FindFirst("/");
|
||||
if (v == 0 || proto == "file") {
|
||||
path = left;
|
||||
printf("path:%s\n", path.String());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (v > -1) {
|
||||
left.MoveInto(path, v+1, left.Length()-v);
|
||||
left.Remove(v, 1);
|
||||
}
|
||||
printf("path:%s\n", path.String());
|
||||
|
||||
// user:pass@host
|
||||
v = left.FindFirst("@");
|
||||
if (v > -1) {
|
||||
left.MoveInto(user, 0, v);
|
||||
left.Remove(0, 1);
|
||||
printf("user:%s\n", user.String());
|
||||
v = user.FindFirst(":");
|
||||
if (v > -1) {
|
||||
user.MoveInto(pass, v, user.Length() - v);
|
||||
pass.Remove(0, 1);
|
||||
printf("pass:%s\n", pass.String());
|
||||
}
|
||||
}
|
||||
|
||||
// host:port
|
||||
v = left.FindFirst(":");
|
||||
if (v > -1) {
|
||||
left.MoveInto(port, v + 1, left.Length() - v);
|
||||
left.Remove(v, 1);
|
||||
printf("port:%s\n", port.String());
|
||||
}
|
||||
|
||||
// not much left...
|
||||
host = left;
|
||||
printf("host:%s\n", host.String());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
status_t UrlWrapperApp::SplitUrl(const char *url, BString &host, BString &port, BString &user, BString &pass, BString &path)
|
||||
{
|
||||
Url u(url);
|
||||
if (u.InitCheck() < 0)
|
||||
return u.InitCheck();
|
||||
host = u.host;
|
||||
port = u.port;
|
||||
user = u.user;
|
||||
pass = u.pass;
|
||||
path = u.path;
|
||||
return 0;
|
||||
}
|
||||
|
||||
UrlWrapperApp::UrlWrapperApp() : BApplication(kAppSig)
|
||||
{
|
||||
#if 0
|
||||
BMimeType mt(B_URL_TELNET);
|
||||
if (mt.InitCheck())
|
||||
return;
|
||||
if (!mt.IsInstalled()) {
|
||||
mt.Install();
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
BAppFileInfo afi;
|
||||
if (!afi.Supports(&mt)) {
|
||||
@ -46,31 +178,34 @@ TWApp::TWApp() : BApplication(app_mime)
|
||||
#endif
|
||||
}
|
||||
|
||||
TWApp::~TWApp()
|
||||
UrlWrapperApp::~UrlWrapperApp()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// XXX: handle ":port" as well
|
||||
status_t TWApp::SplitUrlHostUserPass(const char *url, BString &host, BString &user, BString &pass)
|
||||
|
||||
status_t UrlWrapperApp::UnurlString(BString &s)
|
||||
{
|
||||
host = url;
|
||||
if (host.FindFirst("@") > -1) {
|
||||
printf("%s -- %s\n", host.String(), user.String());
|
||||
host.MoveInto(user, 0, host.FindFirst("@"));
|
||||
host.Remove(0, 1);
|
||||
if (user.FindFirst(":") > -1) {
|
||||
user.MoveInto(pass, user.FindFirst(":"), user.Length());
|
||||
pass.Remove(0, 1);
|
||||
return 3;
|
||||
}
|
||||
printf("%s -- %s\n", host.String(), user.String());
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
// TODO:WRITEME
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void TWApp::ArgvReceived(int32 argc, char **argv)
|
||||
status_t UrlWrapperApp::Warn(const char *url)
|
||||
{
|
||||
BString message("An application has requested the system to open the following url: \n");
|
||||
message << "\n" << url << "\n\n";
|
||||
message << "This type of urls has a potential security risk.\n";
|
||||
message << "Proceed anyway ?";
|
||||
BAlert *alert = new BAlert("Warning", message.String(), "Ok", "No", NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
||||
int32 v;
|
||||
v = alert->Go();
|
||||
if (v == 0)
|
||||
return B_OK;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
void UrlWrapperApp::ArgvReceived(int32 argc, char **argv)
|
||||
{
|
||||
#if 0
|
||||
for (int i = 1; i < argc; i++) {
|
||||
@ -80,76 +215,71 @@ void TWApp::ArgvReceived(int32 argc, char **argv)
|
||||
if (argc <= 1)
|
||||
return;
|
||||
|
||||
const char *failc = " || read -p 'Press any key'";
|
||||
const char *pausec = "; read -p 'Press any key'";
|
||||
char *args[] = { "/bin/sh", "-c", NULL, NULL};
|
||||
|
||||
BString proto;
|
||||
BString host;
|
||||
BString port;
|
||||
BString user;
|
||||
BString pass;
|
||||
BString path;
|
||||
|
||||
BString url(argv[1]);
|
||||
Url u(argv[1]);
|
||||
BString rawurl(argv[1]);
|
||||
BString url = rawurl;
|
||||
if (url.FindFirst(":") < 0) {
|
||||
fprintf(stderr, "malformed url: '%s'\n", url.String());
|
||||
return;
|
||||
}
|
||||
url.MoveInto(proto, 0, url.FindFirst(":"));
|
||||
url.Remove(0, 1);
|
||||
if (url.FindFirst("//") == 0)
|
||||
url.RemoveFirst("//");
|
||||
|
||||
// XXX: should factorize that
|
||||
// pre-slice the url, but you're not forced to use the result.
|
||||
// original still in rawurl.
|
||||
SplitUrl(u.String(), host, port, user, pass, path);
|
||||
|
||||
if (url.FindFirst("telnet:") == 0) {
|
||||
url.RemoveFirst("telnet:");
|
||||
if (url.FindFirst("//") == 0)
|
||||
url.RemoveFirst("//");
|
||||
|
||||
|
||||
const char *failc = " || read -p 'Press any key'";
|
||||
// XXX: debug
|
||||
printf("PROTO='%s'\n", proto.String());
|
||||
printf("HOST='%s'\n", host.String());
|
||||
printf("PORT='%s'\n", port.String());
|
||||
printf("USER='%s'\n", user.String());
|
||||
printf("PASS='%s'\n", pass.String());
|
||||
printf("PATH='%s'\n", path.String());
|
||||
|
||||
if (proto == "telnet") {
|
||||
BString cmd("telnet ");
|
||||
SplitUrlHostUserPass(url.String(), host, user, pass);
|
||||
printf("HOST='%s'\n", host.String());
|
||||
printf("USER='%s'\n", user.String());
|
||||
printf("PASS='%s'\n", pass.String());
|
||||
if (user.Length())
|
||||
cmd << "-l " << user << " ";
|
||||
cmd << host;
|
||||
printf("CMD='%s'\n", cmd.String());
|
||||
cmd << failc;
|
||||
args[2] = (char *)cmd.String();
|
||||
be_roster->Launch(terminal_sig, 3, args);
|
||||
be_roster->Launch(kTerminalSig, 3, args);
|
||||
return;
|
||||
}
|
||||
|
||||
if (url.FindFirst("ssh:") == 0) {
|
||||
url.RemoveFirst("ssh:");
|
||||
if (url.FindFirst("//") == 0)
|
||||
url.RemoveFirst("//");
|
||||
|
||||
|
||||
const char *failc = " || read -p 'Press any key'";
|
||||
if (proto == "ssh") {
|
||||
BString cmd("ssh ");
|
||||
|
||||
SplitUrlHostUserPass(url.String(), host, user, pass);
|
||||
printf("HOST='%s'\n", host.String());
|
||||
printf("USER='%s'\n", user.String());
|
||||
printf("PASS='%s'\n", pass.String());
|
||||
if (user.Length())
|
||||
cmd << "-l " << user << " ";
|
||||
cmd << host;
|
||||
printf("CMD='%s'\n", cmd.String());
|
||||
cmd << failc;
|
||||
args[2] = (char *)cmd.String();
|
||||
be_roster->Launch(terminal_sig, 3, args);
|
||||
// XXX: handle errors
|
||||
be_roster->Launch(kTerminalSig, 3, args);
|
||||
// TODO: handle errors
|
||||
return;
|
||||
}
|
||||
|
||||
if (url.FindFirst("ftp:") == 0) {
|
||||
url.RemoveFirst("ftp:");
|
||||
if (url.FindFirst("//") == 0)
|
||||
url.RemoveFirst("//");
|
||||
|
||||
|
||||
const char *failc = " || read -p 'Press any key'";
|
||||
if (proto == "ftp") {
|
||||
BString cmd("ftp ");
|
||||
|
||||
/*
|
||||
SplitUrlHostUserPass(url.String(), host, user, pass);
|
||||
printf("HOST='%s'\n", host.String());
|
||||
printf("USER='%s'\n", user.String());
|
||||
printf("PASS='%s'\n", pass.String());
|
||||
if (user.Length())
|
||||
cmd << "-l " << user << " ";
|
||||
cmd << host;
|
||||
@ -158,25 +288,15 @@ void TWApp::ArgvReceived(int32 argc, char **argv)
|
||||
printf("CMD='%s'\n", cmd.String());
|
||||
cmd << failc;
|
||||
args[2] = (char *)cmd.String();
|
||||
be_roster->Launch(terminal_sig, 3, args);
|
||||
// XXX: handle errors
|
||||
be_roster->Launch(kTerminalSig, 3, args);
|
||||
// TODO: handle errors
|
||||
return;
|
||||
}
|
||||
|
||||
if (url.FindFirst("sftp:") == 0) {
|
||||
url.RemoveFirst("sftp:");
|
||||
if (url.FindFirst("//") == 0)
|
||||
url.RemoveFirst("//");
|
||||
|
||||
|
||||
const char *failc = " || read -p 'Press any key'";
|
||||
if (proto == "sftp") {
|
||||
BString cmd("sftp ");
|
||||
|
||||
/*
|
||||
SplitUrlHostUserPass(url.String(), host, user, pass);
|
||||
printf("HOST='%s'\n", host.String());
|
||||
printf("USER='%s'\n", user.String());
|
||||
printf("PASS='%s'\n", pass.String());
|
||||
if (user.Length())
|
||||
cmd << "-l " << user << " ";
|
||||
cmd << host;
|
||||
@ -185,34 +305,123 @@ void TWApp::ArgvReceived(int32 argc, char **argv)
|
||||
printf("CMD='%s'\n", cmd.String());
|
||||
cmd << failc;
|
||||
args[2] = (char *)cmd.String();
|
||||
be_roster->Launch(terminal_sig, 3, args);
|
||||
// XXX: handle errors
|
||||
be_roster->Launch(kTerminalSig, 3, args);
|
||||
// TODO: handle errors
|
||||
return;
|
||||
}
|
||||
|
||||
if (proto == "finger") {
|
||||
BString cmd("finger ");
|
||||
|
||||
// TODO: SplitUrl thinks the user is host when it's not present... FIXME.
|
||||
if (user.Length())
|
||||
cmd << user;
|
||||
if (host.Length() == 0)
|
||||
host = "127.0.0.1";
|
||||
cmd << "@" << host;
|
||||
printf("CMD='%s'\n", cmd.String());
|
||||
cmd << pausec;
|
||||
args[2] = (char *)cmd.String();
|
||||
be_roster->Launch(kTerminalSig, 3, args);
|
||||
// TODO: handle errors
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HANDLE_FILE
|
||||
if (proto == "file") {
|
||||
BMessage m(B_REFS_RECEIVED);
|
||||
entry_ref ref;
|
||||
// UnurlString(path);
|
||||
if (get_ref_for_path(path.String(), &ref) < B_OK)
|
||||
return;
|
||||
m.AddRef("refs", &ref);
|
||||
be_roster->Launch(kTrackerSig, &m);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HANDLE_SH
|
||||
if (proto == "sh") {
|
||||
BString cmd(url);
|
||||
if (Warn(rawurl.String()) != B_OK)
|
||||
return;
|
||||
printf("CMD='%s'\n", cmd.String());
|
||||
cmd << pausec;
|
||||
args[2] = (char *)cmd.String();
|
||||
be_roster->Launch(kTerminalSig, 3, args);
|
||||
// TODO: handle errors
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HANDLE_BESHARE
|
||||
if (proto == "beshare") {
|
||||
team_id team;
|
||||
be_roster->Launch(kBeShareSig, (BMessage *)NULL, &team);
|
||||
BMessenger msgr(NULL, team);
|
||||
if (host.Length()) {
|
||||
BMessage mserver('serv');
|
||||
mserver.AddString("server", host);
|
||||
//msgs.AddItem(&mserver);
|
||||
msgr.SendMessage(mserver);
|
||||
|
||||
}
|
||||
if (path.Length()) {
|
||||
BMessage mquery('quer');
|
||||
mquery.AddString("query", path);
|
||||
//msgs.AddItem(&mquery);
|
||||
msgr.SendMessage(mquery);
|
||||
}
|
||||
// TODO: handle errors
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HANDLE_IM
|
||||
if (proto == "icq" || proto == "msn") {
|
||||
// TODO
|
||||
team_id team;
|
||||
be_roster->Launch(kIMSig, (BMessage *)NULL, &team);
|
||||
BMessenger msgr(NULL, team);
|
||||
if (host.Length()) {
|
||||
BMessage mserver(B_REFS_RECEIVED);
|
||||
mserver.AddString("server", host);
|
||||
//msgs.AddItem(&mserver);
|
||||
msgr.SendMessage(mserver);
|
||||
|
||||
}
|
||||
// TODO: handle errors
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HANDLE_VLC
|
||||
if (proto == "mms" || proto == "rtp" || proto == "rtsp") {
|
||||
args[0] = "vlc";
|
||||
args[1] = (char *)rawurl.String();
|
||||
be_roster->Launch(kVLCSig, 2, args);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// finger:user@host
|
||||
// vnc: ?
|
||||
// irc: ?
|
||||
//
|
||||
// file: -> Tracker ?
|
||||
// svn: ?
|
||||
// cvs: ?
|
||||
// mms: -> VLC
|
||||
// rtsp: -> VLC
|
||||
// rtp: -> VLC
|
||||
|
||||
// smb: ?
|
||||
// nfs: ?
|
||||
|
||||
}
|
||||
|
||||
void TWApp::ReadyToRun(void)
|
||||
void UrlWrapperApp::ReadyToRun(void)
|
||||
{
|
||||
Quit();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
TWApp app;
|
||||
UrlWrapperApp app;
|
||||
if (be_app)
|
||||
app.Run();
|
||||
return 0;
|
||||
|
@ -1,37 +1,18 @@
|
||||
|
||||
resource(1, "BEOS:APP_SIG") #'MIMS' "application/x-vnd.mmu_man.telnetwrapper";
|
||||
resource app_signature "application/x-vnd.haiku.urlwrapper";
|
||||
resource app_flags B_MULTIPLE_LAUNCH | B_BACKGROUND_APP | B_ARGV_ONLY;
|
||||
|
||||
resource(1, "BEOS:FILE_TYPES") message
|
||||
{
|
||||
"types" = "application/x-vnd.Be.URL.telnet",
|
||||
"types" = "application/x-vnd.Be.URL.ssh",
|
||||
"types" = "application/x-vnd.Be-URL.ftp"
|
||||
"types" = "application/x-vnd.Be.URL.ftp",
|
||||
"types" = "application/x-vnd.Be.URL.sftp",
|
||||
"types" = "application/x-vnd.Be.URL.finger",
|
||||
"types" = "application/x-vnd.Be.URL.sh",
|
||||
"types" = "application/x-vnd.Be.URL.file",
|
||||
"types" = "application/x-vnd.Be.URL.beshare",
|
||||
"types" = "application/x-vnd.Be.URL.mms",
|
||||
"types" = "application/x-vnd.Be.URL.rtp",
|
||||
"types" = "application/x-vnd.Be.URL.rtsp"
|
||||
};
|
||||
|
||||
resource(1, "BEOS:APP_VERSION") #'APPV' array
|
||||
{
|
||||
$"0000000000000000010000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000"
|
||||
};
|
||||
|
||||
resource(1, "BEOS:APP_FLAGS") #'APPF' $"04000000";
|
||||
|
Loading…
Reference in New Issue
Block a user