#define SCREEN

#include "convert.h"

#include <stdio.h>
#include <curses.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>

#define ARROW 1
#define NO_ARROW 0
#define SAVE 1
#define GET 0


int interactive ();
int start_curses ();
int end_curses ();
int too_small ();
int make_form ();
int fill_struct ();
int read_struct ();
int read_val ();
struct x400_addr *init_addr ();
int gen_slash_addr ();
int gen_or_address ();
int get_char ();
int make_printable ();
int block_signals ();
void handler ();
int my_position ();


/************************************************************
 *
 * int interactive ()
 *
 ************************************************************/
int interactive ()
{
  char s[1025];
  char *x;
  struct x400_addr *x400addr;

  signal(SIGCONT, handler);

  block_signals ();

  start_curses ();

  while (1) {

    x400addr = init_addr(0);

    fill_struct (x400addr,16,2,5,15);

    gen_slash_addr (x400addr, s);
#ifdef DEBUG
    strcpy (x400addr->test, s);
#endif

    if ((strcmp (s, "/")) == 0) {
      if (x400addr->rfc[0]) {
#ifdef USE_DNS
	char *s;
	s = fqdn (x400addr->rfc);
	strcpy (x400addr->rfc, s);
	free (s);
#endif
	x=rfc2or (x400addr->rfc);
	gen_or_addr (x400addr, x);      
#ifdef DEBUG
	strcpy (x400addr->test, x);
#endif
      } else {
	/* Nothing */
      }
    } else {
      x=or2rfc (s);
      strcpy (x400addr->rfc, x);
    }
    free (x);
    make_form (17,2,x400addr, NO_ARROW);
    
    getch();
    erase();
    refresh ();
  }
} /* interactive () */


/************************************************************
 *
 * int start_curses ()
 *
 ************************************************************/
int start_curses ()
{
  static int done=0;

  if (!done) {
    initscr ();
    done = 1;
  }
  noecho ();
  raw ();
  if ((stdscr->_maxx < 80) || (stdscr->_maxy < 24))
    too_small (stdscr->_maxx, stdscr->_maxy);
} /* start_curses () */


/************************************************************
 *
 * int end_curses ()
 *
 ************************************************************/
int end_curses ()
{
  move (LINES-1,0);
  endwin ();
} /* end_curses () */


/************************************************************
 *
 * int too_small (x,y)
 * int x,y;
 *
 ************************************************************/
int too_small (x,y)
int x,y;
{
  char s [256];
  sprintf (s, "Too small a window (%d,%d)\nPress any key ",x,y);
  addstr (s);
  refresh();
  noecho();
  getch();
  end_curses();
  exit (1);
} /* too_small (x,y) */


/************************************************************
 *
 * int make_form (x,y,addr, arrow)
 * int x,y,arrow;
 * struct x400_addr *addr;
 *
 * Leaves cursor at x,y
 *
 ************************************************************/
int make_form (x,y,addr, arrow)
int x,y,arrow;
struct x400_addr *addr;
{
  int i;

  erase();

  if (arrow == ARROW) {
    move (y,0);
    addstr ("->");
  }

  /* box (stdscr, '|', '-'); */
  move (0,15);
  addstr (" ADDRESS CONVERTER ");
  i=1;

  move (++i,4);
  addstr ("Country    :");
  move (i,17);
  addstr (addr->c);
  move (++i,4);
  addstr ("ADMD       :");
  move (i,17);
  if (strcmp (addr->admd, " "))
    addstr (addr->admd);
  else
    addstr ("<space>");
  move (++i,4);
  addstr ("PRMD       :");
  move (i,17);
  addstr (addr->prmd);
  move (++i,4);
  addstr ("Org        :");
  move (i,17);
  addstr (addr->o);
  move (++i,4);
  addstr ("OU1        :");
  move (i,17);
  addstr (addr->ou1);
  move (++i,4);
  addstr ("OU2        :");
  move (i,17);
  addstr (addr->ou2);
  move (++i,4);
  addstr ("OU3        :");
  move (i,17);
  addstr (addr->ou3);
  move (++i,4);
  addstr ("OU4        :");
  move (i,17);
  addstr (addr->ou4);
  move (++i,4);
  addstr ("Surname    :");
  move (i,17);
  addstr (addr->s);
  move (++i,4);
  addstr ("Initials   :");
  move (i,17);
  addstr (addr->i);
  move (++i,4);
  addstr ("Given name :");
  move (i,17);
  addstr (addr->g);
  move (++i,4);
  addstr ("Generation :");
  move (i,17);
  addstr (addr->gq);
  move (++i,4);

