VAXman's Musings Soapbox » VAXman's Musings SoapboxFact, Friction, Faff and Folderol …2024-03-19T07:02:41-04:00VAXmanhttp://tmesis.org/VAXman@tmesis.orgtag:vaxmans-musings-soapbox,2024:vaxmans-musings-soapboxPivotXCopyright (c) 2024, Authors of VAXman's Musings SoapboxRocketry Video utilizing a Strap-on Camera Mount2017-06-12T13:57:00-04:002015-10-15T14:05:00-04:00tag:vaxmans-musings-soapbox,2024:vaxmans-musings-soapbox.49Amateur rocketry is great fun! 5-4-3-2-1 Launch! The motor ignites, the rocket accelerates upward toward the sky and it's soon well out of sight hundreds, if not thousands, of feet into the air. For a great many rocketry enthusiasts, this would be enough; however, I soon found myself pining to see what I could not — the view from the rocket's point of view. I found numerous on-board rocketry videos on YouTube made by other amateur rocketeers which prompted me to want to try my hand at doing the same. If you too should have an interest in video documentation of your own amateur rocket's flights, read on.5-4-3-2-1 Launch! The motor ignites, the rocket accelerates upward toward the sky and it's soon well out of sight hundreds, if not thousands, of feet into the air. For a great many rocketry enthusiasts, this would be enough; however, I soon found myself pining to see what I could not — the view from the rocket's point of view. I found numerous on-board rocketry videos on YouTube made by other amateur rocketeers which prompted me to want to try my hand at doing the same. If you too should have an interest in video documentation of your own amateur rocket's flights, read on.
The first thing, obviously, is that you will need an appropriate camera. My criteria were: Small, so that it could be mounted inside or affixed to the outside of a rocket without drastically affecting the stability of the rocket; Lightweight, so that it didn't dramatically affect the overall flight performance of a rocket; Relatively inexpensive, so that if there was a CATO or if the rocket should lawn dart taking out the camera, there wouldn't be a great monetary loss. Any camera I'd purchase would, of course, also need to also be Mac OSX or Linux compatible. I searched around for small, lightweight, and inexpensive digital video gear for some time. After searching the internet for several possible options, I came across what appeared to be a suitable item on eBay. It was described as a Mini USB spy camera and its price was only $9.99. It seemed it was worth giving it a try for a meager $10 plus its shipping charge from China.
When the camera arrived, I made a few test videos with it — not rocket videos — to check out its video quality. For $0, the video quality was quite impressive.
For my inaugural rocket video, I my plan was to attach this camera on-board my Estes Nike Smoke which can be launched on F and G class APCP propellant motors. This rocket stands close to 4 feet tall and it has a three (3) inch diameter airframe. I could have followed the lead of other video rocketeers by simply taping the camera to the rocket's airframe but I didn't want to ruin my rocket's finish; especially, after having spent countless hours sanding, painting, clear-coating and polishing it to achieve its mirror gloss finish. I decided that I'd fashion some sort of removable strap mount to hold the camera to the rocket; thus, allowing the camera to be easily attached and detached. I possess a large roll of 1.5 inch wide adhesive backed Velcro which came to mind immediately for use as a possible solution. However, I needed the adhesive backing only for affixing the Velcro to the camera. What I now needed was a band of Velcro that could wrap around the rocket's airframe. I set out to locate an already fabricated Velcro strap.
An internet search quickly landed a couple of possible leads for a suitable Velcro strap. One of the possible sources was, of all places, Walmart. I almost never frequent the local Walmart but, because I wanted to get this project completed, I made an exception. There, I found a package with two, 36 inch long, Velcrocinch straps. 3 feet was much longer than I needed but I figured I could fashion a shorter, more suitable, strap from these two longer straps.
Because the Estes Nike Smoke airframe is three (3) inches in diameter, I would need about 9.5 (3" • Π ≈ 9.5") inches of strap to encircle its airframe. I added an additional 6 inches to fold back over the camera and for Velcro adhesion, and one inch to wrap around the plastic loop buckle. I cut the length needed from the tapered end of the strap and cut the rest of the strap free from the plastic loop buckle. I then fastened the plastic loop buckle to the shortened strap with two-part 5-minute epoxy adhesive. The resultant strap is shown below.
The following two images depict the mounting of the camera using the aforementioned mounting strap. The first image is the strap wrapped around the Estes Nike Smoke with the camera affixed to the strap via adhesive Velcro strips. There is a cap which covers the camera's USB connector. There's a small strip of adhesive Velco on it as well; thus, allowing the cap to be removed but it also insures that the cap is secured when the camera is attached.
The photo below is showing the strap's 6 inch excess pulled back taught over the camera and attached to the Velcro strap itself.
The YouTube video featured below shows the camera being mounted to the Estes Nike Smoke with the fashioned Velcrocinch strap camera mounting strap as well as a full flight video aboard my Estes Nike Smoke. I can also be seen setting up communications with my Jolly LogicAltimeterThree — which I will discuss in another blog — in the video. Enjoy!
Post Scriptum
Attaching a camera to a rocket will affect both its CG (center of gravity) and its CP (center of pressure). To achieve a stable flight, the rocket's CG must be ahead of the rocket's CP. I have not done the aerodynamic mathematics to compute the CP contribution of the camera attached with its Velcro mounting strap but I would conclude that its contribution to the overall CP is relatively minor. However, the camera and its Velcro mounting strap do have mass; therefore, to minimize any affects on flight performance, I'd suggest that it be placed on the rocket forward of its known CG. This will move the overall CG forward maintaining the rocket's overall stability. This is why, in the video, so much of the rocket's airframe is seen. The only other way to address the CP/CG concern would be to add additional weight to the nosecone end of the rocket. I'm seeking to document altitude flights; therefore, the addition of nosecone mass would limit altitude achievement.
]]>VAXmanssh-ecurity — Part 10: Android Paranoid2017-06-12T13:58:00-04:002014-06-25T09:22:00-04:00tag:vaxmans-musings-soapbox,2024:vaxmans-musings-soapbox.48The summer season is here again! The pool is open and the dinner comestibles are a welcome anything I prepare on the grill. This year, to replace aging outdoor speakers, I purchased a Bluetooth sound system for my backyard oasis. The plan was to broadcast to it from iTunes on my MacBook Pro or the IMac in the bedroom, but the distance to either yielded undesired sound quality. So, it was either lug out the MacBook Pro — which I was reluctant to do after a recent costly repair to it due to a spilt coffee — and risk getting it splashed from the pool shenanigans, or invest in something else that I could use for streaming internet radio to the Bluetooth sound system. I finally opted for an Android tablet. A couple of downloaded apps and I was streaming Aural Moon to the Bluetooth system. Now, armed with a new toy, my inner geek was pining for other things that I could do with this tablet. The first thing that came to mind was configuring terminal access into my OpenVMS, Mac and Linux systems; securely, of course!Aural Moon to the Bluetooth system. Now, armed with a new toy, my inner geek was pining for other things that I could do with this tablet. The first thing that came to mind was configuring terminal access into my OpenVMS, Mac and Linux systems; securely, of course!
My first thoughts were to find a terminal app that performed well; especially, one that could do a reasonable VT100 emulation. I went into the Android's app store (called the Play Store) to see what existed for Terminal apps. I selected several. I installed them, tested them, and uninstalled all but one. It did the best, albeit far from perfect by any stretch of the imagination, VT emulation based upon running the VTTEST suite which I have setup on one of my OpenVMS systems as a CAPTIVE account. I then tried typing 'ssh' at the terminal's local command prompt. No such luck. There was no 'ssh' installed by default with Android. So, back to the Play Store to search for an ssh client.
Entering 'ssh' into the Play Store search bar, I was presented with a long list of ssh apps. I read through some of their descriptions, and I installed and uninstalled them one-by-one. None of them gave me a command line 'ssh' command. I then decided that I should look for a version of PuTTY for Android because it contains, at least on other platforms, a GUI based ssh configuration. What I found and tested didn't provide me with an interface I'd be comfortable using. I then opted for the JuiceSSH app. Also GUI, it did appear, after preliminary test, to have terminal performance and emulation that might suit my needs.
After installing it, I was able to ssh into my OpenVMS systems with username and password; however, I'd much rather have and use public and private key authentication. This JuiceSSH app maintains connections in one list and another list is maintained for identity. In the identify list, there are options for generation of public and private key pairs. So, I selected my identity — created when I engaged JuiceSSH to connect via username and password — and clicked the option button to create public and private key pairs. In typical GUI fashion, the button changed it title to Update / Clear; thus, indicating that a key pair existed. Now, how do I get to these keys? After all, the public key has to be deposited on the system(s) to which I wanted to connect. Albeit, it's not intuitive, clicking on the identity in the list will open a popup privinging management functions for the identity. Under this heading was Export Public Key. Selecting this option, yet another popup appeared with options to share the key: Bluetooth, Gmail, Google+ Hangouts, Send Tab To Devices, and Term here. I selected Gmail which allowed me to email the public key to one of my accounts on my OpenVMS systems.
On the OpenVMS system, I opened the email containing the public key. Of course, it was not in a format usable with OpenVMS. For details, read: ssh-security — Look Ma', no passwords! I could have used the OpenVMS editor on this key file to massage it into the format acceptable to OpenVMS but, instead, I passed the key file to my Ubuntu Linux laptop where I could generate the OpenVMS format using ssh-keygen. I still do not understand why the OpenVMS ssh_keygen can not perform this same function. Regardless, once the key was formatted to be acceptable to OpenVMS, I passed it back to the OpenVMS system. I put the key file into the account's [.SSH2] directory and modified the AUTHORIZATION. file to add this new key.
Back on the Android tablet, I clicked on the connection list in JuiceSSH and connected to the OpenVMS system on which I just updated the keys. The connection was successful. The JuiceSSH had even indicated that it used the public and private keys for authentication.
I proceeded to move the tablet's public key to other systems that I might wish to ssh into. I then moved the public key to Eisner, the DECUServe system. However, there, my username is not SYSTEM and the JuiceSSH, because I setup the keys with the SYSTEM identity, wanted to connect with the SYSTEM username. So, I created another identity in JuiceSSH. I could not connect to Eisner with the appropriate username. Now, all I needed to do was pair up this new identity with the private key I'd created for the SYSTEM identity. In the same fashion as I found the Export Public Key" I found an option to export the private key. I clicked on Export Private Key. This gave me all the same sharing options as before; however, I'm leary of putting private keys in the hands of entities I don't trust. In the present case, this would be Google via their Gmail. Sending my private key through Google's email servers meant that somewhere there would be an archive of that key — unless, of course, Lois Lerner and her miscreant rouges of government/IRS conspiratorial cover-up, technology challenged dimwits, are running Gmail. I opted to simply generate a new public and private key pair for the account name associated with my Eisner account. I exported the public key, as before, converted it to the OpenVMS acceptable format, and placed it in the [.SSH2] directory of my account on Eisner.
The next task at hand — getting X11 tunneled over ssh to the X11 server that I installed on the tablet. Perhaps, this will be detailed in the next installment.
]]>VAXmanMOVPSL — I've a feeling we're not in Kansas anymore!2017-06-12T13:59:00-04:002014-06-12T11:43:00-04:00tag:vaxmans-musings-soapbox,2024:vaxmans-musings-soapbox.46Having just completed the latest round of new features for the TMESIS DCL Debugger, it was time to build and test the code on all three OpenVMS Architectures — VAX, Alpha and Itanium. The development of the project had been seeded on the Alpha; thus, that's where it has remained to this day. When a new feature or bug fix has been vetted on the Alpha, the code is then built and checked on OpenVMS VAX and OpenVMS Itanium. Everything newly added was working fine on all three platforms, so it was time to run through some of the regression tests. What this uncovered surprized me. The EDIT functions, which had nothing to do with the newly added functionality, were failing on the Itanium. Never underestimate the need to perform regression testing!TMESIS DCL Debugger, it was time to build and test the code on all three OpenVMS Architectures — VAX, Alpha and Itanium. The development of the project had been seeded on the Alpha; thus, that's where it has remained to this day. When a new feature or bug fix has been vetted on the Alpha, the code is then built and checked on OpenVMS VAX and OpenVMS Itanium. Everything newly added was working fine on all three platforms, so it was time to run through some of the regression tests. What this uncovered surprized me. The EDIT functions, which had nothing to do with the newly added functionality, were failing on the Itanium. Never underestimate the need to perform regression testing!
It was time to have a look-see into what was causing the TMESIS DCL Debugger to process stack dump when any of its EDIT functions were invoked. The TMESIS DCL Debugger uses the OpenVMS callable editors to create and edit its MACROS, as well as to edit the procedure that is being debugged. To allow the user a selectable preference for the OpenVMS editor of his or her choice, the editor is dynamically activated using LIB$FIND_IMAGE_SYMBOL. This was working and working without issue prior to the newly added functionality. Perhaps, there was an edit where I accidentally trampled on one of the routines. However, since the editor is invoked dynamically in three separate routines, I thought this to be a specious conclusion. Differencing the current edit with a prior generation proved that this was not the case. All the code check out the same and all in tact.
What could be causing these, formerly functioning, features to suddenly cause a process stack dump? I reviewed the values in the process stack dump. The TMESIS DCL Debugger was crashing with an ACCVIO (ACCess VIOlation) and its PC (Program Counter) was in the code. I pulled up the latest build .MAP and .LISting files to resolve the PC address. The PC lead me to the entry of an SSI (System Service Intercept) trap routine in my code. One of the routines I'd newly created in the course of adding the new functionality. I scratched my head for a moment while puzzlingly reviewing the routine.
The obvious course of thought was to comment out the code where the SSI$DECLARE_INTERCEPT installed this trap routine. I built and installed the code and, sure as eggs is eggs, the edit functions worked flawlessly. Now, the question was, what is causing this to invoke the process stack dump when the editor is invoked?
The trap was relatively simple. It determined the current mode and, if not USER mode, it would return. If is was USER mode, it rewrote an argument in the argument list for a particular system service. This particular system service wouldn't, couldn't, shouldn't be called in the course of editing a file but I decided to elide the code in the trap just to be sure. I built, installed and tested the code with this trap elided. Again, however, calling up one of the editing functions caused a process stack dump.
I studied this most recent process stack dump carefully. I noticed a system space address in the R16 register. In system service dispatching on Integrity, R16 holds the FD (Function Descriptor) of the system service to be handled by the change mode dispatcher. I pondered as to what service this could be and, perhaps, knowning which service might shed some light on why the code is crashing. I called up the system analyzer (SDA) and had a look-see.
Its address turned out to be for the SWIS (SoftWare Interrupt Services) routine SYS$PAL_RD_PS. But why? I didn't invoke this routine, nor did I use the Macro built-in EVAX_RD_PD. The only thing in my trap routine was a MOVPSL — a VAX instruction primitive. However, this being compiled Macro on Itanium, I had a look at the Itanium machine code in the .LISting. There is was! The Macro compiler on Itanium invokes SYS$PAL_RD_PS to provide the MOVPSL functionality. But why should a MOVPSL cause an access violation? It was time to investigate this phenomenon further.
The first ting I did was to create a small program pared down to the basic functions involved based upon what was in the TMESIS DCL Debugger — callable edit and a system servcie interrupt routine. The code follows. If you are unfamiliar with SSI (System Service Interrupts), I suggest tht you read up on them by following this link:
$OFFDEF SS_TRAP,<-
ARG_PTR,- ; service argument list pointer (quad)
SSV_SYS,- ; service PD/FD (system address space)
SSV_PRC,- ; service PD/FD (process address space)
RET_ADR,- ; return address into SSI trap service
SSI_PTR,- ; address of the original SSI structure
>
.ENTRY SSI.PRE_TRAP,0
.IIF DF,PUKE_MOVPSL, MOVPSL R0 ; will barf
MOVL #1,R0
RET
.END GO
The above code, compiled as-is and linked, will successfully invoke the EDT editor to edit the file TEST.TXT. Remove the comments from the line: ;;;PUKE_MOVPSL = 1
... and compile and link it and the program will process stack dump when it is executed.
So, what's happening here to cause this? The symbol SYS$PAL_RD_PS is, as are all of the system services, define in the image SYS$PUBLIC_VECTORS.EXE. If you've read the article, referenced above, about SSI, you will know that the SSI defines its own vectors to supplant those in SYS$PUBLIC_VECTORS.EXE. Because SYS$PAL_RD_PS is one of those vectors, it too is subject to SSI. So, what is happening is that the MOVPSL in the SSI trap routine is being recursively intercepted! Eventually, the trap routine can not be invoked and there's an access violation.
By now you're probably thinking, as I did, that the MOVPSL should behave like a MOVPSL. I believed this to be the case and files a trouble report with HP. Will it be address? I know not. However, I'm not one to sit about waiting for HP to fix what I believe to be an OpenVMS Macro bug. What I did was devise a workaround for this problem.
First, what I really only needed was to know the current access mode. This can be had by knowing a bit about the Itanium architecture or, at a minimum, its instruction set. I took a look, using the OpenVMS system analyzer, at the actual code of SYS$PAL_RD_PS routine.
The second instruction in the first instruction bundle obtains the current privilege mode from the Itanium's PFS (Previous Function State) register. Because this is all I needed, I first tried replacing the MOVPSL in the system service intercept trap routine with:
$IA64REGDEF ; Itanium special register definitions
$PFSDEF ; previous function state definitions
⋮
IA64_GETREG R0,#IA64_REG$_AR_PFS ; get previous function state
EVAX_SRL R0,#PFS$V_PPL,R0 ; get previous privilege level
CMPL R0,#PSL$C_USER ; insure access mode is USER
This provided me with what I needed for my system servcie interrupt trap. I compiled and linked the TMESIS DCL Debugger with the above workaround and everyting was, once again, functional. However, I was determined to devise a solution which would allow me to actually use the MOVPSL in the intercept just as it was used for the Alpha and VAX code.
The solution was, remarkably, simple. The system service intercept trap routine needed to check if the reason it was being invokes was because it was servicing a call for SYS$PAL_RD_PS. This is accomplished by checking the value passed as the SS_TRAP$_SSV_PRC argument. Comparing this address with that of the SYS$PAL_RD_PSFD address and leaving the system service intercept trap routine if the values compare is the solution. The completely amended code is:
.LIBRARY "SYS$LIBRARY:LIB.MLB"
$SSIDEF ; System Service Intercept DEFinitions
$OFFDEF SS_TRAP,<-
ARG_PTR,- ; service argument list pointer (quad)
SSV_SYS,- ; service PD/FD (system address space)
SSV_PRC,- ; service PD/FD (process address space)
RET_ADR,- ; return address into SSI trap service
SSI_PTR,- ; address of the original SSI structure
>
The above will now be able to use the MOVPSL to get the customary PS and it will allow the use of the PS field definitions in $PSLDEF to extract or test fields of the PS.
While I'm at this, this is not only a problem with the SYS$PAL_RD_PS evoked because of the MOVPSL instruction; this will be a problem if any of the VAX or Alpha buit-ins provided by SWIS are invoked within a system service intercept trap routine. And, this is not just a problem with the Macro compiler. Any high-level language employing a system service intercept via the SSI services will have to contend with this issue if, within the system service intercept trap routine, one of the VAX or Alpha SWIS routines is invoked either directly or via a language specific built-in function.
]]>VAXmanssh-ecurity — Part 9: Confusion will be my Epitaph!2017-06-12T13:59:00-04:002014-05-16T12:57:00-04:00tag:vaxmans-musings-soapbox,2024:vaxmans-musings-soapbox.45I have received myriad accolades for my series of blogs on ssh; especially, because it has covered the inter-operability issues with OpenVMS, Linux and Mac OS X. Despite the series, I am still being called upon to assist with ssh implementation on all three of the aforementioned environments. It is, of course, not a bad thing for one, like myself, who is in the computer consulting business but, in almost all of the cases, it was because of simple and stupid errors introduced when taking my blog examples and massaging them into one's own working environment.I have received myriad accolades for my series of blogs on ssh; especially, because it has covered the inter-operability issues with OpenVMS, Linux and Mac OS X. Despite the series, I am still being called upon to assist with ssh implementation on all three of the aforementioned environments. It is, of course, not a bad thing for one, like myself, who is in the computer consulting business but, in almost all of the cases, it was because of simple and stupid errors introduced when taking my blog examples and massaging them into one's own working environment.
One of the most egregious and pervasive errors I find myself repeatedly encountering concerns keeping the semantics straight. Public keys are the components of ssh which are distributed to the public. Private keys are the components of ssh which are to be kept private. This should not be rocket science as their names reflect upon their purpose and distribution; yet, I keep seeing both pairs being placed on both sides of the communication channel. In my examples in the ssh-ecutiry series of blogs, the public key component was always denoted with the filename extension of .PUB. This is the key, the only key, which should be distributed or disseminated. The other component is the private key and should be held in strict confidence on the system for which is was created. Distribution or dissemination of the private key defeats the whole purpose of ssh.
Another issue which seems to cause great vexation is one that can be classified as simple system and or file management. Confusion, especially in an environment where there are many systems with secure communications requirements, abounds when it comes to naming the files containing the keys. I suggest using the system's host name or its host IP when creating ssh key pairs. This, then, allows the remote host's management to enter the system's public key into its key repository with something meaningful to relate the key to the system to which it belongs. A recent, marathon, WEBEX session I was invited to attend dealt with this very issue. It is far too easy to become confused — Yes, even me — when the ssh key components maintain meaningless names or, worse, the same names. ssh does not know, nor does it care, what you call the key files, so why not make it simple and obvious, and give the key files meaningful names?
Follow all of the steps that have been outlined in my series on ssh and there should be no problems interconnecting using ssh. I make use of ssh and sftp extensively every day. I interface with OpenVMS — both my own systems and with remote client's systems — Linux and Mac OS X. One of the systems I use ssh to access — specifically, I use ssh tunnels — is even a Micro$oft box; however, it has had CygWin installed to provide a shell for command line access and control. I have no knowledge as to whether or not it's possible to directly ssh into Weendoze, so don't ask. I've even established ssh connectivity to my Cisco routers with public key encryption. While I have not detailed this, yet, in any of my ssh articles, it doesn't mean that there may not be another segment to this series to exposé how that too can be configured.
Stay tuned for more. In the mean time, keep it straight; keep it simple and, above all, keep it secure!
]]>VAXmanApocalypse 327672017-06-12T14:00:00-04:002012-12-21T16:32:00-04:00tag:vaxmans-musings-soapbox,2024:vaxmans-musings-soapbox.44It's here! Today is the much anticipated and much over-hyped Mayan Apocalypse. Thus far — and this day is nearly complete — today's prognostications have turned out to be more apocryphal than apocalyptic. However, for one of my clients, today was not so uneventful. They had experienced an apocalypse that was not manifest in the numerology of the ancient Mayan calendar; their apocalypse was rooted in the stored binary numerics of the OpenVMS file system. Yes, they hit the OpenVMS file version number limit.Mayan Apocalypse. Thus far — and this day is nearly complete — today's prognostications have turned out to be more apocryphal than apocalyptic. However, for one of my clients, today was not so uneventful. They had experienced an apocalypse that was not manifest in the numerology of the ancient Mayan calendar; their apocalypse was rooted in the stored binary numerics of the OpenVMS file system. Yes, they hit the OpenVMS file version number limit.
Generally, a file attaining the OpenVMS file version limit — 32,767 — is not the end of the world! It can certainly be a nuisance but it's usually not nefarious. As it was in this case, it was primarily a nuisance; however, the files in question could not just be deleted, nor could they be purged away and the remaining files renamed to version one. Some of these files contain transaction data which the client needed to maintain. Only after an established period of time could these files be purged away with a DELETE/BEFORE... or a PURGE/BEFORE... command. So, what was needed was a way to rename a collection of files with the oldest file being renamed back to version ;1 and then, through subsequent versions to account for the newer files as they had been created before the version apocalypse.
The problem here is that the OpenVMS RENAME command cannot wildcard rename a collection of files. RENAME can reversion a single file name to back to version;1 but it cannot or will not accept a wildcard version number in its input file specification to rename a glob of files. The client was faced with a daunting task of renaming hundreds of files manually to maintain the required archive of these transaction data files as well as to maintain their chronological order. One other aspect of this exercise was that there could be holes in the file version number continuum. Some files, if a transaction did not complete, would be deleted.
My first thought was, "Somebody must have written a DCL procedure to do this very thing." So, I consulted Google with hopes that it could find a DCL procedure to provide my client to a quick solution to their dilemma. Google turned up several promising links but when I reviewed the DCL code, I was underwhelmed. None of the procedures I reviewed would handle a wildcard in the file name specification. This was paramount because this wasn't just a single file name needing reversioning; there were hundreds of file names needing reversioning! There was only one solution. I'd have to write such a procedure myself.
The first hurdle to tackle was the possibility of "holes" in the version number continuum. I thought about this for a while and then, realized that it really wasn't a problem if I could sort the files that needed to be renamed in a fashion that would present the files in chronological — with respect to the version number — order. The OpenVMS SORTcommand should be perfect for this; however, there was one catch. The OpenVMS DCL SORT command, applied to file name, would sort based on an ASCII collating precedence. What would this mean? It meant that the files FILE.EXT;10 and FILE.EXT;11 would collate before the file FILE.EXT;2. This simply would not do. Fortunately, because I've spent several decades with the OpenVMS file system, I knew a few useful tricks. For example, the version number of the file can have leading zeroes, and RMS and the file system will still handle them correctly. So, I set out to format the file names in question with leading zeroes.
"''F$parse(F$fao(";!5ZL",F$integer(F$parse(FILE,,,"VERSION")-";")),FILE)'"
The above would take the current file name and prefix its version number with zeroes. From a pure ASCII collating perspective, this would allow the OpenVMS DCL SORT command to properly collate the list of files. This is also an example of another practical use of the F$fao() (F$ForgottenAvoidedOverlooked) lexical function.
The rest of the task at hand was pretty straightforward complements of simple exploitation of the OpenVMS DCL lexical functions. The first thing to do was to F$parse() a provided file specification. Yes, even wildcarded file specifications. Then, the F$search() lexical availed itself to find the actual file names which needed to be reversioned. These commands were then placed in a loop, allowing the procedure to traverse files within a directory and to even traverse directories. The collected file names were written to a temporary file with a named created using the F$unique() lexical. When the F$search() loop was exhausted, the file was closed.
Now, the procedure only needed to invoke the OpenVMS DCL SORT command to order all of the files written to file containing the file names which were scanned with F$search(). Because these files were written with a version number that was extended with leading zeroes, the files would all be collated in the proper sequence for renaming.
It was now time to address the required task. The previously assembled file was opened and read. Each record read is the full file specification of a file which needs to be renamed to a new version number. This was another simple task, complements of the F$parse() lexical. A DCL symbol containing the current reversioning version number is passed, along with the file name, to the F$parse() lexical to compose the RENAME target output-filespec. The result — a short and simple DCL procedure which can rename any supplied file specification containing any acceptable wildcard patterns back to version ;1.
Here is the download link for the complete DCL source code of the described REVERSION.COM procedure.
Post Scriptum
Post apocalypse, the REVERSION.COM procedure has been modified to accept an optional /LOG qualifier. The procedure, in order for this new, optional /LOG qualifier feature to function as intended, must first be defined to be executed from a DCL symbol.
]]>VAXman