 
/* xmlfs -- a translator for accessing XML documents

   Copyright (C) 2002, 2005 HurdFR.
   Written by  Manuel Menal          <mmenal@hurdfr.org>
           and Marc de Saint Sauveur <marc@hurdfr.org>
   
   xmlfs 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.

   xmlfs 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, USA. 
*/

#include "xmlfs.h"
#include "version.h"

#include <argp.h>

#include <sys/types.h>
#include <fcntl.h>

FILE *debug;

char *netfs_server_name = "xmlfs";
char *netfs_server_version = XMLFS_VERSION; /* defined in version.h */
const char *argp_program_version;

/* our filesystem */
struct xmlfs *xmlfs; 

int netfs_maxsymlinks = 0; /* not much sense ... */

static const struct argp_option options[] =
{
  { "debug-filen", 'd', "FILE", 0,
    "Enable debug and write debug statements to FILE." },
  { 0 }
};

static const char args_doc[] = "XML-DOC";
static const char doc[] =
  "A translator for accessing XML documents."
  "\vThis translator appears like a directory which tries to match the XML"
  " tree in XML-DOC as closely as possible.";

int
main (int argc, char **argv)
{
  mach_port_t bootstrap, underlying_node;
  io_statbuf_t underlying_stat;
  file_t xmlfile;
  char *xmlfilename = NULL;
  error_t err;

  debug = NULL;

  error_t parse_opt (int key, char *arg, struct argp_state *state)
    {
      switch (key)
	{
	case 'd':
	  debug = fopen (arg, "w");
	  setbuf (debug, NULL);
	  break;
	case ARGP_KEY_ARG:
	  if (state->arg_num == 0)
	    xmlfilename = arg;
	  else
	    return ARGP_ERR_UNKNOWN;
	  break;
	default:
	  return ARGP_ERR_UNKNOWN;
	}
      return 0;
    }
  struct argp argp = { options, parse_opt, args_doc, doc };

  asprintf ((char **) &argp_program_version, "%s %s", netfs_server_name, netfs_server_version);

  /* Parse our command line arguments.  */
  argp_parse (&argp, argc, argv, ARGP_IN_ORDER, 0, 0);

  DEBUG ("Entering %s (xml: %s)\n", argv[0], xmlfilename);

  task_get_bootstrap_port (mach_task_self (), &bootstrap);

  netfs_init ();
  
  underlying_node = netfs_startup (bootstrap, O_READ);

  err = io_stat (underlying_node, &underlying_stat);
  if (err)
    error (2, err, "cannot stat underlying node");

  if (!xmlfilename)
      /* Try to open the underlying node, which is incidently
	 our default XML file. */
    xmlfile = openport (underlying_node, O_READ);
  else
    xmlfile = open (xmlfilename, O_READ);
  
  xmlfs = malloc (sizeof (struct xmlfs));

  err = xmlfs_create (xmlfile, xmlfs);

  netfs_root_node->nn_stat = underlying_stat;
  netfs_root_node->nn_stat.st_mode = 
    S_IFDIR | (underlying_stat.st_mode & ~S_IFMT & ~S_ITRANS);
  
  if (err)
    error (1, err, "Cannot create filesystem");

  DEBUG ("INFO: Entering main loop\n");

  netfs_server_loop ();

  free (xmlfs);

  if (debug)
    fclose (debug);

  return 0; /* never reached */
}
