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

/*----------------------------------------------------
 * dqs_c_qhold.c Neil Lincoln 12/22 08:28:16 1995
 *
 * Copyright 1995
 *
 * 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.
 *
 *
 *--------------------------------------------------*/


#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_qhold(sfd,request_head)
     int           sfd;
     dqs_list_type **request_head;
     
     /*
       dqs_c_qhold-  is used solely by the qmaster and provides services
       to the qdel ancillary.
     */
     
{
  
  int                found;
  int                status;
  int			    holdval;
  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;
  string         holdmsg;
  
  DENTER((DQS_EVENT,"dqs_c_qhold"));
  
  request_list= *request_head;
  
  if ((reply_head=dqs_locate_tid(request_list->tid)))
    {  /* this transaction has already occurred */ 
      INFO((DQS_EVENT,"DQS_ERROR_0127 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 QHOLD:
      DPRINTF((DQS_EVENT,"===>QHOLD:"));
      if( (VALID(SYSTEM,request_list->job->hold) )||
	  (VALID(OTHER,request_list->job->hold)) ) {
	if (dqs_operator(request_list->user))
	  {
	    NAK((ACK_EVENT,"error: \"%s\" - using SYSTEM or OTHER holds requires manager/operator privilages",
		 request_list->user));
	    ERROR((DQS_EVENT,"DQS_ERROR_0128 %s",ACK_EVENT));
	    goto dqs_c_qhold_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_0129 %s",ACK_EVENT));
	    lp=lp->next;
	    continue;
	  }
	  DTRACE;
	  
	  if (job->status == RUNNING){
	    NAK((ACK_EVENT,"error: %d - cannot HOLD a job already RUNNING", job->job_number));
	    ERROR((DQS_EVENT,"DQS_ERROR_0130 %s",ACK_EVENT));
	    lp= lp->next;
	    continue;
	  }
	  
	  if ( (dqs_job_owner(request_list->user,lp->str0) ) && ( dqs_operator(request_list->user) ) ){
	    NAK((ACK_EVENT,"error: %s - you do not have the necessary privilages to place a hold on job \"%s\"",
		 request_list->user,lp->str0));
	    ERROR((DQS_EVENT,"DQS_ERROR_0131 %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_0132 %s",ACK_EVENT));
	      lp=lp->next;
	      continue;
	    }
	  }  /* job master queue */
	  DTRACE;
	  
	  holdval= request_list->job->hold;
	  
	  if(VALID(NO_HOLD,holdval) ){
	    CLEARBIT(OTHER,job->hold);
	    CLEARBIT(SYSTEM,job->hold);
	    CLEARBIT(USER,job->hold);
	    SETBIT(NO_HOLD,job->hold);
	    sprintf(holdmsg,"cleared holds for");
	  }
	  else{
	    sprintf(holdmsg,"set holds ");
	    
	    if(VALID(OTHER,holdval) ){
	      SETBIT(OTHER,job->hold);
	      strcat(holdmsg,"OTHER ");
	    }
	    if(VALID(SYSTEM,holdval) ){
	      SETBIT(SYSTEM, job->hold);
	      strcat(holdmsg, "SYSTEM ");
	    }
	    if(VALID(USER,holdval) ){
	      SETBIT(USER, job->hold);
	      strcat(holdmsg,"USER ");
	    }
	  }
	  DTRACE;
	  ACK((ACK_EVENT,"%s %s for  the job \"%s\"",
	       request_list->user, holdmsg, lp->str0));
	  INFO((DQS_EVENT,"DQS_ERROR_0133 %s",ACK_EVENT));
	  
	  lp=lp->next;
	}  /* while lp */
      
      break;
      
      /*------------------------------------------------------*/
    default:
      NAK((ACK_EVENT,"error: unknown list type %d",request_list->type));
      INFO((DQS_EVENT,"DQS_ERROR_0134 %s",ACK_EVENT));
      break;
      
    } /* case */
  
 dqs_c_qhold_end:
  
  if (!reply_head)
    {
      NAK((ACK_EVENT,"error: no suitable queues"));
    }
  DTRACE;
  
  reply_head->tid=request_list->tid;
  dqs_save_tid(reply_head,QHOLD);
  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;
  
}
