xref: /openbsd/gnu/usr.bin/cvs/contrib/descend.sh (revision 7b36286a)
1#! /bin/sh
2#
3# descend - walk down a directory tree and execute a command at each node
4
5fullname=$0
6name=descend
7usage="Usage: $name [-afqrv] command [directory ...]\n
8\040\040-a\040\040All: descend into directories starting with '.'\n
9\040\040-f\040\040Force: ignore errors during descent\n
10\040\040-q\040\040Quiet: don't print directory names\n
11\040\040-r\040\040Restricted: don't descend into RCS, CVS.adm, SCCS directories\n
12\040\040-v\040\040Verbose: print command before executing it"
13
14# Scan for options
15while getopts afqrv option; do
16    case $option in
17	a)
18	    alldirs=$option
19	    options=$options" "-$option
20	    ;;
21	f)
22	    force=$option
23	    options=$options" "-$option
24	    ;;
25	q)
26	    verbose=
27	    quiet=$option
28	    options=$options" "-$option
29	    ;;
30	r)
31	    restricted=$option
32	    options=$options" "-$option
33	    ;;
34	v)
35	    verbose=$option
36	    quiet=
37	    options=$options" "-$option
38	    ;;
39	\?)
40	    /usr/5bin/echo $usage 1>&2
41	    exit 1
42	    ;;
43    esac
44done
45shift `expr $OPTIND - 1`
46
47# Get command to execute
48if [ $# -lt 1 ] ; then
49    /usr/5bin/echo $usage 1>&2
50    exit 1
51else
52    command=$1
53    shift
54fi
55
56# If no directory specified, use '.'
57if [ $# -lt 1 ] ; then
58    default_dir=.
59fi
60
61# For each directory specified
62for dir in $default_dir "$@" ; do
63
64    # Spawn sub-shell so we return to starting directory afterward
65    (cd $dir
66
67	# Execute specified command
68	if [ -z "$quiet" ] ; then
69	    echo In directory `hostname`:`pwd`
70	fi
71	if [ -n "$verbose" ] ; then
72	    echo $command
73	fi
74	eval "$command" || if [ -z "$force" ] ; then exit 1; fi
75
76	# Collect dot file names if necessary
77	if [ -n "$alldirs" ] ; then
78	    dotfiles=.*
79	else
80	    dotfiles=
81	fi
82
83	# For each file in current directory
84	for file in $dotfiles * ; do
85
86	    # Skip '.' and '..'
87	    if [ "$file" = "." -o "$file" = ".." ] ; then
88		continue
89	    fi
90
91	    # If a directory but not a symbolic link
92	    if [ -d "$file" -a ! -h "$file" ] ; then
93
94		# If not skipping this type of directory
95		if [ \( "$file" != "RCS" -a \
96			"$file" != "SCCS" -a \
97			"$file" != "CVS" -a \
98			"$file" != "CVS.adm" \) \
99			-o -z "$restricted" ] ; then
100
101		    # Recursively descend into it
102		    $fullname $options "$command" "$file" \
103		    || if [ -z "$force" ] ; then exit 1; fi
104		fi
105
106	    # Else if a directory AND a symbolic link
107	    elif [ -d "$file" -a -h "$file" ] ; then
108
109		if [ -z "$quiet" ] ; then
110		    echo In directory `hostname`:`pwd`/$file: symbolic link: skipping
111		fi
112	    fi
113	done
114    ) || if [ -z "$force" ] ; then exit 1; fi
115done
116