Blame src/updown.c

Packit 15a96c
/*
Packit 15a96c
 * updown.c	Routines to do up and downloading by calling external
Packit 15a96c
 *		programs (sz, rz, kermit).
Packit 15a96c
 *
Packit 15a96c
 *		This file is part of the minicom communications package,
Packit 15a96c
 *		Copyright 1991-1995 Miquel van Smoorenburg.
Packit 15a96c
 *
Packit 15a96c
 *		This program is free software; you can redistribute it and/or
Packit 15a96c
 *		modify it under the terms of the GNU General Public License
Packit 15a96c
 *		as published by the Free Software Foundation; either version
Packit 15a96c
 *		2 of the License, or (at your option) any later version.
Packit 15a96c
 *
Packit 15a96c
 *  You should have received a copy of the GNU General Public License along
Packit 15a96c
 *  with this program; if not, write to the Free Software Foundation, Inc.,
Packit 15a96c
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Packit 15a96c
 *
Packit 15a96c
 * jl 13.09.97	pass actual terminal lines (LINES - statusline)
Packit 15a96c
 *		to runscript in environment variable TERMLIN
Packit 15a96c
 * jl 16.09.97	logging of sz/rz file transfers
Packit 15a96c
 * jl 29.09.97	fix on the transfer logging
Packit 15a96c
 * hgk&jl 2.98	filename selection window
Packit 15a96c
 * acme 25.02.98 i18n
Packit 15a96c
 * js&jl 04.98	the better filename selection window
Packit 15a96c
 */
Packit 15a96c
Packit 15a96c
#include <poll.h>
Packit 15a96c
Packit 15a96c
#ifdef HAVE_CONFIG_H
Packit 15a96c
#include <config.h>
Packit 15a96c
#endif
Packit 15a96c
Packit 15a96c
#include <wchar.h>
Packit 15a96c
Packit 15a96c
#include "port.h"
Packit 15a96c
#include "minicom.h"
Packit 15a96c
#include "intl.h"
Packit 15a96c
Packit 15a96c
/*#define LOG_XFER	  debugging option to log all output of rz/sz
Packit 15a96c
 */
Packit 15a96c
static int udpid;
Packit 15a96c
static int script_running;
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Change to a directory.
Packit 15a96c
 */
