static char dqs_c_qdel_rcsid[]="$Id: dqs_c_qdel.c,v 1.1.1.1 1998/08/18 14:39:11 green Exp $";

/*----------------------------------------------------
 * dqs_c_qdel.c Tom Green Mon Jan 31 10:42:38 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_c_qdel.c,v $
 * Revision 1.1.1.1  1998/08/18 14:39:11  green
 * DQS 3.2.0.5 WIP Import
 *
 * Revision 1.1.1.1  1997/04/10 15:10:31  green
 * DQS 3.1.3.4.1 Distribution
 *
 * Revision 3.9  1996/11/20 23:03:19  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:19:57  nrl
 * Added error cataloguing number to all routines
 *
 * Revision 3.7  1995/11/01  16:16:29  nrl
 * Fixed spelling error.. privelages -> privileges
 *
 * Revision 3.6  1995/06/12  17:59:07  nrl
 * repair another SIGNAL handling problem
 *
 * Revision 3.5  1995/05/26  19:07:28  nrl
 * Cleaned up signal handling and the notify option with the
 * help of Ron Lee.
 *
 * Revision 3.4  1995/02/16  21:54:45  nrl
 * removed buggy cleanup
 *
 * Revision 3.3  1995/02/16  20:34:13  nrl
 * Force cleared job structure to prevent garbage from fouling things up.
 * Added SIGCHLD to iomask to keep "mailer" from messing up
 * socket transfers.
 *
 * Revision 3.2  1995/01/17  16:32:01  nrl
 * completed mailer feature
 *
 * Revision 3.1  1994/06/16  10:46:47  green
 * now calls dqs_signal_queue() with job_number
 *
 * Revision 3.0  1994/03/07  04:13:23  green
 * 3.0 freeze
 *
 * Revision 1.1.1.1  1994/02/01  17:57:38  green
 * DQS 3.0 ALPHA
 *
 *--------------------------------------------------*/


#include "h.h"
#include "def.h"
#include "dqs.h"
#include "struct.h"
#include "func.h"
#include "globals.h"
#include "dqs_errno.h"

/************************************************************************/
void dqs_c_qdel(sfd,request_head)
     int           sfd;
     dqs_list_type **request_head;
     
     /*
       dqs_c_qdel-  is used solely by the qmaster and provides services
       to the qdel ancillary.
     */
     
