summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Orlenko <zxteam@gmail.com>2010-08-12 23:59:32 +1100
committerAlexander Orlenko <zxteam@gmail.com>2010-08-12 23:59:32 +1100
commit702fa15c0d474fbcb9a4d5a5ae8ce0f6be48385e (patch)
tree519aed830a3eb9193bbdddbebc390167fdc1b193
parent2536337055de99f662612cdc3db6a969289c87ce (diff)
downloadbluez-tools-702fa15c0d474fbcb9a4d5a5ae8ce0f6be48385e.tar.gz
Added man for bt-obex
Some bugfixes and improvements
-rwxr-xr-xcontrib/build-mans.sh2
-rw-r--r--contrib/man/bt-obex.pod64
-rw-r--r--src/bt-adapter.c4
-rw-r--r--src/bt-agent.c4
-rw-r--r--src/bt-audio.c8
-rw-r--r--src/bt-device.c10
-rw-r--r--src/bt-input.c8
-rw-r--r--src/bt-monitor.c14
-rw-r--r--src/bt-network.c11
-rw-r--r--src/bt-obex.1191
-rw-r--r--src/bt-obex.c188
-rw-r--r--src/bt-serial.c10
-rw-r--r--src/lib/helpers.c61
-rw-r--r--src/lib/helpers.h4
-rw-r--r--src/lib/obexd/obexagent.c10
15 files changed, 467 insertions, 122 deletions
diff --git a/contrib/build-mans.sh b/contrib/build-mans.sh
index 7191465..2c96802 100755
--- a/contrib/build-mans.sh
+++ b/contrib/build-mans.sh
@@ -10,3 +10,5 @@ pod2man -n bt-audio -c "bluez-tools" -r "" man/bt-audio.pod > ../src/bt-audio.1
pod2man -n bt-input -c "bluez-tools" -r "" man/bt-input.pod > ../src/bt-input.1
pod2man -n bt-network -c "bluez-tools" -r "" man/bt-network.pod > ../src/bt-network.1
pod2man -n bt-serial -c "bluez-tools" -r "" man/bt-serial.pod > ../src/bt-serial.1
+
+pod2man -n bt-obex -c "bluez-tools" -r "" man/bt-obex.pod > ../src/bt-obex.1
diff --git a/contrib/man/bt-obex.pod b/contrib/man/bt-obex.pod
new file mode 100644
index 0000000..41559ef
--- /dev/null
+++ b/contrib/man/bt-obex.pod
@@ -0,0 +1,64 @@
+=head1 NAME
+
+bt-obex - a bluetooth OBEX client/server
+
+=head1 SYNOPSIS
+
+bt-obex [OPTION...]
+
+Help Options:
+ -h, --help
+
+Application Options:
+ -a, --adapter=<name|mac>
+ -s, --server [<path>]
+ -p, --opp <name|mac> <file>
+ -f, --ftp=<name|mac>
+
+=head1 DESCRIPTION
+
+This utility implemented support of Object Push Profile (OPP) and File Transfer Profile (FTP).
+You can send and receive files to/from remote device using this tool.
+
+=head1 OPTIONS
+
+B<-h, --help>
+ Show help
+
+B<-a, --adapter E<lt>name|macE<gt>>
+ Specify adapter to use by his Name or MAC address
+ (if this option does not defined - default adapter used)
+
+B<-s, --server [E<lt>pathE<gt>]>
+ Register agent at OBEX server and set incoming/root directory to
+ `path` or current folder will be used; Agent is used to
+ accept/reject imcoming bluetooth object push requests
+
+B<-p, --opp E<lt>name|macE<gt> E<lt>fileE<gt>>
+ Send local file to the specified remove device using object push
+ profile
+
+B<-f, --ftp E<lt>name|macE<gt>>
+ Start ftp session with remote device; If session opened
+ successfuly, ftp shell will be opened
+
+ FTP commands:
+
+ help Show help message
+ exit Close FTP session
+ cd <folder> Change the current folder of the remote device
+ mkdir <folder> Create a new folder in the remote device
+ ls List folder contents
+ get <src> <dst> Copy the src file (from remote device) to the dst file (on local filesystem)
+ put <src> <dst> Copy the src file (from local filesystem) to the dst file (on remote device)
+ cp <src> <dst> Copy a file within the remote device from src file to dst file
+ mv <src> <dst> Move a file within the remote device from src file to dst file
+ rm <target> Deletes the specified file/folder
+
+=head1 AUTHOR
+
+Alexander Orlenko <zxteam@gmail.com>.
+
+=head1 SEE ALSO
+
+bt-adapter(1) bt-agent(1) bt-audio(1) bt-device(1) bt-input(1) bt-monitor(1) bt-network(1) bt-serial(1)
diff --git a/src/bt-adapter.c b/src/bt-adapter.c
index 20f609d..28b9731 100644
--- a/src/bt-adapter.c
+++ b/src/bt-adapter.c
@@ -89,7 +89,7 @@ static gchar *set_value_arg = NULL;
static GOptionEntry entries[] = {
{"list", 'l', 0, G_OPTION_ARG_NONE, &list_arg, "List all available adapters", NULL},
- {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter name or MAC", "<name|mac>"},
+ {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or MAC", "<name|mac>"},
{"info", 'i', 0, G_OPTION_ARG_NONE, &info_arg, "Show adapter info", NULL},
{"discover", 'd', 0, G_OPTION_ARG_NONE, &discover_arg, "Discover remote devices", NULL},
{"set", 0, 0, G_OPTION_ARG_NONE, &set_arg, "Set adapter property", NULL},
@@ -137,7 +137,7 @@ int main(int argc, char *argv[])
g_option_context_free(context);
if (!dbus_system_connect(&error)) {
- g_printerr("Couldn't connect to dbus system bus: %s\n", error->message);
+ g_printerr("Couldn't connect to DBus system bus: %s\n", error->message);
exit(EXIT_FAILURE);
}
diff --git a/src/bt-agent.c b/src/bt-agent.c
index 288d350..0fc97bb 100644
--- a/src/bt-agent.c
+++ b/src/bt-agent.c
@@ -60,7 +60,7 @@ static void agent_released(Agent *agent, gpointer data)
static gchar *adapter_arg = NULL;
static GOptionEntry entries[] = {
- {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter name or MAC", "<name|mac>"},
+ {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or MAC", "<name|mac>"},
{NULL}
};
@@ -89,7 +89,7 @@ int main(int argc, char *argv[])
g_option_context_free(context);
if (!dbus_system_connect(&error)) {
- g_printerr("Couldn't connect to dbus system bus: %s\n", error->message);
+ g_printerr("Couldn't connect to DBus system bus: %s\n", error->message);
exit(EXIT_FAILURE);
}
diff --git a/src/bt-audio.c b/src/bt-audio.c
index 3fc59e5..8d2e7ee 100644
--- a/src/bt-audio.c
+++ b/src/bt-audio.c
@@ -57,9 +57,9 @@ static gchar *connect_arg = NULL;
static gchar *disconnect_arg = NULL;
static GOptionEntry entries[] = {
- {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter name or MAC", "<name|mac>"},
- {"connect", 'c', 0, G_OPTION_ARG_STRING, &connect_arg, "Connect to an audio device", "<name|mac>"},
- {"disconnect", 'd', 0, G_OPTION_ARG_STRING, &disconnect_arg, "Disconnect from an audio device", "<name|mac>"},
+ {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or MAC", "<name|mac>"},
+ {"connect", 'c', 0, G_OPTION_ARG_STRING, &connect_arg, "Connect to the audio device", "<name|mac>"},
+ {"disconnect", 'd', 0, G_OPTION_ARG_STRING, &disconnect_arg, "Disconnect from the audio device", "<name|mac>"},
{NULL}
};
@@ -91,7 +91,7 @@ int main(int argc, char *argv[])
g_option_context_free(context);
if (!dbus_system_connect(&error)) {
- g_printerr("Couldn't connect to dbus system bus: %s\n", error->message);
+ g_printerr("Couldn't connect to DBus system bus: %s\n", error->message);
exit(EXIT_FAILURE);
}
diff --git a/src/bt-device.c b/src/bt-device.c
index 46c67cb..f011d79 100644
--- a/src/bt-device.c
+++ b/src/bt-device.c
@@ -236,14 +236,14 @@ static void create_paired_device_done(gpointer data)
}
static GOptionEntry entries[] = {
- {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter name or MAC", "<name|mac>"},
+ {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or MAC", "<name|mac>"},
{"list", 'l', 0, G_OPTION_ARG_NONE, &list_arg, "List added devices", NULL},
- {"connect", 'c', 0, G_OPTION_ARG_STRING, &connect_arg, "Connect to a device", "<mac>"},
+ {"connect", 'c', 0, G_OPTION_ARG_STRING, &connect_arg, "Connect to the remote device", "<mac>"},
{"remove", 'r', 0, G_OPTION_ARG_STRING, &remove_arg, "Remove device", "<name|mac>"},
{"info", 'i', 0, G_OPTION_ARG_STRING, &info_arg, "Get info about device", "<name|mac>"},
{"services", 's', 0, G_OPTION_ARG_NONE, &services_arg, "Discover device services", NULL},
{"set", 0, 0, G_OPTION_ARG_NONE, &set_arg, "Set device property", NULL},
- {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose_arg, "Verbosely list services", NULL},
+ {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose_arg, "Verbosely display remote service records", NULL},
{NULL}
};
@@ -265,7 +265,7 @@ int main(int argc, char *argv[])
"Set Options:\n"
" --set <name|mac> <property> <value>\n"
" Where\n"
- " `name|mac` is a device name or MAC\n"
+ " `name|mac` is a device Name or MAC\n"
" `property` is one of:\n"
" Alias\n"
" Trusted\n"
@@ -294,7 +294,7 @@ int main(int argc, char *argv[])
g_option_context_free(context);
if (!dbus_system_connect(&error)) {
- g_printerr("Couldn't connect to dbus system bus: %s\n", error->message);
+ g_printerr("Couldn't connect to DBus system bus: %s\n", error->message);
exit(EXIT_FAILURE);
}
diff --git a/src/bt-input.c b/src/bt-input.c
index fb75c5a..4e9889a 100644
--- a/src/bt-input.c
+++ b/src/bt-input.c
@@ -54,9 +54,9 @@ static gchar *connect_arg = NULL;
static gchar *disconnect_arg = NULL;
static GOptionEntry entries[] = {
- {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter name or MAC", "<name|mac>"},
- {"connect", 'c', 0, G_OPTION_ARG_STRING, &connect_arg, "Connect to an input device", "<name|mac>"},
- {"disconnect", 'd', 0, G_OPTION_ARG_STRING, &disconnect_arg, "Disconnect from an input device", "<name|mac>"},
+ {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or MAC", "<name|mac>"},
+ {"connect", 'c', 0, G_OPTION_ARG_STRING, &connect_arg, "Connect to the input device", "<name|mac>"},
+ {"disconnect", 'd', 0, G_OPTION_ARG_STRING, &disconnect_arg, "Disconnect from the input device", "<name|mac>"},
{NULL}
};
@@ -88,7 +88,7 @@ int main(int argc, char *argv[])
g_option_context_free(context);
if (!dbus_system_connect(&error)) {
- g_printerr("Couldn't connect to dbus system bus: %s\n", error->message);
+ g_printerr("Couldn't connect to DBus system bus: %s\n", error->message);
exit(EXIT_FAILURE);
}
diff --git a/src/bt-monitor.c b/src/bt-monitor.c
index 1d03c51..6fb0488 100644
--- a/src/bt-monitor.c
+++ b/src/bt-monitor.c
@@ -273,7 +273,7 @@ static void capture_adapter(Adapter *adapter)
g_assert(ADAPTER_IS(adapter));
GSList *t = g_slist_append(NULL, adapter);
- g_hash_table_insert(captured_adapters_devices_t, adapter_get_dbus_object_path(adapter), t);
+ g_hash_table_insert(captured_adapters_devices_t, g_strdup(adapter_get_dbus_object_path(adapter)), t);
g_signal_connect(adapter, "DeviceCreated", G_CALLBACK(adapter_device_created), NULL);
g_signal_connect(adapter, "DeviceDisappeared", G_CALLBACK(adapter_device_disappeared), NULL);
@@ -333,8 +333,8 @@ static void capture_device(Device *device)
g_signal_connect(device, "DisconnectRequested", G_CALLBACK(device_disconnect_requested), NULL);
g_signal_connect(device, "PropertyChanged", G_CALLBACK(device_property_changed), NULL);
- g_hash_table_insert(captured_adapters_devices_t, device_get_adapter(device), t);
- g_hash_table_insert(captured_devices_services_t, device_get_dbus_object_path(device), t2);
+ g_hash_table_insert(captured_adapters_devices_t, g_strdup(device_get_adapter(device)), t);
+ g_hash_table_insert(captured_devices_services_t, g_strdup(device_get_dbus_object_path(device)), t2);
reload_device_services(device);
}
@@ -348,7 +348,7 @@ static void release_device(Device *device)
GSList *t = g_hash_table_lookup(captured_adapters_devices_t, device_get_adapter(device));
if (t != NULL) {
t = g_slist_remove(t, device);
- g_hash_table_insert(captured_adapters_devices_t, device_get_adapter(device), t);
+ g_hash_table_insert(captured_adapters_devices_t, g_strdup(device_get_adapter(device)), t);
}
GSList *t2 = g_hash_table_lookup(captured_devices_services_t, device_get_dbus_object_path(device));
@@ -396,11 +396,11 @@ static void reload_device_services(Device *device)
t2 = g_slist_append(t2, network);
}
- g_hash_table_insert(captured_devices_services_t, device_get_dbus_object_path(device), t2);
+ g_hash_table_insert(captured_devices_services_t, g_strdup(device_get_dbus_object_path(device)), t2);
}
static GOptionEntry entries[] = {
- {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter name or MAC", "<name|mac>"},
+ {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or MAC", "<name|mac>"},
{NULL}
};
@@ -429,7 +429,7 @@ int main(int argc, char *argv[])
g_option_context_free(context);
if (!dbus_system_connect(&error)) {
- g_printerr("Couldn't connect to dbus system bus: %s\n", error->message);
+ g_printerr("Couldn't connect to DBus system bus: %s\n", error->message);
exit(EXIT_FAILURE);
}
diff --git a/src/bt-network.c b/src/bt-network.c
index 8c1e906..4b751c0 100644
--- a/src/bt-network.c
+++ b/src/bt-network.c
@@ -68,9 +68,9 @@ static gchar *server_uuid_arg = NULL;
static gchar *server_brige_arg = NULL;
static GOptionEntry entries[] = {
- {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter name or MAC", "<name|mac>"},
- {"connect", 'c', 0, G_OPTION_ARG_NONE, &connect_arg, "Connect to a network device", NULL},
- {"disconnect", 'd', 0, G_OPTION_ARG_STRING, &disconnect_arg, "Disconnect from a network device", "<name|mac>"},
+ {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or MAC", "<name|mac>"},
+ {"connect", 'c', 0, G_OPTION_ARG_NONE, &connect_arg, "Connect to the network device", NULL},
+ {"disconnect", 'd', 0, G_OPTION_ARG_STRING, &disconnect_arg, "Disconnect from the network device", "<name|mac>"},
{"server", 's', 0, G_OPTION_ARG_NONE, &server_arg, "Start GN/PANU/NAP server", NULL},
{NULL}
};
@@ -90,7 +90,7 @@ int main(int argc, char *argv[])
"Connect Options:\n"
" -c, --connect <name|mac> <uuid>\n"
" Where\n"
- " `name|mac` is a device name or MAC\n"
+ " `name|mac` is a device Name or MAC\n"
" `uuid` is:\n"
" Profile short name: gn, panu or nap\n\n"
"Server Options:\n"
@@ -120,7 +120,7 @@ int main(int argc, char *argv[])
g_option_context_free(context);
if (!dbus_system_connect(&error)) {
- g_printerr("Couldn't connect to dbus system bus: %s\n", error->message);
+ g_printerr("Couldn't connect to DBus system bus: %s\n", error->message);
exit(EXIT_FAILURE);
}
@@ -195,7 +195,6 @@ int main(int argc, char *argv[])
gchar *server_uuid_upper = g_ascii_strup(server_uuid_arg, -1);
NetworkServer *network_server = g_object_new(NETWORK_SERVER_TYPE, "DBusObjectPath", adapter_get_dbus_object_path(adapter), NULL);
-
network_server_register(network_server, server_uuid_arg, server_brige_arg, &error);
exit_if_error(error);
g_print("%s server registered\n", server_uuid_upper);
diff --git a/src/bt-obex.1 b/src/bt-obex.1
new file mode 100644
index 0000000..2fca75a
--- /dev/null
+++ b/src/bt-obex.1
@@ -0,0 +1,191 @@
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.14)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "bt-obex 1"
+.TH bt-obex 1 "2010-08-12" "" "bluez-tools"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+bt\-obex \- a bluetooth OBEX client/server
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+bt-obex [\s-1OPTION\s0...]
+.PP
+Help Options:
+ \-h, \-\-help
+.PP
+Application Options:
+ \-a, \-\-adapter=<name|mac>
+ \-s, \-\-server [<path>]
+ \-p, \-\-opp <name|mac> <file>
+ \-f, \-\-ftp=<name|mac>
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+This utility implemented support of Object Push Profile (\s-1OPP\s0) and File Transfer Profile (\s-1FTP\s0).
+You can send and receive files to/from remote device using this tool.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+\&\fB\-h, \-\-help\fR
+ Show help
+.PP
+\&\fB\-a, \-\-adapter <name|mac>\fR
+ Specify adapter to use by his Name or \s-1MAC\s0 address
+ (if this option does not defined \- default adapter used)
+.PP
+\&\fB\-s, \-\-server [<path>]\fR
+ Register agent at \s-1OBEX\s0 server and set incoming/root directory to
+ `path` or current folder will be used; Agent is used to
+ accept/reject imcoming bluetooth object push requests
+.PP
+\&\fB\-p, \-\-opp <name|mac> <file>\fR
+ Send local file to the specified remove device using object push
+ profile
+.PP
+\&\fB\-f, \-\-ftp <name|mac>\fR
+ Start ftp session with remote device; If session opened
+ successfuly, ftp shell will be opened
+.PP
+.Vb 1
+\& FTP commands:
+\&
+\& help Show help message
+\& exit Close FTP session
+\& cd <folder> Change the current folder of the remote device
+\& mkdir <folder> Create a new folder in the remote device
+\& ls List folder contents
+\& get <src> <dst> Copy the src file (from remote device) to the dst file (on local filesystem)
+\& put <src> <dst> Copy the src file (from local filesystem) to the dst file (on remote device)
+\& cp <src> <dst> Copy a file within the remote device from src file to dst file
+\& mv <src> <dst> Move a file within the remote device from src file to dst file
+\& rm <target> Deletes the specified file/folder
+.Ve
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Alexander Orlenko <zxteam@gmail.com>.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIbt\-adapter\fR\|(1) \fIbt\-agent\fR\|(1) \fIbt\-audio\fR\|(1) \fIbt\-device\fR\|(1) \fIbt\-input\fR\|(1) \fIbt\-monitor\fR\|(1) \fIbt\-network\fR\|(1) \fIbt\-serial\fR\|(1)
diff --git a/src/bt-obex.c b/src/bt-obex.c
index e9f7432..704e1e6 100644
--- a/src/bt-obex.c
+++ b/src/bt-obex.c
@@ -28,10 +28,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
+
#include <readline/readline.h>
#include <readline/history.h>
@@ -99,7 +96,7 @@ static void obexmanager_transfer_started(OBEXManager *manager, const gchar *tran
OBEXTransfer *t = g_object_new(OBEXTRANSFER_TYPE, "DBusObjectPath", transfer_path, NULL);
g_signal_connect(t, "Progress", G_CALLBACK(obextransfer_progress), NULL);
- g_hash_table_insert(server_transfers, transfer_path, t);
+ g_hash_table_insert(server_transfers, g_strdup(transfer_path), t);
}
static void obexmanager_transfer_completed(OBEXManager *manager, const gchar *transfer_path, gboolean success, gpointer data)
@@ -182,12 +179,12 @@ int main(int argc, char *argv[])
g_option_context_free(context);
if (!dbus_system_connect(&error)) {
- g_printerr("Couldn't connect to dbus system bus: %s\n", error->message);
+ g_printerr("Couldn't connect to DBus system bus: %s\n", error->message);
exit(EXIT_FAILURE);
}
if (!dbus_session_connect(&error)) {
- g_printerr("Couldn't connect to dbus session bus: %s\n", error->message);
+ g_printerr("Couldn't connect to DBus session bus: %s\n", error->message);
exit(EXIT_FAILURE);
}
@@ -211,20 +208,9 @@ int main(int argc, char *argv[])
}
/* Check that `path` is valid */
- gchar *root_dir = NULL;
- if (server_path_arg == NULL) {
- root_dir = g_get_current_dir();
- } else {
- struct stat buf;
- if (stat(server_path_arg, &buf) != 0) {
- g_printerr("%s: %s\n", g_get_prgname(), strerror(errno));
- exit(EXIT_FAILURE);
- }
- if (!S_ISDIR(buf.st_mode)) {
- g_printerr("%s: Invalid directory: %s\n", g_get_prgname(), server_path_arg);
- exit(EXIT_FAILURE);
- }
- root_dir = g_strdup(server_path_arg);
+ gchar *root_folder = server_path_arg == NULL ? g_get_current_dir() : g_strdup(server_path_arg);
+ if (!is_dir(root_folder, &error)) {
+ exit_if_error(error);
}
server_transfers = g_hash_table_new(g_str_hash, g_str_equal);
@@ -235,9 +221,9 @@ int main(int argc, char *argv[])
g_signal_connect(manager, "TransferStarted", G_CALLBACK(obexmanager_transfer_started), NULL);
g_signal_connect(manager, "TransferCompleted", G_CALLBACK(obexmanager_transfer_completed), NULL);
- OBEXAgent *agent = g_object_new(OBEXAGENT_TYPE, "RootFolder", root_dir, NULL);
+ OBEXAgent *agent = g_object_new(OBEXAGENT_TYPE, "RootFolder", root_folder, NULL);
- g_free(root_dir);
+ g_free(root_folder);
obexmanager_register_agent(manager, OBEXAGENT_DBUS_PATH, &error);
exit_if_error(error);
@@ -263,7 +249,7 @@ int main(int argc, char *argv[])
g_hash_table_iter_init(&iter, server_transfers);
while (g_hash_table_iter_next(&iter, &key, &value)) {
OBEXTransfer *t = OBEXTRANSFER(value);
- obextransfer_cancel(t, NULL);
+ obextransfer_cancel(t, NULL); // skip errors
g_object_unref(t);
g_hash_table_iter_remove(&iter);
}
@@ -276,26 +262,13 @@ int main(int argc, char *argv[])
opp_device_arg = argv[1];
opp_file_arg = argv[2];
- /* Check that `file` is valid and readable */
- {
- struct stat buf;
- if (stat(opp_file_arg, &buf) != 0) {
- g_printerr("%s: %s\n", g_get_prgname(), strerror(errno));
- exit(EXIT_FAILURE);
- }
- if (!S_ISREG(buf.st_mode)) {
- g_printerr("%s: Invalid file: %s\n", g_get_prgname(), opp_file_arg);
- exit(EXIT_FAILURE);
- }
+ /* Check that `file` is valid */
+ if (!is_file(opp_file_arg, &error)) {
+ exit_if_error(error);
}
+
gchar * files_to_send[] = {NULL, NULL};
- if (!g_path_is_absolute(opp_file_arg)) {
- gchar *current_dir = g_get_current_dir();
- files_to_send[0] = g_build_filename(current_dir, opp_file_arg, NULL);
- g_free(current_dir);
- } else {
- files_to_send[0] = g_strdup(opp_file_arg);
- }
+ files_to_send[0] = g_path_is_absolute(opp_file_arg) ? g_strdup(opp_file_arg) : get_absolute_path(opp_file_arg);
/* Get source address (address of adapter) */
Adapter *adapter = find_adapter(adapter_arg, &error);
@@ -313,14 +286,14 @@ int main(int argc, char *argv[])
/* Build arguments */
GHashTable *device_dict = g_hash_table_new(g_str_hash, g_str_equal);
- GValue source = {0};
- GValue destination = {0};
- g_value_init(&source, G_TYPE_STRING);
- g_value_init(&destination, G_TYPE_STRING);
- g_value_set_string(&source, src_address);
- g_value_set_string(&destination, dst_address);
- g_hash_table_insert(device_dict, "Source", &source);
- g_hash_table_insert(device_dict, "Destination", &destination);
+ GValue src_v = {0};
+ GValue dst_v = {0};
+ g_value_init(&src_v, G_TYPE_STRING);
+ g_value_init(&dst_v, G_TYPE_STRING);
+ g_value_set_string(&src_v, src_address);
+ g_value_set_string(&dst_v, dst_address);
+ g_hash_table_insert(device_dict, "Source", &src_v);
+ g_hash_table_insert(device_dict, "Destination", &dst_v);
mainloop = g_main_loop_new(NULL, FALSE);
@@ -349,8 +322,8 @@ int main(int argc, char *argv[])
g_object_unref(agent);
g_object_unref(client);
- g_value_unset(&source);
- g_value_unset(&destination);
+ g_value_unset(&src_v);
+ g_value_unset(&dst_v);
g_hash_table_unref(device_dict);
g_free(src_address);
@@ -373,18 +346,18 @@ int main(int argc, char *argv[])
/* Build arguments */
GHashTable *device_dict = g_hash_table_new(g_str_hash, g_str_equal);
- GValue source = {0};
- GValue destination = {0};
- GValue target = {0};
- g_value_init(&source, G_TYPE_STRING);
- g_value_init(&destination, G_TYPE_STRING);
- g_value_init(&target, G_TYPE_STRING);
- g_value_set_string(&source, src_address);
- g_value_set_string(&destination, dst_address);
- g_value_set_string(&target, "FTP");
- g_hash_table_insert(device_dict, "Source", &source);
- g_hash_table_insert(device_dict, "Destination", &destination);
- g_hash_table_insert(device_dict, "Target", &target);
+ GValue src_v = {0};
+ GValue dst_v = {0};
+ GValue target_v = {0};
+ g_value_init(&src_v, G_TYPE_STRING);
+ g_value_init(&dst_v, G_TYPE_STRING);
+ g_value_init(&target_v, G_TYPE_STRING);
+ g_value_set_string(&src_v, src_address);
+ g_value_set_string(&dst_v, dst_address);
+ g_value_set_string(&target_v, "FTP");
+ g_hash_table_insert(device_dict, "Source", &src_v);
+ g_hash_table_insert(device_dict, "Destination", &dst_v);
+ g_hash_table_insert(device_dict, "Target", &target_v);
OBEXClient *client = g_object_new(OBEXCLIENT_TYPE, NULL);
OBEXAgent *agent = g_object_new(OBEXAGENT_TYPE, NULL);
@@ -400,7 +373,7 @@ int main(int argc, char *argv[])
while (TRUE) {
gchar *cmd = readline("> ");
- if (cmd == NULL || strlen(cmd) == 0) {
+ if (cmd == NULL) {
continue;
} else {
add_history(cmd);
@@ -413,6 +386,9 @@ int main(int argc, char *argv[])
g_print("%s\n", error->message);
g_error_free(error);
error = NULL;
+
+ g_free(cmd);
+ continue;
}
/* Execute commands */
@@ -450,40 +426,67 @@ int main(int argc, char *argv[])
} else {
for (int i = 0; i < folders->len; i++) {
GHashTable *el = g_ptr_array_index(folders, i);
- g_print("%s\n", g_value_get_string(g_hash_table_lookup(el, "Name")));
+ g_print(
+ "%s\t%llu\t%s\n",
+ g_value_get_string(g_hash_table_lookup(el, "Type")),
+ G_VALUE_HOLDS_UINT64(g_hash_table_lookup(el, "Size")) ?
+ g_value_get_uint64(g_hash_table_lookup(el, "Size")) :
+ 0,
+ g_value_get_string(g_hash_table_lookup(el, "Name"))
+ );
}
- //g_ptr_array_unref(folders);
-
- /*obexclient_remove_session(client, obexclient_file_transfer_get_dbus_object_path(ftp_session), &error);
- exit_if_error(error);
- g_object_unref(ftp_session);
- session_path = obexclient_create_session(client, device_dict, &error);
- exit_if_error(error);
- ftp_session = g_object_new(OBEXCLIENT_FILE_TRANSFER_TYPE, "DBusObjectPath", session_path, NULL);
- g_free(session_path);*/
}
+
+ if (folders) g_ptr_array_unref(folders);
+
+ /*obexclient_remove_session(client, obexclient_file_transfer_get_dbus_object_path(ftp_session), &error);
+ exit_if_error(error);
+ g_object_unref(ftp_session);
+ session_path = obexclient_create_session(client, device_dict, &error);
+ exit_if_error(error);
+ ftp_session = g_object_new(OBEXCLIENT_FILE_TRANSFER_TYPE, "DBusObjectPath", session_path, NULL);
+ g_free(session_path);*/
+
}
} else if (g_strcmp0(f_argv[0], "get") == 0) {
if (f_argc != 3 || strlen(f_argv[1]) == 0 || strlen(f_argv[2]) == 0) {
g_print("invalid arguments\n");
} else {
- obexclient_file_transfer_get_file(ftp_session, f_argv[1], f_argv[2], &error);
- if (error) {
+ gchar *abs_dst_path = get_absolute_path(f_argv[2]);
+ gchar *dir = g_path_get_dirname(abs_dst_path);
+ if (!is_dir(dir, &error)) {
g_print("%s\n", error->message);
g_error_free(error);
error = NULL;
+ } else {
+ obexclient_file_transfer_get_file(ftp_session, abs_dst_path, f_argv[1], &error);
+ if (error) {
+ g_print("%s\n", error->message);
+ g_error_free(error);
+ error = NULL;
+ }
}
+ g_free(dir);
+ g_free(abs_dst_path);
}
} else if (g_strcmp0(f_argv[0], "put") == 0) {
if (f_argc != 3 || strlen(f_argv[1]) == 0 || strlen(f_argv[2]) == 0) {
g_print("invalid arguments\n");
} else {
- obexclient_file_transfer_put_file(ftp_session, f_argv[1], f_argv[2], &error);
- if (error) {
+ gchar *abs_src_path = get_absolute_path(f_argv[1]);
+ if (!is_file(abs_src_path, &error)) {
g_print("%s\n", error->message);
g_error_free(error);
error = NULL;
+ } else {
+ obexclient_file_transfer_put_file(ftp_session, abs_src_path, f_argv[2], &error);
+ if (error) {
+ g_print("%s\n", error->message);
+ g_error_free(error);
+ error = NULL;
+ }
}
+ g_free(abs_src_path);
}
} else if (g_strcmp0(f_argv[0], "cp") == 0) {
if (f_argc != 3 || strlen(f_argv[1]) == 0 || strlen(f_argv[2]) == 0) {
@@ -519,11 +522,22 @@ int main(int argc, char *argv[])
}
}
} else if (g_strcmp0(f_argv[0], "help") == 0) {
-
+ g_print(
+ "help\t\t\tShow this message\n"
+ "exit\t\t\tClose FTP session\n"
+ "cd <folder>\t\tChange the current folder of the remote device\n"
+ "mkdir <folder>\t\tCreate a new folder in the remote device\n"
+ "ls\t\t\tList folder contents\n"
+ "get <src> <dst>\t\tCopy the src file (from remote device) to the dst file (on local filesystem)\n"
+ "put <src> <dst>\t\tCopy the src file (from local filesystem) to the dst file (on remote device)\n"
+ "cp <src> <dst>\t\tCopy a file within the remote device from src file to dst file\n"
+ "mv <src> <dst>\t\tMove a file within the remote device from src file to dst file\n"
+ "rm <target>\t\tDeletes the specified file/folder\n"
+ );
} else if (g_strcmp0(f_argv[0], "exit") == 0 || g_strcmp0(f_argv[0], "quit") == 0) {
obexclient_remove_session(client, obexclient_file_transfer_get_dbus_object_path(ftp_session), &error);
exit_if_error(error);
-
+
g_strfreev(f_argv);
g_free(cmd);
break;
@@ -534,6 +548,18 @@ int main(int argc, char *argv[])
g_strfreev(f_argv);
g_free(cmd);
}
+
+ g_object_unref(agent);
+ g_object_unref(client);
+ g_object_unref(ftp_session);
+
+ g_value_unset(&src_v);
+ g_value_unset(&dst_v);
+ g_value_unset(&target_v);
+ g_hash_table_unref(device_dict);
+
+ g_free(src_address);
+ g_free(dst_address);
}
dbus_disconnect();
diff --git a/src/bt-serial.c b/src/bt-serial.c
index cedde7e..a2abe11 100644
--- a/src/bt-serial.c
+++ b/src/bt-serial.c
@@ -43,9 +43,9 @@ static gchar *disconnect_device_arg = NULL;
static gchar *disconnect_tty_device_arg = NULL;
static GOptionEntry entries[] = {
- {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter name or MAC", "<name|mac>"},
- {"connect", 'c', 0, G_OPTION_ARG_NONE, &connect_arg, "Connect to a serial device", NULL},
- {"disconnect", 'd', 0, G_OPTION_ARG_NONE, &disconnect_arg, "Disconnect from a serial device", NULL},
+ {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or MAC", "<name|mac>"},
+ {"connect", 'c', 0, G_OPTION_ARG_NONE, &connect_arg, "Connect to the serial device", NULL},
+ {"disconnect", 'd', 0, G_OPTION_ARG_NONE, &disconnect_arg, "Disconnect from the serial device", NULL},
{NULL}
};
@@ -72,7 +72,7 @@ int main(int argc, char *argv[])
"Disconnect Options:\n"
" -d, --disconnect <name|mac> <tty_device>\n"
" Where\n"
- " `name|mac` is a device name or MAC\n"
+ " `name|mac` is a device Name or MAC\n"
" `tty_device` is a RFCOMM TTY device that has been connected\n\n"
//"Report bugs to <"PACKAGE_BUGREPORT">."
"Project home page <"PACKAGE_URL">."
@@ -106,7 +106,7 @@ int main(int argc, char *argv[])
}
if (!dbus_system_connect(&error)) {
- g_printerr("Couldn't connect to dbus system bus: %s\n", error->message);
+ g_printerr("Couldn't connect to DBus system bus: %s\n", error->message);
exit(EXIT_FAILURE);
}
diff --git a/src/lib/helpers.c b/src/lib/helpers.c
index d287843..e4da3d1 100644
--- a/src/lib/helpers.c
+++ b/src/lib/helpers.c
@@ -26,6 +26,10 @@
#endif
#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
#include <glib.h>
#include <dbus/dbus-glib.h>
@@ -274,3 +278,60 @@ gboolean intf_supported(const gchar *dbus_service_name, const gchar *dbus_object
return supported;
}
+gboolean is_file(const gchar *filename, GError **error)
+{
+ g_assert(filename != NULL && strlen(filename) > 0);
+
+ struct stat buf;
+ if (stat(filename, &buf) != 0) {
+ if (error) {
+ *error = g_error_new(g_quark_from_string("bluez-tools"), 1, "%s: %s", g_strdup(filename), strerror(errno));
+ }
+ return FALSE;
+ }
+
+ if (!S_ISREG(buf.st_mode)) {
+ if (error) {
+ *error = g_error_new(g_quark_from_string("bluez-tools"), 2, "%s: Invalid file", g_strdup(filename));
+ }
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean is_dir(const gchar *dirname, GError **error)
+{
+ g_assert(dirname != NULL && strlen(dirname) > 0);
+
+ struct stat buf;
+ if (stat(dirname, &buf) != 0) {
+ if (error) {
+ *error = g_error_new(g_quark_from_string("bluez-tools"), 1, "%s: %s", g_strdup(dirname), strerror(errno));
+ }
+ return FALSE;
+ }
+
+ if (!S_ISDIR(buf.st_mode)) {
+ if (error) {
+ *error = g_error_new(g_quark_from_string("bluez-tools"), 2, "%s: Invalid directory", g_strdup(dirname));
+ }
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gchar *get_absolute_path(const gchar *path)
+{
+ if (g_path_is_absolute(path)) {
+ return g_strdup(path);
+ }
+
+ gchar *current_dir = g_get_current_dir();
+ gchar *abs_path = g_build_filename(current_dir, path, NULL);
+ g_free(current_dir);
+
+ return abs_path;
+}
+
diff --git a/src/lib/helpers.h b/src/lib/helpers.h
index 90ca331..a7b8f45 100644
--- a/src/lib/helpers.h
+++ b/src/lib/helpers.h
@@ -57,5 +57,9 @@ inline int xtoi(const gchar *str)
const gchar *uuid2name(const gchar *uuid);
const gchar *name2uuid(const gchar *name);
+gboolean is_file(const gchar *filename, GError **error);
+gboolean is_dir(const gchar *dirname, GError **error);
+gchar *get_absolute_path(const gchar *path);
+
#endif /* __HELPERS_H */
diff --git a/src/lib/obexd/obexagent.c b/src/lib/obexd/obexagent.c
index 78024d3..156f738 100644
--- a/src/lib/obexd/obexagent.c
+++ b/src/lib/obexd/obexagent.c
@@ -158,7 +158,7 @@ static void _obexagent_set_property(GObject *object, guint property_id, const GV
/* Server API */
gboolean obexagent_authorize(OBEXAgent *self, const gchar *transfer, const gchar *bt_address, const gchar *name, const gchar *type, gint length, gint time, gchar **ret, GError **error)
{
- g_assert(self->priv->root_folder != NULL && strlen(self->priv->root_folder));
+ g_assert(self->priv->root_folder != NULL && strlen(self->priv->root_folder) > 0);
*ret = NULL;
g_print("[ObjectPush Request]\n");
@@ -180,11 +180,9 @@ gboolean obexagent_authorize(OBEXAgent *self, const gchar *transfer, const gchar
}
if (g_strcmp0(yn, "y") == 0 || g_strcmp0(yn, "yes") == 0) {
if (!g_path_is_absolute(self->priv->root_folder)) {
- gchar *current_dir = g_get_current_dir();
- gchar *end_path = g_build_filename(self->priv->root_folder, name, NULL);
- *ret = g_build_filename(current_dir, end_path, NULL);
- g_free(current_dir);
- g_free(end_path);
+ gchar *abs_path = get_absolute_path(self->priv->root_folder);
+ *ret = g_build_filename(abs_path, name, NULL);
+ g_free(abs_path);
} else {
*ret = g_build_filename(self->priv->root_folder, name, NULL);
}