Exemplo n.º 1
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();
    }
Exemplo n.º 2
0
/*
 * Read a character from the keyboard.
 * Handle special characters too!
 */
int wxgetch(void)
{
  int f, g;
  int match = 1;
  int len;
  char c;
  static unsigned char mem[8];
  static int leftmem = 0;
  static int init = 0;
  int nfound = 0;
  int start_match;
#if VT_KLUDGE
  char temp[8];
#endif
  struct timeval timeout;
  fd_set readfds;

  if (init == 0) {
    _initkeys();
    init++;
    erasechar = setcbreak(3);
  }

  /* Some sequence still in memory ? */
  if (leftmem > 0) {
    leftmem--;
    if (leftmem == 0)
      pendingkeys = 0;
    if (pendingkeys == 0 && keys_in_buf == 0)
      io_pending = 0;
    return mem[leftmem];
  }
  gotalrm = 0;
  pendingkeys = 0;

  for (len = 1; len < 8 && match; len++) {
#if KEY_KLUDGE
    if (len > 1 && keys_in_buf == 0)
#else
    if (len > 1)
#endif
    {
      timeout.tv_sec = 0;
      timeout.tv_usec = 400000; /* 400 ms */
      FD_ZERO(&readfds);
      FD_SET(0, &readfds);
      if (!(nfound = select(1, &readfds, NULL, NULL, &timeout)))
        break;
    }

#if KEY_KLUDGE
    while ((nfound = cread(&c)) < 0 && (errno == EINTR && !gotalrm))
      ;
#else
    while ((nfound = read(0, &c, 1)) < 0 && (errno == EINTR && !gotalrm))
      ;
#endif

    if (nfound < 1)
      return EOF;

    if (len == 1) {
      /* Enter and erase have precedence over anything else */
      if (c == '\n')
        return c;
      if (c == erasechar)
        return K_ERA;
    }
#if KEY_KLUDGE
    /* Return single characters immideately */
    if (isconsole && nfound == 1 && len == 1)
      return c;

    /* Another hack - detect the Meta Key. */
    if (isconsole && nfound == 2 && len == 1 && c == 27 && escape == 27) {
      cread(&c);
      return c + K_META;
    }
#endif
    mem[len - 1] = c;
    match = 0;
#if VT_KLUDGE
    /* Oh boy. Stupid vt100 2 mode keyboard. */
    strncpy(temp, mem, len);
    if (len > 1 && temp[0] == 27) {
      if (temp[1] == '[')
        temp[1] = 'O';
      else if (temp[1] == 'O')
        temp[1] = '[';
    }
    /* We now have an alternate string to check. */
#endif
    start_match = 0;
    for (f = 0; f < NUM_KEYS; f++) {
#if VT_KLUDGE
      if (_keys[f].len >= len &&
          (strncmp(_keys[f].cap, (char *)mem,  len) == 0 ||
           strncmp(_keys[f].cap, (char *)temp, len) == 0))
#else
        if (_keys[f].len >= len &&
            strncmp(_keys[f].cap, (char *)mem, len) == 0)
#endif
        {
          match++;
          if (_keys[f].len == len) {
            return f + KEY_OFFS;
          }
        }
      /* Does it match on first two chars? */
      if (_keys[f].len > 1 && len == 2 &&
          strncmp(_keys[f].cap, (char *)mem, 2) == 0)
        start_match++;
    }
#if KEY_KLUDGE
    if (!isconsole)
#endif
#ifndef _MINIX /* Minix doesn't have ESC-c meta mode */
      /* See if this _might_ be a meta-key. */
      if (escape == 27 && !start_match && len == 2 && mem[0] == 27)
        return c + K_META;
#endif
  }
  /* No match. in len we have the number of characters + 1 */
  len--; /* for convenience */
  if (len == 1)
    return mem[0];
  /* Remember there are more keys waiting in the buffer */
  pendingkeys++;
  io_pending++;

  /* Reverse the "mem" array */
  for (f = 0; f < len / 2; f++) {
    g = mem[f];
    mem[f] = mem[len - f - 1];
    mem[len - f - 1] = g;
  }
  leftmem = len - 1;
  return mem[leftmem];
}
Exemplo n.º 3
0
int main() {
  printf("\033[?25l"); // Hide the cursor

  d_clear(0);

  int x=40<<3; // We store the upscaled coordinates here, divide this by 4 to get real screen coordinates
  int y=10<<3;
  int dx=4;    // Direction on x axis, upscaled coordinate compatible value
  int dy=1;    // Direction on y axis, upscaled coordinate compatible value
  int oldx;    // Screen coordinate for erasing the ball
  int oldy;
  int newx;    // Used for converting back to the "screen" coordinates before checking wall hits and paddle hits
  int newy;

  int p1=10;   // Paddle 1's y coordinate - this is a screen coordinate
  int p2=10;
#define pw 5

  int p1score=0;
  int p2score=0;

  d_vline( 1, p1, p1+pw, 6);
  d_vline(78, p2, p2+pw, 6);

  int simpletimer=6;

  setcbreak();
  int ch=-1;
  while (ch==-1 || ch!='q') {
    usleep(3000);
    ch=getch();
    if (ch!=-1) {
      // Handles for the first paddle
      if (ch=='w' && p1>0) {
        d_putpixel(1, p1+pw, 0);
        --p1;
        d_putpixel(1, p1, 6);
      }
      if (ch=='s' && p1+pw<23) {
        d_putpixel(1, p1, 0);
        ++p1;
        d_putpixel(1, p1+pw, 6);
      }
      // Handles for the second paddle
      if (ch=='o' && p2>0) {
        d_putpixel(78, p2+pw, 0);
        --p2;
        d_putpixel(78, p2, 6);
      }
      if (ch=='l' && p2+pw<23) {
        d_putpixel(78, p2, 0);
        ++p2;
        d_putpixel(78, p2+pw, 6);
      }
    }

    --simpletimer;
    if (simpletimer<=0) {
      simpletimer=6;

      oldx=x>>3;
      oldy=y>>3;
      newx=(x+dx)>>3; // Now we can check screen objects against these for collision
      newy=(y+dy)>>3;

      if (newx==1 && newy>=p1 && newy<=p1+pw) dx*=-1; // Check if first paddle would be hit, if it is, reverse the x axis movement direction
      if (newx==78 && newy>=p2 && newy<=p2+pw) dx*=-1; // Check if second paddle...
      if (newy>23 || newy<0) dy*=-1; // If the upper or lower border would be crossed by this move, reverse the y axis movement

      if (newx<0 || newx>79) {// The ball went out on one side, place it on the center of the loser's paddle and let it fly
        d_goto(30,12); // Prepare the drawing cursor for text output at this position
        if (newx<40) {// The ball was on the left side when it exited the playable area, increment player 2's score, and put the ball on player 1's paddle
	        ++p2score;
	        newx=2;
	        newy=p1+(pw/2);

	        printf("Player 2 scores!");
	      } else { // Otherwise it was on the right side, increment player 1 score, put ball on player 2's paddle
	        ++p1score;
	        newx=77;
	        newy=p2+(pw/2);

	        printf("Player 1 scores!");
	      }
        dx*=-1; // Remember that the ball was headed outwards the last time we saw it, so we have to switch the horizontal direction
	      x=newx<<3; // And scale up the screen coordinates for later use
	      y=newy<<3;

        // Wait for a bit then erase the text
        d_goto(0,0);
	      d_flush();
        usleep(1000000);
        d_goto(30,12); printf("                ");
        d_goto(0,0);
	      d_flush();
      }

      x+=dx; y+=dy; // This is the movement

      d_putpixel(oldx, oldy, 0);
      d_putpixel(x>>3, y>>3, 3); // Remember, x and y stores upscaled coordinates, so we have to divide them by 4 for drawing  [also remember that a bit shift to the right by 3 equals to that divide]
    }
    d_goto(10,0); printf("%i", p1score);
    d_goto(50,0); printf("%i", p2score);
    d_goto(0,0);
    d_flush();
  }
Exemplo n.º 4
0
/*
 * Main program of keyserv.
 */
int main(int argc, char **argv)
{
  int c;
  char ch;
  int f, fun;
  int stopped = 0;

  if (argc < 2 || (parent = atoi(argv[1])) == 0) {
    printf("Usage: %s <parent>\n", *argv);
    exit(1);
  }
  
  /* Initialize signal handlers */
  /* signal(SIGHUP, SIG_IGN); */
  signal(SIGQUIT, SIG_IGN);
  signal(SIGINT, SIG_IGN);
#ifdef SIGTSTP
  signal(SIGTSTP, SIG_IGN);
  signal(SIGTTIN, SIG_IGN);
  signal(SIGTTOU, SIG_IGN);
#endif
  signal(HELLO, handler);

  /* Set up escape sequence table */
  escseq = st_vtesc;

  /* Cbreak, no echo (minicom itself sets to raw if needed) */
  setcbreak(1);

  if ((fun = setjmp(mainloop)) != 0) {
    switch (fun) {

      /* We come here after minicom has told us something */

      case KVT100: /* VT100 keyboard */
        mode = EVT100;
        escseq = st_vtesc;
        break;
      case KANSI:  /* ANSI keyboard */
        mode = EANSI;
        escseq = ansiesc;
        break;
      case KKPST: /* Keypad in standard mode, not used */
        keypadmode = NORMAL; 
        break;
      case KKPAPP: /* Keypad in applications mode, not used */
        keypadmode = APPL;
        break;
      case KCURST: /* Standard cursor keys */
        cursormode = NORMAL;
        if (mode == EVT100)
          escseq = st_vtesc;
        break;
      case KCURAPP: /* cursor keys in applications mode */
        cursormode = APPL;
        if (mode == EVT100)
          escseq = app_vtesc;
        break;
      case KSTOP:  /* Sleep until further notice */
        stopped = 1;
        break;
      case KSIGIO: /* Wait for keypress and tell parent */
        kill(parent, ACK);
        f = read(0, &ch, 1);
        if (f == 1) {
          write(to_minicom, &ch, 1);
          kill(parent, HELLO);
        }
        break;
      case KSTART: /* Restart when stopped */
        stopped  = 0;
        break;
      case KSETBS: /* Set code that BS key sends */
        bs_code = argument;
        break;
      case KSETESC: /* Set escape character */
        esc_char = argument;
        break;
      default:
        break;
    }
    if (fun != KSIGIO)
      kill(parent, ACK);
  }
  /* Wait if stopped */
  if (stopped)
    pause();

  /* Main loop: read keyboard, send to modem */
  while (1) {
    c = wxgetch();
    if (c > 256 && c < 256 + NUM_KEYS) {
      sendstr(escseq[c - 256]);
    }
    if (c < 256) {
      if (c == K_ERA)
        c = bs_code;
      ch = c;
      /* Test for escape characters */
      if (c == esc_char || (esc_char == 128 && c > 128)) { 
        /* If we typed too fast, and the escape sequence
         * was not that of a function key, the next key
         * is already in the buffer.
         */
        if (c == esc_char && pendingkeys > 0) {
          ch = wxgetch();
        }
        write(to_minicom, &ch, 1);
        kill(parent, HELLO);
      } else {
        write(1, &ch, 1);
      }
    }
  }

  return 0;
}
Exemplo n.º 5
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("");
}
Exemplo n.º 6
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);
}