static char dqs_parse_rcsid[]="$Id: dqs_parse.c,v 1.1.1.1 1998/08/18 14:39:12 green Exp $";

/*----------------------------------------------------
 * dqs_parse.c Tom Green Mon Jan 31 10:42:55 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_parse.c,v $
 * Revision 1.1.1.1  1998/08/18 14:39:12  green
 * DQS 3.2.0.5 WIP Import
 *
 * Revision 1.6  1998/07/13 12:54:31  decker
 * One more time
 *
 * Revision 1.5  1998/06/30 18:39:35  decker
 * Oops...syntax error fixed
 *
 * Revision 1.4  1998/06/30 17:45:45  decker
 * Bug fixes by Hayden implemented
 *
 * Revision 1.3  1997/10/23 17:14:54  decker
 * Fix by Doug Gibson, if '=' detected in string
 *
 * Revision 1.2  1997/04/14 19:06:04  green
 * make sure "-N" doesn't contain a "/"
 *
 * Revision 1.1.1.1  1997/04/10 15:10:33  green
 * DQS 3.1.3.4.1 Distribution
 *
 * Revision 3.46  1996/08/13 13:00:02  nrl
 * Several dqs_string_insert calls were missing the returned pointer
 * target.
 *
 * Revision 3.45  1996/07/18  11:40:20  nrl
 * fixed a "double scan" problem in dqs_parse.c with a misplaced
 * continue statement. Qsub Was SegVing on LINUX system because
 * of the use of dqs_free_job. LINUX heap management is obviously not
 * compliant with UNIX standards.
 *
 * Revision 3.43  1996/07/12  00:43:35  nrl
 * more fixes for SOLARIS and linux
 *
 * Revision 3.42  1996/06/27  01:55:53  nrl
 * changes to accomodate osf gcc
 *
 * Revision 3.41  1996/06/17  02:28:58  nrl
 * Updtaes from Guntram Wolski, Ron Lee, John Makosky and
 * Bodo Beckebach
 *
 * Revision 3.40  1996/03/26  00:03:14  nrl
 * changed hold/release to explicit use of hold types
 *
 * Revision 3.39  1996/03/25  16:28:34  nrl
 * Repaired parameter scanning for qidle
 *
 * Revision 3.38  1996/03/22  04:20:48  nrl
 * Added error cataloguing number to all routines
 *
 * Revision 3.37  1996/03/21  17:06:57  nrl
 * added fortran and "c" syntax to resource requests
 *
 * Revision 3.36  1996/03/17  00:57:45  nrl
 * merge in qsub prevalidation scheme and consumable restoration
 *
 * Revision 3.35  1996/03/12  17:12:25  nrl
 * removed aborts and replaced with an error messaging scheme
 * to send email to the dqs adminsitrator and wait for
 * actions by that administrator
 *
 * Revision 3.34  1996/02/19  19:02:15  nrl
 * added a separate subpriority field, pluys scheduling_flags and
 * job_seq_number to remove the 3.1.2.4 kludges , modified the
 * scheduling algorith once again
 *
 * Revision 3.33  1996/02/07  13:08:10  nrl
 * Added "process leader" and TMP_FILES link capability
 *
 * Revision 3.32  1996/01/19  20:58:55  nrl
 * merged SCRI code and new job and queue structure changes
 *
 * Revision 3.31  1996/01/14  22:26:34  nrl
 * Added job_status_info to contain detailed information about
 * the job status
 *
 * Revision 3.30  1996/01/10  13:52:45  nrl
 * Base for 3.1.3
 *
 * Revision 3.29  1995/11/01  17:47:56  nrl
 * Changed keyword reautht to reauth to match docs
 *
 * Revision 3.28  1995/06/21  16:57:45  nrl
 * Major scheduling changes... added a subpriority field to manage
 * things within the user submitted priority. Added priority info to the
 * accounting file.
 *
 * Revision 3.27  1995/06/16  15:35:26  nrl
 * eliminated the need to have a "qty.eq.1" in the default cases
 * fixed the "-notify" option when used with suspend queue function
 *
 * Revision 3.26  1995/06/15  12:26:10  nrl
 * Created default "qty.eq.1" when no resources specified
 *
 * Revision 3.25  1995/06/15  11:39:43  nrl
 * Changed accounting info for Solaris and AIX.
 *
 * Revision 3.24  1995/05/28  16:44:39  nrl
 * Fixes for solaris2.3 and solaris 2.4 and mailer default recipients
 *
 * Revision 3.23  1995/03/05  03:47:27  nrl
 * Included Axel Brandes job scheduling mechanism to keep one
 * user from hawging the queue.
 *
 * Revision 3.22  1995/02/17  02:57:00  nrl
 * Added formal skeletons for PVM and TCGMSG parallel modes
 *
 * Revision 3.21  1995/02/16  20:34:20  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.20  1995/02/05  00:51:13  nrl
 * Changed meaning of "-clean" option to mean cleanout all
 * options potentially resettable by qalter. Added interactive
 * prompting.
 *
 * Revision 3.19  1995/01/27  14:09:49  nrl
 * Changed Supspend on completion to continue beyond an unsuspend operation
 * so that jobs can be "stepped" thru the queues. Increased timout
 * retries for connect to make the system more tolerant of network delyas.
 *
 * Revision 3.18  1995/01/24  21:04:59  nrl
 * made changes to plug memory leaks and to complete the suspend
 * on completion function.
 *
 * Revision 3.17  1994/08/02  23:11:09  green
 * added support for a crude job staging mechanism
 *
 * Revision 3.16  1994/06/12  23:09:33  green
 * force "job->notify" to true if a "-par opt" is requested.  THIS IS A
 * MUST to allow remote dshd's to cleanup...
 *
 * QUEUES MUST HAVE NOTIFY ENABLED TO UTILIZE PARALLEL ATTRIBUTES!!!
 *
 * Revision 3.15  1994/06/09  20:03:51  green
 * added "-par generic_sla" and "-par generic_all" to dqs_pars.c,
 * dqs_exec_job.c and dqs_utility.c
 *
 * forgot a couple ";" on my last checkin of dqs_sec.c(knew I should
 * have compiled before checking in...)
 *
 * Revision 3.14  1994/06/06  01:23:04  green
 * added "dqs_dshd_service" to the DQS config
 *
 * add "-par pvm" - though we do NOT intend to support it
 * (see dqs_start_pvm.c for a more thorough discussion)
 *
 * Revision 3.13  1994/06/04  15:56:18  green
 * added "-par p4|mpi" parse support
 *
 * Revision 3.12  1994/06/04  15:24:29  green
 * added "-par parallel_packge" support
 *
 * Revision 3.11  1994/06/04  14:54:58  green
 * added the variable "job->parallel_package"
 *
 * Revision 3.10  1994/06/03  03:44:04  green
 * updated to support p4/mpi
 *
 * Revision 3.9  1994/06/03  00:25:50  green
 * replaced "DQSX_STR12" with "master_queue_exec_str" in support of MPI
 * mods
 *
 * Revision 3.8  1994/06/03  00:17:29  green
 * modified default "conf_file" and "dqs.h"
 *
 * modified the parsing routines to move the "-exec" option into
 * "-l", "-master" and "-q"
 *
 * Revision 3.7  1994/05/31  01:38:50  green
 * disallowed "-passwd" and "-Passwd" if AFS support not compiled in
 *
 * Revision 3.6  1994/04/20  23:25:53  green
 * added qhold.c qrls.c
 *
 * Revision 3.5  1994/04/01  02:59:30  green
 * added "qalter" support
 *
 * Revision 3.4  1994/03/26  16:33:34  green
 * added "-srl" support.
 *
 * dqs_resolve.c:dqs_read_resolve_file() now returns the primary qmaster
 * name for fields marked as "none"
 *
 * Revision 3.3  1994/03/18  18:13:14  green
 * patched dqs_parse_date_time() to check first dqs_strtok() call.
 * (patch forwarded by wdg@uncc.edu)
 *
 * Revision 3.2  1994/03/18  17:52:53  green
 * modified the checking of set variables to use absolute pointer.
 *
 * Revision 3.1  1994/03/17  15:40:15  green
 * added support for "qconf -qmon"
 *
 * Revision 3.0  1994/03/07  04:14:14  green
 * 3.0 freeze
 *
 * Revision 1.6  1994/03/04  20:49:31  green
 * figured as much - last patch broke more than it fixed - removed.
 *
 * FINR
 *
 * Revision 1.5  1994/03/04  20:07:46  green
 * modified dqs_showlist() to handle NULLs - more gracefully.
 *
 * added a warning for "unknown" requests in dqs_parse.c - this should
 * probably be an exit - but as the code is being relased in 2 days,
 * scared I might break more than I fix....
 *
 * fixed qconf so it no longer drops core if no options.
 *
 * Revision 1.4  1994/03/04  16:04:24  green
 * all calls to setenv() now funnel through dqs_setenv() to verify they
 * are strlen() < MAX_STRING_SIZE
 *
 * Revision 1.3  1994/02/23  20:34:22  green
 * added some sanity checking to dqs_parse_job() and dqs_parse_qconf()
 *
 * Revision 1.2  1994/02/10  18:24:21  green
 * removed the following options from "qsub"
 *
 *      -k
 *      -p
 *      -u
 *      -z
 *
 * fixed the following options in "qsub"
 *
 *      -e
 *      -o
 *      -N
 *      -v
 *
 * synced with docs
 *
 * Revision 1.1.1.1  1994/02/01  17:57:44  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"

int    hard=TRUE;

/************************************************************************/
dqs_job_type *dqs_parse_job(head,envp)
     dqs_list_type *head;
     char **envp;
     