  addstr ("DD.        :");
  move (i,7);
  if (addr->dd1_type[0])
    addstr (addr->dd1_type);
  else
    addstr ("<type>");
  if (addr->dd1_value[0]) {
    move (i,17);
    addstr (addr->dd1_value);
  }
  i++;
  move (i,4);
  addstr ("DD.        :");
  move (i,7);
  if (addr->dd2_type[0])
    addstr (addr->dd2_type);
  else
    addstr ("<type>");
  if (addr->dd2_value[0]) {
    move (i,17);
    addstr (addr->dd2_value);
  }
  i++;
  move (i,4);
  addstr ("DD.        :");
  move (i,7);
  if (addr->dd3_type[0])
    addstr (addr->dd3_type);
  else
    addstr ("<type>");
  if (addr->dd3_value[0]) {
    move (i,17);
    addstr (addr->dd3_value);
  }
  i++;
  move (i,4);
  addstr ("DD.        :");
  move (i,7);
  if (addr->dd4_type[0])
    addstr (addr->dd4_type);
  else
    addstr ("<type>");
  if (addr->dd4_value[0]) {
    move (i,17);
    addstr (addr->dd4_value);
  }
  i++;
  i++;

  move (i,4);
  addstr ("Internet   :");
  move (i,17);
  addstr (addr->rfc);
#ifdef DEBUG
  i++;
  move (i,4);
  addstr ("Test       :");
  move (i,17);
  addstr (addr->test);
#endif
  move (y,x);
  refresh ();
} /* make_form (x,y,addr, arrow) */


/************************************************************
 *
 * int fill_struct (addr)
 * struct x400_addr *addr;
 *
 ************************************************************/
int fill_struct (addr)
struct x400_addr *addr;
{
  int i=1,j;

  make_form (16,2,addr, NO_ARROW);

  while (i) {
    j=read_struct (addr,i);
    if (j == 1)
      i++;
    else if (j == 14) {
      i++;
      if ((i == 13) || (i == 15) || (i == 17) || (i == 19) ||
	  (i == 14) || (i == 16) || (i == 18))
	i++;
    } else if (j == 16) {
      i--;
      if (i == 0)
	i = 21;
      if ((i == 13) || (i == 15) || (i == 17) || (i == 19) ||
	  (i == 14) || (i == 16) || (i == 18))
	i--;
    } else if (j == 2) {
      if ((i == 14) || (i == 16) || (i == 18) || (i == 20))
	i--;
    } else if (j == 6) {
      if ((i == 13) || (i == 15) || (i == 17) || (i == 19))
	i++;
    } else if (j == 0)
      i=0;
    else {
      fprintf (stderr, "Something went wrong\n");
      exit (2);
    }
    if (i == 22)
      i = 1;
  }
  make_form (16,2,addr, NO_ARROW);
} /* fill_struct (addr) */


/************************************************************
 *
 * int read_struct (addr,which)
 * struct x400_addr *addr;
 * int which;
 *
 ************************************************************/
