DR (release 1.5b) What we got here is Yet Another CLI Directory Listing Command, called Dr (pronounced "dr", one syllable) because it leaves out .info files. (Like, the missing I in Dir stands for .info ...? never mind.) It is a very fast and full featured program which is superior to all of the ten or so other Amiga directory listers I've tried. I couldn't live without it. Even its half-finished versions were preferable to Dir. The features it offers are: + By default, .info files are not mentioned in the output. Instead, it shows you which files have *.info files associated with them by writing their names in orange (or whatever you have set color 3 to be), unless you use the -M option (for Monochrome). Any *.info file that is not associated with a regular file or directory is shown normally, e.g. Disk.info. You can see all *.info files normally with the -I option. + It is fully reentrant and reexecutable. The "pure" bit is set; you can make it resident. + It is faster than other directory listers. If you install the included fastscan.library in your LIBS: directory, Dr (or any other program written to use the library) can sometimes be many times as fast as Dir at scanning floppies; other allegedly "fast" listers are all slower than Dr, and are often less reliable besides. Under the Fast File System, there is much less difference, but Dr still has an edge. Dr still works if the library is not present, but with a much smaller speed advantage. + It arranges the output in a variable number of columns, with spacing based on both the length of the longest filenames and the width of the window. It assumes a width of 77 when output is not going to a CON: window. By default, it sorts the entries in columns, not in rows; it's easier to find things alphabetically that way (try it out if you don't think so). The -H option makes it sort in rows. Directories are listed before files, with slash characters after their names. + It handles AmigaDOS wildcard patterns, like "#?.(c|o)" to list all files with names ending in ".c" or ".o". Those of you who hate "#?" can use "*" instead -- under dos 1.x Dr translates "*" to "#?", but under 2.x you must activate the AmigaDOS WILDSTAR flag to do this; the NathanHale program included with Dr (it's tiny, pure, and PD) switches this feature on or off for all regular AmigaDOS programs, as well as Dr. Under AmigaDOS 1.3 and older, you can also show all files that do NOT fit a pattern by putting a "~" at the beginning of it; for instance "dr foo/~#?.o" shows all files in directory foo that do not end with ".o" -- a "~" in the middle of a pattern has no special meaning, under 1.x. Under dos 2.04 and newer, Dr uses the full new pattern syntax including tildes and square brackets (character classes); to negate an entire pattern, you must use "~(pattern)". + It understands dos 2.x file links. When the -L option is used, it shows what each soft link is linked to, in an extra line after the regular information for that file. Using the -X option on a soft link tells the pathname that it is linked to, but no other information (this is due to a limitation of AmigaDOS). In normal output, soft links are grouped with directories but do not have slashes on the ends of their names as directories do. Hard links do not at present get any special treatment, except that Dr will notice if a directory is linked "inside itself". (Note that if you list a directory containing a hard link, you will not see any filenote on it, but if you ask for a listing of just that link (with the -X option if it is a directory), you may see one. This is the filesystem's fault, not Dr's.) + It has lots of genuinely useful options. There isn't much one could ask of a directory lister that Dr can't somehow accomplish. + And last but certainly not least, Dr is public domain and the source code is provided both for Dr and for fastscan.library, which is copyright © 1992 by Paul Kienitz but freely distributable if not modified. CREDIT: the pattern matching code for dos 1.3 and older is PatMatch by Jeff Lydiatt, available on Fish disk 85, modified to be reentrant. USAGE: type "Dr" followed by zero or more file names, directory names, patterns, or options, or type "Dr ?" for a summary of options. Anything that starts with a dash character and is not enclosed in quotes is taken as options. Example: dr -orf devs: In this command, "devs:" is the directory that gets listed, and the set of options is "-orf". By default, Dr lists the names of files and subdirectories in whatever directories you tell it to list, alphabetically sorted in columns. It's usually easier to find something alphabetically by reading down columns instead of across rows, in my experience. If you disagree, use the -H option (H for "horizontal"). Directory names are listed before file names, with the filenames indented one space. (This method of visibly separating them replaces that stupid line of dashes that many users disliked.) Each directory name is followed by a slash. Only the name itself, not the slash, is orange if it has an icon. Things with associated *.info files will be marked as such even if the *.info file itself is excluded by the pattern you used, or by the -D or -A or -B options. If you list just a single file, it will check whether it has a *.info file and show the name in the alternate color if so, unless you use the -I (show .infos) or -M (monochrome) option. It does not check to see whether files with names ending in .info are actual valid icon files. Note that if the output is not a CON: window, it is as if -M were used; it doesn't show you which files had icons. Pattern wildcard characters are currently only recognized at the end of a pathname you give to dr (that is, after the last slash or colon if any); e.g. you can't yet go "Dr */src/*.c" to find all .c files in all subdirectories named src. This ability will be added someday. If anybody cares. New in release 1.5 is an extension of pattern syntax (besides a "~" at the beginning to negate it, under 1.x): If you end the pattern with a double colon, it applies that pattern to files within all subdirectories it encounters, as well as the directory you specify. Think of "pattern::" as being equivalent to "pattern" and "#?/pattern" and "#?/#?/pattern" and so on. This is different from using the -R option (show contents of subdirectories) with a pattern. With -R, it shows files in the top directory that fit the pattern, and looks in each subdirectory with a name that fits the pattern, showing all the files inside. With "::" it looks in all subdirectories and shows the items in them that match the pattern. The "::" can be used only at the very end of a path/pattern specification. Hopefully someday it will also be usable in the middle, before a slash. -R will also search the contents of directories which are not shown, if the reason they are not shown is because of the -A, -B, -F, or -P options, rather than because of a pattern. Those options will limit which files are shown within those subdirectories. If an actual directory has a name with pattern characters in it, like maybe a drawer named "Doesn't work?", Dr will list that directory instead of expanding the pattern. You can force it to expand by adding an extra percent sign to the pattern, so it doesn't match the name. Patterns may be up to 128 characters long, not counting the directory path in front of it (but a "*" counts for two characters under dos 1.x). If you wish to use a single question mark as a pattern to show all files with one-character names, and there are no other arguments on the command line, you must put quotes around it or add a percent-sign to it, or Dr will think you are asking it for a brief summary of usage and options. As of Dr 1.5, the way to specify a quote within quotes is with "" rather than the BCPL- style *", in order to make it easier to use the asterisk as a wildcard. You can give several option letters after one dash, like "Dr -chs foo", or separately, like "Dr -c -h foo -s". The case of the option letters doesn't matter. Each option affects those files and directories that come after it on the command line, except that any options at the end, after the last filename, act as if they were entered at the beginning. Example: "dr foo -s bar" lists directory foo without showing sizes, and directory bar with sizes shown. If a directory name begins with a dash, put quotes around so that it isn't taken as options. If you give an option twice, the second one cancels the first. This means that if you make an alias like "alias list dr -lc []", saying "list -c" turns the -c option off. Or, you can show directory foo with sizes, and directory arf without sizes, with the command "Dr -s foo -s arf". (Note: since options at the end act like they are at the beginning, "Dr -s directory -s" will show the directory without the -s option!) The complete set of options for Dr release 1.5b is: -I List .info files like normal files instead of using an alternate color to mark the other files they are associated with. -M Turns off the use of color to mark files that have icons. -S Show the size of each file in bytes, and totals. -C Sort chronologically (newest last) instead of alphabetically. -Z Sort by file size, from smallest to largest; items of the same size are sorted alphabetically or chronologically depending on presence of -C. -V Sort in reverse (Z to A, newest to oldest, or largest to smallest). -H Sort into rows instead of columns, if more than one column. -L Show sizes, protection bits, datestamps and filenotes like the List command. Overrides -S. Show total bytes/blocks used. Unlike List, it puts the filename after the other information instead of before. For soft links it adds an extra line telling what path it is linked to. Output is sorted unless you also use the -O option. -R Recursively show contents of all subdirectories found. If you're going to descend a whole lot of levels (like more than about nine) you might need a bigger stack than the default 4K. It checks for adequate stack before entering each subdirectory. An 8K stack would let you go about 40 levels deep. -U Show only disk space consumed, and a count of files and directories, without listing any names unless you also use -O or custom formatting. As far as output goes, -U overrides all other options except -R, -O, and custom formatting, but patterns and options may affect the totals shown. -O Put each filename on a separate line as a complete pathname, do not sort or hide .info files, and when -R is used merge all the directories and subdirectories into a single list. If -L is also used, size and protection and such is shown, and totals are given at the end, with no subtotals for inner directories. Names in this case are shown as relative pathnames from the directory specified, including inner dir names if -R is used, not as complete pathnames. Using -U with -O also causes totals to be shown at the end, but leaves the output in the form of one complete name per line. If neither -L nor -U is used, there are no headers to separate directories, just nothing but names. This can be very useful as input to other programs. Overrides -S, -K, -C, and lack of -I. The beginning of the pathname shown is the directory arg as you specified it in the command, not the absolute path. The pathnames output have a maximum length of 300 characters. Output is continuous while the disk is being scanned, instead of done afterwards. Unsorted output can be noticeably faster if you are using fastscan.library, because the disk IO is asynchronous. -D Do not show file names, only subdirectory names. Cancels -F. -F Do not show subdirectory names, only file names. Cancels -D. -K Show the disk address (header block key) of each file or directory, in square brackets. -X Show the protection bits, datestamp, and filenote of the directories you specify, instead of showing the files inside. If an arg is a soft link instead of a directory, show the pathname that it is linked to. Ignored if -R or a pattern is used. Overrides -F -D -P and -O. -A# (example: -A30) Show all files dated within the last # days. The cutoff point is midnight before the day # days ago. Thus -A0 shows files changed today. -A not followed by a digit cancels. -B# (example: -B5) Like -A, but show all files more than # days old. Combining -A with -B uses a range of days, or excludes a range of days if the -A number is smaller (more recent) than the -B number. -P A bit more complicated than the options above; the letter P may have other letters after it, each one optionally preceded by a tilde (~). The letters allowed are H, S, P, A, R, W, E, or D (lowercase okay). These letters represent protection bits. If the tilde is in front of a letter, Dr will show only files for which that protection bit is not set. If there is no tilde it will show only those for which it is set. For instance, to show all "pure" files, use -PP. To show all script files which have not been backed up, use -PS~A. Use -P with a space after it to cancel earlier -P options, making it ignore protection bits. For the bits R, W, E, and D, "set" means that the bit shows as present when you use List or Dr -L. (The physical bit is actually a zero in these cases.) So for example -P~D means show files protected from deletion. You can use a caret (^) instead of a tilde (~) if you want. Must not be followed by another option letter; that is, you can't use -PAU for -PA -U. -[...format string...] Control the format of the output. For each file or directory to be listed, the text inside the brackets is written out followed by a newline. Substitutions are made on that text as follows: \n is replaced with a newline. \e is replaced with an escape character. \d is replaced with the name of the directory being searched. (If you specified a file instead of a dir, or used -X, \d will give the full name, and any filename added after it will be invalid.) \f is replaced with the name of the current file or directory being listed, with no path in front. \p is replaced with the pathname of the current file or directory -- like \d followed by \f, with a slash in between if needed. \? becomes a slash if the current file is a directory, or a colon if it is a volume (with -X option), or nothing for files. Usually used right after \f or \p to show whether it is a directory. \/ is a slash unless the preceding character output was a slash, colon, double-quote, whitespace, or control character. Possibly useful for joining filenames onto directory names. \b is replaced with the file's protection bits, shown as eight letters or dashes; e.g. "-s-arw-d". \t is replaced with the file's timestamp, in the format DD-Mmm-YY HH:MM:SS. No choice of date format yet. \s is replaced with the file's size in bytes, padded to a constant width (no field width choice yet), or blanks for a directory. \k is replaced with the disk address (key) of the file or directory, padded to a constant width. For both this and \s, the amount of space used is that needed by the largest number in the output, or a fixed value if the output is unsorted. In short, don't assume a constant value. \i is replaced by (n) spaces, where (n) is how many levels deep in recursive descent you are -- no spaces when no recursion. Use a few \i's before the filename to get indentation corresponding to the nesting of subdirectories. \+ prevents the newline at the end of each output. \ before anything else "quotes" it. Use \\ for \ and \] for ]. The options \b, \t, \k, \s, \e, \i, and \? are new in release 1.5 of Dr. To cancel a previous format option and use normal output, use -[]. Overrides -S, -L, and -K. Output is sorted normally, and has the usual headers to separate subdirectories and separate command line argument directories unless you use -O also. Note that whitespace and double-quotes inside -[...] are treated like any other characters, not as marking separate arguments to Dr. The result that is output after substitutions is limited to 255 characters. The name written by \p or \f will be in the cursor color (orange or whatever) if it has an icon, unless you use -I or -M or -O or send the output to a file. -{... format string...} Like -[...], except it executes the result as an AmigaDOS command instead of just writing it out. (\} means } in this case.) This is done in addition to, not instead of, normal output. So you can use both -[...] and -{...} at once with different formats. The command is done first, the output last; commands are executed during the disk scan instead of saved until afterwards, so they are done in unsorted order. You can use -[\+] to suppress all output and just run commands. -! Turn off the cursor during output to the screen. This makes it go faster. This option has no real purpose except for speed competitions with other directory lister programs which also use this trick. Unlike other options, a -! anywhere in the command line takes effect throughout the whole program run. If Dr lists the contents of more than one directory, each one will be preceded with its name, written like this: === path/whatever/dir === unless you use -O (but not -U or custom formatting) in which case the different listings will all run together without separation. If you give no directory or pattern, it lists the current directory, of course. Or you can specify the current directory as empty quotes: "". The usage totals given at the end of a -S, -L, or -U output tell the number of directories listed, the number of files, the total number of bytes in the files, and the number of disk blocks they occupy. For each of these numbers it may give a second number in parentheses. This represents the total found in the whole directory, when it differs from the total of those selected for listing. Things excluded by a pattern or by -A, -B, -D, -F, or lack of -I, may contribute to the differences between the numbers. Note that when you use fastscan.library it does not actually count all the blocks in each file, it just estimates the number of blocks from the file's length. This is to avoid unnecessary disk access to read file extension blocks. There are occasionally files that are bigger than they look; fake files made to contain bad tracks are often like this, having a length of zero yet containing a track's worth of blocks. The next release of fastscan.library may address this shortcoming, but until then Dr with fastscan.library will show incorrect information in these cases. Some examples of using format strings: to mark the files in directory foo as having been last updated yesterday, use Dr -o -{setdate "\p" yesterday} foo The -o is not necessary but usually a good idea. Or you might want to use -[\+] to suppress output. To copy all files ending in ".c" in directory foo to directory bar with ".BAK" stuck on the end (foo/xxxxx.c becomes bar/xxxxx.c.BAK), use Dr -o -{Copy "\p" to "bar/\f.BAK"} foo/#?.c WARNING: Using Rename in the -{...} command may not work. With at least some versions of the file system, such as the AmigaDOS 1.3 Ram-Handler, renaming a file, and then looking up the "next" file in that directory after the one that just got moved, gets it very confused. Better to use -[] to write the Rename commands to a temporary file and then Execute that file. Similar cautions apply to Delete. Some Un#@%!x folks like to list their files by simply going "echo *". This writes out the names of the files packed all onto one line. Well if you want to misuse Dr that way, you can: (you'll probably want to use an alias) Dr -f -[\f \+] foo That could be shortened to "Dr -f[\f \+] foo" ... with Dr 1.5, unlike 1.3, you can put letter options after the same dash as [] and {} options, before or after the brackets. Dr will output a newline before it exits. You can execute more than one command for each file by putting \n in between the commands inside -{ }. Or alternatively, you can split the Dr command into multiple lines with a plus sign at the end of all but the last, and the newlines will be included in the bracketed command string. (Plus-newline outside of brackets is considered the same as a space.) But the complete text after all substitutions are made must be less than 256 characters long or Dr cannot execute it. If a command comes out too long, Dr will write out a warning message and continue, and return 5 ("Warn") when it exits. As an example of using more than one command separated by newlines, the following will type out all the files in directory foo with a header in front of each one: Dr -[\+] -{echo "*N #### FILE \p -=>" \n type "\p"} foo Or, alternatively: Dr -[\+]{echo "*N #### FILE \p -=>" + type "\p"} foo Under AmigaDOS 1.3 and older, if a command returns a DOS error code Dr will stop, returning 10 ("Error"), and Dr's DOS error code will be that set by the failing command. Some programs never set a DOS error code (e.g. 205 = "object not found") but indicate failure purely by their return value (e.g. 5 = WARN, 10 = ERROR). But Dr cannot tell what the return value is under 1.x, only the dos error code. This is because it uses the DOS Execute() function. Under 2.04 or newer, on the other hand, It uses System() instead of Execute() and is able to tell what the return code is. At present, it quits whenever the return code is not zero. A future version will have some way of setting a "Failat" level for such commands. To work around this limitation under 1.3, I am including a tiny program called R2E, which returns as its error code the value which the previous program gave as its return value. You would use it by adding "\n r2e" to the end of your -{...} format command. For instance, the RX program for running rexx scripts never sets a dos error code. You would use R2E on it like this: Dr -{rx whatever \n r2e} foo. Then if RX returned nonzero, R2E would cause Dr to stop at that point. UNLESS the return from RX was higher than the FailAt level (default 10), in which case R2E won't be executed at all because the command-executer quits when it gets a return value that high ... so in practice you have to use a FailAt command. For example -{failat 999 \n rx whatever \n r2e}. Another example; your command is "type \p", and you want Dr to stop if you interrupt Type with a control-C, you would use Dr -{type "\p" \n r2e} foo, because when Type is control-C'ed it returns 5 but no error code. For programs which don't react to control-C at all ... if you want to stop Dr, just keep banging control-C and sooner or later the signal will be heard by Dr instead of by the program being run. Or try control-D which also works to stop Dr. To make the -{...} option work most efficiently under 1.3 and older, there are certain steps you should take. Make C:Run resident, and if you are using AmigaDOS 1.3, make sure you are using version 1.3.2 or later of SetPatch, not the older 1.3 ... if you have any older version of AmigaDOS, get 1.3.2 or 1.3.3! Otherwise any program that uses the Execute function will reload C:Run from disk every time it's called. Do this even if you don't use AmigaShell and don't make anything else resident. But it helps if you DO use AmigaShell (make L:ShellSeg resident as "CLI") and make resident if possible whatever commands you are executing with Dr. Under 2.0 you only have to consider making resident the commands you actually use in -{ }. Make R2E resident if you ever use it at all; it takes up extremely little space. If you can't make the programs you're running resident, you can copy them into ramdisk and run them from there. When the same program is being run over and over, once for each file, running it from disk each time is very wasteful. A hack called Rez 0.5 by Jim Goodnow II is very useful for effectively making non-pure programs resident. You can put a number after R2E to give it a "fail level". Return values below this number from the previous program will be returned as zero. Like, "R2E 10" will report no error if the previous program returns 5, but will if it returns 10. The default "fail level" is 1. If it is a rexx command in particular that you want to execute, you might want to try using my FRX command instead of RX, if you can find a copy. It doesn't need R2E. FRX also lets you set up command line templates for your rexx scripts. Neat trick: With Dr you can turn Lharc into a hard disk backup utility! Dr > Tempfile -orfp~a -{protect "\p" +a} Disk: This will write a list of all the files in Disk: that have been altered since the last backup into Tempfile, and simultaneously mark all those files as archived. (To be safest it would be better to not mark them until after the backup is done ... maybe someday I'll write a "backup-one-file" program to be used with Dr.) Then give the command Lharc -x -iTempfile a Vol:ArchiveName and it will archive all the files named in Tempfile into Vol:ArchiveName.LZH. You can use a pattern to not back up certain files, using the tilde and double-colon features. For instance, to avoid backing up files with names ending in .o or .bak, the above Dr command might be rewritten like this: Dr > Tempfile -orfp~a -{protect "\p" +a} Disk:~(#?.(o|bak)):: The following are features that you can probably expect in Dr 1.6: Completely separate versions for 1.x and 2.x AmigaDOS, each one smaller. Optional conversion of pathnames entered on the command line into absolute paths (e.g. "dr -o libs:" writes "Workbench2.0:libs/asl.library" instead of "libs:asl.library", etc). Default options read from an environment variable or local shell variable, and special style options suited for being put there. These would let you choose stuff like: - whether to show directory names before filenames, or after, or mix them together - whether to show inner directory contents before or after outer ones - how to separate directory names -- blank line, line of dashes, differing indentation, use of color, or a combination maybe - whether to use names like "Yesterday" or "Wednesday" in reporting datestamps - what format to write dates in (e.g. MM/DD/YY or DD-Mmm-YY or ...) - whether to pursue soft links when using -R The ability for the \f and \p formatting options to perform string substitution on filenames, so that (for instance) FOO.TXT becomes FOO.DOC. This would be expressed with a syntax like "\:.txt/:.doc:p". (The slash after ".txt" would indicate that it must be found at the end of the name.) And more ways to split and combine the starting pathname as given, the absolute pathname of that, the subdirectory under that, and the local name. Other features I might add eventually: -G: Show file's timestamp as age; days and hh:mm:ss before present. Handle patterns in the middles of paths, like foo/#?/src/#?.c Make -A and -B able to parse date-and-time ... Well, under dos 2.x maybe. -Q: Super-compact columnation like ls 4.1ljr, maybe. Make -X and -R both work at once. Some way to handle filenotes and days-of-the-week and "Today" and "Yesterday" in custom formatting maybe. The Amiga is now the fourth system I have written a directory lister for. First was TOPS-20 (one that showed only files that you are the owner of), next Kaypro II (fast, 2K long, sorted, showed size), third 4.2 BSD Un*#%$!x (like ls -ls but faster because don't look up group names, just indicate whether your group). So this one is, like, the crowning achievement of a great career in directory lister writing. There is now almost no use at all for any other lister, except maybe if you actually find Dir's interactive mode to be of any use. My original goal was just to produce an adequate alternative that left out .info files; my goal now is for Dr to be the best available. Dr is in the public domain, written by Paul Kienitz. Fastscan.library is Copyright © 1992 by Paul Kienitz, and is freely distributable in unmodified form provided that this copyright notice is visibly included. Feature suggestions and bug reports are appreciated. I can be reached at: snail: Paul Kienitz bbses: try 6430 San Pablo ave. Winners Circle 510-845-4812 Oakland, CA 94608 FAUG 415-595-2479 USA net: paulk@terapin.com If you want the source and didn't get it with the executable, you should be able to download it from one of those bbses.