C******************************************************************************
	SUBROUTINE AK$SWITCH(FORM,USERNAME,LINE,LINE_LENGTH)
C******************************************************************************
C AKSWITCH.FOR
C
C  written by:  K. Trumbley
C  date:        May 1984
C  modified:    K. Trumbley, July 1986, - added repair command switches
C                                       - improved switch parsing
C
C  Routine to search the incoming LINE for all the various switches and
C  to set the appropriate flag if the switch is set. Also checks to see
C  if current process is in BATCH mode, and if so then set BATCH_FLAG.
C
C		REPORT GENERATOR SWITCH DEFINITIONS
C		-----------------------------------
C
C	/ACCOUNT=account	Print output for this account.
C
C	/BEGIN=date		Start search of AKCOUNT file from
C				that date, default = previous week.
C
C	/END=date		End search of AKCOUNT file as of that
C				date, default = previous week.
C
C	/INPUT=filename		Search "filename" instead of current
C				AKCOUNT.TOT file in SYS$ACCOUNT:
C				default filename = SYS$ACCOUNT:AKCOUNT.TOT
C
C	/OUTPUT=filename	Output all printout to this file,
C				Default = User's terminal
C				Default filename = AKREPORT.LIS
C
C	/PRINT			Force output file to be printed on
C				line printer
C
C	/SORT=USERNAME		Sort summary by these types, default
C	      ACCOUNT		is USERNAME. Sort in ascending order.
C	      UIC
C	      DISK_USAGE
C	      PRINTED_PAGES
C	      CHARGES
C
C	/DSORT=USERNAME		Sort summary by these types, default
C	      ACCOUNT		is USERNAME. Sort in descending order.
C	      UIC
C	      DISK_USAGE
C	      PRINTED_PAGES
C	      CHARGES
C
C	/SUMMARY		Print output in summary table instead
C				of detailed form.
C
C	/RATE_TABLE		Append current charges per resource
C				table at end of printout, if detailed
C				printout, then table printed after each
C				user printout.
C
C	/NOTOTAL		Disable totalize of printout,
C				default = TOTALIZE
C
C	/LAST_LOGIN		Display date of last time account used.
C
C	/HELP			Specifies enter HELP facility to get
C				help on AKREPORT utility

C
C		REPAIR UTILITY SWITCH DEFINITIONS
C		---------------------------------
C
C	/BEGIN=date		Start search of AKCOUNT file from
C				that date, default = beginning of file.
C
C	/END=date		End search of AKCOUNT file as of that
C				date, default = end of file.
C
C	/INPUT=filename		Search "filename" instead of current
C				AKCOUNT.TOT file in SYS$ACCOUNT:
C				default filename = SYS$ACCOUNT:AKCOUNT.TOT
C
C	/OUTPUT=filename	Output goes to this file,
C				Default filename = SYS$ACCOUNT:AKCOUNT.TOT
C
C	/FIX			Specifies query fix mode. User queried
C				for action desired when error detected
C
C	/AUTOFIX		Specifies auto fix mode. Errors repaired
C				automatically.
C
C	/EDIT			Specifies edit mode. Should be used with
C				USER and HEADER switches
C
C	/USER			Specifies edit user records
C
C	/HEADER			Specifies edit header records
C
C	/HELP			Specifies enter HELP facility to get
C				help on AKREPAIR utility
C
C  NOTE:
C	1. The date and filenames described above have the following
C	   forms, (do not insert spaces in string), filename is optional
C
C		date     = 2-JAN-1984
C		filename = SYS$ACCOUNT:AKCOUNT.Y83
C

	INCLUDE '($JPIDEF)'
	INCLUDE 'AK.INC/NOLIST'
	CHARACTER USERNAME*12,LINE*132,SWITCHES*132
	CHARACTER*20 SORT_TABLE(7)
	INTEGER*4 JPI_INFO(2),JOB_STATUS,JOB_STATUS_SIZE,FORM
	INTEGER*2 JPI_STATUS(2)
	COMMON/JPI/JPI_STATUS,JPI_INFO
C
	DATA SORT_TABLE/'USERNAME','ACCOUNT','UIC','DISK_USAGE'
     &	               ,'PRINTED_PAGES','CHARGES','END_TABLE'/
