/*
 * dip		A program for handling dialup IP connecions.
 *		Handle the process of going into the background.
 *
 * Version:	@(#)daemon.c	3.3.3	08/16/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.
 */
#include "dip.h"

extern int tty_lock(char *path, int mode);
static void (*oldalrmsig)(int);

/* Catch any signals. */
static void
sig_catcher(int sig)
{
  alarm (0);
  (void) signal (SIGALRM, oldalrmsig);

  (void) tty_close();
  exit(0);
}


static void sig_login_catcher(int sig)
{
  (void) signal (SIGALRM, oldalrmsig);
  alarm (0);

  (void) tty_login_close();
  exit(0);
}



/* Record the current processID in a file. */
static void
dip_record(void)
{
  FILE *fp;

  fp = fopen(_PATH_DIP_PID, "w");
  if (fp == NULL) {
    syslog(LOG_ERR, "DIP: cannot create %s: %s\n",
	   _PATH_DIP_PID, strerror(errno));
    fprintf(stderr, "DIP: cannot create %s: %s\n",
	    _PATH_DIP_PID, strerror(errno));
    return;
  }
  fprintf(fp, "%d", getpid());
  (void) fclose(fp);
}


int
dip_setup(struct dip *dp)
{
  int i;

  oldalrmsig = signal (SIGALRM, SIG_IGN);
  for(i = 1; i < 32; i++) 
    (void) signal(i, SIG_IGN);
  (void) signal(SIGHUP,  sig_login_catcher);
  (void) signal(SIGINT,  sig_catcher);
  (void) signal(SIGTERM, sig_catcher);
  (void) signal(SIGQUIT,  sig_catcher);

  (void) chdir(dp->home);

  /* Fire up the protocol here. */
  protosw[dp->protonr-1].func(dp);

  /* Wait forever to terminate. */
  while(1) {
	(void) sleep(30);
  }

  syslog(LOG_ERR, "DIP must never be here!!!\n");
  return(0);
}



int dip_login_setup(struct dip *dp)
{
  int i;

  oldalrmsig = signal (SIGALRM, SIG_IGN);
  for(i = 1; i < 32; i++) 
    (void) signal(i, SIG_IGN);
  (void) signal(SIGHUP,  sig_login_catcher);
  (void) signal(SIGINT,  sig_catcher);
  (void) signal(SIGTERM, sig_login_catcher);
  (void) signal(SIGQUIT, sig_catcher);

  (void) chdir(dp->home);

  /* Fire up the protocol here. */
  protosw[dp->protonr-1].func(dp);

  /* Wait forever to terminate. */
  while(1) {
	(void) sleep(30);
  }

  return(0);
}



int
dip_daemon(struct dip *dip)
{
  int i;

  /* First of all, fork off a sub-process. */
  if ((i = fork()) < 0) return(-1);
  if (i != 0) exit(0);

#if 1
  /* Make tty the control terminal, detect DCD loss from now. */
  if ((i = tty_notlocal()) < 0)
  	return i;
#endif

  /* Record our PID. */
  dip_record();

  /* Re-acquire the lock */
  (void)tty_lock("no_matter", 2);

  /* Standard BSD behaviour: change to the root dir. */
  return(dip_setup(dip));
}