int read_struct (addr,which)
struct x400_addr *addr;
int which;
{
  int i;

  switch (which) {

  case (1):
    make_form (17,2,addr, ARROW); 
    i=read_val (addr->c, 2, addr, 1); 
    make_printable (addr->c, 2);
    return (i);
  case (2):
    make_form (17,3,addr, ARROW); 
    i=read_val (addr->admd, 16, addr, 1);
    make_printable (addr->admd, 16);
    return (i);
  case (3):
    make_form (17,4,addr, ARROW); 
    i=read_val (addr->prmd, 16, addr, 1);
    make_printable (addr->prmd, 16);
    return (i);
  case (4):
    make_form (17,5,addr, ARROW); 
    i=read_val (addr->o, 64, addr, 1);
    make_printable (addr->o, 64);
    return (i);
  case (5):
    make_form (17,6,addr, ARROW); 
    i=read_val (addr->ou1, 32, addr, 1);
    make_printable (addr->ou1, 32);
    return (i);
  case (6):
    make_form (17,7,addr, ARROW); 
    i=read_val (addr->ou2, 32, addr, 1);
    make_printable (addr->ou2, 32);
    return (i);
  case (7):
    make_form (17,8,addr, ARROW); 
    i=read_val (addr->ou3, 32, addr, 1);
    make_printable (addr->ou3, 32);
    return (i);
  case (8):
    make_form (17,9,addr, ARROW); 
    i=read_val (addr->ou4, 32, addr, 1);
    make_printable (addr->ou4, 32);
    return (i);
  case (9):
    make_form (17,10,addr, ARROW); 
    i=read_val (addr->s, 40, addr, 1);
    make_printable (addr->s, 40);
    return (i);
  case (10):
    make_form (17,11,addr, ARROW); 
    i=read_val (addr->i, 5, addr, 1);
    make_printable (addr->i, 5);
    return (i);
  case (11):
    make_form (17,12,addr, ARROW); 
    i=read_val (addr->g, 16, addr, 1);
    make_printable (addr->g, 16);
    return (i);
  case (12):
    make_form (17,13,addr, ARROW); 
    i=read_val (addr->gq, 3, addr, 1);
    make_printable (addr->gq, 3);
    return (i);

  case (13):
    make_form (7,14,addr, ARROW); 
    i=read_val (addr->dd1_type, 8, addr, 1);
    make_printable (addr->dd1_type, 8);
    if (addr->dd1_type[0] == 0)
      addr->dd1_value[0] = 0;
    return (i);
  case (14):
    make_form (17,14,addr, ARROW); 
    i=read_val (addr->dd1_value, 128, addr, 1);
    make_printable (addr->dd1_value, 128);
    return (i);

  case (15):
    make_form (7,15,addr, ARROW); 
    i=read_val (addr->dd2_type, 8, addr, 1);
    make_printable (addr->dd2_type, 8);
    if (addr->dd2_type[0] == 0)
      addr->dd2_value[0] = 0;
    return (i);
  case (16):
    make_form (17,15,addr, ARROW); 
    i=read_val (addr->dd2_value, 128, addr, 1);
    make_printable (addr->dd2_value, 128);
    return (i);

  case (17):
    make_form (7,16,addr, ARROW); 
    i=read_val (addr->dd3_type, 8, addr, 1);
    make_printable (addr->dd3_type, 8);
    if (addr->dd3_type[0] == 0)
      addr->dd3_value[0] = 0;
    return (i);
  case (18):
    make_form (17,16,addr, ARROW); 
    i=read_val (addr->dd3_value, 128, addr, 1);
    make_printable (addr->dd3_value, 128);
    return (i);

  case (19):
    make_form (7,17,addr, ARROW); 
    i=read_val (addr->dd4_type, 8, addr, 1);
    make_printable (addr->dd4_type, 8);
    if (addr->dd4_type[0] == 0)
      addr->dd4_value[0] = 0;
    return (i);
  case (20):
    make_form (17,17,addr, ARROW); 
    i=read_val (addr->dd4_value, 128, addr, 1);
    make_printable (addr->dd4_value, 128);
    return (i);

  case (21):
    make_form (17,19,addr, ARROW);
    i=read_val (addr->rfc, 1024, addr, 0);
    if (i) {
      char c[1024];
      strcpy (c, addr->rfc);
      init_addr (addr);
      strcpy (addr->rfc, c);
    }
    return (i);

  default:
    exit (2);
  }
} /* read_struct (addr,which) */


/************************************************************
 *
 * int read_val (str, len, addr)
 * struct x400_addr *addr;
 * char *str;
 * int len;
 *
 * Return 0 if user presses <ESC>, othervice 1.
 *
 ************************************************************/
