#include "common.h" #define FUSE_USE_VERSION 26 #include #include #include #include #include "log.h" #include "utils.h" #include "seaf-fuse.h" #include "seafile-session.h" #include "seaf-utils.h" static CcnetEmailUser *get_user_from_ccnet (SearpcClient *client, const char *user) { return (CcnetEmailUser *)searpc_client_call__object (client, "get_emailuser", CCNET_TYPE_EMAIL_USER, NULL, 1, "string", user); } static int getattr_root(SeafileSession *seaf, struct stat *stbuf) { stbuf->st_mode = S_IFDIR | 0755; stbuf->st_nlink = 2; stbuf->st_size = 4096; return 0; } static int getattr_user(SeafileSession *seaf, const char *user, struct stat *stbuf) { CcnetEmailUser *emailuser; emailuser = ccnet_user_manager_get_emailuser (seaf->user_mgr, user); if (!emailuser) { return -ENOENT; } g_object_unref (emailuser); stbuf->st_mode = S_IFDIR | 0755; stbuf->st_nlink = 2; stbuf->st_size = 4096; return 0; } static int getattr_repo(SeafileSession *seaf, const char *user, const char *repo_id, const char *repo_path, struct stat *stbuf) { SeafRepo *repo = NULL; SeafBranch *branch; SeafCommit *commit = NULL; guint32 mode = 0; char *id = NULL; int ret = 0; repo = seaf_repo_manager_get_repo(seaf->repo_mgr, repo_id); if (!repo) { seaf_warning ("Failed to get repo %s.\n", repo_id); ret = -ENOENT; goto out; } branch = repo->head; commit = seaf_commit_manager_get_commit(seaf->commit_mgr, repo->id, repo->version, branch->commit_id); if (!commit) { seaf_warning ("Failed to get commit %s:%.8s.\n", repo->id, branch->commit_id); ret = -ENOENT; goto out; } id = seaf_fs_manager_path_to_obj_id(seaf->fs_mgr, repo->store_id, repo->version, commit->root_id, repo_path, &mode, NULL); if (!id) { seaf_warning ("Path %s doesn't exist in repo %s.\n", repo_path, repo_id); ret = -ENOENT; goto out; } if (S_ISDIR(mode)) { SeafDir *dir; GList *l; int cnt = 2; /* '.' and '..' */ dir = seaf_fs_manager_get_seafdir(seaf->fs_mgr, repo->store_id, repo->version, id); if (dir) { for (l = dir->entries; l; l = l->next) cnt++; } if (strcmp (repo_path, "/") != 0) { // get dirent of the dir SeafDirent *dirent = seaf_fs_manager_get_dirent_by_path (seaf->fs_mgr, repo->store_id, repo->version, commit->root_id, repo_path, NULL); if (dirent && repo->version != 0) stbuf->st_mtime = dirent->mtime; seaf_dirent_free (dirent); } stbuf->st_size += cnt * sizeof(SeafDirent); stbuf->st_mode = mode | 0755; stbuf->st_nlink = 2; seaf_dir_free (dir); } else if (S_ISREG(mode)) { Seafile *file; file = seaf_fs_manager_get_seafile(seaf->fs_mgr, repo->store_id, repo->version, id); if (file) stbuf->st_size = file->file_size; SeafDirent *dirent = seaf_fs_manager_get_dirent_by_path (seaf->fs_mgr, repo->store_id, repo->version, commit->root_id, repo_path, NULL); if (dirent && repo->version != 0) stbuf->st_mtime = dirent->mtime; stbuf->st_mode = mode | 0644; stbuf->st_nlink = 1; seaf_dirent_free (dirent); seafile_unref (file); } else { return -ENOENT; } out: g_free (id); seaf_repo_unref (repo); seaf_commit_unref (commit); return ret; } int do_getattr(SeafileSession *seaf, const char *path, struct stat *stbuf) { int n_parts; char *user, *repo_id, *repo_path; int ret = 0; if (parse_fuse_path (path, &n_parts, &user, &repo_id, &repo_path) < 0) { return -ENOENT; } switch (n_parts) { case 0: ret = getattr_root(seaf, stbuf); break; case 1: ret = getattr_user(seaf, user, stbuf); break; case 2: case 3: ret = getattr_repo(seaf, user, repo_id, repo_path, stbuf); break; } g_free (user); g_free (repo_id); g_free (repo_path); return ret; }