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