/* *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); }
/* *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); } }
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); }
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; }
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; }
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); } }
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; }
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; }
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; }