Blame src/dial.c

Packit 15a96c
/*
Packit 15a96c
 * dial.c	Functions to dial, retry etc. Als contains the dialing
Packit 15a96c
 *		directory code, _and_ the famous tu-di-di music.
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 22.06.97  Logging connects and disconnects.
Packit 15a96c
 *   jl 23.06.97  Adjustable DTR droptime
Packit 15a96c
 *   jl 21.09.97  Conversion table filenames in dialdir
Packit 15a96c
 *   jl 05.10.97  Line speed changed to long in dial()
Packit 15a96c
 *   jl 26.01.98  last login date & time added to dialing window
Packit 15a96c
 *   jl 16.04.98  start searching for dialing tags from the highlighted entry
Packit 15a96c
 *   jl 12.06.98  save the old dialdir if it was an old version
Packit 15a96c
 *   er 18-Apr-99 When calling a multiline BBS
Packit 15a96c
 *		  tagged entries with same name are untagged
Packit 15a96c
 *   jl 01.09.99  Move entry up/down in directory
Packit 15a96c
 *   jl 10.02.2000 Stopbits field added
Packit 15a96c
 */
Packit 15a96c
#ifdef HAVE_CONFIG_H
Packit 15a96c
#include <config.h>
Packit 15a96c
#endif
Packit 15a96c
Packit 15a96c
#include <stdint.h>
Packit 15a96c
#include <limits.h>
Packit 15a96c
#include <arpa/inet.h>
Packit 15a96c
Packit 15a96c
#include "port.h"
Packit 15a96c
#include "minicom.h"
Packit 15a96c
#include "intl.h"
Packit 15a96c
Packit 15a96c
#ifdef VC_MUSIC
Packit 15a96c
#  if defined(__GLIBC__)
Packit 15a96c
#    include <sys/ioctl.h>
Packit 15a96c
#    include <sys/kd.h>
Packit 15a96c
#    include <sys/time.h>
Packit 15a96c
#  endif
Packit 15a96c
#endif
Packit 15a96c
Packit 15a96c
enum { CURRENT_VERSION = 6 };
Packit 15a96c
Packit 15a96c
/* Dialing directory. */
Packit 15a96c
struct v1_dialent {
Packit 15a96c
  char name[32];
Packit 15a96c
  char number[16];
Packit 15a96c
  char script[16];
Packit 15a96c
  char username[32];
Packit 15a96c
  char password[32];
Packit 15a96c
  char term;
Packit 15a96c
  char baud[8];
Packit 15a96c
  char parity[2];
Packit 15a96c
  char dialtype;
Packit 15a96c
  char flags; /* Localecho in v0 */
Packit 15a96c
  char bits[2];
Packit 15a96c
  struct dialent *next;
Packit 15a96c
};
Packit 15a96c
Packit 15a96c
struct v3_dialent {
Packit 15a96c
  char name[32];
Packit 15a96c
  char number[32];
Packit 15a96c
  char script[32];
Packit 15a96c
  char username[32];
Packit 15a96c
  char password[32];
Packit 15a96c
  char term;
Packit 15a96c
  char baud[8];
Packit 15a96c
  char parity[2];
Packit 15a96c
  char dialtype;
Packit 15a96c
  char flags;
Packit 15a96c
  char bits[2];
Packit 15a96c
  struct dialent *next;
Packit 15a96c
};
Packit 15a96c
Packit 15a96c
struct v4_dialent {
Packit 15a96c
  char name[32];
Packit 15a96c
  char number[32];
Packit 15a96c
  char script[32];
Packit 15a96c
  char username[32];
Packit 15a96c
  char password[32];
Packit 15a96c
  char term;
Packit 15a96c
  char baud[8];
Packit 15a96c
  char parity[2];
Packit 15a96c
  char dialtype;
Packit 15a96c
  char flags;
Packit 15a96c
  char bits[2];
Packit 15a96c
  char lastdate[9];	/* jl 22.06.97 */
Packit 15a96c
  char lasttime[9];	/* jl 22.06.97 */
Packit 15a96c
  int  count;		/* jl 22.06.97 */
Packit 15a96c
  char convfile[16];	/* jl 21.09.97 */
Packit 15a96c
  char stopb[2];	/* jl 10.02.2000 */
Packit 15a96c
  struct dialent *next;
Packit 15a96c
};
Packit 15a96c
Packit 15a96c
/* v5 is a packed version of v4 so that there's no difference between 32 and
Packit 15a96c
 * 64 bit versions as well as LE and BE.
Packit 15a96c
 */
Packit 15a96c
struct dialent {
Packit 15a96c
  char     name[32];
Packit 15a96c
  char     number[32];
Packit 15a96c
  char     script[32];
Packit 15a96c
  char     username[32];
Packit 15a96c
  char     password[32];
Packit 15a96c
  char     term;
Packit 15a96c
  char     baud[8];
Packit 15a96c
  char     parity[2];
Packit 15a96c
  char     dialtype;
Packit 15a96c
  char     flags;
Packit 15a96c
  char     bits[2];
Packit 15a96c
  char     lastdate[9];
Packit 15a96c
  char     lasttime[9];
Packit 15a96c
  uint32_t count;
Packit 15a96c
  char     convfile[16];
Packit 15a96c
  char     stopb[2];
Packit 15a96c
  struct dialent *next;
Packit 15a96c
} __attribute__((packed));
Packit 15a96c
Packit 15a96c
/* Version info. */
Packit 15a96c
#define DIALMAGIC 0x55AA
Packit 15a96c
struct dver {
Packit 15a96c
  short magic;
Packit 15a96c
  short version;
Packit 15a96c
  unsigned short size;
Packit 15a96c
  short res1;
Packit 15a96c
  short res2;
Packit 15a96c
  short res3;
Packit 15a96c
  short res4;
Packit 15a96c
} __attribute__((packed));
Packit 15a96c
Packit 15a96c
/* Forward declaration */
Packit 15a96c
static void writedialdir(void);
Packit 15a96c
Packit 15a96c
#define dialentno(di, no) ((struct dialent *)((char *)(di) + ((no) * sizeof(struct dialent))))  
Packit 15a96c
Packit 15a96c
static struct dialent *dialents;
Packit 15a96c
static struct dialent *d_man;
Packit 15a96c
static int nrents = 1;
Packit 15a96c
static int newtype;
Packit 15a96c
/* Access to ".dialdir" denied? */
Packit 15a96c
static int dendd = 0;
Packit 15a96c
static char *tagged;
Packit 15a96c
char *dial_user;
Packit 15a96c
char *dial_pass;
Packit 15a96c
Packit 15a96c
/* Change the baud rate.  Treat all characters in the given array as if
Packit 15a96c
 * they were key presses within the comm parameters dialog (C-A P) and
Packit 15a96c
 * change the line speed accordingly.  Terminate when a space or other
Packit 15a96c
 * unrecognised character is found.
Packit 15a96c
 */
