void x_print_expansions(int nwords, char *const *words, int is_command) { int prefix_len; /* Check if all matches are in the same directory (in this * case, we want to omit the directory name) */ if (!is_command && (prefix_len = x_longest_prefix(nwords, words)) > 0) { int i; /* Special case for 1 match (prefix is whole word) */ if (nwords == 1) prefix_len = x_basename(words[0], NULL); /* Any (non-trailing) slashes in non-common word suffixes? */ for (i = 0; i < nwords; i++) if (x_basename(words[i] + prefix_len, NULL) > prefix_len) break; /* All in same directory? */ if (i == nwords) { XPtrV l; while (prefix_len > 0 && words[0][prefix_len - 1] != '/') prefix_len--; XPinit(l, nwords + 1); for (i = 0; i < nwords; i++) XPput(l, words[i] + prefix_len); XPput(l, NULL); /* Enumerate expansions */ x_putc('\r'); x_putc('\n'); pr_list((char **) XPptrv(l)); XPfree(l); /* not x_free_words() */ return; } } /* Enumerate expansions */ x_putc('\r'); x_putc('\n'); pr_list(words); }
static inline void edit_status_fullscreen (WEdit * edit, int color) { const int w = edit->widget.owner->cols; const size_t status_size = w + 1; char *const status = g_malloc (status_size); int status_len; const char *fname = ""; int fname_len; const int gap = 3; /* between the filename and the status */ const int right_gap = 5; /* at the right end of the screen */ const int preferred_fname_len = 16; status_string (edit, status, status_size); status_len = (int) str_term_width1 (status); if (edit->filename_vpath != NULL) fname = x_basename (vfs_path_get_last_path_str (edit->filename_vpath)); fname_len = str_term_width1 (fname); if (fname_len < preferred_fname_len) fname_len = preferred_fname_len; if (fname_len + gap + status_len + right_gap >= w) { if (preferred_fname_len + gap + status_len + right_gap >= w) fname_len = preferred_fname_len; else fname_len = w - (gap + status_len + right_gap); fname = str_trunc (fname, fname_len); } dlg_move (edit->widget.owner, 0, 0); tty_setcolor (color); printwstr (fname, fname_len + gap); printwstr (status, w - (fname_len + gap)); if (simple_statusbar && w > EDITOR_MINIMUM_TERMINAL_WIDTH) { size_t percent = 100; if (edit->total_lines + 1 != 0) percent = (edit->curs_line + 1) * 100 / (edit->total_lines + 1); dlg_move (edit->widget.owner, 0, w - 6 - 6); tty_printf (" %3d%%", percent); } g_free (status); }
static char * lock_build_symlink_name (const char *fname) { char *fname_copy, *symlink_name; char absolute_fname[PATH_MAX]; if (mc_realpath (fname, absolute_fname) == NULL) return NULL; fname = x_basename (absolute_fname); fname_copy = g_strdup (fname); absolute_fname[fname - absolute_fname] = '\0'; symlink_name = g_strconcat (absolute_fname, ".#", fname_copy, (char *) NULL); g_free (fname_copy); return symlink_name; }
#endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */ #ifdef USE_TERMCAP int ok_tcap = 1; char termcap[TERMCAP_SIZE]; char newtc[TERMCAP_SIZE]; #endif /* USE_TERMCAP */ char buf[BUFSIZ]; #ifdef TTYSIZE_STRUCT TTYSIZE_STRUCT ts; #endif char *name_of_tty; #ifdef CANT_OPEN_DEV_TTY extern char *ttyname(); #endif myname = x_basename(argv[0]); if (strcmp(myname, sunname) == 0) emu = SUN; for (argv++, argc--; argc > 0 && **argv == '-'; argv++, argc--) { switch ((*argv)[1]) { case 's': /* Sun emulation */ if (emu == SUN) Usage(); /* Never returns */ emu = SUN; break; case 'u': /* Bourne (Unix) shell */ shell_type = SHELL_BOURNE; break; case 'c': /* C shell */ shell_type = SHELL_C; break;
gboolean mcview_load (mcview_t * view, const char *command, const char *file, int start_line) { gboolean retval = FALSE; vfs_path_t *vpath = NULL; #ifdef HAVE_ASSERT_H assert (view->bytes_per_line != 0); #endif view->filename_vpath = vfs_path_from_str (file); /* get working dir */ if (file != NULL && file[0] != '\0') { vfs_path_free (view->workdir_vpath); if (!g_path_is_absolute (file)) { vfs_path_t *p; p = vfs_path_clone (vfs_get_raw_current_dir ()); view->workdir_vpath = vfs_path_append_new (p, file, (char *) NULL); vfs_path_free (p); } else { /* try extract path form filename */ const char *fname; char *dir; fname = x_basename (file); dir = g_strndup (file, (size_t) (fname - file)); view->workdir_vpath = vfs_path_from_str (dir); g_free (dir); } } if (!mcview_is_in_panel (view)) view->dpy_text_column = 0; mcview_set_codeset (view); if (command != NULL && (view->magic_mode || file == NULL || file[0] == '\0')) retval = mcview_load_command_output (view, command); else if (file != NULL && file[0] != '\0') { int fd; char tmp[BUF_MEDIUM]; struct stat st; /* Open the file */ vpath = vfs_path_from_str (file); fd = mc_open (vpath, O_RDONLY | O_NONBLOCK); if (fd == -1) { g_snprintf (tmp, sizeof (tmp), _("Cannot open \"%s\"\n%s"), file, unix_error_string (errno)); mcview_show_error (view, tmp); vfs_path_free (view->filename_vpath); view->filename_vpath = NULL; vfs_path_free (view->workdir_vpath); view->workdir_vpath = NULL; goto finish; } /* Make sure we are working with a regular file */ if (mc_fstat (fd, &st) == -1) { mc_close (fd); g_snprintf (tmp, sizeof (tmp), _("Cannot stat \"%s\"\n%s"), file, unix_error_string (errno)); mcview_show_error (view, tmp); vfs_path_free (view->filename_vpath); view->filename_vpath = NULL; vfs_path_free (view->workdir_vpath); view->workdir_vpath = NULL; goto finish; } if (!S_ISREG (st.st_mode)) { mc_close (fd); mcview_show_error (view, _("Cannot view: not a regular file")); vfs_path_free (view->filename_vpath); view->filename_vpath = NULL; vfs_path_free (view->workdir_vpath); view->workdir_vpath = NULL; goto finish; } if (st.st_size == 0 || mc_lseek (fd, 0, SEEK_SET) == -1) { /* Must be one of those nice files that grow (/proc) */ mcview_set_datasource_vfs_pipe (view, fd); } else { int type; type = get_compression_type (fd, file); if (view->magic_mode && (type != COMPRESSION_NONE)) { char *tmp_filename; vfs_path_t *vpath1; int fd1; tmp_filename = g_strconcat (file, decompress_extension (type), (char *) NULL); vpath1 = vfs_path_from_str (tmp_filename); fd1 = mc_open (vpath1, O_RDONLY | O_NONBLOCK); if (fd1 == -1) { g_snprintf (tmp, sizeof (tmp), _("Cannot open \"%s\" in parse mode\n%s"), file, unix_error_string (errno)); mcview_show_error (view, tmp); } else { mc_close (fd); fd = fd1; mc_fstat (fd, &st); } vfs_path_free (vpath1); g_free (tmp_filename); } mcview_set_datasource_file (view, fd, &st); } retval = TRUE; } finish: view->command = g_strdup (command); view->dpy_start = 0; view->search_start = 0; view->search_end = 0; view->dpy_text_column = 0; mcview_compute_areas (view); mcview_update_bytes_per_line (view); if (mcview_remember_file_position && view->filename_vpath != NULL && start_line == 0) { long line, col; off_t new_offset, max_offset; load_file_position (view->filename_vpath, &line, &col, &new_offset, &view->saved_bookmarks); max_offset = mcview_get_filesize (view) - 1; if (max_offset < 0) new_offset = 0; else new_offset = min (new_offset, max_offset); if (!view->hex_mode) view->dpy_start = mcview_bol (view, new_offset, 0); else { view->dpy_start = new_offset - new_offset % view->bytes_per_line; view->hex_cursor = new_offset; } } else if (start_line > 0) mcview_moveto (view, start_line - 1, 0); view->hexedit_lownibble = FALSE; view->hexview_in_text = FALSE; view->change_list = NULL; vfs_path_free (vpath); return retval; }
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; }
static int x_command_glob(int flags, const char *str, int slen, char ***wordsp) { char *toglob; char *pat; char *fpath; int nwords; XPtrV w; struct block *l; if (slen < 0) return 0; toglob = add_glob(str, slen); /* Convert "foo*" (toglob) to a pattern for future use */ pat = evalstr(toglob, DOPAT|DOTILDE); afree(toglob, ATEMP); XPinit(w, 32); glob_table(pat, &w, &keywords); glob_table(pat, &w, &aliases); glob_table(pat, &w, &builtins); for (l = e->loc; l; l = l->next) glob_table(pat, &w, &l->funs); glob_path(flags, pat, &w, path); if ((fpath = str_val(global("FPATH"))) != null) glob_path(flags, pat, &w, fpath); nwords = XPsize(w); if (!nwords) { *wordsp = NULL; XPfree(w); return 0; } /* Sort entries */ if (flags & XCF_FULLPATH) { /* Sort by basename, then path order */ struct path_order_info *info; struct path_order_info *last_info = NULL; char **words = (char **) XPptrv(w); int path_order = 0; int i; info = areallocarray(NULL, nwords, sizeof(struct path_order_info), ATEMP); for (i = 0; i < nwords; i++) { info[i].word = words[i]; info[i].base = x_basename(words[i], NULL); if (!last_info || info[i].base != last_info->base || strncmp(words[i], last_info->word, info[i].base) != 0) { last_info = &info[i]; path_order++; } info[i].path_order = path_order; } qsort(info, nwords, sizeof(struct path_order_info), path_order_cmp); for (i = 0; i < nwords; i++) words[i] = info[i].word; afree(info, ATEMP); } else { /* Sort and remove duplicate entries */ char **words = (char **) XPptrv(w); int i, j; qsortp(XPptrv(w), (size_t) nwords, xstrcmp); for (i = j = 0; i < nwords - 1; i++) { if (strcmp(words[i], words[i + 1])) words[j++] = words[i]; else afree(words[i], ATEMP); } words[j++] = words[i]; nwords = j; w.cur = (void **) &words[j]; } XPput(w, NULL); *wordsp = (char **) XPclose(w); return nwords; }
static inline void edit_status_window (WEdit * edit) { int y, x; int cols = edit->widget.cols; tty_setcolor (STATUSBAR_COLOR); if (cols > 5) { const char *fname = N_("NoName"); char *full_fname = NULL; if (edit->filename_vpath != NULL) { full_fname = vfs_path_to_str (edit->filename_vpath); fname = x_basename (full_fname); } #ifdef ENABLE_NLS else fname = _(fname); #endif edit_move (2, 0); tty_printf ("[%s]", str_term_trim (fname, edit->widget.cols - 8 - 6)); g_free (full_fname); } tty_getyx (&y, &x); x -= edit->widget.x; x += 4; if (x + 6 <= cols - 2 - 6) { edit_move (x, 0); tty_printf ("[%c%c%c%c]", edit->mark1 != edit->mark2 ? (edit->column_highlight ? 'C' : 'B') : '-', edit->modified ? 'M' : '-', macro_index < 0 ? '-' : 'R', edit->overwrite == 0 ? '-' : 'O'); } if (cols > 30) { edit_move (2, edit->widget.lines - 1); tty_printf ("%3ld %5ld/%ld %6ld/%ld", edit->curs_col + edit->over_col, edit->curs_line + 1, edit->total_lines + 1, edit->curs1, edit->last_byte); } /* * If we are at the end of file, print <EOF>, * otherwise print the current character as is (if printable), * as decimal and as hex. */ if (cols > 46) { edit_move (32, edit->widget.lines - 1); if (edit->curs1 >= edit->last_byte) tty_print_string ("[<EOF> ]"); #ifdef HAVE_CHARSET else if (edit->utf8) { unsigned int cur_utf; int cw = 1; cur_utf = edit_get_utf (edit, edit->curs1, &cw); if (cw <= 0) cur_utf = edit_get_byte (edit, edit->curs1); tty_printf ("[%05d 0x%04X]", cur_utf, cur_utf); } #endif else { unsigned char cur_byte; cur_byte = edit_get_byte (edit, edit->curs1); tty_printf ("[%05d 0x%04X]", (unsigned int) cur_byte, (unsigned int) cur_byte); } } }
int lock_file (const vfs_path_t * fname_vpath) { char *lockfname = NULL, *newlock, *msg, *lock; struct stat statbuf; struct lock_s *lockinfo; gboolean is_local; gboolean symlink_ok = FALSE; const char *elpath; if (fname_vpath == NULL) return 0; elpath = vfs_path_get_by_index (fname_vpath, 0)->path; /* Just to be sure (and don't lock new file) */ if (*elpath == '\0') return 0; /* Locking on VFS is not supported */ is_local = vfs_file_is_local (fname_vpath); if (is_local) { /* Check if already locked */ lockfname = lock_build_symlink_name (fname_vpath); } if (!is_local || lockfname == NULL) return 0; if (lstat (lockfname, &statbuf) == 0) { lock = lock_get_info (lockfname); if (lock == NULL) goto ret; lockinfo = lock_extract_info (lock); /* Check if locking process alive, ask user if required */ if (lockinfo->pid == 0 || !(kill (lockinfo->pid, 0) == -1 && errno == ESRCH)) { msg = g_strdup_printf (_ ("File \"%s\" is already being edited.\n" "User: %s\nProcess ID: %d"), x_basename (lockfname) + 2, lockinfo->who, (int) lockinfo->pid); /* TODO: Implement "Abort" - needs to rewind undo stack */ switch (query_dialog (_("File locked"), msg, D_NORMAL, 2, _("&Grab lock"), _("&Ignore lock"))) { case 0: break; case 1: case -1: g_free (msg); goto ret; break; /* FIXME: unneeded? */ } g_free (msg); } unlink (lockfname); } /* Create lock symlink */ newlock = lock_build_name (); symlink_ok = (symlink (newlock, lockfname) != -1); g_free (newlock); ret: g_free (lockfname); return symlink_ok ? 1 : 0; }
int main (int argc, char **argv) { int rows, cols; struct termios tio; char buf[BUFSIZ]; struct winsize ws; char *name_of_tty; myname = x_basename(argv[0]); if (argc > 1) Usage(); name_of_tty = "/dev/tty"; if ((ttyfp = fopen (name_of_tty, "r+")) == NULL) { fprintf (stderr, "%s: can't open terminal %s\n", myname, name_of_tty); exit (1); } tty = fileno(ttyfp); tcgetattr(tty, &tioorig); tio = tioorig; tio.c_iflag &= ~ICRNL; tio.c_lflag &= ~(ICANON | ECHO); tio.c_cflag |= CS8; tio.c_cc[VMIN] = 6; tio.c_cc[VTIME] = 1; signal(SIGINT, onintr); signal(SIGQUIT, onintr); signal(SIGTERM, onintr); tcsetattr(tty, TCSADRAIN, &tio); write(tty, getsize, strlen(getsize)); readstring(ttyfp, buf, size); if(sscanf (buf, size, &rows, &cols) != 2) { fprintf(stderr, "%s: Can't get rows and columns\r\n", myname); onintr(0); } write(tty, restore, strlen(restore)); if (ioctl (tty, TIOCGWINSZ, &ws) != -1) { /* we don't have any way of directly finding out the current height & width of the window in pixels. We try our best by computing the font height and width from the "old" struct winsize values, and multiplying by these ratios...*/ if (ws.ws_col != 0) ws.ws_xpixel = cols * (ws.ws_xpixel / ws.ws_col); if (ws.ws_row != 0) ws.ws_ypixel = rows * (ws.ws_ypixel / ws.ws_row); ws.ws_row = rows; ws.ws_col = cols; ioctl (tty, TIOCSWINSZ, &ws); } tcsetattr(tty, TCSADRAIN, &tioorig); signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGTERM, SIG_DFL); exit(0); }
/* Tries to raise file lock Returns 1 on success, 0 on failure, -1 if abort Warning: Might do screen refresh and lose edit->force */ int edit_lock_file (const char *fname) { char *lockfname, *newlock, *msg, *lock; struct stat statbuf; struct lock_s *lockinfo; /* Just to be sure (and don't lock new file) */ if (!fname || !*fname) return 0; /* Locking on VFS is not supported */ if (!vfs_file_is_local (fname)) return 0; /* Check if already locked */ lockfname = lock_build_symlink_name (fname); if (lockfname == NULL) return 0; if (lstat (lockfname, &statbuf) == 0) { lock = lock_get_info (lockfname); if (!lock) { g_free (lockfname); return 0; } lockinfo = lock_extract_info (lock); /* Check if locking process alive, ask user if required */ if (!lockinfo->pid || !(kill (lockinfo->pid, 0) == -1 && errno == ESRCH)) { msg = g_strdup_printf (_ ("File \"%s\" is already being edited\n" "User: %s\nProcess ID: %d"), x_basename (lockfname) + 2, lockinfo->who, (int) lockinfo->pid); /* TODO: Implement "Abort" - needs to rewind undo stack */ switch (edit_query_dialog2 (_("File locked"), msg, _("&Grab lock"), _("&Ignore lock"))) { case 0: break; case 1: case -1: g_free (lockfname); g_free (msg); return 0; } g_free (msg); } unlink (lockfname); } /* Create lock symlink */ newlock = lock_build_name (); if (symlink (newlock, lockfname) == -1) { g_free (lockfname); g_free (newlock); return 0; } g_free (lockfname); g_free (newlock); return 1; }
gboolean mc_setup_by_args (int argc, char **argv, GError ** error) { const char *base; char *tmp; if (mc_args__force_colors) mc_global.tty.disable_colors = FALSE; #ifdef HAVE_SUBSHELL_SUPPORT if (mc_args__nouse_subshell) mc_global.tty.use_subshell = FALSE; #endif /* HAVE_SUBSHELL_SUPPORT */ #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_run_param0 = parse_mcedit_arguments (argc - 1, &argv[1]); 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 */ if (tmp != NULL) mc_run_param0 = g_strdup (tmp); else { *error = g_error_new (MC_ERROR, 0, "%s\n", _("No arguments given to the viewer.")); return FALSE; } 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 */ if (argc < 3) { *error = g_error_new (MC_ERROR, 0, "%s\n", _("Two files are required to evoke the diffviewer.")); return FALSE; } if (tmp != NULL) { mc_run_param0 = g_strdup (tmp); tmp = (argc > 1) ? argv[2] : NULL; if (tmp != NULL) mc_run_param1 = g_strdup (tmp); mc_global.mc_run_mode = MC_RUN_DIFFVIEWER; } } #endif /* USE_DIFF_VIEW */ else { /* MC is run as mc */ 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: /* mc_run_param0 is set up in parse_mc_v_argument() */ break; case MC_RUN_DIFFVIEWER: /* not implemented yet */ break; case MC_RUN_FULL: default: /* sets the current dir and the other dir */ if (tmp != NULL) { mc_run_param0 = g_strdup (tmp); tmp = (argc > 1) ? argv[2] : NULL; if (tmp != NULL) mc_run_param1 = g_strdup (tmp); } mc_global.mc_run_mode = MC_RUN_FULL; break; } } return TRUE; }