/*
*
* uustatus - display UUCP communications status for HDB systems
*
* usage: uustatus [-obui]
*
* Written 01/19/89 by Ed Carp
*
* Copyright 1989, by Edwin R. Carp
*
* Version     Date     Status       Comments
*
*  1.0.c    01/21/89   INTERNAL     IO display, number of IO msgs, uucico log
*                                   file display, <sys/types.h> include.
*
*  1.0.d    01/24/89   PREREL       tails first system talking instead of
*                                   last, displays star on system tailed,
*                                   improved method of tailing log files,
*                                   create status files if they don't exist.
*                                   now should be owned by uucp or nuucp.
*
*  1.1      01/25/89   RELEASE      Released version to USENET.
*
*  1.1.a    01/26/89   PREREL       Fixed XENIX defines.
*
*  1.1.b    01/28/89   PREREL       Display time/date.
*
*  1.1.c    02/03/87   PREREL       Added -b, -o options.
*
*  1.1.d    03/02/89   PREREL       Took out 2 second wait before init.
*
*  1.1.e    03/08/89   PREREL       -u option kicks off uucico for sites that
*                                   have files.
*
*  1.1.f    12/04/89   REPOST       Fixes case where program dumps core if
*                                   log file goes away while program is running.
*
*  1.1.fa   07/08/92   SPLIT        Added -i flag (only display systems that
*                                   have work).
*
*  1.1.fb   07/15/92   SPLIT        Reduce tail startup time by doing an fseek.
*
*  1.2      07/16/92   REPOST       Delete "NEXT TRY", add "CPS I/O".
*
*  1.2.a    07/17/92   REPOST       Fixed bugs in CPS display.
*
*  1.2.b    07/17/92   REPOST       More bug fixes.  Now works for SVR4 uucp.
*
*  1.2.c    07/17/92                If transfer takes less than XFERTIME, we
*                                   ignore those stats, since they are probably
*                                   artifically low.
*
*  1.2.d    08/10/92   REPOST       Bug fixes by Cory West and Michael Traub.
*                                   Now does proper averaging for cps.
*
*  1.2.e    08/25/92   PATCH        Stupid Bug fixes. Thanks to Michael
*                                   Traub for (again) saving my ass. :)
*
*  1.3      08/28/92                Incorporated contributions from
*                                   anonymous sources on the net.  Adds
*                                   functionality for Sun's.
*
*/

#include <stdio.h>
#include <sys/types.h>
#ifdef SUN
#include	<sys/time.h>
#endif
#include <sys/stat.h>
#include <curses.h>
#ifdef defined(hpux) || defined(M_XENIX)
#include <sys/ndir.h>
#define dirent direct
#else
#include <dirent.h>
#endif
#include <time.h>
#include <signal.h>
#define YES 1
#define NO 0
#include "uustatus.h"
#include "patchlevel.h"
#include "basename.fun"
#include "touch.fun"

#ifdef NULL
#undef NULL
#define NULL (0)
#endif
DIR *din, *win;
struct dirent *dp, *dpw;
FILE *in, *exp;
FILE *tin;
FILE *xfer;			/* for XFERSTATS */
char ltname[64], *strtok();
char tline[50][132];	/* bad hack to handle bigger screens (should malloc) */
extern char *optarg;
extern int optind, opterr;
int bflag = 0, oflag = 0, uflag = 0, iflag = 0;
int icps, ocps;
int xsave, ysave;
long xfertime = 0L;
#ifdef SVR4
char *gptr;
#endif

   int	sysline = 1;
#ifdef SUN
   char	workstr[128];
   int poll_flag = 0;
   fd_set rd_set;

   struct timeval timer;

   static void catch_child();
#include	<sys/wait.h>
#include	<errno.h>
#endif


