/*
 * dip		A program for handling dialup IP connecions.
 *		This program handles the connections needed for dialup
 *		IP links, like SLIP or PPP.  It can handle both incoming
 *		and outgoing connections, using password security for
 *		incoming connections.  The outgoing connections use the
 *		system's dial(3) library if possible.
 *
 * Usage:	dip -i [-v]
 *		dip -k [-v]
 *		dip -t [-v]
 *		dip [-v] [-m mtu] [-p proto] [telno | script]
 *		diplogin [-v]
 *
 * Version:	@(#)main.c	3.3.7	12/13/93
 *
 * Author:      Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 *		Copyright 1988-1993 MicroWalt Corporation
 *
 *		This program is free software; you can redistribute it
 *		and/or  modify it under  the terms of  the GNU General
 *		Public  License as  published  by  the  Free  Software
 *		Foundation;  either  version 2 of the License, or  (at
 *		your option) any later version.
 */
#define GLOBAL
#include "dip.h"

#ifdef __MINT__
#define VERSION	"3.3.7-uri (for MiNT, 23 Oct 94)"
#else
#define VERSION "3.3.7-uri (05 Apr 94)"
#endif

char *Version = "@(#) dip " VERSION;


struct dip	mydip;			/* global DIP entry		*/
int		opt_v = 0;		/* debug flag			*/


/* Kill a running DIP process. */
static void
kill_dip(void)
{
  char buff[128];
  int pid;
  FILE *fp;

  fp = fopen(_PATH_DIP_PID, "rt");
  if (fp == NULL) {
	fprintf(stderr, "DIP: cannot open %s: %s\n",
			_PATH_DIP_PID, strerror(errno));
	return;
  }
  (void) fgets(buff, 128, fp);
  pid = atoi(buff);
  if (kill(pid, SIGHUP)) {
	fprintf(stderr, "DIP: cannot kill process %d: %s\n",
			pid, strerror(errno));
	return;
  } else printf("DIP: process %d killed.\n", pid);
  (void) fclose(fp);
  (void) unlink(_PATH_DIP_PID);
}


/* Fill in the global DIP entry. */
static void
dip_init(void)
{
  struct passwd *pw;
  struct hostent *hp;

  if ((pw = getpwuid(getuid())) == (struct passwd *)NULL) {
	fprintf(stderr, "You do not exist.  Go away!\n");
	exit(-1);
  }
  memset((char *) &mydip, 0, sizeof(struct dip));
  strncpy(mydip.name, pw->pw_name, 16);
  strcpy(mydip.home, "/tmp");

  if (gethostname(mydip.local, 128) < 0) {
	perror("gethostname");
	exit(-1);
  }
#ifdef __MINT__
  /*
   * First try /etc/hosts, because most probably the namserver is on the
   * other end of the slip link.
   */
  if ((hp = (struct hostent *)_gethtbyname (mydip.local)) == NULL)
#endif
  if ((hp = gethostbyname(mydip.local)) == (struct hostent *)NULL) {
	herror(mydip.local);
	strcpy(mydip.local, "");
	exit(-1);
  }
  strncpy(mydip.local, hp->h_name, 128);
  memcpy((char *) &mydip.loc_ip, (char *) hp->h_addr_list[0], hp->h_length);

  strcpy(mydip.protocol, DEF_PROT);
  mydip.protonr = get_prot(mydip.protocol);
  mydip.mtu = DEF_MTU;
}


static void
usage(void)
{
  fprintf(stderr, "Usage: dip -i [-v]\n");
  fprintf(stderr, "       diplogin [-v]\n");
  fprintf(stderr, "       dip -k [-v]\n");
  fprintf(stderr, "       dip -t [-v]\n");
  fprintf(stderr, "       dip [-v] [-m mtu] [-p proto] [telno | script]\n");
  exit(-1);
}


int
main(int argc, char *argv[])
{
  char path[128];
  FILE *fp;
  register int s;
  register char *sp;
  int opt_i, opt_k, opt_t;
#ifdef __MINT__
  extern char *optarg;
  extern int opterr, optind;
#endif

  /* Setup. */
  dip_init();

  strcpy(path, "");
  opt_i = 0;
  opt_k = 0;
  opt_t = 0;

  /*
   * This is a kludge for bad "login" programs which cannot pass
   * arguments. Needless to say, this includes the SLS login(8)
   * program, and most BSD derivatives... -FvK
   */
  if ((sp = strrchr(argv[0], '/')) != NULL) *sp = '\0';
    else sp = argv[0];
  if ((*sp == '-') || !strcmp(sp, "diplogin")) opt_i = 1;

  /* Scan command line for any arguments. */
  opterr = 0;
  while ((s = getopt(argc, argv, "ikm:p:vt")) != EOF) switch(s) {
	case 'i':
		opt_i = 1;
		break;

	case 'k':
		opt_k = 1;
		break;

	case 'm':
		mydip.mtu = atoi(optarg);
		if (mydip.mtu <= 0 || mydip.mtu > 32767) usage();
		break;

	case 'p':
		strcpy(mydip.protocol, optarg);
		mydip.protonr = get_prot(mydip.protocol);
		if (mydip.protonr == 0) usage();
		break;

	case 't':
		opt_t = 1;
		break;

	case 'v':
		opt_v = 1;
		break;

	default:
		usage();
  }

  printf("DIP: Dialup IP Protocol Driver version %s\n", VERSION);
  printf("Written by Fred N. van Kempen, MicroWalt Corporation.\n");
#ifdef __MINT__
  printf("MiNT version by Kay Roemer.\n");
#endif
  printf ("\n");

  /* Are we called to kill off a DIP process? */
  if (opt_k == 1) {
	kill_dip();
	exit(0);
  }
  /* Verbose mode? -> print mydip values */
  if (opt_v == 1) {
	printf("DIP: name=%s home=%s\n",mydip.name,mydip.home);
	printf("     host=%s IP=%s\n",mydip.local,inet_ntoa(mydip.loc_ip));
	printf("     prot=%s MTU=%d\n\n",mydip.protocol,mydip.mtu);
  }

  /* Are we going to be a dialIN server? */
  if (opt_i == 1) {
	if (optind == argc) sp = mydip.name;
	  else sp = argv[optind];
	do_login(sp, &argv[0]);
	/*NOTREACHED*/
  }

  /* Are we running in TEST mode? */
  if (opt_t == 1) {
	if (optind != argc) usage();
	do_command(stdin);
	/*NOTREACHED*/
  }

  /* No, so we are running in dialOUT mode. */
  if (optind != (argc - 1)) usage();
  strncpy(path, argv[optind], 128);
  if ((sp = strrchr(path, '/')) != (char *)NULL) sp++;
    else sp = path;
  if (strchr(sp, '.') == (char *)NULL) strcat(path, DIP_SFX);

  if ((fp = fopen(path, "rt")) == (FILE *)NULL) {
	fprintf(stderr, "dip: %s: %s\n", path, strerror(errno));
	exit(-1);
  }
  (void) setbuf(fp, (char *)NULL);
  do_command(fp);

  /*NOTREACHED*/
  return(-1);
}
