📄 minicom.c
字号:
/* * minicom.c Main program. The main loop of the terminal emulator * itself is in main.c. (Yeah yeah it's confusing). * * This file is part of the minicom communications package, * Copyright 1991-1996 Miquel van Smoorenburg. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * fmg 1/11/94 colors * jl 30.06.97 log it if you quit without reset while online * fmg 8/20/97 History buffer searching added * jseymour@jimsun.LinxNet.com (Jim Seymour) 03/26/98 - Added support for * multiple tty devices via new "get_port()" function. * kubota@debian.or.jp 07/98 - Added option -C to start capturing from the * command line * jl 09.07.98 added option -S to start a script at startup */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "rcsid.h"RCSID(PKG_VER "$Id: minicom.c,v 1.29 2005/10/31 12:13:51 al-guest Exp $")#include <getopt.h>#include <wchar.h>#include <wctype.h>#define EXTERN#include "port.h"#include "minicom.h"#include "intl.h"static const char option_string[] =#ifdef ENABLE_NLS"I18n "#endif"";#define RESET 1#define NORESET 2#ifdef _SVR2extern struct passwd *getpwuid();#endif /*_SVR2*/#ifdef DEBUG/* Show signals when debug is on. */static void signore(int sig){ if (stdwin) werror(_("Got signal %d"), sig); else printf("%s\r\n", _("Got signal %d"), sig);}#endif /*DEBUG*//* * Sub - menu's. */static const char *c1[] = { N_(" Yes "), N_(" No "), NULL };static const char *c2[] = { N_(" Close "), N_(" Pause "), N_(" Exit "), NULL };static const char *c3[] = { N_(" Close "), N_(" Unpause"), N_(" Exit "), NULL };static const char *c7[] = { N_(" Yes "), N_(" No "), NULL };/* Initialize modem port. */void port_init(void){ m_setparms(portfd, P_BAUDRATE, P_PARITY, P_BITS, P_STOPB, P_HASRTS[0] == 'Y', P_HASXON[0] == 'Y');}static void do_hang(int askit){ int c = 0; if (askit) c = ask(_("Hang-up line?"), c7); if (c == 0) hangup();}/* * We've got the hangup or term signal. */static void hangsig(int sig){ if (stdwin) werror(_("Killed by signal %d !\n"), sig); if (capfp) fclose(capfp); keyboard(KUNINSTALL, 0); hangup(); modemreset(); leave("\n");}/* * Jump to a shell */#ifdef SIGTSTP/*ARGSUSED*/static void shjump(int dummy /* __attribute__((unused)) */){ dummy = dummy; /* avoid compiler warning, should be optimized away... */ wleave(); signal(SIGTSTP, SIG_DFL); fputs(_("Suspended. Type \"fg\" to resume.\n"),stdout); kill(getpid(), SIGTSTP); signal(SIGTSTP, shjump); wreturn(); if (use_status) show_status();}#else/*ARGSUSED*/static void shjump(int dummy /* __attribute__((unused)) */){ char *sh; int pid; int status; int f; dummy = dummy; /* avoid compiler warning, should be optimized away... */ sh = getenv("SHELL"); if (sh == NULL) { werror(_("SHELL variable not set")); return; } if ((pid = fork()) == -1) { werror(_("Out of memory: could not fork()")); return; } if (pid != 0) wleave(); if (pid == 0) { for (f = 1; f < _NSIG; f++) signal(f, SIG_DFL); for (f = 3; f < 20; f++) close(f); set_privs(); setgid((gid_t)real_gid); setuid((uid_t)real_uid); fputs(_("Shelled out. Type \"exit\" to return.\n"), stdout); execl(sh, sh, NULL); exit(1); } m_wait(&status); wreturn(); if (use_status) show_status();}#endif /*SIGTSTP*//* Get a line from either window or scroll back buffer. */static ELM *getline(WIN *w, int no){ int i; static ELM outofrange[MAXCOLS] = {{0,0,0}}; if (no < us->histlines) { /* Get a line from the history buffer. */ i = no + us->histline /*- 1*/; if (i >= us->histlines) i -= us->histlines; if (i < 0) i = us->histlines - 1; return us->histbuf + (i * us->xs); } /* Get a line from the "us" window. */ no -= us->histlines; if (no >= w->ys) { if (outofrange[0].value == 0) { for (i = 0; i < MAXCOLS; i++) { outofrange[i].value = ' '; outofrange[i].color = us->color; outofrange[i].attr = us->attr; } outofrange[0].value = '~'; } return outofrange; } return w->map + (no * us->xs);}/* Redraw the window. */static void drawhist(WIN *w, int y, int r){ int f; w->direct = 0; for (f = 0; f < w->ys; f++) wdrawelm(w, f, getline(w, y++)); if (r) wredraw(w, 1); w->direct = 1;}/* * fmg 8/20/97 * drawhist_look() * Redraw the window, highlight line that was found to contain * pattern 'look' * Needed by re-draw screen function after EACH find_next() */void drawhist_look(WIN *w, int y, int r, wchar_t *look, int case_matters){ int f; ELM *tmp_e; wchar_t tmp_line[MAXCOLS]; tmp_line[0]='\0'; w->direct = 0; for (f = 0; f < w->ys; f++) { tmp_e = getline(w, y++); /* First we "accumulate" the line into a variable */ wdrawelm_var(w, tmp_e, tmp_line); /* Does it have what we want? */ if (wcslen(look) > 1 && wcslen(tmp_line) > 1) { if (StrStr(tmp_line,look, case_matters)) wdrawelm_inverse(w, f, tmp_e); /* 'inverse' it */ else wdrawelm(w, f, tmp_e); /* 'normal' output */ } } if (r) wredraw(w, 1); w->direct = 1;}/* * fmg 8/20/97 * Search history - main function that started the C-code blasphemy :-) * This function doesn't care about case/case-less status... */void searchhist(WIN *w_hist, wchar_t *str){ int y; WIN *w_new; const char *hline; size_t i; /* Find out how big a window we must open. */ y = w_hist->y2; if (st == (WIN *)0 || (st && tempst)) y--; /* Open a Search line window. */ w_new = wopen(0, y+1, w_hist->x2, y+1, 0, st_attr, sfcolor, sbcolor, 0, 0, 1); w_new->doscroll = 0; w_new->wrap = 0; hline = _("SEARCH FOR (ESC=Exit)"); wprintf(w_new, "%s(%d):",hline,MAX_SEARCH); wredraw(w_new, 1); wflush(); wlocate(w_new, mbslen(hline)+6, 0); for (i = 0; str[i] != 0; i++) wputc(w_new, str[i]); wlocate(w_new, mbslen(hline)+6, 0); wgetwcs(w_new, str, MAX_SEARCH, MAX_SEARCH);#if 0 if (!str[0]) { /* then unchanged... must have pressed ESC... get out */ wflush(); wclose(w_new, 0); return; }#endif wredraw(w_hist, 1); wclose(w_new, 1); wflush(); return;}/* * fmg 8/20/97 * Move scope to next hit of pattern in the buffer. * Returns line-number of next "hit_line" or -1 if none found * (we beep elsewhere ;-) */int find_next(WIN *w, WIN *w_hist, int hit_line, /* 'current' Match line */ wchar_t *look, /* pattern */ int case_matters) /* guess... */{ int next_line; ELM *tmp_e; wchar_t tmp_line[MAXCOLS]; int all_lines; if (!look) return(++hit_line); /* next line */ tmp_line[0] = '\0'; /* Personal phobia, I need to do this.. */ hit_line++; /* we NEED this so we don't search only same line! */ all_lines = w->histlines + w_hist->ys; if (hit_line >= all_lines) { /* Make sure we've got a valid line! */ werror(_("Search Wrapping Around to Start!")); hit_line = 0; } for (next_line = hit_line; next_line <= all_lines; next_line++) { /* we do 'something' here... :-) */ tmp_e = getline(w_hist, next_line); /* * First we "accumulate" the line into a variable. * To see 'why', see what an 'ELM' structure looks like! */ wdrawelm_var(w, tmp_e, tmp_line); /* Does it have what we want? */ if (wcslen(tmp_line) > 1 && wcslen(look) > 1) if (StrStr(tmp_line, look, case_matters)) return next_line; } if (hit_line >= all_lines) { /* Make sure we've got a valid line! */ werror(_("Search Wrapping Around to Start!")); hit_line = 0; } return -1; /* nothing found! */}/* * fmg 8/22/97 * Needed this for the case-less conparison... and Linux libc * doesn't seem to have a strnstr function... so we fudge.. ;-) */const wchar_t *upcase(wchar_t *dest, wchar_t *src){ wchar_t *d = dest; while (*src) *d++ = towupper(*src++); *d = '\0'; return dest;}/* * fmg 8/22/97 * Needed this for the case-less conparison... and Linux libc * doesn't seem to have a strnstr function... so we fudge.. ;-) */wchar_t *StrStr(wchar_t *str1, wchar_t *str2, int case_matters){ wchar_t tmpstr1[MAXCOLS], tmpstr2[MAXCOLS]; if (case_matters) return wcsstr(str1, str2); else return wcsstr(upcase(tmpstr1, str1), upcase(tmpstr2, str2));}static void drawcite(WIN *w, int y, int citey, int start, int end){ if (y+citey >= start && y+citey <= end) wdrawelm_inverse(w, y, getline(w, y+citey)); else wdrawelm(w, y, getline(w, y+citey));}static void drawcite_whole(WIN *w, int y, int start, int end){ int sy; for (sy = 0; sy < w->ys; sy++) drawcite(w, sy, y, start, end);}static void do_cite(WIN *w, int start, int end){ wchar_t tmp_line[MAXCOLS]; ELM *tmp_e; int x, y; for (y=start; y<=end; y++) { vt_send('>'); vt_send(' '); tmp_e = getline(w, y); wdrawelm_var(w, tmp_e, tmp_line); tmp_line[w->xs] = 0; for (x = w->xs-1; x >= 0; x--) { if (tmp_line[x] <= ' ') tmp_line[x]=0; else break; } for (x = 0; tmp_line[x]; x++) { char buf[MB_LEN_MAX]; size_t i, len; len = one_wctomb(buf, tmp_line[x]); for (i = 0; i < len; i++) vt_send(buf[i]); } vt_send(13); }}/* Scroll back */static void scrollback(void){ int y,c; WIN *b_us, *b_st; ELM *tmp_e; int case_matters=0; /* fmg: case-importance, needed for 'N' */ static wchar_t look_for[MAX_SEARCH]; /* fmg: last used search pattern */ wchar_t tmp_line[MAXCOLS]; int citemode = 0; int cite_ystart = 1000000, cite_yend = -1, cite_y = 0; int inverse; int loop = 1; char hline0[128], hline1[128], *hline; static int hit=0; /* Find out how big a window we must open. */ y = us->y2; if (st == (WIN *)0 || (st && tempst)) y--; /* Open a window. */ b_us = wopen(0, 0, us->x2, y, 0, us->attr, COLFG(us->color), COLBG(us->color), 0, 0, 0); wcursor(b_us, CNONE); /* Open a help line window. */ b_st = wopen(0, y+1, us->x2, y+1, 0, st_attr, sfcolor, sbcolor, 0, 0, 1); b_st->doscroll = 0; b_st->wrap = 0; /* Make sure help line is as wide as window. */ /* * fmg 8/20/97 * added /=Srch, \=CaseLess, and N=Next and changed rest of line... * Hope you like it :-) */ strcpy(hline0, _("HISTORY: U=Up D=Down F=PgDn B=PgUp s=Srch S=CaseLess N=Next C=Cite ESC=Exit ")); if (b_st->xs < 127) hline0[b_st->xs] = 0; hline = hline0; wprintf(b_st, hline); wredraw(b_st, 1); wflush(); /* And do the job. */ y = us->histlines; /* fmg 8/20/97 * Needed for N)extSearch, keeps track of line on which current "hit" * is... we advance it to 'N'ext hit in find_next(). We start at "top" * of history stack */ hit = 0; drawhist(b_us, y, 0); while (loop) { c = wxgetch(); switch (c) { /* * fmg 8/22/97 * Take care of the search key: Caseless */ case '\\': case 'S': case_matters = 0; /* case-importance, ie. none :-) */ /* * fmg 8/22/97 * Take care of the search key: Exact Match */ case '/': case 's': if (!us->histlines) { wbell(); werror(_("History buffer Disabled!")); break; } if (!us->histline) { wbell(); werror(_("History buffer empty!")); break; } if (citemode) break; /* we need this for the case-importance-toggle to work.. */ if (c == '/' || c == 's') case_matters=1; /* case-importance, ie. DOES */ /* open up new search window... */ searchhist(b_us, look_for); /* must redraw status line... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -