/*
 * create.c
 *
 * $Author: dm3e $
 * $Date: 1993/01/08 19:21:35 $
 * $Revision: 1.2 $
 * $State: Exp $
 * $Locker:  $
 */

/*********************************************************** 

  Copyright 1991 by Carnegie Mellon University

All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
   documentation for any purpose and without fee is hereby granted, provided
   that the above copyright notice appear in all copies and that both that
   copyright notice and this permission notice appear in supporting
   documentation, and that the name of CMU not be used in advertising or
   publicity pertaining to distribution of the software without specific,
   written prior permission.

CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL CMU
   BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

 *****************************************************************/

#include "emtd.h"

/***************************************************************************
 * [exported] emtd_CreateCommand
 *
 * Description:
 *      This is the procedure called by the command processing routine,
 *      when the user makes a valid create command.
 *
 * Arguments:
 *
 * Environment:
 *
 * History:
 *      Wed Oct  7 11:00:21 1992 - created by David Allen Markley
 *
 ***************************************************************************/
long emtd_CreateCommand(request, errstr)
comreq_t            request;
char **errstr;
{
    register long       code;

    IF_RTN(emtd_AddCollectionToTree(request));
    IF_RTN(emtd_CheckVersions(request, errstr));
    IF_RTN(emtd_MakeGroups(request, errstr)); 
    IF_RTN(emtd_AddToGroups(request, errstr));
    IF_RTN(emtd_CreateSourceArea(request, errstr));
    IF_RTN(emtd_CreateDestArea(request, errstr));
    IF_RTN(emtd_CreateObjectArea(request, errstr));
    emtd_Broadcast(request, EMTD_LOGBASE, "Creation complete.\n");
    return OK;
}

/***************************************************************************
 * [exported] emtd_TitleCreate
 *
 * Description:
 *
 * Arguments:
 *
 * Environment:
 *
 * History:
 *      Fri Nov 13 16:32:57 1992 - created by David Allen Markley
 *
 ***************************************************************************/
long emtd_TitleCreate(request, errstr)
comreq_t            request;
char **errstr;
{
    emtd_Broadcast(request, EMTD_LOGBASE, "Creating %s %s.\n",
		   REQ_COLLECTION, REQ_VERSION);
    return OK;
}

/***************************************************************************
 * [exported] emtd_CheckVersions
 *
 * Description:
 *
 * Arguments:
 *
 * Environment:
 *
 * History:
 *      Tue Dec  1 17:00:35 1992 - created by David Allen Markley
 *
 ***************************************************************************/
long emtd_CheckVersions(request, errstr)
comreq_t            request;
char **errstr;
{
    long versions_allowed = emtd_VersionsRestricted(request);
    long versions_found = 0;
    char *vol = make_volume_name (NULL, REQ_COLLECTION, REQ_VERSION, SRC_VOL);
    DIR *sdir;
    struct direct *sdirent;
    char spath[MAXPATHLEN], path[MAXPATHLEN];
    char *mount = NULL;
    int mnterr;

    sprintf(spath, "%s/%s", request->tree->src_path, REQ_COLLECTION);
    if (NULL == (sdir = opendir(spath))) {
	Log("error opening directory %s.\n",spath);
	free(vol);
	if (errno == ENOENT) return OK;
	return EMTD_STILL_MOUNTED;
    }
    while (NULL != (sdirent = readdir(sdir))) {
	if ('.' == (char)(sdirent->d_name)[0]) continue;
	sprintf(path, "%s/%s", spath, sdirent->d_name);
	if (NULL != (mount = statMount(path, &mnterr))) {
	    if (!strcmp(mount, vol)) {
		free(vol);
		closedir(sdir);
		return OK;
	    } else {
		versions_found++;
	    }
	} else {
	    if (STATMOUNT_NOT_A_MOUNTPOINT != mnterr) {
		versions_found++;
	    }
	}
    }
    closedir(sdir);
    free(vol);
    Log("Versions allowed = %ld, found = %ld\n", versions_allowed, versions_found);
    if (versions_found < versions_allowed) return OK;
    if ((REQ_FLAGS & FORCE_REQUEST) && (REQ_AUTH & ~(EMTAUTH_MAINTAINER))) {
	emtd_Broadcast(request, EMTD_LOGWARN,
		       "Too many versions of this collection exist. FORCED THROUGH!\n");
	return OK;
    } else {
	emtd_Broadcast(request, EMTD_LOGERR,
		       "Too many versions of this collection exist. ABORTED!\n");
	return TRUE;
    }
}

/***************************************************************************
 * [exported] emtd_CreateSourceArea
 *
 * Description:
 *
 * Arguments:
 *
 * Environment:
 *
 * History:
 *      Wed Oct  7 11:02:16 1992 - created by David Allen Markley
 *
 ***************************************************************************/