Packit 15a96c
const char* change_baud(const char *s)
Packit 15a96c
{
Packit 15a96c
  while (s && *s
Packit 15a96c
         && update_bbp_from_char(*s, P_BAUDRATE, P_BITS, P_PARITY, P_STOPB, 0))
Packit 15a96c
    ++s;
Packit 15a96c
Packit 15a96c
  // reinitialise the port and update the status line
Packit 15a96c
  if (portfd >= 0)
Packit 15a96c
    port_init();
Packit 15a96c
  show_status();
Packit 15a96c
Packit 15a96c
  return s;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Functions to talk to the modem.
Packit 15a96c
 */
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Send a string to the modem.
Packit 15a96c
 * If how == 0, '~'  sleeps 1 second.
Packit 15a96c
 * If how == 1, "^~" sleeps 1 second.
Packit 15a96c
 */
Packit 15a96c
void mputs(const char *s, int how)
Packit 15a96c
{
Packit 15a96c
  char c;
Packit 15a96c
Packit 15a96c
  while (*s) {
Packit 15a96c
    if (*s == '^' && (*(s + 1))) {
Packit 15a96c
      s++;
Packit 15a96c
      if (*s == '^')
Packit 15a96c
        c = *s;
Packit 15a96c
      else if (how == 1 && *s == '~') {
Packit 15a96c
        sleep(1);
Packit 15a96c
        s++;
Packit 15a96c
        continue;
Packit 15a96c
      } else
Packit 15a96c
        c = (*s) & 31;
Packit 15a96c
    } else if (*s == '\\' && (*(s + 1))) {
Packit 15a96c
      s++;
Packit 15a96c
      switch (toupper (*s)) {
Packit 15a96c
        case '\\':
Packit 15a96c
          c = *s;
Packit 15a96c
          break;
Packit 15a96c
        case 'U':
Packit 15a96c
          if (dial_user && *dial_user)
Packit 15a96c
            mputs (dial_user, how);
Packit 15a96c
          s++;
Packit 15a96c
          continue;
Packit 15a96c
        case 'P':
Packit 15a96c
          if (dial_pass && *dial_pass)
Packit 15a96c
            mputs (dial_pass, how);
Packit 15a96c
          s++;
Packit 15a96c
          continue;
Packit 15a96c
        case 'B': /* line speed change. */
Packit 15a96c
          s = change_baud(++s);
Packit 15a96c
          continue;
Packit 15a96c
        case 'L': /* toggle linefeed addition */
Packit 15a96c
          toggle_addlf();
Packit 15a96c
          s++; /* nothing to do with the modem, move along */
Packit 15a96c
          continue;
Packit 15a96c
        case 'E': /* toggle local echo */
Packit 15a96c
          toggle_local_echo();
Packit 15a96c
          s++; /* again, move along. */
Packit 15a96c
          continue;
Packit 15a96c
	case 'G': /* run a script */
Packit 15a96c
	  runscript(0, s + 1, "", "");
Packit 15a96c
	  return;
Packit 15a96c
        default:
Packit 15a96c
          s++;
Packit 15a96c
          continue;
Packit 15a96c
      }
Packit 15a96c
    } else
Packit 15a96c
      c = *s;
Packit 15a96c
    if (how == 0 && c == '~')
Packit 15a96c
      sleep(1);
Packit 15a96c
    else
Packit 15a96c
      if (write(portfd, &c, 1) != 1)
Packit 15a96c
        break;
Packit 15a96c
    s++;
Packit 15a96c
  }
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Initialize the modem.
Packit 15a96c
 */
Packit 15a96c
void modeminit(void)
Packit 15a96c
{
Packit 15a96c
  WIN *w;
Packit 15a96c
Packit 15a96c
  if (P_MINIT[0] == '\0')
Packit 15a96c
    return;
Packit 15a96c
Packit 15a96c
  w = mc_tell(_("Initializing Modem"));
Packit 15a96c
  m_dtrtoggle(portfd, 1);         /* jl 23.06.97 */
Packit 15a96c
  mputs(P_MINIT, 0);
Packit 15a96c
  mc_wclose(w, 1);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Reset the modem.
Packit 15a96c
 */
Packit 15a96c
void modemreset(void)
Packit 15a96c
{
Packit 15a96c
  WIN *w;
Packit 15a96c
Packit 15a96c
  if (P_MRESET[0] == '\0')
Packit 15a96c
    return;
Packit 15a96c
Packit 15a96c
  w = mc_tell(_("Resetting Modem"));
Packit 15a96c
  mputs(P_MRESET, 0);
Packit 15a96c
  sleep(1);
Packit 15a96c
  mc_wclose(w, 1);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Hang the line up.
Packit 15a96c
 */
Packit 15a96c
void hangup(void)
Packit 15a96c
{
Packit 15a96c
  WIN *w;
Packit 15a96c
  int sec=1;
Packit 15a96c
Packit 15a96c
  w = mc_tell(_("Hanging up"));
Packit 15a96c
Packit 15a96c
  timer_update();
Packit 15a96c
  if (P_LOGCONN[0] == 'Y')
Packit 15a96c
    do_log(_("Hangup (%ld:%02ld:%02ld)"),
Packit 15a96c
           online / 3600, (online / 60) % 60, online>0 ? online % 60 : 0);
Packit 15a96c
  online = -1;
Packit 15a96c
  old_online = -1;
Packit 15a96c
Packit 15a96c
  if (isdigit(P_MDROPDTR[0]))
Packit 15a96c
    sscanf(P_MDROPDTR,"%2d",&sec);
Packit 15a96c
Packit 15a96c
  if (P_MDROPDTR[0] == 'Y' || (isdigit(P_MDROPDTR[0]) && sec>0)) {
Packit 15a96c
    m_dtrtoggle(portfd, sec);   /* jl 23.06.97 */
Packit 15a96c
  } else {
Packit 15a96c
    mputs(P_MHANGUP, 0);
Packit 15a96c
    sleep(1);
Packit 15a96c
  }
Packit 15a96c
#ifdef _DCDFLOW
Packit 15a96c
  /* DCD has dropped, turn off hw flow control. */
Packit 15a96c
  m_sethwf(portfd, 0);
Packit 15a96c
#endif
Packit 15a96c
  /* If we don't have DCD support fake DCD dropped */
Packit 15a96c
  bogus_dcd = 0;
Packit 15a96c
  mc_wclose(w, 1);
Packit 15a96c
  show_status();
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * This seemed to fit best in this file
Packit 15a96c
 * Send a break signal.
Packit 15a96c
 */
Packit 15a96c
void sendbreak()
Packit 15a96c
{
Packit 15a96c
  WIN *w;
Packit 15a96c
Packit 15a96c
  w = mc_tell(_("Sending BREAK"));
Packit 15a96c
  mc_wcursor(w, CNONE);
Packit 15a96c
Packit 15a96c
  m_break(portfd);
Packit 15a96c
  mc_wclose(w, 1);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
WIN *dialwin;
Packit 15a96c
int dialtime;
Packit 15a96c
Packit 15a96c
#ifdef VC_MUSIC
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Play music until key is pressed.
Packit 15a96c
 */
Packit 15a96c
void music(void)
Packit 15a96c
{
Packit 15a96c
  int x, i, k;
Packit 15a96c
  int consolefd = 0;
Packit 15a96c
  char *disp;
Packit 15a96c
Packit 15a96c
  /* If we're in X, we have to explicitly use the console */
Packit 15a96c
  if (strncmp(getenv("TERM"), "xterm", 5) == 0 &&
Packit 15a96c
      (disp = getenv("DISPLAY")) != NULL &&
Packit 15a96c
      (strcmp(disp, ":0.0") == 0 ||
Packit 15a96c
       (strcmp(disp, ":0") == 0))) {
Packit 15a96c
    consolefd = open("/dev/console", O_WRONLY);
Packit 15a96c
    if (consolefd < 0) consolefd = 0;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Tell keyboard handler what we want. */
Packit 15a96c
  keyboard(KSIGIO, 0);
Packit 15a96c
Packit 15a96c
  /* And loop forever :-) */
Packit 15a96c
  for(i = 0; i < 9; i++) {
Packit 15a96c
    k = 2000 - 200 * (i % 3);
Packit 15a96c
    ioctl(consolefd, KIOCSOUND, k);
Packit 15a96c
Packit 15a96c
    /* Check keypress with timeout 160 ms */
Packit 15a96c
    x = check_io(-1, 0, 160, NULL, 0, NULL);
Packit 15a96c
    if (x & 2)
Packit 15a96c
      break;
Packit 15a96c
  }
Packit 15a96c
  ioctl(consolefd, KIOCSOUND, 0);
Packit 15a96c
  if (consolefd)
Packit 15a96c
    close(consolefd);
Packit 15a96c
Packit 15a96c
  /* Wait for keypress and absorb it */
Packit 15a96c
  while ((x & 2) == 0) {
Packit 15a96c
    x = check_io(-1, 0, 10000, NULL, 0, NULL);
Packit 15a96c
    timer_update();
Packit 15a96c
  }
Packit 15a96c
  keyboard(KGETKEY, 0);
Packit 15a96c
}
Packit 15a96c
#endif
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * The dial has failed. Tell user.
Packit 15a96c
 * Count down until retrytime and return.
Packit 15a96c
 */
Packit 15a96c
static int dialfailed(char *s, int rtime)
Packit 15a96c
{
Packit 15a96c
  int f, x;
Packit 15a96c
  int ret = 0;
Packit 15a96c
Packit 15a96c
  mc_wlocate(dialwin, 1, 5);
Packit 15a96c
  mc_wprintf(dialwin, _("    No connection: %s.      \n"), s);
Packit 15a96c
  if (rtime < 0) {
Packit 15a96c
    mc_wprintf(dialwin, _("   Press any key to continue..    "));
Packit 15a96c
    if (check_io(-1, 0, 10000, NULL, 0, NULL) & 2)
Packit 15a96c
      keyboard(KGETKEY, 0);
Packit 15a96c
    return 0;
Packit 15a96c
  }
Packit 15a96c
  mc_wprintf(dialwin, _("     Retry in %2d seconds             "), rtime);
Packit 15a96c
Packit 15a96c
  for (f = rtime - 1; f >= 0; f--) {
Packit 15a96c
    x = check_io(-1, 0, 1000, NULL, 0, NULL);
Packit 15a96c
    if (x & 2) {
Packit 15a96c
      /* Key pressed - absorb it. */
Packit 15a96c
      x = keyboard(KGETKEY, 0);
Packit 15a96c
      if (x != ' ')
Packit 15a96c
        ret = -1;
Packit 15a96c
      break;
Packit 15a96c
    }
Packit 15a96c
    mc_wlocate(dialwin, 0, 6);
Packit 15a96c
    mc_wprintf(dialwin, _("     Retry in %2d seconds             "), f);
Packit 15a96c
  }
Packit 15a96c
#ifdef HAVE_USLEEP
Packit 15a96c
  /* MARK updated 02/17/94 - Min dial delay set to 0.35 sec instead of 1 sec */
Packit 15a96c
  if (f < 0) /* Allow modem time to hangup if redial time == 0 */
Packit 15a96c
    usleep(350000);
Packit 15a96c
#else
Packit 15a96c
  if (f < 0)
Packit 15a96c
    sleep(1);
Packit 15a96c
#endif
Packit 15a96c
  mc_wlocate(dialwin, 1, 5);
Packit 15a96c
  mc_wprintf(dialwin, "                                       \n");
Packit 15a96c
  mc_wprintf(dialwin, "                                             ");
Packit 15a96c
  return ret;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Dial a number, and display the name.
Packit 15a96c
 */
Packit 15a96c
long dial(struct dialent *d, struct dialent **d2)
Packit 15a96c
{
Packit 15a96c
  char *s = 0, *t = 0;
Packit 15a96c
  int f, x = 0;
Packit 15a96c
  int modidx, retries = 0;
Packit 15a96c
  int maxretries = 1, rdelay = 45;
Packit 15a96c
  long nb, retst = -1;
Packit 15a96c
  char *reason = _("Max retries");
Packit 15a96c
  time_t now, last;
Packit 15a96c
  struct tm *ptime;
Packit 15a96c
  char buf[128];
Packit 15a96c
  char modbuf[128];
Packit 15a96c
  /*  char logline[128]; */
Packit 15a96c
Packit 15a96c
  timer_update(); /* Statusline may still show 'Online' / jl 16.08.97 */
Packit 15a96c
  /* don't do anything if already online! jl 07.07.98 */
Packit 15a96c
  if (P_HASDCD[0]=='Y' && online >= 0) {
Packit 15a96c
    werror(_("You are already online! Hang up first."));
Packit 15a96c
    return(retst);
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  dialwin = mc_wopen(18, 9, 62, 16, BSINGLE, stdattr, mfcolor, mbcolor, 0, 0, 1);
Packit 15a96c
  mc_wtitle(dialwin, TMID, _("Autodial"));
Packit 15a96c
  mc_wcursor(dialwin, CNONE);
Packit 15a96c
Packit 15a96c
  mc_wputs(dialwin, "\n");
Packit 15a96c
  mc_wprintf(dialwin, " %s : %s\n", _("Dialing"), d->name);
Packit 15a96c
  mc_wprintf(dialwin, _("      At : %s"), d->number);
Packit 15a96c
  mc_wprintf(dialwin, "\n"); /* help translators */
Packit 15a96c
  if (d->lastdate[0] && d->lasttime[0])		/* jl 26.01.98 */
Packit 15a96c
    mc_wprintf(dialwin, _(" Last on : %s at %s"), d->lastdate, d->lasttime);
Packit 15a96c
  mc_wprintf(dialwin, "\n");
Packit 15a96c
  mc_wredraw(dialwin, 1);
Packit 15a96c
Packit 15a96c
  /* Tell keyboard routines we need them. */
Packit 15a96c
  keyboard(KSIGIO, 0);
Packit 15a96c
Packit 15a96c
  maxretries = atoi(P_MRETRIES);
Packit 15a96c
  if (maxretries <= 0)
Packit 15a96c
    maxretries = 1;
Packit 15a96c
  rdelay = atoi(P_MRDELAY);
Packit 15a96c
  if (rdelay < 0)
Packit 15a96c
    rdelay = 0;
Packit 15a96c
Packit 15a96c
  /* Main retry loop of dial() */
Packit 15a96c
MainLoop:
Packit 15a96c
  while (++retries <= maxretries) {
Packit 15a96c
Packit 15a96c
    /* See if we need to try the next tagged entry. */
Packit 15a96c
    if (retries > 1 && (d->flags & FL_TAG)) {
Packit 15a96c
      do {
Packit 15a96c
        d = d->next;
Packit 15a96c
        if (d == (struct dialent *)NULL)
Packit 15a96c
          d = dialents;
Packit 15a96c
      } while (!(d->flags & FL_TAG));
Packit 15a96c
      mc_wlocate(dialwin, 0, 1);
Packit 15a96c
      mc_wprintf(dialwin, " %s : %s", _("Dialing"), d->name);
Packit 15a96c
      mc_wclreol(dialwin);
Packit 15a96c
      mc_wprintf(dialwin, "\n"); /* helps translators */
Packit 15a96c
      mc_wprintf(dialwin, _("      At : %s"), d->number);
Packit 15a96c
      mc_wclreol(dialwin);
Packit 15a96c
      if (d->lastdate[0] && d->lasttime[0]) {
Packit 15a96c
	mc_wprintf(dialwin, "\n"); /* don't merge with next printf, helps translators */
Packit 15a96c
        mc_wprintf(dialwin, _(" Last on : %s at %s"),
Packit 15a96c
                d->lastdate, d->lasttime);
Packit 15a96c
        mc_wclreol(dialwin);
Packit 15a96c
      }
Packit 15a96c
    }
Packit 15a96c
Packit 15a96c
    /* Calculate dial time */
Packit 15a96c
    dialtime = atoi(P_MDIALTIME);
Packit 15a96c
    if (dialtime == 0)
Packit 15a96c
      dialtime = 45;
Packit 15a96c
    time(&now;;
Packit 15a96c
    last = now;
Packit 15a96c
Packit 15a96c
    /* Show used time */
Packit 15a96c
    mc_wlocate(dialwin, 0, 4);
Packit 15a96c
    mc_wprintf(dialwin, _("    Time : %-3d"), dialtime);
Packit 15a96c
    if (maxretries > 1)
Packit 15a96c
      mc_wprintf(dialwin, _("     Attempt #%d"), retries);
Packit 15a96c
    mc_wputs(dialwin, _("\n\n\n Escape to cancel, space to retry."));
Packit 15a96c
Packit 15a96c
    /* Start the dial */
Packit 15a96c
    m_flush(portfd);
Packit 15a96c
    switch (d->dialtype) {
Packit 15a96c
      case 0:
Packit 15a96c
        mputs(P_MDIALPRE, 0);
Packit 15a96c
        mputs(d->number, 0);
Packit 15a96c
        mputs(P_MDIALSUF, 0);
Packit 15a96c
        break;
Packit 15a96c
      case 1:
Packit 15a96c
        mputs(P_MDIALPRE2, 0);
Packit 15a96c
        mputs(d->number, 0);
Packit 15a96c
        mputs(P_MDIALSUF2, 0);
Packit 15a96c
        break;
Packit 15a96c
      case 2:
Packit 15a96c
        mputs(P_MDIALPRE3, 0);
Packit 15a96c
        mputs(d->number, 0);
Packit 15a96c
        mputs(P_MDIALSUF3, 0);
Packit 15a96c
        break;
Packit 15a96c
    }
Packit 15a96c
Packit 15a96c
    /* Wait 'till the modem says something */
Packit 15a96c
    modbuf[0] = 0;
Packit 15a96c
    modidx = 0;
Packit 15a96c
    s = buf;
Packit 15a96c
    buf[0] = 0;
Packit 15a96c
    while (dialtime > 0) {
Packit 15a96c
      if (*s == 0) {
Packit 15a96c
        x = check_io(portfd_connected, 0, 1000, buf, sizeof(buf), NULL);
Packit 15a96c
        s = buf;
Packit 15a96c
      }
Packit 15a96c
      if (x & 2) {
Packit 15a96c
        f = keyboard(KGETKEY, 0);
Packit 15a96c
        /* Cancel if escape was pressed. */
Packit 15a96c
        if (f == K_ESC)
Packit 15a96c
          mputs(P_MDIALCAN, 0);
Packit 15a96c
Packit 15a96c
        /* On space retry. */
Packit 15a96c
        if (f == ' ') {
Packit 15a96c
          mputs(P_MDIALCAN, 0);
Packit 15a96c
          dialfailed(_("Cancelled"), 4);
Packit 15a96c
          m_flush(portfd);
Packit 15a96c
          break;
Packit 15a96c
        }
Packit 15a96c
        keyboard(KSTOP, 0);
Packit 15a96c
        mc_wclose(dialwin, 1);
Packit 15a96c
        return retst;
Packit 15a96c
      }
Packit 15a96c
      if (x & 1) {
Packit 15a96c
        /* Data available from the modem. Put in buffer. */
Packit 15a96c
        if (*s == '\r' || *s == '\n') {
Packit 15a96c
          /* We look for [\r\n]STRING[\r\n] */
Packit 15a96c
          modbuf[modidx] = 0;
Packit 15a96c
          modidx = 0;
Packit 15a96c
        } else if (modidx < 127) {
Packit 15a96c
          /* Normal character. Add. */
Packit 15a96c
          modbuf[modidx++] = *s;
Packit 15a96c
          modbuf[modidx] = 0;
Packit 15a96c
        }
Packit 15a96c
        /* Skip to next received char */
Packit 15a96c
        if (*s)
Packit 15a96c
          s++;
Packit 15a96c
        /* Only look when we got a whole line. */
Packit 15a96c
        if (modidx == 0 &&
Packit 15a96c
            !strncmp(modbuf, P_MCONNECT, strlen(P_MCONNECT))) {
Packit 15a96c
          timer_update(); /* the login scipt may take long.. */
Packit 15a96c
          retst = 0;
Packit 15a96c
          /* Try to do auto-bauding */
Packit 15a96c
          if (sscanf(modbuf + strlen(P_MCONNECT), "%ld", &nb) == 1)
Packit 15a96c
            retst = nb;
Packit 15a96c
          linespd = retst;
Packit 15a96c
Packit 15a96c
          /* Try to figure out if this system supports DCD */
Packit 15a96c
          f = m_getdcd(portfd);
Packit 15a96c
          bogus_dcd = 1;
Packit 15a96c
Packit 15a96c
          /* jl 22.05.97, 22.09.97, 05.04.99 */
Packit 15a96c
          if (P_LOGCONN[0] == 'Y')
Packit 15a96c
            do_log("%s %s, %s",modbuf, d->name, d->number);
Packit 15a96c
Packit 15a96c
          ptime = localtime(&now;;
Packit 15a96c
          sprintf(d->lastdate,"%4.4d%2.2d%2.2d",
Packit 15a96c
                  (ptime->tm_year)+1900,(ptime->tm_mon)+1,
Packit 15a96c
                  ptime->tm_mday);
Packit 15a96c
          sprintf(d->lasttime,"%02d:%02d",
Packit 15a96c
                  ptime->tm_hour,ptime->tm_min);
Packit 15a96c
          d->count++;
Packit 15a96c
Packit 15a96c
          if (d->convfile[0]) {
Packit 15a96c
            loadconv(d->convfile);    /* jl 21.09.97 */
Packit 15a96c
            strcpy(P_CONVF, d->convfile);
Packit 15a96c
          }
Packit 15a96c
Packit 15a96c
          mc_wlocate(dialwin, 1, 7);
Packit 15a96c
          if (d->script[0] == 0) {
Packit 15a96c
            mc_wputs(dialwin,
Packit 15a96c
                  _("Connected. Press any key to continue"));
Packit 15a96c
#ifdef VC_MUSIC
Packit 15a96c
            if (P_SOUND[0] == 'Y')
Packit 15a96c
              music();
Packit 15a96c
            else {
Packit 15a96c
              x = check_io(-1, 0, 0, NULL, 0, NULL);
Packit 15a96c
              if ((x & 2) == 2)
Packit 15a96c
                keyboard(KGETKEY, 0);
Packit 15a96c
            }
Packit 15a96c
#else
Packit 15a96c
            /* MARK updated 02/17/94 - If VC_MUSIC is not */
Packit 15a96c
            /* defined, then at least make some beeps! */
Packit 15a96c
            if (P_SOUND[0] == 'Y')
Packit 15a96c
              mc_wputs(dialwin,"\007\007\007");
Packit 15a96c
#endif
Packit 15a96c
            x = check_io(-1, 0, 0, NULL, 0, NULL);
Packit 15a96c
            if ((x & 2) == 2)
Packit 15a96c
              keyboard(KGETKEY, 0);
Packit 15a96c
          }
Packit 15a96c
          keyboard(KSTOP, 0);
Packit 15a96c
          mc_wclose(dialwin, 1);
Packit 15a96c
          /* Print out the connect strings. */
Packit 15a96c
          mc_wprintf(us, "\r\n%s\r\n", modbuf);
Packit 15a96c
          dialwin = NULL;
Packit 15a96c
Packit 15a96c
          /* Un-tag this entry. */
Packit 15a96c
          d->flags &= ~FL_TAG;
Packit 15a96c
Packit 15a96c
          /* store pointer to the entry that ANSWERED */
Packit 15a96c
          if (d2 != (struct dialent**)NULL)
Packit 15a96c
            *d2 = d;	/* jl 23.09.97 */
Packit 15a96c
Packit 15a96c
          /* Here should placed code to untag phones with similar names */
Packit 15a96c
          if (P_MULTILINE[0] == 'Y') {
Packit 15a96c
            struct dialent *d3 = dialents;
Packit 15a96c
Packit 15a96c
            while (d3 != (struct dialent*)NULL) {
Packit 15a96c
              if (!strcmp(d3->name, d->name))
Packit 15a96c
                d3->flags &= ~FL_TAG;
Packit 15a96c
              d3 = d3->next;
Packit 15a96c
            }
Packit 15a96c
          }				/*  er 27-Apr-99 */
Packit 15a96c
          return retst;
Packit 15a96c
        }
Packit 15a96c
Packit 15a96c
        for (f = 0; f < 3; f++) {
Packit 15a96c
          if (f == 0)
Packit 15a96c
            t = P_MNOCON1;
Packit 15a96c
          if (f == 1)
Packit 15a96c
            t = P_MNOCON2;
Packit 15a96c
          if (f == 2)
Packit 15a96c
            t = P_MNOCON3;
Packit 15a96c
          if (f == 3)
Packit 15a96c
            t = P_MNOCON4;
Packit 15a96c
          if ((*t) && (!strncmp(modbuf, t, strlen(t)))) {
Packit 15a96c
            if (retries < maxretries) {
Packit 15a96c
              x = dialfailed(t, rdelay);
Packit 15a96c
              if (x < 0) {
Packit 15a96c
                keyboard(KSTOP, 0);
Packit 15a96c
                mc_wclose(dialwin, 1);
Packit 15a96c
                return retst;
Packit 15a96c
              }
Packit 15a96c
            }
Packit 15a96c
            if (maxretries == 1)
Packit 15a96c
              reason = t;
Packit 15a96c
            goto MainLoop;
Packit 15a96c
          }
Packit 15a96c
        }
Packit 15a96c
      }
Packit 15a96c
Packit 15a96c
      /* Do timer routines here. */
Packit 15a96c
      time(&now;;
Packit 15a96c
      if (last != now) {
Packit 15a96c
        dialtime -= (now - last);
Packit 15a96c
        if (dialtime < 0)
Packit 15a96c
          dialtime = 0;
Packit 15a96c
        mc_wlocate(dialwin, 11, 4);
Packit 15a96c
        mc_wprintf(dialwin, "%-3d  ", dialtime);
Packit 15a96c
        if (dialtime <= 0) {
Packit 15a96c
          mputs(P_MDIALCAN, 0);
Packit 15a96c
          reason = _("Timeout");
Packit 15a96c
          retst = -1;
Packit 15a96c
          if (retries < maxretries) {
Packit 15a96c
            x = dialfailed(reason, rdelay);
Packit 15a96c
            if (x < 0) {
Packit 15a96c
              keyboard(KSTOP, 0);
Packit 15a96c
              mc_wclose(dialwin, 1);
Packit 15a96c
              return retst;
Packit 15a96c
            }
Packit 15a96c
          }
Packit 15a96c
        }
Packit 15a96c
      }
Packit 15a96c
      last = now;
Packit 15a96c
    }
Packit 15a96c
  } /* End of main while cq MainLoop */
Packit 15a96c
  dialfailed(reason, -1);
Packit 15a96c
  keyboard(KSTOP, 0);
Packit 15a96c
  mc_wclose(dialwin, 1);
Packit 15a96c
  return retst;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Create an empty entry.
Packit 15a96c
 */
Packit 15a96c
static struct dialent *mkstdent(void)
Packit 15a96c
{
Packit 15a96c
  struct dialent *d = malloc(sizeof(struct dialent));
Packit 15a96c
Packit 15a96c
  if (d == NULL)
Packit 15a96c
    return d;
Packit 15a96c
Packit 15a96c
  d->name[0] = 0;
Packit 15a96c
  d->number[0] = 0;
Packit 15a96c
  d->script[0] = 0;
Packit 15a96c
  d->username[0] = 0;
Packit 15a96c
  d->password[0] = 0;
Packit 15a96c
  d->term = 1;
Packit 15a96c
  d->dialtype = 0;
Packit 15a96c
  d->flags = FL_DEL;
Packit 15a96c
  strcpy(d->baud, "Curr");
Packit 15a96c
  strcpy(d->bits, "8");
Packit 15a96c
  strcpy(d->parity, "N");
Packit 15a96c
  d->lastdate[0] = 0;	/* jl 22.06.97 */
Packit 15a96c
  d->lasttime[0] = 0;
Packit 15a96c
  d->count = 0;
Packit 15a96c
  d->convfile[0] = 0;	/* jl 21.09.97 */
Packit 15a96c
  strcpy(d->stopb, "1");
Packit 15a96c
  d->next = NULL;
Packit 15a96c
Packit 15a96c
  return d;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
static void convert_to_save_order(struct dialent *dst, const struct dialent *src)
Packit 15a96c
{
Packit 15a96c
  memcpy(dst, src, sizeof(*dst));
Packit 15a96c
  dst->count = htonl(dst->count);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
static void convert_to_host_order(struct dialent *dst, const struct dialent *src)
Packit 15a96c
{
Packit 15a96c
  memcpy(dst, src, sizeof(*dst));
Packit 15a96c
  dst->count = ntohl(dst->count);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/* Read version 5 of the dialing directory. */
Packit 15a96c
static int v5_read(FILE *fp, struct dialent *d)
Packit 15a96c
{
Packit 15a96c
  struct dialent dent_n;
Packit 15a96c
  if (fread(&dent_n, sizeof(dent_n), 1, fp) != 1)
Packit 15a96c
    return 1;
Packit 15a96c
  convert_to_host_order(d, &dent_n);
Packit 15a96c
  return 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
static int v6_read(FILE *fp, struct dialent *d)
Packit 15a96c
{
Packit 15a96c
  struct dialent dent_n;
Packit 15a96c
  if (fread(&dent_n, sizeof(dent_n) - sizeof(void *), 1, fp) != 1)
Packit 15a96c
    return 1;
Packit 15a96c
  convert_to_host_order(d, &dent_n);
Packit 15a96c
  return 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/* Read version 4 of the dialing directory. */
Packit 15a96c
static int v4_read(FILE *fp, struct dialent *d, struct dver *dv)
Packit 15a96c
{
Packit 15a96c
  struct v4_dialent v4;
Packit 15a96c
Packit 15a96c
  if (fread(&v4, dv->size, 1, fp) != 1)
Packit 15a96c
    return 1;
Packit 15a96c
Packit 15a96c
  if (dv->size < sizeof(struct dialent)) {
Packit 15a96c
    if (dv->size < offsetof(struct dialent, count) + sizeof(struct dialent *)) {
Packit 15a96c
      d->count = 0;
Packit 15a96c
      d->lasttime[0] = 0;
Packit 15a96c
      d->lastdate[0] = 0;
Packit 15a96c
    }
Packit 15a96c
    if (dv->size < offsetof(struct dialent, stopb) + sizeof(struct dialent *))
Packit 15a96c
      d->convfile[0] = 0;
Packit 15a96c
    strcpy(d->stopb, "1");
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  return 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/* Read version 3 of the dialing directory. */
Packit 15a96c
static int v3_read(FILE *fp, struct dialent *d)
Packit 15a96c
{
Packit 15a96c
  struct v3_dialent v3;   /* jl 22.06.97 */
Packit 15a96c
Packit 15a96c
  if (fread(&v3, sizeof(v3), 1, fp) != 1)
Packit 15a96c
    return 1;
Packit 15a96c
Packit 15a96c
  memcpy(d, &v3, offsetof(struct v3_dialent, next));
Packit 15a96c
Packit 15a96c
  d->lastdate[0] = 0;
Packit 15a96c
  d->lasttime[0] = 0;
Packit 15a96c
  d->count = 0;
Packit 15a96c
  d->convfile[0] = 0;
Packit 15a96c
  strcpy(d->stopb, "1");
Packit 15a96c
Packit 15a96c
  return 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/* Read version 2 of the dialing directory. */
Packit 15a96c
static int v2_read(FILE *fp, struct dialent *d)
Packit 15a96c
{
Packit 15a96c
  struct v3_dialent v3;   /* jl 22.06.97 */
Packit 15a96c
Packit 15a96c
  if (fread((char *)&v3, sizeof(v3), 1, fp) != 1)
Packit 15a96c
    return 1;
Packit 15a96c
Packit 15a96c
  memcpy(d, &v3, offsetof(struct v3_dialent, next));
Packit 15a96c
  if (d->flags & FL_ANSI)
Packit 15a96c
    d->flags |= FL_WRAP;
Packit 15a96c
  d->lastdate[0] = 0;
Packit 15a96c
  d->lasttime[0] = 0;
Packit 15a96c
  d->count = 0;
Packit 15a96c
  d->convfile[0] = 0;
Packit 15a96c
  strcpy(d->stopb, "1");
Packit 15a96c
Packit 15a96c
  return 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/* Read version 1 of the dialing directory. */
Packit 15a96c
static int v1_read(FILE *fp, struct dialent *d)
Packit 15a96c
{
Packit 15a96c
  struct v1_dialent v1;
Packit 15a96c
Packit 15a96c
  if (fread((char *)&v1, sizeof(v1), (size_t)1, fp) != 1)
Packit 15a96c
    return 1;
Packit 15a96c
Packit 15a96c
  memcpy(d->username, v1.username, sizeof(v1) - offsetof(struct v1_dialent, username));
Packit 15a96c
  strncpy(d->name, v1.name, sizeof(d->name));
rpm-build c8e99c
  d->name[sizeof(d->name) - 1] = '\0';
Packit 15a96c
  strncpy(d->number, v1.number, sizeof(d->number));
rpm-build c8e99c
  d->number[sizeof(d->number) - 1] = '\0';
Packit 15a96c
  strncpy(d->script, v1.script, sizeof(d->script));
rpm-build c8e99c
  d->script[sizeof(d->script) - 1] = '\0';
Packit 15a96c
  d->lastdate[0]=0;
Packit 15a96c
  d->lasttime[0]=0;
Packit 15a96c
  d->count=0;
Packit 15a96c
  d->convfile[0]=0;
Packit 15a96c
  strcpy(d->stopb, "1");
Packit 15a96c
Packit 15a96c
  return 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/* Read version 0 of the dialing directory. */
Packit 15a96c
static int v0_read(FILE *fp, struct dialent *d)
Packit 15a96c
{
Packit 15a96c
  if (v1_read(fp, d))
Packit 15a96c
    return 1;
Packit 15a96c
  d->dialtype = 0;
Packit 15a96c
  d->flags = 0;
Packit 15a96c
Packit 15a96c
  return 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Read in the dialing directory from $HOME/.dialdir
Packit 15a96c
 */
Packit 15a96c
int readdialdir(void)
Packit 15a96c
{
Packit 15a96c
  long size;
Packit 15a96c
  FILE *fp;
Packit 15a96c
  char dfile[256];
Packit 15a96c
  char copycmd[512];
Packit 15a96c
  static int didread = 0;
Packit 15a96c
  int f;
Packit 15a96c
  struct dialent *d = NULL, *tail = NULL;
Packit 15a96c
  struct dver dial_ver;
Packit 15a96c
  WIN *w;
Packit 15a96c
Packit 15a96c
  if (didread)
Packit 15a96c
    return 0;
Packit 15a96c
  didread = 1;
Packit 15a96c
  nrents = 1;
Packit 15a96c
  tagged = malloc(1);
Packit 15a96c
  if (!tagged)
Packit 15a96c
    return 0;
Packit 15a96c
  tagged[0] = 0;
Packit 15a96c
Packit 15a96c
  /* Make the manual dial entry. */
Packit 15a96c
  d_man = mkstdent();
Packit 15a96c
  strncpy(d_man->name, _("Manually entered number"), sizeof(d_man->name));
Packit 15a96c
  d_man->name[sizeof(d_man->name) - 1] = 0;
Packit 15a96c
Packit 15a96c
  /* Construct path */
Packit 15a96c
  snprintf(dfile, sizeof(dfile), "%s/.dialdir", homedir);
Packit 15a96c
Packit 15a96c
  /* Try to open ~/.dialdir */
Packit 15a96c
  if ((fp = fopen(dfile, "r")) == NULL) {
Packit 15a96c
    if (errno == EPERM) {
Packit 15a96c
      werror(_("Cannot open ~/.dialdir: permission denied"));
Packit 15a96c
      dialents = mkstdent();
Packit 15a96c
      dendd = 1;
Packit 15a96c
      return 0;
Packit 15a96c
    }
Packit 15a96c
    dialents = mkstdent();
Packit 15a96c
    return 0;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Get size of the file */
Packit 15a96c
  fseek(fp, 0L, SEEK_END);
Packit 15a96c
  size = ftell(fp);
Packit 15a96c
  if (size == 0) {
Packit 15a96c
    dialents = mkstdent();
Packit 15a96c
    fclose(fp);
Packit 15a96c
    return 0;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Get version of the dialing directory */
Packit 15a96c
  fseek(fp, 0L, SEEK_SET);
Packit 15a96c
  if (fread(&dial_ver, sizeof(dial_ver), 1, fp) != 1)
Packit 15a96c
    {
Packit 15a96c
      werror(_("Failed to read dialing directory\n"));
rpm-build 2746f2
      fclose(fp);
Packit 15a96c
      return -1;
Packit 15a96c
    }
Packit 15a96c
  if (dial_ver.magic != DIALMAGIC) {
Packit 15a96c
    /* First version without version info. */
Packit 15a96c
    dial_ver.version = 0;
Packit 15a96c
    fseek(fp, 0L, SEEK_SET);
Packit 15a96c
  } else {
Packit 15a96c
    dial_ver.size = ntohs(dial_ver.size);
Packit 15a96c
    size -= sizeof(dial_ver);
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* See if the size of the file is allright. */
Packit 15a96c
  switch (dial_ver.version) {
Packit 15a96c
    case 0:
Packit 15a96c
    case 1:
Packit 15a96c
      dial_ver.size = sizeof(struct v1_dialent);
Packit 15a96c
      break;
Packit 15a96c
    case 2:
Packit 15a96c
    case 3:
Packit 15a96c
      dial_ver.size = sizeof(struct v3_dialent);
Packit 15a96c
      break;
Packit 15a96c
    case 4:
Packit 15a96c
      /* dial_ver.size = sizeof(struct dialent); */
Packit 15a96c
      /* Removed the forced setting to add flexibility.
Packit 15a96c
       * Now you don't need to change the version number
Packit 15a96c
       * if you just add fields to the end of the dialent structure
Packit 15a96c
       * before the *next pointer and don't change existing fields.
Packit 15a96c
       * Just update the initialization in the functions
Packit 15a96c
       * v4_read/v5_read and mkstdent (and whatever you added the field for)
Packit 15a96c
       * jl 21.09.97
Packit 15a96c
       */
Packit 15a96c
      if (dial_ver.size < 200 ||
Packit 15a96c
          dial_ver.size > sizeof(struct v4_dialent)) {
Packit 15a96c
        werror(_("Phonelist garbled (unknown version?)"));
Packit 15a96c
        dialents = mkstdent();
rpm-build 2746f2
        fclose(fp);
Packit 15a96c
        return -1;
Packit 15a96c
      }
Packit 15a96c
      break;
Packit 15a96c
    case 5:
Packit 15a96c
      if (dial_ver.size != sizeof(struct dialent)) {
Packit 15a96c
	werror(_("Phonelist corrupted"));
rpm-build 2746f2
        fclose(fp);
Packit 15a96c
	return -1;
Packit 15a96c
      }
Packit 15a96c
      break;
Packit 15a96c
    case 6:
Packit 15a96c
      // v6 is the same as v5 but the pointer is not saved and thus does not
Packit 15a96c
      // have different size on 32 and 64bit systems
Packit 15a96c
      if (dial_ver.size != sizeof(struct dialent) - sizeof(void *)) {
Packit 15a96c
        werror(_("Phonelist corrupted"));
rpm-build 2746f2
        fclose(fp);
Packit 15a96c
        return -1;
Packit 15a96c
      }
Packit 15a96c
      break;
Packit 15a96c
    default:
Packit 15a96c
      werror(_("Unknown dialing directory version"));
Packit 15a96c
      dendd = 1;
Packit 15a96c
      dialents = mkstdent();
rpm-build 2746f2
      fclose(fp);
Packit 15a96c
      return -1;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  if (size % dial_ver.size != 0) {
Packit 15a96c
    werror(_("Phonelist garbled (?)"));
Packit 15a96c
    fclose(fp);
Packit 15a96c
    dendd = 1;
Packit 15a96c
    dialents = mkstdent();
Packit 15a96c
    return -1;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Read in the dialing entries */
Packit 15a96c
  nrents = size / dial_ver.size;
Packit 15a96c
  if (nrents == 0) {
Packit 15a96c
    dialents = mkstdent();
Packit 15a96c
    nrents = 1;
Packit 15a96c
    fclose(fp);
Packit 15a96c
    return 0;
Packit 15a96c
  }
Packit 15a96c
  for(f = 1; f <= nrents; f++) {
Packit 15a96c
    if ((d = malloc(sizeof (struct dialent))) == NULL) {
Packit 15a96c
      if (f == 1)
Packit 15a96c
        dialents = mkstdent();
Packit 15a96c
      else
Packit 15a96c
        tail->next = NULL;
Packit 15a96c
Packit 15a96c
      werror(_("Out of memory while reading dialing directory"));
Packit 15a96c
      fclose(fp);
Packit 15a96c
      return -1;
Packit 15a96c
    }
Packit 15a96c
    int r = 0;
Packit 15a96c
    switch (dial_ver.version) {
Packit 15a96c
      case 0:
Packit 15a96c
        r = v0_read(fp, d);
Packit 15a96c
        break;
Packit 15a96c
      case 1:
Packit 15a96c
        r = v1_read(fp, d);
Packit 15a96c
        break;
Packit 15a96c
      case 2:
Packit 15a96c
        r = v2_read(fp, d);
Packit 15a96c
        break;
Packit 15a96c
      case 3:
Packit 15a96c
        r = v3_read(fp, d);
Packit 15a96c
        break;
Packit 15a96c
      case 4:
Packit 15a96c
        r = v4_read(fp, d, &dial_ver);
Packit 15a96c
        break;
Packit 15a96c
      case 5:
Packit 15a96c
	r = v5_read(fp, d);
Packit 15a96c
	break;
Packit 15a96c
      case 6:
Packit 15a96c
	r = v6_read(fp, d);
Packit 15a96c
	break;
Packit 15a96c
    }
Packit 15a96c
Packit 15a96c
    if (r)
Packit 15a96c
      werror("Failed to read phonelist\n");
Packit 15a96c
Packit 15a96c
    /* MINIX terminal type is obsolete */
Packit 15a96c
    if (d->term == 2)
Packit 15a96c
      d->term = 1;
Packit 15a96c
Packit 15a96c
    if (tail)
Packit 15a96c
      tail->next = d;
Packit 15a96c
    else
Packit 15a96c
      dialents = d;
Packit 15a96c
    tail = d;
Packit 15a96c
  }
Packit 15a96c
  d->next = NULL;
Packit 15a96c
  fclose(fp);
Packit 15a96c
Packit 15a96c
  if (dial_ver.version != CURRENT_VERSION) {
Packit 15a96c
    if (snprintf(copycmd, sizeof(copycmd),
Packit 15a96c
                 "cp -p %s %s.v%hd", dfile, dfile, dial_ver.version) > 0) {
Packit 15a96c
      if (P_LOGFNAME[0] != 0)
Packit 15a96c
        do_log("%s", copycmd);
Packit 15a96c
      if (system(copycmd) == 0) {
Packit 15a96c
        snprintf(copycmd, sizeof(copycmd),
Packit 15a96c
                 _("Converted dialdir to new format, old saved as %s.v%hd"),
Packit 15a96c
                 dfile, dial_ver.version);
Packit 15a96c
        w = mc_tell("%s", copycmd);
Packit 15a96c
        if (w) {
Packit 15a96c
          sleep(2);
Packit 15a96c
          mc_wclose(w,1);
Packit 15a96c
        }
Packit 15a96c
        writedialdir();
Packit 15a96c
      }
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
  return 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Write the new $HOME/.dialdir
Packit 15a96c
 */
Packit 15a96c
static void writedialdir(void)
Packit 15a96c
{
Packit 15a96c
  struct dialent *d;
Packit 15a96c
  char dfile[256];
Packit 15a96c
  FILE *fp;
Packit 15a96c
  struct dver dial_ver;
Packit 15a96c
  char oldfl;
Packit 15a96c
  int omask;
Packit 15a96c
Packit 15a96c
  /* Make no sense if access denied */
Packit 15a96c
  if (dendd)
Packit 15a96c
    return;
Packit 15a96c
Packit 15a96c
  snprintf(dfile, sizeof(dfile), "%s/.dialdir", homedir);
Packit 15a96c
Packit 15a96c
  omask = umask(077);
Packit 15a96c
  if ((fp = fopen(dfile, "w")) == NULL) {
Packit 15a96c
    umask(omask);
Packit 15a96c
    werror(_("Cannot open ~/.dialdir for writing!"));
Packit 15a96c
    dendd = 1;
Packit 15a96c
    return;
Packit 15a96c
  }
Packit 15a96c
  umask(omask);
Packit 15a96c
Packit 15a96c
  d = dialents;
Packit 15a96c
  /* Set up version info. */
Packit 15a96c
  dial_ver.magic   = DIALMAGIC;
Packit 15a96c
  dial_ver.version = CURRENT_VERSION;
Packit 15a96c
  dial_ver.size = htons(sizeof(struct dialent) - sizeof(void *));
Packit 15a96c
  dial_ver.res1 = 0;	/* We don't use these res? fields, but let's */
Packit 15a96c
  dial_ver.res2 = 0;	/* initialize them to a known init value for */
Packit 15a96c
  dial_ver.res3 = 0;	/* whoever needs them later / jl 22.09.97    */
Packit 15a96c
  dial_ver.res4 = 0;
Packit 15a96c
  if (fwrite(&dial_ver, sizeof(dial_ver), 1, fp) != 1) {
Packit 15a96c
    werror(_("Error writing to ~/.dialdir!"));
Packit 15a96c
    fclose(fp);
Packit 15a96c
    return;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Write dialing directory */
Packit 15a96c
  while (d) {
Packit 15a96c
    struct dialent dent_n;
Packit 15a96c
    oldfl = d->flags;
Packit 15a96c
    d->flags &= FL_SAVE;
Packit 15a96c
    convert_to_save_order(&dent_n, d);
Packit 15a96c
    if (fwrite(&dent_n, sizeof(dent_n) - sizeof(void *), 1, fp) != 1) {
Packit 15a96c
      werror(_("Error writing to ~/.dialdir!"));
Packit 15a96c
      fclose(fp);
Packit 15a96c
      return;
Packit 15a96c
    }
Packit 15a96c
    d->flags = oldfl;
Packit 15a96c
    d = d->next;
Packit 15a96c
  }
Packit 15a96c
  fclose(fp);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Get entry "no" in list.
Packit 15a96c
 */
Packit 15a96c
static struct dialent *getno(int no)
Packit 15a96c
{
Packit 15a96c
  struct dialent *d;
Packit 15a96c
Packit 15a96c
  d = dialents;
Packit 15a96c
Packit 15a96c
  if (no < 0 || no >= nrents)
Packit 15a96c
    return (struct dialent *)NULL;
Packit 15a96c
Packit 15a96c
  while (no--)
Packit 15a96c
    d = d->next;
Packit 15a96c
Packit 15a96c
  return d;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/* Note: Minix does not exist anymore. */
Packit 15a96c
static const char *te[] = { "VT102", "MINIX", "ANSI " };
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Display a "dedit" entry
Packit 15a96c
 * We need to make sure that the previous value
Packit 15a96c
 * gets fully overwritten in all languages (i.e. arbitrary strings)!
Packit 15a96c
 */
Packit 15a96c
static void dedit_toggle_entry(WIN *w, int x, int y, int toggle,
Packit 15a96c
                               char *toggle_true, char *toggle_false)
Packit 15a96c
{
Packit 15a96c
  int lt = mbslen(toggle_true);
Packit 15a96c
  int lf = mbslen(toggle_false);
Packit 15a96c
  int l = ((lt > lf) ? lt : lf) + 1;
Packit 15a96c
  char *buf, *s = toggle ? toggle_true : toggle_false;
Packit 15a96c
  int i;
Packit 15a96c
Packit 15a96c
  if (!(buf = alloca(l)))
Packit 15a96c
    return;
Packit 15a96c
Packit 15a96c
  strncpy(buf, s, l);
Packit 15a96c
  for (i = mbslen(s); i < l - 1; i++)
Packit 15a96c
    buf[i] = ' ';
Packit 15a96c
  buf[l - 1] = 0;
Packit 15a96c
Packit 15a96c
  mc_wlocate(w, x, y);
Packit 15a96c
  mc_wputs(w, buf);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Edit an entry.
Packit 15a96c
 */
Packit 15a96c
static void dedit(struct dialent *d)
Packit 15a96c
{
Packit 15a96c
  WIN *w;
Packit 15a96c
  int c;
Packit 15a96c
  char *name		    = _(" A -  Name                :"),
Packit 15a96c
       *number		    = _(" B -  Number              :"),
Packit 15a96c
       *dial_string	    = _(" C -  Dial string #       :"),
Packit 15a96c
       *local_echo_str	    = _(" D -  Local echo          :"),
Packit 15a96c
       *script		    = _(" E -  Script              :"),
Packit 15a96c
       *username	    = _(" F -  Username            :"),
Packit 15a96c
       *password	    = _(" G -  Password            :"),
Packit 15a96c
       *terminal_emulation  = _(" H -  Terminal Emulation  :"),
Packit 15a96c
       *backspace_key_sends = _(" I -  Backspace key sends :"),
Packit 15a96c
       *linewrap            = _(" J -  Linewrap            :"),
Packit 15a96c
       *line_settings       = _(" K -  Line Settings       :"),
Packit 15a96c
       *conversion_table    = _(" L -  Conversion table    :"),
Packit 15a96c
       *question            = _("Change which setting?");
Packit 15a96c
Packit 15a96c
  w = mc_wopen(5, 4, 75, 19, BDOUBLE, stdattr, mfcolor, mbcolor, 0, 0, 1);
Packit 15a96c
  mc_wprintf(w, "%s %s\n", name, d->name);
Packit 15a96c
  mc_wprintf(w, "%s %s\n", number, d->number);
Packit 15a96c
  mc_wprintf(w, "%s %d\n", dial_string, d->dialtype + 1);
Packit 15a96c
  mc_wprintf(w, "%s %s\n", local_echo_str, _(yesno(d->flags & FL_ECHO)));
Packit 15a96c
  mc_wprintf(w, "%s %s\n", script, d->script);
Packit 15a96c
  mc_wprintf(w, "%s %s\n", username, d->username);
Packit 15a96c
  mc_wprintf(w, "%s %s\n", password, d->password);
Packit 15a96c
  mc_wprintf(w, "%s %s\n", terminal_emulation, te[d->term - 1]);
Packit 15a96c
  mc_wprintf(w, "%s %s\n", backspace_key_sends,
Packit 15a96c
          d->flags & FL_DEL ? _("Delete") : _("Backspace"));
Packit 15a96c
  mc_wprintf(w, "%s %s\n", linewrap,
Packit 15a96c
          d->flags & FL_WRAP ? _("On") : _("Off"));
Packit 15a96c
  mc_wprintf(w, "%s %s %s%s%s\n", line_settings,
Packit 15a96c
          d->baud, d->bits, d->parity, d->stopb);
Packit 15a96c
  mc_wprintf(w, "%s %s\n", conversion_table, d->convfile);
Packit 15a96c
  mc_wprintf(w, _("      Last dialed         : %s %s\n"),d->lastdate,d->lasttime);
Packit 15a96c
  mc_wprintf(w, _("      Times on            : %d"),d->count);
Packit 15a96c
  mc_wlocate(w, 4, 15);
Packit 15a96c
  mc_wputs(w, question);
Packit 15a96c
  mc_wredraw(w, 1);
Packit 15a96c
Packit 15a96c
  while (1) {
Packit 15a96c
    mc_wlocate(w, mbslen (question) + 5, 15);
Packit 15a96c
    c = wxgetch();
Packit 15a96c
    if (c >= 'a')
Packit 15a96c
      c -= 32;
Packit 15a96c
    switch(c) {
Packit 15a96c
      case '\033':
Packit 15a96c
      case '\r':
Packit 15a96c
      case '\n':
Packit 15a96c
        mc_wclose(w, 1);
Packit 15a96c
        return;
Packit 15a96c
      case 'A':
Packit 15a96c
        mc_wlocate(w, mbslen (name) + 1, 0);
Packit 15a96c
        mc_wgets(w, d->name, 31, 32);
Packit 15a96c
        break;
Packit 15a96c
      case 'B':
Packit 15a96c
        mc_wlocate(w, mbslen (number) + 1, 1);
Packit 15a96c
        mc_wgets(w, d->number, 31, 32);
Packit 15a96c
        break;
Packit 15a96c
      case 'C':
Packit 15a96c
        d->dialtype = (d->dialtype + 1) % 3;
Packit 15a96c
        mc_wlocate(w, mbslen (dial_string) + 1, 2);
Packit 15a96c
        mc_wprintf(w, "%d", d->dialtype + 1);
Packit 15a96c
        mc_wflush();
Packit 15a96c
        break;
Packit 15a96c
      case 'D':
Packit 15a96c
        d->flags ^= FL_ECHO;
Packit 15a96c
        mc_wlocate(w, mbslen (local_echo_str) + 1, 3);
Packit 15a96c
        mc_wprintf(w, "%s", _(yesno(d->flags & FL_ECHO)));
Packit 15a96c
        mc_wflush();
Packit 15a96c
        break;
Packit 15a96c
      case 'E':
Packit 15a96c
        mc_wlocate(w, mbslen (script) + 1, 4);
Packit 15a96c
        mc_wgets(w, d->script, 31, 32);
Packit 15a96c
        break;
Packit 15a96c
      case 'F':
Packit 15a96c
        mc_wlocate(w, mbslen (username) + 1, 5);
Packit 15a96c
        mc_wgets(w, d->username, 31, 32);
Packit 15a96c
        break;
Packit 15a96c
      case 'G':
Packit 15a96c
        mc_wlocate(w, mbslen (password) + 1, 6);
Packit 15a96c
        mc_wgets(w, d->password, 31, 32);
Packit 15a96c
        break;
Packit 15a96c
      case 'H':
Packit 15a96c
        d->term = (d->term % 3) + 1;
Packit 15a96c
        /* MINIX == 2 is obsolete. */
Packit 15a96c
        if (d->term == 2)
Packit 15a96c
          d->term = 3;
Packit 15a96c
        mc_wlocate(w, mbslen (terminal_emulation) + 1, 7);
Packit 15a96c
        mc_wputs(w, te[d->term - 1]);
Packit 15a96c
Packit 15a96c
        /* Also set backspace key. */
Packit 15a96c
        if (d->term == ANSI) {
Packit 15a96c
          d->flags &= ~FL_DEL;
Packit 15a96c
          d->flags |= FL_WRAP;
Packit 15a96c
        } else {
Packit 15a96c
          d->flags |= FL_DEL;
Packit 15a96c
          d->flags &= ~FL_WRAP;
Packit 15a96c
        }
Packit 15a96c
	dedit_toggle_entry(w, mbslen(backspace_key_sends) + 1, 8,
Packit 15a96c
	                   d->flags & FL_DEL, _("Delete"), _("Backspace"));
Packit 15a96c
	dedit_toggle_entry(w, mbslen(linewrap) + 1, 9,
Packit 15a96c
	                   d->flags & FL_WRAP, _("On"), _("Off"));
Packit 15a96c
        break;
Packit 15a96c
      case 'I':
Packit 15a96c
        d->flags ^= FL_DEL;
Packit 15a96c
	dedit_toggle_entry(w, mbslen(backspace_key_sends) + 1, 8,
Packit 15a96c
	                   d->flags & FL_DEL, _("Delete"), _("Backspace"));
Packit 15a96c
        break;
Packit 15a96c
      case 'J':
Packit 15a96c
        d->flags ^= FL_WRAP;
Packit 15a96c
	dedit_toggle_entry(w, mbslen(linewrap) + 1, 9,
Packit 15a96c
	                   d->flags & FL_WRAP, _("On"), _("Off"));
Packit 15a96c
        break;
Packit 15a96c
      case 'K':
Packit 15a96c
        get_bbp(d->baud, d->bits, d->parity, d->stopb, 1);
Packit 15a96c
        mc_wlocate(w, mbslen (line_settings) + 1, 10);
Packit 15a96c
        mc_wprintf(w, "%s %s%s%s  ",
Packit 15a96c
                d->baud, d->bits, d->parity, d->stopb);
Packit 15a96c
        break;
Packit 15a96c
      case 'L':	/* jl 21.09.97 */
Packit 15a96c
        mc_wlocate(w, mbslen (conversion_table) + 1, 11);
Packit 15a96c
        mc_wgets(w, d->convfile, 15, 16);
Packit 15a96c
        break;
Packit 15a96c
      default:
Packit 15a96c
        break;
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
static WIN *dsub;
Packit 15a96c
static const char *const what[] =
Packit 15a96c
  {
Packit 15a96c
    /* TRANSLATORS: Translation of each of these menu items should not be
Packit 15a96c
     * longer than 7 characters. The upper-case letter is a shortcut,
Packit 15a96c
     * so keep them unique and ASCII; 'h', 'j', 'k', 'l' are reserved */
Packit 15a96c
    N_("Dial"), N_("Find"), N_("Add"), N_("Edit"), N_("Remove"), N_("moVe"),
Packit 15a96c
    N_("Manual")
Packit 15a96c
  };
Packit 15a96c
/* Offsets of what[] entries from position_dialing_directory */
Packit 15a96c
#define DIALOPTS (sizeof(what) / sizeof(*what))
Packit 15a96c
#define DIAL_WIDTH 8 /* Width of one entry */
Packit 15a96c
static int what_lens[DIALOPTS]; /* Number of bytes for <= 7 characters */
Packit 15a96c
/* Number of ' ' padding entries at left and right, left is >= 1 */
Packit 15a96c
static int what_padding[DIALOPTS][2];
Packit 15a96c
Packit 15a96c
static int dprev;
Packit 15a96c
Packit 15a96c
/* Draw an entry in the horizontal menu */
Packit 15a96c
static void horiz_draw(size_t k)
Packit 15a96c
{
Packit 15a96c
  static const char spaces[] = "        ";
Packit 15a96c
Packit 15a96c
  mc_wprintf(dsub, "%.*s", what_padding[k][0], spaces);
Packit 15a96c
  mc_wprintf(dsub, "%.*s", what_lens[k], _(what[k]));
Packit 15a96c
  mc_wprintf(dsub, "%.*s", what_padding[k][1], spaces);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Highlight a choice in the horizontal menu.
Packit 15a96c
 */
Packit 15a96c
static void dhili(int position_dialing_directory, int k)
Packit 15a96c
{
Packit 15a96c
  if (k == dprev)
Packit 15a96c
    return;
Packit 15a96c
Packit 15a96c
  if (dprev >= 0) {
Packit 15a96c
    mc_wlocate(dsub, position_dialing_directory + DIAL_WIDTH * dprev, 0);
Packit 15a96c
    if (!useattr) {
Packit 15a96c
      mc_wputs(dsub, " ");
Packit 15a96c
    } else {
Packit 15a96c
      mc_wsetattr(dsub, XA_REVERSE | stdattr);
Packit 15a96c
      horiz_draw(dprev);
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
  dprev = k;
Packit 15a96c
  mc_wlocate(dsub, position_dialing_directory + DIAL_WIDTH * k, 0);
Packit 15a96c
  if (!useattr) {
Packit 15a96c
    mc_wputs(dsub, ">");
Packit 15a96c
  } else {
Packit 15a96c
    mc_wsetattr(dsub, stdattr);
Packit 15a96c
    horiz_draw(k);
Packit 15a96c
  }
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
static const char *fmt = "\r %2d %c%-16.16s%-16.16s%8.8s %5.5s %4d %-15.15s\n";
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Print the dialing directory. Only draw from "cur" to bottom.
Packit 15a96c
 */
Packit 15a96c
static void prdir(WIN *dialw, int top, int cur)
Packit 15a96c
{
Packit 15a96c
  int f, start;
Packit 15a96c
  struct dialent *d;
Packit 15a96c
Packit 15a96c
  start = cur - top;
Packit 15a96c
  dirflush = 0;
Packit 15a96c
  mc_wlocate(dialw, 0, start + 1);
Packit 15a96c
  for (f = start; f < dialw->ys - 2; f++) {
Packit 15a96c
    d = getno(f + top);
Packit 15a96c
    if (d == (struct dialent *)0)
Packit 15a96c
      break;
Packit 15a96c
    mc_wprintf(dialw, fmt, f+1+top, (d->flags & FL_TAG) ? '>' : ' ',
Packit 15a96c
            d->name, d->number, d->lastdate, d->lasttime, 
Packit 15a96c
            d->count, d->script);
Packit 15a96c
  }
Packit 15a96c
  dirflush = 1;
Packit 15a96c
  mc_wflush();
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Move an entry forward/back in the dial directory. jl 1.9.1999
Packit 15a96c
 */
Packit 15a96c
int move_entry(WIN *dialw, struct dialent *d, int cur, int *top)
Packit 15a96c
{
Packit 15a96c
  int ocur = cur,
Packit 15a96c
      quit = 0,
Packit 15a96c
      c = 0;
Packit 15a96c
  struct dialent *dtmp;
Packit 15a96c
Packit 15a96c
  while (!quit) {
Packit 15a96c
    switch (c = wxgetch()) {
Packit 15a96c
      case K_DN:
Packit 15a96c
      case 'j':
Packit 15a96c
        if (!(d->next))
Packit 15a96c
          break;
Packit 15a96c
        if (cur == 0) {   /* special case: move d from start to 2nd */
Packit 15a96c
          dtmp = d->next;
Packit 15a96c
          d->next = dtmp->next;
Packit 15a96c
          dtmp->next = d;
Packit 15a96c
          dialents = dtmp;
Packit 15a96c
        } else {	    /* swap d with the next one in the list */
Packit 15a96c
          dtmp = getno(cur - 1);
Packit 15a96c
          dtmp->next = d->next;
Packit 15a96c
          d->next = d->next->next;
Packit 15a96c
          dtmp->next->next = d;
Packit 15a96c
        }
Packit 15a96c
        cur++;
Packit 15a96c
        break;
Packit 15a96c
      case K_UP:
Packit 15a96c
      case 'k':
Packit 15a96c
        if (cur == 0)
Packit 15a96c
          break;
Packit 15a96c
        if (cur == 1) { /* special case: move d to start of list */
Packit 15a96c
          dtmp = dialents;
Packit 15a96c
          dtmp->next = d-> next;
Packit 15a96c
          d->next = dtmp;
Packit 15a96c
          dialents = d;
Packit 15a96c
        } else {	  /* swap d with the previous one in the list */
Packit 15a96c
          dtmp = getno(cur - 2);
Packit 15a96c
          dtmp->next->next = d-> next;
Packit 15a96c
          d->next = dtmp->next;
Packit 15a96c
          dtmp->next = d;
Packit 15a96c
        }
Packit 15a96c
        cur--;
Packit 15a96c
        break;
Packit 15a96c
      case '\033':
Packit 15a96c
      case '\r':
Packit 15a96c
      case '\n':
Packit 15a96c
        quit = 1;
Packit 15a96c
        break;
Packit 15a96c
      default:
Packit 15a96c
        break;
Packit 15a96c
    } /* end switch */
Packit 15a96c
Packit 15a96c
    /* If the list order changed, redraw the directory window */
Packit 15a96c
    if (cur != ocur) {
Packit 15a96c
      /* First remove cursor bar from the old position */
Packit 15a96c
      mc_wcurbar(dialw, ocur + 1 - *top, XA_NORMAL | stdattr);
Packit 15a96c
      if (cur < *top)
Packit 15a96c
        (*top)--;
Packit 15a96c
      else if (cur - *top > dialw->ys - 3)
Packit 15a96c
        (*top)++;
Packit 15a96c
      prdir(dialw, *top, *top);
Packit 15a96c
      mc_wcurbar(dialw, cur + 1 - *top, XA_REVERSE | stdattr);
Packit 15a96c
      ocur = cur;
Packit 15a96c
    } /* end redraw condition */
Packit 15a96c
  }   /* end loop   */
Packit 15a96c
Packit 15a96c
  return cur;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/* Little menu. */
Packit 15a96c
static const char *d_yesno[] = { N_("   Yes  "), N_("   No   "), NULL };
Packit 15a96c
Packit 15a96c
/* Try to dial an entry. */
Packit 15a96c
static void dial_entry(struct dialent *d)
Packit 15a96c
{
Packit 15a96c
  long nb;
Packit 15a96c
  struct dialent *d2;
Packit 15a96c
Packit 15a96c
  /* Change settings for this entry. */
Packit 15a96c
  if (atoi(d->baud) != 0) {
Packit 15a96c
    strcpy(P_BAUDRATE, d->baud);
Packit 15a96c
    strcpy(P_PARITY, d->parity);
Packit 15a96c
    strcpy(P_BITS, d->bits);
Packit 15a96c
    strcpy(P_STOPB, d->stopb);
Packit 15a96c
    port_init();
Packit 15a96c
    show_status();
Packit 15a96c
  }
Packit 15a96c
  newtype = d->term;
Packit 15a96c
  vt_set(-1, d->flags & FL_WRAP, -1, -1, d->flags & FL_ECHO, -1, -1, -1, -1);
Packit 15a96c
  local_echo = d->flags & FL_ECHO;
Packit 15a96c
  if (newtype != terminal)
Packit 15a96c
    init_emul(newtype, 1);
Packit 15a96c
Packit 15a96c
  /* Set backspace key. */
Packit 15a96c
  keyboard(KSETBS, d->flags & FL_DEL ? 127 : 8);
Packit 15a96c
  strcpy(P_BACKSPACE, d->flags & FL_DEL ? "DEL" : "BS");
Packit 15a96c
Packit 15a96c
  /* Now that everything has been set, dial. */
Packit 15a96c
  if ((nb = dial(d, &d2)) < 0)
Packit 15a96c
    return;
Packit 15a96c
  
Packit 15a96c
  if (d2 != (struct dialent *)NULL)
Packit 15a96c
    d = d2;	/* jl 22.09.97 */
Packit 15a96c
Packit 15a96c
  /* Did we detect a baudrate , and can we set it? */
Packit 15a96c
  if (P_MAUTOBAUD[0] == 'Y' && nb) {
Packit 15a96c
    sprintf(P_BAUDRATE, "%ld", nb);
Packit 15a96c
    port_init();
Packit 15a96c
    show_status();
Packit 15a96c
  } else if (P_SHOWSPD[0] == 'l')
Packit 15a96c
    show_status();
Packit 15a96c
Packit 15a96c
  /* Make sure the last date is updated   / jl 22.06.97 */
Packit 15a96c
  writedialdir();
Packit 15a96c
Packit 15a96c
  /* Run script if needed. */
Packit 15a96c
  if (d->script[0])
Packit 15a96c
    runscript(0, d->script, d->username, d->password);
Packit 15a96c
Packit 15a96c
  /* Remember _what_ we dialed.. */
Packit 15a96c
  dial_name = d->name;
Packit 15a96c
  dial_number = d->number;
Packit 15a96c
  dial_user = d->username;
Packit 15a96c
  dial_pass = d->password;
Packit 15a96c
Packit 15a96c
  return;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Dial an entry from the dialing directory; this
Packit 15a96c
 * is used for the "-d" command line flag.
Packit 15a96c
 * Now you can tag multiple entries with the -d option / jl 3.5.1999
Packit 15a96c
 */
Packit 15a96c
void dialone(char *entry)
Packit 15a96c
{
Packit 15a96c
  int num;
Packit 15a96c
  struct dialent *d;
Packit 15a96c
  struct dialent *d1 = (struct dialent *)NULL;
Packit 15a96c
  char *s;
Packit 15a96c
  char buf[128];
Packit 15a96c
Packit 15a96c
  s = strtok(entry,",;");
Packit 15a96c
  while (s) {
Packit 15a96c
    /* Find entry. */
Packit 15a96c
    if ((num = atoi(s)) != 0) {
Packit 15a96c
      if ((d = getno(num - 1))) {
Packit 15a96c
        d->flags |= FL_TAG;
Packit 15a96c
        if (d1 == (struct dialent *)NULL)
Packit 15a96c
          d1 = d;
Packit 15a96c
      }
Packit 15a96c
    } else {
Packit 15a96c
      for (d = dialents; d; d = d->next)
Packit 15a96c
        if (strstr(d->name, s)) {
Packit 15a96c
          d->flags |= FL_TAG;
Packit 15a96c
          if (d1 == (struct dialent *)NULL)
Packit 15a96c
            d1 = d;
Packit 15a96c
        }
Packit 15a96c
    }
Packit 15a96c
    s = strtok(NULL,",;");
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Not found. */
Packit 15a96c
  if (d1 == NULL) {
Packit 15a96c
    snprintf(buf, sizeof(buf), _("Entry \"%s\" not found. Enter dialdir?"), entry);
Packit 15a96c
    if (ask(buf, d_yesno) != 0)
Packit 15a96c
      return;
Packit 15a96c
    dialdir();
Packit 15a96c
    return;
Packit 15a96c
  }
Packit 15a96c
  /* Dial the number! */
Packit 15a96c
  sleep(1);
Packit 15a96c
  dial_entry(d1);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Draw the dialing directory.
Packit 15a96c
 */
Packit 15a96c
void dialdir(void)
Packit 15a96c
{
Packit 15a96c
  WIN *w;
Packit 15a96c
  struct dialent *d = NULL, *d1, *d2;
Packit 15a96c
  static int cur = 0;
Packit 15a96c
  static int ocur = 0;
Packit 15a96c
  int subm = 0;
Packit 15a96c
  int quit = 0;
Packit 15a96c
  static int top = 0;
Packit 15a96c
  int c = 0;
Packit 15a96c
  int pgud = 0;
Packit 15a96c
  int first = 1;
Packit 15a96c
  int x1, x2;
Packit 15a96c
  char *s, dname[128];
Packit 15a96c
  static char manual[128];
Packit 15a96c
  int changed = 0;
Packit 15a96c
  static const char *tag_exit  = N_("( Escape to exit, Space to tag )"),
Packit 15a96c
                    *move_exit = N_(" Move entry up/down, Escape to exit");
Packit 15a96c
  unsigned int tagmvlen = 0;
Packit 15a96c
  size_t i;
Packit 15a96c
  int position_dialing_directory = ((COLS / 2) + 32 - DIALOPTS * DIAL_WIDTH) / 2;
Packit 15a96c
Packit 15a96c
  dprev = -1;
Packit 15a96c
  dname[0] = 0;
Packit 15a96c
  tagmvlen = strlen(_(move_exit));
Packit 15a96c
  if (strlen(_(tag_exit)) > tagmvlen)
Packit 15a96c
    tagmvlen = strlen(_(tag_exit));
Packit 15a96c
Packit 15a96c
  /* Allright, draw the dialing directory! */
Packit 15a96c
Packit 15a96c
  dirflush = 0;
Packit 15a96c
  x1 = (COLS / 2) - 37;
Packit 15a96c
  x2 = (COLS / 2) + 37;
Packit 15a96c
  dsub = mc_wopen(x1 - 1, LINES - 3, x2 + 1, LINES - 3, BNONE,
Packit 15a96c
               XA_REVERSE | stdattr, mfcolor, mbcolor, 0, 0, 1);
Packit 15a96c
  w = mc_wopen(x1, 2, x2, LINES - 6, BSINGLE, stdattr, mfcolor, mbcolor, 0, 0, 1);
Packit 15a96c
  mc_wcursor(w, CNONE);
Packit 15a96c
  mc_wtitle(w, TMID, _("Dialing Directory"));
Packit 15a96c
  mc_wputs(w,
Packit 15a96c
        _("     Name            Number            Last on      Times Script\n"));
Packit 15a96c
  for (i = 0; i < DIALOPTS; i++) {
Packit 15a96c
    const char *str, *c;
Packit 15a96c
    size_t j;
Packit 15a96c
Packit 15a96c
    str = _(what[i]);
Packit 15a96c
    c = str;
Packit 15a96c
    for (j = 0; j < DIAL_WIDTH - 1 && *c != 0; j++) {
Packit 15a96c
      wchar_t wc;
Packit 15a96c
      c += one_mbtowc(&wc, c, MB_LEN_MAX);
Packit 15a96c
    }
Packit 15a96c
    what_lens[i] = c - str;
Packit 15a96c
    j = DIAL_WIDTH - j; /* Characters left for padding */
Packit 15a96c
    what_padding[i][1] = j / 2; /* Rounding down */
Packit 15a96c
    what_padding[i][0] = j - what_padding[i][1]; /* >= 1 */
Packit 15a96c
  }
Packit 15a96c
  mc_wlocate(dsub, position_dialing_directory, 0);
Packit 15a96c
  for (i = 0; i < DIALOPTS; i++)
Packit 15a96c
    horiz_draw(i);
Packit 15a96c
Packit 15a96c
  mc_wsetregion(w, 1, w->ys - 1);
Packit 15a96c
  w->doscroll = 0;
Packit 15a96c
Packit 15a96c
  prdir(w, top, top);
Packit 15a96c
  mc_wlocate(w, position_dialing_directory, w->ys - 1);
Packit 15a96c
  mc_wprintf(w, "%*.*s", tagmvlen,tagmvlen, tag_exit);
Packit 15a96c
  dhili(position_dialing_directory, subm);
Packit 15a96c
  dirflush = 1;
Packit 15a96c
  mc_wredraw(dsub, 1);
Packit 15a96c
Packit 15a96c
again:
Packit 15a96c
  mc_wcurbar(w, cur + 1 - top, XA_REVERSE | stdattr);
Packit 15a96c
  if (first) {
Packit 15a96c
    mc_wredraw(w, 1);
Packit 15a96c
    first = 0;
Packit 15a96c
  }
Packit 15a96c
  while(!quit) {
Packit 15a96c
    d = getno(cur);
Packit 15a96c
    switch (c = wxgetch()) {
Packit 15a96c
      case K_UP:
Packit 15a96c
      case 'k':
Packit 15a96c
        cur -= (cur > 0);
Packit 15a96c
        break;
Packit 15a96c
      case K_DN:
Packit 15a96c
      case 'j':
Packit 15a96c
        cur += (cur < nrents - 1);
Packit 15a96c
        break;
Packit 15a96c
      case K_LT:
Packit 15a96c
      case 'h':
Packit 15a96c
        subm--;
Packit 15a96c
        if (subm < 0)
Packit 15a96c
          subm = DIALOPTS - 1;
Packit 15a96c
        break;
Packit 15a96c
      case K_RT:
Packit 15a96c
      case 'l':
Packit 15a96c
        subm = (subm + 1) % DIALOPTS;
Packit 15a96c
        break;
Packit 15a96c
      case K_PGUP:
Packit 15a96c
      case '\002': /* Control-B */
Packit 15a96c
        pgud = 1;
Packit 15a96c
        quit = 1;
Packit 15a96c
        break;
Packit 15a96c
      case K_PGDN:
Packit 15a96c
      case '\006': /* Control-F */
Packit 15a96c
        pgud = 2;
Packit 15a96c
        quit = 1;
Packit 15a96c
        break;
Packit 15a96c
      case ' ':    /* Tag. */
Packit 15a96c
        mc_wlocate(w, 4, cur + 1 - top);
Packit 15a96c
        d->flags ^= FL_TAG;
Packit 15a96c
        mc_wsetattr(w, XA_REVERSE | stdattr);
Packit 15a96c
        mc_wprintf(w, "%c", d->flags & FL_TAG ? '>' : ' ');
Packit 15a96c
        mc_wsetattr(w, XA_NORMAL | stdattr);
Packit 15a96c
        cur += (cur < nrents - 1);
Packit 15a96c
        break;
Packit 15a96c
      case '\033':
Packit 15a96c
      case '\r':
Packit 15a96c
      case '\n':
Packit 15a96c
      selected:
Packit 15a96c
        quit = (subm == 5 ? 2 : 1);
Packit 15a96c
        break;
Packit 15a96c
      default:
Packit 15a96c
	for (i = 0; i < DIALOPTS; i++) {
Packit 15a96c
	  if (strchr(_(what[i]), toupper(c)) != NULL) {
Packit 15a96c
	    subm = i;
Packit 15a96c
	    goto selected;
Packit 15a96c
	  }
Packit 15a96c
	}
Packit 15a96c
        break;
Packit 15a96c
    }
Packit 15a96c
    /* Decide if we have to delete the cursor bar */
Packit 15a96c
    if (cur != ocur || quit == 1)
Packit 15a96c
      mc_wcurbar(w, ocur + 1 - top, XA_NORMAL | stdattr);
Packit 15a96c
Packit 15a96c
    if (cur < top) {
Packit 15a96c
      top--;
Packit 15a96c
      prdir(w, top, top);
Packit 15a96c
    }
Packit 15a96c
    if (cur - top > w->ys - 3) {
Packit 15a96c
      top++;
Packit 15a96c
      prdir(w, top, top);
Packit 15a96c
    }
Packit 15a96c
    if (cur != ocur)
Packit 15a96c
      mc_wcurbar(w, cur + 1 - top, XA_REVERSE | stdattr);
Packit 15a96c
    ocur = cur;
Packit 15a96c
    dhili(position_dialing_directory, subm);
Packit 15a96c
  }
Packit 15a96c
  quit = 0;
Packit 15a96c
  /* ESC means quit */
Packit 15a96c
  if (c == '\033') {
Packit 15a96c
    if (changed)
Packit 15a96c
      writedialdir();
Packit 15a96c
    mc_wclose(w, 1);
Packit 15a96c
    mc_wclose(dsub, 1);
Packit 15a96c
    return;
Packit 15a96c
  }
Packit 15a96c
  /* Page up or down ? */
Packit 15a96c
  if (pgud == 1) { /* Page up */
Packit 15a96c
    ocur = top;
Packit 15a96c
    top -= w->ys - 2;
Packit 15a96c
    if (top < 0)
Packit 15a96c
      top = 0;
Packit 15a96c
    cur = top;
Packit 15a96c
    pgud = 0;
Packit 15a96c
    if (ocur != top)
Packit 15a96c
      prdir(w, top, cur);
Packit 15a96c
    ocur = cur;
Packit 15a96c
    goto again;
Packit 15a96c
  }
Packit 15a96c
  if (pgud == 2) { /* Page down */
Packit 15a96c
    ocur = top;
Packit 15a96c
    if (top < nrents - w->ys + 2) {
Packit 15a96c
      top += w->ys - 2;
Packit 15a96c
      if (top > nrents - w->ys + 2)
Packit 15a96c
        top = nrents - w->ys + 2;
Packit 15a96c
      cur = top;
Packit 15a96c
    } else
Packit 15a96c
      cur = nrents - 1;
Packit 15a96c
    pgud = 0;
Packit 15a96c
    if (ocur != top)
Packit 15a96c
      prdir(w, top, cur);
Packit 15a96c
    ocur = cur;
Packit 15a96c
    goto again;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Dial an entry */
Packit 15a96c
  if (subm == 0) {
Packit 15a96c
    mc_wclose(w, 1);
Packit 15a96c
    mc_wclose(dsub, 1);
Packit 15a96c
    if (changed)
Packit 15a96c
      writedialdir();
Packit 15a96c
Packit 15a96c
    /* See if any entries were tagged. */
Packit 15a96c
    if (!(d->flags & FL_TAG)) {
Packit 15a96c
      /* First check the entries from the highlighted one to end.. */
Packit 15a96c
      for (d1 = d; d1; d1 = d1->next)
Packit 15a96c
        if (d1->flags & FL_TAG) {
Packit 15a96c
          d = d1;
Packit 15a96c
          break;
Packit 15a96c
        }
Packit 15a96c
      /* ..and if none of them was tagged, check from the begining. */
Packit 15a96c
      if (!d1)
Packit 15a96c
        for (d1 = dialents; d1 && d1!=d; d1 = d1->next)
Packit 15a96c
          if (d1->flags & FL_TAG) {
Packit 15a96c
            d = d1;
Packit 15a96c
            break;
Packit 15a96c
          }
Packit 15a96c
      /* If no tags were found, we'll dial the highlighted one */
Packit 15a96c
    }
Packit 15a96c
    dial_entry(d);
Packit 15a96c
    return;
Packit 15a96c
  }
Packit 15a96c
  /* Find an entry */
Packit 15a96c
  if (subm == 1) {
Packit 15a96c
    s = input(_("Find an entry"), dname);
Packit 15a96c
    if (s == NULL || s[0] == 0)
Packit 15a96c
      goto again;
Packit 15a96c
    x1 = 0;
Packit 15a96c
    for (d = dialents; d; d = d->next, x1++)
Packit 15a96c
      if (strstr(d->name, s))
Packit 15a96c
        break;
Packit 15a96c
    if (d == NULL) {
Packit 15a96c
      mc_wbell();
Packit 15a96c
      goto again;
Packit 15a96c
    }
Packit 15a96c
    /* Set current to found entry. */
Packit 15a96c
    ocur = top;
Packit 15a96c
    cur = x1;
Packit 15a96c
    /* Find out if it fits on screen. */
Packit 15a96c
    if (cur < top || cur >= top + w->ys - 2) {
Packit 15a96c
      /* No, try to put it in the middle. */
Packit 15a96c
      top = cur - (w->ys / 2) + 1;
Packit 15a96c
      if (top < 0)
Packit 15a96c
        top = 0;
Packit 15a96c
      if (top > nrents - w->ys + 2)
Packit 15a96c
        top = nrents - w->ys + 2;
Packit 15a96c
    }
Packit 15a96c
    if (ocur != top)
Packit 15a96c
      prdir(w, top, top);
Packit 15a96c
    ocur = cur;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Add / insert an entry */
Packit 15a96c
  if (subm == 2) {
Packit 15a96c
    d1 = mkstdent();
Packit 15a96c
    if (d1 == (struct dialent *)0) {
Packit 15a96c
      mc_wbell();
Packit 15a96c
      goto again;
Packit 15a96c
    }
Packit 15a96c
    changed++;
Packit 15a96c
    cur++;
Packit 15a96c
    ocur = cur;
Packit 15a96c
    d2 = d->next;
Packit 15a96c
    d->next = d1;
Packit 15a96c
    d1->next = d2;
Packit 15a96c
Packit 15a96c
    nrents++;
Packit 15a96c
    if (cur - top > w->ys - 3) {
Packit 15a96c
      top++;
Packit 15a96c
      prdir(w, top, top);
Packit 15a96c
    } else {
Packit 15a96c
      prdir(w, top, cur);
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Edit an entry */
Packit 15a96c
  if (subm == 3) {
Packit 15a96c
    dedit(d);
Packit 15a96c
    changed++;
Packit 15a96c
    mc_wlocate(w, 0, cur + 1 - top);
Packit 15a96c
    mc_wprintf(w, fmt, cur+1, (d->flags & FL_TAG) ? 16 : ' ', d->name,
Packit 15a96c
            d->number, d->lastdate, d->lasttime, d->count, d->script);
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Delete an entry from the list */
Packit 15a96c
  if (subm == 4 && ask(_("Remove entry?"), d_yesno) == 0) {
Packit 15a96c
    changed++;
Packit 15a96c
    if (nrents == 1) {
Packit 15a96c
      free((char *)d);
Packit 15a96c
      d = dialents = mkstdent();
Packit 15a96c
      prdir(w, top, top);
Packit 15a96c
      goto again;
Packit 15a96c
    }
Packit 15a96c
    if (cur == 0)
Packit 15a96c
      dialents = d->next;
Packit 15a96c
    else
Packit 15a96c
      getno(cur - 1)->next = d->next;
Packit 15a96c
    free((char *)d);
Packit 15a96c
    nrents--;
Packit 15a96c
    if (cur - top == 0 && top == nrents) {
Packit 15a96c
      top--;
Packit 15a96c
      cur--;
Packit 15a96c
      prdir(w, top, top);
Packit 15a96c
    } else {
Packit 15a96c
      if (cur == nrents)
Packit 15a96c
        cur--;
Packit 15a96c
      prdir(w, top, cur);
Packit 15a96c
    }
Packit 15a96c
    if (nrents - top <= w->ys - 3) {
Packit 15a96c
      mc_wlocate(w, 0, nrents - top + 1);
Packit 15a96c
      mc_wclreol(w);
Packit 15a96c
    }
Packit 15a96c
    ocur = cur;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Move the entry up/down in directory. */
Packit 15a96c
  if (subm == 5) {
Packit 15a96c
    mc_wlocate(w, position_dialing_directory, w->ys - 1);
Packit 15a96c
    mc_wprintf(w, "%*.*s", tagmvlen,tagmvlen, move_exit);
Packit 15a96c
    cur = move_entry (w, d, cur, &top);
Packit 15a96c
    if (cur != ocur)
Packit 15a96c
      changed++;
Packit 15a96c
    ocur = cur;
Packit 15a96c
    mc_wlocate(w, position_dialing_directory, w->ys - 1);
Packit 15a96c
    mc_wprintf(w, "%*.*s", tagmvlen,tagmvlen, tag_exit);
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Dial a number manually. */
Packit 15a96c
  if (subm == 6) {
Packit 15a96c
    s = input(_("Enter number"), manual);
Packit 15a96c
    if (s && *s) {
Packit 15a96c
      if (changed)
Packit 15a96c
        writedialdir();
Packit 15a96c
      mc_wclose(w, 1);
Packit 15a96c
      mc_wclose(dsub, 1);
Packit 15a96c
Packit 15a96c
      strncpy(d_man->number, manual, sizeof(d_man->number));
Packit 15a96c
      dial(d_man, (struct dialent**)NULL);
Packit 15a96c
      if (P_SHOWSPD[0] == 'l')
Packit 15a96c
        show_status();
Packit 15a96c
      return;
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
  goto again;
Packit 15a96c
}