static int my_mkdir_rec (const vfs_path_t * s_vpath, mode_t mode) { vfs_path_t *q; int result; if (mc_mkdir (s_vpath, mode) == 0) return 0; if (errno != ENOENT) return (-1); /* FIXME: should check instead if s_vpath is at the root of that filesystem */ if (!vfs_file_is_local (s_vpath)) return (-1); if (strcmp (vfs_path_as_str (s_vpath), PATH_SEP_STR) == 0) { errno = ENOTDIR; return (-1); } q = vfs_path_append_new (s_vpath, "..", NULL); result = my_mkdir_rec (q, mode); vfs_path_free (q); if (result == 0) result = mc_mkdir (s_vpath, mode); return result; }
void mkdir_cmd (void) { char *dir; const char *name = ""; /* If 'on' then automatically fills name with current selected item name */ if (auto_fill_mkdir_name && !DIR_IS_DOTDOT (selection (current_panel)->fname)) name = selection (current_panel)->fname; dir = input_expand_dialog (_("Create a new Directory"), _("Enter directory name:"), MC_HISTORY_FM_MKDIR, name, INPUT_COMPLETE_FILENAMES); if (dir != NULL && *dir != '\0') { vfs_path_t *absdir; if (dir[0] == '/' || dir[0] == '~') absdir = vfs_path_from_str (dir); else { /* possible escaped '~' */ /* allow create directory with name '~' */ char *tmpdir = dir; if (dir[0] == '\\' && dir[1] == '~') tmpdir = dir + 1; absdir = vfs_path_append_new (current_panel->cwd_vpath, tmpdir, NULL); } save_cwds_stat (); if (my_mkdir (absdir, 0777) == 0) { update_panels (UP_OPTIMIZE, dir); repaint_screen (); select_item (current_panel); } else { message (D_ERROR, MSG_ERROR, "%s", unix_error_string (errno)); } vfs_path_free (absdir); } g_free (dir); }
static gboolean dir_get_dotdot_stat (const vfs_path_t * vpath, struct stat *st) { gboolean ret = FALSE; if ((vpath != NULL) && (st != NULL)) { const char *path; path = vfs_path_get_by_index (vpath, 0)->path; if (path != NULL && *path != '\0') { vfs_path_t *tmp_vpath; tmp_vpath = vfs_path_append_new (vpath, "..", (char *) NULL); ret = mc_stat (tmp_vpath, st) == 0; vfs_path_free (tmp_vpath); } } return ret; }
static void do_link (link_type_t link_type, const char *fname) { char *dest = NULL, *src = NULL; vfs_path_t *fname_vpath, *dest_vpath = NULL; fname_vpath = vfs_path_from_str (fname); if (link_type == LINK_HARDLINK) { src = g_strdup_printf (_("Link %s to:"), str_trunc (fname, 46)); dest = input_expand_dialog (_("Link"), src, MC_HISTORY_FM_LINK, "", INPUT_COMPLETE_FILENAMES); if (!dest || !*dest) goto cleanup; save_cwds_stat (); dest_vpath = vfs_path_from_str (dest); if (-1 == mc_link (fname_vpath, dest_vpath)) message (D_ERROR, MSG_ERROR, _("link: %s"), unix_error_string (errno)); } else { vfs_path_t *s, *d; /* suggest the full path for symlink, and either the full or relative path to the file it points to */ s = vfs_path_append_new (current_panel->cwd_vpath, fname, NULL); if (get_other_type () == view_listing) d = vfs_path_append_new (other_panel->cwd_vpath, fname, NULL); else d = vfs_path_from_str (fname); if (link_type == LINK_SYMLINK_RELATIVE) { char *s_str; s_str = diff_two_paths (other_panel->cwd_vpath, s); vfs_path_free (s); s = vfs_path_from_str_flags (s_str, VPF_NO_CANON); g_free (s_str); } symlink_dialog (s, d, &dest, &src); vfs_path_free (d); vfs_path_free (s); if (!dest || !*dest || !src || !*src) goto cleanup; save_cwds_stat (); dest_vpath = vfs_path_from_str_flags (dest, VPF_NO_CANON); s = vfs_path_from_str (src); if (mc_symlink (dest_vpath, s) == -1) message (D_ERROR, MSG_ERROR, _("symlink: %s"), unix_error_string (errno)); vfs_path_free (s); } update_panels (UP_OPTIMIZE, UP_KEEPSEL); repaint_screen (); cleanup: vfs_path_free (fname_vpath); vfs_path_free (dest_vpath); g_free (src); g_free (dest); }
static void compare_dir (WPanel * panel, WPanel * other, enum CompareMode mode) { int i, j; /* No marks by default */ panel->marked = 0; panel->total = 0; panel->dirs_marked = 0; /* Handle all files in the panel */ for (i = 0; i < panel->dir.len; i++) { file_entry_t *source = &panel->dir.list[i]; /* Default: unmarked */ file_mark (panel, i, 0); /* Skip directories */ if (S_ISDIR (source->st.st_mode)) continue; /* Search the corresponding entry from the other panel */ for (j = 0; j < other->dir.len; j++) { if (strcmp (source->fname, other->dir.list[j].fname) == 0) break; } if (j >= other->dir.len) /* Not found -> mark */ do_file_mark (panel, i, 1); else { /* Found */ file_entry_t *target = &other->dir.list[j]; if (mode != compare_size_only) { /* Older version is not marked */ if (source->st.st_mtime < target->st.st_mtime) continue; } /* Newer version with different size is marked */ if (source->st.st_size != target->st.st_size) { do_file_mark (panel, i, 1); continue; } if (mode == compare_size_only) continue; if (mode == compare_quick) { /* Thorough compare off, compare only time stamps */ /* Mark newer version, don't mark version with the same date */ if (source->st.st_mtime > target->st.st_mtime) { do_file_mark (panel, i, 1); } continue; } /* Thorough compare on, do byte-by-byte comparison */ { vfs_path_t *src_name, *dst_name; src_name = vfs_path_append_new (panel->cwd_vpath, source->fname, NULL); dst_name = vfs_path_append_new (other->cwd_vpath, target->fname, NULL); if (compare_files (src_name, dst_name, source->st.st_size)) do_file_mark (panel, i, 1); vfs_path_free (src_name); vfs_path_free (dst_name); } } } /* for (i ...) */ }
gboolean mcview_load (mcview_t * view, const char *command, const char *file, int start_line) { gboolean retval = FALSE; vfs_path_t *vpath = NULL; #ifdef HAVE_ASSERT_H assert (view->bytes_per_line != 0); #endif view->filename_vpath = vfs_path_from_str (file); /* get working dir */ if (file != NULL && file[0] != '\0') { vfs_path_free (view->workdir_vpath); if (!g_path_is_absolute (file)) { vfs_path_t *p; p = vfs_path_clone (vfs_get_raw_current_dir ()); view->workdir_vpath = vfs_path_append_new (p, file, (char *) NULL); vfs_path_free (p); } else { /* try extract path form filename */ const char *fname; char *dir; fname = x_basename (file); dir = g_strndup (file, (size_t) (fname - file)); view->workdir_vpath = vfs_path_from_str (dir); g_free (dir); } } if (!mcview_is_in_panel (view)) view->dpy_text_column = 0; mcview_set_codeset (view); if (command != NULL && (view->magic_mode || file == NULL || file[0] == '\0')) retval = mcview_load_command_output (view, command); else if (file != NULL && file[0] != '\0') { int fd; char tmp[BUF_MEDIUM]; struct stat st; /* Open the file */ vpath = vfs_path_from_str (file); fd = mc_open (vpath, O_RDONLY | O_NONBLOCK); if (fd == -1) { g_snprintf (tmp, sizeof (tmp), _("Cannot open \"%s\"\n%s"), file, unix_error_string (errno)); mcview_show_error (view, tmp); vfs_path_free (view->filename_vpath); view->filename_vpath = NULL; vfs_path_free (view->workdir_vpath); view->workdir_vpath = NULL; goto finish; } /* Make sure we are working with a regular file */ if (mc_fstat (fd, &st) == -1) { mc_close (fd); g_snprintf (tmp, sizeof (tmp), _("Cannot stat \"%s\"\n%s"), file, unix_error_string (errno)); mcview_show_error (view, tmp); vfs_path_free (view->filename_vpath); view->filename_vpath = NULL; vfs_path_free (view->workdir_vpath); view->workdir_vpath = NULL; goto finish; } if (!S_ISREG (st.st_mode)) { mc_close (fd); mcview_show_error (view, _("Cannot view: not a regular file")); vfs_path_free (view->filename_vpath); view->filename_vpath = NULL; vfs_path_free (view->workdir_vpath); view->workdir_vpath = NULL; goto finish; } if (st.st_size == 0 || mc_lseek (fd, 0, SEEK_SET) == -1) { /* Must be one of those nice files that grow (/proc) */ mcview_set_datasource_vfs_pipe (view, fd); } else { int type; type = get_compression_type (fd, file); if (view->magic_mode && (type != COMPRESSION_NONE)) { char *tmp_filename; vfs_path_t *vpath1; int fd1; tmp_filename = g_strconcat (file, decompress_extension (type), (char *) NULL); vpath1 = vfs_path_from_str (tmp_filename); fd1 = mc_open (vpath1, O_RDONLY | O_NONBLOCK); if (fd1 == -1) { g_snprintf (tmp, sizeof (tmp), _("Cannot open \"%s\" in parse mode\n%s"), file, unix_error_string (errno)); mcview_show_error (view, tmp); } else { mc_close (fd); fd = fd1; mc_fstat (fd, &st); } vfs_path_free (vpath1); g_free (tmp_filename); } mcview_set_datasource_file (view, fd, &st); } retval = TRUE; } finish: view->command = g_strdup (command); view->dpy_start = 0; view->search_start = 0; view->search_end = 0; view->dpy_text_column = 0; mcview_compute_areas (view); mcview_update_bytes_per_line (view); if (mcview_remember_file_position && view->filename_vpath != NULL && start_line == 0) { long line, col; off_t new_offset, max_offset; load_file_position (view->filename_vpath, &line, &col, &new_offset, &view->saved_bookmarks); max_offset = mcview_get_filesize (view) - 1; if (max_offset < 0) new_offset = 0; else new_offset = min (new_offset, max_offset); if (!view->hex_mode) view->dpy_start = mcview_bol (view, new_offset, 0); else { view->dpy_start = new_offset - new_offset % view->bytes_per_line; view->hex_cursor = new_offset; } } else if (start_line > 0) mcview_moveto (view, start_line - 1, 0); view->hexedit_lownibble = FALSE; view->hexview_in_text = FALSE; view->change_list = NULL; vfs_path_free (vpath); return retval; }
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); } }