static char dqs_mail_rcsid[]="$Id: dqs_mail.c,v 1.3 1998/10/13 15:08:48 green Exp $";

/*----------------------------------------------------
 * dqs_mail.c Tom Green Mon Jan 31 10:42:49 1994
 *
 * Copyright 1993
 *
 * SUPER COMPUTER COMPUTATIONS RESEARCH INSTITUTE
 *            FLORIDA STATE UNIVERSITY
 *
 *
 * SCRI representatives make no claims about the
 * suitability of this software for any purpose.
 * It is provided "as is" without express or
 * implied warranty.
 *
 * $Log: dqs_mail.c,v $
 * Revision 1.3  1998/10/13 15:08:48  green
 * Solaris 2.6 support - hopefully, as I don't have access to one...
 *
 * Revision 1.2  1998/10/13 14:23:12  green
 * Patching Solaris defines - shooting in the dark here as I don't have access to
 * a Solaris 2.5 box
 *
 * Revision 1.1.1.1  1998/08/18 14:39:12  green
 * DQS 3.2.0.5 WIP Import
 *
 * Revision 1.1.1.1  1997/04/10 15:10:33  green
 * DQS 3.1.3.4.1 Distribution
 *
 * Revision 3.9  1996/11/20 23:03:59  nrl
 * Several fixes submitted by or as a result of investigations by
 * Ron Lee, Bodo Bechenback, Guntram Wolski and Frank Dwyyer.
 *
 * Revision 3.8  1996/03/22  04:20:41  nrl
 * Added error cataloguing number to all routines
 *
 * Revision 3.7  1995/07/12  18:47:52  nrl
 * Fixed numerous problmes with Irix 5.3 and 6.0 systems
 *
 * Revision 3.6  1995/06/15  11:39:37  nrl
 * Changed accounting info for Solaris and AIX.
 *
 * Revision 3.5  1995/05/29  18:08:51  nrl
 * More solaris stuff GAGGHH had to differentiate more cases of
 * solaris2.3 and solaris2.4 stuff
 *
 * Revision 3.4  1995/05/28  16:44:38  nrl
 * Fixes for solaris2.3 and solaris 2.4 and mailer default recipients
 *
 * Revision 3.3  1995/02/21  20:36:58  nrl
 * fixed write_queue_to)disk as per A.brandes in schedule.c
 *
 * Revision 3.2  1995/01/30  15:22:01  nrl
 * added "tid" verification between execd and qmaster to prevent
 * "ghost" jobs from persisting in visible queue. Changed ERROR messages
 * which were for information only to DEBUG messages.
 *
 * Revision 3.1  1995/01/17  16:32:09  nrl
 * completed mailer feature
 *
 * Revision 3.0  1994/03/07  04:14:04  green
 * 3.0 freeze
 *
 * Revision 1.1.1.1  1994/02/01  17:57:43  green
 * DQS 3.0 ALPHA
 *
 *--------------------------------------------------*/


#include "h.h"
#include "def.h"
#include "dqs.h"
#include "struct.h"
#include "func.h"
#include "globals.h"
#include <sys/errno.h>
#include "dqs_errno.h"

/************************************************************/
void dqs_mail(user_list,subj,buf)
     dqs_list_type *user_list;
     char          *subj;
     char          *buf;
     
{
  
  DENTER((DQS_EVENT,"dqs_mail"));
  
  if (!buf)
    buf=subj;
  
  if (user_list->next) user_list=user_list->next;
  while (user_list)
    {
      dqs_send_mail(user_list->str0,user_list->str1,subj,buf);
      user_list=user_list->next;
    }
  DEXIT;
  return;
  
}

/************************************************************/
void dqs_send_mail(user,host,subj,buf)
     char *user;
     char *host;
     char *subj;
     char *buf;
     
