This source file includes following definitions.
- do_view_cmd
- do_edit
- compare_files
- compare_dir
- do_link
- nice_cd
- configure_panel_listing
- switch_to_listing
- view_file_at_line
- view_file
- view_cmd
- view_file_cmd
- view_raw_cmd
- view_filtered_cmd
- edit_file_at_line
- edit_cmd
- edit_cmd_force_internal
- edit_cmd_new
- mkdir_cmd
- reread_cmd
- ext_cmd
- edit_mc_menu_cmd
- edit_fhl_cmd
- hotlist_cmd
- vfs_list
- compare_dirs_cmd
- diff_view_cmd
- swap_cmd
- link_cmd
- edit_symlink_cmd
- help_cmd
- ftplink_cmd
- sftplink_cmd
- shelllink_cmd
- undelete_cmd
- quick_cd_cmd
- smart_dirsize_cmd
- single_dirsize_cmd
- dirsizes_cmd
- save_setup_cmd
- info_cmd_no_menu
- quick_cmd_no_menu
- listing_cmd
- setup_listing_format_cmd
- panel_tree_cmd
- info_cmd
- quick_view_cmd
- encoding_cmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include <config.h>
34
35 #include <errno.h>
36 #include <stdio.h>
37 #include <string.h>
38
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #ifdef ENABLE_VFS_NET
42 # include <netdb.h>
43 #endif
44 #include <unistd.h>
45 #include <stdlib.h>
46 #include <pwd.h>
47 #include <grp.h>
48
49 #include "lib/global.h"
50
51 #include "lib/tty/tty.h"
52 #include "lib/tty/key.h"
53 #include "lib/mcconfig.h"
54 #include "lib/filehighlight.h"
55 #include "lib/vfs/vfs.h"
56 #include "lib/fileloc.h"
57 #include "lib/strutil.h"
58 #include "lib/file-entry.h"
59 #include "lib/util.h"
60 #include "lib/widget.h"
61 #include "lib/keybind.h"
62 #include "lib/event.h"
63
64 #include "src/setup.h"
65 #include "src/execute.h"
66 #include "src/history.h"
67 #include "src/util.h"
68
69 #include "src/viewer/mcviewer.h"
70
71 #ifdef USE_INTERNAL_EDIT
72 # include "src/editor/edit.h"
73 #endif
74
75 #ifdef USE_DIFF_VIEW
76 # include "src/diffviewer/ydiff.h"
77 #endif
78
79 #include "filegui.h"
80 #include "filenot.h"
81 #include "hotlist.h"
82 #include "tree.h"
83 #include "filemanager.h"
84 #include "command.h"
85 #include "layout.h"
86 #include "ext.h"
87 #include "boxes.h"
88 #include "dir.h"
89 #include "cd.h"
90 #include "ioblksize.h"
91
92 #include "cmd.h"
93
94
95
96
97
98
99
100 enum CompareMode
101 {
102 compare_quick = 0,
103 compare_size_only,
104 compare_thourough
105 };
106
107
108
109
110
111 #ifdef ENABLE_VFS_NET
112 static const char *machine_str = N_ ("Enter machine name (F1 for details):");
113 #endif
114
115
116
117
118
119
120
121
122 static void
123 do_view_cmd (WPanel *panel, gboolean plain_view)
124 {
125 const file_entry_t *fe;
126
127 fe = panel_current_entry (panel);
128 if (fe == NULL)
129 return;
130
131
132 if (S_ISDIR (fe->st.st_mode) || link_isdir (fe))
133 {
134 vfs_path_t *fname_vpath;
135
136 if (confirm_view_dir && (panel->marked != 0 || panel->dirs_marked != 0)
137 && query_dialog (_ ("Confirmation"), _ ("Files tagged, want to cd?"), D_NORMAL, 2,
138 _ ("&Yes"), _ ("&No"))
139 != 0)
140 return;
141
142 fname_vpath = vfs_path_from_str (fe->fname->str);
143 if (!panel_cd (panel, fname_vpath, cd_exact))
144 cd_error_message (fe->fname->str);
145 vfs_path_free (fname_vpath, TRUE);
146 }
147 else
148 {
149 vfs_path_t *filename_vpath;
150
151 filename_vpath = vfs_path_from_str (fe->fname->str);
152 view_file (filename_vpath, plain_view, use_internal_view);
153 vfs_path_free (filename_vpath, TRUE);
154 }
155
156 repaint_screen ();
157 }
158
159
160
161 static inline void
162 do_edit (const vfs_path_t *what_vpath)
163 {
164 edit_file_at_line (what_vpath, use_internal_edit, 0);
165 }
166
167
168
169 static int
170 compare_files (const vfs_path_t *vpath1, const vfs_path_t *vpath2, off_t size)
171 {
172 int file1;
173 int result = -1;
174
175 if (size == 0)
176 return 0;
177
178 file1 = open (vfs_path_as_str (vpath1), O_RDONLY);
179 if (file1 >= 0)
180 {
181 int file2;
182
183 file2 = open (vfs_path_as_str (vpath2), O_RDONLY);
184 if (file2 >= 0)
185 {
186 char buf1[IO_BUFSIZE], buf2[IO_BUFSIZE];
187 ssize_t n1, n2;
188
189 rotate_dash (TRUE);
190 do
191 {
192 while ((n1 = read (file1, buf1, sizeof (buf1))) == -1 && errno == EINTR)
193 ;
194 while ((n2 = read (file2, buf2, sizeof (buf2))) == -1 && errno == EINTR)
195 ;
196 }
197 while (n1 == n2 && n1 == sizeof (buf1) && memcmp (buf1, buf2, sizeof (buf1)) == 0);
198 result = (n1 != n2) || (memcmp (buf1, buf2, n1) != 0);
199 rotate_dash (FALSE);
200
201 close (file2);
202 }
203 close (file1);
204 }
205
206 return result;
207 }
208
209
210
211 static void
212 compare_dir (WPanel *panel, const WPanel *other, enum CompareMode mode)
213 {
214 int i, j;
215
216
217 panel->marked = 0;
218 panel->total = 0;
219 panel->dirs_marked = 0;
220
221
222 for (i = 0; i < panel->dir.len; i++)
223 {
224 file_entry_t *source = &panel->dir.list[i];
225 const char *source_fname;
226
227
228 file_mark (panel, i, 0);
229
230
231 if (S_ISDIR (source->st.st_mode))
232 continue;
233
234 source_fname = source->fname->str;
235 if (panel->is_panelized)
236 source_fname = x_basename (source_fname);
237
238
239 for (j = 0; j < other->dir.len; j++)
240 {
241 const char *other_fname;
242
243 other_fname = other->dir.list[j].fname->str;
244 if (other->is_panelized)
245 other_fname = x_basename (other_fname);
246
247 if (strcmp (source_fname, other_fname) == 0)
248 break;
249 }
250
251 if (j >= other->dir.len)
252
253 do_file_mark (panel, i, 1);
254 else
255 {
256
257 file_entry_t *target = &other->dir.list[j];
258
259 if (mode != compare_size_only)
260
261 if (source->st.st_mtime < target->st.st_mtime)
262 continue;
263
264
265 if (source->st.st_size != target->st.st_size)
266 {
267 do_file_mark (panel, i, 1);
268 continue;
269 }
270
271 if (mode == compare_size_only)
272 continue;
273
274 if (mode == compare_quick)
275 {
276
277
278 if (source->st.st_mtime > target->st.st_mtime)
279 do_file_mark (panel, i, 1);
280
281 continue;
282 }
283
284
285 {
286 vfs_path_t *src_name, *dst_name;
287
288 src_name =
289 vfs_path_append_new (panel->cwd_vpath, source->fname->str, (char *) NULL);
290 dst_name =
291 vfs_path_append_new (other->cwd_vpath, target->fname->str, (char *) NULL);
292 if (compare_files (src_name, dst_name, source->st.st_size))
293 do_file_mark (panel, i, 1);
294 vfs_path_free (src_name, TRUE);
295 vfs_path_free (dst_name, TRUE);
296 }
297 }
298 }
299 }
300
301
302
303 static void
304 do_link (link_type_t link_type, const char *fname)
305 {
306 char *dest = NULL, *src = NULL;
307 vfs_path_t *dest_vpath = NULL;
308
309 if (link_type == LINK_HARDLINK)
310 {
311 vfs_path_t *fname_vpath;
312
313 src = g_strdup_printf (_ ("Link %s to:"), str_trunc (fname, 46));
314 dest =
315 input_expand_dialog (_ ("Link"), src, MC_HISTORY_FM_LINK, "", INPUT_COMPLETE_FILENAMES);
316 if (dest == NULL || *dest == '\0')
317 goto cleanup;
318
319 save_cwds_stat ();
320
321 fname_vpath = vfs_path_from_str (fname);
322 dest_vpath = vfs_path_from_str (dest);
323 if (mc_link (fname_vpath, dest_vpath) == -1)
324 message (D_ERROR, MSG_ERROR, _ ("link: %s"), unix_error_string (errno));
325 vfs_path_free (fname_vpath, TRUE);
326 }
327 else
328 {
329 vfs_path_t *s, *d;
330
331
332
333 s = vfs_path_append_new (current_panel->cwd_vpath, fname, (char *) NULL);
334
335 if (get_other_type () == view_listing)
336 d = vfs_path_append_new (other_panel->cwd_vpath, fname, (char *) NULL);
337 else
338 d = vfs_path_from_str (fname);
339
340 if (link_type == LINK_SYMLINK_RELATIVE)
341 {
342 char *s_str;
343
344 s_str = diff_two_paths (other_panel->cwd_vpath, s);
345 vfs_path_free (s, TRUE);
346 s = vfs_path_from_str_flags (s_str, VPF_NO_CANON);
347 g_free (s_str);
348 }
349
350 symlink_box (s, d, &dest, &src);
351 vfs_path_free (d, TRUE);
352 vfs_path_free (s, TRUE);
353
354 if (dest == NULL || *dest == '\0' || src == NULL || *src == '\0')
355 goto cleanup;
356
357 save_cwds_stat ();
358
359 dest_vpath = vfs_path_from_str_flags (dest, VPF_NO_CANON);
360
361 s = vfs_path_from_str (src);
362 if (mc_symlink (dest_vpath, s) == -1)
363 message (D_ERROR, MSG_ERROR, _ ("symlink: %s"), unix_error_string (errno));
364 vfs_path_free (s, TRUE);
365 }
366
367 update_panels (UP_OPTIMIZE, UP_KEEPSEL);
368 repaint_screen ();
369
370 cleanup:
371 vfs_path_free (dest_vpath, TRUE);
372 g_free (src);
373 g_free (dest);
374 }
375
376
377
378 #if defined(ENABLE_VFS_UNDELFS) || defined(ENABLE_VFS_NET)
379 static void
380 nice_cd (const char *text, const char *xtext, const char *help, const char *history_name,
381 const char *prefix, int to_home, gboolean strip_password)
382 {
383 char *machine;
384 char *cd_path;
385
386 machine = input_dialog_help (text, xtext, help, history_name, INPUT_LAST_TEXT, strip_password,
387 INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD
388 | INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_USERNAMES);
389 if (machine == NULL)
390 return;
391
392 to_home = 0;
393
394
395 if (strncmp (prefix, machine, strlen (prefix)) == 0)
396 cd_path = g_strconcat (machine, to_home ? "/~/" : (char *) NULL, (char *) NULL);
397 else
398 cd_path = g_strconcat (prefix, machine, to_home ? "/~/" : (char *) NULL, (char *) NULL);
399
400 g_free (machine);
401
402 if (!IS_PATH_SEP (*cd_path))
403 {
404 char *tmp = cd_path;
405
406 cd_path = g_strconcat (PATH_SEP_STR, tmp, (char *) NULL);
407 g_free (tmp);
408 }
409
410 {
411 panel_view_mode_t save_type;
412 vfs_path_t *cd_vpath;
413
414 save_type = get_panel_type (MENU_PANEL_IDX);
415
416 if (save_type != view_listing)
417 create_panel (MENU_PANEL_IDX, view_listing);
418
419 cd_vpath = vfs_path_from_str_flags (cd_path, VPF_NO_CANON);
420 if (!panel_do_cd (MENU_PANEL, cd_vpath, cd_parse_command))
421 {
422 cd_error_message (cd_path);
423
424 if (save_type != view_listing)
425 create_panel (MENU_PANEL_IDX, save_type);
426 }
427 vfs_path_free (cd_vpath, TRUE);
428 }
429 g_free (cd_path);
430
431
432 if (MENU_PANEL != current_panel)
433 (void) mc_chdir (current_panel->cwd_vpath);
434 }
435 #endif
436
437
438
439 static void
440 configure_panel_listing (WPanel *p, int list_format, int brief_cols, gboolean use_msformat,
441 char **user, char **status)
442 {
443 p->user_mini_status = use_msformat;
444 p->list_format = list_format;
445
446 if (list_format == list_brief)
447 p->brief_cols = brief_cols;
448
449 if (list_format == list_user || use_msformat)
450 {
451 g_free (p->user_format);
452 p->user_format = *user;
453 *user = NULL;
454
455 g_free (p->user_status_format[list_format]);
456 p->user_status_format[list_format] = *status;
457 *status = NULL;
458
459 set_panel_formats (p);
460 }
461
462 set_panel_formats (p);
463 do_refresh ();
464 }
465
466
467
468 static void
469 switch_to_listing (int panel_index)
470 {
471 if (get_panel_type (panel_index) != view_listing)
472 create_panel (panel_index, view_listing);
473 }
474
475
476
477
478
479 gboolean
480 view_file_at_line (const vfs_path_t *filename_vpath, gboolean plain_view, gboolean internal,
481 long start_line, off_t search_start, off_t search_end)
482 {
483 gboolean ret = TRUE;
484
485 if (plain_view)
486 {
487 mcview_mode_flags_t changed_flags;
488
489 mcview_clear_mode_flags (&changed_flags);
490 mcview_altered_flags.hex = FALSE;
491 mcview_altered_flags.magic = FALSE;
492 mcview_altered_flags.nroff = FALSE;
493 if (mcview_global_flags.hex)
494 changed_flags.hex = TRUE;
495 if (mcview_global_flags.magic)
496 changed_flags.magic = TRUE;
497 if (mcview_global_flags.nroff)
498 changed_flags.nroff = TRUE;
499 mcview_global_flags.hex = FALSE;
500 mcview_global_flags.magic = FALSE;
501 mcview_global_flags.nroff = FALSE;
502
503 ret = mcview_viewer (NULL, filename_vpath, start_line, search_start, search_end);
504
505 if (changed_flags.hex && !mcview_altered_flags.hex)
506 mcview_global_flags.hex = TRUE;
507 if (changed_flags.magic && !mcview_altered_flags.magic)
508 mcview_global_flags.magic = TRUE;
509 if (changed_flags.nroff && !mcview_altered_flags.nroff)
510 mcview_global_flags.nroff = TRUE;
511
512 dialog_switch_process_pending ();
513 }
514 else if (internal)
515 {
516 char view_entry[BUF_TINY];
517
518 if (start_line > 0)
519 g_snprintf (view_entry, sizeof (view_entry), "View:%ld", start_line);
520 else
521 strcpy (view_entry, "View");
522
523 ret = (regex_command (filename_vpath, view_entry) == 0);
524 if (ret)
525 {
526 ret = mcview_viewer (NULL, filename_vpath, start_line, search_start, search_end);
527 dialog_switch_process_pending ();
528 }
529 }
530 else
531 {
532 static const char *viewer = NULL;
533
534 if (viewer == NULL)
535 {
536 viewer = getenv ("VIEWER");
537 if (viewer == NULL)
538 viewer = getenv ("PAGER");
539 if (viewer == NULL)
540 viewer = "view";
541 }
542
543 execute_external_editor_or_viewer (viewer, filename_vpath, start_line);
544 }
545
546 return ret;
547 }
548
549
550
551
552
553
554
555
556
557
558
559 gboolean
560 view_file (const vfs_path_t *filename_vpath, gboolean plain_view, gboolean internal)
561 {
562 return view_file_at_line (filename_vpath, plain_view, internal, 0, 0, 0);
563 }
564
565
566
567
568 void
569 view_cmd (WPanel *panel)
570 {
571 do_view_cmd (panel, FALSE);
572 }
573
574
575
576
577 void
578 view_file_cmd (const WPanel *panel)
579 {
580 const file_entry_t *fe;
581 char *filename;
582 vfs_path_t *vpath;
583
584 fe = panel_current_entry (panel);
585 if (fe == NULL)
586 return;
587
588 filename = input_expand_dialog (_ ("View file"), _ ("Filename:"), MC_HISTORY_FM_VIEW_FILE,
589 fe->fname->str, INPUT_COMPLETE_FILENAMES);
590 if (filename == NULL)
591 return;
592
593 vpath = vfs_path_from_str (filename);
594 g_free (filename);
595 view_file (vpath, FALSE, use_internal_view);
596 vfs_path_free (vpath, TRUE);
597 }
598
599
600
601 void
602 view_raw_cmd (WPanel *panel)
603 {
604 do_view_cmd (panel, TRUE);
605 }
606
607
608
609 void
610 view_filtered_cmd (const WPanel *panel)
611 {
612 char *command;
613 const char *initial_command;
614
615 if (input_is_empty (cmdline))
616 {
617 const file_entry_t *fe;
618
619 fe = panel_current_entry (panel);
620 if (fe == NULL)
621 return;
622
623 initial_command = fe->fname->str;
624 }
625 else
626 initial_command = input_get_ctext (cmdline);
627
628 command = input_dialog (_ ("Filtered view"), _ ("Filter command and arguments:"),
629 MC_HISTORY_FM_FILTERED_VIEW, initial_command,
630 INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_COMMANDS);
631
632 if (command != NULL)
633 {
634 mcview_viewer (command, NULL, 0, 0, 0);
635 g_free (command);
636 dialog_switch_process_pending ();
637 }
638 }
639
640
641
642 void
643 edit_file_at_line (const vfs_path_t *what_vpath, gboolean internal, long start_line)
644 {
645 #ifdef USE_INTERNAL_EDIT
646 if (internal)
647 {
648 const edit_arg_t arg = { (vfs_path_t *) what_vpath, start_line };
649
650 edit_file (&arg);
651 dialog_switch_process_pending ();
652 }
653 else
654 #endif
655 {
656 static const char *editor = NULL;
657
658 (void) internal;
659
660 if (editor == NULL)
661 {
662 editor = getenv ("EDITOR");
663 if (editor == NULL)
664 editor = get_default_editor ();
665 }
666
667 execute_external_editor_or_viewer (editor, what_vpath, start_line);
668 }
669 }
670
671
672
673 void
674 edit_cmd (const WPanel *panel)
675 {
676 const file_entry_t *fe;
677 vfs_path_t *fname;
678
679 fe = panel_current_entry (panel);
680 if (fe == NULL)
681 return;
682
683 fname = vfs_path_from_str (fe->fname->str);
684 if (regex_command (fname, "Edit") == 0)
685 do_edit (fname);
686 vfs_path_free (fname, TRUE);
687 }
688
689
690
691 #ifdef USE_INTERNAL_EDIT
692 void
693 edit_cmd_force_internal (const WPanel *panel)
694 {
695 const file_entry_t *fe;
696 vfs_path_t *fname;
697
698 fe = panel_current_entry (panel);
699 if (fe == NULL)
700 return;
701
702 fname = vfs_path_from_str (fe->fname->str);
703 if (regex_command (fname, "Edit") == 0)
704 edit_file_at_line (fname, TRUE, 1);
705 vfs_path_free (fname, TRUE);
706 }
707 #endif
708
709
710
711 void
712 edit_cmd_new (void)
713 {
714 vfs_path_t *fname_vpath = NULL;
715
716 if (editor_ask_filename_before_edit)
717 {
718 char *fname;
719
720 fname = input_expand_dialog (_ ("Edit file"), _ ("Enter file name:"), MC_HISTORY_EDIT_LOAD,
721 "", INPUT_COMPLETE_FILENAMES);
722 if (fname == NULL)
723 return;
724
725 if (*fname != '\0')
726 fname_vpath = vfs_path_from_str (fname);
727
728 g_free (fname);
729 }
730
731 #ifdef HAVE_CHARSET
732 mc_global.source_codepage = default_source_codepage;
733 #endif
734 do_edit (fname_vpath);
735
736 vfs_path_free (fname_vpath, TRUE);
737 }
738
739
740
741 void
742 mkdir_cmd (WPanel *panel)
743 {
744 const file_entry_t *fe;
745 char *dir;
746 const char *name = "";
747
748 fe = panel_current_entry (panel);
749 if (fe == NULL)
750 return;
751
752
753 if (auto_fill_mkdir_name && !DIR_IS_DOTDOT (fe->fname->str))
754 name = fe->fname->str;
755
756 dir = input_expand_dialog (_ ("Create a new Directory"), _ ("Enter directory name:"),
757 MC_HISTORY_FM_MKDIR, name, INPUT_COMPLETE_FILENAMES);
758
759 if (dir != NULL && *dir != '\0')
760 {
761 vfs_path_t *absdir;
762
763 if (IS_PATH_SEP (dir[0]) || dir[0] == '~')
764 absdir = vfs_path_from_str (dir);
765 else
766 {
767
768
769 char *tmpdir = dir;
770
771 if (dir[0] == '\\' && dir[1] == '~')
772 tmpdir = dir + 1;
773
774 absdir = vfs_path_append_new (panel->cwd_vpath, tmpdir, (char *) NULL);
775 }
776
777 save_cwds_stat ();
778
779 if (my_mkdir (absdir, 0777) != 0)
780 message (D_ERROR, MSG_ERROR, "%s", unix_error_string (errno));
781 else
782 {
783 update_panels (UP_OPTIMIZE, dir);
784 repaint_screen ();
785 select_item (panel);
786 }
787
788 vfs_path_free (absdir, TRUE);
789 }
790 g_free (dir);
791 }
792
793
794
795 void
796 reread_cmd (void)
797 {
798 panel_update_flags_t flag = UP_ONLY_CURRENT;
799
800 if (get_current_type () == view_listing && get_other_type () == view_listing
801 && vfs_path_equal (current_panel->cwd_vpath, other_panel->cwd_vpath))
802 flag = UP_OPTIMIZE;
803
804 update_panels (UP_RELOAD | flag, UP_KEEPSEL);
805 repaint_screen ();
806 }
807
808
809
810 void
811 ext_cmd (void)
812 {
813 vfs_path_t *extdir_vpath;
814 int dir = 0;
815
816 if (geteuid () == 0)
817 dir = query_dialog (_ ("Extension file edit"), _ ("Which extension file you want to edit?"),
818 D_NORMAL, 2, _ ("&User"), _ ("&System Wide"));
819
820 extdir_vpath = vfs_path_build_filename (mc_global.sysconfig_dir, MC_EXT_FILE, (char *) NULL);
821
822 if (dir == 0)
823 {
824 vfs_path_t *buffer_vpath;
825
826 buffer_vpath = mc_config_get_full_vpath (MC_EXT_FILE);
827 check_for_default (extdir_vpath, buffer_vpath);
828 do_edit (buffer_vpath);
829 vfs_path_free (buffer_vpath, TRUE);
830 }
831 else if (dir == 1)
832 {
833 if (!exist_file (vfs_path_get_last_path_str (extdir_vpath)))
834 {
835 vfs_path_free (extdir_vpath, TRUE);
836 extdir_vpath =
837 vfs_path_build_filename (mc_global.share_data_dir, MC_EXT_FILE, (char *) NULL);
838 }
839 do_edit (extdir_vpath);
840 }
841
842 vfs_path_free (extdir_vpath, TRUE);
843 flush_extension_file ();
844 }
845
846
847
848
849 void
850 edit_mc_menu_cmd (void)
851 {
852 vfs_path_t *buffer_vpath;
853 vfs_path_t *menufile_vpath;
854 int dir = 0;
855
856 query_set_sel (1);
857 dir = query_dialog (_ ("Menu edit"), _ ("Which menu file do you want to edit?"), D_NORMAL,
858 geteuid () ? 2 : 3, _ ("&Local"), _ ("&User"), _ ("&System Wide"));
859
860 menufile_vpath =
861 vfs_path_build_filename (mc_global.sysconfig_dir, MC_GLOBAL_MENU, (char *) NULL);
862
863 if (!exist_file (vfs_path_get_last_path_str (menufile_vpath)))
864 {
865 vfs_path_free (menufile_vpath, TRUE);
866 menufile_vpath =
867 vfs_path_build_filename (mc_global.share_data_dir, MC_GLOBAL_MENU, (char *) NULL);
868 }
869
870 switch (dir)
871 {
872 case 0:
873 buffer_vpath = vfs_path_from_str (MC_LOCAL_MENU);
874 check_for_default (menufile_vpath, buffer_vpath);
875 chmod (vfs_path_get_last_path_str (buffer_vpath), 0600);
876 break;
877
878 case 1:
879 buffer_vpath = mc_config_get_full_vpath (MC_USERMENU_FILE);
880 check_for_default (menufile_vpath, buffer_vpath);
881 break;
882
883 case 2:
884 buffer_vpath =
885 vfs_path_build_filename (mc_global.sysconfig_dir, MC_GLOBAL_MENU, (char *) NULL);
886 if (!exist_file (vfs_path_get_last_path_str (buffer_vpath)))
887 {
888 vfs_path_free (buffer_vpath, TRUE);
889 buffer_vpath =
890 vfs_path_build_filename (mc_global.share_data_dir, MC_GLOBAL_MENU, (char *) NULL);
891 }
892 break;
893
894 default:
895 vfs_path_free (menufile_vpath, TRUE);
896 return;
897 }
898
899 do_edit (buffer_vpath);
900
901 vfs_path_free (buffer_vpath, TRUE);
902 vfs_path_free (menufile_vpath, TRUE);
903 }
904
905
906
907 void
908 edit_fhl_cmd (void)
909 {
910 vfs_path_t *fhlfile_vpath = NULL;
911 int dir = 0;
912
913 if (geteuid () == 0)
914 dir = query_dialog (_ ("Highlighting groups file edit"),
915 _ ("Which highlighting file you want to edit?"), D_NORMAL, 2,
916 _ ("&User"), _ ("&System Wide"));
917
918 fhlfile_vpath =
919 vfs_path_build_filename (mc_global.sysconfig_dir, MC_FHL_INI_FILE, (char *) NULL);
920
921 if (dir == 0)
922 {
923 vfs_path_t *buffer_vpath;
924
925 buffer_vpath = mc_config_get_full_vpath (MC_FHL_INI_FILE);
926 check_for_default (fhlfile_vpath, buffer_vpath);
927 do_edit (buffer_vpath);
928 vfs_path_free (buffer_vpath, TRUE);
929 }
930 else if (dir == 1)
931 {
932 if (!exist_file (vfs_path_get_last_path_str (fhlfile_vpath)))
933 {
934 vfs_path_free (fhlfile_vpath, TRUE);
935 fhlfile_vpath =
936 vfs_path_build_filename (mc_global.sysconfig_dir, MC_FHL_INI_FILE, (char *) NULL);
937 }
938 do_edit (fhlfile_vpath);
939 }
940
941 vfs_path_free (fhlfile_vpath, TRUE);
942
943 mc_fhl_free (&mc_filehighlight);
944 mc_filehighlight = mc_fhl_new (TRUE);
945 }
946
947
948
949 void
950 hotlist_cmd (WPanel *panel)
951 {
952 char *target;
953
954 target = hotlist_show (LIST_HOTLIST, panel);
955 if (target == NULL)
956 return;
957
958 if (get_current_type () == view_tree)
959 {
960 vfs_path_t *vpath;
961
962 vpath = vfs_path_from_str (target);
963 tree_chdir (the_tree, vpath);
964 vfs_path_free (vpath, TRUE);
965 }
966 else
967 {
968 vfs_path_t *deprecated_vpath;
969 const char *deprecated_path;
970
971 deprecated_vpath = vfs_path_from_str_flags (target, VPF_USE_DEPRECATED_PARSER);
972 deprecated_path = vfs_path_as_str (deprecated_vpath);
973 cd_to (deprecated_path);
974 vfs_path_free (deprecated_vpath, TRUE);
975 }
976
977 g_free (target);
978 }
979
980
981
982 #ifdef ENABLE_VFS
983 void
984 vfs_list (WPanel *panel)
985 {
986 char *target;
987 vfs_path_t *target_vpath;
988
989 target = hotlist_show (LIST_VFSLIST, panel);
990 if (target == NULL)
991 return;
992
993 target_vpath = vfs_path_from_str (target);
994 if (!panel_cd (current_panel, target_vpath, cd_exact))
995 cd_error_message (target);
996 vfs_path_free (target_vpath, TRUE);
997 g_free (target);
998 }
999 #endif
1000
1001
1002
1003 void
1004 compare_dirs_cmd (void)
1005 {
1006 int choice;
1007 enum CompareMode thorough_flag;
1008
1009 choice = query_dialog (_ ("Compare directories"), _ ("Select compare method:"), D_NORMAL, 4,
1010 _ ("&Quick"), _ ("&Size only"), _ ("&Thorough"), _ ("&Cancel"));
1011
1012 if (choice < 0 || choice > 2)
1013 return;
1014
1015 thorough_flag = choice;
1016
1017 if (get_current_type () == view_listing && get_other_type () == view_listing)
1018 {
1019 compare_dir (current_panel, other_panel, thorough_flag);
1020 compare_dir (other_panel, current_panel, thorough_flag);
1021 }
1022 else
1023 message (D_ERROR, MSG_ERROR,
1024 _ ("Both panels should be in the listing mode\nto use this command"));
1025 }
1026
1027
1028
1029 #ifdef USE_DIFF_VIEW
1030 void
1031 diff_view_cmd (void)
1032 {
1033
1034 if (get_current_type () == view_listing && get_other_type () == view_listing)
1035 {
1036 if (get_current_index () == 0)
1037 dview_diff_cmd (current_panel, other_panel);
1038 else
1039 dview_diff_cmd (other_panel, current_panel);
1040
1041 if (mc_global.mc_run_mode == MC_RUN_FULL)
1042 update_panels (UP_OPTIMIZE, UP_KEEPSEL);
1043
1044 dialog_switch_process_pending ();
1045 }
1046 }
1047 #endif
1048
1049
1050
1051 void
1052 swap_cmd (void)
1053 {
1054 swap_panels ();
1055 tty_touch_screen ();
1056 repaint_screen ();
1057 }
1058
1059
1060
1061 void
1062 link_cmd (link_type_t link_type)
1063 {
1064 const file_entry_t *fe;
1065
1066 fe = panel_current_entry (current_panel);
1067 if (fe != NULL)
1068 do_link (link_type, fe->fname->str);
1069 }
1070
1071
1072
1073 void
1074 edit_symlink_cmd (void)
1075 {
1076 const file_entry_t *fe;
1077 const char *p;
1078
1079 fe = panel_current_entry (current_panel);
1080 if (fe == NULL)
1081 return;
1082
1083 p = fe->fname->str;
1084
1085 if (!S_ISLNK (fe->st.st_mode))
1086 message (D_ERROR, MSG_ERROR, _ ("'%s' is not a symbolic link"), p);
1087 else
1088 {
1089 char buffer[MC_MAXPATHLEN];
1090 int i;
1091
1092 i = readlink (p, buffer, sizeof (buffer) - 1);
1093 if (i > 0)
1094 {
1095 char *q, *dest;
1096
1097 buffer[i] = '\0';
1098
1099 q = g_strdup_printf (_ ("Symlink '%s\' points to:"), str_trunc (p, 32));
1100 dest = input_expand_dialog (_ ("Edit symlink"), q, MC_HISTORY_FM_EDIT_LINK, buffer,
1101 INPUT_COMPLETE_FILENAMES);
1102 g_free (q);
1103
1104 if (dest != NULL && *dest != '\0' && strcmp (buffer, dest) != 0)
1105 {
1106 vfs_path_t *p_vpath;
1107
1108 p_vpath = vfs_path_from_str (p);
1109
1110 save_cwds_stat ();
1111
1112 if (mc_unlink (p_vpath) == -1)
1113 message (D_ERROR, MSG_ERROR, _ ("edit symlink, unable to remove %s: %s"), p,
1114 unix_error_string (errno));
1115 else
1116 {
1117 vfs_path_t *dest_vpath;
1118
1119 dest_vpath = vfs_path_from_str_flags (dest, VPF_NO_CANON);
1120 if (mc_symlink (dest_vpath, p_vpath) == -1)
1121 message (D_ERROR, MSG_ERROR, _ ("edit symlink: %s"),
1122 unix_error_string (errno));
1123 vfs_path_free (dest_vpath, TRUE);
1124 }
1125
1126 vfs_path_free (p_vpath, TRUE);
1127
1128 update_panels (UP_OPTIMIZE, UP_KEEPSEL);
1129 repaint_screen ();
1130 }
1131
1132 g_free (dest);
1133 }
1134 }
1135 }
1136
1137
1138
1139 void
1140 help_cmd (void)
1141 {
1142 ev_help_t event_data = { NULL, NULL };
1143
1144 if (current_panel->quick_search.active)
1145 event_data.node = "[Quick search]";
1146 else
1147 event_data.node = "[main]";
1148
1149 mc_event_raise (MCEVENT_GROUP_CORE, "help", &event_data);
1150 }
1151
1152
1153
1154 #ifdef ENABLE_VFS_FTP
1155 void
1156 ftplink_cmd (void)
1157 {
1158 nice_cd (_ ("FTP to machine"), _ (machine_str), "[FTP File System]",
1159 ":ftplink_cmd: FTP to machine ", "ftp://", 1, TRUE);
1160 }
1161 #endif
1162
1163
1164
1165 #ifdef ENABLE_VFS_SFTP
1166 void
1167 sftplink_cmd (void)
1168 {
1169 nice_cd (_ ("SFTP to machine"), _ (machine_str),
1170 "[SFTP (SSH File Transfer Protocol) filesystem]", ":sftplink_cmd: SFTP to machine ",
1171 "sftp://", 1, TRUE);
1172 }
1173 #endif
1174
1175
1176
1177 #ifdef ENABLE_VFS_SHELL
1178 void
1179 shelllink_cmd (void)
1180 {
1181 nice_cd (_ ("Shell link to machine"), _ (machine_str), "[FIle transfer over SHell filesystem]",
1182 ":fishlink_cmd: Shell link to machine ", "sh://", 1, TRUE);
1183 }
1184 #endif
1185
1186
1187
1188 #ifdef ENABLE_VFS_UNDELFS
1189 void
1190 undelete_cmd (void)
1191 {
1192 nice_cd (_ ("Undelete files on an ext2 file system"),
1193 _ ("Enter device (without /dev/) to undelete\nfiles on: (F1 for details)"),
1194 "[Undelete File System]", ":undelete_cmd: Undel on ext2 fs ", "undel://", 0, FALSE);
1195 }
1196 #endif
1197
1198
1199
1200 void
1201 quick_cd_cmd (WPanel *panel)
1202 {
1203 char *p;
1204
1205 p = cd_box (panel);
1206 if (p != NULL && *p != '\0')
1207 cd_to (p);
1208 g_free (p);
1209 }
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222 void
1223 smart_dirsize_cmd (WPanel *panel)
1224 {
1225 const file_entry_t *entry;
1226
1227 entry = panel_current_entry (panel);
1228 if ((entry != NULL && S_ISDIR (entry->st.st_mode) && DIR_IS_DOTDOT (entry->fname->str))
1229 || panel->dirs_marked)
1230 dirsizes_cmd (panel);
1231 else
1232 single_dirsize_cmd (panel);
1233 }
1234
1235
1236
1237 void
1238 single_dirsize_cmd (WPanel *panel)
1239 {
1240 file_entry_t *entry;
1241
1242 entry = panel_current_entry (panel);
1243
1244 if (entry != NULL && S_ISDIR (entry->st.st_mode) && !DIR_IS_DOTDOT (entry->fname->str))
1245 {
1246 size_t dir_count = 0;
1247 size_t count = 0;
1248 uintmax_t total = 0;
1249 dirsize_status_msg_t dsm;
1250 vfs_path_t *p;
1251
1252 p = vfs_path_from_str (entry->fname->str);
1253
1254 memset (&dsm, 0, sizeof (dsm));
1255 status_msg_init (STATUS_MSG (&dsm), _ ("Directory scanning"), 0, dirsize_status_init_cb,
1256 dirsize_status_update_cb, dirsize_status_deinit_cb);
1257
1258 if (compute_dir_size (p, &dsm, &dir_count, &count, &total, FALSE) == FILE_CONT)
1259 {
1260 entry->st.st_size = (off_t) total;
1261 entry->f.dir_size_computed = 1;
1262 }
1263
1264 vfs_path_free (p, TRUE);
1265
1266 status_msg_deinit (STATUS_MSG (&dsm));
1267 }
1268
1269 if (panels_options.mark_moves_down)
1270 send_message (panel, NULL, MSG_ACTION, CK_Down, NULL);
1271
1272 recalculate_panel_summary (panel);
1273
1274 if (panel->sort_field->sort_routine == (GCompareFunc) sort_size)
1275 panel_re_sort (panel);
1276
1277 panel->dirty = TRUE;
1278 }
1279
1280
1281
1282 void
1283 dirsizes_cmd (WPanel *panel)
1284 {
1285 int i;
1286 dirsize_status_msg_t dsm;
1287
1288 memset (&dsm, 0, sizeof (dsm));
1289 status_msg_init (STATUS_MSG (&dsm), _ ("Directory scanning"), 0, dirsize_status_init_cb,
1290 dirsize_status_update_cb, dirsize_status_deinit_cb);
1291
1292 for (i = 0; i < panel->dir.len; i++)
1293 if (S_ISDIR (panel->dir.list[i].st.st_mode)
1294 && ((panel->dirs_marked != 0 && panel->dir.list[i].f.marked != 0)
1295 || panel->dirs_marked == 0)
1296 && !DIR_IS_DOTDOT (panel->dir.list[i].fname->str))
1297 {
1298 vfs_path_t *p;
1299 size_t dir_count = 0;
1300 size_t count = 0;
1301 uintmax_t total = 0;
1302 gboolean ok;
1303
1304 p = vfs_path_from_str (panel->dir.list[i].fname->str);
1305 ok = compute_dir_size (p, &dsm, &dir_count, &count, &total, FALSE) != FILE_CONT;
1306 vfs_path_free (p, TRUE);
1307 if (ok)
1308 break;
1309
1310 panel->dir.list[i].st.st_size = (off_t) total;
1311 panel->dir.list[i].f.dir_size_computed = 1;
1312 }
1313
1314 status_msg_deinit (STATUS_MSG (&dsm));
1315
1316 recalculate_panel_summary (panel);
1317
1318 if (panel->sort_field->sort_routine == (GCompareFunc) sort_size)
1319 panel_re_sort (panel);
1320
1321 panel->dirty = TRUE;
1322 }
1323
1324
1325
1326 void
1327 save_setup_cmd (void)
1328 {
1329 vfs_path_t *vpath;
1330 const char *path;
1331
1332 vpath = vfs_path_from_str_flags (mc_config_get_path (), VPF_STRIP_HOME);
1333 path = vfs_path_as_str (vpath);
1334
1335 if (save_setup (TRUE, TRUE))
1336 message (D_NORMAL, _ ("Setup"), _ ("Setup saved to %s"), path);
1337 else
1338 message (D_ERROR, _ ("Setup"), _ ("Unable to save setup to %s"), path);
1339
1340 vfs_path_free (vpath, TRUE);
1341 }
1342
1343
1344
1345 void
1346 info_cmd_no_menu (void)
1347 {
1348 if (get_panel_type (0) == view_info)
1349 create_panel (0, view_listing);
1350 else if (get_panel_type (1) == view_info)
1351 create_panel (1, view_listing);
1352 else
1353 create_panel (current_panel == left_panel ? 1 : 0, view_info);
1354 }
1355
1356
1357
1358 void
1359 quick_cmd_no_menu (void)
1360 {
1361 if (get_panel_type (0) == view_quick)
1362 create_panel (0, view_listing);
1363 else if (get_panel_type (1) == view_quick)
1364 create_panel (1, view_listing);
1365 else
1366 create_panel (current_panel == left_panel ? 1 : 0, view_quick);
1367 }
1368
1369
1370
1371 void
1372 listing_cmd (void)
1373 {
1374 WPanel *p;
1375
1376 switch_to_listing (MENU_PANEL_IDX);
1377
1378 p = PANEL (get_panel_widget (MENU_PANEL_IDX));
1379
1380 p->is_panelized = FALSE;
1381 panel_set_filter (p, NULL);
1382 }
1383
1384
1385
1386 void
1387 setup_listing_format_cmd (void)
1388 {
1389 int list_format;
1390 gboolean use_msformat;
1391 int brief_cols;
1392 char *user, *status;
1393 WPanel *p = NULL;
1394
1395 if (SELECTED_IS_PANEL)
1396 p = MENU_PANEL_IDX == 0 ? left_panel : right_panel;
1397
1398 list_format = panel_listing_box (p, MENU_PANEL_IDX, &user, &status, &use_msformat, &brief_cols);
1399 if (list_format != -1)
1400 {
1401 switch_to_listing (MENU_PANEL_IDX);
1402 p = MENU_PANEL_IDX == 0 ? left_panel : right_panel;
1403 configure_panel_listing (p, list_format, brief_cols, use_msformat, &user, &status);
1404 g_free (user);
1405 g_free (status);
1406 }
1407 }
1408
1409
1410
1411 void
1412 panel_tree_cmd (void)
1413 {
1414 create_panel (MENU_PANEL_IDX, view_tree);
1415 }
1416
1417
1418
1419 void
1420 info_cmd (void)
1421 {
1422 create_panel (MENU_PANEL_IDX, view_info);
1423 }
1424
1425
1426
1427 void
1428 quick_view_cmd (void)
1429 {
1430 if (PANEL (get_panel_widget (MENU_PANEL_IDX)) == current_panel)
1431 (void) change_panel ();
1432 create_panel (MENU_PANEL_IDX, view_quick);
1433 }
1434
1435
1436
1437 #ifdef HAVE_CHARSET
1438 void
1439 encoding_cmd (void)
1440 {
1441 if (SELECTED_IS_PANEL)
1442 panel_change_encoding (MENU_PANEL);
1443 }
1444 #endif
1445
1446