/**********************************************************************
 * filesystem-attaching module
 *
 * $Author: miki $
 * $Source: /afs/sipb.mit.edu/project/sipb-athena/repository/src/olh/libmenu/attach.c,v $
 * $Header: /afs/sipb.mit.edu/project/sipb-athena/repository/src/olh/libmenu/attach.c,v 1.2 1993/05/03 13:59:14 miki Exp $
 *
 * Copyright (c) 1990, Massachusetts Institute of Technology
 **********************************************************************/

#ifndef lint
#ifndef SABER
static char rcsid_attach_c[] = "$Header: /afs/sipb.mit.edu/project/sipb-athena/repository/src/olh/libmenu/attach.c,v 1.2 1993/05/03 13:59:14 miki Exp $";
#endif
#endif

#include <stdio.h>
#include <errno.h>
#include <strings.h>
#include <menu.h>
#include <sys/types.h>
#include <sys/wait.h>

/**********************************************************************
 * Set olh_attach_hook and olh_attach_done_hook to point to procedures
 * which print a message before and after a locker is attached.
 * olh_attach_hook should take one argument: the name of the locker.
 * olh_attach_done_hook takes the name of the locker and
 * also takes exit status of the shell that ran attach.
 **********************************************************************/

#ifdef __STDC__
void (*olh_attach_hook)(char *) = NULL;
void (*olh_attach_done_hook)(char *, long) = NULL;
#else
void (*olh_attach_hook)() = NULL;
void (*olh_attach_done_hook)() = NULL;
#endif

long
olh_attach(filsys, map)
     char *filsys;
     int map;
{
  long ret;
  int pid;
#ifdef SYSV
  int status;
#else
  union wait status;
#endif

  if (olh_attach_hook) olh_attach_hook(filsys);

  if ((pid = vfork()) == -1)
    {
      com_err("olh",errno,"Error forking to attach");
      ret = ERR_MENU_NOFORK;
      goto done;
    }

  if (pid == 0) {
    /* child */
    if (!map)
      execl("/bin/athena/attach","attach","-quiet","-nomap",filsys,NULL);
    else
      execl("/bin/athena/attach","attach","-quiet",filsys,NULL);
    perror("olh_attach: execl /bin/athena/attach");
    _exit(-2);
  }
  else {
    /* Parent */
    while (wait(&status) != pid)
      ;
  }

  /* User error status to return com_err code; */
#ifdef SYSV
  switch(WEXITSTATUS(status)) {
#else
  switch(status.w_retcode) {
#endif
  case 0:
    ret = 0L;			/* no error */
    break;
  case 1:
    ret = ERR_MENU_ATTACH1;	/* Bad arguments */
    break;
  case 3:
    ret = ERR_MENU_ATTACH3;	/* Internal fatal error */
    break;
  case 10:
    ret = ERR_MENU_ATTACH10;	/* Keberos failure */
    break;
  case 11:
    ret = ERR_MENU_ATTACH11;	/* Host communication failure */
    break;
  case 12:
    ret = ERR_MENU_ATTACH12;	/* Authentication failure */
    break;
  case 13:
    ret = ERR_MENU_ATTACH13;	/* No reserved ports available */
    break;
  case 20:
    ret = ERR_MENU_ATTACH20;	/* Bad filesystem name */
    break;
  case 21:
    ret = ERR_MENU_ATTACH21;	/* Filesystem in use by other attach process */
    break;
  case 24:
    ret = ERR_MENU_ATTACH24;	/* User is not allowed to attach filesystem */
    break;
  case 25:
    ret = ERR_MENU_ATTACH25;	/* not allowed to attach at this mountpoint */
    break;
  case 26:
    ret = ERR_MENU_ATTACH26;	/* The remote filesystem does not exist */
    break;
  default:
    ret = ERR_MENU_ATTACH;	/* Generic error */
    break;
  }

done:

  if (olh_attach_done_hook) olh_attach_done_hook(filsys, ret);

  return(ret);
}
 
