Пример #1
0
/* *INDENT-OFF* */
END_PARAMETRIZED_TEST
/* *INDENT-ON* */

/* --------------------------------------------------------------------------------------------- */

/* Relative to panel_correct_path_to_show()  */

/* @Test */
/* *INDENT-OFF* */
START_TEST (test_vpath_to_str_filter)
/* *INDENT-ON* */
{
    /* given */
    vfs_path_t *vpath, *last_vpath;
    char *filtered_path;
    const vfs_path_element_t *path_element;

    /* when */
    vpath = vfs_path_from_str ("/test1://some.host/dir");
    path_element = vfs_path_element_clone (vfs_path_get_by_index (vpath, -1));
    vfs_path_free (vpath);

    last_vpath = vfs_path_new ();
    last_vpath->relative = TRUE;

    vfs_path_add_element (last_vpath, path_element);

    filtered_path = vfs_path_to_str_flags (last_vpath, 0,
                                           VPF_STRIP_HOME | VPF_STRIP_PASSWORD | VPF_HIDE_CHARSET);

    /* then */
    mctest_assert_str_eq (filtered_path, "test1://some.host/dir");

    vfs_path_free (last_vpath);
    g_free (filtered_path);
}
Пример #2
0
/* *INDENT-OFF* */
START_PARAMETRIZED_TEST (test_relative_cd, test_relative_cd_ds)
/* *INDENT-ON* */
{
    /* given */
    vfs_path_t *vpath;
    int actual_result;

    test_chdir__return_value = 0;

    vpath = vfs_path_from_str_flags (data->input_string, data->input_flags);

    /* when */
    actual_result = mc_chdir (vpath);

    /* then */
    {
        const vfs_path_element_t *element;

        mctest_assert_int_eq (actual_result, 0);
        element = vfs_path_get_by_index (vpath, -1);
        mctest_assert_str_eq (element->path, data->expected_element_path);
        vfs_path_free (vpath);
    }
}
Пример #3
0
void
dir_list_reload (dir_list * list, const vfs_path_t * vpath, GCompareFunc sort,
                 const dir_sort_options_t * sort_op, const char *fltr)
{
    DIR *dirp;
    struct dirent *dp;
    int i, link_to_dir, stale_link;
    struct stat st;
    int marked_cnt;
    GHashTable *marked_files;
    const char *tmp_path;

    dirp = mc_opendir (vpath);
    if (dirp == NULL)
    {
        message (D_ERROR, MSG_ERROR, _("Cannot read directory contents"));
        dir_list_clean (list);
        dir_list_init (list);
        return;
    }

    tree_store_start_check (vpath);

    marked_files = g_hash_table_new (g_str_hash, g_str_equal);
    alloc_dir_copy (list->len);
    for (marked_cnt = i = 0; i < list->len; i++)
    {
        file_entry_t *fentry, *dfentry;

        fentry = &list->list[i];
        dfentry = &dir_copy.list[i];

        dfentry->fnamelen = fentry->fnamelen;
        dfentry->fname = g_strndup (fentry->fname, fentry->fnamelen);
        dfentry->f.marked = fentry->f.marked;
        dfentry->f.dir_size_computed = fentry->f.dir_size_computed;
        dfentry->f.link_to_dir = fentry->f.link_to_dir;
        dfentry->f.stale_link = fentry->f.stale_link;
        dfentry->sort_key = NULL;
        dfentry->second_sort_key = NULL;
        if (fentry->f.marked)
        {
            g_hash_table_insert (marked_files, dfentry->fname, dfentry);
            marked_cnt++;
        }
    }

    /* save len for later dir_list_clean() */
    dir_copy.len = list->len;

    /* Add ".." except to the root directory. The ".." entry
       (if any) must be the first in the list. */
    tmp_path = vfs_path_get_by_index (vpath, 0)->path;
    if (vfs_path_elements_count (vpath) == 1 && IS_PATH_SEP (tmp_path[0]) && tmp_path[1] == '\0')
    {
        /* root directory */
        dir_list_clean (list);
    }
    else
    {
        dir_list_clean (list);
        if (!dir_list_init (list))
        {
            dir_list_clean (&dir_copy);
            return;
        }

        if (dir_get_dotdot_stat (vpath, &st))
        {
            file_entry_t *fentry;

            fentry = &list->list[0];
            fentry->st = st;
        }
    }

    while ((dp = mc_readdir (dirp)) != NULL)
    {
        file_entry_t *fentry;

        if (!handle_dirent (dp, fltr, &st, &link_to_dir, &stale_link))
            continue;

        if (!dir_list_append (list, dp->d_name, &st, link_to_dir != 0, stale_link != 0))
        {
            mc_closedir (dirp);
            /* Norbert (Feb 12, 1997):
               Just in case someone finds this memory leak:
               -1 means big trouble (at the moment no memory left),
               I don't bother with further cleanup because if one gets to
               this point he will have more problems than a few memory
               leaks and because one 'dir_list_clean' would not be enough (and
               because I don't want to spent the time to make it working,
               IMHO it's not worthwhile).
               dir_list_clean (&dir_copy);
             */
            tree_store_end_check ();
            g_hash_table_destroy (marked_files);
            return;
        }
        fentry = &list->list[list->len - 1];

        fentry->f.marked = 0;

        /*
         * If we have marked files in the copy, scan through the copy
         * to find matching file.  Decrease number of remaining marks if
         * we copied one.
         */
        if (marked_cnt > 0 && g_hash_table_lookup (marked_files, dp->d_name) != NULL)
        {
            fentry->f.marked = 1;
            marked_cnt--;
        }

        if ((list->len & 15) == 0)
            rotate_dash (TRUE);
    }
    mc_closedir (dirp);
    tree_store_end_check ();
    g_hash_table_destroy (marked_files);

    dir_list_sort (list, sort, sort_op);

    dir_list_clean (&dir_copy);
    rotate_dash (FALSE);
}
Пример #4
0
    int mode = 0, result = -1;
    const vfs_path_element_t *path_element;

    if (vpath == NULL)
        return -1;

    /* Get the mode flag */
    if (flags & O_CREAT)
    {
        va_list ap;
        va_start (ap, flags);
        mode = va_arg (ap, int);
        va_end (ap);
    }

    path_element = vfs_path_get_by_index (vpath, -1);
    if (vfs_path_element_valid (path_element) && path_element->class->open != NULL)
    {
        void *info;
        /* open must be supported */
        info = path_element->class->open (vpath, flags, mode);
        if (info == NULL)
            errno = vfs_ferrno (path_element->class);
        else
            result = vfs_new_handle (path_element->class, info);
    }
    else
        errno = -EOPNOTSUPP;

    return result;
}
Пример #5
0
Файл: dir.c Проект: Chainie/mc
int
do_reload_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, int count,
               gboolean lc_reverse, gboolean lc_case_sensitive, gboolean exec_ff, const char *fltr)
{
    DIR *dirp;
    struct dirent *dp;
    int next_free = 0;
    int i, status, link_to_dir, stale_link;
    struct stat st;
    int marked_cnt;
    GHashTable *marked_files;
    const char *tmp_path;

    dirp = mc_opendir (vpath);
    if (dirp == NULL)
    {
        message (D_ERROR, MSG_ERROR, _("Cannot read directory contents"));
        clean_dir (list, count);
        return set_zero_dir (list) ? 1 : 0;
    }

    tree_store_start_check (vpath);

    marked_files = g_hash_table_new (g_str_hash, g_str_equal);
    alloc_dir_copy (list->size);
    for (marked_cnt = i = 0; i < count; i++)
    {
        dir_copy.list[i].fnamelen = list->list[i].fnamelen;
        dir_copy.list[i].fname = list->list[i].fname;
        dir_copy.list[i].f.marked = list->list[i].f.marked;
        dir_copy.list[i].f.dir_size_computed = list->list[i].f.dir_size_computed;
        dir_copy.list[i].f.link_to_dir = list->list[i].f.link_to_dir;
        dir_copy.list[i].f.stale_link = list->list[i].f.stale_link;
        dir_copy.list[i].sort_key = NULL;
        dir_copy.list[i].second_sort_key = NULL;
        if (list->list[i].f.marked)
        {
            g_hash_table_insert (marked_files, dir_copy.list[i].fname, &dir_copy.list[i]);
            marked_cnt++;
        }
    }

    /* Add ".." except to the root directory. The ".." entry
       (if any) must be the first in the list. */
    tmp_path = vfs_path_get_by_index (vpath, 0)->path;
    if (!
        (vfs_path_elements_count (vpath) == 1 && (tmp_path[0] == PATH_SEP)
         && (tmp_path[1] == '\0')))
    {
        if (!set_zero_dir (list))
        {
            clean_dir (list, count);
            clean_dir (&dir_copy, count);
            return next_free;
        }

        if (get_dotdot_dir_stat (vpath, &st))
            list->list[next_free].st = st;

        next_free++;
    }

    while ((dp = mc_readdir (dirp)))
    {
        status = handle_dirent (list, fltr, dp, &st, next_free, &link_to_dir, &stale_link);
        if (status == 0)
            continue;
        if (status == -1)
        {
            mc_closedir (dirp);
            /* Norbert (Feb 12, 1997):
               Just in case someone finds this memory leak:
               -1 means big trouble (at the moment no memory left),
               I don't bother with further cleanup because if one gets to
               this point he will have more problems than a few memory
               leaks and because one 'clean_dir' would not be enough (and
               because I don't want to spent the time to make it working,
               IMHO it's not worthwhile).
               clean_dir (&dir_copy, count);
             */
            tree_store_end_check ();
            g_hash_table_destroy (marked_files);
            return next_free;
        }

        list->list[next_free].f.marked = 0;

        /*
         * If we have marked files in the copy, scan through the copy
         * to find matching file.  Decrease number of remaining marks if
         * we copied one.
         */
        if (marked_cnt > 0)
        {
            if ((g_hash_table_lookup (marked_files, dp->d_name)))
            {
                list->list[next_free].f.marked = 1;
                marked_cnt--;
            }
        }

        list->list[next_free].fnamelen = NLENGTH (dp);
        list->list[next_free].fname = g_strndup (dp->d_name, list->list[next_free].fnamelen);
        list->list[next_free].f.link_to_dir = link_to_dir;
        list->list[next_free].f.stale_link = stale_link;
        list->list[next_free].f.dir_size_computed = 0;
        list->list[next_free].st = st;
        list->list[next_free].sort_key = NULL;
        list->list[next_free].second_sort_key = NULL;
        next_free++;
        if (!(next_free % 16))
            rotate_dash ();
    }
    mc_closedir (dirp);
    tree_store_end_check ();
    g_hash_table_destroy (marked_files);
    if (next_free)
    {
        do_sort (list, sort, next_free - 1, lc_reverse, lc_case_sensitive, exec_ff);
    }
    clean_dir (&dir_copy, count);
    return next_free;
}
Пример #6
0
Файл: command.c Проект: V07D/mc
void
do_cd_command (char *orig_cmd)
{
    int len;
    int operand_pos = CD_OPERAND_OFFSET;
    const char *cmd;

    /* Any final whitespace should be removed here
       (to see why, try "cd fred "). */
    /* NOTE: I think we should not remove the extra space,
       that way, we can cd into hidden directories */
    /* FIXME: what about interpreting quoted strings like the shell.
       so one could type "cd <tab> M-a <enter>" and it would work. */
    len = strlen (orig_cmd) - 1;
    while (len >= 0 && (orig_cmd[len] == ' ' || orig_cmd[len] == '\t' || orig_cmd[len] == '\n'))
    {
        orig_cmd[len] = 0;
        len--;
    }

    cmd = orig_cmd;
    if (cmd[CD_OPERAND_OFFSET - 1] == 0)
        cmd = "cd ";            /* 0..2 => given text, 3 => \0 */

    /* allow any amount of white space in front of the path operand */
    while (cmd[operand_pos] == ' ' || cmd[operand_pos] == '\t')
        operand_pos++;

    if (get_current_type () == view_tree)
    {
        if (cmd[0] == 0)
        {
            sync_tree (mc_config_get_home_dir ());
        }
        else if (DIR_IS_DOTDOT (cmd + operand_pos))
        {
            if (vfs_path_elements_count (current_panel->cwd_vpath) != 1 ||
                strlen (vfs_path_get_by_index (current_panel->cwd_vpath, 0)->path) > 1)
            {
                vfs_path_t *tmp_vpath = current_panel->cwd_vpath;

                current_panel->cwd_vpath =
                    vfs_path_vtokens_get (tmp_vpath, 0, vfs_path_tokens_count (tmp_vpath) - 1);
                vfs_path_free (tmp_vpath);
            }
            sync_tree (vfs_path_as_str (current_panel->cwd_vpath));
        }
        else if (cmd[operand_pos] == PATH_SEP)
        {
            sync_tree (cmd + operand_pos);
        }
        else
        {
            vfs_path_t *new_vpath;

            new_vpath = vfs_path_append_new (current_panel->cwd_vpath, cmd + operand_pos, NULL);
            sync_tree (vfs_path_as_str (new_vpath));
            vfs_path_free (new_vpath);
        }
    }
    else
    {
        char *path;
        vfs_path_t *q_vpath;
        gboolean ok;

        path = examine_cd (&cmd[operand_pos]);

        if (*path == '\0')
            q_vpath = vfs_path_from_str (mc_config_get_home_dir ());
        else
            q_vpath = vfs_path_from_str_flags (path, VPF_NO_CANON);

        ok = do_cd (q_vpath, cd_parse_command);
        if (!ok)
            ok = handle_cdpath (path);

        if (!ok)
        {
            char *d;

            d = vfs_path_to_str_flags (q_vpath, 0, VPF_STRIP_PASSWORD);
            message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\"\n%s"), d,
                     unix_error_string (errno));
            g_free (d);
        }

        vfs_path_free (q_vpath);
        g_free (path);
    }
}
Пример #7
0
Файл: lock.c Проект: BrEacK/mc
int
lock_file (const vfs_path_t * fname_vpath)
{
    char *lockfname = NULL, *newlock, *msg, *lock;
    struct stat statbuf;
    struct lock_s *lockinfo;
    gboolean is_local;
    gboolean symlink_ok = FALSE;
    const char *elpath;

    if (fname_vpath == NULL)
        return 0;

    elpath = vfs_path_get_by_index (fname_vpath, 0)->path;
    /* Just to be sure (and don't lock new file) */
    if (*elpath == '\0')
        return 0;

    /* Locking on VFS is not supported */
    is_local = vfs_file_is_local (fname_vpath);
    if (is_local)
    {
        /* Check if already locked */
        lockfname = lock_build_symlink_name (fname_vpath);
    }

    if (!is_local || lockfname == NULL)
        return 0;

    if (lstat (lockfname, &statbuf) == 0)
    {
        lock = lock_get_info (lockfname);
        if (lock == NULL)
            goto ret;
        lockinfo = lock_extract_info (lock);

        /* Check if locking process alive, ask user if required */
        if (lockinfo->pid == 0 || !(kill (lockinfo->pid, 0) == -1 && errno == ESRCH))
        {
            msg =
                g_strdup_printf (_
                                 ("File \"%s\" is already being edited.\n"
                                  "User: %s\nProcess ID: %d"), x_basename (lockfname) + 2,
                                 lockinfo->who, (int) lockinfo->pid);
            /* TODO: Implement "Abort" - needs to rewind undo stack */
            switch (query_dialog
                    (_("File locked"), msg, D_NORMAL, 2, _("&Grab lock"), _("&Ignore lock")))
            {
            case 0:
                break;
            case 1:
            case -1:
                g_free (msg);
                goto ret;
                break;          /* FIXME: unneeded? */
            }
            g_free (msg);
        }
        unlink (lockfname);
    }

    /* Create lock symlink */
    newlock = lock_build_name ();
    symlink_ok = (symlink (newlock, lockfname) != -1);
    g_free (newlock);

  ret:
    g_free (lockfname);
    return symlink_ok ? 1 : 0;
}
Пример #8
0
int
sftpfs_chmod (const vfs_path_t * vpath, mode_t mode, GError ** mcerror)
{
    struct vfs_s_super *super;
    sftpfs_super_data_t *super_data;
    LIBSSH2_SFTP_ATTRIBUTES attrs;
    int res;
    const vfs_path_element_t *path_element;

    mc_return_val_if_error (mcerror, -1);

    path_element = vfs_path_get_by_index (vpath, -1);

    if (vfs_s_get_path (vpath, &super, 0) == NULL)
        return -1;

    if (super == NULL)
        return -1;

    super_data = (sftpfs_super_data_t *) super->data;
    if (super_data->sftp_session == NULL)
        return -1;

    do
    {
        const char *fixfname;

        fixfname = sftpfs_fix_filename (path_element->path);

        res = libssh2_sftp_stat_ex (super_data->sftp_session, fixfname,
                                    sftpfs_filename_buffer->len, LIBSSH2_SFTP_LSTAT, &attrs);
        if (res >= 0)
            break;

        if (res != LIBSSH2_ERROR_EAGAIN)
        {
            sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
            return -1;
        }

        sftpfs_waitsocket (super_data, mcerror);
        mc_return_val_if_error (mcerror, -1);
    }
    while (res == LIBSSH2_ERROR_EAGAIN);

    attrs.permissions = mode;

    do
    {
        const char *fixfname;

        fixfname = sftpfs_fix_filename (path_element->path);

        res = libssh2_sftp_stat_ex (super_data->sftp_session, fixfname,
                                    sftpfs_filename_buffer->len, LIBSSH2_SFTP_SETSTAT, &attrs);
        if (res >= 0)
            break;
        else if (res != LIBSSH2_ERROR_EAGAIN)
        {
            sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
            return -1;
        }

        sftpfs_waitsocket (super_data, mcerror);
        mc_return_val_if_error (mcerror, -1);
    }
    while (res == LIBSSH2_ERROR_EAGAIN);
    return res;
}
Пример #9
0
int
sftpfs_stat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror)
{
    struct vfs_s_super *super;
    sftpfs_super_data_t *super_data;
    LIBSSH2_SFTP_ATTRIBUTES attrs;
    int res;
    const vfs_path_element_t *path_element;

    mc_return_val_if_error (mcerror, -1);

    path_element = vfs_path_get_by_index (vpath, -1);

    if (vfs_s_get_path (vpath, &super, 0) == NULL)
        return -1;

    if (super == NULL)
        return -1;

    super_data = (sftpfs_super_data_t *) super->data;
    if (super_data->sftp_session == NULL)
        return -1;

    do
    {
        const char *fixfname;

        fixfname = sftpfs_fix_filename (path_element->path);

        res =
            libssh2_sftp_stat_ex (super_data->sftp_session,
                                  fixfname, sftpfs_filename_buffer->len, LIBSSH2_SFTP_STAT, &attrs);
        if (res >= 0)
            break;

        if (res != LIBSSH2_ERROR_EAGAIN)
        {
            sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
            return -1;
        }

        sftpfs_waitsocket (super_data, mcerror);
        mc_return_val_if_error (mcerror, -1);
    }
    while (res == LIBSSH2_ERROR_EAGAIN);

    buf->st_nlink = 1;
    if ((attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID) != 0)
    {
        buf->st_uid = attrs.uid;
        buf->st_gid = attrs.gid;
    }

    if ((attrs.flags & LIBSSH2_SFTP_ATTR_ACMODTIME) != 0)
    {
        buf->st_atime = attrs.atime;
        buf->st_mtime = attrs.mtime;
        buf->st_ctime = attrs.mtime;
    }

    if ((attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) != 0)
        buf->st_size = attrs.filesize;

    if ((attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) != 0)
        buf->st_mode = attrs.permissions;

    return 0;
}