From 702fa15c0d474fbcb9a4d5a5ae8ce0f6be48385e Mon Sep 17 00:00:00 2001 From: Alexander Orlenko Date: Thu, 12 Aug 2010 23:59:32 +1100 Subject: Added man for bt-obex Some bugfixes and improvements --- src/bt-adapter.c | 4 +- src/bt-agent.c | 4 +- src/bt-audio.c | 8 +- src/bt-device.c | 10 +-- src/bt-input.c | 8 +- src/bt-monitor.c | 14 ++-- src/bt-network.c | 11 ++- src/bt-obex.1 | 191 ++++++++++++++++++++++++++++++++++++++++++++++ src/bt-obex.c | 188 +++++++++++++++++++++++++-------------------- src/bt-serial.c | 10 +-- src/lib/helpers.c | 61 +++++++++++++++ src/lib/helpers.h | 4 + src/lib/obexd/obexagent.c | 10 +-- 13 files changed, 401 insertions(+), 122 deletions(-) create mode 100644 src/bt-obex.1 (limited to 'src') 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", ""}, + {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or 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", ""}, + {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or 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", ""}, - {"connect", 'c', 0, G_OPTION_ARG_STRING, &connect_arg, "Connect to an audio device", ""}, - {"disconnect", 'd', 0, G_OPTION_ARG_STRING, &disconnect_arg, "Disconnect from an audio device", ""}, + {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or MAC", ""}, + {"connect", 'c', 0, G_OPTION_ARG_STRING, &connect_arg, "Connect to the audio device", ""}, + {"disconnect", 'd', 0, G_OPTION_ARG_STRING, &disconnect_arg, "Disconnect from the audio device", ""}, {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", ""}, + {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or 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", ""}, + {"connect", 'c', 0, G_OPTION_ARG_STRING, &connect_arg, "Connect to the remote device", ""}, {"remove", 'r', 0, G_OPTION_ARG_STRING, &remove_arg, "Remove device", ""}, {"info", 'i', 0, G_OPTION_ARG_STRING, &info_arg, "Get info about device", ""}, {"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 \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", ""}, - {"connect", 'c', 0, G_OPTION_ARG_STRING, &connect_arg, "Connect to an input device", ""}, - {"disconnect", 'd', 0, G_OPTION_ARG_STRING, &disconnect_arg, "Disconnect from an input device", ""}, + {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or MAC", ""}, + {"connect", 'c', 0, G_OPTION_ARG_STRING, &connect_arg, "Connect to the input device", ""}, + {"disconnect", 'd', 0, G_OPTION_ARG_STRING, &disconnect_arg, "Disconnect from the input device", ""}, {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", ""}, + {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or 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", ""}, - {"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", ""}, + {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter Name or 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", ""}, {"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 \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= + \-s, \-\-server [] + \-p, \-\-opp + \-f, \-\-ftp= +.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 \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 []\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 \fR + Send local file to the specified remove device using object push + profile +.PP +\&\fB\-f, \-\-ftp \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 Change the current folder of the remote device +\& mkdir Create a new folder in the remote device +\& ls List folder contents +\& get Copy the src file (from remote device) to the dst file (on local filesystem) +\& put Copy the src file (from local filesystem) to the dst file (on remote device) +\& cp Copy a file within the remote device from src file to dst file +\& mv Move a file within the remote device from src file to dst file +\& rm Deletes the specified file/folder +.Ve +.SH "AUTHOR" +.IX Header "AUTHOR" +Alexander Orlenko . +.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 #include #include -#include -#include -#include -#include + #include #include @@ -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 \t\tChange the current folder of the remote device\n" + "mkdir \t\tCreate a new folder in the remote device\n" + "ls\t\t\tList folder contents\n" + "get \t\tCopy the src file (from remote device) to the dst file (on local filesystem)\n" + "put \t\tCopy the src file (from local filesystem) to the dst file (on remote device)\n" + "cp \t\tCopy a file within the remote device from src file to dst file\n" + "mv \t\tMove a file within the remote device from src file to dst file\n" + "rm \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", ""}, - {"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", ""}, + {"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 \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 +#include +#include +#include +#include #include #include @@ -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); } -- cgit v1.2.1