1
0
mirror of https://github.com/haiwen/seafile-server.git synced 2025-06-20 20:33:19 +00:00
seafile-server/fuse/readdir.c
feiniks d50359c908
Add and del ccnet compilation dependency in seafile (#347)
* Add and del ccnet compilation dependency in seafile

* Del import ccnet

* Del extra ccnet compilation dependencies

* Del support WIN32
2020-05-09 16:31:47 +08:00

220 lines
6.0 KiB
C

#include "common.h"
#define FUSE_USE_VERSION 26
#include <fuse.h>
#include <glib.h>
#include <glib-object.h>
#include <seaf-db.h>
#include "log.h"
#include "utils.h"
#include "seaf-fuse.h"
#include "seafile-session.h"
#include "seaf-utils.h"
static char *replace_slash (const char *repo_name)
{
char *ret = g_strdup(repo_name);
char *p;
for (p = ret; *p != 0; ++p)
if (*p == '/')
*p = '_';
return ret;
}
static GList *get_users_from_ccnet (SearpcClient *client, const char *source)
{
return searpc_client_call__objlist (client,
"get_emailusers", CCNET_TYPE_EMAIL_USER, NULL,
3, "string", source, "int", -1, "int", -1);
}
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 readdir_root(SeafileSession *seaf,
void *buf, fuse_fill_dir_t filler, off_t offset,
struct fuse_file_info *info)
{
GList *users, *p;
CcnetEmailUser *user;
const char *email;
GHashTable *user_hash;
int dummy;
user_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
users = ccnet_user_manager_get_emailusers (seaf->user_mgr, "DB", -1, -1, NULL);
for (p = users; p; p = p->next) {
user = p->data;
email = ccnet_email_user_get_email (user);
g_hash_table_insert (user_hash, g_strdup(email), &dummy);
g_object_unref (user);
}
g_list_free (users);
users = ccnet_user_manager_get_emailusers (seaf->user_mgr, "LDAPImport", -1, -1, NULL);
for (p = users; p; p = p->next) {
user = p->data;
email = ccnet_email_user_get_email (user);
g_hash_table_insert (user_hash, g_strdup(email), &dummy);
g_object_unref (user);
}
g_list_free (users);
users = g_hash_table_get_keys (user_hash);
for (p = users; p; p = p->next) {
email = p->data;
char *exclude = g_hash_table_lookup (seaf->excluded_users, email);
if (exclude)
continue;
filler (buf, email, NULL, 0);
}
g_list_free (users);
g_hash_table_destroy (user_hash);
return 0;
}
static int readdir_user(SeafileSession *seaf, const char *user,
void *buf, fuse_fill_dir_t filler, off_t offset,
struct fuse_file_info *info)
{
CcnetEmailUser *emailuser;
GList *list = NULL, *p;
GString *name;
emailuser = ccnet_user_manager_get_emailuser (seaf->user_mgr, user);
if (!emailuser) {
return -ENOENT;
}
g_object_unref (emailuser);
list = seaf_repo_manager_get_repos_by_owner (seaf->repo_mgr, user);
if (!list) {
return 0;
}
for (p = list; p; p = p->next) {
SeafRepo *repo = (SeafRepo *)p->data;
/* Don't list virtual repos. */
if (seaf_repo_manager_is_virtual_repo(seaf->repo_mgr, repo->id)) {
seaf_repo_unref (repo);
continue;
}
// Don't list encrypted repo
if (repo->encrypted) {
continue;
}
char *clean_repo_name = replace_slash (repo->name);
name = g_string_new ("");
g_string_printf (name, "%s_%s", repo->id, clean_repo_name);
filler(buf, name->str, NULL, 0);
g_string_free (name, TRUE);
g_free (clean_repo_name);
seaf_repo_unref (repo);
}
g_list_free (list);
return 0;
}
static int readdir_repo(SeafileSession *seaf,
const char *user, const char *repo_id, const char *repo_path,
void *buf, fuse_fill_dir_t filler, off_t offset,
struct fuse_file_info *info)
{
SeafRepo *repo = NULL;
SeafBranch *branch;
SeafCommit *commit = NULL;
SeafDir *dir = NULL;
GList *l;
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;
}
dir = seaf_fs_manager_get_seafdir_by_path(seaf->fs_mgr,
repo->store_id, repo->version,
commit->root_id,
repo_path, NULL);
if (!dir) {
seaf_warning ("Path %s doesn't exist in repo %s.\n", repo_path, repo_id);
ret = -ENOENT;
goto out;
}
for (l = dir->entries; l; l = l->next) {
SeafDirent *seaf_dent = (SeafDirent *) l->data;
/* FIXME: maybe we need to return stbuf */
filler(buf, seaf_dent->name, NULL, 0);
}
out:
seaf_repo_unref (repo);
seaf_commit_unref (commit);
seaf_dir_free (dir);
return ret;
}
int do_readdir(SeafileSession *seaf, const char *path, void *buf,
fuse_fill_dir_t filler, off_t offset,
struct fuse_file_info *info)
{
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 = readdir_root(seaf, buf, filler, offset, info);
break;
case 1:
ret = readdir_user(seaf, user, buf, filler, offset, info);
break;
case 2:
case 3:
ret = readdir_repo(seaf, user, repo_id, repo_path, buf, filler, offset, info);
break;
}
g_free (user);
g_free (repo_id);
g_free (repo_path);
return ret;
}