home *** CD-ROM | disk | FTP | other *** search
- /*
- * Make treewalk pretend that it's a files command. Uses rexx treewalk
- * macros basename.ftw, rootname.ftw, copy.ftw, patname.ftw and
- * nonrecursive.ftw. Note that this version only allows one copy destination,
- * and one grep pattern. Files isn't documented as doing that, but behaves
- * that way in practice.
- *
- * Copyright (C) 1989 Mike Meyer
- *
- * This program is free software; 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.
- */
-
- /*
- * Start by being obnoxious, just like the real thing.
- */
- /*
- say "Files version 1a: Copyright 1989 by Mike Meyer"
- say "Interface design Copyright 1985,1988 by Lattice, Inc."
- */
-
- /*
- * Initalize variables used for arguments.
- */
- basename = ""
- copy = ""
- daydelta = 0
- days = ""
- erase = ""
- namecomp = "#=" /* Changes to *= if we see -m */
- recursive = 1
- matchname = ""
- match = ""
- newer = ""
- older = ""
- patname = ""
- rootname = ""
- size = ""
- type = ""
- verbose = ""
-
- /*
- * Now, scan args getting options
- */
- parse arg args
-
- i = 1
- do forever
- if i > words(args) then do
- Say "files [options] dir1 dir2 ..."
- exit 10
- end
-
- arg = word(args, i)
- select
- when arg = "-b" then basename = "&&basename&&false"
- when arg = "-m" then namecomp = "*="
- when arg = "-n" then recursive = 0
- when arg = "-r" then rootname = "&&rootname&&false"
- when arg = "-rerase" then erase = "post single delete"
- when arg = "-v" then verbose = "verbose"
- when arg = "-copy" then do
- i = i + 1
- call setclip "tw.copyname", word(args, i)
- copy = "&&file&©"
- end
- when arg = "-days" then do
- i = i + 1
- daydelta = word(args, i)
- end
- when arg = "-erase" then do
- erase = "single delete"
- recursive = 0
- end
- when arg = "-name" then do
- i = i + 1
- matchname = word(args, i)
- end
- when arg = "-newer" then do
- i = i + 1
- newer = "&&date>"word(args, i)
- end
- when arg = "-older" then do
- i = i + 1
- older = "&&date<"word(args, i)
- end
- when arg = "-pat" then do
- i = i + 1
- call setclip "tw.patname", word(args, i)
- patname = "&&patname"
- end
- when arg = "-size" then do
- i = i + 1
- size = "&&size>"word(args, i)
- end
- when arg = "-type" then do
- i = i + 1
- arg = word(args, i)
- select
- when arg = "f" then type = "&&file"
- when arg = "d" then type = "&&dir"
- otherwise
- say "Unrecognized -type option"
- exit 10
- end
- end
- otherwise
- leave
- end
- i = i + 1
- end
-
- /*
- * all options done, so get the directory list.
- */
- directorylist = substr(args, wordindex(args, i))
-
- /*
- * Now, check the options for interference.
- */
- if (erase ~= "" | copy ~= "") & (rootname != "" | basename ~= "") then do
- say "-b and -r flags are inconsistent with -erase, -rerase, and -copy flags"
- exit 10
- end
-
- if basename ~= "" & rootname ~= "" then do
- say "Warning: -r flag overrides -b flag"
- basename = ""
- end
-
-
- /*
- * If we are doing a copy & not an erase, then we need to fail after the
- * copy. Basename & rootname don't need this, as they just fail.
- */
- if copy ~= "" and erase = "" then copy = copy'&&false'
-
- /*
- * Check to see if we need to do a name comparison. Decide whether we're
- * going to use filename or name based on contents.
- *
- * This code doesn't do what the documentation does. Then again, neither
- * does the real files. In fact, I can't make it do much at all in when
- * it's got a "/" or ":" in the matchname.
- */
- if matchname ~= "" then do
- if verify(":/", matchname) = 0 then
- matchname = "&&filename"namecomp"`"matchname"`"
- else if left(matchcomp, 1) = '#' then
- matchname = "&&name"namecomp"`#?"matchname"`"
- else matchname = "&&name"namecomp"`*"matchname"`"
- end
-
- /*
- * If we had days specified, then count backwards over years & then months.
- */
- if daydelta > 0 then do
- parse value date('USA') with month '/' dom '/' year
- days = date('Days')
- do while daydelta > 0
- if daydelta < dom then do
- dom = dom - daydelta
- daydelta = 0
- end
- else if daydelta > days then do
- month = 12
- dom = 31
- year = year - 1
- daydelta = daydelta - days
- if year // 4 = 0 then days = 366
- else days = 365
- end
- else do
- daydelta = daydelta - dom
- if month > 7 then
- if month // 2 = 1 then dom = 31
- else dom = 30
- else if month = 3 then
- if year // 4 = 0 then dom = 29
- else dom = 28
- else if month // 2 = 1 then dom = 30
- else dom = 31
-
- month = month - 1
- if month = 0 then do
- month = 12
- year = year - 1
- dom = 31 /* oh well... */
- if year // 4 = 0 then days = 366
- else days = 365
- end
- end
- end
-
- days = "&&day>`"dom"/"month"/"year"`"
- end
-
- /*
- * Check recursive, cause we don't do anything else..
- */
- if ~recursive then do
- say "We don't do that yet"
- exit 5
- end
-
- /*
- * ok, all done. Now build the filter, and run the sucker.
- */
-
- filter = days||matchname||newer||older||patname||size||type||basename||rootname||copy
- if filter ~= "" then filter = 'filter "true'filter'"' verbose erase
- else filter = verbose erase
-
- do i = 1 to words(directorylist)
- dir = word(directorylist, i)
- /*
- * Various options depend on knowing the "full path" to the directory
- * that roots the tree we're going to walk. To make that work, we put
- * the directory name in a clip, and clear a clip for paths. The first
- * time something needs the path, the fullpath clip will be found
- * empty, so it will be computed and filled. Ugly, but needed.
- */
- call setclip "tw.dirname", dir
- call setclip "tw.fullpath"
- "treewalk dir" dir filter
- end
-
- /* Clean up the clips */
- call setclip "tw.dirname"
- call setclip "tw.fullpath"
- call setclip "tw.copyname"
- call setclip "tw.patname"
- exit 0
-