From:	CSBVAX::CSBVAX::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 14-DEC-1988 02:55
To:	MRGATE::"ARISIA::EVERHART"
Subj:	EXECUTE batch utility 2/2


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Tue, 13 DEC 88 11:57:09 PDT
Received: from XX.LCS.MIT.EDU by KL.SRI.COM with TCP; Tue, 13 Dec 88 11:40:39 PST
Received: from PFC-VAX.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 13 Dec 88 14:12-EST
Date: 13 Dec 88 14:13:44 EST
From: MRL%PFC-VAX.MIT.EDU@XX.LCS.MIT.EDU
To: INFO-VAX@KL.SRI.COM@XX
Subject: EXECUTE batch utility 2/2

+-+-+-+ Beginning of part 2 +-+-+-+
X`009`009`009`009/* Now add items to list
X`009ADD_2_ITMLST(LEN,SJC$_FILE_SPECIFICATION,%LOC(FILENAME))
X`009ADD_2_ITMLST(9,SJC$_QUEUE,%LOC(QUEUE))
X`009END_ITMLST(SNDJBC_ITMLST)`009/* Get address of itemlist
X`009IER = SYS$SNDJBCW(,%VAL(SJC$_ENTER_FILE),,%VAL(SNDJBC_ITMLST),IOSB,,)
X
X  NOTE: These routines don't presently allow return length address
X  in item list.`009`009`009`009`009`009`009`009*/
X
Xstruct ITEM_LIST `123
X`009short buflen ;
X`009short code ;
X`009int bufadr ;
X`009int retadr ;
X`009`125 ;
X
Xint save_itmlst_address = 0,num_items = 0,queue_header = 0;
Xint input_itmlst,itmlst_length;
X
Xinit_itmlst()
X`123
X`009if (queue_header == 0) `123`009/* First time INIT_ITMLST called? */
X`009   lib$get_vm(&8,&queue_header);  /* Yes, create queue header pointer */
X`009   lib$movc3(&4,&0,queue_header);`009/* Zero out header */
X`009   lib$movc3(&4,&0,queue_header+4);`009/* Zero out header */
V`009`125 else if (save_itmlst_address > 0) `123`009/* Clean out old item list *
X/
X`009   lib$free_vm(&itmlst_length,&save_itmlst_address);
X`009   num_items = 0;`009`009/* Release old itemlist memory */
X`009   save_itmlst_address = 0;
X`009`125 else `123`009`009`009/* ITMLST calls cannot be nested. */
X`009   printf(" ERROR: INIT_ITMLST called before previous");
X`009   printf(" ITMLST terminated with END_ITMLST.");
X`009   exit();
X`009`125
X`125
X
Xadd_2_itmlst(buflen,code,bufadr)
X
Xint buflen,code,*bufadr;
X`123
X
X/* ITMLST entries are initially stored in a queue.  Each queue entry`009*/
X/* needs 8 bytes for pointer + 12 bytes for itemlist info.`009`009*/
X
X`009lib$get_vm(&20,&input_itmlst);`009/* Get memory for entry */
X
X`009store_itmlst_entry(input_itmlst+8,buflen,code,bufadr,0);
X`009`009`009`009`009/* Store data in itemlist format */
X`009lib$insqti(input_itmlst,queue_header);
X`009`009`009`009`009/* Insert entry into queue */
X`009num_items = num_items + 1;`009/* Increment item count */
X`125
X
Xadd_2_itmlst_with_ret(buflen,code,bufadr,retadr)
X
Xint buflen,code,*bufadr,*retadr;
X
X`123
X/* ITMLST entries are initially stored in a queue.  Each queue entry`009*/
X/* needs 8 bytes for pointer + 12 bytes for itemlist info.`009`009*/
X
X`009lib$get_vm(&20,&input_itmlst);`009/* Get memory for entry */
X
X`009store_itmlst_entry(input_itmlst+8,buflen,code,bufadr,retadr);
X`009`009`009`009`009/* Store data in itemlist format */
X`009lib$insqti(input_itmlst,queue_header);
X`009`009`009`009`009/* Insert entry into queue */
X`009num_items = num_items + 1;`009/* Increment item count */
X`125
X
Xend_itmlst(itmlst_address)
Xint *itmlst_address;
X`123
X`009int i;
X`009itmlst_length = (num_items+1)*12;
X`009lib$get_vm(&itmlst_length,itmlst_address);
X`009`009`009`009`009`009/* Get memory for itemlist */
X`009save_itmlst_address = *itmlst_address;`009/* Save to remove memory */
X
X`009for (i = 0; i < num_items; i++) `123`009/* Place entries in itemlist */
X`009   lib$remqhi(queue_header,&input_itmlst);
X`009   lib$movc3(&12,input_itmlst+8,*itmlst_address+i*12);
X`009   lib$free_vm(&20,&input_itmlst);
X`009`125
X
X`009lib$movc3(&4,&0,*itmlst_address+num_items*12);
X`009`009`009`009/* Place terminating 0 at end of itemlist */
X`125
X
X
Xstore_itmlst_entry(input_item_list,buflen,code,bufadr,retadr)
Xint buflen,code,*bufadr,*retadr;
Xstruct ITEM_LIST *input_item_list;
X
X`123
X`009input_item_list->buflen = buflen;
X`009input_item_list->code = code;
X`009input_item_list->bufadr = bufadr;
X`009if (retadr != 0)
X`009`009input_item_list->retadr = retadr;
X`009else
X`009`009input_item_list->retadr = 0;
X`125
$ GOSUB UNPACK_FILE
$ FILE_IS = "SUBMIT.C"
$ CHECKSUM_IS = 19814035
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X#define SJC$_ENTRY_NUMBER_OUTPUT       0x0000001F
X#define SJC$_DELETE_FILE               0x00000018
X#define SJC$_ENTER_FILE                0x00000013
X#define SJC$_QUEUE                     0x00000086
X#define SJC$_NOTIFY                    0x0000006C
X#define SJC$_JOB_NAME                  0x0000004F
X#define SJC$_FILE_SPECIFICATION        0x0000002A
X#define SJC$_LOG_SPECIFICATION         0x00000062
X#define SJC$_NO_LOG_SPOOL              0x00000065
X#define SJC$_AFTER_TIME                0x00000003
X
Xsubmit(filename,queue,after,after_time,logfile,jobnum)
Xchar *filename,*queue,*logfile;
Xint after,after_time[2],*jobnum;
X
X`123
X`009int sndjbc_itmlst,len,sndefn,ier;
X`009short iosb[4];
X
X`009init_itmlst();`009`009/* Initialize item list */
X`009`009`009`009/* Now add items to list */
X
X`009add_2_itmlst(strcspn(filename,"\40\0"),SJC$_FILE_SPECIFICATION,
X`009`009`009`009`009`009`009`009filename);
X`009add_2_itmlst(strcspn(queue,"\40\0"),SJC$_QUEUE,queue);
X`009add_2_itmlst(0,SJC$_NO_LOG_SPOOL,0);
X`009if (strcspn(logfile,":]") == strlen(logfile)) `123
X`009`009len = strlen(getenv("PATH"));
X`009`009strcpy(logfile+len,logfile);
X`009`009strncpy(logfile,getenv("PATH"),len);
X`009`125
X`009add_2_itmlst(strlen(logfile),SJC$_LOG_SPECIFICATION,logfile);
X`009add_2_itmlst(0,SJC$_DELETE_FILE,0);
X`009add_2_itmlst(0,SJC$_NOTIFY,0);
X
X`009if (after&1) add_2_itmlst(8,SJC$_AFTER_TIME,after_time);
X
X`009add_2_itmlst(4,SJC$_ENTRY_NUMBER_OUTPUT,jobnum);
X
X`009end_itmlst(&sndjbc_itmlst);`009/* Get address of itemlist */
X
X`009lib$get_ef(&sndefn);
X
X`009ier = sys$sndjbcw(sndefn,SJC$_ENTER_FILE,0,sndjbc_itmlst,iosb,0,0);
X
X`009if (!(iosb[0]&1)) ier = iosb[0];
X
X`009return(ier);
X`125
$ GOSUB UNPACK_FILE
$ EXIT
-+-+-+-+-+ End of part 2 +-+-+-+-+-

