Esempio n. 1
0
static void
handle_download_ok (CcnetProcessor *processor, TransferTask *task,
                    char *content, int clen)
{
    if (clen != 41 || content[clen-1] != '\0') {
        g_warning ("Bad response content.\n");
        transfer_task_set_error (task, TASK_ERR_UNKNOWN);
        ccnet_processor_send_update (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0);
        ccnet_processor_done (processor, FALSE);
        return;
    }

    memcpy (task->head, content, 41);
    ccnet_processor_send_update (processor,
                                 SC_GET_TOKEN, SS_GET_TOKEN,
                                 NULL, 0);
}
Esempio n. 2
0
static void ccnet_processor_keep_alive_response (CcnetProcessor *processor)
{
    if (IS_SLAVE (processor))
        ccnet_processor_send_response (processor, SC_PROC_ALIVE, 
                                       SS_PROC_ALIVE, NULL, 0);
    else
        ccnet_processor_send_update (processor, SC_PROC_ALIVE, 
                                     SS_PROC_ALIVE, NULL, 0);
}
Esempio n. 3
0
static
void handle_update (CcnetProcessor *processor,
                    char *code, char *code_msg,
                    char *content, int clen)
{

    /* ccnet_debug ("[Svc Stub] %d handle update: %s %s\n", */
    /*              PRINT_ID(processor->id), code, code_msg); */
    ccnet_processor_send_update (processor, code, code_msg, content, clen);
}
Esempio n. 4
0
void ccnet_processor_keep_alive (CcnetProcessor *processor)
{
    if (IS_SLAVE (processor))
        ccnet_processor_send_response (processor, SC_PROC_KEEPALIVE, 
                                       SS_PROC_KEEPALIVE, NULL, 0);
    else
        ccnet_processor_send_update (processor, SC_PROC_KEEPALIVE, 
                                     SS_PROC_KEEPALIVE, NULL, 0);
    processor->t_keepalive_sent = time (NULL);
}
Esempio n. 5
0
static int
recv_fs_object (CcnetProcessor *processor, char *content, int clen)
{
    USE_PRIV;
    ObjectPack *pack = (ObjectPack *)content;
    uint32_t type;
    /* TransferTask *task = ((SeafileGetfsProc *)processor)->tx_task; */

    if (clen < sizeof(ObjectPack)) {
        g_warning ("[getfs] invalid object id.\n");
        goto bad;
    }

    --priv->pending_objects;

    type = seaf_metadata_type_from_data(pack->object, clen);
    if (type == SEAF_METADATA_TYPE_DIR) {
        SeafDir *dir;
        dir = seaf_dir_from_data (pack->id, pack->object, clen - 41);
        if (!dir) {
            g_warning ("[getfs] Bad directory object %s.\n", pack->id);
            goto bad;
        }
        g_queue_push_tail (priv->inspect_queue, g_strdup(dir->dir_id));
        seaf_dir_free (dir);
    } else if (type == SEAF_METADATA_TYPE_FILE) {
        /* TODO: check seafile format. */
#if 0
        int ret = seafile_check_data_format (pack->object, clen - 41);
        if (ret < 0) {
            goto bad;
        }
#endif
    } else {
        g_warning ("[getfs] Invalid object type.\n");
        goto bad;
    }

    if (save_fs_object (pack, clen) < 0) {
        goto bad;
    }

    g_hash_table_remove (priv->fs_objects, pack->id);
    return 0;

bad:
    g_warning ("Bad fs object received.\n");
    transfer_task_set_error (((SeafileGetfsProc *)processor)->tx_task,
                             TASK_ERR_DOWNLOAD_FS);
    ccnet_processor_send_update (processor, SC_BAD_OBJECT, SS_BAD_OBJECT,
                                 NULL, 0);
    ccnet_processor_done (processor, FALSE);
    return -1;
}
Esempio n. 6
0
static void
send_commits (CcnetProcessor *processor, const char *head)
{
    TransferTask *task = ((SeafileSendcommitV2Proc *)processor)->tx_task;
    gboolean ret;

    ret = seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr,
                                                    task->repo_id,
                                                    task->repo_version,
                                                    head,
                                                    traverse_commit,
                                                    processor, FALSE);
    if (!ret) {
        ccnet_processor_send_update (processor, SC_NOT_FOUND, SS_NOT_FOUND,
                                     NULL, 0);
        ccnet_processor_done (processor, FALSE);
    }

    ccnet_processor_send_update (processor, SC_END, SS_END, NULL, 0);
    ccnet_processor_done (processor, TRUE);
}
Esempio n. 7
0
static void handle_response (CcnetProcessor *processor,
                             char *code, char *code_msg,
                             char *content, int clen)
{
    SeafileGetcommitProc *proc = (SeafileGetcommitProc *)processor;
    if (proc->tx_task->state != TASK_STATE_NORMAL) {
        /* TODO: not tested yet */
        ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN,
                                     NULL, 0);
        ccnet_processor_done (processor, TRUE);
        return;
    }

    switch (processor->state) {
    case INIT:
        if (strncmp(code, SC_OK, 3) == 0) {
            processor->state = RECV_IDS;
        } else {
            g_warning ("[getcommit] Bad response: %s %s\n", code, code_msg);
            transfer_task_set_error (proc->tx_task,
                                     TASK_ERR_DOWNLOAD_COMMIT);
            ccnet_processor_done (processor, FALSE);
        }
        break;
    case RECV_IDS:
        if (strncmp(code, SC_COMMIT_IDS, 3) == 0) {
            /* add to inspect queue */
            process_commit_list (processor, content, clen);
        } else if (strncmp(code, SC_END, 3) == 0) {
            /* change state to FETCH_OBJECT */
            processor->state = FETCH_OBJECT;
        } else {
            g_warning ("[getcommit] Bad response: %s %s\n", code, code_msg);
            transfer_task_set_error (proc->tx_task,
                                      TASK_ERR_DOWNLOAD_COMMIT);
            ccnet_processor_done (processor, FALSE);
        }
        break;
    case FETCH_OBJECT:
        if (strncmp(code, SC_OBJECT, 3) == 0) {
            receive_commit (processor, content, clen);
        } else {
            g_warning ("[getcommit] Bad response: %s %s\n", code, code_msg);
            /* Transfer the task state to error when an error ocurred */
            transfer_task_set_error (proc->tx_task,
                                     TASK_ERR_DOWNLOAD_COMMIT);
            ccnet_processor_done (processor, FALSE);
        }
        break;
    default:
        g_assert (0);
    }
}
Esempio n. 8
0
inline static void
request_object_batch_flush (CcnetProcessor *processor,
                            SeafileGetcommitProcPriv *priv)
{
    if (priv->bufptr == priv->buf)
        return;
    *priv->bufptr = '\0';       /* add ending '\0' */
    priv->bufptr++;
    ccnet_processor_send_update (processor, SC_GET_OBJECT, SS_GET_OBJECT,
                                   priv->buf, priv->bufptr - priv->buf);
    g_debug ("[getcommit] Request more objects:\n%s", priv->buf);
}
Esempio n. 9
0
static void
send_object_list_segment (CcnetProcessor *processor)
{
    USE_PRIV;
    char buf[OBJECT_LIST_SEGMENT_LEN];

    if (priv->needed_objs == NULL) {
        seaf_debug ("All objects saved. Done.\n");
        ccnet_processor_send_update (processor, SC_END, SS_END, NULL, 0);
        ccnet_processor_done (processor, TRUE);
        return;
    }

    priv->n_pending = 0;
    priv->n_saved = 0;

    int i = 0;
    char *p = buf;
    char *obj_id;
    while (priv->needed_objs != NULL) {
        obj_id = priv->needed_objs->data;
        priv->needed_objs = g_list_delete_link (priv->needed_objs,
                                                priv->needed_objs);

        memcpy (p, obj_id, 40);
        p += 40;
        g_free (obj_id);
        if (++i == OBJECT_LIST_SEGMENT_N)
            break;
    }

    if (i > 0) {
        seaf_debug ("Send %d object ids.\n", i);
        priv->n_pending = i;
        ccnet_processor_send_update (processor,
                                     SC_OBJ_LIST_SEG, SS_OBJ_LIST_SEG,
                                     buf, i * 40);
    }
}
Esempio n. 10
0
static void
handle_upload_ok (CcnetProcessor *processor, TransferTask *task,
                  char *content, int clen)
{
    if (clen == 0) {
        ccnet_processor_send_update (processor,
                                     SC_GET_TOKEN, SS_GET_TOKEN,
                                     NULL, 0);
        return;
    }

    if (clen != 41 || content[clen-1] != '\0') {
        seaf_warning ("Bad response content.\n");
        transfer_task_set_error (task, TASK_ERR_UNKNOWN);
        ccnet_processor_send_update (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0);
        ccnet_processor_done (processor, FALSE);
        return;
    }

    /* Ignore the returned remote head id, just use the head of master branch.
     * For protocol version >= 6, the complete hitstory is not downloaded, so
     * there is no way to check fast forward on the client. For protocol version
     * < 6, the server will check fast forward anyway.
     */
    SeafBranch *master = seaf_branch_manager_get_branch (seaf->branch_mgr,
                                                         task->repo_id, "master");
    if (!master) {
        seaf_warning ("Cannot find branch master for repo %s.\n", task->repo_id);
        ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0);
        ccnet_processor_done (processor, FALSE);
        return;
    }
    memcpy (task->remote_head, master->commit_id, 40);
    seaf_branch_unref (master);

    ccnet_processor_send_update (processor,
                                 SC_GET_TOKEN, SS_GET_TOKEN,
                                 NULL, 0);
}
Esempio n. 11
0
static void
handle_response (CcnetProcessor *processor,
                 char *code, char *code_msg,
                 char *content, int clen)
{
    SeafileCheckTxV2Proc *proc = (SeafileCheckTxV2Proc *)processor;
    TransferTask *task = proc->task;

    if (strncmp(code, SC_OK, 3) == 0) {
        if (proc->type == CHECK_TX_TYPE_UPLOAD)
            handle_upload_ok (processor, task, content, clen);
        else
            handle_download_ok (processor, task, content, clen);
    } else if (strncmp (code, SC_PUT_TOKEN, 3) == 0) {
        /* In LAN sync, we don't use session token. */
        if (clen == 0) {
            ccnet_processor_done (processor, TRUE);
            return;
        }

        if (content[clen-1] != '\0') {
            g_warning ("Bad response content.\n");
            transfer_task_set_error (task, TASK_ERR_UNKNOWN);
            ccnet_processor_done (processor, FALSE);
            return;
        }
        task->session_token = g_strdup (content);

        ccnet_processor_send_update (processor, SC_GET_VERSION, SS_GET_VERSION,
                                     NULL, 0);
    } else if (strncmp (code, SC_VERSION, 3) == 0) {
        task->protocol_version = atoi(content);
        ccnet_processor_done (processor, TRUE);
    } else {
        g_warning ("[check tx v2] Bad response: %s %s", code, code_msg);
        if (strncmp(code, SC_ACCESS_DENIED, 3) == 0)
            transfer_task_set_error (task, TASK_ERR_ACCESS_DENIED);
        else if (strncmp(code, SC_QUOTA_ERROR, 3) == 0)
            transfer_task_set_error (task, TASK_ERR_CHECK_QUOTA);
        else if (strncmp(code, SC_QUOTA_FULL, 3) == 0)
            transfer_task_set_error (task, TASK_ERR_QUOTA_FULL);
        else if (strncmp(code, SC_PROTOCOL_MISMATCH, 3) == 0)
            transfer_task_set_error (task, TASK_ERR_PROTOCOL_VERSION);
        else if (strncmp(code, SC_BAD_REPO, 3) == 0)
            transfer_task_set_error (task, TASK_ERR_BAD_REPO_ID);
        else
            transfer_task_set_error (task, TASK_ERR_UNKNOWN);
        ccnet_processor_done (processor, FALSE);
    }
}
Esempio n. 12
0
static void
compute_upload_commits_done (void *vdata)
{
    CcnetProcessor *processor = vdata;
    USE_PRIV;

    if (!priv->compute_success) {
        ccnet_processor_send_update (processor, SC_NOT_FOUND, SS_NOT_FOUND, 
                                     NULL, 0);
        ccnet_processor_done (processor, FALSE);
        return;
    }

    send_one_commit (processor);
}
Esempio n. 13
0
inline static void
request_object_batch_flush (CcnetProcessor *processor,
                            SeafileGetfsProcPriv *priv)
{
    if (priv->bufptr == priv->buf)
        return;
    *priv->bufptr = '\0';       /* add ending '\0' */
    priv->bufptr++;

    ccnet_processor_send_update (processor, SC_GET_OBJECT, SS_GET_OBJECT,
                                 priv->buf, priv->bufptr - priv->buf);

    /* Clean state */
    priv->n_batch = 0;
    priv->bufptr = priv->buf;
}
Esempio n. 14
0
static void send_challenge_user(CcnetProcessor *processor, CcnetUser *user)
{
    CcnetKeepaliveProcPriv *priv = GET_PRIV (processor);
    unsigned char *buf;
    int len;

    ccnet_debug ("[Keepalive] Send user challenge to %.8s\n",
                 processor->peer->id);
    RAND_pseudo_bytes (priv->random_buf, 40);
    buf = public_key_encrypt (user->pubkey, priv->random_buf, 40, &len);
    ccnet_processor_send_update (processor, "321", NULL, (char *)buf, len);

    g_free(buf);
    processor->state = WAIT_CHALLENGE_USER;
    reset_timeout (processor);
}
Esempio n. 15
0
static int
check_object (CcnetProcessor *processor)
{
    USE_PRIV;
    char *obj_id;
    SeafDir *dir;
    static int i = 0;

    request_object_batch_begin(priv);

    /* process inspect queue */
    /* Note: All files in a directory must be checked in an iteration,
     * so we may send out more items than REQUEST_THRESHOLD */
    while (g_hash_table_size (priv->fs_objects) < MAX_NUM_UNREVD) {
        obj_id = (char *) g_queue_pop_head (priv->inspect_queue);
        if (obj_id == NULL)
            break;
        if (!seaf_fs_manager_object_exists(seaf->fs_mgr, obj_id)) {
            request_object_batch (processor, priv, obj_id);
        } else {
            dir = seaf_fs_manager_get_seafdir (seaf->fs_mgr, obj_id);
            if (!dir) {
                /* corrupt dir object */
                request_object_batch (processor, priv, obj_id);
            } else {
                check_seafdir(processor, dir);
                seaf_dir_free (dir);
            }
        }
        g_free (obj_id);        /* free the memory */
    }

    request_object_batch_flush (processor, priv);

    /* check end condition */
    if (i%10 == 0)
        seaf_debug ("[getfs] pending objects num: %d\n", priv->pending_objects);
    ++i;

    if (priv->pending_objects == 0 && g_queue_is_empty(priv->inspect_queue)) {
        ccnet_processor_send_update (processor, SC_END, SS_END, NULL, 0);
        ccnet_processor_done (processor, TRUE);
        return FALSE;
    } else
        return TRUE;
}
Esempio n. 16
0
static void
send_commits (CcnetProcessor *processor, const char *head)
{
    gboolean ret;

    ret = seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr,
                                                    head,
                                                    traverse_commit,
                                                    processor);
    if (!ret) {
        ccnet_processor_send_update (processor, SC_NOT_FOUND, SS_NOT_FOUND,
                                     NULL, 0);
        ccnet_processor_done (processor, FALSE);
        return;
    }

    send_one_commit (processor);
}
Esempio n. 17
0
static void
on_fs_write (OSAsyncResult *res, void *cb_data)
{
    CcnetProcessor *processor = cb_data;
    USE_PRIV;

    if (!res->success) {
        seaf_warning ("[getfs] Failed to write %s.\n", res->obj_id);
        ccnet_processor_send_update (processor, SC_BAD_OBJECT, SS_BAD_OBJECT,
                                     NULL, 0);
        ccnet_processor_done (processor, FALSE);
        return;
    }

    seaf_debug ("[getfs] Wrote fs object %s.\n", res->obj_id);

    if (++(priv->n_saved) == priv->n_pending)
        send_object_list_segment (processor);
}
Esempio n. 18
0
void ccnet_processor_handle_response (CcnetProcessor *processor, 
                                      char *code, char *code_msg,
                                      char *content, int clen)
{
    g_return_if_fail (CCNET_PROCESSOR_GET_CLASS(processor)->handle_response != NULL);

    g_object_ref (processor);
    processor->is_active = TRUE;

    if (code[0] == '5') {
        ccnet_warning ("[Proc] Shutdown processor %s(%d) for bad response: %s %s from %s\n",
                       GET_PNAME(processor), PRINT_ID(processor->id),
                       code, code_msg, processor->peer_id);
        if (memcmp(code, SC_UNKNOWN_SERVICE, 3) == 0)
            processor->failure = PROC_NO_SERVICE;
        else if (memcmp(code, SC_PERM_ERR, 3) == 0)
            processor->failure = PROC_PERM_ERR;
        else if (memcmp(code, SC_NETDOWN, 3) == 0)
            processor->failure = PROC_REMOTE_DEAD;
        else
            processor->failure = PROC_BAD_RESP;

        ccnet_processor_done (processor, FALSE);
        return;
    }

    if (strncmp (code, SC_PROC_KEEPALIVE, 3) == 0) {
        ccnet_processor_send_update (processor, SC_PROC_ALIVE, 
                                     SS_PROC_ALIVE, NULL, 0);
    } else if (strncmp (code, SC_PROC_DEAD, 3) == 0) {
        g_warning ("[proc] Shutdown processor %s(%d) when peer(%.8s) processor is dead\n",
                   GET_PNAME(processor), PRINT_ID(processor->id),
                   processor->peer_id);
        processor->failure = PROC_REMOTE_DEAD;
        ccnet_processor_done (processor, FALSE);
    } else {
        CCNET_PROCESSOR_GET_CLASS (processor)->handle_response (processor, 
                                                                code, code_msg, 
                                                                content, clen);
    }
    processor->is_active = FALSE;
    g_object_unref (processor);
}
Esempio n. 19
0
static void
send_one_commit (CcnetProcessor *processor)
{
    USE_PRIV;
    char *commit_id;

    if (!priv->id_list) {
        ccnet_processor_send_update (processor, SC_END, SS_END, NULL, 0);
        ccnet_processor_done (processor, TRUE);
        return;
    }

    commit_id = priv->id_list->data;
    priv->id_list = g_list_delete_link (priv->id_list, priv->id_list);

    send_commit (processor, commit_id);

    g_free (commit_id);
}
Esempio n. 20
0
void
ccnet_processor_done (CcnetProcessor *processor, gboolean success)
{
    if (processor->thread_running) {
        processor->delay_shutdown = TRUE;
        processor->was_success = success;
        return;
    }

    if (processor->state == STATE_IN_SHUTDOWN) {
        return;
    }

    processor->state = STATE_IN_SHUTDOWN;
    if (processor->failure == PROC_NOTSET)
        processor->failure = PROC_DONE;
    if (!processor->peer->is_local)
        ccnet_debug ("Processsor %s(%d) done %d\n", GET_PNAME(processor),
                     PRINT_ID(processor->id), success);

    if (!processor->detached && success)
    {
        if (!IS_SLAVE (processor)) {
            ccnet_processor_send_update (processor, SC_PROC_DONE, SS_PROC_DONE,
                                         NULL, 0);
        }
    }

    /* When we emit the done signal, the corresponding handler may
     * shutdown the peer, we should remove this processor from the
     * peers processor list, otherwise this processor will be freed
     * twice. */
    g_signal_emit (processor, signals[DONE_SIG], 0, success);

    if (!processor->detached) {
        ccnet_peer_remove_processor (processor->peer, processor);
    }

    ccnet_processor_release_resource (processor);

    ccnet_proc_factory_recycle (processor->session->proc_factory, processor);
}
Esempio n. 21
0
int
seafile_getblock_v2_proc_get_block (SeafileGetblockV2Proc *proc,
                                 int block_idx)
{
    CcnetProcessor *processor = (CcnetProcessor *)proc;
    char *block_id;
    char buf[128];
    int len;

    ++(proc->pending_blocks);
    BitfieldAdd (&proc->active, block_idx);

    block_id = g_ptr_array_index (proc->tx_task->block_list->block_ids, block_idx);
    len = snprintf (buf, 128, "%d %s", block_idx, block_id);
    ccnet_processor_send_update (processor,
                                 SC_GET_BLOCK, SS_GET_BLOCK,
                                 buf, len + 1);

    return 0;
}
Esempio n. 22
0
static void handle_response (CcnetProcessor *processor, 
                             char *code, char *code_msg,
                             char *content, int clen)
{
    if (code[0] == '4' || code[0] == '5') {
        ccnet_warning ("[Keepalive] Error from peer %s %s\n",
                       code, code_msg);
        close_processor (processor);
        return;
    }

    struct Handler *handler = get_handler(code, rsp_handler_tab);
    if (!handler) {
        ccnet_processor_send_update (processor, SC_BAD_RESPONSE_CODE,
                                     SS_BAD_RESPONSE_CODE, NULL, 0);
        close_processor (processor);
        return;
    }

    handler->handler(processor, code, code_msg, content, clen);
}
Esempio n. 23
0
static int
recv_fs_object (CcnetProcessor *processor, char *content, int clen)
{
    ObjectPack *pack = (ObjectPack *)content;
    /* SeafFSObject *fs_obj = NULL; */

    if (clen < sizeof(ObjectPack)) {
        seaf_warning ("invalid object id.\n");
        goto bad;
    }

    seaf_debug ("[getfs] Recv fs object %.8s.\n", pack->id);

    /* Check object integrity by parsing it. */
    /* fs_obj = seaf_fs_object_from_data(pack->id, */
    /*                                   pack->object, clen - sizeof(ObjectPack), */
    /*                                   (priv->repo_version > 0)); */
    /* if (!fs_obj) { */
    /*     seaf_warning ("Bad fs object %s.\n", pack->id); */
    /*     goto bad; */
    /* } */

    /* seaf_fs_object_free (fs_obj); */

    if (save_fs_object (processor, pack, clen) < 0) {
        goto bad;
    }

    return 0;

bad:
    ccnet_processor_send_update (processor, SC_BAD_OBJECT,
                                   SS_BAD_OBJECT, NULL, 0);
    seaf_warning ("[getfs] Bad fs object received.\n");
    ccnet_processor_done (processor, FALSE);

    /* seaf_fs_object_free (fs_obj); */

    return -1;
}
Esempio n. 24
0
static void handle_response (CcnetProcessor *processor,
                             char *code, char *code_msg,
                             char *content, int clen)
{
    SeafileSendcommitProc *proc = (SeafileSendcommitProc *)processor;
    TransferTask *task = proc->tx_task;
    if (task->state != TASK_STATE_NORMAL) {
        /* TODO: not tested yet */
        ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN,
                                     NULL, 0);
        ccnet_processor_done (processor, TRUE);
        return;
    }

    switch (processor->state) {
    case INIT:
        if (memcmp (code, SC_OK, 3) == 0)
            send_commit_ids (processor);
        else {
            seaf_warning ("Bad response: %s %s.\n", code, code_msg);
            ccnet_processor_done (processor, FALSE);
        }
        break;
    case SEND_OBJECT:
        if (strncmp(code, SC_GET_OBJECT, 3) == 0) {
            send_commits (processor, content, clen);
        } else if (strncmp(code, SC_END, 3) == 0) {
            ccnet_processor_done (processor, TRUE);
        } else {
            seaf_warning ("[sendcommit] Bad response in state SEND_OBJECT: %s %s\n",
                       code, code_msg);
            ccnet_processor_done (processor, FALSE);
        }
        break;
    default:
        g_return_if_reached ();
    }
}
Esempio n. 25
0
static void
receive_commit (CcnetProcessor *processor, char *content, int clen)
{
    ObjectPack *pack = (ObjectPack *)content;
    TransferTask *task = ((SeafileGetcommitV2Proc *)processor)->tx_task;
    SeafCommit *commit;

    if (clen < sizeof(ObjectPack)) {
        g_warning ("[getcommit] invalid object id.\n");
        goto bad;
    }

    seaf_debug ("[getcommit] recv commit object %.8s\n", pack->id);

    if (save_commit (pack, clen) < 0) {
        goto bad;
    }

    commit = seaf_commit_manager_get_commit (seaf->commit_mgr, pack->id);
    if (!commit)
        goto bad;

    if (strcmp (commit->root_id, EMPTY_SHA1) != 0)
        object_list_insert (task->fs_roots, commit->root_id);
    seaf_commit_unref (commit);

    return;

bad:
    g_warning ("[getcommit] Bad commit object received.\n");
    transfer_task_set_error (((SeafileGetcommitV2Proc *)processor)->tx_task,
                             TASK_ERR_DOWNLOAD_COMMIT);
    ccnet_processor_send_update (processor, SC_BAD_OBJECT, SS_BAD_OBJECT,
                                 NULL, 0);
    ccnet_processor_done (processor, FALSE);
}
Esempio n. 26
0
static void
send_commits (CcnetProcessor *processor, char *content, int clen)
{
    char *object_id;
    int n_objects;
    int i;

    if (clen % 41 != 1 || content[clen-1] != '\0') {
        seaf_warning ("Bad fs object list.\n");
        ccnet_processor_send_update (processor, SC_BAD_OL, SS_BAD_OL, NULL, 0);
        ccnet_processor_done (processor, FALSE);
        return;
    }

    n_objects = clen/41;

    object_id = content;
    for (i = 0; i < n_objects; ++i) {
        object_id[40] = '\0';
        if (send_commit (processor, object_id) == FALSE)
            return;
        object_id += 41;
    }
}
Esempio n. 27
0
static void
handle_response (CcnetProcessor *processor,
                 char *code, char *code_msg,
                 char *content, int clen)
{
    switch (processor->state) {
    case INIT:
        if (strncmp (code, SC_OK, 3) == 0)
            processor->state = CHECK_OBJECT_LIST;
        else {
            seaf_warning ("Bad response: %s %s\n", code, code_msg);
            ccnet_processor_done (processor, FALSE);
        }
        break;
    case CHECK_OBJECT_LIST:
        if (strncmp (code, SC_OBJ_LIST_SEG, 3) == 0) {
            if (clen % 40 != 0) {
                seaf_warning ("Invalid object list segment length %d.\n", clen);
                ccnet_processor_send_update (processor,
                                             SC_SHUTDOWN, SS_SHUTDOWN,
                                             NULL, 0);
                ccnet_processor_done (processor, FALSE);
                return;
            }

            process_recv_object_list (processor, content, clen);

        } else if (strncmp (code, SC_OBJ_LIST_SEG_END, 3) == 0) {

            ccnet_processor_thread_create (processor, seaf->job_mgr,
                                           calculate_needed_object_list,
                                           calculate_needed_object_list_done,
                                           processor);

        } else if (strncmp (code, SC_END, 3) == 0) {
            /* The server finds nothing to put. */
            ccnet_processor_done (processor, TRUE);
        } else {
            seaf_warning ("Bad response: %s %s\n", code, code_msg);
            ccnet_processor_send_update (processor,
                                         SC_BAD_RESPONSE_CODE, SS_BAD_RESPONSE_CODE,
                                         NULL, 0);
            ccnet_processor_done (processor, FALSE);
        }
        break;
    case GET_OBJECTS:
        if (strncmp(code, SC_OBJ_SEG, 3) == 0) {
            recv_fs_object_seg (processor, content, clen);
        } else if (strncmp(code, SC_OBJ_SEG_END, 3) == 0) {
            recv_fs_object_seg (processor, content, clen);
            process_fs_object_seg (processor);
        } else if (strncmp(code, SC_OBJECT, 3) == 0) {
            recv_fs_object (processor, content, clen);
        } else {
            seaf_warning ("Bad response: %s %s\n", code, code_msg);
            ccnet_processor_send_update (processor,
                                           SC_BAD_RESPONSE_CODE, SS_BAD_RESPONSE_CODE,
                                           NULL, 0);
            ccnet_processor_done (processor, FALSE);
        }
        break;
    default:
        g_return_if_reached ();
    }
}
Esempio n. 28
0
static void
handle_response (CcnetProcessor *processor,
                 char *code, char *code_msg,
                 char *content, int clen)
{
    SeafileCheckTxV3Proc *proc = (SeafileCheckTxV3Proc *)processor;
    TransferTask *task = proc->task;

    if (strncmp(code, SC_OK, 3) == 0) {
        if (proc->type == CHECK_TX_TYPE_UPLOAD)
            handle_upload_ok (processor, task, content, clen);
        else
            handle_download_ok (processor, task, content, clen);
    } else if (strncmp (code, SC_PUT_TOKEN, 3) == 0) {
        /* In LAN sync, we don't use session token. */
        if (clen == 0) {
            ccnet_processor_done (processor, TRUE);
            return;
        }

        if (content[clen-1] != '\0') {
            seaf_warning ("Bad response content.\n");
            transfer_task_set_error (task, TASK_ERR_UNKNOWN);
            ccnet_processor_send_update (processor, SC_BAD_ARGS, SS_BAD_ARGS,
                                         NULL, 0);
            ccnet_processor_done (processor, FALSE);
            return;
        }
        task->session_token = g_strdup (content);

        ccnet_processor_send_update (processor, SC_GET_VERSION, SS_GET_VERSION,
                                     NULL, 0);
    } else if (strncmp (code, SC_VERSION, 3) == 0) {
        int server_version = atoi(content);
        /* There is a bug in block transfer in version 4, so it's not supported. */
        if (server_version == 4)
            server_version = 3;
        task->protocol_version = MIN (server_version, CURRENT_PROTO_VERSION);

        if (task->protocol_version < 5) {
            seaf_warning ("Deprecated server protocol version %d.\n",
                          task->protocol_version);
            transfer_task_set_error (task, TASK_ERR_DEPRECATED_SERVER);
            ccnet_processor_done (processor, FALSE);
            return;
        }

        if (task->repo_version == 0)
            task->protocol_version = 5;
        else if (task->protocol_version == 5) {
            /* Syncing version 1 reop with 2.x server is not supported.
             * Actually version 1 repo can only be created by 3.x servers.
             * If version 1 repos exist on 2.x server, it means a down-grade
             * operation has been performed, which is not supported.
             */
            seaf_warning ("Syncing version %d repo with protocol version %d "
                          "is not supported.\n",
                          task->repo_version, task->protocol_version);
            transfer_task_set_error (task, TASK_ERR_DEPRECATED_SERVER);
            ccnet_processor_done (processor, FALSE);
            return;
        }

        if (task->protocol_version >= 7 && !task->server_side_merge)
            task->protocol_version = 6;

        if (task->protocol_version >= 7 && task->type == TASK_TYPE_DOWNLOAD)
            set_download_head_info (task);

        seaf_message ("repo version is %d, protocol version is %d.\n",
                      task->repo_version, task->protocol_version);
        ccnet_processor_done (processor, TRUE);
    } else {
        seaf_warning ("[check tx v3] Bad response: %s %s", code, code_msg);
        if (strncmp(code, SC_ACCESS_DENIED, 3) == 0)
            transfer_task_set_error (task, TASK_ERR_ACCESS_DENIED);
        else if (strncmp(code, SC_QUOTA_ERROR, 3) == 0)
            transfer_task_set_error (task, TASK_ERR_CHECK_QUOTA);
        else if (strncmp(code, SC_QUOTA_FULL, 3) == 0)
            transfer_task_set_error (task, TASK_ERR_QUOTA_FULL);
        else if (strncmp(code, SC_PROTOCOL_MISMATCH, 3) == 0)
            transfer_task_set_error (task, TASK_ERR_PROTOCOL_VERSION);
        else if (strncmp(code, SC_BAD_REPO, 3) == 0)
            transfer_task_set_error (task, TASK_ERR_BAD_REPO_ID);
        else
            transfer_task_set_error (task, TASK_ERR_UNKNOWN);
        ccnet_processor_done (processor, FALSE);
    }
}