Packit 15a96c
static int mcd(char *dir)
Packit 15a96c
{
Packit 15a96c
  char buf[256];
Packit 15a96c
  char err[50];
Packit 15a96c
  static char odir[256];
Packit 15a96c
  static int init = 0;
Packit 15a96c
Packit 15a96c
  if (!init) {
Packit 15a96c
    if (*dir == 0)
Packit 15a96c
      return 0;
Packit 15a96c
    init = 1;
Packit 15a96c
    if (getcwd(odir, sizeof(odir)) == NULL)
Packit 15a96c
      return -1;
Packit 15a96c
  }
Packit 15a96c
  if (*dir == 0) {
Packit 15a96c
    if (chdir(odir) == -1)
Packit 15a96c
      return -1;
Packit 15a96c
    return 0;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  if (*dir != '/') {
Packit 15a96c
    snprintf(buf, sizeof(buf), "%s/%s", homedir, dir);
Packit 15a96c
    dir = buf;
Packit 15a96c
  }
Packit 15a96c
  if (chdir(dir) < 0) {
Packit 15a96c
    /* This may look safe but you might I8N change the string! so
Packit 15a96c
       snprintf it */
Packit 15a96c
    snprintf(err, sizeof(err),  _("Cannot chdir to %.30s"), dir);
Packit 15a96c
    err[sizeof(err) - 1] = 0;
Packit 15a96c
    werror("%s", err);
Packit 15a96c
    return -1;
Packit 15a96c
  }
Packit 15a96c
  return 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Catch the CTRL-C signal.
Packit 15a96c
 */
Packit 15a96c
static void udcatch(int dummy)
Packit 15a96c
{
Packit 15a96c
  (void)dummy;
Packit 15a96c
  signal(SIGINT, udcatch);
Packit 15a96c
  if (udpid)
Packit 15a96c
    kill((pid_t)udpid, SIGKILL);
Packit 15a96c
  script_running = 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Translate %b to the current bps rate, and
Packit 15a96c
 *           %l to the current tty port.
Packit 15a96c
 *           %f to the serial port file descriptor
Packit 15a96c
 *
Packit 15a96c
 * Caller must free the returned string
Packit 15a96c
 */
Packit 15a96c
static char *translate(char *s)
Packit 15a96c
{
Packit 15a96c
  char * ptr;
Packit 15a96c
  char * translation;
Packit 15a96c
  size_t translation_length;
Packit 15a96c
  char   str_portfd[8];     /* kino */
Packit 15a96c
Packit 15a96c
  /* determine how many bytes we'll need for the translated version */
Packit 15a96c
  translation_length = 0;
Packit 15a96c
  for (ptr = s; *ptr != '\0'; ptr++) {
Packit 15a96c
    if (*ptr != '%') {
Packit 15a96c
      translation_length++;
Packit 15a96c
    }
Packit 15a96c
    else {
Packit 15a96c
      switch(*++ptr) {
Packit 15a96c
Packit 15a96c
        case 'l': /* tty port */
Packit 15a96c
          translation_length += strlen(dial_tty);
Packit 15a96c
          break;
Packit 15a96c
Packit 15a96c
        case 'b': /* baud rate (bbp) */
Packit 15a96c
          translation_length += strlen(P_BAUDRATE);
Packit 15a96c
          break;
Packit 15a96c
Packit 15a96c
        case 'f': /* serial port file descriptor */
Packit 15a96c
          sprintf(str_portfd, "%d", portfd);
Packit 15a96c
          translation_length += strlen(str_portfd);
Packit 15a96c
          break;
Packit 15a96c
Packit 15a96c
        default: /* treat all other escape sequences literally */
Packit 15a96c
          translation_length += 2;
Packit 15a96c
          break;
Packit 15a96c
      }
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  translation = malloc(translation_length + 1);
Packit 15a96c
  if (translation == NULL) {
Packit 15a96c
    do_log("out of memory");
Packit 15a96c
    return NULL;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* now copy and translate s into the allocated buffer */
Packit 15a96c
  for (ptr = translation; *s != '\0'; s++) {
Packit 15a96c
    if (*s != '%') {
Packit 15a96c
      *ptr++ = *s;
Packit 15a96c
      continue;
Packit 15a96c
    }
Packit 15a96c
    switch(*++s) {
Packit 15a96c
      case 'l': /* tty port */
Packit 15a96c
        strcpy(ptr, dial_tty);
Packit 15a96c
        ptr += strlen(dial_tty);
Packit 15a96c
        break;
Packit 15a96c
Packit 15a96c
      case 'b': /* baud rate (bbp) */
Packit 15a96c
        strcpy(ptr, P_BAUDRATE);
Packit 15a96c
        ptr += strlen(P_BAUDRATE);
Packit 15a96c
        break;
Packit 15a96c
Packit 15a96c
      case 'f': /* serial port file descriptor */
Packit 15a96c
        sprintf(str_portfd, "%d", portfd);
Packit 15a96c
        strcpy(ptr, str_portfd);
Packit 15a96c
        ptr += strlen(str_portfd);
Packit 15a96c
        break;
Packit 15a96c
Packit 15a96c
      default: /* treat all other escape sequences literally */
Packit 15a96c
        *ptr++ = '%';
Packit 15a96c
        *ptr++ = *s;
Packit 15a96c
        break;
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
  *ptr = '\0';
Packit 15a96c
Packit 15a96c
  return translation;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Trim the leading & trailing whitespaces from the string
Packit 15a96c
 * jl 15.09.97
Packit 15a96c
 */
Packit 15a96c
char *trim(char *outstring, char *instring, int n)
Packit 15a96c
{
Packit 15a96c
  char *p;
Packit 15a96c
  char *ip;
Packit 15a96c
  char *op;
Packit 15a96c
  char *np;
Packit 15a96c
Packit 15a96c
  ip = instring;
Packit 15a96c
  np = ip + n;
Packit 15a96c
  while ((*ip <= ' ') && (ip < np))
Packit 15a96c
    ip++;
Packit 15a96c
Packit 15a96c
  op = outstring;
Packit 15a96c
  np = op + n;
Packit 15a96c
  while ((*ip >= ' ') && (op <= np)) {
Packit 15a96c
    *op = *ip;
Packit 15a96c
    ip++;
Packit 15a96c
    op++;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  if (op < np)
Packit 15a96c
    *op = 0;
Packit 15a96c
Packit 15a96c
  while ((op > outstring) && (*op <= ' ')) {
Packit 15a96c
    *op = 0;
Packit 15a96c
    op--;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  p = outstring;
Packit 15a96c
  return p;
Packit 15a96c
}
Packit 15a96c
  
Packit 15a96c
/*
Packit 15a96c
 * Choose from numerous up and download protocols!
Packit 15a96c
 */
Packit 15a96c
Packit 15a96c
void updown(int what, int nr)
Packit 15a96c
{
Packit 15a96c
#ifdef LOG_XFER
Packit 15a96c
  #warning LOG_XFER defined!
Packit 15a96c
  FILE *xfl;
Packit 15a96c
#endif
Packit 15a96c
  const char *name[13];
Packit 15a96c
  int idx[13];
Packit 15a96c
  int r, f, g = 0;
Packit 15a96c
  char *t = what == 'U' ? _("Upload") : _("Download");
Packit 15a96c
  char buf[160];
Packit 15a96c
  char buffirst[20];
Packit 15a96c
  char xfrstr[160] = "";
Packit 15a96c
  char trimbuf[160] = "";
Packit 15a96c
  char title[64];
Packit 15a96c
  const char *s  ="";
Packit 15a96c
  int pipefd[2];
Packit 15a96c
  int n, status;
Packit 15a96c
  char * cmdline = NULL;
Packit 15a96c
  char * translated_cmdline = NULL;
Packit 15a96c
  WIN *win = (WIN *)NULL;
Packit 15a96c
Packit 15a96c
  if (mcd(what == 'U' ? P_UPDIR : P_DOWNDIR) < 0)
Packit 15a96c
    return;
Packit 15a96c
Packit 15a96c
  /* Automatic? */
Packit 15a96c
  if (nr == 0) {
Packit 15a96c
    for (f = 0; f < 12; f++) {
Packit 15a96c
      if (P_PNAME(f)[0] && P_PUD(f) == what) {
Packit 15a96c
        name[g] = P_PNAME(f);
Packit 15a96c
        idx[g++] = f;
Packit 15a96c
      }
Packit 15a96c
    }
Packit 15a96c
    name[g] = NULL;
Packit 15a96c
    if (g == 0)
Packit 15a96c
      return;
Packit 15a96c
Packit 15a96c
    r = mc_wselect(30, 7, name, NULL, t, stdattr, mfcolor, mbcolor) - 1;
Packit 15a96c
    if (r < 0)
Packit 15a96c
      return;
Packit 15a96c
Packit 15a96c
    g = idx[r];
Packit 15a96c
  } else
Packit 15a96c
    g = nr;
Packit 15a96c
Packit 15a96c
  buf[0] = 0;
Packit 15a96c
Packit 15a96c
/* jseymour file selector with choice of dir on zmodem, etc. download */
Packit 15a96c
#if 1
Packit 15a96c
  {
Packit 15a96c
    int multiple; /* 0:only directory, 1:one file, -1:any number */
Packit 15a96c
    size_t cmdline_length;
Packit 15a96c
Packit 15a96c
    if (P_MUL(g)=='Y')
Packit 15a96c
      /* need file(s), or just a directory? */
Packit 15a96c
      multiple = what == 'U'? -1 : 0;
Packit 15a96c
    else
Packit 15a96c
      multiple = 1;	/* only one allowed */
Packit 15a96c
Packit 15a96c
    if (P_FSELW[0] == 'Y' && (what == 'U' || P_ASKDNDIR[0] == 'Y')) {
Packit 15a96c
      s = filedir(multiple, what == 'U'? 0 : 1);
Packit 15a96c
      if (s == NULL)
Packit 15a96c
        return;
Packit 15a96c
    }
Packit 15a96c
    else if (P_PNN(g) == 'Y') {
Packit 15a96c
      s = input(_("Please enter file names"), buf);
Packit 15a96c
      if (s == NULL)
Packit 15a96c
        return;
Packit 15a96c
    }
Packit 15a96c
Packit 15a96c
    /* discard directory if "multiple" == 0 */
Packit 15a96c
    cmdline_length = strlen(P_PPROG(g)) + strlen((char*) (multiple == 0 ? "" : s)) + 1; /* + 1 for ' ' */
Packit 15a96c
    cmdline = malloc(cmdline_length + 1); /* + 1 for NUL */
Packit 15a96c
    if (cmdline == NULL) {
Packit 15a96c
      werror(_("Out of memory: could allocate buffer for command line"));
Packit 15a96c
      return;
Packit 15a96c
    }
Packit 15a96c
    snprintf(cmdline, cmdline_length + 1, "%s %s", P_PPROG(g), multiple == 0 ? "" : s);
Packit 15a96c
  }
Packit 15a96c
#endif
Packit 15a96c
Packit 15a96c
  if (P_LOGXFER[0] == 'Y')
Packit 15a96c
    do_log("%s", cmdline);   /* jl 22.06.97 */
Packit 15a96c
Packit 15a96c
  if (P_PFULL(g) == 'N') {
Packit 15a96c
    win = mc_wopen(10, 7, 70, 13, BSINGLE, stdattr, mfcolor, mbcolor, 1, 0, 1);
Packit 15a96c
    snprintf(title, sizeof(title), _("%.30s %s - Press CTRL-C to quit"), P_PNAME(g),
Packit 15a96c
             what == 'U' ? _("upload") : _("download"));
Packit 15a96c
    mc_wtitle(win, TMID, title);
Packit 15a96c
    if (pipe(pipefd) == -1)
Packit 15a96c
      werror("pipe() call failed");
Packit 15a96c
  } else
Packit 15a96c
    mc_wleave();
Packit 15a96c
Packit 15a96c
  m_flush(portfd);
Packit 15a96c
Packit 15a96c
  switch (udpid = fork()) {
Packit 15a96c
    case -1:
Packit 15a96c
      werror(_("Out of memory: could not fork()"));
Packit 15a96c
      if (win) {
Packit 15a96c
        close(pipefd[0]);
Packit 15a96c
        close(pipefd[1]);
Packit 15a96c
        mc_wclose(win, 1);
Packit 15a96c
      } else
Packit 15a96c
        mc_wreturn();
Packit 15a96c
      mcd("");
Packit 15a96c
      if(cmdline)
Packit 15a96c
        free(cmdline);
Packit 15a96c
      return;
Packit 15a96c
    case 0: /* Child */
Packit 15a96c
      if (P_PIORED(g) == 'Y') {
Packit 15a96c
        dup2(portfd, 0);
Packit 15a96c
        dup2(portfd, 1);
Packit 15a96c
      }
Packit 15a96c
      if (win) {
Packit 15a96c
        dup2(pipefd[1], 2);
Packit 15a96c
        close(pipefd[0]);
Packit 15a96c
        if (pipefd[1] != 2)
Packit 15a96c
          close(pipefd[1]);
Packit 15a96c
      }
Packit 15a96c
Packit 15a96c
      lockfile_remove();
Packit 15a96c
Packit 15a96c
      for (n = 1; n < _NSIG; n++)
Packit 15a96c
        signal(n, SIG_DFL);
Packit 15a96c
Packit 15a96c
      translated_cmdline = translate(cmdline);
Packit 15a96c
      if (translated_cmdline != NULL) {
Packit 15a96c
        fastexec(translated_cmdline);
Packit 15a96c
        free(translated_cmdline);
Packit 15a96c
      }
Packit 15a96c
      if(cmdline)
Packit 15a96c
        free(cmdline);
Packit 15a96c
      exit(1);
Packit 15a96c
    default: /* Parent */
Packit 15a96c
      break;
Packit 15a96c
  }
Packit 15a96c
 
Packit 15a96c
  if(cmdline)
Packit 15a96c
    free(cmdline);
Packit 15a96c
Packit 15a96c
  if (win) {
Packit 15a96c
    setcbreak(1);         /* Cbreak, no echo. */
Packit 15a96c
    enab_sig(1, 0);       /* But enable SIGINT */
Packit 15a96c
  }
Packit 15a96c
  signal(SIGINT, udcatch);
Packit 15a96c
  if (P_PIORED(g) == 'Y') {
Packit 15a96c
    close(pipefd[1]);
Packit 15a96c
#ifdef LOG_XFER
Packit 15a96c
    xfl=fopen("xfer.log","wb");
Packit 15a96c
#endif
Packit 15a96c
    while ((n = read(pipefd[0], buf, sizeof(buf))) > 0) {
Packit 15a96c
      buf[n] = '\0';
Packit 15a96c
      mc_wputs(win, buf);
Packit 15a96c
      timer_update();
Packit 15a96c
      /* Log the filenames & sizes 	jl 14.09.97 */
Packit 15a96c
      if (P_LOGXFER[0] == 'Y') {
Packit 15a96c
#ifdef LOG_XFER
Packit 15a96c
        if (xfl)
Packit 15a96c
          fprintf(xfl,">%s<\n",buf);
Packit 15a96c
#endif
Packit 15a96c
        if (sscanf(buf, "%19s", buffirst)) { /* if / jl 29.09.97 */
Packit 15a96c
          if (!strncmp (buffirst, "Receiving", 9) ||
Packit 15a96c
              !strncmp (buffirst, "Sending", 7)) {
Packit 15a96c
            if (xfrstr[0]) {
Packit 15a96c
              trim (trimbuf, xfrstr, sizeof(trimbuf));
Packit 15a96c
              do_log ("%s", trimbuf);
Packit 15a96c
              xfrstr[0] = 0;
Packit 15a96c
            }
Packit 15a96c
            trim (trimbuf, buf, sizeof(trimbuf));
Packit 15a96c
            do_log("%s", trimbuf);
Packit 15a96c
          } else if (!strncmp (buffirst, "Bytes", 5)) {
Packit 15a96c
            strncpy (xfrstr, buf, sizeof(xfrstr));
rpm-build c8e99c
            xfrstr[sizeof(xfrstr) - 1] = '\0';
Packit 15a96c
          }
Packit 15a96c
          buffirst[0] = 0;
Packit 15a96c
          trimbuf[0] = 0;
Packit 15a96c
        }
Packit 15a96c
      }
Packit 15a96c
    }
Packit 15a96c
#ifdef LOG_XFER
Packit 15a96c
    if (xfl)
Packit 15a96c
      fclose(xfl);
Packit 15a96c
#endif
Packit 15a96c
  }
Packit 15a96c
  /* Log the last file size	jl 14.09.97 */
Packit 15a96c
  if (P_LOGXFER[0] == 'Y' && xfrstr[0]) {
Packit 15a96c
    trim (trimbuf, xfrstr, sizeof(trimbuf));
Packit 15a96c
    do_log ("%s", trimbuf);
Packit 15a96c
    xfrstr[0] = 0;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  while (udpid != m_wait(&status));
Packit 15a96c
  if (win) {
Packit 15a96c
    enab_sig(0, 0);
Packit 15a96c
    signal(SIGINT, SIG_IGN);
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  if (win == (WIN *)0)
Packit 15a96c
    mc_wreturn();
Packit 15a96c
Packit 15a96c
  lockfile_create(0);
Packit 15a96c
Packit 15a96c
  /* MARK updated 02/17/94 - Flush modem port before displaying READY msg */
Packit 15a96c
  /* because a BBS often displays menu text right after a download, and we */
Packit 15a96c
  /* don't want the modem buffer to be lost while waiting for key to be hit */
Packit 15a96c
  m_flush(portfd);
Packit 15a96c
  port_init();
Packit 15a96c
  setcbreak(2); /* Raw, no echo. */
Packit 15a96c
  if (win)
Packit 15a96c
    close(pipefd[0]);
Packit 15a96c
  mcd("");
Packit 15a96c
  timer_update();
Packit 15a96c
Packit 15a96c
  /* If we got interrupted, status != 0 */
Packit 15a96c
  if (win && (status & 0xFF00) == 0) {
Packit 15a96c
#if VC_MUSIC
Packit 15a96c
    if (P_SOUND[0] == 'Y') {
Packit 15a96c
      mc_wprintf(win, _("\n READY: press any key to continue..."));
Packit 15a96c
      music();
Packit 15a96c
    } else
Packit 15a96c
      sleep(1);
Packit 15a96c
#else
Packit 15a96c
    /* MARK updated 02/17/94 - If there was no VC_MUSIC capability, */
Packit 15a96c
    /* then at least make some beeps! */
Packit 15a96c
    if (P_SOUND[0] == 'Y')
Packit 15a96c
      mc_wprintf(win, "\007\007\007");
Packit 15a96c
    sleep(1);
Packit 15a96c
#endif
Packit 15a96c
  }
Packit 15a96c
  if (win)
Packit 15a96c
    mc_wclose(win, 1);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
void lockfile_remove(void)
Packit 15a96c
{
Packit 15a96c
  if (portfd_is_socket)
Packit 15a96c
    return;
Packit 15a96c
Packit 15a96c
#if !HAVE_LOCKDEV
Packit 15a96c
  if (lockfile[0])
Packit 15a96c
    unlink(lockfile);
Packit 15a96c
#else
Packit 15a96c
  ttyunlock(dial_tty);
Packit 15a96c
#endif
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
int lockfile_create(int no_msgs)
Packit 15a96c
{
Packit 15a96c
  int n;
Packit 15a96c
Packit 15a96c
  if (portfd_is_socket)
Packit 15a96c
    return 0;
Packit 15a96c
Packit 15a96c
#if !HAVE_LOCKDEV
Packit 15a96c
  if (!lockfile[0])
Packit 15a96c
    return 0;
Packit 15a96c
Packit 15a96c
  int fd;
Packit 15a96c
  n = umask(022);
Packit 15a96c
  /* Create lockfile compatible with UUCP-1.2 */
Packit 15a96c
  if ((fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, 0666)) < 0) {
Packit 15a96c
    if (!no_msgs)
Packit 15a96c
      werror(_("Cannot create lockfile!"));
Packit 15a96c
  } else {
Packit 15a96c
    // FHS format:
Packit 15a96c
    char buf[12];
Packit 15a96c
    snprintf(buf, sizeof(buf),  "%10d\n", getpid());
Packit 15a96c
    buf[sizeof(buf) - 1] = 0;
Packit 15a96c
    if (write(fd, buf, strlen(buf)) < (ssize_t)strlen(buf))
Packit 15a96c
      if (!no_msgs)
Packit 15a96c
        fprintf(stderr, _("Failed to write lockfile %s\n"), lockfile);
Packit 15a96c
    close(fd);
Packit 15a96c
  }
Packit 15a96c
  umask(n);
Packit 15a96c
  return 0;
Packit 15a96c
#else
Packit 15a96c
  n = ttylock(dial_tty);
Packit 15a96c
  if (!no_msgs)
Packit 15a96c
    {
Packit 15a96c
      if (n < 0)
Packit 15a96c
        fprintf(stderr, _("Cannot create lockfile for %s: %s\n"), dial_tty, strerror(-n));
Packit 15a96c
      else if (n > 0)
Packit 15a96c
        fprintf(stderr, _("Device %s is locked.\n"), dial_tty);
Packit 15a96c
    }
Packit 15a96c
  return n;
Packit 15a96c
#endif
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Run kermit. Used to do this in the main window, but newer
Packit 15a96c
 * versions of kermit are too intelligent and just want a tty
Packit 15a96c
 * for themselves or they won't function ok. Shame.
Packit 15a96c
 */
Packit 15a96c
void kermit(void)
Packit 15a96c
{
Packit 15a96c
  int status, pid, n;
Packit 15a96c
  char * translated_cmdline;
Packit 15a96c
  char *kermit_path = P_KERMIT;
Packit 15a96c
Packit 15a96c
  if (!kermit_path || !*kermit_path) {
Packit 15a96c
    werror("No kermit path defined!");
Packit 15a96c
    return;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Clear screen, set keyboard modes etc. */
Packit 15a96c
  mc_wleave();
Packit 15a96c
Packit 15a96c
  switch (pid = fork()) {
Packit 15a96c
    case -1:
Packit 15a96c
      mc_wreturn();
Packit 15a96c
      werror(_("Out of memory: could not fork()"));
Packit 15a96c
      return;
Packit 15a96c
    case 0: /* Child */
Packit 15a96c
      close(portfd);
Packit 15a96c
Packit 15a96c
      /* Remove lockfile */
Packit 15a96c
      lockfile_remove();
Packit 15a96c
Packit 15a96c
      for (n = 0; n < _NSIG; n++)
Packit 15a96c
        signal(n, SIG_DFL);
Packit 15a96c
Packit 15a96c
      translated_cmdline = translate(P_KERMIT);
Packit 15a96c
      if (translated_cmdline != NULL) {
Packit 15a96c
        fastexec(translated_cmdline);
Packit 15a96c
        free(translated_cmdline);
Packit 15a96c
      }
Packit 15a96c
      exit(1);
Packit 15a96c
    default: /* Parent */
Packit 15a96c
      break;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  m_wait(&status);
Packit 15a96c
Packit 15a96c
  /* Restore screen and keyboard modes */
Packit 15a96c
  mc_wreturn();
Packit 15a96c
Packit 15a96c
  /* Re-create lockfile */
Packit 15a96c
  lockfile_create(0);
Packit 15a96c
Packit 15a96c
  m_flush(portfd);
Packit 15a96c
  port_init();
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/* ============ Here begins the setenv function ============= */
Packit 15a96c
/*
Packit 15a96c
 * Compare two strings up to '='
Packit 15a96c
 */
Packit 15a96c
static int varcmp(const char *s1, const char *s2)
Packit 15a96c
{
Packit 15a96c
  while (*s1 && *s2) {
Packit 15a96c
    if (*s1 == '=' && *s2 == '=')
Packit 15a96c
      return 1;
Packit 15a96c
    if (*s1++ != *s2++)
Packit 15a96c
      return 0;
Packit 15a96c
  }
Packit 15a96c
  return 1;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Generate a name=value string.
Packit 15a96c
 */
Packit 15a96c
static char *makenv(const char *name, const char *value)
Packit 15a96c
{
Packit 15a96c
  char *p;
Packit 15a96c
Packit 15a96c
  if ((p = malloc(strlen(name) + strlen(value) + 3)) == NULL)
Packit 15a96c
    return p;
Packit 15a96c
  sprintf(p, "%s=%s", name, value);
Packit 15a96c
  return p;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Set a environment variable.
Packit 15a96c
 */
Packit 15a96c
int mc_setenv(const char *name, const char *value)
Packit 15a96c
{
Packit 15a96c
  static int init = 0;
Packit 15a96c
  char *p, **e, **newe;
Packit 15a96c
  int count = 0;
Packit 15a96c
Packit 15a96c
  if ((p = makenv(name, value)) == NULL)
Packit 15a96c
    return -1;
Packit 15a96c
Packit 15a96c
  for (e = environ; *e; e++) {
Packit 15a96c
    count++;
Packit 15a96c
    if (varcmp(p, *e)) {
Packit 15a96c
      *e = p;
Packit 15a96c
      return 0;
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
  count += 2;
Packit 15a96c
  if ((newe = (char **)malloc(sizeof(char *) * count)) == (char **)0) {
Packit 15a96c
    free(p);
Packit 15a96c
    return -1;
Packit 15a96c
  }
Packit 15a96c
  memcpy((char *)newe, (char *)environ , (int) (count * sizeof(char *)));
Packit 15a96c
  if (init)
Packit 15a96c
    free((char *)environ);
Packit 15a96c
  init = 1;
Packit 15a96c
  environ = newe;
Packit 15a96c
  for(e = environ; *e; e++)
Packit 15a96c
    ;
Packit 15a96c
  *e++ = p;
Packit 15a96c
  *e = NULL;
Packit 15a96c
  return 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/* ============ This is the end of the setenv function ============= */
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Run an external script.
Packit 15a96c
 * ask = 1 if first ask for confirmation.
Packit 15a96c
 * s = scriptname, l=loginname, p=password.
Packit 15a96c
 */
Packit 15a96c
void runscript(int ask, const char *s, const char *l, const char *p)
Packit 15a96c
{
Packit 15a96c
  int status;
Packit 15a96c
  int n, i;
Packit 15a96c
  int pipefd[2];
Packit 15a96c
  char buf[81];
Packit 15a96c
  char scr_lines[5];
Packit 15a96c
  char cmdline[128];
Packit 15a96c
  struct pollfd fds[2];
Packit 15a96c
  char *translated_cmdline;
Packit 15a96c
  char *ptr;
Packit 15a96c
  WIN *w;
Packit 15a96c
  int done = 0;
Packit 15a96c
  char *msg = _("Same as last");
Packit 15a96c
  char *username = _(" A -   Username        :"),
Packit 15a96c
       *password = _(" B -   Password        :"),
Packit 15a96c
       *name_of_script = _(" C -   Name of script  :"),
Packit 15a96c
       *question = _("Change which setting?     (Return to run, ESC to stop)");
Packit 15a96c
Packit 15a96c
Packit 15a96c
  if (ask) {
Packit 15a96c
    w = mc_wopen(10, 5, 70, 10, BDOUBLE, stdattr, mfcolor, mbcolor, 0, 0, 1);
Packit 15a96c
    mc_wtitle(w, TMID, _("Run a script"));
Packit 15a96c
    mc_wputs(w, "\n");
Packit 15a96c
    mc_wprintf(w, "%s %s\n", username, scr_user[0] ? msg : "");
Packit 15a96c
    mc_wprintf(w, "%s %s\n", password, scr_passwd[0] ? msg : "");
Packit 15a96c
    mc_wprintf(w, "%s %s\n", name_of_script, scr_name);
Packit 15a96c
    mc_wlocate(w, 4, 5);
Packit 15a96c
    mc_wputs(w, question);
Packit 15a96c
    mc_wredraw(w, 1);
Packit 15a96c
Packit 15a96c
    while (!done) {
Packit 15a96c
      mc_wlocate(w, mbslen (question) + 5, 5);
Packit 15a96c
      n = wxgetch();
Packit 15a96c
      if (islower(n))
Packit 15a96c
        n = toupper(n);
Packit 15a96c
      switch (n) {
Packit 15a96c
        case '\r':
Packit 15a96c
        case '\n':
Packit 15a96c
          if (scr_name[0] == '\0') {
Packit 15a96c
            mc_wbell();
Packit 15a96c
            break;
Packit 15a96c
          }
Packit 15a96c
          mc_wclose(w, 1);
Packit 15a96c
          done = 1;
Packit 15a96c
          break;
Packit 15a96c
        case 27: /* ESC */
Packit 15a96c
          mc_wclose(w, 1);
Packit 15a96c
          return;
Packit 15a96c
        case 'A':
Packit 15a96c
          mc_wlocate(w, mbslen (username) + 1, 1);
Packit 15a96c
          mc_wclreol(w);
Packit 15a96c
          scr_user[0] = 0;
Packit 15a96c
          mc_wgets(w, scr_user, 32, 32);
Packit 15a96c
          break;
Packit 15a96c
        case 'B':
Packit 15a96c
          mc_wlocate(w, mbslen (password) + 1, 2);
Packit 15a96c
          mc_wclreol(w);
Packit 15a96c
          scr_passwd[0] = 0;
Packit 15a96c
          mc_wgets(w, scr_passwd, 32, 32);
Packit 15a96c
          break;
Packit 15a96c
        case 'C':
Packit 15a96c
          mc_wlocate(w, mbslen (name_of_script) + 1, 3);
Packit 15a96c
          mc_wgets(w, scr_name, 32, sizeof(scr_name) - 1);
Packit 15a96c
          break;
Packit 15a96c
        default:
Packit 15a96c
          break;
Packit 15a96c
      }
Packit 15a96c
    }
Packit 15a96c
  } else {
Packit 15a96c
    strncpy(scr_user, l, sizeof(scr_user));
rpm-build c8e99c
    scr_user[sizeof(scr_user) - 1] = '\0';
Packit 15a96c
    strncpy(scr_name, s, sizeof(scr_name));
rpm-build c8e99c
    scr_name[sizeof(scr_name) - 1] = '\0';
Packit 15a96c
    strncpy(scr_passwd, p, sizeof(scr_passwd));
rpm-build c8e99c
    scr_passwd[sizeof(scr_passwd) - 1] = '\0';
Packit 15a96c
  }
Packit 15a96c
  sprintf(scr_lines, "%d", (int) lines);  /* jl 13.09.97 */
Packit 15a96c
Packit 15a96c
  /* Throw away status line if temporary */
Packit 15a96c
  if (tempst) {
Packit 15a96c
    mc_wclose(st, 1);
Packit 15a96c
    tempst = 0;
Packit 15a96c
    st = NULL;
Packit 15a96c
  }
Packit 15a96c
  scriptname(scr_name);
Packit 15a96c
Packit 15a96c
  if (pipe(pipefd) < 0)
Packit 15a96c
    return;
Packit 15a96c
Packit 15a96c
  if (mcd(P_SCRIPTDIR) < 0)
Packit 15a96c
    return;
Packit 15a96c
Packit 15a96c
  snprintf(cmdline, sizeof(cmdline), "%s %s %s %s",
Packit 15a96c
           P_SCRIPTPROG, scr_name, logfname, logfname[0]==0? "": homedir);
Packit 15a96c
Packit 15a96c
  switch (udpid = fork()) {
Packit 15a96c
    case -1:
Packit 15a96c
      werror(_("Out of memory: could not fork()"));
Packit 15a96c
      close(pipefd[0]);
Packit 15a96c
      close(pipefd[1]);
Packit 15a96c
      mcd("");
Packit 15a96c
      return;
Packit 15a96c
    case 0: /* Child */
Packit 15a96c
      dup2(portfd, 0);
Packit 15a96c
      dup2(portfd, 1);
Packit 15a96c
      dup2(pipefd[1], 2);
Packit 15a96c
      close(pipefd[0]);
Packit 15a96c
      close(pipefd[1]);
Packit 15a96c
Packit 15a96c
      for (n = 1; n < _NSIG; n++)
Packit 15a96c
	signal(n, SIG_DFL);
Packit 15a96c
Packit 15a96c
      mc_setenv("LOGIN", scr_user);
Packit 15a96c
      mc_setenv("PASS", scr_passwd);
Packit 15a96c
      mc_setenv("TERMLIN", scr_lines);	/* jl 13.09.97 */
Packit 15a96c
      translated_cmdline = translate(cmdline);
Packit 15a96c
Packit 15a96c
      if (translated_cmdline != NULL) {
Packit 15a96c
        fastexec(translated_cmdline);
Packit 15a96c
        free(translated_cmdline);
Packit 15a96c
      }
Packit 15a96c
      exit(1);
Packit 15a96c
    default: /* Parent */
Packit 15a96c
      break;
Packit 15a96c
  }
Packit 15a96c
  setcbreak(1); /* Cbreak, no echo */
Packit 15a96c
  enab_sig(1, 0);	       /* But enable SIGINT */
Packit 15a96c
  signal(SIGINT, udcatch);
Packit 15a96c
  close(pipefd[1]);
Packit 15a96c
Packit 15a96c
  /* pipe output from "runscript" program to terminal emulator */
Packit 15a96c
  fds[0].fd     = pipefd[0]; /* runscript */
Packit 15a96c
  fds[0].events = POLLIN;
Packit 15a96c
  fds[1].fd     = STDIN_FILENO; /* stdin */
Packit 15a96c
  fds[1].events = POLLIN;
Packit 15a96c
  script_running = 1;
Packit 15a96c
  while (script_running && poll(fds, 2, -1) > 0)
Packit 15a96c
    for (i = 0; i < 2; i++) {
Packit 15a96c
      if (fds[i].revents & (POLLERR | POLLHUP | POLLNVAL))
Packit 15a96c
        script_running = 0;
Packit 15a96c
      else if ((fds[i].revents & POLLIN)
Packit 15a96c
               && (n = read(fds[i].fd, buf, sizeof(buf)-1)) > 0) {
Packit 15a96c
        ptr = buf;
Packit 15a96c
        while (n--)
Packit 15a96c
          if (i)
Packit 15a96c
            vt_send(*ptr++);
Packit 15a96c
          else
Packit 15a96c
            vt_out(*ptr++);
Packit 15a96c
        timer_update();
Packit 15a96c
        mc_wflush();
Packit 15a96c
      }
Packit 15a96c
    }
Packit 15a96c
Packit 15a96c
  /* Collect status, and clean up. */
Packit 15a96c
  m_wait(&status);
Packit 15a96c
  enab_sig(0, 0);
Packit 15a96c
  signal(SIGINT, SIG_IGN);
Packit 15a96c
  setcbreak(2); /* Raw, no echo */
Packit 15a96c
  close(pipefd[0]);
Packit 15a96c
  scriptname("");
Packit 15a96c
  mcd("");
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
* Paste text file to console/serial line. Avoid ascii-xfer problem of 
Packit 15a96c
* swallowing up status messages returned via the serial line.
Packit 15a96c
* This is especially useful for Embedded Microprocessor Development Kits
Packit 15a96c
* that use raw file transfer mode (no protocols) to download text encoded
Packit 15a96c
* executable files (eg., in S-Record or Intel Hex formats)
Packit 15a96c
*
Packit 15a96c
* TC Wan <tcwan@cs.usm.my> 2003-10-18
Packit 15a96c
*/
Packit 15a96c
int paste_file(void)
Packit 15a96c
{
Packit 15a96c
  FILE *fp;
Packit 15a96c
  char line[1024];
Packit 15a96c
  char *s;
Packit 15a96c
  const int dotrans = 0;
Packit 15a96c
  const int ldelay = 1;      /* hardcoded 1 ms */
Packit 15a96c
  char buf[128] = "";
Packit 15a96c
  char *ptr;
Packit 15a96c
  int bytes_read;
Packit 15a96c
  unsigned long bdone = 0;
Packit 15a96c
  int x;
Packit 15a96c
Packit 15a96c
  if ((s = filedir(1, 0)) == NULL)
Packit 15a96c
    return 0;
Packit 15a96c
  if ((fp = fopen(s, "r")) == NULL) {
Packit 15a96c
    perror(s);
Packit 15a96c
    return -1;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  while (fgets(line, sizeof(line), fp)) {
Packit 15a96c
    /* Check for I/O or timer. */
Packit 15a96c
    x = check_io(portfd_connected, 0, 1000, buf, sizeof(buf), &bytes_read);
Packit 15a96c
Packit 15a96c
    /*  Send data from the modem to the screen. */
Packit 15a96c
    if ((x & 1)) {
Packit 15a96c
      ptr = buf;
Packit 15a96c
      while (bytes_read-- > 0) {
Packit 15a96c
	if (P_PARITY[0] == 'M' || P_PARITY[0] == 'S')
Packit 15a96c
	  *ptr &= 0x7f;
Packit 15a96c
	vt_out(*ptr++);
Packit 15a96c
      }
Packit 15a96c
      mc_wflush();
Packit 15a96c
    }
Packit 15a96c
Packit 15a96c
    if (dotrans && (s = strrchr(line, '\n')) != NULL) {
Packit 15a96c
      if (s > line && *(s - 1) == '\r')
Packit 15a96c
	s--;
Packit 15a96c
      *s = 0;
Packit 15a96c
      s = line;
Packit 15a96c
      for (s = line; *s; s++)
Packit 15a96c
	vt_send(*s);
Packit 15a96c
      vt_send('\r');
Packit 15a96c
      vt_send('\n');
Packit 15a96c
      bdone += strlen(line) + 2;
Packit 15a96c
    } else {
Packit 15a96c
      for (s = line; *s; s++)
Packit 15a96c
	vt_send(*s);
Packit 15a96c
      bdone += strlen(s);
Packit 15a96c
    }
Packit 15a96c
    if (ldelay) {
Packit 15a96c
#ifdef HAVE_USLEEP
Packit 15a96c
      usleep(ldelay * 1000);
Packit 15a96c
#endif
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
  fclose(fp);
Packit 15a96c
  return 0;
Packit 15a96c
}