Exemple #1
0
/*
 * Print the directory. Only draw from "cur" to bottom.
 */
static void prdir(WIN *dirw, int top, int cur,
                  GETSDIR_ENTRY *dirdat, int longest)
{
  int f, start;
  char f_str[BUFSIZ];
  char t_str[BUFSIZ];

  start = cur - top;
  dirflush = 0;
  sprintf(f_str, " %%-%ds", longest + 2);
  mc_wlocate(dirw, 0, start + FILE_MWTR);
  for (f = start; f < dirw->ys - (1 + FILE_MWTR); f++) {
    GETSDIR_ENTRY *d;
    if (!(d = getno(f + top, dirdat)))
      break;
    if (d->cflags & FL_TAG)
      mc_wsetattr(dirw, XA_REVERSE | stdattr);
    if (S_ISDIR(d->mode)) {
      snprintf(t_str, sizeof(t_str), "[%s]", d->fname);
      mc_wprintf(dirw, f_str, t_str);
    } else
      mc_wprintf(dirw, f_str, d->fname);
    mc_wsetattr(dirw, XA_NORMAL | stdattr);
    mc_wputc(dirw, '\n');
  }
  dirflush = 1;
  mc_wflush();
}
Exemple #2
0
/* Draw an entry in the horizontal menu */
static void horiz_draw(size_t k, char start_attr, char end_attr)
{
  static const char spaces[] = "        ";

  mc_wprintf(dsub, "%.*s", what_padding[k][0], spaces);
  mc_wsetattr(dsub, start_attr);
  mc_wprintf(dsub, "%.*s", what_lens[k], _(what[k]));
  mc_wsetattr(dsub, end_attr);
  mc_wprintf(dsub, "%.*s", what_padding[k][1], spaces);
}
Exemple #3
0
/*
 * Show the name of the script running now.
 */
void scriptname(const char *s)
{
  if (st == NULL)
    return;
  mc_wlocate(st, 39, 0);
  if (*s == 0)
    mc_wprintf(st, "Minicom %-6.6s", VERSION);
  else
    mc_wprintf(st, "script %-7.7s", s);
  ret_csr();
}
Exemple #4
0
/*
 * Print one directory entry.
 */
static void prone(WIN *dirw, GETSDIR_ENTRY *dirdat, int longest, int inverse)
{
  char f_str[BUFSIZ];
  char t_str[BUFSIZ];

  dirflush = 0;
  sprintf(f_str, " %%-%ds", longest + 2);
  /*
  if (dirdat->cflags & FL_TAG)
    mc_wsetattr(dirw, XA_REVERSE | stdattr);
     */
  if (inverse)
    mc_wsetattr(dirw, XA_REVERSE | stdattr);
  if (S_ISDIR(dirdat->mode)) {
    snprintf(t_str, sizeof(t_str),  "[%s]", dirdat->fname);
    mc_wprintf(dirw, f_str, t_str);
  } else
    mc_wprintf(dirw, f_str, dirdat->fname);
  mc_wsetattr(dirw, XA_NORMAL | stdattr);
  dirflush = 1;
  mc_wflush();
}
Exemple #5
0
/*
 * 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;
}
Exemple #6
0
/*
 * Show the status line
 */
static void show_status_fmt(const char *fmt)
{
  if (!st)
    return;

  char buf[COLS];
  int bufi = 0;
  int l = strlen(fmt);
  for (int i = 0; i < l && bufi < COLS; ++i)
    {
      if (fmt[i] == '%' && i + 1 < l)
        {
          char func = fmt[i + 1];
          ++i;

          switch (func)
            {
            case '%':
              bufi += snprintf(buf + bufi, COLS - bufi, "%%");
              break;
            case 'H':
              bufi += snprintf(buf + bufi, COLS - bufi, "%sZ", esc_key());
              break;
            case 'V':
              bufi += snprintf(buf + bufi, COLS - bufi, "%s", VERSION);
              break;
            case 'b':
              if (portfd_is_socket)
                bufi += snprintf(buf + bufi, COLS - bufi, "unix-socket");
              else
                {
                  if (P_SHOWSPD[0] == 'l')
                    bufi += snprintf(buf + bufi, COLS - bufi, "%6ld", linespd);
                  else
                    bufi += snprintf(buf + bufi, COLS - bufi, "%s", P_BAUDRATE);
                  bufi += snprintf(buf + bufi, COLS - bufi, " %s%s%s",  P_BITS, P_PARITY, P_STOPB);
                }
              break;
            case 'T':
              switch (terminal)
                {
                case VT100:
                  bufi += snprintf(buf + bufi, COLS - bufi, "VT102");
                  break;
                case ANSI:
                  bufi += snprintf(buf + bufi, COLS - bufi, "ANSI");
                  break;
                }

              break;
            case 'C':
              bufi += snprintf(buf + bufi, COLS - bufi, cursormode == NORMAL ? "NOR" : "APP");
              break;

            case 't':
              if (online < 0)
                bufi += snprintf(buf + bufi, COLS - bufi, "%s",
                                 P_HASDCD[0] == 'Y' ? _("Offline") : _("OFFLINE"));
              else
                bufi += snprintf(buf + bufi, COLS - bufi, "%s %ld:%ld",
                                 P_HASDCD[0] == 'Y' ? _("Online") : _("ONLINE"),
                                 online / 3600, (online / 60) % 60);
              break;

            case 'D':
                {
                  char b[COLS - bufi];
                  bufi += snprintf(buf + bufi, COLS - bufi, "%s",
                                   shortened_devpath(b, sizeof(b), P_PORT));
                }
              break;

            case '$':
              bufi += snprintf(buf + bufi, COLS - bufi, "%s", status_message);
              break;

            default:
              bufi += snprintf(buf + bufi, COLS - bufi, "?%c", func);
              break;
            }
        }
      else
        {
          buf[bufi] = fmt[i];
          bufi++;
        }
    }

  if (bufi < COLS - 1)
    memset(buf + bufi, ' ', COLS - bufi);
  buf[COLS - 1] = 0;

  st->direct = 0;
  mc_wlocate(st, 0, 0);
  mc_wprintf(st, "%s", buf);
  mc_wredraw(st, 1);
  ret_csr();
}
Exemple #7
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);
}
Exemple #8
0
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;
}
Exemple #9
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("");
}
Exemple #10
0
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);
}