;-----------------------------------------------------------------------* ; Program: OWN * ;-----------------------------------------------------------------------* ; Programmer: DUANE RIECH * ;-----------------------------------------------------------------------* ; Date: NOVEMBER 1, 1984 * ;-----------------------------------------------------------------------* ; Language: VAX-11 MACRO * ;-----------------------------------------------------------------------* ; System: VAX-11/780 running VAX/VMS V3.6 * ;-----------------------------------------------------------------------* ; Site: UNITED TECHNOLOGY * ; Building Systems * ; Computer Center * ; Waterway Tower * ; 433 Las Colinas Boulevard * ; Irving, Texas 75039 * ; (214) 830-7501 * ;-----------------------------------------------------------------------* ; This software is furnished for free and may * ; be used and copied as desired. This software * ; or any other copies thereof may be provided * ; or otherwise made available to any other * ; person. No title to and ownership of the * ; software is hereby transferred or allowed. * ; * ; The information in this software is subject to * ; change without notice and should not be * ; construed as a commitment by UNITED TECHNOLOGY * ; BUILDING SYSTEMS. * ; * ; UNITED TECHNOLOGY BUILDING SYSTEMS assumes no * ; responsibility for the use or reliability of * ; this software on any equipment whatsoever. * ; * ;-----------------------------------------------------------------------* ; * ; PURPOSE: This is a rewrite of the OWN verb submitted in * ; the spring SIG tape. Macro is used for clarity * ; in using ACP QIO's. * ; * ; The program has three parts. * ; (1) Parsing and expanding the file specification* ; entered by the user to include the translated * ; device, default directory + subdirectories if * ; needed. * ; (2) Extracting the lowest parent directory from * ; the expanded string to obtain the correct UIC * ; for changing the files requested by the user. * ; This is explained in detail in the * ; documentation. * ; (3) Changing the UIC in the file(s) requested * ; by the user. * ; * ; * ; This program does NOT change the file's UIC to * ; the user's UIC but to the lowest defined * ; directory's UIC. Therefore, you do not have to * ; worry about someone using this verb to gain * ; control of another users directory. * ; * ; We also found a bug in the old version. By * ; setting your default to the directory containing* ; your default directory, as in [000000], a user * ; could change the UIC on anybody's default.DIR to* ; the same UIC value as it's parent . This meant * ; the next time the orginal user of the changed * ; default.DIR logged in he would not own his top * ; level directory and could not access anything. * ; * ; I have made an effort to fix this by looking at * ; the FID and DID of each file read before * ; modifing it. If either one contains a value of * ; 4 in the first word ( 3 words long ), I display * ; an error and do no modification. * ; * ; Depending upon how your system and user's top * ; directories are setup, this may or may not solve* ; the problem, but it's better than before and it * ; works for us. * ; * ; Software support assures me that that file id * ; FID for the top directory is reserved and would * ; not change between systems. If in doubt do: * ; DUMP/HEADER DRnn:[000000]000000.DIR and look at * ; the first word of the file id. If you have to * ; make a change the documentation tells you where * ; to do it. * ; * ; I use QIO's whenever possible because it's * ; easier to see whats happening. The $OPEN macro * ; is used when accessing the parent directory * ; file to obtain the file's FID and DID for the * ; ACP QIOW. * ; * ; In an attempt to access files that are * ; installed, I set the FIB$M_NOLOCK bit to * ; override exclusive access by another image. * ; * ; * ;-----------------------------------------------------------------------* $IODEF $FABDEF $RABDEF $ATRDEF $NAMDEF $FIBDEF $RMSDEF $SBKDEF $SSDEF $CLIMSGDEF .PSECT DATA,WRT,NOEXE INFAB: $FAB FAC = , - FNA = BUFFER, - FNS = 70, - NAM = NAM_BLOCK INRAB: $RAB FAB = INFAB, - RBF = REC_BUF, - RSZ = 512, - UBF = USER_BUF, - USZ = 128 NAM_BLOCK: $NAM ESA = EXP_STR, - ESS = NAM$C_MAXRSS, - RSA = RES_STR, - RSS = NAM$C_MAXRSS EXP_STR: .BLKB NAM$C_MAXRSS RES_STR: .BLKB NAM$C_MAXRSS REC_BUF: .BLKB 512 USER_BUF: .BLKB 128 FIB: .BLKB 512 FIB_D: .LONG 512 .ADDRESS FIB FIB_OUT: .BLKB 512 FIB_OUT_D: .LONG 512 .ADDRESS FIB_OUT DEVICE: .BLKB 64 DEVICE_D: .LONG 1 .ADDRESS NAM_BLOCK+NAM$T_DVI+1 INPUT: .ASCID /SYS$INPUT/ FILE_CHAN: .BLKW 1 USER_CHAN: .BLKW 1 ; User channel IOS_STAT: .BLKQ 1 ; Status block TERMINATOR: .BLKQ 0 ; QIOW terminator block BUFFER: .BLKB 70 TEMP_BUFFER: .BLKB 70 TEMP_BUFFER_D: .LONG 70 .ADDRESS TEMP_BUFFER TEMP_BUFFER_AD: .ADDRESS TEMP_BUFFER BUFFER_D: .LONG 70 .ADDRESS BUFFER FILE_NAME: .BLKB 30 FILE_D: .LONG 0 ; File name .ADDRESS FILE_NAME FILE_NAME_D: .LONG 11 ; File name descriptor .ADDRESS OUT_NAME OUT_NAME: .BLKB 20 OUT_NAME_AD: .ADDRESS OUT_NAME REC_ATR: .WORD ATR$S_UCHAR,ATR$C_UCHAR ; File characteristics .ADDRESS FILE_CHAR .WORD ATR$S_RECATTR,ATR$C_RECATTR ; File attributes .ADDRESS REC_ATR_BUFF .WORD ATR$S_FPRO,ATR$C_FPRO ; File protection .ADDRESS FILE_PROT .WORD ATR$S_UIC,ATR$C_UIC ; File UIC .ADDRESS FILE_UIC .WORD ATR$S_ASCNAME,ATR$C_ASCNAME ; File ascii name .ADDRESS OUT_NAME .WORD ATR$S_STATBLK,ATR$C_STATBLK ; Record status block .ADDRESS STAT_BLOCK .LONG 0 DE_REC_ATR: .WORD ATR$S_UIC,ATR$C_UIC ; File UIC .ADDRESS FILE_UIC .LONG 0 REC_ATR_BUFF: .BLKB 32 STAT_BLOCK: .BLKB ATR$S_STATBLK FILE_CHAR: .BLKB 4 ; File's characteristics FILE_PROT: .BLKB 2 ; File's protection FILE_UIC: .BLKB 4 ; File's UIC OWNER_UIC: .BLKB 4 NOPRIV_STR: .ASCID "%SYSTEM-F-NOPRIV, operation requires SYSPRV on " - "file !AD " SYSPRV_STR: .ASCID "%SYSTEM-F-NOSYSPRV, operation requires SYSPRV " - "privilege" PROMPT_STR: .ASCII " Enter file name --> " CONF_STR: .ASCID " You now own !AD " CONFIRM_STR: .ASCID "!/ Own !AD " CONF_LEN: .WORD 0 OUT_STR: .BLKB 132 OUT_STR_D: .LONG 132 .ADDRESS OUT_STR LEN: .LONG 1 DIFF: .LONG 1 ; attribute. FILE_ERROR: .ASCID " !/ Error opening file !A70 " ERROR_LEN: .WORD 1 ; Length of output buffer ERROR_BUF: .BLKB 80 ; Error buffer ERROR_BUF_D: .LONG 80 ; Error buffer descriptor .ADDRESS ERROR_BUF RESULT_LENGTH: .WORD 0 RESULT_STR_D: .LONG 13 .ADDRESS OUT_NAME RESULT_STR: .BLKB 13 CONTEXT: .LONG 0 DIR_NAME_D: .LONG 0 .ADDRESS NAM_BLOCK+NAM$L_DIR DIR_EXT: .ASCII /.DIR/ CONV_NAME: .BLKB 70 CONV_NAME_D: .LONG 70 .ADDRESS CONV_NAME END_AD: .LONG 0 START_AD: .LONG 0 TEMP: .LONG 0 SUB_DIR: .ASCII /[./ SEARCH: .ASCII /[000000./ DOT_DOT: .ASCII /../ DOT_BR: .ASCII /.]/ NUL_DIR: .ASCII /[]/ LOG_B: .BYTE 0 CONFIRM_B: .BYTE 0 LOG: .ASCID "LOG" CONFIRM: .ASCID "CONFIRM" RESP: .BLKB 1 TOP_DIR: .ASCII /[000000]/ SUB_EXT: .ASCII /...]/ SYS$DISK: .ASCID /SYS$DISK/ TRN_BUF: .BLKB 30 TRN_BUF_D: .LONG 30 .ADDRESS TRN_BUF TRN_LEN: .WORD 0 DISK_BUF: .BLKB 30 DISK_BUF_D: .LONG 30 .ADDRESS DISK_BUF .PSECT CODE,NOWRT,EXE .ENTRY OWN ^M<> $ASSIGN_S DEVNAM=INPUT,CHAN=USER_CHAN ; Assign a channel to the user ; for later use. PUSHAL BUFFER_D ; Get the command line. CALLS #1,G^LIB$GET_FOREIGN PUSHAL LOG ; Parse for the qualifier CALLS #1,G^CLI$PRESENT ; "/LOG". CMPL R0,#CLI$_PRESENT ; Check if qualifier is BNEQ 1$ ; present. MOVB #1,LOG_B ; Yes, set variable. 1$: PUSHAL CONFIRM ; Parse for the qualifier CALLS #1,G^CLI$PRESENT ; "/CONFIRM". CMPL R0,#CLI$_PRESENT ; Check if qualifier is BNEQ 2$ ; present. MOVB #1,CONFIRM_B ; Yes, set variable. 2$: ; ; Now that the qualifier variables have/have-not been set, strip ; out the qualfiers in the buffer since they have no more use. ; FIND_QUAL: LOCC #^X2F,#70,BUFFER ; Locate a "/" CMPL R0,#0 ; Not found... done. BNEQ 1$ JMP 2$ 1$: MOVL R1,TEMP ; Address of "/" LOCC #^X20,R0,@TEMP ; Locate next space after "/" INCL R1 ; Don't include space. MOVC3 R0,(R1),@TEMP ; Move string after space to ; location of "/". JMP FIND_QUAL ; Go back and look for another ; qualifier. 2$: LOCC #^X20,#70,BUFFER ; Find length of string by MOVAL BUFFER,R0 ; looking for space. SUBL3 R0,R1,LEN ; Subtract addresses to get MOVL LEN,BUFFER_D ; length. Update descriptor. MOVC3 LEN,BUFFER,TEMP_BUFFER ; Move string into temporary ; buffer for modification. ; ; In order to determine the correct UIC for all the files to be changed ; the top directory specified in the input must be located and its ; parent's UIC retrieved. The directory specification located in the ; NAM block will contain the name of the topmost directory. This is ; converted into a "dirname.DIR" and used in another call to $PARSE ; to open the file. ; ; Examples of the conversion are: ; ; [TOP.SECOND.THIRD] ; ; to ; ; [TOP.SECOND]THIRD.DIR ; ; or ; ; [TOP] ; ; to ; ; TOP.DIR ; FIND_NUL: MATCHC #2,NUL_DIR,LEN,TEMP_BUFFER ; Locate "[]" CMPL R0,#0 ; BNEQ FIND_.. ; Not found MOVC3 R2,(R3),TEMP_BUFFER ; Found. Shift left rest of ; buffer to location of "[]". ADDL3 #70,TEMP_BUFFER_AD,R0 ; Compute remaining length of ; string. SUBL2 R3,R0 ; MOVC5 #1,#^X20,#^X20,R0,(R3) ; Padd remaining length of ; string with spaces. SUBL2 #2,LEN ; Adjust length of string by 2. JSB GET_DIR ; Get default directory. FIND_..: MATCHC #2,DOT_DOT,LEN,TEMP_BUFFER ; Locate ".." . CMPL R0,#0 ; Found ... Extract. BEQL 2$ ; MATCHC #2,DOT_BR,LEN,TEMP_BUFFER ; Locate ".]" . CMPL R0,#0 ; Found ... Extract. BEQL 2$ ; JMP FIND_L_BR_. ; Not found ... Continue. 2$: SUBL3 #2,R3,START_AD ; Subtract 2 from last byte ; found. Move result into ; starting address of move. MATCHC #1,#^X5D,LEN,TEMP_BUFFER ; Locate "]" in string. INCL R2 ; Increment number of bytes ; remaining. DECL R3 ; Decrement address one past ; match. MOVC3 R2,(R3),@START_AD ; Move bytes in string from "]" ; on to starting address ; START_AD. ADDL3 #70,TEMP_BUFFER_AD,R0 ; Compute remainging length of ; string buffer. SUBL2 R3,R0 ; MOVC5 #1,#^X20,#^X20,R0,(R3) ; Padd the string buffer with JMP FIND_NUL ; spaces. To be safe, look ; again at string for another ; occurance. FIND_L_BR_.: MATCHC #2,SUB_DIR,LEN,TEMP_BUFFER ; Locate "[.". CMPL R0,#0 ; Not found.. BNEQ FIND_L_BR ; SUBL3 #2,R3,START_AD ; Subtract 2 from length, put ; resulting address into ; "START_AD". JSB GET_DEV ; Get default device. JSB MOD_DEF ; Get current default directory FIND_L_BR: LOCC #^X5B,LEN,TEMP_BUFFER ; Is a directory specified ? CMPL R0,#0 ; Yes ... Continue. BNEQ 2$ ; LOCC #^X3A,LEN,TEMP_BUFFER ; User may have specified a ; logical name for the device ; and directory. Check for a ; ":". If found jump to ; FIND_DEV. ; i.e. ; UTCLIB_TOOLS:LOGIN.COM ; || ; VV ; SYS$SYSDEVICE:[UTCLIB.TOOLS]LOGIN.COM CMPL R0,#0 ; Was the ":" found ? BEQL 1$ ; No. JMP FIND_DEV ; Yes. 1$: JSB GET_DIR ; No directory specified. Get ; current default directory. 2$: MOVL R1,START_AD ; Update starting address.. ; i.e. address of "[". FIND_R_BR: LOCC #^X5D,LEN,TEMP_BUFFER ; Locate "]". CMPL R0,#0 ; Found ... Continue. BNEQ FIND_DEV ; JMP ERROR ; String contained a "[" but ; no "]". Display error and ; exit. FIND_DEV: ; Prepare to expand the device ; logical name to a physical ; device. LOCC #^X3A,#70,TEMP_BUFFER ; Locate the ":". CMPL R0,#0 ; None found ... Use SYS$DISK. BEQL 1$ DECL R0 ; Found ... Decrement number ; of bytes remaining in string ; so to not include the ":". SUBL3 R0,#70,DISK_BUF_D ; Set up descriptor. PUSHR #^M ; Save it before MOVC3 instr. MOVC3 DISK_BUF_D,TEMP_BUFFER,DISK_BUF ; Move the string into buffer ; for conversion. POPR #^M ; Reset R0. MOVC5 R0,(R1),#^X20,#70,TEMP_BUFFER ; Shift orginal string left to ; erase device string. SUBL2 DISK_BUF_D,LEN ; Adjust length of string. SUBL2 #1,DISK_BUF_D ; Adjust device buffer ; descriptor to exclude ":". JSB TRN_DISK ; Translate the device string. JMP 2$ 1$: MOVZBL SYS$DISK,DISK_BUF_D ; No device name found in ; string. Set up descriptor. MOVAL SYS$DISK+1,DISK_BUF_D+4 ; JSB TRN_DISK ; Translate the device string. 2$: LOCC #^X5B,LEN,TEMP_BUFFER ; Adjust "START_AD" to point ; to "[". MOVL R1,START_AD ; LOCC #^X5D,LEN,TEMP_BUFFER ; Adjust "END_AD" to point MOVL R1,END_AD ; to "]". ; ; ; At this point the program should have a full and correct device and ; directory specification. The name of the parent directory of the ; last directory specified is needed to extract the UIC. The buffer ; is parsed for "." until the second to last occurance is used as ; the parent. ; ; Example: ; ; [dir.one.two] ==> [dir]one.DIR ; ^ ^ ; This file contains the UIC value to be put into all files ; specified by the user. ; ; If no subdirectories are found, take the default directory. ; ; Example: ; ; [dir] Is translated into dir.DIR. ; ; Both of the above examples are combined with either the default or ; specified device and used by LIB$FIND_FILE to obtain a full file ; specifcation. ; ; PARSE: MOVL R1,END_AD ; Update "END_AD". ; i.e. address of "]". INCL START_AD ; Compute lenght of string SUBL3 START_AD,END_AD,LEN ; between "[" and "]". 2$: LOCC #^X2E,LEN,@START_AD ; Locate a "." between "[" and ; "]". CMPL R0,#0 ; Was it found ? BNEQ 4$ ; Yes. JMP 7$ ; No ... All done. 4$: MOVL START_AD,TEMP ; Save current valude of ; "START_AD". ADDL3 #1,R1,START_AD ; Adjust "START_AD" to 1 byte ; past location of ".". SUBL3 START_AD,END_AD,LEN ; Adjust "LEN" between "[" and ; "]". LOCC #^X2E,LEN,@START_AD ; Locate ".". CMPL R0,#0 ; Found ? BNEQ 4$ ; Yes ... Continue loop. 6$: MOVL START_AD,END_AD ; New location of "]". MOVL TEMP,START_AD ; Saved value of "START_AD". SUBL3 START_AD,END_AD,LEN ; Compute new length, DECL LEN ; minus 1. 7$: MOVL #70,LEN ; No "." found . Reset "LEN" ; to 70. JSB COMP_DEF JMP DONE_CONV ; ; All conversions are done on the temporary buffer. Use LIB$FIND_FILE ; to obtain the full file specification. This file specification is in ; turn used by $OPEN to get the FID and DID associated with the file. ; Finally, using the FID and DID, get the UIC of this directory. This ; value will be inserted into all files specified by the user. ; ; DONE_CONV: CLRL CONTEXT ; Clear context value PUSHAL CONTEXT ; Push arguments onto stack. PUSHAL TEMP_BUFFER_D ; Result buffer. PUSHAL CONV_NAME_D ; Orginal buffer. CALLS #3,G^LIB$FIND_FILE MOVAL TEMP_BUFFER,INFAB+FAB$L_FNA ; Move address of converted ; file name buffer into FAB. MOVB TEMP_BUFFER_D,INFAB+FAB$B_FNS ; Move length of buffer into ; FAB. $OPEN FAB=INFAB ; Open the directory file to $CLOSE FAB=INFAB ; obtain the FID and DID and ; immediately close it. MOVL NAM_BLOCK+NAM$W_FID,FIB+FIB$W_FID ; Load FIB with FID MOVW NAM_BLOCK+NAM$W_FID+4,FIB+FIB$W_FID+4 ; MOVL NAM_BLOCK+NAM$W_DID,FIB+FIB$W_DID ; Load FIB with DID MOVW NAM_BLOCK+NAM$W_DID+4,FIB+FIB$W_DID+4 ; MOVL #FIB$M_NOLOCK,FIB+FIB$L_ACCTL ; Override lockout by another ; image. MOVW #FIB$M_FINDFID,FIB+FIB$W_NMCTL ; Find file by FID. ASSIGN: MOVZBL NAM_BLOCK+NAM$T_DVI,DEVICE_D ; Assign channel to device. $ASSIGN_S DEVNAM=DEVICE_D,CHAN=FILE_CHAN MOVAL REC_ATR,R6 ; Record attributes buffer. ; ; Access the file and get the record attributes ; $QIOW_S CHAN=FILE_CHAN,FUNC=#IO$_ACCESS!IO$M_ACCESS, - IOSB=IOS_STAT,P1=FIB_D,P5=R6 MOVL FILE_UIC,OWNER_UIC ; Move UIC value. This value ; will be inserted into all ; files specified by user. ; ; Deaccess this file. ; $QIOW_S CHAN=FILE_CHAN,FUNC=#IO$_DEACCESS,P1=FIB_D CLRW FIB+FIB$W_NMCTL ; Clear name contol area before MOVW #FIB$M_WILD,FIB+FIB$W_NMCTL ; inserting wildcard modifier. MOVAL TEMP_BUFFER,INFAB+FAB$L_FNA ; Update FAB with filename MOVB TEMP_BUFFER_D,INFAB+FAB$B_FNS ; returned by LIB$FIND_FILE. ; ; This section locates the next file for changes in the UIC. ; LOCATE: MOVL #FIB$M_WRITE!FIB$M_WRITETHRU,FIB+FIB$L_ACCTL ; Write access.. Write file header ; back to disk. MOVL #70,TEMP_BUFFER_D ; ; Find next file. ; PUSHAL CONTEXT ; Push arguments onto list. PUSHAL TEMP_BUFFER_D ; Result string. PUSHAL BUFFER_D ; Source string. CALLS #3,G^LIB$FIND_FILE CMPL R0,#RMS$_NORMAL ; Is files found. BEQL 2$ ; Another file ... continue. CMPL R0,#RMS$_NMF ; If the last file has already BNEQ 1$ ; been processed, exit without ; displaying a message. $EXIT_S 1$: $EXIT_S R0 ; Exit and display error. 2$: $PARSE FAB=INFAB ; Parse the file for the DID. MOVL NAM_BLOCK+NAM$W_DID,FIB+FIB$W_DID ; Move the DID MOVW NAM_BLOCK+NAM$W_DID+4,FIB+FIB$W_DID+4 ; into the FIB. MOVAL TEMP_BUFFER,TEMP ; Locate the filename returned ; in the NAM block. This ; filename is used by the QIOW ; to locate the file. LOCC #^X5D,#70,@TEMP ; Find the "]" in the filename. CMPL R0,#0 ; Found it ... Continue. BNEQ 3$ ; JMP ERROR ; An error has occured. 3$: ADDL3 #1,R1,TEMP ; 1 past "]". LOCC #^X20,#70,TEMP_BUFFER ; Locate the space after the ; filename. Subtract the SUBL3 TEMP_BUFFER_AD,R1,TEMP_BUFFER_D ; address of "]" from " " for SUBL3 TEMP,R1,FILE_D ; the length. Update ; descriptors. MOVL TEMP,FILE_D+4 ; Update the address of the ; "FILE_D" descriptor variable ; to the location of the ; filename within the NAM block CLRL FIB+FIB$W_FID ; Clear the FID within the CLRW FIB+FIB$W_FID+4 ; FIB. MOVAL FILE_D,R7 ; Move address into parameters. MOVAL REC_ATR,R6 ; ; ; Read the file. ; READ: $QIOW_S CHAN=FILE_CHAN,FUNC=#IO$_ACCESS!IO$M_ACCESS, - IOSB=IOS_STAT,P1=FIB_D,P2=R7,P5=R6 CMPL IOS_STAT,#SS$_NOPRIV ; Is file set against system BNEQ CHECK_TOP_DIR ; access ? If so, display error $FAO_S CTRSTR=NOPRIV_STR,OUTLEN=CONF_LEN,OUTBUF=OUT_STR_D, - P1=TEMP_BUFFER_D,P2=#TEMP_BUFFER $BRDCST_S MSGBUF=OUT_STR_D,DEVNAM=INPUT ; Broadcast message to terminal ; ; ; Check first word of DID and FID. To keep user's from the top levels ; of the directories, check the value against 4. If the DID is 4, ; the user's default is one under [000000]. If the FID is 4, the ; user's default is [000000]. Give a error status and exit ; IT IS ASSUMED THAT THE DIRECTORY [000000] HAS A FID OF 4 BY DEFAULT. ; THIS IS TRUE ON ALL THREE OF OUR SYSTEMS. IF NOT, CHANGE THE VALUE ; OF 4 TO nn ON BOTH INSTRUCTIONS. ; ; CHECK_TOP_DIR: CMPW NAM_BLOCK+NAM$W_DID,#4 ; Is first word of DID 4 ? BNEQ 1$ ; No ... Continue JMP 2$ ; Yes ... Display error. 1$: CMPW NAM_BLOCK+NAM$W_FID,#4 ; Is first word of FID 4 ? BNEQ 3$ ; No ... Continue 2$: $FAO_S CTRSTR=SYSPRV_STR,OUTLEN=CONF_LEN,OUTBUF=OUT_STR_D $BRDCST_S MSGBUF=OUT_STR_D,DEVNAM=INPUT ; Broadcast message to terminal JMP DEACCESS ; Deaccess file without moving ; new UIC into "FILE_UIC". 3$: CMPB CONFIRM_B,#1 ; Is the CONFIRM byte set. BEQL 4$ ; Yes. JMP NO_CONF ; No ; ; Construct string to display to user. ; 4$: $FAO_S CTRSTR=CONFIRM_STR,OUTLEN=CONF_LEN,OUTBUF=OUT_STR_D, - P1=TEMP_BUFFER_D,P2=#TEMP_BUFFER MOVZWL CONF_LEN,TEMP ; Adjust output descriptor. ; ; Display the prompt using a QIOW readprompt. ; $QIOW_S CHAN=USER_CHAN,FUNC=#IO$_READPROMPT,IOSB=IOS_STAT, - P1=RESP,P2=#1,P5=#OUT_STR,P6=TEMP CMPB RESP,#^X4E ; Compare response with "N". BNEQ NO_CONF ; JMP NO_LOG ; Don't change it. NO_CONF: MOVL OWNER_UIC,FILE_UIC ; Confirmed. Move new UIC ; value into "FILE_UIC". ; ; Deaccess this file. ; CLRW FIB+FIB$W_NMCTL ; Clear name contol area. MOVAL DE_REC_ATR,R6 DEACCESS: $QIOW_S CHAN=FILE_CHAN,FUNC=#IO$_DEACCESS,IOSB=IOS_STAT, - P1=FIB_D,P5=R6 MOVW #FIB$M_WILD,FIB+FIB$W_NMCTL ; Insert wildcard modifier. CMPB LOG_B,#1 ; Is "LOG" byte set. BNEQ NO_LOG ; NO. ; ; Construct output string. ; $FAO_S CTRSTR=CONF_STR,OUTLEN=CONF_LEN,OUTBUF=OUT_STR_D, - P1=TEMP_BUFFER_D,P2=#TEMP_BUFFER MOVZWL CONF_LEN,OUT_STR_D ; Update output descriptor. $BRDCST_S MSGBUF=OUT_STR_D,DEVNAM=INPUT ; Broadcast message to terminal NO_LOG: JMP LOCATE ; Look for next file. ERROR: $FAO_S CTRSTR=FILE_ERROR,OUTLEN=ERROR_LEN, - OUTBUF=ERROR_BUF_D,P1=#FILE_D $QIOW_S CHAN=USER_CHAN,FUNC=#IO$_WRITEVBLK,IOSB=IOS_STAT, - P1=ERROR_BUF,P2=ERROR_LEN $DASSGN_S CHAN=USER_CHAN $EXIT_S R0 ; ; This section inserts the string ".DIR" and "]" in the buffer. ; ; Example : ; ; BEFORE: DRnn:[def] AFTER: DRnn:[000000]def.DIR ; ; or ; ; BEFORE: DRnn:[def.one.two] AFTER: DRnn:[SYS0.def.one]two.DIR ; ; Please note that the logical device name might translate to something ; other than the top directory "[000000]" as in the second case. ; COMP_DEF: LOCC #^X5D,LEN,TEMP_BUFFER ; Locate the "]" . This is ; where the ".DIR" will be ; placed. MOVAL TEMP_BUFFER,TEMP ; Compute the length of the ADDL3 #70,TEMP,R0 ; remainder of the buffer for ; blank padding. SUBL3 R1,R0,DIFF ; MOVC5 #4,DIR_EXT,#^X20,DIFF,(R1) ; Move ".DIR" in the buffer and ; padd the rest of the buffer ; with spaces. SUBL3 TEMP,R3,LEN ; Adjust length of string. ; DECL END_AD ; minus 1, MOVB #^X5D,@END_AD ; and insert a "]". MOVC3 LEN,TEMP_BUFFER,CONV_NAME ; Move completed string into ; conversion buffer for ; function LIB$FIND_FILE. RSB ; and return. ; ; This section inserts the default directory if it is not already ; included. ; MOD_DEF: PUSHAL CONV_NAME_D ; Push arguments onto stack. PUSHAL CONTEXT ; Length of returned string. PUSHL #0 ; Default requested. CALLS #3,SYS$SETDDIR ; Get default directory. MOVZWL CONTEXT,DIFF ; Move length into longword. SUBL3 #2,DIFF,R0 ; Adjust length to not include ; "[" or "]". ADDL2 START_AD,R0 ; Address to move string over ; to make room for default ; string spec. MOVC3 LEN,@START_AD,(R0) ; Move existing string right ; starting at "START_AD" to ; "R0". SUBL2 #1,DIFF ; Now insert default string not MOVC3 DIFF,CONV_NAME,@START_AD ; including "[". ADDL2 DIFF,LEN ; Adjust length. RSB ; Return. ; ; This subroutine inserts the default device name into the temporary ; buffer "TEMP_BUFFER". This device will be translated down to a ; physical device later. ; GET_DEV: $TRNLOG_S LOGNAM=SYS$DISK,RSLLEN=TRN_LEN,RSLBUF=TRN_BUF_D MOVZWL TRN_LEN,DIFF ; Move translated word lenght ; into longword. ; Compute the address to shift ; right the string for ADDL3 TEMP_BUFFER_AD,DIFF,TEMP ; inserting the device. MOVC3 LEN,TEMP_BUFFER,@TEMP ; Move orginal string right. MOVC3 DIFF,TRN_BUF,TEMP_BUFFER ; Move in device string. MOVL R3,START_AD ; Adjust "START_AD". ADDL2 DIFF,LEN ; Adjust the length variable ; "LEN". RSB ; Return. ; ; This section is used when no directory specification is given. ; GET_DIR: JSB GET_DEV PUSHAL CONV_NAME_D ; Push arguments onto stack. PUSHAL CONTEXT ; Length of result string. PUSHL #0 ; CALLS #3,SYS$SETDDIR ; Get default directory. MOVZWL CONTEXT,DIFF ; Move length into longword. ADDL3 DIFF,START_AD,R0 ; Move the contents of the ; temporary buffer to the right MOVC3 LEN,@START_AD,(R0) ; to make room for the ; specification. MOVC3 DIFF,CONV_NAME,@START_AD ; Now include the directory ; specification. ADDL2 DIFF,LEN ; Adjust the length of the ; string. MOVL START_AD,R1 ; RSB ; Return. ; ; This subroutine translates the device string included in the ; temporary buffer "TEMP_BUFFER" down to a physical device. This ; is done to give an exact device and directory specification when ; used by LIB$FIND_FILE. ; ; It is possible that the device name will translate to a device and ; directory i.e. SYS$SYSROOT: ==> DRA0:[SYS0.] . If this is true, insert ; this string MINUS the "]" to the beginning of the buffer "TEMP_BUFFER". ; ; Otherwise, the translation should give a disk i.e. DRA0: . Insert this ; at the beginning of the buffer PLUS "[000000." giving : ; ; DRA0:[000000.def.one] ; ; TRN_DISK: $TRNLOG_S LOGNAM=DISK_BUF_D,RSLLEN=TRN_LEN,RSLBUF=TRN_BUF_D CMPL R0,#SS$_NOTRAN ; Translation done. BEQL 1$ ; Continue. MOVZWL TRN_LEN,DISK_BUF_D ; Save length of device ; translation. MOVC5 DISK_BUF_D,TRN_BUF,#^X20, - ; Move translation into buffer. #30,DISK_BUF DECL DISK_BUF_D ; Subtract 1 from length so ; to not include ":". MOVAL DISK_BUF,DISK_BUF_D+4 ; Set descriptor. JMP TRN_DISK ; Translate again until ; physical device is found. 1$: LOCC #^X5B,#30,DISK_BUF ; Locate "[". CMPL R0,#0 ; Not found ... Continue. BEQL 4$ MATCHC #2,DOT_BR,#30,DISK_BUF ; If translated device contains ; ".]" , adjust length to ; exclude "]" and insert as ; part of the directory ; specification. CMPL R0,#0 ; Was the string found ? BEQL 2$ ; Yes. INCL DISK_BUF_D ; Add 1 to variable to offset ; decrement instruction above. ADDL3 #1,DISK_BUF_D,DIFF ; No. Set variable for JMP 3$ ; computation and continue. 2$: SUBL3 #1,DISK_BUF_D,DIFF ; Subtract 1 from length to ; exclude "]". 3$: ADDL3 TEMP_BUFFER_AD,DIFF,R1 ; Compute address for shifting ; existing string right. MOVC3 LEN,TEMP_BUFFER,(R1) ; Shift string right. MOVC3 DISK_BUF_D,DISK_BUF,TEMP_BUFFER ; Insert translated device. JMP 5$ 4$: INCL DISK_BUF_D ; A directory specification was ; not found. Add 1 to length. ADDL3 #8,DISK_BUF_D,DIFF ; Plus 8 for "[000000.". ADDL3 TEMP_BUFFER_AD,DIFF,R1 ; Compute the address to shift ; contents right for device ; string. DECL R1 ; Don't move the "[" ; in "TEMP_BUFFER", so ; subtract 1 from ; destination address. MOVC3 LEN,TEMP_BUFFER,(R1) ; Move orginal contents ; of "TEMP_BUFFER" ; right. MOVC3 DISK_BUF_D,DISK_BUF,TEMP_BUFFER ; Insert the device string. MOVC3 #8,SEARCH,(R3) ; Insert "[000000.". 5$: ADDL2 DIFF,LEN ; Compute the new length of the ; string. RSB ; And return. .END OWN