C
	DATA PCB$V_BATCH/14/
	DATA JPI_STATUS/4,JPI$_STS/
	JPI_INFO(1)=%LOC(JOB_STATUS)
	JPI_INFO(2)=%LOC(JOB_STATUS_SIZE)
C
	ISTAT=SYS$GETJPI(,,,JPI_STATUS,,,)
	IF (.NOT.ISTAT) CALL LIB$SIGNAL(%VAL(ISTAT))
C
C  Check if batch job, if yes then BATCH_FLAG = .TRUE.
C	PCB$V_BATCH=14
C
	MODE=JOB_STATUS.AND.2**PCB$V_BATCH
	IF (MODE.NE.0) THEN
	  BATCH_FLAG=.TRUE.
	ELSE
	  BATCH_FLAG=.FALSE.
	END IF

C
C  Parse command line into USERNAME and SWITCHES
C
	LINE(LINE_LENGTH+1:LINE_LENGTH+1)='~'
	CALL PARSE(USERNAME,SWITCHES,LINE)
	AKCOUNT_FILENAME=' '
	OUTPUT_FILENAME=' '
C
C  Parse report generator command switches and set flags
C
	IF (SWITCHES.NE.'~'.AND.FORM.EQ.FORM_REPORT) THEN
	 CALL CHECK_SWITCH(SWITCHES,'/SUMMARY',SUMMARY_FLAG,POS)
	 CALL CHECK_SWITCH(SWITCHES,'/ACCOUNT',ACCOUNT_FLAG,POS)
	   IF(ACCOUNT_FLAG) CALL GET_STRING(SWITCHES,POS,ACCOUNT_NAME)
	 CALL CHECK_SWITCH(SWITCHES,'/SORT',SORT_FLAG,POS)
	   IF(SORT_FLAG) CALL GET_STRING(SWITCHES,POS,SORT_TYPE)
	 CALL CHECK_SWITCH(SWITCHES,'/DSORT',ASCEND_FLAG,POS)
	   IF(ASCEND_FLAG) THEN
	      SORT_FLAG=.TRUE.
	      CALL GET_STRING(SWITCHES,POS,SORT_TYPE)
	   END IF
	   ASCEND_FLAG=.NOT.ASCEND_FLAG
	 CALL CHECK_SWITCH(SWITCHES,'/PRINT',LINE_PRINTER_FLAG,POS)
	 CALL CHECK_SWITCH(SWITCHES,'/NOTOTAL',TOTAL_FLAG,POS)
	 TOTAL_FLAG=.NOT.TOTAL_FLAG
	 CALL CHECK_SWITCH(SWITCHES,'/LAST_LOGIN',LAST_LOGIN_FLAG,POS)
	 CALL CHECK_SWITCH(SWITCHES,'/RATE_TABLE',RATE_TABLE_FLAG,POS)
	END IF
C
C  Parse repair utility command switches and set flags
C
	IF (SWITCHES.NE.'~'.AND.FORM.EQ.FORM_REPAIR) THEN
	 CALL CHECK_SWITCH(SWITCHES,'/FIX',FIX_FLAG,POS)
	 CALL CHECK_SWITCH(SWITCHES,'/AUTOFIX',AUTO_FIX_FLAG,POS)
	 CALL CHECK_SWITCH(SWITCHES,'/EDIT',EDIT_FLAG,POS)
	 CALL CHECK_SWITCH(SWITCHES,'/HEADER',HEADER_FLAG,POS)
	 CALL CHECK_SWITCH(SWITCHES,'/USER',USER_FLAG,POS)
	END IF
