Ejemplo n.º 1
0
void tty_cooked(register int fd)
{
	register Edit_t *ep = (Edit_t*)(shgd->ed_context);
	ep->e_keytrap = 0;
	if(ep->e_raw==0)
		return;
	if(fd < 0)
		fd = ep->e_savefd;
#ifdef L_MASK
	/* restore flags */
	if(l_changed&L_MASK)
		ioctl(fd,TIOCLSET,&l_mask);
	if(l_changed&T_CHARS)
		/* restore alternate break character */
		ioctl(fd,TIOCSETC,&l_ttychars);
	if(l_changed&L_CHARS)
		/* restore alternate break character */
		ioctl(fd,TIOCSLTC,&l_chars);
	l_changed = 0;
#endif	/* L_MASK */
	/*** don't do tty_set unless ttyparm has valid data ***/
	if(tty_set(fd, TCSANOW, &ttyparm) == SYSERR)
		return;
	ep->e_raw = 0;
	return;
}
Ejemplo n.º 2
0
static SIGRETTYPE ctl_c(int sig)
{
    tty_reset(tty_fd);

    sys_sigset(sig, orig_ctl_c); /* Set ctl_c break handler to original */
    sys_sigrelease(sig);	/* Allow 'sig' to come through */
    kill(getpid(), sig);	/* Send ourselves the signal */
    sys_sigblock(sig);		/* Reset to old mask */
    sys_sigset(sig, ctl_c);	/* Reset signal handler */ 

    tty_set(tty_fd);
}
Ejemplo n.º 3
0
static SIGRETTYPE suspend(int sig)	
{
    tty_reset(tty_fd);

    sys_sigset(sig, SIG_DFL);	/* Set signal handler to default */
    sys_sigrelease(sig);	/* Allow 'sig' to come through */
    kill(getpid(), sig);	/* Send ourselves the signal */
    sys_sigblock(sig);		/* Reset to old mask */
    sys_sigset(sig, suspend);	/* Reset signal handler */

    tty_set(tty_fd);
}
Ejemplo n.º 4
0
/*
**	funkey_meta(test_list, status, ch)
**
**	Test meta key (km) (smm) (rmm)
*/
static void
funkey_meta(
	       TestList * t,
	       int *state,
	       int *ch)
{
    if (has_meta_key) {
	int i, j, k, len;
	char outbuf[256];

	put_crlf();
	if (char_mask != ALLOW_PARITY) {
	    if (tty_meta_prep()) {
		ptext("\nHit any key to continue > ");
		(void) wait_here();
		put_crlf();
	    }
	}
	ptext("Begin meta key test. (km) (smm) (rmm)  Hit any key");
	ptext(" with the meta key.  The character will be");
	ptext(" displayed in hex.  If the meta key is working");
	ptext(" then the most significant bit will be set.  Type");
	ptextln(" 'end' to exit.");
	tty_raw(1, ALLOW_PARITY);
	tc_putp(meta_on);

	for (i = j = k = len = 0; i != 'e' || j != 'n' || k != 'd';) {
	    i = j;
	    j = k;
	    k = getchp(ALLOW_PARITY);
	    if (k == EOF) {
		break;
	    }
	    if ((len += 3) >= columns) {
		put_crlf();
		len = 3;
	    }
	    sprintf(outbuf, "%02X ", k);
	    put_str(outbuf);
	    k &= STRIP_PARITY;
	}
	tc_putp(meta_off);
	put_crlf();
	tty_set();
	put_crlf();
    } else {
	ptext("(km) Has-meta-key is not set.  ");
    }
    generic_done_message(t, state, ch);
}
Ejemplo n.º 5
0
/**** start of autodetect code ***************************/
int is_it_is_it_huh(int port)
{
	int j;

	tty_clear(port, 1, 0);

	ioctl(port, TIOCMGET, &j);
	if ((j & TIOCM_CTS) || (j & TIOCM_DSR))
		return 0;

	tty_set(port, 1, 0);
	ioctl(port, TIOCMGET, &j);
	if ((!(j & TIOCM_CTS)) || (j & TIOCM_DSR))
		return 0;
	return 1;
}
Ejemplo n.º 6
0
int tty_init(int fd, unsigned int baudrate)
{
    /* FIXME: handle speed */
    if (tcgetattr(fd, &tty_rmode) < 0)
      return -1;
    tty_smode = tty_rmode;

    /* Default characteristics for all usage including termcap output. */
    tty_smode.c_iflag &= ~ISTRIP;

    tty_smode.c_iflag |= ICRNL;     /* cr -> nl on input */
    tty_smode.c_lflag &= ~ICANON;   
    tty_smode.c_oflag |= OPOST;     /* nl -> cr-nl .. */
    /* Must get these really right or funny effects can occur. */
    tty_smode.c_cc[VMIN] = 1;
    tty_smode.c_cc[VTIME] = 0;
#ifdef VDSUSP
    tty_smode.c_cc[VDSUSP] = 0;
#endif

    tty_smode.c_cflag &= ~(CSIZE | PARENB); /* clear char-size,diable parity */
    tty_smode.c_cflag |= CS8;               /* 8-bit */
    tty_smode.c_lflag &= ~ECHO;             /* no echo */

    if (tty_set(fd) < 0) {
	tty_fd = -1;
	tty_reset(fd);
	return -1;
    }
    tty_fd = fd;

    sys_sigset(SIGTSTP, suspend);
    sys_sigset(SIGTTIN, suspend);
    sys_sigset(SIGTTOU, suspend);
    orig_ctl_c = sys_sigset(SIGINT, ctl_c);

    return 0;
}
Ejemplo n.º 7
0
/*
**	subtest_xenl(test_list, status, ch)
**
**	(xenl) eat newline glitch
*/
static void
subtest_xenl(
	struct test_list *t,
	int *state,
	int *ch)
{
	int i, j, k;

	if (over_strike) {
		/* test (xenl) on overstrike terminals */
		if (!can_go_home || !can_clear_screen) {
			ptextln("(xenl) Newline-glitch not tested, can't home cursor and clear.");
			generic_done_message(t, state, ch);
			return;
		}
		put_clear();
		/*
		   this test must be done in raw mode.  Otherwise UNIX will
		   translate CR to CRLF.
		*/
		if (stty_query(TTY_OUT_TRANS))
			tty_raw(1, char_mask);
		ptext("\nreset (xenl). Does ");
		i = char_count;
		put_str("not ignore CR, does ");
		k = char_count;
		put_str("not ignore LF");
		go_home();
		for (j = 0; j < columns; j++)
			put_this(' ');
		put_cr();
		for (j = 0; j < i; j++)
			putchp(' ');
		put_str("@@@\n@@");
		go_home();
		for (j = 0; j < columns; j++)
			put_this(' ');
		put_lf();
		for (j = 0; j < k; j++)
			putchp(' ');
		put_str("@@@\r@@");
		tty_set();
		go_home();
		put_newlines(4);
		sprintf(temp, "(xenl) Newline-glitch is %s in the data base",
			eat_newline_glitch ? "true" : "false");
		ptextln(temp);
	} else {
		/* test (xenl) when (os) is reset */
		if (!can_go_home) {
			ptextln("(xenl) Newline-glitch not tested, can't home cursor");
			generic_done_message(t, state, ch);
			return;
		}
		/* (xenl) test */
		put_clear();
		/*
		   this test must be done in raw mode.  Otherwise
		   UNIX will translate CR to CRLF.
		*/
		if (stty_query(TTY_OUT_TRANS))
			tty_raw(1, char_mask);
		for (j = 0; j < columns; j++)
			put_this(' ');
		put_cr();
		ptext("(xenl) should be set. Does not ignore CR");
		go_home();
		put_crlf();
		for (j = 0; j < columns; j++)
			put_this(' ');
		put_lf();	/* test (cud1) */
		ptext("(xenl) should be set. Ignores (cud1)");
		go_home();
		put_newlines(3);
		if (scroll_forward && cursor_down &&
			strcmp(scroll_forward, cursor_down)) {
			for (j = 0; j < columns; j++)
				put_this(' ');
			put_ind();	/* test (ind) */
			ptext("(xenl) should be set. Ignores (ind)");
			go_home();
			put_newlines(5);
		}
		tty_set();
		ptextln("If you don't see text above telling you to set it, (xenl) should be false");
		sprintf(temp, "(xenl) Newline-glitch is %s in the data base",
			eat_newline_glitch ? "true" : "false");
		ptextln(temp);
	}
	generic_done_message(t, state, ch);
}
Ejemplo n.º 8
0
/*
**	curses_setup(exec_name)
**
**	Startup ncurses
*/
void
curses_setup(
	char *exec_name)
{
	int status;
	static TERMTYPE term;
	char tty_filename[2048];

	tty_init();

	/**
	   See if the terminal is in the terminfo data base.  This call has
	two useful benefits, 1) it returns the filename of the terminfo entry,
	and 2) it searches only terminfo's.  This allows us to abort before
	ncurses starts scanning the termcap file.
	**/
	if ((status = _nc_read_entry(tty_basename, tty_filename, &term)) == 0) {
		const TERMTYPE *fallback = _nc_fallback(tty_basename);

		if (fallback) {
		    term = *fallback;
		    sprintf(tty_filename, "(fallback)%s", tty_basename);
		    status = 1;
		} else {
		    fprintf(stderr, "Terminal not found: TERM=%s\n", tty_basename);
		    show_usage(exec_name);
		    exit(1);
		}
	}
	if (status == -1) {
		fprintf(stderr, "Terminfo database is inaccessible\n");
		exit(1);
	}

	/**
	   This call will load the terminfo data base and set the cur-term
	variable.  Only terminals that actually exist will get here so its
	OK to ignore errors.  This is a good thing since ncurses does not
	permit (os) or (gn) to be set.
	**/
	setupterm(tty_basename, 1, &status);

	/**
	   Get the current terminal definitions.  This must be done before
	getting the baudrate.
	**/
	_nc_get_curterm(&cur_term->Nttyb);
	tty_baud_rate = baudrate();
	tty_cps = (tty_baud_rate << 1) / tty_frame_size;

	/* set up the defaults */
	replace_mode = TRUE;
	scan_mode = 0;
	char_count = 0;
	select_delay_type = debug_level = 0;
	char_mask = (meta_on && meta_on[0] == '\0') ? ALLOW_PARITY : STRIP_PARITY;
	/* Don't change the XON/XOFF modes yet. */
	select_xon_xoff = initial_stty_query(TTY_XON_XOFF) ? 1 : needs_xon_xoff;

	fflush(stdout);	/* flush any output */
	tty_set();

	go_home();	/* set can_go_home */
	put_clear();	/* set can_clear_screen */

	if (send_reset_init) {
		reset_init();
	}

	/*
	   I assume that the reset and init strings may not have the correct
	   pads.  (Because that part of the test comes much later.)  Because
	   of this, I allow the terminal some time to catch up.
	*/
	fflush(stdout);	/* waste some time */
	sleep(1);	/* waste more time */
	charset_can_test();
	can_test("lines cols cr nxon rf if iprog rmp smcup rmcup", FLAG_CAN_TEST);
	edit_init();			/* initialize the edit data base */

	if (send_reset_init && enter_ca_mode) {
		tc_putp(enter_ca_mode);
		put_clear();	/* just in case we switched pages */
	}
	put_crlf();
	ptext("Using terminfo from: ");
	ptextln(tty_filename);
	put_crlf();

	if (tty_can_sync == SYNC_NEEDED) {
		verify_time();
	}

	display_basic();
}
Ejemplo n.º 9
0
/*
**	keys_tested(first-time, show-help, hex-output)
**
**	Display a list of the keys not tested.
*/
static void
keys_tested(
	       int first_time,
	       int show_help,
	       int hex_output)
{
    int i, l;
    char outbuf[256];

    alloc_strings();
    put_clear();
    tty_set();
    flush_input();
    if (got_labels) {
	putln("Function key labels:");
	for (i = 0; i < key_count; ++i) {
	    if (fk_label[i]) {
		sprintf(outbuf, "%s %s",
			fk_name[i] ? fk_name[i] : "??", fk_label[i]);
		put_columns(outbuf, (int) strlen(outbuf), 16);
	    }
	}
	put_newlines(2);
    }
    if (funk) {
	putln("The following keys are not defined:");
	for (i = 0; i < funk; ++i) {
	    put_columns(fk_unknown[i], fk_length[i], 16);
	}
	put_mode(exit_attribute_mode);
	put_newlines(2);
    }
    if (first_time) {
	putln("The following keys are defined:");
    } else {
	putln("The following keys have not been tested:");
    }
    if (scan_mode) {
	for (i = 0; scan_down[i]; i++) {
	    if (!scan_tested[i]) {
		if (hex_output) {
		    strcpy(outbuf, hex_expand_to(scan_down[i], 3));
		} else {
		    strcpy(outbuf, expand(scan_down[i]));
		}
		l = expand_chars;
		if (hex_output) {
		    strcat(outbuf, hex_expand_to(scan_up[i], 3));
		} else {
		    strcat(outbuf, expand(scan_up[i]));
		}
		expand_chars += l;
		l = (int) strlen(scan_name[i]);
		if (((char_count + 16) & ~15) +
		    ((expand_chars + 7) & ~7) + l >= columns) {
		    put_crlf();
		} else if (char_count + 24 > columns) {
		    put_crlf();
		} else if (char_count) {
		    putchp(' ');
		}
		put_columns(outbuf, expand_chars, 16);
		put_columns(scan_name[i], l, 8);
	    }
	}
    } else {
	for (i = 0; i < key_count; i++) {
	    if (!fk_tested[i] && fk_name[i] != 0) {
		if (hex_output) {
		    strcpy(outbuf, hex_expand_to(fkval[i], 3));
		} else {
		    strcpy(outbuf, expand(fkval[i]));
		}
		l = (int) strlen(fk_name[i]);
		if (((char_count + 16) & ~15) +
		    ((expand_chars + 7) & ~7) + l >= columns) {
		    put_crlf();
		} else if (char_count + 24 > columns) {
		    put_crlf();
		} else if (char_count) {
		    putchp(' ');
		}
		put_columns(outbuf, expand_chars, 16);
		put_columns(fk_name[i], l, 8);
	    }
	}
    }
    put_newlines(2);
    if (show_help) {
	ptextln("Hit any function key.  Type 'end' to quit.  Type ? to update the display.");
	put_crlf();
    }
}
Ejemplo n.º 10
0
static int
found_exit(char *keybuf, int hx, int cc)
{				/* return true if the user wants to exit */
    int j;
    char *s;

    if (scan_mode) {
	if (*keybuf == '\0') {
	    return TRUE;
	}
    } else {
	int k;

	/* break is a special case */
	if (*keybuf == '\0') {
	    fresh_line();
	    tty_set();
	    ptext("Hit X to exit: ");
	    if (wait_here() == 'X') {
		return TRUE;
	    }
	    keys_tested(0, 1, hx);
	    tty_raw(cc, char_mask);
	    return FALSE;
	}
	/* is this the end? */
	for (k = 0; (j = (keybuf[k] & STRIP_PARITY)); k++) {
	    if (end_funky(j)) {
		return TRUE;
	    }
	}

	j = TRUE;		/* does he need an updated list? */
	for (k = 0; keybuf[k]; k++) {
	    j &= (keybuf[k] & STRIP_PARITY) == '?';
	}
	if (j || end_state == '?') {
	    keys_tested(0, 1, hx);
	    tty_raw(cc, char_mask);
	    end_state = 0;
	    return FALSE;
	}
    }

    put_cr();
    if (hx) {
	s = hex_expand_to(keybuf, 10);
    } else {
	s = expand_to(keybuf, 10);
    }
    sprintf(temp, "%s Unknown", s);
    put_str(temp);
    for (j = 0; j < MAX_FK_UNK; j++) {
	if (j == funk) {
	    fk_length[funk] = expand_chars;
	    if ((fk_unknown[funk] = (char *) malloc(strlen(s) + 1))) {
		strcpy(fk_unknown[funk++], s);
	    }
	    break;
	}
	if (fk_length[j] == expand_chars) {
	    if (!strcmp(fk_unknown[j], s)) {
		break;
	    }
	}
    }
    return FALSE;
}
Ejemplo n.º 11
0
int tty_alt(register int fd)
{
	register Edit_t *ep = (Edit_t*)(shgd->ed_context);
	switch(ep->e_raw)
	{
	    case ECHOMODE:
		return(-1);
	    case ALTMODE:
		return(0);
	    case RAWMODE:
		tty_cooked(fd);
	}
	if((tty_get(fd, &ttyparm)==SYSERR) || (!(ttyparm.c_lflag&ECHO)))
		return(-1);
#	ifdef FLUSHO
	    ttyparm.c_lflag &= ~FLUSHO;
#	endif /* FLUSHO */
	nttyparm = ttyparm;
	ep->e_eof = ttyparm.c_cc[VEOF];
#	ifdef ECHOCTL
	    /* escape character echos as ^[ */
	    nttyparm.c_lflag |= (ECHOE|ECHOK|ECHOCTL|PENDIN|IEXTEN);
	    nttyparm.c_cc[VEOL] = ESC;
#	else
	    /* switch VEOL2 and EOF, since EOF isn't echo'd by driver */
	    nttyparm.c_lflag |= (ECHOE|ECHOK);
	    nttyparm.c_cc[VEOF] = ESC;	/* make ESC the eof char */
#	    ifdef VEOL2
		nttyparm.c_iflag &= ~(IGNCR|ICRNL);
		nttyparm.c_iflag |= INLCR;
		nttyparm.c_cc[VEOL] = '\r';	/* make CR an eol char */
		nttyparm.c_cc[VEOL2] = ep->e_eof; /* make EOF an eol char */
#	    else
		nttyparm.c_cc[VEOL] = ep->e_eof; /* make EOF an eol char */
#	    endif /* VEOL2 */
#	endif /* ECHOCTL */
#	ifdef VREPRINT
		nttyparm.c_cc[VREPRINT] = _POSIX_DISABLE;
#	endif /* VREPRINT */
#	ifdef VDISCARD
		nttyparm.c_cc[VDISCARD] = _POSIX_DISABLE;
#	endif /* VDISCARD */
#	ifdef VWERASE
	    if(ttyparm.c_cc[VWERASE] == _POSIX_DISABLE)
		    nttyparm.c_cc[VWERASE] = cntl('W');
	    ep->e_werase = nttyparm.c_cc[VWERASE];
#	else
	    ep->e_werase = cntl('W');
#	endif /* VWERASE */
#	ifdef VLNEXT
	    if(ttyparm.c_cc[VLNEXT] == _POSIX_DISABLE )
		    nttyparm.c_cc[VLNEXT] = cntl('V');
	    ep->e_lnext = nttyparm.c_cc[VLNEXT];
#	else
	    ep->e_lnext = cntl('V');
#	endif /* VLNEXT */
	ep->e_erase = ttyparm.c_cc[VERASE];
	ep->e_kill = ttyparm.c_cc[VKILL];
	if( tty_set(fd, TCSADRAIN, &nttyparm) == SYSERR )
		return(-1);
	ep->e_ttyspeed = (cfgetospeed(&ttyparm)>=B1200?FAST:SLOW);
	ep->e_raw = ALTMODE;
	return(0);
}
Ejemplo n.º 12
0
int tty_raw(register int fd, int echomode)
{
	int echo = echomode;
#ifdef L_MASK
	struct ltchars lchars;
#endif	/* L_MASK */
	register Edit_t *ep = (Edit_t*)(shgd->ed_context);
	if(ep->e_raw==RAWMODE)
		return(echo?-1:0);
	else if(ep->e_raw==ECHOMODE)
		return(echo?0:-1);
#if !SHOPT_RAWONLY
	if(ep->e_raw != ALTMODE)
#endif /* SHOPT_RAWONLY */
	{
		if(tty_get(fd,&ttyparm) == SYSERR)
			return(-1);
	}
#if  L_MASK || VENIX
	if(ttyparm.sg_flags&LCASE)
		return(-1);
	if(!(ttyparm.sg_flags&ECHO))
	{
		if(!echomode)
			return(-1);
		echo = 0;
	}
	nttyparm = ttyparm;
	if(!echo)
		nttyparm.sg_flags &= ~(ECHO | TBDELAY);
#   ifdef CBREAK
	nttyparm.sg_flags |= CBREAK;
#   else
	nttyparm.sg_flags |= RAW;
#   endif /* CBREAK */
	ep->e_erase = ttyparm.sg_erase;
	ep->e_kill = ttyparm.sg_kill;
	ep->e_eof = cntl('D');
	ep->e_werase = cntl('W');
	ep->e_lnext = cntl('V');
	if( tty_set(fd, TCSADRAIN, &nttyparm) == SYSERR )
		return(-1);
	ep->e_ttyspeed = (ttyparm.sg_ospeed>=B1200?FAST:SLOW);
#   ifdef TIOCGLTC
	/* try to remove effect of ^V  and ^Y and ^O */
	if(ioctl(fd,TIOCGLTC,&l_chars) != SYSERR)
	{
		lchars = l_chars;
		lchars.t_lnextc = -1;
		lchars.t_flushc = -1;
		lchars.t_dsuspc = -1;	/* no delayed stop process signal */
		if(ioctl(fd,TIOCSLTC,&lchars) != SYSERR)
			l_changed |= L_CHARS;
	}
#   endif	/* TIOCGLTC */
#else
	if (!(ttyparm.c_lflag & ECHO ))
	{
		if(!echomode)
			return(-1);
		echo = 0;
	}
#   ifdef FLUSHO
	ttyparm.c_lflag &= ~FLUSHO;
#   endif /* FLUSHO */
	nttyparm = ttyparm;
#  ifndef u370
	nttyparm.c_iflag &= ~(IGNPAR|PARMRK|INLCR|IGNCR|ICRNL);
	nttyparm.c_iflag |= BRKINT;
#   else
	nttyparm.c_iflag &= 
			~(IGNBRK|PARMRK|INLCR|IGNCR|ICRNL|INPCK);
	nttyparm.c_iflag |= (BRKINT|IGNPAR);
#   endif	/* u370 */
	if(echo)
		nttyparm.c_lflag &= ~(ICANON);
	else
		nttyparm.c_lflag &= ~(ICANON|ISIG|ECHO|ECHOK);
	nttyparm.c_cc[VTIME] = 0;
	nttyparm.c_cc[VMIN] = 1;
#   ifdef VREPRINT
	nttyparm.c_cc[VREPRINT] = _POSIX_DISABLE;
#   endif /* VREPRINT */
#   ifdef VDISCARD
	nttyparm.c_cc[VDISCARD] = _POSIX_DISABLE;
#   endif /* VDISCARD */
#   ifdef VDSUSP
	nttyparm.c_cc[VDSUSP] = _POSIX_DISABLE;
#   endif /* VDSUSP */
#   ifdef VWERASE
	if(ttyparm.c_cc[VWERASE] == _POSIX_DISABLE)
		ep->e_werase = cntl('W');
	else
		ep->e_werase = nttyparm.c_cc[VWERASE];
	nttyparm.c_cc[VWERASE] = _POSIX_DISABLE;
#   else
	    ep->e_werase = cntl('W');
#   endif /* VWERASE */
#   ifdef VLNEXT
	if(ttyparm.c_cc[VLNEXT] == _POSIX_DISABLE )
		ep->e_lnext = cntl('V');
	else
		ep->e_lnext = nttyparm.c_cc[VLNEXT];
	nttyparm.c_cc[VLNEXT] = _POSIX_DISABLE;
#   else
	ep->e_lnext = cntl('V');
#   endif /* VLNEXT */
	ep->e_intr = ttyparm.c_cc[VINTR];
	ep->e_eof = ttyparm.c_cc[VEOF];
	ep->e_erase = ttyparm.c_cc[VERASE];
	ep->e_kill = ttyparm.c_cc[VKILL];
	if( tty_set(fd, TCSADRAIN, &nttyparm) == SYSERR )
		return(-1);
	ep->e_ttyspeed = (cfgetospeed(&ttyparm)>=B1200?FAST:SLOW);
#endif
	ep->e_raw = (echomode?ECHOMODE:RAWMODE);
	return(0);
}
Ejemplo n.º 13
0
int pinsys_init(void)
{
	signal_length = (hw.code_length + (hw.code_length / BITS_COUNT) * 2) * 1000000 / 1200;

	if (!tty_create_lock(hw.device)) {
		logprintf(LOG_ERR, "could not create lock files");
		return (0);
	}
	if ((hw.fd = open(hw.device, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) {
		int detected;
		/* last character gets overwritten */
		char auto_lirc_device[] = "/dev/ttyS_";

		tty_delete_lock();
		logprintf(LOG_WARNING, "could not open %s, autodetecting on /dev/ttyS[0-3]", hw.device);
		logperror(LOG_WARNING, "pinsys_init()");
		/* it can also mean you compiled serial support as a
		   module and it isn't inserted, but that's unlikely
		   unless you're me. */

		detected = autodetect();

		if (detected == -1) {
			logprintf(LOG_ERR, "no device found on /dev/ttyS[0-3]");
			tty_delete_lock();
			return (0);
		} else {	/* detected */

			auto_lirc_device[9] = '0' + detected;
			hw.device = auto_lirc_device;
			if ((hw.fd = open(hw.device, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) {
				/* unlikely, but hey. */
				logprintf(LOG_ERR, "couldn't open autodetected device \"%s\"", hw.device);
				logperror(LOG_ERR, "pinsys_init()");
				tty_delete_lock();
				return (0);
			}
		}
	}
	if (!tty_reset(hw.fd)) {
		logprintf(LOG_ERR, "could not reset tty");
		pinsys_deinit();
		return (0);
	}
	if (!tty_setbaud(hw.fd, 1200)) {
		logprintf(LOG_ERR, "could not set baud rate");
		pinsys_deinit();
		return (0);
	}
	/* set RTS, clear DTR */
	if (!tty_set(hw.fd, 1, 0) || !tty_clear(hw.fd, 0, 1)) {
		logprintf(LOG_ERR, "could not set modem lines (DTR/RTS)");
		pinsys_deinit();
		return (0);
	}

	/* I dunno, but when lircd starts may log `reading of byte 1
	   failed' I know that happened when testing, it's a zero
	   byte. Problem is, flushing doesn't fix it. It's not fatal,
	   it's an indication that it gets fixed.  still... */

	if (tcflush(hw.fd, TCIFLUSH) < 0) {
		logprintf(LOG_ERR, "could not flush input buffer");
		pinsys_deinit();
		return (0);
	}
	return (1);
}