int read_val (str, len, addr)
struct x400_addr *addr;
char *str;
int len;
{
  int i=0,c;
  int y_orig, x_orig;
  char *s;
  int ret_val = 1;

  getyx (stdscr, y_orig, x_orig);
  s = (char *)malloc (len+1);
  if (s == 0) {
    perror ("allocating memory");
    exit (1);
  }

  while (i<len+1) {
    s[i] = get_char();
    if ((s[i] == 10) || (s[i] == 13)) { /* <RET> */
      s[i] = 0;
      i=len+1;
    } else if ((s[i] == 8) || (s[i] == 127)) { /* <BS> or <DEL> */
      if (i > 0) {
	move (y_orig, x_orig+i-1);
	clrtoeol();
	move (y_orig, COLS);
	move (y_orig, x_orig+i-1);
	refresh();
	i--;
      } else {
	int x,y;
	str[0] = 0;
	getyx (stdscr, y, x);
	make_form (x,y,addr, ARROW);
      }
    } else if ((s[i] == 3) || (s[i] == 4)) { /* ^C or ^D */
                        /* If (or when) ^D is treated as EOF
			 * pressing it doesn't actually work.
			 */
      end_curses ();
      exit (0);
    } else if (s[i] == 26) { /* ^Z */
      int pid, i;
      my_position (SAVE);
      pid = getpid ();
      if (pid)
	kill (pid, SIGSTOP);
      if (i == -1) {
	perror ("sending SIGSTOP");
	exit (1);
      }
    } else if (s[i] == 12) { /* ^L */
      int x,y;
      getyx (stdscr, y, x);
      s[i] = 0;
      if (s[0] != NULL)
	strcpy (str,s);
      clear ();
      make_form (x,y,addr,ARROW);
    } else if (s[i] == 27) { /* <ESC> */
      c = getch();
      if (c == 27) {
	free (s);
	return (0);
      }
      else if (c == '[') {
        c=getch ();
        switch (c) {
        case 65:
	  s[i] = 0;
	  if (s[0] != NULL)
	    strcpy (str,s);
	  free (s);
	  return (16);
          break;
        case 66:
	  s[i] = 0;
	  if (s[0] != NULL)
	    strcpy (str,s);
	  free (s);
	  return (14);
          break;
        case 68:
	  s[i] = 0;
	  if (s[0] != NULL)
	    strcpy (str,s);
	  free (s);
	  return (2);
          break;
        case 67:
	  s[i] = 0;
	  if (s[0] != NULL)
	    strcpy (str,s);
	  free (s);
	  return (6);
          break;
        }
      }
    } else if (s[i] == 14) { /* ^N */
      s[i] = 0;
      if (s[0] != NULL)
	strcpy (str,s);
      free (s);
      return (14);
    } else if (s[i] == 2) { /* ^B */
      s[i] = 0;
      if (s[0] != NULL)
	strcpy (str,s);
      free (s);
      return (2);
    } else if (s[i] == 6) { /* ^F */
      s[i] = 0;
      if (s[0] != NULL)
	strcpy (str,s);
      free (s);
      return (6);
    } else if (s[i] == 16) { /* ^P */
      s[i] = 0;
      if (s[0] != NULL)
	strcpy (str,s);
      free (s);
      return (16);
    } else {
      addch (s[i]);
      refresh();
      i++;
      if (i == len+1) {
	int x,y;
	i--;
	getyx (stdscr, y, x);
	move (y,x-1);
	refresh();
      }
    }
  }
  s[len+1] = 0;
  if (s[0] != NULL)
    strcpy (str,s);
  free (s);
  return (1);
} /* read_val (str, len, addr) */


/************************************************************
 *
 * struct x400_addr *init_addr (addr)
 * struct x400_addr *addr;
 *
 ************************************************************/