C
C  Parse all common command switches and set flags
C
	IF (SWITCHES.NE.'~') THEN
	 CALL CHECK_SWITCH(SWITCHES,'/HELP',HELP_FLAG,POS)
	 CALL CHECK_SWITCH(SWITCHES,'/BEGIN=',BEGIN_FLAG,POS)
	 IF (BEGIN_FLAG) THEN
	   CALL GET_DATE(SWITCHES,POS,BEGIN_DATE,BEGIN_FLAG)
	 END IF
	 CALL CHECK_SWITCH(SWITCHES,'/END=',END_FLAG,POS)
	 IF (END_FLAG) THEN
	   CALL GET_DATE(SWITCHES,POS,END_DATE,END_FLAG)
	 END IF
	 CALL CHECK_SWITCH(SWITCHES,'/INPUT',INPUT_FLAG,POS)
	 IF (INPUT_FLAG) THEN
	   CALL GET_STRING(SWITCHES,POS,AKCOUNT_FILENAME)
	 END IF
	 CALL CHECK_SWITCH(SWITCHES,'/OUTPUT',OUTPUT_FLAG,POS)
	 IF (OUTPUT_FLAG) THEN
	   CALL GET_STRING(SWITCHES,POS,OUTPUT_FILENAME)
	 END IF
	END IF

C
C  Set all defaults if switches not set
C
	IF (AKCOUNT_FILENAME.EQ.' ') THEN
	  AKCOUNT_FILENAME='SYS$ACCOUNT:AKCOUNT.TOT'
	END IF
	IF (LINE_PRINTER_FLAG) OUTPUT_FLAG=.TRUE.
	IF (OUTPUT_FILENAME.EQ.' ') THEN
	  OUTPUT_FILENAME='AKREPORT.LIS'
	  IF (FORM.EQ.FORM_REPAIR) THEN
	    OUTPUT_FILENAME=AKCOUNT_FILENAME
	  END IF
	END IF
C
	IF (.NOT.SUMMARY_FLAG.AND.BATCH_FLAG
     &	                     .AND.(USERNAME.EQ.'*')) THEN
	  PAGE_FLAG=.TRUE.
	END IF
	IF (OUTPUT_FLAG.OR.LINE_PRINTER_FLAG) PAGE_FLAG=.TRUE.
C
	IF (SORT_FLAG) THEN
	  I=1
	  S_LEN=INDEX(SORT_TYPE,' ')-1
	  DO WHILE(SORT_TABLE(I).NE.'END_TABLE')
	    IF (SORT_TYPE(1:S_LEN).EQ.SORT_TABLE(I)(1:S_LEN)) THEN
	      SORT_TYPE=SORT_TABLE(I)
	      GOTO 100
	    END IF
	    I=I+1
	  END DO
	  SORT_TYPE='USERNAME'
100	  CONTINUE
	ELSE
	  SORT_FLAG=.TRUE.
	  SORT_TYPE='USERNAME'
	END IF
	IF (.NOT.ACCOUNT_FLAG) ACCOUNT_NAME='*'
	ACC_NAME_LEN=INDEX(ACCOUNT_NAME,' ')-1
	RETURN
	END
C
C
C******************************************************************************
	SUBROUTINE CHECK_SWITCH(SWITCHES,SWITCH,SWITCH_FLAG,REL_POS)
C******************************************************************************
C
C  Check command line to see if switch present, if yes then set switch flag
C  TRUE, else set flag FALSE.
C
	INCLUDE 'AK.INC/NOLIST'
	LOGICAL*1 SWITCH_FLAG
	CHARACTER *(*) SWITCHES,SWITCH
C
	IND=INDEX(SWITCHES,'~')
	REL_POS=STR$POSITION(SWITCHES(1:IND-1),SWITCH(1:4))
	IF(REL_POS.NE.0) THEN
	  SWITCH_FLAG=.TRUE.
	ELSE
	  SWITCH_FLAG=.FALSE.
	END IF
	RETURN
	END
	  
C
C
C******************************************************************************
	SUBROUTINE GET_DATE(SWITCHES,REL_POS,DATE,FLAG)
C******************************************************************************
C
C  Get date from command line and convert to 64 bit time, if error then
C  report and exit.
C
	INCLUDE 'AK.INC/NOLIST'
	CHARACTER*(*)  SWITCHES
	CHARACTER  DATE_STR*20
	LOGICAL*1  FLAG
C
	CALL GET_STRING(SWITCHES,REL_POS,DATE_STR)
	IF (DATE_STR.EQ.' ') THEN
	  FLAG=.FALSE.
	  RETURN
	END IF
