static gboolean mc_config_new_or_override_file (mc_config_t * mc_config, const gchar * ini_path, GError ** mcerror) { gchar *data, *written_data; gsize len, total_written; gboolean ret; int fd; ssize_t cur_written; vfs_path_t *ini_vpath; mc_return_val_if_error (mcerror, FALSE); data = g_key_file_to_data (mc_config->handle, &len, NULL); if (!exist_file (ini_path)) { ret = g_file_set_contents (ini_path, data, len, mcerror); g_free (data); return ret; } mc_util_make_backup_if_possible (ini_path, "~"); ini_vpath = vfs_path_from_str (ini_path); fd = mc_open (ini_vpath, O_WRONLY | O_TRUNC, 0); vfs_path_free (ini_vpath); if (fd == -1) { mc_propagate_error (mcerror, 0, "%s", unix_error_string (errno)); g_free (data); return FALSE; } for (written_data = data, total_written = len; (cur_written = mc_write (fd, (const void *) written_data, total_written)) > 0; written_data += cur_written, total_written -= cur_written) ; mc_close (fd); g_free (data); if (cur_written == -1) { mc_util_restore_from_backup_if_possible (ini_path, "~"); mc_propagate_error (mcerror, 0, "%s", unix_error_string (errno)); return FALSE; } mc_util_unlink_backup_if_possible (ini_path, "~"); return TRUE; }
gboolean mc_skin_init (const gchar * skin_override, GError ** mcerror) { gboolean is_good_init = TRUE; mc_return_val_if_error (mcerror, FALSE); mc_skin__default.have_256_colors = FALSE; mc_skin__default.name = skin_override != NULL ? g_strdup (skin_override) : mc_skin_get_default_name (); mc_skin__default.colors = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, mc_skin_hash_destroy_value); if (!mc_skin_ini_file_load (&mc_skin__default)) { mc_propagate_error (mcerror, 0, _("Unable to load '%s' skin.\nDefault skin has been loaded"), mc_skin__default.name); mc_skin_try_to_load_default (); is_good_init = FALSE; } mc_skin_colors_old_configure (&mc_skin__default); if (!mc_skin_ini_file_parse (&mc_skin__default)) { mc_propagate_error (mcerror, 0, _("Unable to parse '%s' skin.\nDefault skin has been loaded"), mc_skin__default.name); mc_skin_try_to_load_default (); mc_skin_colors_old_configure (&mc_skin__default); (void) mc_skin_ini_file_parse (&mc_skin__default); is_good_init = FALSE; } if (is_good_init && !tty_use_256colors () && mc_skin__default.have_256_colors) { mc_propagate_error (mcerror, 0, _ ("Unable to use '%s' skin with 256 colors support\non non-256 colors terminal.\nDefault skin has been loaded"), mc_skin__default.name); mc_skin_try_to_load_default (); mc_skin_colors_old_configure (&mc_skin__default); (void) mc_skin_ini_file_parse (&mc_skin__default); is_good_init = FALSE; } mc_skin_is_init = TRUE; return is_good_init; }
void mc_pread (mc_pipe_t * p, GError ** error) { gboolean read_out, read_err; fd_set fds; int maxfd = 0; int res; if (error != NULL) *error = NULL; read_out = p->out.fd >= 0 && p->out.len > 0; read_err = p->err.fd >= 0 && p->err.len > 0; if (!read_out && !read_err) { p->out.len = MC_PIPE_STREAM_UNREAD; p->err.len = MC_PIPE_STREAM_UNREAD; return; } FD_ZERO (&fds); if (read_out) { FD_SET (p->out.fd, &fds); maxfd = p->out.fd; } if (read_err) { FD_SET (p->err.fd, &fds); maxfd = max (maxfd, p->err.fd); } /* no timeout */ res = select (maxfd + 1, &fds, NULL, NULL, NULL); if (res < 0 && errno != EINTR) { mc_propagate_error (error, MC_PIPE_ERROR_READ, _ ("Unexpected error in select() reading data from a child process:\n%s"), unix_error_string (errno)); return; } if (read_out) mc_pread_stream (&p->out, &fds); else p->out.len = MC_PIPE_STREAM_UNREAD; if (read_err) mc_pread_stream (&p->err, &fds); else p->err.len = MC_PIPE_STREAM_UNREAD; }
void sftpfs_ssherror_to_gliberror (sftpfs_super_data_t * super_data, int libssh_errno, GError ** mcerror) { char *err = NULL; int err_len; mc_return_if_error (mcerror); libssh2_session_last_error (super_data->session, &err, &err_len, 1); mc_propagate_error (mcerror, libssh_errno, "%s", err); g_free (err); }
gboolean mc_event_init (GError ** mcerror) { mc_return_val_if_error (mcerror, FALSE); if (mc_event_grouplist != NULL) { mc_propagate_error (mcerror, 1, "%s", _("Event system already initialized")); return FALSE; } mc_event_grouplist = g_tree_new_full ((GCompareDataFunc) g_ascii_strcasecmp, NULL, (GDestroyNotify) g_free, (GDestroyNotify) g_tree_destroy); if (mc_event_grouplist == NULL) { mc_propagate_error (mcerror, 2, "%s", _("Failed to initialize event system")); return FALSE; } return TRUE; }
gboolean mc_event_deinit (GError ** mcerror) { mc_return_val_if_error (mcerror, FALSE); if (mc_event_grouplist == NULL) { mc_propagate_error (mcerror, 3, "%s", _("Event system not initialized")); return FALSE; } g_tree_destroy (mc_event_grouplist); mc_event_grouplist = NULL; return TRUE; }
ssize_t sftpfs_read_file (vfs_file_handler_t * file_handler, char *buffer, size_t count, GError ** mcerror) { ssize_t rc; sftpfs_file_handler_data_t *file_handler_data; sftpfs_super_data_t *super_data; mc_return_val_if_error (mcerror, -1); if (file_handler == NULL || file_handler->data == NULL) { mc_propagate_error (mcerror, -1, "%s", _("sftp: No file handler data present for reading file")); return -1; } file_handler_data = file_handler->data; super_data = (sftpfs_super_data_t *) file_handler->ino->super->data; do { rc = libssh2_sftp_read (file_handler_data->handle, buffer, count); if (rc >= 0) break; if (rc != LIBSSH2_ERROR_EAGAIN) { sftpfs_ssherror_to_gliberror (super_data, rc, mcerror); return -1; } sftpfs_waitsocket (super_data, mcerror); mc_return_val_if_error (mcerror, -1); } while (rc == LIBSSH2_ERROR_EAGAIN); file_handler->pos = (off_t) libssh2_sftp_tell64 (file_handler_data->handle); return rc; }
gboolean mc_setup_by_args (int argc, char **argv, GError ** mcerror) { const char *base; char *tmp; mc_return_val_if_error (mcerror, FALSE); if (mc_args__force_colors) mc_global.tty.disable_colors = FALSE; #ifdef ENABLE_SUBSHELL if (mc_args__nouse_subshell) mc_global.tty.use_subshell = FALSE; #endif /* ENABLE_SUBSHELL */ #ifdef ENABLE_VFS_SMB if (mc_args__debug_level != 0) smbfs_set_debug (mc_args__debug_level); #endif /* ENABLE_VFS_SMB */ if (mc_args__netfs_logfile != NULL) { vfs_path_t *vpath; #ifdef ENABLE_VFS_FTP vpath = vfs_path_from_str ("ftp://"); mc_setctl (vpath, VFS_SETCTL_LOGFILE, (void *) mc_args__netfs_logfile); vfs_path_free (vpath); #endif /* ENABLE_VFS_FTP */ #ifdef ENABLE_VFS_SMB vpath = vfs_path_from_str ("smb://"); mc_setctl (vpath, VFS_SETCTL_LOGFILE, (void *) mc_args__netfs_logfile); vfs_path_free (vpath); #endif /* ENABLE_VFS_SMB */ (void) vpath; } base = x_basename (argv[0]); tmp = (argc > 0) ? argv[1] : NULL; if (strncmp (base, "mce", 3) == 0 || strcmp (base, "vi") == 0) { /* mce* or vi is link to mc */ mc_global.mc_run_mode = MC_RUN_EDITOR; } else if (strncmp (base, "mcv", 3) == 0 || strcmp (base, "view") == 0) { /* mcv* or view is link to mc */ mc_global.mc_run_mode = MC_RUN_VIEWER; } #ifdef USE_DIFF_VIEW else if (strncmp (base, "mcd", 3) == 0 || strcmp (base, "diff") == 0) { /* mcd* or diff is link to mc */ mc_global.mc_run_mode = MC_RUN_DIFFVIEWER; } #endif /* USE_DIFF_VIEW */ switch (mc_global.mc_run_mode) { case MC_RUN_EDITOR: mc_run_param0 = parse_mcedit_arguments (argc - 1, &argv[1]); break; case MC_RUN_VIEWER: if (tmp == NULL) { mc_propagate_error (mcerror, 0, "%s\n", _("No arguments given to the viewer.")); return FALSE; } mc_run_param0 = g_strdup (tmp); break; #ifdef USE_DIFF_VIEW case MC_RUN_DIFFVIEWER: if (argc < 3) { mc_propagate_error (mcerror, 0, "%s\n", _("Two files are required to envoke the diffviewer.")); return FALSE; } /* fallthrough */ #endif /* USE_DIFF_VIEW */ case MC_RUN_FULL: default: /* set the current dir and the other dir for filemanager, or two files for diff viewer */ if (tmp != NULL) { mc_run_param0 = g_strdup (tmp); tmp = (argc > 1) ? argv[2] : NULL; if (tmp != NULL) mc_run_param1 = g_strdup (tmp); } break; } return TRUE; }
gboolean mc_args_parse (int *argc, char ***argv, const char *translation_domain, GError ** mcerror) { const gchar *_system_codepage; gboolean ok = TRUE; mc_return_val_if_error (mcerror, FALSE); _system_codepage = str_detect_termencoding (); #ifdef ENABLE_NLS if (!str_isutf8 (_system_codepage)) bind_textdomain_codeset ("mc", "UTF-8"); #endif context = g_option_context_new (mc_args_add_usage_info ()); g_option_context_set_ignore_unknown_options (context, FALSE); mc_args_add_extended_info_to_help (); main_group = g_option_group_new ("main", _("Main options"), _("Main options"), NULL, NULL); g_option_group_add_entries (main_group, argument_main_table); g_option_context_set_main_group (context, main_group); g_option_group_set_translation_domain (main_group, translation_domain); terminal_group = g_option_group_new ("terminal", _("Terminal options"), _("Terminal options"), NULL, NULL); g_option_group_add_entries (terminal_group, argument_terminal_table); g_option_context_add_group (context, terminal_group); g_option_group_set_translation_domain (terminal_group, translation_domain); color_group = mc_args_new_color_group (); g_option_group_add_entries (color_group, argument_color_table); g_option_context_add_group (context, color_group); g_option_group_set_translation_domain (color_group, translation_domain); if (!g_option_context_parse (context, argc, argv, mcerror)) { if (*mcerror == NULL) mc_propagate_error (mcerror, 0, "%s\n", _("Arguments parse error!")); else { gchar *help_str; help_str = g_option_context_get_help (context, TRUE, NULL); if (str_isutf8 (_system_codepage)) mc_replace_error (mcerror, (*mcerror)->code, "%s\n\n%s\n", (*mcerror)->message, help_str); else { gchar *full_help_str; full_help_str = mc_args__convert_help_to_syscharset (_system_codepage, (*mcerror)->message, help_str); mc_replace_error (mcerror, (*mcerror)->code, "%s", full_help_str); g_free (full_help_str); } g_free (help_str); } ok = FALSE; } g_option_context_free (context); mc_args_clean_temp_help_strings (); #ifdef ENABLE_NLS if (!str_isutf8 (_system_codepage)) bind_textdomain_codeset ("mc", _system_codepage); #endif return ok; }
int main (int argc, char *argv[]) { GError *mcerror = NULL; gboolean config_migrated = FALSE; char *config_migrate_msg; int exit_code = EXIT_FAILURE; mc_global.timer = mc_timer_new (); /* We had LC_CTYPE before, LC_ALL includs LC_TYPE as well */ #ifdef HAVE_SETLOCALE (void) setlocale (LC_ALL, ""); #endif (void) bindtextdomain (PACKAGE, LOCALEDIR); (void) textdomain (PACKAGE); /* do this before args parsing */ str_init_strings (NULL); if (!mc_args_parse (&argc, &argv, "mc", &mcerror)) { startup_exit_falure: fprintf (stderr, _("Failed to run:\n%s\n"), mcerror->message); g_error_free (mcerror); g_free (mc_global.tty.shell); startup_exit_ok: str_uninit_strings (); mc_timer_destroy (mc_global.timer); return exit_code; } /* do this before mc_args_show_info () to view paths in the --datadir-info output */ OS_Setup (); if (!g_path_is_absolute (mc_config_get_home_dir ())) { mc_propagate_error (&mcerror, 0, "%s: %s", _("Home directory path is not absolute"), mc_config_get_home_dir ()); mc_event_deinit (NULL); goto startup_exit_falure; } if (!mc_args_show_info ()) { exit_code = EXIT_SUCCESS; goto startup_exit_ok; } if (!events_init (&mcerror)) goto startup_exit_falure; mc_config_init_config_paths (&mcerror); config_migrated = mc_config_migrate_from_old_place (&mcerror, &config_migrate_msg); if (mcerror != NULL) { mc_event_deinit (NULL); goto startup_exit_falure; } vfs_init (); vfs_plugins_init (); load_setup (); /* Must be done after load_setup because depends on mc_global.vfs.cd_symlinks */ vfs_setup_work_dir (); /* Resolve the other_dir panel option. Must be done after vfs_setup_work_dir */ { char *buffer; vfs_path_t *vpath; buffer = mc_config_get_string (mc_panels_config, "Dirs", "other_dir", "."); vpath = vfs_path_from_str (buffer); if (vfs_file_is_local (vpath)) saved_other_dir = buffer; else g_free (buffer); vfs_path_free (vpath); } /* Set up temporary directory after VFS initialization */ mc_tmpdir (); /* do this after vfs initialization and vfs working directory setup due to mc_setctl() and mcedit_arg_vpath_new() calls in mc_setup_by_args() */ if (!mc_setup_by_args (argc, argv, &mcerror)) { vfs_shut (); done_setup (); g_free (saved_other_dir); mc_event_deinit (NULL); goto startup_exit_falure; } /* check terminal type * $TEMR must be set and not empty * mc_global.tty.xterm_flag is used in init_key() and tty_init() * Do this after mc_args_handle() where mc_args__force_xterm is set up. */ mc_global.tty.xterm_flag = tty_check_term (mc_args__force_xterm); /* NOTE: This has to be called before tty_init or whatever routine calls any define_sequence */ init_key (); /* Must be done before installing the SIGCHLD handler [[FIXME]] */ handle_console (CONSOLE_INIT); #ifdef ENABLE_SUBSHELL /* Don't use subshell when invoked as viewer or editor */ if (mc_global.mc_run_mode != MC_RUN_FULL) mc_global.tty.use_subshell = FALSE; if (mc_global.tty.use_subshell) subshell_get_console_attributes (); #endif /* ENABLE_SUBSHELL */ /* Install the SIGCHLD handler; must be done before init_subshell() */ init_sigchld (); /* We need this, since ncurses endwin () doesn't restore the signals */ save_stop_handler (); /* Must be done before init_subshell, to set up the terminal size: */ /* FIXME: Should be removed and LINES and COLS computed on subshell */ tty_init (!mc_args__nomouse, mc_global.tty.xterm_flag); /* start check mc_global.display_codepage and mc_global.source_codepage */ check_codeset (); /* Removing this from the X code let's us type C-c */ load_key_defs (); load_keymap_defs (!mc_args__nokeymap); macros_list = g_array_new (TRUE, FALSE, sizeof (macros_t)); tty_init_colors (mc_global.tty.disable_colors, mc_args__force_colors); mc_skin_init (NULL, &mcerror); dlg_set_default_colors (); input_set_default_colors (); if (mc_global.mc_run_mode == MC_RUN_FULL) command_set_default_colors (); mc_error_message (&mcerror); #ifdef ENABLE_SUBSHELL /* Done here to ensure that the subshell doesn't */ /* inherit the file descriptors opened below, etc */ if (mc_global.tty.use_subshell) init_subshell (); #endif /* ENABLE_SUBSHELL */ /* Also done after init_subshell, to save any shell init file messages */ if (mc_global.tty.console_flag != '\0') handle_console (CONSOLE_SAVE); if (mc_global.tty.alternate_plus_minus) application_keypad_mode (); /* Done after subshell initialization to allow select and paste text by mouse w/o Shift button in subshell in the native console */ init_mouse (); /* Done after do_enter_ca_mode (tty_init) because in VTE bracketed mode is separate for the normal and alternate screens */ enable_bracketed_paste (); /* subshell_prompt is NULL here */ mc_prompt = (geteuid () == 0) ? "# " : "$ "; if (config_migrated) { message (D_ERROR, _("Warning"), "%s", config_migrate_msg); g_free (config_migrate_msg); } /* Program main loop */ if (mc_global.midnight_shutdown) exit_code = EXIT_SUCCESS; else exit_code = do_nc ()? EXIT_SUCCESS : EXIT_FAILURE; /* Save the tree store */ (void) tree_store_save (); free_keymap_defs (); /* Virtual File System shutdown */ vfs_shut (); flush_extension_file (); /* does only free memory */ mc_skin_deinit (); tty_colors_done (); tty_shutdown (); done_setup (); if (mc_global.tty.console_flag != '\0' && (quit & SUBSHELL_EXIT) == 0) handle_console (CONSOLE_RESTORE); if (mc_global.tty.alternate_plus_minus) numeric_keypad_mode (); (void) signal (SIGCHLD, SIG_DFL); /* Disable the SIGCHLD handler */ if (mc_global.tty.console_flag != '\0') handle_console (CONSOLE_DONE); if (mc_global.mc_run_mode == MC_RUN_FULL && mc_args__last_wd_file != NULL && last_wd_string != NULL && !print_last_revert) { int last_wd_fd; last_wd_fd = open (mc_args__last_wd_file, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, S_IRUSR | S_IWUSR); if (last_wd_fd != -1) { ssize_t ret1; int ret2; ret1 = write (last_wd_fd, last_wd_string, strlen (last_wd_string)); ret2 = close (last_wd_fd); (void) ret1; (void) ret2; } } g_free (last_wd_string); g_free (mc_global.tty.shell); done_key (); if (macros_list != NULL) { guint i; for (i = 0; i < macros_list->len; i++) { macros_t *macros; macros = &g_array_index (macros_list, struct macros_t, i); if (macros != NULL && macros->macro != NULL) (void) g_array_free (macros->macro, FALSE); } (void) g_array_free (macros_list, TRUE); }