#include <sys/ioctl.h>
#include <stdio.h>
#include <strings.h>
#include <errno.h>

#define TRUE (1)
#define FALSE (0)

struct sgttyb terminit, termmod;
struct gstr *mesglist;

extern char *getenv();
extern int errno;

struct gstr
{
  char *group, *last;
  int unread;
  struct gstr *next;
};

struct twoway
{
  FILE *sock_rd, *sock_wt;
};

/* Shutdown writes each group and the last message read in it to the
 * ~/.nmsgsrc file.  The source for this data is the mesglist pointer.
 * If it is null, no ~/.nmsgsrc file is written.  Either way, the
 * program then exits.
 */

void Shutdown()
{
  char *homedir, *rcpath;
  FILE *nmsgsrc;

  if (ioctl(fileno(stdout), TIOCSETP, &terminit) == -1)
    {
      perror("TIOCGETP blew it");
      printf("%d\n", errno);
    }
  if (mesglist != NULL)
    {

/* Set up the path to .nmsgsrc and open it. */

      homedir = getenv("HOME");
      rcpath = (char *)malloc(strlen(homedir)+strlen("/.nmsgsrc")+1);
      if (rcpath == NULL)
	{
	  perror("Nmsgs: Shutdown: malloc");
	  exit(1);
	}
      strcpy(rcpath, homedir);
      nmsgsrc = fopen(strcat(rcpath, "/.nmsgsrc"), "w");
      free(rcpath);
      if (nmsgsrc == NULL)
	{
	  perror("Nmsgs: Shutdown: fopen");
	  exit(1);
	}
      else
	{

/* Cycle through the linked list of messages, write each as they
 * appear.  Both group name and the last message read are listed.
 */

	  fprintf(nmsgsrc, "Message_list\n");
	  while (mesglist != NULL)
	    {
	      fprintf(nmsgsrc, "%s %s\n", mesglist->group, mesglist->last);
	      mesglist = mesglist->next;
	    }
	  fclose(nmsgsrc);
	}
    }

/* Depart from this mortal coil. */

  exit(0);
}


/* PutLine dumps a null-terminated string to a previously
 * opened file pointer, one character at a time.
 * There should probably be some kind of sanity checking
 * done in this function.
 */

void PutLine(string, fd)
     char *string;
     FILE *fd;
{
  int off = 0;
  char c;

/* Loop through the string */

  while(TRUE)
    {
      c = *(string + off);

/* Close, flush, and exit when the job is done. */

      if (c == '\0')
	{
	  fflush(fd);
	  return;
	}
      putc(c, fd);
      off++;
    }
}


/* GetLine retrieves a crlf terminated string from a previously opened
 * file pointer, and returns the string null-terminated, removing the
 * crlf.  The conditions and return value may be easily changed.  This
 * code shamelessly swiped from a function written by Mike Patton.
 */

char *GetLine(fd)
     FILE *fd;
{
  int c;
  int char_count = 0;
  static char *buff_p = NULL;
  static int buff_size = 0;

  void error();

/* First (and hopefully only) malloc performed on buff_p. */

  if (buff_p == NULL)
    {
      buff_p = (char *)malloc(buff_size=80);
      if (buff_p == NULL)
	error("Allocation error for initial buffer\n");
    }

/* Cycle until you run out of string. */

  while(TRUE)
    {
      c = getc(fd);

/* Check for end of string.  If so, return the string null-terminated. */

      if (c=='\012' || c==EOF)
	{
	  buff_p[char_count] = '\0';
	  return(buff_p);
	}

/* Punt non-printing characters. */

      if (c<' ') continue;

/* If the line is too long for the current buffer, add more space. */

      if (char_count >= buff_size)
	{
	  buff_p = (char *)realloc(buff_p,buff_size <<= 1);
	  if (buff_p == NULL)
	    error("Allocation error for input buffer");
	}
      buff_p[char_count++] = c;
    }
}
