/* * Tell a little message */ static void file_tell(const char *s) { WIN *w; w = mc_tell("%s", s); sleep(1); mc_wclose(w, 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 = mc_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)"); mc_wprintf(w_new, "%s(%d):",hline,MAX_SEARCH); mc_wredraw(w_new, 1); mc_wflush(); mc_wlocate(w_new, mbslen(hline)+6, 0); for (i = 0; str[i] != 0; i++) mc_wputc(w_new, str[i]); mc_wlocate(w_new, mbslen(hline)+6, 0); mc_wgetwcs(w_new, str, MAX_SEARCH, MAX_SEARCH); #if 0 if (!str[0]) { /* then unchanged... must have pressed ESC... get out */ mc_wflush(); mc_wclose(w_new, 0); return; } #endif mc_wredraw(w_hist, 1); mc_wclose(w_new, 1); mc_wflush(); return; }
/* * Leave. */ void leave(const char *s) { if (stdwin) mc_wclose(stdwin, 1); if (portfd > 0) { m_restorestate(portfd); close(portfd); } lockfile_remove(); if (P_CALLIN[0]) fastsystem(P_CALLIN, NULL, NULL, NULL); fprintf(stderr, "%s", s); exit(1); }
/* * Draw the file directory. * * howmany - How many files can be selected * 0 = none (for directory selection only, as in "rz") * 1 = one (for single-file up-/down-loads, as in "rx") * -1 = any number (for multiple files, as in "sz") * * downloading - Is this for download selection? * 0 = no * 1 = yes - when single file selected, see if it exists */ char * filedir(int howmany, int downloading) { time_t click_time = (time_t) 0; size_t i; how_many = howmany; down_loading = downloading; init_filedir(); again: mc_wlocate(main_w, 0, cur + FILE_MWTR - top); if (first) { mc_wredraw(main_w, 1); first = 0; } while (!quit) { GETSDIR_ENTRY *d = getno(cur, global_dirdat); /* if(S_ISDIR(d->mode)) prone(main_w, d, longest, 0); */ switch (c = wxgetch()) { case K_UP: case 'k': /* if(S_ISDIR(d->mode)) prone(main_w, d, longest, 1); */ cur -= cur > 0; break; case K_DN: case 'j': /* if(S_ISDIR(d->mode)) prone(main_w, d, longest, 1); */ cur += cur < nrents - 1; break; case K_LT: case 'h': subm--; if (subm < 0) subm = SUBM_OKAY; break; case K_RT: case 'l': subm = (subm + 1) % 6; break; case K_PGUP: case '\002': /* Control-B */ pgud = 1; quit = 1; break; case K_PGDN: case '\006': /* Control-F */ pgud = 2; quit = 1; break; case ' ': /* Tag if not directory */ if (S_ISDIR(d->mode)) { time_t this_time = time((time_t *)NULL); if (this_time - click_time < 2) { GETSDIR_ENTRY *d2 = getno(cur, global_dirdat); goto_filedir(d2->fname, 0); click_time = (time_t)0; } else click_time = this_time; } else { if (how_many) { if ((d->cflags ^= FL_TAG) & FL_TAG) { if (tag_cnt && how_many == 1) { d->cflags &= ~FL_TAG; file_tell(_("Can select only one!")); break; } ++tag_cnt; } else --tag_cnt; mc_wlocate(main_w, 0, cur + FILE_MWTR - top); prone(main_w, d, longest, d->cflags & FL_TAG); mc_wputc(main_w, '\n'); cur += cur < nrents - 1; } } break; case '\033': case '\r': case '\n': quit = 1; break; default: for (i = 0; i < WHAT_NR_OPTIONS; i++) { if (strchr (_(what[i]), toupper (c)) != NULL) { subm = i; c = '\n'; quit = 1; break; } } break; } if (c != ' ') click_time = (time_t)0; if (cur < top) { top--; prdir(main_w, top, top, global_dirdat, longest); } if (cur - top > main_w->ys - (2 + FILE_MWTR)) { top++; prdir(main_w, top, top, global_dirdat, longest); } /* if(cur != ocur) mc_wlocate(main_w, 0, cur + FILE_MWTR - top); */ ocur = cur; dhili(subm); /* this really needs to go in dhili !!!*/ mc_wlocate(main_w, 0, cur + FILE_MWTR - top); } quit = 0; /* ESC means quit */ if (c == '\033') { mc_wclose(main_w, 1); mc_wclose(dsub, 1); free(global_dirdat); global_dirdat = NULL; return NULL; } /* Page up or down ? */ if (pgud == 1) { /* Page up */ ocur = top; top -= main_w->ys - (1 + FILE_MWTR); if (top < 0) top = 0; cur = top; pgud = 0; if (ocur != top) prdir(main_w, top, cur, global_dirdat, longest); ocur = cur; goto again; } if (pgud == 2) { /* Page down */ ocur = top; if (top < nrents - main_w->ys + (1 + FILE_MWTR)) { top += main_w->ys - (1 + FILE_MWTR); if (top > nrents - main_w->ys + (1 + FILE_MWTR)) { top = nrents - main_w->ys + (1 + FILE_MWTR); } cur = top; } else cur = nrents - 1; pgud = 0; if (ocur != top) prdir(main_w, top, cur, global_dirdat, longest); ocur = cur; goto again; } if (c =='\r' || c == '\n') { switch(subm) { case 0: /* Goto directory */ { char buf[128]; char *s; strncpy(buf, down_loading? P_DOWNDIR : P_UPDIR, sizeof(buf) -1); s = input(_("Goto directory:"), buf); /* if(s == NULL || *s == (char) 0) */ if (s == NULL) break; goto_filedir(buf, 1); } break; case 1: /* Previous directory */ goto_filedir(prev_dir, 1); break; case 2: /* File (wildcard) spec */ { char *s = input(_("Filename pattern:"), wc_mem); if (s == NULL || *s == (char) 0) break; strcpy(wc_str, wc_mem); new_filedir(global_dirdat, 1); wc_str[0] = (char)0; } break; case 3: /* Tag */ if (how_many == 1) file_tell(_("Can select only one!")); else if (how_many == -1) { char tag_buf[128]; char *s; strncpy(tag_buf, wc_mem, 128); s = input(_("Tag pattern:"), tag_buf); if (s != NULL && *s != (char)0) { int newly_tagged; if ((newly_tagged = tag_untag(tag_buf, 1)) == 0) { file_tell(_("No file(s) tagged")); goto tag_end; } tag_cnt += newly_tagged; prdir(main_w, top, top, global_dirdat, longest); } } tag_end: break; case 4: /* Untag */ { char tag_buf[128]; char *s; int untagged; strncpy(tag_buf, wc_mem, 128); s = input(_("Untag pattern:"), tag_buf); if (s == NULL || *s == (char)0) goto untag_end; if ((untagged = tag_untag(tag_buf, 0)) == 0) { file_tell(_("No file(s) untagged")); goto untag_end; } tag_cnt -= untagged; prdir(main_w, top, top, global_dirdat, longest); } untag_end: break; case 5: { /* Done */ char *ret_ptr = NULL; /* failsafe: assume failure */ if (how_many != 0 && !tag_cnt) { while (1) { s = input(_("No file selected - enter filename:"), ret_buf); if (s != NULL && *s != (char) 0) { int f_exist = access(ret_buf, F_OK); if (down_loading) { if (f_exist != -1) { /* ask 'em if they're *sure* */ char buf[BUFSIZ]; snprintf(buf, sizeof(buf), _("File: \"%s\" exists! Overwrite?"), ret_buf); if (ask(buf, d_yesno) == 0) { ret_ptr = ret_buf; break; } } else { ret_ptr = ret_buf; break; } } else { if (f_exist == -1) file_tell(_("no such file!")); else { ret_ptr = ret_buf; break; } } } else { /* maybe want to ask: "abort?", here */ goto again; } } } else { /* put 'em in a buffer for return */ if (how_many == 0) { /* current working directory */ ret_ptr = work_dir; } else { ret_ptr = concat_list(global_dirdat); } } mc_wclose(main_w, 1); mc_wclose(dsub, 1); free(global_dirdat); global_dirdat = NULL; return ret_ptr; } break; default: /* should "beep", I guess (? shouldn't get here) */ file_tell("BEEP!"); break; } /* switch */ } goto again; }
/* * Initialize new file directory. * * Sets the current working directory. Non-0 return = no change. */ static int new_filedir(GETSDIR_ENTRY *dirdat, int flushit) { static size_t dp_len = 0; static char cwd_str_fmt[BUFSIZ] = ""; size_t new_dp_len, fmt_len; char disp_dir[80]; int initial_y = (76 - (WHAT_NR_OPTIONS * WHAT_WIDTH >= 76 ? 74 : WHAT_NR_OPTIONS * WHAT_WIDTH)) / 2; size_t i; char * new_prev_dir; cur = 0; ocur = 0; subm = SUBM_OKAY; quit = 0; top = 0; c = 0; pgud = 0; first = 1; min_len = 1; dprev = -1; tag_cnt = 0; /* * get last directory */ work_dir = down_loading ? d_work_dir : u_work_dir; /* * init working directory to default? */ if (work_dir == NULL) { char *s = down_loading? P_DOWNDIR : P_UPDIR; min_len = 1; if (*s != '/') min_len += strlen(homedir) + 1; min_len += strlen(s); if (min_len < BUFSIZ) min_len = BUFSIZ; work_dir = set_work_dir(NULL, min_len); if (*s == '/') strncpy(work_dir, s, min_len); else snprintf(work_dir, min_len, "%s/%s", homedir, s); } /* lop-off trailing "/" for consistency */ if (strlen(work_dir) > 1 && work_dir[strlen(work_dir) - 1] == '/') work_dir[strlen(work_dir) - 1] = (char)0; /* get the current working directory, which will become the prev_dir, on success */ new_prev_dir = getcwd(NULL, BUFSIZ); if (!new_prev_dir) return -1; if (!access(work_dir, R_OK | X_OK) && !chdir(work_dir)) { /* was able to change to new working directory */ free(prev_dir); prev_dir = new_prev_dir; } else { /* Could not change to the new working directory */ mc_wbell(); werror( _("Could not change to directory %s (%s)"), work_dir, strerror(errno)); /* restore the previous working directory */ free(work_dir); work_dir = set_work_dir(new_prev_dir, strlen(new_prev_dir)); } /* All right, draw the file directory! */ if (flushit) { dirflush = 0; mc_winclr(main_w); mc_wredraw(main_w, 1); } mc_wcursor(main_w, CNORMAL); { char *s; if (down_loading) { if (how_many < 0) s = _("Select one or more files for download"); else if (how_many) s = _("Select a file for download"); else s = _("Select a directory for download"); } else { if (how_many < 0) s = _("Select one or more files for upload"); else if (how_many) s = _("Select a file for upload"); else s = _("Select a directory for upload"); } snprintf(file_title, sizeof(file_title), "%s", s); } mc_wtitle(main_w, TMID, file_title); if ((new_dp_len = strlen(work_dir)) > dp_len) { dp_len = new_dp_len; snprintf(cwd_str_fmt, sizeof(cwd_str_fmt), _("Directory: %%-%ds"), (int)dp_len); } new_dp_len = mbslen (work_dir); if (new_dp_len + (fmt_len = mbslen(cwd_str_fmt)) > 75) { size_t i; char *tmp_dir = work_dir; /* We want the last 73 characters */ for (i = 0; 73 + i < new_dp_len + fmt_len; i++) { wchar_t wc; tmp_dir += one_mbtowc(&wc, work_dir, MB_LEN_MAX); } snprintf(disp_dir, sizeof(disp_dir), "...%s", tmp_dir); snprintf(cwd_str, sizeof(cwd_str), cwd_str_fmt, disp_dir); } else snprintf(cwd_str, sizeof(cwd_str), cwd_str_fmt, work_dir); mc_wlocate(main_w, 0, 0); mc_wputs(main_w, cwd_str); for (i = 0; i < WHAT_NR_OPTIONS; i++) { const char *str, *c; size_t j; str = _(what[i]); c = str; for (j = 0; j < WHAT_WIDTH - 1 && *c != 0; j++) { wchar_t wc; c += one_mbtowc (&wc, c, MB_LEN_MAX); } what_lens[i] = c - str; j = WHAT_WIDTH - j; /* Characters left for padding */ what_padding[i][1] = j / 2; /* Rounding down */ what_padding[i][0] = j - what_padding[i][1]; /* >= 1 */ } mc_wlocate(dsub, initial_y, 0); for (i = 0; i < WHAT_NR_OPTIONS; i++) horiz_draw(i, mc_wgetattr(dsub), mc_wgetattr(dsub)); mc_wsetregion(main_w, 1, main_w->ys - FILE_MWTR); main_w->doscroll = 0; /* old dir to discard? */ free(dirdat); dirdat = NULL; /* get sorted directory */ if ((nrents = getsdir(".", wc_str, GETSDIR_PARNT|GETSDIR_NSORT|GETSDIR_DIRSF, 0, &dirdat, &longest)) < 0) { /* we really want to announce the error here!!! */ mc_wclose(main_w, 1); mc_wclose(dsub, 1); free(dirdat); dirdat = NULL; return -1; } global_dirdat = dirdat; // Hmm... prdir(main_w, top, top, dirdat, longest); mc_wlocate(main_w, initial_y, main_w->ys - FILE_MWTR); mc_wputs(main_w, _("( Escape to exit, Space to tag )")); dhili(subm); /* this really needs to go in dhili !!!*/ mc_wlocate(main_w, 0, cur + FILE_MWTR - top); if (flushit) { dirflush = 1; mc_wredraw(dsub, 1); } return 0; }
/* * The main terminal loop: * - If there are characters received send them * to the screen via the appropriate translate function. */ int do_terminal(void) { char buf[128]; int buf_offset = 0; int c; int x; int blen; int zauto = 0; static const char zsig[] = "**\030B00"; int zpos = 0; const char *s; dirflush = 0; WIN *error_on_open_window = NULL; dirty_goto: /* Show off or online time */ update_status_time(); /* If the status line was shown temporarily, delete it again. */ if (tempst) { tempst = 0; mc_wclose(st, 1); st = NULL; } /* Auto Zmodem? */ if (P_PAUTO[0] >= 'A' && P_PAUTO[0] <= 'Z') zauto = P_PAUTO[0]; /* Set the terminal modes */ setcbreak(2); /* Raw, no echo */ keyboard(KSTART, 0); /* Main loop */ while (1) { /* See if window size changed */ if (size_changed) { size_changed = 0; wrapln = us->wrap; /* I got the resize code going again! Yeah! */ mc_wclose(us, 0); us = NULL; if (st) mc_wclose(st, 0); st = NULL; mc_wclose(stdwin, 0); if (win_init(tfcolor, tbcolor, XA_NORMAL) < 0) leave(_("Could not re-initialize window system.")); /* Set the terminal modes */ setcbreak(2); /* Raw, no echo */ init_emul(terminal, 0); } /* Update the timer. */ timer_update(); /* check if device is ok, if not, try to open it */ if (!get_device_status(portfd_connected)) { /* Ok, it's gone, most probably someone unplugged the USB-serial, we * need to free the FD so that a replug can get the same device * filename, open it again and be back */ int reopen = portfd == -1; close(portfd); lockfile_remove(); portfd = -1; if (open_term(reopen, reopen, 1) < 0) { if (!error_on_open_window) error_on_open_window = mc_tell(_("Cannot open %s!"), dial_tty); } else { if (error_on_open_window) { mc_wclose(error_on_open_window, 1); error_on_open_window = NULL; } } } /* Check for I/O or timer. */ x = check_io(portfd_connected, 0, 1000, buf + buf_offset, sizeof(buf) - buf_offset, &blen); blen += buf_offset; buf_offset = 0; /* Data from the modem to the screen. */ if ((x & 1) == 1) { char obuf[sizeof(buf)]; char *ptr; if (using_iconv()) { char *otmp = obuf; size_t output_len = sizeof(obuf); size_t input_len = blen; ptr = buf; do_iconv(&ptr, &input_len, &otmp, &output_len); // something happened at all? if (output_len < sizeof(obuf)) { if (input_len) { // something remained, we need to adapt buf accordingly memmove(buf, ptr, input_len); buf_offset = input_len; } blen = sizeof(obuf) - output_len; ptr = obuf; } else ptr = buf; } else { ptr = buf; } while (blen-- > 0) { /* Auto zmodem detect */ if (zauto) { if (zsig[zpos] == *ptr) zpos++; else zpos = 0; } if (P_PARITY[0] == 'M' || P_PARITY[0] == 'S') *ptr &= 0x7f; if (display_hex) { unsigned char c = *ptr++; unsigned char u = c >> 4; c &= 0xf; vt_out(u > 9 ? 'a' + (u - 10) : '0' + u); vt_out(c > 9 ? 'a' + (c - 10) : '0' + c); vt_out(' '); } else vt_out(*ptr++); if (zauto && zsig[zpos] == 0) { dirflush = 1; keyboard(KSTOP, 0); updown('D', zauto - 'A'); dirflush = 0; zpos = 0; blen = 0; goto dirty_goto; } } mc_wflush(); }
/* * Initialize screen and status line. */ void init_emul(int type, int do_init) { int x = -1, y = -1; char attr = 0; int maxy; int ypos; if (st) { mc_wclose(st, 1); tempst = 0; st = NULL; } if (us) { x = us->curx; y = us->cury; attr = us->attr; mc_wclose(us, 0); } /* See if we have space for a fixed status line */ maxy = LINES - 1; if ((use_status || LINES > 24) && P_STATLINE[0] == 'e') { if (use_status) { ypos = LINES; maxy = LINES - 1; } else { ypos = LINES - 1; maxy = LINES - 2; } st = mc_wopen(0, ypos, COLS - 1, ypos, BNONE, st_attr, sfcolor, sbcolor, 1, 0, 1); mc_wredraw(st, 1); } /* MARK updated 02/17/95 - Customizable size for history buffer */ num_hist_lines = atoi(P_HISTSIZE); if (num_hist_lines < 0) num_hist_lines = 0; if (num_hist_lines > 5000) num_hist_lines = 5000; /* Open a new main window, and define the configured history buffer size. */ us = mc_wopen(0, 0, COLS - 1, maxy, BNONE, XA_NORMAL, tfcolor, tbcolor, 1, num_hist_lines, 0); if (x >= 0) { mc_wlocate(us, x, y); mc_wsetattr(us, attr); } us->autocr = 0; us->wrap = wrapln; terminal = type; lines = LINES - (st != NULL); cols = COLS; /* Install and reset the terminal emulator. */ if (do_init) { vt_install(do_output, kb_handler, us); vt_init(type, tfcolor, tbcolor, us->wrap, addlf, addcr); } else vt_pinit(us, -1, -1); show_status(); }
/* * Open the terminal. * * \return -1 on error, 0 on success */ int open_term(int doinit, int show_win_on_error, int no_msgs) { struct stat stt; union { char bytes[128]; int kermit; } buf; int fd, n = 0; int pid; #ifdef HAVE_ERRNO_H int s_errno; #endif #ifdef USE_SOCKET #define SOCKET_PREFIX "unix#" portfd_is_socket = portfd_is_connected = 0; if (strncmp(dial_tty, SOCKET_PREFIX, strlen(SOCKET_PREFIX)) == 0) { portfd_is_socket = 1; } #endif if (portfd_is_socket) goto nolock; #if !HAVE_LOCKDEV /* First see if the lock file directory is present. */ if (P_LOCK[0] && stat(P_LOCK, &stt) == 0) { #ifdef SVR4_LOCKS stat(dial_tty, &stt); sprintf(lockfile, "%s/LK.%03d.%03d.%03d", P_LOCK, major(stt.st_dev), major(stt.st_rdev), minor(stt.st_rdev)); #else /* SVR4_LOCKS */ snprintf(lockfile, sizeof(lockfile), "%s/LCK..%s", P_LOCK, mdevlockname(dial_tty, buf.bytes, sizeof(buf.bytes))); #endif /* SVR4_LOCKS */ } else lockfile[0] = 0; if (doinit > 0 && lockfile[0] && (fd = open(lockfile, O_RDONLY)) >= 0) { n = read(fd, buf.bytes, 127); close(fd); if (n > 0) { pid = -1; if (n == 4) /* Kermit-style lockfile. */ pid = buf.kermit; else { /* Ascii lockfile. */ buf.bytes[n] = 0; sscanf(buf.bytes, "%d", &pid); } if (pid > 0 && kill((pid_t)pid, 0) < 0 && errno == ESRCH) { fprintf(stderr, _("Lockfile is stale. Overriding it..\n")); sleep(1); unlink(lockfile); } else n = 0; } if (n == 0) { if (stdwin) mc_wclose(stdwin, 1); fprintf(stderr, _("Device %s is locked.\n"), dial_tty); return -1; } } #endif if (doinit > 0 && lockfile_create(no_msgs) != 0) return -1; nolock: /* Run a special program to disable callin if needed. */ if (doinit > 0 && P_CALLOUT[0]) { if (fastsystem(P_CALLOUT, NULL, NULL, NULL) < 0) { if (stdwin) mc_wclose(stdwin, 1); fprintf(stderr, _("Could not setup for dial out.\n")); lockfile_remove(); return -1; } } /* Now open the tty device. */ if (setjmp(albuf) == 0) { portfd = -1; signal(SIGALRM, get_alrm); alarm(20); #ifdef USE_SOCKET if (portfd_is_socket) { portfd_sock_addr.sun_family = AF_UNIX; strncpy(portfd_sock_addr.sun_path, dial_tty + strlen(SOCKET_PREFIX), sizeof(portfd_sock_addr.sun_path)-1); portfd_sock_addr.sun_path[sizeof(portfd_sock_addr.sun_path)-1] = 0; term_socket_connect(); } #endif /* USE_SOCKET */ if (!portfd_is_socket) { #if defined(O_NDELAY) && defined(F_SETFL) portfd = open(dial_tty, O_RDWR|O_NDELAY|O_NOCTTY); if (portfd >= 0) { /* Cancel the O_NDELAY flag. */ n = fcntl(portfd, F_GETFL, 0); fcntl(portfd, F_SETFL, n & ~O_NDELAY); } #else if (portfd < 0) portfd = open(dial_tty, O_RDWR|O_NOCTTY); #endif } if (portfd >= 0) { if (doinit > 0) m_savestate(portfd); port_init(); } } #ifdef HAVE_ERRNO_H s_errno = errno; #endif alarm(0); signal(SIGALRM, SIG_IGN); if (portfd < 0 && !portfd_is_socket) { if (!no_msgs) { if (doinit > 0) { if (stdwin) mc_wclose(stdwin, 1); #ifdef HAVE_ERRNO_H fprintf(stderr, _("minicom: cannot open %s: %s\n"), dial_tty, strerror(s_errno)); #else fprintf(stderr, _("minicom: cannot open %s. Sorry.\n"), dial_tty); #endif lockfile_remove(); return -1; } if (show_win_on_error) werror(_("Cannot open %s!"), dial_tty); } lockfile_remove(); return -1; } /* Set CLOCAL mode */ m_nohang(portfd); /* Set Hangup on Close if program crashes. (Hehe) */ m_hupcl(portfd, 1); if (doinit > 0) m_flush(portfd); return 0; }
/* 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 = mc_wopen(0, 0, us->x2, y, 0, us->attr, COLFG(us->color), COLBG(us->color), 0, 0, 0); mc_wcursor(b_us, CNONE); /* Open a help line window. */ b_st = mc_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; mc_wprintf(b_st, "%s", hline); mc_wredraw(b_st, 1); mc_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) { mc_wbell(); werror(_("History buffer Disabled!")); break; } if (!us->histline) { mc_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... */ mc_wlocate(b_st, 0, 0); /* move back to column 0! */ mc_wprintf(b_st, "%s", hline); /* and show the above-defined hline */ mc_wredraw(b_st, 1); /* again... */ /* highlight any matches */ if (wcslen(look_for) > 1) { hit = find_next(us, b_us, y, look_for, case_matters); if (hit == -1) { mc_wbell(); mc_wflush(); hit = 0; break; } drawhist_look(b_us, hit, 1, look_for, case_matters); y = hit; } else { mc_wbell(); break; } mc_wflush(); break; /* * fmg 8/22/97 * Take care of the Next Hit key... * Popup an error window if no previous... why not start a new * search? How do we know which case-importance they wanted? */ case 'n': case 'N': /* highlight NEXT match */ if (citemode) break; if (wcslen(look_for) > 1) { hit = find_next(us, b_us, y, look_for, case_matters); if (hit == -1) { mc_wbell(); mc_wflush(); hit = 0; break; } drawhist_look(b_us, hit, 1, look_for, case_matters); y = hit; } else { /* no search pattern... */ mc_wbell(); werror(_("No previous search!\n Please 's' or 'S' first!")); } mc_wflush(); break; case 'u': case 'U': case K_UP: if (citemode && cite_y) { cite_y--; if (cite_ystart != 1000000) { cite_yend = y + cite_y; drawcite(b_us, cite_y+1, y, cite_ystart, cite_yend); drawcite(b_us, cite_y, y, cite_ystart, cite_yend); } mc_wlocate(b_us, 0, cite_y); break; } if (y <= 0) break; y--; if (cite_ystart != 1000000) cite_yend = y + cite_y; mc_wscroll(b_us, S_DOWN); /* * fmg 8/20/97 * This is needed so that the movement in window will HIGHLIGHT * the lines that have the pattern we wanted... it's just nice. * This almost beggs for a function :-) */ if (citemode) { inverse = (y+cite_y >= cite_ystart && y+cite_y <= cite_yend); } else { tmp_e = mc_getline(b_us, y); if (wcslen(look_for) > 1) { /* quick scan for pattern match */ mc_wdrawelm_var(b_us, tmp_e, tmp_line); inverse = (wcslen(tmp_line)>1 && StrStr(tmp_line, look_for, case_matters)); } else inverse = 0; } if (inverse) mc_wdrawelm_inverse(b_us, 0, mc_getline(b_us, y)); else mc_wdrawelm(b_us, 0, mc_getline(b_us, y)); if (citemode) mc_wlocate(b_us, 0, cite_y); mc_wflush(); break; case 'd': case 'D': case K_DN: if (citemode && cite_y < b_us->ys-1) { cite_y++; if (cite_ystart != 1000000) { cite_yend = y + cite_y; drawcite(b_us, cite_y-1, y, cite_ystart, cite_yend); drawcite(b_us, cite_y, y, cite_ystart, cite_yend); } mc_wlocate(b_us, 0, cite_y); break; } if (y >= us->histlines) break; y++; if (cite_ystart != 1000000) cite_yend = y + cite_y; mc_wscroll(b_us, S_UP); /* * fmg 8/20/97 * This is needed so that the movement in window will HIGHLIGHT * the lines that have the pattern we wanted... it's just nice. * This almost beggs for a function :-) */ if (citemode) { inverse = (y+cite_y >= cite_ystart && y+cite_y <= cite_yend); } else { tmp_e = mc_getline(b_us, y + b_us->ys - 1); if (wcslen(look_for) > 1) { /* quick scan for pattern match */ mc_wdrawelm_var(b_us, tmp_e, tmp_line); inverse = (wcslen(tmp_line)>1 && StrStr(tmp_line, look_for, case_matters)); } else inverse = 0; } if (inverse) mc_wdrawelm_inverse(b_us, b_us->ys - 1, mc_getline(b_us, y + b_us->ys - 1)); else mc_wdrawelm(b_us, b_us->ys - 1, mc_getline(b_us, y + b_us->ys - 1)); if (citemode) mc_wlocate(b_us, 0, cite_y); mc_wflush(); break; case 'b': case 'B': case K_PGUP: if (y <= 0) break; y -= b_us->ys; if (y < 0) y = 0; if (cite_ystart != 1000000) cite_yend = y + cite_y; /* * fmg 8/20/97 * This is needed so that the movement in window will HIGHLIGHT * the lines that have the pattern we wanted... it's just nice. * Highlight any matches */ if (wcslen(look_for) > 1 && us->histline) drawhist_look(b_us, y, 1, look_for, case_matters); else drawhist(b_us, y, 1); if (citemode) mc_wlocate(b_us, 0, cite_y); break; case 'f': case 'F': case ' ': /* filipg: space bar will go page-down... pager-like */ case K_PGDN: if (y >= us->histlines) break; y += b_us->ys; if (y > us->histlines) y=us->histlines; if (cite_ystart != 1000000) cite_yend = y + cite_y; /* * fmg 8/20/97 * This is needed so that the movement in window will HIGHLIGHT * the lines that have the pattern we wanted... it's just nice. * Highlight any matches */ if (wcslen(look_for) > 1 && us->histline) drawhist_look(b_us, y, 1, look_for, case_matters); else drawhist(b_us, y, 1); if (citemode) mc_wlocate(b_us, 0, cite_y); break; case 'C': case 'c': /* start citation mode */ if (citemode ^= 1) { cite_y = 0; cite_ystart = 1000000; cite_yend = -1; strcpy(hline1, _(" CITATION: ENTER=select start line ESC=exit ")); if (b_st->xs < 127) hline1[b_st->xs]=0; hline = hline1; } else { hline = hline0; } mc_wlocate(b_st, 0, 0); mc_wprintf(b_st, "%s", hline); mc_wredraw(b_st, 1); if (citemode) mc_wlocate(b_us, 0, cite_y); break; case 10: case 13: if (!citemode) break; if (cite_ystart == 1000000) { cite_yend = cite_ystart = y + cite_y; strcpy(hline1, _(" CITATION: ENTER=select end line ESC=exit ")); if (b_st->xs < 127) hline1[b_st->xs]=0; } else { if (cite_ystart > cite_yend) break; drawcite_whole(b_us, y, 1000000, -1); loop = 0; break; } mc_wlocate(b_st, 0, 0); mc_wprintf(b_st, "%s", hline); mc_wredraw(b_st, 1); mc_wdrawelm_inverse(b_us, cite_y, mc_getline(b_us, cite_ystart)); mc_wlocate(b_us, 0, cite_y); break; case K_ESC: if (!citemode) { loop = 0; break; } if (cite_ystart == 1000000) { citemode = 0; hline = hline0; } else { cite_ystart = 1000000; strcpy(hline1, _(" CITATION: ENTER=select start line ESC=exit ")); } drawcite_whole(b_us, y, cite_ystart, cite_yend); mc_wlocate(b_st, 0, 0); mc_wprintf(b_st, "%s", hline); mc_wredraw(b_st, 1); if (citemode) mc_wlocate(b_us, 0, cite_y); break; } } /* Cleanup. */ if (citemode) do_cite(b_us, cite_ystart, cite_yend); mc_wclose(b_us, y == us->histlines ? 0 : 1); mc_wclose(b_st, 1); mc_wlocate(us, us->curx, us->cury); mc_wflush(); mc_wredraw(us, 1); }
int main(int argc, char **argv) { int c; /* Command character */ int quit = 0; /* 'q' or 'x' pressed */ char *s, *bufp; /* Scratch pointers */ int doinit = 1; /* -o option */ char capname[128]; /* Name of capture file */ struct passwd *pwd; /* To look up user name */ char *use_port; /* Name of initialization file */ char *args[20]; /* New argv pointer */ int argk = 1; /* New argc */ char *mc; /* For 'MINICOM' env. variable */ int env_args; /* Number of args in env. variable */ char *cmd_dial; /* Entry from the command line. */ int alt_code = 0; /* Type of alt key */ char *cmdline_baudrate = NULL;/* Baudrate given on the command line via -b */ char *cmdline_device = NULL; /* Device/Port given on the command line via -D */ char *remote_charset = NULL; /* Remote charset given on the command line via -R */ char pseudo[64]; /* char* console_encoding = getenv ("LC_CTYPE"); */ static struct option long_options[] = { { "setup", no_argument, NULL, 's' }, { "help", no_argument, NULL, 'h' }, { "ptty", required_argument, NULL, 'p' }, { "metakey", no_argument, NULL, 'm' }, { "metakey8", no_argument, NULL, 'M' }, { "ansi", no_argument, NULL, 'l' }, { "iso", no_argument, NULL, 'L' }, { "term", required_argument, NULL, 't' }, { "noinit", no_argument, NULL, 'o' }, { "color", required_argument, NULL, 'c' }, { "attrib", required_argument, NULL, 'a' }, { "dial", required_argument, NULL, 'd' }, { "statline", no_argument, NULL, 'z' }, { "capturefile", required_argument, NULL, 'C' }, { "script", required_argument, NULL, 'S' }, { "7bit", no_argument, NULL, '7' }, { "8bit", no_argument, NULL, '8' }, { "version", no_argument, NULL, 'v' }, { "wrap", no_argument, NULL, 'w' }, { "displayhex", no_argument, NULL, 'H' }, { "disabletime", no_argument, NULL, 'T' }, // obsolete { "baudrate", required_argument, NULL, 'b' }, { "device", required_argument, NULL, 'D' }, { "remotecharset", required_argument, NULL, 'R' }, { "statlinefmt", required_argument, NULL, 'F' }, { NULL, 0, NULL, 0 } }; /* initialize locale support */ setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); /* Initialize global variables */ portfd = -1; capfp = NULL; docap = 0; online = -1; linespd = 0; stdattr = XA_NORMAL; us = NULL; addlf = 0; addcr = 0; line_timestamp = 0; wrapln = 0; display_hex = 0; option_T_used = 0; local_echo = 0; strcpy(capname, "minicom.cap"); lockfile[0] = 0; tempst = 0; st = NULL; us = NULL; bogus_dcd = 0; usecolor = 0; screen_ibmpc = screen_iso = 1; useattr = 1; strncpy(termtype, getenv("TERM") ? getenv("TERM") : "dumb", sizeof(termtype)); stdattr = XA_NORMAL; use_port = "dfl"; alt_override = 0; scr_name[0] = 0; scr_user[0] = 0; scr_passwd[0] = 0; dial_name = (char *)NULL; dial_number = (char *)NULL; dial_user = (char *)NULL; dial_pass = (char *)NULL; size_changed = 0; escape = 1; cmd_dial = NULL; /* fmg 1/11/94 colors (set defaults) */ /* MARK updated 02/17/95 to be more similiar to TELIX */ mfcolor = YELLOW; mbcolor = BLUE; tfcolor = WHITE; tbcolor = BLACK; sfcolor = WHITE; sbcolor = RED; st_attr = XA_NORMAL; /* If no LANG or LC_ALL is set, fall back to 7bit mode * since in 8bit mode we can't have fancy window borders... */ { char *e1 = getenv("LANG"), *e2 = getenv("LC_ALL"); if ((!e1 || !strcmp("C", e1) || !strcmp("POSIX", e1)) && (!e2 || !strcmp("C", e2) || !strcmp("POSIX", e2))) screen_ibmpc = screen_iso = 0; } /* MARK updated 02/17/95 default history buffer size */ num_hist_lines = 256; /* fmg - but we reset these to F=WHITE, B=BLACK if -b flag found */ /* Before processing the options, first add options * from the environment variable 'MINICOM'. */ args[0] = "minicom"; if ((mc = getenv("MINICOM")) != NULL) { char buf[80]; strncpy(buf, mc, 80); bufp = buf; buf[79] = 0; while (isspace(*bufp)) bufp++; while (*bufp && argk < 19) { for (s = bufp; !isspace(*bufp) && *bufp; bufp++) ; args[argk++] = s; while (isspace(*bufp)) *bufp++ = 0; } } env_args = argk; /* Add command - line options */ for(c = 1; c < argc && argk < 19; c++) args[argk++] = argv[c]; args[argk] = NULL; do { /* Process options with getopt */ while ((c = getopt_long(argk, args, "v78zhlLsomMHb:wTc:a:t:d:p:C:S:D:R:F:", long_options, NULL)) != EOF) switch(c) { case 'v': printf(_("%s version %s"), PACKAGE, VERSION); #ifdef __DATE__ printf(_(" (compiled %s)"), __DATE__); #endif printf("\n"); printf(_("Copyright (C) Miquel van Smoorenburg.\n\n")); printf("This program is free software; you can redistribute it and/or\n" "modify it under the terms of the GNU General Public License\n" "as published by the Free Software Foundation; either version\n" "2 of the License, or (at your option) any later version.\n\n"); exit(1); break; case 's': /* setup mode */ dosetup = 1; break; case 'h': helpthem(); exit(1); break; case 'p': /* Pseudo terminal to use. */ if (strncmp(optarg, "/dev/", 5) == 0) optarg += 5; if (((strncmp(optarg, "tty", 3) != 0) /* /dev/pts support --misiek. */ && (strncmp(optarg, "pts", 3) != 0) /* /dev/pty support --jl. */ && (strncmp(optarg, "pty", 3) != 0)) || !strchr("pqrstuvwxyz/", optarg[3])) { fprintf(stderr, _("minicom: argument to -p must be a pty\n")); exit(1); } snprintf(pseudo, sizeof(pseudo), "/dev/%s", optarg); dial_tty = pseudo; break; case 'm': /* ESC prefix metakey */ alt_override++; alt_code = 27; break; case 'M': /* 8th bit metakey. */ alt_override++; alt_code = 128; break; case 'l': /* Don't assume literal ANSI chars */ screen_ibmpc = 0; break; case 'L': /* Don't assume literal ISO8859 chars */ screen_iso = 0; break; case 't': /* Terminal type */ strncpy(termtype, optarg, sizeof(termtype)); #ifdef __GLIBC__ /* Bug in older libc's (< 4.5.26 I think) */ if ((s = getenv("TERMCAP")) != NULL && *s != '/') unsetenv("TERMCAP"); #endif break; case 'o': /* DON'T initialize */ doinit = 0; break; case 'c': /* Color on/off */ if (strcmp("on", optarg) == 0) { usecolor = 1; stdattr = XA_BOLD; break; } if (strcmp("off", optarg) == 0) { usecolor = 0; stdattr = XA_NORMAL; break; } usage(env_args, optind - 1, mc); break; case 'a': /* Attributes on/off */ if (strcmp("on", optarg) == 0) { useattr = 1; break; } if (strcmp("off", optarg) == 0) { useattr = 0; break; } usage(env_args, optind - 1, mc); break; case 'd': /* Dial from the command line. */ cmd_dial = optarg; break; case 'z': /* Enable status line. */ use_status = 1; break; case 'C': /* Capturing */ capfp = fopen(optarg, "a"); if (capfp == NULL) { werror(_("Cannot open capture file")); exit(1); } docap = 1; vt_set(addlf, -1, docap, -1, -1, -1, -1, -1, addcr); break; case 'S': /* start Script */ strncpy(scr_name, optarg, 33); break; case '7': /* 7bit fallback mode */ screen_ibmpc = screen_iso = 0; break; case '8': /* force 8bit mode */ screen_ibmpc = screen_iso = 1; break; case 'w': /* Linewrap on */ wrapln = 1; break; case 'H': /* Display in hex */ display_hex = 1; break; case 'T': option_T_used = 1; break; case 'F': /* format of status line */ set_status_line_format(optarg); break; case 'b': cmdline_baudrate = optarg; break; case 'D': cmdline_device = optarg; break; case 'R': remote_charset = optarg; break; default: usage(env_args, optind, mc); break; } /* Now, get portname if mentioned. Stop at end or '-'. */ while (optind < argk && args[optind][0] != '-') use_port = args[optind++]; /* Loop again if more options */ } while (optind < argk); init_iconv(remote_charset); if (screen_iso && screen_ibmpc) /* init VT */ vt_set(-1, -1, -1, -1, -1, -1, 1, -1, -1); /* Avoid fraude ! */ for (s = use_port; *s; s++) if (*s == '/') *s = '_'; snprintf(parfile, sizeof(parfile), "%s/minirc.%s", CONFDIR, use_port); /* Get password file information of this user. */ if ((pwd = getpwuid(getuid())) == NULL) { fputs(_("You don't exist. Go away.\n"), stderr); exit(1); } /* Remember home directory and username. */ if ((s = getenv("HOME")) == NULL) strncpy(homedir, pwd->pw_dir, sizeof(homedir)); else strncpy(homedir, s, sizeof(homedir)); strncpy(username, pwd->pw_name, sizeof(username)); /* Get personal parameter file */ snprintf(pparfile, sizeof(pparfile), "%s/.minirc.%s", homedir, use_port); read_parms(); num_hist_lines = atoi(P_HISTSIZE); strcpy(logfname,P_LOGFNAME); /* Set default terminal behaviour */ addlf = strcasecmp(P_ADDLINEFEED, "yes") == 0; local_echo = strcasecmp(P_LOCALECHO, "yes") == 0; addcr = strcasecmp(P_ADDCARRIAGERETURN, "yes") == 0; /* -w overrides config file */ if (!wrapln) wrapln = strcasecmp(P_LINEWRAP, "yes") == 0; /* -H overrides config file */ if (!display_hex) display_hex = strcasecmp(P_DISPLAYHEX, "yes") == 0; /* After reading in the config via read_parms we can possibly overwrite * the baudrate with a value given at the cmdline */ if (cmdline_baudrate) { unsigned int b = strtol(cmdline_baudrate, (char **)NULL, 0); if (speed_valid(b)) { snprintf(P_BAUDRATE, sizeof(P_BAUDRATE), "%d", b); P_BAUDRATE[sizeof(P_BAUDRATE) - 1] = 0; } } /* Now we can also overwrite the device name, if one was given */ if (cmdline_device) { strncpy(P_PORT, cmdline_device, sizeof(P_PORT)); P_PORT[sizeof(P_PORT) - 1] = 0; } stdwin = NULL; /* It better be! */ /* Reset colors if we don't use 'em. */ if (!usecolor) { mfcolor = tfcolor = sfcolor = WHITE; mbcolor = tbcolor = sbcolor = BLACK; st_attr = XA_REVERSE; } if (dial_tty == NULL) { if (!dosetup) { while ((dial_tty = get_port(P_PORT)) != NULL && open_term(doinit, 1, 0) < 0) ; if (dial_tty == NULL) exit(1); } } else { if (!dosetup && open_term(doinit, 1, 0) < 0) exit(1); } mc_setenv("TERM", termtype); if (win_init(tfcolor, tbcolor, XA_NORMAL) < 0) leave(""); if (COLS < 40 || LINES < 10) leave(_("Sorry. Your screen is too small.\n")); if (dosetup) { if (config(1)) { mc_wclose(stdwin, 1); exit(0); } while ((dial_tty = get_port(P_PORT)) != NULL && open_term(doinit, 1, 0) < 0) ; if (dial_tty == NULL) exit(1); } /* Signal handling */ signal(SIGTERM, hangsig); signal(SIGHUP, hangsig); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGPIPE, SIG_IGN); #ifdef SIGTSTP signal(SIGTSTP, shjump); signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); #endif #ifdef SIGTINT signal(SIGTINT, SIG_IGN); #endif #ifdef SIGWINCH signal(SIGWINCH, change_size); #endif #ifdef DEBUG for(c = 1; c < _NSIG; c++) { if (c == SIGTERM) continue; /* Saviour when hung */ signal(c, signore); } #endif keyboard(KINSTALL, 0); if (strcmp(P_BACKSPACE, "BS") != 0) keyboard(KSETBS, P_BACKSPACE[0] == 'B' ? 8 : 127); if (alt_override) keyboard(KSETESC, alt_code); else if (strcmp(P_ESCAPE, "^A") != 0) { switch (P_ESCAPE[0]) { case '^': c = P_ESCAPE[1] & 31; break; case 'E': c = 27; break; default: c = 128; break; } keyboard(KSETESC, c); } st = NULL; us = NULL; init_emul(VT100, 1); if (doinit) modeminit(); if (option_T_used) mc_wprintf(us, "WARNING: Option -T ignored, use -F now\n\n"); mc_wprintf(us, "\n%s %s\r\n", _("Welcome to minicom"), VERSION); mc_wprintf(us, "\n%s: %s\r\n", _("OPTIONS"), option_string); #if defined (__DATE__) && defined (__TIME__) mc_wprintf(us, "%s %s, %s.\r\n",_("Compiled on"), __DATE__,__TIME__); #endif { struct stat st; char port_date[20] = ""; if (stat(P_PORT, &st) == 0) { time_t t = time(NULL); struct tm tm; if ( st.st_mtime + 20 * 60 * 60 > t && localtime_r(&st.st_mtime, &tm)) { strftime(port_date, sizeof(port_date), ", %T", &tm); port_date[sizeof(port_date) - 1] = 0; } } mc_wprintf(us, "%s %s%s\r\n", _("Port"), P_PORT, port_date); } if (using_iconv()) mc_wprintf(us, "%s\r\n", _("Using character set conversion")); mc_wprintf(us, _("\nPress %sZ for help on special keys%c\n\n"),esc_key(),'\r'); readdialdir(); if (scr_name[0]) runscript (0, scr_name, "", ""); if (cmd_dial) dialone(cmd_dial); set_local_echo(local_echo); set_addlf(addlf); set_line_timestamp(line_timestamp); /* The main loop calls do_terminal and gets a function key back. */ while (!quit) { c = do_terminal(); dirty_goto: switch (c + 32 *(c >= 'A' && c <= 'Z')) { case 'a': /* Add line feed */ toggle_addlf(); s = addlf ? _("Add linefeed ON") : _("Add linefeed OFF"); status_set_display(s, 0); break; case 'u': /* Add carriage return */ toggle_addcr(); s = addcr ? _("Add carriage return ON") : _("Add carriage return OFF"); status_set_display(s, 0); break; case 'e': /* Local echo on/off. */ toggle_local_echo(); s = local_echo ? _("Local echo ON") : _("Local echo OFF"); status_set_display(s, 0); break; case 'z': /* Help */ c = help(); if (c != 'z') goto dirty_goto; break; case 'c': /* Clear screen */ mc_winclr(us); break; case 'f': /* Send break */ sendbreak(); break; case 'b': /* Scroll back */ scrollback(); break; case 'm': /* Initialize modem */ if (P_HASDCD[0]=='Y' && online >= 0) { c = ask(_("You are online. Really initialize?"), c1); if (c != 0) break; } modeminit(); break; case 'q': /* Exit without resetting */ c = ask(_("Leave without reset?"), c1); if (c == 0) quit = NORESET; if (!strcmp(P_MACCHG,"CHANGED")) { c = ask (_("Save macros?"),c1); if (c == 0) if (dodflsave() < 0) { /* fmg - error */ c = 'O'; /* hehe */ quit = 0; goto dirty_goto; } } break; case 'x': /* Exit Minicom */ c = ask(_("Leave Minicom?"), c1); if (c == 0) { quit = RESET; if(online >= 0) do_hang(0); modemreset(); } if (!strcmp(P_MACCHG,"CHANGED")) { c = ask (_("Save macros?"), c1); if (c == 0) if (dodflsave() < 0) { /* fmg - error */ c = 'O'; /* hehe */ quit = 0; goto dirty_goto; } } break; case 'l': /* Capture file */ if (capfp == (FILE *)0 && !docap) { s = input(_("Capture to which file? "), capname); if (s == NULL || *s == 0) break; if ((capfp = fopen(s, "a")) == (FILE *)NULL) { werror(_("Cannot open capture file")); break; } docap = 1; } else if (capfp != (FILE *)0 && !docap) { c = ask(_("Capture file"), c3); if (c == 0) { fclose(capfp); capfp = (FILE *)NULL; docap = 0; } if (c == 1) docap = 1; } else if (capfp != (FILE *)0 && docap) { c = ask(_("Capture file"), c2); if (c == 0) { fclose(capfp); capfp = (FILE *)NULL; docap = 0; } if (c == 1) docap = 0; } vt_set(addlf, -1, docap, -1, -1, -1, -1, -1, addcr); break; case 'p': /* Set parameters */ get_bbp(P_BAUDRATE, P_BITS, P_PARITY, P_STOPB, 0); port_init(); show_status(); quit = 0; break; case 'k': /* Run kermit */ kermit(); break; case 'h': /* Hang up */ do_hang(1); break; case 'd': /* Dial */ dialdir(); break; case 't': /* Terminal emulation */ c = dotermmenu(); if (c > 0) init_emul(c, 1); break; case 'w': /* Line wrap on-off */ c = !us->wrap; vt_set(addlf, c, docap, -1, -1, -1, -1, -1, addcr); s = c ? _("Linewrap ON") : _("Linewrap OFF"); status_set_display(s, 0); break; case 'n': /* Line timestamp */ toggle_line_timestamp(); switch (line_timestamp) { default: case TIMESTAMP_LINE_OFF: s = _("Timestamp OFF"); break; case TIMESTAMP_LINE_SIMPLE: s = _("Timestamp every line (simple)"); break; case TIMESTAMP_LINE_EXTENDED: s = _("Timestamp every line (extended)"); break; case TIMESTAMP_LINE_PER_SECOND: s = _("Timestamp lines every second"); break; } status_set_display(s, 0); break; case 'o': /* Configure Minicom */ (void) config(0); break; case 's': /* Upload */ updown('U', 0); break; case 'r': /* Download */ updown('D', 0); break; case 'j': /* Jump to a shell */ shjump(0); break; case 'g': /* Run script */ runscript(1, "", "", ""); break; case 'i': /* Re-init, re-open portfd. */ cursormode = (cursormode == NORMAL) ? APPL : NORMAL; keyboard(cursormode == NORMAL ? KCURST : KCURAPP, 0); show_status(); break; case 'y': /* Paste file */ paste_file(); break; case EOF: /* Cannot read from stdin anymore, exit silently */ quit = NORESET; break; default: break; } }; /* Reset parameters */ if (quit != NORESET) m_restorestate(portfd); else { if (P_LOGCONN[0] == 'Y' && online > 0) do_log("%s", _("Quit without reset while online.")); m_hupcl(portfd, 0); } signal(SIGTERM, SIG_IGN); signal(SIGHUP, SIG_IGN); #ifdef SIGTSTP signal(SIGTSTP, SIG_DFL); #endif signal(SIGQUIT, SIG_DFL); if (capfp != (FILE *)0) fclose(capfp); mc_wclose(us, 0); mc_wclose(st, 0); mc_wclose(stdwin, 1); keyboard(KUNINSTALL, 0); lockfile_remove(); close(portfd); if (quit != NORESET && P_CALLIN[0]) fastsystem(P_CALLIN, NULL, NULL, NULL); close_iconv(); return 0; }
/* * Run an external script. * ask = 1 if first ask for confirmation. * s = scriptname, l=loginname, p=password. */ void runscript(int ask, const char *s, const char *l, const char *p) { int status; int n, i; int pipefd[2]; char buf[81]; char scr_lines[5]; char cmdline[128]; struct pollfd fds[2]; char *translated_cmdline; char *ptr; WIN *w; int done = 0; char *msg = _("Same as last"); char *username = _(" A - Username :"******" B - Password :"******" C - Name of script :"), *question = _("Change which setting? (Return to run, ESC to stop)"); if (ask) { w = mc_wopen(10, 5, 70, 10, BDOUBLE, stdattr, mfcolor, mbcolor, 0, 0, 1); mc_wtitle(w, TMID, _("Run a script")); mc_wputs(w, "\n"); mc_wprintf(w, "%s %s\n", username, scr_user[0] ? msg : ""); mc_wprintf(w, "%s %s\n", password, scr_passwd[0] ? msg : ""); mc_wprintf(w, "%s %s\n", name_of_script, scr_name); mc_wlocate(w, 4, 5); mc_wputs(w, question); mc_wredraw(w, 1); while (!done) { mc_wlocate(w, mbslen (question) + 5, 5); n = wxgetch(); if (islower(n)) n = toupper(n); switch (n) { case '\r': case '\n': if (scr_name[0] == '\0') { mc_wbell(); break; } mc_wclose(w, 1); done = 1; break; case 27: /* ESC */ mc_wclose(w, 1); return; case 'A': mc_wlocate(w, mbslen (username) + 1, 1); mc_wclreol(w); scr_user[0] = 0; mc_wgets(w, scr_user, 32, 32); break; case 'B': mc_wlocate(w, mbslen (password) + 1, 2); mc_wclreol(w); scr_passwd[0] = 0; mc_wgets(w, scr_passwd, 32, 32); break; case 'C': mc_wlocate(w, mbslen (name_of_script) + 1, 3); mc_wgets(w, scr_name, 32, 32); break; default: break; } } } else { strncpy(scr_user, l, sizeof(scr_user)); strncpy(scr_name, s, sizeof(scr_name)); strncpy(scr_passwd, p, sizeof(scr_passwd)); } sprintf(scr_lines, "%d", (int) lines); /* jl 13.09.97 */ /* Throw away status line if temporary */ if (tempst) { mc_wclose(st, 1); tempst = 0; st = NULL; } scriptname(scr_name); pipe(pipefd); if (mcd(P_SCRIPTDIR) < 0) return; snprintf(cmdline, sizeof(cmdline), "%s %s %s %s", P_SCRIPTPROG, scr_name, logfname, logfname[0]==0? "": homedir); switch (udpid = fork()) { case -1: werror(_("Out of memory: could not fork()")); close(pipefd[0]); close(pipefd[1]); mcd(""); return; case 0: /* Child */ dup2(portfd, 0); dup2(portfd, 1); dup2(pipefd[1], 2); close(pipefd[0]); close(pipefd[1]); for (n = 1; n < _NSIG; n++) signal(n, SIG_DFL); mc_setenv("LOGIN", scr_user); mc_setenv("PASS", scr_passwd); mc_setenv("TERMLIN", scr_lines); /* jl 13.09.97 */ translated_cmdline = translate(cmdline); if (translated_cmdline != NULL) { fastexec(translated_cmdline); free(translated_cmdline); } exit(1); default: /* Parent */ break; } setcbreak(1); /* Cbreak, no echo */ enab_sig(1, 0); /* But enable SIGINT */ signal(SIGINT, udcatch); close(pipefd[1]); /* pipe output from "runscript" program to terminal emulator */ fds[0].fd = pipefd[0]; /* runscript */ fds[0].events = POLLIN; fds[1].fd = STDIN_FILENO; /* stdin */ fds[1].events = POLLIN; script_running = 1; while (script_running && poll(fds, 2, -1) > 0) for (i = 0; i < 2; i++) { if (fds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) script_running = 0; else if ((fds[i].revents & POLLIN) && (n = read(fds[i].fd, buf, sizeof(buf)-1)) > 0) { ptr = buf; while (n--) if (i) vt_send(*ptr++); else vt_out(*ptr++); timer_update(); mc_wflush(); } } /* Collect status, and clean up. */ m_wait(&status); enab_sig(0, 0); signal(SIGINT, SIG_IGN); setcbreak(2); /* Raw, no echo */ close(pipefd[0]); scriptname(""); mcd(""); }
void updown(int what, int nr) { #ifdef LOG_XFER #warning LOG_XFER defined! FILE *xfl; #endif const char *name[13]; int idx[13]; int r, f, g = 0; char *t = what == 'U' ? _("Upload") : _("Download"); char buf[160]; char buffirst[20]; char xfrstr[160] = ""; char trimbuf[160] = ""; char title[64]; const char *s =""; int pipefd[2]; int n, status; char * cmdline = NULL; char * translated_cmdline = NULL; WIN *win = (WIN *)NULL; if (mcd(what == 'U' ? P_UPDIR : P_DOWNDIR) < 0) return; /* Automatic? */ if (nr == 0) { for (f = 0; f < 12; f++) { if (P_PNAME(f)[0] && P_PUD(f) == what) { name[g] = P_PNAME(f); idx[g++] = f; } } name[g] = NULL; if (g == 0) return; r = mc_wselect(30, 7, name, NULL, t, stdattr, mfcolor, mbcolor) - 1; if (r < 0) return; g = idx[r]; } else g = nr; buf[0] = 0; /* jseymour file selector with choice of dir on zmodem, etc. download */ #if 1 { int multiple; /* 0:only directory, 1:one file, -1:any number */ size_t cmdline_length; if (P_MUL(g)=='Y') /* need file(s), or just a directory? */ multiple = what == 'U'? -1 : 0; else multiple = 1; /* only one allowed */ if (P_FSELW[0] == 'Y' && (what == 'U' || P_ASKDNDIR[0] == 'Y')) { s = filedir(multiple, what == 'U'? 0 : 1); if (s == NULL) return; } else if (P_PNN(g) == 'Y') { s = input(_("Please enter file names"), buf); if (s == NULL) return; } /* discard directory if "multiple" == 0 */ cmdline_length = strlen(P_PPROG(g)) + strlen((char*) (multiple == 0 ? "" : s)) + 1; /* + 1 for ' ' */ cmdline = malloc(cmdline_length + 1); /* + 1 for NUL */ if (cmdline == NULL) { werror(_("Out of memory: could allocate buffer for command line")); return; } snprintf(cmdline, cmdline_length + 1, "%s %s", P_PPROG(g), multiple == 0 ? "" : s); } #endif if (P_LOGXFER[0] == 'Y') do_log("%s", cmdline); /* jl 22.06.97 */ if (P_PFULL(g) == 'N') { win = mc_wopen(10, 7, 70, 13, BSINGLE, stdattr, mfcolor, mbcolor, 1, 0, 1); snprintf(title, sizeof(title), _("%.30s %s - Press CTRL-C to quit"), P_PNAME(g), what == 'U' ? _("upload") : _("download")); mc_wtitle(win, TMID, title); pipe(pipefd); } else mc_wleave(); m_flush(portfd); switch (udpid = fork()) { case -1: werror(_("Out of memory: could not fork()")); if (win) { close(pipefd[0]); close(pipefd[1]); mc_wclose(win, 1); } else mc_wreturn(); mcd(""); if(cmdline) free(cmdline); return; case 0: /* Child */ if (P_PIORED(g) == 'Y') { dup2(portfd, 0); dup2(portfd, 1); } if (win) { dup2(pipefd[1], 2); close(pipefd[0]); if (pipefd[1] != 2) close(pipefd[1]); } lockfile_remove(); for (n = 1; n < _NSIG; n++) signal(n, SIG_DFL); translated_cmdline = translate(cmdline); if (translated_cmdline != NULL) { fastexec(translated_cmdline); free(translated_cmdline); } if(cmdline) free(cmdline); exit(1); default: /* Parent */ break; } if(cmdline) free(cmdline); if (win) { setcbreak(1); /* Cbreak, no echo. */ enab_sig(1, 0); /* But enable SIGINT */ } signal(SIGINT, udcatch); if (P_PIORED(g) == 'Y') { close(pipefd[1]); #ifdef LOG_XFER xfl=fopen("xfer.log","wb"); #endif while ((n = read(pipefd[0], buf, sizeof(buf))) > 0) { buf[n] = '\0'; mc_wputs(win, buf); timer_update(); /* Log the filenames & sizes jl 14.09.97 */ if (P_LOGXFER[0] == 'Y') { #ifdef LOG_XFER if (xfl) fprintf(xfl,">%s<\n",buf); #endif if (sscanf(buf, "%19s", buffirst)) { /* if / jl 29.09.97 */ if (!strncmp (buffirst, "Receiving", 9) || !strncmp (buffirst, "Sending", 7)) { if (xfrstr[0]) { trim (trimbuf, xfrstr, sizeof(trimbuf)); do_log ("%s", trimbuf); xfrstr[0] = 0; } trim (trimbuf, buf, sizeof(trimbuf)); do_log("%s", trimbuf); } else if (!strncmp (buffirst, "Bytes", 5)) { strncpy (xfrstr, buf, sizeof(xfrstr)); } buffirst[0] = 0; trimbuf[0] = 0; } } } #ifdef LOG_XFER if (xfl) fclose(xfl); #endif } /* Log the last file size jl 14.09.97 */ if (P_LOGXFER[0] == 'Y' && xfrstr[0]) { trim (trimbuf, xfrstr, sizeof(trimbuf)); do_log ("%s", trimbuf); xfrstr[0] = 0; } while (udpid != m_wait(&status)); if (win) { enab_sig(0, 0); signal(SIGINT, SIG_IGN); } if (win == (WIN *)0) mc_wreturn(); lockfile_create(); /* MARK updated 02/17/94 - Flush modem port before displaying READY msg */ /* because a BBS often displays menu text right after a download, and we */ /* don't want the modem buffer to be lost while waiting for key to be hit */ m_flush(portfd); port_init(); setcbreak(2); /* Raw, no echo. */ if (win) close(pipefd[0]); mcd(""); timer_update(); /* If we got interrupted, status != 0 */ if (win && (status & 0xFF00) == 0) { #if VC_MUSIC if (P_SOUND[0] == 'Y') { mc_wprintf(win, _("\n READY: press any key to continue...")); music(); } else sleep(1); #else /* MARK updated 02/17/94 - If there was no VC_MUSIC capability, */ /* then at least make some beeps! */ if (P_SOUND[0] == 'Y') mc_wprintf(win, "\007\007\007"); sleep(1); #endif } if (win) mc_wclose(win, 1); }
/* ESC [? ... [hl] seen. */ static void dec_mode(int on_off) { int i; for (i = 0; i <= ptr; i++) { switch (escparms[i]) { case 1: /* Cursor keys in cursor/appl mode */ vt_cursor = on_off ? APPL : NORMAL; if (vt_keyb) (*vt_keyb)(vt_keypad, vt_cursor); break; case 6: /* Origin mode. */ vt_om = on_off; mc_wlocate(vt_win, 0, newy1); break; case 7: /* Auto wrap */ vt_win->wrap = on_off; break; case 25: /* Cursor on/off */ mc_wcursor(vt_win, on_off ? CNORMAL : CNONE); break; case 67: /* Backspace key sends. (FIXME: vt420) */ /* setbackspace(on_off ? 8 : 127); */ break; case 47: /* Alternate screen */ case 1047: case 1049: if ((us_alternate && on_off) || !on_off) { vt_win = us; mc_clear_window_simple(us_alternate); mc_wclose(us_alternate, 1); us_alternate = NULL; } if (on_off) { us_alternate = mc_wopen(0, 0, COLS - 1, us->y2, BNONE, XA_NORMAL, tfcolor, tbcolor, 1, 0, 0); vt_win = us_alternate; } { char b[10]; snprintf(b, sizeof(b), "\e[?%d%c", escparms[i], on_off ? 'h' : 'l'); b[sizeof(b) - 1] = 0; mc_wputs(stdwin, b); } if (on_off) mc_clear_window_simple(us_alternate); break; default: /* Mostly set up functions */ /* IGNORED */ break; } } }