1#! @BASH_FULL_PATH@
2# Copyright (C) 2004, 2005 Stephen Bach
3# This is script is a wrapper interface to the Viewglob package.
4#
5# Viewglob 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 of the License, or
8# (at your option) any later version.
9#
10# Viewglob 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# You should have received a copy of the GNU General Public License
16# along with Viewglob; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19SCRIPT_NAME="${0##*/}"
20VG_LIB_DIR="@pkglibdir@"
21VGPING="$VG_LIB_DIR/vgping"
22
23HOST_DEFAULT=localhost
24PORT_DEFAULT=16108
25
26# Execution configuration
27REMOTE=
28VGSEER_OPTS=
29VGSEER_EXEC=vgseer
30VGD_OPTS=
31
32# We need extended globbing.
33shopt -s extglob
34
35vg_usage() {
36	cat >&2 << EOF
37usage: viewglob [-h <host>] [-p <port>] [-c <shell mode>] [-d <display>]
38                [-s <sort style>] [-r <dir ordering>] [-t <on/off>]
39                [-i <on/off>] [-z <font size modifier>]
40
41-h, --host                  Host to connect to.            [localhost]
42-p, --port                  Port to use or connect to.     [16108]
43-c, --shell-mode            Shell to use (bash or zsh).    [bash]
44-d, --display               Display program.               [vgmini]
45-s, --sort-style            Windows (dirs first) or ls.    [ls]
46-r, --dir-order             Directory list ordering.       [ascending]
47
48-t, --shell-star            Asterisk character at prompt.  [on]
49-i, --file-icons            File type icons in display.    [on]
50
51-z, --font-size-modifier    Increase/decrease display font size.
52
53-h, --help                  This usage.
54-V, --version               Print the version.
55EOF
56
57	exit 0
58}
59
60vg_error() {
61	echo "$SCRIPT_NAME: $1" >&2
62	exit $2
63}
64
65vg_version() {
66cat << EOF
67@PACKAGE_NAME@ @PACKAGE_VERSION@
68Released @RELEASE_DATE@
69EOF
70	exit 0
71}
72
73
74# Option verification functions
75
76vg_test_shell_mode() {
77	if [ "$1" != bash ] && [ "$1" != zsh ]
78		then vg_error "Shell mode must be \"bash\" or \"zsh\"" 1
79	fi
80}
81
82vg_test_display() {
83	if [ ! "$1" ]
84		then vg_error "No display program specified" 1
85	elif [ "$1" = vgmini ] || [ "$1" = vgclassic ]
86		then vg_disp="$VG_LIB_DIR/$1"
87	else
88		vg_disp="$1"
89	fi
90
91	if [ ! -x "$vg_disp" ]
92		then vg_error "$1 is not present or not executable" 1
93	fi
94}
95
96vg_test_sort_style() {
97	if [ "$1" != ls ] && [ "$1" != win ]
98		then vg_error "Unknown sort style \"$1\"" 1
99	fi
100}
101
102vg_test_dir_order() {
103	if [ "$1" != descending ] && \
104	   [ "$1" != ascending ] && \
105	   [ "$1" != ascending-pwd-first ]
106		then vg_error "Invalid directory ordering \"$1\"" 1
107	fi
108}
109
110vg_test_font_size_modifier() {
111	if [[ "$1" != ?([-+])*([0-9]) ]]
112		then vg_error "Invalid font size modifier" 1
113	fi
114}
115
116vg_test_onoff() {
117	if [[ "$OPTARG" != on ]] && [[ "$OPTARG" != off ]]
118		then vg_error "Argument must be \"on\" or \"off\"" 1
119	fi
120}
121
122
123if [[ "$VG_VIEWGLOB_ACTIVE" = yep ]]
124	then vg_error "This shell is already being monitored" 2
125elif [[ -z "$DISPLAY" ]]
126	then REMOTE=yep
127elif [[ -z "$TERM" ]] || [[ "$TERM" = dumb ]]; then
128	# There's no terminal associated with the shell, but an X display is
129	# present, so make a new xterm.  Try to use gconf-tool2 to determine
130	# a usable terminal program.
131
132	GCONF='gconftool-2'
133	if [ `which ${GCONF} 2>/dev/null` ]; then
134		TERM_EXEC="`${GCONF} -g \
135			/desktop/gnome/applications/terminal/exec \
136			2>/dev/null`"
137		TERM_EXEC_ARG="`${GCONF} -g \
138			/desktop/gnome/applications/terminal/exec_arg \
139			2>/dev/null`"
140	fi
141
142	if [ -z "$TERM_EXEC" ] || [ -z "$TERM_EXEC_ARG" ]; then
143		# Fallback to xterm.
144		TERM_EXEC=xterm
145		TERM_EXEC_ARG=-e
146	fi
147
148	VGSEER_EXEC="$TERM_EXEC $TERM_EXEC_ARG $VGSEER_EXEC"
149fi
150
151# This is an excellent script to replace bash's getopts with one which allows
152# long names.  It's written by Grigoriy Strokin.
153. $VG_LIB_DIR/getopt.sh
154
155# Parse the options.
156while getoptex "h: p: i: c: d: r: s: t: H; v; V; z: host: port: shell-mode: display: font-size-modifier: sort-style: dir-order: shell-star: file-icons: help; version;" "$@"
157	do case "$OPTOPT" in
158
159		h|host)
160			REMOTE=yep
161			HOST="$OPTARG"
162			VGSEER_OPTS="$VGSEER_OPTS --host=$OPTARG"
163			;;
164
165		p|port)
166			VGSEER_OPTS="$VGSEER_OPTS --port=$OPTARG"
167			PORT="$OPTARG"
168			VGD_OPTS="$VGD_OPTS --port=$OPTARG"
169			;;
170
171		i|file-icons)
172			vg_test_onoff "$OPTARG"
173			VGD_OPTS="$VGD_OPTS --file-icons $OPTARG"
174			;;
175
176		c|shell-mode)
177			vg_test_shell_mode "$OPTARG"
178			VGSEER_OPTS="$VGSEER_OPTS --shell-mode=$OPTARG"
179			;;
180
181		d|display)
182			vg_test_display "$OPTARG"
183			VGD_OPTS="$VGD_OPTS --display=$OPTARG"
184			;;
185
186		s|sort-style)
187			[ "$OPTARG" == windows ] && OPTARG=win
188			vg_test_sort_style "$OPTARG"
189			VGD_OPTS="$VGD_OPTS --sort-style=$OPTARG"
190			;;
191
192		r|dir-order)
193			vg_test_dir_order "$OPTARG"
194			VGD_OPTS="$VGD_OPTS --dir-order=$OPTARG"
195			;;
196
197		t|shell-star)
198			vg_test_onoff "$OPTARG"
199			VGSEER_OPTS="$VGSEER_OPTS --shell-star $OPTARG"
200			;;
201
202		z|font-size-modifier)
203			vg_test_font_size_modifier "$OPTARG"
204			VGD_OPTS="$VGD_OPTS --font-size-modifier=$OPTARG"
205			;;
206
207		H|help) vg_usage ;;
208
209		v|V|version) vg_version ;;
210
211		*) vg_error "invalid argument" 3 ;;
212	esac
213done
214shift $((OPTIND - 1))
215
216if [ "$OPTOPT" = \? ]
217	# getopt.sh already emitted an error message.
218	then exit 5
219fi
220
221# Just in case the user has turned daemonizing off in vgd.conf.
222VGD_OPTS="$VGD_OPTS --daemon=on"
223
224if [ -z "${HOST}${PORT}" ]; then
225	# A local connection is assumed.
226
227	VGSEER_OPTS="$VGSEER_OPTS --unix-socket=on"
228
229	vgd_ports=
230	nvgds=0
231
232	# Create list of active sockets, and clean out inactive ones (if any).
233	for file in $HOME/.viewglob/.*; do
234		if [[ $file == */.+([0-9]) ]]; then
235			if $VGPING dummy ${file##*/}; then
236				vgd_ports="$vgd_ports ${file##*/.}"
237				nvgds=`expr $nvgds + 1`
238			else
239				rm -f $file
240			fi
241		fi
242	done
243
244	if [ $nvgds -eq 0 ]; then
245		# There are no active vgds.
246
247		# Find an unused port for vgd and create new vgd and vgseer
248		# processes.
249		port=$PORT_DEFAULT
250		while true; do
251
252			while true; do
253			    if $VGPING localhost $port
254				then port=`expr $port + 1`
255			    else
256				break
257			    fi
258			done
259
260			vgd $VGD_OPTS --port $port
261
262			case "$?" in
263				0)
264					exec $VGSEER_EXEC $VGSEER_OPTS \
265						--port $port ;;
266				2)
267					# Socket error -- try another port.
268					continue ;;
269				*)
270					# Other error -- give up.
271					break ;;
272			esac
273		done
274
275	elif [ $nvgds -eq 1 ]; then
276		# There is a single active vgd.
277		exec $VGSEER_EXEC $VGSEER_OPTS --port $vgd_ports
278	else
279		echo "There are active vgds on the following local ports:"
280		for port in $vgd_ports; do
281			echo "	$port"
282		done
283	fi
284else
285	test -z "$HOST" && HOST=$HOST_DEFAULT
286	test -z "$PORT" && PORT=$PORT_DEFAULT
287
288	if [ "$REMOTE" = yep ]; then
289		# We're running in a displayless environment or the user
290		# specified a host to connect to.  Either case implies we're
291		# not connecting locally, and so we shouldn't create a vgd.
292
293		VGSEER_OPTS="$VGSEER_OPTS --unix-socket=off"
294
295		if ! $VGPING $HOST $PORT ; then
296			vg_error "Couldn't handshake with a vgd at \
297				${HOST}:${PORT}" 6
298		fi
299
300		exec $VGSEER_EXEC $VGSEER_OPTS --unix-socket=off
301
302	else
303		VGSEER_OPTS="$VGSEER_OPTS --unix-socket=on"
304
305		# First check for an existing vgd.  If there is one, connect
306		# to it.
307		if $VGPING $HOST .$PORT ; then
308			exec $VGSEER_EXEC $VGSEER_OPTS
309		fi
310
311		# We'll have to setup a new vgd, then exec.
312		if vgd $VGD_OPTS ; then
313			exec $VGSEER_EXEC $VGSEER_OPTS
314		fi
315	fi
316fi
317
318