/*
 * Copyright (c) 2003-2016
 * Distributed Systems Software.  All rights reserved.
 * See the file LICENSE for redistribution information.
 */

/*
 * Bundle DACS utilities into a single binary.
 */

#ifndef lint
static const char copyright[] =
"Copyright (c) 2003-2016\n\
Distributed Systems Software.  All rights reserved.";
static const char revid[] =
  "$Id: dacs.c 2876 2016-05-16 23:00:00Z brachman $";
#endif

#include "dacs.h"

static int
show_digests(int argc, char **argv, int do_init, void *main_out)
{

  if (argc == 2)
	crypto_show_digest_info(stdout, argv[1]);
  else
	crypto_show_digest_info(stdout, NULL);

  return(0);
}

static int
check_digest(int argc, char **argv, int do_init, void *main_out)
{
  Digest_desc *dd;

  if (argc != 2) {
	printf("Digest spec required\n");
	return(-1);
  }

  if ((dd = passwd_get_digest_algorithm(argv[1])) == NULL) {
	printf("Digest spec is invalid: \"%s\"\n", argv[1]);
	return(-1);
  }

  printf("%s: OK\n", dd->formatted_desc);
  return(0);
}

typedef struct Commands {
  char *name;
  int (*func)(int argc, char **argv, int do_init, void *main_out);
} Commands;

/*
 * If there are alternate names, separate them with a comma and list the
 * canonical name first.
 */
static Commands commands[] = {
  { "checkdigest",             check_digest },
  { "dacsacl,aclcheck",        dacsacl_main },
  { "dacsauth",                dacsauth_main },
  { "dacsgrid,auth_grid",      dacsgrid_main },
  { "dacsconf,conf",           conf_main },
  { "dacscookie,cookie",       dacscookie_main },
  { "dacscheck",               dacscheck_main },
  { "dacscred,cred",           dacscred_main },
  { "dacsexpr,expr",           dacsexpr_main },
  { "dacskey,mkkey",           dacskey_main },
  { "dacslist,list",           dacslist_main },
  { "dacspasswd,passwd",       dacspasswd_main },
  { "dacstoken,auth_token",    dacstoken_main },
  { "dacstransform,transform", dacstransform_main },
  { "dacsversion,version",     dacsversion_main },
  { "dacsvfs,vfs",             dacsvfs_main },
  { "dacshttp",                dacshttp_main },
  { "digests",                 show_digests },
  { "license",                 show_license },
  { "sslclient",               sslclient_main },
  { NULL,                      NULL }
};

static void
dacs_usage(void)
{
  int i;

  fprintf(stderr,
		  "Usage: dacs [-v|--verbose] [--version] [--checkdigest digest-spec] [--digests] [--license] [--dumpenv] [<command> <command-args>]\n");
  fprintf(stderr, "Where <command> is one of:\n");
  for (i = 0; commands[i].name != NULL; i++) {
	fprintf(stderr, "  %s\n", commands[i].name);
  }

  exit(1);
}

int
main(int argc, char **argv)
{
  int i, j;
  
  if (argc == 1) {
	dacs_usage();
	/*NOTREACHED*/
  }

  for (i = 1; i < argc && argv[i][0] == '-'; i++) {
	if (streq(argv[i], "--verbose") || streq(argv[i], "-v"))
	  verbose_level++;
	else if (streq(argv[i], "--dumpenv")) {
	  envdump();
	  exit(0);
	}
	else if (streq(argv[i], "--checkdigest")) {
	  if (argv[i + 1] == NULL) {
		dacs_usage();
		/*NOTREACHED*/
	  }

	  if (check_digest(2, argv + 1, 0, NULL) == -1)
		exit(1);

	  exit(0);
	}
	else if (streq(argv[i], "--digest") || streq(argv[i], "--digests")) {
	  if (argv[i + 1] != NULL) {
		show_digests(2, argv + 1, 0, NULL);
	  }
	  else
		show_digests(0, NULL, 1, NULL);
	  exit(0);
	}
	else if (streq(argv[i], "--license")) {
	  show_license(0, NULL, 1, NULL);
	  exit(0);
	}
	else if (streq(argv[i], "--version")) {
	  dacs_version(stderr);
	  exit(0);
	}
	else {
	  dacs_usage();
	  /*NOTREACHED*/
	}
  }

  if (i == argc) {
	dacs_usage();
	/*NOTREACHED*/
  }

  for (j = 0; commands[j].name != NULL; j++) {
	int c;
	Dsvec *cmds;

	if ((cmds = strsplit(commands[j].name, ",", 0)) == NULL)
	  continue;
	for (c = 0; c < dsvec_len(cmds); c++) {
	  if (streq(dsvec_ptr(cmds, c, char *), argv[i]))
		break;
	}
	if (c != dsvec_len(cmds))
	  break;
  }

  if (commands[j].name == NULL) {
	dacs_usage();
	/*NOTREACHED*/
  }

  (void) commands[j].func(argc - i, argv + i, 1, NULL);

  /*NOTREACHED*/
  exit(1);
}
