/* 
   Copyright (C) 1994 Free Software Foundation

   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., 675 Mass Ave, Cambridge, MA 02139, USA. */

#include "priv.h"
#include <fcntl.h>

int fshelp_transboot_port_type = PT_TRANSBOOT;

/* Start the translator on node NP.  NP is locked.  The node
   referenced by DIR must not be locked.  NP will be unlocked during
   the execution of this function.  The authentication of DIR is
   ignored, so it may be anything convenient.  DIRCRED is from the
   dir-lookup call by which this node was found, or 0 if it is root. */
error_t
diskfs_start_translator (struct node *np, file_t dir,
			 struct protid *dircred)
{
  error_t error;
  char buf[1000];
  char *transname = buf;
  file_t npport;
  u_int namelen = 1000;
  uid_t uid, gid;
  int openmode;

  error = diskfs_get_translator (np, &transname, &namelen);
  if (error)
    return error;
  
  uid = np->dn_stat.st_uid;
  gid = np->dn_stat.st_gid;

  openmode = O_READ | O_EXEC;
  
  if (!diskfs_readonly && (np->dn_stat.st_mode & S_IFMT) == S_IFREG)
    openmode |= O_WRITE;

  if (!dircred)
    /* Allocate right that we will store in new peropen below */
    mach_port_mod_refs (mach_task_self (), dir, MACH_PORT_RIGHT_SEND, 1);

  /* Create the REALNODE port for the new filesystem. */
  npport = (ports_get_right
	    (diskfs_make_protid
	     (diskfs_make_peropen (np, openmode, 
				   dircred ? dircred->po->dotdotport : dir),
	      &uid, 1, &gid, 1)));
  
  mach_port_insert_right (mach_task_self (), npport, npport,
			  MACH_MSG_TYPE_MAKE_SEND);

  mutex_unlock (&np->lock);
  
  error = fshelp_start_translator (&np->translator, transname, namelen,
				   dir, npport, uid, gid);

  if (transname != buf)
    vm_deallocate (mach_task_self (), (vm_address_t) transname, namelen);
  
  return error;
}