{
  
  int           pid;
  int           pid2;
  int           exit_status;
  int           fd;
  int           pipefds[2];
  FILE          *fp;
  string        user_str;
#if ( defined(_UNICOS) || defined(__hpux) || defined(solaris) || defined(SOLARIS23_UP) )
  
#else
  struct rusage rusage;
#endif     
  
#if (SVR3) /* DAMN this is irratating */
  union wait status;
#else
  int status;
#endif
  
  
  DENTER((DQS_EVENT,"dqs_send_mail"));
  
  if (!user)
    {
      ERROR((DQS_EVENT,"DQS_ERROR_0283 error: NULL \"user\" string passed to dqs_send_mail()"));
      DEXITE;
      return;
    }
  
  alarm(0);
  
  if (fork())
    {
      DEXIT;
      return;
    }
  
  SETPGRP;
  
  dqs_close_fds();
  
  if (pipe(pipefds) < 0)
    {
      CRITICAL((DQS_EVENT,"DQS_ERROR_0284 error: pipe() failed"));
      DEXITE;
      exit(-1);
    }
  if ((pid = fork()) < 0) {
    CRITICAL((DQS_EVENT,"DQS_ERROR_0285 error: fork() failed"));
    DEXITE;
    exit(-1);
  }
  if (!pid)
    {
      int duped;
      
      if (host)
	sprintf(user_str,"%s@%s",user,host);
      else
	sprintf(user_str,"%s",user);
      
      if ((duped = dup2(pipefds[0], 0)) < 0)
	{
	  CRITICAL((DQS_EVENT,"DQS_ERROR_0286 error: dup() failed"));
	  exit(-1);
	}
      
      close(pipefds[1]);
      
      if (MAIL_HAS_SUBJ_LINE)
	execl(conf.mailer,"mail","-s",subj,user_str,0);
      else
	execl(conf.mailer,"mail",user_str,0);
      CRITICAL((DQS_EVENT,"DQS_ERROR_0287 error: mail failed"));
      DEXITE;
      exit(-1);
    }
  
  close(pipefds[0]);
  fp = fdopen(pipefds[1],"w");
  fprintf(fp,"%s\n",buf);
  fclose(fp);
  
  dqs_setup_sig_handlers();
  while (TRUE)
    {
      alarm(60); /* max time to allow for mail */
      sigprocmask(SIG_SETMASK,&io_mask,&omask);   
      SFD=9999;
      sigaction(SIGALRM,&sigalrm_vec,&sigalrm_ovec); 
      
#if ( defined(_UNICOS) || defined(__hpux) || defined(solaris) || defined(SOLARIS23_UP) )
      pid2=waitpid(-1,&status,0);
#else
      pid2=wait3(&status,0,(struct rusage *) &rusage);
#endif       
      
      alarm(0);
      if (pid2==0)
	{ /* how could this happen? */
	  kill(pid,SIGKILL);
	  CRITICAL((DQS_EVENT,"DQS_ERROR_0288 error: mail failed"));
	  DEXITE;
	  exit(-1);
	}
      
      if (pid2==-1)
	{ /* alarm must have went off */
	  kill(pid,SIGKILL);
	  DPRINTF((DQS_EVENT,"error: mail failed %d",errno));
	  DEXITE;
	  exit(-1);
	}
      
      if (WIFSTOPPED(status))
	{ /* how could this happen? */
	  kill(pid,SIGKILL);
	  CRITICAL((DQS_EVENT,"DQS_ERROR_0289 error: mail failed"));
	  DEXITE;
	  exit(-1);
	}
#if (SVR3)
      exit_status=status.w_retcode;
#else
      exit_status=status;
#endif
      if (exit_status)
	{
	  CRITICAL((DQS_EVENT,"DQS_ERROR_0290 error: mail failed"));
	  DEXITE;
	  exit(-1);
	}
      else
	{
	  DPRINTF((DQS_EVENT,"info: mail successful"));
	  DEXIT;
	  exit(0);
	}
    }
  
}