main (argc, argv)
     int argc;
     char **argv;
{
   char line[512], lock[64], cretries[6], *lptr;
   char cfiles[6], work[64], name[25], tname[64], c;
   int i, status, ifiles, ofiles, files, retries, bye ();
   int systems, expflag, display, ret, tnameset = 0;
   long secs, retryt, curr;
   struct tm *t1, *t2;
   int	fork_retval;


   while ((c = getopt (argc, argv, "boui")) != (char) EOF)
     {
	switch (c)
	  {
	  case 'b':		/* beep on conversation */
	     bflag = 1;
	     break;
	  case 'o':		/* oneshot - no curses */
	     oflag = 1;
	     break;
	  case 'i':		/* only display systems that have work */
	     iflag = 1;
	     break;
	  case 'u':		/* start uucico for each site that has files */
	     uflag = 1;
	     oflag = 1;
	     break;
	  }
     }
   if (!uflag)
      fprintf (stderr, "%s\n", sccsid);
   chdir (STATUS);
   for (i = 1; i < 4; i++)
      signal (i, bye);
#ifdef SUN
   signal(SIGCHLD, catch_child);
#endif
   if (LOGON)
      exp = fopen (LOGFILE, "w");
   *ltname = NULL;
   if ((xfer = fopen (XFERSTATS, "r")) == (FILE *) NULL)
      perror (XFERSTATS);
   /* create status files if they don't exist */
   if ((in = fopen (SYSTEMS, "r")) == (FILE *) NULL)
      perror (SYSTEMS);
   else
     {
	while (fgets (line, 510, in) != (char *) NULL)
	  {
	     lptr = line;
	     while (*lptr == ' ' || *lptr == TABCHAR)
		lptr++;
	     if (*lptr == '#')
		continue;
	     while (*lptr != ' ' && *lptr != TABCHAR && *lptr != NULL)
		lptr++;
	     *lptr = NULL;
	     ofiles = ifiles = files = 0;
#ifdef SVR4
             gptr = grades;
             while(*gptr)
             {
	     sprintf (work, WORKFILE, line, *gptr);
             gptr++;
#else
	     sprintf (work, WORKFILE, line);
#endif
	     if ((win = opendir (work)) != (DIR *) NULL)
	       {
		  /* count the number of C., TM., and X. files */
		  while ((dp = readdir (win)) != (struct dirent *) NULL)
		    {
		       if (strncmp (dp->d_name, "C.", 2) == 0)
			  ofiles++;
		       if (strncmp (dp->d_name, "X.", 2) == 0)
			  ifiles++;
		       if (strncmp (dp->d_name, "TM.", 3) == 0)
			  ifiles++;
#ifdef SVR4
		       if (strncmp (dp->d_name, "P.", 2) == 0) /* partial xfer */
			  ifiles++;
#endif
		       if (ifiles + ofiles > FLIMIT)
			  break;
		    }
		  closedir (win);
	       }
#ifdef SVR4
	     }
#endif
	     if (access (line, 0) != 0 && (ifiles > 0 || ofiles > 0))
	       {
		  if ((tin = fopen (line, "w")) == (FILE *) NULL)
		    {
		       perror (line);
		       continue;
		    }
		  fprintf (tin, "24 0 %ld 0 %s", time (0L), errortext[24]);
		  fclose (tin);
		  chmod (line, 0666);
		  chown (line, UUCPOWN, UUCPGRP);
	       }
	     if (uflag && ofiles > 0)
	       {
#ifdef SVR4
		  sprintf (work, "/etc/uucp/uucico -r1 -s%s", line);
#else
		  sprintf (work, "/usr/lib/uucp/uucico -r1 -s%s", line);
#endif
		  system (work);
	       }
	  }
	fclose (in);
     }
   if (uflag)
      exit (0);
   fflush (stdout);
   if (oflag == 0)
   {
      initscr ();
#ifdef SUN
      halfdelay(5);
      noecho();
      nonl();
      intrflush(stdscr, FALSE);
      keypad(stdscr, TRUE);
#endif
   }

   while (1)
     {
	if (oflag == 0)
	   move (0, 0);
	if ((din = opendir (".")) == (DIR *) NULL)
	  {
	     perror (STATUS);
	     exit (1);
	  }
	if (oflag == 0)
	   printw ("SYSTEM       RETRY IO FIL   LAST TRY      CPS I/O      STATUS  ");
	else
	   printf ("SYSTEM       RETRY IO FIL   LAST TRY      CPS I/O      STATUS  ");
	time (&curr);
	t1 = localtime (&curr);
	if (oflag == 0)
	   printw ("%02d/%02d %02d:%02d  ",
		   t1->tm_mon + 1, t1->tm_mday, t1->tm_hour, t1->tm_min);
	else
	   printf ("%02d/%02d %02d:%02d\n\n",
		   t1->tm_mon + 1, t1->tm_mday, t1->tm_hour, t1->tm_min);
	if (LOGON)
	   fprintf (exp, "%s", ctime (&curr));
	display = systems = 0;
	if (oflag == 0)
	  {
	     move (0, COLS - (1 + strlen (WAITMSG)));
	     standout ();
	     addstr (WAITMSG);
	     standend ();
	     move (sysline, 0);
	     refresh ();
	     clrtobot ();
	  }
	*tname = NULL;
	while ((dp = readdir (din)) != (struct dirent *) NULL)
	  {
	     if (display > LLIMIT && oflag == 0)
		break;
	     if (*dp->d_name == '.')
		continue;
	     systems++;
	     if ((in = fopen (dp->d_name, "r")) == (FILE *) NULL)
		continue;
	     fgets (line, 510, in);
	     fclose (in);
	     line[strlen (line) - 1] = NULL;
	     sscanf (line, "%d %d %ld %ld", &status, &retries, &secs, &retryt);
	     expflag = 0;
	     strcpy (name, dp->d_name);
#ifdef SUN
	     if ( poll_flag - 1 == systems ) 
		poll_system(name);
#endif
	     if ((curr - secs) > ((long) EXPDAYS * (long) 24 * (long) 60 * (long) 60))
	       {
		  if (LOGON)
		     fprintf (exp, "%s EXPIRED! (%ld - %ld) > %ld\n",
			      name, curr, secs,
		      ((long) EXPDAYS * (long) 24 * (long) 60 * (long) 60));
		  expflag = 1;
	       }
	     sprintf (lock, LOCKFILE, name);
	     ofiles = ifiles = files = 0;
#ifdef SVR4
             gptr = grades;
             while(*gptr)
             {
	     sprintf (work, WORKFILE, name, *gptr);
             gptr++;
#else
	     sprintf (work, WORKFILE, name);
#endif
	     if ((win = opendir (work)) != (DIR *) NULL)
	       {
		  /* count the number of C., TM., and X. files */
		  while ((dp = readdir (win)) != (struct dirent *) NULL)
		    {
		       if (strncmp (dp->d_name, "C.", 2) == 0)
			  ofiles++;
		       if (strncmp (dp->d_name, "X.", 2) == 0)
			  ifiles++;
		       if (strncmp (dp->d_name, "TM.", 3) == 0)
			  ifiles++;
#ifdef SVR4
		       if (strncmp (dp->d_name, "P.", 2) == 0) /* partial xfer */
			  ifiles++;
#endif
		       if (ifiles + ofiles > FLIMIT)
			  break;
		    }
		  closedir (win);
	       }
#ifdef SVR4
	     }
#endif
	     files = ifiles + ofiles;
	     if (files != 0)
		sprintf (cfiles, "%d", files);
	     else
		strcpy (cfiles, "   ");
	     if (files > FLIMIT)
		sprintf (cfiles, "%d+", FLIMIT);
	     if (retries != 0)
		sprintf (cretries, "%d", retries);
	     else
		strcpy (cretries, "   ");
	     /* kludges for screwy status stuff with HDB */
	     if (access (lock, 0) == 0 && status != 3)
		status = 22;
	     if (status == 11)
		status = 13;	/* fix bug */
	     /* skip WRONG TIME TO CALL  and STATUS UNKNOWN messages */
#ifndef WTTC
	     if ((status == 23 || status == 2) && files == 0)
		continue;
#endif
	     t1 = localtime (&secs);
	     retryt += secs;
	     t2 = localtime (&retryt);
             if(oflag == 0) move (display + 2, 0);
	     if (expflag == 0)
	       {
		  if (!iflag || (iflag && ofiles + ifiles > 0))
		    {
		       if (oflag == 0)
			  printw ("%-14s  %-3s%c%c %-3s ",
				  name, cretries, ifiles == 0 ? ' ' : 'I', ofiles == 0 ? ' ' : 'O', cfiles);
		       else
			  printf ("%-14s  %-3s%c%c %-3s ",
				  name, cretries, ifiles == 0 ? ' ' : 'I', ofiles == 0 ? ' ' : 'O', cfiles);
		    }
	       }
	     else if (LOGON)
		fprintf (exp, "%-14s  %-3d ", name, retries);
	     t1 = localtime (&secs);
	     /* last time */
	     if (expflag == 0)
	       {
		  if (!iflag || (iflag && ofiles + ifiles > 0))
		    {
		       if (oflag == 0)
			  printw ("%02d/%02d %02d:%02d  ",
				  t1->tm_mon + 1, t1->tm_mday, t1->tm_hour, t1->tm_min);
		       else
			  printf ("%02d/%02d %02d:%02d  ",
				  t1->tm_mon + 1, t1->tm_mday, t1->tm_hour, t1->tm_min);
		    }
	       }
	     else if (LOGON)
		fprintf (exp, "%02d/%02d %02d:%02d  ",
		      t1->tm_mon + 1, t1->tm_mday, t1->tm_hour, t1->tm_min);
	     /* next time */
	     t2 = localtime (&retryt);
	     if (expflag == 0)
	       {
		  if (!iflag || (iflag && ofiles + ifiles > 0))
		    {
		       calcxfer (name);	/* calculate xfer stats */
		       if(icps > -1 && ocps > -1)
		       {
		       if (oflag == 0)
			  printw ("%5d / %5d ", icps, ocps);
		       else
			  printf ("%5d / %5d ", icps, ocps);
		       icps = ocps = 0;
		       }
		       else
		       {
		       if (oflag == 0)
		       {
			  getyx(stdscr, ysave, xsave);
			  move(ysave, xsave+14);
		       }
		       else
			  printf ("      /       ");
		       }
		    }
	       }
	     else if (LOGON)
	       {
		  calcxfer (name);	/* calculate xfer stats */
		  if(icps > -1 && ocps > -1)
		     fprintf (exp, "%5d / %5d ", icps, ocps);
		  else
		     fprintf (exp, "      /       ");
		  icps = ocps = 0;
	       }
	     if (status == 3 || status == 22)
	       {
		  if (tnameset == 0)
		    {
		       sprintf (tname, UUCICO, name);
		       tnameset = 1;
		       if (oflag == 0)
			  printw ("* ");
		       else
			  printf ("* ");
		    }
		  else
		    {
		       if (oflag == 0)
			  printw ("  ");
		       else
			  printf ("  ");
		    }
		  if (oflag == 0)
		     standout ();
	       }
	     else
	       {
		  if (!iflag || (iflag && ofiles + ifiles > 0))
		    {
		       if (oflag == 0)
			  printw ("  ");
		       else
			  printf ("  ");
		    }
	       }
	     if (expflag == 0)
	       {
		  if (!iflag || (iflag && ofiles + ifiles > 0))
		    {
		       if (oflag == 0)
			  printw ("%s\n", errortext[status]);
		       else
			  printf ("%s\n", errortext[status]);
		    }
	       }
	     else if (LOGON)
		fprintf (exp, "%s\n", errortext[status]);
	     if ((status == 3 || status == 22) && oflag == 0)
		standend ();
	     if (!iflag || (iflag && ofiles + ifiles > 0))
		display++;
	  }
	tnameset = 0;
	if (oflag == 1)
	   break;		/* once only */
	printw ("\n%d UUCP connections active", systems);
	clrtobot ();
	ret = tailfile (tname, display + 5, LINES);
	move (0, COLS - (1 + strlen (BWAITMSG)));
	addstr (BWAITMSG);
	move (sysline, 0);
	refresh ();
	closedir (din);
#ifdef SUN
	if (ret == NULL)
	  {
	     timer.tv_sec = 1;
	     timer.tv_usec = 0;
	  }
	else
	  {
	     timer.tv_sec = SLEEPTIME;
	     timer.tv_usec = 0;
	  }

        FD_ZERO(&rd_set);
        FD_SET(0, &rd_set);

	select(FD_SETSIZE,
	       &rd_set,
	        (struct fd_set *) NULL,
		(struct fd_set *) NULL,
		&timer);


	c=getch();
#else
	if (ret == NULL)
	  {
	     sleep (1);
	  }
	else
	  {
	     sleep (SLEEPTIME);
	  }
#endif

#ifdef SUN
	switch ( c ) {
	case '\022':	/* ^R - clear the screen and redraw */
	case '\014':	/* ^L - clear the screen and redraw */
		wrefresh(curscr);
		break;
	case 'q':	/* exit the program */
	case 'Q':
	case 'x':
	case 'X':
		erase();
		refresh();
		endwin();
		exit(0);
		break;
	case '?':	/* display help screen */
		usage();
		move(0, 0);
		clrtobot();
		break;
	case '\002':	/* ^B - Toggle bell */
		if ( bflag )
		{
			bflag = 0;
			move ( 1, 0 );
			printw("Bell disabled");
			refresh();
		} else {
			bflag = 1;
			move ( 1, 0 );
			printw("Bell enabled");
		}
		break;

	case '\025':	/* ^U - start uucico for all systems that have work */
		uflag = 1;
		move ( 1, 0 );
		printw("uucico enabled");

		fork_retval = fork();

		switch (fork_retval)
		{
		case -1:	/* fork failed */
			fprintf(stderr, "Fork failed\n");
			continue;

		case 0:		/* child */
			sprintf(workstr, "%s/uustatus", "/usr/local/bin");
			execlp( workstr, workstr, "-u", (char *) 0);
			fprintf(stderr, "Cannot execute %s", workstr);
			break;

		default:	/* parent */
			break;
		}
		break;

	case '\011':	/* ^I - display only systems with work */
		if ( iflag )
		{
			iflag = 0;
			move ( 1, 0 );
			printw("diplaying all systems");
			refresh();
		} else {
			iflag = 1;
			move ( 1, 0 );
			printw("displaying only systems with work");
		}
		break;

	case '\012':	/* Move down 1 line */
	case 'j':
	case 'J':
	case KEY_DOWN:
		++sysline;
		if ( sysline > systems + 1 )
			sysline = systems + 1;
		break;

	case '\013':	/* Move up 1 line */
	case 'k':
	case 'K':
	case KEY_UP:
		--sysline;
		if ( sysline < 1 )
			sysline = 1;
		break;
	case '\020':	/* Poll the selected system (cntrl-P) */
	case 'P':
		if ( sysline == 1 )
		{
			move(1, 0);
			printw("No system selected");
		} else {
			poll_flag = sysline;
			move(1, 0);
			printw("Polling system ");
		}
		refresh();
		sleep(2);
		move(1, 0);
		clrtoeol();
		refresh();
			
		break;

	default:
		continue;
		break;
	}
#endif
     }
}

