/* Copyright (c) 1997, 1998 Thorsten Kukuk
   Author: Thorsten Kukuk <kukuk@vt.uni-paderborn.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 <ctype.h>
#include <locale.h>
#include <libintl.h>
#include <rpcsvc/nis.h>

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

static inline int
yesno (void)
{
  char buf[128];
  int len = 0;
  int c;

  while ((c = getchar ()) != EOF && c != '\n')
    if ((len > 0 && len < 127) || (len == 0 && !isspace (c)))
      buf[len++] = c;
  buf[len] = '\0';

  return rpmatch (buf) == 1;
}

/* Print the version information.  */
static inline void
print_version (void)
{
  fprintf (stdout, "niscat (%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 (_("nisrm [ -if ] name\n"), stdout);
}

static void
print_help (void)
{
  print_usage ();
  fputs (_("nisrm - remove NIS+ objects from the namespace\n\n"),
         stdout);

  fputs (_("  -i             Interactive mode\n"), stdout);
  fputs (_("  -f, --force    Force the command to succeed\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 = "nisrm";

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

int
main (int argc, char *argv[])
{
  int interactive = 0;
  int force = 0;
  int i;

  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'},
	{"force", no_argument, NULL, 'f'},
	{NULL, 0, NULL, '\0'}
      };

      c = getopt_long (argc, argv, "if", long_options, &option_index);
      if (c == EOF)
	break;
      switch (c)
	{
	case 'i':
	  interactive = 1;
	  break;
	case 'f':
	  force = 1;
	  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 < 1)
    {
      fprintf (stderr, _("%s: To few arguments\n"), "nisrm");
      print_error ();
      return 1;
    }

  for (i = 0; i < argc; ++i)
    {
      int j;
      nis_name *names;
      nis_result *result;
      nis_result *res;

      names = nis_getnames (argv[i]);
      for (j = 0; names[j] != NULL; ++j)
	{
	  res = nis_lookup (names[j], 0);

	  if (res->status != NIS_SUCCESS)
	    {
	      if (res->status != NIS_NOSUCHNAME)
		fprintf (stderr, "nisrm: %s: %s\n", names[j],
			 nis_sperrno (res->status));
	      continue;
	    }
	  if (__type_of (NIS_RES_OBJECT(res)) == NIS_DIRECTORY_OBJ)
	    {
	      fprintf (stderr, _("nisrm: %s is a directory!\n"), names[j]);
	      continue;
	    }
	  if ((interactive || argv[i][strlen (argv[i]) -1] != '.') && !force)
	    {
	      fprintf (stdout, _("nisrm: remove `%s'? "), names[j]);
	      if (!yesno ())
		continue;
	    }
	  /* First try to delete a object */
	  result = nis_remove (names[j], NIS_RES_OBJECT (res));
	  if (result->status == NIS_PERMISSION && force)
	    {
	      /* NO Permissions ? Set destroy for all fields */
	      NIS_RES_OBJECT (res)->zo_access =
		NIS_RES_OBJECT (res)->zo_access | (NIS_DESTROY_ACC);
	      NIS_RES_OBJECT (res)->zo_access =
		NIS_RES_OBJECT (res)->zo_access | ((NIS_DESTROY_ACC) << 8);
	      NIS_RES_OBJECT (res)->zo_access =
		NIS_RES_OBJECT (res)->zo_access | ((NIS_DESTROY_ACC) << 16);
	      NIS_RES_OBJECT (res)->zo_access =
		NIS_RES_OBJECT (res)->zo_access | ((NIS_DESTROY_ACC) << 24);
	      nis_freeresult (result);
	      result = nis_modify (names[j], NIS_RES_OBJECT (res));
	      nis_freeresult (result);
	      result = nis_remove (names[j], NULL);
	    }
	  if (result->status != NIS_SUCCESS && !force)
	    fprintf (stderr, "nisrm: %s: %s\n", names [j],
		     nis_sperrno (result->status));
	  nis_freeresult (res);
	  nis_freeresult (result);
	  break;
	}
      nis_freenames (names);
    }
  return 0;
}
