Diff between c869ca28b82757500bb5c86d1f58cdcd9fe5ea52 and 14d2bde30d43c7d677f75530360231ea64f634e6

Changed Files

File Additions Deletions Status
tools/obex-client-tool.c +54 -10 modified
tools/obex-server-tool.c +87 -4 modified

Full Patch

diff --git a/tools/obex-client-tool.c b/tools/obex-client-tool.c
index a621ec2..f83edfa 100644
--- a/tools/obex-client-tool.c
+++ b/tools/obex-client-tool.c
@@ -115,18 +115,18 @@ static void cmd_connect(int argc, char **argv)
 	g_obex_connect(obex, conn_complete, NULL, NULL, G_OBEX_HDR_INVALID);
 }
 
-struct put_data {
+struct transfer_data {
 	int fd;
 };
 
-static void put_complete(GObex *obex, GError *err, gpointer user_data)
+static void transfer_complete(GObex *obex, GError *err, gpointer user_data)
 {
-	struct put_data *data = user_data;
+	struct transfer_data *data = user_data;
 
 	if (err != NULL)
-		g_printerr("put failed: %s\n", err->message);
+		g_printerr("failed: %s\n", err->message);
 	else
-		g_print("put succeeded\n");
+		g_print("transfer succeeded\n");
 
 	close(data->fd);
 	g_free(data);
@@ -134,14 +134,14 @@ static void put_complete(GObex *obex, GError *err, gpointer user_data)
 
 static gssize put_data_cb(void *buf, gsize len, gpointer user_data)
 {
-	struct put_data *data = user_data;
+	struct transfer_data *data = user_data;
 
 	return read(data->fd, buf, len);
 }
 
 static void cmd_put(int argc, char **argv)
 {
-	struct put_data *data;
+	struct transfer_data *data;
 	GError *err = NULL;
 	int fd;
 
@@ -152,14 +152,57 @@ static void cmd_put(int argc, char **argv)
 
 	fd = open(argv[1], O_RDONLY | O_NOCTTY, 0);
 	if (fd < 0) {
-		g_printerr("open: %s", strerror(errno));
+		g_printerr("open: %s\n", strerror(errno));
+		return;
+	}
+
+	data = g_new0(struct transfer_data, 1);
+	data->fd = fd;
+
+	g_obex_put_req(obex, put_data_cb, transfer_complete, data, &err,
+						G_OBEX_HDR_NAME, argv[1],
+						G_OBEX_HDR_INVALID);
+	if (err != NULL) {
+		g_printerr("put failed: %s\n", err->message);
+		g_error_free(err);
+		close(data->fd);
+		g_free(data);
+	}
+}
+
+static gboolean get_data_cb(const void *buf, gsize len, gpointer user_data)
+{
+	struct transfer_data *data = user_data;
+
+	if (write(data->fd, buf, len) < 0) {
+		g_printerr("write: %s\n", strerror(errno));
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static void cmd_get(int argc, char **argv)
+{
+	struct transfer_data *data;
+	GError *err = NULL;
+	int fd;
+
+	if (argc < 2) {
+		g_printerr("Filename required\n");
+		return;
+	}
+
+	fd = open(argv[1], O_WRONLY | O_CREAT | O_NOCTTY, 0);
+	if (fd < 0) {
+		g_printerr("open: %s\n", strerror(errno));
 		return;
 	}
 
-	data = g_new0(struct put_data, 1);
+	data = g_new0(struct transfer_data, 1);
 	data->fd = fd;
 
-	g_obex_put_req(obex, put_data_cb, put_complete, data, &err,
+	g_obex_get_req(obex, get_data_cb, transfer_complete, data, &err,
 						G_OBEX_HDR_NAME, argv[1],
 						G_OBEX_HDR_INVALID);
 	if (err != NULL) {
@@ -188,6 +231,7 @@ static struct {
 	{ "quit",	cmd_exit,	"",		"Exit application" },
 	{ "connect",	cmd_connect,	"[target]",	"OBEX Connect" },
 	{ "put",	cmd_put,	"<file>",	"Send a file" },
+	{ "get",	cmd_get,	"<file>",	"Receive a file" },
 	{ NULL },
 };
 
diff --git a/tools/obex-server-tool.c b/tools/obex-server-tool.c
index 39ec18a..fdf078a 100644
--- a/tools/obex-server-tool.c
+++ b/tools/obex-server-tool.c
@@ -21,6 +21,7 @@
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <fcntl.h>
 #include <sys/un.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -62,17 +63,34 @@ static void disconn_func(GObex *obex, GError *err, gpointer user_data)
 	g_obex_unref(obex);
 }
 
-static void put_complete(GObex *obex, GError *err, gpointer user_data)
+struct transfer_data {
+	int fd;
+};
+
+static void transfer_complete(GObex *obex, GError *err, gpointer user_data)
 {
+	struct transfer_data *data = user_data;
+
 	if (err != NULL)
-		g_printerr("put failed: %s\n", err->message);
+		g_printerr("transfer failed: %s\n", err->message);
 	else
-		g_print("put succeeded\n");
+		g_print("transfer succeeded\n");
+
+	close(data->fd);
+	g_free(data);
 }
 
 static gboolean recv_data(const void *buf, gsize len, gpointer user_data)
 {
+	struct transfer_data *data = user_data;
+
 	g_print("received %zu bytes of data\n", len);
+
+	if (write(data->fd, buf, len) < 0) {
+		g_printerr("write: %s\n", strerror(errno));
+		return FALSE;
+	}
+
 	return TRUE;
 }
 
@@ -81,6 +99,7 @@ static void handle_put(GObex *obex, GObexPacket *req, gpointer user_data)
 	GError *err = NULL;
 	GObexHeader *hdr;
 	const char *type, *name;
+	struct transfer_data *data;
 	gsize type_len;
 
 	hdr = g_obex_packet_find_header(req, G_OBEX_HDR_TYPE);
@@ -103,11 +122,74 @@ static void handle_put(GObex *obex, GObexPacket *req, gpointer user_data)
 	g_print("put type \"%s\" name \"%s\"\n", type ? type : "",
 							name ? name : "");
 
-	g_obex_put_rsp(obex, req, recv_data, put_complete, NULL, &err,
+	data = g_new0(struct transfer_data, 1);
+
+	data->fd = open(name, O_WRONLY | O_CREAT | O_NOCTTY, 0);
+	if (data->fd < 0) {
+		g_printerr("open(%s): %s\n", name, strerror(errno));
+		g_free(data);
+		return;
+	}
+
+	g_obex_put_rsp(obex, req, recv_data, transfer_complete, data, &err,
+							G_OBEX_HDR_INVALID);
+	if (err != NULL) {
+		g_printerr("Unable to send response: %s\n", err->message);
+		g_error_free(err);
+		g_free(data);
+	}
+}
+
+static gssize send_data(void *buf, gsize len, gpointer user_data)
+{
+	struct transfer_data *data = user_data;
+
+	return read(data->fd, buf, len);
+}
+
+static void handle_get(GObex *obex, GObexPacket *req, gpointer user_data)
+{
+	GError *err = NULL;
+	struct transfer_data *data;
+	const char *type, *name;
+	GObexHeader *hdr;
+	gsize type_len;
+
+	hdr = g_obex_packet_find_header(req, G_OBEX_HDR_TYPE);
+	if (hdr != NULL) {
+		g_obex_header_get_bytes(hdr, (const guint8 **) &type,
+								&type_len);
+		if (type[type_len - 1] != '\0') {
+			g_printerr("non-nul terminated type header\n");
+			type = NULL;
+		}
+	} else
+		type = NULL;
+
+	hdr = g_obex_packet_find_header(req, G_OBEX_HDR_NAME);
+	if (hdr != NULL)
+		g_obex_header_get_unicode(hdr, &name);
+	else
+		name = NULL;
+
+	g_print("get type \"%s\" name \"%s\"\n", type ? type : "",
+							name ? name : "");
+
+	data = g_new0(struct transfer_data, 1);
+
+	data->fd = open(name, O_RDONLY | O_NOCTTY, 0);
+	if (data->fd < 0) {
+		g_printerr("open(%s): %s", name, strerror(errno));
+		g_free(data);
+		return;
+	}
+
+	g_obex_get_rsp(obex, send_data, transfer_complete, data, &err,
 							G_OBEX_HDR_INVALID);
 	if (err != NULL) {
 		g_printerr("Unable to send response: %s\n", err->message);
 		g_error_free(err);
+		g_free(data);
 	}
 }
 
@@ -166,6 +248,7 @@ static gboolean unix_accept(GIOChannel *chan, GIOCondition cond, gpointer data)
 	g_io_channel_unref(io);
 	g_obex_set_disconnect_function(obex, disconn_func, NULL);
 	g_obex_add_request_function(obex, G_OBEX_OP_PUT, handle_put, NULL);
+	g_obex_add_request_function(obex, G_OBEX_OP_GET, handle_get, NULL);
 	g_obex_add_request_function(obex, G_OBEX_OP_CONNECT, handle_connect,
 									NULL);
 	clients = g_slist_append(clients, obex);;