Diff between 30e3b9e9f2aa55fbe7fce6565a18552dce8ab984 and 810e80df6f8c884369642b94ba3666208017d1a4

Changed Files

File Additions Deletions Status
obexd/src/ftp.c +38 -3 modified
obexd/src/obex.c +22 -4 modified
obexd/src/obex.h +3 -0 modified
obexd/src/opp.c +1 -1 modified

Full Patch

diff --git a/obexd/src/ftp.c b/obexd/src/ftp.c
index 95e8c2b..f656e53 100644
--- a/obexd/src/ftp.c
+++ b/obexd/src/ftp.c
@@ -241,6 +241,24 @@ fail:
 	return;
 }
 
+static gint ftp_delete(struct obex_session *os)
+{
+	gchar *path;
+	int ret = 0;
+
+	if (!(os->current_folder && os->name))
+		return -EINVAL;
+
+	path = g_build_filename(os->current_folder, os->name, NULL);
+
+	if (remove(path) < 0)
+		ret = -errno;
+
+	g_free(path);
+
+	return ret;
+}
+
 gint ftp_chkput(obex_t *obex, obex_object_t *obj)
 {
 	struct obex_session *os;
@@ -249,8 +267,8 @@ gint ftp_chkput(obex_t *obex, obex_object_t *obj)
 	if (os == NULL)
 		return -EINVAL;
 
-	if (os->size < 0)
-		return -EINVAL;
+	if (os->size == OBJECT_SIZE_DELETE)
+		return 0;
 
 	return os_prepare_put(os);
 }
@@ -258,6 +276,7 @@ gint ftp_chkput(obex_t *obex, obex_object_t *obj)
 void ftp_put(obex_t *obex, obex_object_t *obj)
 {
 	struct obex_session *os;
+	int ret = 0;
 
 	os = OBEX_GetUserData(obex);
 	if (os == NULL)
@@ -273,7 +292,23 @@ void ftp_put(obex_t *obex, obex_object_t *obj)
 		return;
 	}
 
-	OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
+	if (os->size == OBJECT_SIZE_DELETE)
+		ret = ftp_delete(os);
+
+	if (ret == 0) {
+		OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
+		return;
+	}
+
+	switch (ret) {
+	case -ENOTEMPTY:
+		OBEX_ObjectSetRsp(obj, OBEX_RSP_PRECONDITION_FAILED,
+					OBEX_RSP_PRECONDITION_FAILED);
+		break;
+	default:
+		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
+		break;
+	}
 }
 
 void ftp_setpath(obex_t *obex, obex_object_t *obj)
diff --git a/obexd/src/obex.c b/obexd/src/obex.c
index b9ddf31..25e29e9 100644
--- a/obexd/src/obex.c
+++ b/obexd/src/obex.c
@@ -106,7 +106,7 @@ static void os_reset_session(struct obex_session *os, gboolean aborted)
 		os->buf = NULL;
 	}
 	os->offset = 0;
-	os->size = -1;
+	os->size = OBJECT_SIZE_DELETE;
 }
 
 static void obex_session_free(struct obex_session *os)
@@ -568,6 +568,7 @@ static gboolean check_put(obex_t *obex, obex_object_t *obj)
 	guint hlen;
 	guint8 hi;
 	guint64 free;
+	int ret;
 
 	os = OBEX_GetUserData(obex);
 
@@ -620,7 +621,8 @@ static gboolean check_put(obex_t *obex, obex_object_t *obj)
 			break;
 
 		case OBEX_HDR_BODY:
-			os->size = 0;
+			if (os->size < 0)
+				os->size = OBJECT_SIZE_UNKNOWN;
 			break;
 
 		case OBEX_HDR_LENGTH:
@@ -646,11 +648,27 @@ static gboolean check_put(obex_t *obex, obex_object_t *obj)
 	if (!os->cmds->chkput)
 		goto done;
 
-	if (os->cmds->chkput(obex, obj) < 0) {
+	ret = os->cmds->chkput(obex, obj);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		OBEX_ObjectSetRsp(obj, OBEX_RSP_BAD_REQUEST,
+				OBEX_RSP_BAD_REQUEST);
+		return FALSE;
+	case -EPERM:
 		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
 		return FALSE;
+	default:
+		debug("Unhandled chkput error: %d", ret);
+		OBEX_ObjectSetRsp(obj, OBEX_RSP_INTERNAL_SERVER_ERROR,
+				OBEX_RSP_INTERNAL_SERVER_ERROR);
+		return FALSE;
 	}
 
+	if (os->size == OBJECT_SIZE_DELETE)
+		goto done;
+
 	if (fstatvfs(os->fd, &buf) < 0) {
 		int err = errno;
 		error("fstatvfs(): %s(%d)", strerror(err), err);
@@ -871,7 +889,7 @@ gint obex_session_start(gint fd, struct server *server)
 	os->rx_mtu = RX_MTU;
 	os->tx_mtu = TX_MTU;
 	os->fd = -1;
-	os->size = -1;
+	os->size = OBJECT_SIZE_DELETE;
 
 	obex = OBEX_Init(OBEX_TRANS_FD, obex_event, 0);
 	if (!obex) {
diff --git a/obexd/src/obex.h b/obexd/src/obex.h
index ceef235..132ae1b 100644
--- a/obexd/src/obex.h
+++ b/obexd/src/obex.h
@@ -32,6 +32,9 @@
 #define OBEX_OPUSH	0x00
 #define OBEX_FTP	0x01
 
+#define OBJECT_SIZE_UNKNOWN -1
+#define OBJECT_SIZE_DELETE -2
+
 struct obex_commands {
 	void (*get) (obex_t *obex, obex_object_t *obj);
 	gint (*chkput) (obex_t *obex, obex_object_t *obj);
diff --git a/obexd/src/opp.c b/obexd/src/opp.c
index 851e432..390b074 100644
--- a/obexd/src/opp.c
+++ b/obexd/src/opp.c
@@ -59,7 +59,7 @@ gint opp_chkput(obex_t *obex, obex_object_t *obj)
 	if (os == NULL)
 		return -EINVAL;
 
-	if (!os->size)
+	if (os->size == OBJECT_SIZE_DELETE)
 		return -EINVAL;
 
 	if (os->server->auto_accept)