{
  
  int hard=TRUE;
  char          *cp,*cp2,*cp3;
  string        tmp_str;
  dqs_job_type  *job;
  dqs_list_type *sp=(dqs_list_type *) NULL;
  dqs_list_type *argv_list=(dqs_list_type *) NULL;
  dqs_list_type *request_list=(dqs_list_type *) NULL;
  string        tmp_str2, tmp_str3;
  dqs_list_type *tmp_sp  = (dqs_list_type *) NULL;
  dqs_list_type *tmp_sp2 = (dqs_list_type *) NULL;
  
  DENTER((DQS_EVENT,"dqs_parse_job"));
  
  job=(dqs_job_type *)dqs_malloc(sizeof(dqs_job_type));
  bzero((char *)job,sizeof(dqs_job_type) );   /* ensure clean entry */
  
  DTRACE;
  
  job->submission_time=dqs_get_gmt();
  job->owner=dqs_string_insert(job->owner,me.user_name);
  job->uid=me.uid;
  job->euid=me.euid;
  cp=dqs_getenv("HOME");
  job->dqs_o_home=dqs_string_insert(job->dqs_o_home,cp);
  cp=dqs_getenv("LOGNAME");
  job->dqs_o_log_name=dqs_string_insert(job->dqs_o_log_name,cp);
  cp=dqs_getenv("PATH");
  job->dqs_o_path=dqs_string_insert(job->dqs_o_path,cp);
  cp=dqs_getenv("MAIL");
  job->dqs_o_mail=dqs_string_insert(job->dqs_o_mail,cp);
  cp=dqs_getenv("SHELL");
  job->dqs_o_shell=dqs_string_insert(job->dqs_o_shell,cp);
  cp=dqs_getenv("TZ");
  job->dqs_o_tz=dqs_string_insert(job->dqs_o_tz,cp);
  cp=dqs_getenv("WORKDIR");
  job->dqs_o_workdir=dqs_string_insert(job->dqs_o_workdir,cp);
  cp=dqs_getenv("HOST");
  if (!cp) cp=me.unqualified_hostname;
  
  job->dqs_o_host=dqs_string_insert(job->dqs_o_host,cp);
  job->cell=dqs_string_insert(job->cell,me.default_cell);
  
  /* to ensure a default mailer address we start with the submitter's name */
  /* for the time being this means that if qalter is invoked and the mailing*/
  /* list is null then the mailer target host will be the host where the  */
  /* qalter was executed. This will be changed in the future              */
  
  if (me.who == QSUB || me.who == QALTER)
    {
      strcpy(tmp_str,job->owner);
      strcat(tmp_str,"@");
      strcat(tmp_str,me.qualified_hostname);
      dqs_parse_mail_list(&job->mail_list,tmp_str);
    }
  
  job->script_argv_list = (dqs_list_type *) NULL;
  if (me.who == QSUB) job->priority = BASE_PRIORITY;
  
  DTRACE;
  
  sp=head;
  
  while (sp) {
    
    /*-----------------------------------------------------------------------------*/
    /* "-a [op] date_time */
    
    if (!strcmp("-a",sp->str0)) { 
      
      dqs_validate_option(a_OPT,sp->str0);
      
      if (job->execution_time) {
	WARNING((DQS_EVENT,
		 "\"%s\" option has already been set, overriding previous setting",
		 sp->str0));
      }
      
      /* next field(s) is "[op] date_time" */
      sp=dqs_parser_get_next(sp,sp->str0);
      if (me.who==QSELECT) { /* could have an option operator field */
	job->execution_time_op=dqs_parse_op(sp->str0);
	if (job->execution_time_op) { /* must have had an op */
	  sprintf(tmp_str,"-a %s",sp->str0);
	  sp=dqs_parser_get_next(sp,tmp_str);
	}
	else {
	  sprintf(tmp_str,"-a");
	}
      }
      
      DPRINTF((DQS_EVENT,"\"%s %s\"",tmp_str,sp->str0));
      
      job->execution_time=dqs_parse_date_time(sp->str0);
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-A account_list" */
    
    if (!strcmp("-A",sp->str0)) { 
      
      dqs_validate_option(A_OPT,sp->str0);
      
      if (job->account_list) {
	WARNING((DQS_EVENT,
		 "\"%s\" option has already been set, overiding previous setting",
		 sp->str0));
	job->account_list=dqs_free_list(job->account_list);
      }
      
      /* next field is account_list */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-A %s\"",sp->str0));
      dqs_parse_account_list(&job->account_list,sp->str0);
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-B" */
    
    if (!strcmp("-B",sp->str0)) { 
      
      dqs_validate_option(B_OPT,sp->str0);
      
      if (job->server_name) {
	WARNING((DQS_EVENT,"DQS_ERROR_0291 \"%s\" option has already been set",sp->str0));
      }
      
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      job->server_name=TRUE;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-c [op] interval */
    
    if (!strcmp("-c",sp->str0)) { 
      
      dqs_validate_option(c_OPT,sp->str0);
      
      if (job->checkpoint_attr) {
	WARNING((DQS_EVENT,
		 "\"%s\" option has already been set, overriding previous setting",
		 sp->str0));
      }
      
      /* next field is [op] interval */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      if (me.who==QSELECT) { /* could have an optional operator field */
	job->checkpoint_attr_op=dqs_parse_op(sp->str0);
	if (job->checkpoint_attr_op) { /* must have had an op */
	  sprintf(tmp_str,"-s %s",sp->str0);
	  sp=dqs_parser_get_next(sp,tmp_str);
	}
	else {
	  sprintf(tmp_str,"-s");
	}
      }
      
      DPRINTF((DQS_EVENT,"\"%s %s\"",tmp_str,sp->str0));
      
      job->checkpoint_attr=dqs_parse_checkpoint_attr(sp->str0);
      if (!job->checkpoint_attr)
	job->checkpoint_interval=dqs_parse_checkpoint_interval(sp->str0);
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-cell cell_name" */
    
    if (!strcmp("-cell",sp->str0)) {
      
      dqs_validate_option(cell_OPT,sp->str0);
      
      /* next field is cell_name */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-cell %s\"",sp->str0));
      
      job->cell=dqs_string_insert(job->cell,sp->str0);
      me.default_cell=dqs_string_insert(me.default_cell,sp->str0);
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-clean" */
    
    if (!strcmp("-clean",sp->str0)) {
      
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      job->clean=TRUE;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-cwd" */
    
    if (!strcmp("-cwd",sp->str0)) {
      
      dqs_validate_option(cwd_OPT,sp->str0);
      
#ifdef GETWD
      if (!getwd(tmp_str))
#else
	if (!getcwd(tmp_str,sizeof(tmp_str)))
#endif
	  {
	    ERROR((DQS_EVENT,"DQS_ERROR_0292 error: getwd() failed"));
	    exit(DQS_EINVAL);
	  }
      
#ifdef SCRI_AUTOMOUNT
      
      if (!strncmp(tmp_str,"/a/",3)) {
	cp2=tmp_str;
	cp2 += 3;   
	cp3=strstr(cp2,"/");
	if (!cp3)
	  {      
	    ERROR((DQS_EVENT,"DQS_ERROR_0293 error: unable to stat directory >%s<",tmp_str));
	    exit(DQS_EINVAL);          
	  }      
	job->cwd=dqs_string_insert(job->cwd,cp3);        
      }
      else
#endif
	job->cwd=dqs_string_insert(job->cwd,tmp_str);      /* musta been right */
      
      job->cwd=dqs_string_insert(job->cwd,tmp_str);
      
      DPRINTF((DQS_EVENT,"\"-cwd %s\"",tmp_str));
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-C directive_prefix" */
    
    if (!strcmp("-C",sp->str0)) {
      
      dqs_validate_option(C_OPT,sp->str0);
      
      if (job->directive_prefix) {
	WARNING((DQS_EVENT,
		 "\"%s\" option has already been set, overriding previous setting",
		 sp->str0));
      }
      
      /* next field is directive_prefix */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-c %s\"",sp->str0));
      job->directive_prefix=
	job->directive_prefix=dqs_string_insert(job->directive_prefix,sp->str0);
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-d" */
    
    if (!strcmp("-d",sp->str0)) {
      
      dqs_validate_option(d_OPT,sp->str0);
      if(me.who==QIDLE){
	sp=dqs_parser_get_next(sp,sp->str0);
	job->DQSX_STR15=dqs_string_insert(job->DQSX_STR15,sp->str0);
      }
      else{
	if (job->suspend_enable){
	  WARNING((DQS_EVENT,"DQS_ERROR_0294 \"suspend_enable\" has already been set, overriding previous setting"));
	}
	DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
	job->suspend_enable=DISABLED;
      }
      sp=sp->next;
      continue;
      
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-e path_name" */
    
    if (!strcmp("-e",sp->str0)) {
      
      dqs_validate_option(e_OPT,sp->str0);
      
      if (me.who==QMOD)
	{
	  if (job->suspend_enable)
	    {
	      WARNING((DQS_EVENT,"DQS_ERROR_0295 \"suspend_enable\" has already been set, overriding previous setting"));
	    }
	  DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
	  job->suspend_enable=ENABLED;
	}
      else
	{
	  /* next field is path_name */
	  sp=dqs_parser_get_next(sp,sp->str0);
	  
	  DPRINTF((DQS_EVENT,"\"-e %s\"",sp->str0));
	  dqs_parse_path_list(&job->stderr_path_list,sp->str0);
	}
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-ext " */
    
    if (!strcmp("-ext",sp->str0)) {
      
      dqs_validate_option(ext_OPT,sp->str0);
      job->ext=TRUE;
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-E" */
    
    if (!strcmp("-E",sp->str0)) {
      
      dqs_validate_option(E_OPT,sp->str0);
      
      if (job->send_msg_to_stderr) {
	WARNING((DQS_EVENT,"DQS_ERROR_0296 \"%s\" option has already been set",sp->str0));
      }
      
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      job->send_msg_to_stderr=TRUE;
      
      sp=sp->next;
      continue;
    }
    
    
    /*-----------------------------------------------------------------------------*/
    /* "-f" */
    
    if (!strcmp("-f",sp->str0)) {
      
      dqs_validate_option(f_OPT,sp->str0);
      
      if ((me.who==QMOD)|| (me.who==QDEL))
	{
	  job->force=TRUE;
	}
      else
	{
	  if (job->full_listing) {
	    WARNING((DQS_EVENT,"DQS_ERROR_0297 \"%s\" option has already been set",sp->str0));
	  }
	  
	  DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
	  job->full_listing=TRUE;
	}
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-F" */
    
    if (!strcmp("-F",sp->str0)) {
      
      dqs_validate_option(F_OPT,sp->str0);
      
      if (job->force_submission) {
	WARNING((DQS_EVENT,"DQS_ERROR_0298 \"%s\" option has already been set",sp->str0));
      }
      
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      job->force_submission=TRUE;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/          
    /* "-g geometry" */
    
    if (!strcmp("-g",sp->str0)) {
      
      dqs_validate_option(g_OPT,sp->str0);
      
      /* next field is qidle geometry */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-g %s\"",sp->str0));
      job->DQSX_STR13=dqs_string_insert(job->DQSX_STR13,sp->str0);
      
      sp=sp->next;
      continue;
    }
    
    
    
    
    /*-----------------------------------------------------------------------------*/
    /* "-h [hold_list]" */
    
    if (!strcmp("-h",sp->str0)) {
      
      dqs_validate_option(h_OPT,sp->str0);
      
      if (job->hold) {
	WARNING((DQS_EVENT,
		 "\"%s\" option has already been set, overriding previous setting",
		 sp->str0));
      }
      
      if (me.who==QSUB) {
	job->hold=USER;
	DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
	sp=sp->next;
	continue;
      }
      
      if ((me.who==QALTER)|(me.who==QHOLD)|(me.who==QRLS)) {
	/* next field is hold_list */
	sp=dqs_parser_get_next(sp,sp->str0);
	DPRINTF((DQS_EVENT,"\"-h %s\"",sp->str0));
	job->hold=dqs_parse_hold_list(sp->str0);
      }
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-hard" */
    
    if (!strcmp("-hard",sp->str0)) {
      
      dqs_validate_option(hard_OPT,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      hard=TRUE;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-help" */
    
    if (!strcmp("-help",sp->str0)) {
      dqs_usage();
      exit(0);
    }
    
    
    /*-----------------------------------------------------------------------------*/
    /* "-hold_jid jid[,jid,...]" */
    
    if (!strcmp("-hold_jid",sp->str0)) {
      
      dqs_validate_option(hold_jid_OPT,sp->str0);
      
      if (job->jid_hold_list) {
	WARNING((DQS_EVENT,
		 "\"%s\" option has already been set, overriding previous setting",
		 sp->str0));
      }
      
      /* next field is hold_list */
      sp=dqs_parser_get_next(sp,sp->str0);
      DPRINTF((DQS_EVENT,"\"-hold_jid %s\"",sp->str0));
      job->jid_hold_list=dqs_parse_jid_hold_list(sp->str0);
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-j y|n" */
    
    if (!strcmp("-j",sp->str0)) {
      
      dqs_validate_option(j_OPT,sp->str0);
      
      if (job->merge_stderr) {
	WARNING((DQS_EVENT,
		 "\"%s\" option has already been set, overriding previous setting",
		 sp->str0));
      }
      
      /* next field is "y|n" */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-j %s\"",sp->str0));
      
      if (!strcmp("y",sp->str0))
	job->merge_stderr=TRUE;
      else if (!strcmp("n",sp->str0))
	job->merge_stderr=FALSE;
      else {
	ERROR((DQS_EVENT,"DQS_ERROR_0299 invalid option argument \"-j %s\"",sp->str0));
	dqs_usage();
	DEXITE;
	exit(DQS_EINVAL);
      }
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-jid jid" */
    
    if (!strcmp("-jid",sp->str0)) {
      
      dqs_validate_option(jid_OPT,sp->str0);
      
      /* next field is "jid" */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-jid %s\"",sp->str0));
      dqs_parse_job_identifier_list(&job->job_identifier_list,sp->str0);
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-k keep */
    
    if (!strcmp("-k",sp->str0)) {
      
      dqs_validate_option(k_OPT,sp->str0);
      
      if (job->maint_local_output) {
	WARNING((DQS_EVENT,"DQS_ERROR_0300 \"%s\" option has already been set",sp->str0));
      }
      
      /* next field is keep_list */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-k %s\"",sp->str0));
      job->maint_local_output=dqs_parse_keep_list(sp->str0);
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-l resource_list" */
    
    if (!strcmp("-l",sp->str0)) {
      
      
      
      dqs_validate_option(l_OPT,sp->str0);
      
      /* next field is resource_list */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-l %s\"",sp->str0));
      if (hard)
	dqs_parse_resource_list(&job->hard_resource_list,sp->str0);
      else
	dqs_parse_resource_list(&job->soft_resource_list,sp->str0);
      sp=sp->next;
      continue;
    }
    
    /*----------------------------------------------------------------------------*/
    /* "-m mail_options */
    
    if (!strcmp("-m",sp->str0)) {
      
      dqs_validate_option(m_OPT,sp->str0);
      
      /* next field is mail_options */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-m %s\"",sp->str0));
      job->mail_options=dqs_parse_mail_options(sp->str0);
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-master  destination_identifier" */
    
    if (!strcmp("-master",sp->str0)) { /* next field is destination_identifier */
      
      dqs_validate_option(master_OPT,sp->str0);
      
      /* next filed is destination_identifier */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-master %s\"",sp->str0));
      if (hard)
	dqs_parse_destination_identifier_list(&job->hard_master_list,sp->str0);
      else
	dqs_parse_destination_identifier_list(&job->soft_master_list,sp->str0);
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-M mail_list" */
    
    if (!strcmp("-M",sp->str0)) {
      
      dqs_validate_option(M_OPT,sp->str0);
      
      /* next field is mail_list */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-M %s\"",sp->str0));
      dqs_parse_mail_list(&job->mail_list,sp->str0);
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-N name" */
    
    if (!strcmp("-N",sp->str0)) {
      
      dqs_validate_option(N_OPT,sp->str0);
      
      if (job->job_name) {
	WARNING((DQS_EVENT,
		 "\"%s\" option has already been set, overiding previous setting",
		 sp->str0));
      }
      
      /* next field is name */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-N %s\"",sp->str0));
      job->job_name=dqs_string_insert( (char *)NULL,sp->str0);
      if (strstr(job->job_name,"/")) {
	ERROR((DQS_EVENT,"job_name cannot contain a \"/\""));
	exit(DQS_EINVAL);
      }
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-notify" */
    
    if (!strcmp("-notify",sp->str0)) {
      
      dqs_validate_option(notify_OPT,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-notify\""));
      job->notify=TRUE;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-o path_name" */
    
    if (!strcmp("-o",sp->str0)) {
      
      dqs_validate_option(o_OPT,sp->str0);
      
      /* next field is path_name */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-o %s\"",sp->str0));
      dqs_parse_path_list(&job->stdout_path_list,sp->str0);
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-O" */
    
    if (!strcmp("-O",sp->str0)) {
      
      dqs_validate_option(O_OPT,sp->str0);
      
      if (job->send_msg_to_stdout) {
	WARNING((DQS_EVENT,"DQS_ERROR_0301 \"%s\" option has already been set",sp->str0));
      }
      
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      job->send_msg_to_stdout=TRUE;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-p [op] priority */
    
    if (!strcmp("-p",sp->str0)) { 
      
      dqs_validate_option(p_OPT,sp->str0);
      
      sp=dqs_parser_get_next(sp,sp->str0);
      
      if (job->priority> 0) {
	WARNING((DQS_EVENT,
		 "\"%s\" option has already been set, overriding previous setting",
		 sp->str0));
      }
      
      if (( me.who == QSUB)|| (me.who==QALTER) ) {
	job->priority=BASE_PRIORITY + dqs_parse_priority(sp->str0);
      }
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    if (!strcmp("-par",sp->str0)) {
      
      dqs_validate_option(par_OPT,sp->str0);
      
      /* next field is path_name */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-par %s\"",sp->str0));
      if (!strcmp("p4",sp->str0))
	job->parallel_package=P4;
      else if (!strcmp("mpi",sp->str0))
	job->parallel_package=MPI;
      else if (!strcmp("generic_sla",sp->str0))
	job->parallel_package=GENERIC_SLA;
      else if (!strcmp("generic_all",sp->str0))
	job->parallel_package=GENERIC_ALL;
      else if (!strcmp("PVM",sp->str0))
	job->parallel_package=PVM;
      else if (!strcmp("TCGMSG",sp->str0))
	job->parallel_package=TCGMSG;
      
      else
	{
	  dqs_usage();
	  exit(-1);
	}
      job->notify=TRUE; /* got to notify dsh'es */
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-passwd" */
    
    if (!strcmp("-passwd",sp->str0)) {
      
      dqs_validate_option(passwd_OPT,sp->str0);
      
      if (!AFS) {
	ERROR((DQS_EVENT,"DQS_ERROR_0302 AFS support not compiled in \"-passwd\" not supported"));
	exit(-1);
      }
      
      DPRINTF((DQS_EVENT,"\"-passwd\""));
      job->passwd=TRUE;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-Passwd path_name" */
    
    if (!strcmp("-Passwd",sp->str0)) {
      
      dqs_validate_option(Passwd_OPT,sp->str0);
      
      if (!AFS) {
	ERROR((DQS_EVENT,"DQS_ERROR_0303 AFS support not compiled in \"-passwd\" not supported"));
	exit(-1);
      }
      
      /* next field is path_name */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-Passwd %s\"",sp->str0));
      job->Passwd=dqs_string_insert( (char *)NULL,sp->str0);
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-q destination_identifier_list" */
    
    if (!strcmp("-q",sp->str0)) { 
      
      dqs_validate_option(q_OPT,sp->str0);
      
      /* next field is destination_identifier */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-q %s\"",sp->str0));
      if (hard)
	dqs_parse_destination_identifier_list(&job->hard_queue_list,sp->str0);
      else
	dqs_parse_destination_identifier_list(&job->soft_queue_list,sp->str0);
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-Q" */
    
    if (!strcmp("-Q",sp->str0)) { 
      
      dqs_validate_option(A_OPT,sp->str0);
      
      if (job->op_is_destin_id) {
	WARNING((DQS_EVENT,"DQS_ERROR_0304 \"%s\" option has already been set",sp->str0));
      }
      
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      job->op_is_destin_id=TRUE;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-reauth #seconds" */
    
    if (!strcmp("-reauth",sp->str0)) {
      
      dqs_validate_option(reauth_OPT,sp->str0);
      
      if (job->reauth_time) {
	WARNING((DQS_EVENT,"DQS_ERROR_0305 \"%s\" option has already been set",sp->str0));
      }
      
      /* next field is number of seconds */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      job->reauth_time=dqs_atoi(sp->str0);
      if (job->reauth_time<600)
	{
	  ERROR((DQS_EVENT,"DQS_ERROR_0306 error: AFS reauth time must be greater than 600"));
	  DEXITE;
	  exit(-1);
	}
      
      DPRINTF((DQS_EVENT,"\"-reauth %s\"",sp->str0));
      job->op_is_destin_id=TRUE;
      
      sp=sp->next;
      continue;
    }
    
    
    /*-----------------------------------------------------------------------------*/
    /* "-r y|n" */
    
    if (!strcmp("-r",sp->str0)) {
      
      dqs_validate_option(r_OPT,sp->str0);
      
      if (job->restart) {
	WARNING((DQS_EVENT,"DQS_ERROR_0307 \"%s\" option has already been set",sp->str0));
      }
      
      /* next filed is "y|n" */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-j %s\"",sp->str0));
      if (!strcmp("y",sp->str0))
	job->restart=TRUE;
      else if (!strcmp("n",sp->str0))
	job->restart=FALSE;
      else {
	ERROR((DQS_EVENT,"DQS_ERROR_0308 invalid option argument \"-r %s\"",sp->str0));
	dqs_usage();
	DEXITE;
	exit(DQS_EINVAL);
      }
      
      sp=sp->next;
      continue;
      
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-rc consumable=amount" */
    
    if (!strcmp("-rc",sp->str0)) {
      
      dqs_validate_option(rc_OPT,sp->str0);
      
      if (job->consumable_resources_used) {
	WARNING((DQS_EVENT,"DQS_ERROR_0309 \"%s\" option has already been set",sp->str0));
      }
      if(me.who==QALTER){                               
	dqs_parse_consumable_list(job->consumable_resources_used, sp->str0);
      }
      
      sp=sp->next;
      continue;
      
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-s states" (qselect)*/
    /* "-s signal" (qsig)   */
    /* "-s"        (qmod)   */
    /* "-s seconds (qidle)  */
    if (!strcmp("-s",sp->str0)) {
      
      dqs_validate_option(s_OPT,sp->str0);
      
      if (me.who==QMOD)
	{
	  if (job->suspend_enable)
	    {
	      WARNING((DQS_EVENT,"DQS_ERROR_0310 \"suspend_enable\" has already been set, overriding previous setting"));
	    }
	  
	  DPRINTF((DQS_EVENT,"\"%-s\"",sp->str0));
	  
	  job->suspend_enable=SUSPENDED;
	}
      else{
	if (me.who==QIDLE){   /* sleep seconds  */
	  sp=dqs_parser_get_next(sp,sp->str0);
	  job->DQSX_STR13=dqs_string_insert(job->DQSX_STR13,sp->str0);
	}
	else{
	  /* next field is either "states" | "signal" */
	  sp=dqs_parser_get_next(sp,sp->str0);
	  
	  DPRINTF((DQS_EVENT,"\"%-s\"",sp->str0));
	  
	  if (me.who==QSELECT) job->states=dqs_parse_states(sp->str0);
	  else if ((me.who==QALTER)|(me.who==QHOLD)|(me.who==QRLS)) 
	    job->signal=dqs_parse_signal(sp->str0);
	}
      }
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-soc" */
    
    if (!strcmp("-soc",sp->str0)) {
      
      dqs_validate_option(soc_OPT,sp->str0);
      
      if (job->suspend_enable)
	{
	  WARNING((DQS_EVENT,"DQS_ERROR_0311 \"suspend_enable\" has already been set, overriding previous setting"));
	}
      
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      job->suspend_enable=SUSPEND_ON_COMP;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-soft" */
    
    if (!strcmp("-soft",sp->str0)) {
      
      dqs_validate_option(soft_OPT,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      hard=FALSE;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-srl" */
    
    if (!strcmp("-srl",sp->str0))
      {
	dqs_validate_option(srl_OPT,sp->str0);
	printf("Resolve list\n");
	dqs_showlist(Resolver_head,DQS_STDOUT|DQS_STR0|DQS_STR1|DQS_STR2|DQS_STR3|DQS_CHAIN,8);
	sp=sp->next;
	continue;
      }
    
    /*-----------------------------------------------------------------------------*/
    /* "-S path_name" */
    
    if (!strcmp("-S",sp->str0)) {
      
      dqs_validate_option(S_OPT,sp->str0);
      
      /* next field is path_name */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-S %s\"",sp->str0));
      dqs_parse_path_list(&job->shell_list,sp->str0);
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-u user_list" */
    
    if (!strcmp("-u",sp->str0)) {
      
      dqs_validate_option(u_OPT,sp->str0);
      
      /* next field is user_list */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-u %s\"",sp->str0));
      dqs_parse_user_list(&job->user_list,sp->str0);
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-ul" */
    
    if (!strcmp("-ul",sp->str0)) {
      
      dqs_validate_option(ul_OPT,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      job->unlog=TRUE;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-us" */
    
    if (!strcmp("-us",sp->str0)) {
      
      dqs_validate_option(us_OPT,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      job->suspend_enable=RUNNING;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-v variable_list" */
    
    if (!strcmp("-v",sp->str0)) {
      
      dqs_validate_option(v_OPT,sp->str0);
      
      /* next field is variable_list */
      sp=dqs_parser_get_next(sp,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-v %s\"",sp->str0));
      dqs_parse_variable_list(&job->variable_list,sp->str0);
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-verify" */
    
    if (!strcmp("-verify",sp->str0)) {
      
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      job->verify=TRUE;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-V" */
    
    if (!strcmp("-V",sp->str0)) {
      
      dqs_validate_option(V_OPT,sp->str0);
      
      if (job->env_list) {
	WARNING((DQS_EVENT,"DQS_ERROR_0312 \"%s\" option has already been set",sp->str0));
	sp=sp->next;
	continue;
      }
      
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      dqs_get_env_list(&job->env_list,envp);
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-xsoc" */
    
    if (!strcmp("-xsoc",sp->str0)) {
      
      dqs_validate_option(xsoc_OPT,sp->str0);
      
      if (job->suspend_enable)
	{
	  WARNING((DQS_EVENT,"DQS_ERROR_0313 \"suspend_enable\" has already been set, overriding previous setting"));
	}
      
      DPRINTF((DQS_EVENT,"\"%s\"",sp->str0));
      job->suspend_enable=XSUSPEND_ON_COMP;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-z" */
    
    if (!strcmp("-z",sp->str0)) {
      
      dqs_validate_option(z_OPT,sp->str0);
      
      DPRINTF((DQS_EVENT,"\"-z\""));
      job->silent=TRUE;
      
      sp=sp->next;
      continue;
    }
    
    /*-----------------------------------------------------------------------------*/
    /* "-huh?" */
    
    if (!strncmp("-",sp->str0,1)) {
      ERROR((DQS_EVENT,"DQS_ERROR_0314 invalid option argument \"%s\"",sp->str0));
      dqs_usage();
      DEXITE;
      exit(DQS_EINVAL);
    }
    
    /*-----------------------------------------------------------------------------*/
    
    DPRINTF((DQS_EVENT,"===%s===",sp->str0));
    
    
    if (VALID_OPT(DESTIN_OPR,me.who))
      dqs_parse_destination_identifier_list(&job->destin_identifier_list,sp->str0);
    else if (VALID_OPT(JOB_ID_OPR,me.who))
      dqs_parse_job_identifier_list(&job->job_identifier_list,sp->str0);
    else if (VALID_OPT(MESSAGE_OPR,me.who))
      job->message=dqs_string_insert(job->message,sp->str0);
    else if (VALID_OPT(SCRIPT_OPR,me.who)){
      
      /*------------------------------------------------------------------------**
      **        Q: script_file already set?
      **          N: set script_file to current sp->str0
      **            Q: first use of this subroutine? (no script directives
      **               so far near the end of the list sp)
      **              Y: sign this list element with [int1,str1]=[41,"41"]
      **                 and get a pointer to it
      **              N: sign this list element with [int1,str1]=[42,"42"]
      **                 and get a pointer to it
      **          Y: if first use of this subroutine (tmp_sp2:
      **               [int1,str1]=[41,"41"]) collect rest of list in
      **                 script_argv_list and sign every element with
      **                 [int1,str1]=[42,"42"],
      **              else collect only elements with
      **                  [int1,str1]=[42,"42"] in script_argv_list
      **------------------------------------------------------------------------*/
      if (! job->script_file) {                              
	job->script_file =dqs_string_insert (job->script_file, sp->str0);    
	
	if (! tmp_sp2 ||                                  
	    (tmp_sp2->int1 != 41 && strcmp ("41", tmp_sp2->str1))) {
	  sp->int1 = 41;                                     
	  sp->str1 = dqs_string_insert (sp->str1, "41");     
	}
	else {                                             
	  sp->int1 = 42;                                     
	  sp->str1 = dqs_string_insert (sp->str1, "42");     
	}                                                    
	tmp_sp2 = sp;                                        
      }
      else{                                               
	while (sp && ((tmp_sp2->int1 == 41 && !strcmp ("41", tmp_sp2->str1)) ||
		      (sp->int1 == 42      && !strcmp ("42", sp->str1))))
	  {
	    if (job->script_argv_list) {                       
	      tmp_sp = (dqs_list_type *) dqs_malloc (sizeof (dqs_list_type));
	      tmp_sp->str0 = dqs_string_insert (tmp_sp->str0, sp->str0);
	      tmp_sp->int0 = job->script_argv_list->int0 + 1;  
	      tmp_sp->next = job->script_argv_list;            
	      job->script_argv_list = tmp_sp;                  
	    }
	    else {                                           
	      /* initialize script_argv_list and assign 1st argument    */
	      job->script_argv_list =                          
		(dqs_list_type *) dqs_malloc (sizeof (dqs_list_type));
	      job->script_argv_list->str0 =                    
		job->script_argv_list->str0=dqs_string_insert (job->script_argv_list->str0, sp->str0);
	      job->script_argv_list->int0 = 1;                 
	      job->script_argv_list->next = (dqs_list_type *) NULL;
	    }
	    sp->int1 = 42;                                     
	    sp->str1 = dqs_string_insert (sp->str1, "42");     
	    sp=sp->next;                                       
	  }         /* while */
	continue;                                            
      } /* if !job->script_file  */
      
    } /*if VALID(SCRIPT_OPR */
    
    sp=sp->next;
    
  }
  
  if (!job->dqs_o_workdir) { 
    if (job->cwd) {
      job->dqs_o_workdir = job->cwd;
    } else {
      job->dqs_o_workdir = job->dqs_o_home;
    }
  }
  
  
  DEXIT;
  return(job);
  
}

/***************************************************************************/
void dqs_validate_option(opt,str)
     int  opt;
     char *str;
     
{
  
  DENTER_EXT((DQS_EVENT,"dqs_validate_option"));
  
  if (!VALID_OPT(opt,me.who)) {
    ERROR((DQS_EVENT,"DQS_ERROR_0315 \"%s\" is not a valid option %d %d",
           str, opt,me.who));
    dqs_usage();
    DEXITE;
    exit(DQS_EINVAL);
  }
  
  DEXIT;
  return;
  
}

/***************************************************************************/
dqs_list_type *dqs_parser_get_next(head,op_str)
     dqs_list_type *head;
     char          *op_str;
     
{
  
  DENTER((DQS_EVENT,"dqs_parser_get_next"));
  if (!head->next)
    {
      ERROR((DQS_EVENT,"DQS_ERROR_0316 no option argument provided to \"%s\"",op_str));
      dqs_usage();
      DEXITE;
      exit(DQS_EINVAL);
    }
  else
    { 
      head=head->next;
    }
  
  DEXIT;
  return(head);
}

/***************************************************************************/
u_long dqs_parse_date_time(date_str)
     char *date_str;
     
     /* 
	-a date_time 
	"touch -t" format
	[[CC]YY]MMDDhhmm[.SS]
     */
     
{
  
  int i;
  char *seconds;
  char *non_seconds;
  string tmp_str;
  
  time_t tt;
  char *zone;
  time_t gmt_secs;
  struct tm *tmp_timeptr,timeptr;
  
  DENTER((DQS_EVENT,"dqs_parse_date_time"));
  
  bzero((char *)tmp_str,sizeof(tmp_str));
  
  non_seconds=dqs_strtok(date_str,".");
  seconds=dqs_strtok( (char *)NULL,".");
  
  if(seconds)        /* added by wdg */
    i=strlen(seconds);
  else
    i = 0;
  
  if ((i!=0)&&(i!=2)) 
    {
      ERROR((DQS_EVENT,"DQS_ERROR_0317 invalid date_time string \"%s\"",date_str));
      dqs_usage();
      DEXITE;
      exit(DQS_EINVAL);
    }
  
  i=strlen(non_seconds);
  
  if ((i!=8)&&(i!=10)&&(i!=12))
    {
      ERROR((DQS_EVENT,"DQS_ERROR_0318 invalid date_time string \"%s\"",date_str));
      dqs_usage();
      DEXITE;
      exit(DQS_EINVAL);
    }
  
  bzero((char *)&timeptr,sizeof(timeptr));
  
  if (i==12)
    non_seconds+=2;
  
  if (i>=10)
    {
      bzero((char *)tmp_str,sizeof(tmp_str));
      bcopy(non_seconds,tmp_str,2);
      timeptr.tm_year=dqs_atoi(tmp_str);
      non_seconds+=2;
    }
  else
    {
      gmt_secs=dqs_get_gmt();
      tmp_timeptr=localtime(&gmt_secs);
      timeptr.tm_year=tmp_timeptr->tm_year;
    }
  
  bzero((char *)tmp_str,sizeof(tmp_str));
  bcopy(non_seconds,tmp_str,2);
  timeptr.tm_mon=dqs_atoi(tmp_str)-1;/* 00==Jan, we don't like that do we */
  if ((timeptr.tm_mon>12)||(timeptr.tm_mon<0))
    {
      ERROR((DQS_EVENT,"DQS_ERROR_0319 invalid date_time string \"%s\"",date_str));
      dqs_usage();
      DEXITE;
      exit(DQS_EINVAL);
    }
  
  non_seconds+=2;
  
  bzero((char *)tmp_str,sizeof(tmp_str));
  bcopy(non_seconds,tmp_str,2);
  timeptr.tm_mday=dqs_atoi(tmp_str);
  non_seconds+=2;
  
  if ((timeptr.tm_mday>31)||(timeptr.tm_mday<1)) /* yea, we should do it by months */
    {                                          /* actually mktime() should frigging do it */
      ERROR((DQS_EVENT,"DQS_ERROR_0320 invalid date_time string \"%s\"",date_str));
      dqs_usage();
      DEXITE;
      exit(DQS_EINVAL);
    }
  
  bzero((char *)tmp_str,sizeof(tmp_str));
  bcopy(non_seconds,tmp_str,2);
  timeptr.tm_hour=dqs_atoi(tmp_str);
  non_seconds+=2;
  
  /*Fix submitted by Hadyen*/
  if ((timeptr.tm_hour>24)||(timeptr.tm_hour<0))
    {
      ERROR((DQS_EVENT,"DQS_ERROR_0321 invalid date_time string \"%s\"",date_str));
      dqs_usage();
      DEXITE;
      exit(DQS_EINVAL);
    }
  
  bzero((char *)tmp_str,sizeof(tmp_str));
  bcopy(non_seconds,tmp_str,2);
  timeptr.tm_min=dqs_atoi(tmp_str);
  
  if ((timeptr.tm_min>59)||(timeptr.tm_min<0))
    {
      ERROR((DQS_EVENT,"DQS_ERROR_0322 invalid date_time string \"%s\"",date_str));
      dqs_usage();
      DEXITE;
      exit(DQS_EINVAL);
    }
  
  if (seconds)
    timeptr.tm_sec=dqs_atoi(seconds);
  if ((timeptr.tm_sec>59)||(timeptr.tm_mday<0))
    {
      ERROR((DQS_EVENT,"DQS_ERROR_0323 invalid date_time string \"%s\"",date_str));
      dqs_usage();
      DEXITE;
      exit(DQS_EINVAL);
    }
  
  /*Another fix by Hayden*/
  /*timeptr.tm_isdst=1;*/
  /*To fix daylight ST, may or may not be needed based on OS*/ 
  gmt_secs=mktime(&timeptr);
  
  if (gmt_secs<0)
    {
      ERROR((DQS_EVENT,"DQS_ERROR_0324 invalid date_time string \"%s\"",date_str));
      dqs_usage();
      DEXITE;
      exit(DQS_EINVAL);
    }
  
  DPRINTF((DQS_EVENT,"%s",ctime((time_t *)&gmt_secs)));
  
  DEXIT;
  return(gmt_secs);
  
} /*dqs_parse_string*/    

/***************************************************************************/
int dqs_parse_op(op_str)
     char *op_str;
     
{
  
  int opr=0;
  
  DENTER((DQS_EVENT,"dqs_parse_op"));
  
  if (!strcmp(op_str,".eq."))
    opr=EQ_OP;
  else if (!strcmp(op_str,".ge."))
    opr=GE_OP;
  else if (!strcmp(op_str,".gt."))
    opr=GT_OP;
  else if (!strcmp(op_str,".lt."))
    opr=LT_OP;
  else if (!strcmp(op_str,".le."))
    opr=LE_OP;
  else if (!strcmp(op_str,".ne."))
    opr=NE_OP;
  
  DEXIT;
  
  return(opr);
  
}

/***************************************************************************/
void dqs_parse_account_list(head,account_str)
     dqs_list_type **head;
     char           *account_str;
     
     /*   account[@cell][,account[@cell]...] 
	  
	  str0 - account
	  str1 - cell
	  str3 - temporary
	  int3 - temporary
     */
     
{
  
  char          *account;
  char          *cell;
  char          *account_cell;
  dqs_list_type *sp;
  dqs_list_type element;
  
  DENTER((DQS_EVENT,"dqs_parse_account_list"));
  
  bzero((char *)&element,sizeof(element));
  account_cell=dqs_strtok(account_str,",");
  DQS_ASSERT((account_cell));
  element.str3=dqs_string_insert(element.str3,account_cell);
  *head=dqs_insert(DQS_STR3,TAIL,*head,&element);
  
  while ((account_cell=dqs_strtok((char *)NULL,","))!=(char *)NULL) {
    bzero((char *)&element,sizeof(element));
    DQS_ASSERT((account_cell));
    element.str3=dqs_string_insert(element.str3,account_cell);
    *head=dqs_insert(DQS_STR0,TAIL,*head,&element);
  } 
  
  sp= *head;
  
  while (sp) {
    if (!sp->int3) 
      {
	account=dqs_strtok(sp->str3,"@");           
	DQS_ASSERT((account));
	sp->str0=dqs_string_insert(sp->str0,account);
	cell=dqs_strtok((char *)NULL,"@");
	if (cell) 
	  sp->str1=dqs_string_insert(sp->str1,cell);
	else
	  sp->str1=dqs_string_insert(sp->str1,me.default_cell);
	sp->int3=TRUE;
      }
    sp=sp->next;
  }
  
  DEXIT;
  return;
  
}

/***********************************************************************/
int dqs_parse_hold_list(hold_str)
     char *hold_str;
     
{
  
  int i,j;
  int hold=0;
  
  DENTER((DQS_EVENT,"dqs_parse_hold_list"));
  
  i=strlen(hold_str);
  
  for (j=0;j<i;j++) {
    if ((char)hold_str[j]=='n'){
      SETBIT(NO_HOLD, hold);
    }
    else{
      if ((char)hold_str[j]=='o'){
	SETBIT(OTHER,hold);
      }
      else {
	if ((char)hold_str[j]=='s'){
	  SETBIT(SYSTEM, hold);
	}
	else{
	  if ((char)hold_str[j]=='u'){
	    SETBIT(USER, hold);
	  }
	  else {
	    ERROR((DQS_EVENT,"DQS_ERROR_0325 invalid hold_list \"%s\"",hold_str));
	    dqs_usage();
	    DEXITE;
	    exit(DQS_EINVAL);
	  }
	}
      }
    }
  }
  if(hold==0) hold=NO_HOLD;  /* force default to NO_HOLD  */
  DEXIT;
  return(hold);
  
}

/***********************************************************************/
int dqs_parse_keep_list(keep_str)
     char *keep_str;
     
{
  
  int i,j;
  int keep=KEEP_NONE;
  
  DENTER((DQS_EVENT,"dqs_parse_keep_list"));
  
  i=strlen(keep_str);
  
  for (j=0;j<i;j++) {
    if ((char)keep_str[j]=='e')
      keep=keep|KEEP_STD_ERROR;
    else if ((char)keep_str[j]=='o')
      keep=keep|KEEP_STD_OUTPUT;
    else if ((char)keep_str[j]=='n')
      keep=KEEP_NONE;
    else {
      ERROR((DQS_EVENT,"DQS_ERROR_0326 invalid keep_list \"%s\"",keep_str));
      dqs_usage();
      DEXITE;
      exit(DQS_EINVAL);
    }
  }
  DEXIT;
  return(keep);
  
}

/***********************************************************************/
int dqs_parse_mail_options(mail_str)
     char *mail_str;
     
{
  
  int i,j;
  int mail_opt=0;
  
  DENTER((DQS_EVENT,"dqs_parse_mail_options"));
  
  i=strlen(mail_str);
  
  for (j=0;j<i;j++) {
    if ((char)mail_str[j]=='a')
      mail_opt=mail_opt|MAIL_AT_ABORT;
    else if ((char)mail_str[j]=='b')
      mail_opt=mail_opt|MAIL_AT_BEGINNING;
    else if ((char)mail_str[j]=='e')
      mail_opt=mail_opt|MAIL_AT_EXIT;
    else if ((char)mail_str[j]=='n')
      mail_opt=mail_opt|NO_MAIL;
    else if ((char)mail_str[j]=='s')
      mail_opt=mail_opt|MAIL_AT_SUSPENSION;
    else {
      ERROR((DQS_EVENT,"DQS_ERROR_0327 invalid mail_option_list \"%s\"",mail_str));
      dqs_usage();
      DEXITE;
      exit(DQS_EINVAL);
    }
  }
  
  DEXIT;
  return(mail_opt);
  
}

/***************************************************************************/
int dqs_parse_checkpoint_attr(attr_str)
     char *attr_str;
     
{
  
  int opr=0;
  
  DENTER((DQS_EVENT,"dqs_parse_checkpoint_attr"));
  
  if (!strcmp(attr_str,"n"))
    opr=NO_CHECKPOINT;
  else if (!strcmp(attr_str,"s"))
    opr=CHECKPOINT_AT_SHUTDOWN;
  else if (!strcmp(attr_str,"m"))
    opr=CHECKPOINT_AT_MINIMUM_INTERVAL;
  
  DEXIT;
  return(opr);
  
}

/***************************************************************************/
int dqs_parse_checkpoint_interval(minutes_str)
     char *minutes_str;
     
{
  
  int minutes;
  
  DENTER((DQS_EVENT,"dqs_parse_checkpoint_interval"));
  
  minutes=dqs_atoi(minutes_str);
  
  DEXIT;
  return(minutes);
  
}

/***************************************************************************/
void dqs_parse_path_list(head,path_str)
     dqs_list_type **head;
     char          *path_str;
     
     /* 
	[host:]path[,[host:]path...]
	
	str0 - path
	str1 - host
	str3 - temporary
	int  - temporary
     */
     
{
  
  char          *path=NULL;
  char          *cell=NULL;
  char          *path_host=NULL;
  dqs_list_type *sp=NULL;
  
  dqs_list_type element;
  
  DENTER((DQS_EVENT,"dqs_parse_path_list"));
  
  bzero((char *)&element,sizeof(element));
  path_host=dqs_strtok(path_str,",");
  DQS_ASSERT((path_host));
  element.str3=dqs_string_insert(element.str3,path_host);
  *head=dqs_insert(DQS_STR3,TAIL,*head,&element);
  
  while ((path_host=dqs_strtok(0,","))!=(char *)NULL) {
    bzero((char *)&element,sizeof(element));
    DQS_ASSERT((path_host));
    element.str3=dqs_string_insert(element.str3,path_host);
    *head=dqs_insert(DQS_STR3,TAIL,*head,&element);
  } 
  
  sp= *head;
  
  while (sp) {
    if (!sp->int3) 
      {
	path=NULL;
	cell=NULL;
	
	if (strstr(sp->str3,":"))
	  {
	    cell=dqs_strtok(sp->str3,":");
	    path=dqs_strtok( (char *)NULL,":");
	  }
	else
	  {
	    path=dqs_string_insert( (char *)NULL,sp->str3);
	  }
	
	DQS_ASSERT((path));
	
	sp->str0=dqs_string_insert(sp->str0,path);
	sp->str1=dqs_string_insert(sp->str1,cell);
	sp->int3=TRUE;
      }
    sp=sp->next;
  }
  
  DEXIT;
  return;
  
}

/***************************************************************************/
void dqs_parse_resource_list(head,resource_str)
     dqs_list_type **head;
     char          *resource_str;
     
     /* 
	
	ex: -l qty.eq.5,group=ibm,mem.gt.128,pvm
	or: -l qty.eq.5.and.group=ibm.and.mem.gt.128.and.pvm
	or: -l (qty==5)&&(group=ibm)&&(mem>128)&&pvm
	
	
	each entry preceeded by "-l" id  a "resource_group".
	
	each "resource_group" will consist of a "chain" with the head being the qty.
	by default "qty=1"
	
	ops: == != >= <= > <  .eq. .ne. .ge. .le. .gt. .lt.  && .and. || .or.  ! .not
	optional_field==numeric||string <a numeric of 0 is considered invalid>
	
	listel.int0=qty <default=1>
	listel.int1=chain_length
	listel.chain=chained_element->
	resource[.op.field][,resource[.op.field],...]
	str0 - resource
	str1 - [field]
	int0 - [qty]
	int1 - [op]
	next->
	resource[.op.field][,resource[.op.field],...]
	str0 - resource
	str1 - [field]
	int0 - qty
	int1 - [op]
	next->
	...
	listel.next
	:
	:
	NULL
	
     */
     
{
  
  char          * cp;
  char          *exec_str=NULL;
  char          *resource_str_el=NULL;
  char          *resource=NULL;
  char          *resource_field=NULL;
  char          *tstr;
  char          *tptr, *oldptr;
  int           parenlvl;
  dqs_list_type *lp=NULL;
  dqs_list_type *tmp_head=NULL;
  
  dqs_list_type element;
  dqs_list_type chained_element;
  
  DENTER((DQS_EVENT,"dqs_parse_resource_list"));
  
  bzero((char *)&element,sizeof(element));
  
  tstr= dqs_malloc(MAX_STRING_SIZE);
  bzero((char *)tstr, MAX_STRING_SIZE);
  
  oldptr= resource_str;
  
  
  element.int1=0;  /* paranthesis level  */
  element.int0=0;  /* logical operation  */
  element.int2=0;  /* relational operation */
  
  while(*oldptr){
    tptr= tstr;
    element.str1= NULL;  /* resource field  */
    
    do{
      *tptr= *oldptr;   /* move one byte then test it  */
      
      if(*oldptr==','){
	element.int0= AND_OP;
	oldptr= oldptr +1;
	break;
      }
      
      if( *oldptr=='('){
	element.int1 ++;
	oldptr=oldptr +1;
	continue;
      }
      
      if( *oldptr==')' ){
	element.int1--;
	oldptr=oldptr +1;
	continue;
      }
      
      if(*oldptr=='.'){
	if( !strncasecmp(oldptr,".and.",5) ){
	  element.int0= AND_OP;
	  oldptr= oldptr +5;
	  break;
	}
	if( !strncasecmp(oldptr,".or.",4) ){
	  element.int0= OR_OP;
	  oldptr= oldptr +4;
	  break;
	}
	if( !strncasecmp(oldptr,".not.",5) ){
	  element.int0= NOT_OP;
	  oldptr= oldptr +5;
	  break;
	}
	if( !strncasecmp(oldptr,".eq.",4) ){
	  element.int2= EQ_OP;
	  oldptr= oldptr +4;
	  break;
	}
	if( !strncasecmp(oldptr,".ne.",4) ){
	  element.int2= NE_OP;
	  oldptr= oldptr +4;
	  break;
	}
	if( !strncasecmp(oldptr,".gt.",4) ){
	  element.int2= GT_OP;
	  oldptr= oldptr +4;
	  break;
	}
	if( !strncasecmp(oldptr,".ge.",4) ){
	  element.int2= GE_OP;
	  oldptr= oldptr +4;
	  break;
	}
	if( !strncasecmp(oldptr,".lt.",4) ){
	  element.int2= LT_OP;
	  oldptr= oldptr +4;
	  break;
	}
	if( !strncasecmp(oldptr,".le.",4) ){
	  element.int2= LE_OP;
	  oldptr= oldptr +4;
	  break;
	}
      } /* delimited by "."      */
      
      if(*oldptr== '='){
	oldptr++;
	if(*oldptr== '='){
	  element.int2= EQ_OP;
	  oldptr++;
	  break;
	}
	element.int2= STREQ_OP;         /* string equaliaty */
	break;
      }
      
      if(*oldptr== '!'){
	oldptr++;
	if(*oldptr== '='){
	  element.int2= NE_OP;
	  oldptr++;
	  break;
	}
	element.int0= NOT_OP;
	break;
      }
      
      if(*oldptr== '<'){
	oldptr++;
	if(*oldptr== '='){
	  element.int2= LE_OP;
	  oldptr++;
	  break;
	}
	element.int2= LT_OP;
	break;
      }
      
      if(*oldptr== '>'){
	oldptr++;
	if(*oldptr== '='){
	  element.int2= GE_OP;
	  oldptr++;
	  break;
	}
	element.int2= GT_OP;
	break;
      }
      
      if(*oldptr=='&'){
	oldptr++;
	if(*oldptr=='&'){
	  element.int0= AND_OP;
	  oldptr++;
	  break;
	}
	continue;  /* discard extraneous ampersand */
      }
      
      if(*oldptr=='|'){
	oldptr++;
	if(*oldptr=='|'){
	  element.int0= OR_OP;
	  oldptr++;
	  break;
	}
	continue;  /* discard extraneous "|"   */
      }
      oldptr++;       
      tptr++;   /* advance output pointer   */
    } while (*oldptr);
    
    if( !*oldptr) element.int0= END_OP;   /* force a termination operation  */
    
    *tptr= '\0';  /* ensure NULL termination of string  */     
    
    if( (tptr- tstr) <=0) continue;   /* no valid string  */
    
    if( element.int0){    /*  end of one element marked by a logical op or termination */
      
      /*   if we have a relational operator and a logical operation this is resource field  */
      if(element.int2)  element.str1=dqs_string_insert( (char *)NULL,tstr);     	
      else element.str0=dqs_string_insert( (char *)NULL,tstr);     	
      
      tmp_head=dqs_insert(DQS_STR0,TAIL,tmp_head,&element);
      element.int0=0;   /* clear logical operations */
      element.int2=0;   /*  clear relational operations */
      continue;
    }
    /***   found   string bounded by relational operator  */
    element.str0=dqs_string_insert( (char *)NULL,tstr);     	
    
    
  }  /* while *oldptr  */
  
  /* now we break out the chained head */
  bzero((char *)&element,sizeof(element));
  /* set default qty value */
  element.int0=1; 
  
  
  lp=tmp_head;
  while (lp) {
    if (strstr(lp->str0,"-exec")) {
      /* this string would have appeared as "-exec.eq." in the command line */
      if(lp->int2= EQ_OP){
	exec_str=dqs_string_insert( (char *)NULL,lp->str1);
	element.str2=dqs_string_insert( (char *)NULL,lp->str1);
	lp=lp->next;
	continue;
      }
    }
    bzero((char *)&chained_element,sizeof(chained_element));
    
    chained_element.int1= lp->int2;   /* relational operator */
    chained_element.int2= lp->int0;   /* logical operation */
    chained_element.int3= lp->int1;   /*  parenthesis level  */
    
    if (chained_element.int1)  { /* we have an operator to contend with */
      DTRACE;
      resource= lp->str0;
      resource_field= lp->str1;
      if (!resource_field) {
	DTRACE;
	ERROR((DQS_EVENT,
	       "invalid or missing resource_field after relational operator"));
	dqs_usage();
	exit(DQS_EINVAL);
      }
      if (!resource) {
	DTRACE;
	ERROR((DQS_EVENT,
	       "invalid or missing resource after \"-l\" "));
	dqs_usage();
	exit(DQS_EINVAL);
      }
      DTRACE;
      
      if (!dqs_is_int(resource_field))
	{
	  DTRACE;
	  chained_element.int0=dqs_atoi(resource_field);
	}
      else{
	if ((chained_element.int1!=EQ_OP)&&(chained_element.int1!=NE_OP)) {
	  ERROR((DQS_EVENT,
		 "invalid op_field \"%s\" - op must be \".eq.\" or \".ne.\" with string resource_field",
		 lp->str0));
	  dqs_usage();
	  exit(DQS_EINVAL);
	}
	else   chained_element.str1=dqs_string_insert( (char *)NULL,resource_field);
      }
      DTRACE;
      DPRINTF((DQS_EVENT,">%s< operator=%d >%s<\n",resource,lp->int2,resource_field));
      
      chained_element.str0=dqs_string_insert( (char *)NULL,resource);
      
      DTRACE;
      if (!strcmp(resource,"qty")) {
	DTRACE;
	if (chained_element.int0<=0) {
	  ERROR((DQS_EVENT,"invalid resource quantity field \"%s\"", lp->str1));
	  dqs_usage();
	  exit(DQS_EINVAL);
	}
	if (chained_element.int1!=EQ_OP)   {
	  ERROR((DQS_EVENT,
		 "invalid op_field \"%s\" - op must be \".eq.\" with \"qty\" resource",
		 lp->str0));
	  dqs_usage();
	  exit(DQS_EINVAL);
	}
	DTRACE;
	element.int0=chained_element.int0;
	/*   qty.eq. entries are not included in the resource searches  */
	lp=lp->next;
	continue;
      }  /*  "qty"  */
    }  /* operator  */
    else {
      DTRACE;
      chained_element.str0=dqs_string_insert( (char *)NULL,lp->str0);
    }
    element.str2=dqs_string_insert( (char *)NULL,exec_str);
    element.chain=dqs_insert(DQS_STR0,TAIL,element.chain,&chained_element);
    
    element.int1++; /* length of chain - speeds up scheduler */
    DTRACE;
    lp=lp->next;
  }  /*   while lp  */
  element.str2=exec_str;
  *head=dqs_insert(DQS_STR0,TAIL,*head,&element);
  dqs_free_list(tmp_head);
  DEXIT;
  return;
  
}

/***************************************************************************/
void dqs_parse_mail_list(head,mail_str)
     dqs_list_type **head;
     char          *mail_str;
     
     /* here's what we're gonna do with the list elements:
	
	user[@host][,user[@host],...]
	str0 - user
	str1 - host
	str3 - temporary
	int1 - temporary
     */
     
{
  
  char          *user;
  char          *host;
  char          *user_host;
  dqs_list_type *sp;
  dqs_list_type element;
  
  DENTER((DQS_EVENT,"dqs_parse_mail_list"));
  
  bzero((char *)&element,sizeof(element));
  user_host=dqs_strtok(mail_str,",");
  DQS_ASSERT((user_host));
  element.str3=dqs_string_insert(element.str3,user_host);
  *head=dqs_insert(DQS_STR3,TAIL,*head,&element);
  
  while ((user_host=dqs_strtok((char *)NULL,","))!=(char *)NULL) 
    {
      bzero((char *)&element,sizeof(element));
      DQS_ASSERT((user_host));
      element.str3=dqs_string_insert(element.str3,user_host);
      *head=dqs_insert(DQS_STR0,TAIL,*head,&element);
    }
  
  sp= *head;
  
  while (sp) 
    {
      if (!sp->int3) 
	{
	  user=dqs_strtok(sp->str3,"@");
	  DQS_ASSERT((user));
	  sp->str0=dqs_string_insert(sp->str0,user);
	  host=dqs_strtok((char *)NULL,"@");
	  if (host) 
	    sp->str1=dqs_string_insert(sp->str1,host);
	  sp->int3=TRUE;
	}
      sp=sp->next;
    }
  
  DEXIT;
  return;
  
}


/***************************************************************************/
int dqs_parse_priority(priority_str)
     char *priority_str;
     
{
  
  int priority;
  
  DENTER((DQS_EVENT,"dqs_parse_priority"));
  
  priority=dqs_atoi(priority_str);
  
  if (priority>1024) {
    ERROR((DQS_EVENT,"DQS_ERROR_0328 invalid priority, priority must be less than 1024 \"%s\"",priority_str));
    dqs_usage();
    DEXITE;
    exit(DQS_EINVAL);
  }
  
  if (priority<-1023) {
    ERROR((DQS_EVENT,"DQS_ERROR_0329 invalid priority, priority must be greater than -1023 \"%s\"",priority_str));
    dqs_usage();
    DEXITE;
    exit(DQS_EINVAL);
  }
  
  
  
  DEXIT;
  return(priority);
  
}

/***************************************************************************/
int dqs_parse_states(state_str)
     char *state_str;
     
{
  
  int i,j;
  int state=NONE;
  
  DENTER((DQS_EVENT,"dqs_parse_states"));
  
  i=strlen(state_str);
  
  for (j=0;j<i;j++) {
    if ((char)state_str[j]==EXITING_SYM)
      state=state|EXITING;
    else if ((char)state_str[j]==HELD_SYM)
      state=state|HELD;
    else if ((char)state_str[j]==MIGRATING_SYM)
      state=state|MIGRATING;
    else if ((char)state_str[j]==QUEUED_SYM)
      state=state|QUEUED;
    else if ((char)state_str[j]==RUNNING_SYM)
      state=state|RUNNING;
    else if ((char)state_str[j]==SUSPENDED_SYM)
      state=state|SUSPENDED;
    else if ((char)state_str[j]==TRANSISTING_SYM)
      state=state|TRANSISTING;
    else if ((char)state_str[j]==WAITING_SYM)
      state=state|WAITING;
    else {
      ERROR((DQS_EVENT,"DQS_ERROR_0330 invalid state_list \"%s\"",state_str));
      dqs_usage();
      DEXITE;
      exit(DQS_EINVAL);
    }
  }
  
  DEXIT;
  return(state);
  
}

/***************************************************************************/
int dqs_parse_signal(signal_str)
     char *signal_str;
     
{
  int dqs_sig;
  
  DENTER((DQS_EVENT,"dqs_parse_signal"));
  
  dqs_sig = NONE;
  
  if ((signal_str[0])!='-') {
    ERROR((DQS_EVENT,"DQS_ERROR_0331 invalid signal \"%s\"",signal_str));
    dqs_usage();
    DEXITE;
    exit(DQS_EINVAL);
  }
  
  signal_str++;
  
  if (!strcmp(signal_str,"HUP"))
    dqs_sig=DQS_SIGHUP;
  else if (!strcmp(signal_str,"INT"))
    dqs_sig=DQS_SIGINT;
  else if (!strcmp(signal_str,"QUIT"))
    dqs_sig=DQS_SIGQUIT;
  else if (!strcmp(signal_str,"ILL"))
    dqs_sig=DQS_SIGILL;
  else if (!strcmp(signal_str,"TRAP"))
    dqs_sig=DQS_SIGTRAP;
  else if (!strcmp(signal_str,"ABRT"))
    dqs_sig=DQS_SIGABRT;
  else if (!strcmp(signal_str,"EMT"))
    dqs_sig=DQS_SIGEMT;
  else if (!strcmp(signal_str,"FPE"))
    dqs_sig=DQS_SIGFPE;
  else if (!strcmp(signal_str,"KILL"))
    dqs_sig=DQS_SIGKILL;
  else if (!strcmp(signal_str,"BUS"))
    dqs_sig=DQS_SIGBUS;
  else if (!strcmp(signal_str,"SEGV"))
    dqs_sig=DQS_SIGSEGV;
  else if (!strcmp(signal_str,"SYS"))
    dqs_sig=DQS_SIGSYS;
  else if (!strcmp(signal_str,"PIPE"))
    dqs_sig=DQS_SIGPIPE;
  else if (!strcmp(signal_str,"ALRM"))
    dqs_sig=DQS_SIGALRM;
  else if (!strcmp(signal_str,"TERM"))
    dqs_sig=DQS_SIGTERM;
  else if (!strcmp(signal_str,"URG"))
    dqs_sig=DQS_SIGURG;
  else if (!strcmp(signal_str,"STOP"))
    dqs_sig=DQS_SIGSTOP;
  else if (!strcmp(signal_str,"TSTP"))
    dqs_sig=DQS_SIGTSTP;
  else if (!strcmp(signal_str,"CONT"))
    dqs_sig=DQS_SIGCONT;
  else if (!strcmp(signal_str,"CHLD"))
    dqs_sig=DQS_SIGCHLD;
  else if (!strcmp(signal_str,"TTIN"))
    dqs_sig=DQS_SIGTTIN;
  else if (!strcmp(signal_str,"TTOU"))
    dqs_sig=DQS_SIGTTOU;
  else if (!strcmp(signal_str,"IO"))
    dqs_sig=DQS_SIGIO;
  else if (!strcmp(signal_str,"VTALRM"))
    dqs_sig=DQS_SIGVTALRM;
  else if (!strcmp(signal_str,"PROF"))
    dqs_sig=DQS_SIGPROF;
  else if (!strcmp(signal_str,"WINCH"))
    dqs_sig=DQS_SIGWINCH;
  else if (!strcmp(signal_str,"LOST"))
    dqs_sig=DQS_SIGLOST;
  else if (!strcmp(signal_str,"USR1"))
    dqs_sig=DQS_SIGUSR1;
  else if (!strcmp(signal_str,"USR2"))
    dqs_sig=DQS_SIGUSR2;
  else if (!dqs_sig) {
    dqs_sig=dqs_atoi(signal_str);
    
    if (dqs_sig==SIGHUP)
      dqs_sig=DQS_SIGHUP;
    else if (dqs_sig==SIGINT)
      dqs_sig=DQS_SIGINT;
    else if (dqs_sig==SIGQUIT)
      dqs_sig=DQS_SIGQUIT;
    else if (dqs_sig==SIGILL)
      dqs_sig=DQS_SIGILL;
    else if (dqs_sig==SIGTRAP)
      dqs_sig=DQS_SIGTRAP;
    else if (dqs_sig==SIGABRT)
      dqs_sig=DQS_SIGABRT;
    else if (dqs_sig==SIGKILL)
      dqs_sig=DQS_SIGKILL;
    else if (dqs_sig==SIGSEGV)
      dqs_sig=DQS_SIGSEGV;
    else if (dqs_sig==SIGPIPE)
      dqs_sig=DQS_SIGPIPE;
    else if (dqs_sig==SIGALRM)
      dqs_sig=DQS_SIGALRM;
    else if (dqs_sig==SIGTERM)
      dqs_sig=DQS_SIGTERM;
    else if (dqs_sig==SIGURG)
      dqs_sig=DQS_SIGURG;
    else if (dqs_sig==SIGSTOP)
      dqs_sig=DQS_SIGSTOP;
    else if (dqs_sig==SIGTSTP)
      dqs_sig=DQS_SIGTSTP;
    else if (dqs_sig==SIGCONT)
      dqs_sig=DQS_SIGCONT;
    else if (dqs_sig==SIGCHLD)
      dqs_sig=DQS_SIGCHLD;
    else if (dqs_sig==SIGTTIN)
      dqs_sig=DQS_SIGTTIN;
    else if (dqs_sig==SIGTTOU)
      dqs_sig=DQS_SIGTTOU;
    else if (dqs_sig==SIGIO)
      dqs_sig=DQS_SIGIO;
    else if (dqs_sig==SIGVTALRM)
      dqs_sig=DQS_SIGVTALRM;
    else if (dqs_sig==SIGPROF)
      dqs_sig=DQS_SIGPROF;
    else if (dqs_sig==SIGWINCH)
      dqs_sig=DQS_SIGWINCH;
    else if (dqs_sig==SIGUSR1)
      dqs_sig=DQS_SIGUSR1;
    else if (dqs_sig==SIGUSR2)
      dqs_sig=DQS_SIGUSR2;
  }
  
  if ((dqs_sig>31)|(dqs_sig<1)) {
    ERROR((DQS_EVENT,"DQS_ERROR_0332 invalid signal \"%s\"",signal_str));
    dqs_usage();
    DEXITE;
    exit(DQS_EINVAL);
  }
  
  DEXIT;
  return(dqs_sig);
  
}

/***************************************************************************/
void dqs_parse_variable_list(head,variable_str)
     dqs_list_type **head;
     char          *variable_str;
     
     /*   variable[=value][,variable[=value],...]
	  
	  str0 - variable
	  str1 - value
	  str3 - temporary
	  int3 - temporary
     */
     
{
  
  char          *cp;
  char          *variable;
  char          *value;
  char          *variable_value;
  string        str;
  dqs_list_type *sp;
  dqs_list_type element;
  
  DENTER((DQS_EVENT,"dqs_parse_variable_list"));
  
  bzero((char *)&element,sizeof(element));
  variable_value=dqs_strtok(variable_str,",");
  DQS_ASSERT((variable_value));
  element.str3=dqs_string_insert(element.str3,variable_value);
  *head=dqs_insert(DQS_STR3,TAIL,*head,&element);
  
  while ((variable_value=dqs_strtok((char *)NULL,","))!=(char *)NULL) 
    {
      bzero((char *)&element,sizeof(element));
      DQS_ASSERT((variable_value));
      element.str3=dqs_string_insert(element.str3,variable_value);
      *head=dqs_insert(DQS_STR0,TAIL,*head,&element);
    }
  
  sp= *head;
  
  while (sp) 
    {
      if (!sp->int3) 
	{
	  variable=dqs_strtok(sp->str3,"=");           
	  DQS_ASSERT((variable));
	  bzero((char *)str,sizeof(str));
	  sprintf(str,"%s=",variable);
	  sp->str0=dqs_string_insert(sp->str0,str);
	  value=dqs_strtok((char *)NULL,"=");
	  if (value) 
	    {
	      sp->str1=dqs_string_insert(sp->str1,value);
	    }
	  else
	    {
	      cp=dqs_getenv(variable);
	      if (!cp)
		{
		  ERROR((DQS_EVENT,"DQS_ERROR_0333 invalid variable string \"%s\"",variable));
		  dqs_usage();
		  DEXITE;
		  exit(DQS_EINVAL);
		}
	      sp->str1=dqs_string_insert(sp->str1,cp);
	    }
	  sp->int3=TRUE;
	}
      sp=sp->next;
    }
  
  DEXIT;
  return;
  
}

/***************************************************************************/
void dqs_parse_user_list(head,user_str)
     dqs_list_type **head;
     char          *user_str;
     
     /*   user[@cell][,user[@cell]...] 
	  
	  str0 - user
	  str1 - cell
	  str3 - temporary
	  int3 - temporary
     */
     
{
  
  char          *user;
  char          *cell;
  char          *user_cell;
  dqs_list_type *sp;
  dqs_list_type element;
  
  DENTER((DQS_EVENT,"dqs_parse_user_list"));
  
  bzero((char *)&element,sizeof(element));
  user_cell=dqs_strtok(user_str,",");
  DQS_ASSERT((user_cell));
  element.str3=dqs_string_insert(element.str3,user_cell);
  *head=dqs_insert(DQS_STR3,TAIL,*head,&element);
  
  while ((user_cell=dqs_strtok((char *)NULL,","))!=(char *)NULL) 
    {
      bzero((char *)&element,sizeof(element));
      DQS_ASSERT((user_cell));
      element.str3=dqs_string_insert(element.str3,user_cell);
      *head=dqs_insert(DQS_STR0,TAIL,*head,&element);
    }
  
  sp= *head;
  
  while (sp) 
    {
      if (!sp->int3) 
	{
	  user=dqs_strtok(sp->str3,"@");
	  DQS_ASSERT((user));
	  sp->str0=dqs_string_insert(sp->str0,user);
	  cell=dqs_strtok((char *)NULL,"@");
	  if (cell) 
	    sp->str1=dqs_string_insert(sp->str1,cell);
	  else
	    sp->str1=dqs_string_insert(sp->str1,me.default_cell);
	  sp->int3=TRUE;
	}
      sp=sp->next;
    }
  
  DEXIT;
  return;
  
}


/***************************************************************************/
void *dqs_get_env_list(head,envp)
     dqs_list_type **head;
     char **envp;
     
     /*
       str0 = env_name
       str1 = env_description
       str3 = tempoary
       int3 = tempoary
     */
     
{
  
  int i;
  char          *env_name;
  char          *env_description;
  string        str;                        /******************/
  
  dqs_list_type *sp=NULL;
  dqs_list_type element;
  
  DENTER((DQS_EVENT,"dqs_get_env_list"));
  
  while (*envp) {
    bzero((char *)&element,sizeof(element));
    element.str3=dqs_string_insert(element.str3,envp[0]);
    *head=dqs_insert(DQS_STR0,TAIL,*head,&element);    
    envp++;
  }
  
  sp= *head;
  while (sp) {
    env_name=dqs_strtok(sp->str3,"=");
    DQS_ASSERT((env_name));
    bzero((char *)str,sizeof(str));                   /*******************/
    sprintf(str,"%s=",env_name);             /*******************/
    sp->str0=dqs_string_insert(sp->str0,str);  /****************/
    /*Change via Doug Gibson, what if have '=' in it*/  
    env_description=sp->str3+strlen(env_name)+1;
    if (env_description) 
      sp->str1=dqs_string_insert(sp->str1,env_description);
    sp=sp->next;
  }
  
  DEXIT;
  return;
  
}

/***************************************************************************/
void dqs_parse_destination_identifier_list(head,dest_str)
     dqs_list_type **head;
     char          *dest_str;
     
     /*
       
       
       destination_identifier  "queue[exec.eq.foo]" "@cell[exec.eq.foo]" "queue@cell[exec.eq.foo]"
       
       str0 - queue
       str1 - cell
       str2 - [exec_str]
       str3 - temporary
       int3 - temporary
     */
     
{
  
  char          *queue;
  char          *cell;
  char          *queue_cell;
  char          * cp;
  dqs_list_type *sp;
  dqs_list_type element;
  
  DENTER((DQS_EVENT,"dqs_parse_destination_identifier_list"));
  
  bzero((char *)&element,sizeof(element));
  queue_cell=dqs_strtok(dest_str,",");
  DQS_ASSERT((queue_cell));
  element.str3=dqs_string_insert(element.str3,queue_cell);
  *head=dqs_insert(DQS_STR3,TAIL,*head,&element);
  
  while ((queue_cell=dqs_strtok((char *)NULL,","))!=(char *)NULL) 
    {
      bzero((char *)&element,sizeof(element));
      DQS_ASSERT((queue_cell));
      element.str3=dqs_string_insert(element.str3,queue_cell);
      *head=dqs_insert(DQS_STR0,TAIL,*head,&element);
    }
  
  sp= *head;
  while (sp) 
    {
      if (!sp->int3) 
	{
	  if (strstr(sp->str3,"-exec.eq."))
	    {
	      cp=strstr(sp->str3,"-exec.eq.");
	      cp[0]='\0';
	      cp+=9;
	      sp->str2=cp;
	    }
	  if (sp->str3[0]=='@')
	    {
	      cell=sp->str3;
	      cell++;
	      sp->str1=dqs_string_insert(sp->str1,cell);
	    }
	  else
	    {
	      queue=dqs_strtok(sp->str3,"@");
	      DQS_ASSERT((queue));
	      sp->str0=dqs_string_insert(sp->str0,queue);
	      cell=dqs_strtok( (char *)NULL,"@");
	      if (cell) 
		{
		  sp->str1=dqs_string_insert(sp->str1,cell);
		}
	      else
		{
		  sp->str1=dqs_string_insert(sp->str1,me.default_cell);
		}
	    }
	  sp->int3=TRUE;
	}
      sp=sp->next;
    }
  
  DEXIT;
  return;
  
}


/***************************************************************************/
void dqs_parse_job_identifier_list(head,job_str)
     dqs_list_type **head;
     char          *job_str;
     
     /*
       job_identifier                  sequence_number[.server_name][@server]
       
       str0 - sequence_number_str
       str0 - cell
       str3 - temporary
       int0 - sequence_number
       int3 - temporary
     */
     
{
  
  char          *job;
  char          *cell;
  char          *job_server;
  dqs_list_type *sp;
  dqs_list_type element;
  
  DENTER((DQS_EVENT,"dqs_parse_job_identifier_list"));
  
  bzero((char *)&element,sizeof(element));
  job_server=dqs_strtok(job_str,",");
  DQS_ASSERT((job_server));
  element.str3=dqs_string_insert(element.str3,job_server);
  *head=dqs_insert(DQS_STR3,TAIL,*head,&element);
  
  while ((job_server=dqs_strtok((char *)NULL,","))!=(char *)NULL) {
    bzero((char *)&element,sizeof(element));
    DQS_ASSERT((job_server));
    element.str3=dqs_string_insert(element.str3,job_server);
    *head=dqs_insert(DQS_STR0,TAIL,*head,&element);
  } 
  
  sp= *head;
  while (sp) {
    if (!sp->int3) 
      {
	/*        ???     if (strchr(sp->int3,'.'))*/
	if (strchr(sp->str3,'.'))
	  {
	    job=dqs_strtok(sp->str3,".");
	  }
	else
	  {
	    job=dqs_strtok(sp->str3,"@");
	  }
	DQS_ASSERT((job));
	sp->int0=dqs_atoi(job);
	sp->str0=dqs_string_insert(sp->str0,job);
	cell=dqs_strtok((char *)NULL,"@");
	if (cell) 
	  sp->str1=dqs_string_insert(sp->str1,cell);
	else
	  sp->str1=dqs_string_insert(sp->str1,me.default_cell);
	sp->int3=TRUE;
      }
    sp=sp->next;
  }
  
  DEXIT;
  return;
  
}

/***************************************************************************/
int dqs_show_job(job)
     dqs_job_type *job;
     
{
  
  int i;     
  dqs_list_type *sp;
  
  DENTER((DQS_EVENT,"dqs_show_job"));
  
  printf("----------------------------------------------------------------\n");
  
  if (job->job_number)
    printf("job_number              %d\n",job->job_number);
  else
    printf("job_number              unassigned\n");
  
  printf("submission_time            %s",ctime((time_t *)&job->submission_time));
  
  if (job->start_time)
    printf("start_time                 %s",ctime((time_t *)&job->start_time));
  
  if (job->end_time)
    printf("end_time                   %s",ctime((time_t *)&job->end_time));
  
  printf("owner                      %s\n",job->owner);
  
  printf("uid                        %d\n",job->uid);
  
  printf("euid                       %d\n",job->euid);
  
  if (job->dqs_o_home)
    printf("dqs_o_home         %s\n",job->dqs_o_home);
  
  if (job->dqs_o_log_name)
    printf("dqs_o_log_name             %s\n",job->dqs_o_log_name);
  
  if (job->dqs_o_path)
    printf("dqs_o_path                 %s\n",job->dqs_o_path);
  
  if (job->dqs_o_mail)
    printf("dqs_o_mail                 %s\n",job->dqs_o_mail);
  
  if (job->dqs_o_shell)
    printf("dqs_o_shell                %s\n",job->dqs_o_shell);
  
  if (job->dqs_o_tz)
    printf("dqs_o_tz                   %s\n",job->dqs_o_tz);
  
  if (job->dqs_o_workdir)
    printf("dqs_o_workdir              %s\n",job->dqs_o_workdir);
  
  if (job->dqs_o_host)
    printf("dqs_o_host                 %s\n",job->dqs_o_host);
  
  if (job->execution_time) 
    {
      printf("execution_time                ");
      if (job->execution_time_op) 
	{
	  dqs_show_op(DQS_STDOUT,job->execution_time_op);
	  printf(" ");
	}
      printf("%s\n",ctime((time_t *)&job->execution_time));   
    }
  
  if (job->account_list)
    {
      printf("account_list\n");
      dqs_showlist(job->account_list,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->server_name)
    printf("-B\n");
  
  if (job->checkpoint_attr) 
    {
      printf("checkpoint_attr               ");
      if (job->checkpoint_attr_op) 
	{
	  dqs_show_op(DQS_STDOUT,job->checkpoint_attr_op);
	  printf(" ");
	}       
      dqs_show_checkpoint(DQS_STDOUT,job->checkpoint_attr);
      printf("\n");
    }
  
  if (job->checkpoint_interval)
    {
      printf("checkpoint_interval           ");
      if (job->checkpoint_attr_op)
	{
	  dqs_show_op(DQS_STDOUT,job->checkpoint_attr_op);
	  printf(" ");
	}
      printf("%d minutes\n",job->checkpoint_interval);
    }
  
  if (job->cell)
    {
      printf("cell                  %s\n",job->cell);
    }
  
  if (job->cwd)
    {
      printf("cwd                     %s\n",job->cwd);
    }
  
  if (job->directive_prefix)
    printf("directive_prefix   %s\n",job->directive_prefix);
  
  if (job->stderr_path_list)
    {
      printf("stderr_path_list\n");
      dqs_showlist(job->stderr_path_list,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->exec_list)
    {
      printf("exec_list\n");
      dqs_showlist(job->exec_list,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->ext)
    {
      printf("-ext\n");
    }
  
  if (job->send_msg_to_stderr)
    printf("-E");
  
  if (job->full_listing)
    printf("-f");
  
  if (job->group_list)
    {
      printf("group_list\n");
      dqs_showlist(job->group_list,DQS_STDOUT|DQS_STR0,8);
    }
  
  if (job->hold)
    {
      printf("hold                  ");
      dqs_show_hold_list(job->hold,DQS_STDOUT);
      printf("\n");
    }
  
  if (job->merge_stderr)
    {
      printf("merge                 ");
      dqs_show_y_n(job->merge_stderr,DQS_STDOUT);
      printf("\n");
    }
  
  if (job->maint_local_output)
    {
      printf("keep_list             ");
      dqs_show_keep_list(job->maint_local_output,DQS_STDOUT);
      printf("\n");
    }
  
  if (job->hard_resource_list)
    {
      printf("hard resource_list          \n");
      dqs_show_resource_list(job->hard_resource_list);
    }
  
  if (job->soft_resource_list)
    {
      printf("soft resource_list          \n");
      dqs_show_resource_list(job->soft_resource_list);
    }
  
  if (job->mail_options)
    {
      printf("mail_options          ");
      dqs_show_mail_options(job->mail_options,DQS_STDOUT);
      printf("\n");
    }
  
  if (job->hard_master_list)
    {
      printf("hard master_list      \n");
      dqs_showlist(job->hard_master_list,DQS_STDOUT|DQS_STR0|DQS_STR1|DQS_STR2,8);
    }
  
  if (job->soft_master_list)
    {
      printf("soft master_list      \n");
      dqs_showlist(job->soft_master_list,DQS_STDOUT|DQS_STR0|DQS_STR1|DQS_STR2,8);
    }
  
  if (job->mail_list)
    {
      printf("mail_list             ");
      dqs_showlist(job->mail_list,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  printf("notify                  %s\n",true_false[job->notify]);
  
  if (job->job_name)
    {
      printf("job_name              %s\n",job->job_name);
    }
  
  if (job->stdout_path_list)
    {
      printf("stdout_path_list\n");
      dqs_showlist(job->stdout_path_list,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->send_msg_to_stdout)
    {
      printf("-O\n");
    }
  
  if (job->priority)
    {
      printf("priority              ");
      if (job->priority_op)
	{
	  dqs_show_op(job->priority_op,DQS_STDOUT);
	  printf(" ");
	}
      printf("%d\n",job->priority-BASE_PRIORITY);
    }
  
  if (job->parallel_package)
    {
      printf("parallel_package        %s\n",
	     parallel_package[job->parallel_package]);
    }
  
  if (job->passwd)
    {
      printf("passwd\n");
      dqs_showlist(job->passwd_list,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->Passwd)
    printf("Passwd              %s\n",job->Passwd);
  
  if (job->hard_queue_list)
    {
      printf("hard queue_list\n");
      dqs_showlist(job->hard_queue_list,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->soft_queue_list)
    {
      printf("soft queue_list\n");
      dqs_showlist(job->soft_queue_list,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->reauth_time)
    {
      printf("reauth_time            %d\n",job->reauth_time);
    }
  
  if (job->restart) 
    {
      printf("restart               ");
      dqs_show_y_n(job->restart,DQS_STDOUT);
      printf("\n");
    }
  
  if (job->state) 
    {
      printf("state         ");
      dqs_show_states(DQS_STDOUT,job->state);
      printf("\n");
    }
  
  if (job->states)
    {
      printf("states                ");
      dqs_show_states(DQS_STDOUT,job->states);
      printf("\n");
    }
  
  if (job->signal)
    {
      i=dqs_unmap_signal(job->signal);
      printf("signal                -%d\n",job->signal);
    }
  
  if (job->shell_list)
    {
      printf("shell_list            \n");
      dqs_showlist(job->shell_list,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->user_list)
    {
      printf("user_list             \n");
      dqs_showlist(job->user_list,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->unlog)
    {
      printf("unlog AFS tokens at end of job\n");
    }
  
  if (job->variable_list)
    {
      printf("variable_list         \n");
      dqs_showlist(job->variable_list,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->verify)
    {
      printf("-verify\n");
    }
  
  if (job->env_list)
    {
      printf("env_list              \n");
      dqs_showlist(job->env_list,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->silent)
    {
      printf("-z\n");
    }
  
  if (job->master_queue)
    {
      printf("master_queue          %s\n",job->master_queue);
    }
  
  if (job->master_queue_exec_str)
    {
      printf("master_queue_exec_str         %s\n",job->master_queue_exec_str);
    }
  
  if (job->DQSX_STR13)
    {
      printf("DQSX_STR%s\n",job->DQSX_STR13);
    }
  
  if (job->DQSX_STR14)
    {
      printf("DQSX_STR14            %s\n",job->DQSX_STR14);
    }
  
  if (job->DQSX_STR15)
    {
      printf("DQSX_STR15            %s\n",job->DQSX_STR15);
    }
  
  if (job->clean)
    {
      printf("clean                 %d\n",true_false[job->clean]);
    }
  
  if (job->scheduling_flags)
    {
      printf("Scheduling flags<             %d\n",job->scheduling_flags);
    }
  
  if (job->subpriority)
    {
      printf("subpriority<          %d\n",job->subpriority);
    }
  
  if (job->schedule_seq_num)
    {
      printf("Schedule Sequence Number<             %d\n",job->schedule_seq_num);
    }
  
  if (job->jid_hold_list)
    {
      printf("jid_hold_list\n");
      dqs_showlist(job->jid_hold_list,DQS_STDOUT|DQS_INT0,8);
    }
  
  if (job->job_status_info)
    {
      printf("job_status_info\n");
      dqs_showlist(job->job_status_info,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->DQSX_L13)
    {
      printf("DQSX_L13\n");
      dqs_showlist(job->DQSX_L13,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->DQSX_L14)
    {
      printf("DQSX_L14\n");
      dqs_showlist(job->DQSX_L14,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->DQSX_L15)
    {
      printf("DQSX_L15\n");
      dqs_showlist(job->DQSX_L15,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->destin_identifier_list)     
    {
      printf("destin_identifier_list\n");
      dqs_showlist(job->destin_identifier_list,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->job_identifier_list)
    {
      printf("job_identifier_list\n");
      dqs_showlist(job->job_identifier_list,DQS_STDOUT|DQS_STR0|DQS_INT0,8);
    }
  
  if (job->message)
    printf("message                    %s\n",job->message);
  
  if (job->srvr_nm_list)
    {
      printf("srvr_nm_list\n");
      dqs_showlist(job->srvr_nm_list,DQS_STDOUT|DQS_STR0|DQS_STR1,8);
    }
  
  if (job->script_file)
    printf("script_file              %s\n",job->script_file);
  
  
  DEXIT;
  return 0;
  
}

/***************************************************************************/
dqs_list_type *dqs_parse_jid_hold_list(str)
     char          *str;
     
     /*   jid[,jid,...]
	  
	  int0 - jid
	  
     */
     
{
  
  char          *variable_value;
  dqs_list_type *head=NULL;
  dqs_list_type element;
  
  DENTER((DQS_EVENT,"dqs_parse_jid_hold_list"));
  
  bzero((char *)&element,sizeof(element));
  variable_value=dqs_strtok(str,",");
  DQS_ASSERT((variable_value));
  element.int0=dqs_atoi(variable_value);
  head=dqs_insert(DQS_INT0,TAIL,head,&element);
  
  while ((variable_value=dqs_strtok((char *)NULL,","))!=(char *)NULL) 
    {
      bzero((char *)&element,sizeof(element));
      DQS_ASSERT((variable_value));
      element.int0=dqs_atoi(variable_value);
      head=dqs_insert(DQS_INT0,TAIL,head,&element);
    }
  
  DEXIT;
  return(head);
  
}

/***************************************************************************/
void dqs_parse_consumable_list(head,path_str)
     dqs_list_type *head;
     char          *path_str;
     
     /* 
	-rc consumable_name=amount
	
	str0 - consumable_name
	int0  - amount
     */
     
{
  
  char          *path=NULL;
  
  dqs_list_type *sp=NULL;
  char  *cname=NULL;
  char  *amount_str=NULL;
  dqs_list_type element;
  int amount;
  
  DENTER((DQS_EVENT,"dqs_parse_consumable_list"));
  
  bzero((char *)&element,sizeof(element));
  cname=dqs_strtok(path_str,"=");
  DQS_ASSERT((cname));
  element.str0=dqs_string_insert(element.str0,cname);
  
  if( (amount_str=dqs_strtok(0,", ") )!=(char *)NULL) {
    DQS_ASSERT((amount_str));
    amount= atoi(amount_str);
    if(amount<=0){
      DEXIT;	
      return;     
    }
    element.int3= amount;
    head=dqs_insert(DQS_STR3,TAIL,head,&element);
  } 
  
  DEXIT;
  return;
  
}


