static int opp_chkput(struct obex_session *os, void *user_data) { char *folder, *name, *path; int32_t time; const char *t; int err; if (obex_get_size(os) == OBJECT_SIZE_DELETE) return -ENOSYS; t = obex_get_name(os); if (t != NULL && !is_filename(t)) return -EBADR; if (obex_option_auto_accept()) { folder = g_strdup(obex_option_root_folder()); name = g_strdup(obex_get_name(os)); goto skip_auth; } time = 0; err = manager_request_authorization(user_data, time, &folder, &name); if (err < 0) return -EPERM; if (folder == NULL) folder = g_strdup(obex_option_root_folder()); if (name == NULL) name = g_strdup(obex_get_name(os)); skip_auth: if (name == NULL || strlen(name) == 0) { err = -EBADR; goto failed; } if (g_strcmp0(name, obex_get_name(os)) != 0) obex_set_name(os, name); path = g_build_filename(folder, name, NULL); err = obex_put_stream_start(os, path); g_free(path); if (err < 0) goto failed; manager_emit_transfer_started(user_data); failed: g_free(folder); g_free(name); return err; }
static gboolean get_root(const GDBusPropertyTable *property, DBusMessageIter *iter, void *data) { const char *root; root = obex_option_root_folder(); dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &root); return TRUE; }
static void *opp_filesystem_open(const char *name, int oflag, mode_t mode, void *context, size_t *size, int *err) { const char *roots[] = { obex_option_root_folder(), g_get_tmp_dir(), NULL }; DBG("name '%s'", name); return common_filesystem_open(name, oflag, mode, context, size, err, NULL, 0, roots); }
static void *filesystem_open(const char *name, int oflag, mode_t mode, void *context, size_t *size, int *err) { const char *roots[] = { obex_option_root_folder(), NULL }; DBG("name '%s'", name); return common_filesystem_open(name, oflag, mode, context, size, err, FTP_TARGET, FTP_TARGET_SIZE, roots); }
static int opp_put(struct obex_session *os, void *user_data) { const char *name = obex_get_name(os); const char *folder = obex_option_root_folder(); if (folder == NULL) return -EPERM; if (name == NULL) return -EBADR; return 0; }
int verify_path(const char *path) { char *t; int ret = 0; if (obex_option_symlinks()) return 0; t = realpath(path, NULL); if (t == NULL) return -errno; if (!g_str_has_prefix(t, obex_option_root_folder())) ret = -EPERM; free(t); return ret; }
static DBusMessage *get_properties(DBusConnection *conn, DBusMessage *msg, void *data) { struct obex_session *os = data; DBusMessage *reply; DBusMessageIter iter; DBusMessageIter dict; char *uuid; const char *root; reply = dbus_message_new_method_return(msg); if (!reply) return NULL; dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); /* Target */ uuid = target2str(os->service->target); dbus_message_iter_append_dict_entry(&dict, "Target", DBUS_TYPE_STRING, &uuid); g_free(uuid); /* Root folder */ root = obex_option_root_folder(); dbus_message_iter_append_dict_entry(&dict, "Root", DBUS_TYPE_STRING, &root); /* FIXME: Added Remote Address or USB */ dbus_message_iter_close_container(&iter, &dict); return reply; }
static GString *append_listing(GString *object, const char *name, gboolean pcsuite, size_t *size, int *err) { struct stat fstat, dstat; struct dirent *ep; DIR *dp; gboolean root; int ret; root = g_str_equal(name, obex_option_root_folder()); dp = opendir(name); if (dp == NULL) { if (err) *err = -ENOENT; goto failed; } if (root) object = g_string_append(object, FL_PARENT_FOLDER_ELEMENT); ret = verify_path(name); if (ret < 0) { *err = ret; goto failed; } ret = stat(name, &dstat); if (ret < 0) { if (err) *err = -errno; goto failed; } while ((ep = readdir(dp))) { char *filename; char *fullname; char *line; if (ep->d_name[0] == '.') continue; filename = g_filename_to_utf8(ep->d_name, -1, NULL, NULL, NULL); if (name == NULL) { error("g_filename_to_utf8: invalid filename"); continue; } fullname = g_build_filename(name, ep->d_name, NULL); ret = stat(fullname, &fstat); if (ret < 0) { DBG("stat: %s(%d)", strerror(errno), errno); g_free(filename); g_free(fullname); continue; } g_free(fullname); line = file_stat_line(filename, &fstat, &dstat, root, FALSE); if (line == NULL) { g_free(filename); continue; } g_free(filename); object = g_string_append(object, line); g_free(line); } closedir(dp); object = g_string_append(object, FL_BODY_END); if (size) *size = object->len; if (err) *err = 0; return object; failed: if (dp) closedir(dp); g_string_free(object, TRUE); return NULL; }
static void *filesystem_open(const char *name, int oflag, mode_t mode, void *context, size_t *size, int *err) { struct stat stats; struct statvfs buf; const char *root_folder; char *folder; gboolean root; int fd = open(name, oflag, mode); uint64_t avail; if (fd < 0) { if (err) *err = -errno; return NULL; } if (fstat(fd, &stats) < 0) { if (err) *err = -errno; goto failed; } root_folder = obex_option_root_folder(); folder = g_path_get_dirname(name); root = g_strcmp0(folder, root_folder); g_free(folder); if (!root || obex_option_symlinks()) { if (S_ISLNK(stats.st_mode)) { if (err) *err = -EPERM; goto failed; } } if (oflag == O_RDONLY) { if (size) *size = stats.st_size; goto done; } if (fstatvfs(fd, &buf) < 0) { if (err) *err = -errno; goto failed; } if (size == NULL) goto done; avail = (uint64_t) buf.f_bsize * buf.f_bavail; if (avail < *size) { if (err) *err = -ENOSPC; goto failed; } done: if (err) *err = 0; return GINT_TO_POINTER(fd); failed: close(fd); return NULL; }