This source file includes following definitions.
- exec_cleanup_script
- exec_cleanup_file_name
- exec_get_file_name
- exec_expand_format
- exec_get_export_variables
- exec_make_shell_string
- exec_extension_view
- exec_extension_cd
- exec_extension
- get_popen_information
- get_file_type_local
- get_file_encoding_local
- regex_check_type
- check_old_extension_file
- load_extension_file
- flush_extension_file
- regex_command_for
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 #include <config.h>
33
34 #include <ctype.h>
35 #include <errno.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <unistd.h>
40
41 #include "lib/global.h"
42 #include "lib/tty/tty.h"
43 #include "lib/search.h"
44 #include "lib/fileloc.h"
45 #include "lib/mcconfig.h"
46 #include "lib/util.h"
47 #include "lib/vfs/vfs.h"
48 #include "lib/widget.h"
49 #ifdef HAVE_CHARSET
50 # include "lib/charsets.h"
51 #endif
52
53 #ifdef USE_FILE_CMD
54 # include "src/setup.h"
55 #endif
56 #include "src/execute.h"
57 #include "src/history.h"
58 #include "src/usermenu.h"
59
60 #include "src/consaver/cons.saver.h"
61 #include "src/viewer/mcviewer.h"
62
63 #ifdef HAVE_CHARSET
64 # include "src/selcodepage.h"
65 #endif
66
67 #include "filemanager.h"
68 #include "panel.h"
69
70 #include "ext.h"
71
72
73
74
75
76 #ifdef USE_FILE_CMD
77 # ifdef FILE_B
78 # define FILE_CMD "file -z " FILE_B FILE_S FILE_L
79 # else
80 # define FILE_CMD "file -z " FILE_S FILE_L
81 # endif
82 #endif
83
84
85
86 typedef char *(*quote_func_t) (const char *name, gboolean quote_percent);
87
88
89
90
91
92
93
94
95
96 static mc_config_t *ext_ini = NULL;
97 static gchar **ext_ini_groups = NULL;
98 static vfs_path_t *localfilecopy_vpath = NULL;
99 static char buffer[BUF_1K];
100
101 static char *pbuffer = NULL;
102 static time_t localmtime = 0;
103 static quote_func_t quote_func = name_quote;
104 static gboolean run_view = FALSE;
105 static gboolean is_cd = FALSE;
106 static gboolean written_nonspace = FALSE;
107 static gboolean do_local_copy = FALSE;
108
109 static const char *descr_group = "mc.ext.ini";
110 static const char *default_group = "Default";
111
112
113
114
115
116 static void
117 exec_cleanup_script (vfs_path_t *script_vpath)
118 {
119 if (script_vpath != NULL)
120 {
121 (void) mc_unlink (script_vpath);
122 vfs_path_free (script_vpath, TRUE);
123 }
124 }
125
126
127
128 static void
129 exec_cleanup_file_name (const vfs_path_t *filename_vpath, gboolean has_changed)
130 {
131 if (localfilecopy_vpath == NULL)
132 return;
133
134 if (has_changed)
135 {
136 struct stat mystat;
137
138 mc_stat (localfilecopy_vpath, &mystat);
139 has_changed = localmtime != mystat.st_mtime;
140 }
141 mc_ungetlocalcopy (filename_vpath, localfilecopy_vpath, has_changed);
142 vfs_path_free (localfilecopy_vpath, TRUE);
143 localfilecopy_vpath = NULL;
144 }
145
146
147
148 static char *
149 exec_get_file_name (const vfs_path_t *filename_vpath)
150 {
151 if (!do_local_copy)
152 return quote_func (vfs_path_get_last_path_str (filename_vpath), FALSE);
153
154 if (localfilecopy_vpath == NULL)
155 {
156 struct stat mystat;
157 localfilecopy_vpath = mc_getlocalcopy (filename_vpath);
158 if (localfilecopy_vpath == NULL)
159 return NULL;
160
161 mc_stat (localfilecopy_vpath, &mystat);
162 localmtime = mystat.st_mtime;
163 }
164
165 return quote_func (vfs_path_get_last_path_str (localfilecopy_vpath), FALSE);
166 }
167
168
169
170 static char *
171 exec_expand_format (char symbol, gboolean is_result_quoted)
172 {
173 char *text;
174
175 text = expand_format (NULL, symbol, TRUE);
176 if (is_result_quoted && text != NULL)
177 {
178 char *quoted_text;
179
180 quoted_text = g_strdup_printf ("\"%s\"", text);
181 g_free (text);
182 text = quoted_text;
183 }
184 return text;
185 }
186
187
188
189 static GString *
190 exec_get_export_variables (const vfs_path_t *filename_vpath)
191 {
192 char *text;
193 GString *export_vars_string;
194 size_t i;
195
196 struct
197 {
198 const char symbol;
199 const char *name;
200 const gboolean is_result_quoted;
201 } export_variables[] = {
202 { 'p', "MC_EXT_BASENAME", FALSE },
203 { 'd', "MC_EXT_CURRENTDIR", FALSE },
204 { 's', "MC_EXT_SELECTED", TRUE },
205 { 't', "MC_EXT_ONLYTAGGED", TRUE },
206 { '\0', NULL, FALSE },
207 };
208
209 text = exec_get_file_name (filename_vpath);
210 if (text == NULL)
211 return NULL;
212
213 export_vars_string = g_string_new ("MC_EXT_FILENAME=");
214 g_string_append_printf (export_vars_string, "%s\nexport MC_EXT_FILENAME\n", text);
215 g_free (text);
216
217 for (i = 0; export_variables[i].name != NULL; i++)
218 {
219 text =
220 exec_expand_format (export_variables[i].symbol, export_variables[i].is_result_quoted);
221 if (text != NULL)
222 {
223 g_string_append_printf (export_vars_string, "%s=%s\nexport %s\n",
224 export_variables[i].name, text, export_variables[i].name);
225 g_free (text);
226 }
227 }
228
229 return export_vars_string;
230 }
231
232
233
234 static GString *
235 exec_make_shell_string (const char *lc_data, const vfs_path_t *filename_vpath)
236 {
237 GString *shell_string;
238 char lc_prompt[80] = "\0";
239 gboolean parameter_found = FALSE;
240 gboolean expand_prefix_found = FALSE;
241
242 shell_string = g_string_new ("");
243
244 for (; *lc_data != '\0' && *lc_data != '\n'; lc_data++)
245 {
246 if (parameter_found)
247 {
248 if (*lc_data == '}')
249 {
250 char *parameter;
251
252 parameter_found = FALSE;
253 parameter = input_dialog (_ ("Parameter"), lc_prompt, MC_HISTORY_EXT_PARAMETER, "",
254 INPUT_COMPLETE_NONE);
255 if (parameter == NULL)
256 {
257
258 g_string_free (shell_string, TRUE);
259 exec_cleanup_file_name (filename_vpath, FALSE);
260 return NULL;
261 }
262 g_string_append (shell_string, parameter);
263 written_nonspace = TRUE;
264 g_free (parameter);
265 }
266 else
267 {
268 size_t len = strlen (lc_prompt);
269
270 if (len < sizeof (lc_prompt) - 1)
271 {
272 lc_prompt[len] = *lc_data;
273 lc_prompt[len + 1] = '\0';
274 }
275 }
276 }
277 else if (expand_prefix_found)
278 {
279 expand_prefix_found = FALSE;
280 if (*lc_data == '{')
281 parameter_found = TRUE;
282 else
283 {
284 int i;
285
286 i = check_format_view (lc_data);
287 if (i != 0)
288 {
289 lc_data += i - 1;
290 run_view = TRUE;
291 }
292 else
293 {
294 i = check_format_cd (lc_data);
295 if (i > 0)
296 {
297 is_cd = TRUE;
298 quote_func = fake_name_quote;
299 do_local_copy = FALSE;
300 pbuffer = buffer;
301 lc_data += i - 1;
302 }
303 else
304 {
305 char *v;
306
307 i = check_format_var (lc_data, &v);
308 if (i > 0)
309 {
310 g_string_append (shell_string, v);
311 g_free (v);
312 lc_data += i;
313 }
314 else
315 {
316 char *text;
317
318 if (*lc_data != 'f')
319 text = expand_format (NULL, *lc_data, !is_cd);
320 else
321 {
322 text = exec_get_file_name (filename_vpath);
323 if (text == NULL)
324 {
325 g_string_free (shell_string, TRUE);
326 return NULL;
327 }
328 }
329
330 if (text != NULL)
331 {
332 if (!is_cd)
333 g_string_append (shell_string, text);
334 else
335 {
336 strcpy (pbuffer, text);
337 pbuffer = strchr (pbuffer, '\0');
338 }
339
340 g_free (text);
341 }
342
343 written_nonspace = TRUE;
344 }
345 }
346 }
347 }
348 }
349 else if (*lc_data == '%')
350 expand_prefix_found = TRUE;
351 else
352 {
353 if (!whitespace (*lc_data))
354 written_nonspace = TRUE;
355 if (is_cd)
356 *(pbuffer++) = *lc_data;
357 else
358 g_string_append_c (shell_string, *lc_data);
359 }
360 }
361
362 return shell_string;
363 }
364
365
366
367 static void
368 exec_extension_view (void *target, char *cmd, const vfs_path_t *filename_vpath, int start_line)
369 {
370 mcview_mode_flags_t def_flags = {
371 .wrap = FALSE,
372 .hex = mcview_global_flags.hex,
373 .magic = FALSE,
374 .nroff = mcview_global_flags.nroff,
375 };
376
377 mcview_mode_flags_t changed_flags;
378
379 mcview_clear_mode_flags (&changed_flags);
380 mcview_altered_flags.hex = FALSE;
381 mcview_altered_flags.nroff = FALSE;
382 if (def_flags.hex != mcview_global_flags.hex)
383 changed_flags.hex = TRUE;
384 if (def_flags.nroff != mcview_global_flags.nroff)
385 changed_flags.nroff = TRUE;
386
387 if (target == NULL)
388 mcview_viewer (cmd, filename_vpath, start_line, 0, 0);
389 else
390 mcview_load ((WView *) target, cmd, vfs_path_as_str (filename_vpath), start_line, 0, 0);
391
392 if (changed_flags.hex && !mcview_altered_flags.hex)
393 mcview_global_flags.hex = def_flags.hex;
394 if (changed_flags.nroff && !mcview_altered_flags.nroff)
395 mcview_global_flags.nroff = def_flags.nroff;
396
397 dialog_switch_process_pending ();
398 }
399
400
401
402 static void
403 exec_extension_cd (WPanel *panel)
404 {
405 char *q;
406 vfs_path_t *p_vpath;
407
408 *pbuffer = '\0';
409 pbuffer = buffer;
410
411
412 q = pbuffer + strlen (pbuffer) - 1;
413 while (q >= pbuffer && whitespace (*q))
414 q--;
415 q[1] = 0;
416
417 p_vpath = vfs_path_from_str_flags (pbuffer, VPF_NO_CANON);
418 panel_cd (panel, p_vpath, cd_parse_command);
419 vfs_path_free (p_vpath, TRUE);
420 }
421
422
423
424 static vfs_path_t *
425 exec_extension (WPanel *panel, void *target, const vfs_path_t *filename_vpath, const char *lc_data,
426 int start_line)
427 {
428 GString *shell_string, *export_variables;
429 vfs_path_t *script_vpath = NULL;
430 int cmd_file_fd;
431 FILE *cmd_file;
432 char *cmd = NULL;
433
434 pbuffer = NULL;
435 localmtime = 0;
436 quote_func = name_quote;
437 run_view = FALSE;
438 is_cd = FALSE;
439 written_nonspace = FALSE;
440
441
442 do_local_copy = !vfs_file_is_local (filename_vpath);
443
444 shell_string = exec_make_shell_string (lc_data, filename_vpath);
445 if (shell_string == NULL)
446 goto ret;
447
448 if (is_cd)
449 {
450 exec_extension_cd (panel);
451 g_string_free (shell_string, TRUE);
452 goto ret;
453 }
454
455
456
457
458
459
460
461 cmd_file_fd = mc_mkstemps (&script_vpath, "mcext", SCRIPT_SUFFIX);
462
463 if (cmd_file_fd == -1)
464 {
465 message (D_ERROR, MSG_ERROR, _ ("Cannot create temporary command file\n%s"),
466 unix_error_string (errno));
467 g_string_free (shell_string, TRUE);
468 goto ret;
469 }
470
471 cmd_file = fdopen (cmd_file_fd, "w");
472 fputs ("#! /bin/sh\n\n", cmd_file);
473
474 export_variables = exec_get_export_variables (filename_vpath);
475 if (export_variables != NULL)
476 {
477 fputs (export_variables->str, cmd_file);
478 g_string_free (export_variables, TRUE);
479 }
480
481 fputs (shell_string->str, cmd_file);
482 g_string_free (shell_string, TRUE);
483
484
485
486
487
488
489 if (!run_view)
490 fprintf (cmd_file, "\n/bin/rm -f %s\n", vfs_path_as_str (script_vpath));
491
492 fclose (cmd_file);
493
494 if ((run_view && !written_nonspace) || is_cd)
495 {
496 exec_cleanup_script (script_vpath);
497 script_vpath = NULL;
498 }
499 else
500 {
501
502 mc_chmod (script_vpath, S_IRWXU);
503
504 cmd = g_strconcat ("/bin/sh ", vfs_path_as_str (script_vpath), (char *) NULL);
505 }
506
507 if (run_view)
508 {
509
510 if (!written_nonspace)
511 exec_extension_view (target, NULL, filename_vpath, start_line);
512 else
513 exec_extension_view (target, cmd, filename_vpath, start_line);
514 }
515 else
516 {
517 shell_execute (cmd, EXECUTE_INTERNAL);
518 if (mc_global.tty.console_flag != '\0')
519 {
520 handle_console (CONSOLE_SAVE);
521 if (output_lines != 0 && mc_global.keybar_visible)
522 {
523 unsigned char end_line;
524
525 end_line = LINES - (mc_global.keybar_visible ? 1 : 0) - 1;
526 show_console_contents (output_start_y, end_line - output_lines, end_line);
527 }
528 }
529 }
530
531 g_free (cmd);
532
533 exec_cleanup_file_name (filename_vpath, TRUE);
534 ret:
535 return script_vpath;
536 }
537
538
539
540
541
542
543
544
545
546
547 #ifdef USE_FILE_CMD
548 static int
549 get_popen_information (const char *cmd_file, const char *args, char *buf, int buflen)
550 {
551 gboolean read_bytes = FALSE;
552 char *command;
553 FILE *f;
554
555 command = g_strconcat (cmd_file, args, " 2>/dev/null", (char *) NULL);
556 f = popen (command, "r");
557 g_free (command);
558
559 if (f != NULL)
560 {
561 # ifdef __QNXNTO__
562 if (setvbuf (f, NULL, _IOFBF, 0) != 0)
563 {
564 (void) pclose (f);
565 return -1;
566 }
567 # endif
568 read_bytes = (fgets (buf, buflen, f) != NULL);
569 if (!read_bytes)
570 buf[0] = '\0';
571 pclose (f);
572 }
573 else
574 {
575 buf[0] = '\0';
576 return -1;
577 }
578
579 buf[buflen - 1] = '\0';
580
581 return read_bytes ? 1 : 0;
582 }
583
584
585
586
587
588
589
590 static int
591 get_file_type_local (const vfs_path_t *filename_vpath, char *buf, int buflen)
592 {
593 char *filename_quoted;
594 int ret = 0;
595
596 filename_quoted = name_quote (vfs_path_get_last_path_str (filename_vpath), FALSE);
597 if (filename_quoted != NULL)
598 {
599 ret = get_popen_information (FILE_CMD, filename_quoted, buf, buflen);
600 g_free (filename_quoted);
601 }
602
603 return ret;
604 }
605
606
607
608
609
610
611
612 # ifdef HAVE_CHARSET
613 static int
614 get_file_encoding_local (const vfs_path_t *filename_vpath, char *buf, int buflen)
615 {
616 char *filename_quoted;
617 int ret = 0;
618
619 filename_quoted = name_quote (vfs_path_get_last_path_str (filename_vpath), FALSE);
620 if (filename_quoted != NULL)
621 {
622 char *lang;
623
624 lang = name_quote (autodetect_codeset, FALSE);
625 if (lang != NULL)
626 {
627 char *args;
628
629 args = g_strdup_printf (" -L %s -i %s", lang, filename_quoted);
630 g_free (lang);
631
632 ret = get_popen_information ("enca", args, buf, buflen);
633 g_free (args);
634 }
635
636 g_free (filename_quoted);
637 }
638
639 return ret;
640 }
641 # endif
642
643
644
645
646
647
648
649
650
651 static gboolean
652 regex_check_type (const vfs_path_t *filename_vpath, const char *ptr, gboolean case_insense,
653 gboolean *have_type, GError **mcerror)
654 {
655 gboolean found = FALSE;
656
657
658 static char content_string[2048];
659 static size_t content_shift = 0;
660 static int got_data = 0;
661
662 mc_return_val_if_error (mcerror, FALSE);
663
664 if (!*have_type)
665 {
666 vfs_path_t *localfile_vpath;
667
668 # ifdef HAVE_CHARSET
669 static char encoding_id[21];
670 int got_encoding_data;
671 # endif
672
673
674 *have_type = TRUE;
675
676 localfile_vpath = mc_getlocalcopy (filename_vpath);
677 if (localfile_vpath == NULL)
678 {
679 mc_propagate_error (mcerror, 0, _ ("Cannot fetch a local copy of %s"),
680 vfs_path_as_str (filename_vpath));
681 return FALSE;
682 }
683
684 # ifdef HAVE_CHARSET
685 got_encoding_data = is_autodetect_codeset_enabled
686 ? get_file_encoding_local (localfile_vpath, encoding_id, sizeof (encoding_id))
687 : 0;
688
689 if (got_encoding_data > 0)
690 {
691 char *pp;
692 int cp_id;
693
694 pp = strchr (encoding_id, '\n');
695 if (pp != NULL)
696 *pp = '\0';
697
698 cp_id = get_codepage_index (encoding_id);
699 if (cp_id == -1)
700 cp_id = default_source_codepage;
701
702 do_set_codepage (cp_id);
703 }
704 # endif
705
706 got_data = get_file_type_local (localfile_vpath, content_string, sizeof (content_string));
707
708 mc_ungetlocalcopy (filename_vpath, localfile_vpath, FALSE);
709
710 if (got_data > 0)
711 {
712 char *pp;
713
714 pp = strchr (content_string, '\n');
715 if (pp != NULL)
716 *pp = '\0';
717
718 # ifndef FILE_B
719 {
720 const char *real_name;
721 size_t real_len;
722
723 real_name = vfs_path_get_last_path_str (localfile_vpath);
724 real_len = strlen (real_name);
725
726 if (strncmp (content_string, real_name, real_len) == 0)
727 {
728
729 content_shift = real_len;
730
731
732 if (content_string[content_shift] == ':')
733 for (content_shift++; whitespace (content_string[content_shift]);
734 content_shift++)
735 ;
736 }
737 }
738 # endif
739 }
740 else
741 {
742
743 content_string[0] = '\0';
744 }
745 vfs_path_free (localfile_vpath, TRUE);
746 }
747
748 if (got_data == -1)
749 {
750 mc_propagate_error (mcerror, 0, "%s", _ ("Pipe failed"));
751 return FALSE;
752 }
753
754 if (content_string[0] != '\0')
755 {
756 mc_search_t *search;
757
758 search = mc_search_new (ptr, DEFAULT_CHARSET);
759 if (search != NULL)
760 {
761 search->search_type = MC_SEARCH_T_REGEX;
762 search->is_case_sensitive = !case_insense;
763 found = mc_search_run (search, content_string + content_shift, 0,
764 sizeof (content_string) - 1, NULL);
765 mc_search_free (search);
766 }
767 else
768 {
769 mc_propagate_error (mcerror, 0, "%s", _ ("Regular expression error"));
770 }
771 }
772
773 return found;
774 }
775 #endif
776
777
778
779 static void
780 check_old_extension_file (void)
781 {
782 char *extension_old_file;
783
784 extension_old_file = mc_config_get_full_path (MC_EXT_OLD_FILE);
785 if (exist_file (extension_old_file))
786 message (D_ERROR, _ ("Warning"),
787 _ ("You have an outdated %s file.\nMidnight Commander now uses %s file.\n"
788 "Please copy your modifications of the old file to the new one."),
789 extension_old_file, MC_EXT_FILE);
790 g_free (extension_old_file);
791 }
792
793
794
795 static gboolean
796 load_extension_file (void)
797 {
798 char *extension_file;
799 gboolean mc_user_ext = TRUE;
800 gboolean home_error = FALSE;
801
802 extension_file = mc_config_get_full_path (MC_EXT_FILE);
803 if (!exist_file (extension_file))
804 {
805 g_free (extension_file);
806
807 check_old_extension_file ();
808
809 check_stock_mc_ext:
810 extension_file = mc_build_filename (mc_global.sysconfig_dir, MC_EXT_FILE, (char *) NULL);
811 if (!exist_file (extension_file))
812 {
813 g_free (extension_file);
814 extension_file =
815 mc_build_filename (mc_global.share_data_dir, MC_EXT_FILE, (char *) NULL);
816 if (!exist_file (extension_file))
817 MC_PTR_FREE (extension_file);
818 }
819 mc_user_ext = FALSE;
820 }
821
822 if (extension_file != NULL)
823 {
824 ext_ini = mc_config_init (extension_file, TRUE);
825 g_free (extension_file);
826 }
827 if (ext_ini == NULL)
828 return FALSE;
829
830
831 if (!mc_config_has_group (ext_ini, descr_group))
832 {
833 flush_extension_file ();
834
835 if (!mc_user_ext)
836 {
837 message (D_ERROR, MSG_ERROR,
838 _ ("The format of the\n%s%s\nfile has changed with version 4.0.\n"
839 "It seems that the installation has failed.\nPlease fetch a fresh copy "
840 "from the Midnight Commander package."),
841 mc_global.sysconfig_dir, MC_EXT_FILE);
842 return FALSE;
843 }
844
845 home_error = TRUE;
846 goto check_stock_mc_ext;
847 }
848
849 if (home_error)
850 {
851 extension_file = mc_config_get_full_path (MC_EXT_FILE);
852 message (
853 D_ERROR, MSG_ERROR,
854 _ ("The format of the\n%s\nfile has changed with version 4.0.\nYou may either want "
855 "to copy it from\n%s%s\nor use that file as an example of how to write it."),
856 extension_file, mc_global.sysconfig_dir, MC_EXT_FILE);
857 g_free (extension_file);
858 }
859
860 return TRUE;
861 }
862
863
864
865
866
867 void
868 flush_extension_file (void)
869 {
870 g_strfreev (ext_ini_groups);
871 ext_ini_groups = NULL;
872
873 mc_config_deinit (ext_ini);
874 ext_ini = NULL;
875 }
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892 int
893 regex_command_for (void *target, const vfs_path_t *filename_vpath, const char *action,
894 vfs_path_t **script_vpath)
895 {
896 const char *filename;
897 size_t filename_len;
898 gboolean found = FALSE;
899 gboolean error_flag = FALSE;
900 int ret = 0;
901 struct stat mystat;
902 int view_at_line_number = 0;
903 #ifdef USE_FILE_CMD
904 gboolean have_type = FALSE;
905 #endif
906 char **group_iter;
907 char *include_group = NULL;
908 const char *current_group;
909
910 if (filename_vpath == NULL)
911 return 0;
912
913 if (script_vpath != NULL)
914 *script_vpath = NULL;
915
916
917 if (strncmp (action, "View:", 5) == 0)
918 {
919 view_at_line_number = atoi (action + 5);
920 action = "View";
921 }
922
923 if (ext_ini == NULL && !load_extension_file ())
924 return 0;
925
926 mc_stat (filename_vpath, &mystat);
927
928 filename = vfs_path_get_last_path_str (filename_vpath);
929 filename = x_basename (filename);
930 filename_len = strlen (filename);
931
932 if (ext_ini_groups == NULL)
933 ext_ini_groups = mc_config_get_groups (ext_ini, NULL);
934
935
936 for (group_iter = ext_ini_groups; *group_iter != NULL && !found; group_iter++)
937 {
938 enum
939 {
940 TYPE_UNUSED,
941 TYPE_NOT_FOUND,
942 TYPE_FOUND
943 } type_state = TYPE_UNUSED;
944
945 const gchar *g = *group_iter;
946 gchar *pattern;
947 gboolean ignore_case;
948
949 if (strcmp (g, descr_group) == 0 || strncmp (g, "Include/", 8) == 0
950 || strcmp (g, default_group) == 0)
951 continue;
952
953
954
955 pattern = mc_config_get_string_raw (ext_ini, g, "Directory", NULL);
956 if (pattern != NULL)
957 {
958 found = S_ISDIR (mystat.st_mode)
959 && mc_search (pattern, DEFAULT_CHARSET, vfs_path_as_str (filename_vpath),
960 MC_SEARCH_T_REGEX);
961 g_free (pattern);
962
963 continue;
964 }
965
966 #ifdef USE_FILE_CMD
967 if (use_file_to_check_type)
968 {
969 pattern = mc_config_get_string_raw (ext_ini, g, "Type", NULL);
970 if (pattern != NULL)
971 {
972 GError *mcerror = NULL;
973
974 ignore_case = mc_config_get_bool (ext_ini, g, "TypeIgnoreCase", FALSE);
975 type_state =
976 regex_check_type (filename_vpath, pattern, ignore_case, &have_type, &mcerror)
977 ? TYPE_FOUND
978 : TYPE_NOT_FOUND;
979 g_free (pattern);
980
981 if (mc_error_message (&mcerror, NULL))
982 error_flag = TRUE;
983
984 if (type_state == TYPE_NOT_FOUND)
985 continue;
986 }
987 }
988 #endif
989
990 pattern = mc_config_get_string_raw (ext_ini, g, "Regex", NULL);
991 if (pattern != NULL)
992 {
993 mc_search_t *search;
994
995 ignore_case = mc_config_get_bool (ext_ini, g, "RegexIgnoreCase", FALSE);
996 search = mc_search_new (pattern, DEFAULT_CHARSET);
997 g_free (pattern);
998
999 if (search != NULL)
1000 {
1001 search->search_type = MC_SEARCH_T_REGEX;
1002 search->is_case_sensitive = !ignore_case;
1003 found = mc_search_run (search, filename, 0, filename_len, NULL);
1004 mc_search_free (search);
1005 }
1006
1007 found = found && (type_state == TYPE_UNUSED || type_state == TYPE_FOUND);
1008 }
1009 else
1010 {
1011 pattern = mc_config_get_string_raw (ext_ini, g, "Shell", NULL);
1012 if (pattern != NULL)
1013 {
1014 int (*cmp_func) (const char *s1, const char *s2, size_t n);
1015 size_t pattern_len;
1016
1017 ignore_case = mc_config_get_bool (ext_ini, g, "ShellIgnoreCase", FALSE);
1018 cmp_func = ignore_case ? strncasecmp : strncmp;
1019 pattern_len = strlen (pattern);
1020
1021 if (*pattern == '.' && filename_len >= pattern_len)
1022 found =
1023 cmp_func (pattern, filename + filename_len - pattern_len, pattern_len) == 0;
1024 else
1025 found = pattern_len == filename_len
1026 && cmp_func (pattern, filename, filename_len) == 0;
1027
1028 g_free (pattern);
1029
1030 found = found && (type_state == TYPE_UNUSED || type_state == TYPE_FOUND);
1031 }
1032 else
1033 found = type_state == TYPE_FOUND;
1034 }
1035 }
1036
1037
1038 if (found)
1039 {
1040 char *include_value;
1041
1042 group_iter--;
1043
1044
1045 include_value = mc_config_get_string_raw (ext_ini, *group_iter, "Include", NULL);
1046 if (include_value != NULL)
1047 {
1048
1049 include_group = g_strconcat ("Include/", include_value, (char *) NULL);
1050 g_free (include_value);
1051 found = mc_config_has_group (ext_ini, include_group);
1052 }
1053 }
1054
1055 if (found)
1056 current_group = include_group != NULL ? include_group : *group_iter;
1057 else
1058 {
1059 current_group = default_group;
1060 found = mc_config_has_group (ext_ini, current_group);
1061 }
1062
1063 if (found && !error_flag)
1064 {
1065 gchar *action_value;
1066
1067 action_value = mc_config_get_string_raw (ext_ini, current_group, action, NULL);
1068 if (action_value == NULL)
1069 {
1070
1071 action_value = mc_config_get_string_raw (ext_ini, default_group, action, NULL);
1072 found = (action_value != NULL && *action_value != '\0');
1073 }
1074 else
1075 {
1076
1077 found = (*action_value != '\0');
1078 }
1079
1080 if (found)
1081 {
1082 vfs_path_t *sv;
1083
1084 sv = exec_extension (current_panel, target, filename_vpath, action_value,
1085 view_at_line_number);
1086 if (script_vpath != NULL)
1087 *script_vpath = sv;
1088 else
1089 exec_cleanup_script (sv);
1090
1091 ret = 1;
1092 }
1093
1094 g_free (action_value);
1095 }
1096
1097 g_free (include_group);
1098
1099 return (error_flag ? -1 : ret);
1100 }
1101
1102