Copyright 1987-2016 by Kevin G. Barkes All rights reserved. This article may be duplicated or redistributed provided no alterations of any kind are made to this file. This edition of DCL Dialogue is sponsored by Networking Dynamics, developers and marketers of productivity software for OpenVMS systems. Contact our website www.networkingdynamics.com to download free demos of our software and see how you will save time, money and raise productivity! Be sure to mention DCL Dialogue! DCL DIALOGUE Originally published December, 1987 "DCL STOCKING STUFFERS" By Kevin G. Barkes 'Tis the season for sharing, so this month I thought I'd pass along a few tiny command procedures as "stocking stuffers". To call these DCL files utilities would be somewhat presumptuous... one of my clients refers to them as "uties" (pronounced ooties). "They're not precisely full-blown utilities, but they're not entirely disposable, either," reports my friend, who frequently calls me on the phone and asks "Can you write me something to - (fill in the blank)." The simplest of the three is RAD.COM, (Program 1) which displays the decimal, octal, and hexadecimal radices of the supplied integer. It's great for doing those quick conversions on Monday morning before the caffeine has kicked in. Assign the symbol RAD to @device:[directory]rad.com and simply enter $ RAD (integer) The procedure assumes the supplied number is decimal; you can supply hex or octal values by preceding the integer with %x and %o, respectively: $ RAD %x10 (hexadecimal 10) $ RAD %o10 (octal 10) All the procedure does is assign the number to the symbol DECIMAL, then displays the symbol. DECIMAL was chosen as the symbol name simply to make the display consistent. Utie number 2 is ZAPZERO.COM, a procedure which deletes empty files in the user's current default directory. You'll want to modify the symbol NODEL to contain the extensions of zero-length files which you don't want to obliterate. The sample procedure saves from destruction files with file types .DIR (directories), .CTL (in this instance, a site-specific file which must exist), and files with null extensions. Notice the null type is entered as ". " (a period with three trailing spaces). This is done so the procedure can accurately parse through the no-delete listing. To invoke the procedure, just enter @ZAPZERO. You're asked if you want to confirm deletions before they're performed; by default, the DELETE command will prompt for permission before blowing away the file. The F$SEARCH lexical function is used to return the file names; F$PARSE extracts the file type. Note the padding of the null type we mentioned earlier. ZAPZERO first checks that the file type isn't on our "no delete" list. If it is, the procedure loops and gets the next file name. Otherwise, the F$FILE_ATTRIBUTES lexical is used to return the file size; zero- length files are then deleted. HOG.COM (Program 3) is one of those utilities that really isn't needed; a SHOW/DEVICE/FULL (device) will return, among other things, the name of the process currently "hogging" a device. A client who works at 300 baud from a terminal in his home hated waiting for the entire display to appear, and asked me to whip together something that would show what he needed with a minimum of screen i/o. The procedure is essentially self-explanatory, except for the use of the NSYM symbol. This is one method of reducing the number of lines of code required by the lack of an ELSE statement in DCL. NSYM is toggled between a null string and the text "NOT ", and is used within WRITE statements to identify the various device conditions reported. It's not exactly pretty, but it is an effective workaround for the missing ELSE construct. These "uties" have two things in common; brevity and minimal error checking. They can serve as the core of more elaborate utilities, or can be used as-is for quick and dirty functions. And they're the perfect gifts for those hard-to-shop-for DCL hackers. ------- VAX BIAS - Rev. Ronald E. Wozniak of Boston College High School wrote in to raise a point that I've totally missed... VAX/VMS is not the sole domain of Digital Command Language. "..it would be an added service, much appreciated by RSTS/E users on PDP-11s, if articles giving programs... would indicate whether or not these programs will work on the PDP-11," he notes. "If 'yes' with alterations, could those be listed?" Rev. Wozniak isn't the first to point out that the 11 has its own flavor of DCL. Unfortunately, this column is for and about VAX/VMS DCL; I know nada about the RSTS variety. Are there any VMS-RSTS conversion experts out there? ------- PROGRAM 1 ! RAD.COM ! Displays the radices of the supplied number $ DECIMAL = F$INTEGER(P1) $ SHOW SYM DECIMAL $ EXIT ------- PROGRAM 2 ! ZAPZERO.COM ! $ SET NOON $ SAY := WRITE SYS$OUTPUT ! ! NODEL contains the extension of files you don't ! want deleted... $ NODEL = ".DIR.CTL. " $ NODELSIZE = F$LENGTH(NODEL) $ SAY "ZAPZERO..." $ SAY "Your current default is ",F$ENV("DEFAULT") $ QUALIFIER = "/NOCONFIRM" $ INQUIRE/NOPUNC ANS - "Do you want to confirm deletions (CR = yes)? " $ IF ANS .OR. ANS .EQS. "" - THEN QUALIFIER = "/CONFIRM" $ DEL_LOOP: $ DELFILE = F$SEARCH("*.*;*") $ IF DELFILE .EQS. "" THEN EXIT $ EXT = F$PARSE(DELFILE,,,"TYPE") $ IF EXT .EQS. "." THEN EXT = ". " $ IF NODELSIZE .NE. F$LOCATE(EXT,NODEL) - THEN GOTO DEL_LOOP $ IF F$FILE(DELFILE,"EOF") .EQS. "0" THEN - DELETE/LOG 'QUALIFIER' 'DELFILE' $ GOTO DEL_LOOP $ EXIT --------- PROGRAM 3 ! HOG.COM ! Identifies user hogging a device ! $ ON WARNING THEN GOTO NODEVICE $ NSYM = "NOT " $ IF P1 .EQS. "" THEN GOTO NODEVICE $ IF .NOT. F$GETDVI(P1,"ALL") THEN GOTO NOTALL $ WRITE SYS$OUTPUT F$GETJPI(F$GETDVI(P1,"PID"),"PRCNAM"), - " is hogging ",P1 $ GOTO CHECKREST ! $ NOTALL: $ WRITE SYS$OUTPUT P1," is not allocated." ! $ CHECKREST: $ IF F$GETDVI(P1,"MNT") THEN NSYM = "" $ WRITE SYS$OUTPUT P1," is ''NSYM'mounted." $ IF .NOT. F$GETDVI(P1,"AVL") THEN NSYM = "NOT " $ WRITE SYS$OUTPUT P1," is ''NSYM'available." $ IF F$GETDVI(P1,"SHR") THEN NSYM = "" $ WRITE SYS$OUTPUT P1," is ''NSYM'shareable." $ EXIT ! $ NODEVICE: $ WRITE SYS$OUTPUT "Inaccessible or invalid device name." $ EXIT **** $ Verify = F$Verify(0) $! $ Define_Variables: $! ++ Variables needed for screen display. $ Esc[0,8] = %x1B $ W = "Write Sys$Output" $ Default = F$Environment("DEFAULT") $! $ Ask_Input: $! Ask user for input and see if the user- $! specified directory exists. $ Inquire Root_Directory "Root Directory ''Default' " $ If Root_Directory .Eqs. "" Then Root_Directory = Default $ Parse_Root = F$Parse(Root_Directory + "*.*;*") $ If F$Search(Parse_Root) .Eqs. "" Then Goto Error $ FileSpec = Root_Directory + "*.DIR" $! $ Declare_DRAW_Variables: $! Declare variables needed to draw a box onto the screen. $! $ Level = 1 $ Indent = "" $ Length = F$Length(Root_Directory) + 2 $ Division = Length / 2 $ Chars = F$Fao("!''Length'*q") $! $ Draw: $! Using the variables defined above, draw the box. $! $ W Esc,"[H",Esc,"[2J" $ W Esc,"(0","1",Chars,"k" $ W "x ",Root_Directory," x" $ W Esc,"(0m",Chars,"j" $ W Esc,"[4;''Division'Hw",Esc,"(B" $ Tree_Symbol = "''Esc'(0t''Esc'(B" $ Indent = Indent + " " $ Division = Division - 1 $ Division = F$Fao("!''Division'* ") $! $ Start: $! Extract each DIRECTORY-SPEC from the user-specified $! directory and display it on the screen. Then check to $! see if the DIRECTORY-SPEC has subdirectories; if it $! does, then branch to EXTRACT or else goto CHECK and $! extract the above directories. $! $ Search_For_Dir = F$Search(FileSpec,Level) $ If Search_For_Dir .Eqs. "" Then Goto Check $ Spec_Parsed_'Level' = F$Parse(Search_For_Dir,,,"NAME") $ Length = F$Length(Spec_Parsed_'Level') $ Spec_Parsed_'Level'[1,'Length'] := "''F$Edit(F$Extract(1,Length,- Spec_Parsed_'Level'),"LOWERCASE")'" $ W Division,Tree_Symbol,Indent,Spec_Parsed_'Level' $ Goto Extract $! $ Check: $! Extract each above directory (POP up a level). $ If Level .Eq. 1 Then Goto Exit $ Level = Level - 1 $ Sub_Directory = "." + Spec_Parsed_'Level' $ FileSpec = FileSpec - Sub_Directory - "]*.DIR" + "]" + "*.DIR" $ Indent = Indent - " " $ Goto Start $! $ Extract: $! Extract each subdirectory (PUSH down a level) $ Sub_Directory = "." + Spec_Parsed_'Level' $ FileSpec = FileSpec - "]*.DIR" + Sub_Directory + "]" + "*.DIR" $ Level = Level + 1 $ Indent = Indent + " " $ Goto Start $! $ Error: $! There is an error in processing user-specified directory. $ W "Error parsing directory ",Root_Directory,"." $ Exit: $ If Verify Then Set Verify $ Exit $! $! Author: Shishir Gundavaram $! 280 Elm Street #12 $! Marlboro, MA 01752 $! $ TREE :== @Disk:[Directory]DIRECTORY_TREE.COM $! $ TREE/OUTPUT=filename disk:[directory] ---------- Kevin G. Barkes is an independent consultant. He publishes the KGB Report newsletter, operates the www.kgbreport.com website, lurks on comp.os.vms, and can be reached at kgbarkes@gmail.com.