1#! /bin/sh
2#
3# Copyright (C) 1995-2005 The Free Software Foundation, Inc.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2, or (at your option)
8# any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# descend - walk down a directory tree and execute a command at each node
16
17fullname=$0
18name=descend
19usage="Usage: $name [-afqrv] command [directory ...]\n
20\040\040-a\040\040All: descend into directories starting with '.'\n
21\040\040-f\040\040Force: ignore errors during descent\n
22\040\040-q\040\040Quiet: don't print directory names\n
23\040\040-r\040\040Restricted: don't descend into RCS, CVS.adm, SCCS directories\n
24\040\040-v\040\040Verbose: print command before executing it"
25
26# Scan for options
27while getopts afqrv option; do
28    case $option in
29	a)
30	    alldirs=$option
31	    options=$options" "-$option
32	    ;;
33	f)
34	    force=$option
35	    options=$options" "-$option
36	    ;;
37	q)
38	    verbose=
39	    quiet=$option
40	    options=$options" "-$option
41	    ;;
42	r)
43	    restricted=$option
44	    options=$options" "-$option
45	    ;;
46	v)
47	    verbose=$option
48	    quiet=
49	    options=$options" "-$option
50	    ;;
51	\?)
52	    /usr/5bin/echo $usage 1>&2
53	    exit 1
54	    ;;
55    esac
56done
57shift `expr $OPTIND - 1`
58
59# Get command to execute
60if [ $# -lt 1 ] ; then
61    /usr/5bin/echo $usage 1>&2
62    exit 1
63else
64    command=$1
65    shift
66fi
67
68# If no directory specified, use '.'
69if [ $# -lt 1 ] ; then
70    default_dir=.
71fi
72
73# For each directory specified
74for dir in $default_dir "$@" ; do
75
76    # Spawn sub-shell so we return to starting directory afterward
77    (cd $dir
78
79	# Execute specified command
80	if [ -z "$quiet" ] ; then
81	    echo In directory `hostname`:`pwd`
82	fi
83	if [ -n "$verbose" ] ; then
84	    echo $command
85	fi
86	eval "$command" || if [ -z "$force" ] ; then exit 1; fi
87
88	# Collect dot file names if necessary
89	if [ -n "$alldirs" ] ; then
90	    dotfiles=.*
91	else
92	    dotfiles=
93	fi
94
95	# For each file in current directory
96	for file in $dotfiles * ; do
97
98	    # Skip '.' and '..'
99	    if [ "$file" = "." -o "$file" = ".." ] ; then
100		continue
101	    fi
102
103	    # If a directory but not a symbolic link
104	    if [ -d "$file" -a ! -h "$file" ] ; then
105
106		# If not skipping this type of directory
107		if [ \( "$file" != "RCS" -a \
108			"$file" != "SCCS" -a \
109			"$file" != "CVS" -a \
110			"$file" != "CVS.adm" \) \
111			-o -z "$restricted" ] ; then
112
113		    # Recursively descend into it
114		    $fullname $options "$command" "$file" \
115		    || if [ -z "$force" ] ; then exit 1; fi
116		fi
117
118	    # Else if a directory AND a symbolic link
119	    elif [ -d "$file" -a -h "$file" ] ; then
120
121		if [ -z "$quiet" ] ; then
122		    echo In directory `hostname`:`pwd`/$file: symbolic link: skipping
123		fi
124	    fi
125	done
126    ) || if [ -z "$force" ] ; then exit 1; fi
127done
128