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