From 4ff2b6f9a77809785bb9f0a579d3fb2102823cd4 Mon Sep 17 00:00:00 2001 From: Vinicius Costa Gomes Date: Thu, 10 Jul 2008 19:01:45 -0300 Subject: [PATCH] obexd: Support for dynamic capability file. Now a script could be passed as a capability file and its output is sent as a capability object, just prepend the file name with '!' (some escaping may be needed). --- obexd/src/bluetooth.c | 9 ++++++--- obexd/src/bluetooth.h | 3 ++- obexd/src/ftp.c | 37 +++++++++++++++++++++++++++++++--- obexd/src/main.c | 47 ++++++++++++++++++++++++++----------------- obexd/src/obex.h | 1 + 5 files changed, 71 insertions(+), 26 deletions(-) diff --git a/obexd/src/bluetooth.c b/obexd/src/bluetooth.c index bc7836af3..8f3b40e71 100644 --- a/obexd/src/bluetooth.c +++ b/obexd/src/bluetooth.c @@ -192,7 +192,8 @@ static void server_destroyed(gpointer user_data) } static gint server_register(guint16 service, const gchar *name, guint8 channel, - const gchar *folder, gboolean secure, gboolean auto_accept) + const gchar *folder, gboolean secure, + gboolean auto_accept, const gchar *capability) { struct sockaddr_rc laddr; GIOChannel *io; @@ -253,6 +254,7 @@ static gint server_register(guint16 service, const gchar *name, guint8 channel, server->service = service; server->folder = g_strdup(folder); server->auto_accept = auto_accept; + server->capability = g_strdup(capability); io = g_io_channel_unix_new(sk); g_io_channel_set_close_on_unref(io, TRUE); @@ -273,7 +275,8 @@ failed: } gint bluetooth_init(guint service, const gchar *name, const gchar *folder, - guint8 channel, gboolean secure, gboolean auto_accept) + guint8 channel, gboolean secure, gboolean auto_accept, + const gchar *capability) { if (!session) { session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); @@ -285,7 +288,7 @@ gint bluetooth_init(guint service, const gchar *name, const gchar *folder, } return server_register(service, name, channel, - folder, secure, auto_accept); + folder, secure, auto_accept, capability); } static void unregister_record(gpointer rec_handle, gpointer user_data) diff --git a/obexd/src/bluetooth.h b/obexd/src/bluetooth.h index dec0b14a9..bc50c1951 100644 --- a/obexd/src/bluetooth.h +++ b/obexd/src/bluetooth.h @@ -28,5 +28,6 @@ #endif gint bluetooth_init(guint service, const gchar *name, const gchar *folder, - guint8 channel, gboolean secure, gboolean auto_accept); + guint8 channel, gboolean secure, gboolean auto_accept, + const gchar *capability); void bluetooth_exit(void); diff --git a/obexd/src/ftp.c b/obexd/src/ftp.c index e27954dec..969c2881f 100644 --- a/obexd/src/ftp.c +++ b/obexd/src/ftp.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -51,8 +52,6 @@ #define LST_TYPE "x-obex/folder-listing" #define CAP_TYPE "x-obex/capability" -#define CAP_FILE CONFIGDIR "/capability.xml" - #define EOL_CHARS "\n" #define FL_VERSION "" EOL_CHARS @@ -173,13 +172,45 @@ static gboolean folder_listing(struct obex_session *os, guint32 *size) return TRUE; } +static gboolean get_capability(struct obex_session *os, guint32 *size) +{ + GError *gerr = NULL; + gchar *buf; + gint exit; + gboolean ret; + + debug("%s - cap: %s", __func__, os->server->capability); + + if (os->server->capability[0] != '!') { + return os_prepare_get(os, os->server->capability, size); + } + + ret = g_spawn_command_line_sync(os->server->capability + 1, + &buf, NULL, &exit, &gerr); + if (ret == FALSE) { + error("g_spawn_command_line_sync: %s", gerr->message); + g_error_free(gerr); + return FALSE; + } + + if (WEXITSTATUS(exit) != EXIT_SUCCESS) { + g_free(buf); + return FALSE; + } + + os->buf = (guint8 *) buf; + *size = strlen(buf); + + return TRUE; +} + static gboolean get_by_type(struct obex_session *os, gchar *type, guint32 *size) { if (type == NULL) return FALSE; if (g_str_equal(type, CAP_TYPE)) - return os_prepare_get(os, CAP_FILE, size); + return get_capability(os, size); if (g_str_equal(type, LST_TYPE)) return folder_listing(os, size); diff --git a/obexd/src/main.c b/obexd/src/main.c index 5bfd84f42..17bf2f65d 100644 --- a/obexd/src/main.c +++ b/obexd/src/main.c @@ -50,21 +50,25 @@ #define DEFAULT_ROOT_PATH "/tmp" +#define DEFAULT_CAP_FILE CONFIGDIR "/capability.xml" + static GMainLoop *main_loop = NULL; static int server_start(int service, const char *root_path, - gboolean auto_accept) + gboolean auto_accept, const gchar *capability) { /* FIXME: Necessary check enabled transports(Bluetooth/USB) */ switch (service) { case OBEX_OPUSH: bluetooth_init(OBEX_OPUSH, "OBEX OPUSH server", - root_path, OPUSH_CHANNEL, FALSE, auto_accept); + root_path, OPUSH_CHANNEL, FALSE, + auto_accept, capability); break; case OBEX_FTP: bluetooth_init(OBEX_FTP, "OBEX FTP server", - root_path, FTP_CHANNEL, TRUE, auto_accept); + root_path, FTP_CHANNEL, TRUE, + auto_accept, capability); break; default: return -EINVAL; @@ -93,24 +97,26 @@ static void usage(void) "\n"); printf("Options:\n" - "\t-n, --nodaemon Don't fork daemon to background\n" - "\t-d, --debug Enable output of debug information\n" - "\t-r, --root Specify root folder location\n" - "\t-a, --auto-accept Automatically accept push requests\n" - "\t-h, --help Display help\n"); + "\t-n, --nodaemon Don't fork daemon to background\n" + "\t-d, --debug Enable output of debug information\n" + "\t-r, --root Specify root folder location\n" + "\t-c, --capability Specify the capability file.\n" + "\t-a, --auto-accept Automatically accept push requests\n" + "\t-h, --help Display help\n"); printf("Servers:\n" - "\t-o, --opp Enable OPP server\n" - "\t-f, --ftp Enable FTP server\n" + "\t-o, --opp Enable OPP server\n" + "\t-f, --ftp Enable FTP server\n" "\n"); } static struct option options[] = { - { "nodaemon", 0, 0, 'n' }, - { "debug", 0, 0, 'd' }, - { "ftp", 0, 0, 'f' }, - { "opp", 0, 0, 'o' }, - { "help", 0, 0, 'h' }, - { "root", 1, 0, 'r' }, + { "nodaemon", 0, 0, 'n' }, + { "debug", 0, 0, 'd' }, + { "ftp", 0, 0, 'f' }, + { "opp", 0, 0, 'o' }, + { "help", 0, 0, 'h' }, + { "root", 1, 0, 'r' }, + { "capability", 1, 0, 'c' }, { "auto-accept", 0, 0, 'a' }, { } }; @@ -123,8 +129,9 @@ int main(int argc, char *argv[]) int log_option = LOG_NDELAY | LOG_PID; int opt, detach = 1, debug = 0, opush = 0, ftp = 0, auto_accept = 0; const char *root_path = DEFAULT_ROOT_PATH; + const char *capability = DEFAULT_CAP_FILE; - while ((opt = getopt_long(argc, argv, "+ndhofr:a", options, NULL)) != EOF) { + while ((opt = getopt_long(argc, argv, "+ndhofr:c:a", options, NULL)) != EOF) { switch(opt) { case 'n': detach = 0; @@ -141,6 +148,8 @@ int main(int argc, char *argv[]) case 'r': root_path = optarg; break; + case 'c': + capability = optarg; case 'a': auto_accept = 1; break; @@ -191,10 +200,10 @@ int main(int argc, char *argv[]) } if (opush) - server_start(OBEX_OPUSH, root_path, auto_accept); + server_start(OBEX_OPUSH, root_path, auto_accept, capability); if (ftp) - server_start(OBEX_FTP, root_path, auto_accept); + server_start(OBEX_FTP, root_path, auto_accept, capability); if (!manager_init(conn)) goto fail; diff --git a/obexd/src/obex.h b/obexd/src/obex.h index 132ae1bac..006d314f6 100644 --- a/obexd/src/obex.h +++ b/obexd/src/obex.h @@ -46,6 +46,7 @@ struct server { guint16 service; gboolean auto_accept; gchar *folder; + gchar *capability; }; struct obex_session { -- 2.47.3