diff options
-rw-r--r-- | src/ftp.c | 41 | ||||
-rw-r--r-- | src/obex.c | 26 | ||||
-rw-r--r-- | src/obex.h | 3 | ||||
-rw-r--r-- | src/opp.c | 2 |
4 files changed, 64 insertions, 8 deletions
@@ -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) @@ -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) { @@ -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); @@ -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) |