bye (sig)
     int sig;
{
   if (LOGON)
      fclose (exp);
   clear ();
   refresh ();
   endwin ();
   exit (0);
}

#ifdef SUN
usage()
{
	char	c;

	move(0,0);
	clrtobot();
	erase();
	refresh();
	printw("\n\n\n\nusage: uustatus [-obui]\n\n\n");
	printw("^R - clear the screen\n");
	printw("^L - clear the screen\n");
	printw("^B - toggle bell on conversation\n");
	printw("^I - toggle display of systems with work\n");
	printw("^U - poll all systems with work\n");
	printw("^P - poll the selected system\n");

	printw("\n\nk,K,^K - scroll up\n");
	printw("j,J,^J - scroll down\n");

	printw("\n ? - print this message\n");
	printw("\n\n\n\tType any key to return to uustatus\n\n");
	nocbreak();
	nodelay(curscr, FALSE);
	while ((c = getch()) == ERR )
		sleep(1);
	wclear(curscr);
	halfdelay(5);
}
#endif

tailfile (s, from, to)		/* returns NULL if done, EOF if error */
     char *s;
     int from, to;
{
   char wrk[512];
   int i;

   move (from, 0);
   clrtobot ();
   if (*s == NULL)
      return (EOF);
   if (access (s, 0) == EOF)
      return (EOF);
   if (strcmp (s, ltname) != 0)
     {
	fclose (tin);
	strcpy (ltname, s);
	if ((tin = fopen (s, "r")) == (FILE *) NULL)
	   return (EOF);
	/* display the last (to-from) lines of file s */
	/* must be limited to COLS */
	for (i = 0; i < (to - from) - 1; i++)
	   *tline[i] = NULL;
     }
   /* do a seek to reduce startup time */
   fseek (tin, (((from - to) - 10) * COLS), 2); /* go back a goodly amount */
   fgets (wrk, 510, tin);   /* eat rest of first line */
   while (fgets (wrk, 510, tin) != (char *) NULL)
     {
	if ('\n' != wrk[strlen (wrk) - 1])
	  {
#ifdef SUN
	     timer.tv_sec = 1;
	     timer.tv_usec = 0;

             FD_ZERO(&rd_set);
             FD_SET(0, &rd_set);

	     select(FD_SETSIZE,
	        &rd_set,
	        (struct fd_set *) NULL,
		(struct fd_set *) NULL,
		&timer);
	     if ( FD_ISSET(0, &rd_set) )
		return(1);
#else
	     sleep (1);
#endif
	     fseek (tin, (long) strlen (wrk), 1);
	     continue;
	  }
	wrk[strlen (wrk) - 1] = NULL;
	for (i = 0; i < (to - from) - 1; i++)
	   strcpy (tline[i], tline[i + 1]);
	strcpy (tline[(to - from) - 1],
	 strlen (wrk) > COLS - 1 ? wrk + (strlen (wrk) - (COLS - 1)) : wrk);
     }
   move (from - 1, 20);
   standout ();
   addstr (s);
   if (bflag)
      printf ("\7");
   standend ();
   move (from, 0);
   for (i = 0; i < to - from; i++)
     {
	if (strlen (tline[i]) > COLS - 1)
	   printw ("%s\n", tline[i] + (strlen (tline[i]) - (COLS - 1)));
	else
	   printw ("%s\n", tline[i]);
     }
   return (NULL);
}