{
  
  int                found;
  int                status;
  char               *cp;
  u_long32           i;
  string             str;
  dqs_list_type      *lp;
  dqs_list_type      *lp2;
  dqs_list_type      listel;
  dqs_list_type      *request_list;
  dqs_list_type      *reply_head=NULL;
  dqs_queue_type     *queue;
  dqs_job_type       *job;
  struct sockaddr_in cli_addr;
  char dqs_mail_subj[1024];
  char dqs_mail_body[1024];
  dqs_list_type *mail_users;
  int            mail_options;
  
  
  DENTER((DQS_EVENT,"dqs_c_qdel"));
  
  request_list= *request_head;
  
  if ((reply_head=dqs_locate_tid(request_list->tid)))
    {  /* this transaction has already occurred */ 
      INFO((DQS_EVENT,"DQS_ERROR_0117 TRANSACTION ALREADY OCCURRED"));
      *request_head=dqs_free_list(*request_head);
      if ((sfd=dqs_send_list(NULL,NULL,sfd,reply_head))<0)
	{
	  DEXITE;
	  return;
	}
      dqs_close_sfd(sfd);
      DEXIT;
      return;
    }
  
  DPRINTF((DQS_EVENT,"------------------------------------------------------"));
  
  switch(request_list->type)
    {
    case DELETE_JOB_REQUEST:
      DPRINTF((DQS_EVENT,"===>QDEL:"));
      DTRACE;
      
      /* first lets make sure they have permission IFF a force is involved */
      if (request_list->job->force)
	{
	  if (dqs_operator(request_list->user))
	    {
	      NAK((ACK_EVENT,"error: \"%s\" - forcing a queue state requires manager/operator privilages",
		   request_list->user));
	      ERROR((DQS_EVENT,"DQS_ERROR_0118 %s",ACK_EVENT));
	      goto dqs_c_qmod_end;
	      break;
	      
	    }
	}
      DTRACE;
      
      lp=request_list->job->job_identifier_list;
      while (lp)
	{
	  DTRACE;
	  job=dqs_locate_job(lp->str0);
	  if (!job)
	    {
	      NAK((ACK_EVENT,"error: cannot locate the job \"%s\"",
		   lp->str0));
	      ERROR((DQS_EVENT,"DQS_ERROR_0119 %s",ACK_EVENT));
	      lp=lp->next;
	      continue;
	    }
	  DTRACE;
	  
	  if (dqs_job_owner(request_list->user,lp->str0))
	    {
	      NAK((ACK_EVENT,"error: %s - you do not have the necessary privilages to delete the job \"%s\"",
		   request_list->user,lp->str0));
	      ERROR((DQS_EVENT,"DQS_ERROR_0120 %s",ACK_EVENT));
	      lp=lp->next;
	      continue;
	    }
	  DTRACE;
	  if (job->master_queue)
	    {
	      queue=dqs_locate_queue(job->master_queue);
	      DTRACE;
	      if (!queue)
		{
		  NAK((ACK_EVENT,"error: cannot locate the queue \"%s\" associated with this job",
		       job->master_queue));
		  ERROR((DQS_EVENT,"DQS_ERROR_0121 %s",ACK_EVENT));
		  lp=lp->next;
		  continue;
		}
	      
	      DTRACE;
	      /*   send mail to users if requested                  */
	      mail_users= job->mail_list;
	      mail_options= job->mail_options;
	      if ( VALID(MAIL_AT_ABORT ,mail_options) ){
		sprintf(dqs_mail_subj,"Job %d Killed",job->job_number);
		sprintf(dqs_mail_body,"Job %d Killed",job->job_number);
		dqs_mail(mail_users,dqs_mail_subj, dqs_mail_body);
	      }
	      
	      if (dqs_signal_queue(DQS_SIGKILL,queue,job->job_number))
		{
		  DTRACE;
		  if (request_list->job->force)
		    {
		      DTRACE;
		      NAK((ACK_EVENT,"warning: %s forced the deletion of job \"%s\"",
			   request_list->user,lp->str0));
		      WARNING((DQS_EVENT,"DQS_ERROR_0122 %s",ACK_EVENT));
		    }
		  else
		    {
		      DTRACE;
		      NAK((ACK_EVENT,"error: %s unable to sync state with remote dqs_execd for the deletion of job \"%s\"",
			   request_list->user,lp->str0));
		      ERROR((DQS_EVENT,"DQS_ERROR_0123 %s",ACK_EVENT));
		    }
		  DTRACE;
		}
	      else
		{
		  DTRACE;
		  ACK((ACK_EVENT,"%s has deleted the job \"%s\"",
		       request_list->user,lp->str0));
		  INFO((DQS_EVENT,"DQS_ERROR_0124 %s",ACK_EVENT));
		  
		}
	      DTRACE;
	    }
	  else
	    {
	      DTRACE;
	      ACK((ACK_EVENT,"%s has deleted the job \"%s\"",
		   request_list->user,lp->str0));
	      INFO((DQS_EVENT,"DQS_ERROR_0125 %s",ACK_EVENT));
	      (void) dqs_del_job(lp->str0);
	      
	    }
	  
	  lp=lp->next;
	}
      
      break;
      
      /*------------------------------------------------------*/
    default:
      NAK((ACK_EVENT,"error: unknown list type %d",request_list->type));
      INFO((DQS_EVENT,"DQS_ERROR_0126 %s",ACK_EVENT));
      break;
    }
  DTRACE;
  
 dqs_c_qmod_end:
  
  if (!reply_head)
    {
      NAK((ACK_EVENT,"error: no suitable queues"));
    }
  DTRACE;
  
  reply_head->tid=request_list->tid;
  dqs_save_tid(reply_head,QMOD);
  request_list->tid=NULL;
  DTRACE;
  
  *request_head=dqs_free_list(*request_head);
  
  if ((sfd=dqs_send_list(NULL,NULL,sfd,reply_head))<0)
    {
      DEXITE;
      return;
    }
  
  dqs_close_sfd(sfd);
  
  DEXIT;
  return;
  
}