C
	ISTAT=SYS$BINTIM(DATE_STR,DATE)
	IF(.NOT.ISTAT) CALL LIB$SIGNAL(%VAL(ISTAT))
	RETURN
	END
C
C
C******************************************************************************
	SUBROUTINE GET_STRING(SWITCHES,REL_POS,RETURN_STRING)
C******************************************************************************
C
C   Get string from command line and if not present,
C     set return_string=' '
C
	INCLUDE 'AK.INC/NOLIST'
	CHARACTER*(*)  SWITCHES,RETURN_STRING
C
	RETURN_STRING=' '
	IND=INDEX(SWITCHES,'~')
	IND1=INDEX(SWITCHES(REL_POS:IND),'=')
	INDX=INDEX(SWITCHES(REL_POS+1:IND),'/')
	IF (IND1.NE.0.AND.INDX.NE.0.AND.IND1.GT.INDX) RETURN
	IF (INDX.EQ.0) THEN
	  IND2=IND
	ELSE
	  IND2=INDX+REL_POS
	END IF
	IF(IND1.EQ.0.OR.(IND2-IND1-1).LE.0) RETURN
	IND1=IND1+REL_POS-1
	RETURN_STRING=SWITCHES(IND1+1:IND2-1)
	RETURN
	END

C******************************************************************************
	FUNCTION CMP_DATE(IN_DATE,TEST_DATE)
C******************************************************************************
C
C  Compare two quadword binary time values and set CMP_DATE accordingly.
C
C	CMP_DATE = .TRUE.  if TEST_DATE .LE. IN_DATE
C	CMP_DATE = .FALSE. if TEST_DATE .GT.IN_DATE
C
	IMPLICIT INTEGER(A-Z)
	LOGICAL*1 CMP_DATE
	INTEGER*4 IN_DATE(2),TEST_DATE(2)
	IF (TEST_DATE(2).GT.IN_DATE(2)) THEN
	  CMP_DATE=.FALSE.
	  RETURN
	ELSE
	  IF(TEST_DATE(2).EQ.IN_DATE(2)) THEN
	     IF(TEST_DATE(1).GT.IN_DATE(1)) THEN
	       CMP_DATE=.FALSE.
	       RETURN
	     END IF
	  END IF
	END IF
	CMP_DATE=.TRUE.
	RETURN
	END

c*********************************************************************
c
	subroutine parse(username,switches,line)
c
c*********************************************************************
c
c	This routine parses the input line into a text string
c  which contains the USERNAME and a text string which contains
c  all the command switches. The routine does not worry about the
c  order of the switches and username, only the USERNAME must be
c  preceded by a space or tab character.
c
	implicit integer(a-z)
	character*(*) username,switches,line
	character name*132
c
	l_ptr = 0
	n_ptr = 0
	s_ptr = 0
	mode = 0
	name = '*'
c
	do while (line(l_ptr+1:l_ptr+1).ne.'~')
	  l_ptr = l_ptr + 1
	  if (mode.eq.0) then
	    if (line(l_ptr:l_ptr).eq.'/') then
	      mode = 2
	    else if (line(l_ptr:l_ptr).ne.' '.and.
     &	             line(l_ptr:l_ptr).ne.'	') then
	      mode = 1
	    end if
	  end if
c
c  Copy USERNAME
c
	  if (mode.eq.1) then
	    if (line(l_ptr:l_ptr).eq.'/') then
	      mode = 2
	    else if (line(l_ptr:l_ptr).ne.' '.and.
     &	             line(l_ptr:l_ptr).ne.'	') then
	      n_ptr = n_ptr + 1
	      name(n_ptr:n_ptr) = line(l_ptr:l_ptr)
	    else
	      mode = 0
	    end if
	  end if
c
c  Copy SWITCHES
c
	  if (mode.eq.2) then
	    if (line(l_ptr:l_ptr).ne.' '.and.
     &	        line(l_ptr:l_ptr).ne.'	') then
	      s_ptr = s_ptr + 1
	      switches(s_ptr:s_ptr) = line(l_ptr:l_ptr)
	    else
	      mode = 0
	    end if
	  end if
	end do
c
	username = name(1:len(username))
	switches(s_ptr+1:s_ptr+1) = '~'
c
	return
	end