/* calculate file transfer stats, put in icps, ocps */
calcxfer (s)
     char *s;			/* system name */
{
   char ptr[128], line[512], *lptr, direction, sys[64];
   char dptr[3], chars[8], secs[13];
   int i, sysl;
   long ixfers, oxfers; float isecs, osecs, tmpf;
   long xsecs, moddate ();
   float tsecs, atof();

   icps = ocps = -1;
   /*
   if (xfertime >= (xsecs = moddate (XFERSTATS)) && iflag == 0)
      return;
   */
   xfertime = xsecs;
   rewind (xfer);		/* rewind the xferstats file */
   sprintf (sys, "%s!", s);
   sysl = strlen (sys);
   icps = ocps = ixfers = oxfers = isecs = osecs = 0;

   while (fgets (line, 510, xfer) != (char *) NULL)
     {
	if (strncmp (line, sys, sysl) != 0)
	   continue;
        sscanf(line, "%*s %*s %*s %*s %*s %s %s %*s %s",
           dptr, chars, secs);
        sscanf(secs, "%f", &tsecs);
        if(tsecs < XFERTIME) continue;
        direction = *dptr;
	if (direction == '<')
	  {
	     ixfers += atol (chars);
	     isecs += tsecs;
	  }
	else
	  {
	     oxfers += atol (chars);
	     osecs += tsecs;
	  }
     }
   if (isecs > 0)
	icps = ixfers/isecs;
   if (osecs > 0)
	ocps = oxfers/osecs;
}

