Previous | Index | Next

Master 512 Forum by Robin Burton
Beebug Vol. 12 No. 6 November 1993

We're continuing with our look at back-up strategies for the 512 using PKZIP, but first we'll deal with the little teaser I left with you last month.

MULTIPLE BATCH FILES

Calling a second batch file from a first is easy; the difficulty is getting control back to the first again afterwards. In our example this meant that the second and subsequent parameters submitted to MAIN were useless; as the job stands only the first will ever work.

If you investigated you'll have found that it's not just that the parameters to MAIN are forgotten, but that control doesn't return to MAIN all. You can easily see this by adding a line at the end of MAIN such as 'ECHO Main again'; it doesn't execute because control doesn't return to MAIN after the first called file has completed.

To add interest I said any combination of subsidiary files should be capable of being run in any order, but one thing I didn't specify is that the method shouldn't be limited to three sub-files. However, clearly an ideal answer should handle any reasonable number. It can be done, it's not even difficult, and in fact there are two ways to solve the problem, although one's much more efficient than the other. Let's have a look at them.

Bear in mind that we have two objectives, depending on precisely what we're trying to do in the batch files. One is to preserve parameters in the main file through calls to subsidiary files, as in MAIN; the other can be, in effect, to pass parameters in both directions between several batch files.

The loss of control we've seen is caused by COMMAND.COM, which is pretty simple-minded. Its problem is that it can keep track of only one batch file at a time, so as soon as you call a second one, total and permanent amnesia sets in. One obvious solution therefore is to introduce extra copies of COMMAND.COM, so each can keep its own set of batch data intact. With this method the called files can remain exactly as they are; only MAIN needs alteration as follows:

COMMAND /C %1
COMMAND /C %2
COMMAND /C %3

Now all should, because the original copy of COMMAND.COM only has MAIN to handle, while the three subsidiary files are each executed within a second, separate command shell. By the way, in case you missed it a while ago, the '/C' switch tells COMMAND.COM to terminate automatically when the called program or batch file terminates. This avoids the need for an EXIT command to leave each of the second command shells.

That solves the problem of executing all three files and it also allows us to call them in any order, but it's less than ideal. The disadvantage is that every line unconditionally loads an extra copy of COMMAND.COM which not only slows down the job, but also means that COMMAND.COM must be available in a current path. Both of these can be serious minuses if you're using floppies.

Worse, each extra COMMAND.COM loads whether the relevant batch file is going to be called or not. Null parameters don't, as you might think, leave extra copies of COMMAND.COM occupying precious RAM (they just load and exit without doing anything), but they are a complete waste of time which should definitely be avoided. OK, that's easy too: put an IF EXIST test on each line, like this:

IF EXIST %1.BAT COMMAND /C %l
IF EXIST %2.BAT COMMAND /C %2
IF EXIST %3.BAT COMMAND /C %3

Now, if any of the three (or more) parameters is blank those lines won't execute, because no file called just '.BAT' will be found. Problem solved!

But that causes another. This routine will still waste a lot of time, again worst for floppies, because every line must now search the directory to see if the (parameterised) batch file exists before it can decide whether to execute or not. In fact on my winchester (my COMMAND.COM lives in the RAM disc) this version of the file takes longer than the previous one, so the fix is worse than the problem.

Time for a different approach!

A BETTER MOUSETRAP

That's the 'official' way to tackle the problem; now let's look at the best way.

This method exploits COMMAND.COM's limitations and answers all the questions with no performance implications, no matter how many parameters are supplied or omitted. For this, both the main and subsidiary files must be altered, in our example MAIN becomes a single line, like this:

%1 %2 %3

while the subsidiary files (e.g. ONE.BAT) gain a second line to become:

ECHO This is ONE.BAT
MAIN %1 %2

Note that all subsidiary files have precisely the same extra line – don't change the parameter numbers. What happens now is that MAIN calls %1.BAT (whichever that happens to be) with two parameters, %2 and %3, which are implicitly SHIFTed left one position by the call. Having loaded a second batch file the first one and its parameters are totally forgotten by COMMAND.COM. The second file executes, then calls the first again, this time with the two parameters supplied to it which are therefore passed back to the main routine unchanged.

For example, suppose initially we enter:

MAIN THREE ONE

MAIN executes its single line as:

THREE ONE (blank)

so THREE.BAT is called with one parameter, in this case 'ONE'. THREE executes, then in its second line calls MAIN again, with (now) only one parameter – 'ONE'. ONE.BAT is then called by MAIN, this time with no parameters at all. ONE.BAT executes and then calls MAIN, this time passing nothing back, so MAIN executes a blank command (which of course does nothing) and terminates. Neat eh?

Although in the example I used three subsidiary files, you can see that not only does it not matter if parameters are omitted and the order in which they're supplied is irrelevant, but the method holds for up to nine subsidiary files, In fact, with no penalty whatsoever you can include parameters %1 to %9 in the main file and %1 to %8 in all the subsidiaries, then no files will need alteration if you find you need to add extra subsidiary routines later.

BACK TO BACK-UPS

In case you thought I'd forgotten, the point of all this, apart from providing a bit of entertainment, is that DOS batch facilities are pretty basic, and without a bit of lateral thinking they often impose limits on how you can do a job.

Taking back-ups is a perfect example of a regular and frequent job that may demand flexibility in operation, but which should remain as simple and reliable to operate as possible. I handle the differing needs for my ES back-ups (see last month) using five batch files which use exactly the above technique.

