Diff between 556447e3b854ebf569bbb0d808806fe55e4f901a and 4ce2d8b85b90fb8f80b97954b989e0dbcf3cda43

Changed Files

File Additions Deletions Status
obexd/plugins/filesystem.c +5 -7 modified
obexd/plugins/ftp.c +66 -32 modified
obexd/plugins/opp.c +18 -12 modified
obexd/plugins/pbap.c +34 -17 modified
obexd/src/obex-priv.h +1 -1 modified
obexd/src/obex.c +7 -30 modified
obexd/src/obex.h +1 -2 modified

Full Patch

diff --git a/obexd/plugins/filesystem.c b/obexd/plugins/filesystem.c
index 621bbac..c110c80 100644
--- a/obexd/plugins/filesystem.c
+++ b/obexd/plugins/filesystem.c
@@ -306,12 +306,11 @@ fail:
 	return NULL;
 }
 
-static gpointer folder_open(const char *name, int oflag, mode_t mode,
+static gpointer folder_open(const char *folder, int oflag, mode_t mode,
 		size_t *size, struct obex_session *os, int *err)
 {
 	struct stat fstat, dstat;
 	struct dirent *ep;
-	const gchar *folder;
 	GString *object;
 	DIR *dp;
 	gboolean root, pcsuite, symlinks;
@@ -324,10 +323,9 @@ static gpointer folder_open(const char *name, int oflag, mode_t mode,
 
 	object = g_string_append(object, FL_BODY_BEGIN);
 
-	folder = obex_get_folder(os);
-	root = g_str_equal(name, folder);
+	root = g_str_equal(folder, obex_get_root_folder(os));
 
-	dp = opendir(name);
+	dp = opendir(folder);
 	if (dp == NULL) {
 		if (err)
 			*err = -ENOENT;
@@ -336,10 +334,10 @@ static gpointer folder_open(const char *name, int oflag, mode_t mode,
 
 	symlinks = obex_get_symlinks(os);
 	if (root && symlinks)
-		ret = stat(name, &dstat);
+		ret = stat(folder, &dstat);
 	else {
 		object = g_string_append(object, FL_PARENT_FOLDER_ELEMENT);
-		ret = lstat(name, &dstat);
+		ret = lstat(folder, &dstat);
 	}
 
 	if (ret < 0) {
diff --git a/obexd/plugins/ftp.c b/obexd/plugins/ftp.c
index 1b4b272..cbb3db2 100644
--- a/obexd/plugins/ftp.c
+++ b/obexd/plugins/ftp.c
@@ -144,9 +144,21 @@ static const guint8 FTP_TARGET[TARGET_SIZE] = {
 static const guint8 PCSUITE_WHO[PCSUITE_WHO_SIZE] = {
 			'P','C',' ','S','u','i','t','e' };
 
-static gint get_by_type(struct obex_session *os, const gchar *type)
+struct ftp_session {
+	struct obex_session *os;
+	gchar *folder;
+};
+
+static void set_folder(struct ftp_session *ftp, const char *new_folder)
+{
+	g_free(ftp->folder);
+
+	ftp->folder = new_folder ? g_strdup(new_folder) : NULL;
+}
+
+static gint get_by_type(struct ftp_session *ftp, const gchar *type)
 {
-	const char *folder = obex_get_folder(os);
+	struct obex_session *os = ftp->os;
 	const char *capability = obex_get_capability_path(os);
 
 	if (type == NULL)
@@ -156,18 +168,18 @@ static gint get_by_type(struct obex_session *os, const gchar *type)
 		return obex_stream_start(os, capability);
 
 	if (g_str_equal(type, LST_TYPE))
-		return obex_stream_start(os, folder);
+		return obex_stream_start(os, ftp->folder);
 
 	return -ENOENT;
 }
 
-static gint ftp_prepare_get(struct obex_session *os, gchar *file)
+static gint ftp_prepare_get(struct ftp_session *ftp, gchar *file)
 {
+	struct obex_session *os = ftp->os;
 	const char *root_folder = obex_get_root_folder(os);
-	const char *folder = obex_get_folder(os);
 	gboolean root;
 
-	root = g_str_equal(root_folder, folder);
+	root = g_str_equal(root_folder, ftp->folder);
 
 	if (!root || !obex_get_symlinks(os)) {
 		struct stat dstat;
@@ -188,36 +200,45 @@ static gint ftp_prepare_get(struct obex_session *os, gchar *file)
 
 static gpointer ftp_connect(struct obex_session *os, int *err)
 {
+	struct ftp_session *ftp;
+	const char *root_folder;
+
+	root_folder = obex_get_root_folder(os);
+
 	manager_register_session(os);
 
+	ftp = g_new0(struct ftp_session, 1);
+	set_folder(ftp, root_folder);
+	ftp->os = os;
+
 	if (err)
 		*err = 0;
 
-	return NULL;
+	return ftp;
 }
 
 static int ftp_get(struct obex_session *os, obex_object_t *obj,
 		gpointer user_data)
 {
-	const char *folder = obex_get_folder(os);
+	struct ftp_session *ftp = user_data;
 	const char *type = obex_get_type(os);
 	const char *name = obex_get_name(os);
 	gint err;
 	gchar *path;
 
-	if (folder == NULL) {
+	if (ftp->folder == NULL) {
 		err = -ENOENT;
 		goto fail;
 	}
 
-	err = get_by_type(os, type);
+	err = get_by_type(ftp, type);
 	if (err < 0) {
 		if (!name)
 			goto fail;
 
-		path = g_build_filename(folder, name, NULL);
+		path = g_build_filename(ftp->folder, name, NULL);
 
-		err = ftp_prepare_get(os, path);
+		err = ftp_prepare_get(ftp, path);
 
 		g_free(path);
 
@@ -231,19 +252,17 @@ fail:
 	return err;
 }
 
-static gint ftp_delete(struct obex_session *os)
+static gint ftp_delete(struct ftp_session *ftp, const char *name)
 {
-	const char *name = obex_get_name(os);
-	const char *folder = obex_get_folder(os);
 	gchar *path;
 	int ret = 0;
 
-	if (!(folder && name))
+	if (!(ftp->folder && name))
 		return -EINVAL;
 
-	path = g_build_filename(folder, name, NULL);
+	path = g_build_filename(ftp->folder, name, NULL);
 
-	if (obex_remove(os, path) < 0)
+	if (obex_remove(ftp->os, path) < 0)
 		ret = -errno;
 
 	g_free(path);
@@ -253,27 +272,37 @@ static gint ftp_delete(struct obex_session *os)
 
 static gint ftp_chkput(struct obex_session *os, gpointer user_data)
 {
+	struct ftp_session *ftp = user_data;
+	const gchar *name = obex_get_name(os);
+	gchar *path;
+	int ret;
 
 	if (obex_get_size(os) == OBJECT_SIZE_DELETE)
 		return 0;
 
-	return obex_prepare_put(os);
+	path = g_build_filename(ftp->folder, name, NULL);
+
+	ret = obex_prepare_put(os, path);
+
+	g_free(path);
+
+	return ret;
 }
 
 static int ftp_put(struct obex_session *os, gpointer user_data)
 {
-	const char *folder = obex_get_folder(os);
+	struct ftp_session *ftp = user_data;
 	const char *name = obex_get_name(os);
 	ssize_t size = obex_get_size(os);
 
-	if (folder == NULL)
+	if (ftp->folder == NULL)
 		return -EPERM;
 
 	if (name == NULL)
 		return -EBADR;
 
 	if (size == OBJECT_SIZE_DELETE)
-		return ftp_delete(os);
+		return ftp_delete(ftp, name);
 
 	return 0;
 }
@@ -281,7 +310,8 @@ static int ftp_put(struct obex_session *os, gpointer user_data)
 static int ftp_setpath(struct obex_session *os, obex_object_t *obj,
 		gpointer user_data)
 {
-	const gchar *root_folder, *current_folder, *name;
+	struct ftp_session *ftp = user_data;
+	const gchar *root_folder, *name;
 	guint8 *nonhdr;
 	gchar *fullname;
 	struct stat dstat;
@@ -295,8 +325,7 @@ static int ftp_setpath(struct obex_session *os, obex_object_t *obj,
 
 	name = obex_get_name(os);
 	root_folder = obex_get_root_folder(os);
-	current_folder = obex_get_folder(os);
-	root = g_str_equal(root_folder, current_folder);
+	root = g_str_equal(root_folder, ftp->folder);
 
 	/* Check flag "Backup" */
 	if ((nonhdr[0] & 0x01) == 0x01) {
@@ -305,11 +334,11 @@ static int ftp_setpath(struct obex_session *os, obex_object_t *obj,
 		if (root)
 			return -EPERM;
 
-		fullname = g_path_get_dirname(current_folder);
-		obex_set_folder(os, fullname);
+		fullname = g_path_get_dirname(ftp->folder);
+		set_folder(ftp, fullname);
 		g_free(fullname);
 
-		debug("Set to parent path: %s", current_folder);
+		debug("Set to parent path: %s", ftp->folder);
 
 		return 0;
 	}
@@ -321,7 +350,7 @@ static int ftp_setpath(struct obex_session *os, obex_object_t *obj,
 
 	if (strlen(name) == 0) {
 		debug("Set to root");
-		obex_set_folder(os, root_folder);
+		set_folder(ftp, root_folder);
 		return 0;
 	}
 
@@ -331,7 +360,7 @@ static int ftp_setpath(struct obex_session *os, obex_object_t *obj,
 		return -EPERM;
 	}
 
-	fullname = g_build_filename(current_folder, name, NULL);
+	fullname = g_build_filename(ftp->folder, name, NULL);
 
 	debug("Fullname: %s", fullname);
 
@@ -352,7 +381,7 @@ static int ftp_setpath(struct obex_session *os, obex_object_t *obj,
 
 	if (S_ISDIR(dstat.st_mode) && (dstat.st_mode & S_IRUSR) &&
 						(dstat.st_mode & S_IXUSR)) {
-		obex_set_folder(os, fullname);
+		set_folder(ftp, fullname);
 		goto done;
 	}
 
@@ -370,7 +399,7 @@ not_found:
 		goto done;
 	}
 
-	obex_set_folder(os, fullname);
+	set_folder(ftp, fullname);
 
 done:
 	g_free(fullname);
@@ -379,7 +408,12 @@ done:
 
 static void ftp_disconnect(struct obex_session *os, gpointer user_data)
 {
+	struct ftp_session *ftp = user_data;
+
 	manager_unregister_session(os);
+
+	g_free(ftp->folder);
+	g_free(ftp);
 }
 
 struct obex_service_driver pcsuite = {
diff --git a/obexd/plugins/opp.c b/obexd/plugins/opp.c
index 9c1d959..70882c2 100644
--- a/obexd/plugins/opp.c
+++ b/obexd/plugins/opp.c
@@ -110,7 +110,8 @@ static void opp_progress(struct obex_session *os, gpointer user_data)
 
 static gint opp_chkput(struct obex_session *os, gpointer user_data)
 {
-	gchar *new_folder, *new_name;
+	gchar *folder, *name;
+	gchar *path;
 	gint32 time;
 	gint ret;
 
@@ -121,29 +122,34 @@ static gint opp_chkput(struct obex_session *os, gpointer user_data)
 		goto skip_auth;
 
 	time = 0;
-	ret = manager_request_authorization(os, time, &new_folder, &new_name);
+	ret = manager_request_authorization(os, time, &folder, &name);
 	if (ret < 0)
 		return -EPERM;
 
-	if (new_folder) {
-		obex_set_folder(os, new_folder);
-		g_free(new_folder);
-	}
+	if (folder == NULL)
+		folder = g_strdup(obex_get_root_folder(os));
 
-	if (new_name) {
-		obex_set_name(os, new_name);
-		g_free(new_name);
-	}
+	if (name == NULL)
+		name = g_strdup(obex_get_name(os));
 
 skip_auth:
+	path = g_build_filename(folder, name, NULL);
+
 	manager_emit_transfer_started(os);
-	return obex_prepare_put(os);
+
+	ret = obex_prepare_put(os, path);
+
+	g_free(path);
+	g_free(folder);
+	g_free(name);
+
+	return ret;
 }
 
 static int opp_put(struct obex_session *os, gpointer user_data)
 {
 	const char *name = obex_get_name(os);
-	const char *folder = obex_get_folder(os);
+	const char *folder = obex_get_root_folder(os);
 
 	if (folder == NULL)
 		return -EPERM;
diff --git a/obexd/plugins/pbap.c b/obexd/plugins/pbap.c
index a37b738..7429f23 100644
--- a/obexd/plugins/pbap.c
+++ b/obexd/plugins/pbap.c
@@ -132,33 +132,49 @@ struct apparam_hdr {
 	uint8_t		val[0];
 } __attribute__ ((packed));
 
-struct obex_session;
-
 struct phonebook_query {
 	const char *type;
 	GString *buffer;
 	struct obex_session *os;
 };
 
+struct pbap_session {
+	struct obex_session *os;
+	gchar *folder;
+};
+
 static const guint8 PBAP_TARGET[TARGET_SIZE] = {
 			0x79, 0x61, 0x35, 0xF0,  0xF0, 0xC5, 0x11, 0xD8,
 			0x09, 0x66, 0x08, 0x00,  0x20, 0x0C, 0x9A, 0x66  };
 
+static void set_folder(struct pbap_session *pbap, const char *new_folder)
+{
+	g_free(pbap->folder);
+
+	pbap->folder = new_folder ? g_strdup(new_folder) : NULL;
+}
+
 static gpointer pbap_connect(struct obex_session *os, int *err)
 {
+	struct pbap_session *pbap;
+
 	manager_register_session(os);
 
+	pbap = g_new0(struct pbap_session, 1);
+	pbap->folder = g_strdup("/");
+	pbap->os = os;
+
 	if (*err)
 		err = 0;
 
-	return NULL;
+	return pbap;
 }
 
 static int pbap_get(struct obex_session *os, obex_object_t *obj,
 		gpointer user_data)
 {
+	struct pbap_session *pbap = user_data;
 	const gchar *type = obex_get_type(os);
-	const gchar *folder = obex_get_folder(os);
 	const gchar *name = obex_get_name(os);
 	gchar *path;
 	gint ret;
@@ -173,14 +189,14 @@ static int pbap_get(struct obex_session *os, obex_object_t *obj,
 		/* Always relative */
 		if (!name || strlen(name) == 0)
 			/* Current folder */
-			path = g_strdup(folder);
+			path = g_strdup(pbap->folder);
 		else
 			/* Current folder + relative path */
-			path = g_build_filename(folder, name, NULL);
+			path = g_build_filename(pbap->folder, name, NULL);
 
 	else if (strcmp(type, VCARDENTRY_TYPE) == 0)
 		/* Always relative */
-		path = g_build_filename(folder, name, NULL);
+		path = g_build_filename(pbap->folder, name, NULL);
 	else
 		return -EBADR;
 
@@ -194,7 +210,8 @@ static int pbap_get(struct obex_session *os, obex_object_t *obj,
 static int pbap_setpath(struct obex_session *os, obex_object_t *obj,
 		gpointer user_data)
 {
-	const gchar *current_folder, *name;
+	struct pbap_session *pbap = user_data;
+	const gchar *name;
 	guint8 *nonhdr;
 	gchar *fullname;
 	int ret;
@@ -204,23 +221,18 @@ static int pbap_setpath(struct obex_session *os, obex_object_t *obj,
 		return -EBADMSG;
 	}
 
-	current_folder = obex_get_folder(os);
 	name = obex_get_name(os);
 
-	ret = phonebook_set_folder(current_folder, name, nonhdr[0]);
+	ret = phonebook_set_folder(pbap->folder, name, nonhdr[0]);
 	if (ret < 0)
 		return ret;
 
-	/*
-	 * TODO: current folder should not be stored in the
-	 * "core", it is a service specific attribute.
-	 */
-	if (!current_folder)
+	if (!pbap->folder)
 		fullname = g_strdup(name);
 	else
-		fullname = g_build_filename(current_folder, name, NULL);
+		fullname = g_build_filename(pbap->folder, name, NULL);
 
-	obex_set_folder(os, fullname);
+	set_folder(pbap, fullname);
 
 	g_free(fullname);
 
@@ -230,7 +242,12 @@ static int pbap_setpath(struct obex_session *os, obex_object_t *obj,
 static void pbap_disconnect(struct obex_session *os,
 		gpointer user_data)
 {
+	struct pbap_session *pbap = user_data;
+
 	manager_unregister_session(os);
+
+	g_free(pbap->folder);
+	g_free(pbap);
 }
 
 static gint pbap_chkput(struct obex_session *os,
diff --git a/obexd/src/obex-priv.h b/obexd/src/obex-priv.h
index 28deef2..932f275 100644
--- a/obexd/src/obex-priv.h
+++ b/obexd/src/obex-priv.h
@@ -45,8 +45,8 @@ struct obex_session {
 	guint8		cmd;
 	gchar		*name;
 	gchar		*type;
+	const gchar	*path;
 	time_t		time;
-	gchar		*current_folder;
 	guint8		*buf;
 	gint32		offset;
 	gint32		size;
diff --git a/obexd/src/obex.c b/obexd/src/obex.c
index ab701e2..af87270 100644
--- a/obexd/src/obex.c
+++ b/obexd/src/obex.c
@@ -110,12 +110,8 @@ static void os_reset_session(struct obex_session *os)
 		os->driver->close(os->object);
 		os->object = NULL;
 		os->obj = NULL;
-		if (os->aborted && os->cmd == OBEX_CMD_PUT && os->current_folder) {
-			gchar *path;
-			path = g_build_filename(os->current_folder, os->name, NULL);
-			os->driver->remove(path);
-			g_free(path);
-		}
+		if (os->aborted && os->cmd == OBEX_CMD_PUT && os->path)
+			os->driver->remove(os->path);
 	}
 
 	if (os->name) {
@@ -154,9 +150,6 @@ static void obex_session_free(struct obex_session *os)
 
 	os_reset_session(os);
 
-	if (os->current_folder)
-		g_free(os->current_folder);
-
 	if (os->io)
 		g_io_channel_unref(os->io);
 
@@ -546,23 +539,20 @@ add_header:
 	return len;
 }
 
-gint obex_prepare_put(struct obex_session *os)
+gint obex_prepare_put(struct obex_session *os, const gchar *filename)
 {
-	gchar *path;
 	gint len;
 	int err;
 
-	path = g_build_filename(os->current_folder, os->name, NULL);
-	os->object = os->driver->open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600,
+	os->object = os->driver->open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600,
 					os->size != OBJECT_SIZE_UNKNOWN ?
 					(size_t *) &os->size : NULL, os, &err);
 	if (os->object == NULL) {
-		error("open(%s): %s (%d)", path, strerror(-err), -err);
-		g_free(path);
+		error("open(%s): %s (%d)", filename, strerror(-err), -err);
 		return -EPERM;
 	}
 
-	g_free(path);
+	os->path = filename;
 
 	if (!os->buf) {
 		debug("PUT request checked, no buffered data");
@@ -575,7 +565,7 @@ gint obex_prepare_put(struct obex_session *os)
 
 		w = os->driver->write(os->object, os->buf + len, os->offset - len);
 		if (w < 0) {
-			error("write(%s): %s (%d)", path, strerror(-w), -w);
+			error("write(%s): %s (%d)", filename, strerror(-w), -w);
 			if (w == -EINTR)
 				continue;
 			else
@@ -1067,7 +1057,6 @@ gint obex_session_start(GIOChannel *io, struct server *server)
 
 	os->service = obex_service_driver_find(server->drivers, NULL, 0,
 						NULL, 0);
-	os->current_folder = g_strdup(server->folder);
 	os->server = server;
 	os->rx_mtu = server->rx_mtu ? server->rx_mtu : DEFAULT_RX_MTU;
 	os->tx_mtu = server->tx_mtu ? server->tx_mtu : DEFAULT_TX_MTU;
@@ -1139,18 +1128,6 @@ const char *obex_get_type(struct obex_session *os)
 	return os->type;
 }
 
-const char *obex_get_folder(struct obex_session *os)
-{
-	return os->current_folder;
-}
-
-void obex_set_folder(struct obex_session *os, const gchar *folder)
-{
-	g_free(os->current_folder);
-
-	os->current_folder = (folder ? g_strdup(folder) : NULL);
-}
-
 const char *obex_get_root_folder(struct obex_session *os)
 {
 	return os->server->folder;
diff --git a/obexd/src/obex.h b/obexd/src/obex.h
index ad8a2fc..5c6ca92 100644
--- a/obexd/src/obex.h
+++ b/obexd/src/obex.h
@@ -43,12 +43,11 @@ struct obex_session;
 void obex_connect_cb(GIOChannel *io, GError *err, gpointer user_data);
 
 int obex_stream_start(struct obex_session *os, const gchar *filename);
-gint obex_prepare_put(struct obex_session *os);
+gint obex_prepare_put(struct obex_session *os, const  gchar *filename);
 const char *obex_get_name(struct obex_session *os);
 void obex_set_name(struct obex_session *os, const gchar *name);
 ssize_t obex_get_size(struct obex_session *os);
 const char *obex_get_type(struct obex_session *os);
-const char *obex_get_folder(struct obex_session *os);
 void obex_set_folder(struct obex_session *os, const char *folder);
 const char *obex_get_root_folder(struct obex_session *os);
 guint16 obex_get_service(struct obex_session *os);