static void tree_rmdir (void *data) { WTree *tree = data; FileOpContext *ctx; FileOpTotalContext *tctx; if (!tree->selected_ptr) return; if (confirm_delete) { char *buf; int result; char *selected_ptr_name; selected_ptr_name = vfs_path_to_str (tree->selected_ptr->name); buf = g_strdup_printf (_("Delete %s?"), selected_ptr_name); g_free (selected_ptr_name); result = query_dialog (Q_ ("DialogTitle|Delete"), buf, D_ERROR, 2, _("&Yes"), _("&No")); g_free (buf); if (result != 0) return; } ctx = file_op_context_new (OP_DELETE); tctx = file_op_total_context_new (); file_op_context_create_ui (ctx, FALSE, FILEGUI_DIALOG_ONE_ITEM); if (erase_dir (tctx, ctx, tree->selected_ptr->name) == FILE_CONT) tree_forget (tree); file_op_total_context_destroy (tctx); file_op_context_destroy (ctx); }
static void tree_copy (WTree * tree, const char *default_dest) { char msg[BUF_MEDIUM]; char *dest, *selected_ptr_name; if (tree->selected_ptr == NULL) return; selected_ptr_name = vfs_path_to_str (tree->selected_ptr->name); g_snprintf (msg, sizeof (msg), _("Copy \"%s\" directory to:"), str_trunc (selected_ptr_name, 50)); dest = input_expand_dialog (Q_ ("DialogTitle|Copy"), msg, MC_HISTORY_FM_TREE_COPY, default_dest); if (dest != NULL && *dest != '\0') { FileOpContext *ctx; FileOpTotalContext *tctx; ctx = file_op_context_new (OP_COPY); tctx = file_op_total_context_new (); file_op_context_create_ui (ctx, FALSE, FILEGUI_DIALOG_MULTI_ITEM); tctx->ask_overwrite = FALSE; copy_dir_dir (tctx, ctx, selected_ptr_name, dest, TRUE, FALSE, FALSE, NULL); file_op_total_context_destroy (tctx); file_op_context_destroy (ctx); } g_free (dest); g_free (selected_ptr_name); }
/* *INDENT-OFF* */ END_TEST /* *INDENT-ON* */ /* --------------------------------------------------------------------------------------------- */ /* @Test */ /* *INDENT-OFF* */ START_TEST (test_mc_mkstemps) /* *INDENT-ON* */ { /* given */ vfs_path_t *pname_vpath = NULL; char *pname = NULL; char *begin_pname; int fd; /* when */ fd = mc_mkstemps (&pname_vpath, "mctest-", NULL); if (fd != -1) pname = vfs_path_to_str (pname_vpath); begin_pname = g_build_filename (mc_tmpdir (), "mctest-", NULL); /* then */ vfs_path_free (pname_vpath); close (fd); mctest_assert_int_ne (fd, -1); fail_unless (g_file_test (pname, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR), "\nNo such file: %s\n", pname); unlink (pname); fail_unless (strncmp (pname, begin_pname, strlen (begin_pname)) == 0, "\nstart of %s should be equal to %s\n", pname, begin_pname); g_free (pname); }
void file_progress_show_target (FileOpContext * ctx, const vfs_path_t * s_vpath) { FileOpContextUI *ui; g_return_if_fail (ctx != NULL); g_return_if_fail (ctx->ui != NULL); ui = ctx->ui; if (s_vpath != NULL) { char *s; s = vfs_path_to_str (s_vpath); label_set_text (ui->file_label[1], _("Target")); label_set_text (ui->file_string[1], truncFileStringSecure (ui, s)); g_free (s); } else { label_set_text (ui->file_label[1], ""); label_set_text (ui->file_string[1], ""); } }
END_TEST /* --------------------------------------------------------------------------------------------- */ START_TEST(test_encode_info_at_start) { vfs_path_t *vpath; char *actual; const vfs_path_element_t *vpath_element; test_init_vfs("UTF-8"); vpath = vfs_path_from_str ("#enc:KOI8-R/bla-bla/some/path"); actual = vfs_path_to_str (vpath); fail_unless (strcmp ("/#enc:KOI8-R/bla-bla/some/path", actual) == 0, "\nactual=%s\n", actual); vpath_element = vfs_path_get_by_index (vpath, -1); fail_unless (strcmp ("/bla-bla/some/path", vpath_element->path) == 0, "\nvpath_element->path=%s\n", vpath_element->path); g_free (actual); vfs_path_free (vpath); test_deinit_vfs(); }
END_TEST /* --------------------------------------------------------------------------------------------- */ #define ETALON_STR "/path/to/file.ext/test1://#enc:KOI8-R" START_TEST (test_vfs_path_encoding_at_end) { vfs_path_t *vpath; char *result; const vfs_path_element_t *element; mc_global.sysconfig_dir = (char *) TEST_SHARE_DIR; load_codepages_list (); vpath = vfs_path_from_str_flags ("/path/to/file.ext#test1:/#enc:KOI8-R", VPF_USE_DEPRECATED_PARSER); result = vfs_path_to_str(vpath); element = vfs_path_get_by_index(vpath, -1); fail_unless(*element->path == '\0', "element->path should be empty, but actual value is '%s'",element->path); fail_unless(element->encoding != NULL && strcmp(element->encoding, "KOI8-R") == 0, "element->encoding should be 'KOI8-R', but actual value is '%s'",element->encoding); fail_unless( result != NULL && strcmp(result, ETALON_STR) ==0, "\nactual: %s\netalon: %s", result , ETALON_STR ); g_free(result); vfs_path_free(vpath); free_codepages_list (); }
END_TEST /* --------------------------------------------------------------------------------------------- */ START_TEST (test_vfs_path_from_to_string2) { vfs_path_t *vpath; size_t vpath_len; char *result; const vfs_path_element_t *path_element; vpath = vfs_path_from_str ("/"); vpath_len = vfs_path_elements_count(vpath); fail_unless(vpath_len == 1, "vpath length should be 1 (actial: %d)",vpath_len); result = vfs_path_to_str(vpath); fail_unless(strcmp("/", result) == 0, "expected(%s) doesn't equal to actual(%s)", "/", result); g_free(result); path_element = vfs_path_get_by_index (vpath, -1); fail_unless(strcmp("/", path_element->path) == 0, "expected(%s) doesn't equal to actual(%s)", "/", path_element->path); fail_unless(path_element->class == &vfs_local_ops , "actual vfs-class doesn't equal to localfs"); vfs_path_free(vpath); }
int invoke_subshell (const char *command, int how, vfs_path_t ** new_dir_vpath) { char *pcwd; /* Make the MC terminal transparent */ tcsetattr (STDOUT_FILENO, TCSANOW, &raw_mode); /* Make the subshell change to MC's working directory */ if (new_dir_vpath != NULL) do_subshell_chdir (current_panel->cwd_vpath, TRUE, TRUE); if (command == NULL) /* The user has done "C-o" from MC */ { if (subshell_state == INACTIVE) { subshell_state = ACTIVE; /* FIXME: possibly take out this hack; the user can re-play it by hitting C-hyphen a few times! */ if (subshell_ready) write_all (mc_global.tty.subshell_pty, " \b", 2); /* Hack to make prompt reappear */ } } else /* MC has passed us a user command */ { if (how == QUIETLY) write_all (mc_global.tty.subshell_pty, " ", 1); /* FIXME: if command is long (>8KB ?) we go comma */ write_all (mc_global.tty.subshell_pty, command, strlen (command)); write_all (mc_global.tty.subshell_pty, "\n", 1); subshell_state = RUNNING_COMMAND; subshell_ready = FALSE; } feed_subshell (how, FALSE); { char *cwd_str; cwd_str = vfs_path_to_str (current_panel->cwd_vpath); pcwd = vfs_translate_path_n (cwd_str); g_free (cwd_str); } if (new_dir_vpath != NULL && subshell_alive && strcmp (subshell_cwd, pcwd)) *new_dir_vpath = vfs_path_from_str (subshell_cwd); /* Make MC change to the subshell's CWD */ g_free (pcwd); /* Restart the subshell if it has died by SIGHUP, SIGQUIT, etc. */ while (!subshell_alive && quit == 0 && mc_global.tty.use_subshell) init_subshell (); prompt_pos = 0; return quit; }
static char * sftpfs_correct_file_name (const char *filename) { vfs_path_t *vpath; char *ret_value; vpath = vfs_path_from_str (filename); ret_value = vfs_path_to_str (vpath); vfs_path_free (vpath); return ret_value; }
static void edit_window_list (const Dlg_head * h) { const size_t offset = 2; /* skip menu and buttonbar */ const size_t dlg_num = g_list_length (h->widgets) - offset; int lines, cols; Listbox *listbox; GList *w; int i = 0; int rv; lines = min ((size_t) (LINES * 2 / 3), dlg_num); cols = COLS * 2 / 3; listbox = create_listbox_window (lines, cols, _("Open files"), "[Open files]"); for (w = h->widgets; w != NULL; w = g_list_next (w)) if (edit_widget_is_editor ((Widget *) w->data)) { WEdit *e = (WEdit *) w->data; char *fname; if (e->filename_vpath == NULL) fname = g_strdup_printf ("%c [%s]", e->modified ? '*' : ' ', _("NoName")); else { char *fname2; fname2 = vfs_path_to_str (e->filename_vpath); fname = g_strdup_printf ("%c%s", e->modified ? '*' : ' ', fname2); g_free (fname2); } listbox_add_item (listbox->list, LISTBOX_APPEND_AT_END, get_hotkey (i++), str_term_trim (fname, listbox->list->widget.cols - 2), NULL); g_free (fname); } rv = g_list_position (h->widgets, h->current) - offset; listbox_select_entry (listbox->list, rv); rv = run_listbox (listbox); if (rv >= 0) { w = g_list_nth (h->widgets, rv + offset); dlg_set_top_widget (w->data); } }
static void tree_move (WTree * tree, const char *default_dest) { char msg[BUF_MEDIUM]; char *dest, *selected_ptr_name; struct stat buf; FileOpContext *ctx; FileOpTotalContext *tctx; if (tree->selected_ptr == NULL) return; selected_ptr_name = vfs_path_to_str (tree->selected_ptr->name); g_snprintf (msg, sizeof (msg), _("Move \"%s\" directory to:"), str_trunc (selected_ptr_name, 50)); dest = input_expand_dialog (Q_ ("DialogTitle|Move"), msg, MC_HISTORY_FM_TREE_MOVE, default_dest); if (dest == NULL || *dest == '\0') goto ret; if (stat (dest, &buf)) { message (D_ERROR, MSG_ERROR, _("Cannot stat the destination\n%s"), unix_error_string (errno)); goto ret; } if (!S_ISDIR (buf.st_mode)) { file_error (_("Destination \"%s\" must be a directory\n%s"), dest); goto ret; } ctx = file_op_context_new (OP_MOVE); tctx = file_op_total_context_new (); file_op_context_create_ui (ctx, FALSE, FILEGUI_DIALOG_ONE_ITEM); move_dir_dir (tctx, ctx, selected_ptr_name, dest); file_op_total_context_destroy (tctx); file_op_context_destroy (ctx); ret: g_free (selected_ptr_name); g_free (dest); }
static char * edit_get_title (const Dlg_head * h, size_t len) { const WEdit *edit = find_editor (h); const char *modified = edit->modified ? "(*) " : " "; const char *file_label; char *filename; len -= 4; filename = vfs_path_to_str (edit->filename_vpath); if (filename == NULL) filename = g_strdup (_("[NoName]")); file_label = str_term_trim (filename, len - str_term_width1 (_("Edit: "))); g_free (filename); return g_strconcat (_("Edit: "), modified, file_label, (char *) NULL); }
END_TEST /* --------------------------------------------------------------------------------------------- */ #undef ETALON_PATH_STR #define ETALON_PATH_STR "/test1://bla-bla/some/path/test2://user:[email protected]:1234/bla-bla/some/path/test3://111/22/33" START_TEST (test_vfs_path_from_to_string_uri) { vfs_path_t *vpath; size_t vpath_len; char *result; vpath = vfs_path_from_str (ETALON_PATH_STR); vpath_len = vfs_path_elements_count(vpath); fail_unless(vpath_len == 4, "vpath length should be 4 (actial: %d)",vpath_len); result = vfs_path_to_str(vpath); fail_unless(strcmp(ETALON_PATH_STR, result) == 0, "\nexpected(%s)\ndoesn't equal to actual(%s)", ETALON_PATH_STR, result); g_free(result); vfs_path_free(vpath); }
static void tree_chdir_sel (WTree * tree) { char *tmp_path; if (!tree->is_panel) return; change_panel (); tmp_path = vfs_path_to_str (tree->selected_ptr->name); if (do_cd (tree->selected_ptr->name, cd_exact)) select_item (current_panel); else message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\"\n%s"), tmp_path, unix_error_string (errno)); g_free (tmp_path); change_panel (); show_tree (tree); }
static void tree_show_mini_info (WTree * tree, int tree_lines, int tree_cols) { Dlg_head *h = tree->widget.owner; int line; /* Show mini info */ if (tree->is_panel) { if (!panels_options.show_mini_info) return; line = tree_lines + 2; } else line = tree_lines + 1; if (tree->searching) { /* Show search string */ tty_setcolor (INPUT_COLOR); tty_draw_hline (tree->widget.y + line, tree->widget.x + 1, ' ', tree_cols); widget_move (&tree->widget, line, 1); tty_print_char (PATH_SEP); tty_print_string (str_fit_to_term (tree->search_buffer, tree_cols - 2, J_LEFT_FIT)); tty_print_char (' '); } else { /* Show full name of selected directory */ char *tmp_path; tty_setcolor (tree->is_panel ? NORMAL_COLOR : TREE_NORMALC (h)); tty_draw_hline (tree->widget.y + line, tree->widget.x + 1, ' ', tree_cols); widget_move (&tree->widget, line, 1); tmp_path = vfs_path_to_str (tree->selected_ptr->name); tty_print_string (str_fit_to_term (tmp_path, tree_cols, J_LEFT_FIT)); g_free (tmp_path); } }
/* *INDENT-OFF* */ START_PARAMETRIZED_TEST (test_path_recode, test_path_recode_ds) /* *INDENT-ON* */ { /* given */ vfs_path_t *vpath; char *result; const vfs_path_element_t *element; test_init_vfs (data->input_codepage); /* when */ vpath = vfs_path_from_str (data->input_path); element = vfs_path_get_by_index (vpath, -1); result = vfs_path_to_str (vpath); /* then */ mctest_assert_str_eq (element->path, data->expected_element_path); mctest_assert_str_eq (result, data->expected_recoded_path); g_free (result); vfs_path_free (vpath); test_deinit_vfs (); }
gboolean mcview_viewer (const char *command, const vfs_path_t * file_vpath, int start_line) { gboolean succeeded; mcview_t *lc_mcview; WDialog *view_dlg; /* Create dialog and widgets, put them on the dialog */ view_dlg = create_dlg (FALSE, 0, 0, LINES, COLS, NULL, mcview_dialog_callback, NULL, "[Internal File Viewer]", NULL, DLG_WANT_TAB); lc_mcview = mcview_new (0, 0, LINES - 1, COLS, FALSE); add_widget (view_dlg, lc_mcview); add_widget (view_dlg, buttonbar_new (TRUE)); view_dlg->get_title = mcview_get_title; { char *file; file = vfs_path_to_str (file_vpath); succeeded = mcview_load (lc_mcview, command, file, start_line); g_free (file); } if (succeeded) run_dlg (view_dlg); else view_dlg->state = DLG_CLOSED; if (view_dlg->state == DLG_CLOSED) destroy_dlg (view_dlg); return succeeded; }
int do_load_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, gboolean lc_reverse, gboolean lc_case_sensitive, gboolean exec_ff, const char *fltr) { DIR *dirp; struct dirent *dp; int status, link_to_dir, stale_link; int next_free = 0; struct stat st; char *path; /* ".." (if any) must be the first entry in the list */ if (!set_zero_dir (list)) return next_free; if (get_dotdot_dir_stat (vpath, &st)) list->list[next_free].st = st; next_free++; dirp = mc_opendir (vpath); if (dirp == NULL) { message (D_ERROR, MSG_ERROR, _("Cannot read directory contents")); return next_free; } tree_store_start_check (vpath); /* Do not add a ".." entry to the root directory */ path = vfs_path_to_str (vpath); if ((path[0] == PATH_SEP) && (path[1] == '\0')) next_free--; g_free (path); while ((dp = mc_readdir (dirp)) != NULL) { status = handle_dirent (list, fltr, dp, &st, next_free, &link_to_dir, &stale_link); if (status == 0) continue; if (status == -1) goto ret; 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.marked = 0; 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 & 31) == 0) rotate_dash (); } if (next_free != 0) do_sort (list, sort, next_free - 1, lc_reverse, lc_case_sensitive, exec_ff); ret: mc_closedir (dirp); tree_store_end_check (); return next_free; }
static void exec_extension (const vfs_path_t * filename_vpath, const char *lc_data, int start_line) { char *shell_string, *export_variables; vfs_path_t *temp_file_name_vpath = NULL; int cmd_file_fd; FILE *cmd_file; char *cmd = NULL; g_return_if_fail (lc_data != NULL); pbuffer = NULL; localmtime = 0; quote_func = name_quote; run_view = FALSE; is_cd = FALSE; written_nonspace = FALSE; /* Avoid making a local copy if we are doing a cd */ do_local_copy = !vfs_file_is_local (filename_vpath); shell_string = exec_make_shell_string (lc_data, filename_vpath); if (shell_string == NULL) goto ret; if (is_cd) { exec_extension_cd (); g_free (shell_string); goto ret; } /* * All commands should be run in /bin/sh regardless of user shell. * To do that, create temporary shell script and run it. * Sometimes it's not needed (e.g. for %cd and %view commands), * but it's easier to create it anyway. */ cmd_file_fd = mc_mkstemps (&temp_file_name_vpath, "mcext", SCRIPT_SUFFIX); if (cmd_file_fd == -1) { message (D_ERROR, MSG_ERROR, _("Cannot create temporary command file\n%s"), unix_error_string (errno)); goto ret; } cmd_file = fdopen (cmd_file_fd, "w"); fputs ("#! /bin/sh\n\n", cmd_file); export_variables = exec_get_export_variables (filename_vpath); if (export_variables != NULL) { fprintf (cmd_file, "%s\n", export_variables); g_free (export_variables); } fputs (shell_string, cmd_file); g_free (shell_string); /* * Make the script remove itself when it finishes. * Don't do it for the viewer - it may need to rerun the script, * so we clean up after calling view(). */ if (!run_view) { char *file_name; file_name = vfs_path_to_str (temp_file_name_vpath); fprintf (cmd_file, "\n/bin/rm -f %s\n", file_name); g_free (file_name); } fclose (cmd_file); if ((run_view && !written_nonspace) || is_cd) { mc_unlink (temp_file_name_vpath); vfs_path_free (temp_file_name_vpath); temp_file_name_vpath = NULL; } else { char *file_name; file_name = vfs_path_to_str (temp_file_name_vpath); /* Set executable flag on the command file ... */ mc_chmod (temp_file_name_vpath, S_IRWXU); /* ... but don't rely on it - run /bin/sh explicitly */ cmd = g_strconcat ("/bin/sh ", file_name, (char *) NULL); g_free (file_name); } if (run_view) exec_extension_view (cmd, filename_vpath, start_line, temp_file_name_vpath); else { shell_execute (cmd, EXECUTE_INTERNAL); if (mc_global.tty.console_flag != '\0') { handle_console (CONSOLE_SAVE); if (output_lines && mc_global.keybar_visible) show_console_contents (output_start_y, LINES - mc_global.keybar_visible - output_lines - 1, LINES - mc_global.keybar_visible - 1); } } g_free (cmd); exec_cleanup_file_name (filename_vpath, TRUE); ret: vfs_path_free (temp_file_name_vpath); }
static inline void edit_status_window (WEdit * edit) { int y, x; int cols = edit->widget.cols; tty_setcolor (STATUSBAR_COLOR); if (cols > 5) { const char *fname = N_("NoName"); char *full_fname = NULL; if (edit->filename_vpath != NULL) { full_fname = vfs_path_to_str (edit->filename_vpath); fname = x_basename (full_fname); } #ifdef ENABLE_NLS else fname = _(fname); #endif edit_move (2, 0); tty_printf ("[%s]", str_term_trim (fname, edit->widget.cols - 8 - 6)); g_free (full_fname); } tty_getyx (&y, &x); x -= edit->widget.x; x += 4; if (x + 6 <= cols - 2 - 6) { edit_move (x, 0); tty_printf ("[%c%c%c%c]", edit->mark1 != edit->mark2 ? (edit->column_highlight ? 'C' : 'B') : '-', edit->modified ? 'M' : '-', macro_index < 0 ? '-' : 'R', edit->overwrite == 0 ? '-' : 'O'); } if (cols > 30) { edit_move (2, edit->widget.lines - 1); tty_printf ("%3ld %5ld/%ld %6ld/%ld", edit->curs_col + edit->over_col, edit->curs_line + 1, edit->total_lines + 1, edit->curs1, edit->last_byte); } /* * If we are at the end of file, print <EOF>, * otherwise print the current character as is (if printable), * as decimal and as hex. */ if (cols > 46) { edit_move (32, edit->widget.lines - 1); if (edit->curs1 >= edit->last_byte) tty_print_string ("[<EOF> ]"); #ifdef HAVE_CHARSET else if (edit->utf8) { unsigned int cur_utf; int cw = 1; cur_utf = edit_get_utf (edit, edit->curs1, &cw); if (cw <= 0) cur_utf = edit_get_byte (edit, edit->curs1); tty_printf ("[%05d 0x%04X]", cur_utf, cur_utf); } #endif else { unsigned char cur_byte; cur_byte = edit_get_byte (edit, edit->curs1); tty_printf ("[%05d 0x%04X]", (unsigned int) cur_byte, (unsigned int) cur_byte); } } }
/** Execute the cd command on the command line */ 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 (strcmp (cmd + operand_pos, "..") == 0) { char *str_path; 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); } str_path = vfs_path_to_str (current_panel->cwd_vpath); sync_tree (str_path); g_free (str_path); } else if (cmd[operand_pos] == PATH_SEP) { sync_tree (cmd + operand_pos); } else { char *str_path; vfs_path_t *new_vpath; new_vpath = vfs_path_append_new (current_panel->cwd_vpath, cmd + operand_pos, NULL); str_path = vfs_path_to_str (new_vpath); vfs_path_free (new_vpath); sync_tree (str_path); g_free (str_path); } } 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); } }
static gboolean regex_check_type (const vfs_path_t * filename_vpath, const char *ptr, int *have_type, gboolean case_insense, GError ** error) { gboolean found = FALSE; /* Following variables are valid if *have_type is 1 */ static char content_string[2048]; #ifdef HAVE_CHARSET static char encoding_id[21]; /* CSISO51INISCYRILLIC -- 20 */ #endif static size_t content_shift = 0; static int got_data = 0; if (!use_file_to_check_type) return FALSE; if (*have_type == 0) { vfs_path_t *localfile_vpath; const char *realname; /* name used with "file" */ #ifdef HAVE_CHARSET int got_encoding_data; #endif /* HAVE_CHARSET */ /* Don't repeate even unsuccessful checks */ *have_type = 1; localfile_vpath = mc_getlocalcopy (filename_vpath); if (localfile_vpath == NULL) { char *filename; filename = vfs_path_to_str (filename_vpath); g_propagate_error (error, g_error_new (MC_ERROR, -1, _("Cannot fetch a local copy of %s"), filename)); g_free (filename); return FALSE; } realname = vfs_path_get_last_path_str (localfile_vpath); #ifdef HAVE_CHARSET got_encoding_data = is_autodetect_codeset_enabled ? get_file_encoding_local (localfile_vpath, encoding_id, sizeof (encoding_id)) : 0; if (got_encoding_data > 0) { char *pp; int cp_id; pp = strchr (encoding_id, '\n'); if (pp != NULL) *pp = '\0'; cp_id = get_codepage_index (encoding_id); if (cp_id == -1) cp_id = default_source_codepage; do_set_codepage (cp_id); } #endif /* HAVE_CHARSET */ mc_ungetlocalcopy (filename_vpath, localfile_vpath, FALSE); got_data = get_file_type_local (localfile_vpath, content_string, sizeof (content_string)); if (got_data > 0) { char *pp; size_t real_len; pp = strchr (content_string, '\n'); if (pp != NULL) *pp = '\0'; real_len = strlen (realname); if (strncmp (content_string, realname, real_len) == 0) { /* Skip "realname: " */ content_shift = real_len; if (content_string[content_shift] == ':') { /* Solaris' file prints tab(s) after ':' */ for (content_shift++; content_string[content_shift] == ' ' || content_string[content_shift] == '\t'; content_shift++) ; } } } else { /* No data */ content_string[0] = '\0'; } vfs_path_free (localfile_vpath); } if (got_data == -1) { g_propagate_error (error, g_error_new (MC_ERROR, -1, _("Pipe failed"))); return FALSE; } if (content_string[0] != '\0') { mc_search_t *search; search = mc_search_new (ptr, -1); if (search != NULL) { search->search_type = MC_SEARCH_T_REGEX; search->is_case_sensitive = !case_insense; found = mc_search_run (search, content_string + content_shift, 0, -1, NULL); mc_search_free (search); } else { g_propagate_error (error, g_error_new (MC_ERROR, -1, _("Regular expression error"))); } } return found; }
/** If it actually changed the directory it returns true */ void do_subshell_chdir (const vfs_path_t * vpath, gboolean update_prompt, gboolean reset_prompt) { char *pcwd; char *temp; char *directory; pcwd = vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_RECODE); if (!(subshell_state == INACTIVE && strcmp (subshell_cwd, pcwd) != 0)) { /* We have to repaint the subshell prompt if we read it from * the main program. Please note that in the code after this * if, the cd command that is sent will make the subshell * repaint the prompt, so we don't have to paint it. */ if (update_prompt) do_update_prompt (); g_free (pcwd); return; } /* The initial space keeps this out of the command history (in bash because we set "HISTCONTROL=ignorespace") */ write_all (mc_global.tty.subshell_pty, " cd ", 4); directory = vfs_path_to_str (vpath); if (directory != '\0') { char *translate; translate = vfs_translate_path_n (directory); if (translate != NULL) { temp = subshell_name_quote (translate); if (temp) { write_all (mc_global.tty.subshell_pty, temp, strlen (temp)); g_free (temp); } else { /* Should not happen unless the directory name is so long that we don't have memory to quote it. */ write_all (mc_global.tty.subshell_pty, ".", 1); } g_free (translate); } else { write_all (mc_global.tty.subshell_pty, ".", 1); } } else { write_all (mc_global.tty.subshell_pty, "/", 1); } g_free (directory); write_all (mc_global.tty.subshell_pty, "\n", 1); subshell_state = RUNNING_COMMAND; feed_subshell (QUIETLY, FALSE); if (subshell_alive) { int bPathNotEq = strcmp (subshell_cwd, pcwd); if (bPathNotEq && subshell_type == TCSH) { char rp_subshell_cwd[PATH_MAX]; char rp_current_panel_cwd[PATH_MAX]; char *p_subshell_cwd = mc_realpath (subshell_cwd, rp_subshell_cwd); char *p_current_panel_cwd = mc_realpath (pcwd, rp_current_panel_cwd); if (p_subshell_cwd == NULL) p_subshell_cwd = subshell_cwd; if (p_current_panel_cwd == NULL) p_current_panel_cwd = pcwd; bPathNotEq = strcmp (p_subshell_cwd, p_current_panel_cwd); } if (bPathNotEq && strcmp (pcwd, ".") != 0) { char *cwd; cwd = vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_STRIP_PASSWORD); vfs_print_message (_("Warning: Cannot change to %s.\n"), cwd); g_free (cwd); } } if (reset_prompt) prompt_pos = 0; update_subshell_prompt = FALSE; g_free (pcwd); /* Make sure that MC never stores the CWD in a silly format */ /* like /usr////lib/../bin, or the strcmp() above will fail */ }
void save_file_position (const vfs_path_t * filename_vpath, long line, long column, off_t offset, GArray * bookmarks) { static size_t filepos_max_saved_entries = 0; char *fn, *tmp_fn; FILE *f, *tmp_f; char buf[MC_MAXPATHLEN + 100]; size_t i; const size_t len = vfs_path_len (filename_vpath); gboolean src_error = FALSE; char *filename; if (filepos_max_saved_entries == 0) filepos_max_saved_entries = mc_config_get_int (mc_main_config, CONFIG_APP_SECTION, "filepos_max_saved_entries", 1024); fn = mc_config_get_full_path (MC_FILEPOS_FILE); if (fn == NULL) goto early_error; mc_util_make_backup_if_possible (fn, TMP_SUFFIX); /* open file */ f = fopen (fn, "w"); if (f == NULL) goto open_target_error; tmp_fn = g_strdup_printf ("%s" TMP_SUFFIX, fn); tmp_f = fopen (tmp_fn, "r"); if (tmp_f == NULL) { src_error = TRUE; goto open_source_error; } filename = vfs_path_to_str (filename_vpath); /* put the new record */ if (line != 1 || column != 0 || bookmarks != NULL) { if (fprintf (f, "%s %ld;%ld;%" PRIuMAX, filename, line, column, (uintmax_t) offset) < 0) goto write_position_error; if (bookmarks != NULL) for (i = 0; i < bookmarks->len && i < MAX_SAVED_BOOKMARKS; i++) if (fprintf (f, ";%zu", g_array_index (bookmarks, size_t, i)) < 0) goto write_position_error; if (fprintf (f, "\n") < 0) goto write_position_error; } i = 1; while (fgets (buf, sizeof (buf), tmp_f) != NULL) { if (buf[len] == ' ' && strncmp (buf, filename, len) == 0 && strchr (&buf[len + 1], ' ') == NULL) continue; fprintf (f, "%s", buf); if (++i > filepos_max_saved_entries) break; } write_position_error: g_free (filename); fclose (tmp_f); open_source_error: g_free (tmp_fn); fclose (f); if (src_error) mc_util_restore_from_backup_if_possible (fn, TMP_SUFFIX); else mc_util_unlink_backup_if_possible (fn, TMP_SUFFIX); open_target_error: g_free (fn); early_error: if (bookmarks != NULL) g_array_free (bookmarks, TRUE); }
void load_file_position (const vfs_path_t * filename_vpath, long *line, long *column, off_t * offset, GArray ** bookmarks) { char *fn; FILE *f; char buf[MC_MAXPATHLEN + 100]; const size_t len = vfs_path_len (filename_vpath); char *filename; /* defaults */ *line = 1; *column = 0; *offset = 0; /* open file with positions */ fn = mc_config_get_full_path (MC_FILEPOS_FILE); f = fopen (fn, "r"); g_free (fn); if (f == NULL) return; /* prepare array for serialized bookmarks */ if (bookmarks != NULL) *bookmarks = g_array_sized_new (FALSE, FALSE, sizeof (size_t), MAX_SAVED_BOOKMARKS); filename = vfs_path_to_str (filename_vpath); while (fgets (buf, sizeof (buf), f) != NULL) { const char *p; gchar **pos_tokens; /* check if the filename matches the beginning of string */ if (strncmp (buf, filename, len) != 0) continue; /* followed by single space */ if (buf[len] != ' ') continue; /* and string without spaces */ p = &buf[len + 1]; if (strchr (p, ' ') != NULL) continue; pos_tokens = g_strsplit (p, ";", 3 + MAX_SAVED_BOOKMARKS); if (pos_tokens[0] == NULL) { *line = 1; *column = 0; *offset = 0; } else { *line = strtol (pos_tokens[0], NULL, 10); if (pos_tokens[1] == NULL) { *column = 0; *offset = 0; } else { *column = strtol (pos_tokens[1], NULL, 10); if (pos_tokens[2] == NULL) *offset = 0; else if (bookmarks != NULL) { size_t i; *offset = (off_t) g_ascii_strtoll (pos_tokens[2], NULL, 10); for (i = 0; i < MAX_SAVED_BOOKMARKS && pos_tokens[3 + i] != NULL; i++) { size_t val; val = strtoul (pos_tokens[3 + i], NULL, 10); g_array_append_val (*bookmarks, val); } } } } g_strfreev (pos_tokens); } g_free (filename); fclose (f); }
static char * resolve_symlinks (const vfs_path_t * vpath) { char *p, *p2; char *buf, *buf2, *q, *r, c; struct stat mybuf; if (vpath->relative) return NULL; p = p2 = vfs_path_to_str (vpath); r = buf = g_malloc (MC_MAXPATHLEN); buf2 = g_malloc (MC_MAXPATHLEN); *r++ = PATH_SEP; *r = 0; do { q = strchr (p + 1, PATH_SEP); if (!q) { q = strchr (p + 1, 0); if (q == p + 1) break; } c = *q; *q = 0; if (mc_lstat (vpath, &mybuf) < 0) { g_free (buf); buf = NULL; goto ret; } if (!S_ISLNK (mybuf.st_mode)) strcpy (r, p + 1); else { int len; len = mc_readlink (vpath, buf2, MC_MAXPATHLEN - 1); if (len < 0) { g_free (buf); buf = NULL; goto ret; } buf2[len] = 0; if (*buf2 == PATH_SEP) strcpy (buf, buf2); else strcpy (r, buf2); } canonicalize_pathname (buf); r = strchr (buf, 0); if (!*r || *(r - 1) != PATH_SEP) /* FIXME: this condition is always true because r points to the EOL */ { *r++ = PATH_SEP; *r = 0; } *q = c; p = q; } while (c != '\0'); if (!*buf) strcpy (buf, PATH_SEP_STR); else if (*(r - 1) == PATH_SEP && r != buf + 1) *(r - 1) = 0; ret: g_free (buf2); g_free (p2); return buf; }
int regex_command (const vfs_path_t * filename_vpath, const char *action) { char *filename, *p, *q, *r, c; size_t file_len; gboolean found = FALSE; gboolean error_flag = FALSE; int ret = 0; struct stat mystat; int view_at_line_number; char *include_target; int include_target_len; int have_type = 0; /* Flag used by regex_check_type() */ if (filename_vpath == NULL) return 0; /* Check for the special View:%d parameter */ if (strncmp (action, "View:", 5) == 0) { view_at_line_number = atoi (action + 5); action = "View"; } else { view_at_line_number = 0; } if (data == NULL) { char *extension_file; gboolean mc_user_ext = TRUE; gboolean home_error = FALSE; extension_file = mc_config_get_full_path (MC_FILEBIND_FILE); if (!exist_file (extension_file)) { g_free (extension_file); check_stock_mc_ext: extension_file = mc_build_filename (mc_global.sysconfig_dir, MC_LIB_EXT, NULL); if (!exist_file (extension_file)) { g_free (extension_file); extension_file = mc_build_filename (mc_global.share_data_dir, MC_LIB_EXT, NULL); } mc_user_ext = FALSE; } g_file_get_contents (extension_file, &data, NULL, NULL); g_free (extension_file); if (data == NULL) return 0; if (strstr (data, "default/") == NULL) { if (strstr (data, "regex/") == NULL && strstr (data, "shell/") == NULL && strstr (data, "type/") == NULL) { g_free (data); data = NULL; if (!mc_user_ext) { char *title; title = g_strdup_printf (_(" %s%s file error"), mc_global.sysconfig_dir, MC_LIB_EXT); message (D_ERROR, title, _("The format of the %smc.ext " "file has changed with version 3.0. It seems that " "the installation failed. Please fetch a fresh " "copy from the Midnight Commander package."), mc_global.sysconfig_dir); g_free (title); return 0; } home_error = TRUE; goto check_stock_mc_ext; } } if (home_error) { char *filebind_filename; char *title; filebind_filename = mc_config_get_full_path (MC_FILEBIND_FILE); title = g_strdup_printf (_("%s file error"), filebind_filename); message (D_ERROR, title, _("The format of the %s file has " "changed with version 3.0. You may either want to copy " "it from %smc.ext or use that file as an example of how to write it."), filebind_filename, mc_global.sysconfig_dir); g_free (filebind_filename); g_free (title); } } mc_stat (filename_vpath, &mystat); include_target = NULL; include_target_len = 0; filename = vfs_path_to_str (filename_vpath); file_len = vfs_path_len (filename_vpath); for (p = data; *p != '\0'; p++) { for (q = p; *q == ' ' || *q == '\t'; q++) ; if (*q == '\n' || *q == '\0') p = q; /* empty line */ if (*p == '#') /* comment */ while (*p != '\0' && *p != '\n') p++; if (*p == '\n') continue; if (*p == '\0') break; if (p == q) { /* i.e. starts in the first column, should be * keyword/descNL */ gboolean case_insense; found = FALSE; q = strchr (p, '\n'); if (q == NULL) q = strchr (p, '\0'); c = *q; *q = '\0'; if (include_target) { if ((strncmp (p, "include/", 8) == 0) && (strncmp (p + 8, include_target, include_target_len) == 0)) found = TRUE; } else if (strncmp (p, "regex/", 6) == 0) { mc_search_t *search; p += 6; case_insense = (strncmp (p, "i/", 2) == 0); if (case_insense) p += 2; search = mc_search_new (p, -1); if (search != NULL) { search->search_type = MC_SEARCH_T_REGEX; search->is_case_sensitive = !case_insense; found = mc_search_run (search, filename, 0, file_len, NULL); mc_search_free (search); } } else if (strncmp (p, "directory/", 10) == 0) { if (S_ISDIR (mystat.st_mode) && mc_search (p + 10, filename, MC_SEARCH_T_REGEX)) found = TRUE; } else if (strncmp (p, "shell/", 6) == 0) { int (*cmp_func) (const char *s1, const char *s2, size_t n) = strncmp; p += 6; case_insense = (strncmp (p, "i/", 2) == 0); if (case_insense) { p += 2; cmp_func = strncasecmp; } if (*p == '.' && file_len >= (size_t) (q - p)) { if (cmp_func (p, filename + file_len - (q - p), q - p) == 0) found = TRUE; } else { if ((size_t) (q - p) == file_len && cmp_func (p, filename, q - p) == 0) found = TRUE; } } else if (strncmp (p, "type/", 5) == 0) { GError *error = NULL; p += 5; case_insense = (strncmp (p, "i/", 2) == 0); if (case_insense) p += 2; found = regex_check_type (filename_vpath, p, &have_type, case_insense, &error); if (error != NULL) { g_error_free (error); error_flag = TRUE; /* leave it if file cannot be opened */ } } else if (strncmp (p, "default/", 8) == 0) found = TRUE; *q = c; p = q; if (*p == '\0') break; } else { /* List of actions */ p = q; q = strchr (p, '\n'); if (q == NULL) q = strchr (p, '\0'); if (found && !error_flag) { r = strchr (p, '='); if (r != NULL) { c = *r; *r = '\0'; if (strcmp (p, "Include") == 0) { char *t; include_target = p + 8; t = strchr (include_target, '\n'); if (t != NULL) *t = '\0'; include_target_len = strlen (include_target); if (t != NULL) *t = '\n'; *r = c; p = q; found = FALSE; if (*p == '\0') break; continue; } if (strcmp (action, p) != 0) *r = c; else { *r = c; for (p = r + 1; *p == ' ' || *p == '\t'; p++) ; /* Empty commands just stop searching * through, they don't do anything */ if (p < q) { exec_extension (filename_vpath, r + 1, view_at_line_number); ret = 1; } break; } } } p = q; if (*p == '\0') break; } } g_free (filename); if (error_flag) ret = -1; return ret; }
char * edit_get_file_name (const WEdit * edit) { return vfs_path_to_str (edit->filename_vpath); }
static void show_tree (WTree * tree) { Dlg_head *h = tree->widget.owner; tree_entry *current; int i, j, topsublevel; int x = 0, y = 0; int tree_lines, tree_cols; /* Initialize */ tree_lines = tlines (tree); tree_cols = tree->widget.cols; widget_move ((Widget *) tree, y, x); if (tree->is_panel) { tree_cols -= 2; x = y = 1; } g_free (tree->tree_shown); tree->tree_shown = g_new0 (tree_entry *, tree_lines); if (tree->store->tree_first) topsublevel = tree->store->tree_first->sublevel; else topsublevel = 0; if (!tree->selected_ptr) { tree->selected_ptr = tree->store->tree_first; tree->topdiff = 0; } current = tree->selected_ptr; /* Calculate the directory which is to be shown on the topmost line */ if (!tree_navigation_flag) current = back_ptr (current, &tree->topdiff); else { i = 0; while (current->prev && i < tree->topdiff) { char *current_name; current = current->prev; current_name = vfs_path_to_str (current->name); if (current->sublevel < tree->selected_ptr->sublevel) { if (vfs_path_cmp (current->name, tree->selected_ptr->name) == 0) i++; } else if (current->sublevel == tree->selected_ptr->sublevel) { for (j = strlen (current_name) - 1; current_name[j] != PATH_SEP; j--); if (vfs_path_ncmp (current->name, tree->selected_ptr->name, j) == 0) i++; } else { if (current->sublevel == tree->selected_ptr->sublevel + 1 && vfs_path_len (tree->selected_ptr->name) > 1) { if (vfs_path_ncmp (current->name, tree->selected_ptr->name, vfs_path_len (tree->selected_ptr->name)) == 0) i++; } } g_free (current_name); } tree->topdiff = i; } /* Loop for every line */ for (i = 0; i < tree_lines; i++) { tty_setcolor (tree->is_panel ? NORMAL_COLOR : TREE_NORMALC (h)); /* Move to the beginning of the line */ tty_draw_hline (tree->widget.y + y + i, tree->widget.x + x, ' ', tree_cols); if (current == NULL) continue; if (tree->is_panel) tty_setcolor (tree->active && current == tree->selected_ptr ? SELECTED_COLOR : NORMAL_COLOR); else tty_setcolor (current == tree->selected_ptr ? TREE_CURRENTC (h) : TREE_NORMALC (h)); tree->tree_shown[i] = current; if (current->sublevel == topsublevel) { /* Show full name */ char *current_name; current_name = vfs_path_to_str (current->name); tty_print_string (str_fit_to_term (current_name, tree_cols + (tree->is_panel ? 0 : 1), J_LEFT_FIT)); g_free (current_name); } else { /* Sub level directory */ tty_set_alt_charset (TRUE); /* Output branch parts */ for (j = 0; j < current->sublevel - topsublevel - 1; j++) { if (tree_cols - 8 - 3 * j < 9) break; tty_print_char (' '); if (current->submask & (1 << (j + topsublevel + 1))) tty_print_char (ACS_VLINE); else tty_print_char (' '); tty_print_char (' '); } tty_print_char (' '); j++; if (!current->next || !(current->next->submask & (1 << current->sublevel))) tty_print_char (ACS_LLCORNER); else tty_print_char (ACS_LTEE); tty_print_char (ACS_HLINE); tty_set_alt_charset (FALSE); /* Show sub-name */ tty_print_char (' '); tty_print_string (str_fit_to_term (current->subname, tree_cols - x - 3 * j, J_LEFT_FIT)); } /* Calculate the next value for current */ current = current->next; if (tree_navigation_flag) { while (current != NULL) { if (current->sublevel < tree->selected_ptr->sublevel) { if (vfs_path_ncmp (current->name, tree->selected_ptr->name, vfs_path_len (current->name)) == 0) break; } else if (current->sublevel == tree->selected_ptr->sublevel) { char *current_name; current_name = vfs_path_to_str (current->name); for (j = strlen (current_name) - 1; current_name[j] != PATH_SEP; j--) ; g_free (current_name); if (vfs_path_ncmp (current->name, tree->selected_ptr->name, j) == 0) break; } else if (current->sublevel == tree->selected_ptr->sublevel + 1 && vfs_path_len (tree->selected_ptr->name) > 1) { if (vfs_path_ncmp (current->name, tree->selected_ptr->name, vfs_path_len (tree->selected_ptr->name)) == 0) break; } current = current->next; } } } tree_show_mini_info (tree, tree_lines, tree_cols); }