struct x400_addr *init_addr (addr)
struct x400_addr *addr;
{
  if (addr == 0) {
    addr = (struct x400_addr*)malloc (sizeof (struct x400_addr));
    if (addr == NULL) {
      perror ("allocating memory");
      exit (1);
    }
  }
  addr->c[0]=0;
  addr->admd[0]=0;
  addr->prmd[0]=0;
  addr->o[0]=0;
  addr->ou1[0]=0;
  addr->ou2[0]=0;
  addr->ou3[0]=0;
  addr->ou4[0]=0;
  addr->s[0]=0;
  addr->g[0]=0;
  addr->i[0]=0;
  addr->gq[0]=0;
  addr->dd1_type[0]=0;
  addr->dd1_value[0]=0;
  addr->dd2_type[0]=0;
  addr->dd2_value[0]=0;
  addr->dd3_type[0]=0;
  addr->dd3_value[0]=0;
  addr->dd4_type[0]=0;
  addr->dd4_value[0]=0;
  addr->rfc[0]=0;
#ifdef DEBUG
  addr->test[0]=0;
#endif
  return (addr);
} /* init_addr (addr) */


/************************************************************
 *
 * int gen_slash_addr (addr, str)
 * struct x400_addr *addr;
 * char *str;
 *
 ************************************************************/
int gen_slash_addr (addr, str)
struct x400_addr *addr;
char *str;
{
  char s[1025];

  str[0]='/';
  str[1]=0;

  if (addr->c[0]) {
    sprintf (s, "/C=%s%s", addr->c, str);
    strcpy (str, s);
  }
  if (addr->admd[0]) {
    sprintf (s, "/ADMD=%s%s", addr->admd, str);
    strcpy (str, s);
  }
  if (addr->prmd[0]) {
    sprintf (s, "/PRMD=%s%s", addr->prmd, str);
    strcpy (str, s);
  }
  if (addr->o[0]) {
    sprintf (s, "/O=%s%s", addr->o, str);
    strcpy (str, s);
  }
  if (addr->ou1[0]) {
    sprintf (s, "/OU1=%s%s", addr->ou1, str);
    strcpy (str, s);
  }
  if (addr->ou2[0]) {
    sprintf (s, "/OU2=%s%s", addr->ou2, str);
    strcpy (str, s);
  }
  if (addr->ou3[0]) {
    sprintf (s, "/OU3=%s%s", addr->ou3, str);
    strcpy (str, s);
  }
  if (addr->ou4[0]) {
    sprintf (s, "/OU4=%s%s", addr->ou4, str);
    strcpy (str, s);
  }
  if (addr->s[0]) {
    sprintf (s, "/S=%s%s", addr->s, str);
    strcpy (str, s);
  }
  if (addr->g[0]) {
    sprintf (s, "/G=%s%s", addr->g, str);
    strcpy (str, s);
  }
  if (addr->i[0]) {
    sprintf (s, "/I=%s%s", addr->i, str);
    strcpy (str, s);
  }
  if (addr->gq[0]) {
    sprintf (s, "/GQ=%s%s", addr->gq, str);
    strcpy (str, s);
  }
  if (addr->dd1_type[0]) {
    sprintf (s, "/DD.%s=%s%s", addr->dd1_type, addr->dd1_value, str);
    strcpy (str, s);
  }
  if (addr->dd2_type[0]) {
    sprintf (s, "/DD.%s=%s%s", addr->dd2_type, addr->dd2_value, str);
    strcpy (str, s);
  }
  if (addr->dd3_type[0]) {
    sprintf (s, "/DD.%s=%s%s", addr->dd3_type, addr->dd3_value, str);
    strcpy (str, s);
  }
  if (addr->dd4_type[0]) {
    sprintf (s, "/DD.%s=%s%s", addr->dd4_type, addr->dd4_value, str);
    strcpy (str, s);
  }
} /* gen_slash_addr (addr, str) */


/************************************************************
 *
 * int gen_or_addr (addr, str)
 * struct x400_addr *addr;
 * char *str;
 *
 ************************************************************/