/*
 * moddate - return last modified time for file
 *
 */

long
moddate (fileptr)
     char *fileptr;
{
   struct stat buf;
   char *ctime ();

   if (stat (fileptr, &buf) == EOF)
      return ((long) EOF);
   return (buf.st_mtime);
}

/* MODULE */

#ifdef SUN
poll_system( system )
char	*system;
{
	int fork_val;
	char sysarg[30];

	fork_val = fork();

	switch ( fork_val ) {
	case -1:
		move(1, 0);
		printw("poll_system: fork() failed!");
		break;
	case 0:	/* child */
		sprintf(sysarg, "-s%s", system);
#ifdef SVR4
	        execlp("/etc/uucp/uucico",
		       "/etc/uucp/uucico",
		       "-r1",
		       sysarg,
		       (char *) 0);
#else
	        execlp("/usr/lib/uucp/uucico",
		       "/usr/lib/uucp/uucico",
		       "-r1",
		       sysarg,
		       (char *) 0);
#endif
	default:
		poll_flag = 0;
		break;
	}
	refresh();
}

static void
catch_child()
{
        void    *old_hdlr;
        int     stat;
        pid_t   retpid;

        old_hdlr = signal(SIGCHLD, SIG_IGN);


        while (( retpid = waitpid((pid_t) -1, &stat, WNOHANG)) == (pid_t) -1 &&
               errno == EINTR)
                ;
 
        if (retpid == (pid_t) -1 )
                perror("waitpid");
	else
	{
		move(1, 0);
                printw("caught child (%d)\n", retpid);
		refresh();
	}
 
        signal(SIGCHLD, old_hdlr);
}

#endif
