home *** CD-ROM | disk | FTP | other *** search
- SYNOPSIS:
-
- Treewalk - visit all the files in a directory tree.
-
- usage: treewalk [<options>] [[command] <CLI command>]
-
- options are: post, both, dir <directory>, verbose, single, filter <expression>
-
- options and "command" are only checked in the first 3 characters.
-
- DESCRIPTION:
-
- Treewalk is a command for visiting all the files of a subtree of an
- AmigaDOS file system. It's designed to be reasonably fast, robust, and
- not use a lot of stack space - or any other critical resources. About
- the only thing you're liable to run out of is memory. (Note: "all the
- files of a subtree" doesn't include the directory that's the root. So
- if you do something to every directory in the subtree, it won't do it
- to the root directory.
-
- The normal behavior of the command is to test every file in the
- specified subtree against a user "filter" expression, and if the file
- passes through the filter, to issue the user supplied command with
- that file as one of the arguments.
-
- Any argument that isn't an option starts the user supplied command.
- All arguments after the first command argument are concatenated
- together, with a single space between them, to make up the command. As
- each file is visited, its full path name enclosed in '"''s (so that
- things like RAM DISK: will work) is concatenated to the end of the
- command. When the last file is visited, or the command line becomes to
- long for the system, it is issued to the cli. The current working
- directory of the command is the directory in which the treewalk
- command was started, not the directory being visited or the directory
- that is the root of the tree being walked. The command is run as many
- times as needed so that all files are visited.
-
- The "command" keyword indicates that the next argument is the start of
- the command, whether or not it looks like a keyword. This is useful if
- the command you wish to run on the starts with a valid keyword. If
- there is no command, treewalk will print out the names of all files
- that pass through the filter.
-
- The "verbose" option causes treewalk to print the text of every
- command before issuing it.
-
- The "ignore" option causes treewalk to not print anything on error
- returns from the command.
-
- The "single" option defeats the stacking of files on the command line,
- and the command is run once for every file. This is useful if the
- command in question only accepts one filename. For instance, "list
- nohead" should be done this way.
-
- The "dir" option is followed by the name of a directory. That
- directory will then be used as the root of the tree, instead of the
- current directory.
-
- Normally, treewalk will visit a directory before it visits any of
- it's children. This is a "preorder" treewalk, "pre" because it
- visits parents first. You can change this with the following
- options.
-
- The "post" option causes treewalk to visit all the children of a
- directory before it visits that directory.
-
- The "both" option causes treewalk to visit a directory both before and
- after it visits all the children of that directory. If the directory
- has no subdirectories, then it will list all the files of that
- directory twice, one listing following immediately after another.
-
- The "filter" option is used to specify the filter expression. If no
- filter is provided, all files in the subtree will pass.
-
- The filter expression is similar to a C language expression, Like a C
- expression, it is false if it evaluates to 0, and true otherwise. The
- only variables in the expression are parts of the FileInfoBlock of the
- file being evaluated. They are:
-
- diskkey - for gurus only
- direntrytype - ditto
- entrytype - ditto
- filename - the name of the file in this directory (string value)
- name - the full path name of the file (string value)
- protection - the protection mask
- size - the number of bytes in the file
- numblocks - the number of blocks in the file
- date - date the file was last changed
- day - day the file was last changed
- comment - comment associated with the file (string value)
-
- The "day" version of date ignores the minutes of the day of creation,
- so that it will compare equal to a day with no time specified via the
- "`" construct. I.e., "day == `yesterday`" matches files created
- yesterday.
-
- Note to purists: The "date" value is the number of minutes since
- midnight, January 1, 1978. It's called "date" instead of "datestamp"
- because it's not a real datestamp. The protection bits `rewd` are
- inverted on output, as they have inverted meaning: the `r` bit being
- on means you _can't_ read the file. List prints a `r` when you can
- read the file. These bits are inverted to prevent the user from having
- to remember this.
-
- The FileInfoBlock values can also be gotten for other files. The same names
- as above are used, preceded by a file name and a '.'. For instance,
- main.c.size is the size of the file "main.c" in the directory treewalk
- was started in. Such expressions are evaluated at startup time, and
- are constant throughout the execution of treewalk.
-
- The other valid constants in filter expressions are:
-
- true - longhand for 1
- false - longhand for 0
- integers - The same as C:
- starting with a '0' indicates octal
- starting with a '0x' indicates hex
- otherwise, it's decimal
- "string" - a text string
- 'string' - ditto
-
- In addition any string surrounded by "`"'s is an integer constant, of
- one of two forms. If it consists of a string of characters from the
- set "rwdespah", then the appropriate bits will be turned on to match
- the protection of the file.
-
- Otherwise, this may be a date and time specifier. These are of the
- form "day minute". Day is either a fully specified numeric date of the
- form "month/day/year", a day of the week, "yesterday", or not
- specified. The "month/day/year" form uses a two-digit year between
- 1978 & 1999. The day of the week refers to the previous day of that
- name. If the day is not specified, then today is used.
-
- Time is either "noon", hour:minute on a 24-hour clock, or
- missing. If the time is missing, then midnight is assumed. If
- the day specified is today, and the time is later than the
- current time, then yesterday is assumed - even if you specify
- the day explicitly.
-
- There are some operands that depends on the file currently being
- filtered, or on the user. They are:
-
- dir - true if the current file is a directory, else false
- file - the opposite of dir
- name - the full path name of the file (string value)
- user - name is printed on the console, followed by a ?, and a line
- is read. If the first character of the line is 'y' or
- 'Y', then true, otherwise false.
-
- Finally, any non-string not recognized is assumed to be an ARexx macro
- name. The extension used in searching for the macro is "ftw". This
- macro will be invoked as a function with pathname of the directory as
- it's first argument, and the file name as it's second. The pathname
- will be in a form such that "arg(1) || arg(2)" will be the full
- pathname. The expression the macro returns should be an integer, and
- will be used as the value of the macro token in the expression.
-
- The macro may issue "commands" back to the running treewalk. The
- commands are treated as filters, and the current file is sent through
- them, and the result returned. What the result is depends on whether
- you have specified "options results". If this is not on, the rc is 0
- if the filter returns "true", and 1 if the filter returns "false". If
- the results option is on, and no errors occured, rc is always 0, and
- the result string is the value, formated as four bytes of hex. You can
- then use x2c() and import() to extract strings, if the value returned
- was a string (i.e. - you issued the command 'comment'). In either
- case, return codes greater than 1 indicate a real error - usually in
- the filter expression, sometimes that you're out of memory.
-
- As a suggestion for writing ftw macros, I recommend following the rule
- that if the macro uses the file name, it returns a 1, and if it
- rejects the file name, it returns a 0. This allows treewalk to print
- the names of the files used by the macro by 'treewalk filter macro',
- or to not print the names by 'treewalk filter "macro & false"'. Of
- course, if the macro is just a filter itself, then it should return
- either 0 or 1.
-
- To combine these, there are the operators. All but four are from C,
- and the precedence of the operators is the same as C. They are:
-
- ! - unary logical not; ~ - unary bitwise not
- & - bitwise and
- % - bitwise exclusive or
- | - bitwise or
- =*, =#, !*, !# - string compares <, >, <=, >=, == - integer comparisons
- && - logical and, short circuiting
- || - logical or, short circuiting
-
- (, ) - parens for grouping
-
-
- The only four operators not found in C are =*, =#, !* and !#. These
- are pattern matching operators for use on strings (file names or
- comments). The left-hand operand is a string, the right-hand operand
- is a pattern. =* and !* provides Unix-like regular expressions, with
- '*' and '?' having special meaning. =# and !# provides AmigaDOS like
- regular expressions, with '#' and '?' having special meanings. =* and
- =# are true if the comparisons match, and !* and !# are true if the
- comparisons don't match.
-
- The rest of the operators behave as one would expect them to. The
- only thing that needs to be pointed out is that logical and (or)
- short circuits. So if the left-hand operand is false (true), the
- right-hand operand is never evaluated. This allows a limited form of
- flow control in the filter expression.
-
- Like C, it is legal to apply the logical operators to non-boolean
- ints, and to apply the comparison operators to booleans. Unlike C,
- strings can not have their addresses extracted, and ints cannot be
- used for string addresses. Strings may only appear, and are all that
- may appear, as the operands of the pattern matching operators.
-
- As a final suggestion on filters, unless the filter is a single token,
- it's probably best to surround it in '"''s, as that will cause the
- magic characters in the expression (&, |, <, > come to mind) to not
- be interpreted by whatever CLI you are running.
-
- EXAMPLES:
-
- List all the directories in src:
-
- treewalk dir src: filter dir
-
- Delete the subtree x:
-
- treewalk dir x post single delete
-
- This isn't really very useful, as "delete all" is faster. However, it
- illustrates several points. First, "delete" is broken, as it has a
- limited number of arguments. Second, this requires the postorder
- treewalk, so that all the files in a directory will be deleted before
- the directory is deleted.
-
- Delete all .o files in the current subtree:
-
- treewalk filter "filename =# '#?.o'" single delete
-
- List all files newer than :last-backup.
-
- treewalk filter "date > :last-backup.date"
-
- Find all files on the current device older than :last-backup using
- over 20 blocks, that don't have the execute bit on, and compress them.
-
- treewalk dir : filter "date < :last-backup.date &&
- numblocks > 20 && !(protection & `e`)" compress
-
- Same as above, except we also don't compress .o files in the subtree at
- :go and we only compress if the user wants us to.
-
- treewalk dir : filter "name !* '*:go/*' &&
- date < :last-backup.date && numblocks > 20 &&
- !(protection & `e`) && user" compress
-
- This last might more efficiently be done as a Rexx macro that decides
- whether or not the file will be compressed, and then asks the user.
- Let's assume we've got a macro "munchp.ftw" that does the name, mode
- and size checking. You could then do:
-
- treewalk dir : filter "date < :last-backup.date && munchp
- && user" compress
-
- As an alternative, suppose that instead of compressing them, you
- wanted to save them to an archive somewhere, and had a rexx script to
- do that. Further, suppose that the Rexx script (archive.ftw) return 1
- if it did the archive, and 0 if it didn't. Then you might do:
-
- treewalk dir : filter "date < :last-backup.date && munchp
- && archive && false"
-
- To quietly do the archiving. Or you might do:
-
- treewalk >logs:archive.log dir :
- filter "date < :last-backup.date && munchp && archive"
-
- To list the archived files to logs:archive.log.
-
- Copyright (C) 1989 Mike Meyer
-
- This file is free documentation; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-