summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajeev Kuthiravattath <ext-rajeev.1.kuthiravattath@nokia.com>2010-06-04 16:13:55 +0300
committerLuiz Augusto von Dentz <luiz.dentz-von@nokia.com>2010-06-04 16:13:55 +0300
commitd94e58050664b0ea8b922331237d9a0fe8cd3f56 (patch)
treedec215ce3ac5cb2263283d2866f6cd3514e09fb7
parent6f56a4355585eb29535782f977ba545cc41dd382 (diff)
downloadobexd-d94e58050664b0ea8b922331237d9a0fe8cd3f56.tar.gz
Add nokia backup plugin
-rw-r--r--Makefile.am5
-rw-r--r--configure.ac7
-rw-r--r--plugins/nokia-backup.c295
3 files changed, 307 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 0e5fda8..88e23bd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -40,6 +40,11 @@ endif
builtin_modules += filesystem
builtin_sources += plugins/filesystem.c plugins/filesystem.h
+if NOKIA_BACKUP
+builtin_modules += backup
+builtin_sources += plugins/nokia-backup.c
+endif
+
builtin_modules += opp
builtin_sources += plugins/opp.c
diff --git a/configure.ac b/configure.ac
index 13a771c..fa37b5c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -151,6 +151,13 @@ AC_ARG_ENABLE(usb, AC_HELP_STRING([--enable-usb],
AM_CONDITIONAL(USB, test "${enable_usb}" = "yes" &&
test "${enable_server}" != "no")
+AC_ARG_ENABLE(nokia_backup, AC_HELP_STRING([--enable-nokia-backup],
+ [enable nokia-backup plugin]), [
+ enable_nokia_backup=${enableval}
+])
+AM_CONDITIONAL(NOKIA_BACKUP, test "${enable_nokia_backup}" = "yes" &&
+ test "${enable_server}" != "no")
+
AC_ARG_ENABLE(client, AC_HELP_STRING([--disable-client],
[disable compilation of OBEX client]), [
enable_client=${enableval}
diff --git a/plugins/nokia-backup.c b/plugins/nokia-backup.c
new file mode 100644
index 0000000..10d1a4a
--- /dev/null
+++ b/plugins/nokia-backup.c
@@ -0,0 +1,295 @@
+/*
+ *
+ * OBEX Server
+ *
+ * Copyright (C) 2009-2010 Intel Corporation
+ * Copyright (C) 2007-2010 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <fcntl.h>
+#include <wait.h>
+
+#include <glib.h>
+#include "gdbus.h"
+
+
+#include <openobex/obex.h>
+#include <openobex/obex_const.h>
+
+#include "plugin.h"
+#include "logging.h"
+#include "obex.h"
+#include "mimetype.h"
+#include "service.h"
+
+#define BACKUP_BUS_NAME "com.nokia.backup.plugin"
+#define BACKUP_PATH "/com/nokia/backup"
+#define BACKUP_PLUGIN_INTERFACE "com.nokia.backup.plugin"
+#define BACKUP_DBUS_TIMEOUT (1000 * 60 * 15)
+
+static const uint8_t FTP_TARGET[TARGET_SIZE] = {
+ 0xF9, 0xEC, 0x7B, 0xC4, 0x95, 0x3C, 0x11, 0xD2,
+ 0x98, 0x4E, 0x52, 0x54, 0x00, 0xDC, 0x9E, 0x09 };
+
+struct backup_object{
+ gchar *cmd;
+ int fd;
+ int oflag;
+ int error_code;
+ mode_t mode;
+ DBusPendingCall *pending_call;
+ DBusConnection *conn;
+};
+
+static void on_backup_dbus_notify(DBusPendingCall *pending_call,
+ void *user_data)
+{
+ struct backup_object *obj = user_data;
+ DBusMessage *reply;
+ const char *filename;
+ int error_code;
+
+ debug("backup: Notification received for pending call - %s", obj->cmd);
+
+ reply = dbus_pending_call_steal_reply(pending_call);
+
+ if (reply && dbus_message_get_args(reply, NULL, DBUS_TYPE_INT32,
+ &error_code, DBUS_TYPE_STRING,
+ &filename, DBUS_TYPE_INVALID)) {
+
+ obj->error_code = error_code;
+
+ if (filename) {
+ debug("backup: Notification - file path = %s,"
+ "error_code = %d", filename,
+ error_code);
+ if (error_code == 0)
+ obj->fd = open(filename,obj->oflag,obj->mode);
+ }
+
+ } else
+ debug("backup: Notification timed out or connection got closed");
+
+ if (reply)
+ dbus_message_unref(reply);
+
+ dbus_pending_call_unref(pending_call);
+ obj->pending_call = NULL;
+ dbus_connection_unref(obj->conn);
+ obj->conn = NULL;
+
+ if (obj->fd >= 0) {
+ debug("backup: File opened, setting io flags, cmd = %s",
+ obj->cmd);
+ if (obj->oflag == O_RDONLY)
+ obex_object_set_io_flags(user_data, G_IO_IN, 0);
+ else
+ obex_object_set_io_flags(user_data, G_IO_OUT, 0);
+ } else {
+ debug("backup: File open error, setting io error, cmd = %s",
+ obj->cmd);
+ obex_object_set_io_flags(user_data, G_IO_ERR, -EPERM);
+ }
+}
+
+static gboolean send_backup_dbus_message(const char *oper,
+ struct backup_object *obj,
+ size_t *size)
+{
+ DBusConnection *conn;
+ DBusMessage *msg;
+ DBusPendingCall *pending_call;
+ gboolean ret = FALSE;
+ dbus_uint32_t file_size;
+
+ file_size = size ? *size : 0;
+
+ conn = g_dbus_setup_bus(DBUS_BUS_SESSION, NULL, NULL);
+
+ if (conn == NULL)
+ return FALSE;
+
+ msg = dbus_message_new_method_call(BACKUP_BUS_NAME, BACKUP_PATH,
+ BACKUP_PLUGIN_INTERFACE,
+ "request");
+ if (msg == NULL) {
+ dbus_connection_unref(conn);
+ return FALSE;
+ }
+
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &oper,
+ DBUS_TYPE_STRING, &obj->cmd,
+ DBUS_TYPE_INT32, &file_size,
+ DBUS_TYPE_INVALID);
+
+ ret = dbus_connection_send_with_reply(conn, msg, &pending_call,
+ BACKUP_DBUS_TIMEOUT);
+
+ dbus_message_unref(msg);
+
+ if (ret && (strcmp(oper, "open") == 0)) {
+ obj->conn = conn;
+ obj->pending_call = pending_call;
+ ret = dbus_pending_call_set_notify(pending_call,
+ on_backup_dbus_notify,
+ obj, NULL);
+ } else {
+ dbus_pending_call_unref(pending_call);
+ dbus_connection_unref(conn);
+ }
+
+ return ret;
+}
+
+static void *backup_open(const char *name, int oflag, mode_t mode,
+ void *context, size_t *size, int *err)
+{
+ struct backup_object *obj = g_new0(struct backup_object, 1);
+
+ debug("backup: open(), cmd = %s", name);
+
+ obj->cmd = g_path_get_basename(name);
+ obj->oflag = oflag;
+ obj->mode = mode;
+ obj->fd = -1;
+ obj->pending_call = NULL;
+ obj->conn = NULL;
+ obj->error_code = 0;
+
+ if (send_backup_dbus_message("open", obj, size) == FALSE) {
+ g_free(obj);
+ obj = NULL;
+ }
+
+ if (err)
+ *err = 0;
+
+ return obj;
+}
+
+static int backup_close(void *object)
+{
+ struct backup_object *obj = object;
+ size_t size = 0;
+
+ debug("backup: close(), cmd = %s", obj->cmd);
+
+ if (obj->fd != -1)
+ close(obj->fd);
+
+ if (obj->pending_call) {
+ dbus_pending_call_cancel(obj->pending_call);
+ dbus_pending_call_unref(obj->pending_call);
+ dbus_connection_unref(obj->conn);
+ }
+
+ send_backup_dbus_message("close", obj, &size);
+
+ g_free(obj->cmd);
+ g_free(obj);
+
+ return 0;
+}
+
+static ssize_t backup_read(void *object, void *buf, size_t count, uint8_t *hi)
+{
+ struct backup_object *obj = object;
+ ssize_t ret = 0;
+
+ *hi = OBEX_HDR_BODY;
+
+ if (obj->pending_call) {
+ debug("backup: read(), cmd = %s, IN WAITING STAGE", obj->cmd);
+ return -EAGAIN;
+ }
+
+ if (obj->fd != -1) {
+ debug("backup: read(), cmd = %s, READING DATA", obj->cmd);
+ ret = read(obj->fd, buf, count);
+ if (ret < 0)
+ ret = -errno;
+ } else {
+ debug("backup: read(), cmd = %s, PERMANENT FAILURE", obj->cmd);
+ ret = obj->error_code?(-obj->error_code):(-ENOENT);
+ }
+
+ return ret;
+}
+
+static ssize_t backup_write(void *object, const void *buf, size_t count)
+{
+ struct backup_object *obj = object;
+ ssize_t ret = 0;
+
+ if (obj->pending_call) {
+ debug("backup: write(), cmd = %s, IN WAITING STAGE", obj->cmd);
+ return -EAGAIN;
+ }
+
+ if (obj->fd != -1) {
+ ret = write(obj->fd, buf, count);
+
+ debug("backup: write(), cmd = %s, WRITTING", obj->cmd);
+
+ if (ret < 0) {
+ debug("backup: write() error, cmd = %s", obj->cmd);
+ ret = -errno;
+ }
+ } else {
+ debug("backup: write() error, cmd = %s", obj->cmd);
+ ret = obj->error_code ? -obj->error_code : -ENOENT;
+ }
+
+ return ret;
+}
+
+static struct obex_mime_type_driver backup = {
+ .target = FTP_TARGET,
+ .mimetype = "application/vnd.nokia-backup",
+ .open = backup_open,
+ .close = backup_close,
+ .read = backup_read,
+ .write = backup_write,
+};
+
+static int backup_init(void)
+{
+ return obex_mime_type_driver_register(&backup);
+}
+
+static void backup_exit(void)
+{
+ obex_mime_type_driver_unregister(&backup);
+}
+
+OBEX_PLUGIN_DEFINE(backup, backup_init, backup_exit)