GList * seaf_repo_manager_get_repos_by_owner (SeafRepoManager *mgr, const char *email) { GList *id_list = NULL, *ptr; GList *ret = NULL; char sql[256]; snprintf (sql, 256, "SELECT repo_id FROM RepoOwner WHERE owner_id='%s'", email); if (seaf_db_foreach_selected_row (mgr->seaf->db, sql, collect_repo_id, &id_list) < 0) return NULL; for (ptr = id_list; ptr; ptr = ptr->next) { char *repo_id = ptr->data; SeafRepo *repo = seaf_repo_manager_get_repo (mgr, repo_id); if (repo != NULL) ret = g_list_prepend (ret, repo); } string_list_free (id_list); return ret; }
static SeafRepo* create_repo (const char *repo_name) { SeafRepo *repo; const char *repo_id; GError *error = NULL; char *wt_path; char cmd[1024]; wt_path = g_build_filename (WORKTREE_DIR, repo_name, NULL); snprintf (cmd, 1024, "cp -R %s/data %s", TEST_DIR, wt_path); int ret = system (cmd); if (ret < 0 || WEXITSTATUS(ret) != 0) { fprintf (stderr, "Failed to copy data\n"); exit (1); } /* create a non encrypted repo */ repo_id = seafile_create_repo (repo_name, "test", "*****@*****.**", NULL, &error); if (!repo_id) { fprintf (stderr, "Failed to create repo: %s.\n", error->message); exit (1); } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); g_free (wt_path); return repo; }
static int send_repo_branch_info (CcnetProcessor *processor, const char *repo_id, const char *branch) { SeafRepo *repo; SeafBranch *seaf_branch; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { ccnet_processor_send_response (processor, SC_NO_REPO, SS_NO_REPO, NULL, 0); return 0; } seaf_branch = seaf_branch_manager_get_branch (seaf->branch_mgr, repo_id, branch); if (seaf_branch == NULL) { ccnet_processor_send_response (processor, SC_NO_BRANCH, SS_NO_BRANCH, NULL, 0); return -1; } ccnet_processor_send_response (processor, SC_COMMIT_ID, SS_COMMIT_ID, seaf_branch->commit_id, 41); seaf_branch_unref (seaf_branch); return 0; }
GList * seaf_repo_manager_get_virtual_repos_by_owner (SeafRepoManager *mgr, const char *owner, GError **error) { GList *id_list = NULL, *ptr; GList *ret = NULL; char *sql; sql = "SELECT RepoOwner.repo_id FROM RepoOwner, VirtualRepo " "WHERE owner_id=? " "AND RepoOwner.repo_id = VirtualRepo.repo_id"; if (seaf_db_statement_foreach_row (mgr->seaf->db, sql, collect_virtual_repo_ids, &id_list, 1, "string", owner) < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "DB error"); return NULL; } char *repo_id; SeafRepo *repo; for (ptr = id_list; ptr; ptr = ptr->next) { repo_id = ptr->data; repo = seaf_repo_manager_get_repo (mgr, repo_id); if (repo != NULL) ret = g_list_prepend (ret, repo); } string_list_free (id_list); return ret; }
int seaf_fsck (GList *repo_id_list) { if (!repo_id_list) repo_id_list = seaf_repo_manager_get_repo_id_list (seaf->repo_mgr); GList *ptr; char *repo_id; SeafRepo *repo; for (ptr = repo_id_list; ptr; ptr = ptr->next) { repo_id = ptr->data; seaf_message ("Running fsck for repo %.8s.\n", repo_id); repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { if (recover_corrupted_repo_head (repo_id) < 0) { seaf_warning ("Failed to recover repo %.8s.\n\n", repo_id); } else seaf_message ("Fsck finished for repo %.8s.\n\n", repo_id); continue; } check_and_reset_consistent_state (repo); seaf_message ("Fsck finished for repo %.8s.\n\n", repo_id); seaf_repo_unref (repo); } return 0; }
static int add_watch (const char *repo_id) { SeafRepo *repo; int inotify_fd; char path[PATH_MAX]; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { seaf_warning ("[wt mon] cannot find repo %s.\n", repo_id); return -1; } inotify_fd = inotify_init (); if (inotify_fd < 0) { seaf_warning ("[wt mon] inotify_init failed: %s.\n", strerror(errno)); return -1; } g_strlcpy (path, repo->worktree, PATH_MAX); if (add_watch_recursive (inotify_fd, path, strlen(path)) < 0) { close (inotify_fd); return -1; } return inotify_fd; }
static void start_clone_v2 (CloneTask *task) { GError *error = NULL; if (g_access (task->worktree, F_OK) != 0 && g_mkdir_with_parents (task->worktree, 0777) < 0) { seaf_warning ("[clone mgr] Failed to create worktree %s.\n", task->worktree); transition_to_error (task, CLONE_ERROR_FETCH); return; } SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, task->repo_id); if (repo != NULL) { seaf_repo_manager_set_repo_token (seaf->repo_mgr, repo, task->token); seaf_repo_manager_set_repo_email (seaf->repo_mgr, repo, task->email); seaf_repo_manager_set_repo_relay_info (seaf->repo_mgr, repo->id, task->peer_addr, task->peer_port); if (task->server_url) { seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_PROP_SERVER_URL, task->server_url); } mark_clone_done_v2 (repo, task); return; } if (add_transfer_task (task, &error) == 0) transition_state (task, CLONE_STATE_FETCH); else transition_to_error (task, CLONE_ERROR_FETCH); }
int seaf_passwd_manager_check_passwd (SeafPasswdManager *mgr, const char *repo_id, const char *magic, GError **error) { SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo"); return -1; } if (!repo->encrypted) { seaf_repo_unref (repo); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Repo is not encrypted"); return -1; } if (strcmp (magic, repo->magic) != 0) { seaf_repo_unref (repo); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Incorrect password"); return -1; } seaf_repo_unref (repo); return 0; }
static void fill_in_repo_info (GList *shared_repos) { SeafileSharedRepo *srepo; GList *ptr; SeafRepo *repo = NULL; SeafCommit *commit = NULL; for (ptr = shared_repos; ptr; ptr = ptr->next) { srepo = ptr->data; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, seafile_shared_repo_get_repo_id(srepo)); if (!repo) continue; commit = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->head->commit_id); if (!commit) { seaf_repo_unref (repo); continue; } g_object_set (srepo, "repo_name", repo->name, "repo_desc", repo->desc, "encrypted", repo->encrypted, "last_modified", commit->ctime, NULL); seaf_repo_unref (repo); seaf_commit_unref (commit); } }
GList * seaf_repo_manager_get_repo_list (SeafRepoManager *mgr, int start, int limit) { GList *id_list = NULL, *ptr; GList *ret = NULL; SeafRepo *repo; char sql[256]; if (start == -1 && limit == -1) snprintf (sql, 256, "SELECT repo_id FROM Repo"); else snprintf (sql, 256, "SELECT repo_id FROM Repo LIMIT %d, %d", start, limit); if (seaf_db_foreach_selected_row (mgr->seaf->db, sql, collect_repo_id, &id_list) < 0) return NULL; for (ptr = id_list; ptr; ptr = ptr->next) { char *repo_id = ptr->data; repo = seaf_repo_manager_get_repo (mgr, repo_id); if (repo != NULL) ret = g_list_prepend (ret, repo); } string_list_free (id_list); return g_list_reverse (ret); }
int seaf_passwd_manager_set_passwd (SeafPasswdManager *mgr, const char *repo_id, const char *user, const char *passwd, GError **error) { SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); DecryptKey *crypt_key; GString *hash_key; if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo"); return -1; } if (!repo->encrypted) { seaf_repo_unref (repo); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Repo is not encrypted"); return -1; } if (seaf_repo_verify_passwd (repo, passwd) < 0) { seaf_repo_unref (repo); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Incorrect password"); return -1; } crypt_key = g_new0 (DecryptKey, 1); if (!crypt_key) { g_warning ("Failed to alloc crypt key struct.\n"); seaf_repo_unref (repo); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Internal server error"); return -1; } seafile_generate_enc_key (passwd, strlen(passwd), repo->enc_version, crypt_key->key, crypt_key->iv); crypt_key->passwd = g_strdup(passwd); crypt_key->expire_time = (guint64)time(NULL) + REAP_THRESHOLD; hash_key = g_string_new (NULL); g_string_printf (hash_key, "%s.%s", repo_id, user); /* g_debug ("[passwd mgr] Set passwd for %s\n", hash_key->str); */ g_hash_table_insert (mgr->priv->decrypt_keys, g_string_free (hash_key, FALSE), crypt_key); seaf_repo_unref (repo); return 0; }
static gboolean restart_task (sqlite3_stmt *stmt, void *data) { SeafCloneManager *mgr = data; const char *repo_id, *repo_name, *token, *peer_id, *worktree, *passwd; const char *peer_addr, *peer_port, *email; CloneTask *task; SeafRepo *repo; repo_id = (const char *)sqlite3_column_text (stmt, 0); repo_name = (const char *)sqlite3_column_text (stmt, 1); token = (const char *)sqlite3_column_text (stmt, 2); peer_id = (const char *)sqlite3_column_text (stmt, 3); worktree = (const char *)sqlite3_column_text (stmt, 4); passwd = (const char *)sqlite3_column_text (stmt, 5); peer_addr = (const char *)sqlite3_column_text (stmt, 6); peer_port = (const char *)sqlite3_column_text (stmt, 7); email = (const char *)sqlite3_column_text (stmt, 8); task = clone_task_new (repo_id, peer_id, repo_name, token, worktree, passwd, peer_addr, peer_port, email); task->manager = mgr; /* Default to 1. */ task->enc_version = 1; if (passwd && load_clone_enc_info (task) < 0) { clone_task_free (task); return TRUE; } task->repo_version = 0; load_clone_repo_version_info (task); load_clone_more_info (task); repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (repo != NULL && repo->head != NULL) { transition_state (task, CLONE_STATE_DONE); return TRUE; } if (task->repo_version > 0) { if (task->server_url) { check_http_protocol (task); } else { transition_to_error (task, CLONE_ERROR_CHECK_SERVER); return TRUE; } } g_hash_table_insert (mgr->tasks, g_strdup(task->repo_id), task); return TRUE; }
static gboolean restart_task (sqlite3_stmt *stmt, void *data) { SeafCloneManager *mgr = data; const char *repo_id, *repo_name, *token, *peer_id, *worktree, *passwd; const char *peer_addr, *peer_port, *email; CloneTask *task; SeafRepo *repo; repo_id = (const char *)sqlite3_column_text (stmt, 0); repo_name = (const char *)sqlite3_column_text (stmt, 1); token = (const char *)sqlite3_column_text (stmt, 2); peer_id = (const char *)sqlite3_column_text (stmt, 3); worktree = (const char *)sqlite3_column_text (stmt, 4); passwd = (const char *)sqlite3_column_text (stmt, 5); peer_addr = (const char *)sqlite3_column_text (stmt, 6); peer_port = (const char *)sqlite3_column_text (stmt, 7); email = (const char *)sqlite3_column_text (stmt, 8); task = clone_task_new (repo_id, peer_id, repo_name, token, worktree, passwd, peer_addr, peer_port, email); task->manager = mgr; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (repo != NULL) { if (repo->head != NULL) { /* If repo exists and its head is set, we are done actually. * The task will be removed from db but still left in memory. */ transition_state (task, CLONE_STATE_DONE); g_hash_table_insert (mgr->tasks, g_strdup(task->repo_id), task); } else { /* If head is not set, we haven't finished checkout. */ g_hash_table_insert (mgr->tasks, g_strdup(task->repo_id), task); start_checkout (repo, task); } } else { /* Repo was not created last time. In this case, we just * restart from the very beginning. */ if (!ccnet_peer_is_ready (seaf->ccnetrpc_client, task->peer_id)) { /* the relay is not ready yet */ start_connect_task_relay (task, NULL); } else { start_index_or_transfer (mgr, task, NULL); } g_hash_table_insert (mgr->tasks, g_strdup(task->repo_id), task); } return TRUE; }
static int handle_auth_req_content_cb (char *content, int clen, void *cbarg) { BlockTxServer *server = cbarg; char *session_token = content; SearpcClient *client = NULL; char repo_id[37]; SeafRepo *repo; if (session_token[clen - 1] != '\0') { seaf_warning ("Invalid session token format.\n"); send_auth_response (server, STATUS_BAD_REQUEST); return -1; } client = ccnet_create_pooled_rpc_client (seaf->client_pool, NULL, "ccnet-rpcserver"); if (!client) { seaf_warning ("Failed to create rpc client.\n"); send_auth_response (server, STATUS_INTERNAL_SERVER_ERROR); return -1; } if (seaf_token_manager_verify_token (seaf->token_mgr, client, NULL, session_token, repo_id) < 0) { seaf_warning ("Session token check failed.\n"); send_auth_response (server, STATUS_ACCESS_DENIED); ccnet_rpc_client_free (client); return -1; } ccnet_rpc_client_free (client); repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { seaf_warning ("Failed to get repo %.8s.\n", repo_id); return -1; } memcpy (server->store_id, repo->store_id, 36); server->repo_version = repo->version; seaf_repo_unref (repo); if (send_auth_response (server, STATUS_OK) < 0) return -1; seaf_debug ("recv_state set to HEADER.\n"); server->parser.content_cb = handle_block_header_content_cb; server->recv_state = RECV_STATE_HEADER; return 0; }
void seaf_repo_manager_cleanup_virtual_repos (SeafRepoManager *mgr, const char *origin_repo_id) { SeafRepo *repo = NULL; SeafCommit *head = NULL; GList *vinfo_list = NULL, *ptr; SeafVirtRepo *vinfo; SeafDir *dir; GError *error = NULL; repo = seaf_repo_manager_get_repo (mgr, origin_repo_id); if (!repo) { seaf_warning ("Failed to get repo %.10s.\n", origin_repo_id); goto out; } head = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, repo->head->commit_id); if (!head) { seaf_warning ("Failed to get commit %s:%.8s.\n", repo->id, repo->head->commit_id); goto out; } vinfo_list = seaf_repo_manager_get_virtual_info_by_origin (mgr, origin_repo_id); for (ptr = vinfo_list; ptr; ptr = ptr->next) { vinfo = ptr->data; dir = seaf_fs_manager_get_seafdir_by_path (seaf->fs_mgr, repo->store_id, repo->version, head->root_id, vinfo->path, &error); if (error) { if (error->code == SEAF_ERR_PATH_NO_EXIST) { handle_missing_virtual_repo (mgr, repo, head, vinfo); } g_clear_error (&error); } else seaf_dir_free (dir); seaf_virtual_repo_info_free (vinfo); } out: seaf_repo_unref (repo); seaf_commit_unref (head); g_list_free (vinfo_list); }
static void do_destroy_repo (char *repo_id) { if (!repo_id) return; SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_warning ("Repo %s does not exist\n", repo_id); return; } printf("Deleting repo %s\n", repo_id); seaf_repo_manager_del_repo (seaf->repo_mgr, repo); printf("Done\n"); }
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 %.8s.\n", 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; }
GList * seaf_repo_manager_get_repo_list (SeafRepoManager *mgr, int start, int limit, gboolean ignore_errors, gboolean *error) { char sql[256]; GList *id_list = NULL, *ptr; GList *ret = NULL; SeafRepo *repo; *error = FALSE; if (start == -1 && limit == -1) snprintf (sql, 256, "SELECT repo_id FROM Repo"); else snprintf (sql, 256, "SELECT repo_id FROM Repo LIMIT %d, %d", start, limit); if (seaf_db_foreach_selected_row (mgr->seaf->db, sql, collect_repo_id, &id_list) < 0) goto error; for (ptr = id_list; ptr; ptr = ptr->next) { char *repo_id = ptr->data; repo = seaf_repo_manager_get_repo (mgr, repo_id); if (!repo) { /* In GC, we should be more conservative. * No matter a repo is really corrupted or it's a temp error, * we return error here. */ g_warning ("Failed to get repo %.8s.\n", repo_id); if (!ignore_errors) goto error; else continue; } ret = g_list_prepend (ret, repo); } string_list_free (id_list); return ret; error: *error = TRUE; string_list_free (id_list); for (ptr = ret; ptr; ptr = ptr->next) { repo = ptr->data; seaf_repo_unref (repo); } return NULL; }
char * seaf_clone_manager_add_task (SeafCloneManager *mgr, const char *repo_id, const char *peer_id, const char *repo_name, const char *token, const char *passwd, const char *worktree_in, const char *peer_addr, const char *peer_port, const char *email, GError **error) { SeafRepo *repo; char *worktree; char *ret; g_assert (strlen(repo_id) == 36); repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (repo != NULL && repo->head != NULL) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Repo already exists"); return NULL; } if (is_duplicate_task (mgr, repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Task is already in progress"); return NULL; } if (!check_worktree_path (mgr, worktree_in, error)) return NULL; /* Return error if worktree_in conflicts with another repo or * is not a directory. */ worktree = make_worktree (mgr, worktree_in, FALSE, error); if (!worktree) { return NULL; } ret = add_task_common (mgr, repo, repo_id, peer_id, repo_name, token, passwd, worktree, peer_addr, peer_port, email, error); g_free (worktree); return ret; }
char * seaf_clone_manager_add_download_task (SeafCloneManager *mgr, const char *repo_id, const char *peer_id, const char *repo_name, const char *token, const char *passwd, const char *wt_parent, const char *peer_addr, const char *peer_port, const char *email, GError **error) { SeafRepo *repo; char *wt_tmp, *worktree; char *ret; g_assert (strlen(repo_id) == 36); repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (repo != NULL && repo->head != NULL) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Repo already exists"); return NULL; } if (is_duplicate_task (mgr, repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Task is already in progress"); return NULL; } wt_tmp = g_build_filename (wt_parent, repo_name, NULL); worktree = make_worktree_for_download (mgr, wt_tmp, error); if (!worktree) { g_free (wt_tmp); return NULL; } ret = add_task_common (mgr, repo, repo_id, peer_id, repo_name, token, passwd, worktree, peer_addr, peer_port, email, error); g_free (worktree); g_free (wt_tmp); return ret; }
static gboolean collect_repos (SeafDBRow *row, void *data) { GList **p_repos = data; const char *repo_id; SeafRepo *repo; repo_id = seaf_db_row_get_column_text (row, 0); repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { /* Continue to collect the remaining repos. */ return TRUE; } *p_repos = g_list_prepend (*p_repos, repo); return TRUE; }
static void on_repo_http_fetched (SeafileSession *seaf, HttpTxTask *tx_task, SeafCloneManager *mgr) { CloneTask *task; /* Only handle clone task. */ if (!tx_task->is_clone) return; task = g_hash_table_lookup (mgr->tasks, tx_task->repo_id); g_return_if_fail (task != NULL); if (tx_task->state == HTTP_TASK_STATE_CANCELED) { /* g_assert (task->state == CLONE_STATE_CANCEL_PENDING); */ transition_state (task, CLONE_STATE_CANCELED); return; } else if (tx_task->state == HTTP_TASK_STATE_ERROR) { transition_to_error (task, CLONE_ERROR_FETCH); task->err_detail = g_strdup(http_task_error_str(tx_task->error)); return; } SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, tx_task->repo_id); if (repo == NULL) { seaf_warning ("[Clone mgr] cannot find repo %s after fetched.\n", tx_task->repo_id); transition_to_error (task, CLONE_ERROR_INTERNAL); return; } seaf_repo_manager_set_repo_token (seaf->repo_mgr, repo, task->token); seaf_repo_manager_set_repo_email (seaf->repo_mgr, repo, task->email); seaf_repo_manager_set_repo_relay_info (seaf->repo_mgr, repo->id, task->peer_addr, task->peer_port); if (task->server_url) { seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_PROP_SERVER_URL, task->server_url); } check_folder_permissions (task); }
static FSEventStreamRef add_watch (SeafWTMonitorPriv *priv, const char* repo_id) { SeafRepo *repo = NULL; const char *path = NULL; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { seaf_warning ("[wt mon] cannot find repo %s.\n", repo_id); return 0; } path = repo->worktree; CFStringRef mypath = CFStringCreateWithCString (kCFAllocatorDefault, path, kCFStringEncodingUTF8); CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL); FSEventStreamRef stream; /* Create the stream, passing in a callback */ struct FSEventStreamContext ctx = {0, priv, NULL, NULL, NULL}; stream = FSEventStreamCreate(kCFAllocatorDefault, stream_callback, &ctx, pathsToWatch, kFSEventStreamEventIdSinceNow, 1.0, kFSEventStreamCreateFlagWatchRoot ); CFRelease (mypath); CFRelease (pathsToWatch); if (!stream) { seaf_warning ("[wt] Failed to create event stream \n"); return stream; } FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); FSEventStreamStart (stream); #ifdef FSEVENT_DEBUG FSEventStreamShow (stream); seaf_debug ("[wt mon] Add repo %s watch success :%s.\n", repo_id, repo->worktree); #endif return stream; }
static int refresh_watch (int inotify_fd, const char *repo_id) { SeafRepo *repo; char path[PATH_MAX]; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { seaf_warning ("[wt mon] cannot find repo %s.\n", repo_id); return -1; } g_strlcpy (path, repo->worktree, PATH_MAX); if (add_watch_recursive (inotify_fd, path, strlen(path)) < 0) { return -1; } return 0; }
static void * collect_commit_id_thread (void *vprocessor) { CcnetProcessor *processor = vprocessor; USE_PRIV; SeafRepo *repo; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, priv->repo_id); if (!repo) { seaf_warning ("Failed to get repo %s.\n", priv->repo_id); priv->id_list = NULL; return vprocessor; } priv->repo_version = repo->version; priv->fast_forward = TRUE; if (seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, repo->id, repo->version, priv->head_commit_id, collect_id_fast_forward, processor, FALSE) < 0) { seaf_warning ("[putcommit] Failed to collect commit id.\n"); string_list_free (priv->id_list); priv->id_list = NULL; goto out; } if (priv->fast_forward) { seaf_debug ("Send commits after a fast-forward merge.\n"); goto out; } seaf_debug ("Send commits after a real merge.\n"); compute_delta_commits (processor, priv->head_commit_id); out: seaf_repo_unref (repo); return vprocessor; }
static gboolean collect_repos (SeafDBRow *row, void *data) { GList **p_repos = data; const char *repo_id; const char *email; const char *permission; SeafRepo *repo = NULL; SeafCommit *commit = NULL; SeafileSharedRepo *srepo; repo_id = seaf_db_row_get_column_text (row, 0); repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) goto out; email = seaf_db_row_get_column_text (row, 1); permission = seaf_db_row_get_column_text (row, 2); commit = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->head->commit_id); if (!commit) goto out; srepo = g_object_new (SEAFILE_TYPE_SHARED_REPO, "share_type", "personal", "repo_id", repo_id, "repo_name", repo->name, "repo_desc", repo->desc, "encrypted", repo->encrypted, "user", email, "permission", permission, "last_modified", commit->ctime, NULL); *p_repos = g_list_prepend (*p_repos, srepo); out: seaf_repo_unref (repo); seaf_commit_unref (commit); return TRUE; }
static void * create_system_default_repo (void *data) { SeafileSession *session = data; char *repo_id; char *template_path; /* If default repo is not set or doesn't exist, create a new one. */ repo_id = get_system_default_repo_id (session); if (repo_id != NULL) { SeafRepo *repo; repo = seaf_repo_manager_get_repo (session->repo_mgr, repo_id); if (!repo) { seaf_warning ("Failed to get system default repo. Create a new one.\n"); del_system_default_repo_id (session); seaf_repo_manager_del_repo (session->repo_mgr, repo_id, NULL); } else { seaf_repo_unref (repo); return data; } } repo_id = seaf_repo_manager_create_new_repo (session->repo_mgr, "My Library Template", "Template for creating 'My Libray' for users", "System", NULL, NULL); if (!repo_id) { seaf_warning ("Failed to create system default repo.\n"); return data; } set_system_default_repo_id (session, repo_id); template_path = g_build_filename (session->seaf_dir, DEFAULT_TEMPLATE_DIR, NULL); copy_template_files_recursive (session, repo_id, "/", template_path); g_free (repo_id); g_free (template_path); return data; }
static void * get_repo_info_thread (void *data) { CcnetProcessor *processor = data; USE_PRIV; SeafRepo *repo; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, priv->repo_id); if (!repo) { seaf_warning ("Failed to get repo %s.\n", priv->repo_id); priv->success = FALSE; return data; } memcpy (priv->store_id, repo->store_id, 36); priv->repo_version = repo->version; priv->success = TRUE; seaf_repo_unref (repo); return data; }
static void on_repo_fetched (SeafileSession *seaf, TransferTask *tx_task, SeafCloneManager *mgr) { CloneTask *task; /* Only handle clone task. */ if (!tx_task->is_clone) return; task = g_hash_table_lookup (mgr->tasks, tx_task->repo_id); g_assert (task != NULL); if (tx_task->state == TASK_STATE_CANCELED) { /* g_assert (task->state == CLONE_STATE_CANCEL_PENDING); */ transition_state (task, CLONE_STATE_CANCELED); return; } else if (tx_task->state == TASK_STATE_ERROR) { transition_to_error (task, CLONE_ERROR_FETCH); return; } SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, tx_task->repo_id); if (repo == NULL) { seaf_warning ("[Clone mgr] cannot find repo %s after fetched.\n", tx_task->repo_id); transition_to_error (task, CLONE_ERROR_INTERNAL); return; } seaf_repo_manager_set_repo_token (seaf->repo_mgr, repo, task->token); seaf_repo_manager_set_repo_email (seaf->repo_mgr, repo, task->email); seaf_repo_manager_set_repo_relay_info (seaf->repo_mgr, repo->id, task->peer_addr, task->peer_port); start_checkout (repo, task); }
static void check_folder_perms_done (HttpFolderPerms *result, void *user_data) { CloneTask *task = user_data; GList *ptr; HttpFolderPermRes *res; SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, task->repo_id); if (repo == NULL) { seaf_warning ("[Clone mgr] cannot find repo %s after fetched.\n", task->repo_id); transition_to_error (task, CLONE_ERROR_INTERNAL); return; } if (!result->success) { goto out; } for (ptr = result->results; ptr; ptr = ptr->next) { res = ptr->data; seaf_repo_manager_update_folder_perms (seaf->repo_mgr, res->repo_id, FOLDER_PERM_TYPE_USER, res->user_perms); seaf_repo_manager_update_folder_perms (seaf->repo_mgr, res->repo_id, FOLDER_PERM_TYPE_GROUP, res->group_perms); seaf_repo_manager_update_folder_perm_timestamp (seaf->repo_mgr, res->repo_id, res->timestamp); } out: mark_clone_done_v2 (repo, task); }