int gen_or_addr (addr, str)
struct x400_addr *addr;
char *str;
{
  char *c;
  int phase = 0;
  int dd_phase = 0;

  c = (char *) strrchr (str, '/');

  while (c) {
    if (strlen (c) > 1) {
      if ((c[1] == 'C') && (c[2] == '=')) {
	strcpy (addr->c, &c[3]);
      }  else if (c[1] == 'A') {
	strcpy (addr->admd, &c[6]);
      } else if (c[1] == 'P') {
	strcpy (addr->prmd, &c[6]);
      } else if ((c[1] == 'O') && (c[2] == '=')) {
	strcpy (addr->o, &c[3]);
      } else if ((c[1] == 'O') && (c[2] == 'U')) {
	phase++;
	switch (phase) {
	case 1:
	  strcpy (addr->ou1, &c[4]);
	  break;
	case 2:
	  strcpy (addr->ou2, &c[4]);
	  break;
	case 3:
	  strcpy (addr->ou3, &c[4]);
	  break;
	case 4:
	  strcpy (addr->ou4, &c[4]);
	  break;
	}
      } else if (c[1] == 'S') {
	strcpy (addr->s, &c[3]);
      } else if (c[1] == 'G') {
	strcpy (addr->g, &c[3]);
      } else if (c[1] == 'I') {
	strcpy (addr->i, &c[3]);
      } else if ((c[1] == 'G') && (c[2] == 'Q')) {
	strcpy (addr->gq, &c[4]);
      } else if (c[1] == 'R') {
	dd_phase++;
	switch (dd_phase) {
	case 1:
	  c = (char *) strrchr (str, '=');
	  strcpy (addr->dd1_value, &c[1]);
	  c[0] = 0;
	  c = (char *) strrchr (str, '/');
	  strcpy (addr->dd1_type, &c[1]);
	  break;
	case 2:
	  c = (char *) strrchr (str, '=');
	  strcpy (addr->dd2_value, &c[1]);
	  c[0] = 0;
	  c = (char *) strrchr (str, '/');
	  strcpy (addr->dd2_type, &c[1]);
	  break;
	case 3:
	  c = (char *) strrchr (str, '=');
	  strcpy (addr->dd3_value, &c[1]);
	  c[0] = 0;
	  c = (char *) strrchr (str, '/');
	  strcpy (addr->dd3_type, &c[1]);
	  break;
	case 4:
	  c = (char *) strrchr (str, '=');
	  strcpy (addr->dd4_value, &c[1]);
	  c[0] = 0;
	  c = (char *) strrchr (str, '/');
	  strcpy (addr->dd4_type, &c[1]);
	  break;
	}
      } else if (c[1] == 'D') {
	dd_phase++;
	switch (dd_phase) {
	case 1:
	  c = (char *) strrchr (str, '=');
	  strcpy (addr->dd1_value, &c[1]);
	  c[0] = 0;
	  c = (char *) strrchr (str, '/');
	  strcpy (addr->dd1_type, &c[4]);
	  break;
	case 2:
	  c = (char *) strrchr (str, '=');
	  strcpy (addr->dd2_value, &c[1]);
	  c[0] = 0;
	  c = (char *) strrchr (str, '/');
	  strcpy (addr->dd2_type, &c[4]);
	  break;
	case 3:
	  c = (char *) strrchr (str, '=');
	  strcpy (addr->dd3_value, &c[1]);
	  c[0] = 0;
	  c = (char *) strrchr (str, '/');
	  strcpy (addr->dd3_type, &c[4]);
	  break;
	case 4:
	  c = (char *) strrchr (str, '=');
	  strcpy (addr->dd4_value, &c[1]);
	  c[0] = 0;
	  c = (char *) strrchr (str, '/');
	  strcpy (addr->dd4_type, &c[4]);
	  break;
	}
      }
    }
    c[0] = 0;
    c = (char *) strrchr (str, '/');
  }
} /* gen_or_addr (addr, str) */


/************************************************************
 *
 * int get_char ()
 *
 * Some control characters may mess the screen totally, so it's
 * better to strip them off.
 *
 ************************************************************/
int get_char ()
{
  int i=0;
  while (!i) {
    i = getch ();
    if ((i <= 1) ||                    /* 2 = ^B */
	((i >= 4) && (i <= 5)) ||      /* 3 = ^C */
	(i == 7) ||                    /* 6 = ^F */
	(i == 9) ||                    /* 8 = Back Space */
	(i == 11) ||                   /* 10 = New Line */
	                               /* 12 = ^L */
	                               /* 13 = Carriage Return */
	(i == 15) ||                   /* 14 = ^N */
	((i >= 17) && (i <= 25)) ||    /* 16 = ^P */
	((i >= 28) && (i <= 31)) ||    /* 26 = ^Z */
	(i > 127))                     /* 27 = Esc */
      i = 0;
  }
  return (i);
} /* get_char () */


