This source file includes following definitions.
- check_codeset
- OS_Setup
- sigchld_handler_no_subshell
- init_sigchld
- check_sid
- main
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 <locale.h>
37 #include <pwd.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <sys/types.h>
42 #include <sys/wait.h>
43 #include <signal.h>
44 #include <unistd.h>
45
46 #include "lib/global.h"
47
48 #include "lib/event.h"
49 #include "lib/tty/tty.h"
50 #include "lib/tty/key.h"
51 #include "lib/tty/mouse.h"
52 #include "lib/skin.h"
53 #include "lib/filehighlight.h"
54 #include "lib/fileloc.h"
55 #include "lib/strutil.h"
56 #include "lib/util.h"
57 #include "lib/vfs/vfs.h"
58
59 #include "filemanager/filemanager.h"
60 #include "filemanager/treestore.h"
61 #include "filemanager/layout.h"
62 #include "filemanager/ext.h"
63 #include "filemanager/command.h"
64 #include "filemanager/panel.h"
65
66 #include "vfs/plugins_init.h"
67
68 #include "events_init.h"
69 #include "args.h"
70 #ifdef ENABLE_SUBSHELL
71 #include "subshell/subshell.h"
72 #endif
73 #include "setup.h"
74
75 #ifdef HAVE_CHARSET
76 #include "lib/charsets.h"
77 #include "selcodepage.h"
78 #endif
79
80 #include "consaver/cons.saver.h"
81
82
83
84
85
86
87
88
89
90
91
92
93 static void
94 check_codeset (void)
95 {
96 const char *current_system_codepage = NULL;
97
98 current_system_codepage = str_detect_termencoding ();
99
100 #ifdef HAVE_CHARSET
101 {
102 const char *_display_codepage;
103
104 _display_codepage = get_codepage_id (mc_global.display_codepage);
105
106 if (strcmp (_display_codepage, current_system_codepage) != 0)
107 {
108 mc_global.display_codepage = get_codepage_index (current_system_codepage);
109 if (mc_global.display_codepage == -1)
110 mc_global.display_codepage = 0;
111
112 mc_config_set_string (mc_global.main_config, CONFIG_MISC_SECTION, "display_codepage",
113 cp_display);
114 }
115 }
116 #endif
117
118 mc_global.utf8_display = str_isutf8 (current_system_codepage);
119 }
120
121
122
123
124 static void
125 OS_Setup (void)
126 {
127 const char *datadir_env;
128
129 mc_shell_init ();
130
131
132
133 datadir_env = g_getenv ("MC_DATADIR");
134 if (datadir_env != NULL)
135 mc_global.sysconfig_dir = g_strdup (datadir_env);
136 else
137 mc_global.sysconfig_dir = g_strdup (SYSCONFDIR);
138
139 mc_global.share_data_dir = g_strdup (DATADIR);
140 }
141
142
143
144 static void
145 sigchld_handler_no_subshell (int sig)
146 {
147 #ifdef __linux__
148 int pid, status;
149
150 if (mc_global.tty.console_flag == '\0')
151 return;
152
153
154
155
156
157
158
159
160 pid = waitpid (cons_saver_pid, &status, WUNTRACED | WNOHANG);
161
162 if (pid == cons_saver_pid)
163 {
164 if (WIFSTOPPED (status))
165 {
166
167 kill (pid, SIGCONT);
168 }
169 else
170 {
171
172 handle_console (CONSOLE_DONE);
173 mc_global.tty.console_flag = '\0';
174 }
175 }
176
177 #endif
178
179 (void) sig;
180 }
181
182
183
184 static void
185 init_sigchld (void)
186 {
187 struct sigaction sigchld_action;
188
189 memset (&sigchld_action, 0, sizeof (sigchld_action));
190 sigchld_action.sa_handler =
191 #ifdef ENABLE_SUBSHELL
192 mc_global.tty.use_subshell ? sigchld_handler :
193 #endif
194 sigchld_handler_no_subshell;
195
196 sigemptyset (&sigchld_action.sa_mask);
197
198 #ifdef SA_RESTART
199 sigchld_action.sa_flags = SA_RESTART;
200 #endif
201
202 if (sigaction (SIGCHLD, &sigchld_action, NULL) == -1)
203 {
204 #ifdef ENABLE_SUBSHELL
205
206
207
208
209 mc_global.tty.use_subshell = FALSE;
210 #endif
211 }
212 }
213
214
215
216
217
218
219
220
221 static gboolean
222 check_sid (void)
223 {
224 pid_t my_sid, old_sid;
225 const char *sid_str;
226
227 sid_str = getenv ("MC_SID");
228 if (sid_str == NULL)
229 return TRUE;
230
231 old_sid = (pid_t) strtol (sid_str, NULL, 0);
232 if (old_sid == 0)
233 return TRUE;
234
235 my_sid = getsid (0);
236 if (my_sid == -1)
237 return TRUE;
238
239
240 return (old_sid != my_sid);
241 }
242
243
244
245
246
247 int
248 main (int argc, char *argv[])
249 {
250 GError *mcerror = NULL;
251 int exit_code = EXIT_FAILURE;
252
253 mc_global.run_from_parent_mc = !check_sid ();
254
255
256 #ifdef HAVE_SETLOCALE
257 (void) setlocale (LC_ALL, "");
258 #endif
259 (void) bindtextdomain (PACKAGE, LOCALEDIR);
260 (void) textdomain (PACKAGE);
261
262
263 str_init_strings (NULL);
264
265 mc_setup_run_mode (argv);
266
267 if (!mc_args_parse (&argc, &argv, "mc", &mcerror))
268 {
269 startup_exit_falure:
270 fprintf (stderr, _("Failed to run:\n%s\n"), mcerror->message);
271 g_error_free (mcerror);
272 startup_exit_ok:
273 mc_shell_deinit ();
274 str_uninit_strings ();
275 return exit_code;
276 }
277
278
279 OS_Setup ();
280
281 if (!g_path_is_absolute (mc_config_get_home_dir ()))
282 {
283 mc_propagate_error (&mcerror, 0, "%s: %s", _("Home directory path is not absolute"),
284 mc_config_get_home_dir ());
285 mc_event_deinit (NULL);
286 goto startup_exit_falure;
287 }
288
289 if (!mc_args_show_info ())
290 {
291 exit_code = EXIT_SUCCESS;
292 goto startup_exit_ok;
293 }
294
295 if (!events_init (&mcerror))
296 goto startup_exit_falure;
297
298 mc_config_init_config_paths (&mcerror);
299 if (mcerror != NULL)
300 {
301 mc_event_deinit (NULL);
302 goto startup_exit_falure;
303 }
304
305 vfs_init ();
306 vfs_plugins_init ();
307
308 load_setup ();
309
310
311 vfs_setup_work_dir ();
312
313
314 mc_tmpdir ();
315
316
317
318 if (!mc_setup_by_args (argc, argv, &mcerror))
319 {
320 vfs_shut ();
321 done_setup ();
322 g_free (saved_other_dir);
323 mc_event_deinit (NULL);
324 goto startup_exit_falure;
325 }
326
327
328
329
330
331 if (mc_global.mc_run_mode == MC_RUN_FULL)
332 {
333 char *buffer;
334 vfs_path_t *vpath;
335
336 buffer = mc_config_get_string (mc_global.panels_config, "Dirs", "other_dir", ".");
337 vpath = vfs_path_from_str (buffer);
338 if (vfs_file_is_local (vpath))
339 saved_other_dir = buffer;
340 else
341 g_free (buffer);
342 vfs_path_free (vpath);
343 }
344
345
346
347
348
349
350 mc_global.tty.xterm_flag = tty_check_term (mc_args__force_xterm);
351
352
353
354 init_key ();
355
356
357 handle_console (CONSOLE_INIT);
358
359 #ifdef ENABLE_SUBSHELL
360
361 if (mc_global.mc_run_mode != MC_RUN_FULL && mc_global.run_from_parent_mc)
362 mc_global.tty.use_subshell = FALSE;
363
364 if (mc_global.tty.use_subshell)
365 subshell_get_console_attributes ();
366 #endif
367
368
369 init_sigchld ();
370
371
372 save_stop_handler ();
373
374
375
376 tty_init (!mc_args__nomouse, mc_global.tty.xterm_flag);
377
378
379 check_codeset ();
380
381
382 load_key_defs ();
383
384 load_keymap_defs (!mc_args__nokeymap);
385
386 #ifdef USE_INTERNAL_EDIT
387 macros_list = g_array_new (TRUE, FALSE, sizeof (macros_t));
388 #endif
389
390 tty_init_colors (mc_global.tty.disable_colors, mc_args__force_colors);
391
392 mc_skin_init (NULL, &mcerror);
393 dlg_set_default_colors ();
394 input_set_default_colors ();
395 if (mc_global.mc_run_mode == MC_RUN_FULL)
396 command_set_default_colors ();
397
398 mc_error_message (&mcerror, NULL);
399
400 #ifdef ENABLE_SUBSHELL
401
402
403 if (mc_global.tty.use_subshell && mc_global.run_from_parent_mc)
404 {
405 int r;
406
407 r = query_dialog (_("Warning"),
408 _("GNU Midnight Commander\nis already running on this terminal.\n"
409 "Subshell support will be disabled."),
410 D_ERROR, 2, _("&OK"), _("&Quit"));
411 if (r == 0)
412 {
413
414 ;
415 }
416 else
417 {
418
419 mc_global.midnight_shutdown = TRUE;
420 }
421
422 mc_global.tty.use_subshell = FALSE;
423 }
424
425 if (mc_global.tty.use_subshell)
426 init_subshell ();
427 #endif
428
429 if (!mc_global.midnight_shutdown)
430 {
431
432 if (mc_global.tty.console_flag != '\0')
433 handle_console (CONSOLE_SAVE);
434
435 if (mc_global.tty.alternate_plus_minus)
436 application_keypad_mode ();
437
438
439
440 init_mouse ();
441
442
443
444 enable_bracketed_paste ();
445
446
447 mc_prompt = (geteuid () == 0) ? "# " : "$ ";
448 }
449
450
451 if (mc_global.midnight_shutdown)
452 exit_code = EXIT_SUCCESS;
453 else
454 exit_code = do_nc ()? EXIT_SUCCESS : EXIT_FAILURE;
455
456 disable_bracketed_paste ();
457
458 disable_mouse ();
459
460
461 (void) tree_store_save ();
462
463 free_keymap_defs ();
464
465
466 vfs_shut ();
467
468 flush_extension_file ();
469
470 mc_skin_deinit ();
471 tty_colors_done ();
472
473 tty_shutdown ();
474
475 done_setup ();
476
477 if (mc_global.tty.console_flag != '\0' && (quit & SUBSHELL_EXIT) == 0)
478 handle_console (CONSOLE_RESTORE);
479 if (mc_global.tty.alternate_plus_minus)
480 numeric_keypad_mode ();
481
482 (void) signal (SIGCHLD, SIG_DFL);
483
484 if (mc_global.tty.console_flag != '\0')
485 handle_console (CONSOLE_DONE);
486
487 if (mc_global.mc_run_mode == MC_RUN_FULL && mc_args__last_wd_file != NULL
488 && last_wd_string != NULL && !print_last_revert)
489 {
490 int last_wd_fd;
491
492 last_wd_fd = open (mc_args__last_wd_file, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL,
493 S_IRUSR | S_IWUSR);
494 if (last_wd_fd != -1)
495 {
496 ssize_t ret1;
497 int ret2;
498 ret1 = write (last_wd_fd, last_wd_string, strlen (last_wd_string));
499 ret2 = close (last_wd_fd);
500 (void) ret1;
501 (void) ret2;
502 }
503 }
504 g_free (last_wd_string);
505
506 mc_shell_deinit ();
507
508 done_key ();
509
510 #ifdef USE_INTERNAL_EDIT
511 if (macros_list != NULL)
512 {
513 guint i;
514
515 for (i = 0; i < macros_list->len; i++)
516 {
517 macros_t *macros;
518
519 macros = &g_array_index (macros_list, struct macros_t, i);
520 if (macros != NULL && macros->macro != NULL)
521 (void) g_array_free (macros->macro, TRUE);
522 }
523 (void) g_array_free (macros_list, TRUE);
524 }
525 #endif
526
527 str_uninit_strings ();
528
529 if (mc_global.mc_run_mode != MC_RUN_EDITOR)
530 g_free (mc_run_param0);
531 else
532 g_list_free_full ((GList *) mc_run_param0, (GDestroyNotify) mcedit_arg_free);
533
534 g_free (mc_run_param1);
535 g_free (saved_other_dir);
536
537 mc_config_deinit_config_paths ();
538
539 (void) mc_event_deinit (&mcerror);
540 if (mcerror != NULL)
541 {
542 fprintf (stderr, _("\nFailed while close:\n%s\n"), mcerror->message);
543 g_error_free (mcerror);
544 exit_code = EXIT_FAILURE;
545 }
546
547 (void) putchar ('\n');
548
549 return exit_code;
550 }
551
552