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