static char dqs_c_qrls_rcsid[]="$Id: dqs_c_qrls.c,v 1.1.1.1 1997/04/10 15:10:31 green Exp $";

/*----------------------------------------------------
 * dqs_c_qrls.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_qrls(sfd,request_head)
int           sfd;
dqs_list_type **request_head;

/*
   dqs_c_qrls-  is used solely by the qmaster and provides services
   to the qdel ancillary.
   */

{
     
     int                found;
     int                status;
     char               *cp;
     u_long32           i;
     int				holdval;
     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_qrls"));
     
     request_list= *request_head;
     
     if ((reply_head=dqs_locate_tid(request_list->tid)))
     {  /* this transaction has already occurred */ 
	  INFO((DQS_EVENT,"DQS_ERROR_0191 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 QRLS:
	      DPRINTF((DQS_EVENT,"===>QRLS:"));
          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_0192 %s",ACK_EVENT));
	             goto dqs_c_qrls_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_0193 %s",ACK_EVENT));
                    lp=lp->next;
                    continue;
             }
	         DTRACE;

  	         if (job->status == RUNNING){
                NAK((ACK_EVENT,"error: %d - cannot RELEASE a job already RUNNING", job->job_number));
		        ERROR((DQS_EVENT,"DQS_ERROR_0194 %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 RELEASE on job \"%s\"",
                         request_list->user,lp->str0));
                 ERROR((DQS_EVENT,"DQS_ERROR_0195 %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_0196 %s",ACK_EVENT));
			        lp=lp->next;
			        continue;
		          }
             }		    
		          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,"released holds ");

                if(VALID(OTHER,holdval) ){
                     CLEARBIT(OTHER,job->hold);
                     strcat(holdmsg,"OTHER ");
                }
                if(VALID(SYSTEM,holdval) ){
                     CLEARBIT(SYSTEM, job->hold);
                     strcat(holdmsg, "SYSTEM ");
                }
                if(VALID(USER,holdval) ){
                    CLEARBIT(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_0197 %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_0198 %s",ACK_EVENT));
	      break;
     }/* end of switch  */

     DTRACE;
     
     dqs_c_qrls_end:
     
     if (!reply_head){
	    NAK((ACK_EVENT,"error: no suitable queues"));
     }
     DTRACE;
     
     reply_head->tid=request_list->tid;
     dqs_save_tid(reply_head,QRLS);
     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;
     
}
