mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-12-02 00:24:25 +08:00
obexd: open file during transfer creation
This simplify the API a bit by not having to call obc_transfer_set_file to open the file. In addition to that split transfer creation/registration function so GET/PUT can have more specific logic and different paramenters.
This commit is contained in:
parent
272ef02090
commit
0977754be8
@ -661,6 +661,7 @@ static void session_request_reply(DBusPendingCall *call, gpointer user_data)
|
||||
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||
const char *name;
|
||||
DBusError derr;
|
||||
int err;
|
||||
|
||||
dbus_error_init(&derr);
|
||||
if (dbus_set_error_from_message(&derr, reply)) {
|
||||
@ -685,13 +686,26 @@ static void session_request_reply(DBusPendingCall *call, gpointer user_data)
|
||||
|
||||
DBG("Agent.Request() reply: %s", name);
|
||||
|
||||
if (strlen(name)) {
|
||||
if (obc_transfer_get_operation(transfer) == G_OBEX_OP_PUT)
|
||||
obc_transfer_set_name(transfer, name);
|
||||
else
|
||||
obc_transfer_set_filename(transfer, name);
|
||||
if (strlen(name) == 0)
|
||||
goto done;
|
||||
|
||||
if (obc_transfer_get_operation(transfer) == G_OBEX_OP_PUT) {
|
||||
obc_transfer_set_name(transfer, name);
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = obc_transfer_set_filename(transfer, name);
|
||||
if (err < 0) {
|
||||
GError *gerr = NULL;
|
||||
|
||||
g_set_error(&gerr, OBEX_IO_ERROR, err,
|
||||
"Unable to set filename");
|
||||
session_terminate_transfer(session, transfer, gerr);
|
||||
g_clear_error(&gerr);
|
||||
return;
|
||||
}
|
||||
|
||||
done:
|
||||
if (p->auth_complete)
|
||||
p->auth_complete(session, transfer);
|
||||
|
||||
@ -956,8 +970,8 @@ int obc_session_get(struct obc_session *session, const char *type,
|
||||
else
|
||||
agent = NULL;
|
||||
|
||||
transfer = obc_transfer_register(session->conn, agent, G_OBEX_OP_GET,
|
||||
targetfile, name, type, params);
|
||||
transfer = obc_transfer_get(session->conn, agent, targetfile, name,
|
||||
type, params);
|
||||
if (transfer == NULL) {
|
||||
if (params != NULL) {
|
||||
g_free(params->data);
|
||||
@ -974,24 +988,17 @@ int obc_session_send(struct obc_session *session, const char *filename,
|
||||
{
|
||||
struct obc_transfer *transfer;
|
||||
const char *agent;
|
||||
int err;
|
||||
|
||||
if (session->obex == NULL)
|
||||
return -ENOTCONN;
|
||||
|
||||
agent = obc_agent_get_name(session->agent);
|
||||
|
||||
transfer = obc_transfer_register(session->conn, agent, G_OBEX_OP_PUT,
|
||||
filename, name, NULL, NULL);
|
||||
transfer = obc_transfer_put(session->conn, agent, filename, name,
|
||||
NULL, NULL, 0, NULL);
|
||||
if (transfer == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
err = obc_transfer_set_file(transfer, NULL, 0);
|
||||
if (err < 0) {
|
||||
obc_transfer_unregister(transfer);
|
||||
return err;
|
||||
}
|
||||
|
||||
return session_request(session, transfer, NULL, NULL);
|
||||
}
|
||||
|
||||
@ -1038,24 +1045,17 @@ int obc_session_put(struct obc_session *session, const char *contents,
|
||||
{
|
||||
struct obc_transfer *transfer;
|
||||
const char *agent;
|
||||
int err;
|
||||
|
||||
if (session->obex == NULL)
|
||||
return -ENOTCONN;
|
||||
|
||||
agent = obc_agent_get_name(session->agent);
|
||||
|
||||
transfer = obc_transfer_register(session->conn, agent, G_OBEX_OP_PUT,
|
||||
NULL, name, NULL, NULL);
|
||||
transfer = obc_transfer_put(session->conn, agent, NULL, name, NULL,
|
||||
contents, size, NULL);
|
||||
if (transfer == NULL)
|
||||
return -EIO;
|
||||
|
||||
err = obc_transfer_set_file(transfer, contents, size);
|
||||
if (err < 0) {
|
||||
obc_transfer_unregister(transfer);
|
||||
return err;
|
||||
}
|
||||
|
||||
return session_request(session, transfer, NULL, NULL);
|
||||
}
|
||||
|
||||
|
@ -219,7 +219,7 @@ static void obc_transfer_free(struct obc_transfer *transfer)
|
||||
g_free(transfer);
|
||||
}
|
||||
|
||||
struct obc_transfer *obc_transfer_register(DBusConnection *conn,
|
||||
static struct obc_transfer *obc_transfer_register(DBusConnection *conn,
|
||||
const char *agent,
|
||||
guint8 op,
|
||||
const char *filename,
|
||||
@ -247,23 +247,131 @@ struct obc_transfer *obc_transfer_register(DBusConnection *conn,
|
||||
TRANSFER_BASEPATH, counter++);
|
||||
|
||||
transfer->conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
|
||||
if (transfer->conn == NULL) {
|
||||
obc_transfer_free(transfer);
|
||||
return NULL;
|
||||
}
|
||||
if (transfer->conn == NULL)
|
||||
goto fail;
|
||||
|
||||
if (g_dbus_register_interface(transfer->conn, transfer->path,
|
||||
TRANSFER_INTERFACE,
|
||||
obc_transfer_methods, NULL, NULL,
|
||||
transfer, NULL) == FALSE) {
|
||||
obc_transfer_free(transfer);
|
||||
return NULL;
|
||||
}
|
||||
transfer, NULL) == FALSE)
|
||||
goto fail;
|
||||
|
||||
done:
|
||||
DBG("%p registered %s", transfer, transfer->path);
|
||||
|
||||
return transfer;
|
||||
|
||||
fail:
|
||||
obc_transfer_free(transfer);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int transfer_open(struct obc_transfer *transfer, int flags, mode_t mode)
|
||||
{
|
||||
GError *err = NULL;
|
||||
int fd;
|
||||
|
||||
if (transfer->filename != NULL) {
|
||||
fd = open(transfer->filename, flags, mode);
|
||||
if (fd < 0) {
|
||||
error("open(): %s(%d)", strerror(errno), errno);
|
||||
return -errno;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
fd = g_file_open_tmp("obex-clientXXXXXX", &transfer->filename, &err);
|
||||
if (fd < 0) {
|
||||
error("g_file_open_tmp(): %s", err->message);
|
||||
g_error_free(err);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
remove(transfer->filename);
|
||||
|
||||
done:
|
||||
transfer->fd = fd;
|
||||
return fd;
|
||||
}
|
||||
|
||||
struct obc_transfer *obc_transfer_get(DBusConnection *conn,
|
||||
const char *agent,
|
||||
const char *filename,
|
||||
const char *name,
|
||||
const char *type,
|
||||
struct obc_transfer_params *params)
|
||||
{
|
||||
struct obc_transfer *transfer;
|
||||
|
||||
transfer = obc_transfer_register(conn, agent, G_OBEX_OP_GET, filename,
|
||||
name, type, params);
|
||||
if (transfer == NULL)
|
||||
return NULL;
|
||||
|
||||
if (transfer_open(transfer, O_WRONLY | O_CREAT | O_TRUNC, 0600) < 0) {
|
||||
obc_transfer_free(transfer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return transfer;
|
||||
}
|
||||
|
||||
struct obc_transfer *obc_transfer_put(DBusConnection *conn,
|
||||
const char *agent,
|
||||
const char *filename,
|
||||
const char *name,
|
||||
const char *type,
|
||||
const char *contents,
|
||||
size_t size,
|
||||
struct obc_transfer_params *params)
|
||||
{
|
||||
struct obc_transfer *transfer;
|
||||
struct stat st;
|
||||
int perr;
|
||||
|
||||
transfer = obc_transfer_register(conn, agent, G_OBEX_OP_PUT, filename,
|
||||
name, type, params);
|
||||
if (transfer == NULL)
|
||||
return NULL;
|
||||
|
||||
if (contents != NULL) {
|
||||
ssize_t w;
|
||||
|
||||
perr = transfer_open(transfer, O_RDWR, 0);
|
||||
if (perr < 0)
|
||||
goto fail;
|
||||
|
||||
w = write(transfer->fd, contents, size);
|
||||
if (w < 0) {
|
||||
error("write(): %s(%d)", strerror(errno), errno);
|
||||
perr = -errno;
|
||||
goto fail;
|
||||
} else if ((size_t) w != size) {
|
||||
error("Unable to write all contents to file");
|
||||
perr = -EFAULT;
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
perr = transfer_open(transfer, O_RDONLY, 0);
|
||||
if (perr < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
perr = fstat(transfer->fd, &st);
|
||||
if (perr < 0) {
|
||||
error("fstat(): %s(%d)", strerror(errno), errno);
|
||||
perr = -errno;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
transfer->size = st.st_size;
|
||||
|
||||
return transfer;
|
||||
|
||||
fail:
|
||||
obc_transfer_free(transfer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void obc_transfer_unregister(struct obc_transfer *transfer)
|
||||
@ -416,38 +524,9 @@ gboolean obc_transfer_set_callback(struct obc_transfer *transfer,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int transfer_open(struct obc_transfer *transfer, int flags, mode_t mode)
|
||||
{
|
||||
GError *err = NULL;
|
||||
int fd;
|
||||
|
||||
if (transfer->filename != NULL) {
|
||||
fd = open(transfer->filename, flags, mode);
|
||||
if (fd < 0) {
|
||||
error("open(): %s(%d)", strerror(errno), errno);
|
||||
return -errno;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
fd = g_file_open_tmp("obex-clientXXXXXX", &transfer->filename, &err);
|
||||
if (fd < 0) {
|
||||
error("g_file_open_tmp(): %s", err->message);
|
||||
g_error_free(err);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
remove(transfer->filename);
|
||||
|
||||
done:
|
||||
transfer->fd = fd;
|
||||
return fd;
|
||||
}
|
||||
|
||||
static gboolean transfer_start_get(struct obc_transfer *transfer, GError **err)
|
||||
{
|
||||
GObexPacket *req;
|
||||
int perr;
|
||||
|
||||
if (transfer->xfer > 0) {
|
||||
g_set_error(err, OBC_TRANSFER_ERROR, -EALREADY,
|
||||
@ -455,10 +534,6 @@ static gboolean transfer_start_get(struct obc_transfer *transfer, GError **err)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
perr = transfer_open(transfer, O_WRONLY | O_CREAT, 0600);
|
||||
if (perr < 0)
|
||||
return perr;
|
||||
|
||||
req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, G_OBEX_HDR_INVALID);
|
||||
|
||||
if (transfer->name != NULL)
|
||||
@ -592,11 +667,21 @@ void obc_transfer_set_name(struct obc_transfer *transfer, const char *name)
|
||||
transfer->name = g_strdup(name);
|
||||
}
|
||||
|
||||
void obc_transfer_set_filename(struct obc_transfer *transfer,
|
||||
int obc_transfer_set_filename(struct obc_transfer *transfer,
|
||||
const char *filename)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = rename(transfer->filename, filename);
|
||||
if (err < 0) {
|
||||
error("rename(): %s (%d)", strerror(errno), errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
g_free(transfer->filename);
|
||||
transfer->filename = g_strdup(filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *obc_transfer_get_path(struct obc_transfer *transfer)
|
||||
@ -608,42 +693,3 @@ gint64 obc_transfer_get_size(struct obc_transfer *transfer)
|
||||
{
|
||||
return transfer->size;
|
||||
}
|
||||
|
||||
int obc_transfer_set_file(struct obc_transfer *transfer, const char *contents,
|
||||
size_t size)
|
||||
{
|
||||
int err;
|
||||
struct stat st;
|
||||
|
||||
err = transfer_open(transfer, O_RDONLY, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (contents != NULL) {
|
||||
ssize_t w = write(transfer->fd, contents, size);
|
||||
if (w < 0) {
|
||||
error("write(): %s(%d)", strerror(errno), errno);
|
||||
err = -errno;
|
||||
goto fail;
|
||||
} else if ((size_t) w != size) {
|
||||
error("Unable to write all contents to file");
|
||||
err = -EFAULT;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
err = fstat(transfer->fd, &st);
|
||||
if (err < 0) {
|
||||
error("fstat(): %s(%d)", strerror(errno), errno);
|
||||
err = -errno;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
transfer->size = st.st_size;
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
close(transfer->fd);
|
||||
transfer->fd = -1;
|
||||
return err;
|
||||
}
|
||||
|
@ -32,13 +32,20 @@ typedef void (*transfer_callback_t) (struct obc_transfer *transfer,
|
||||
gint64 transferred, GError *err,
|
||||
void *user_data);
|
||||
|
||||
struct obc_transfer *obc_transfer_register(DBusConnection *conn,
|
||||
struct obc_transfer *obc_transfer_get(DBusConnection *conn,
|
||||
const char *agent,
|
||||
guint8 op,
|
||||
const char *filename,
|
||||
const char *name,
|
||||
const char *type,
|
||||
struct obc_transfer_params *params);
|
||||
struct obc_transfer *obc_transfer_put(DBusConnection *conn,
|
||||
const char *agent,
|
||||
const char *filename,
|
||||
const char *name,
|
||||
const char *type,
|
||||
const char *contents,
|
||||
size_t size,
|
||||
struct obc_transfer_params *params);
|
||||
|
||||
void obc_transfer_unregister(struct obc_transfer *transfer);
|
||||
|
||||
@ -56,9 +63,7 @@ int obc_transfer_get_contents(struct obc_transfer *transfer, char **contents,
|
||||
size_t *size);
|
||||
|
||||
void obc_transfer_set_name(struct obc_transfer *transfer, const char *name);
|
||||
void obc_transfer_set_filename(struct obc_transfer *transfer,
|
||||
int obc_transfer_set_filename(struct obc_transfer *transfer,
|
||||
const char *filename);
|
||||
const char *obc_transfer_get_path(struct obc_transfer *transfer);
|
||||
gint64 obc_transfer_get_size(struct obc_transfer *transfer);
|
||||
int obc_transfer_set_file(struct obc_transfer *transfer, const char *contents,
|
||||
size_t size);
|
||||
|
Loading…
Reference in New Issue
Block a user