For ES back-ups MAIN.BAT is actually called SAVE.BAT, while the four subsidiary files are called DEV, NEWPROGS, SOURCES and ISSUES (BAT) each of which backs up the appropriate section of ES data. I won't list their contents here, but a few examples will let you see how they're used and perhaps you can borrow from these ideas to use for yourself.

If I've been programming, but the job isn't finished, I need to secure only ES\DEV, in which case at the end of the session I simply enter:

SAVE DEV

If I've reached the testing and debugging stage but the program still isn't completely finished, I'll obviously need to secure both ES\DEV and ES\NEWPROGS, so I enter:

SAVE DEV NEWPROGS

When I think a new program is fully tested and ready for use I copy the source file to ES\SOURCES and enter (can you guess?):

SAVE DEV NEWPROGS SOURCES

On the rare occasions that I re-secure the ES issue directories the command becomes:

SAVE ISSUES

and of course, should I ever need to secure the whole lot there's a bit more typing, but it's just as simple:

SAVE DEV NEWPROGS SOURCES ISSUES

Hopefully these examples have been 100% predictable and thoroughly boring. That's precisely how it should be. If your back-up procedures are properly designed and set-up they should be so simple that you can't possibly forget how to use them and so easy that there's no excuse for not doing so.

PKZIP DETAILS

You saw last month how straightforward a PKZIP command can be, but of course there are often one or two extras you'll need in a live situation. I've said several times that the biggest aid to quick and efficient back-ups is to avoid duplication. OK, you can avoid some files altogether such as application files, especially if they're stored separately, but that's not all you can do.

Obviously each time I secure any of the above directories only one or two files are likely to have changed or been added, so all the others can be ignored. This is where PKZIP command options, mentioned last month, are used. These allow you to modify the action of PKZIP and there are a large number of them. We'll concentrate here on the most useful for back-ups and for illustration I'll use my hard disc root directory back-up routine which, in this case, is itself a subsidiary routine (called ROOT.BAT). Here's the file:

echo off
:start
if exist a:root.zip goto checkb
echo INCORRECT DISC IN DRIVE A:
goto retry
:checkb
if exist b:root.zip goto secure
echo INCORRECT DISC IN DRIVE B:
:retry
ECHO Insert correct disc and try again
pause
goto start

:secure
fset a:root.zip [rw
pkzip -i- -ws a:root -x@exclude
pkunzip -t a:root
echo OK to continue? 1=Yes, 2=No
select 1 2
if errorlevel 2 exit

fset a:root.zip [ro
fset b:root.zip [rw
pkzip -i -ws b:root -x@exclude
fset b:root.zip [ro
echo on

As you can see I take two back-ups, so the first section of the file makes sure that I have the right discs in both floppy drives by checking for the presence of the relevant ZIP files. If they're not found the discs can be changed and the job can be re-started.

If all's well execution continues from 'secure', when first A:ROOT.ZIP is set read-write to allow updating. The next line is the first PKZIP command, so let's examine the options.

The first option is '-i-' (NB. many PKZIP and UNZIP options ARE case sensitive) which tells PKZIP to archive only those files which have the archive attribute set, but the trailing minus after the '-i' tells PKZIP not to reset the archive bit because it's needed again for the second back-up. Following that the next option, '-ws', instructs that files with the system bit set (e.g. utilities) should be included in the operation, otherwise they'd be ignored.

Next is the name of the output file which is to be updated (A:ROOT.ZIP) but with the file extension defaulted. Finally there is one further directive, 'x' which is the exclude directive. If followed by a filename the specified file is excluded from the archive operation, but if the filename is preceded by '@', as above, it instructs PKZIP to read the named file (ie. EXCLUDE) for a list of files which are to be excluded. In this case EXCLUDE contains the names DOSPLUS.SYS, 6502.SYS and COMMAND.COM. These needn't be secured because they're automatically recovered if the partition is re-created.

Next the integrity of the updated ZIP file on drive A: is checked by PKUNZIP using the '-t' (test) option, after which confirmation is needed before the second back-up proceeds. Confirmation is handled by a small program called SELECT which provides manual entry into batch files. If there were a fault, of course, the job would be abandoned, the trouble identified, and the back-up re-run.

If drive A:'s back-up file is OK, it's again set to read-only, then drive B:'s ZIP file is updated, but this time note that the trailing minus on the '-i' option is omitted, so the archive attribute of archived files is reset to prevent the same files being re-archived in future (unless they're subsequently updated again of course). B:ROOT.ZIP is then set to readonly and the job ends.

Naturally I don't secure the root directory often, only if an existing program is revised or a new one is added. However, there's virtually nothing to remember so it doesn't matter how long it is since the last back-up, I just select the root directory, enter the command 'SAVE ROOT' and the job runs. SAVE.BAT and ROOT.BAT themselves are of course secured along with all the other files, while batch files for recovery are kept on each of the floppies (along with a working copy of PKUNZIP, think about it!)

In fact each back-up floppy usually contains several ZIP files, so to recover the root directory I'd actually enter 'RECOVER ROOT', but you can guess how that works by now, so I won't go through it again.

The above is an example of how I secure one particular directory which happens to have some unique contents, but you can easily see how to build such an operation into a more flexible routine like the one described for the ES directories. Not all back-ups require things like file exclusion and not all directories contain system files; so many back-ups are simpler. However, other useful options we haven't yet looked at remain.

NEXT MONTH

Next month we'll complete our look at PKZIP by investigating options such as recursing sub-directories, plus of course how PKUNZIP is used when problems force recovery.

Previous | Index | Next

About the Master 512 | Bibliography