/* ppp.c

   Automatic detection of incoming PPP session (as opposed to incoming
   user login... */

/*
 * Copyright (c) 1996 Vixie Enterprises.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of RadioMail Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY RADIOMAIL CORPORATION AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * RADIOMAIL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software was written for Vixie Enterprises by Ted Lemon.
 */

#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1996 Vixie Enterprises.  All rights reserved.\n";
#endif /* not lint */

#include "osdep.h"
#include "cdefs.h"
#include "global.h"
#include "mcap.h"
#include <sys/time.h>
#include <signal.h>

#define EOF -1

void ppp_detect (tty, ttyName)
     int tty;
     char *ttyName;
{
  int ch;
  int seen_flag = 0;
  int seen_addr = 0;
# define IBMAX 511
  unsigned char ibuf [IBMAX + 1];
  char *lbuf;
  int ibix = 0;
  int i;

  /* Print a login prompt (normally /bin/login would do this). */
  ttputs (tty, "login: ");

  do {
    ch = ttgetc (tty);
    if (ch == EOF)
      return;
    if (ch == 0x7e && !seen_flag)
      seen_flag = 1;
    else if (ch == 0xff && seen_flag && !seen_addr)
      {
	/* We believe that this is a PPP packet. */
	info ("PPP login");
	modemcap.do_login = 0;
	modemcap.luser = "ppp";
	modemcap.program = modemcap.ppp_prog;
	modemcap.logstderr = 1;
	setlogin (ttyName);
	return;
      }
    else
      {
	/* This isn't a PPP packet.   Clear any flags we set and echo
	   and buffer any characters we didn't echo and buffer. */
	if (seen_flag)
	  {
	    if (ibix != IBMAX)
	      {
		ttputc (tty, '~');
		ibuf [ibix++] = '~';
	      }
	    else
	      ttputc (tty, 7);

	    seen_flag = seen_addr = 0;
	  }

	/* If it's a delete character, delete the previous character
	   (but don't underrun the buffer). */
	if (ch == 8 || ch == 127)
	  {
	    if (ibix)
	      {
		--ibix;
		if (ibuf [ibix] < 32 || ibuf [ibix] > 126)
		  ttputs (tty, "\010\010\010\010    \010\010\010\010");
		else
		  ttputs (tty, "\010 \010");
	      }
	    else
	      ttputs (tty, "\007");
	  }
	/* If it's a Newline or a Carriage Return, we've got our line
	   of input. */
	else if (ch == 10 || ch == 13)
	  {
	    ttputs (tty, "\r\n");
	    ttoflush (tty);
	    ibuf [ibix++] = 0;
	    lbuf = malloc (strlen (modemcap.program) + ibix + 2);
	    if (!lbuf)
	      error ("Can't allocate space for login string.\n");
	    strcpy (lbuf, modemcap.program);
	    strcat (lbuf, " ");
	    strcat (lbuf, (char *)ibuf);
	    modemcap.program = lbuf;
	    return;
	  }
	else if (ch == 21)
	  {
	    for (i = 0; i < ibix; i++)
	      {
		if (ibuf [i] < 32 || ibuf [i] > 126)
		  ttputs (tty, "\010\010\010\010");
		else
		  ttputc (tty, 8);
	      }

	    for (i = 0; i < ibix; i++)
	      {
		if (ibuf [i] < 32 || ibuf [i] > 126)
		  ttputs (tty, "    ");
		else
		  ttputc (tty, ' ');
	      }

	    for (i = 0; i < ibix; i++)
	      {
		if (ibuf [i] < 32 || ibuf [i] > 126)
		  ttputs (tty, "\010\010\010\010");
		else
		  ttputc (tty, 8);
	      }

	    ibix = 0;
	  }
	else if (ch == 3 || ch == 4 || ch == 28)
	  {
	    ttoflush (tty);
	    error ("Login sequence cancelled by interrupt character");
	  }
	else if (ibix == IBMAX)
	  ttwrite (tty, "\007");
	else
	  {
	    /* Stash the input... */
	    ibuf [ibix++] = ch;

	    if (ch < 32 || ch > 126)
	      {
		char sbuf [5];
		sprintf (sbuf, "\\%03o", ch);
		ttputs (tty, sbuf);
	      }
	    else
	      {
		ttputc (tty, ch);
	      }
	  }
      }
  } while (1);
}
