/* nmsgs.c written by Michael J. Bauer
 * First working version created on 2 August 1990.
 * Current version created 13 February 1991: v. 1.1
 * Please direct all comments, suggestions, and flames to the author.
 * I am reachable as mjbauer@athena.mit.edu (preferred)
 *                   mjbauer@lcs.mit.edu
 *                   mjbauer@media-lab.media.mit.edu
 *
 * Nmsgs is intended to replace msgs where there is no central machine
 * to run msgs from.  It uses NNTP/TCP to connect to the local news
 * feed to read whatever message groups are requested.  All socket
 * communication, and the status checking on the socket replies, is
 * in accordance with NIC RFC document 977: ``Network News Transfer
 * Protocol''.
 *
 * To use nmsgs, type at your prompt:
 * % nmsgs [options] [newsgroup [newsgroup [...]]]
 *
 * Nmsgs will, with no newsgroups on the command line, attempt to read
 * all newsgroups in the .nmsgsrc file.  If no .nmsgsrc file exists,
 * or all groups in that file are up to date, nmsgs will exit
 * silently.  Newsgroups specified on the command line are read in the
 * order they appear in the .nmsgsrc file, with groups not appearing
 * in that file succeeding those that do in command line order.
 *
 * Features already implemented:
 *
 * From prompt:
 * y   Keep going
 * n   Don't keep going (next message)
 * q   Quit (punts to next group)
 * Q   Drop out of nmsgs where you are (don't punt to next group)
 * -   Redisplay previous message
 *        (backing off the earliest message leaves you where you are)
 * s   Save current message to file
 * s-  Save previous message to file
 * #   Go to article # in current group
 *
 * Command line:
 * -f  Override the ``no new messages'' announcement
 * -q  Override ``there are new messages'' announcement and starts reading
 * -s  Set the news server to connect to.  If there is no server set,
 *        it will try the NNTPSERVER environment variable, and, failing
 *        that, use the compiled-in value of NNTP_DEFAULT.
 *
 *
 * Features that this does not have which msgs does (and, supposedly,
 * this will have at some point):
 *
 * Command line:
 * -h  Prints the first part of messages only
 * -l  Print locally-originating messages only
 * -p  Pipe through more
 *        (this one now done by default, no off switch)
 *
 *
 * Features which msgs doesn't have (and this probably should):
 *
 * From prompt:
 * D   Delete current group from rc file
 *
 *
 * Features which msgs does have (and this likely never will):
 *
 * Command line:
 * #   Start at message #
 *        (probably won't be implemented because of multiple message
 *        sources, instead of one)
 * -#  Start # messages back from the marked message
 *        (probably not either)
 *
 * From prompt:
 * m   Invoke mail on message
 *        (probably won't be implemented, at least not until
 *        everything else is dealt with, and I'm really bored)
 */

#include <stdio.h>

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

#define NNTP_DEFAULT "nntp.lcs.mit.edu"

extern char *getenv();

struct gstr *mesglist = NULL;

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

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

extern char *getenv();

main(argc, argv)
     int argc;
     char **argv;
{
  char query, *newsserver = NULL;
  int unread = FALSE, grpcnt, newquiet = 0, noquiet = 0, temp;
  struct twoway *sock_rw;
  struct gstr *tptr;

  void GetGroupList(), CheckGroup(), ReadGroup(), Shutdown();
  void CheckError(), error();
  struct twoway *Setup();

  for (temp = 1; temp < argc; temp++)
    {
      if (*(argv[temp]) != '-')
	break;
      switch (*(argv[temp] + 1))
	{
	case 'f':
	  noquiet = 1;
	  break;
	case 'q':
	  newquiet = 1;
	  break;
	case 's':
	  newsserver = argv[++temp];
	  break;
	}
    }

  if (newsserver == NULL)
    {
      newsserver = getenv("NNTPSERVER");
      if (newsserver == NULL)
	newsserver = NNTP_DEFAULT;
    }

/* Get the list of groups from the rc file and store them in mesglist.
 * Add on any that are on the command line that aren't in the rc file.
 */

  GetGroupList(temp, argc, argv);
  sock_rw = Setup(newsserver);

/* Start cycling through groups.  Find the next article to be read in
 * each group, stash that number in mesglist.
 */

  CheckGroup(sock_rw);

/* Find out if there are unread messages in any of the requested
 * groups.  If there are, announce them, if not, exit quietly.  The
 * verbose mode here should have a commandline shutoff.
 */

  tptr = mesglist;
  while (tptr != NULL)
    {
      if (tptr->unread == TRUE)
	{
	  if (unread == FALSE)
	    {
	      unread = TRUE;
	      if (newquiet == 0)
		printf("Unread messages in groups:\n");
	    }
	  if (newquiet == 0)
	    printf("   %s\n", tptr->group);
	}
      tptr = tptr->next;
    }
  if (unread == FALSE)
    {
      if (noquiet == 0)
	printf("No new messages.\n");
      Shutdown();
    }

/* See if the user really wants to read the messages.  There should
 * probably be an option to shut this off if nmsgs is called by hand,
 * rather than by a program.  Or an option to turn it on when nmsgs
 * is called by a program.
 */

  if (newquiet == 0)
    {
      printf("Read? (y/n) ");
      query = getchar();
      if (query == 'n' || query == 'N' || query == '\177' ||
	  query == 'q' || query == 'Q')
	{
	  printf("\n");
	  Shutdown();
	}
      printf("\nHang on...\n");
    }

  tptr = mesglist;
  while (tptr != NULL)
    {
      if (tptr->unread == FALSE)
	{
	  tptr = tptr->next;
	  continue;
	}
      ReadGroup(sock_rw, tptr);
      printf("*** End of group %s. ***\n", tptr->group);
      tptr = tptr->next;
    }

/* Flag end of groups and exit. */

  printf("*** End of messages ***\n");
  Shutdown();
}
