Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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;

}
Exemple #4
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;
}
Exemple #5
0
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;
}
Exemple #6
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;
}
Exemple #7
0
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);
}
Exemple #8
0
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;
}
Exemple #9
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);
    }
}
Exemple #10
0
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);
}
Exemple #11
0
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;
}
Exemple #12
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;
}
Exemple #13
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;

    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;
}
Exemple #14
0
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;
}
Exemple #15
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);
}
Exemple #16
0
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");
}
Exemple #17
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 %.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;
}
Exemple #18
0
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;
}
Exemple #19
0
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;
}
Exemple #20
0
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;
}
Exemple #21
0
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;
}
Exemple #22
0
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);
}
Exemple #23
0
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;
}
Exemple #24
0
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;
}
Exemple #25
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;
}
Exemple #26
0
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;
}
Exemple #27
0
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;
}
Exemple #28
0
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;
}
Exemple #29
0
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);
}
Exemple #30
0
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);
}