static int verify_path_many(const char *path, const char *roots[]) { int i; char *t; int ret = 0; if (obex_option_symlinks()) return 0; t = realpath(path, NULL); if (t == NULL) return -errno; ret = -EPERM; for (i = 0; roots[i]; i++) { if (g_str_has_prefix(t, roots[i])) { ret = 0; break; } } free(t); return ret; }
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 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, symlinks; int ret; root = g_str_equal(name, obex_option_root_folder()); dp = opendir(name); if (dp == NULL) { if (err) *err = -ENOENT; goto failed; } symlinks = obex_option_symlinks(); if (root && symlinks) ret = stat(name, &dstat); else { object = g_string_append(object, FL_PARENT_FOLDER_ELEMENT); ret = lstat(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); if (root && symlinks) ret = stat(fullname, &fstat); else ret = lstat(fullname, &fstat); if (ret < 0) { DBG("%s: %s(%d)", root ? "stat" : "lstat", 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; }