/************************************************************
 *
 * int make_printable (str, len)
 * char *str;
 * int len;
 *
 ************************************************************/
int make_printable (str, len)
char *str;
int len;
{
  int i,j;
  char *s;
  char c;

  s = (char *)malloc (len + 3);
  if (s == 0) {
    perror ("allocating memory");
    exit (1);
  }
  i=0; j=0;
  while ((i <= len) && (j <= len)) {
    c=str[i];
    if ((isdigit (c)) ||
	(isalpha (c)) ||
	(c == ' ') ||
	(c == '\'') ||
	(c == '+') ||
	(c == ',') ||
	(c == '-') ||
	(c == '.') ||
	(c == ':') ||
	(c == '=') ||
	(c == '?') ||
	(c == 0)) {
      s[j] = c;
    } else if (c == '@') {
      s[j++] = '(';
      s[j++] = 'a';
      s[j] = ')';
    } else if (c == '%') {
      s[j++] = '(';
      s[j++] = 'p';
      s[j] = ')';
    } else if (c == '!') {
      s[j++] = '(';
      s[j++] = 'b';
      s[j] = ')';
    } else if (c == '"') {
      s[j++] = '(';
      s[j++] = 'q';
      s[j] = ')';
    } else if (c == '_') {
      s[j++] = '(';
      s[j++] = 'u';
      s[j] = ')';
    } else if (c == '(' ) {
      s[j++] = '(';
      s[j++] = 'l';
      s[j] = ')';
    } else if (c == ')' ) {
      s[j++] = '(';
      s[j++] = 'r';
      s[j] = ')';
    } else {
      int apu;
      s[j++] = '(';
      apu = c/100;
      s[j++] = apu;
      while (c >= 100)
	c =- 100;
      apu = c/10;
      s[j++] = apu;
      while (c >= 10)
	c =- 10;
      s[j++] = c;
      s[j] = ')';
    }
    i++; j++;
  }
  s[len+1] = 0;
  strcpy (str, s);
} /* make_printable (str, len) */


/************************************************************
 *
 * int block_signals ()
 *
 * Here are all of the signals. I used numbers instead of
 * macro names to simplify my code
 * 
 * SIGHUP	1
 * SIGINT	2
 * SIGQUIT	3
 * SIGILL	4
 * SIGTRAP	5
 * SIGIOT	6
 * SIGABRT	6
 * SIGEMT	7
 * SIGFPE	8
 * SIGKILL	9
 * SIGBUS	10
 * SIGSEGV	11
 * SIGSYS	12
 * SIGPIPE	13
 * SIGALRM	14
 * SIGTERM	15
 * SIGURG	16
 * SIGSTOP	17
 * SIGTSTP	18
 * SIGCONT	19
 * SIGCHLD	20
 * SIGCLD	20
 * SIGTTIN	21
 * SIGTTOU	22
 * SIGIO	23
 * SIGXCPU	24
 * SIGXFSZ	25
 * SIGVTALRM	26
 * SIGPROF	27
 * SIGWINCH	28
 * SIGLOST	29
 * SIGUSR1	30
 * SIGUSR2	31
 * 
 * Block anything but STOP and KILL. (Systes doesn't let them to be
 * blocked.) Also don't block CONT.
 *
 ************************************************************/
int block_signals ()
{
  int mask, i;

  i = 1;

  while (i < 31) {
    if (i != SIGCONT) {
      mask = sigmask (i);
      sigblock (mask);
    }
    i++;
  }
} /* block_signals () */

void handler()
{
  my_position (GET);
  refresh ();
  start_curses ();
} /* handler() */


/************************************************************
 *
 * int my_position (action)
 * int action;
 *
 ************************************************************/
int my_position (action)
int action;
{
  static int x=-1, y=0;

  if (action == SAVE) {
	getyx (stdscr, y, x);
  } else if (action == GET) {
    if (x < 0) {
      /* Nothing - not initialized */
    } else {
      move (y,x);
    }
  } else {
    fprintf (stderr, "Wrong usage: my_position\n");
    exit (1);
  }
} /* my_position (action) */
