예제 #1
0
파일: discofs.c 프로젝트: laevar/discofs
/*! signal handler */
static void sig_handler(int signo)
{
    switch (signo) {
        /* sighup blocks the working thread for 10 seconds. this gives the
           user the opportunity to unmount the remote fs */
        case SIGUSR1:
            INFO("received SIGUSR1, blocking worker for 10 seconds\n");
            worker_block();
            sleep(10);
            worker_unblock();
            break;
        case SIGUSR2:
            INFO("received SIGUSR2\n");
            state_toggle_force_offline();
            break;
    }
}
예제 #2
0
void transfer_abort(void)
{
    worker_block();
    pthread_mutex_lock(&m_transfer);

    if (t_state.active)
    {
        lock_remove(t_state.job->path, LOCK_TRANSFER);
        unlink(t_state.write_path);

        pthread_mutex_unlock(&m_transfer);
        transfer_reset_state();
    }

    worker_unblock();
    pthread_mutex_unlock(&m_transfer);
}
예제 #3
0
void transfer_rename(const char *to)
{
    size_t to_len;

    pthread_mutex_lock(&m_transfer);

    if (!t_state.active)
    {
        pthread_mutex_unlock(&m_transfer);
        return;
    }

    DEBUG("transfer_rename to %s", to);

    to_len = strlen(to);

    worker_block();

    lock_remove(t_state.job->path, LOCK_TRANSFER);
    free(t_state.job->path);
    t_state.job->path = strdup(to);
    lock_set(t_state.job->path, LOCK_TRANSFER);

    free(t_state.read_path);
    free(t_state.write_path);
    if (t_state.job->op == JOB_PUSH)
    {
        t_state.read_path = cache_path2(to, to_len);
        t_state.write_path = remote_path2(to, to_len);
    }
    else
    {
        t_state.read_path = remote_path2(to, to_len);
        t_state.write_path = cache_path2(to, to_len);
    }

    pthread_mutex_unlock(&m_transfer);
    worker_unblock();
}
예제 #4
0
int transfer_instant_pull(const char *path)
{
    int res;
    char *pc, *pr;
    size_t p_len = strlen(path);
    bool path_equal = false;

    VERBOSE("instant_pulling %s", path);

    pthread_mutex_lock(&m_instant_pull);

    worker_block();

    pr = remote_path2(path, p_len);
    pc = cache_path2(path, p_len);

    pthread_mutex_lock(&m_transfer);
    if (t_state.active)
        path_equal = !strcmp(path, t_state.job->path);
    pthread_mutex_unlock(&m_transfer);

    /* requested file is already being transfered (normally).
       just continue the transfer until it is finished */
    if (path_equal)
    {
        /* continuing a running transfer() only works if !worker_blocked() */
        worker_unblock();
        do
        {
            res = transfer(NULL, NULL);
        }
        while (ONLINE && res == TRANSFER_OK);

        res = (res == TRANSFER_FINISH) ? 0 : 1;
        worker_block();
    }
    else
    {
        res = copy_file(pr, pc);

        /* if copy_file failed, possibly because the file's directory didn't
           exist in the cache yet. create it and retry */
        if (res && errno == ENOENT)
        {
            char *dir = dirname_r(path);

            if (dir)
            {
                transfer_pull_dir(dir);
                free(dir);
                res = copy_file(pr, pc);
            }
        }
    }

    worker_unblock();

    copy_attrs(pr, pc);
    free(pr);
    free(pc);

    /* if copying failed, return error and dont set sync */
    if (res)
    {
        ERROR("instant_pull on %s FAILED", path);
        pthread_mutex_unlock(&m_instant_pull);
        return -1;
    }

    /* file is in sync now */
    job_delete(path, JOB_PULL);
    sync_set(path, 0);

    pthread_mutex_unlock(&m_instant_pull);
    return 0;
}