static long emtd_CreateSourceArea(request, errstr)
comreq_t            request;
char **errstr;
{
    register long       code;
    char path[MAXPATHLEN];
    char               *tvol,
                       *fvol;

    if (REQ_FLAGS & (CREATE_SOURCE_COPY | CREATE_SOURCE_NEW)) {
	emtd_Broadcast(request, EMTD_LOGBASE, "Creating the source area.\n");
    } else {
	sprintf(path, "%s/%s", request->tree->src_path, REQ_COLLECTION);
	IF_RTN(emtd_MakeDir(path, 666));
	return OK;
    }
    tvol = make_volume_name (NULL, REQ_COLLECTION, REQ_VERSION, SRC_VOL);
    if (REQ_FLAGS & CREATE_SOURCE_COPY) {
	fvol = make_volume_name (NULL, REQ_COLLECTION, REQ_LAST_VERSION,
				 SRC_VOL);
	IF_RTN(emtd_VolumeCopy(request, fvol, tvol, "src", REQ_SOURCEQ,
			       errstr));
	free (fvol);
    } else if (REQ_FLAGS & CREATE_SOURCE_NEW) {
	IF_RTN(emtd_VolumeCreate(request, tvol, "src", REQ_SOURCEQ, errstr));
    }
    IF_RTN(emtd_VolumeMount(request, tvol, "src", request->tree->src_path,
			    SRC_VOL | SET_VOLUME_ACL, errstr));
    IF_RTN(emtd_VolumeSetQuota(request, tvol, REQ_SOURCEQ, errstr));
    free(tvol);
    return OK;
}

/***************************************************************************
 * [exported] emtd_CreateDestArea
 *
 * Description:
 *
 * Arguments:
 *
 * Environment:
 *
 * History:
 *      Wed Oct  7 13:53:23 1992 - created by David Allen Markley
 *
 ***************************************************************************/
static long emtd_CreateDestArea(request, errstr)
comreq_t            request;
char **errstr;
{
  register long       code;
  llist_t c_system;
  char               *cvol,	/* The name of the common volume */
                     *vol,	/* The name of the current volume in use */
                     *sys;
  int                 has_common = 0, /* If non-zero, a common volume exists */
                      common_acl = 0; /* If non-zero, the common ACL was set */
  edb_sys_t c_sys;

  
  if (REQ_SYSTEMS) {
      emtd_Broadcast(request, EMTD_LOGBASE, "Creating the dest areas.\n");
  }
  for (c_system = REQ_SYSTEMS; c_system; c_system = c_system->next) {
      if (!strcasecmp (c_system->buffA, "common")) {
	  has_common = 1;
	  cvol = make_volume_name("common", REQ_COLLECTION, REQ_VERSION,
				  COMMON_VOL);
	  IF_RTN(emtd_VolumeCreate(request, cvol, "common", REQ_COMMONQ,
				   errstr));
	  IF_RTN(emtd_VolumeSetQuota(request, cvol, REQ_COMMONQ, errstr));
      }
  }
  for (c_system = REQ_SYSTEMS; c_system; c_system = c_system->next) {
      sys = c_system->buffA;
      if (!strcasecmp (sys, "common")) continue;
      if (NULL == (c_sys = get_system (request->tree->dest, sys))) {
	  emtd_Broadcast(request, EMTD_LOGERR, "Unknown system: %s\n", sys);
	  continue;
      }
      vol = make_volume_name(sys, REQ_COLLECTION, REQ_VERSION, DEST_VOL);
      IF_RTN(emtd_VolumeCreate(request, vol, sys, REQ_DESTQ, errstr)); 
      IF_RTN(emtd_VolumeMount(request, vol, sys, c_sys->path,
			      DEST_VOL | SET_VOLUME_ACL, errstr));
      IF_RTN(emtd_VolumeSetQuota(request, vol, REQ_DESTQ, errstr));
      free(vol);
      if (has_common) {
	  IF_RTN(emtd_VolumeMount(request, cvol, "dest", c_sys->path,
				  DEST_VOL | COMMON_VOL | 
				  (common_acl ? 0 : SET_VOLUME_ACL), errstr));
	  if (! common_acl) common_acl++;
      }
  }
  if (has_common) free (cvol);

  return OK;
}

/***************************************************************************
 * [exported] emtd_CreateObjectArea
 *
 * Description:
 *
 * Arguments:
 *
 * Environment:
 *
 * History:
 *      Wed Oct  7 15:30:38 1992 - created by David Allen Markley
 *
 ***************************************************************************/
long emtd_CreateObjectArea(request, errstr)
comreq_t            request;
char **errstr;
{
  register long       code;
  llist_t c_system;
  char *vol,
       *sys;
  edb_sys_t c_sys;

  if (!(REQ_FLAGS & CREATE_OBJECT_AFS)) return OK;
  emtd_Broadcast(request, EMTD_LOGBASE, "Creating the object areas.\n");
  for (c_system = REQ_SYSTEMS; c_system; c_system = c_system->next) {
      sys = c_system->buffA;
      if (!strcasecmp (sys, "common")) continue;
      if (NULL == (c_sys = get_system (request->tree->obj, sys))) {
	  emtd_Broadcast(request, EMTD_LOGERR, "Unknown system: %s\n", sys);
	  continue;
      }
      vol = make_volume_name(sys, REQ_COLLECTION, REQ_VERSION,
			     OBJ_VOL);
      IF_RTN(emtd_VolumeCreate(request, vol, sys, REQ_OBJECTQ, errstr));
      IF_RTN(emtd_VolumeMount(request, vol, sys, c_sys->path,
			      OBJ_VOL | SET_VOLUME_ACL, errstr));
      IF_RTN(emtd_VolumeSetQuota(request, vol, REQ_OBJECTQ, errstr));
      free(vol);
  }
  return OK;
}

