/* Copyright (c) 1996, 1997, 1998, 1999 Thorsten Kukuk
   Author: Thorsten Kukuk <kukuk@suse.de>

   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, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#define _GNU_SOURCE

#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
#include "lib/compat/getopt.h"
#endif
#include <locale.h>
#include <libintl.h>
#include <stdio.h>
#include <string.h>
#include <rpcsvc/nis.h>

#ifndef _
#define _(String) gettext (String)
#endif

static nis_tag query_val[] = {
  {TAG_ROOTSERVER, (char *)""},
  {TAG_NISCOMPAT, (char *)""},
  {TAG_DNSFORWARDING, (char *)""},
  {TAG_SECURITY_LEVEL, (char *)""},
  {TAG_DIRLIST, (char *)""},
  {TAG_OPSTATS, (char *)""},
  {TAG_S_DCACHE, (char *)""},
  {TAG_S_OCACHE, (char *)""},
  {TAG_S_GCACHE, (char *)""},
  {TAG_S_STORAGE, (char *)""},
  {TAG_HEAP, (char *)""},
  {TAG_UPTIME, (char *)""}
};
static int query_len = 11;

static void
print_tags (nis_tag *result, int len)
{
  int i;

  if (result != NULL)
    for (i = 0; i < len; ++i)
      switch (result[i].tag_type)
	{
	case TAG_ROOTSERVER:
	  printf (_("Stat 'root server' = '%s'\n"), result[i].tag_val);
	  break;
	case TAG_NISCOMPAT:
	  printf (_("Stat 'NIS compat mode' = '%s'\n"), result[i].tag_val);
	  break;
	case TAG_DNSFORWARDING:
	  printf (_("Stat 'DNS forwarding' = '%s'\n"), result[i].tag_val);
	  break;
	case TAG_SECURITY_LEVEL:
	  printf (_("Stat 'security level' = '%s'\n"), result[i].tag_val);
	  break;
	case TAG_DIRLIST:
	  {
	    char dir[strlen (result[i].tag_val) + 1];
	    char *cptr1, *cptr2;

	    strcpy (dir, result[i].tag_val);
	    fputs (_("Stat 'serves directories':\n"), stdout);
	    cptr1 = dir;
	    do
	      {
		cptr2 = strpbrk (cptr1, "\n\t ");
		if (cptr2 != NULL)
		  {
		    *cptr2 = '\0';
		    ++cptr2;
		  }
		printf ("\t%s\n", cptr1);
		cptr1 = cptr2;
	      }
	    while (cptr2 != NULL && cptr2[0] != '\0');
	  }
	  break;
	case TAG_OPSTATS:
	  {
	    char buf[strlen (result[i].tag_val) + 1];
	    char *cptr1, *cptr2;

	    strcpy (buf, result[i].tag_val);
	    fputs (_("Stat 'Operation Statistics':\n"), stdout);
	    cptr1 = buf;
	    if (cptr1[0] == '\n')
	      ++cptr1;
	    do
	      {
		cptr2 = strpbrk (cptr1, "\n\t ");
		if (cptr2 != NULL)
		  *cptr2++ = '\0';
		printf ("\t%s\n", cptr1);
		cptr1 = cptr2;
	      } while (cptr2 != NULL && cptr2[0] != '\0');
	  }
	  break;
	case TAG_S_DCACHE:
	  printf (_("Stat 'directory cache' = '%s'\n"), result[i].tag_val);
	  break;
	case TAG_S_OCACHE:
	  printf (_("Stat 'object cache' = '%s'\n"), result[i].tag_val);
	  break;
	case TAG_S_GCACHE:
	  printf (_("Stat 'group cache' = '%s'\n"), result[i].tag_val);
	  break;
	case TAG_S_STORAGE:
	  printf (_("Stat 'static storage' = '%s'\n"), result[i].tag_val);
	  break;
	case TAG_HEAP:
	  printf (_("Stat 'dynamic storage' = '%s'\n"), result[i].tag_val);
	  break;
	case TAG_UPTIME:
	  printf (_("Stat 'up since' = '%s'\n"), result[i].tag_val);
	  break;
	default:
	  printf ("%d: %s\n", result[i].tag_type, result[i].tag_val);
	  break;
	}
}

/* Print the version information.  */
static inline void
print_version (void)
{
  fprintf (stdout, "nisstat (%s) %s\n", PACKAGE, VERSION);
  fprintf (stdout, gettext ("\
Copyright (C) %s Thorsten Kukuk.\n\
This is free software; see the source for copying conditions.  There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
"), "1998");
  /* fprintf (stdout, _("Written by %s.\n"), "Thorsten Kukuk"); */
}

static inline void
print_usage (void)
{
  fputs (_("Usage: nisstat [-H host] [directory]\n"), stdout);
}

static void
print_help (void)
{
  print_usage ();
  fputs (_("nisstat - report NIS+ server statistics\n\n"),
         stdout);

  fputs (_("  -H host        only the machine named host is queried\n"),
	 stdout);
  fputs (_("  --help         Give this help list\n"), stdout);
  fputs (_("  --usage        Give a short usage message\n"), stdout);
  fputs (_("  --version      Print program version\n"), stdout);
}

static inline void
print_error (void)
{
  const char *program = "nisstat";

  fprintf (stderr,
           _("Try `%s --help' or `%s --usage' for more information.\n"),
           program, program);
}

int
main (int argc, char *argv[])
{
  nis_server *serv_val;
  u_int serv_len;
  char *server = NULL;
  nis_tag *result_tags;
  nis_result *dir;
  u_int i;
  size_t server_len = 0;

  setlocale (LC_MESSAGES, "");
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);

  while (1)
    {
      int c;
      int option_index = 0;
      static struct option long_options[] =
      {
        {"version", no_argument, NULL, '\255'},
        {"usage", no_argument, NULL, '\254'},
        {"help", no_argument, NULL, '\253'},
	{NULL, 0, NULL, '\0'}
      };

      c = getopt_long (argc, argv, "H:", long_options, &option_index);
      if (c == (-1))
	break;
      switch (c)
	{
	case 'H':
	  server = optarg;
	  server_len = strlen (server);
	  break;
        case '\253':
          print_help ();
          return 0;
        case '\255':
          print_version ();
          return 0;
        case '\254':
          print_usage ();
          return 0;
        default:
          print_error ();
          return 1;
	}
    }

  argc -= optind;
  argv += optind;

  if (argc > 0)
    {
      fprintf (stderr, _("%s: To many arguments\n"), "nisstat");
      print_error ();
      return 1;
    }

  printf (_("Statistics for domain %s :\n"), nis_local_directory ());
  dir = nis_lookup (nis_local_directory (), 0);

  if (dir->status != NIS_SUCCESS)
    {
      nis_perror (dir->status, "nisstat");
      exit (1);
    }

  serv_val = NIS_RES_OBJECT(dir)->DI_data.do_servers.do_servers_val;
  serv_len = NIS_RES_OBJECT(dir)->DI_data.do_servers.do_servers_len;

  for (i = 0;  i < serv_len; ++i)
    if (!server ||
	((server[server_len - 1] != '.') &&
	 (strncmp (server, serv_val[i].name, server_len) == 0)) ||
	((server[server_len - 1] == '.') &&
	 (strcmp (server, serv_val[i].name) == 0)))
      if (nis_stats (&serv_val[i], query_val, query_len, &result_tags)
  	  == NIS_SUCCESS)
        {
	  printf (_("\nStatistics from server : %s\n"), serv_val[i].name);
	  print_tags (result_tags, query_len);
	  nis_freetags (result_tags, query_len);
        }

  return 0;
}
