commit c4b4d74

xplshn  ·  2026-07-01 01:09:02 +0000 UTC
parent fd3a93f
clang-format, mkpasswd, lsblk, fdisk, blkid, in-process execution, etc

Signed-off-by: xplshn <anto@xplshn.com.ar>
74 files changed,  +14544, -13463
+26, -14
 1@@ -7,6 +7,7 @@ HDR =\
 2 	shared/compat.h\
 3 	shared/config.h\
 4 	shared/crypt.h\
 5+	shared/wexec.h\
 6 	shared/fs.h\
 7 	shared/md5.h\
 8 	shared/queue.h\
 9@@ -21,6 +22,7 @@ HDR =\
10 	shared/utf.h\
11 	shared/util.h\
12 	shared/passwd.h\
13+	shared/paths.h\
14 	shared/reboot.h\
15 	shared/rtc.h\
16 	shared/proc.h\
17@@ -52,6 +54,8 @@ LIBUTILOBJ =\
18 	shared/libutil/cp.o\
19 	shared/libutil/crypt.o\
20 	shared/libutil/confirm.o\
21+	shared/libutil/diffutil.o\
22+	shared/libutil/wexec.o\
23 	shared/libutil/ealloc.o\
24 	shared/libutil/enmasse.o\
25 	shared/libutil/eprintf.o\
26@@ -734,20 +738,28 @@ man: scripts/mkman/mkman
27 	done
28 
29 clean:
30-	rm -f shared/libutf/*.o shared/libutil/*.o shared/libredline/*.o
31-	rm -f cmd/posix/*.o cmd/posix/make/*.o cmd/posix/awk/*.o cmd/posix/sh/*.o
32-	rm -f cmd/linux/*.o cmd/net/*.o cmd/xsi/*.o cmd/pseudo/*.o
33-	rm -f cmd/extra/*.o cmd/dev/ar/*.o cmd/dev/ld/*.o cmd/dev/cc/*.o cmd/dev/as/*.o cmd/dev/xcutil/*.o
34-	rm -f $(POSIX_BIN_ALL) $(LINUX_BIN_ALL) $(NET_BIN_ALL) $(XSI_BIN_ALL) $(PSEUDO_BIN_ALL) $(LIB)
35-	rm -f cmd/posix/make/make cmd/posix/getconf.h cmd/posix/bc.c
36-	rm -f
37-	rm -f cmd/posix/awk/awk cmd/posix/awk/maketab cmd/posix/awk/awkgram.tab.c cmd/posix/awk/awkgram.tab.h cmd/posix/awk/proctab.c
38-	rm -f cmd/posix/sh/sh cmd/posix/sh/mknodes cmd/posix/sh/mksyntax
39-	rm -f cmd/posix/sh/syntax.c cmd/posix/sh/syntax.h cmd/posix/sh/nodes.c cmd/posix/sh/nodes.h cmd/posix/sh/builtins.c cmd/posix/sh/builtins.h cmd/posix/sh/token.h
40-	rm -f cmd/dev/cc/cc1 cmd/dev/cc/cpp cmd/dev/as/as cmd/dev/ld/ld cmd/dev/ar/ar shared/libaruuelf.so
41-	rm -f cmd/dev/config.h cmd/dev/cc/config.h cmd/dev/version.h
42-	rm -rf aruu-box .box man/man1 man/man8 scripts/mkman/mkman
43-
44+	@printf "  CLEAN object files\n"
45+	@find shared cmd -name "*.o" -exec rm -f {} +
46+	@printf "  CLEAN static libraries\n"
47+	@rm -f $(LIB)
48+	@printf "  CLEAN compiled binaries\n"
49+	@rm -f $(POSIX_BIN_ALL) $(LINUX_BIN_ALL) $(NET_BIN_ALL) $(XSI_BIN_ALL) $(PSEUDO_BIN_ALL)
50+	@printf "  CLEAN generated headers\n"
51+	@rm -f cmd/posix/getconf.h cmd/posix/bc.c
52+	@rm -f cmd/posix/awk/awkgram.tab.c cmd/posix/awk/awkgram.tab.h
53+	@rm -f cmd/posix/sh/token.h cmd/posix/sh/syntax.c cmd/posix/sh/syntax.h
54+	@rm -f cmd/posix/sh/nodes.c cmd/posix/sh/nodes.h cmd/posix/sh/builtins.c cmd/posix/sh/builtins.h
55+	@printf "  CLEAN generated sources\n"
56+	@rm -f cmd/posix/awk/proctab.c
57+	@printf "  CLEAN build tools\n"
58+	@rm -f cmd/posix/awk/maketab cmd/posix/sh/mknodes cmd/posix/sh/mksyntax
59+	@rm -f scripts/mkman/mkman
60+	@printf "  CLEAN dev artifacts\n"
61+	@rm -f cmd/dev/cc/cc1 cmd/dev/cc/cpp cmd/dev/as/as cmd/dev/ld/ld cmd/dev/ar/ar shared/libaruuelf.so
62+	@rm -f cmd/dev/config.h cmd/dev/cc/config.h cmd/dev/version.h
63+	@printf "  CLEAN misc\n"
64+	@rm -rf aruu-box .box man/man1 man/man8
65+	@printf "  CLEAN done\n"
66 AWKOBJ =\
67 	cmd/posix/awk/b.o\
68 	cmd/posix/awk/main.o\
+406, -393
  1@@ -14,15 +14,15 @@ LOAD=0
  2 TARGET=all
  3 
  4 while [ $# -gt 0 ]; do
  5-	case "$1" in
  6-		-j)  shift; JOBS="${1:?-j requires a number}" ;;
  7-		-j*) JOBS="${1#-j}" ;;
  8-		-l)  shift; LOAD="${1:?-l requires a number}" ;;
  9-		-l*) LOAD="${1#-l}" ;;
 10-		-*)  printf 'unknown flag: %s\n' "$1" >&2; exit 1 ;;
 11-		*)   TARGET="$1" ;;
 12-	esac
 13-	shift
 14+        case "$1" in
 15+                -j)  shift; JOBS="${1:?-j requires a number}" ;;
 16+                -j*) JOBS="${1#-j}" ;;
 17+                -l)  shift; LOAD="${1:?-l requires a number}" ;;
 18+                -l*) LOAD="${1#-l}" ;;
 19+                -*)  printf 'unknown flag: %s\n' "$1" >&2; exit 1 ;;
 20+                *)   TARGET="$1" ;;
 21+        esac
 22+        shift
 23 done
 24 
 25 [ -f build.cfg ] || { printf 'build.cfg not found; see the repository README\n' >&2; exit 1; }
 26@@ -32,45 +32,45 @@ done
 27 # cppflags derived from build.cfg; any feature_* added there is picked up automatically
 28 _feature_flags=""
 29 while IFS= read -r _line; do
 30-	_trimmed=$(printf '%s' "$_line" | tr -d ' \t')
 31-	case "$_trimmed" in
 32-		FEATURE_*=*)
 33-			_key=${_trimmed%%=*}
 34-			eval "_val=\$$_key"
 35-			_feature_flags="$_feature_flags -D${_key}=${_val}"
 36-			;;
 37-	esac
 38+        _trimmed=$(printf '%s' "$_line" | tr -d ' \t')
 39+        case "$_trimmed" in
 40+                FEATURE_*=*)
 41+                        _key=${_trimmed%%=*}
 42+                        eval "_val=\$$_key"
 43+                        _feature_flags="$_feature_flags -D${_key}=${_val}"
 44+                        ;;
 45+        esac
 46 done <<EOF
 47 $(tr ';' '\n' < build.cfg)
 48 EOF
 49 unset _line _key _val _trimmed
 50 CPPFLAGS="-Ishared -DPREFIX=\"$PREFIX\" -D_DEFAULT_SOURCE -D_GNU_SOURCE -D_NETBSD_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_FILE_OFFSET_BITS=64$_feature_flags"
 51 if [ "$FEATURE_USE_BEARSSL" = "1" ]; then
 52-	if pkg-config --exists libbearssl 2>/dev/null; then
 53-		CPPFLAGS="$CPPFLAGS $(pkg-config --cflags libbearssl)"
 54-		TLS_LDLIBS="$TLS_LDLIBS $(pkg-config --libs libbearssl)"
 55-	elif pkg-config --exists bearssl 2>/dev/null; then
 56-		CPPFLAGS="$CPPFLAGS $(pkg-config --cflags bearssl)"
 57-		TLS_LDLIBS="$TLS_LDLIBS $(pkg-config --libs bearssl)"
 58-	else
 59-		TLS_LDLIBS="$TLS_LDLIBS -LexternalRepos/BearSSL/build -lbearssl"
 60-	fi
 61+        if pkg-config --exists libbearssl 2>/dev/null; then
 62+                CPPFLAGS="$CPPFLAGS $(pkg-config --cflags libbearssl)"
 63+                TLS_LDLIBS="$TLS_LDLIBS $(pkg-config --libs libbearssl)"
 64+        elif pkg-config --exists bearssl 2>/dev/null; then
 65+                CPPFLAGS="$CPPFLAGS $(pkg-config --cflags bearssl)"
 66+                TLS_LDLIBS="$TLS_LDLIBS $(pkg-config --libs bearssl)"
 67+        else
 68+                TLS_LDLIBS="$TLS_LDLIBS -LexternalRepos/BearSSL/build -lbearssl"
 69+        fi
 70 fi
 71 if [ "$FEATURE_USE_LIBRESSL" = "1" ]; then
 72-	if pkg-config --exists libtls 2>/dev/null; then
 73-		CPPFLAGS="$CPPFLAGS $(pkg-config --cflags libtls)"
 74-		TLS_LDLIBS="$TLS_LDLIBS $(pkg-config --libs libtls)"
 75-	else
 76-		TLS_LDLIBS="$TLS_LDLIBS -ltls"
 77-	fi
 78+        if pkg-config --exists libtls 2>/dev/null; then
 79+                CPPFLAGS="$CPPFLAGS $(pkg-config --cflags libtls)"
 80+                TLS_LDLIBS="$TLS_LDLIBS $(pkg-config --libs libtls)"
 81+        else
 82+                TLS_LDLIBS="$TLS_LDLIBS -ltls"
 83+        fi
 84 fi
 85 if [ "$FEATURE_USE_OPENSSL" = "1" ]; then
 86-	if pkg-config --exists openssl 2>/dev/null; then
 87-		CPPFLAGS="$CPPFLAGS $(pkg-config --cflags openssl)"
 88-		TLS_LDLIBS="$TLS_LDLIBS $(pkg-config --libs openssl)"
 89-	else
 90-		TLS_LDLIBS="$TLS_LDLIBS -lssl -lcrypto"
 91-	fi
 92+        if pkg-config --exists openssl 2>/dev/null; then
 93+                CPPFLAGS="$CPPFLAGS $(pkg-config --cflags openssl)"
 94+                TLS_LDLIBS="$TLS_LDLIBS $(pkg-config --libs openssl)"
 95+        else
 96+                TLS_LDLIBS="$TLS_LDLIBS -lssl -lcrypto"
 97+        fi
 98 fi
 99 unset _feature_flags
100 
101@@ -91,22 +91,22 @@ EXTRA_HDR=
102 # timestamp comparison
103 #
104 mtime() {
105-	stat -c '%Y' "$1" 2>/dev/null || stat -f '%m' "$1" 2>/dev/null || echo 0
106+        stat -c '%Y' "$1" 2>/dev/null || stat -f '%m' "$1" 2>/dev/null || echo 0
107 }
108 
109 newer_than() {
110-	local s t
111-	[ -e "$2" ] || return 0
112-	s=$(mtime "$1"); t=$(mtime "$2")
113-	[ "$s" -gt "$t" ]
114+        local s t
115+        [ -e "$2" ] || return 0
116+        s=$(mtime "$1"); t=$(mtime "$2")
117+        [ "$s" -gt "$t" ]
118 }
119 
120 any_newer_than() {
121-	local target="$1"; shift
122-	for src do
123-		newer_than "$src" "$target" && return 0
124-	done
125-	return 1
126+        local target="$1"; shift
127+        for src do
128+                newer_than "$src" "$target" && return 0
129+        done
130+        return 1
131 }
132 
133 # parallel job queue
134@@ -119,441 +119,454 @@ _objs=""
135 
136 # wraps arg in single quotes, escaping embedded ones, for safe eval
137 shquote() {
138-	printf "'"
139-	printf '%s' "$1" | sed "s/'/'\\\\''/g"
140-	printf "'"
141+        printf "'"
142+        printf '%s' "$1" | sed "s/'/'\\\\''/g"
143+        printf "'"
144 }
145 
146 enqueue() {
147-	local desc="$1" cmd="$2"
148-	_qn=$((_qn + 1))
149-	local s="$WORKDIR/j${_qn}.sh"
150-	{
151-		printf '#!/bin/sh\n'
152-		printf 'printf "%%s\\n" %s\n' "$(shquote "$desc")"
153-		printf 'eval %s\n'            "$(shquote "$cmd")"
154-	} > "$s"
155-	_queue="$_queue $_qn"
156+        local desc="$1" cmd="$2"
157+        _qn=$((_qn + 1))
158+        local s="$WORKDIR/j${_qn}.sh"
159+        {
160+                printf '#!/bin/sh\n'
161+                printf 'printf "%%s\\n" %s\n' "$(shquote "$desc")"
162+                printf 'eval %s\n'            "$(shquote "$cmd")"
163+        } > "$s"
164+        _queue="$_queue $_qn"
165 }
166 
167 # silently skipped on systems without /proc/loadavg
168 _wait_for_load() {
169-	[ "$LOAD" -eq 0 ] && return 0
170-	local avg
171-	while true; do
172-		avg=$(awk '{printf "%d", int($1 + 0.5)}' /proc/loadavg 2>/dev/null) || return 0
173-		[ "$avg" -le "$LOAD" ] && return 0
174-		sleep 1
175-	done
176+        [ "$LOAD" -eq 0 ] && return 0
177+        local avg
178+        while true; do
179+                avg=$(awk '{printf "%d", int($1 + 0.5)}' /proc/loadavg 2>/dev/null) || return 0
180+                [ "$avg" -le "$LOAD" ] && return 0
181+                sleep 1
182+        done
183 }
184 
185 drain() {
186-	[ -z "$_queue" ] && return 0
187-	local n
188-	_wait_for_load
189-	if [ "$JOBS" -le 1 ]; then
190-		for n in $_queue; do
191-			sh "$WORKDIR/j${n}.sh" || { printf 'error: build step failed\n' >&2; exit 1; }
192-		done
193-	else
194-		# xargs -P (POSIX 2024), -n 1 so each path becomes its own sh invocation
195-		for n in $_queue; do
196-			printf '%s\n' "$WORKDIR/j${n}.sh"
197-		done | xargs -P "$JOBS" -n 1 sh || { printf 'error: build step failed\n' >&2; exit 1; }
198-	fi
199-	_queue=""
200+        [ -z "$_queue" ] && return 0
201+        local n
202+        _wait_for_load
203+        if [ "$JOBS" -le 1 ]; then
204+                for n in $_queue; do
205+                        sh "$WORKDIR/j${n}.sh" || { printf 'error: build step failed\n' >&2; exit 1; }
206+                done
207+        else
208+                # xargs -P (POSIX 2024), -n 1 so each path becomes its own sh invocation
209+                for n in $_queue; do
210+                        printf '%s\n' "$WORKDIR/j${n}.sh"
211+                done | xargs -P "$JOBS" -n 1 sh || { printf 'error: build step failed\n' >&2; exit 1; }
212+        fi
213+        _queue=""
214 }
215 
216 # compile and link primitives
217 #
218 compile_c() {
219-	local src="$1" obj="$2"; shift 2
220-	# shellcheck disable=SC2086
221-	any_newer_than "$obj" "$src" $HDR $EXTRA_HDR || return 0
222-	enqueue "  CC  $obj" "$CC $* $CPPFLAGS $CFLAGS -o $obj -c $src"
223+        local src="$1" obj="$2"; shift 2
224+        # shellcheck disable=SC2086
225+        any_newer_than "$obj" "$src" $HDR $EXTRA_HDR || return 0
226+        enqueue "  CC  $obj" "$CC $* $CPPFLAGS $CFLAGS -o $obj -c $src"
227 }
228 
229 link_bin() {
230-	local bin="$1" objs="" libs="" sep=0; shift
231-	for a do
232-		if   [ "$a" = "--" ]; then sep=1
233-		elif [ "$sep" = 0  ]; then objs="$objs $a"
234-		else                        libs="$libs $a"
235-		fi
236-	done
237-	drain
238-	# shellcheck disable=SC2086
239-	any_newer_than "$bin" $objs || return 0
240-	printf '  LD  %s\n' "$bin"
241-	# shellcheck disable=SC2086
242-	if [ "${bin##*/}" = "wget" ]; then
243-		eval "$CC $LDFLAGS -o $bin $objs $libs $LDLIBS $TLS_LDLIBS"
244-	else
245-		eval "$CC $LDFLAGS -o $bin $objs $libs $LDLIBS"
246-	fi
247+        local bin="$1" objs="" libs="" sep=0; shift
248+        for a do
249+                if   [ "$a" = "--" ]; then sep=1
250+                elif [ "$sep" = 0  ]; then objs="$objs $a"
251+                else                        libs="$libs $a"
252+                fi
253+        done
254+        drain
255+        # shellcheck disable=SC2086
256+        any_newer_than "$bin" $objs || return 0
257+        printf '  LD  %s\n' "$bin"
258+        # shellcheck disable=SC2086
259+        if [ "${bin##*/}" = "wget" ]; then
260+                eval "$CC $LDFLAGS -o $bin $objs $libs $LDLIBS $TLS_LDLIBS"
261+        else
262+                eval "$CC $LDFLAGS -o $bin $objs $libs $LDLIBS"
263+        fi
264 }
265 
266 # writes to _objs rather than stdout so the caller avoids a subshell that
267 # would discard enqueued jobs
268 objs_for() {
269-	local dir="$1" skip=" $2 " flags="$3" src base
270-	_objs=""
271-	for src in "$dir"/*.c; do
272-		[ -f "$src" ] || continue
273-		base=${src##*/}
274-		case "$skip" in *" $base "*) continue ;; esac
275-		compile_c "$src" "${src%.c}.o" $flags
276-		_objs="$_objs ${src%.c}.o"
277-	done
278+        local dir="$1" skip=" $2 " flags="$3" src base
279+        _objs=""
280+        for src in "$dir"/*.c; do
281+                [ -f "$src" ] || continue
282+                base=${src##*/}
283+                case "$skip" in *" $base "*) continue ;; esac
284+                compile_c "$src" "${src%.c}.o" $flags
285+                _objs="$_objs ${src%.c}.o"
286+        done
287 }
288 
289 # static libraries
290 #
291 # both directories enqueued before the single drain so they compile in parallel
292 build_lib() {
293-	local utf_objs util_objs redline_objs
294-	objs_for shared/libutf "" ""
295-	utf_objs="$_objs"
296-	objs_for shared/libutil "" ""
297-	util_objs="$_objs"
298-	objs_for shared/libredline "" ""
299-	redline_objs="$_objs"
300-	drain
301-	# shellcheck disable=SC2086
302-	any_newer_than shared/libutf/libutf.a $utf_objs && {
303-		printf '  AR  shared/libutf/libutf.a\n'
304-		$AR $ARFLAGS shared/libutf/libutf.a $utf_objs
305-		$RANLIB shared/libutf/libutf.a
306-	}
307-	# shellcheck disable=SC2086
308-	any_newer_than shared/libutil/libutil.a $util_objs && {
309-		printf '  AR  shared/libutil/libutil.a\n'
310-		$AR $ARFLAGS shared/libutil/libutil.a $util_objs
311-		$RANLIB shared/libutil/libutil.a
312-	}
313-	# shellcheck disable=SC2086
314-	any_newer_than shared/libredline/libredline.a $redline_objs && {
315-		printf '  AR  shared/libredline/libredline.a\n'
316-		$AR $ARFLAGS shared/libredline/libredline.a $redline_objs
317-		$RANLIB shared/libredline/libredline.a
318-	}
319-	return 0
320+        local utf_objs util_objs redline_objs
321+        objs_for shared/libutf "" ""
322+        utf_objs="$_objs"
323+        objs_for shared/libutil "" ""
324+        util_objs="$_objs"
325+        objs_for shared/libredline "" ""
326+        redline_objs="$_objs"
327+        drain
328+        # shellcheck disable=SC2086
329+        any_newer_than shared/libutf/libutf.a $utf_objs && {
330+                printf '  AR  shared/libutf/libutf.a\n'
331+                $AR $ARFLAGS shared/libutf/libutf.a $utf_objs
332+                $RANLIB shared/libutf/libutf.a
333+        }
334+        # shellcheck disable=SC2086
335+        any_newer_than shared/libutil/libutil.a $util_objs && {
336+                printf '  AR  shared/libutil/libutil.a\n'
337+                $AR $ARFLAGS shared/libutil/libutil.a $util_objs
338+                $RANLIB shared/libutil/libutil.a
339+        }
340+        # shellcheck disable=SC2086
341+        any_newer_than shared/libredline/libredline.a $redline_objs && {
342+                printf '  AR  shared/libredline/libredline.a\n'
343+                $AR $ARFLAGS shared/libredline/libredline.a $redline_objs
344+                $RANLIB shared/libredline/libredline.a
345+        }
346+        return 0
347 }
348 
349 # per-tool category builder
350 #
351 cfgvar() {
352-	local cat="$1" base="$2"
353-	[ "$cat" = extra ] && cat=pseudo
354-	printf 'BUILD_%s_%s' "$cat" "$base" | tr 'a-z-' 'A-Z_'
355+        local cat="$1" base="$2"
356+        [ "$cat" = extra ] && cat=pseudo
357+        printf 'BUILD_%s_%s' "$cat" "$base" | tr 'a-z-' 'A-Z_'
358 }
359 
360 # individual flag overrides group flag
361 cfg_enabled() {
362-	local _var="$1" _v
363-	while [ -n "$_var" ]; do
364-		eval "_v=\${${_var}-UNSET}"
365-		if [ "$_v" = "1" ]; then
366-			return 0
367-		elif [ "$_v" = "0" ]; then
368-			return 1
369-		fi
370-		case "$_var" in
371-			*_[!_]*) _var=$(printf '%s' "$_var" | sed 's/_[^_]*$//') ;;
372-			*)       break ;;
373-		esac
374-	done
375-	return 1
376+        local _var="$1" _v
377+        while [ -n "$_var" ]; do
378+                eval "_v=\${${_var}-UNSET}"
379+                if [ "$_v" = "1" ]; then
380+                        return 0
381+                elif [ "$_v" = "0" ]; then
382+                        return 1
383+                fi
384+                case "$_var" in
385+                        *_[!_]*) _var=$(printf '%s' "$_var" | sed 's/_[^_]*$//') ;;
386+                        *)       break ;;
387+                esac
388+        done
389+        return 1
390 }
391 
392 build_simple_tools() {
393-	local cat="$1" src base var staged=""
394-	for src in cmd/"$cat"/*.c; do
395-		[ -f "$src" ] || continue
396-		base=${src##*/}; base=${base%.c}
397-		var=$(cfgvar "$cat" "$base")
398-		cfg_enabled "$var" || continue
399-		compile_c "$src" "${src%.c}.o"
400-		staged="$staged ${src%.c}"
401-	done
402-	drain
403-	local bin
404-	for bin in $staged; do
405-		if [ "${bin##*/}" = "diff" ]; then
406-			link_bin "$bin" "${bin}.o" -- $LIB -lm
407-		else
408-			link_bin "$bin" "${bin}.o" -- $LIB
409-		fi
410-	done
411+        local cat="$1" src base var staged=""
412+        for src in cmd/"$cat"/*.c; do
413+                [ -f "$src" ] || continue
414+                base=${src##*/}; base=${base%.c}
415+                var=$(cfgvar "$cat" "$base")
416+                cfg_enabled "$var" || continue
417+                compile_c "$src" "${src%.c}.o"
418+                staged="$staged ${src%.c}"
419+        done
420+        drain
421+        local bin
422+        for bin in $staged; do
423+                if [ "${bin##*/}" = "diff" ]; then
424+                        link_bin "$bin" "${bin}.o" -- $LIB -lm
425+                else
426+                        link_bin "$bin" "${bin}.o" -- $LIB
427+                fi
428+        done
429 }
430 
431 build_awk() {
432-	cfg_enabled BUILD_POSIX_AWK || return 0
433-	local dir=cmd/posix/awk
434-
435-	any_newer_than "$dir/awkgram.tab.c" "$dir/awkgram.y" && {
436-		if   command -v yacc  >/dev/null 2>&1; then
437-			printf '  YACC  %s/awkgram.tab.c\n' "$dir"
438-			yacc  -d -o "$dir/awkgram.tab.c" "$dir/awkgram.y"
439-			if [ ! -f "$dir/awkgram.tab.h" ]; then
440-				if [ -f y.tab.h ]; then
441-					mv y.tab.h "$dir/awkgram.tab.h"
442-				elif [ -f "$dir/y.tab.h" ]; then
443-					mv "$dir/y.tab.h" "$dir/awkgram.tab.h"
444-				fi
445-			fi
446-		elif command -v bison >/dev/null 2>&1; then
447-			printf '  BISON %s/awkgram.tab.c\n' "$dir"
448-			bison -d -o "$dir/awkgram.tab.c" "$dir/awkgram.y"
449-		else
450-			printf 'awk: no yacc/bison; using pre-generated awkgram.tab.c\n' >&2
451-		fi
452-	}
453-
454-	any_newer_than "$dir/maketab" "$dir/maketab.c" "$dir/awkgram.tab.h" && {
455-		printf '  CC    %s/maketab\n' "$dir"
456-		eval "$CC $CFLAGS -o $dir/maketab $dir/maketab.c"
457-	}
458-
459-	any_newer_than "$dir/proctab.c" "$dir/maketab" && {
460-		printf '  GEN   %s/proctab.c\n' "$dir"
461-		"$dir/maketab" "$dir/awkgram.tab.h" > "$dir/proctab.c"
462-	}
463-
464-	EXTRA_HDR="$dir/awk.h $dir/awkgram.tab.h $dir/proto.h"
465-	objs_for "$dir" maketab.c "-I$dir"
466-	EXTRA_HDR=
467-	link_bin "$dir/awk" $_objs -- $LIB -lm
468+        cfg_enabled BUILD_POSIX_AWK || return 0
469+        local dir=cmd/posix/awk
470+
471+        any_newer_than "$dir/awkgram.tab.c" "$dir/awkgram.y" && {
472+                if   command -v yacc  >/dev/null 2>&1; then
473+                        printf '  YACC  %s/awkgram.tab.c\n' "$dir"
474+                        yacc  -d -o "$dir/awkgram.tab.c" "$dir/awkgram.y"
475+                        if [ ! -f "$dir/awkgram.tab.h" ]; then
476+                                if [ -f y.tab.h ]; then
477+                                        mv y.tab.h "$dir/awkgram.tab.h"
478+                                elif [ -f "$dir/y.tab.h" ]; then
479+                                        mv "$dir/y.tab.h" "$dir/awkgram.tab.h"
480+                                fi
481+                        fi
482+                elif command -v bison >/dev/null 2>&1; then
483+                        printf '  BISON %s/awkgram.tab.c\n' "$dir"
484+                        bison -d -o "$dir/awkgram.tab.c" "$dir/awkgram.y"
485+                else
486+                        printf 'awk: no yacc/bison; using pre-generated awkgram.tab.c\n' >&2
487+                fi
488+        }
489+
490+        any_newer_than "$dir/maketab" "$dir/maketab.c" "$dir/awkgram.tab.h" && {
491+                printf '  CC    %s/maketab\n' "$dir"
492+                eval "$CC $CFLAGS -o $dir/maketab $dir/maketab.c"
493+        }
494+
495+        any_newer_than "$dir/proctab.c" "$dir/maketab" && {
496+                printf '  GEN   %s/proctab.c\n' "$dir"
497+                "$dir/maketab" "$dir/awkgram.tab.h" > "$dir/proctab.c"
498+        }
499+
500+        EXTRA_HDR="$dir/awk.h $dir/awkgram.tab.h $dir/proto.h"
501+        objs_for "$dir" maketab.c "-I$dir"
502+        EXTRA_HDR=
503+        link_bin "$dir/awk" $_objs -- $LIB -lm
504 }
505 
506 build_sh() {
507-	cfg_enabled BUILD_POSIX_SH || return 0
508-	local dir=cmd/posix/sh
509-
510-	any_newer_than "$dir/mknodes" "$dir/mknodes.c" && {
511-		printf '  CC    %s/mknodes\n' "$dir"
512-		eval "$CC $CFLAGS -o $dir/mknodes $dir/mknodes.c"
513-	}
514-
515-	any_newer_than "$dir/mksyntax" "$dir/mksyntax.c" && {
516-		printf '  CC    %s/mksyntax\n' "$dir"
517-		eval "$CC $CPPFLAGS -I$dir $CFLAGS -o $dir/mksyntax $dir/mksyntax.c"
518-	}
519-
520-	any_newer_than "$dir/token.h" "$dir/mktokens" && {
521-		printf '  GEN   %s/token.h\n' "$dir"
522-		(cd "$dir" && sh mktokens)
523-	}
524-
525-	any_newer_than "$dir/syntax.c" "$dir/mksyntax" && {
526-		printf '  GEN   %s/syntax.c\n' "$dir"
527-		(cd "$dir" && ./mksyntax)
528-	}
529-
530-	any_newer_than "$dir/nodes.c" "$dir/mknodes" "$dir/nodetypes" "$dir/nodes.c.pat" && {
531-		printf '  GEN   %s/nodes.c\n' "$dir"
532-		(cd "$dir" && ./mknodes nodetypes nodes.c.pat)
533-	}
534-
535-	any_newer_than "$dir/builtins.c" "$dir/mkbuiltins" "$dir/builtins.def" "$dir/shell.h" && {
536-		printf '  GEN   %s/builtins.c\n' "$dir"
537-		(cd "$dir" && sh mkbuiltins .)
538-	}
539-
540-	EXTRA_HDR="$dir/syntax.h $dir/nodes.h $dir/builtins.h $dir/token.h"
541-	objs_for "$dir" "mknodes.c mksyntax.c" "-DSHELL -I$dir"
542-	EXTRA_HDR=
543-	link_bin "$dir/sh" $_objs -- $LIB
544+        cfg_enabled BUILD_POSIX_SH || return 0
545+        local dir=cmd/posix/sh
546+
547+        any_newer_than "$dir/mknodes" "$dir/mknodes.c" && {
548+                printf '  CC    %s/mknodes\n' "$dir"
549+                eval "$CC $CFLAGS -o $dir/mknodes $dir/mknodes.c"
550+        }
551+
552+        any_newer_than "$dir/mksyntax" "$dir/mksyntax.c" && {
553+                printf '  CC    %s/mksyntax\n' "$dir"
554+                eval "$CC $CPPFLAGS -I$dir $CFLAGS -o $dir/mksyntax $dir/mksyntax.c"
555+        }
556+
557+        any_newer_than "$dir/token.h" "$dir/mktokens" && {
558+                printf '  GEN   %s/token.h\n' "$dir"
559+                (cd "$dir" && sh mktokens)
560+        }
561+
562+        any_newer_than "$dir/syntax.c" "$dir/mksyntax" && {
563+                printf '  GEN   %s/syntax.c\n' "$dir"
564+                (cd "$dir" && ./mksyntax)
565+        }
566+
567+        any_newer_than "$dir/nodes.c" "$dir/mknodes" "$dir/nodetypes" "$dir/nodes.c.pat" && {
568+                printf '  GEN   %s/nodes.c\n' "$dir"
569+                (cd "$dir" && ./mknodes nodetypes nodes.c.pat)
570+        }
571+
572+        any_newer_than "$dir/builtins.c" "$dir/mkbuiltins" "$dir/builtins.def" "$dir/shell.h" && {
573+                printf '  GEN   %s/builtins.c\n' "$dir"
574+                (cd "$dir" && sh mkbuiltins .)
575+        }
576+
577+        EXTRA_HDR="$dir/syntax.h $dir/nodes.h $dir/builtins.h $dir/token.h"
578+        objs_for "$dir" "mknodes.c mksyntax.c" "-DSHELL -I$dir"
579+        EXTRA_HDR=
580+        link_bin "$dir/sh" $_objs -- $LIB
581 }
582 
583 build_make() {
584-	cfg_enabled BUILD_POSIX_MAKE || return 0
585-	local dir=cmd/posix/make
586-	EXTRA_HDR="$dir/make.h"
587-	objs_for "$dir" "" ""
588-	EXTRA_HDR=
589-	link_bin "$dir/make" $_objs -- $LIB
590+        cfg_enabled BUILD_POSIX_MAKE || return 0
591+        local dir=cmd/posix/make
592+        EXTRA_HDR="$dir/make.h"
593+        objs_for "$dir" "" ""
594+        EXTRA_HDR=
595+        link_bin "$dir/make" $_objs -- $LIB
596 }
597 
598 build_posix() {
599-	cfg_enabled BUILD_POSIX_GETCONF && [ ! -f cmd/posix/getconf.h ] && {
600-		printf '  GEN   cmd/posix/getconf.h\n'
601-		scripts/getconf.sh > cmd/posix/getconf.h || { rm -f cmd/posix/getconf.h; exit 1; }
602-	}
603-	build_simple_tools posix
604-	build_awk
605-	build_sh
606-	build_make
607+        cfg_enabled BUILD_POSIX_GETCONF && [ ! -f cmd/posix/getconf.h ] && {
608+                printf '  GEN   cmd/posix/getconf.h\n'
609+                scripts/getconf.sh > cmd/posix/getconf.h || { rm -f cmd/posix/getconf.h; exit 1; }
610+        }
611+        build_simple_tools posix
612+        build_awk
613+        build_sh
614+        build_make
615 }
616 
617 # multi-file dev toolchain
618 #
619 build_ar() {
620-	cfg_enabled BUILD_DEV_AR || return 0
621-	local dir=cmd/dev/ar
622-	objs_for "$dir" tinyar.c "-I$dir"
623-	link_bin "$dir/ar" $_objs -- $LIB
624+        cfg_enabled BUILD_DEV_AR || return 0
625+        local dir=cmd/dev/ar
626+        objs_for "$dir" tinyar.c "-I$dir"
627+        link_bin "$dir/ar" $_objs -- $LIB
628 }
629 
630 build_as() {
631-	cfg_enabled BUILD_DEV_AS || return 0
632-	local dir="cmd/dev/as"
633-	local flags="-Icmd/dev/xcutil -I$dir -Ishared"
634-	local objs=""
635-	objs_for "cmd/dev/xcutil" "" "$flags"
636-	objs="$objs $_objs"
637-	objs_for "$dir" "" "$flags"
638-	objs="$objs $_objs"
639-	objs_for "$dir/arch/x64" "" "-Icmd/dev/xcutil -I$dir -I$dir/arch/x64 -Ishared"
640-	objs="$objs $_objs"
641-	link_bin "$dir/as" $objs -- $LIB
642+        cfg_enabled BUILD_DEV_AS || return 0
643+        local dir="cmd/dev/as"
644+        local flags="-Icmd/dev/xcutil -I$dir -Ishared"
645+        local objs=""
646+        objs_for "cmd/dev/xcutil" "" "$flags"
647+        objs="$objs $_objs"
648+        objs_for "$dir" "" "$flags"
649+        objs="$objs $_objs"
650+        objs_for "$dir/arch/x64" "" "-Icmd/dev/xcutil -I$dir -I$dir/arch/x64 -Ishared"
651+        objs="$objs $_objs"
652+        link_bin "$dir/as" $objs -- $LIB
653 }
654 
655 build_ld() {
656-	cfg_enabled BUILD_DEV_LD || return 0
657-	local dir="cmd/dev/ld"
658-	local flags="-Icmd/dev/xcutil -I$dir"
659-	local objs=""
660-	objs_for "cmd/dev/xcutil" "" "$flags"
661-	objs="$objs $_objs"
662-	objs_for "$dir" "" "$flags"
663-	objs="$objs $_objs"
664-	link_bin "$dir/ld" $objs -- $LIB
665+        cfg_enabled BUILD_DEV_LD || return 0
666+        local dir="cmd/dev/ld"
667+        local flags="-Icmd/dev/xcutil -I$dir"
668+        local objs=""
669+        objs_for "cmd/dev/xcutil" "" "$flags"
670+        objs="$objs $_objs"
671+        objs_for "$dir" "" "$flags"
672+        objs="$objs $_objs"
673+        link_bin "$dir/ld" $objs -- $LIB
674 }
675 
676 build_cc() {
677-	cfg_enabled BUILD_DEV_CC || return 0
678-	local dir="cmd/dev/cc"
679-	local cflags="-I$dir"
680-	local common
681-
682-	# compiled once, linked into both cc1 and cpp
683-	objs_for "$dir" "driver.c cc1.c cpp.c" "$cflags"
684-	common="$_objs"
685-	drain
686-
687-	compile_c "$dir/cc1.c"    "$dir/cc1.o"    $cflags
688-	compile_c "$dir/cpp.c"    "$dir/cpp.o"    $cflags
689-	compile_c "$dir/driver.c" "$dir/driver.o" $cflags
690-	drain
691-
692-	link_bin "$dir/cc1" "$dir/cc1.o"    $common -- $LIB
693-	link_bin "$dir/cpp" "$dir/cpp.o"    $common -- $LIB
694-	link_bin "$dir/cc"  "$dir/driver.o" "$dir/util.o" -- $LIB
695+        cfg_enabled BUILD_DEV_CC || return 0
696+        local dir="cmd/dev/cc"
697+        local cflags="-I$dir"
698+        local common
699+
700+        # compiled once, linked into both cc1 and cpp
701+        objs_for "$dir" "driver.c cc1.c cpp.c" "$cflags"
702+        common="$_objs"
703+        drain
704+
705+        compile_c "$dir/cc1.c"    "$dir/cc1.o"    $cflags
706+        compile_c "$dir/cpp.c"    "$dir/cpp.o"    $cflags
707+        compile_c "$dir/driver.c" "$dir/driver.o" $cflags
708+        drain
709+
710+        link_bin "$dir/cc1" "$dir/cc1.o"    $common -- $LIB
711+        link_bin "$dir/cpp" "$dir/cpp.o"    $common -- $LIB
712+        link_bin "$dir/cc"  "$dir/driver.o" "$dir/util.o" -- $LIB
713 }
714 
715 build_dev() {
716-	[ -f cmd/dev/configure ] && sh cmd/dev/configure
717-	build_ar
718-	build_as
719-	build_ld
720-	build_cc
721+        [ -f cmd/dev/configure ] && sh cmd/dev/configure
722+        build_ar
723+        build_as
724+        build_ld
725+        build_cc
726 }
727 
728 # manual page generation
729 #
730 man_section() {
731-	case "$1" in
732-		*/linux/*|*/net/*|*/xsi/*) printf '8\n' ;;
733-		*)                         printf '1\n' ;;
734-	esac
735+        case "$1" in
736+                */linux/*|*/net/*|*/xsi/*) printf '8\n' ;;
737+                *)                         printf '1\n' ;;
738+        esac
739 }
740 
741 build_man_for() {
742-	local var="$1" src="$2" base sec out_mdoc out_txt
743-	cfg_enabled "$var" || return 0
744-	[ -x scripts/mkman/mkman ] || { printf 'error: mkman not built\n' >&2; exit 1; }
745-
746-	grep -qE '!man|\?man' "$src" || return 0
747-
748-	base=${src##*/}; base=${base%.c}
749-	sec=$(man_section "$src")
750-
751-	mkdir -p "man/man${sec}"
752-	out_mdoc="man/man${sec}/${base}.${sec}"
753-	out_txt="man/man${sec}/${base}.${sec}.txt"
754-	if any_newer_than "$out_mdoc" "$src" config.mk scripts/mkman/mkman; then
755-		printf '  MAN   %s\n' "$out_mdoc"
756-		scripts/mkman/mkman -fmt mdoc -config config.mk -section "$sec" "$src" > "$out_mdoc"
757-	fi
758-	if any_newer_than "$out_txt" "$src" config.mk scripts/mkman/mkman; then
759-		printf '  MAN   %s\n' "$out_txt"
760-		scripts/mkman/mkman -fmt txt -config config.mk -section "$sec" "$src" > "$out_txt"
761-	fi
762+        local var="$1" src="$2" base sec out_mdoc out_txt
763+        cfg_enabled "$var" || return 0
764+        [ -x scripts/mkman/mkman ] || { printf 'error: mkman not built\n' >&2; exit 1; }
765+
766+        grep -qE '!man|\?man' "$src" || return 0
767+
768+        base=${src##*/}; base=${base%.c}
769+        sec=$(man_section "$src")
770+
771+        mkdir -p "man/man${sec}"
772+        out_mdoc="man/man${sec}/${base}.${sec}"
773+        out_txt="man/man${sec}/${base}.${sec}.txt"
774+        if any_newer_than "$out_mdoc" "$src" config.mk scripts/mkman/mkman; then
775+                printf '  MAN   %s\n' "$out_mdoc"
776+                scripts/mkman/mkman -fmt mdoc -config config.mk -section "$sec" "$src" > "$out_mdoc"
777+        fi
778+        if any_newer_than "$out_txt" "$src" config.mk scripts/mkman/mkman; then
779+                printf '  MAN   %s\n' "$out_txt"
780+                scripts/mkman/mkman -fmt txt -config config.mk -section "$sec" "$src" > "$out_txt"
781+        fi
782 }
783 
784 build_man() {
785-	local dir cat src base
786-	if [ ! -x scripts/mkman/mkman ] || any_newer_than scripts/mkman/mkman scripts/mkman/main.go scripts/mkman/page.go scripts/mkman/parse.go scripts/mkman/mdoc.go; then
787-		printf '  GO    scripts/mkman/mkman\n'
788-		(cd scripts/mkman && go build -o mkman .)
789-	fi
790-	for dir in cmd/*; do
791-		[ -d "$dir" ] || continue
792-		cat=${dir##*/}
793-		for src in "$dir"/*.c; do
794-			[ -f "$src" ] || continue
795-			base=${src##*/}; base=${base%.c}
796-			build_man_for "$(cfgvar "$cat" "$base")" "$src"
797-		done
798-	done
799+        local dir cat src base
800+        if [ ! -x scripts/mkman/mkman ] || any_newer_than scripts/mkman/mkman scripts/mkman/main.go scripts/mkman/page.go scripts/mkman/parse.go scripts/mkman/mdoc.go; then
801+                printf '  GO    scripts/mkman/mkman\n'
802+                (cd scripts/mkman && go build -o mkman .)
803+        fi
804+        for dir in cmd/*; do
805+                [ -d "$dir" ] || continue
806+                cat=${dir##*/}
807+                for src in "$dir"/*.c; do
808+                        [ -f "$src" ] || continue
809+                        base=${src##*/}; base=${base%.c}
810+                        build_man_for "$(cfgvar "$cat" "$base")" "$src"
811+                done
812+        done
813 }
814 
815 # install and clean
816 #
817 do_install() {
818-	local bin f sec
819-	mkdir -p "$PREFIX/bin" "$MANPREFIX/man1" "$MANPREFIX/man8"
820-	find cmd -type f ! -name '*.*' -perm -100 | while read -r bin; do
821-		printf '  INSTALL %s/bin/%s\n' "$PREFIX" "${bin##*/}"
822-		cp "$bin" "$PREFIX/bin/${bin##*/}"
823-		chmod 755 "$PREFIX/bin/${bin##*/}"
824-	done
825-	find man/man1 man/man8 -type f -name '*.[18]' 2>/dev/null | while read -r f; do
826-		sec=${f%/*}; sec=${sec##*/}
827-		cp "$f" "$MANPREFIX/${sec}/${f##*/}"
828-	done
829+        local bin f sec
830+        mkdir -p "$PREFIX/bin" "$MANPREFIX/man1" "$MANPREFIX/man8"
831+        find cmd -type f ! -name '*.*' -perm -100 | while read -r bin; do
832+                printf '  INSTALL %s/bin/%s\n' "$PREFIX" "${bin##*/}"
833+                cp "$bin" "$PREFIX/bin/${bin##*/}"
834+                chmod 755 "$PREFIX/bin/${bin##*/}"
835+        done
836+        find man/man1 man/man8 -type f -name '*.[18]' 2>/dev/null | while read -r f; do
837+                sec=${f%/*}; sec=${sec##*/}
838+                cp "$f" "$MANPREFIX/${sec}/${f##*/}"
839+        done
840 }
841 
842 do_clean() {
843-	find shared cmd -name '*.o'                   -exec rm -f {} +
844-	find shared    -name '*.a'                    -exec rm -f {} +
845-	find cmd -type f ! -name '*.*' -perm -100     -exec rm -f {} +
846-	rm -f shared/libaruuelf.so
847-	rm -f cmd/posix/bc.c cmd/posix/getconf.h
848-	rm -f cmd/posix/awk/maketab cmd/posix/awk/proctab.c
849-	rm -f cmd/posix/awk/awkgram.tab.c cmd/posix/awk/awkgram.tab.h
850-	rm -f cmd/posix/sh/mknodes cmd/posix/sh/mksyntax
851-	rm -f cmd/posix/sh/token.h cmd/posix/sh/syntax.c cmd/posix/sh/syntax.h
852-	rm -f cmd/posix/sh/nodes.c cmd/posix/sh/nodes.h
853-	rm -f cmd/posix/sh/builtins.c cmd/posix/sh/builtins.h
854-	rm -rf man/man1 man/man8
855-	rm -rf aruu-box .box
856-	rm -f scripts/mkman/mkman
857+        printf '  CLEAN object files\n'
858+        find shared cmd -name '*.o' -exec rm -f {} +
859+        printf '  CLEAN static libraries\n'
860+        find shared -name '*.a' -exec rm -f {} +
861+        printf '  CLEAN compiled binaries\n'
862+        find cmd -type f ! -name '*.*' -perm -100 -exec rm -f {} +
863+        printf '  CLEAN generated headers\n'
864+        rm -f cmd/posix/getconf.h
865+        rm -f cmd/posix/awk/awkgram.tab.c cmd/posix/awk/awkgram.tab.h
866+        rm -f cmd/posix/sh/token.h cmd/posix/sh/syntax.c cmd/posix/sh/syntax.h
867+        rm -f cmd/posix/sh/nodes.c cmd/posix/sh/nodes.h
868+        rm -f cmd/posix/sh/builtins.c cmd/posix/sh/builtins.h
869+        printf '  CLEAN generated sources\n'
870+        rm -f cmd/posix/awk/proctab.c
871+        rm -f cmd/posix/bc.c
872+        printf '  CLEAN build tools\n'
873+        rm -f cmd/posix/awk/maketab
874+        rm -f cmd/posix/sh/mknodes cmd/posix/sh/mksyntax
875+        rm -f scripts/mkman/mkman
876+        printf '  CLEAN dev artifacts\n'
877+        rm -f cmd/dev/cc/cc1 cmd/dev/cc/cpp cmd/dev/as/as cmd/dev/ld/ld cmd/dev/ar/ar
878+        rm -f shared/libaruuelf.so
879+        rm -f cmd/dev/config.h cmd/dev/cc/config.h cmd/dev/version.h
880+        printf '  CLEAN misc\n'
881+        rm -rf man/man1 man/man8
882+        rm -rf aruu-box .box
883+        printf '  CLEAN done\n'
884 }
885 
886 case "$TARGET" in
887-	all)
888-		build_lib
889-		build_posix
890-		build_dev
891-	build_simple_tools linux
892-	build_simple_tools net
893-	build_simple_tools xsi
894-	build_simple_tools pseudo
895-	build_simple_tools extra
896-		;;
897-	lib)             build_lib ;;
898-	posix)           build_lib; build_posix ;;
899-	dev)             build_lib; build_dev ;;
900-	make)            build_lib; build_make ;;
901-	linux|net|xsi|pseudo|extra)
902-	                 build_lib; build_simple_tools "$TARGET" ;;
903-	man)             build_man ;;
904-	install)         do_install ;;
905-	clean)           do_clean ;;
906-	*)
907-		printf 'usage: sh Makefile.sh [-jN] [-lN] [all|clean|install|man|lib|posix|linux|net|xsi|pseudo|extra|dev|make]\n' >&2
908-		exit 1
909-		;;
910+        all)
911+                build_lib
912+                build_posix
913+                build_dev
914+        build_simple_tools linux
915+        build_simple_tools net
916+        build_simple_tools xsi
917+        build_simple_tools pseudo
918+        build_simple_tools extra
919+                ;;
920+        lib)             build_lib ;;
921+        posix)           build_lib; build_posix ;;
922+        dev)             build_lib; build_dev ;;
923+        make)            build_lib; build_make ;;
924+        linux|net|xsi|pseudo|extra)
925+                         build_lib; build_simple_tools "$TARGET" ;;
926+        man)             build_man ;;
927+        install)         do_install ;;
928+        clean)           do_clean ;;
929+        *)
930+                printf 'usage: sh Makefile.sh [-jN] [-lN] [all|clean|install|man|lib|posix|linux|net|xsi|pseudo|extra|dev|make]\n' >&2
931+                exit 1
932+                ;;
933 esac
+21, -1
 1@@ -40,6 +40,12 @@ posix)
 2     FEATURE_SH_SETVAR=0;              FEATURE_SH_WORDEXP=0
 3     FEATURE_CAL_EXT=0
 4     FEATURE_LS_COLOR=0
 5+    FEATURE_DIFF3_MERGE=0;           FEATURE_DIFF3_EDSCRIPT=0
 6+    FEATURE_DIFF_CONTEXT=0;          FEATURE_DIFF_UNIFIED=0
 7+    FEATURE_DIFF_ED=0;               FEATURE_DIFF_BRIEF=0
 8+    FEATURE_DIFF_SIDEBYSIDE=0
 9+    FEATURE_PATCH_BACKUP=0;         FEATURE_PATCH_FUZZ=0
10+    FEATURE_PATCH_STRIP_CR=0
11     FEATURE_MODPROBE_SHOW_DEPENDS=0;  FEATURE_MODPROBE_BLACKLIST=0
12     FEATURE_MODPROBE_SYSLOG=0;        FEATURE_MODPROBE_DIR_OVERRIDE=0
13     FEATURE_DEPMOD_ALIAS=0;           FEATURE_DEPMOD_SYMBOLS=0
14@@ -69,6 +75,12 @@ common)
15     FEATURE_SH_SETVAR=0;              FEATURE_SH_WORDEXP=0
16     FEATURE_CAL_EXT=1
17     FEATURE_LS_COLOR=1
18+    FEATURE_DIFF3_MERGE=0;           FEATURE_DIFF3_EDSCRIPT=1
19+    FEATURE_DIFF_CONTEXT=1;          FEATURE_DIFF_UNIFIED=1
20+    FEATURE_DIFF_ED=1;               FEATURE_DIFF_BRIEF=1
21+    FEATURE_DIFF_SIDEBYSIDE=0
22+    FEATURE_PATCH_BACKUP=1;         FEATURE_PATCH_FUZZ=1
23+    FEATURE_PATCH_STRIP_CR=1
24     FEATURE_MODPROBE_SHOW_DEPENDS=1;  FEATURE_MODPROBE_BLACKLIST=1
25     FEATURE_MODPROBE_SYSLOG=1;        FEATURE_MODPROBE_DIR_OVERRIDE=1
26     FEATURE_DEPMOD_ALIAS=1;           FEATURE_DEPMOD_SYMBOLS=1
27@@ -94,11 +106,18 @@ all)
28     FEATURE_STAT_FILESYSTEM=1;        FEATURE_STAT_FORMAT=1
29     FEATURE_SORT_BIG=1;               FEATURE_SORT_STABLE=1
30     FEATURE_OD_ENDIAN=1;
31-    FEATURE_SH_HISTEDIT=1;            FEATURE_SH_LOCAL=1
32+    FEATURE_SH_HISTEDIT=1
33+FEATURE_INPROC_EXEC=0  # set to 1 for aruu-box in-process dispatch;            FEATURE_SH_LOCAL=1
34     FEATURE_SH_LET=1;                 FEATURE_SH_ULIMIT=1
35     FEATURE_SH_SETVAR=1;              FEATURE_SH_WORDEXP=1
36     FEATURE_CAL_EXT=1
37     FEATURE_LS_COLOR=1
38+    FEATURE_DIFF3_MERGE=1;           FEATURE_DIFF3_EDSCRIPT=1
39+    FEATURE_DIFF_CONTEXT=1;          FEATURE_DIFF_UNIFIED=1
40+    FEATURE_DIFF_ED=1;               FEATURE_DIFF_BRIEF=1
41+    FEATURE_DIFF_SIDEBYSIDE=1
42+    FEATURE_PATCH_BACKUP=1;         FEATURE_PATCH_FUZZ=1
43+    FEATURE_PATCH_STRIP_CR=1
44     FEATURE_MODPROBE_SHOW_DEPENDS=1;  FEATURE_MODPROBE_BLACKLIST=1
45     FEATURE_MODPROBE_SYSLOG=1;        FEATURE_MODPROBE_DIR_OVERRIDE=1
46     FEATURE_DEPMOD_ALIAS=1;           FEATURE_DEPMOD_SYMBOLS=1
47@@ -137,6 +156,7 @@ unset _p
48 # BUILD_POSIX_SH=0       # disable a tool when its group is active
49 # BUILD_DEV_AS=1         # enable a tool whose group isnt in PRESET_UTILS
50 FEATURE_SH_HISTEDIT=1
51+FEATURE_INPROC_EXEC=0  # set to 1 for aruu-box in-process dispatch
52 # tls backend: set exactly one to 1 to enable tls
53 FEATURE_USE_BEARSSL=0
54 FEATURE_USE_LIBRESSL=0
+97, -96
  1@@ -16,64 +16,65 @@ static int Lflag = 0;
  2 static void
  3 usage(void)
  4 {
  5-	eprintf("usage: %s [-o format] [-s tag] [-U] [-L] [device ...]\n", argv0);
  6+        eprintf("usage: %s [-o format] [-s tag] [-U] [-L] [device ...]\n", argv0);
  7 }
  8 
  9 static void
 10 print_tag(const char *devname, const char *tag, const char *value)
 11 {
 12-	if (sflag && strcasecmp(sflag, tag) != 0)
 13-		return;
 14-
 15-	if (strcmp(oflag, "value") == 0) {
 16-		printf("%s\n", value);
 17-	} else if (strcmp(oflag, "export") == 0) {
 18-		printf("%s=%s\n", tag, value);
 19-	} else {
 20-		printf(" %s=\"%s\"", tag, value);
 21-	}
 22+        (void)devname;
 23+        if (sflag && strcasecmp(sflag, tag) != 0)
 24+                return;
 25+
 26+        if (strcmp(oflag, "value") == 0) {
 27+                printf("%s\n", value);
 28+        } else if (strcmp(oflag, "export") == 0) {
 29+                printf("%s=%s\n", tag, value);
 30+        } else {
 31+                printf(" %s=\"%s\"", tag, value);
 32+        }
 33 }
 34 
 35 static int
 36 do_blkid(const char *path)
 37 {
 38-	struct BlockDev dev;
 39-	char type[64] = {0};
 40-	char label[256] = {0};
 41-	char uuid[256] = {0};
 42-	int res;
 43-
 44-	if (blockdev_open(&dev, path, 0) < 0)
 45-		return -1;
 46-
 47-	res = blockdev_detect_fs(&dev, type, sizeof(type), label, sizeof(label), uuid, sizeof(uuid));
 48-	if (res == 0) {
 49-		if (Uflag || Lflag) {
 50-			if (Uflag) {
 51-				printf("%s\n", uuid);
 52-			} else {
 53-				printf("%s\n", label);
 54-			}
 55-		} else {
 56-			if (strcmp(oflag, "export") == 0) {
 57-				printf("DEVNAME=%s\n", path);
 58-			} else if (strcmp(oflag, "value") != 0) {
 59-				printf("%s:", path);
 60-			}
 61-
 62-			if (label[0])
 63-				print_tag(path, "LABEL", label);
 64-			if (uuid[0])
 65-				print_tag(path, "UUID", uuid);
 66-			print_tag(path, "TYPE", type);
 67-
 68-			if (strcmp(oflag, "full") == 0)
 69-				printf("\n");
 70-		}
 71-	}
 72-
 73-	blockdev_close(&dev);
 74-	return res == 0 ? 0 : -2;
 75+        struct BlockDev dev;
 76+        char type[64] = {0};
 77+        char label[256] = {0};
 78+        char uuid[256] = {0};
 79+        int res;
 80+
 81+        if (blockdev_open(&dev, path, 0) < 0)
 82+                return -1;
 83+
 84+        res = blockdev_detect_fs(&dev, type, sizeof(type), label, sizeof(label), uuid, sizeof(uuid));
 85+        if (res == 0) {
 86+                if (Uflag || Lflag) {
 87+                        if (Uflag) {
 88+                                printf("%s\n", uuid);
 89+                        } else {
 90+                                printf("%s\n", label);
 91+                        }
 92+                } else {
 93+                        if (strcmp(oflag, "export") == 0) {
 94+                                printf("DEVNAME=%s\n", path);
 95+                        } else if (strcmp(oflag, "value") != 0) {
 96+                                printf("%s:", path);
 97+                        }
 98+
 99+                        if (label[0])
100+                                print_tag(path, "LABEL", label);
101+                        if (uuid[0])
102+                                print_tag(path, "UUID", uuid);
103+                        print_tag(path, "TYPE", type);
104+
105+                        if (strcmp(oflag, "full") == 0)
106+                                printf("\n");
107+                }
108+        }
109+
110+        blockdev_close(&dev);
111+        return res == 0 ? 0 : -2;
112 }
113 
114 // ?man blkid: print block device attributes
115@@ -83,52 +84,52 @@ do_blkid(const char *path)
116 int
117 main(int argc, char *argv[])
118 {
119-	int ret = 0;
120-
121-	ARGBEGIN {
122-	// ?man -o:specify output format (full, value, export)
123-	case 'o':
124-		oflag = EARGF(usage());
125-		break;
126-	// ?man -s:only show specified tag (e.g. UUID, LABEL, TYPE)
127-	case 's':
128-		sflag = EARGF(usage());
129-		break;
130-	// ?man -U:print UUID only
131-	case 'U':
132-		Uflag = 1;
133-		break;
134-	// ?man -L:print volume label only
135-	case 'L':
136-		Lflag = 1;
137-		break;
138-	default:
139-		usage();
140-	} ARGEND
141-
142-	if (argc > 0) {
143-		for (; *argv; argv++) {
144-			if (do_blkid(*argv) < 0)
145-				ret = 1;
146-		}
147-	} else {
148-		struct BlockDevInfo *list = blockdev_get_list();
149-		struct BlockDevInfo *curr;
150-		if (!list) {
151-			return 1;
152-		}
153-		for (curr = list; curr; curr = curr->next) {
154-			do_blkid(curr->path);
155-			struct BlockDevInfo *part;
156-			for (part = curr->parts; part; part = part->next) {
157-				do_blkid(part->path);
158-			}
159-		}
160-		blockdev_free_list(list);
161-	}
162-
163-	if (fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>"))
164-		ret = 2;
165-
166-	return ret;
167+        int ret = 0;
168+
169+        ARGBEGIN {
170+        // ?man -o:specify output format (full, value, export)
171+        case 'o':
172+                oflag = EARGF(usage());
173+                break;
174+        // ?man -s:only show specified tag (e.g. UUID, LABEL, TYPE)
175+        case 's':
176+                sflag = EARGF(usage());
177+                break;
178+        // ?man -U:print UUID only
179+        case 'U':
180+                Uflag = 1;
181+                break;
182+        // ?man -L:print volume label only
183+        case 'L':
184+                Lflag = 1;
185+                break;
186+        default:
187+                usage();
188+        } ARGEND
189+
190+        if (argc > 0) {
191+                for (; *argv; argv++) {
192+                        if (do_blkid(*argv) < 0)
193+                                ret = 1;
194+                }
195+        } else {
196+                struct BlockDevInfo *list = blockdev_get_list();
197+                struct BlockDevInfo *curr;
198+                if (!list) {
199+                        return 1;
200+                }
201+                for (curr = list; curr; curr = curr->next) {
202+                        do_blkid(curr->path);
203+                        struct BlockDevInfo *part;
204+                        for (part = curr->parts; part; part = part->next) {
205+                                do_blkid(part->path);
206+                        }
207+                }
208+                blockdev_free_list(list);
209+        }
210+
211+        if (fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>"))
212+                ret = 2;
213+
214+        return ret;
215 }
+4, -3
 1@@ -10,6 +10,7 @@
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5+#include "paths.h"
 6 #include "util.h"
 7 
 8 #define KDGKBTYPE	0x4B33	/* get keyboard type */
 9@@ -18,9 +19,9 @@
10 #define VT_WAITACTIVE	0x5607	/* wait for vt active */
11 
12 static char *vt[] = {
13-	"/proc/self/fd/0",
14-	"/dev/console",
15-	"/dev/tty",
16+	ARUU_LINUX_PATH_PROC "/self/fd/0",
17+	ARUU_PATH_DEVCONSOLE,
18+	ARUU_PATH_DEVTTY,
19 	"/dev/tty0",
20 };
21 
+5, -4
 1@@ -1,6 +1,7 @@
 2 
 3 
 4 #include "fs.h"
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 #include <dirent.h>
 9@@ -181,15 +182,15 @@ scan_cb(int fd, const char *name, struct stat *st, void *data, struct recursor *
10 		fp = fopen(r->path, "r");
11 	} else if (strcmp(comp, ".gz") == 0) {
12 		snprintf(cmd, sizeof(cmd), "gzip -dc '%s'", r->path);
13-		fp = popen(cmd, "r");
14+		fp = wpopen(cmd, NULL, "r");
15 		is_pipe = 1;
16 	} else if (strcmp(comp, ".xz") == 0) {
17 		snprintf(cmd, sizeof(cmd), "xz -dc '%s'", r->path);
18-		fp = popen(cmd, "r");
19+		fp = wpopen(cmd, NULL, "r");
20 		is_pipe = 1;
21 	} else if (strcmp(comp, ".zst") == 0) {
22 		snprintf(cmd, sizeof(cmd), "zstd -dc '%s'", r->path);
23-		fp = popen(cmd, "r");
24+		fp = wpopen(cmd, NULL, "r");
25 		is_pipe = 1;
26 	} else {
27 		fp = fopen(r->path, "r");
28@@ -202,7 +203,7 @@ scan_cb(int fd, const char *name, struct stat *st, void *data, struct recursor *
29 
30 	buf = read_all(fp, &len);
31 	if (is_pipe)
32-		pclose(fp);
33+		wpclose(fp);
34 	else
35 		fclose(fp);
36 
+2, -1
 1@@ -9,6 +9,7 @@
 2 #include <stdio.h>
 3 #include <unistd.h>
 4 
 5+#include "paths.h"
 6 #include "util.h"
 7 
 8 enum {
 9@@ -64,7 +65,7 @@ main(int argc, char *argv[])
10 	} ARGEND;
11 
12 	if (!argc) {
13-		eject("/dev/sr0");
14+		eject(ARUU_PATH_DEV "/sr0");
15 	} else {
16 		for (; *argv; argc--, argv++)
17 			eject(*argv);
+1, -0
1@@ -10,6 +10,7 @@
2 #include <stdlib.h>
3 #include <unistd.h>
4 
5+#include "paths.h"
6 #include "util.h"
7 
8 static void
+2, -1
 1@@ -14,6 +14,7 @@
 2 #include <unistd.h>
 3 
 4 #include "rtc.h"
 5+#include "paths.h"
 6 #include "util.h"
 7 
 8 static void
 9@@ -120,7 +121,7 @@ usage(void)
10 int
11 main(int argc, char *argv[])
12 {
13-	char *dev = "/dev/rtc";
14+	char *dev = ARUU_PATH_DEV "/rtc";
15 	int rflag = 0;
16 	int sflag = 0;
17 	int wflag = 0;
+2, -1
 1@@ -4,6 +4,7 @@
 2 #include <string.h>
 3 
 4 #include "text.h"
 5+#include "paths.h"
 6 #include "util.h"
 7 
 8 static void parse_modline(char *buf, char **name, char **size,
 9@@ -20,7 +21,7 @@ usage(void)
10 int
11 main(int argc, char *argv[])
12 {
13-	const char *modfile = "/proc/modules";
14+	const char *modfile = ARUU_LINUX_PATH_PROC_MODULES;
15 	FILE *fp;
16 	char *buf = NULL;
17 	char *name, *size, *refcount, *users;
+2, -1
 1@@ -6,6 +6,7 @@
 2 #include <stdlib.h>
 3 
 4 #include "text.h"
 5+#include "paths.h"
 6 #include "util.h"
 7 
 8 static void
 9@@ -57,6 +58,6 @@ main(int argc, char *argv[])
10 		usage();
11 	} ARGEND;
12 
13-	recurse_dir("/sys/bus/usb/devices", lsusb);
14+	recurse_dir(ARUU_LINUX_PATH_SYS_BUS_USB, lsusb);
15 	return 0;
16 }
+2, -1
 1@@ -1,6 +1,7 @@
 2 
 3 #include "arg.h"
 4 #include "fs.h"
 5+#include "paths.h"
 6 #include "util.h"
 7 
 8 #include <ctype.h>
 9@@ -344,7 +345,7 @@ mark_loaded(void)
10 	char *p;
11 	struct Module *m;
12 
13-	if (!(fp = fopen("/proc/modules", "r")))
14+	if (!(fp = fopen(ARUU_LINUX_PATH_PROC_MODULES, "r")))
15 		return;
16 
17 	while (fgets(line, sizeof(line), fp)) {
+8, -6
 1@@ -15,6 +15,8 @@
 2 #include <unistd.h>
 3 
 4 #include "text.h"
 5+#include "paths.h"
 6+#include "wexec.h"
 7 #include "util.h"
 8 
 9 #define FSOPTS_MAXLEN 512
10@@ -134,10 +136,10 @@ mounthelper(const char *fsname, const char *dir, const char *fstype)
11 		eargv[i++] = dir;
12 		eargv[i] = NULL;
13 
14-		execvp(eprog, (char * const *)eargv);
15+		wexecvp_self(eprog, (char *const *)eargv);
16 		if (errno == ENOENT)
17 			_exit(1);
18-		weprintf("execvp:");
19+		weprintf("wexecvp:");
20 		_exit(1);
21 		break;
22 	default:
23@@ -166,8 +168,8 @@ mounted(const char *dir)
24 		weprintf("stat %s:", dir);
25 		return 0;
26 	}
27-	if (!(fp = setmntent("/proc/mounts", "r")))
28-		eprintf("setmntent %s:", "/proc/mounts");
29+	if (!(fp = setmntent(ARUU_LINUX_PATH_PROC_MOUNTS, "r")))
30+		eprintf("setmntent %s:", ARUU_LINUX_PATH_PROC_MOUNTS);
31 
32 	while ((me = getmntent_r(fp, &mebuf, linebuf, sizeof(linebuf)))) {
33 		if (stat(me->mnt_dir, &st2) < 0) {
34@@ -197,7 +199,7 @@ int
35 main(int argc, char *argv[])
36 {
37 	char *types = NULL, data[FSOPTS_MAXLEN] = "", *resolvpath = NULL;
38-	char *files[] = { "/proc/mounts", "/etc/fstab", NULL };
39+	char *files[] = { ARUU_LINUX_PATH_PROC_MOUNTS, "/etc/fstab", NULL };
40 	const char *source, *target;
41 	struct mntent *me = NULL;
42 	int aflag = 0, status = 0, i, r;
43@@ -263,7 +265,7 @@ main(int argc, char *argv[])
44 
45 	for (i = 0; files[i]; i++) {
46 		if (!(fp = setmntent(files[i], "r"))) {
47-			if (strcmp(files[i], "/proc/mounts") != 0)
48+			if (strcmp(files[i], ARUU_LINUX_PATH_PROC_MOUNTS) != 0)
49 				weprintf("setmntent %s:", files[i]);
50 			continue;
51 		}
+3, -2
 1@@ -11,6 +11,7 @@
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5+#include "paths.h"
 6 #include "util.h"
 7 
 8 static void
 9@@ -81,11 +82,11 @@ main(int argc, char *argv[])
10 		return 0;
11 	}
12 
13-	fp = setmntent("/proc/mounts", "r");
14+	fp = setmntent(ARUU_LINUX_PATH_PROC_MOUNTS, "r");
15 	if (!fp) {
16 		if (qflag)
17 			return 1;
18-		eprintf("setmntent %s:", "/proc/mounts");
19+		eprintf("setmntent %s:", ARUU_LINUX_PATH_PROC_MOUNTS);
20 	}
21 	while ((me = getmntent(fp)) != NULL) {
22 		if (stat(me->mnt_dir, &st2) < 0) {
+163, -167
  1@@ -9,155 +9,151 @@
  2 #include <unistd.h>
  3 
  4 #include "text.h"
  5+#include "paths.h"
  6 #include "util.h"
  7 
  8 static void
  9 replacestr(char *s, int a, int b)
 10 {
 11-	for (; *s; s++)
 12-		if (*s == a)
 13-			*s = b;
 14+        for (; *s; s++)
 15+                if (*s == a)
 16+                        *s = b;
 17 }
 18 
 19 static int
 20 getsysctl(char *variable, char **value)
 21 {
 22-	char path[PATH_MAX];
 23-	char *p;
 24-	char *buf, *tmp, c;
 25-	int fd;
 26-	ssize_t n;
 27-	size_t sz, i;
 28-
 29-	replacestr(variable, '.', '/');
 30-
 31-	strlcpy(path, "/proc/sys/", sizeof(path));
 32-	if (strlcat(path, variable, sizeof(path)) >= sizeof(path)) {
 33-		replacestr(variable, '/', '.');
 34-		return -1;
 35-	}
 36-
 37-	replacestr(variable, '/', '.');
 38-
 39-	fd = open(path, O_RDONLY);
 40-	if (fd < 0)
 41-		return -1;
 42-
 43-	i = 0;
 44-	sz = 1;
 45-	buf = NULL;
 46-	while (1) {
 47-		n = read(fd, &c, 1);
 48-		if (n < 0) {
 49-			close(fd);
 50-			free(buf);
 51-			return -1;
 52-		}
 53-		if (n == 0)
 54-			break;
 55-		if (i == sz - 1) {
 56-			sz *= 2;
 57-			tmp = realloc(buf, sz);
 58-			if (!tmp) {
 59-				close(fd);
 60-				free(buf);
 61-				return -1;
 62-			}
 63-			buf = tmp;
 64-		}
 65-		buf[i++] = c;
 66-	}
 67-	buf[i] = '\0';
 68-
 69-	p = strrchr(buf, '\n');
 70-	if (p)
 71-		*p = '\0';
 72-
 73-	*value = buf;
 74-
 75-	close(fd);
 76-
 77-	return 0;
 78+        char path[PATH_MAX];
 79+        char *p;
 80+        char *buf, *tmp, c;
 81+        int fd;
 82+        ssize_t n;
 83+        size_t sz, i;
 84+
 85+        replacestr(variable, '.', '/');
 86+
 87+        strlcpy(path, ARUU_LINUX_PATH_PROC_SYS "/", sizeof(path));
 88+        if (strlcat(path, variable, sizeof(path)) >= sizeof(path)) {
 89+                replacestr(variable, '/', '.');
 90+                return -1;
 91+        }
 92+
 93+        replacestr(variable, '/', '.');
 94+
 95+        fd = open(path, O_RDONLY);
 96+        if (fd < 0)
 97+                return -1;
 98+
 99+        i = 0;
100+        sz = 1;
101+        buf = NULL;
102+        while (1) {
103+                n = read(fd, &c, 1);
104+                if (n < 0) {
105+                        close(fd);
106+                        free(buf);
107+                        return -1;
108+                }
109+                if (n == 0)
110+                        break;
111+                if (i == sz - 1) {
112+                        sz *= 2;
113+                        tmp = erealloc(buf, sz);
114+                        buf = tmp;
115+                }
116+                buf[i++] = c;
117+        }
118+        buf[i] = '\0';
119+
120+        p = strrchr(buf, '\n');
121+        if (p)
122+                *p = '\0';
123+
124+        *value = buf;
125+
126+        close(fd);
127+
128+        return 0;
129 }
130 
131 static int
132 setsysctl(char *variable, char *value)
133 {
134-	char path[PATH_MAX];
135-	int fd;
136-	ssize_t n;
137+        char path[PATH_MAX];
138+        int fd;
139+        ssize_t n;
140 
141-	replacestr(variable, '.', '/');
142+        replacestr(variable, '.', '/');
143 
144-	strlcpy(path, "/proc/sys/", sizeof(path));
145-	if (strlcat(path, variable, sizeof(path)) >= sizeof(path)) {
146-		replacestr(variable, '/', '.');
147-		return -1;
148-	}
149+        strlcpy(path, ARUU_LINUX_PATH_PROC_SYS "/", sizeof(path));
150+        if (strlcat(path, variable, sizeof(path)) >= sizeof(path)) {
151+                replacestr(variable, '/', '.');
152+                return -1;
153+        }
154 
155-	replacestr(variable, '/', '.');
156+        replacestr(variable, '/', '.');
157 
158-	fd = open(path, O_WRONLY);
159-	if (fd < 0)
160-		return -1;
161+        fd = open(path, O_WRONLY);
162+        if (fd < 0)
163+                return -1;
164 
165-	n = write(fd, value, strlen(value));
166-	if ((size_t)n != strlen(value)) {
167-		close(fd);
168-		return -1;
169-	}
170+        n = write(fd, value, strlen(value));
171+        if ((size_t)n != strlen(value)) {
172+                close(fd);
173+                return -1;
174+        }
175 
176-	close(fd);
177+        close(fd);
178 
179-	return 0;
180+        return 0;
181 }
182 
183 static int
184 parsepair(char *pair)
185 {
186-	char *p;
187-	char *variable;
188-	char *value;
189-
190-	for (p = pair; *p; p++) {
191-		if (p[0] == '.' && p[1] == '.') {
192-			weprintf("malformed input: %s\n", pair);
193-			return -1;
194-		}
195-	}
196-	p = strchr(pair, '=');
197-	if (p) {
198-		if (p[1] == '\0') {
199-			weprintf("malformed input: %s\n", pair);
200-			return -1;
201-		}
202-		*p = '\0';
203-		value = &p[1];
204-	} else {
205-		value = NULL;
206-	}
207-	variable = pair;
208-	if (value) {
209-		if (setsysctl(variable, value) < 0) {
210-			weprintf("failed to set sysctl for %s\n", variable);
211-			return -1;
212-		}
213-	} else {
214-		if (getsysctl(variable, &value) < 0) {
215-			weprintf("failed to get sysctl for %s\n", variable);
216-			return -1;
217-		}
218-		printf("%s = %s\n", variable, value);
219-		free(value);
220-	}
221-
222-	return 0;
223+        char *p;
224+        char *variable;
225+        char *value;
226+
227+        for (p = pair; *p; p++) {
228+                if (p[0] == '.' && p[1] == '.') {
229+                        weprintf("malformed input: %s\n", pair);
230+                        return -1;
231+                }
232+        }
233+        p = strchr(pair, '=');
234+        if (p) {
235+                if (p[1] == '\0') {
236+                        weprintf("malformed input: %s\n", pair);
237+                        return -1;
238+                }
239+                *p = '\0';
240+                value = &p[1];
241+        } else {
242+                value = NULL;
243+        }
244+        variable = pair;
245+        if (value) {
246+                if (setsysctl(variable, value) < 0) {
247+                        weprintf("failed to set sysctl for %s\n", variable);
248+                        return -1;
249+                }
250+        } else {
251+                if (getsysctl(variable, &value) < 0) {
252+                        weprintf("failed to get sysctl for %s\n", variable);
253+                        return -1;
254+                }
255+                printf("%s = %s\n", variable, value);
256+                free(value);
257+        }
258+
259+        return 0;
260 }
261 
262 static void
263 usage(void)
264 {
265-	eprintf("usage: %s [-p file] variable[=value]...\n", argv0);
266+        eprintf("usage: %s [-p file] variable[=value]...\n", argv0);
267 }
268 
269 // ?man sysctl: configure kernel parameters
270@@ -166,54 +162,54 @@ usage(void)
271 int
272 main(int argc, char *argv[])
273 {
274-	FILE *fp;
275-	char *buf = NULL, *p;
276-	char *file = NULL;
277-	size_t size = 0;
278-	int i;
279-	int r = 0;
280-
281-	ARGBEGIN {
282-	// ?man -p:file: preserve file attributes
283-	case 'p':
284-		file = EARGF(usage());
285-		break;
286-	default:
287-		usage();
288-	} ARGEND;
289-
290-	if (!file && argc < 1)
291-		usage();
292-
293-	if (!file) {
294-		for (i = 0; i < argc; i++)
295-			if (parsepair(argv[i]) < 0)
296-				r = 1;
297-	} else {
298-		fp = fopen(file, "r");
299-		if (!fp)
300-			eprintf("fopen %s:", file);
301-		while (agetline(&buf, &size, fp) != -1) {
302-			p = buf;
303-			for (p = buf; *p == ' ' || *p == '\t'; p++)
304-				;
305-			if (*p == '#' || *p == '\n')
306-				continue;
307-			for (p = buf; *p; p++) {
308-				if (*p == '\n') {
309-					*p = '\0';
310-					break;
311-				}
312-			}
313-			p = buf;
314-			if (parsepair(p) < 0)
315-				r = 1;
316-		}
317-		if (ferror(fp))
318-			eprintf("%s: read error:", file);
319-		free(buf);
320-		fclose(fp);
321-	}
322-
323-	return r;
324+        FILE *fp;
325+        char *buf = NULL, *p;
326+        char *file = NULL;
327+        size_t size = 0;
328+        int i;
329+        int r = 0;
330+
331+        ARGBEGIN {
332+        // ?man -p:file: preserve file attributes
333+        case 'p':
334+                file = EARGF(usage());
335+                break;
336+        default:
337+                usage();
338+        } ARGEND;
339+
340+        if (!file && argc < 1)
341+                usage();
342+
343+        if (!file) {
344+                for (i = 0; i < argc; i++)
345+                        if (parsepair(argv[i]) < 0)
346+                                r = 1;
347+        } else {
348+                fp = fopen(file, "r");
349+                if (!fp)
350+                        eprintf("fopen %s:", file);
351+                while (agetline(&buf, &size, fp) != -1) {
352+                        p = buf;
353+                        for (p = buf; *p == ' ' || *p == '\t'; p++)
354+                                ;
355+                        if (*p == '#' || *p == '\n')
356+                                continue;
357+                        for (p = buf; *p; p++) {
358+                                if (*p == '\n') {
359+                                        *p = '\0';
360+                                        break;
361+                                }
362+                        }
363+                        p = buf;
364+                        if (parsepair(p) < 0)
365+                                r = 1;
366+                }
367+                if (ferror(fp))
368+                        eprintf("%s: read error:", file);
369+                free(buf);
370+                fclose(fp);
371+        }
372+
373+        return r;
374 }
+1, -0
1@@ -17,6 +17,7 @@
2 #include <linux/if.h>
3 #include <linux/if_tun.h>
4 
5+#include "paths.h"
6 #include "util.h"
7 
8 static int dflag;
+3, -2
 1@@ -8,6 +8,7 @@
 2 #include <stdlib.h>
 3 #include <string.h>
 4 
 5+#include "paths.h"
 6 #include "util.h"
 7 
 8 #if FEATURE_UMOUNT_OPTIONS
 9@@ -87,9 +88,9 @@ umountall(int flags
10 	char **mntdirs = NULL;
11 	int len = 0;
12 
13-	fp = setmntent("/proc/mounts", "r");
14+	fp = setmntent(ARUU_LINUX_PATH_PROC_MOUNTS, "r");
15 	if (!fp)
16-		eprintf("setmntent %s:", "/proc/mounts");
17+		eprintf("setmntent %s:", ARUU_LINUX_PATH_PROC_MOUNTS);
18 	while ((me = getmntent(fp))) {
19 		if (strcmp(me->mnt_type, "proc") == 0)
20 			continue;
+3, -2
 1@@ -7,6 +7,7 @@
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 static void
 9@@ -58,8 +59,8 @@ main(int argc, char *argv[])
10 	if (unshare(flags) < 0)
11 		eprintf("unshare:");
12 
13-	if (execvp(argv[0], argv) < 0)
14-		eprintf("execvp:");
15+	if (0) wexecvp_self(argv[0], argv);
16+		eprintf("wexecvp:");
17 
18 	return 0;
19 }
+2, -1
 1@@ -10,9 +10,10 @@
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5+#include "paths.h"
 6 #include "util.h"
 7 
 8-#define CONSOLE "/dev/console"
 9+#define CONSOLE ARUU_PATH_DEVCONSOLE
10 
11 #define VT_LOCKSWITCH   0x560B  /* disallow vt switching */
12 #define VT_UNLOCKSWITCH 0x560C  /* allow vt switching */
+428, -424
  1@@ -1,6 +1,7 @@
  2 /* sdhcp: simple DHCP client, ported from git.2f30.org/sdhcp */
  3 /* See LICENSE file for copyright and license details */
  4 #include "arg.h"
  5+#include "wexec.h"
  6 #include "util.h"
  7 
  8 #include <errno.h>
  9@@ -23,67 +24,67 @@
 10 
 11 /* bootp packet layout: fields are byte arrays to avoid alignment/endian issues */
 12 struct Bootp {
 13-	unsigned char op      [1];
 14-	unsigned char htype   [1];
 15-	unsigned char hlen    [1];
 16-	unsigned char hops    [1];
 17-	unsigned char xid     [4];
 18-	unsigned char secs    [2];
 19-	unsigned char flags   [2];
 20-	unsigned char ciaddr  [4];
 21-	unsigned char yiaddr  [4];
 22-	unsigned char siaddr  [4];
 23-	unsigned char giaddr  [4];
 24-	unsigned char chaddr  [16];
 25-	unsigned char sname   [64];
 26-	unsigned char file    [128];
 27-	unsigned char magic   [4];
 28-	unsigned char optdata [312-4];
 29+        unsigned char op      [1];
 30+        unsigned char htype   [1];
 31+        unsigned char hlen    [1];
 32+        unsigned char hops    [1];
 33+        unsigned char xid     [4];
 34+        unsigned char secs    [2];
 35+        unsigned char flags   [2];
 36+        unsigned char ciaddr  [4];
 37+        unsigned char yiaddr  [4];
 38+        unsigned char siaddr  [4];
 39+        unsigned char giaddr  [4];
 40+        unsigned char chaddr  [16];
 41+        unsigned char sname   [64];
 42+        unsigned char file    [128];
 43+        unsigned char magic   [4];
 44+        unsigned char optdata [312-4];
 45 };
 46 
 47 enum {
 48-	DHCP_DISCOVER =       1,
 49-	DHCP_OFFER,
 50-	DHCP_REQUEST,
 51-	DHCP_DECLINE,
 52-	DHCP_ACK,
 53-	DHCP_NAK,
 54-	DHCP_RELEASE,
 55-	DHCP_INFORM,
 56-	/* internal sentinel values returned by dhcprecv */
 57-	TIMEOUT0 =          200,
 58-	TIMEOUT1,
 59-	TIMEOUT2,
 60-
 61-	BOOT_REQUEST =        1,
 62-	BOOT_REPLY =          2,
 63-	/* bootp flags */
 64-	F_BROADCAST =   1 << 15,
 65-
 66-	/* bootp options */
 67-	OB_PAD =              0,
 68-	OB_MASK =             1,
 69-	OB_ROUTER =           3,
 70-	OB_NAMESERVER =       5,
 71-	OB_DNSSERVER =        6,
 72-	OB_HOSTNAME =        12,
 73-	OB_BADDR =           28,
 74-	/* DHCP-specific options */
 75-	OD_IPADDR =          50, /* 0x32 */
 76-	OD_LEASE =           51,
 77-	OD_OVERLOAD =        52,
 78-	OD_TYPE =            53, /* 0x35 */
 79-	OD_SERVERID =        54, /* 0x36 */
 80-	OD_PARAMS =          55, /* 0x37 */
 81-	OD_MESSAGE =         56,
 82-	OD_MAXMSG =          57,
 83-	OD_RENEWALTIME =     58,
 84-	OD_REBINDINGTIME =   59,
 85-	OD_VENDORCLASS =     60,
 86-	OD_CLIENTID =        61, /* 0x3d */
 87-	OD_TFTPSERVER =      66,
 88-	OD_BOOTFILE =        67,
 89-	OB_END =            255,
 90+        DHCP_DISCOVER =       1,
 91+        DHCP_OFFER,
 92+        DHCP_REQUEST,
 93+        DHCP_DECLINE,
 94+        DHCP_ACK,
 95+        DHCP_NAK,
 96+        DHCP_RELEASE,
 97+        DHCP_INFORM,
 98+        /* internal sentinel values returned by dhcprecv */
 99+        TIMEOUT0 =          200,
100+        TIMEOUT1,
101+        TIMEOUT2,
102+
103+        BOOT_REQUEST =        1,
104+        BOOT_REPLY =          2,
105+        /* bootp flags */
106+        F_BROADCAST =   1 << 15,
107+
108+        /* bootp options */
109+        OB_PAD =              0,
110+        OB_MASK =             1,
111+        OB_ROUTER =           3,
112+        OB_NAMESERVER =       5,
113+        OB_DNSSERVER =        6,
114+        OB_HOSTNAME =        12,
115+        OB_BADDR =           28,
116+        /* DHCP-specific options */
117+        OD_IPADDR =          50, /* 0x32 */
118+        OD_LEASE =           51,
119+        OD_OVERLOAD =        52,
120+        OD_TYPE =            53, /* 0x35 */
121+        OD_SERVERID =        54, /* 0x36 */
122+        OD_PARAMS =          55, /* 0x37 */
123+        OD_MESSAGE =         56,
124+        OD_MAXMSG =          57,
125+        OD_RENEWALTIME =     58,
126+        OD_REBINDINGTIME =   59,
127+        OD_VENDORCLASS =     60,
128+        OD_CLIENTID =        61, /* 0x3d */
129+        OD_TFTPSERVER =      66,
130+        OD_BOOTFILE =        67,
131+        OB_END =            255,
132 };
133 
134 enum { BROADCAST, UNICAST };
135@@ -118,485 +119,488 @@ static int fflag = 0;
136 static void
137 hnput(unsigned char *dst, uint32_t src, size_t n)
138 {
139-	unsigned int i;
140+        unsigned int i;
141 
142-	for (i = 0; n--; i++)
143-		dst[i] = (src >> (n * 8)) & 0xff;
144+        for (i = 0; n--; i++)
145+                dst[i] = (src >> (n * 8)) & 0xff;
146 }
147 
148 static struct sockaddr *
149 iptoaddr(struct sockaddr *ifaddr, unsigned char ip[4], int port)
150 {
151-	struct sockaddr_in *in = (struct sockaddr_in *)ifaddr;
152+        struct sockaddr_in *in = (struct sockaddr_in *)ifaddr;
153 
154-	in->sin_family = AF_INET;
155-	in->sin_port = htons(port);
156-	memcpy(&(in->sin_addr), ip, sizeof(in->sin_addr));
157+        in->sin_family = AF_INET;
158+        in->sin_port = htons(port);
159+        memcpy(&(in->sin_addr), ip, sizeof(in->sin_addr));
160 
161-	return ifaddr;
162+        return ifaddr;
163 }
164 
165 /* sendto UDP wrapper: sends n bytes of data to bootp server port on ip */
166 static ssize_t
167 udpsend(unsigned char ip[4], int fd, void *data, size_t n)
168 {
169-	struct sockaddr addr;
170-	socklen_t addrlen = sizeof(addr);
171-	ssize_t sent;
172+        struct sockaddr addr;
173+        socklen_t addrlen = sizeof(addr);
174+        ssize_t sent;
175 
176-	iptoaddr(&addr, ip, 67); /* bootp server */
177-	if ((sent = sendto(fd, data, n, 0, &addr, addrlen)) == -1)
178-		eprintf("sendto:");
179+        iptoaddr(&addr, ip, 67); /* bootp server */
180+        if ((sent = sendto(fd, data, n, 0, &addr, addrlen)) == -1)
181+                eprintf("sendto:");
182 
183-	return sent;
184+        return sent;
185 }
186 
187 /* recvfrom UDP wrapper: receives into data from bootp client port */
188 static ssize_t
189 udprecv(unsigned char ip[4], int fd, void *data, size_t n)
190 {
191-	struct sockaddr addr;
192-	socklen_t addrlen = sizeof(addr);
193-	ssize_t r;
194+        struct sockaddr addr;
195+        socklen_t addrlen = sizeof(addr);
196+        ssize_t r;
197 
198-	iptoaddr(&addr, ip, 68); /* bootp client */
199-	if ((r = recvfrom(fd, data, n, 0, &addr, &addrlen)) == -1)
200-		eprintf("recvfrom:");
201+        iptoaddr(&addr, ip, 68); /* bootp client */
202+        if ((r = recvfrom(fd, data, n, 0, &addr, &addrlen)) == -1)
203+                eprintf("recvfrom:");
204 
205-	return r;
206+        return r;
207 }
208 
209 static void
210 setip(unsigned char ip[4], unsigned char mask[4], unsigned char gateway[4])
211 {
212-	struct ifreq ifreq;
213-	struct rtentry rtreq;
214-	int fd;
215-
216-	memset(&ifreq, 0, sizeof(ifreq));
217-	memset(&rtreq, 0, sizeof(rtreq));
218-
219-	strlcpy(ifreq.ifr_name, ifname, IF_NAMESIZE);
220-	iptoaddr(&(ifreq.ifr_addr), ip, 0);
221-	if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) == -1)
222-		eprintf("can't set ip, socket:");
223-	ioctl(fd, SIOCSIFADDR, &ifreq);
224-	iptoaddr(&(ifreq.ifr_netmask), mask, 0);
225-	ioctl(fd, SIOCSIFNETMASK, &ifreq);
226-	ifreq.ifr_flags = IFF_UP | IFF_RUNNING | IFF_BROADCAST | IFF_MULTICAST;
227-	ioctl(fd, SIOCSIFFLAGS, &ifreq);
228-	/* default gw */
229-	rtreq.rt_flags = RTF_UP | RTF_GATEWAY;
230-	iptoaddr(&(rtreq.rt_gateway), gateway, 0);
231-	iptoaddr(&(rtreq.rt_genmask), IP(0, 0, 0, 0), 0);
232-	iptoaddr(&(rtreq.rt_dst),     IP(0, 0, 0, 0), 0);
233-	ioctl(fd, SIOCADDRT, &rtreq);
234-
235-	close(fd);
236+        struct ifreq ifreq;
237+        struct rtentry rtreq;
238+        int fd;
239+
240+        memset(&ifreq, 0, sizeof(ifreq));
241+        memset(&rtreq, 0, sizeof(rtreq));
242+
243+        strlcpy(ifreq.ifr_name, ifname, IF_NAMESIZE);
244+        iptoaddr(&(ifreq.ifr_addr), ip, 0);
245+        if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) == -1)
246+                eprintf("can't set ip, socket:");
247+        ioctl(fd, SIOCSIFADDR, &ifreq);
248+        iptoaddr(&(ifreq.ifr_netmask), mask, 0);
249+        ioctl(fd, SIOCSIFNETMASK, &ifreq);
250+        ifreq.ifr_flags = IFF_UP | IFF_RUNNING | IFF_BROADCAST | IFF_MULTICAST;
251+        ioctl(fd, SIOCSIFFLAGS, &ifreq);
252+        /* default gw */
253+        rtreq.rt_flags = RTF_UP | RTF_GATEWAY;
254+        iptoaddr(&(rtreq.rt_gateway), gateway, 0);
255+        iptoaddr(&(rtreq.rt_genmask), IP(0, 0, 0, 0), 0);
256+        iptoaddr(&(rtreq.rt_dst),     IP(0, 0, 0, 0), 0);
257+        ioctl(fd, SIOCADDRT, &rtreq);
258+
259+        close(fd);
260 }
261 
262 /* copy contents of src path into dfd; silently skips missing files */
263 static void
264 appendfile(int dfd, char *src)
265 {
266-	char buf[BUFSIZ];
267-	int fd, n;
268-
269-	if ((fd = open(src, O_RDONLY)) == -1)
270-		return;
271-	while ((n = read(fd, buf, sizeof(buf))) > 0)
272-		writeall(dfd, buf, n);
273-	close(fd);
274+        char buf[BUFSIZ];
275+        int fd, n;
276+
277+        if ((fd = open(src, O_RDONLY)) == -1)
278+                return;
279+        while ((n = read(fd, buf, sizeof(buf))) > 0)
280+                writeall(dfd, buf, n);
281+        close(fd);
282 }
283 
284 static void
285 setdns(unsigned char ip[4])
286 {
287-	char buf[128];
288-	int fd, n;
289-
290-	if ((fd = creat("/etc/resolv.conf", 0644)) == -1) {
291-		weprintf("can't change /etc/resolv.conf:");
292-		return;
293-	}
294-	appendfile(fd, "/etc/resolv.conf.head");
295-	n = snprintf(buf, sizeof(buf), "\nnameserver %d.%d.%d.%d\n",
296-	    ip[0], ip[1], ip[2], ip[3]);
297-	if (n > 0)
298-		writeall(fd, buf, n);
299-	appendfile(fd, "/etc/resolv.conf.tail");
300-	close(fd);
301+        char buf[128];
302+        int fd, n;
303+
304+        if ((fd = creat("/etc/resolv.conf", 0644)) == -1) {
305+                weprintf("can't change /etc/resolv.conf:");
306+                return;
307+        }
308+        appendfile(fd, "/etc/resolv.conf.head");
309+        n = snprintf(buf, sizeof(buf), "\nnameserver %d.%d.%d.%d\n",
310+            ip[0], ip[1], ip[2], ip[3]);
311+        if (n > 0)
312+                writeall(fd, buf, n);
313+        appendfile(fd, "/etc/resolv.conf.tail");
314+        close(fd);
315 }
316 
317 /* scan b's option data for opt; copy up to n bytes into data */
318 static void
319 optget(struct Bootp *b, void *data, int opt, int n)
320 {
321-	unsigned char *p = b->optdata;
322-	unsigned char *top = ((unsigned char *)b) + sizeof(*b);
323-	int code, len;
324-
325-	while (p < top) {
326-		code = *p++;
327-		if (code == OB_PAD)
328-			continue;
329-		if (code == OB_END || p == top)
330-			break;
331-		len = *p++;
332-		if (len > top - p)
333-			break;
334-		if (code == opt) {
335-			memcpy(data, p, MIN(len, n));
336-			break;
337-		}
338-		p += len;
339-	}
340+        unsigned char *p = b->optdata;
341+        unsigned char *top = ((unsigned char *)b) + sizeof(*b);
342+        int code, len;
343+
344+        while (p < top) {
345+                code = *p++;
346+                if (code == OB_PAD)
347+                        continue;
348+                if (code == OB_END || p == top)
349+                        break;
350+                len = *p++;
351+                if (len > top - p)
352+                        break;
353+                if (code == opt) {
354+                        memcpy(data, p, MIN(len, n));
355+                        break;
356+                }
357+                p += len;
358+        }
359 }
360 
361 /* append a raw-bytes option to p; return new write cursor */
362 static unsigned char *
363 optput(unsigned char *p, int opt, unsigned char *data, size_t len)
364 {
365-	*p++ = opt;
366-	*p++ = (unsigned char)len;
367-	memcpy(p, data, len);
368+        *p++ = opt;
369+        *p++ = (unsigned char)len;
370+        memcpy(p, data, len);
371 
372-	return p + len;
373+        return p + len;
374 }
375 
376 /* append a big-endian numeric option to p; return new write cursor */
377 static unsigned char *
378 hnoptput(unsigned char *p, int opt, uint32_t data, size_t len)
379 {
380-	*p++ = opt;
381-	*p++ = (unsigned char)len;
382-	hnput(p, data, len);
383+        *p++ = opt;
384+        *p++ = (unsigned char)len;
385+        hnput(p, data, len);
386 
387-	return p + len;
388+        return p + len;
389 }
390 
391 static void
392 dhcpsend(int type, int how)
393 {
394-	unsigned char *ip, *p;
395-
396-	memset(&bp, 0, sizeof(bp));
397-	hnput(bp.op,    BOOT_REQUEST,              1);
398-	hnput(bp.htype, 1,                         1);
399-	hnput(bp.hlen,  6,                         1);
400-	memcpy(bp.xid,   xid,   sizeof(xid));
401-	hnput(bp.flags, F_BROADCAST, sizeof(bp.flags));
402-	hnput(bp.secs,  time(NULL) - starttime, sizeof(bp.secs));
403-	memcpy(bp.magic, magic, sizeof(bp.magic));
404-	memcpy(bp.chaddr, hwaddr, sizeof(bp.chaddr));
405-	p = bp.optdata;
406-	p = hnoptput(p, OD_TYPE,     type,                 1);
407-	p = optput(p,   OD_CLIENTID, cid,   sizeof(cid));
408-	p = optput(p,   OB_HOSTNAME, (unsigned char *)hostname, strlen(hostname));
409-
410-	switch (type) {
411-	case DHCP_DISCOVER:
412-		break;
413-	case DHCP_REQUEST:
414-		p = optput(p, OD_IPADDR,   client, sizeof(client));
415-		p = optput(p, OD_SERVERID, server, sizeof(server));
416-		break;
417-	case DHCP_RELEASE:
418-		memcpy(bp.ciaddr, client, sizeof(client));
419-		p = optput(p, OD_IPADDR,   client, sizeof(client));
420-		p = optput(p, OD_SERVERID, server, sizeof(server));
421-		break;
422-	}
423-	*p++ = OB_END;
424-
425-	ip = (how == BROADCAST) ? IP(255, 255, 255, 255) : server;
426-	udpsend(ip, sock, &bp, p - (unsigned char *)&bp);
427+        unsigned char *ip, *p;
428+
429+        memset(&bp, 0, sizeof(bp));
430+        hnput(bp.op,    BOOT_REQUEST,              1);
431+        hnput(bp.htype, 1,                         1);
432+        hnput(bp.hlen,  6,                         1);
433+        memcpy(bp.xid,   xid,   sizeof(xid));
434+        hnput(bp.flags, F_BROADCAST, sizeof(bp.flags));
435+        hnput(bp.secs,  time(NULL) - starttime, sizeof(bp.secs));
436+        memcpy(bp.magic, magic, sizeof(bp.magic));
437+        memcpy(bp.chaddr, hwaddr, sizeof(bp.chaddr));
438+        p = bp.optdata;
439+        p = hnoptput(p, OD_TYPE,     type,                 1);
440+        p = optput(p,   OD_CLIENTID, cid,   sizeof(cid));
441+        p = optput(p,   OB_HOSTNAME, (unsigned char *)hostname, strlen(hostname));
442+
443+        switch (type) {
444+        case DHCP_DISCOVER:
445+                break;
446+        case DHCP_REQUEST:
447+                p = optput(p, OD_IPADDR,   client, sizeof(client));
448+                p = optput(p, OD_SERVERID, server, sizeof(server));
449+                break;
450+        case DHCP_RELEASE:
451+                memcpy(bp.ciaddr, client, sizeof(client));
452+                p = optput(p, OD_IPADDR,   client, sizeof(client));
453+                p = optput(p, OD_SERVERID, server, sizeof(server));
454+                break;
455+        }
456+        *p++ = OB_END;
457+
458+        ip = (how == BROADCAST) ? IP(255, 255, 255, 255) : server;
459+        udpsend(ip, sock, &bp, p - (unsigned char *)&bp);
460 }
461 
462 /* block on poll; return DHCP message type or a TIMEOUT* sentinel */
463 static int
464 dhcprecv(void)
465 {
466-	unsigned char type = 0;
467-	uint64_t n;
468-	struct pollfd pfd[] = {
469-		{ .fd = sock,      .events = POLLIN },
470-		{ .fd = timers[0], .events = POLLIN },
471-		{ .fd = timers[1], .events = POLLIN },
472-		{ .fd = timers[2], .events = POLLIN },
473-	};
474-
475-	if (poll(pfd, LEN(pfd), -1) == -1)
476-		eprintf("poll:");
477-	if (pfd[0].revents) {
478-		memset(&bp, 0, sizeof(bp));
479-		udprecv(IP(255, 255, 255, 255), sock, &bp, sizeof(bp));
480-		optget(&bp, &type, OD_TYPE, sizeof(type));
481-		return type;
482-	}
483-	if (pfd[1].revents) {
484-		type = TIMEOUT0;
485-		read(timers[0], &n, sizeof(n));
486-	}
487-	if (pfd[2].revents) {
488-		type = TIMEOUT1;
489-		read(timers[1], &n, sizeof(n));
490-	}
491-	if (pfd[3].revents) {
492-		type = TIMEOUT2;
493-		read(timers[2], &n, sizeof(n));
494-	}
495-	return type;
496+        unsigned char type = 0;
497+        uint64_t n;
498+        struct pollfd pfd[] = {
499+                { .fd = sock,      .events = POLLIN },
500+                { .fd = timers[0], .events = POLLIN },
501+                { .fd = timers[1], .events = POLLIN },
502+                { .fd = timers[2], .events = POLLIN },
503+        };
504+
505+        if (poll(pfd, LEN(pfd), -1) == -1)
506+                eprintf("poll:");
507+        if (pfd[0].revents) {
508+                memset(&bp, 0, sizeof(bp));
509+                udprecv(IP(255, 255, 255, 255), sock, &bp, sizeof(bp));
510+                optget(&bp, &type, OD_TYPE, sizeof(type));
511+                return type;
512+        }
513+        if (pfd[1].revents) {
514+                type = TIMEOUT0;
515+                read(timers[0], &n, sizeof(n));
516+        }
517+        if (pfd[2].revents) {
518+                type = TIMEOUT1;
519+                read(timers[1], &n, sizeof(n));
520+        }
521+        if (pfd[3].revents) {
522+                type = TIMEOUT2;
523+                read(timers[2], &n, sizeof(n));
524+        }
525+        return type;
526 }
527 
528 static void
529 acceptlease(void)
530 {
531-	char buf[128];
532-
533-	if (iflag)
534-		setip(client, mask, router);
535-	if (dflag)
536-		setdns(dns);
537-	if (*program) {
538-		snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
539-		    server[0], server[1], server[2], server[3]);
540-		setenv("SERVER", buf, 1);
541-		snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
542-		    client[0], client[1], client[2], client[3]);
543-		setenv("CLIENT", buf, 1);
544-		snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
545-		    mask[0], mask[1], mask[2], mask[3]);
546-		setenv("MASK", buf, 1);
547-		snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
548-		    router[0], router[1], router[2], router[3]);
549-		setenv("ROUTER", buf, 1);
550-		snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
551-		    dns[0], dns[1], dns[2], dns[3]);
552-		setenv("DNS", buf, 1);
553-		system(program);
554-	}
555+        char buf[128];
556+
557+        if (iflag)
558+                setip(client, mask, router);
559+        if (dflag)
560+                setdns(dns);
561+        if (*program) {
562+                snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
563+                    server[0], server[1], server[2], server[3]);
564+                setenv("SERVER", buf, 1);
565+                snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
566+                    client[0], client[1], client[2], client[3]);
567+                setenv("CLIENT", buf, 1);
568+                snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
569+                    mask[0], mask[1], mask[2], mask[3]);
570+                setenv("MASK", buf, 1);
571+                snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
572+                    router[0], router[1], router[2], router[3]);
573+                setenv("ROUTER", buf, 1);
574+                snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
575+                    dns[0], dns[1], dns[2], dns[3]);
576+                setenv("DNS", buf, 1);
577+                wsystem(program);
578+        }
579 }
580 
581 static void
582 settimeout(int n, const struct itimerspec *ts)
583 {
584-	if (timerfd_settime(timers[n], 0, ts, NULL) < 0)
585-		eprintf("timerfd_settime:");
586+        if (timerfd_settime(timers[n], 0, ts, NULL) < 0)
587+                eprintf("timerfd_settime:");
588 }
589 
590 /* set ts to expire halfway to the remaining time on timer n, minimum 60s */
591 static void
592 calctimeout(int n, struct itimerspec *ts)
593 {
594-	if (timerfd_gettime(timers[n], ts) < 0)
595-		eprintf("timerfd_gettime:");
596-	ts->it_value.tv_nsec /= 2;
597-	if (ts->it_value.tv_sec % 2)
598-		ts->it_value.tv_nsec += 500000000;
599-	ts->it_value.tv_sec /= 2;
600-	if (ts->it_value.tv_sec < 60) {
601-		ts->it_value.tv_sec = 60;
602-		ts->it_value.tv_nsec = 0;
603-	}
604+        if (timerfd_gettime(timers[n], ts) < 0)
605+                eprintf("timerfd_gettime:");
606+        ts->it_value.tv_nsec /= 2;
607+        if (ts->it_value.tv_sec % 2)
608+                ts->it_value.tv_nsec += 500000000;
609+        ts->it_value.tv_sec /= 2;
610+        if (ts->it_value.tv_sec < 60) {
611+                ts->it_value.tv_sec = 60;
612+                ts->it_value.tv_nsec = 0;
613+        }
614 }
615 
616 /* RFC 2131 DHCP state machine */
617 static void
618 run(void)
619 {
620-	int forked = 0, t;
621-	struct itimerspec timeout = { 0 };
622-	uint32_t renewaltime, rebindingtime, lease;
623+        int forked = 0, t;
624+        struct itimerspec timeout = { 0 };
625+        uint32_t renewaltime, rebindingtime, lease;
626 
627 Init:
628-	dhcpsend(DHCP_DISCOVER, BROADCAST);
629-	timeout.it_value.tv_sec = 1;
630-	timeout.it_value.tv_nsec = 0;
631-	settimeout(0, &timeout);
632-	goto Selecting;
633+        dhcpsend(DHCP_DISCOVER, BROADCAST);
634+        timeout.it_value.tv_sec = 1;
635+        timeout.it_value.tv_nsec = 0;
636+        settimeout(0, &timeout);
637+        goto Selecting;
638 Selecting:
639-	for (;;) {
640-		switch (dhcprecv()) {
641-		case DHCP_OFFER:
642-			memcpy(client, bp.yiaddr, sizeof(client));
643-			optget(&bp, server, OD_SERVERID, sizeof(server));
644-			goto Requesting;
645-		case TIMEOUT0:
646-			goto Init;
647-		}
648-	}
649+        for (;;) {
650+                switch (dhcprecv()) {
651+                case DHCP_OFFER:
652+                        memcpy(client, bp.yiaddr, sizeof(client));
653+                        optget(&bp, server, OD_SERVERID, sizeof(server));
654+                        goto Requesting;
655+                case TIMEOUT0:
656+                        goto Init;
657+                }
658+        }
659 Requesting:
660-	for (t = 4; t <= 64; t *= 2) {
661-		dhcpsend(DHCP_REQUEST, BROADCAST);
662-		timeout.it_value.tv_sec = t;
663-		settimeout(0, &timeout);
664-		for (;;) {
665-			switch (dhcprecv()) {
666-			case DHCP_ACK:
667-				goto Bound;
668-			case DHCP_NAK:
669-				goto Init;
670-			case TIMEOUT0:
671-				break;
672-			default:
673-				continue;
674-			}
675-			break;
676-		}
677-	}
678-	/* no ACK after several DHCPREQUEST attempts */
679-	goto Init;
680+        for (t = 4; t <= 64; t *= 2) {
681+                dhcpsend(DHCP_REQUEST, BROADCAST);
682+                timeout.it_value.tv_sec = t;
683+                settimeout(0, &timeout);
684+                for (;;) {
685+                        switch (dhcprecv()) {
686+                        case DHCP_ACK:
687+                                goto Bound;
688+                        case DHCP_NAK:
689+                                goto Init;
690+                        case TIMEOUT0:
691+                                break;
692+                        default:
693+                                continue;
694+                        }
695+                        break;
696+                }
697+        }
698+        /* no ACK after several DHCPREQUEST attempts */
699+        goto Init;
700 Bound:
701-	optget(&bp, mask,           OB_MASK,          sizeof(mask));
702-	optget(&bp, router,         OB_ROUTER,        sizeof(router));
703-	optget(&bp, dns,            OB_DNSSERVER,     sizeof(dns));
704-	optget(&bp, &renewaltime,   OD_RENEWALTIME,   sizeof(renewaltime));
705-	optget(&bp, &rebindingtime, OD_REBINDINGTIME, sizeof(rebindingtime));
706-	optget(&bp, &lease,         OD_LEASE,         sizeof(lease));
707-	renewaltime   = ntohl(renewaltime);
708-	rebindingtime = ntohl(rebindingtime);
709-	lease         = ntohl(lease);
710-	acceptlease();
711-	puts("Bound. Network configured.");
712-	if (!fflag && !forked) {
713-		if (fork())
714-			exit(0);
715-		forked = 1;
716-	}
717-	timeout.it_value.tv_sec = renewaltime;
718-	settimeout(0, &timeout);
719-	timeout.it_value.tv_sec = rebindingtime;
720-	settimeout(1, &timeout);
721-	timeout.it_value.tv_sec = lease;
722-	settimeout(2, &timeout);
723-	for (;;) {
724-		switch (dhcprecv()) {
725-		case TIMEOUT0: /* t1: enter renewing */
726-			goto Renewing;
727-		case TIMEOUT1: /* t2: enter rebinding */
728-			goto Rebinding;
729-		case TIMEOUT2: /* lease expired */
730-			goto Init;
731-		}
732-	}
733+        optget(&bp, mask,           OB_MASK,          sizeof(mask));
734+        optget(&bp, router,         OB_ROUTER,        sizeof(router));
735+        optget(&bp, dns,            OB_DNSSERVER,     sizeof(dns));
736+        optget(&bp, &renewaltime,   OD_RENEWALTIME,   sizeof(renewaltime));
737+        optget(&bp, &rebindingtime, OD_REBINDINGTIME, sizeof(rebindingtime));
738+        optget(&bp, &lease,         OD_LEASE,         sizeof(lease));
739+        renewaltime   = ntohl(renewaltime);
740+        rebindingtime = ntohl(rebindingtime);
741+        lease         = ntohl(lease);
742+        acceptlease();
743+        puts("Bound. Network configured.");
744+        if (!fflag && !forked) {
745+                if (fork())
746+                        exit(0);
747+                forked = 1;
748+        }
749+        timeout.it_value.tv_sec = renewaltime;
750+        settimeout(0, &timeout);
751+        timeout.it_value.tv_sec = rebindingtime;
752+        settimeout(1, &timeout);
753+        timeout.it_value.tv_sec = lease;
754+        settimeout(2, &timeout);
755+        for (;;) {
756+                switch (dhcprecv()) {
757+                case TIMEOUT0: /* t1: enter renewing */
758+                        goto Renewing;
759+                case TIMEOUT1: /* t2: enter rebinding */
760+                        goto Rebinding;
761+                case TIMEOUT2: /* lease expired */
762+                        goto Init;
763+                }
764+        }
765 Renewing:
766-	dhcpsend(DHCP_REQUEST, UNICAST);
767-	calctimeout(1, &timeout);
768-	settimeout(0, &timeout);
769-	for (;;) {
770-		switch (dhcprecv()) {
771-		case DHCP_ACK:
772-			goto Bound;
773-		case TIMEOUT0: /* resend unicast */
774-			goto Renewing;
775-		case TIMEOUT1: /* t2 elapsed */
776-			goto Rebinding;
777-		case TIMEOUT2:
778-		case DHCP_NAK:
779-			goto Init;
780-		}
781-	}
782+        dhcpsend(DHCP_REQUEST, UNICAST);
783+        calctimeout(1, &timeout);
784+        settimeout(0, &timeout);
785+        for (;;) {
786+                switch (dhcprecv()) {
787+                case DHCP_ACK:
788+                        goto Bound;
789+                case TIMEOUT0: /* resend unicast */
790+                        goto Renewing;
791+                case TIMEOUT1: /* t2 elapsed */
792+                        goto Rebinding;
793+                case TIMEOUT2:
794+                case DHCP_NAK:
795+                        goto Init;
796+                }
797+        }
798 Rebinding:
799-	calctimeout(2, &timeout);
800-	settimeout(0, &timeout);
801-	dhcpsend(DHCP_REQUEST, BROADCAST);
802-	for (;;) {
803-		switch (dhcprecv()) {
804-		case DHCP_ACK:
805-			goto Bound;
806-		case TIMEOUT0: /* resend broadcast */
807-			goto Rebinding;
808-		case TIMEOUT2: /* lease expired */
809-		case DHCP_NAK:
810-			goto Init;
811-		}
812-	}
813+        calctimeout(2, &timeout);
814+        settimeout(0, &timeout);
815+        dhcpsend(DHCP_REQUEST, BROADCAST);
816+        for (;;) {
817+                switch (dhcprecv()) {
818+                case DHCP_ACK:
819+                        goto Bound;
820+                case TIMEOUT0: /* resend broadcast */
821+                        goto Rebinding;
822+                case TIMEOUT2: /* lease expired */
823+                case DHCP_NAK:
824+                        goto Init;
825+                }
826+        }
827 }
828 
829 static void
830 cleanexit(int unused)
831 {
832-	(void)unused;
833-	dhcpsend(DHCP_RELEASE, UNICAST);
834-	_exit(0);
835+        (void)unused;
836+        dhcpsend(DHCP_RELEASE, UNICAST);
837+        _exit(0);
838 }
839 
840 static void
841 usage(void)
842 {
843-	eprintf("usage: %s [-d] [-e program] [-f] [-i] [ifname] [clientid]\n", argv0);
844+        eprintf("usage: %s [-d] [-e program] [-f] [-i] [ifname] [clientid]\n", argv0);
845 }
846 
847+// ?man sdhcp: minimal DHCP client
848+// ?man arguments: [ifname] [clientid]
849+// ?man obtain an IPv4 lease via DHCP on the given interface
850 int
851 main(int argc, char *argv[])
852 {
853-	struct ifreq ifreq;
854-	struct sockaddr addr;
855-	int bcast = 1;
856-	int rnd;
857-	size_t i;
858-
859-	ARGBEGIN {
860-	case 'd': /* don't update /etc/resolv.conf */
861-		dflag = 0;
862-		break;
863-	case 'e': /* exec program on each lease */
864-		program = EARGF(usage());
865-		break;
866-	case 'f': /* stay in foreground */
867-		fflag = 1;
868-		break;
869-	case 'i': /* don't configure IP address */
870-		iflag = 0;
871-		break;
872-	default:
873-		usage();
874-		break;
875-	} ARGEND
876-
877-	if (argc)
878-		ifname = argv[0];
879-	if (argc >= 2)
880-		strlcpy((char *)cid, argv[1], sizeof(cid));
881-
882-	memset(&ifreq, 0, sizeof(ifreq));
883-	signal(SIGTERM, cleanexit);
884-
885-	if (gethostname(hostname, sizeof(hostname)) == -1)
886-		eprintf("gethostname:");
887-
888-	if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
889-		eprintf("socket:");
890-	if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof(bcast)) == -1)
891-		eprintf("setsockopt SO_BROADCAST:");
892-
893-	strlcpy(ifreq.ifr_name, ifname, IF_NAMESIZE);
894-	ioctl(sock, SIOCGIFINDEX, &ifreq);
895-	if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifreq, sizeof(ifreq)) == -1)
896-		eprintf("setsockopt SO_BINDTODEVICE:");
897-	iptoaddr(&addr, IP(255, 255, 255, 255), 68);
898-	if (bind(sock, &addr, sizeof(addr)) != 0)
899-		eprintf("bind:");
900-	ioctl(sock, SIOCGIFHWADDR, &ifreq);
901-	memcpy(hwaddr, ifreq.ifr_hwaddr.sa_data, sizeof(ifreq.ifr_hwaddr.sa_data));
902-	if (!cid[0])
903-		memcpy(cid, hwaddr, sizeof(cid));
904-
905-	if ((rnd = open("/dev/urandom", O_RDONLY)) == -1)
906-		eprintf("open /dev/urandom:");
907-	if (read(rnd, xid, sizeof(xid)) != (ssize_t)sizeof(xid))
908-		eprintf("read /dev/urandom:");
909-	close(rnd);
910-
911-	for (i = 0; i < LEN(timers); ++i) {
912-		timers[i] = timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC);
913-		if (timers[i] == -1)
914-			eprintf("timerfd_create:");
915-	}
916-
917-	starttime = time(NULL);
918-	run();
919-
920-	return 0;
921+        struct ifreq ifreq;
922+        struct sockaddr addr;
923+        int bcast = 1;
924+        int rnd;
925+        size_t i;
926+
927+        ARGBEGIN {
928+        case 'd': /* don't update /etc/resolv.conf */
929+                dflag = 0;
930+                break;
931+        case 'e': /* exec program on each lease */
932+                program = EARGF(usage());
933+                break;
934+        case 'f': /* stay in foreground */
935+                fflag = 1;
936+                break;
937+        case 'i': /* don't configure IP address */
938+                iflag = 0;
939+                break;
940+        default:
941+                usage();
942+                break;
943+        } ARGEND
944+
945+        if (argc)
946+                ifname = argv[0];
947+        if (argc >= 2)
948+                strlcpy((char *)cid, argv[1], sizeof(cid));
949+
950+        memset(&ifreq, 0, sizeof(ifreq));
951+        signal(SIGTERM, cleanexit);
952+
953+        if (gethostname(hostname, sizeof(hostname)) == -1)
954+                eprintf("gethostname:");
955+
956+        if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
957+                eprintf("socket:");
958+        if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof(bcast)) == -1)
959+                eprintf("setsockopt SO_BROADCAST:");
960+
961+        strlcpy(ifreq.ifr_name, ifname, IF_NAMESIZE);
962+        ioctl(sock, SIOCGIFINDEX, &ifreq);
963+        if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifreq, sizeof(ifreq)) == -1)
964+                eprintf("setsockopt SO_BINDTODEVICE:");
965+        iptoaddr(&addr, IP(255, 255, 255, 255), 68);
966+        if (bind(sock, &addr, sizeof(addr)) != 0)
967+                eprintf("bind:");
968+        ioctl(sock, SIOCGIFHWADDR, &ifreq);
969+        memcpy(hwaddr, ifreq.ifr_hwaddr.sa_data, sizeof(ifreq.ifr_hwaddr.sa_data));
970+        if (!cid[0])
971+                memcpy(cid, hwaddr, sizeof(cid));
972+
973+        if ((rnd = open("/dev/urandom", O_RDONLY)) == -1)
974+                eprintf("open /dev/urandom:");
975+        if (read(rnd, xid, sizeof(xid)) != (ssize_t)sizeof(xid))
976+                eprintf("read /dev/urandom:");
977+        close(rnd);
978+
979+        for (i = 0; i < LEN(timers); ++i) {
980+                timers[i] = timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC);
981+                if (timers[i] == -1)
982+                        eprintf("timerfd_create:");
983+        }
984+
985+        starttime = time(NULL);
986+        run();
987+
988+        return 0;
989 }
+1997, -1990
   1@@ -1,19 +1,19 @@
   2 /* See LICENSE file for copyright and license details. */
   3+#include "paths.h"
   4 #include "util.h"
   5+#include "wexec.h"
   6 
   7 #include <sys/stat.h>
   8 #include <sys/wait.h>
   9 
  10 #include <ctype.h>
  11 #include <dirent.h>
  12-#include <err.h>
  13 #include <errno.h>
  14 #include <fcntl.h>
  15 #include <fnmatch.h>
  16 #include <getopt.h>
  17 #include <limits.h>
  18 #include <math.h>
  19-#include <paths.h>
  20 #include <poll.h>
  21 #include <regex.h>
  22 #include <signal.h>
  23@@ -86,114 +86,113 @@
  24 #define COLORFLAG_ALWAYS 2
  25 
  26 #define FUNCTION_CONTEXT_SIZE 55
  27-#define _PATH_PR "/usr/bin/pr"
  28 
  29 #ifndef roundup
  30 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
  31 #endif
  32 
  33 struct Excludes {
  34-	char *pattern;
  35-	struct Excludes *next;
  36+        char *pattern;
  37+        struct Excludes *next;
  38 };
  39 
  40 struct Cand {
  41-	int x;
  42-	int y;
  43-	int pred;
  44+        int x;
  45+        int y;
  46+        int pred;
  47 };
  48 
  49 struct Line {
  50-	int serial;
  51-	int value;
  52+        int serial;
  53+        int value;
  54 };
  55 
  56 struct ContextVec {
  57-	int a;
  58-	int b;
  59-	int c;
  60-	int d;
  61+        int a;
  62+        int b;
  63+        int c;
  64+        int d;
  65 };
  66 
  67 struct Pr {
  68-	int ostdout;
  69-	pid_t cpid;
  70+        int ostdout;
  71+        pid_t cpid;
  72 };
  73 
  74 struct Algorithm {
  75-	const char *name;
  76-	int id;
  77+        const char *name;
  78+        int id;
  79 };
  80 
  81 static struct Algorithm algorithms[] = {
  82-	{"stone", D_DIFFSTONE},
  83-	{"myers", D_DIFFMYERS},
  84-	{"patience", D_DIFFPATIENCE},
  85-	{NULL, D_DIFFNONE}
  86+        {"stone", D_DIFFSTONE},
  87+        {"myers", D_DIFFMYERS},
  88+        {"patience", D_DIFFPATIENCE},
  89+        {NULL, D_DIFFNONE}
  90 };
  91 
  92 /* options */
  93 #define OPTIONS "0123456789A:aBbC:cdD:efF:HhI:iL:lnNPpqrS:sTtU:uwW:X:x:y"
  94 enum {
  95-	OPT_TSIZE = CHAR_MAX + 1,
  96-	OPT_STRIPCR,
  97-	OPT_IGN_FN_CASE,
  98-	OPT_NO_IGN_FN_CASE,
  99-	OPT_NORMAL,
 100-	OPT_HELP,
 101-	OPT_HORIZON_LINES,
 102-	OPT_CHANGED_GROUP_FORMAT,
 103-	OPT_SUPPRESS_COMMON,
 104-	OPT_COLOR,
 105-	OPT_NO_DEREFERENCE,
 106-	OPT_VERSION,
 107+        OPT_TSIZE = CHAR_MAX + 1,
 108+        OPT_STRIPCR,
 109+        OPT_IGN_FN_CASE,
 110+        OPT_NO_IGN_FN_CASE,
 111+        OPT_NORMAL,
 112+        OPT_HELP,
 113+        OPT_HORIZON_LINES,
 114+        OPT_CHANGED_GROUP_FORMAT,
 115+        OPT_SUPPRESS_COMMON,
 116+        OPT_COLOR,
 117+        OPT_NO_DEREFERENCE,
 118+        OPT_VERSION,
 119 };
 120 
 121 static struct option longopts[] = {
 122-	{ "algorithm",                  required_argument,      0,      'A' },
 123-	{ "text",                       no_argument,            0,      'a' },
 124-	{ "ignore-space-change",        no_argument,            0,      'b' },
 125-	{ "context",                    optional_argument,      0,      'C' },
 126-	{ "ifdef",                      required_argument,      0,      'D' },
 127-	{ "minimal",                    no_argument,            0,      'd' },
 128-	{ "ed",                         no_argument,            0,      'e' },
 129-	{ "forward-ed",                 no_argument,            0,      'f' },
 130-	{ "show-function-line",         required_argument,      0,      'F' },
 131-	{ "speed-large-files",          no_argument,            NULL,   'H' },
 132-	{ "ignore-blank-lines",         no_argument,            0,      'B' },
 133-	{ "ignore-matching-lines",      required_argument,      0,      'I' },
 134-	{ "ignore-case",                no_argument,            0,      'i' },
 135-	{ "paginate",                   no_argument,            NULL,   'l' },
 136-	{ "label",                      required_argument,      0,      'L' },
 137-	{ "new-file",                   no_argument,            0,      'N' },
 138-	{ "rcs",                        no_argument,            0,      'n' },
 139-	{ "unidirectional-new-file",    no_argument,            0,      'P' },
 140-	{ "show-c-function",            no_argument,            0,      'p' },
 141-	{ "brief",                      no_argument,            0,      'q' },
 142-	{ "recursive",                  no_argument,            0,      'r' },
 143-	{ "report-identical-files",     no_argument,            0,      's' },
 144-	{ "starting-file",              required_argument,      0,      'S' },
 145-	{ "expand-tabs",                no_argument,            0,      't' },
 146-	{ "initial-tab",                no_argument,            0,      'T' },
 147-	{ "unified",                    optional_argument,      0,      'U' },
 148-	{ "ignore-all-space",           no_argument,            0,      'w' },
 149-	{ "width",                      required_argument,      0,      'W' },
 150-	{ "exclude",                    required_argument,      0,      'x' },
 151-	{ "exclude-from",               required_argument,      0,      'X' },
 152-	{ "side-by-side",               no_argument,            NULL,   'y' },
 153-	{ "ignore-file-name-case",      no_argument,            NULL,   OPT_IGN_FN_CASE },
 154-	{ "help",                       no_argument,            NULL,   OPT_HELP},
 155-	{ "horizon-lines",              required_argument,      NULL,   OPT_HORIZON_LINES },
 156-	{ "no-dereference",             no_argument,            NULL,   OPT_NO_DEREFERENCE},
 157-	{ "no-ignore-file-name-case",   no_argument,            NULL,   OPT_NO_IGN_FN_CASE },
 158-	{ "normal",                     no_argument,            NULL,   OPT_NORMAL },
 159-	{ "strip-trailing-cr",          no_argument,            NULL,   OPT_STRIPCR },
 160-	{ "tabsize",                    required_argument,      NULL,   OPT_TSIZE },
 161-	{ "changed-group-format",       required_argument,      NULL,   OPT_CHANGED_GROUP_FORMAT},
 162-	{ "suppress-common-lines",      no_argument,            NULL,   OPT_SUPPRESS_COMMON },
 163-	{ "color",                      optional_argument,      NULL,   OPT_COLOR },
 164-	{ "version",                    no_argument,            NULL,   OPT_VERSION},
 165-	{ NULL,                         0,                      0,      '\0'}
 166+        { "algorithm",                  required_argument,      0,      'A' },
 167+        { "text",                       no_argument,            0,      'a' },
 168+        { "ignore-space-change",        no_argument,            0,      'b' },
 169+        { "context",                    optional_argument,      0,      'C' },
 170+        { "ifdef",                      required_argument,      0,      'D' },
 171+        { "minimal",                    no_argument,            0,      'd' },
 172+        { "ed",                         no_argument,            0,      'e' },
 173+        { "forward-ed",                 no_argument,            0,      'f' },
 174+        { "show-function-line",         required_argument,      0,      'F' },
 175+        { "speed-large-files",          no_argument,            NULL,   'H' },
 176+        { "ignore-blank-lines",         no_argument,            0,      'B' },
 177+        { "ignore-matching-lines",      required_argument,      0,      'I' },
 178+        { "ignore-case",                no_argument,            0,      'i' },
 179+        { "paginate",                   no_argument,            NULL,   'l' },
 180+        { "label",                      required_argument,      0,      'L' },
 181+        { "new-file",                   no_argument,            0,      'N' },
 182+        { "rcs",                        no_argument,            0,      'n' },
 183+        { "unidirectional-new-file",    no_argument,            0,      'P' },
 184+        { "show-c-function",            no_argument,            0,      'p' },
 185+        { "brief",                      no_argument,            0,      'q' },
 186+        { "recursive",                  no_argument,            0,      'r' },
 187+        { "report-identical-files",     no_argument,            0,      's' },
 188+        { "starting-file",              required_argument,      0,      'S' },
 189+        { "expand-tabs",                no_argument,            0,      't' },
 190+        { "initial-tab",                no_argument,            0,      'T' },
 191+        { "unified",                    optional_argument,      0,      'U' },
 192+        { "ignore-all-space",           no_argument,            0,      'w' },
 193+        { "width",                      required_argument,      0,      'W' },
 194+        { "exclude",                    required_argument,      0,      'x' },
 195+        { "exclude-from",               required_argument,      0,      'X' },
 196+        { "side-by-side",               no_argument,            NULL,   'y' },
 197+        { "ignore-file-name-case",      no_argument,            NULL,   OPT_IGN_FN_CASE },
 198+        { "help",                       no_argument,            NULL,   OPT_HELP},
 199+        { "horizon-lines",              required_argument,      NULL,   OPT_HORIZON_LINES },
 200+        { "no-dereference",             no_argument,            NULL,   OPT_NO_DEREFERENCE},
 201+        { "no-ignore-file-name-case",   no_argument,            NULL,   OPT_NO_IGN_FN_CASE },
 202+        { "normal",                     no_argument,            NULL,   OPT_NORMAL },
 203+        { "strip-trailing-cr",          no_argument,            NULL,   OPT_STRIPCR },
 204+        { "tabsize",                    required_argument,      NULL,   OPT_TSIZE },
 205+        { "changed-group-format",       required_argument,      NULL,   OPT_CHANGED_GROUP_FORMAT},
 206+        { "suppress-common-lines",      no_argument,            NULL,   OPT_SUPPRESS_COMMON },
 207+        { "color",                      optional_argument,      NULL,   OPT_COLOR },
 208+        { "version",                    no_argument,            NULL,   OPT_VERSION},
 209+        { NULL,                         0,                      0,      '\0'}
 210 };
 211 
 212 static const char diff_version[] = "FreeBSD diff 20240307";
 213@@ -213,9 +212,9 @@ struct Excludes *excludes_list;
 214 regex_t ignore_re, most_recent_re;
 215 
 216 enum Readhash {
 217-	RH_BINARY,
 218-	RH_OK,
 219-	RH_EOF
 220+        RH_BINARY,
 221+        RH_OK,
 222+        RH_EOF
 223 };
 224 
 225 static struct Line *file[2];
 226@@ -305,101 +304,109 @@ void stop_pr(struct Pr *);
 227 static void
 228 handle_sig(int signo)
 229 {
 230-	write(sigpipe[1], &signo, sizeof(signo));
 231+        write(sigpipe[1], &signo, sizeof(signo));
 232 }
 233 
 234 struct Pr *
 235 start_pr(char *file1, char *file2)
 236 {
 237-	int pfd[2];
 238-	pid_t pid;
 239-	char *header;
 240-	struct Pr *pr;
 241-
 242-	pr = ecalloc(1, sizeof(*pr));
 243-	xasprintf(&header, "%s %s %s", diffargs, file1, file2);
 244-	signal(SIGPIPE, SIG_IGN);
 245-	fflush(stdout);
 246-	if (pipe(pfd) == -1)
 247-		err(2, "pipe");
 248-	if (sigpipe[0] < 0) {
 249-		if (pipe(sigpipe) == -1)
 250-			err(2, "pipe");
 251-		if (fcntl(sigpipe[0], F_SETFD, FD_CLOEXEC) == -1)
 252-			err(2, "fcntl");
 253-		if (fcntl(sigpipe[1], F_SETFD, FD_CLOEXEC) == -1)
 254-			err(2, "fcntl");
 255-		if (signal(SIGCHLD, handle_sig) == SIG_ERR)
 256-			err(2, "signal");
 257-		poll_fd.fd = sigpipe[0];
 258-		poll_fd.events = POLLIN;
 259-	}
 260-	poll_fd.revents = 0;
 261-	switch ((pid = fork())) {
 262-	case -1:
 263-		status |= 2;
 264-		free(header);
 265-		err(2, "no more processes");
 266-	case 0:
 267-		if (pfd[0] != STDIN_FILENO) {
 268-			dup2(pfd[0], STDIN_FILENO);
 269-			close(pfd[0]);
 270-		}
 271-		close(pfd[1]);
 272-		execl(_PATH_PR, _PATH_PR, "-h", header, (char *)0);
 273-		_exit(127);
 274-	default:
 275-		if (pfd[1] != STDOUT_FILENO) {
 276-			pr->ostdout = dup(STDOUT_FILENO);
 277-			dup2(pfd[1], STDOUT_FILENO);
 278-			close(pfd[1]);
 279-		}
 280-		close(pfd[0]);
 281-		free(header);
 282-		pr->cpid = pid;
 283-	}
 284-	return pr;
 285+        int pfd[2];
 286+        pid_t pid;
 287+        char *header;
 288+        struct Pr *pr;
 289+
 290+        pr = ecalloc(1, sizeof(*pr));
 291+        xasprintf(&header, "%s %s %s", diffargs, file1, file2);
 292+        signal(SIGPIPE, SIG_IGN);
 293+        fflush(stdout);
 294+        if (pipe(pfd) == -1)
 295+                enprintf(2, "pipe");
 296+        if (sigpipe[0] < 0) {
 297+                if (pipe(sigpipe) == -1)
 298+                        enprintf(2, "pipe");
 299+                if (fcntl(sigpipe[0], F_SETFD, FD_CLOEXEC) == -1)
 300+                        enprintf(2, "fcntl");
 301+                if (fcntl(sigpipe[1], F_SETFD, FD_CLOEXEC) == -1)
 302+                        enprintf(2, "fcntl");
 303+                if (signal(SIGCHLD, handle_sig) == SIG_ERR)
 304+                        enprintf(2, "signal");
 305+                poll_fd.fd = sigpipe[0];
 306+                poll_fd.events = POLLIN;
 307+        }
 308+        poll_fd.revents = 0;
 309+        switch ((pid = fork())) {
 310+        case -1:
 311+                status |= 2;
 312+                free(header);
 313+                enprintf(2, "no more processes");
 314+                /* fallthrough */
 315+        case 0:
 316+                if (pfd[0] != STDIN_FILENO) {
 317+                        dup2(pfd[0], STDIN_FILENO);
 318+                        close(pfd[0]);
 319+                }
 320+                close(pfd[1]);
 321+                {
 322+                        char *pr_argv[4];
 323+                        pr_argv[0] = "pr";
 324+                        pr_argv[1] = "-h";
 325+                        pr_argv[2] = header;
 326+                        pr_argv[3] = NULL;
 327+                        wexecvp_self("pr", pr_argv);
 328+                }
 329+                _exit(127);
 330+        default:
 331+                if (pfd[1] != STDOUT_FILENO) {
 332+                        pr->ostdout = dup(STDOUT_FILENO);
 333+                        dup2(pfd[1], STDOUT_FILENO);
 334+                        close(pfd[1]);
 335+                }
 336+                close(pfd[0]);
 337+                free(header);
 338+                pr->cpid = pid;
 339+        }
 340+        return pr;
 341 }
 342 
 343 void
 344 stop_pr(struct Pr *pr)
 345 {
 346-	int wstatus;
 347-	int done = 0;
 348-
 349-	if (!pr)
 350-		return;
 351-
 352-	fflush(stdout);
 353-	if (pr->ostdout != STDOUT_FILENO) {
 354-		close(STDOUT_FILENO);
 355-		dup2(pr->ostdout, STDOUT_FILENO);
 356-		close(pr->ostdout);
 357-	}
 358-	while (!done) {
 359-		pid_t wpid;
 360-		int npe = poll(&poll_fd, 1, -1);
 361-		if (npe == -1) {
 362-			if (errno == EINTR)
 363-				continue;
 364-			err(2, "poll");
 365-		}
 366-		if (poll_fd.revents != POLLIN)
 367-			continue;
 368-		if (read(poll_fd.fd, &npe, sizeof(npe)) < 0)
 369-			err(2, "read");
 370-		while ((wpid = waitpid(-1, &wstatus, WNOHANG)) > 0) {
 371-			if (wpid != pr->cpid)
 372-				continue;
 373-			if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != 0)
 374-				errx(2, "pr exited abnormally");
 375-			else if (WIFSIGNALED(wstatus))
 376-				errx(2, "pr killed by signal %d", WTERMSIG(wstatus));
 377-			done = 1;
 378-			break;
 379-		}
 380-	}
 381-	free(pr);
 382+        int wstatus;
 383+        int done = 0;
 384+
 385+        if (!pr)
 386+                return;
 387+
 388+        fflush(stdout);
 389+        if (pr->ostdout != STDOUT_FILENO) {
 390+                close(STDOUT_FILENO);
 391+                dup2(pr->ostdout, STDOUT_FILENO);
 392+                close(pr->ostdout);
 393+        }
 394+        while (!done) {
 395+                pid_t wpid;
 396+                int npe = poll(&poll_fd, 1, -1);
 397+                if (npe == -1) {
 398+                        if (errno == EINTR)
 399+                                continue;
 400+                        enprintf(2, "poll");
 401+                }
 402+                if (poll_fd.revents != POLLIN)
 403+                        continue;
 404+                if (read(poll_fd.fd, &npe, sizeof(npe)) < 0)
 405+                        enprintf(2, "read");
 406+                while ((wpid = waitpid(-1, &wstatus, WNOHANG)) > 0) {
 407+                        if (wpid != pr->cpid)
 408+                                continue;
 409+                        if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != 0)
 410+                                enprintf(2, "pr exited abnormally");
 411+                        else if (WIFSIGNALED(wstatus))
 412+                                enprintf(2, "pr killed by signal %d", WTERMSIG(wstatus));
 413+                        done = 1;
 414+                        break;
 415+                }
 416+        }
 417+        free(pr);
 418 }
 419 
 420 // ?man diff: differential file and directory comparator
 421@@ -408,1823 +415,1823 @@ stop_pr(struct Pr *pr)
 422 int
 423 main(int argc, char **argv)
 424 {
 425-	const char *errstr = NULL;
 426-	char *ep, **oargv;
 427-	long l;
 428-	int ch, dflags, lastch, gotstdin, prevoptind, newarg;
 429-
 430-	oargv = argv;
 431-	gotstdin = 0;
 432-	dflags = 0;
 433-	lastch = '\0';
 434-	prevoptind = 1;
 435-	newarg = 1;
 436-	diff_context = 3;
 437-	diff_format = D_UNSET;
 438-	diff_algorithm = D_DIFFMYERS;
 439-	diff_algorithm_set = 0;
 440+        const char *errstr = NULL;
 441+        char *ep, **oargv;
 442+        long l;
 443+        int ch, dflags, lastch, gotstdin, prevoptind, newarg;
 444+
 445+        oargv = argv;
 446+        gotstdin = 0;
 447+        dflags = 0;
 448+        lastch = '\0';
 449+        prevoptind = 1;
 450+        newarg = 1;
 451+        diff_context = 3;
 452+        diff_format = D_UNSET;
 453+        diff_algorithm = D_DIFFMYERS;
 454+        diff_algorithm_set = 0;
 455 #define FORMAT_MISMATCHED(type) \
 456-	(diff_format != D_UNSET && diff_format != (type))
 457-	while ((ch = getopt_long(argc, argv, OPTIONS, longopts, NULL)) != -1) {
 458-		// ?man -0: context length
 459-		// ?man -1: context length
 460-		// ?man -2: context length
 461-		// ?man -3: context length
 462-		// ?man -4: context length
 463-		// ?man -5: context length
 464-		// ?man -6: context length
 465-		// ?man -7: context length
 466-		// ?man -8: context length
 467-		// ?man -9: context length
 468-		switch (ch) {
 469-		case '0': case '1': case '2': case '3': case '4':
 470-		case '5': case '6': case '7': case '8': case '9':
 471-			if (newarg)
 472-				usage();
 473-			else if (lastch == 'c' || lastch == 'u')
 474-				diff_context = 0;
 475-			else if (!isdigit(lastch) || diff_context > INT_MAX / 10)
 476-				usage();
 477-			diff_context = (diff_context * 10) + (ch - '0');
 478-			break;
 479-		// ?man -A:algo: algorithm (stone, myers, patience)
 480-		case 'A':
 481-			diff_algorithm = D_DIFFNONE;
 482-			for (struct Algorithm *a = algorithms; a->name; a++) {
 483-				if (strcasecmp(optarg, a->name) == 0) {
 484-					diff_algorithm = a->id;
 485-					diff_algorithm_set = 1;
 486-					break;
 487-				}
 488-			}
 489-			if (diff_algorithm == D_DIFFNONE) {
 490-				printf("unknown algorithm: %s\n", optarg);
 491-				usage();
 492-			}
 493-			break;
 494-		// ?man -a: force text mode
 495-		case 'a':
 496-			dflags |= D_FORCEASCII;
 497-			break;
 498-		// ?man -b: ignore space changes
 499-		case 'b':
 500-			dflags |= D_FOLDBLANKS;
 501-			break;
 502-		// ?man -C:lines: context format
 503-		case 'C':
 504-		// ?man -c: context format
 505-		case 'c':
 506-			if (FORMAT_MISMATCHED(D_CONTEXT))
 507-				conflicting_format();
 508-			cflag = 1;
 509-			diff_format = D_CONTEXT;
 510-			if (optarg != NULL) {
 511-				l = strtol(optarg, &ep, 10);
 512-				if (*ep != '\0' || l < 0 || l >= INT_MAX)
 513-					usage();
 514-				diff_context = (int)l;
 515-			}
 516-			break;
 517-		// ?man -d: minimal diff search
 518-		case 'd':
 519-			dflags |= D_MINIMAL;
 520-			break;
 521-		// ?man -D:name: ifdef format
 522-		case 'D':
 523-			if (FORMAT_MISMATCHED(D_IFDEF))
 524-				conflicting_format();
 525-			diff_format = D_IFDEF;
 526-			ifdefname = optarg;
 527-			break;
 528-		// ?man -e: ed script format
 529-		case 'e':
 530-			if (FORMAT_MISMATCHED(D_EDIT))
 531-				conflicting_format();
 532-			diff_format = D_EDIT;
 533-			break;
 534-		// ?man -f: forward ed script format
 535-		case 'f':
 536-			if (FORMAT_MISMATCHED(D_REVERSE))
 537-				conflicting_format();
 538-			diff_format = D_REVERSE;
 539-			break;
 540-		// ?man -H: speed up large files (stub)
 541-		case 'H':
 542-			break;
 543-		// ?man -h: backward compatibility (stub)
 544-		case 'h':
 545-			break;
 546-		// ?man -B: ignore blank lines
 547-		case 'B':
 548-			dflags |= D_SKIPBLANKLINES;
 549-			break;
 550-		// ?man -F:pat: show function matching pattern
 551-		case 'F':
 552-			if (dflags & D_PROTOTYPE)
 553-				conflicting_format();
 554-			dflags |= D_MATCHLAST;
 555-			most_recent_pat = estrdup(optarg);
 556-			break;
 557-		// ?man -I:pat: ignore pattern matching lines
 558-		case 'I':
 559-			push_ignore_pats(optarg);
 560-			break;
 561-		// ?man -i: ignore case
 562-		case 'i':
 563-			dflags |= D_IGNORECASE;
 564-			break;
 565-		// ?man -L:label: custom label
 566-		case 'L':
 567-			if (label[0] == NULL)
 568-				label[0] = optarg;
 569-			else if (label[1] == NULL)
 570-				label[1] = optarg;
 571-			else
 572-				usage();
 573-			break;
 574-		// ?man -l: paginate output using pr
 575-		case 'l':
 576-			lflag = 1;
 577-			break;
 578-		// ?man -N: treat missing files as empty
 579-		case 'N':
 580-			Nflag = 1;
 581-			break;
 582-		// ?man -n: rcs format
 583-		case 'n':
 584-			if (FORMAT_MISMATCHED(D_NREVERSE))
 585-				conflicting_format();
 586-			diff_format = D_NREVERSE;
 587-			break;
 588-		// ?man -p: show C prototype context
 589-		case 'p':
 590-			if (dflags & D_MATCHLAST)
 591-				conflicting_format();
 592-			dflags |= D_PROTOTYPE;
 593-			break;
 594-		// ?man -P: treat missing destination files as empty
 595-		case 'P':
 596-			Pflag = 1;
 597-			break;
 598-		// ?man -r: recursive directory comparison
 599-		case 'r':
 600-			rflag = 1;
 601-			break;
 602-		// ?man -q: brief output (differ / same only)
 603-		case 'q':
 604-			if (FORMAT_MISMATCHED(D_BRIEF))
 605-				conflicting_format();
 606-			diff_format = D_BRIEF;
 607-			break;
 608-		// ?man -S:name: starting file in directory comparison
 609-		case 'S':
 610-			start = optarg;
 611-			break;
 612-		// ?man -s: report identical files
 613-		case 's':
 614-			sflag = 1;
 615-			break;
 616-		// ?man -T: initial tab alignment
 617-		case 'T':
 618-			Tflag = 1;
 619-			break;
 620-		// ?man -t: expand tabs in output
 621-		case 't':
 622-			dflags |= D_EXPANDTABS;
 623-			break;
 624-		// ?man -U:lines: unified context format
 625-		case 'U':
 626-		// ?man -u: unified context format
 627-		case 'u':
 628-			if (FORMAT_MISMATCHED(D_UNIFIED))
 629-				conflicting_format();
 630-			diff_format = D_UNIFIED;
 631-			if (optarg != NULL) {
 632-				l = strtol(optarg, &ep, 10);
 633-				if (*ep != '\0' || l < 0 || l >= INT_MAX)
 634-					usage();
 635-				diff_context = (int)l;
 636-			}
 637-			break;
 638-		// ?man -w: ignore all whitespace
 639-		case 'w':
 640-			dflags |= D_IGNOREBLANKS;
 641-			break;
 642-		// ?man -W:cols: column width for side-by-side
 643-		case 'W':
 644-			width = (int)strtonum(optarg, 1, INT_MAX, &errstr);
 645-			if (errstr) {
 646-				warnx("invalid width argument");
 647-				usage();
 648-			}
 649-			break;
 650-		// ?man -X:file: exclude patterns file
 651-		case 'X':
 652-			read_excludes_file(optarg);
 653-			break;
 654-		// ?man -x:pat: exclude pattern
 655-		case 'x':
 656-			push_excludes(optarg);
 657-			break;
 658-		// ?man -y: side by side format
 659-		case 'y':
 660-			if (FORMAT_MISMATCHED(D_SIDEBYSIDE))
 661-				conflicting_format();
 662-			diff_format = D_SIDEBYSIDE;
 663-			break;
 664-		case OPT_CHANGED_GROUP_FORMAT:
 665-			if (FORMAT_MISMATCHED(D_GFORMAT))
 666-				conflicting_format();
 667-			diff_format = D_GFORMAT;
 668-			group_format = optarg;
 669-			break;
 670-		case OPT_HELP:
 671-			help = 1;
 672-			usage();
 673-			break;
 674-		case OPT_HORIZON_LINES:
 675-			break;
 676-		case OPT_IGN_FN_CASE:
 677-			ignore_file_case = 1;
 678-			break;
 679-		case OPT_NO_IGN_FN_CASE:
 680-			ignore_file_case = 0;
 681-			break;
 682-		case OPT_NORMAL:
 683-			if (FORMAT_MISMATCHED(D_NORMAL))
 684-				conflicting_format();
 685-			diff_format = D_NORMAL;
 686-			break;
 687-		case OPT_TSIZE:
 688-			tabsize = (int)strtonum(optarg, 1, INT_MAX, &errstr);
 689-			if (errstr) {
 690-				warnx("invalid tabsize argument");
 691-				usage();
 692-			}
 693-			break;
 694-		case OPT_STRIPCR:
 695-			dflags |= D_STRIPCR;
 696-			break;
 697-		case OPT_SUPPRESS_COMMON:
 698-			suppress_common = 1;
 699-			break;
 700-		case OPT_COLOR:
 701-			if (optarg == NULL || strncmp(optarg, "auto", 4) == 0)
 702-				colorflag = COLORFLAG_AUTO;
 703-			else if (strncmp(optarg, "always", 6) == 0)
 704-				colorflag = COLORFLAG_ALWAYS;
 705-			else if (strncmp(optarg, "never", 5) == 0)
 706-				colorflag = COLORFLAG_NEVER;
 707-			else
 708-				errx(2, "unsupported color option %s", optarg);
 709-			break;
 710-		case OPT_NO_DEREFERENCE:
 711-			noderef = 1;
 712-			break;
 713-		case OPT_VERSION:
 714-			printf("%s\n", diff_version);
 715-			exit(0);
 716-		default:
 717-			usage();
 718-			break;
 719-		}
 720-		lastch = ch;
 721-		newarg = optind != prevoptind;
 722-		prevoptind = optind;
 723-	}
 724-	if (diff_format == D_UNSET && (dflags & D_PROTOTYPE) != 0)
 725-		diff_format = D_CONTEXT;
 726-	if (diff_format == D_UNSET)
 727-		diff_format = D_NORMAL;
 728-	argc -= optind;
 729-	argv += optind;
 730-
 731-	if (do_color()) {
 732-		char *p;
 733-		const char *env;
 734-
 735-		color = 1;
 736-		add_code = "32";
 737-		del_code = "31";
 738-		env = getenv("DIFFCOLORS");
 739-		if (env != NULL && *env != '\0' && (p = estrdup(env))) {
 740-			add_code = p;
 741-			strsep(&p, ":");
 742-			if (p != NULL)
 743-				del_code = p;
 744-		}
 745-	}
 746-
 747-	if (argc != 2)
 748-		usage();
 749-	checked_regcomp(ignore_pats, &ignore_re);
 750-	checked_regcomp(most_recent_pat, &most_recent_re);
 751-	if (strcmp(argv[0], "-") == 0) {
 752-		fstat(STDIN_FILENO, &stb1);
 753-		gotstdin = 1;
 754-	} else if (stat(argv[0], &stb1) != 0) {
 755-		if (!Nflag || errno != ENOENT)
 756-			err(2, "%s", argv[0]);
 757-		dflags |= D_EMPTY1;
 758-		memset(&stb1, 0, sizeof(struct stat));
 759-	}
 760-
 761-	if (strcmp(argv[1], "-") == 0) {
 762-		fstat(STDIN_FILENO, &stb2);
 763-		gotstdin = 1;
 764-	} else if (stat(argv[1], &stb2) != 0) {
 765-		if (!Nflag || errno != ENOENT)
 766-			err(2, "%s", argv[1]);
 767-		dflags |= D_EMPTY2;
 768-		memset(&stb2, 0, sizeof(stb2));
 769-		stb2.st_mode = stb1.st_mode;
 770-	}
 771-
 772-	if (dflags & D_EMPTY1 && dflags & D_EMPTY2){
 773-		warn("%s", argv[0]);
 774-		warn("%s", argv[1]);
 775-		exit(2);
 776-	}
 777-
 778-	if (stb1.st_mode == 0)
 779-		stb1.st_mode = stb2.st_mode;
 780-
 781-	if (gotstdin && (S_ISDIR(stb1.st_mode) || S_ISDIR(stb2.st_mode)))
 782-		errx(2, "cant compare - to directory");
 783-	set_argstr(oargv, argv);
 784-	if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) {
 785-		if (diff_format == D_IFDEF)
 786-			errx(2, "-D option not supported with directories");
 787-		diffdir(argv[0], argv[1], dflags);
 788-	} else {
 789-		if (S_ISDIR(stb1.st_mode)) {
 790-			argv[0] = diff_splice(argv[0], argv[1]);
 791-			if (stat(argv[0], &stb1) == -1)
 792-				err(2, "%s", argv[0]);
 793-		}
 794-		if (S_ISDIR(stb2.st_mode)) {
 795-			argv[1] = diff_splice(argv[1], argv[0]);
 796-			if (stat(argv[1], &stb2) == -1)
 797-				err(2, "%s", argv[1]);
 798-		}
 799-		print_status(diffreg(argv[0], argv[1], dflags, 1), argv[0], argv[1], "");
 800-	}
 801-	if (fflush(stdout) != 0)
 802-		err(2, "stdout");
 803-	exit(status);
 804+        (diff_format != D_UNSET && diff_format != (type))
 805+        while ((ch = getopt_long(argc, argv, OPTIONS, longopts, NULL)) != -1) {
 806+                // ?man -0: context length
 807+                // ?man -1: context length
 808+                // ?man -2: context length
 809+                // ?man -3: context length
 810+                // ?man -4: context length
 811+                // ?man -5: context length
 812+                // ?man -6: context length
 813+                // ?man -7: context length
 814+                // ?man -8: context length
 815+                // ?man -9: context length
 816+                switch (ch) {
 817+                case '0': case '1': case '2': case '3': case '4':
 818+                case '5': case '6': case '7': case '8': case '9':
 819+                        if (newarg)
 820+                                usage();
 821+                        else if (lastch == 'c' || lastch == 'u')
 822+                                diff_context = 0;
 823+                        else if (!isdigit(lastch) || diff_context > INT_MAX / 10)
 824+                                usage();
 825+                        diff_context = (diff_context * 10) + (ch - '0');
 826+                        break;
 827+                // ?man -A:algo: algorithm (stone, myers, patience)
 828+                case 'A':
 829+                        diff_algorithm = D_DIFFNONE;
 830+                        for (struct Algorithm *a = algorithms; a->name; a++) {
 831+                                if (strcasecmp(optarg, a->name) == 0) {
 832+                                        diff_algorithm = a->id;
 833+                                        diff_algorithm_set = 1;
 834+                                        break;
 835+                                }
 836+                        }
 837+                        if (diff_algorithm == D_DIFFNONE) {
 838+                                printf("unknown algorithm: %s\n", optarg);
 839+                                usage();
 840+                        }
 841+                        break;
 842+                // ?man -a: force text mode
 843+                case 'a':
 844+                        dflags |= D_FORCEASCII;
 845+                        break;
 846+                // ?man -b: ignore space changes
 847+                case 'b':
 848+                        dflags |= D_FOLDBLANKS;
 849+                        break;
 850+                // ?man -C:lines: context format
 851+                case 'C':
 852+                // ?man -c: context format
 853+                case 'c':
 854+                        if (FORMAT_MISMATCHED(D_CONTEXT))
 855+                                conflicting_format();
 856+                        cflag = 1;
 857+                        diff_format = D_CONTEXT;
 858+                        if (optarg != NULL) {
 859+                                l = strtol(optarg, &ep, 10);
 860+                                if (*ep != '\0' || l < 0 || l >= INT_MAX)
 861+                                        usage();
 862+                                diff_context = (int)l;
 863+                        }
 864+                        break;
 865+                // ?man -d: minimal diff search
 866+                case 'd':
 867+                        dflags |= D_MINIMAL;
 868+                        break;
 869+                // ?man -D:name: ifdef format
 870+                case 'D':
 871+                        if (FORMAT_MISMATCHED(D_IFDEF))
 872+                                conflicting_format();
 873+                        diff_format = D_IFDEF;
 874+                        ifdefname = optarg;
 875+                        break;
 876+                // ?man -e: ed script format
 877+                case 'e':
 878+                        if (FORMAT_MISMATCHED(D_EDIT))
 879+                                conflicting_format();
 880+                        diff_format = D_EDIT;
 881+                        break;
 882+                // ?man -f: forward ed script format
 883+                case 'f':
 884+                        if (FORMAT_MISMATCHED(D_REVERSE))
 885+                                conflicting_format();
 886+                        diff_format = D_REVERSE;
 887+                        break;
 888+                // ?man -H: speed up large files (stub)
 889+                case 'H':
 890+                        break;
 891+                // ?man -h: backward compatibility (stub)
 892+                case 'h':
 893+                        break;
 894+                // ?man -B: ignore blank lines
 895+                case 'B':
 896+                        dflags |= D_SKIPBLANKLINES;
 897+                        break;
 898+                // ?man -F:pat: show function matching pattern
 899+                case 'F':
 900+                        if (dflags & D_PROTOTYPE)
 901+                                conflicting_format();
 902+                        dflags |= D_MATCHLAST;
 903+                        most_recent_pat = estrdup(optarg);
 904+                        break;
 905+                // ?man -I:pat: ignore pattern matching lines
 906+                case 'I':
 907+                        push_ignore_pats(optarg);
 908+                        break;
 909+                // ?man -i: ignore case
 910+                case 'i':
 911+                        dflags |= D_IGNORECASE;
 912+                        break;
 913+                // ?man -L:label: custom label
 914+                case 'L':
 915+                        if (label[0] == NULL)
 916+                                label[0] = optarg;
 917+                        else if (label[1] == NULL)
 918+                                label[1] = optarg;
 919+                        else
 920+                                usage();
 921+                        break;
 922+                // ?man -l: paginate output using pr
 923+                case 'l':
 924+                        lflag = 1;
 925+                        break;
 926+                // ?man -N: treat missing files as empty
 927+                case 'N':
 928+                        Nflag = 1;
 929+                        break;
 930+                // ?man -n: rcs format
 931+                case 'n':
 932+                        if (FORMAT_MISMATCHED(D_NREVERSE))
 933+                                conflicting_format();
 934+                        diff_format = D_NREVERSE;
 935+                        break;
 936+                // ?man -p: show C prototype context
 937+                case 'p':
 938+                        if (dflags & D_MATCHLAST)
 939+                                conflicting_format();
 940+                        dflags |= D_PROTOTYPE;
 941+                        break;
 942+                // ?man -P: treat missing destination files as empty
 943+                case 'P':
 944+                        Pflag = 1;
 945+                        break;
 946+                // ?man -r: recursive directory comparison
 947+                case 'r':
 948+                        rflag = 1;
 949+                        break;
 950+                // ?man -q: brief output (differ / same only)
 951+                case 'q':
 952+                        if (FORMAT_MISMATCHED(D_BRIEF))
 953+                                conflicting_format();
 954+                        diff_format = D_BRIEF;
 955+                        break;
 956+                // ?man -S:name: starting file in directory comparison
 957+                case 'S':
 958+                        start = optarg;
 959+                        break;
 960+                // ?man -s: report identical files
 961+                case 's':
 962+                        sflag = 1;
 963+                        break;
 964+                // ?man -T: initial tab alignment
 965+                case 'T':
 966+                        Tflag = 1;
 967+                        break;
 968+                // ?man -t: expand tabs in output
 969+                case 't':
 970+                        dflags |= D_EXPANDTABS;
 971+                        break;
 972+                // ?man -U:lines: unified context format
 973+                case 'U':
 974+                // ?man -u: unified context format
 975+                case 'u':
 976+                        if (FORMAT_MISMATCHED(D_UNIFIED))
 977+                                conflicting_format();
 978+                        diff_format = D_UNIFIED;
 979+                        if (optarg != NULL) {
 980+                                l = strtol(optarg, &ep, 10);
 981+                                if (*ep != '\0' || l < 0 || l >= INT_MAX)
 982+                                        usage();
 983+                                diff_context = (int)l;
 984+                        }
 985+                        break;
 986+                // ?man -w: ignore all whitespace
 987+                case 'w':
 988+                        dflags |= D_IGNOREBLANKS;
 989+                        break;
 990+                // ?man -W:cols: column width for side-by-side
 991+                case 'W':
 992+                        width = (int)strtonum(optarg, 1, INT_MAX, &errstr);
 993+                        if (errstr) {
 994+                                weprintf("invalid width argument");
 995+                                usage();
 996+                        }
 997+                        break;
 998+                // ?man -X:file: exclude patterns file
 999+                case 'X':
1000+                        read_excludes_file(optarg);
1001+                        break;
1002+                // ?man -x:pat: exclude pattern
1003+                case 'x':
1004+                        push_excludes(optarg);
1005+                        break;
1006+                // ?man -y: side by side format
1007+                case 'y':
1008+                        if (FORMAT_MISMATCHED(D_SIDEBYSIDE))
1009+                                conflicting_format();
1010+                        diff_format = D_SIDEBYSIDE;
1011+                        break;
1012+                case OPT_CHANGED_GROUP_FORMAT:
1013+                        if (FORMAT_MISMATCHED(D_GFORMAT))
1014+                                conflicting_format();
1015+                        diff_format = D_GFORMAT;
1016+                        group_format = optarg;
1017+                        break;
1018+                case OPT_HELP:
1019+                        help = 1;
1020+                        usage();
1021+                        break;
1022+                case OPT_HORIZON_LINES:
1023+                        break;
1024+                case OPT_IGN_FN_CASE:
1025+                        ignore_file_case = 1;
1026+                        break;
1027+                case OPT_NO_IGN_FN_CASE:
1028+                        ignore_file_case = 0;
1029+                        break;
1030+                case OPT_NORMAL:
1031+                        if (FORMAT_MISMATCHED(D_NORMAL))
1032+                                conflicting_format();
1033+                        diff_format = D_NORMAL;
1034+                        break;
1035+                case OPT_TSIZE:
1036+                        tabsize = (int)strtonum(optarg, 1, INT_MAX, &errstr);
1037+                        if (errstr) {
1038+                                weprintf("invalid tabsize argument");
1039+                                usage();
1040+                        }
1041+                        break;
1042+                case OPT_STRIPCR:
1043+                        dflags |= D_STRIPCR;
1044+                        break;
1045+                case OPT_SUPPRESS_COMMON:
1046+                        suppress_common = 1;
1047+                        break;
1048+                case OPT_COLOR:
1049+                        if (optarg == NULL || strncmp(optarg, "auto", 4) == 0)
1050+                                colorflag = COLORFLAG_AUTO;
1051+                        else if (strncmp(optarg, "always", 6) == 0)
1052+                                colorflag = COLORFLAG_ALWAYS;
1053+                        else if (strncmp(optarg, "never", 5) == 0)
1054+                                colorflag = COLORFLAG_NEVER;
1055+                        else
1056+                                enprintf(2, "unsupported color option %s", optarg);
1057+                        break;
1058+                case OPT_NO_DEREFERENCE:
1059+                        noderef = 1;
1060+                        break;
1061+                case OPT_VERSION:
1062+                        printf("%s\n", diff_version);
1063+                        exit(0);
1064+                default:
1065+                        usage();
1066+                        break;
1067+                }
1068+                lastch = ch;
1069+                newarg = optind != prevoptind;
1070+                prevoptind = optind;
1071+        }
1072+        if (diff_format == D_UNSET && (dflags & D_PROTOTYPE) != 0)
1073+                diff_format = D_CONTEXT;
1074+        if (diff_format == D_UNSET)
1075+                diff_format = D_NORMAL;
1076+        argc -= optind;
1077+        argv += optind;
1078+
1079+        if (do_color()) {
1080+                char *p;
1081+                const char *env;
1082+
1083+                color = 1;
1084+                add_code = "32";
1085+                del_code = "31";
1086+                env = getenv("DIFFCOLORS");
1087+                if (env != NULL && *env != '\0' && (p = estrdup(env))) {
1088+                        add_code = p;
1089+                        strsep(&p, ":");
1090+                        if (p != NULL)
1091+                                del_code = p;
1092+                }
1093+        }
1094+
1095+        if (argc != 2)
1096+                usage();
1097+        checked_regcomp(ignore_pats, &ignore_re);
1098+        checked_regcomp(most_recent_pat, &most_recent_re);
1099+        if (strcmp(argv[0], "-") == 0) {
1100+                fstat(STDIN_FILENO, &stb1);
1101+                gotstdin = 1;
1102+        } else if (stat(argv[0], &stb1) != 0) {
1103+                if (!Nflag || errno != ENOENT)
1104+                        enprintf(2, "%s", argv[0]);
1105+                dflags |= D_EMPTY1;
1106+                memset(&stb1, 0, sizeof(struct stat));
1107+        }
1108+
1109+        if (strcmp(argv[1], "-") == 0) {
1110+                fstat(STDIN_FILENO, &stb2);
1111+                gotstdin = 1;
1112+        } else if (stat(argv[1], &stb2) != 0) {
1113+                if (!Nflag || errno != ENOENT)
1114+                        enprintf(2, "%s", argv[1]);
1115+                dflags |= D_EMPTY2;
1116+                memset(&stb2, 0, sizeof(stb2));
1117+                stb2.st_mode = stb1.st_mode;
1118+        }
1119+
1120+        if (dflags & D_EMPTY1 && dflags & D_EMPTY2){
1121+                weprintf("%s", argv[0]);
1122+                weprintf("%s", argv[1]);
1123+                exit(2);
1124+        }
1125+
1126+        if (stb1.st_mode == 0)
1127+                stb1.st_mode = stb2.st_mode;
1128+
1129+        if (gotstdin && (S_ISDIR(stb1.st_mode) || S_ISDIR(stb2.st_mode)))
1130+                enprintf(2, "cant compare - to directory");
1131+        set_argstr(oargv, argv);
1132+        if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) {
1133+                if (diff_format == D_IFDEF)
1134+                        enprintf(2, "-D option not supported with directories");
1135+                diffdir(argv[0], argv[1], dflags);
1136+        } else {
1137+                if (S_ISDIR(stb1.st_mode)) {
1138+                        argv[0] = diff_splice(argv[0], argv[1]);
1139+                        if (stat(argv[0], &stb1) == -1)
1140+                                enprintf(2, "%s", argv[0]);
1141+                }
1142+                if (S_ISDIR(stb2.st_mode)) {
1143+                        argv[1] = diff_splice(argv[1], argv[0]);
1144+                        if (stat(argv[1], &stb2) == -1)
1145+                                enprintf(2, "%s", argv[1]);
1146+                }
1147+                print_status(diffreg(argv[0], argv[1], dflags, 1), argv[0], argv[1], "");
1148+        }
1149+        if (fflush(stdout) != 0)
1150+                enprintf(2, "stdout");
1151+        exit(status);
1152 }
1153 
1154 static void
1155 checked_regcomp(char const *pattern, regex_t *comp)
1156 {
1157-	char buf[BUFSIZ];
1158-	int error;
1159-
1160-	if (pattern == NULL)
1161-		return;
1162-
1163-	error = regcomp(comp, pattern, REG_NEWLINE | REG_EXTENDED);
1164-	if (error != 0) {
1165-		regerror(error, comp, buf, sizeof(buf));
1166-		if (*pattern != '\0')
1167-			errx(2, "%s: %s", pattern, buf);
1168-		else
1169-			errx(2, "%s", buf);
1170-	}
1171+        char buf[BUFSIZ];
1172+        int error;
1173+
1174+        if (pattern == NULL)
1175+                return;
1176+
1177+        error = regcomp(comp, pattern, REG_NEWLINE | REG_EXTENDED);
1178+        if (error != 0) {
1179+                regerror(error, comp, buf, sizeof(buf));
1180+                if (*pattern != '\0')
1181+                        enprintf(2, "%s: %s", pattern, buf);
1182+                else
1183+                        enprintf(2, "%s", buf);
1184+        }
1185 }
1186 
1187 static void
1188 set_argstr(char **av, char **ave)
1189 {
1190-	size_t argsize;
1191-	char **ap;
1192-
1193-	argsize = strlen("diff") + 1;
1194-	for (ap = av + 1; ap < ave; ap++) {
1195-		if (strcmp(*ap, "--") != 0)
1196-			argsize += 1 + strlen(*ap);
1197-	}
1198-	diffargs = emalloc(argsize);
1199-	strlcpy(diffargs, "diff", argsize);
1200-	for (ap = av + 1; ap < ave; ap++) {
1201-		if (strcmp(*ap, "--") != 0) {
1202-			strlcat(diffargs, " ", argsize);
1203-			strlcat(diffargs, *ap, argsize);
1204-		}
1205-	}
1206+        size_t argsize;
1207+        char **ap;
1208+
1209+        argsize = strlen("diff") + 1;
1210+        for (ap = av + 1; ap < ave; ap++) {
1211+                if (strcmp(*ap, "--") != 0)
1212+                        argsize += 1 + strlen(*ap);
1213+        }
1214+        diffargs = emalloc(argsize);
1215+        strlcpy(diffargs, "diff", argsize);
1216+        for (ap = av + 1; ap < ave; ap++) {
1217+                if (strcmp(*ap, "--") != 0) {
1218+                        strlcat(diffargs, " ", argsize);
1219+                        strlcat(diffargs, *ap, argsize);
1220+                }
1221+        }
1222 }
1223 
1224 static void
1225 read_excludes_file(char *file)
1226 {
1227-	FILE *fp;
1228-	char *pattern = NULL;
1229-	size_t blen = 0;
1230-	ssize_t len;
1231-
1232-	if (strcmp(file, "-") == 0)
1233-		fp = stdin;
1234-	else if ((fp = fopen(file, "r")) == NULL)
1235-		err(2, "%s", file);
1236-	while ((len = getline(&pattern, &blen, fp)) >= 0) {
1237-		if ((len > 0) && (pattern[len - 1] == '\n'))
1238-			pattern[len - 1] = '\0';
1239-		push_excludes(pattern);
1240-		pattern = NULL;
1241-		blen = 0;
1242-	}
1243-	free(pattern);
1244-	if (strcmp(file, "-") != 0)
1245-		fclose(fp);
1246+        FILE *fp;
1247+        char *pattern = NULL;
1248+        size_t blen = 0;
1249+        ssize_t len;
1250+
1251+        if (strcmp(file, "-") == 0)
1252+                fp = stdin;
1253+        else if ((fp = fopen(file, "r")) == NULL)
1254+                enprintf(2, "%s", file);
1255+        while ((len = getline(&pattern, &blen, fp)) >= 0) {
1256+                if ((len > 0) && (pattern[len - 1] == '\n'))
1257+                        pattern[len - 1] = '\0';
1258+                push_excludes(pattern);
1259+                pattern = NULL;
1260+                blen = 0;
1261+        }
1262+        free(pattern);
1263+        if (strcmp(file, "-") != 0)
1264+                fclose(fp);
1265 }
1266 
1267 static void
1268 push_excludes(char *pattern)
1269 {
1270-	struct Excludes *entry;
1271+        struct Excludes *entry;
1272 
1273-	entry = emalloc(sizeof(*entry));
1274-	entry->pattern = pattern;
1275-	entry->next = excludes_list;
1276-	excludes_list = entry;
1277+        entry = emalloc(sizeof(*entry));
1278+        entry->pattern = pattern;
1279+        entry->next = excludes_list;
1280+        excludes_list = entry;
1281 }
1282 
1283 static void
1284 push_ignore_pats(char *pattern)
1285 {
1286-	size_t len;
1287-
1288-	if (ignore_pats == NULL)
1289-		ignore_pats = estrdup(pattern);
1290-	else {
1291-		len = strlen(ignore_pats) + strlen(pattern) + 2;
1292-		ignore_pats = ereallocarray(ignore_pats, 1, len);
1293-		strlcat(ignore_pats, "|", len);
1294-		strlcat(ignore_pats, pattern, len);
1295-	}
1296+        size_t len;
1297+
1298+        if (ignore_pats == NULL)
1299+                ignore_pats = estrdup(pattern);
1300+        else {
1301+                len = strlen(ignore_pats) + strlen(pattern) + 2;
1302+                ignore_pats = ereallocarray(ignore_pats, 1, len);
1303+                strlcat(ignore_pats, "|", len);
1304+                strlcat(ignore_pats, pattern, len);
1305+        }
1306 }
1307 
1308 void
1309 print_status(int val, char *path1, char *path2, const char *entry)
1310 {
1311-	if (label[0] != NULL)
1312-		path1 = label[0];
1313-	if (label[1] != NULL)
1314-		path2 = label[1];
1315-
1316-	switch (val) {
1317-	case D_BINARY:
1318-		printf("Binary files %s%s and %s%s differ\n", path1, entry, path2, entry);
1319-		break;
1320-	case D_DIFFER:
1321-		if (diff_format == D_BRIEF)
1322-			printf("Files %s%s and %s%s differ\n", path1, entry, path2, entry);
1323-		break;
1324-	case D_SAME:
1325-		if (sflag)
1326-			printf("Files %s%s and %s%s are identical\n", path1, entry, path2, entry);
1327-		break;
1328-	case D_MISMATCH1:
1329-		printf("File %s%s is directory, %s%s is file\n", path1, entry, path2, entry);
1330-		break;
1331-	case D_MISMATCH2:
1332-		printf("File %s%s is file, %s%s is directory\n", path1, entry, path2, entry);
1333-		break;
1334-	case D_SKIPPED1:
1335-		printf("File %s%s is not regular file or directory\n", path1, entry);
1336-		break;
1337-	case D_SKIPPED2:
1338-		printf("File %s%s is not regular file or directory\n", path2, entry);
1339-		break;
1340-	}
1341+        if (label[0] != NULL)
1342+                path1 = label[0];
1343+        if (label[1] != NULL)
1344+                path2 = label[1];
1345+
1346+        switch (val) {
1347+        case D_BINARY:
1348+                printf("Binary files %s%s and %s%s differ\n", path1, entry, path2, entry);
1349+                break;
1350+        case D_DIFFER:
1351+                if (diff_format == D_BRIEF)
1352+                        printf("Files %s%s and %s%s differ\n", path1, entry, path2, entry);
1353+                break;
1354+        case D_SAME:
1355+                if (sflag)
1356+                        printf("Files %s%s and %s%s are identical\n", path1, entry, path2, entry);
1357+                break;
1358+        case D_MISMATCH1:
1359+                printf("File %s%s is directory, %s%s is file\n", path1, entry, path2, entry);
1360+                break;
1361+        case D_MISMATCH2:
1362+                printf("File %s%s is file, %s%s is directory\n", path1, entry, path2, entry);
1363+                break;
1364+        case D_SKIPPED1:
1365+                printf("File %s%s is not regular file or directory\n", path1, entry);
1366+                break;
1367+        case D_SKIPPED2:
1368+                printf("File %s%s is not regular file or directory\n", path2, entry);
1369+                break;
1370+        }
1371 }
1372 
1373 static void
1374 usage(void)
1375 {
1376-	fprintf(stderr, "usage: diff [-aBbdipTtw] [-c|-e|-f|-n|-q|-u|-y] [-A algo] "
1377-	    "[-I pattern] [-F pattern] [-L label] file1 file2\n");
1378-	exit(2);
1379+        fprintf(stderr, "usage: diff [-aBbdipTtw] [-c|-e|-f|-n|-q|-u|-y] [-A algo] "
1380+            "[-I pattern] [-F pattern] [-L label] file1 file2\n");
1381+        exit(2);
1382 }
1383 
1384 static void
1385 conflicting_format(void)
1386 {
1387-	errx(2, "conflicting output format options");
1388+        enprintf(2, "conflicting output format options");
1389 }
1390 
1391 static char *
1392 diff_splice(char *dir, char *file)
1393 {
1394-	char *p, *res;
1395+        char *p, *res;
1396 
1397-	p = strrchr(file, '/');
1398-	p = p ? p + 1 : file;
1399-	xasprintf(&res, "%s/%s", dir, p);
1400-	return res;
1401+        p = strrchr(file, '/');
1402+        p = p ? p + 1 : file;
1403+        xasprintf(&res, "%s/%s", dir, p);
1404+        return res;
1405 }
1406 
1407 static void
1408 xasprintf(char **strp, const char *fmt, ...)
1409 {
1410-	va_list ap;
1411-	int r;
1412-
1413-	va_start(ap, fmt);
1414-	r = vasprintf(strp, fmt, ap);
1415-	va_end(ap);
1416-	if (r == -1)
1417-		err(2, "asprintf");
1418+        va_list ap;
1419+        int r;
1420+
1421+        va_start(ap, fmt);
1422+        r = vasprintf(strp, fmt, ap);
1423+        va_end(ap);
1424+        if (r == -1)
1425+                enprintf(2, "asprintf");
1426 }
1427 
1428 static int
1429 cup2low(int c)
1430 {
1431-	return tolower(c);
1432+        return tolower(c);
1433 }
1434 
1435 static int
1436 clow2low(int c)
1437 {
1438-	return c;
1439+        return c;
1440 }
1441 
1442 static int
1443 do_color(void)
1444 {
1445-	if (colorflag == COLORFLAG_ALWAYS)
1446-		return 1;
1447-	if (colorflag == COLORFLAG_NEVER)
1448-		return 0;
1449-	if (isatty(STDOUT_FILENO)) {
1450-		char *term = getenv("COLORTERM");
1451-		if (term && *term != '\0')
1452-			return 1;
1453-	}
1454-	return 0;
1455+        if (colorflag == COLORFLAG_ALWAYS)
1456+                return 1;
1457+        if (colorflag == COLORFLAG_NEVER)
1458+                return 0;
1459+        if (isatty(STDOUT_FILENO)) {
1460+                char *term = getenv("COLORTERM");
1461+                if (term && *term != '\0')
1462+                        return 1;
1463+        }
1464+        return 0;
1465 }
1466 
1467 void
1468 diffdir(char *p1, char *p2, int flags)
1469 {
1470-	struct dirent *dent1, **dp1, **edp1, **dirp1 = NULL;
1471-	struct dirent *dent2, **dp2, **edp2, **dirp2 = NULL;
1472-	size_t dirlen1, dirlen2;
1473-	char path1[PATH_MAX], path2[PATH_MAX];
1474-	int pos;
1475-
1476-	edp1 = edp2 = NULL;
1477-	dirlen1 = strlcpy(path1, *p1 ? p1 : ".", sizeof(path1));
1478-	if (dirlen1 >= sizeof(path1) - 1) {
1479-		errno = ENAMETOOLONG;
1480-		warn("%s", p1);
1481-		status |= 2;
1482-		return;
1483-	}
1484-	if (path1[dirlen1 - 1] != '/') {
1485-		path1[dirlen1++] = '/';
1486-		path1[dirlen1] = '\0';
1487-	}
1488-	dirlen2 = strlcpy(path2, *p2 ? p2 : ".", sizeof(path2));
1489-	if (dirlen2 >= sizeof(path2) - 1) {
1490-		errno = ENAMETOOLONG;
1491-		warn("%s", p2);
1492-		status |= 2;
1493-		return;
1494-	}
1495-	if (path2[dirlen2 - 1] != '/') {
1496-		path2[dirlen2++] = '/';
1497-		path2[dirlen2] = '\0';
1498-	}
1499-
1500-	pos = scandir(path1, &dirp1, selectfile, alphasort);
1501-	if (pos == -1) {
1502-		if (errno == ENOENT && (Nflag || Pflag))
1503-			pos = 0;
1504-		else {
1505-			warn("%s", path1);
1506-			goto closem;
1507-		}
1508-	}
1509-	dp1 = dirp1;
1510-	edp1 = dirp1 + pos;
1511-
1512-	pos = scandir(path2, &dirp2, selectfile, alphasort);
1513-	if (pos == -1) {
1514-		if (errno == ENOENT && Nflag)
1515-			pos = 0;
1516-		else {
1517-			warn("%s", path2);
1518-			goto closem;
1519-		}
1520-	}
1521-	dp2 = dirp2;
1522-	edp2 = dirp2 + pos;
1523-
1524-	if (start != NULL) {
1525-		while (dp1 != edp1 && strcmp((*dp1)->d_name, start) < 0)
1526-			dp1++;
1527-		while (dp2 != edp2 && strcmp((*dp2)->d_name, start) < 0)
1528-			dp2++;
1529-	}
1530-
1531-	while (dp1 != edp1 || dp2 != edp2) {
1532-		dent1 = dp1 != edp1 ? *dp1 : NULL;
1533-		dent2 = dp2 != edp2 ? *dp2 : NULL;
1534-
1535-		pos = dent1 == NULL ? 1 : dent2 == NULL ? -1 :
1536-		    ignore_file_case ? strcasecmp(dent1->d_name, dent2->d_name) :
1537-		    strcmp(dent1->d_name, dent2->d_name);
1538-		if (pos == 0) {
1539-			diffit(dent1, path1, dirlen1, dent2, path2, dirlen2, flags);
1540-			dp1++;
1541-			dp2++;
1542-		} else if (pos < 0) {
1543-			if (Nflag)
1544-				diffit(dent1, path1, dirlen1, dent2, path2, dirlen2, flags);
1545-			else {
1546-				print_only(path1, dirlen1, dent1->d_name);
1547-				status |= 1;
1548-			}
1549-			dp1++;
1550-		} else {
1551-			if (Nflag || Pflag)
1552-				diffit(dent2, path1, dirlen1, dent1, path2, dirlen2, flags);
1553-			else {
1554-				print_only(path2, dirlen2, dent2->d_name);
1555-				status |= 1;
1556-			}
1557-			dp2++;
1558-		}
1559-	}
1560+        struct dirent *dent1, **dp1, **edp1, **dirp1 = NULL;
1561+        struct dirent *dent2, **dp2, **edp2, **dirp2 = NULL;
1562+        size_t dirlen1, dirlen2;
1563+        char path1[PATH_MAX], path2[PATH_MAX];
1564+        int pos;
1565+
1566+        edp1 = edp2 = NULL;
1567+        dirlen1 = strlcpy(path1, *p1 ? p1 : ".", sizeof(path1));
1568+        if (dirlen1 >= sizeof(path1) - 1) {
1569+                errno = ENAMETOOLONG;
1570+                weprintf("%s", p1);
1571+                status |= 2;
1572+                return;
1573+        }
1574+        if (path1[dirlen1 - 1] != '/') {
1575+                path1[dirlen1++] = '/';
1576+                path1[dirlen1] = '\0';
1577+        }
1578+        dirlen2 = strlcpy(path2, *p2 ? p2 : ".", sizeof(path2));
1579+        if (dirlen2 >= sizeof(path2) - 1) {
1580+                errno = ENAMETOOLONG;
1581+                weprintf("%s", p2);
1582+                status |= 2;
1583+                return;
1584+        }
1585+        if (path2[dirlen2 - 1] != '/') {
1586+                path2[dirlen2++] = '/';
1587+                path2[dirlen2] = '\0';
1588+        }
1589+
1590+        pos = scandir(path1, &dirp1, selectfile, alphasort);
1591+        if (pos == -1) {
1592+                if (errno == ENOENT && (Nflag || Pflag))
1593+                        pos = 0;
1594+                else {
1595+                        weprintf("%s", path1);
1596+                        goto closem;
1597+                }
1598+        }
1599+        dp1 = dirp1;
1600+        edp1 = dirp1 + pos;
1601+
1602+        pos = scandir(path2, &dirp2, selectfile, alphasort);
1603+        if (pos == -1) {
1604+                if (errno == ENOENT && Nflag)
1605+                        pos = 0;
1606+                else {
1607+                        weprintf("%s", path2);
1608+                        goto closem;
1609+                }
1610+        }
1611+        dp2 = dirp2;
1612+        edp2 = dirp2 + pos;
1613+
1614+        if (start != NULL) {
1615+                while (dp1 != edp1 && strcmp((*dp1)->d_name, start) < 0)
1616+                        dp1++;
1617+                while (dp2 != edp2 && strcmp((*dp2)->d_name, start) < 0)
1618+                        dp2++;
1619+        }
1620+
1621+        while (dp1 != edp1 || dp2 != edp2) {
1622+                dent1 = dp1 != edp1 ? *dp1 : NULL;
1623+                dent2 = dp2 != edp2 ? *dp2 : NULL;
1624+
1625+                pos = dent1 == NULL ? 1 : dent2 == NULL ? -1 :
1626+                    ignore_file_case ? strcasecmp(dent1->d_name, dent2->d_name) :
1627+                    strcmp(dent1->d_name, dent2->d_name);
1628+                if (pos == 0) {
1629+                        diffit(dent1, path1, dirlen1, dent2, path2, dirlen2, flags);
1630+                        dp1++;
1631+                        dp2++;
1632+                } else if (pos < 0) {
1633+                        if (Nflag)
1634+                                diffit(dent1, path1, dirlen1, dent2, path2, dirlen2, flags);
1635+                        else {
1636+                                print_only(path1, dirlen1, dent1->d_name);
1637+                                status |= 1;
1638+                        }
1639+                        dp1++;
1640+                } else {
1641+                        if (Nflag || Pflag)
1642+                                diffit(dent2, path1, dirlen1, dent1, path2, dirlen2, flags);
1643+                        else {
1644+                                print_only(path2, dirlen2, dent2->d_name);
1645+                                status |= 1;
1646+                        }
1647+                        dp2++;
1648+                }
1649+        }
1650 
1651 closem:
1652-	if (dirp1 != NULL) {
1653-		for (dp1 = dirp1; dp1 < edp1; dp1++)
1654-			free(*dp1);
1655-		free(dirp1);
1656-	}
1657-	if (dirp2 != NULL) {
1658-		for (dp2 = dirp2; dp2 < edp2; dp2++)
1659-			free(*dp2);
1660-		free(dirp2);
1661-	}
1662+        if (dirp1 != NULL) {
1663+                for (dp1 = dirp1; dp1 < edp1; dp1++)
1664+                        free(*dp1);
1665+                free(dirp1);
1666+        }
1667+        if (dirp2 != NULL) {
1668+                for (dp2 = dirp2; dp2 < edp2; dp2++)
1669+                        free(*dp2);
1670+                free(dirp2);
1671+        }
1672 }
1673 
1674 static void
1675 diffit(struct dirent *dp, char *path1, size_t plen1, struct dirent *dp2,
1676     char *path2, size_t plen2, int flags)
1677 {
1678-	flags |= D_HEADER;
1679-	strlcpy(path1 + plen1, dp->d_name, PATH_MAX - plen1);
1680-
1681-	if (ignore_file_case && strcasecmp(dp->d_name, dp2->d_name) == 0)
1682-		strlcpy(path2 + plen2, dp2->d_name, PATH_MAX - plen2);
1683-	else
1684-		strlcpy(path2 + plen2, dp->d_name, PATH_MAX - plen2);
1685-
1686-	if (noderef) {
1687-		if (lstat(path1, &stb1) != 0) {
1688-			if (!(Nflag || Pflag) || errno != ENOENT) {
1689-				warn("%s", path1);
1690-				return;
1691-			}
1692-			flags |= D_EMPTY1;
1693-			memset(&stb1, 0, sizeof(stb1));
1694-		}
1695-
1696-		if (lstat(path2, &stb2) != 0) {
1697-			if (!Nflag || errno != ENOENT) {
1698-				warn("%s", path2);
1699-				return;
1700-			}
1701-			flags |= D_EMPTY2;
1702-			memset(&stb2, 0, sizeof(stb2));
1703-			stb2.st_mode = stb1.st_mode;
1704-		}
1705-		if (stb1.st_mode == 0)
1706-			stb1.st_mode = stb2.st_mode;
1707-		if (S_ISLNK(stb1.st_mode) || S_ISLNK(stb2.st_mode)) {
1708-			if (S_ISLNK(stb1.st_mode) && S_ISLNK(stb2.st_mode)) {
1709-				char buf1[PATH_MAX];
1710-				char buf2[PATH_MAX];
1711-				ssize_t len1;
1712-				ssize_t len2;
1713-
1714-				len1 = readlink(path1, buf1, sizeof(buf1));
1715-				len2 = readlink(path2, buf2, sizeof(buf2));
1716-				if (len1 < 0 || len2 < 0) {
1717-					perror("reading links");
1718-					return;
1719-				}
1720-				buf1[len1] = '\0';
1721-				buf2[len2] = '\0';
1722-				if (len1 != len2 || strncmp(buf1, buf2, len1) != 0) {
1723-					printf("Symbolic links %s and %s differ\n", path1, path2);
1724-					status |= 1;
1725-				}
1726-				return;
1727-			}
1728-			printf("File %s is a %s while file %s is a %s\n",
1729-			    path1, S_ISLNK(stb1.st_mode) ? "symbolic link" :
1730-				S_ISDIR(stb1.st_mode) ? "directory" : "file",
1731-			    path2, S_ISLNK(stb2.st_mode) ? "symbolic link" :
1732-				S_ISDIR(stb2.st_mode) ? "directory" : "file");
1733-			status |= 1;
1734-			return;
1735-		}
1736-	} else {
1737-		if (stat(path1, &stb1) != 0) {
1738-			if (!(Nflag || Pflag) || errno != ENOENT) {
1739-				warn("%s", path1);
1740-				return;
1741-			}
1742-			flags |= D_EMPTY1;
1743-			memset(&stb1, 0, sizeof(stb1));
1744-		}
1745-
1746-		if (stat(path2, &stb2) != 0) {
1747-			if (!Nflag || errno != ENOENT) {
1748-				warn("%s", path2);
1749-				return;
1750-			}
1751-			flags |= D_EMPTY2;
1752-			memset(&stb2, 0, sizeof(stb2));
1753-			stb2.st_mode = stb1.st_mode;
1754-		}
1755-		if (stb1.st_mode == 0)
1756-			stb1.st_mode = stb2.st_mode;
1757-	}
1758-	if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) {
1759-		if (rflag)
1760-			diffdir(path1, path2, flags);
1761-		else
1762-			printf("Common subdirectories: %s and %s\n", path1, path2);
1763-		return;
1764-	}
1765-	if (!S_ISREG(stb1.st_mode) && !S_ISDIR(stb1.st_mode))
1766-		dp->d_status = D_SKIPPED1;
1767-	else if (!S_ISREG(stb2.st_mode) && !S_ISDIR(stb2.st_mode))
1768-		dp->d_status = D_SKIPPED2;
1769-	else
1770-		dp->d_status = diffreg(path1, path2, flags, 0);
1771-	print_status(dp->d_status, path1, path2, "");
1772+        flags |= D_HEADER;
1773+        strlcpy(path1 + plen1, dp->d_name, PATH_MAX - plen1);
1774+
1775+        if (ignore_file_case && strcasecmp(dp->d_name, dp2->d_name) == 0)
1776+                strlcpy(path2 + plen2, dp2->d_name, PATH_MAX - plen2);
1777+        else
1778+                strlcpy(path2 + plen2, dp->d_name, PATH_MAX - plen2);
1779+
1780+        if (noderef) {
1781+                if (lstat(path1, &stb1) != 0) {
1782+                        if (!(Nflag || Pflag) || errno != ENOENT) {
1783+                                weprintf("%s", path1);
1784+                                return;
1785+                        }
1786+                        flags |= D_EMPTY1;
1787+                        memset(&stb1, 0, sizeof(stb1));
1788+                }
1789+
1790+                if (lstat(path2, &stb2) != 0) {
1791+                        if (!Nflag || errno != ENOENT) {
1792+                                weprintf("%s", path2);
1793+                                return;
1794+                        }
1795+                        flags |= D_EMPTY2;
1796+                        memset(&stb2, 0, sizeof(stb2));
1797+                        stb2.st_mode = stb1.st_mode;
1798+                }
1799+                if (stb1.st_mode == 0)
1800+                        stb1.st_mode = stb2.st_mode;
1801+                if (S_ISLNK(stb1.st_mode) || S_ISLNK(stb2.st_mode)) {
1802+                        if (S_ISLNK(stb1.st_mode) && S_ISLNK(stb2.st_mode)) {
1803+                                char buf1[PATH_MAX];
1804+                                char buf2[PATH_MAX];
1805+                                ssize_t len1;
1806+                                ssize_t len2;
1807+
1808+                                len1 = readlink(path1, buf1, sizeof(buf1));
1809+                                len2 = readlink(path2, buf2, sizeof(buf2));
1810+                                if (len1 < 0 || len2 < 0) {
1811+                                        perror("reading links");
1812+                                        return;
1813+                                }
1814+                                buf1[len1] = '\0';
1815+                                buf2[len2] = '\0';
1816+                                if (len1 != len2 || strncmp(buf1, buf2, len1) != 0) {
1817+                                        printf("Symbolic links %s and %s differ\n", path1, path2);
1818+                                        status |= 1;
1819+                                }
1820+                                return;
1821+                        }
1822+                        printf("File %s is a %s while file %s is a %s\n",
1823+                            path1, S_ISLNK(stb1.st_mode) ? "symbolic link" :
1824+                                S_ISDIR(stb1.st_mode) ? "directory" : "file",
1825+                            path2, S_ISLNK(stb2.st_mode) ? "symbolic link" :
1826+                                S_ISDIR(stb2.st_mode) ? "directory" : "file");
1827+                        status |= 1;
1828+                        return;
1829+                }
1830+        } else {
1831+                if (stat(path1, &stb1) != 0) {
1832+                        if (!(Nflag || Pflag) || errno != ENOENT) {
1833+                                weprintf("%s", path1);
1834+                                return;
1835+                        }
1836+                        flags |= D_EMPTY1;
1837+                        memset(&stb1, 0, sizeof(stb1));
1838+                }
1839+
1840+                if (stat(path2, &stb2) != 0) {
1841+                        if (!Nflag || errno != ENOENT) {
1842+                                weprintf("%s", path2);
1843+                                return;
1844+                        }
1845+                        flags |= D_EMPTY2;
1846+                        memset(&stb2, 0, sizeof(stb2));
1847+                        stb2.st_mode = stb1.st_mode;
1848+                }
1849+                if (stb1.st_mode == 0)
1850+                        stb1.st_mode = stb2.st_mode;
1851+        }
1852+        if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) {
1853+                if (rflag)
1854+                        diffdir(path1, path2, flags);
1855+                else
1856+                        printf("Common subdirectories: %s and %s\n", path1, path2);
1857+                return;
1858+        }
1859+        if (!S_ISREG(stb1.st_mode) && !S_ISDIR(stb1.st_mode))
1860+                dp->d_status = D_SKIPPED1;
1861+        else if (!S_ISREG(stb2.st_mode) && !S_ISDIR(stb2.st_mode))
1862+                dp->d_status = D_SKIPPED2;
1863+        else
1864+                dp->d_status = diffreg(path1, path2, flags, 0);
1865+        print_status(dp->d_status, path1, path2, "");
1866 }
1867 
1868 static int
1869 selectfile(const struct dirent *dp)
1870 {
1871-	struct Excludes *excl;
1872+        struct Excludes *excl;
1873 
1874-	if (dp->d_fileno == 0)
1875-		return 0;
1876+        if (dp->d_fileno == 0)
1877+                return 0;
1878 
1879-	if (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' ||
1880-	    (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
1881-		return 0;
1882+        if (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' ||
1883+            (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
1884+                return 0;
1885 
1886-	for (excl = excludes_list; excl != NULL; excl = excl->next)
1887-		if (fnmatch(excl->pattern, dp->d_name, FNM_PATHNAME) == 0)
1888-			return 0;
1889+        for (excl = excludes_list; excl != NULL; excl = excl->next)
1890+                if (fnmatch(excl->pattern, dp->d_name, FNM_PATHNAME) == 0)
1891+                        return 0;
1892 
1893-	return 1;
1894+        return 1;
1895 }
1896 
1897 void
1898 print_only(const char *path, size_t dirlen, const char *entry)
1899 {
1900-	if (dirlen > 1)
1901-		dirlen--;
1902-	printf("Only in %.*s: %s\n", (int)dirlen, path, entry);
1903+        if (dirlen > 1)
1904+                dirlen--;
1905+        printf("Only in %.*s: %s\n", (int)dirlen, path, entry);
1906 }
1907 
1908 int
1909 diffreg(char *file1, char *file2, int flags, int capsicum)
1910 {
1911-	FILE *f1, *f2;
1912-	int i, rval;
1913-	struct Pr *pr = NULL;
1914-
1915-	f1 = f2 = NULL;
1916-	rval = D_SAME;
1917-	anychange = 0;
1918-	lastline = 0;
1919-	lastmatchline = 0;
1920-
1921-	if (diff_format == D_SIDEBYSIDE) {
1922-		if (flags & D_EXPANDTABS) {
1923-			if (width > 3)
1924-				hw = (width - 3) / 2;
1925-			else
1926-				hw = 0;
1927-		} else if (width <= 3 || width <= tabsize) {
1928-			hw = 0;
1929-		} else {
1930-			hw = (width - 3) / 2;
1931-			while (hw > 0 && roundup(hw + 3, tabsize) + hw > width)
1932-				hw--;
1933-			if (width - (roundup(hw + 3, tabsize) + hw) < tabsize)
1934-				width = roundup(hw + 3, tabsize) + hw;
1935-		}
1936-		lpad = (width - hw * 2 - 1) / 2;
1937-		rpad = (width - hw * 2 - 1) - lpad;
1938-	}
1939-
1940-	if (flags & D_IGNORECASE)
1941-		chrtran = cup2low;
1942-	else
1943-		chrtran = clow2low;
1944-	if (S_ISDIR(stb1.st_mode) != S_ISDIR(stb2.st_mode))
1945-		return S_ISDIR(stb1.st_mode) ? D_MISMATCH1 : D_MISMATCH2;
1946-	if (strcmp(file1, "-") == 0 && strcmp(file2, "-") == 0)
1947-		goto closem;
1948-
1949-	if (flags & D_EMPTY1)
1950-		f1 = fopen(_PATH_DEVNULL, "r");
1951-	else {
1952-		if (!S_ISREG(stb1.st_mode)) {
1953-			if ((f1 = opentemp(file1)) == NULL || fstat(fileno(f1), &stb1) == -1) {
1954-				warn("%s", file1);
1955-				rval = D_ERROR;
1956-				status |= 2;
1957-				goto closem;
1958-			}
1959-		} else if (strcmp(file1, "-") == 0)
1960-			f1 = stdin;
1961-		else
1962-			f1 = fopen(file1, "r");
1963-	}
1964-	if (f1 == NULL) {
1965-		warn("%s", file1);
1966-		rval = D_ERROR;
1967-		status |= 2;
1968-		goto closem;
1969-	}
1970-
1971-	if (flags & D_EMPTY2)
1972-		f2 = fopen(_PATH_DEVNULL, "r");
1973-	else {
1974-		if (!S_ISREG(stb2.st_mode)) {
1975-			if ((f2 = opentemp(file2)) == NULL || fstat(fileno(f2), &stb2) == -1) {
1976-				warn("%s", file2);
1977-				rval = D_ERROR;
1978-				status |= 2;
1979-				goto closem;
1980-			}
1981-		} else if (strcmp(file2, "-") == 0)
1982-			f2 = stdin;
1983-		else
1984-			f2 = fopen(file2, "r");
1985-	}
1986-	if (f2 == NULL) {
1987-		warn("%s", file2);
1988-		rval = D_ERROR;
1989-		status |= 2;
1990-		goto closem;
1991-	}
1992-
1993-	if (lflag)
1994-		pr = start_pr(file1, file2);
1995-
1996-	(void)capsicum;
1997-
1998-	switch (files_differ(f1, f2, flags)) {
1999-	case 0:
2000-		goto closem;
2001-	case 1:
2002-		break;
2003-	default:
2004-		rval = D_ERROR;
2005-		status |= 2;
2006-		goto closem;
2007-	}
2008-
2009-	if (diff_format == D_BRIEF && ignore_pats == NULL &&
2010-	    (flags & (D_FOLDBLANKS|D_IGNOREBLANKS|D_IGNORECASE|D_SKIPBLANKLINES|D_STRIPCR)) == 0)
2011-	{
2012-		rval = D_DIFFER;
2013-		status |= 1;
2014-		goto closem;
2015-	}
2016-	if ((flags & D_FORCEASCII) != 0) {
2017-		prepare(0, f1, stb1.st_size, flags);
2018-		prepare(1, f2, stb2.st_size, flags);
2019-	} else if (!asciifile(f1) || !asciifile(f2) ||
2020-		   !prepare(0, f1, stb1.st_size, flags) ||
2021-		   !prepare(1, f2, stb2.st_size, flags)) {
2022-		rval = D_BINARY;
2023-		status |= 1;
2024-		goto closem;
2025-	}
2026-	if (len[0] > INT_MAX - 2)
2027-		errno = EFBIG, err(1, "%s", file1);
2028-	if (len[1] > INT_MAX - 2)
2029-		errno = EFBIG, err(1, "%s", file2);
2030-
2031-	prune();
2032-	sort(sfile[0], slen[0]);
2033-	sort(sfile[1], slen[1]);
2034-
2035-	member = (int *)file[1];
2036-	equiv(sfile[0], slen[0], sfile[1], slen[1], member);
2037-	member = ereallocarray(member, slen[1] + 2, sizeof(*member));
2038-
2039-	class = (int *)file[0];
2040-	unsort(sfile[0], slen[0], class);
2041-	class = ereallocarray(class, slen[0] + 2, sizeof(*class));
2042-
2043-	klist = ecalloc(slen[0] + 2, sizeof(*klist));
2044-	clen = 0;
2045-	clistlen = 100;
2046-	clist = ecalloc(clistlen, sizeof(*clist));
2047-	i = stone(class, slen[0], member, klist, flags);
2048-	free(member);
2049-	free(class);
2050-
2051-	J = ereallocarray(J, len[0] + 2, sizeof(*J));
2052-	unravel(klist[i]);
2053-	free(clist);
2054-	free(klist);
2055-
2056-	ixold = ereallocarray(ixold, len[0] + 2, sizeof(*ixold));
2057-	ixnew = ereallocarray(ixnew, len[1] + 2, sizeof(*ixnew));
2058-	check(f1, f2, flags);
2059-	output(file1, f1, file2, f2, flags);
2060+        FILE *f1, *f2;
2061+        int i, rval;
2062+        struct Pr *pr = NULL;
2063+
2064+        f1 = f2 = NULL;
2065+        rval = D_SAME;
2066+        anychange = 0;
2067+        lastline = 0;
2068+        lastmatchline = 0;
2069+
2070+        if (diff_format == D_SIDEBYSIDE) {
2071+                if (flags & D_EXPANDTABS) {
2072+                        if (width > 3)
2073+                                hw = (width - 3) / 2;
2074+                        else
2075+                                hw = 0;
2076+                } else if (width <= 3 || width <= tabsize) {
2077+                        hw = 0;
2078+                } else {
2079+                        hw = (width - 3) / 2;
2080+                        while (hw > 0 && roundup(hw + 3, tabsize) + hw > width)
2081+                                hw--;
2082+                        if (width - (roundup(hw + 3, tabsize) + hw) < tabsize)
2083+                                width = roundup(hw + 3, tabsize) + hw;
2084+                }
2085+                lpad = (width - hw * 2 - 1) / 2;
2086+                rpad = (width - hw * 2 - 1) - lpad;
2087+        }
2088+
2089+        if (flags & D_IGNORECASE)
2090+                chrtran = cup2low;
2091+        else
2092+                chrtran = clow2low;
2093+        if (S_ISDIR(stb1.st_mode) != S_ISDIR(stb2.st_mode))
2094+                return S_ISDIR(stb1.st_mode) ? D_MISMATCH1 : D_MISMATCH2;
2095+        if (strcmp(file1, "-") == 0 && strcmp(file2, "-") == 0)
2096+                goto closem;
2097+
2098+        if (flags & D_EMPTY1)
2099+                f1 = fopen(ARUU_PATH_DEVNULL, "r");
2100+        else {
2101+                if (!S_ISREG(stb1.st_mode)) {
2102+                        if ((f1 = opentemp(file1)) == NULL || fstat(fileno(f1), &stb1) == -1) {
2103+                                weprintf("%s", file1);
2104+                                rval = D_ERROR;
2105+                                status |= 2;
2106+                                goto closem;
2107+                        }
2108+                } else if (strcmp(file1, "-") == 0)
2109+                        f1 = stdin;
2110+                else
2111+                        f1 = fopen(file1, "r");
2112+        }
2113+        if (f1 == NULL) {
2114+                weprintf("%s", file1);
2115+                rval = D_ERROR;
2116+                status |= 2;
2117+                goto closem;
2118+        }
2119+
2120+        if (flags & D_EMPTY2)
2121+                f2 = fopen(ARUU_PATH_DEVNULL, "r");
2122+        else {
2123+                if (!S_ISREG(stb2.st_mode)) {
2124+                        if ((f2 = opentemp(file2)) == NULL || fstat(fileno(f2), &stb2) == -1) {
2125+                                weprintf("%s", file2);
2126+                                rval = D_ERROR;
2127+                                status |= 2;
2128+                                goto closem;
2129+                        }
2130+                } else if (strcmp(file2, "-") == 0)
2131+                        f2 = stdin;
2132+                else
2133+                        f2 = fopen(file2, "r");
2134+        }
2135+        if (f2 == NULL) {
2136+                weprintf("%s", file2);
2137+                rval = D_ERROR;
2138+                status |= 2;
2139+                goto closem;
2140+        }
2141+
2142+        if (lflag)
2143+                pr = start_pr(file1, file2);
2144+
2145+        (void)capsicum;
2146+
2147+        switch (files_differ(f1, f2, flags)) {
2148+        case 0:
2149+                goto closem;
2150+        case 1:
2151+                break;
2152+        default:
2153+                rval = D_ERROR;
2154+                status |= 2;
2155+                goto closem;
2156+        }
2157+
2158+        if (diff_format == D_BRIEF && ignore_pats == NULL &&
2159+            (flags & (D_FOLDBLANKS|D_IGNOREBLANKS|D_IGNORECASE|D_SKIPBLANKLINES|D_STRIPCR)) == 0)
2160+        {
2161+                rval = D_DIFFER;
2162+                status |= 1;
2163+                goto closem;
2164+        }
2165+        if ((flags & D_FORCEASCII) != 0) {
2166+                prepare(0, f1, stb1.st_size, flags);
2167+                prepare(1, f2, stb2.st_size, flags);
2168+        } else if (!asciifile(f1) || !asciifile(f2) ||
2169+                   !prepare(0, f1, stb1.st_size, flags) ||
2170+                   !prepare(1, f2, stb2.st_size, flags)) {
2171+                rval = D_BINARY;
2172+                status |= 1;
2173+                goto closem;
2174+        }
2175+        if (len[0] > INT_MAX - 2)
2176+                errno = EFBIG, enprintf(1, "%s", file1);
2177+        if (len[1] > INT_MAX - 2)
2178+                errno = EFBIG, enprintf(1, "%s", file2);
2179+
2180+        prune();
2181+        sort(sfile[0], slen[0]);
2182+        sort(sfile[1], slen[1]);
2183+
2184+        member = (int *)file[1];
2185+        equiv(sfile[0], slen[0], sfile[1], slen[1], member);
2186+        member = ereallocarray(member, slen[1] + 2, sizeof(*member));
2187+
2188+        class = (int *)file[0];
2189+        unsort(sfile[0], slen[0], class);
2190+        class = ereallocarray(class, slen[0] + 2, sizeof(*class));
2191+
2192+        klist = ecalloc(slen[0] + 2, sizeof(*klist));
2193+        clen = 0;
2194+        clistlen = 100;
2195+        clist = ecalloc(clistlen, sizeof(*clist));
2196+        i = stone(class, slen[0], member, klist, flags);
2197+        free(member);
2198+        free(class);
2199+
2200+        J = ereallocarray(J, len[0] + 2, sizeof(*J));
2201+        unravel(klist[i]);
2202+        free(clist);
2203+        free(klist);
2204+
2205+        ixold = ereallocarray(ixold, len[0] + 2, sizeof(*ixold));
2206+        ixnew = ereallocarray(ixnew, len[1] + 2, sizeof(*ixnew));
2207+        check(f1, f2, flags);
2208+        output(file1, f1, file2, f2, flags);
2209 
2210 closem:
2211-	if (pr != NULL)
2212-		stop_pr(pr);
2213-	if (anychange) {
2214-		status |= 1;
2215-		if (rval == D_SAME)
2216-			rval = D_DIFFER;
2217-	}
2218-	if (f1 != NULL && f1 != stdin)
2219-		fclose(f1);
2220-	if (f2 != NULL && f2 != stdin)
2221-		fclose(f2);
2222-
2223-	return rval;
2224+        if (pr != NULL)
2225+                stop_pr(pr);
2226+        if (anychange) {
2227+                status |= 1;
2228+                if (rval == D_SAME)
2229+                        rval = D_DIFFER;
2230+        }
2231+        if (f1 != NULL && f1 != stdin)
2232+                fclose(f1);
2233+        if (f2 != NULL && f2 != stdin)
2234+                fclose(f2);
2235+
2236+        return rval;
2237 }
2238 
2239 static int
2240 files_differ(FILE *f1, FILE *f2, int flags)
2241 {
2242-	char buf1[BUFSIZ], buf2[BUFSIZ];
2243-	size_t i, j;
2244-
2245-	if ((flags & (D_EMPTY1|D_EMPTY2)) || stb1.st_size != stb2.st_size ||
2246-	    (stb1.st_mode & S_IFMT) != (stb2.st_mode & S_IFMT))
2247-		return 1;
2248-
2249-	if (stb1.st_dev == stb2.st_dev && stb1.st_ino == stb2.st_ino)
2250-		return 0;
2251-
2252-	for (;;) {
2253-		i = fread(buf1, 1, sizeof(buf1), f1);
2254-		j = fread(buf2, 1, sizeof(buf2), f2);
2255-		if ((!i && ferror(f1)) || (!j && ferror(f2)))
2256-			return -1;
2257-		if (i != j)
2258-			return 1;
2259-		if (i == 0)
2260-			return 0;
2261-		if (memcmp(buf1, buf2, i) != 0)
2262-			return 1;
2263-	}
2264+        char buf1[BUFSIZ], buf2[BUFSIZ];
2265+        size_t i, j;
2266+
2267+        if ((flags & (D_EMPTY1|D_EMPTY2)) || stb1.st_size != stb2.st_size ||
2268+            (stb1.st_mode & S_IFMT) != (stb2.st_mode & S_IFMT))
2269+                return 1;
2270+
2271+        if (stb1.st_dev == stb2.st_dev && stb1.st_ino == stb2.st_ino)
2272+                return 0;
2273+
2274+        for (;;) {
2275+                i = fread(buf1, 1, sizeof(buf1), f1);
2276+                j = fread(buf2, 1, sizeof(buf2), f2);
2277+                if ((!i && ferror(f1)) || (!j && ferror(f2)))
2278+                        return -1;
2279+                if (i != j)
2280+                        return 1;
2281+                if (i == 0)
2282+                        return 0;
2283+                if (memcmp(buf1, buf2, i) != 0)
2284+                        return 1;
2285+        }
2286 }
2287 
2288 static FILE *
2289 opentemp(const char *f)
2290 {
2291-	char buf[BUFSIZ], tempfile[PATH_MAX];
2292-	ssize_t nread;
2293-	int ifd, ofd;
2294-
2295-	if (strcmp(f, "-") == 0)
2296-		ifd = STDIN_FILENO;
2297-	else if ((ifd = open(f, O_RDONLY, 0644)) == -1)
2298-		return NULL;
2299-
2300-	strlcpy(tempfile, _PATH_TMP "/diff.XXXXXXXX", sizeof(tempfile));
2301-	if ((ofd = mkstemp(tempfile)) == -1) {
2302-		close(ifd);
2303-		return NULL;
2304-	}
2305-	unlink(tempfile);
2306-	while ((nread = read(ifd, buf, BUFSIZ)) > 0) {
2307-		if (write(ofd, buf, nread) != nread) {
2308-			close(ifd);
2309-			close(ofd);
2310-			return NULL;
2311-		}
2312-	}
2313-	close(ifd);
2314-	lseek(ofd, (off_t)0, SEEK_SET);
2315-	return fdopen(ofd, "r");
2316+        char buf[BUFSIZ], tempfile[PATH_MAX];
2317+        ssize_t nread;
2318+        int ifd, ofd;
2319+
2320+        if (strcmp(f, "-") == 0)
2321+                ifd = STDIN_FILENO;
2322+        else if ((ifd = open(f, O_RDONLY, 0644)) == -1)
2323+                return NULL;
2324+
2325+        strlcpy(tempfile, ARUU_PATH_TMP "/diff.XXXXXXXX", sizeof(tempfile));
2326+        if ((ofd = mkstemp(tempfile)) == -1) {
2327+                close(ifd);
2328+                return NULL;
2329+        }
2330+        unlink(tempfile);
2331+        while ((nread = read(ifd, buf, BUFSIZ)) > 0) {
2332+                if (write(ofd, buf, nread) != nread) {
2333+                        close(ifd);
2334+                        close(ofd);
2335+                        return NULL;
2336+                }
2337+        }
2338+        close(ifd);
2339+        lseek(ofd, (off_t)0, SEEK_SET);
2340+        return fdopen(ofd, "r");
2341 }
2342 
2343 static int
2344 prepare(int i, FILE *fd, size_t filesize, int flags)
2345 {
2346-	struct Line *p;
2347-	unsigned h;
2348-	size_t sz, j = 0;
2349-	enum Readhash r;
2350-
2351-	rewind(fd);
2352-	sz = filesize / 25;
2353-	if (sz < 100)
2354-		sz = 100;
2355-
2356-	p = ecalloc(sz + 3, sizeof(*p));
2357-	while ((r = readhash(fd, flags, &h)) != RH_EOF) {
2358-		if (r == RH_BINARY)
2359-			return 0;
2360-		if (j == SIZE_MAX)
2361-			break;
2362-		if (j == sz) {
2363-			sz = sz * 3 / 2;
2364-			p = ereallocarray(p, sz + 3, sizeof(*p));
2365-		}
2366-		p[++j].value = h;
2367-	}
2368-	len[i] = j;
2369-	file[i] = p;
2370-	return 1;
2371+        struct Line *p;
2372+        unsigned h;
2373+        size_t sz, j = 0;
2374+        enum Readhash r;
2375+
2376+        rewind(fd);
2377+        sz = filesize / 25;
2378+        if (sz < 100)
2379+                sz = 100;
2380+
2381+        p = ecalloc(sz + 3, sizeof(*p));
2382+        while ((r = readhash(fd, flags, &h)) != RH_EOF) {
2383+                if (r == RH_BINARY)
2384+                        return 0;
2385+                if (j == SIZE_MAX)
2386+                        break;
2387+                if (j == sz) {
2388+                        sz = sz * 3 / 2;
2389+                        p = ereallocarray(p, sz + 3, sizeof(*p));
2390+                }
2391+                p[++j].value = h;
2392+        }
2393+        len[i] = j;
2394+        file[i] = p;
2395+        return 1;
2396 }
2397 
2398 static void
2399 prune(void)
2400 {
2401-	size_t i, j;
2402-
2403-	for (pref = 0; pref < len[0] && pref < len[1] &&
2404-	    file[0][pref + 1].value == file[1][pref + 1].value;
2405-	    pref++)
2406-		;
2407-	for (suff = 0; suff < len[0] - pref && suff < len[1] - pref &&
2408-	    file[0][len[0] - suff].value == file[1][len[1] - suff].value;
2409-	    suff++)
2410-		;
2411-	for (j = 0; j < 2; j++) {
2412-		sfile[j] = file[j] + pref;
2413-		slen[j] = len[j] - pref - suff;
2414-		for (i = 0; i <= slen[j]; i++)
2415-			sfile[j][i].serial = i;
2416-	}
2417+        size_t i, j;
2418+
2419+        for (pref = 0; pref < len[0] && pref < len[1] &&
2420+            file[0][pref + 1].value == file[1][pref + 1].value;
2421+            pref++)
2422+                ;
2423+        for (suff = 0; suff < len[0] - pref && suff < len[1] - pref &&
2424+            file[0][len[0] - suff].value == file[1][len[1] - suff].value;
2425+            suff++)
2426+                ;
2427+        for (j = 0; j < 2; j++) {
2428+                sfile[j] = file[j] + pref;
2429+                slen[j] = len[j] - pref - suff;
2430+                for (i = 0; i <= slen[j]; i++)
2431+                        sfile[j][i].serial = i;
2432+        }
2433 }
2434 
2435 static void
2436 equiv(struct Line *a, int n, struct Line *b, int m, int *c)
2437 {
2438-	int i, j;
2439-
2440-	i = j = 1;
2441-	while (i <= n && j <= m) {
2442-		if (a[i].value < b[j].value)
2443-			a[i++].value = 0;
2444-		else if (a[i].value == b[j].value)
2445-			a[i++].value = j;
2446-		else
2447-			j++;
2448-	}
2449-	while (i <= n)
2450-		a[i++].value = 0;
2451-	b[m + 1].value = 0;
2452-	j = 0;
2453-	while (++j <= m) {
2454-		c[j] = -b[j].serial;
2455-		while (b[j + 1].value == b[j].value) {
2456-			j++;
2457-			c[j] = b[j].serial;
2458-		}
2459-	}
2460-	c[j] = -1;
2461+        int i, j;
2462+
2463+        i = j = 1;
2464+        while (i <= n && j <= m) {
2465+                if (a[i].value < b[j].value)
2466+                        a[i++].value = 0;
2467+                else if (a[i].value == b[j].value)
2468+                        a[i++].value = j;
2469+                else
2470+                        j++;
2471+        }
2472+        while (i <= n)
2473+                a[i++].value = 0;
2474+        b[m + 1].value = 0;
2475+        j = 0;
2476+        while (++j <= m) {
2477+                c[j] = -b[j].serial;
2478+                while (b[j + 1].value == b[j].value) {
2479+                        j++;
2480+                        c[j] = b[j].serial;
2481+                }
2482+        }
2483+        c[j] = -1;
2484 }
2485 
2486 static int
2487 stone(int *a, int n, int *b, int *c, int flags)
2488 {
2489-	int i, k, y, j, l;
2490-	int oldc, tc, oldl, sq;
2491-	unsigned numtries, bound;
2492-
2493-	if (flags & D_MINIMAL)
2494-		bound = UINT_MAX;
2495-	else {
2496-		sq = sqrt(n);
2497-		bound = MAX(256, sq);
2498-	}
2499-
2500-	k = 0;
2501-	c[0] = newcand(0, 0, 0);
2502-	for (i = 1; i <= n; i++) {
2503-		j = a[i];
2504-		if (j == 0)
2505-			continue;
2506-		y = -b[j];
2507-		oldl = 0;
2508-		oldc = c[0];
2509-		numtries = 0;
2510-		do {
2511-			if (y <= clist[oldc].y)
2512-				continue;
2513-			l = search(c, k, y);
2514-			if (l != oldl + 1)
2515-				oldc = c[l - 1];
2516-			if (l <= k) {
2517-				if (clist[c[l]].y <= y)
2518-					continue;
2519-				tc = c[l];
2520-				c[l] = newcand(i, y, oldc);
2521-				oldc = tc;
2522-				oldl = l;
2523-				numtries++;
2524-			} else {
2525-				c[l] = newcand(i, y, oldc);
2526-				k++;
2527-				break;
2528-			}
2529-		} while ((y = b[++j]) > 0 && numtries < bound);
2530-	}
2531-	return k;
2532+        int i, k, y, j, l;
2533+        int oldc, tc, oldl, sq;
2534+        unsigned numtries, bound;
2535+
2536+        if (flags & D_MINIMAL)
2537+                bound = UINT_MAX;
2538+        else {
2539+                sq = sqrt(n);
2540+                bound = MAX(256, sq);
2541+        }
2542+
2543+        k = 0;
2544+        c[0] = newcand(0, 0, 0);
2545+        for (i = 1; i <= n; i++) {
2546+                j = a[i];
2547+                if (j == 0)
2548+                        continue;
2549+                y = -b[j];
2550+                oldl = 0;
2551+                oldc = c[0];
2552+                numtries = 0;
2553+                do {
2554+                        if (y <= clist[oldc].y)
2555+                                continue;
2556+                        l = search(c, k, y);
2557+                        if (l != oldl + 1)
2558+                                oldc = c[l - 1];
2559+                        if (l <= k) {
2560+                                if (clist[c[l]].y <= y)
2561+                                        continue;
2562+                                tc = c[l];
2563+                                c[l] = newcand(i, y, oldc);
2564+                                oldc = tc;
2565+                                oldl = l;
2566+                                numtries++;
2567+                        } else {
2568+                                c[l] = newcand(i, y, oldc);
2569+                                k++;
2570+                                break;
2571+                        }
2572+                } while ((y = b[++j]) > 0 && numtries < bound);
2573+        }
2574+        return k;
2575 }
2576 
2577 static int
2578 newcand(int x, int y, int pred)
2579 {
2580-	struct Cand *q;
2581-
2582-	if (clen == clistlen) {
2583-		clistlen = clistlen * 11 / 10;
2584-		clist = ereallocarray(clist, clistlen, sizeof(*clist));
2585-	}
2586-	q = clist + clen;
2587-	q->x = x;
2588-	q->y = y;
2589-	q->pred = pred;
2590-	return clen++;
2591+        struct Cand *q;
2592+
2593+        if (clen == clistlen) {
2594+                clistlen = clistlen * 11 / 10;
2595+                clist = ereallocarray(clist, clistlen, sizeof(*clist));
2596+        }
2597+        q = clist + clen;
2598+        q->x = x;
2599+        q->y = y;
2600+        q->pred = pred;
2601+        return clen++;
2602 }
2603 
2604 static int
2605 search(int *c, int k, int y)
2606 {
2607-	int i, j, l, t;
2608-
2609-	if (clist[c[k]].y < y)
2610-		return k + 1;
2611-	i = 0;
2612-	j = k + 1;
2613-	for (;;) {
2614-		l = (i + j) / 2;
2615-		if (l <= i)
2616-			break;
2617-		t = clist[c[l]].y;
2618-		if (t > y)
2619-			j = l;
2620-		else if (t < y)
2621-			i = l;
2622-		else
2623-			return l;
2624-	}
2625-	return l + 1;
2626+        int i, j, l, t;
2627+
2628+        if (clist[c[k]].y < y)
2629+                return k + 1;
2630+        i = 0;
2631+        j = k + 1;
2632+        for (;;) {
2633+                l = (i + j) / 2;
2634+                if (l <= i)
2635+                        break;
2636+                t = clist[c[l]].y;
2637+                if (t > y)
2638+                        j = l;
2639+                else if (t < y)
2640+                        i = l;
2641+                else
2642+                        return l;
2643+        }
2644+        return l + 1;
2645 }
2646 
2647 static void
2648 unravel(int p)
2649 {
2650-	struct Cand *q;
2651-	size_t i;
2652-
2653-	for (i = 0; i <= len[0]; i++)
2654-		J[i] = i <= pref ? i :
2655-		    i > len[0] - suff ? i + len[1] - len[0] : 0;
2656-	for (q = clist + p; q->y != 0; q = clist + q->pred)
2657-		J[q->x + pref] = q->y + pref;
2658+        struct Cand *q;
2659+        size_t i;
2660+
2661+        for (i = 0; i <= len[0]; i++)
2662+                J[i] = i <= pref ? i :
2663+                    i > len[0] - suff ? i + len[1] - len[0] : 0;
2664+        for (q = clist + p; q->y != 0; q = clist + q->pred)
2665+                J[q->x + pref] = q->y + pref;
2666 }
2667 
2668 static void
2669 check(FILE *f1, FILE *f2, int flags)
2670 {
2671-	int i, j, c, d;
2672-	long ctold, ctnew;
2673-
2674-	rewind(f1);
2675-	rewind(f2);
2676-	j = 1;
2677-	ixold[0] = ixnew[0] = 0;
2678-	ctold = ctnew = 0;
2679-	for (i = 1; i <= (int)len[0]; i++) {
2680-		if (J[i] == 0) {
2681-			ixold[i] = ctold += skipline(f1);
2682-			continue;
2683-		}
2684-		while (j < J[i]) {
2685-			ixnew[j] = ctnew += skipline(f2);
2686-			j++;
2687-		}
2688-		if (flags & (D_FOLDBLANKS | D_IGNOREBLANKS | D_IGNORECASE | D_STRIPCR)) {
2689-			for (;;) {
2690-				c = getc(f1);
2691-				d = getc(f2);
2692-				if (flags & (D_FOLDBLANKS | D_IGNOREBLANKS)) {
2693-					if (c == EOF && isspace(d)) {
2694-						ctnew++;
2695-						break;
2696-					} else if (isspace(c) && d == EOF) {
2697-						ctold++;
2698-						break;
2699-					}
2700-				}
2701-				ctold++;
2702-				ctnew++;
2703-				if (flags & D_STRIPCR && (c == '\r' || d == '\r')) {
2704-					if (c == '\r') {
2705-						if ((c = getc(f1)) == '\n')
2706-							ctold++;
2707-						else
2708-							ungetc(c, f1);
2709-					}
2710-					if (d == '\r') {
2711-						if ((d = getc(f2)) == '\n')
2712-							ctnew++;
2713-						else
2714-							ungetc(d, f2);
2715-					}
2716-					break;
2717-				}
2718-				if ((flags & D_FOLDBLANKS) && isspace(c) && isspace(d)) {
2719-					do {
2720-						if (c == '\n')
2721-							break;
2722-						ctold++;
2723-					} while (isspace(c = getc(f1)));
2724-					do {
2725-						if (d == '\n')
2726-							break;
2727-						ctnew++;
2728-					} while (isspace(d = getc(f2)));
2729-				} else if (flags & D_IGNOREBLANKS) {
2730-					while (isspace(c) && c != '\n') {
2731-						c = getc(f1);
2732-						ctold++;
2733-					}
2734-					while (isspace(d) && d != '\n') {
2735-						d = getc(f2);
2736-						ctnew++;
2737-					}
2738-				}
2739-				if (chrtran(c) != chrtran(d)) {
2740-					J[i] = 0;
2741-					if (c != '\n' && c != EOF)
2742-						ctold += skipline(f1);
2743-					if (d != '\n' && c != EOF)
2744-						ctnew += skipline(f2);
2745-					break;
2746-				}
2747-				if (c == '\n' || c == EOF)
2748-					break;
2749-			}
2750-		} else {
2751-			for (;;) {
2752-				ctold++;
2753-				ctnew++;
2754-				if ((c = getc(f1)) != (d = getc(f2))) {
2755-					J[i] = 0;
2756-					if (c != '\n' && c != EOF)
2757-						ctold += skipline(f1);
2758-					if (d != '\n' && c != EOF)
2759-						ctnew += skipline(f2);
2760-					break;
2761-				}
2762-				if (c == '\n' || c == EOF)
2763-					break;
2764-			}
2765-		}
2766-		ixold[i] = ctold;
2767-		ixnew[j] = ctnew;
2768-		j++;
2769-	}
2770-	for (; j <= (int)len[1]; j++) {
2771-		ixnew[j] = ctnew += skipline(f2);
2772-	}
2773+        int i, j, c, d;
2774+        long ctold, ctnew;
2775+
2776+        rewind(f1);
2777+        rewind(f2);
2778+        j = 1;
2779+        ixold[0] = ixnew[0] = 0;
2780+        ctold = ctnew = 0;
2781+        for (i = 1; i <= (int)len[0]; i++) {
2782+                if (J[i] == 0) {
2783+                        ixold[i] = ctold += skipline(f1);
2784+                        continue;
2785+                }
2786+                while (j < J[i]) {
2787+                        ixnew[j] = ctnew += skipline(f2);
2788+                        j++;
2789+                }
2790+                if (flags & (D_FOLDBLANKS | D_IGNOREBLANKS | D_IGNORECASE | D_STRIPCR)) {
2791+                        for (;;) {
2792+                                c = getc(f1);
2793+                                d = getc(f2);
2794+                                if (flags & (D_FOLDBLANKS | D_IGNOREBLANKS)) {
2795+                                        if (c == EOF && isspace(d)) {
2796+                                                ctnew++;
2797+                                                break;
2798+                                        } else if (isspace(c) && d == EOF) {
2799+                                                ctold++;
2800+                                                break;
2801+                                        }
2802+                                }
2803+                                ctold++;
2804+                                ctnew++;
2805+                                if (flags & D_STRIPCR && (c == '\r' || d == '\r')) {
2806+                                        if (c == '\r') {
2807+                                                if ((c = getc(f1)) == '\n')
2808+                                                        ctold++;
2809+                                                else
2810+                                                        ungetc(c, f1);
2811+                                        }
2812+                                        if (d == '\r') {
2813+                                                if ((d = getc(f2)) == '\n')
2814+                                                        ctnew++;
2815+                                                else
2816+                                                        ungetc(d, f2);
2817+                                        }
2818+                                        break;
2819+                                }
2820+                                if ((flags & D_FOLDBLANKS) && isspace(c) && isspace(d)) {
2821+                                        do {
2822+                                                if (c == '\n')
2823+                                                        break;
2824+                                                ctold++;
2825+                                        } while (isspace(c = getc(f1)));
2826+                                        do {
2827+                                                if (d == '\n')
2828+                                                        break;
2829+                                                ctnew++;
2830+                                        } while (isspace(d = getc(f2)));
2831+                                } else if (flags & D_IGNOREBLANKS) {
2832+                                        while (isspace(c) && c != '\n') {
2833+                                                c = getc(f1);
2834+                                                ctold++;
2835+                                        }
2836+                                        while (isspace(d) && d != '\n') {
2837+                                                d = getc(f2);
2838+                                                ctnew++;
2839+                                        }
2840+                                }
2841+                                if (chrtran(c) != chrtran(d)) {
2842+                                        J[i] = 0;
2843+                                        if (c != '\n' && c != EOF)
2844+                                                ctold += skipline(f1);
2845+                                        if (d != '\n' && c != EOF)
2846+                                                ctnew += skipline(f2);
2847+                                        break;
2848+                                }
2849+                                if (c == '\n' || c == EOF)
2850+                                        break;
2851+                        }
2852+                } else {
2853+                        for (;;) {
2854+                                ctold++;
2855+                                ctnew++;
2856+                                if ((c = getc(f1)) != (d = getc(f2))) {
2857+                                        J[i] = 0;
2858+                                        if (c != '\n' && c != EOF)
2859+                                                ctold += skipline(f1);
2860+                                        if (d != '\n' && c != EOF)
2861+                                                ctnew += skipline(f2);
2862+                                        break;
2863+                                }
2864+                                if (c == '\n' || c == EOF)
2865+                                        break;
2866+                        }
2867+                }
2868+                ixold[i] = ctold;
2869+                ixnew[j] = ctnew;
2870+                j++;
2871+        }
2872+        for (; j <= (int)len[1]; j++) {
2873+                ixnew[j] = ctnew += skipline(f2);
2874+        }
2875 }
2876 
2877 static void
2878 sort(struct Line *a, int n)
2879 {
2880-	struct Line *ai, *aim, w;
2881-	int j, m = 0, k;
2882-
2883-	if (n == 0)
2884-		return;
2885-	for (j = 1; j <= n; j *= 2)
2886-		m = 2 * j - 1;
2887-	for (m /= 2; m != 0; m /= 2) {
2888-		k = n - m;
2889-		for (j = 1; j <= k; j++) {
2890-			for (ai = &a[j]; ai > a; ai -= m) {
2891-				aim = &ai[m];
2892-				if (aim < ai)
2893-					break;
2894-				if (aim->value > ai[0].value ||
2895-				    (aim->value == ai[0].value && aim->serial > ai[0].serial))
2896-					break;
2897-				w.value = ai[0].value;
2898-				ai[0].value = aim->value;
2899-				aim->value = w.value;
2900-				w.serial = ai[0].serial;
2901-				ai[0].serial = aim->serial;
2902-				aim->serial = w.serial;
2903-			}
2904-		}
2905-	}
2906+        struct Line *ai, *aim, w;
2907+        int j, m = 0, k;
2908+
2909+        if (n == 0)
2910+                return;
2911+        for (j = 1; j <= n; j *= 2)
2912+                m = 2 * j - 1;
2913+        for (m /= 2; m != 0; m /= 2) {
2914+                k = n - m;
2915+                for (j = 1; j <= k; j++) {
2916+                        for (ai = &a[j]; ai > a; ai -= m) {
2917+                                aim = &ai[m];
2918+                                if (aim < ai)
2919+                                        break;
2920+                                if (aim->value > ai[0].value ||
2921+                                    (aim->value == ai[0].value && aim->serial > ai[0].serial))
2922+                                        break;
2923+                                w.value = ai[0].value;
2924+                                ai[0].value = aim->value;
2925+                                aim->value = w.value;
2926+                                w.serial = ai[0].serial;
2927+                                ai[0].serial = aim->serial;
2928+                                aim->serial = w.serial;
2929+                        }
2930+                }
2931+        }
2932 }
2933 
2934 static void
2935 unsort(struct Line *f, int l, int *b)
2936 {
2937-	int *a, i;
2938-
2939-	a = ecalloc(l + 1, sizeof(*a));
2940-	for (i = 1; i <= l; i++)
2941-		a[f[i].serial] = f[i].value;
2942-	for (i = 1; i <= l; i++)
2943-		b[i] = a[i];
2944-	free(a);
2945+        int *a, i;
2946+
2947+        a = ecalloc(l + 1, sizeof(*a));
2948+        for (i = 1; i <= l; i++)
2949+                a[f[i].serial] = f[i].value;
2950+        for (i = 1; i <= l; i++)
2951+                b[i] = a[i];
2952+        free(a);
2953 }
2954 
2955 static int
2956 skipline(FILE *f)
2957 {
2958-	int i, c;
2959+        int i, c;
2960 
2961-	for (i = 1; (c = getc(f)) != '\n' && c != EOF; i++)
2962-		continue;
2963-	return i;
2964+        for (i = 1; (c = getc(f)) != '\n' && c != EOF; i++)
2965+                continue;
2966+        return i;
2967 }
2968 
2969 static void
2970 output(char *file1, FILE *f1, char *file2, FILE *f2, int flags)
2971 {
2972-	int i, j, m, i0, i1, j0, j1, nc;
2973-
2974-	rewind(f1);
2975-	rewind(f2);
2976-	m = len[0];
2977-	J[0] = 0;
2978-	J[m + 1] = len[1] + 1;
2979-	if (diff_format != D_EDIT) {
2980-		for (i0 = 1; i0 <= m; i0 = i1 + 1) {
2981-			while (i0 <= m && J[i0] == J[i0 - 1] + 1) {
2982-				if (diff_format == D_SIDEBYSIDE && suppress_common != 1) {
2983-					nc = fetch(ixold, i0, i0, f1, '\0', 1, flags);
2984-					print_space(nc, hw - nc + lpad + 1 + rpad, flags);
2985-					fetch(ixnew, J[i0], J[i0], f2, '\0', 0, flags);
2986-					printf("\n");
2987-				}
2988-				i0++;
2989-			}
2990-			j0 = J[i0 - 1] + 1;
2991-			i1 = i0 - 1;
2992-			while (i1 < m && J[i1 + 1] == 0)
2993-				i1++;
2994-			j1 = J[i1 + 1] - 1;
2995-			J[i1] = j1;
2996-
2997-			if (diff_format == D_SIDEBYSIDE) {
2998-				for (i = i0, j = j0; i <= i1 && j <= j1; i++, j++)
2999-					change(file1, f1, file2, f2, i, i, j, j, &flags);
3000-				while (i <= i1) {
3001-					change(file1, f1, file2, f2, i, i, j + 1, j, &flags);
3002-					i++;
3003-				}
3004-				while (j <= j1) {
3005-					change(file1, f1, file2, f2, i + 1, i, j, j, &flags);
3006-					j++;
3007-				}
3008-			} else
3009-				change(file1, f1, file2, f2, i0, i1, j0, j1, &flags);
3010-		}
3011-	} else {
3012-		for (i0 = m; i0 >= 1; i0 = i1 - 1) {
3013-			while (i0 >= 1 && J[i0] == J[i0 + 1] - 1 && J[i0] != 0)
3014-				i0--;
3015-			j0 = J[i0 + 1] - 1;
3016-			i1 = i0 + 1;
3017-			while (i1 > 1 && J[i1 - 1] == 0)
3018-				i1--;
3019-			j1 = J[i1 - 1] + 1;
3020-			J[i1] = j1;
3021-			change(file1, f1, file2, f2, i1, i0, j1, j0, &flags);
3022-		}
3023-	}
3024-	if (m == 0)
3025-		change(file1, f1, file2, f2, 1, 0, 1, len[1], &flags);
3026-	if (diff_format == D_IFDEF || diff_format == D_GFORMAT) {
3027-		for (;;) {
3028+        int i, j, m, i0, i1, j0, j1, nc;
3029+
3030+        rewind(f1);
3031+        rewind(f2);
3032+        m = len[0];
3033+        J[0] = 0;
3034+        J[m + 1] = len[1] + 1;
3035+        if (diff_format != D_EDIT) {
3036+                for (i0 = 1; i0 <= m; i0 = i1 + 1) {
3037+                        while (i0 <= m && J[i0] == J[i0 - 1] + 1) {
3038+                                if (diff_format == D_SIDEBYSIDE && suppress_common != 1) {
3039+                                        nc = fetch(ixold, i0, i0, f1, '\0', 1, flags);
3040+                                        print_space(nc, hw - nc + lpad + 1 + rpad, flags);
3041+                                        fetch(ixnew, J[i0], J[i0], f2, '\0', 0, flags);
3042+                                        printf("\n");
3043+                                }
3044+                                i0++;
3045+                        }
3046+                        j0 = J[i0 - 1] + 1;
3047+                        i1 = i0 - 1;
3048+                        while (i1 < m && J[i1 + 1] == 0)
3049+                                i1++;
3050+                        j1 = J[i1 + 1] - 1;
3051+                        J[i1] = j1;
3052+
3053+                        if (diff_format == D_SIDEBYSIDE) {
3054+                                for (i = i0, j = j0; i <= i1 && j <= j1; i++, j++)
3055+                                        change(file1, f1, file2, f2, i, i, j, j, &flags);
3056+                                while (i <= i1) {
3057+                                        change(file1, f1, file2, f2, i, i, j + 1, j, &flags);
3058+                                        i++;
3059+                                }
3060+                                while (j <= j1) {
3061+                                        change(file1, f1, file2, f2, i + 1, i, j, j, &flags);
3062+                                        j++;
3063+                                }
3064+                        } else
3065+                                change(file1, f1, file2, f2, i0, i1, j0, j1, &flags);
3066+                }
3067+        } else {
3068+                for (i0 = m; i0 >= 1; i0 = i1 - 1) {
3069+                        while (i0 >= 1 && J[i0] == J[i0 + 1] - 1 && J[i0] != 0)
3070+                                i0--;
3071+                        j0 = J[i0 + 1] - 1;
3072+                        i1 = i0 + 1;
3073+                        while (i1 > 1 && J[i1 - 1] == 0)
3074+                                i1--;
3075+                        j1 = J[i1 - 1] + 1;
3076+                        J[i1] = j1;
3077+                        change(file1, f1, file2, f2, i1, i0, j1, j0, &flags);
3078+                }
3079+        }
3080+        if (m == 0)
3081+                change(file1, f1, file2, f2, 1, 0, 1, len[1], &flags);
3082+        if (diff_format == D_IFDEF || diff_format == D_GFORMAT) {
3083+                for (;;) {
3084 #define c i0
3085-			if ((c = getc(f1)) == EOF)
3086-				return;
3087-			printf("%c", c);
3088-		}
3089+                        if ((c = getc(f1)) == EOF)
3090+                                return;
3091+                        printf("%c", c);
3092+                }
3093 #undef c
3094-	}
3095-	if (anychange != 0) {
3096-		if (diff_format == D_CONTEXT)
3097-			dump_context_vec(f1, f2, flags);
3098-		else if (diff_format == D_UNIFIED)
3099-			dump_unified_vec(f1, f2, flags);
3100-	}
3101+        }
3102+        if (anychange != 0) {
3103+                if (diff_format == D_CONTEXT)
3104+                        dump_context_vec(f1, f2, flags);
3105+                else if (diff_format == D_UNIFIED)
3106+                        dump_unified_vec(f1, f2, flags);
3107+        }
3108 }
3109 
3110 static void
3111 range(int a, int b, const char *separator)
3112 {
3113-	printf("%d", a > b ? b : a);
3114-	if (a < b)
3115-		printf("%s%d", separator, b);
3116+        printf("%d", a > b ? b : a);
3117+        if (a < b)
3118+                printf("%s%d", separator, b);
3119 }
3120 
3121 static void
3122 uni_range(int a, int b)
3123 {
3124-	if (a < b)
3125-		printf("%d,%d", a, b - a + 1);
3126-	else if (a == b)
3127-		printf("%d", b);
3128-	else
3129-		printf("%d,0", b);
3130+        if (a < b)
3131+                printf("%d,%d", a, b - a + 1);
3132+        else if (a == b)
3133+                printf("%d", b);
3134+        else
3135+                printf("%d,0", b);
3136 }
3137 
3138 static char *
3139 preadline(int fd, size_t rlen, off_t off)
3140 {
3141-	char *line;
3142-	ssize_t nr;
3143-
3144-	line = emalloc(rlen + 1);
3145-	if ((nr = pread(fd, line, rlen, off)) == -1)
3146-		err(2, "preadline");
3147-	if (nr > 0 && line[nr-1] == '\n')
3148-		nr--;
3149-	line[nr] = '\0';
3150-	return line;
3151+        char *line;
3152+        ssize_t nr;
3153+
3154+        line = emalloc(rlen + 1);
3155+        if ((nr = pread(fd, line, rlen, off)) == -1)
3156+                enprintf(2, "preadline");
3157+        if (nr > 0 && line[nr-1] == '\n')
3158+                nr--;
3159+        line[nr] = '\0';
3160+        return line;
3161 }
3162 
3163 static int
3164 ignoreline_pattern(char *line)
3165 {
3166-	int ret;
3167+        int ret;
3168 
3169-	ret = regexec(&ignore_re, line, 0, NULL, 0);
3170-	return ret == 0;
3171+        ret = regexec(&ignore_re, line, 0, NULL, 0);
3172+        return ret == 0;
3173 }
3174 
3175 static int
3176 ignoreline(char *line, int skip_blanks)
3177 {
3178-	if (skip_blanks && *line == '\0')
3179-		return 1;
3180-	if (ignore_pats != NULL && ignoreline_pattern(line))
3181-		return 1;
3182-	return 0;
3183+        if (skip_blanks && *line == '\0')
3184+                return 1;
3185+        if (ignore_pats != NULL && ignoreline_pattern(line))
3186+                return 1;
3187+        return 0;
3188 }
3189 
3190 static void
3191 change(char *file1, FILE *f1, char *file2, FILE *f2, int a, int b, int c, int d,
3192     int *pflags)
3193 {
3194-	static size_t max_context = 64;
3195-	long curpos;
3196-	int i, nc;
3197-	const char *walk;
3198-	int skip_blanks, ignore;
3199+        static size_t max_context = 64;
3200+        long curpos;
3201+        int i, nc;
3202+        const char *walk;
3203+        int skip_blanks, ignore;
3204 
3205-	skip_blanks = (*pflags & D_SKIPBLANKLINES);
3206+        skip_blanks = (*pflags & D_SKIPBLANKLINES);
3207 restart:
3208-	if ((diff_format != D_IFDEF || diff_format == D_GFORMAT) && a > b && c > d)
3209-		return;
3210-	if (ignore_pats != NULL || skip_blanks) {
3211-		char *line;
3212-		if (a <= b) {
3213-			for (i = a; i <= b; i++) {
3214-				line = preadline(fileno(f1), ixold[i] - ixold[i - 1], ixold[i - 1]);
3215-				ignore = ignoreline(line, skip_blanks);
3216-				free(line);
3217-				if (!ignore)
3218-					goto proceed;
3219-			}
3220-		}
3221-		if (a > b || c <= d) {
3222-			for (i = c; i <= d; i++) {
3223-				line = preadline(fileno(f2), ixnew[i] - ixnew[i - 1], ixnew[i - 1]);
3224-				ignore = ignoreline(line, skip_blanks);
3225-				free(line);
3226-				if (!ignore)
3227-					goto proceed;
3228-			}
3229-		}
3230-		return;
3231-	}
3232+        if ((diff_format != D_IFDEF || diff_format == D_GFORMAT) && a > b && c > d)
3233+                return;
3234+        if (ignore_pats != NULL || skip_blanks) {
3235+                char *line;
3236+                if (a <= b) {
3237+                        for (i = a; i <= b; i++) {
3238+                                line = preadline(fileno(f1), ixold[i] - ixold[i - 1], ixold[i - 1]);
3239+                                ignore = ignoreline(line, skip_blanks);
3240+                                free(line);
3241+                                if (!ignore)
3242+                                        goto proceed;
3243+                        }
3244+                }
3245+                if (a > b || c <= d) {
3246+                        for (i = c; i <= d; i++) {
3247+                                line = preadline(fileno(f2), ixnew[i] - ixnew[i - 1], ixnew[i - 1]);
3248+                                ignore = ignoreline(line, skip_blanks);
3249+                                free(line);
3250+                                if (!ignore)
3251+                                        goto proceed;
3252+                        }
3253+                }
3254+                return;
3255+        }
3256 proceed:
3257-	if (*pflags & D_HEADER && diff_format != D_BRIEF) {
3258-		printf("%s %s %s\n", diffargs, file1, file2);
3259-		*pflags &= ~D_HEADER;
3260-	}
3261-	if (diff_format == D_CONTEXT || diff_format == D_UNIFIED) {
3262-		if (context_vec_start == NULL || context_vec_ptr == context_vec_end - 1) {
3263-			ptrdiff_t offset = -1;
3264-
3265-			if (context_vec_start != NULL)
3266-				offset = context_vec_ptr - context_vec_start;
3267-			max_context <<= 1;
3268-			context_vec_start = ereallocarray(context_vec_start, max_context, sizeof(*context_vec_start));
3269-			context_vec_end = context_vec_start + max_context;
3270-			context_vec_ptr = context_vec_start + offset;
3271-		}
3272-		if (anychange == 0) {
3273-			print_header(file1, file2);
3274-			anychange = 1;
3275-		} else if (a > context_vec_ptr->b + (2 * diff_context) + 1 &&
3276-		    c > context_vec_ptr->d + (2 * diff_context) + 1) {
3277-			if (diff_format == D_CONTEXT)
3278-				dump_context_vec(f1, f2, *pflags);
3279-			else
3280-				dump_unified_vec(f1, f2, *pflags);
3281-		}
3282-		context_vec_ptr++;
3283-		context_vec_ptr->a = a;
3284-		context_vec_ptr->b = b;
3285-		context_vec_ptr->c = c;
3286-		context_vec_ptr->d = d;
3287-		return;
3288-	}
3289-	if (anychange == 0)
3290-		anychange = 1;
3291-	switch (diff_format) {
3292-	case D_BRIEF:
3293-		return;
3294-	case D_NORMAL:
3295-	case D_EDIT:
3296-		range(a, b, ",");
3297-		printf("%c", a > b ? 'a' : c > d ? 'd' : 'c');
3298-		if (diff_format == D_NORMAL)
3299-			range(c, d, ",");
3300-		printf("\n");
3301-		break;
3302-	case D_REVERSE:
3303-		printf("%c", a > b ? 'a' : c > d ? 'd' : 'c');
3304-		range(a, b, " ");
3305-		printf("\n");
3306-		break;
3307-	case D_NREVERSE:
3308-		if (a > b)
3309-			printf("a%d %d\n", b, d - c + 1);
3310-		else {
3311-			printf("d%d %d\n", a, b - a + 1);
3312-			if (!(c > d))
3313-				printf("a%d %d\n", b, d - c + 1);
3314-		}
3315-		break;
3316-	}
3317-	if (diff_format == D_GFORMAT) {
3318-		curpos = ftell(f1);
3319-		nc = ixold[a > b ? b : a - 1] - curpos;
3320-		for (i = 0; i < nc; i++)
3321-			printf("%c", getc(f1));
3322-		for (walk = group_format; *walk != '\0'; walk++) {
3323-			if (*walk == '%') {
3324-				walk++;
3325-				switch (*walk) {
3326-				case '<':
3327-					fetch(ixold, a, b, f1, '<', 1, *pflags);
3328-					break;
3329-				case '>':
3330-					fetch(ixnew, c, d, f2, '>', 0, *pflags);
3331-					break;
3332-				default:
3333-					printf("%%%c", *walk);
3334-					break;
3335-				}
3336-				continue;
3337-			}
3338-			printf("%c", *walk);
3339-		}
3340-	}
3341-	if (diff_format == D_SIDEBYSIDE) {
3342-		if (color && a > b)
3343-			printf("\033[%sm", add_code);
3344-		else if (color && c > d)
3345-			printf("\033[%sm", del_code);
3346-		if (a > b) {
3347-			print_space(0, hw + lpad, *pflags);
3348-		} else {
3349-			nc = fetch(ixold, a, b, f1, '\0', 1, *pflags);
3350-			print_space(nc, hw - nc + lpad, *pflags);
3351-		}
3352-		if (color && a > b)
3353-			printf("\033[%sm", add_code);
3354-		else if (color && c > d)
3355-			printf("\033[%sm", del_code);
3356-		printf("%c", (a > b) ? '>' : ((c > d) ? '<' : '|'));
3357-		if (color && c > d)
3358-			printf("\033[m");
3359-		print_space(hw + lpad + 1, rpad, *pflags);
3360-		fetch(ixnew, c, d, f2, '\0', 0, *pflags);
3361-		printf("\n");
3362-	}
3363-	if (diff_format == D_NORMAL || diff_format == D_IFDEF) {
3364-		fetch(ixold, a, b, f1, '<', 1, *pflags);
3365-		if (a <= b && c <= d && diff_format == D_NORMAL)
3366-			printf("---\n");
3367-	}
3368-	if (diff_format != D_GFORMAT && diff_format != D_SIDEBYSIDE)
3369-		fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0, *pflags);
3370-	if (edoffset != 0 && diff_format == D_EDIT) {
3371-		printf(".\n");
3372-		printf("%ds/.//\n", a + edoffset - 1);
3373-		b = a + edoffset - 1;
3374-		a = b + 1;
3375-		c += edoffset;
3376-		goto restart;
3377-	}
3378-	if ((diff_format == D_EDIT || diff_format == D_REVERSE) && c <= d)
3379-		printf(".\n");
3380-	if (inifdef) {
3381-		printf("#endif /* %s */\n", ifdefname);
3382-		inifdef = 0;
3383-	}
3384+        if (*pflags & D_HEADER && diff_format != D_BRIEF) {
3385+                printf("%s %s %s\n", diffargs, file1, file2);
3386+                *pflags &= ~D_HEADER;
3387+        }
3388+        if (diff_format == D_CONTEXT || diff_format == D_UNIFIED) {
3389+                if (context_vec_start == NULL || context_vec_ptr == context_vec_end - 1) {
3390+                        ptrdiff_t offset = -1;
3391+
3392+                        if (context_vec_start != NULL)
3393+                                offset = context_vec_ptr - context_vec_start;
3394+                        max_context <<= 1;
3395+                        context_vec_start = ereallocarray(context_vec_start, max_context, sizeof(*context_vec_start));
3396+                        context_vec_end = context_vec_start + max_context;
3397+                        context_vec_ptr = context_vec_start + offset;
3398+                }
3399+                if (anychange == 0) {
3400+                        print_header(file1, file2);
3401+                        anychange = 1;
3402+                } else if (a > context_vec_ptr->b + (2 * diff_context) + 1 &&
3403+                    c > context_vec_ptr->d + (2 * diff_context) + 1) {
3404+                        if (diff_format == D_CONTEXT)
3405+                                dump_context_vec(f1, f2, *pflags);
3406+                        else
3407+                                dump_unified_vec(f1, f2, *pflags);
3408+                }
3409+                context_vec_ptr++;
3410+                context_vec_ptr->a = a;
3411+                context_vec_ptr->b = b;
3412+                context_vec_ptr->c = c;
3413+                context_vec_ptr->d = d;
3414+                return;
3415+        }
3416+        if (anychange == 0)
3417+                anychange = 1;
3418+        switch (diff_format) {
3419+        case D_BRIEF:
3420+                return;
3421+        case D_NORMAL:
3422+        case D_EDIT:
3423+                range(a, b, ",");
3424+                printf("%c", a > b ? 'a' : c > d ? 'd' : 'c');
3425+                if (diff_format == D_NORMAL)
3426+                        range(c, d, ",");
3427+                printf("\n");
3428+                break;
3429+        case D_REVERSE:
3430+                printf("%c", a > b ? 'a' : c > d ? 'd' : 'c');
3431+                range(a, b, " ");
3432+                printf("\n");
3433+                break;
3434+        case D_NREVERSE:
3435+                if (a > b)
3436+                        printf("a%d %d\n", b, d - c + 1);
3437+                else {
3438+                        printf("d%d %d\n", a, b - a + 1);
3439+                        if (!(c > d))
3440+                                printf("a%d %d\n", b, d - c + 1);
3441+                }
3442+                break;
3443+        }
3444+        if (diff_format == D_GFORMAT) {
3445+                curpos = ftell(f1);
3446+                nc = ixold[a > b ? b : a - 1] - curpos;
3447+                for (i = 0; i < nc; i++)
3448+                        printf("%c", getc(f1));
3449+                for (walk = group_format; *walk != '\0'; walk++) {
3450+                        if (*walk == '%') {
3451+                                walk++;
3452+                                switch (*walk) {
3453+                                case '<':
3454+                                        fetch(ixold, a, b, f1, '<', 1, *pflags);
3455+                                        break;
3456+                                case '>':
3457+                                        fetch(ixnew, c, d, f2, '>', 0, *pflags);
3458+                                        break;
3459+                                default:
3460+                                        printf("%%%c", *walk);
3461+                                        break;
3462+                                }
3463+                                continue;
3464+                        }
3465+                        printf("%c", *walk);
3466+                }
3467+        }
3468+        if (diff_format == D_SIDEBYSIDE) {
3469+                if (color && a > b)
3470+                        printf("\033[%sm", add_code);
3471+                else if (color && c > d)
3472+                        printf("\033[%sm", del_code);
3473+                if (a > b) {
3474+                        print_space(0, hw + lpad, *pflags);
3475+                } else {
3476+                        nc = fetch(ixold, a, b, f1, '\0', 1, *pflags);
3477+                        print_space(nc, hw - nc + lpad, *pflags);
3478+                }
3479+                if (color && a > b)
3480+                        printf("\033[%sm", add_code);
3481+                else if (color && c > d)
3482+                        printf("\033[%sm", del_code);
3483+                printf("%c", (a > b) ? '>' : ((c > d) ? '<' : '|'));
3484+                if (color && c > d)
3485+                        printf("\033[m");
3486+                print_space(hw + lpad + 1, rpad, *pflags);
3487+                fetch(ixnew, c, d, f2, '\0', 0, *pflags);
3488+                printf("\n");
3489+        }
3490+        if (diff_format == D_NORMAL || diff_format == D_IFDEF) {
3491+                fetch(ixold, a, b, f1, '<', 1, *pflags);
3492+                if (a <= b && c <= d && diff_format == D_NORMAL)
3493+                        printf("---\n");
3494+        }
3495+        if (diff_format != D_GFORMAT && diff_format != D_SIDEBYSIDE)
3496+                fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0, *pflags);
3497+        if (edoffset != 0 && diff_format == D_EDIT) {
3498+                printf(".\n");
3499+                printf("%ds/.//\n", a + edoffset - 1);
3500+                b = a + edoffset - 1;
3501+                a = b + 1;
3502+                c += edoffset;
3503+                goto restart;
3504+        }
3505+        if ((diff_format == D_EDIT || diff_format == D_REVERSE) && c <= d)
3506+                printf(".\n");
3507+        if (inifdef) {
3508+                printf("#endif /* %s */\n", ifdefname);
3509+                inifdef = 0;
3510+        }
3511 }
3512 
3513 static int
3514 fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile, int flags)
3515 {
3516-	int i, j, c, lastc, col, nc, newcol;
3517-
3518-	edoffset = 0;
3519-	nc = 0;
3520-	col = 0;
3521-	if ((diff_format == D_IFDEF) && oldfile) {
3522-		long curpos = ftell(lb);
3523-		nc = f[a > b ? b : a - 1] - curpos;
3524-		for (i = 0; i < nc; i++)
3525-			printf("%c", getc(lb));
3526-	}
3527-	if (a > b)
3528-		return 0;
3529-	if (diff_format == D_IFDEF) {
3530-		if (inifdef) {
3531-			printf("#else /* %s%s */\n",
3532-			    oldfile == 1 ? "!" : "", ifdefname);
3533-		} else {
3534-			if (oldfile)
3535-				printf("#ifndef %s\n", ifdefname);
3536-			else
3537-				printf("#ifdef %s\n", ifdefname);
3538-		}
3539-		inifdef = 1 + oldfile;
3540-	}
3541-	for (i = a; i <= b; i++) {
3542-		fseek(lb, f[i - 1], SEEK_SET);
3543-		nc = f[i] - f[i - 1];
3544-		if (diff_format == D_SIDEBYSIDE && hw < nc)
3545-			nc = hw;
3546-		if (diff_format != D_IFDEF && diff_format != D_GFORMAT && ch != '\0') {
3547-			if (color && (ch == '>' || ch == '+'))
3548-				printf("\033[%sm", add_code);
3549-			else if (color && (ch == '<' || ch == '-'))
3550-				printf("\033[%sm", del_code);
3551-			printf("%c", ch);
3552-			if (Tflag && (diff_format == D_NORMAL ||
3553-			    diff_format == D_CONTEXT ||
3554-			    diff_format == D_UNIFIED))
3555-				printf("\t");
3556-			else if (diff_format != D_UNIFIED)
3557-				printf(" ");
3558-		}
3559-		col = j = 0;
3560-		lastc = '\0';
3561-		while (j < nc && (hw == 0 || col < hw)) {
3562-			c = getc(lb);
3563-			if (flags & D_STRIPCR && c == '\r') {
3564-				if ((c = getc(lb)) == '\n')
3565-					j++;
3566-				else {
3567-					ungetc(c, lb);
3568-					c = '\r';
3569-				}
3570-			}
3571-			if (c == EOF) {
3572-				if (diff_format == D_EDIT ||
3573-				    diff_format == D_REVERSE ||
3574-				    diff_format == D_NREVERSE)
3575-					warnx("No newline at end of file");
3576-				else
3577-					printf("\n\\ No newline at end of file\n");
3578-				return col;
3579-			}
3580-			if (c == '\t') {
3581-				newcol = roundup(col + 1, tabsize);
3582-				if ((flags & D_EXPANDTABS) == 0) {
3583-					if (hw > 0 && newcol >= hw)
3584-						return col;
3585-					printf("\t");
3586-				} else {
3587-					if (hw > 0 && newcol > hw)
3588-						newcol = hw;
3589-					printf("%*s", newcol - col, "");
3590-				}
3591-				col = newcol;
3592-			} else {
3593-				if (diff_format == D_EDIT && j == 1 && c == '\n' && lastc == '.') {
3594-					printf(".\n");
3595-					edoffset = i - a + 1;
3596-					return edoffset;
3597-				}
3598-				if (diff_format != D_SIDEBYSIDE || c != '\n') {
3599-					if (color && c == '\n')
3600-						printf("\033[m%c", c);
3601-					else
3602-						printf("%c", c);
3603-					col++;
3604-				}
3605-			}
3606-			j++;
3607-			lastc = c;
3608-		}
3609-	}
3610-	if (color && diff_format == D_SIDEBYSIDE)
3611-		printf("\033[m");
3612-	return col;
3613+        int i, j, c, lastc, col, nc, newcol;
3614+
3615+        edoffset = 0;
3616+        nc = 0;
3617+        col = 0;
3618+        if ((diff_format == D_IFDEF) && oldfile) {
3619+                long curpos = ftell(lb);
3620+                nc = f[a > b ? b : a - 1] - curpos;
3621+                for (i = 0; i < nc; i++)
3622+                        printf("%c", getc(lb));
3623+        }
3624+        if (a > b)
3625+                return 0;
3626+        if (diff_format == D_IFDEF) {
3627+                if (inifdef) {
3628+                        printf("#else /* %s%s */\n",
3629+                            oldfile == 1 ? "!" : "", ifdefname);
3630+                } else {
3631+                        if (oldfile)
3632+                                printf("#ifndef %s\n", ifdefname);
3633+                        else
3634+                                printf("#ifdef %s\n", ifdefname);
3635+                }
3636+                inifdef = 1 + oldfile;
3637+        }
3638+        for (i = a; i <= b; i++) {
3639+                fseek(lb, f[i - 1], SEEK_SET);
3640+                nc = f[i] - f[i - 1];
3641+                if (diff_format == D_SIDEBYSIDE && hw < nc)
3642+                        nc = hw;
3643+                if (diff_format != D_IFDEF && diff_format != D_GFORMAT && ch != '\0') {
3644+                        if (color && (ch == '>' || ch == '+'))
3645+                                printf("\033[%sm", add_code);
3646+                        else if (color && (ch == '<' || ch == '-'))
3647+                                printf("\033[%sm", del_code);
3648+                        printf("%c", ch);
3649+                        if (Tflag && (diff_format == D_NORMAL ||
3650+                            diff_format == D_CONTEXT ||
3651+                            diff_format == D_UNIFIED))
3652+                                printf("\t");
3653+                        else if (diff_format != D_UNIFIED)
3654+                                printf(" ");
3655+                }
3656+                col = j = 0;
3657+                lastc = '\0';
3658+                while (j < nc && (hw == 0 || col < hw)) {
3659+                        c = getc(lb);
3660+                        if (flags & D_STRIPCR && c == '\r') {
3661+                                if ((c = getc(lb)) == '\n')
3662+                                        j++;
3663+                                else {
3664+                                        ungetc(c, lb);
3665+                                        c = '\r';
3666+                                }
3667+                        }
3668+                        if (c == EOF) {
3669+                                if (diff_format == D_EDIT ||
3670+                                    diff_format == D_REVERSE ||
3671+                                    diff_format == D_NREVERSE)
3672+                                        weprintf("No newline at end of file");
3673+                                else
3674+                                        printf("\n\\ No newline at end of file\n");
3675+                                return col;
3676+                        }
3677+                        if (c == '\t') {
3678+                                newcol = roundup(col + 1, tabsize);
3679+                                if ((flags & D_EXPANDTABS) == 0) {
3680+                                        if (hw > 0 && newcol >= hw)
3681+                                                return col;
3682+                                        printf("\t");
3683+                                } else {
3684+                                        if (hw > 0 && newcol > hw)
3685+                                                newcol = hw;
3686+                                        printf("%*s", newcol - col, "");
3687+                                }
3688+                                col = newcol;
3689+                        } else {
3690+                                if (diff_format == D_EDIT && j == 1 && c == '\n' && lastc == '.') {
3691+                                        printf(".\n");
3692+                                        edoffset = i - a + 1;
3693+                                        return edoffset;
3694+                                }
3695+                                if (diff_format != D_SIDEBYSIDE || c != '\n') {
3696+                                        if (color && c == '\n')
3697+                                                printf("\033[m%c", c);
3698+                                        else
3699+                                                printf("%c", c);
3700+                                        col++;
3701+                                }
3702+                        }
3703+                        j++;
3704+                        lastc = c;
3705+                }
3706+        }
3707+        if (color && diff_format == D_SIDEBYSIDE)
3708+                printf("\033[m");
3709+        return col;
3710 }
3711 
3712 static enum Readhash
3713 readhash(FILE *f, int flags, unsigned *hash)
3714 {
3715-	int i, t, space;
3716-	unsigned sum;
3717-
3718-	sum = 1;
3719-	space = 0;
3720-	for (i = 0;;) {
3721-		switch (t = getc(f)) {
3722-		case '\0':
3723-			if ((flags & D_FORCEASCII) == 0)
3724-				return RH_BINARY;
3725-			goto hashchar;
3726-		case '\r':
3727-			if (flags & D_STRIPCR) {
3728-				t = getc(f);
3729-				if (t == '\n')
3730-					break;
3731-				ungetc(t, f);
3732-			}
3733-			/* FALLTHROUGH */
3734-		case '\t':
3735-		case '\v':
3736-		case '\f':
3737-		case ' ':
3738-			if ((flags & (D_FOLDBLANKS|D_IGNOREBLANKS)) != 0) {
3739-				space++;
3740-				continue;
3741-			}
3742-			/* FALLTHROUGH */
3743-		default:
3744-		hashchar:
3745-			if (space && (flags & D_IGNOREBLANKS) == 0) {
3746-				i++;
3747-				space = 0;
3748-			}
3749-			sum = sum * 127 + chrtran(t);
3750-			i++;
3751-			continue;
3752-		case EOF:
3753-			if (i == 0)
3754-				return RH_EOF;
3755-			/* FALLTHROUGH */
3756-		case '\n':
3757-			break;
3758-		}
3759-		break;
3760-	}
3761-	*hash = sum;
3762-	return RH_OK;
3763+        int i, t, space;
3764+        unsigned sum;
3765+
3766+        sum = 1;
3767+        space = 0;
3768+        for (i = 0;;) {
3769+                switch (t = getc(f)) {
3770+                case '\0':
3771+                        if ((flags & D_FORCEASCII) == 0)
3772+                                return RH_BINARY;
3773+                        goto hashchar;
3774+                case '\r':
3775+                        if (flags & D_STRIPCR) {
3776+                                t = getc(f);
3777+                                if (t == '\n')
3778+                                        break;
3779+                                ungetc(t, f);
3780+                        }
3781+                        /* FALLTHROUGH */
3782+                case '\t':
3783+                case '\v':
3784+                case '\f':
3785+                case ' ':
3786+                        if ((flags & (D_FOLDBLANKS|D_IGNOREBLANKS)) != 0) {
3787+                                space++;
3788+                                continue;
3789+                        }
3790+                        /* FALLTHROUGH */
3791+                default:
3792+                hashchar:
3793+                        if (space && (flags & D_IGNOREBLANKS) == 0) {
3794+                                i++;
3795+                                space = 0;
3796+                        }
3797+                        sum = sum * 127 + chrtran(t);
3798+                        i++;
3799+                        continue;
3800+                case EOF:
3801+                        if (i == 0)
3802+                                return RH_EOF;
3803+                        /* FALLTHROUGH */
3804+                case '\n':
3805+                        break;
3806+                }
3807+                break;
3808+        }
3809+        *hash = sum;
3810+        return RH_OK;
3811 }
3812 
3813 static int
3814 asciifile(FILE *f)
3815 {
3816-	unsigned char buf[BUFSIZ];
3817-	size_t cnt;
3818+        unsigned char buf[BUFSIZ];
3819+        size_t cnt;
3820 
3821-	if (f == NULL)
3822-		return 1;
3823+        if (f == NULL)
3824+                return 1;
3825 
3826-	rewind(f);
3827-	cnt = fread(buf, 1, sizeof(buf), f);
3828-	return memchr(buf, '\0', cnt) == NULL;
3829+        rewind(f);
3830+        cnt = fread(buf, 1, sizeof(buf), f);
3831+        return memchr(buf, '\0', cnt) == NULL;
3832 }
3833 
3834 #define begins_with(s, pre) (strncmp(s, pre, sizeof(pre) - 1) == 0)
3835@@ -2232,258 +2239,258 @@ asciifile(FILE *f)
3836 static char *
3837 match_function(const long *f, int pos, FILE *fp)
3838 {
3839-	char buf[FUNCTION_CONTEXT_SIZE];
3840-	size_t nc;
3841-	int last = lastline;
3842-	const char *state = NULL;
3843-
3844-	lastline = pos;
3845-	for (; pos > last; pos--) {
3846-		fseek(fp, f[pos - 1], SEEK_SET);
3847-		nc = f[pos] - f[pos - 1];
3848-		if (nc >= sizeof(buf))
3849-			nc = sizeof(buf) - 1;
3850-		nc = fread(buf, 1, nc, fp);
3851-		if (nc == 0)
3852-			continue;
3853-		buf[nc] = '\0';
3854-		buf[strcspn(buf, "\n")] = '\0';
3855-		if (most_recent_pat != NULL) {
3856-			int ret = regexec(&most_recent_re, buf, 0, NULL, 0);
3857-			if (ret != 0)
3858-				continue;
3859-			strlcpy(lastbuf, buf, sizeof(lastbuf));
3860-			lastmatchline = pos;
3861-			return lastbuf;
3862-		} else if (isalpha(buf[0]) || buf[0] == '_' || buf[0] == '$' || buf[0] == '-' || buf[0] == '+') {
3863-			if (begins_with(buf, "private:")) {
3864-				if (!state)
3865-					state = " (private)";
3866-			} else if (begins_with(buf, "protected:")) {
3867-				if (!state)
3868-					state = " (protected)";
3869-			} else if (begins_with(buf, "public:")) {
3870-				if (!state)
3871-					state = " (public)";
3872-			} else {
3873-				strlcpy(lastbuf, buf, sizeof(lastbuf));
3874-				if (state)
3875-					strlcat(lastbuf, state, sizeof(lastbuf));
3876-				lastmatchline = pos;
3877-				return lastbuf;
3878-			}
3879-		}
3880-	}
3881-	return lastmatchline > 0 ? lastbuf : NULL;
3882+        char buf[FUNCTION_CONTEXT_SIZE];
3883+        size_t nc;
3884+        int last = lastline;
3885+        const char *state = NULL;
3886+
3887+        lastline = pos;
3888+        for (; pos > last; pos--) {
3889+                fseek(fp, f[pos - 1], SEEK_SET);
3890+                nc = f[pos] - f[pos - 1];
3891+                if (nc >= sizeof(buf))
3892+                        nc = sizeof(buf) - 1;
3893+                nc = fread(buf, 1, nc, fp);
3894+                if (nc == 0)
3895+                        continue;
3896+                buf[nc] = '\0';
3897+                buf[strcspn(buf, "\n")] = '\0';
3898+                if (most_recent_pat != NULL) {
3899+                        int ret = regexec(&most_recent_re, buf, 0, NULL, 0);
3900+                        if (ret != 0)
3901+                                continue;
3902+                        strlcpy(lastbuf, buf, sizeof(lastbuf));
3903+                        lastmatchline = pos;
3904+                        return lastbuf;
3905+                } else if (isalpha(buf[0]) || buf[0] == '_' || buf[0] == '$' || buf[0] == '-' || buf[0] == '+') {
3906+                        if (begins_with(buf, "private:")) {
3907+                                if (!state)
3908+                                        state = " (private)";
3909+                        } else if (begins_with(buf, "protected:")) {
3910+                                if (!state)
3911+                                        state = " (protected)";
3912+                        } else if (begins_with(buf, "public:")) {
3913+                                if (!state)
3914+                                        state = " (public)";
3915+                        } else {
3916+                                strlcpy(lastbuf, buf, sizeof(lastbuf));
3917+                                if (state)
3918+                                        strlcat(lastbuf, state, sizeof(lastbuf));
3919+                                lastmatchline = pos;
3920+                                return lastbuf;
3921+                        }
3922+                }
3923+        }
3924+        return lastmatchline > 0 ? lastbuf : NULL;
3925 }
3926 
3927 static void
3928 dump_context_vec(FILE *f1, FILE *f2, int flags)
3929 {
3930-	struct ContextVec *cvp = context_vec_start;
3931-	int lowa, upb, lowc, upd, do_output;
3932-	int a, b, c, d;
3933-	char ch, *f;
3934-
3935-	if (context_vec_start > context_vec_ptr)
3936-		return;
3937-
3938-	b = d = 0;
3939-	lowa = MAX(1, cvp->a - diff_context);
3940-	upb = MIN((int)len[0], context_vec_ptr->b + diff_context);
3941-	lowc = MAX(1, cvp->c - diff_context);
3942-	upd = MIN((int)len[1], context_vec_ptr->d + diff_context);
3943-
3944-	printf("***************");
3945-	if (flags & (D_PROTOTYPE | D_MATCHLAST)) {
3946-		f = match_function(ixold, cvp->a - 1, f1);
3947-		if (f != NULL)
3948-			printf(" %s", f);
3949-	}
3950-	printf("\n*** ");
3951-	range(lowa, upb, ",");
3952-	printf(" ****\n");
3953-
3954-	do_output = 0;
3955-	for (; cvp <= context_vec_ptr; cvp++)
3956-		if (cvp->a <= cvp->b) {
3957-			cvp = context_vec_start;
3958-			do_output++;
3959-			break;
3960-		}
3961-	if (do_output) {
3962-		while (cvp <= context_vec_ptr) {
3963-			a = cvp->a;
3964-			b = cvp->b;
3965-			c = cvp->c;
3966-			d = cvp->d;
3967-
3968-			if (a <= b && c <= d)
3969-				ch = 'c';
3970-			else
3971-				ch = (a <= b) ? 'd' : 'a';
3972-
3973-			if (ch == 'a')
3974-				fetch(ixold, lowa, b, f1, ' ', 0, flags);
3975-			else {
3976-				fetch(ixold, lowa, a - 1, f1, ' ', 0, flags);
3977-				fetch(ixold, a, b, f1, ch == 'c' ? '!' : '-', 0, flags);
3978-			}
3979-			lowa = b + 1;
3980-			cvp++;
3981-		}
3982-		fetch(ixold, b + 1, upb, f1, ' ', 0, flags);
3983-	}
3984-
3985-	printf("--- ");
3986-	range(lowc, upd, ",");
3987-	printf(" ----\n");
3988-
3989-	do_output = 0;
3990-	for (cvp = context_vec_start; cvp <= context_vec_ptr; cvp++)
3991-		if (cvp->c <= cvp->d) {
3992-			cvp = context_vec_start;
3993-			do_output++;
3994-			break;
3995-		}
3996-	if (do_output) {
3997-		while (cvp <= context_vec_ptr) {
3998-			a = cvp->a;
3999-			b = cvp->b;
4000-			c = cvp->c;
4001-			d = cvp->d;
4002-
4003-			if (a <= b && c <= d)
4004-				ch = 'c';
4005-			else
4006-				ch = (a <= b) ? 'd' : 'a';
4007-
4008-			if (ch == 'd')
4009-				fetch(ixnew, lowc, d, f2, ' ', 0, flags);
4010-			else {
4011-				fetch(ixnew, lowc, c - 1, f2, ' ', 0, flags);
4012-				fetch(ixnew, c, d, f2, ch == 'c' ? '!' : '+', 0, flags);
4013-			}
4014-			lowc = d + 1;
4015-			cvp++;
4016-		}
4017-		fetch(ixnew, d + 1, upd, f2, ' ', 0, flags);
4018-	}
4019-	context_vec_ptr = context_vec_start - 1;
4020+        struct ContextVec *cvp = context_vec_start;
4021+        int lowa, upb, lowc, upd, do_output;
4022+        int a, b, c, d;
4023+        char ch, *f;
4024+
4025+        if (context_vec_start > context_vec_ptr)
4026+                return;
4027+
4028+        b = d = 0;
4029+        lowa = MAX(1, cvp->a - diff_context);
4030+        upb = MIN((int)len[0], context_vec_ptr->b + diff_context);
4031+        lowc = MAX(1, cvp->c - diff_context);
4032+        upd = MIN((int)len[1], context_vec_ptr->d + diff_context);
4033+
4034+        printf("***************");
4035+        if (flags & (D_PROTOTYPE | D_MATCHLAST)) {
4036+                f = match_function(ixold, cvp->a - 1, f1);
4037+                if (f != NULL)
4038+                        printf(" %s", f);
4039+        }
4040+        printf("\n*** ");
4041+        range(lowa, upb, ",");
4042+        printf(" ****\n");
4043+
4044+        do_output = 0;
4045+        for (; cvp <= context_vec_ptr; cvp++)
4046+                if (cvp->a <= cvp->b) {
4047+                        cvp = context_vec_start;
4048+                        do_output++;
4049+                        break;
4050+                }
4051+        if (do_output) {
4052+                while (cvp <= context_vec_ptr) {
4053+                        a = cvp->a;
4054+                        b = cvp->b;
4055+                        c = cvp->c;
4056+                        d = cvp->d;
4057+
4058+                        if (a <= b && c <= d)
4059+                                ch = 'c';
4060+                        else
4061+                                ch = (a <= b) ? 'd' : 'a';
4062+
4063+                        if (ch == 'a')
4064+                                fetch(ixold, lowa, b, f1, ' ', 0, flags);
4065+                        else {
4066+                                fetch(ixold, lowa, a - 1, f1, ' ', 0, flags);
4067+                                fetch(ixold, a, b, f1, ch == 'c' ? '!' : '-', 0, flags);
4068+                        }
4069+                        lowa = b + 1;
4070+                        cvp++;
4071+                }
4072+                fetch(ixold, b + 1, upb, f1, ' ', 0, flags);
4073+        }
4074+
4075+        printf("--- ");
4076+        range(lowc, upd, ",");
4077+        printf(" ----\n");
4078+
4079+        do_output = 0;
4080+        for (cvp = context_vec_start; cvp <= context_vec_ptr; cvp++)
4081+                if (cvp->c <= cvp->d) {
4082+                        cvp = context_vec_start;
4083+                        do_output++;
4084+                        break;
4085+                }
4086+        if (do_output) {
4087+                while (cvp <= context_vec_ptr) {
4088+                        a = cvp->a;
4089+                        b = cvp->b;
4090+                        c = cvp->c;
4091+                        d = cvp->d;
4092+
4093+                        if (a <= b && c <= d)
4094+                                ch = 'c';
4095+                        else
4096+                                ch = (a <= b) ? 'd' : 'a';
4097+
4098+                        if (ch == 'd')
4099+                                fetch(ixnew, lowc, d, f2, ' ', 0, flags);
4100+                        else {
4101+                                fetch(ixnew, lowc, c - 1, f2, ' ', 0, flags);
4102+                                fetch(ixnew, c, d, f2, ch == 'c' ? '!' : '+', 0, flags);
4103+                        }
4104+                        lowc = d + 1;
4105+                        cvp++;
4106+                }
4107+                fetch(ixnew, d + 1, upd, f2, ' ', 0, flags);
4108+        }
4109+        context_vec_ptr = context_vec_start - 1;
4110 }
4111 
4112 static void
4113 dump_unified_vec(FILE *f1, FILE *f2, int flags)
4114 {
4115-	struct ContextVec *cvp = context_vec_start;
4116-	int lowa, upb, lowc, upd;
4117-	int a, b, c, d;
4118-	char ch, *f;
4119-
4120-	if (context_vec_start > context_vec_ptr)
4121-		return;
4122-
4123-	b = d = 0;
4124-	lowa = MAX(1, cvp->a - diff_context);
4125-	upb = MIN((int)len[0], context_vec_ptr->b + diff_context);
4126-	lowc = MAX(1, cvp->c - diff_context);
4127-	upd = MIN((int)len[1], context_vec_ptr->d + diff_context);
4128-
4129-	printf("@@ -");
4130-	uni_range(lowa, upb);
4131-	printf(" +");
4132-	uni_range(lowc, upd);
4133-	printf(" @@");
4134-	if (flags & (D_PROTOTYPE | D_MATCHLAST)) {
4135-		f = match_function(ixold, cvp->a - 1, f1);
4136-		if (f != NULL)
4137-			printf(" %s", f);
4138-	}
4139-	printf("\n");
4140-
4141-	for (; cvp <= context_vec_ptr; cvp++) {
4142-		a = cvp->a;
4143-		b = cvp->b;
4144-		c = cvp->c;
4145-		d = cvp->d;
4146-
4147-		if (a <= b && c <= d)
4148-			ch = 'c';
4149-		else
4150-			ch = (a <= b) ? 'd' : 'a';
4151-
4152-		switch (ch) {
4153-		case 'c':
4154-			fetch(ixold, lowa, a - 1, f1, ' ', 0, flags);
4155-			fetch(ixold, a, b, f1, '-', 0, flags);
4156-			fetch(ixnew, c, d, f2, '+', 0, flags);
4157-			break;
4158-		case 'd':
4159-			fetch(ixold, lowa, a - 1, f1, ' ', 0, flags);
4160-			fetch(ixold, a, b, f1, '-', 0, flags);
4161-			break;
4162-		case 'a':
4163-			fetch(ixnew, lowc, c - 1, f2, ' ', 0, flags);
4164-			fetch(ixnew, c, d, f2, '+', 0, flags);
4165-			break;
4166-		}
4167-		lowa = b + 1;
4168-		lowc = d + 1;
4169-	}
4170-	fetch(ixnew, d + 1, upd, f2, ' ', 0, flags);
4171-	context_vec_ptr = context_vec_start - 1;
4172+        struct ContextVec *cvp = context_vec_start;
4173+        int lowa, upb, lowc, upd;
4174+        int a, b, c, d;
4175+        char ch, *f;
4176+
4177+        if (context_vec_start > context_vec_ptr)
4178+                return;
4179+
4180+        b = d = 0;
4181+        lowa = MAX(1, cvp->a - diff_context);
4182+        upb = MIN((int)len[0], context_vec_ptr->b + diff_context);
4183+        lowc = MAX(1, cvp->c - diff_context);
4184+        upd = MIN((int)len[1], context_vec_ptr->d + diff_context);
4185+
4186+        printf("@@ -");
4187+        uni_range(lowa, upb);
4188+        printf(" +");
4189+        uni_range(lowc, upd);
4190+        printf(" @@");
4191+        if (flags & (D_PROTOTYPE | D_MATCHLAST)) {
4192+                f = match_function(ixold, cvp->a - 1, f1);
4193+                if (f != NULL)
4194+                        printf(" %s", f);
4195+        }
4196+        printf("\n");
4197+
4198+        for (; cvp <= context_vec_ptr; cvp++) {
4199+                a = cvp->a;
4200+                b = cvp->b;
4201+                c = cvp->c;
4202+                d = cvp->d;
4203+
4204+                if (a <= b && c <= d)
4205+                        ch = 'c';
4206+                else
4207+                        ch = (a <= b) ? 'd' : 'a';
4208+
4209+                switch (ch) {
4210+                case 'c':
4211+                        fetch(ixold, lowa, a - 1, f1, ' ', 0, flags);
4212+                        fetch(ixold, a, b, f1, '-', 0, flags);
4213+                        fetch(ixnew, c, d, f2, '+', 0, flags);
4214+                        break;
4215+                case 'd':
4216+                        fetch(ixold, lowa, a - 1, f1, ' ', 0, flags);
4217+                        fetch(ixold, a, b, f1, '-', 0, flags);
4218+                        break;
4219+                case 'a':
4220+                        fetch(ixnew, lowc, c - 1, f2, ' ', 0, flags);
4221+                        fetch(ixnew, c, d, f2, '+', 0, flags);
4222+                        break;
4223+                }
4224+                lowa = b + 1;
4225+                lowc = d + 1;
4226+        }
4227+        fetch(ixnew, d + 1, upd, f2, ' ', 0, flags);
4228+        context_vec_ptr = context_vec_start - 1;
4229 }
4230 
4231 static void
4232 print_header(const char *file1, const char *file2)
4233 {
4234-	const char *time_format;
4235-	char buf[256];
4236-	struct tm tm1, tm2, *tm_ptr1, *tm_ptr2;
4237-	int nsec1 = stb1.st_mtim.tv_nsec;
4238-	int nsec2 = stb2.st_mtim.tv_nsec;
4239-
4240-	time_format = "%Y-%m-%d %H:%M:%S";
4241-	if (cflag)
4242-		time_format = "%c";
4243-	tm_ptr1 = localtime_r(&stb1.st_mtime, &tm1);
4244-	tm_ptr2 = localtime_r(&stb2.st_mtime, &tm2);
4245-	if (label[0] != NULL)
4246-		printf("%s %s\n", diff_format == D_CONTEXT ? "***" : "---", label[0]);
4247-	else {
4248-		strftime(buf, sizeof(buf), time_format, tm_ptr1);
4249-		printf("%s %s\t%s", diff_format == D_CONTEXT ? "***" : "---", file1, buf);
4250-		if (!cflag) {
4251-			strftime(buf, sizeof(buf), "%z", tm_ptr1);
4252-			printf(".%.9d %s", nsec1, buf);
4253-		}
4254-		printf("\n");
4255-	}
4256-	if (label[1] != NULL)
4257-		printf("%s %s\n", diff_format == D_CONTEXT ? "---" : "+++", label[1]);
4258-	else {
4259-		strftime(buf, sizeof(buf), time_format, tm_ptr2);
4260-		printf("%s %s\t%s", diff_format == D_CONTEXT ? "---" : "+++", file2, buf);
4261-		if (!cflag) {
4262-			strftime(buf, sizeof(buf), "%z", tm_ptr2);
4263-			printf(".%.9d %s", nsec2, buf);
4264-		}
4265-		printf("\n");
4266-	}
4267+        const char *time_format;
4268+        char buf[256];
4269+        struct tm tm1, tm2, *tm_ptr1, *tm_ptr2;
4270+        int nsec1 = stb1.st_mtim.tv_nsec;
4271+        int nsec2 = stb2.st_mtim.tv_nsec;
4272+
4273+        time_format = "%Y-%m-%d %H:%M:%S";
4274+        if (cflag)
4275+                time_format = "%c";
4276+        tm_ptr1 = localtime_r(&stb1.st_mtime, &tm1);
4277+        tm_ptr2 = localtime_r(&stb2.st_mtime, &tm2);
4278+        if (label[0] != NULL)
4279+                printf("%s %s\n", diff_format == D_CONTEXT ? "***" : "---", label[0]);
4280+        else {
4281+                strftime(buf, sizeof(buf), time_format, tm_ptr1);
4282+                printf("%s %s\t%s", diff_format == D_CONTEXT ? "***" : "---", file1, buf);
4283+                if (!cflag) {
4284+                        strftime(buf, sizeof(buf), "%z", tm_ptr1);
4285+                        printf(".%.9d %s", nsec1, buf);
4286+                }
4287+                printf("\n");
4288+        }
4289+        if (label[1] != NULL)
4290+                printf("%s %s\n", diff_format == D_CONTEXT ? "---" : "+++", label[1]);
4291+        else {
4292+                strftime(buf, sizeof(buf), time_format, tm_ptr2);
4293+                printf("%s %s\t%s", diff_format == D_CONTEXT ? "---" : "+++", file2, buf);
4294+                if (!cflag) {
4295+                        strftime(buf, sizeof(buf), "%z", tm_ptr2);
4296+                        printf(".%.9d %s", nsec2, buf);
4297+                }
4298+                printf("\n");
4299+        }
4300 }
4301 
4302 static void
4303 print_space(int nc, int n, int flags)
4304 {
4305-	int col, newcol, tabstop;
4306-
4307-	col = nc;
4308-	newcol = nc + n;
4309-	if ((flags & D_EXPANDTABS) == 0) {
4310-		while ((tabstop = roundup(col + 1, tabsize)) <= newcol) {
4311-			printf("\t");
4312-			col = tabstop;
4313-		}
4314-	}
4315-	printf("%*s", newcol - col, "");
4316+        int col, newcol, tabstop;
4317+
4318+        col = nc;
4319+        newcol = nc + n;
4320+        if ((flags & D_EXPANDTABS) == 0) {
4321+                while ((tabstop = roundup(col + 1, tabsize)) <= newcol) {
4322+                        printf("\t");
4323+                        col = tabstop;
4324+                }
4325+        }
4326+        printf("%*s", newcol - col, "");
4327 }
+446, -838
   1@@ -1,894 +1,502 @@
   2 /* See LICENSE file for copyright and license details. */
   3+#include "config.h"
   4+#include "diffutil.h"
   5 #include "util.h"
   6 
   7-#include <sys/types.h>
   8-#include <sys/wait.h>
   9-
  10 #include <ctype.h>
  11-#include <err.h>
  12-#include <errno.h>
  13-#include <fcntl.h>
  14-#include <stdarg.h>
  15-#include <getopt.h>
  16-#include <inttypes.h>
  17-#include <limits.h>
  18-#include <poll.h>
  19 #include <stdio.h>
  20 #include <stdlib.h>
  21 #include <string.h>
  22 #include <unistd.h>
  23 
  24-struct Range {
  25-	int from;
  26-	int to;
  27+struct region {
  28+        size_t from;
  29+        size_t to;
  30 };
  31 
  32-struct Diff {
  33-#define DIFF_TYPE1 1
  34-#define DIFF_TYPE2 2
  35-#define DIFF_TYPE3 3
  36-	int type;
  37-
  38-	struct Range old;
  39-	struct Range new;
  40+struct pair_hunk {
  41+        struct region old;
  42+        struct region new;
  43 };
  44 
  45-#define EFLAG_NONE     0
  46-#define EFLAG_OVERLAP  1
  47-#define EFLAG_NOOVERLAP 2
  48-#define EFLAG_UNMERGED 3
  49-
  50-static size_t szchanges;
  51-
  52-static struct Diff *d13;
  53-static struct Diff *d23;
  54-static struct Diff *de;
  55-static char *overlap;
  56-static int overlapcnt;
  57-static FILE *fp[3];
  58-static int cline[3];
  59-static int sigpipe[2];
  60-static int last[4];
  61-static int Aflag, eflag, iflag, mflag, Tflag;
  62-static int oflag;
  63-static int strip_cr;
  64-static char *f1mark, *f2mark, *f3mark;
  65-static const char *oldmark = "<<<<<<<";
  66-static const char *orgmark = "|||||||";
  67-static const char *newmark = ">>>>>>>";
  68-static const char *divider = "=======";
  69-
  70-static int duplicate(struct Range *, struct Range *);
  71-static int edit(struct Diff *, int, int, int);
  72-static char *getchange(FILE *);
  73-static char *get_line(FILE *, size_t *);
  74-static int readin(int, struct Diff **);
  75-static int skip(int, int, const char *);
  76-static void change(int, struct Range *, int);
  77-static void keep(int, struct Range *);
  78-static void merge(int, int);
  79-static void prange(struct Range *, int);
  80-static void repos(int);
  81-static void separate(const char *);
  82-static void edscript(int);
  83-static void Ascript(int);
  84-static void mergescript(int);
  85-static void increase(void);
  86-static void usage(void);
  87-static void printrange(FILE *, struct Range *);
  88-static void diffexec(const char *, char **, int *);
  89-static int strtoi(char *, char **);
  90-static void handle_sig(int);
  91-static void xasprintf(char **, const char *, ...);
  92-
  93-static const char diff3_version[] = "FreeBSD diff3 20240925";
  94-
  95-enum {
  96-	DIFFPROG_OPT,
  97-	STRIPCR_OPT,
  98-	HELP_OPT,
  99-	VERSION_OPT
 100+enum hunk_kind {
 101+        HUNK_NONE,
 102+        HUNK_TYPE1,
 103+        HUNK_TYPE2,
 104+        HUNK_TYPE3,
 105 };
 106 
 107-#define DIFF_PATH "/usr/bin/diff"
 108-
 109-#define OPTIONS "3aAeEiL:mTxX"
 110-static struct option longopts[] = {
 111-	{ "ed",                 no_argument,            NULL,   'e' },
 112-	{ "show-overlap",       no_argument,            NULL,   'E' },
 113-	{ "overlap-only",       no_argument,            NULL,   'x' },
 114-	{ "initial-tab",        no_argument,            NULL,   'T' },
 115-	{ "text",               no_argument,            NULL,   'a' },
 116-	{ "strip-trailing-cr",  no_argument,            NULL,   STRIPCR_OPT },
 117-	{ "show-all",           no_argument,            NULL,   'A' },
 118-	{ "easy-only",          no_argument,            NULL,   '3' },
 119-	{ "merge",              no_argument,            NULL,   'm' },
 120-	{ "label",              required_argument,      NULL,   'L' },
 121-	{ "diff-program",       required_argument,      NULL,   DIFFPROG_OPT },
 122-	{ "help",               no_argument,            NULL,   HELP_OPT},
 123-	{ "version",            no_argument,            NULL,   VERSION_OPT}
 124+struct three_hunk {
 125+        enum hunk_kind kind;
 126+        struct region r1;
 127+        struct region r2;
 128+        struct region r3;
 129+        int dup;
 130 };
 131 
 132-static void
 133-usage(void)
 134-{
 135-	fprintf(stderr, "usage: diff3 [-3aAeEimTxX] [-L label1] [-L label2] "
 136-	    "[-L label3] file1 file2 file3\n");
 137-}
 138-
 139-static int
 140-strtoi(char *str, char **end)
 141-{
 142-	intmax_t num;
 143-
 144-	errno = 0;
 145-	num = strtoimax(str, end, 10);
 146-	if ((end != NULL && *end == str) ||
 147-	    num < 0 || num > INT_MAX ||
 148-	    errno == EINVAL || errno == ERANGE)
 149-		err(1, "error in diff output");
 150-	return (int)num;
 151-}
 152-
 153-static int
 154-readin(int fd, struct Diff **dd)
 155-{
 156-	int a, b, c, d;
 157-	int i;
 158-	char kind, *p;
 159-	FILE *f;
 160-
 161-	f = fdopen(fd, "r");
 162-	if (f == NULL)
 163-		err(2, "fdopen");
 164-	for (i = 0; (p = getchange(f)) != NULL; i++) {
 165-		if ((size_t)i >= szchanges - 1)
 166-			increase();
 167-
 168-		a = b = strtoi(p, &p);
 169-		if (*p == ',')
 170-			b = strtoi(p + 1, &p);
 171-		kind = *p++;
 172-		c = d = strtoi(p, &p);
 173-		if (*p == ',')
 174-			d = strtoi(p + 1, &p);
 175-		if (*p != '\n')
 176-			errx(1, "error in diff output");
 177-		if (kind == 'a')
 178-			a++;
 179-		else if (kind == 'c')
 180-			/* nothing */ ;
 181-		else if (kind == 'd')
 182-			c++;
 183-		else
 184-			errx(1, "error in diff output");
 185-		b++;
 186-		d++;
 187-		if (b < a || d < c)
 188-			errx(1, "error in diff output");
 189-		(*dd)[i].old.from = a;
 190-		(*dd)[i].old.to = b;
 191-		(*dd)[i].new.from = c;
 192-		(*dd)[i].new.to = d;
 193-		if (i > 0) {
 194-			if ((*dd)[i].old.from < (*dd)[i - 1].old.to ||
 195-			    (*dd)[i].new.from < (*dd)[i - 1].new.to)
 196-				errx(1, "diff output out of order");
 197-		}
 198-	}
 199-	if (i > 0) {
 200-		(*dd)[i].old.from = (*dd)[i].old.to = (*dd)[i - 1].old.to;
 201-		(*dd)[i].new.from = (*dd)[i].new.to = (*dd)[i - 1].new.to;
 202-	}
 203-	fclose(f);
 204-	return i;
 205-}
 206+static int aflag;
 207+static int Tflag;
 208+static int eflag;
 209+static int Eflag;
 210+static int xflag;
 211+static int Xflag;
 212+static int Aflag;
 213+static int mflag;
 214+static int iflag;
 215+static int strip_cr;
 216+static char *labels[3];
 217+static int nlabels;
 218 
 219 static void
 220-diffexec(const char *diffprog, char **diffargv, int fd[])
 221-{
 222-	switch (fork()) {
 223-	case 0:
 224-		close(fd[0]);
 225-		if (dup2(fd[1], STDOUT_FILENO) == -1)
 226-			err(2, "child could not duplicate descriptor");
 227-		close(fd[1]);
 228-		execvp(diffprog, diffargv);
 229-		err(2, "could not execute diff: %s", diffprog);
 230-		break;
 231-	case -1:
 232-		err(2, "could not fork");
 233-		break;
 234-	}
 235-	close(fd[1]);
 236-}
 237-
 238-static char *
 239-getchange(FILE *b)
 240-{
 241-	char *line;
 242-
 243-	while ((line = get_line(b, NULL)) != NULL) {
 244-		if (isdigit((unsigned char)line[0]))
 245-			return line;
 246-	}
 247-	return NULL;
 248-}
 249-
 250-static char *
 251-get_line(FILE *b, size_t *n)
 252+usage(void)
 253 {
 254-	ssize_t len;
 255-	static char *buf = NULL;
 256-	static size_t bufsize = 0;
 257-
 258-	if ((len = getline(&buf, &bufsize, b)) < 0)
 259-		return NULL;
 260-
 261-	if (strip_cr && len >= 2 && strcmp("\r\n", &(buf[len - 2])) == 0) {
 262-		buf[len - 2] = '\n';
 263-		buf[len - 1] = '\0';
 264-		len--;
 265-	}
 266-
 267-	if (n != NULL)
 268-		*n = len;
 269-
 270-	return buf;
 271+        eprintf("usage: %s [-3aAeEimTxX] [-L label] file1 file2 file3\n", argv0);
 272 }
 273 
 274 static void
 275-merge(int m1, int m2)
 276+convert_hunks(const struct diffhunks *in, struct pair_hunk **out, size_t *outn)
 277 {
 278-	struct Diff *d1, *d2, *d3;
 279-	int j, t1, t2;
 280-	int dup = 0;
 281-
 282-	d1 = d13;
 283-	d2 = d23;
 284-	j = 0;
 285-
 286-	for (;;) {
 287-		t1 = (d1 < d13 + m1);
 288-		t2 = (d2 < d23 + m2);
 289-		if (!t1 && !t2)
 290-			break;
 291-
 292-		if (!t2 || (t1 && d1->new.to < d2->new.from)) {
 293-			if (eflag == EFLAG_NONE) {
 294-				separate("1");
 295-				change(1, &d1->old, 0);
 296-				keep(2, &d1->new);
 297-				change(3, &d1->new, 0);
 298-			} else if (eflag == EFLAG_OVERLAP) {
 299-				j = edit(d2, dup, j, DIFF_TYPE1);
 300-			}
 301-			d1++;
 302-			continue;
 303-		}
 304-		if (!t1 || (t2 && d2->new.to < d1->new.from)) {
 305-			if (eflag == EFLAG_NONE) {
 306-				separate("2");
 307-				keep(1, &d2->new);
 308-				change(3, &d2->new, 0);
 309-				change(2, &d2->old, 0);
 310-			} else if (Aflag || mflag) {
 311-				if (eflag == EFLAG_UNMERGED)
 312-					j = edit(d2, dup, j, DIFF_TYPE2);
 313-			}
 314-			d2++;
 315-			continue;
 316-		}
 317-		if (d1 + 1 < d13 + m1 && d1->new.to >= d1[1].new.from) {
 318-			d1[1].old.from = d1->old.from;
 319-			d1[1].new.from = d1->new.from;
 320-			d1++;
 321-			continue;
 322-		}
 323-		if (d2 + 1 < d23 + m2 && d2->new.to >= d2[1].new.from) {
 324-			d2[1].old.from = d2->old.from;
 325-			d2[1].new.from = d2->new.from;
 326-			d2++;
 327-			continue;
 328-		}
 329-		if (d1->new.from == d2->new.from && d1->new.to == d2->new.to) {
 330-			dup = duplicate(&d1->old, &d2->old);
 331-			if (eflag == EFLAG_NONE) {
 332-				separate(dup ? "3" : "");
 333-				change(1, &d1->old, dup);
 334-				change(2, &d2->old, 0);
 335-				d3 = d1->old.to > d1->old.from ? d1 : d2;
 336-				change(3, &d3->new, 0);
 337-			} else {
 338-				j = edit(d1, dup, j, DIFF_TYPE3);
 339-			}
 340-			dup = 0;
 341-			d1++;
 342-			d2++;
 343-			continue;
 344-		}
 345-		if (d1->new.from < d2->new.from) {
 346-			d2->old.from -= d2->new.from - d1->new.from;
 347-			d2->new.from = d1->new.from;
 348-		} else if (d2->new.from < d1->new.from) {
 349-			d1->old.from -= d1->new.from - d2->new.from;
 350-			d1->new.from = d2->new.from;
 351-		}
 352-		if (d1->new.to > d2->new.to) {
 353-			d2->old.to += d1->new.to - d2->new.to;
 354-			d2->new.to = d1->new.to;
 355-		} else if (d2->new.to > d1->new.to) {
 356-			d1->old.to += d2->new.to - d1->new.to;
 357-			d1->new.to = d2->new.to;
 358-		}
 359-	}
 360-
 361-	if (mflag)
 362-		mergescript(j);
 363-	else if (Aflag)
 364-		Ascript(j);
 365-	else if (eflag)
 366-		edscript(j);
 367+        size_t i;
 368+        struct pair_hunk *p;
 369+
 370+        p = ecalloc(in->n + 1, sizeof(*p));
 371+        for (i = 0; i < in->n; i++) {
 372+                p[i].old.from = in->v[i].old.from;
 373+                p[i].old.to = in->v[i].old.to;
 374+                p[i].new.from = in->v[i].new.from;
 375+                p[i].new.to = in->v[i].new.to;
 376+        }
 377+        *out = p;
 378+        *outn = in->n;
 379 }
 380 
 381-static void
 382-separate(const char *s)
 383+static int
 384+region_same(const struct difffile *a, struct region *ra,
 385+            const struct difffile *b, struct region *rb)
 386 {
 387-	printf("====%s\n", s);
 388+        size_t i;
 389+        if (ra->to - ra->from != rb->to - rb->from)
 390+                return 0;
 391+        for (i = 0; i < ra->to - ra->from; i++) {
 392+                if (a->lines[ra->from + i].len != b->lines[rb->from + i].len)
 393+                        return 0;
 394+                if (memcmp(a->lines[ra->from + i].data,
 395+                           b->lines[rb->from + i].data,
 396+                           a->lines[ra->from + i].len) != 0)
 397+                        return 0;
 398+        }
 399+        return 1;
 400 }
 401 
 402-static void
 403-change(int i, struct Range *rold, int dup)
 404+static int
 405+merge_hunks(const struct difffile *f1, const struct difffile *f2,
 406+            const struct difffile *f3,
 407+            const struct pair_hunk *d13, size_t n13,
 408+            const struct pair_hunk *d23, size_t n23,
 409+            struct three_hunk **out, size_t *outn)
 410 {
 411-	printf("%d:", i);
 412-	last[i] = rold->to;
 413-	prange(rold, 0);
 414-	if (dup)
 415-		return;
 416-	i--;
 417-	skip(i, rold->from, NULL);
 418-	skip(i, rold->to, "  ");
 419+        struct three_hunk *hs;
 420+        size_t i, j, k, cap;
 421+        int have1, have2;
 422+        size_t a1, a2, b1, b2;
 423+
 424+        cap = n13 + n23 + 4;
 425+        hs = ecalloc(cap, sizeof(*hs));
 426+        k = 0;
 427+        i = j = 0;
 428+
 429+        while (i < n13 || j < n23) {
 430+                have1 = i < n13;
 431+                have2 = j < n23;
 432+                a1 = have1 ? d13[i].new.from : 0;
 433+                a2 = have1 ? d13[i].new.to : 0;
 434+                b1 = have2 ? d23[j].old.from : 0;
 435+                b2 = have2 ? d23[j].old.to : 0;
 436+
 437+                if (have1 && (!have2 || a2 <= b1)) {
 438+                        if (k + 1 >= cap) {
 439+                                cap *= 2;
 440+                                hs = erealloc(hs, cap * sizeof(*hs));
 441+                        }
 442+                        hs[k].kind = HUNK_TYPE1;
 443+                        hs[k].r1.from = d13[i].old.from;
 444+                        hs[k].r1.to = d13[i].old.to;
 445+                        hs[k].r2.from = d13[i].new.from;
 446+                        hs[k].r2.to = d13[i].new.to;
 447+                        hs[k].r3.from = d13[i].new.from;
 448+                        hs[k].r3.to = d13[i].new.to;
 449+                        hs[k].dup = 0;
 450+                        k++;
 451+                        i++;
 452+                        continue;
 453+                }
 454+                if (have2 && (!have1 || b2 < a1)) {
 455+                        if (k + 1 >= cap) {
 456+                                cap *= 2;
 457+                                hs = erealloc(hs, cap * sizeof(*hs));
 458+                        }
 459+                        hs[k].kind = HUNK_TYPE2;
 460+                        hs[k].r1.from = d23[j].old.from;
 461+                        hs[k].r1.to = d23[j].old.to;
 462+                        hs[k].r2.from = d23[j].old.from;
 463+                        hs[k].r2.to = d23[j].old.to;
 464+                        hs[k].r3.from = d23[j].new.from;
 465+                        hs[k].r3.to = d23[j].new.to;
 466+                        hs[k].dup = 0;
 467+                        k++;
 468+                        j++;
 469+                        continue;
 470+                }
 471+                {
 472+                        struct region r2;
 473+                        size_t extra_pre, extra_post;
 474+
 475+                        r2.from = a1 < b1 ? a1 : b1;
 476+                        r2.to = a2 > b2 ? a2 : b2;
 477+                        extra_pre = (a1 > b1) ? (a1 - b1) : (b1 - a1);
 478+                        extra_post = (a2 > b2) ? (a2 - b2) : (b2 - a2);
 479+                        if (k + 1 >= cap) {
 480+                                cap *= 2;
 481+                                hs = erealloc(hs, cap * sizeof(*hs));
 482+                        }
 483+                        hs[k].kind = HUNK_TYPE3;
 484+                        hs[k].r2 = r2;
 485+                        if (a1 >= b1) {
 486+                                hs[k].r1.from = d13[i].old.from - extra_pre;
 487+                                hs[k].r1.to = d13[i].old.to + extra_post;
 488+                        } else {
 489+                                hs[k].r1.from = d13[i].old.from;
 490+                                hs[k].r1.to = d13[i].old.to + (extra_pre + extra_post);
 491+                        }
 492+                        if (b1 >= a1) {
 493+                                hs[k].r3.from = d23[j].new.from - extra_pre;
 494+                                hs[k].r3.to = d23[j].new.to + extra_post;
 495+                        } else {
 496+                                hs[k].r3.from = d23[j].new.from;
 497+                                hs[k].r3.to = d23[j].new.to + (extra_pre + extra_post);
 498+                        }
 499+                        hs[k].dup = region_same(f1, &hs[k].r1, f3, &hs[k].r3);
 500+                        k++;
 501+                        i++;
 502+                        j++;
 503+                }
 504+        }
 505+        *out = hs;
 506+        *outn = k;
 507+        (void)f1; (void)f2; (void)f3;
 508+        return 0;
 509 }
 510 
 511 static void
 512-prange(struct Range *rold, int delete)
 513+print_lines(const struct difffile *f, size_t from, size_t to)
 514 {
 515-	if (rold->to <= rold->from)
 516-		printf("%da\n", rold->from - 1);
 517-	else {
 518-		printf("%d", rold->from);
 519-		if (rold->to > rold->from + 1)
 520-			printf(",%d", rold->to - 1);
 521-		if (delete)
 522-			printf("d\n");
 523-		else
 524-			printf("c\n");
 525-	}
 526+        size_t i;
 527+        for (i = from; i < to; i++) {
 528+                fwrite(f->lines[i].data, 1, f->lines[i].len, stdout);
 529+                fputc('\n', stdout);
 530+        }
 531 }
 532 
 533 static void
 534-keep(int i, struct Range *rnew)
 535+print_range_cmd(FILE *out, size_t from, size_t to, char op)
 536 {
 537-	int delta;
 538-	struct Range trange;
 539-
 540-	delta = last[3] - last[i];
 541-	trange.from = rnew->from - delta;
 542-	trange.to = rnew->to - delta;
 543-	change(i, &trange, 1);
 544+        if (to <= from) {
 545+                fprintf(out, "%zua\n", from == 0 ? 0 : from);
 546+        } else {
 547+                fprintf(out, "%zu", from + 1);
 548+                if (to - from > 1)
 549+                        fprintf(out, ",%zu", to);
 550+                fprintf(out, "%c\n", op);
 551+        }
 552 }
 553 
 554 static int
 555-skip(int i, int from, const char *pr)
 556+format_normal(const struct three_hunk *hs, size_t n,
 557+              const struct difffile *f1, const struct difffile *f2,
 558+              const struct difffile *f3)
 559 {
 560-	size_t j, n;
 561-	char *line;
 562-
 563-	for (n = 0; cline[i] < from - 1; n += j) {
 564-		if ((line = get_line(fp[i], &j)) == NULL)
 565-			errx(EXIT_FAILURE, "logic error");
 566-		if (pr != NULL)
 567-			printf("%s%s", Tflag == 1 ? "\t" : pr, line);
 568-		cline[i]++;
 569-	}
 570-	return (int)n;
 571+        size_t i;
 572+        for (i = 0; i < n; i++) {
 573+                const struct three_hunk *h = &hs[i];
 574+                const char *tag = "";
 575+                if (h->kind == HUNK_TYPE1) tag = "1";
 576+                else if (h->kind == HUNK_TYPE2) tag = "2";
 577+                else if (h->kind == HUNK_TYPE3) tag = h->dup ? "3" : "";
 578+                printf("====%s\n", tag);
 579+                if (h->kind == HUNK_TYPE1) {
 580+                        printf("1:%zu", h->r1.from + 1);
 581+                        if (h->r1.to - h->r1.from > 1)
 582+                                printf(",%zu", h->r1.to);
 583+                        printf("a\n");
 584+                        printf("3:%zu", h->r3.from + 1);
 585+                        if (h->r3.to - h->r3.from > 1)
 586+                                printf(",%zu", h->r3.to);
 587+                        printf("a\n");
 588+                        print_lines(f1, h->r1.from, h->r1.to);
 589+                } else if (h->kind == HUNK_TYPE2) {
 590+                        printf("2:%zu", h->r2.from + 1);
 591+                        if (h->r2.to - h->r2.from > 1)
 592+                                printf(",%zu", h->r2.to);
 593+                        printf("a\n");
 594+                        printf("3:%zu", h->r3.from + 1);
 595+                        if (h->r3.to - h->r3.from > 1)
 596+                                printf(",%zu", h->r3.to);
 597+                        printf("a\n");
 598+                        print_lines(f3, h->r3.from, h->r3.to);
 599+                } else {
 600+                        printf("1:%zu", h->r1.from + 1);
 601+                        if (h->r1.to - h->r1.from > 1)
 602+                                printf(",%zu", h->r1.to);
 603+                        printf("c\n");
 604+                        printf("2:%zu", h->r2.from + 1);
 605+                        if (h->r2.to - h->r2.from > 1)
 606+                                printf(",%zu", h->r2.to);
 607+                        printf("c\n");
 608+                        printf("3:%zu", h->r3.from + 1);
 609+                        if (h->r3.to - h->r3.from > 1)
 610+                                printf(",%zu", h->r3.to);
 611+                        printf("c\n");
 612+                        print_lines(f1, h->r1.from, h->r1.to);
 613+                        print_lines(f3, h->r3.from, h->r3.to);
 614+                }
 615+        }
 616+        (void)f2;
 617+        return 0;
 618 }
 619 
 620 static int
 621-duplicate(struct Range *r1, struct Range *r2)
 622+format_ed(const struct three_hunk *hs, size_t n, int overlap_only,
 623+          int show_all, const struct difffile *f2, const struct difffile *f3)
 624 {
 625-	int c, d;
 626-	int nchar;
 627-	int nline;
 628-
 629-	if (r1->to-r1->from != r2->to-r2->from)
 630-		return 0;
 631-	skip(0, r1->from, NULL);
 632-	skip(1, r2->from, NULL);
 633-	nchar = 0;
 634-	for (nline = 0; nline < r1->to - r1->from; nline++) {
 635-		do {
 636-			c = getc(fp[0]);
 637-			d = getc(fp[1]);
 638-			if (c == -1 && d == -1)
 639-				break;
 640-			if (c == -1 || d == -1)
 641-				errx(EXIT_FAILURE, "logic error");
 642-			nchar++;
 643-			if (c != d) {
 644-				repos(nchar);
 645-				return 0;
 646-			}
 647-		} while (c != '\n');
 648-	}
 649-	repos(nchar);
 650-	return 1;
 651-}
 652-
 653-static void
 654-repos(int nchar)
 655-{
 656-	int i;
 657-
 658-	for (i = 0; i < 2; i++)
 659-		(void)fseek(fp[i], (long)-nchar, SEEK_CUR);
 660+        size_t i;
 661+        for (i = n; i > 0; i--) {
 662+                const struct three_hunk *h = &hs[i - 1];
 663+
 664+                if (h->kind == HUNK_TYPE1) {
 665+                        if (h->r1.to == h->r1.from) {
 666+                                print_range_cmd(stdout, h->r2.from, h->r2.from, 'a');
 667+                                print_lines(f2, h->r2.from, h->r2.from);
 668+                                printf(".\n");
 669+                        } else {
 670+                                print_range_cmd(stdout, h->r2.from, h->r2.to, 'c');
 671+                                print_lines(f2, h->r1.from, h->r1.to);
 672+                                printf(".\n");
 673+                        }
 674+                        continue;
 675+                }
 676+                if (h->kind == HUNK_TYPE2) {
 677+                        print_range_cmd(stdout, h->r2.from, h->r2.to, 'c');
 678+                        print_lines(f3, h->r3.from, h->r3.to);
 679+                        printf(".\n");
 680+                        continue;
 681+                }
 682+                if (h->dup) {
 683+                        print_range_cmd(stdout, h->r2.from, h->r2.to, 'c');
 684+                        print_lines(f2, h->r1.from, h->r1.to);
 685+                        printf(".\n");
 686+                        continue;
 687+                }
 688+                if (overlap_only)
 689+                        continue;
 690+                if (show_all) {
 691+                        print_range_cmd(stdout, h->r2.from, h->r2.to, 'c');
 692+                        print_lines(f3, h->r3.from, h->r3.to);
 693+                        printf(".\n");
 694+                }
 695+        }
 696+        return 0;
 697 }
 698 
 699+#if FEATURE_DIFF3_MERGE
 700 static int
 701-edit(struct Diff *diff, int dup, int j, int difftype)
 702-{
 703-	if (!(eflag == EFLAG_UNMERGED ||
 704-	    (!dup && eflag == EFLAG_OVERLAP) ||
 705-	    (dup && eflag == EFLAG_NOOVERLAP))) {
 706-		return j;
 707-	}
 708-	j++;
 709-	overlap[j] = !dup;
 710-	if (!dup)
 711-		overlapcnt++;
 712-
 713-	de[j].type = difftype;
 714-	de[j].old.from = diff->old.from;
 715-	de[j].old.to = diff->old.to;
 716-	de[j].new.from = diff->new.from;
 717-	de[j].new.to = diff->new.to;
 718-	return j;
 719-}
 720-
 721-static void
 722-printrange(FILE *p, struct Range *r)
 723-{
 724-	char *line = NULL;
 725-	size_t len = 0;
 726-	int i = 1;
 727-
 728-	if (r->from == r->to)
 729-		return;
 730-
 731-	if (r->from > r->to)
 732-		errx(EXIT_FAILURE, "invalid print range");
 733-
 734-	fseek(p, 0L, SEEK_SET);
 735-	while (getline(&line, &len, p) > 0) {
 736-		if (i >= r->from)
 737-			printf("%s", line);
 738-		if (++i > r->to - 1)
 739-			break;
 740-	}
 741-	free(line);
 742-}
 743-
 744-static void
 745-edscript(int n)
 746-{
 747-	int delete;
 748-	struct Range *new, *old;
 749-
 750-	for (; n > 0; n--) {
 751-		new = &de[n].new;
 752-		old = &de[n].old;
 753-
 754-		delete = (new->from == new->to);
 755-		if (de[n].type == DIFF_TYPE1) {
 756-			if (delete)
 757-				printf("%dd\n", new->from - 1);
 758-			else if (old->from == new->from && old->to == new->to) {
 759-				printf("%dc\n", old->from);
 760-				printrange(fp[2], old);
 761-				printf(".\n");
 762-			}
 763-			continue;
 764-		} else {
 765-			if (!oflag || !overlap[n]) {
 766-				prange(old, delete);
 767-			} else {
 768-				printf("%da\n", old->to - 1);
 769-				printf("%s\n", divider);
 770-			}
 771-			printrange(fp[2], new);
 772-			if (!oflag || !overlap[n]) {
 773-				if (!delete)
 774-					printf(".\n");
 775-			} else {
 776-				printf("%s %s\n.\n", newmark, f3mark);
 777-				printf("%da\n%s %s\n.\n", old->from - 1, oldmark, f1mark);
 778-			}
 779-		}
 780-	}
 781-	if (iflag)
 782-		printf("w\nq\n");
 783-
 784-	exit(eflag == EFLAG_NONE ? overlapcnt : 0);
 785-}
 786-
 787-static void
 788-Ascript(int n)
 789-{
 790-	int startmark;
 791-	int deletenew;
 792-	int deleteold;
 793-	struct Range *new, *old;
 794-
 795-	for (; n > 0; n--) {
 796-		new = &de[n].new;
 797-		old = &de[n].old;
 798-		deletenew = (new->from == new->to);
 799-		deleteold = (old->from == old->to);
 800-
 801-		if (de[n].type == DIFF_TYPE2) {
 802-			if (!oflag || !overlap[n]) {
 803-				prange(old, deletenew);
 804-				printrange(fp[2], new);
 805-			} else {
 806-				startmark = new->to - 1;
 807-				printf("%da\n", startmark);
 808-				printf("%s %s\n", newmark, f3mark);
 809-				printf(".\n");
 810-				printf("%da\n", startmark - (new->to - new->from));
 811-				printf("%s %s\n", oldmark, f2mark);
 812-				if (!deleteold)
 813-					printrange(fp[1], old);
 814-				printf("%s\n.\n", divider);
 815-			}
 816-		} else if (de[n].type == DIFF_TYPE3) {
 817-			startmark = old->to - 1;
 818-			if (!oflag || !overlap[n]) {
 819-				prange(old, deletenew);
 820-				printrange(fp[2], new);
 821-			} else {
 822-				printf("%da\n", startmark);
 823-				printf("%s %s\n", orgmark, f2mark);
 824-				if (deleteold) {
 825-					struct Range r;
 826-					r.from = old->from-1;
 827-					r.to = new->to;
 828-					printrange(fp[1], &r);
 829-				} else
 830-					printrange(fp[1], old);
 831-				printf("%s\n", divider);
 832-				printrange(fp[2], new);
 833-			}
 834-			if (!oflag || !overlap[n]) {
 835-				if (!deletenew)
 836-					printf(".\n");
 837-			} else {
 838-				printf("%s %s\n.\n", newmark, f3mark);
 839-				printf("%da\n%s %s\n.\n", startmark - (old->to - old->from), oldmark, f1mark);
 840-			}
 841-		}
 842-	}
 843-	if (iflag)
 844-		printf("w\nq\n");
 845-
 846-	exit(overlapcnt > 0);
 847-}
 848-
 849-static void
 850-mergescript(int i)
 851-{
 852-	struct Range r, *new, *old;
 853-	int n;
 854-	int delete = 0;
 855-
 856-	r.from = 1;
 857-	r.to = 1;
 858-
 859-	for (n = 1; n <= i; n++) {
 860-		new = &de[n].new;
 861-		old = &de[n].old;
 862-
 863-		delete = (new->from == new->to);
 864-		if (de[n].type == DIFF_TYPE1 && delete)
 865-			r.to = new->from - 1;
 866-		else if (de[n].type == DIFF_TYPE3 && (old->from == old->to)) {
 867-			r.from = old->from - 1;
 868-			r.to = new->from;
 869-		} else
 870-			r.to = old->from;
 871-
 872-		printrange(fp[0], &r);
 873-		switch (de[n].type) {
 874-		case DIFF_TYPE1:
 875-			if (!delete)
 876-				printrange(fp[2], new);
 877-			break;
 878-		case DIFF_TYPE2:
 879-			printf("%s %s\n", oldmark, f2mark);
 880-			printrange(fp[1], old);
 881-			printf("%s\n", divider);
 882-			printrange(fp[2], new);
 883-			printf("%s %s\n", newmark, f3mark);
 884-			break;
 885-		case DIFF_TYPE3:
 886-			if (!oflag || !overlap[n]) {
 887-				printrange(fp[2], new);
 888-			} else {
 889-				printf("%s %s\n", oldmark, f1mark);
 890-				printrange(fp[0], old);
 891-				if (eflag != EFLAG_OVERLAP) {
 892-					printf("%s %s\n", orgmark, f2mark);
 893-					if (old->from == old->to) {
 894-						struct Range or;
 895-						or.from = old->from - 1;
 896-						or.to = new->to;
 897-						printrange(fp[1], &or);
 898-					} else {
 899-						printrange(fp[1], old);
 900-					}
 901-				}
 902-				printf("%s\n", divider);
 903-				printrange(fp[2], new);
 904-				printf("%s %s\n", newmark, f3mark);
 905-			}
 906-			break;
 907-		default:
 908-			printf("Error: Unhandled diff type - exiting\n");
 909-			exit(EXIT_FAILURE);
 910-		}
 911-
 912-		if (old->from == old->to)
 913-			r.from = new->to;
 914-		else
 915-			r.from = old->to;
 916-	}
 917-
 918-	new = &de[n-1].new;
 919-	old = &de[n-1].old;
 920-
 921-	if (old->from == new->from && old->to == new->to)
 922-		r.from--;
 923-	else if (new->from == new->to)
 924-		r.from = old->from;
 925-
 926-	r.to = INT_MAX;
 927-	printrange(fp[2], &r);
 928-	exit(overlapcnt > 0);
 929-}
 930-
 931-static void
 932-increase(void)
 933-{
 934-	struct Diff *p;
 935-	char *q;
 936-	size_t newsz, incr;
 937-
 938-	newsz = szchanges == 0 ? 64 : 2 * szchanges;
 939-	incr = newsz - szchanges;
 940-
 941-	p = ereallocarray(d13, newsz, sizeof(*p));
 942-	memset(p + szchanges, 0, incr * sizeof(*p));
 943-	d13 = p;
 944-
 945-	p = ereallocarray(d23, newsz, sizeof(*p));
 946-	memset(p + szchanges, 0, incr * sizeof(*p));
 947-	d23 = p;
 948-
 949-	p = ereallocarray(de, newsz, sizeof(*p));
 950-	memset(p + szchanges, 0, incr * sizeof(*p));
 951-	de = p;
 952-
 953-	q = ereallocarray(overlap, newsz, 1);
 954-	memset(q + szchanges, 0, incr * 1);
 955-	overlap = q;
 956-	szchanges = newsz;
 957-}
 958-
 959-static void
 960-handle_sig(int signo)
 961-{
 962-	write(sigpipe[1], &signo, sizeof(signo));
 963-}
 964-
 965-static void
 966-xasprintf(char **strp, const char *fmt, ...)
 967+format_merge(const struct three_hunk *hs, size_t n,
 968+             const struct difffile *f1, const struct difffile *f2,
 969+             const struct difffile *f3)
 970 {
 971-	va_list ap;
 972-	int r;
 973-
 974-	va_start(ap, fmt);
 975-	r = vasprintf(strp, fmt, ap);
 976-	va_end(ap);
 977-	if (r == -1)
 978-		err(2, "asprintf");
 979+        size_t i, j;
 980+        size_t cursor;
 981+        const char *l1, *l2, *l3;
 982+
 983+        l1 = nlabels >= 1 ? labels[0] : "file1";
 984+        l2 = nlabels >= 2 ? labels[1] : "file2";
 985+        l3 = nlabels >= 3 ? labels[2] : "file3";
 986+        cursor = 0;
 987+        for (i = 0; i < n; i++) {
 988+                const struct three_hunk *h = &hs[i];
 989+                for (j = cursor; j < h->r2.from; j++) {
 990+                        fwrite(f2->lines[j].data, 1, f2->lines[j].len, stdout);
 991+                        fputc('\n', stdout);
 992+                }
 993+                cursor = h->r2.to;
 994+                if (h->kind == HUNK_TYPE1) {
 995+                        print_lines(f1, h->r1.from, h->r1.to);
 996+                } else if (h->kind == HUNK_TYPE2) {
 997+                        print_lines(f3, h->r3.from, h->r3.to);
 998+                } else if (h->dup) {
 999+                        print_lines(f1, h->r1.from, h->r1.to);
1000+                } else {
1001+                        printf("<<<<<<< %s\n", l1);
1002+                        print_lines(f1, h->r1.from, h->r1.to);
1003+                        printf("||||||| %s\n", l2);
1004+                        print_lines(f2, h->r2.from, h->r2.to);
1005+                        printf("=======\n");
1006+                        print_lines(f3, h->r3.from, h->r3.to);
1007+                        printf(">>>>>>> %s\n", l3);
1008+                }
1009+        }
1010+        for (j = cursor; j < f2->nlines; j++) {
1011+                fwrite(f2->lines[j].data, 1, f2->lines[j].len, stdout);
1012+                fputc('\n', stdout);
1013+        }
1014+        return 0;
1015 }
1016+#endif
1017 
1018-// ?man diff3: 3-way differential file comparison
1019+// ?man diff3: three-way file comparison
1020 // ?man arguments: file1 file2 file3
1021-// ?man synopsis: [-3aAeEiL:mTxX] [--diff-program program] [--strip-trailing-cr] [-L label1] [-L label2] [-L label3] file1 file2 file3
1022+// ?man compare three files line by line and show the differences
1023 int
1024-main(int argc, char **argv)
1025+main(int argc, char *argv[])
1026 {
1027-	int ch, nblabels, status, m, n, npe, nleft;
1028-	char *labels[] = { NULL, NULL, NULL };
1029-	const char *diffprog = DIFF_PATH;
1030-	char *file1, *file2, *file3;
1031-	char *diffargv[7];
1032-	int diffargc = 0;
1033-	int fd13[2], fd23[2], signo;
1034-	pid_t wpid;
1035-	struct pollfd pfd;
1036-
1037-	nblabels = 0;
1038-	eflag = EFLAG_NONE;
1039-	oflag = 0;
1040-	diffargv[diffargc++] = (char *)diffprog;
1041-	while ((ch = getopt_long(argc, argv, OPTIONS, longopts, NULL)) != -1) {
1042-		// ?man -3: output changes specific only to file3
1043-		switch (ch) {
1044-		case '3':
1045-			eflag = EFLAG_NOOVERLAP;
1046-			break;
1047-		// ?man -a: treat files as text
1048-		case 'a':
1049-			diffargv[diffargc++] = "-a";
1050-			break;
1051-		// ?man -A: output all changes bracketing conflicts
1052-		case 'A':
1053-			Aflag = 1;
1054-			break;
1055-		// ?man -e: output ed script
1056-		case 'e':
1057-			eflag = EFLAG_UNMERGED;
1058-			break;
1059-		// ?man -E: show overlapping changes
1060-		case 'E':
1061-			eflag = EFLAG_OVERLAP;
1062-			oflag = 1;
1063-			break;
1064-		// ?man -i: append w and q ed commands
1065-		case 'i':
1066-			iflag = 1;
1067-			break;
1068-		// ?man -L:label: define label
1069-		case 'L':
1070-			oflag = 1;
1071-			if (nblabels >= 3)
1072-				errx(2, "too many file label options");
1073-			labels[nblabels++] = optarg;
1074-			break;
1075-		// ?man -m: merge output
1076-		case 'm':
1077-			Aflag = 1;
1078-			oflag = 1;
1079-			mflag = 1;
1080-			break;
1081-		// ?man -T: use tab prefix in normal listing
1082-		case 'T':
1083-			Tflag = 1;
1084-			break;
1085-		// ?man -x: output script with changes specific to all three
1086-		case 'x':
1087-			eflag = EFLAG_OVERLAP;
1088-			break;
1089-		// ?man -X: show overlapping changes
1090-		case 'X':
1091-			oflag = 1;
1092-			eflag = EFLAG_OVERLAP;
1093-			break;
1094-		case DIFFPROG_OPT:
1095-			diffprog = optarg;
1096-			break;
1097-		case STRIPCR_OPT:
1098-			strip_cr = 1;
1099-			diffargv[diffargc++] = "--strip-trailing-cr";
1100-			break;
1101-		case HELP_OPT:
1102-			usage();
1103-			exit(0);
1104-		case VERSION_OPT:
1105-			printf("%s\n", diff3_version);
1106-			exit(0);
1107-		}
1108-	}
1109-	argc -= optind;
1110-	argv += optind;
1111-
1112-	if (Aflag) {
1113-		if (eflag == EFLAG_NONE)
1114-			eflag = EFLAG_UNMERGED;
1115-		oflag = 1;
1116-	}
1117-
1118-	if (argc != 3) {
1119-		usage();
1120-		exit(2);
1121-	}
1122-
1123-	file1 = argv[0];
1124-	file2 = argv[1];
1125-	file3 = argv[2];
1126-
1127-	if (oflag) {
1128-		xasprintf(&f1mark, "%s", labels[0] != NULL ? labels[0] : file1);
1129-		xasprintf(&f2mark, "%s", labels[1] != NULL ? labels[1] : file2);
1130-		xasprintf(&f3mark, "%s", labels[2] != NULL ? labels[2] : file3);
1131-	}
1132-	fp[0] = fopen(file1, "r");
1133-	if (fp[0] == NULL)
1134-		err(2, "Can't open %s", file1);
1135-
1136-	fp[1] = fopen(file2, "r");
1137-	if (fp[1] == NULL)
1138-		err(2, "Can't open %s", file2);
1139-
1140-	fp[2] = fopen(file3, "r");
1141-	if (fp[2] == NULL)
1142-		err(2, "Can't open %s", file3);
1143-
1144-	if (pipe(fd13))
1145-		err(2, "pipe");
1146-	if (pipe(fd23))
1147-		err(2, "pipe");
1148-	if (pipe(sigpipe))
1149-		err(2, "pipe");
1150-	if (fcntl(sigpipe[0], F_SETFD, FD_CLOEXEC))
1151-		err(2, "fcntl");
1152-	if (fcntl(sigpipe[1], F_SETFD, FD_CLOEXEC))
1153-		err(2, "fcntl");
1154-
1155-	pfd.fd = sigpipe[0];
1156-	pfd.events = POLLIN;
1157-	pfd.revents = 0;
1158-
1159-	if (signal(SIGCHLD, handle_sig) == SIG_ERR)
1160-		err(2, "signal");
1161-
1162-	diffargv[diffargc] = file1;
1163-	diffargv[diffargc + 1] = file3;
1164-	diffargv[diffargc + 2] = NULL;
1165-
1166-	nleft = 0;
1167-	diffexec(diffprog, diffargv, fd13);
1168-	nleft++;
1169-
1170-	diffargv[diffargc] = file2;
1171-	diffexec(diffprog, diffargv, fd23);
1172-	nleft++;
1173-
1174-	increase();
1175-	m = readin(fd13[0], &d13);
1176-	n = readin(fd23[0], &d23);
1177-
1178-	while (nleft > 0) {
1179-		npe = poll(&pfd, 1, -1);
1180-		if (npe == -1) {
1181-			if (errno == EINTR)
1182-				continue;
1183-			err(2, "poll");
1184-		}
1185-		if (pfd.revents != POLLIN)
1186-			continue;
1187-		if (read(pfd.fd, &signo, sizeof(signo)) < 0)
1188-			err(2, "read");
1189-		while ((wpid = waitpid(-1, &status, WNOHANG)) > 0) {
1190-			if (WIFEXITED(status) && WEXITSTATUS(status) >= 2)
1191-				errx(2, "diff exited abnormally");
1192-			else if (WIFSIGNALED(status))
1193-				errx(2, "diff killed by signal %d", WTERMSIG(status));
1194-			nleft--;
1195-		}
1196-	}
1197-	merge(m, n);
1198-
1199-	return EXIT_SUCCESS;
1200+        struct difffile f1, f2, f3;
1201+        struct pair_hunk *d13, *d23;
1202+        size_t n13, n23;
1203+        struct three_hunk *hs;
1204+        size_t nhunks;
1205+        struct diffhunks raw13, raw23;
1206+        struct diffopts opts;
1207+        int ret, conflicts;
1208+
1209+        ARGBEGIN {
1210+        case '3':
1211+                // ?man -3: like -A but skip overlapping changes
1212+                Aflag = 1;
1213+                break;
1214+        case 'a':
1215+                // ?man -a: treat all files as text
1216+                aflag = 1;
1217+                break;
1218+        case 'A':
1219+                // ?man -A: emit ed script with all changes including overlaps
1220+                Aflag = 1;
1221+                break;
1222+        case 'e':
1223+                // ?man -e: emit ed script to apply non-overlapping changes
1224+                eflag = 1;
1225+                break;
1226+        case 'E':
1227+                // ?man -E: like -e but include overlap markers
1228+                Eflag = 1;
1229+                break;
1230+#if FEATURE_DIFF3_MERGE
1231+        case 'i':
1232+                // ?man -i: ignore case when comparing lines
1233+                iflag = 1;
1234+                break;
1235+        case 'L':
1236+                // ?man -L:label: use label in place of file name in merge output
1237+                if (nlabels >= 3)
1238+                        usage();
1239+                labels[nlabels++] = EARGF(usage());
1240+                break;
1241+        case 'm':
1242+                // ?man -m: emit merged output with conflict markers
1243+                mflag = 1;
1244+                break;
1245+        case 'T':
1246+                // ?man -T: prefix output lines with a tab
1247+                Tflag = 1;
1248+                break;
1249+#endif
1250+        case 'x':
1251+                // ?man -x: emit ed script for overlapping changes only
1252+                xflag = 1;
1253+                break;
1254+        case 'X':
1255+                // ?man -X: emit ed script for overlapping changes with markers
1256+                Xflag = 1;
1257+                break;
1258+        default:
1259+                usage();
1260+        } ARGEND
1261+
1262+        if (argc != 3)
1263+                usage();
1264+
1265+        if (diff_load(&f1, argv[0]) < 0)
1266+                return 2;
1267+        if (diff_load(&f2, argv[1]) < 0) {
1268+                diff_free(&f1);
1269+                return 2;
1270+        }
1271+        if (diff_load(&f3, argv[2]) < 0) {
1272+                diff_free(&f1);
1273+                diff_free(&f2);
1274+                return 2;
1275+        }
1276+
1277+        memset(&opts, 0, sizeof(opts));
1278+        opts.format = DIFF_NORMAL;
1279+        opts.ignore_case = iflag;
1280+        opts.strip_cr = strip_cr;
1281+        opts.context = 3;
1282+
1283+        if (diff_compute(&raw13, &f1, &f2, &opts) < 0 ||
1284+            diff_compute(&raw23, &f2, &f3, &opts) < 0) {
1285+                diff_free(&f1); diff_free(&f2); diff_free(&f3);
1286+                return 2;
1287+        }
1288+        convert_hunks(&raw13, &d13, &n13);
1289+        convert_hunks(&raw23, &d23, &n23);
1290+
1291+        if (merge_hunks(&f1, &f2, &f3, d13, n13, d23, n23, &hs, &nhunks) < 0) {
1292+                diff_hunks_free(&raw13);
1293+                diff_hunks_free(&raw23);
1294+                free(d13); free(d23);
1295+                diff_free(&f1); diff_free(&f2); diff_free(&f3);
1296+                return 2;
1297+        }
1298+
1299+        ret = 0;
1300+        conflicts = 0;
1301+        if (nhunks == 0) {
1302+                ret = 0;
1303+        } else {
1304+#if FEATURE_DIFF3_MERGE
1305+                if (mflag) {
1306+                        size_t i;
1307+                        for (i = 0; i < nhunks; i++)
1308+                                if (hs[i].kind == HUNK_TYPE3 && !hs[i].dup)
1309+                                        conflicts++;
1310+                        format_merge(hs, nhunks, &f1, &f2, &f3);
1311+                        ret = conflicts ? 1 : 0;
1312+                } else
1313+#endif
1314+                if (eflag || Eflag) {
1315+                        format_ed(hs, nhunks, Eflag && !eflag, 0, &f2, &f3);
1316+                        ret = 1;
1317+                } else if (xflag) {
1318+                        format_ed(hs, nhunks, 1, 0, &f2, &f3);
1319+                        ret = 1;
1320+                } else if (Xflag) {
1321+                        format_ed(hs, nhunks, 0, 1, &f2, &f3);
1322+                        ret = 1;
1323+                } else if (Aflag) {
1324+                        format_ed(hs, nhunks, 0, 1, &f2, &f3);
1325+                        ret = 1;
1326+                } else {
1327+                        format_normal(hs, nhunks, &f1, &f2, &f3);
1328+                        ret = 1;
1329+                }
1330+        }
1331+
1332+        if (fshut(stdout, "<stdout>"))
1333+                ret = 2;
1334+
1335+        diff_hunks_free(&raw13);
1336+        diff_hunks_free(&raw23);
1337+        free(d13); free(d23);
1338+        free(hs);
1339+        diff_free(&f1); diff_free(&f2); diff_free(&f3);
1340+        return ret;
1341 }
+8, -7
 1@@ -15,6 +15,7 @@
 2 #include <stdlib.h>
 3 #include <string.h>
 4 
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 #define REGEXSIZE  100
 9@@ -837,13 +838,13 @@ dowrite(const char *fname, int trunc)
10 	char *mode;
11 
12 	if (fp) {
13-		sh ? pclose(fp) : fclose(fp);
14+		sh ? wpclose(fp) : fclose(fp);
15 		fp = NULL;
16 	}
17 
18 	if (fname[0] == '!') {
19 		sh = 1;
20-		if((fp = popen(expandcmd(), "w")) == NULL)
21+		if((fp = wpopen(expandcmd(), NULL, "w")) == NULL)
22 			error("bad exec");
23 	} else {
24 		sh = 0;
25@@ -865,7 +866,7 @@ dowrite(const char *fname, int trunc)
26 
27 	aux = fp;
28 	fp = NULL;
29-	r = sh ? pclose(aux) : fclose(aux);
30+	r = sh ? wpclose(aux) : fclose(aux);
31 	if (r)
32 		error("input/output error");
33 	strcpy(savfname, fname);
34@@ -890,13 +891,13 @@ doread(const char *fname)
35 	static FILE *fp;
36 
37 	if (fp) {
38-		sh ? pclose(fp) : fclose(fp);
39+		sh ? wpclose(fp) : fclose(fp);
40 		fp = NULL;
41 	}
42 
43 	if(fname[0] == '!') {
44 		sh = 1;
45-		if((fp = popen(expandcmd(), "r")) == NULL)
46+		if((fp = wpopen(expandcmd(), NULL, "r")) == NULL)
47 			error("bad exec");
48 	} else if ((fp = fopen(fname, "r")) == NULL) {
49 		error("cannot open input file");
50@@ -921,7 +922,7 @@ doread(const char *fname)
51 
52 	aux = fp;
53 	fp = NULL;
54-	r = sh ? pclose(aux) : fclose(aux);
55+	r = sh ? wpclose(aux) : fclose(aux);
56 	if (r)
57 		error("input/output error");
58 }
59@@ -1153,7 +1154,7 @@ copy(int where)
60 static void
61 execsh(void)
62 {
63-	system(expandcmd());
64+	wsystem(expandcmd());
65 	if (optdiag)
66 		puts("!");
67 }
+3, -2
 1@@ -7,6 +7,7 @@
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 extern char **environ;
 9@@ -43,9 +44,9 @@ main(int argc, char *argv[])
10 		putenv(*argv);
11 
12 	if (*argv) {
13-		execvp(*argv, argv);
14+		wexecvp_self(*argv, argv);
15 		savederrno = errno;
16-		weprintf("execvp %s:", *argv);
17+		weprintf("wexecvp %s:", *argv);
18 		_exit(126 + (savederrno == ENOENT));
19 	}
20 
+2, -1
 1@@ -2,6 +2,7 @@
 2 
 3 
 4 #include "config.h"
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 #include <dirent.h>
 9@@ -344,7 +345,7 @@ spawn(char *argv[])
10 		eprintf("fork:");
11 		break;
12 	case 0:
13-		execvp(*argv, argv);
14+		wexecvp_self(*argv, argv);
15 		weprintf("exec %s failed:", *argv);
16 		_exit(1);
17 	}
+236, -251
  1@@ -31,288 +31,268 @@ volatile sig_atomic_t  stop;
  2 void
  3 debug(char *fmt, ...)
  4 {
  5-	va_list va;
  6+        va_list va;
  7 
  8-	if (!dflag)
  9-		return;
 10+        if (!dflag)
 11+                return;
 12 
 13-	va_start(va, fmt);
 14-	vfprintf(stdout, fmt, va);
 15-	fputc('\n', stdout);
 16-	va_end(va);
 17+        va_start(va, fmt);
 18+        vfprintf(stdout, fmt, va);
 19+        fputc('\n', stdout);
 20+        va_end(va);
 21 }
 22 
 23 int
 24 hash(char *name)
 25 {
 26-	int c;
 27-	unsigned h = 5381;
 28+        int c;
 29+        unsigned h = 5381;
 30 
 31-	while ((c = *name++))
 32-		h = h*33 ^ c;
 33+        while ((c = *name++))
 34+                h = h*33 ^ c;
 35 
 36-	return h;
 37-}
 38-
 39-void *
 40-emalloc(size_t siz)
 41-{
 42-	void *p;
 43-
 44-	if ((p = malloc(siz)) == NULL) {
 45-		perror("make");
 46-		exit(EXIT_FAILURE);
 47-	}
 48-
 49-	return p;
 50-}
 51-
 52-void *
 53-erealloc(void *p, size_t siz)
 54-{
 55-	if ((p = realloc(p, siz)) == NULL) {
 56-		perror("make");
 57-		exit(EXIT_FAILURE);
 58-	}
 59-
 60-	return p;
 61-}
 62-
 63-char *
 64-estrdup(char *s)
 65-{
 66-	size_t len;
 67-
 68-	len = strlen(s) + 1;
 69-	return memcpy(emalloc(len), s, len);
 70+        return h;
 71 }
 72 
 73 void
 74 sighandler(int signo)
 75 {
 76-	killchild();
 77-	stop = signo;
 78+        killchild();
 79+        stop = signo;
 80 }
 81 
 82 static void
 83 usage(void)
 84 {
 85-	fputs("usage: make [-eiknprSstd] [-f file] [-j jobs] "
 86-	      "[macro=value ...] [target ...]\n",
 87-	      stderr);
 88-	exit(EXIT_FAILURE);
 89+        fputs("usage: make [-eiknprSstd] [-f file] [-j jobs] "
 90+              "[macro=value ...] [target ...]\n",
 91+              stderr);
 92+        exit(EXIT_FAILURE);
 93 }
 94 
 95 static char *
 96 getarg(char **args, char ***argv)
 97 {
 98-	char *s;
 99+        char *s;
100 
101-	if ((*args)[1]) {
102-		s = (*args) + 1;
103-		*args += strlen(*args) - 1;
104-		return s;
105-	}
106+        if ((*args)[1]) {
107+                s = (*args) + 1;
108+                *args += strlen(*args) - 1;
109+                return s;
110+        }
111 
112-	if (!argv)
113-		usage();
114+        if (!argv)
115+                usage();
116 
117-	if ((*argv)[1] == NULL)
118-		usage();
119-	(*argv)++;
120+        if ((*argv)[1] == NULL)
121+                usage();
122+        (*argv)++;
123 
124-	return **argv;
125+        return **argv;
126 }
127 
128 static void
129 appendmakeflags(char *text)
130 {
131-	int n;
132-	char *s, *t, *fmt;
133+        int n;
134+        char *s, *t, *fmt;
135 
136-	s = getmacro("MAKEFLAGS");
137-	fmt = *s ? "%s %s" : "%s%s";
138-	n = snprintf(NULL, 0, fmt, s, text);
139+        s = getmacro("MAKEFLAGS");
140+        fmt = *s ? "%s %s" : "%s%s";
141+        n = snprintf(NULL, 0, fmt, s, text);
142 
143-	t = emalloc(n+1);
144-	snprintf(t, n+1, fmt, s, text);
145-	setmacro("MAKEFLAGS", t, MAKEFLAGS, EXPORT);
146+        t = emalloc(n+1);
147+        snprintf(t, n+1, fmt, s, text);
148+        setmacro("MAKEFLAGS", t, MAKEFLAGS, EXPORT);
149 
150-	free(t);
151+        free(t);
152 }
153 
154 static int
155 hasargs(int c)
156 {
157-	return c == 'f' || c == 'j';
158+        return c == 'f' || c == 'j';
159 }
160 
161 static void
162 parseflag(int flag, char **args, char ***argv)
163 {
164-	if (hasargs(flag))
165-		getarg(args, argv);
166-
167-	switch (flag) {
168-	case 'j':
169-	case 'f':
170-		break;
171-	case 'e':
172-		eflag = 1;
173-		appendmakeflags("-e");
174-		break;
175-	case 'i':
176-		iflag = 1;
177-		appendmakeflags("-i");
178-		break;
179-	case 'k':
180-		kflag = 1;
181-		appendmakeflags("-k");
182-		break;
183-	case 'n':
184-		nflag = 1;
185-		appendmakeflags("-n");
186-		break;
187-	case 'p':
188-		pflag = 1;
189-		break;
190-	case 'q':
191-		qflag = 1;
192-		appendmakeflags("-q");
193-		break;
194-	case 'r':
195-		addtarget(".SUFFIXES", 0);
196-		appendmakeflags("-r");
197-		break;	
198-	case 'S':
199-		kflag = 0;
200-		appendmakeflags("-S");
201-		break;
202-	case 's':
203-		sflag = 1;
204-		appendmakeflags("-s");
205-		break;
206-	case 't':
207-		tflag = 1;
208-		appendmakeflags("-t");
209-		break;
210-	case 'd':
211-		dflag = 1;
212-		appendmakeflags("-d");
213-		break;
214-	default:
215-		usage();
216-	}
217+        if (hasargs(flag))
218+                getarg(args, argv);
219+
220+        switch (flag) {
221+        case 'j':
222+                /* ?man -j:jobs: number of parallel jobs (accepted, runs serially) */
223+        case 'f':
224+                /* ?man -f:file: read rules from file instead of makefile or Makefile */
225+                break;
226+        case 'e':
227+                /* ?man -e: environment variables override makefile assignments */
228+                eflag = 1;
229+                appendmakeflags("-e");
230+                break;
231+        case 'i':
232+                /* ?man -i: ignore errors from executed commands */
233+                iflag = 1;
234+                appendmakeflags("-i");
235+                break;
236+        case 'k':
237+                /* ?man -k: continue building other targets after an error */
238+                kflag = 1;
239+                appendmakeflags("-k");
240+                break;
241+        case 'n':
242+                /* ?man -n: print commands without executing them */
243+                nflag = 1;
244+                appendmakeflags("-n");
245+                break;
246+        case 'p':
247+                /* ?man -p: print the rule and macro database then exit */
248+                pflag = 1;
249+                break;
250+        case 'q':
251+                /* ?man -q: question mode, return zero if up to date, one otherwise */
252+                qflag = 1;
253+                appendmakeflags("-q");
254+                break;
255+        case 'r':
256+                /* ?man -r: clear the built-in suffix rules and variables */
257+                addtarget(".SUFFIXES", 0);
258+                appendmakeflags("-r");
259+                break;
260+        case 'S':
261+                /* ?man -S: cancel a previous -k, stop on first error */
262+                kflag = 0;
263+                appendmakeflags("-S");
264+                break;
265+        case 's':
266+                /* ?man -s: silent, do not echo commands before running them */
267+                sflag = 1;
268+                appendmakeflags("-s");
269+                break;
270+        case 't':
271+                /* ?man -t: touch targets instead of rebuilding them */
272+                tflag = 1;
273+                appendmakeflags("-t");
274+                break;
275+        case 'd':
276+                /* ?man -d: enable debug output */
277+                dflag = 1;
278+                appendmakeflags("-d");
279+                break;
280+        default:
281+                usage();
282+        }
283 }
284 
285 static int
286 assign(char *s, int where, int export)
287 {
288-	int pos;
289-	char *t;
290+        int pos;
291+        char *t;
292 
293-	if ((t = strchr(s, '=')) == NULL)
294-		return 0;
295+        if ((t = strchr(s, '=')) == NULL)
296+                return 0;
297 
298-	pos = t - s;
299+        pos = t - s;
300 
301-	appendmakeflags(s);
302-	t = estrdup(s); 
303-	t[pos] = '\0';
304+        appendmakeflags(s);
305+        t = estrdup(s); 
306+        t[pos] = '\0';
307 
308-	setmacro(t, t+pos+1, where, export);
309-	free(t);
310-	return 1;
311+        setmacro(t, t+pos+1, where, export);
312+        free(t);
313+        return 1;
314 }
315 
316 static void
317 parseargv(char **argv, char ***targets, int where, int export)
318 {
319-	char *s;
320-	char *hm = NULL;
321-
322-	for ( ; *argv; ++argv) {
323-		s = *argv;
324-		if (hm == NULL && strcmp(s, "--") == 0) {
325-			hm = *argv;
326-		} else if (hm && s[0] == '-') {
327-			break;
328-		} else if (s[0] != '-') {
329-			if (!assign(s, where, export))
330-				break;
331-			continue;
332-		}
333-		while (hm == NULL && *++s)
334-			parseflag(*s, &s, &argv);
335-	}
336-
337-	if (targets)
338-		*targets = argv;
339+        char *s;
340+        char *hm = NULL;
341+
342+        for ( ; *argv; ++argv) {
343+                s = *argv;
344+                if (hm == NULL && strcmp(s, "--") == 0) {
345+                        hm = *argv;
346+                } else if (hm && s[0] == '-') {
347+                        break;
348+                } else if (s[0] != '-') {
349+                        if (!assign(s, where, export))
350+                                break;
351+                        continue;
352+                }
353+                while (hm == NULL && *++s)
354+                        parseflag(*s, &s, &argv);
355+        }
356+
357+        if (targets)
358+                *targets = argv;
359 }
360 
361 static void
362 parsemakeflags(void)
363 {
364-	int n;
365-	char *s, *flags, **arr;
366-
367-	if ((flags = getenv("MAKEFLAGS")) == NULL)
368-		return;
369-
370-	setmacro("MAKEFLAGS", "", MAKEFLAGS, EXPORT);
371-
372-	while (*flags == ' ' || *flags == '\t')
373-		flags++;
374-
375-	if (flags[0] != '-' && !strchr(flags, '=')) {
376-		while (*flags) {
377-			parseflag(*flags, &flags, NULL);
378-			flags++;
379-		}
380-	} else {
381-		n = 0;
382-		arr = NULL;
383-		for (s = strtok(flags, " \t"); s; s = strtok(NULL, " \t")) {
384-			n++;
385-			arr = erealloc(arr, sizeof(char *) * (n+1));
386-			arr[n-1] = s;
387-			arr[n] = NULL;
388-		}
389-
390-		if (arr)
391-			parseargv(arr, NULL, MAKEFLAGS, NOEXPORT);
392-		free(arr);
393-	}
394+        int n;
395+        char *s, *flags, **arr;
396+
397+        if ((flags = getenv("MAKEFLAGS")) == NULL)
398+                return;
399+
400+        setmacro("MAKEFLAGS", "", MAKEFLAGS, EXPORT);
401+
402+        while (*flags == ' ' || *flags == '\t')
403+                flags++;
404+
405+        if (flags[0] != '-' && !strchr(flags, '=')) {
406+                while (*flags) {
407+                        parseflag(*flags, &flags, NULL);
408+                        flags++;
409+                }
410+        } else {
411+                n = 0;
412+                arr = NULL;
413+                for (s = strtok(flags, " \t"); s; s = strtok(NULL, " \t")) {
414+                        n++;
415+                        arr = erealloc(arr, sizeof(char *) * (n+1));
416+                        arr[n-1] = s;
417+                        arr[n] = NULL;
418+                }
419+
420+                if (arr)
421+                        parseargv(arr, NULL, MAKEFLAGS, NOEXPORT);
422+                free(arr);
423+        }
424 }
425 
426 static void
427 parsemakefiles(char **argv)
428 {
429-	char *s, *arg;
430-	int c, hasmake;
431-
432-	hasmake = 0;
433-	for ( ; *argv && **argv == '-'; ++argv) {
434-		for (s = *argv; (c = *s); ++s) {
435-			if (hasargs(c))
436-				arg = getarg(&s, &argv);
437-
438-			if (c == 'f') {
439-				if (strcmp(arg, "-") == 0)
440-					arg = NULL;
441-				parse(arg);
442-				hasmake = 1;
443-			}
444-		}
445-	}
446-
447-	if (hasmake)
448-		return;
449-
450-	if (parse("makefile"))
451-		return;
452-	if (parse("Makefile"))
453-		return;
454+        char *s, *arg;
455+        int c, hasmake;
456+
457+        hasmake = 0;
458+        for ( ; *argv && **argv == '-'; ++argv) {
459+                for (s = *argv; (c = *s); ++s) {
460+                        if (hasargs(c))
461+                                arg = getarg(&s, &argv);
462+
463+                        if (c == 'f') {
464+                                if (strcmp(arg, "-") == 0)
465+                                        arg = NULL;
466+                                parse(arg);
467+                                hasmake = 1;
468+                        }
469+                }
470+        }
471+
472+        if (hasmake)
473+                return;
474+
475+        if (parse("makefile"))
476+                return;
477+        if (parse("Makefile"))
478+                return;
479 }
480 
481 /*
482@@ -323,57 +303,62 @@ parsemakefiles(char **argv)
483 static void
484 enadebug(char *argv[])
485 {
486-	int c;
487-	char *p;
488-
489-	for ( ; *argv && **argv == '-'; ++argv) {
490-		p = *argv;
491-		for (++p; (c = *p); ++p) {
492-			if (hasargs(c))
493-				getarg(&p, &argv);
494-			if (c == 'd')
495-				dflag = 1;
496-		}
497-	}
498+        int c;
499+        char *p;
500+
501+        for ( ; *argv && **argv == '-'; ++argv) {
502+                p = *argv;
503+                for (++p; (c = *p); ++p) {
504+                        if (hasargs(c))
505+                                getarg(&p, &argv);
506+                        if (c == 'd')
507+                                dflag = 1;
508+                }
509+        }
510 }
511 
512+// ?man make: maintain program dependencies
513+// ?man arguments: [name=value ...] [target ...]
514+// ?man update files based on dependency rules in a makefile.
515+// ?man if no -f is given, make tries makefile then Makefile.
516+// ?man if no target is given the first non-dot target in the makefile is built.
517 int
518 main(int argc, char *argv[])
519 {
520-	char *arg0, **targets;
521+        char *arg0, **targets;
522 
523-	(void)argc;
524+        (void)argc;
525 
526-	signal(SIGINT, sighandler);
527-	signal(SIGHUP, sighandler);
528-	signal(SIGTERM, sighandler);
529-	signal(SIGQUIT, sighandler);
530+        signal(SIGINT, sighandler);
531+        signal(SIGHUP, sighandler);
532+        signal(SIGTERM, sighandler);
533+        signal(SIGQUIT, sighandler);
534 
535-	targets = NULL;
536-	arg0 = *argv++;
537+        targets = NULL;
538+        arg0 = *argv++;
539 
540-	enadebug(argv);
541-	inject(defaults);
542-	setmacro("MAKE", arg0, MAKEFILE, NOEXPORT);
543+        enadebug(argv);
544+        inject(defaults);
545+        setmacro("MAKE", arg0, MAKEFILE, NOEXPORT);
546 
547-	parsemakeflags();
548-	parseargv(argv, &targets, CMDLINE, EXPORT);
549-	parsemakefiles(argv);
550+        parsemakeflags();
551+        parseargv(argv, &targets, CMDLINE, EXPORT);
552+        parsemakefiles(argv);
553 
554-	if (pflag) {
555-		dumpmacros();
556-		dumprules();
557-		exit(EXIT_SUCCESS);
558-	}
559+        if (pflag) {
560+                dumpmacros();
561+                dumprules();
562+                exit(EXIT_SUCCESS);
563+        }
564 
565-	if (!*targets) {
566-		build(NULL);
567-	} else {
568-		while (*targets)
569-			build(*targets++);
570-	}
571+        if (!*targets) {
572+                build(NULL);
573+        } else {
574+                while (*targets)
575+                        build(*targets++);
576+        }
577 
578-	exit(exitstatus);
579+        exit(exitstatus);
580 
581-	return 0;
582+        return 0;
583 }
+26, -27
 1@@ -1,52 +1,51 @@
 2 #include <stddef.h>
 3 #include <time.h>
 4 
 5+#include "util.h"
 6+#include "wexec.h"
 7+
 8 typedef struct target Target;
 9 
10 enum {
11-	NOEXPORT,
12-	EXPORT,
13+        NOEXPORT,
14+        EXPORT,
15 };
16 
17 enum {
18-	UNDEF,
19-	ENVIRON,
20-	CMDLINE,
21-	INTERNAL,
22-	MAKEFILE,
23-	MAKEFLAGS,
24+        UNDEF,
25+        ENVIRON,
26+        CMDLINE,
27+        INTERNAL,
28+        MAKEFILE,
29+        MAKEFLAGS,
30 };
31 
32 struct loc {
33-	char *fname;
34-	int lineno;
35+        char *fname;
36+        int lineno;
37 };
38 
39 struct action {
40-	char *line;
41-	struct loc loc;
42+        char *line;
43+        struct loc loc;
44 };
45 
46 struct target {
47-	char *name;
48-	char *target;
49-	char *req;
50-	time_t stamp;
51-	int defined;
52+        char *name;
53+        char *target;
54+        char *req;
55+        time_t stamp;
56+        int defined;
57 
58-	int ndeps;
59-	struct target **deps;
60+        int ndeps;
61+        struct target **deps;
62 
63-	int nactions;
64-	struct action *actions;
65+        int nactions;
66+        struct action *actions;
67 
68-	struct target *next;
69+        struct target *next;
70 };
71 
72-void *emalloc(size_t);
73-void *erealloc(void *, size_t);
74-char *estrdup(char *);
75-
76 void dumprules(void);
77 void dumpmacros(void);
78 
79@@ -57,7 +56,7 @@ int build(char *);
80 int hash(char *);
81 int parse(char *);
82 void debug(char *, ...);
83-void error(char *, ...);
84+void error(char *, ...) __attribute__((noreturn));
85 void warning(char *, ...);
86 void adddep(char *, char *);
87 void addrule(char *, struct action *, int);
+1133, -760
   1@@ -17,37 +17,37 @@
   2 typedef struct macro Macro;
   3 
   4 enum inputype {
   5-	FTFILE,
   6-	FTEXPAN,
   7+        FTFILE,
   8+        FTEXPAN,
   9 };
  10 
  11 enum {
  12-	STBEGIN,
  13-	STINTERNAL,
  14-	STREPLACE,
  15-	STTO,
  16-	STEND,
  17+        STBEGIN,
  18+        STINTERNAL,
  19+        STREPLACE,
  20+        STTO,
  21+        STEND,
  22 };
  23 
  24 struct input {
  25-	int siz;
  26-	int type;
  27+        int siz;
  28+        int type;
  29 
  30-	FILE *fp;
  31-	struct loc loc;
  32+        FILE *fp;
  33+        struct loc loc;
  34 
  35-	int pos;
  36-	char *buf;
  37+        int pos;
  38+        char *buf;
  39 
  40-	struct input *prev;
  41+        struct input *prev;
  42 };
  43 
  44 struct macro {
  45-	char *name;
  46-	char *value;
  47-	int where;
  48+        char *name;
  49+        char *value;
  50+        int where;
  51 
  52-	struct macro *next;
  53+        struct macro *next;
  54 };
  55 
  56 static struct input *input;
  57@@ -58,352 +58,617 @@ static Macro *htab[TABSIZ];
  58 void
  59 dumpmacros(void)
  60 {
  61-	Macro **pp, *p;
  62+        Macro **pp, *p;
  63 
  64-	for (pp = htab; pp < &htab[TABSIZ]; ++pp) {
  65-		for (p = *pp; p; p = p->next)
  66-			printf("%s = %s\n", p->name, getmacro(p->name));
  67-	}
  68+        for (pp = htab; pp < &htab[TABSIZ]; ++pp) {
  69+                for (p = *pp; p; p = p->next)
  70+                        printf("%s = %s\n", p->name, getmacro(p->name));
  71+        }
  72 }
  73 
  74 static Macro *
  75 lookup(char *name)
  76 {
  77-	Macro *mp;
  78-	int h = hash(name) & (TABSIZ-1);
  79+        Macro *mp;
  80+        int h = hash(name) & (TABSIZ-1);
  81 
  82-	for (mp = htab[h]; mp && strcmp(mp->name, name); mp = mp->next)
  83-		;
  84+        for (mp = htab[h]; mp && strcmp(mp->name, name); mp = mp->next)
  85+                ;
  86 
  87-	if (mp)
  88-		return mp;
  89+        if (mp)
  90+                return mp;
  91 
  92-	mp = emalloc(sizeof(*mp));
  93-	mp->name = estrdup(name);
  94-	mp->value = estrdup("");
  95-	mp->next = htab[h];
  96-	mp->where = UNDEF;
  97-	htab[h] = mp;
  98+        mp = emalloc(sizeof(*mp));
  99+        mp->name = estrdup(name);
 100+        mp->value = estrdup("");
 101+        mp->next = htab[h];
 102+        mp->where = UNDEF;
 103+        htab[h] = mp;
 104 
 105-	return mp;
 106+        return mp;
 107 }
 108 
 109 static char *
 110 macroinfo(char *name, int *pwhere, Macro **mpp)
 111 {
 112-	char *s, *t;
 113-	int hide, where;
 114-	Macro *mp = lookup(name);
 115-
 116-	hide = 0;
 117-	if (!strcmp(name, "SHELL") || !strcmp(name, "MAKEFLAGS"))
 118-		hide = 1;
 119-
 120-	s = mp->value;
 121-	where = mp->where;
 122-
 123-	if (!hide && (where == UNDEF || where == INTERNAL || eflag)) {
 124-		t = getenv(name);
 125-		if (t) {
 126-			where = ENVIRON;
 127-			s = t;
 128-		}
 129-	}
 130-
 131-	if (pwhere)
 132-		*pwhere = where;
 133-	if (mpp)
 134-		*mpp = mp;
 135-
 136-	return s;
 137+        char *s, *t;
 138+        int hide, where;
 139+        Macro *mp = lookup(name);
 140+
 141+        hide = 0;
 142+        if (!strcmp(name, "SHELL") || !strcmp(name, "MAKEFLAGS"))
 143+                hide = 1;
 144+
 145+        s = mp->value;
 146+        where = mp->where;
 147+
 148+        if (!hide && (where == UNDEF || where == INTERNAL || eflag)) {
 149+                t = getenv(name);
 150+                if (t) {
 151+                        where = ENVIRON;
 152+                        s = t;
 153+                }
 154+        }
 155+
 156+        if (pwhere)
 157+                *pwhere = where;
 158+        if (mpp)
 159+                *mpp = mp;
 160+
 161+        return s;
 162 }
 163 
 164 char *
 165 getmacro(char *name)
 166 {
 167-	return macroinfo(name, NULL, NULL);
 168+        return macroinfo(name, NULL, NULL);
 169 }
 170 
 171 void
 172 setmacro(char *name, char *val, int where, int export)
 173 {
 174-	int owhere, set;
 175-	char *s;
 176-	Macro *mp;
 177-
 178-	assert(where != ENVIRON);
 179-
 180-	s = macroinfo(name, &owhere, &mp);
 181-
 182-	/*
 183-	 *  Default values are defined before anything else, and marked
 184-	 *  as INTERNAL because they are injected as parseable text, and
 185-	 *  MAKEFILE and INTERNAL variables are always overriden. ENVIRON
 186-	 *  macros are generated in macroinfo() and this is why this function
 187-	 *  should not receive a where == ENVIRON ever.
 188-	 */
 189-	switch (owhere) {
 190-	case UNDEF:
 191-	case INTERNAL:
 192-	case MAKEFILE:
 193-		set = 1;
 194-		break;
 195-	case ENVIRON:
 196-		set = (where == MAKEFLAGS || where == CMDLINE);
 197-		set |= (where == MAKEFILE && !eflag);
 198-		break;
 199-	case MAKEFLAGS:
 200-		set = (where == CMDLINE || where == MAKEFLAGS);
 201-		break;
 202-	case CMDLINE:
 203-		set = (where == CMDLINE);
 204-		break;
 205-	default:
 206-		abort();
 207-	}
 208-
 209-	if (!set) {
 210-		debug("hidding override of %s from '%s' to '%s'", name, s, val);
 211-	} else {
 212-		debug("override %s from '%s' to '%s'", name, s, val);
 213-		free(mp->value);
 214-		mp->value = estrdup(val);
 215-		mp->where = where;
 216-
 217-		if (export && strcmp(name, "SHELL") != 0) {
 218-			debug("exporting macro %s", name);
 219-			exportvar(name, val);
 220-		}
 221-	}
 222+        int owhere, set;
 223+        char *s;
 224+        Macro *mp;
 225+
 226+        assert(where != ENVIRON);
 227+
 228+        s = macroinfo(name, &owhere, &mp);
 229+
 230+        /*
 231+         *  Default values are defined before anything else, and marked
 232+         *  as INTERNAL because they are injected as parseable text, and
 233+         *  MAKEFILE and INTERNAL variables are always overriden. ENVIRON
 234+         *  macros are generated in macroinfo() and this is why this function
 235+         *  should not receive a where == ENVIRON ever.
 236+         */
 237+        switch (owhere) {
 238+        case UNDEF:
 239+        case INTERNAL:
 240+        case MAKEFILE:
 241+                set = 1;
 242+                break;
 243+        case ENVIRON:
 244+                set = (where == MAKEFLAGS || where == CMDLINE);
 245+                set |= (where == MAKEFILE && !eflag);
 246+                break;
 247+        case MAKEFLAGS:
 248+                set = (where == CMDLINE || where == MAKEFLAGS);
 249+                break;
 250+        case CMDLINE:
 251+                set = (where == CMDLINE);
 252+                break;
 253+        default:
 254+                abort();
 255+        }
 256+
 257+        if (!set) {
 258+                debug("hidding override of %s from '%s' to '%s'", name, s, val);
 259+        } else {
 260+                debug("override %s from '%s' to '%s'", name, s, val);
 261+                free(mp->value);
 262+                mp->value = estrdup(val);
 263+                mp->where = where;
 264+
 265+                if (export && strcmp(name, "SHELL") != 0) {
 266+                        debug("exporting macro %s", name);
 267+                        exportvar(name, val);
 268+                }
 269+        }
 270 }
 271 
 272 void
 273 freeloc(struct loc *loc)
 274 {
 275-	free(loc->fname);
 276+        free(loc->fname);
 277 }
 278 
 279 static struct loc *
 280 getloc(void)
 281 {
 282-	struct input *ip;
 283+        struct input *ip;
 284 
 285-	for (ip = input; ip && ip->type != FTFILE; ip = ip->prev)
 286-		;
 287-	if (!ip)
 288-		return NULL;
 289+        for (ip = input; ip && ip->type != FTFILE; ip = ip->prev)
 290+                ;
 291+        if (!ip)
 292+                return NULL;
 293 
 294-	return &ip->loc;
 295+        return &ip->loc;
 296 }
 297 
 298 
 299 void
 300 error(char *fmt, ...)
 301 {
 302-	va_list va;
 303-	struct loc *loc;
 304+        va_list va;
 305+        struct loc *loc;
 306 
 307-	fprintf(stderr, "make: error: ");
 308-	if ((loc = getloc()) != NULL)
 309-		fprintf(stderr, "%s:%d: ", loc->fname, loc->lineno);
 310+        fprintf(stderr, "make: error: ");
 311+        if ((loc = getloc()) != NULL)
 312+                fprintf(stderr, "%s:%d: ", loc->fname, loc->lineno);
 313 
 314-	va_start(va, fmt);
 315-	vfprintf(stderr, fmt, va);
 316-	va_end(va);
 317-	putc('\n', stderr);
 318+        va_start(va, fmt);
 319+        vfprintf(stderr, fmt, va);
 320+        va_end(va);
 321+        putc('\n', stderr);
 322 
 323-	exit(EXIT_FAILURE);
 324+        exit(EXIT_FAILURE);
 325 }
 326 
 327 void
 328 warning(char *fmt, ...)
 329 {
 330-	va_list va;
 331-	struct loc *loc;
 332+        va_list va;
 333+        struct loc *loc;
 334 
 335-	fprintf(stderr, "make: warning: ");
 336-	if ((loc = getloc()) != NULL)
 337-		fprintf(stderr, "%s:%d: ", loc->fname, loc->lineno);
 338+        fprintf(stderr, "make: warning: ");
 339+        if ((loc = getloc()) != NULL)
 340+                fprintf(stderr, "%s:%d: ", loc->fname, loc->lineno);
 341 
 342-	va_start(va, fmt);
 343-	vfprintf(stderr, fmt, va);
 344-	va_end(va);
 345-	putc('\n', stderr);
 346+        va_start(va, fmt);
 347+        vfprintf(stderr, fmt, va);
 348+        va_end(va);
 349+        putc('\n', stderr);
 350 }
 351 
 352 static void
 353 pop(void)
 354 {
 355-	struct input *ip = input->prev;
 356+        struct input *ip = input->prev;
 357 
 358-	if (input->type == FTFILE) {
 359-		if (input->fp)
 360-			fclose(input->fp);
 361-		freeloc(&input->loc);
 362-	}
 363-	free(input->buf);
 364-	free(input);
 365+        if (input->type == FTFILE) {
 366+                if (input->fp)
 367+                        fclose(input->fp);
 368+                freeloc(&input->loc);
 369+        }
 370+        free(input->buf);
 371+        free(input);
 372 
 373-	input = ip;
 374+        input = ip;
 375 }
 376 
 377 static void
 378 push(int type, ...)
 379 {
 380-	int line, len, pos;
 381-	FILE *fp = NULL;
 382-	char *buf, *s, *fname = NULL;
 383-	va_list va;
 384-	struct input *ip;
 385-
 386-	va_start(va, type);
 387-	switch (type) {
 388-	case FTFILE:
 389-		fp = va_arg(va, FILE *);
 390-		s = va_arg(va, char *);
 391-		line = va_arg(va, int);
 392-		fname = estrdup(s);
 393-		buf = emalloc(BUFSIZ);
 394-		pos = len = BUFSIZ;
 395-		break;
 396-	case FTEXPAN:
 397-		s = va_arg(va, char *);
 398-		buf = estrdup(s);
 399-		line = pos = 0;
 400-		len = strlen(s);
 401-		break;
 402-	}
 403-	va_end(va);
 404-
 405-	ip = emalloc(sizeof(*ip));
 406-	ip->siz = len;
 407-	ip->buf = buf;
 408-	ip->type = type;
 409-	ip->fp = fp;
 410-	ip->loc.fname = fname;
 411-	ip->loc.lineno = line;
 412-	ip->pos = pos;
 413-	ip->prev = input;
 414-
 415-	input = ip;
 416+        int line, len, pos;
 417+        FILE *fp = NULL;
 418+        char *buf, *s, *fname = NULL;
 419+        va_list va;
 420+        struct input *ip;
 421+
 422+        va_start(va, type);
 423+        switch (type) {
 424+        case FTFILE:
 425+                fp = va_arg(va, FILE *);
 426+                s = va_arg(va, char *);
 427+                line = va_arg(va, int);
 428+                fname = estrdup(s);
 429+                buf = emalloc(BUFSIZ);
 430+                pos = len = BUFSIZ;
 431+                break;
 432+        case FTEXPAN:
 433+                s = va_arg(va, char *);
 434+                buf = estrdup(s);
 435+                line = pos = 0;
 436+                len = strlen(s);
 437+                break;
 438+        }
 439+        va_end(va);
 440+
 441+        ip = emalloc(sizeof(*ip));
 442+        ip->siz = len;
 443+        ip->buf = buf;
 444+        ip->type = type;
 445+        ip->fp = fp;
 446+        ip->loc.fname = fname;
 447+        ip->loc.lineno = line;
 448+        ip->pos = pos;
 449+        ip->prev = input;
 450+
 451+        input = ip;
 452 }
 453 
 454 static char *
 455 trim(char *s)
 456 {
 457-	size_t len;
 458+        size_t len;
 459 
 460-	while (isspace(*s))
 461-		s++;
 462+        while (isspace(*s))
 463+                s++;
 464 
 465-	for (len = strlen(s); len > 0 && isspace(s[len-1]); --len)
 466-		s[len-1] = '\0';
 467+        for (len = strlen(s); len > 0 && isspace(s[len-1]); --len)
 468+                s[len-1] = '\0';
 469 
 470-	return s;
 471+        return s;
 472 }
 473 
 474 static void
 475 include(char *s)
 476 {
 477-	FILE *fp;
 478-	char *fil, *t;
 479+        FILE *fp;
 480+        char *fil, *t, *end;
 481+
 482+        s = trim(s);
 483+        if (*s == '<' || *s == '"') {
 484+                char delim = (*s == '<') ? '>' : '"';
 485+                s++;
 486+                end = strchr(s, delim);
 487+                if (end)
 488+                        *end = '\0';
 489+        }
 490+        fil = expandstring(s, NULL, getloc());
 491+
 492+        t = trim(fil);
 493+        if (strlen(t) != 0) {
 494+                debug("including '%s'", t);
 495+                if ((fp = fopen(t, "r")) == NULL)
 496+                        error("opening %s:%s", t, strerror(errno));
 497+                push(FTFILE, fp, t, 0);
 498+        }
 499+
 500+        free(fil);
 501+}
 502+
 503+static void
 504+sinclude(char *s)
 505+{
 506+        FILE *fp;
 507+        char *fil, *t, *end;
 508+
 509+        s = trim(s);
 510+        if (*s == '<' || *s == '"') {
 511+                char delim = (*s == '<') ? '>' : '"';
 512+                s++;
 513+                end = strchr(s, delim);
 514+                if (end)
 515+                        *end = '\0';
 516+        }
 517+        fil = expandstring(s, NULL, getloc());
 518+
 519+        t = trim(fil);
 520+        if (strlen(t) != 0) {
 521+                debug("trying to include '%s'", t);
 522+                if ((fp = fopen(t, "r")) != NULL)
 523+                        push(FTFILE, fp, t, 0);
 524+                else
 525+                        debug("skipping missing include %s", t);
 526+        }
 527+
 528+        free(fil);
 529+}
 530+
 531+#define MAXCOND 32
 532+static struct {
 533+        int active;
 534+        int matched;
 535+        int parent_active;
 536+} condstack[MAXCOND];
 537+static int conddepth = 0;
 538+
 539+static int
 540+cond_active(void)
 541+{
 542+        if (conddepth == 0)
 543+                return 1;
 544+        return condstack[conddepth].active && condstack[conddepth].parent_active;
 545+}
 546+
 547+static void
 548+cond_if(int truth)
 549+{
 550+        int parent;
 551+        if (conddepth >= MAXCOND)
 552+                error("too many nested .if directives");
 553+        parent = cond_active();
 554+        conddepth++;
 555+        condstack[conddepth].parent_active = parent;
 556+        condstack[conddepth].matched = truth;
 557+        condstack[conddepth].active = truth;
 558+}
 559+
 560+static void
 561+cond_elif(int truth)
 562+{
 563+        if (conddepth == 0)
 564+                error(".elif without .if");
 565+        if (condstack[conddepth].matched)
 566+                condstack[conddepth].active = 0;
 567+        else {
 568+                condstack[conddepth].matched = condstack[conddepth].matched || truth;
 569+                condstack[conddepth].active = truth;
 570+        }
 571+}
 572 
 573-	s = trim(s);
 574-	fil = expandstring(s, NULL, getloc());
 575+static void
 576+cond_else(void)
 577+{
 578+        if (conddepth == 0)
 579+                error(".else without .if");
 580+        condstack[conddepth].active = !condstack[conddepth].matched;
 581+        condstack[conddepth].matched = 1;
 582+}
 583 
 584-	t = trim(fil);
 585-	if (strlen(t) != 0) {
 586-		debug("including '%s'", t);
 587-		if ((fp = fopen(t, "r")) == NULL)
 588-			error("opening %s:%s", t, strerror(errno));
 589-		push(FTFILE, fp, t, 0);
 590-	}
 591+static void
 592+cond_endif(void)
 593+{
 594+        if (conddepth == 0)
 595+                error(".endif without .if");
 596+        conddepth--;
 597+}
 598 
 599-	free(fil);
 600+static int
 601+eval_if(char *expr)
 602+{
 603+        char *s, *p, *var, *val, *end;
 604+        int neg = 0, result;
 605+
 606+        s = trim(expr);
 607+        if (!*s)
 608+                return 0;
 609+
 610+        while (*s == '(') {
 611+                end = s + strlen(s);
 612+                if (end > s && end[-1] == ')') end[-1] = '\0';
 613+                s++;
 614+                s = trim(s);
 615+        }
 616+
 617+        if (*s == '!') {
 618+                neg = 1;
 619+                s++;
 620+                s = trim(s);
 621+        }
 622+
 623+        if (strncmp(s, "defined", 7) == 0 && (s[7] == '(' || s[7] == ' ')) {
 624+                var = trim(s + 7);
 625+                if (*var == '(') var++;
 626+                end = var + strlen(var);
 627+                if (end > var && end[-1] == ')') end[-1] = '\0';
 628+                var = trim(var);
 629+                result = getmacro(var)[0] != '\0';
 630+                return neg ? !result : result;
 631+        }
 632+
 633+        if (strncmp(s, "make", 4) == 0 && (s[4] == '(' || s[4] == ' ')) {
 634+                var = trim(s + 4);
 635+                if (*var == '(') var++;
 636+                end = var + strlen(var);
 637+                if (end > var && end[-1] == ')') end[-1] = '\0';
 638+                var = trim(var);
 639+                result = getmacro(var)[0] != '\0';
 640+                return neg ? !result : result;
 641+        }
 642+
 643+        {
 644+                char *expanded = expandstring(s, NULL, getloc());
 645+                s = expanded;
 646+        }
 647+
 648+        p = strstr(s, "==");
 649+        if (!p) p = strstr(s, "!=");
 650+        if (p) {
 651+                int eq = (p[1] == '=');
 652+                *p = '\0';
 653+                val = trim(p + 2);
 654+                var = trim(s);
 655+                {
 656+                        char *ev = expandstring(var, NULL, getloc());
 657+                        result = strcmp(ev, val) == 0;
 658+                        free(ev);
 659+                }
 660+                if (!eq) result = !result;
 661+                free(s);
 662+                return neg ? !result : result;
 663+        }
 664+
 665+        /* bare expression: true if non-empty after expansion */
 666+        result = s[0] != '\0';
 667+        free(s);
 668+        return neg ? !result : result;
 669 }
 670 
 671 static char *
 672 nextline(void)
 673 {
 674-	int c;
 675-	FILE *fp;
 676-	char *s, *lim;
 677+        int c;
 678+        FILE *fp;
 679+        char *s, *lim;
 680 
 681-	assert(input->type == FTFILE);
 682+        assert(input->type == FTFILE);
 683 
 684 repeat:
 685-	fp = input->fp;
 686-	if (!fp || feof(fp))
 687-		return NULL;
 688-
 689-	lim = &input->buf[input->siz];
 690-	for (s = input->buf; s < lim; *s++ = c) {
 691-		c = getc(fp);
 692-		if (c == '\n' || c == EOF) {
 693-			input->loc.lineno++;
 694-			*s++ = '\n';
 695-			break;
 696-		}
 697-		if (c > UCHAR_MAX || c < 0)
 698-			error("invalid character '%c' (%d)", c, c);
 699-	}
 700-
 701-
 702-	if (s == lim)
 703-		error("too long line");
 704-	if (ferror(fp))
 705-		error(strerror(errno));
 706-	*s = '\0';
 707-
 708-	if (!strcmp(input->buf, ""))
 709-		goto repeat;
 710-
 711-	if (!strncmp(input->buf, "include", 7) && isblank(input->buf[7])) {
 712-		input->pos = input->siz;
 713-		include(input->buf+7);
 714-		goto repeat;
 715-	}
 716-
 717-	input->pos = 0;
 718-
 719-
 720-	return input->buf;
 721+        fp = input->fp;
 722+        if (!fp || feof(fp))
 723+                return NULL;
 724+
 725+        lim = &input->buf[input->siz];
 726+        for (s = input->buf; s < lim; *s++ = c) {
 727+                c = getc(fp);
 728+                if (c == '\n' || c == EOF) {
 729+                        input->loc.lineno++;
 730+                        *s++ = '\n';
 731+                        break;
 732+                }
 733+                if (c > UCHAR_MAX || c < 0)
 734+                        error("invalid character '%c' (%d)", c, c);
 735+        }
 736+
 737+
 738+        if (s == lim)
 739+                error("too long line");
 740+        if (ferror(fp))
 741+                error(strerror(errno));
 742+        *s = '\0';
 743+
 744+        if (!strcmp(input->buf, ""))
 745+                goto repeat;
 746+
 747+        /* bmake style .include / .sinclude / .-include */
 748+        if (input->buf[0] == '.') {
 749+                char *d = input->buf + 1;
 750+                size_t dl;
 751+                /* strip trailing whitespace/newline so strcmp works */
 752+                dl = strlen(d);
 753+                while (dl > 0 && isspace((unsigned char)d[dl-1]))
 754+                        d[--dl] = '\0';
 755+                if (strncmp(d, "include", 7) == 0 && isblank(d[7])) {
 756+                        input->pos = input->siz;
 757+                        if (cond_active()) include(d + 7);
 758+                        goto repeat;
 759+                }
 760+                if (strncmp(d, "sinclude", 8) == 0 && isblank(d[8])) {
 761+                        input->pos = input->siz;
 762+                        if (cond_active()) sinclude(d + 8);
 763+                        goto repeat;
 764+                }
 765+                if (strncmp(d, "-include", 8) == 0 && isblank(d[8])) {
 766+                        input->pos = input->siz;
 767+                        if (cond_active()) sinclude(d + 8);
 768+                        goto repeat;
 769+                }
 770+                if (strncmp(d, "optinclude", 10) == 0 && isblank(d[10])) {
 771+                        input->pos = input->siz;
 772+                        if (cond_active()) sinclude(d + 10);
 773+                        goto repeat;
 774+                }
 775+                /* conditionals */
 776+                if (strncmp(d, "if", 2) == 0 && (isblank(d[2]) || d[2] == '\0')) {
 777+                        if (cond_active()) {
 778+                                if (d[2] == '\0')
 779+                                        cond_if(eval_if(""));
 780+                                else
 781+                                        cond_if(eval_if(d + 3));
 782+                        } else {
 783+                                cond_if(0);
 784+                        }
 785+                        goto repeat;
 786+                }
 787+                if (strncmp(d, "ifdef", 5) == 0 && (isblank(d[5]) || d[5] == '\0')) {
 788+                        if (cond_active()) {
 789+                                char *v = trim(d[5] ? d + 6 : "");
 790+                                cond_if(getmacro(v)[0] != '\0');
 791+                        } else {
 792+                                cond_if(0);
 793+                        }
 794+                        goto repeat;
 795+                }
 796+                if (strncmp(d, "ifndef", 6) == 0 && (isblank(d[6]) || d[6] == '\0')) {
 797+                        if (cond_active()) {
 798+                                char *v = trim(d[6] ? d + 7 : "");
 799+                                cond_if(getmacro(v)[0] == '\0');
 800+                        } else {
 801+                                cond_if(0);
 802+                        }
 803+                        goto repeat;
 804+                }
 805+                if (strncmp(d, "elif", 4) == 0 && (isblank(d[4]) || d[4] == '\0')) {
 806+                        if (condstack[conddepth].parent_active)
 807+                                cond_elif(eval_if(d[4] ? d + 5 : ""));
 808+                        else
 809+                                cond_elif(0);
 810+                        goto repeat;
 811+                }
 812+                if (strcmp(d, "else") == 0) {
 813+                        cond_else();
 814+                        goto repeat;
 815+                }
 816+                if (strcmp(d, "endif") == 0) {
 817+                        cond_endif();
 818+                        goto repeat;
 819+                }
 820+                if (strncmp(d, "error", 5) == 0 && isblank(d[5])) {
 821+                        if (cond_active())
 822+                                error("%s", trim(d + 6));
 823+                        goto repeat;
 824+                }
 825+                if (strncmp(d, "warning", 7) == 0 && isblank(d[7])) {
 826+                        if (cond_active())
 827+                                warning("%s", trim(d + 8));
 828+                        goto repeat;
 829+                }
 830+        }
 831+
 832+        /* POSIX include */
 833+        if (!strncmp(input->buf, "include", 7) && isblank(input->buf[7])) {
 834+                input->pos = input->siz;
 835+                if (cond_active()) include(input->buf+7);
 836+                goto repeat;
 837+        }
 838+
 839+        /* sinclude / -include (GNU/POSIX style without dot) */
 840+        if ((!strncmp(input->buf, "sinclude", 8) && isblank(input->buf[8])) ||
 841+            (!strncmp(input->buf, "-include", 8) && isblank(input->buf[8]))) {
 842+                input->pos = input->siz;
 843+                if (cond_active()) sinclude(input->buf + 8);
 844+                goto repeat;
 845+        }
 846+
 847+        /* if we are inside an inactive conditional branch, skip this line */
 848+        if (!cond_active()) {
 849+                input->pos = input->siz;
 850+                goto repeat;
 851+        }
 852+
 853+        input->pos = 0;
 854+
 855+
 856+        return input->buf;
 857 }
 858 
 859 static int
 860 empty(struct input *ip)
 861 {
 862-	return ip->pos == ip->siz || ip->buf[ip->pos] == '\0';
 863+        return ip->pos == ip->siz || ip->buf[ip->pos] == '\0';
 864 }
 865 
 866 static int
 867 moreinput(void)
 868 {
 869-	while (input) {
 870-		if (!empty(input))
 871-			break;
 872-
 873-		switch (input->type) {
 874-		case FTEXPAN:
 875-			pop();
 876-			break;
 877-		case FTFILE:
 878-			if (!nextline())
 879-				pop();
 880-			break;
 881-		}
 882-	}
 883-
 884-	return input != NULL;
 885+        while (input) {
 886+                if (!empty(input))
 887+                        break;
 888+
 889+                switch (input->type) {
 890+                case FTEXPAN:
 891+                        pop();
 892+                        break;
 893+                case FTFILE:
 894+                        if (!nextline())
 895+                                pop();
 896+                        break;
 897+                }
 898+        }
 899+
 900+        return input != NULL;
 901 }
 902 
 903 static int
 904 nextc(void)
 905 {
 906-	if (!moreinput())
 907-		return EOF;
 908+        if (!moreinput())
 909+                return EOF;
 910 
 911-	return input->buf[input->pos++];
 912+        return input->buf[input->pos++];
 913 }
 914 
 915 /*
 916@@ -415,284 +680,302 @@ nextc(void)
 917 static int
 918 ahead(void)
 919 {
 920-	return input->buf[input->pos];
 921+        return input->buf[input->pos];
 922 }
 923 
 924 static int
 925 back(int c)
 926 {
 927-	if (c == EOF)
 928-		return c;
 929-	assert(input->pos > 0);
 930-	return input->buf[--input->pos] = c;
 931+        if (c == EOF)
 932+                return c;
 933+        assert(input->pos > 0);
 934+        return input->buf[--input->pos] = c;
 935 }
 936 
 937 static void
 938 comment(void)
 939 {
 940-	int c;
 941+        int c;
 942 
 943-	while ((c = nextc()) != EOF && c != '\n') {
 944-		if (c == '\\' && nextc() == EOF)
 945-			break;
 946-	}
 947+        while ((c = nextc()) != EOF && c != '\n') {
 948+                if (c == '\\' && nextc() == EOF)
 949+                        break;
 950+        }
 951 }
 952 
 953 static void
 954 skipspaces(void)
 955 {
 956-	int c;
 957+        int c;
 958 
 959-	for (c = nextc(); c == ' ' || c == '\t'; c = nextc())
 960-		;
 961-	back(c);
 962+        for (c = nextc(); c == ' ' || c == '\t'; c = nextc())
 963+                ;
 964+        back(c);
 965 }
 966 
 967 static int
 968 validchar(int c)
 969 {
 970-	if (c == EOF)
 971-		return 0;
 972-	return c == '.' || c == '/' || c == '_' || c == '-' || isalnum(c);
 973+        if (c == EOF)
 974+                return 0;
 975+        return c == '.' || c == '/' || c == '_' || c == '-' || isalnum(c);
 976 }
 977 
 978 static char *
 979 expandmacro(char *name)
 980 {
 981-	char *s;
 982+        char *s;
 983 
 984-	s = expandstring(getmacro(name), NULL, getloc());
 985-	debug("macro %s expanded to '%s'", name, s);
 986+        s = expandstring(getmacro(name), NULL, getloc());
 987+        debug("macro %s expanded to '%s'", name, s);
 988 
 989-	return s;
 990+        return s;
 991 }
 992 
 993 static void
 994 replace(char *line, char *repl, char *to)
 995 {
 996-	int siz, at, len, replsiz, tosiz, pos;
 997-	char *oline, *cur, *buf;
 998-
 999-	debug("replacing '%s', with '%s' to '%s'", line, repl, to);
1000-	oline = line;
1001-	tosiz = strlen(to);
1002-	replsiz = strlen(repl);
1003-
1004-	buf = NULL;
1005-	for (pos = 0; *line; pos += siz) {
1006-		cur = NULL;
1007-		siz = 0;
1008-
1009-		for (siz = 0; *line == ' ' || *line == '\t'; ++siz) {
1010-			cur = erealloc(cur, siz+1);
1011-			cur[siz] = *line++;
1012-		}
1013-
1014-		len = strcspn(line, " \t");
1015-		at = len - replsiz;
1016-		if (at < 0 || memcmp(line + at, repl, replsiz)) {
1017-			cur = erealloc(cur, siz + len);
1018-			memcpy(cur + siz, line, len);
1019-			siz += len;
1020-		} else {
1021-			cur = erealloc(cur, siz + at + tosiz);
1022-			memcpy(cur + siz, line, at);
1023-			memcpy(cur + siz + at, to, tosiz);
1024-			siz += at + tosiz;
1025-		}
1026-
1027-		line += len;
1028-		buf = erealloc(buf, pos + siz);
1029-		memcpy(buf + pos, cur, siz);
1030-		free(cur);
1031-	}
1032-
1033-	if (pos > 0) {
1034-		buf = erealloc(buf, pos + 1);
1035-		buf[pos] = '\0';
1036-		debug("\treplace '%s' with '%s'", oline, buf);
1037-		push(FTEXPAN, buf);
1038-	}
1039-
1040-	free(buf);
1041+        int siz, at, len, replsiz, tosiz, pos;
1042+        char *oline, *cur, *buf;
1043+
1044+        debug("replacing '%s', with '%s' to '%s'", line, repl, to);
1045+        oline = line;
1046+        tosiz = strlen(to);
1047+        replsiz = strlen(repl);
1048+
1049+        buf = NULL;
1050+        for (pos = 0; *line; pos += siz) {
1051+                cur = NULL;
1052+                siz = 0;
1053+
1054+                for (siz = 0; *line == ' ' || *line == '\t'; ++siz) {
1055+                        cur = erealloc(cur, siz+1);
1056+                        cur[siz] = *line++;
1057+                }
1058+
1059+                len = strcspn(line, " \t");
1060+                at = len - replsiz;
1061+                if (at < 0 || memcmp(line + at, repl, replsiz)) {
1062+                        cur = erealloc(cur, siz + len);
1063+                        memcpy(cur + siz, line, len);
1064+                        siz += len;
1065+                } else {
1066+                        cur = erealloc(cur, siz + at + tosiz);
1067+                        memcpy(cur + siz, line, at);
1068+                        memcpy(cur + siz + at, to, tosiz);
1069+                        siz += at + tosiz;
1070+                }
1071+
1072+                line += len;
1073+                buf = erealloc(buf, pos + siz);
1074+                memcpy(buf + pos, cur, siz);
1075+                free(cur);
1076+        }
1077+
1078+        if (pos > 0) {
1079+                buf = erealloc(buf, pos + 1);
1080+                buf[pos] = '\0';
1081+                debug("\treplace '%s' with '%s'", oline, buf);
1082+                push(FTEXPAN, buf);
1083+        }
1084+
1085+        free(buf);
1086 }
1087 
1088 static void
1089 expandsimple(Target *tp)
1090 {
1091-	char *s;
1092-	Target **p;
1093-	int len, c;
1094-
1095-	switch (c = nextc()) {
1096-	case '@':
1097-		if (!tp || !tp->target)
1098-			return;
1099-		push(FTEXPAN, tp->target);
1100-		break;
1101-	case '<':
1102-		if (!tp || !tp->req)
1103-			return;
1104-		push(FTEXPAN, tp->req);
1105-		break;
1106-	case '*':
1107-		if (!tp || !tp->target)
1108-			return;
1109-		s = strrchr(tp->target, '.');
1110-		if (!s) {
1111-			push(FTEXPAN, tp->target);
1112-			return;
1113-		}
1114-
1115-		len = s - tp->target;
1116-		s = emalloc(len+1);
1117-		memcpy(s, tp->target, len);
1118-		s[len] = '\0';
1119-		push(FTEXPAN, s);
1120-		free(s);
1121-		break;
1122-	case '?':
1123-		if (!tp)
1124-			return;
1125-
1126-		if (tp->req && stamp(tp->req) > tp->stamp) {
1127-			push(FTEXPAN, " ");
1128-			push(FTEXPAN, tp->req);
1129-		}
1130-
1131-		for (p = tp->deps; p && *p; ++p) {
1132-			if (stamp((*p)->name) > tp->stamp) {
1133-				push(FTEXPAN, " ");
1134-				push(FTEXPAN, (*p)->name);
1135-			}
1136-		}
1137-		break;
1138-	default:
1139-		token[0] = c;
1140-		token[1] = '\0';
1141-		s = expandmacro(token);
1142-		push(FTEXPAN, s);
1143-		free(s);
1144-		break;
1145-	}
1146+        char *s;
1147+        Target **p;
1148+        int len, c, first;
1149+
1150+        switch (c = nextc()) {
1151+        case '@':
1152+                if (!tp || !tp->target)
1153+                        return;
1154+                push(FTEXPAN, tp->target);
1155+                break;
1156+        case '<':
1157+                if (!tp || !tp->req)
1158+                        return;
1159+                push(FTEXPAN, tp->req);
1160+                break;
1161+        case '*':
1162+                if (!tp || !tp->target)
1163+                        return;
1164+                s = strrchr(tp->target, '.');
1165+                if (!s) {
1166+                        push(FTEXPAN, tp->target);
1167+                        return;
1168+                }
1169+
1170+                len = s - tp->target;
1171+                s = emalloc(len+1);
1172+                memcpy(s, tp->target, len);
1173+                s[len] = '\0';
1174+                push(FTEXPAN, s);
1175+                free(s);
1176+                break;
1177+        case '?':
1178+                if (!tp)
1179+                        return;
1180+
1181+                if (tp->req && stamp(tp->req) > tp->stamp) {
1182+                        push(FTEXPAN, " ");
1183+                        push(FTEXPAN, tp->req);
1184+                }
1185+
1186+                for (p = tp->deps; p && *p; ++p) {
1187+                        if (stamp((*p)->name) > tp->stamp) {
1188+                                push(FTEXPAN, " ");
1189+                                push(FTEXPAN, (*p)->name);
1190+                        }
1191+                }
1192+                break;
1193+        case '>':
1194+        case '^':
1195+                if (!tp)
1196+                        return;
1197+                first = 1;
1198+                if (tp->req) {
1199+                        push(FTEXPAN, tp->req);
1200+                        first = 0;
1201+                }
1202+                for (p = tp->deps; p && *p; ++p) {
1203+                        if (!first)
1204+                                push(FTEXPAN, " ");
1205+                        push(FTEXPAN, (*p)->name);
1206+                        first = 0;
1207+                }
1208+                break;
1209+        default:
1210+                token[0] = c;
1211+                token[1] = '\0';
1212+                s = expandmacro(token);
1213+                push(FTEXPAN, s);
1214+                free(s);
1215+                break;
1216+        }
1217 }
1218 
1219 static int
1220 internal(int ch)
1221 {
1222-	switch (ch) {
1223-	case '@':
1224-	case '?':
1225-	case '*':
1226-	case '<':
1227-		return 1;
1228-	default:
1229-		return 0;
1230-	}
1231+        switch (ch) {
1232+        case '@':
1233+        case '?':
1234+        case '*':
1235+        case '<':
1236+        case '>':
1237+        case '^':
1238+                return 1;
1239+        default:
1240+                return 0;
1241+        }
1242 }
1243 
1244 static void
1245 expansion(Target *tp)
1246 {
1247-	int delim, c, repli, toi, namei, st;
1248-	char name[MAXTOKEN], repl[MAXREPL], to[MAXREPL];
1249-	char *s, *erepl;
1250-
1251-	c = nextc();
1252-	if (c == '(')
1253-		delim = ')';
1254-	else if (c == '{')
1255-		delim = '}';
1256-	else
1257-		delim = 0;
1258-
1259-	if (!delim) {
1260-		back(c);
1261-		expandsimple(tp);
1262-		return;
1263-	}
1264-
1265-	s = NULL;
1266-	namei = repli = toi = 0;
1267-	st = STBEGIN;
1268-
1269-	while (st != STEND && (c = nextc()) != EOF) {
1270-		switch (st) {
1271-		case STBEGIN:
1272-			if (c == ':') {
1273-				st = STREPLACE;
1274-				name[namei] = '\0';
1275-				s = expandmacro(name);
1276-				break;
1277-			}
1278-			if (c == delim) {
1279-				name[namei] = '\0';
1280-				s = expandmacro(name);
1281-				goto no_replace;
1282-			}
1283-			if (namei == MAXTOKEN-1)
1284-				error("expansion text too long");
1285-
1286-			if (namei == 0 && internal(c)) {
1287-				name[namei++] = '$';
1288-				name[namei++] = c;
1289-				name[namei] = '\0';
1290-				st = STINTERNAL;
1291-				s = expandstring(name, tp, getloc());
1292-				break;
1293-			}
1294-
1295-			if (!validchar(c))
1296-				error("invalid macro name in expansion");
1297-			name[namei++] = c;
1298-			break;
1299-		case STINTERNAL:
1300-			if (c == delim)
1301-				goto no_replace;
1302-			if (c != ':')
1303-				error("invalid internal macro in expansion");
1304-			st = STREPLACE;
1305-			break;
1306-		case STREPLACE:
1307-			if (c == '=') {
1308-				st = STTO;
1309-				break;
1310-			}
1311-			if (c == delim)
1312-				error("invalid replacement pattern in expansion");
1313-			if (repli == MAXREPL-1)
1314-				error("macro replacement too big");
1315-			repl[repli++] = c;
1316-			break;
1317-		case STTO:
1318-			if (c == delim) {
1319-				st = STEND;
1320-				break;
1321-			}
1322-
1323-			if (toi == MAXREPL-1)
1324-				error("macro substiturion too big");
1325-			to[toi++] = c;
1326-			break;
1327-		}
1328-	}
1329-
1330-	if (c == EOF)
1331-		error("found eof while parsing expansion");
1332-
1333-	repl[repli] = '\0';
1334-	to[toi] = '\0';
1335-
1336-	erepl = expandstring(repl, tp, getloc());
1337-	replace(s, erepl, to);
1338-
1339-	free(erepl);
1340-	free(s);
1341-	return;
1342+        int delim, c, repli, toi, namei, st;
1343+        char name[MAXTOKEN], repl[MAXREPL], to[MAXREPL];
1344+        char *s, *erepl;
1345+
1346+        c = nextc();
1347+        if (c == '(')
1348+                delim = ')';
1349+        else if (c == '{')
1350+                delim = '}';
1351+        else
1352+                delim = 0;
1353+
1354+        if (!delim) {
1355+                back(c);
1356+                expandsimple(tp);
1357+                return;
1358+        }
1359+
1360+        s = NULL;
1361+        namei = repli = toi = 0;
1362+        st = STBEGIN;
1363+
1364+        while (st != STEND && (c = nextc()) != EOF) {
1365+                switch (st) {
1366+                case STBEGIN:
1367+                        if (c == ':') {
1368+                                st = STREPLACE;
1369+                                name[namei] = '\0';
1370+                                s = expandmacro(name);
1371+                                break;
1372+                        }
1373+                        if (c == delim) {
1374+                                name[namei] = '\0';
1375+                                s = expandmacro(name);
1376+                                goto no_replace;
1377+                        }
1378+                        if (namei == MAXTOKEN-1)
1379+                                error("expansion text too long");
1380+
1381+                        if (namei == 0 && internal(c)) {
1382+                                name[namei++] = '$';
1383+                                name[namei++] = c;
1384+                                name[namei] = '\0';
1385+                                st = STINTERNAL;
1386+                                s = expandstring(name, tp, getloc());
1387+                                break;
1388+                        }
1389+
1390+                        if (!validchar(c))
1391+                                error("invalid macro name in expansion");
1392+                        name[namei++] = c;
1393+                        break;
1394+                case STINTERNAL:
1395+                        if (c == delim)
1396+                                goto no_replace;
1397+                        if (c != ':')
1398+                                error("invalid internal macro in expansion");
1399+                        st = STREPLACE;
1400+                        break;
1401+                case STREPLACE:
1402+                        if (c == '=') {
1403+                                st = STTO;
1404+                                break;
1405+                        }
1406+                        if (c == delim)
1407+                                error("invalid replacement pattern in expansion");
1408+                        if (repli == MAXREPL-1)
1409+                                error("macro replacement too big");
1410+                        repl[repli++] = c;
1411+                        break;
1412+                case STTO:
1413+                        if (c == delim) {
1414+                                st = STEND;
1415+                                break;
1416+                        }
1417+
1418+                        if (toi == MAXREPL-1)
1419+                                error("macro substiturion too big");
1420+                        to[toi++] = c;
1421+                        break;
1422+                }
1423+        }
1424+
1425+        if (c == EOF)
1426+                error("found eof while parsing expansion");
1427+
1428+        repl[repli] = '\0';
1429+        to[toi] = '\0';
1430+
1431+        erepl = expandstring(repl, tp, getloc());
1432+        replace(s, erepl, to);
1433+
1434+        free(erepl);
1435+        free(s);
1436+        return;
1437 
1438 no_replace:
1439-	push(FTEXPAN, s);
1440-	free(s);
1441+        push(FTEXPAN, s);
1442+        free(s);
1443 }
1444 
1445 /*
1446@@ -705,330 +988,420 @@ no_replace:
1447 char *
1448 expandstring(char *line, Target *tp, struct loc *loc)
1449 {
1450-	int c, n;
1451-	char *s;
1452-	struct input *ip = input;
1453-
1454-	input = NULL;
1455-	push(FTFILE, NULL, loc->fname, loc->lineno);
1456-	push(FTEXPAN, line);
1457-
1458-	n = 0;
1459-	s = NULL;
1460-	while ((c = nextc()) != EOF) {
1461-		if (c != '$') {
1462-			s = erealloc(s, ++n);
1463-			s[n-1] = c;
1464-			continue;
1465-		}
1466-
1467-		if ((c = nextc()) == '$') {
1468-			s = erealloc(s, n += 2);
1469-			s[n-2] = '$';
1470-			s[n-1] = '$';
1471-		} else {
1472-			back(c);
1473-			expansion(tp);
1474-		}
1475-	}
1476-
1477-	s = erealloc(s, n+1);
1478-	s[n] = '\0';
1479-	input = ip;
1480-
1481-	return s;
1482+        int c, n;
1483+        char *s;
1484+        struct input *ip = input;
1485+
1486+        input = NULL;
1487+        push(FTFILE, NULL, loc->fname, loc->lineno);
1488+        push(FTEXPAN, line);
1489+
1490+        n = 0;
1491+        s = NULL;
1492+        while ((c = nextc()) != EOF) {
1493+                if (c != '$') {
1494+                        s = erealloc(s, ++n);
1495+                        s[n-1] = c;
1496+                        continue;
1497+                }
1498+
1499+                if ((c = nextc()) == '$') {
1500+                        s = erealloc(s, n += 2);
1501+                        s[n-2] = '$';
1502+                        s[n-1] = '$';
1503+                } else {
1504+                        back(c);
1505+                        expansion(tp);
1506+                }
1507+        }
1508+
1509+        s = erealloc(s, n+1);
1510+        s[n] = '\0';
1511+        input = ip;
1512+
1513+        return s;
1514 }
1515 
1516 static int
1517 item(void)
1518 {
1519-	int c;
1520-	char *s;
1521-	char buf[MAXTOKEN];
1522-
1523-	for (s = buf; s < &buf[MAXTOKEN] - 1; ) {
1524-		c = nextc();
1525-		if (c == '$' && ahead() != '$')
1526-			expansion(NULL);
1527-		else if (validchar(c))
1528-			*s++ = c;
1529-		else
1530-			break;
1531-	}
1532-	back(c);
1533-
1534-	if (s >= &buf[MAXTOKEN] - 1)
1535-		error("token too long");
1536-	if (s == buf)
1537-		error("invalid empty token");
1538-	*s++ = '\0';
1539-	memcpy(token, buf, s - buf);
1540-
1541-	return ITEM;
1542+        int c;
1543+        char *s;
1544+        char buf[MAXTOKEN];
1545+
1546+        for (s = buf; s < &buf[MAXTOKEN] - 1; ) {
1547+                c = nextc();
1548+                if (c == '$' && ahead() != '$')
1549+                        expansion(NULL);
1550+                else if (validchar(c))
1551+                        *s++ = c;
1552+                else
1553+                        break;
1554+        }
1555+        back(c);
1556+
1557+        if (s >= &buf[MAXTOKEN] - 1)
1558+                error("token too long");
1559+        if (s == buf)
1560+                error("invalid empty token");
1561+        *s++ = '\0';
1562+        memcpy(token, buf, s - buf);
1563+
1564+        return ITEM;
1565 }
1566 
1567 static int
1568 next(void)
1569 {
1570-	int c;
1571+        int c;
1572 
1573 repeat:
1574-	/*
1575-	 * It is better to avoid skipspaces() here, because
1576-	 * it can generate the need for 2 calls to back(),
1577-	 * and we need the character anyway.
1578-	 */
1579-	c = nextc();
1580-	if (c == ' ' || c == '\t')
1581-		goto repeat;
1582-
1583-	if (c == '\\') {
1584-		if ((c = nextc()) == '\n')
1585-			goto repeat;
1586-		back(c);
1587-		c = '\\';
1588-	}
1589-
1590-	switch (c) {
1591-	case EOF:
1592-		strcpy(token, "<EOF>");
1593-		tok = EOF;
1594-		break;
1595-	case '$':
1596-		if ((c = nextc()) == '$')
1597-			goto single;
1598-		back(c);
1599-		expansion(NULL);
1600-		goto repeat;
1601-	case '#':
1602-		comment();
1603-		c = '\n';
1604-		/* fallthrough */
1605-	case ';':
1606-	case ':':
1607-	case '=':
1608-	case '\n':
1609-	single:
1610-		token[0] = c;
1611-		token[1] = '\0';
1612-		tok = c;
1613-		break;
1614-	default:
1615-		if (!validchar(c))
1616-			error("unexpected character '%c'", c);
1617-		back(c);
1618-		tok = item();
1619-		break;
1620-	}
1621-
1622-	return tok;
1623+        /*
1624+         * It is better to avoid skipspaces() here, because
1625+         * it can generate the need for 2 calls to back(),
1626+         * and we need the character anyway.
1627+         */
1628+        c = nextc();
1629+        if (c == ' ' || c == '\t')
1630+                goto repeat;
1631+
1632+        if (c == '\\') {
1633+                if ((c = nextc()) == '\n')
1634+                        goto repeat;
1635+                back(c);
1636+                c = '\\';
1637+        }
1638+
1639+        switch (c) {
1640+        case EOF:
1641+                strcpy(token, "<EOF>");
1642+                tok = EOF;
1643+                break;
1644+        case '$':
1645+                if ((c = nextc()) == '$')
1646+                        goto single;
1647+                back(c);
1648+                expansion(NULL);
1649+                goto repeat;
1650+        case '#':
1651+                comment();
1652+                c = '\n';
1653+                /* fallthrough */
1654+        case ';':
1655+        case ':':
1656+        case '=':
1657+        case '\n':
1658+        single:
1659+                token[0] = c;
1660+                token[1] = '\0';
1661+                tok = c;
1662+                break;
1663+        case '+':
1664+                if (nextc() == '=') {
1665+                        token[0] = '+';
1666+                        token[1] = '=';
1667+                        token[2] = '\0';
1668+                        tok = '+';
1669+                        break;
1670+                }
1671+                error("unexpected character '+'");
1672+        case '!':
1673+                if (nextc() == '=') {
1674+                        token[0] = '!';
1675+                        token[1] = '=';
1676+                        token[2] = '\0';
1677+                        tok = '!';
1678+                        break;
1679+                }
1680+                error("unexpected character '!'");
1681+        default:
1682+                if (!validchar(c))
1683+                        error("unexpected character '%c'", c);
1684+                back(c);
1685+                tok = item();
1686+                break;
1687+        }
1688+
1689+        return tok;
1690 }
1691 
1692 static char *
1693 readmacrodef(void)
1694 {
1695-	int n, c;
1696-	char *line;
1697-
1698-	n = 0;
1699-	line = NULL;
1700-	while ((c = nextc()) != EOF) {
1701-		line = erealloc(line, n+1);
1702-		if (c == '\n')
1703-			break;
1704-		if (c == '#') {
1705-			comment();
1706-			break;
1707-		}
1708-		if (c == '\\') {
1709-			if ((c = nextc()) != '\n') {
1710-				back(c);
1711-				c = '\\';
1712-			} else {
1713-				skipspaces();
1714-				c = ' ';
1715-			}
1716-		}
1717-
1718-		line[n++] = c;
1719-	}
1720-	if (c == EOF)
1721-		error("EOF while looking for end of line");
1722-	line[n] = '\0';
1723-
1724-	return line;
1725+        int n, c;
1726+        char *line;
1727+
1728+        n = 0;
1729+        line = NULL;
1730+        while ((c = nextc()) != EOF) {
1731+                line = erealloc(line, n+1);
1732+                if (c == '\n')
1733+                        break;
1734+                if (c == '#') {
1735+                        comment();
1736+                        break;
1737+                }
1738+                if (c == '\\') {
1739+                        if ((c = nextc()) != '\n') {
1740+                                back(c);
1741+                                c = '\\';
1742+                        } else {
1743+                                skipspaces();
1744+                                c = ' ';
1745+                        }
1746+                }
1747+
1748+                line[n++] = c;
1749+        }
1750+        if (c == EOF)
1751+                error("EOF while looking for end of line");
1752+        line[n] = '\0';
1753+
1754+        return line;
1755 }
1756 
1757 static struct action
1758 readcmd(void)
1759 {
1760-	int n, c;
1761-	struct loc *loc;
1762-	struct action act;
1763-
1764-	skipspaces();
1765-
1766-	loc = getloc();
1767-	act.loc.fname = estrdup(loc->fname);
1768-	act.loc.lineno = loc->lineno;
1769-
1770-	n = 0;
1771-	act.line = NULL;
1772-	while ((c = nextc()) != EOF) {
1773-		act.line = erealloc(act.line, n+1);
1774-		if (c == '\n')
1775-			break;
1776-		if (c == '\\') {
1777-			if ((c = nextc()) == '\n') {
1778-				if ((c = nextc()) != '\t')
1779-					back(c);
1780-				continue;
1781-			}
1782-			back(c);
1783-			c = '\\';
1784-		}
1785-		act.line[n++] = c;
1786-	}
1787-	if (c == EOF)
1788-		error("EOF while looking for end of command");
1789-	act.line[n] = '\0';
1790-
1791-	return act;
1792+        int n, c;
1793+        struct loc *loc;
1794+        struct action act;
1795+
1796+        skipspaces();
1797+
1798+        loc = getloc();
1799+        act.loc.fname = estrdup(loc->fname);
1800+        act.loc.lineno = loc->lineno;
1801+
1802+        n = 0;
1803+        act.line = NULL;
1804+        while ((c = nextc()) != EOF) {
1805+                act.line = erealloc(act.line, n+1);
1806+                if (c == '\n')
1807+                        break;
1808+                if (c == '\\') {
1809+                        if ((c = nextc()) == '\n') {
1810+                                if ((c = nextc()) != '\t')
1811+                                        back(c);
1812+                                continue;
1813+                        }
1814+                        back(c);
1815+                        c = '\\';
1816+                }
1817+                act.line[n++] = c;
1818+        }
1819+        if (c == EOF)
1820+                error("EOF while looking for end of command");
1821+        act.line[n] = '\0';
1822+
1823+        return act;
1824 }
1825 
1826 static void
1827 rule(char *targets[], int ntargets)
1828 {
1829-	int c, i, j, ndeps, nactions;
1830-	struct action *acts;
1831-	char **deps = NULL;
1832-
1833-	if (ntargets == 0)
1834-		error("missing target");
1835-
1836-	for (ndeps = 0; next() == ITEM; ++ndeps) {
1837-		deps = erealloc(deps, (ndeps+1) * sizeof(char *));
1838-		deps[ndeps] = estrdup(token);
1839-	}
1840-
1841-	if (tok != '\n' && tok != ';')
1842-		error("garbage at the end of the line");
1843-
1844-	nactions = 0;
1845-	acts = NULL;
1846-	if (tok == ';') {
1847-		nactions++;
1848-		acts = erealloc(acts, nactions * sizeof(*acts));
1849-		acts[nactions-1] = readcmd();
1850-	}
1851-
1852-	for (;;) {
1853-		if ((c = nextc()) == '#') {
1854-			comment();
1855-			continue;
1856-		}
1857-		if (c != '\t')
1858-			break;
1859-		nactions++;
1860-		acts = erealloc(acts, nactions * sizeof(*acts));
1861-		acts[nactions-1] = readcmd();
1862-	}
1863-	back(c);
1864-
1865-	for (i = 0; i < ntargets; i++) {
1866-		addtarget(targets[i], ndeps);
1867-		for (j = 0; j < ndeps; j++)
1868-			adddep(targets[i], deps[j]);
1869-		if (nactions > 0)
1870-			addrule(targets[i], acts, nactions);
1871-	}
1872-
1873-	for (i = 0; i < ndeps; i++)
1874-		free(deps[i]);
1875-	free(deps);
1876-
1877-	for (i = 0; i < nactions; i++) {
1878-		free(acts[i].line);
1879-		freeloc(&acts[i].loc);
1880-	}
1881-	free(acts);
1882+        int c, i, j, ndeps, nactions;
1883+        struct action *acts;
1884+        char **deps = NULL;
1885+
1886+        if (ntargets == 0)
1887+                error("missing target");
1888+
1889+        for (ndeps = 0; next() == ITEM; ++ndeps) {
1890+                deps = erealloc(deps, (ndeps+1) * sizeof(char *));
1891+                deps[ndeps] = estrdup(token);
1892+        }
1893+
1894+        if (tok != '\n' && tok != ';')
1895+                error("garbage at the end of the line");
1896+
1897+        nactions = 0;
1898+        acts = NULL;
1899+        if (tok == ';') {
1900+                nactions++;
1901+                acts = erealloc(acts, nactions * sizeof(*acts));
1902+                acts[nactions-1] = readcmd();
1903+        }
1904+
1905+        for (;;) {
1906+                if ((c = nextc()) == '#') {
1907+                        comment();
1908+                        continue;
1909+                }
1910+                if (c != '\t')
1911+                        break;
1912+                nactions++;
1913+                acts = erealloc(acts, nactions * sizeof(*acts));
1914+                acts[nactions-1] = readcmd();
1915+        }
1916+        back(c);
1917+
1918+        for (i = 0; i < ntargets; i++) {
1919+                addtarget(targets[i], ndeps);
1920+                for (j = 0; j < ndeps; j++)
1921+                        adddep(targets[i], deps[j]);
1922+                if (nactions > 0)
1923+                        addrule(targets[i], acts, nactions);
1924+        }
1925+
1926+        for (i = 0; i < ndeps; i++)
1927+                free(deps[i]);
1928+        free(deps);
1929+
1930+        for (i = 0; i < nactions; i++) {
1931+                free(acts[i].line);
1932+                freeloc(&acts[i].loc);
1933+        }
1934+        free(acts);
1935 }
1936 
1937 static void
1938 assign(char *macros[], int where, int n)
1939 {
1940-	char *defs;
1941+        char *defs;
1942 
1943-	if (n != 1)
1944-		error("invalid macro definition");
1945+        if (n != 1)
1946+                error("invalid macro definition");
1947 
1948-	skipspaces();
1949-	defs = readmacrodef();
1950-	setmacro(*macros, defs, where, NOEXPORT);
1951-	free(defs);
1952+        skipspaces();
1953+        defs = readmacrodef();
1954+        setmacro(*macros, defs, where, NOEXPORT);
1955+        free(defs);
1956+}
1957+
1958+static void
1959+assign_append(char *macros[], int where, int n)
1960+{
1961+        char *defs, *old, *new;
1962+        size_t olen, dlen;
1963+
1964+        if (n != 1)
1965+                error("invalid macro definition");
1966+
1967+        skipspaces();
1968+        defs = readmacrodef();
1969+        old = getmacro(*macros);
1970+        olen = strlen(old);
1971+        dlen = strlen(defs);
1972+        /* old + " " + defs + '\0' */
1973+        new = emalloc(olen + (olen > 0 ? 1 : 0) + dlen + 1);
1974+        memcpy(new, old, olen);
1975+        if (olen > 0)
1976+                new[olen++] = ' ';
1977+        memcpy(new + olen, defs, dlen);
1978+        new[olen + dlen] = '\0';
1979+        setmacro(*macros, new, where, NOEXPORT);
1980+        free(new);
1981+        free(defs);
1982+}
1983+
1984+static void
1985+assign_shell(char *macros[], int where, int n)
1986+{
1987+        char *cmd, *out;
1988+        FILE *p;
1989+        size_t cap, len;
1990+        int c;
1991+
1992+        if (n != 1)
1993+                error("invalid macro definition");
1994+
1995+        skipspaces();
1996+        cmd = readmacrodef();
1997+        {
1998+                char *expanded = expandstring(cmd, NULL, getloc());
1999+                free(cmd);
2000+                cmd = expanded;
2001+        }
2002+        p = wpopen(cmd, NULL, "r");
2003+        if (!p)
2004+                error("popen: %s", strerror(errno));
2005+        cap = 64;
2006+        out = emalloc(cap);
2007+        len = 0;
2008+        while ((c = getc(p)) != EOF) {
2009+                if (len + 1 >= cap) {
2010+                        cap *= 2;
2011+                        out = erealloc(out, cap);
2012+                }
2013+                if (c == '\n')
2014+                        break;
2015+                out[len++] = c;
2016+        }
2017+        out[len] = '\0';
2018+        wpclose(p);
2019+        setmacro(*macros, out, where, NOEXPORT);
2020+        free(out);
2021+        free(cmd);
2022 }
2023 
2024 void
2025 parseinput(int where)
2026 {
2027-	int i, n;
2028-	char **targets;
2029-
2030-	while (moreinput()) {
2031-		n = 0;
2032-		targets = NULL;
2033-
2034-		next();
2035-		if (tok == '\n')
2036-			continue;
2037-
2038-		while (tok == ITEM) {
2039-			n++;
2040-			targets = erealloc(targets, n * sizeof(char *));
2041-			targets[n-1] = estrdup(token);
2042-			next();
2043-		}
2044-
2045-		switch (tok) {
2046-		case ':':
2047-			rule(targets, n);
2048-			break;
2049-		case '=':
2050-			assign(targets, where, n);
2051-			break;
2052-		default:
2053-			error("unexpected token '%s'(%d)", token, tok);
2054-		}
2055-
2056-		for (i = 0; i < n; i++)
2057-			free(targets[i]);
2058-		free(targets);
2059-	}
2060+        int i, n;
2061+        char **targets;
2062+
2063+        while (moreinput()) {
2064+                n = 0;
2065+                targets = NULL;
2066+
2067+                next();
2068+                if (tok == '\n')
2069+                        continue;
2070+
2071+                while (tok == ITEM) {
2072+                        n++;
2073+                        targets = erealloc(targets, n * sizeof(char *));
2074+                        targets[n-1] = estrdup(token);
2075+                        next();
2076+                }
2077+
2078+                switch (tok) {
2079+                case ':':
2080+                        rule(targets, n);
2081+                        break;
2082+                case '=':
2083+                        assign(targets, where, n);
2084+                        break;
2085+                case '+':
2086+                        assign_append(targets, where, n);
2087+                        break;
2088+                case '!':
2089+                        assign_shell(targets, where, n);
2090+                        break;
2091+                default:
2092+                        error("unexpected token '%s'(%d)", token, tok);
2093+                }
2094+
2095+                for (i = 0; i < n; i++)
2096+                        free(targets[i]);
2097+                free(targets);
2098+        }
2099 }
2100 
2101 int
2102 parse(char *fname)
2103 {
2104-	FILE *fp;
2105+        FILE *fp;
2106 
2107-	if (!fname) {
2108-		fp = stdin;
2109-		fname = "<stdin>";
2110-	} else if ((fp = fopen(fname, "r")) == NULL) {
2111-		return 0;
2112-	}
2113+        if (!fname) {
2114+                fp = stdin;
2115+                fname = "<stdin>";
2116+        } else if ((fp = fopen(fname, "r")) == NULL) {
2117+                return 0;
2118+        }
2119 
2120-	debug("parsing %s", fname);
2121-	push(FTFILE, fp, fname, 0);
2122-	parseinput(MAKEFILE);
2123+        debug("parsing %s", fname);
2124+        push(FTFILE, fp, fname, 0);
2125+        parseinput(MAKEFILE);
2126 
2127-	return 1;
2128+        return 1;
2129 }
2130 
2131 void
2132 inject(char *s)
2133 {
2134-	push(FTFILE, NULL, "<internal>", 0);
2135-	push(FTEXPAN, s);
2136-	parseinput(INTERNAL);
2137+        push(FTFILE, NULL, "<internal>", 0);
2138+        push(FTEXPAN, s);
2139+        parseinput(INTERNAL);
2140 }
+473, -450
   1@@ -14,554 +14,577 @@ static Target *htab[TABSIZ], *deftarget;
   2 void
   3 dumprules(void)
   4 {
   5-	int i;
   6-	Target **pp, **q, *p;
   7-
   8-	for (pp = htab; pp < &htab[TABSIZ]; ++pp) {
   9-		for (p = *pp; p; p = p->next) {
  10-			if (!p->defined)
  11-				continue;
  12-			printf("%s:", p->name);
  13-			for (q = p->deps; q && *q; ++q)
  14-				printf(" %s", (*q)->name);
  15-			putchar('\n');
  16-			for (i = 0; i < p->nactions; i++)
  17-				printf("\t%s\n", p->actions[i].line);
  18-			putchar('\n');
  19-		}
  20-	}
  21+        int i;
  22+        Target **pp, **q, *p;
  23+
  24+        for (pp = htab; pp < &htab[TABSIZ]; ++pp) {
  25+                for (p = *pp; p; p = p->next) {
  26+                        if (!p->defined)
  27+                                continue;
  28+                        printf("%s:", p->name);
  29+                        for (q = p->deps; q && *q; ++q)
  30+                                printf(" %s", (*q)->name);
  31+                        putchar('\n');
  32+                        for (i = 0; i < p->nactions; i++)
  33+                                printf("\t%s\n", p->actions[i].line);
  34+                        putchar('\n');
  35+                }
  36+        }
  37 }
  38 
  39 static Target *
  40 lookup(char *name)
  41 {
  42-	Target *tp;
  43-	int h = hash(name) & (TABSIZ-1);
  44-
  45-	for (tp = htab[h]; tp && strcmp(tp->name, name); tp = tp->next)
  46-		;
  47-
  48-	if (tp)
  49-		return tp;
  50-
  51-	tp = emalloc(sizeof(*tp));
  52-	tp->name = estrdup(name);
  53-	tp->target = tp->name;
  54-	tp->req = NULL;
  55-	tp->ndeps = 0;
  56-	tp->deps = NULL;
  57-	tp->actions = NULL;
  58-	tp->nactions = 0;
  59-	tp->next = htab[h];
  60-	tp->defined = 0;
  61-	htab[h] = tp;
  62-
  63-	return tp;
  64+        Target *tp;
  65+        int h = hash(name) & (TABSIZ-1);
  66+
  67+        for (tp = htab[h]; tp && strcmp(tp->name, name); tp = tp->next)
  68+                ;
  69+
  70+        if (tp)
  71+                return tp;
  72+
  73+        tp = emalloc(sizeof(*tp));
  74+        tp->name = estrdup(name);
  75+        tp->target = tp->name;
  76+        tp->req = NULL;
  77+        tp->ndeps = 0;
  78+        tp->deps = NULL;
  79+        tp->actions = NULL;
  80+        tp->nactions = 0;
  81+        tp->next = htab[h];
  82+        tp->defined = 0;
  83+        htab[h] = tp;
  84+
  85+        return tp;
  86 }
  87 
  88 static void
  89 cleanup(Target *tp)
  90 {
  91-	int sig, precious;
  92-	Target *p, **q;
  93-
  94-	sig = stop;
  95-	printf("make: signal %d arrived\n", sig);
  96-
  97-	precious = 0;
  98-	p = lookup(".PRECIOUS");
  99-	for (q = p->deps; q && *q; q++) {
 100-		if (strcmp((*q)->name, tp->name) == 0) {
 101-			precious = 1;
 102-			break;
 103-		}
 104-	}
 105-
 106-	if (!precious && !nflag && !qflag && !is_dir(tp->name)) {
 107-		printf("make: trying to remove target %s\n", tp->name);
 108-		remove(tp->name);
 109-	}
 110-
 111-	signal(sig, SIG_DFL);
 112-	raise(sig);
 113+        int sig, precious;
 114+        Target *p, **q;
 115+
 116+        sig = stop;
 117+        printf("make: signal %d arrived\n", sig);
 118+
 119+        precious = 0;
 120+        p = lookup(".PRECIOUS");
 121+        for (q = p->deps; q && *q; q++) {
 122+                if (strcmp((*q)->name, tp->name) == 0) {
 123+                        precious = 1;
 124+                        break;
 125+                }
 126+        }
 127+
 128+        if (!precious && !nflag && !qflag && !is_dir(tp->name)) {
 129+                printf("make: trying to remove target %s\n", tp->name);
 130+                remove(tp->name);
 131+        }
 132+
 133+        signal(sig, SIG_DFL);
 134+        raise(sig);
 135 }
 136 
 137 static int
 138 depends(char *target, char *dep)
 139 {
 140-	Target **p, *tp = lookup(target);
 141+        Target **p, *tp = lookup(target);
 142 
 143-	for (p = tp->deps; p && *p; ++p) {
 144-		if (strcmp((*p)->name, dep) == 0)
 145-			return 1;
 146-	}
 147+        for (p = tp->deps; p && *p; ++p) {
 148+                if (strcmp((*p)->name, dep) == 0)
 149+                        return 1;
 150+        }
 151 
 152-	return 0;
 153+        return 0;
 154 }
 155 
 156 void
 157 addtarget(char *target, int ndeps)
 158 {
 159-	Target *tp = lookup(target);
 160-
 161-	tp->defined = 1;
 162-	if (!deftarget && target[0] != '.') {
 163-		deftarget = tp;
 164-		return;
 165-	}
 166-
 167-	if (strcmp(target, ".SUFFIXES") == 0 && ndeps == 0) {
 168-		free(tp->deps);
 169-		tp->deps = NULL;
 170-		tp->ndeps = 0;
 171-		return;
 172-	}
 173-
 174-	if (strcmp(target, ".DEFAULT") == 0) {
 175-		if (ndeps > 0)
 176-			error("DEFAULT rule with prerequisites");
 177-		return;
 178-	}
 179-
 180-	if (strcmp(target, ".SILENT") == 0 && ndeps == 0) {
 181-		sflag = 1;
 182-		return;
 183-	}
 184-
 185-	if (strcmp(target, ".IGNORE") == 0 && ndeps == 0) {
 186-		iflag = 1;
 187-		return;
 188-	}
 189+        Target *tp = lookup(target);
 190+
 191+        tp->defined = 1;
 192+        if (!deftarget && target[0] != '.') {
 193+                deftarget = tp;
 194+                return;
 195+        }
 196+
 197+        if (strcmp(target, ".SUFFIXES") == 0 && ndeps == 0) {
 198+                free(tp->deps);
 199+                tp->deps = NULL;
 200+                tp->ndeps = 0;
 201+                return;
 202+        }
 203+
 204+        if (strcmp(target, ".DEFAULT") == 0) {
 205+                if (ndeps > 0)
 206+                        error("DEFAULT rule with prerequisites");
 207+                return;
 208+        }
 209+
 210+        if (strcmp(target, ".SILENT") == 0 && ndeps == 0) {
 211+                sflag = 1;
 212+                return;
 213+        }
 214+
 215+        if (strcmp(target, ".IGNORE") == 0 && ndeps == 0) {
 216+                iflag = 1;
 217+                return;
 218+        }
 219+
 220+        /* .PHONY */
 221+        if (strcmp(target, ".PHONY") == 0) {
 222+                if (ndeps == 0) {
 223+                        free(tp->deps);
 224+                        tp->deps = NULL;
 225+                        tp->ndeps = 0;
 226+                }
 227+                return;
 228+        }
 229 }
 230 
 231 void
 232 adddep(char *target, char *dep)
 233 {
 234-	size_t siz;
 235-	Target **p, *tp = lookup(target);
 236-
 237-	if (depends(dep, target)) {
 238-		warning("circular dependency %s <- %s dropped", target, dep);
 239-		return;
 240-	}
 241-
 242-	for (p = tp->deps; p && *p; ++p) {
 243-		if (strcmp((*p)->name, dep) == 0)
 244-			return;
 245-	}
 246-
 247-	tp->ndeps++;
 248-	siz = (tp->ndeps + 1) * sizeof(Target *);
 249-	tp->deps = erealloc(tp->deps, siz);
 250-	tp->deps[tp->ndeps-1] = lookup(dep);
 251-	tp->deps[tp->ndeps] = NULL;
 252-
 253-	debug("adding dependency %s <- %s", target, dep);
 254+        size_t siz;
 255+        Target **p, *tp = lookup(target);
 256+
 257+        if (depends(dep, target)) {
 258+                warning("circular dependency %s <- %s dropped", target, dep);
 259+                return;
 260+        }
 261+
 262+        for (p = tp->deps; p && *p; ++p) {
 263+                if (strcmp((*p)->name, dep) == 0)
 264+                        return;
 265+        }
 266+
 267+        tp->ndeps++;
 268+        siz = (tp->ndeps + 1) * sizeof(Target *);
 269+        tp->deps = erealloc(tp->deps, siz);
 270+        tp->deps[tp->ndeps-1] = lookup(dep);
 271+        tp->deps[tp->ndeps] = NULL;
 272+
 273+        debug("adding dependency %s <- %s", target, dep);
 274 }
 275 
 276 static void
 277 freeaction(struct action *act)
 278 {
 279-	free(act->line);
 280-	freeloc(&act->loc);
 281+        free(act->line);
 282+        freeloc(&act->loc);
 283 }
 284 
 285 void
 286 addrule(char *target, struct action  *acts, int n)
 287 {
 288-	int i;
 289-	struct action *v;
 290-	Target *tp = lookup(target);
 291-
 292-	debug("adding actions for target %s", target);
 293-
 294-	if (tp->actions) {
 295-		debug("overring actions of target %s", target);
 296-		for (i = 0; i < tp->nactions; i++)
 297-			freeaction(&tp->actions[i]);
 298-		free(tp->actions);
 299-	}
 300-
 301-	v = emalloc(n * sizeof(*v));
 302-	for (i = 0; i < n; i++) {
 303-		v[i].line = estrdup(acts[i].line);
 304-		v[i].loc.lineno = acts[i].loc.lineno;
 305-		v[i].loc.fname = estrdup(acts[i].loc.fname);
 306-	}
 307-
 308-	tp->nactions = n;
 309-	tp->actions = v;
 310+        int i;
 311+        struct action *v;
 312+        Target *tp = lookup(target);
 313+
 314+        debug("adding actions for target %s", target);
 315+
 316+        if (tp->actions) {
 317+                debug("overring actions of target %s", target);
 318+                for (i = 0; i < tp->nactions; i++)
 319+                        freeaction(&tp->actions[i]);
 320+                free(tp->actions);
 321+        }
 322+
 323+        v = emalloc(n * sizeof(*v));
 324+        for (i = 0; i < n; i++) {
 325+                v[i].line = estrdup(acts[i].line);
 326+                v[i].loc.lineno = acts[i].loc.lineno;
 327+                v[i].loc.fname = estrdup(acts[i].loc.fname);
 328+        }
 329+
 330+        tp->nactions = n;
 331+        tp->actions = v;
 332 }
 333 
 334 static int
 335 execline(Target *tp, char *line, int ignore, int silence)
 336 {
 337-	char *s, *t;
 338-	int r, at, plus, minus, l;
 339-
 340-	(void)tp;
 341-
 342-	debug("executing '%s'", line);
 343-
 344-	at = plus = minus = 0;
 345-	for (s = line; ; s++) {
 346-		switch (*s) {
 347-		case '@':
 348-			at = 1;
 349-			break;
 350-		case '-':
 351-			minus = 1;
 352-			break;
 353-		case '+':
 354-			plus = 1;
 355-			break;
 356-		default:
 357-			goto out_loop;
 358-		}
 359-	}
 360+        char *s, *t;
 361+        int r, at, plus, minus, l;
 362+
 363+        (void)tp;
 364+
 365+        debug("executing '%s'", line);
 366+
 367+        at = plus = minus = 0;
 368+        for (s = line; ; s++) {
 369+                switch (*s) {
 370+                case '@':
 371+                        at = 1;
 372+                        break;
 373+                case '-':
 374+                        minus = 1;
 375+                        break;
 376+                case '+':
 377+                        plus = 1;
 378+                        break;
 379+                default:
 380+                        goto out_loop;
 381+                }
 382+        }
 383 
 384 out_loop:
 385-	/* unescape $$ */
 386-	for (l = strlen(s)+1, t = s; *t; --l, ++t) {
 387-		if (t[0] == '$' && t[1] == '$') {
 388-			memmove(t+1, t+2, l-2);
 389-			l--;
 390-		}
 391-	}
 392-
 393-	if (tflag && !plus)
 394-		return 0;
 395-
 396-	if (sflag || silence || (qflag && !plus))
 397-		at = 1;
 398-	if (nflag)
 399-		at = 0;
 400-	if (!at) {
 401-		puts(s);
 402-		fflush(stdout);
 403-	}
 404-
 405-	if ((nflag || qflag) && !plus) {
 406-		if (qflag)
 407-			exitstatus = 1;
 408-		return 0;
 409-	}
 410-
 411-	if (minus || iflag || ignore)
 412-		ignore = 1;
 413-
 414-	r = launch(s, ignore);
 415-	if (ignore)
 416-		return 0;
 417-
 418-	return r;
 419+        /* unescape $$ */
 420+        for (l = strlen(s)+1, t = s; *t; --l, ++t) {
 421+                if (t[0] == '$' && t[1] == '$') {
 422+                        memmove(t+1, t+2, l-2);
 423+                        l--;
 424+                }
 425+        }
 426+
 427+        if (tflag && !plus)
 428+                return 0;
 429+
 430+        if (sflag || silence || (qflag && !plus))
 431+                at = 1;
 432+        if (nflag)
 433+                at = 0;
 434+        if (!at) {
 435+                puts(s);
 436+                fflush(stdout);
 437+        }
 438+
 439+        if ((nflag || qflag) && !plus) {
 440+                if (qflag)
 441+                        exitstatus = 1;
 442+                return 0;
 443+        }
 444+
 445+        if (minus || iflag || ignore)
 446+                ignore = 1;
 447+
 448+        r = launch(s, ignore);
 449+        if (ignore)
 450+                return 0;
 451+
 452+        return r;
 453 }
 454 
 455 static int
 456 touch(char *name, int ignore, int silence)
 457 {
 458-	char *cmd;
 459-	int r, n;
 460+        char *cmd;
 461+        int r, n;
 462 
 463-	n = snprintf(NULL, 0, "touch %s", name) + 1;
 464-	cmd = emalloc(n);
 465-	snprintf(cmd, n, "touch %s", name);
 466+        n = snprintf(NULL, 0, "touch %s", name) + 1;
 467+        cmd = emalloc(n);
 468+        snprintf(cmd, n, "touch %s", name);
 469 
 470-	if (!sflag && !silence)
 471-		puts(cmd);
 472+        if (!sflag && !silence)
 473+                puts(cmd);
 474 
 475-	r = system(cmd);
 476-	free(cmd);
 477+        r = wsystem(cmd);
 478+        free(cmd);
 479 
 480-	if (ignore || iflag)
 481-		return 0;
 482+        if (ignore || iflag)
 483+                return 0;
 484 
 485-	return r;
 486+        return r;
 487 }
 488 
 489 static int
 490 touchdeps(Target *tp, int ignore, int silent)
 491 {
 492-	int r;
 493-	Target **p;
 494-
 495-	if (tp->req) {
 496-		r = touch(tp->req, silent, ignore);
 497-		if (r)
 498-			return r;
 499-	}
 500-
 501-	for (p = tp->deps; p && *p; ++p) {
 502-		r = touch((*p)->name, silent, ignore);
 503-		if (r)
 504-			return r;
 505-	}
 506-
 507-	return 0;
 508+        int r;
 509+        Target **p;
 510+
 511+        if (tp->req) {
 512+                r = touch(tp->req, silent, ignore);
 513+                if (r)
 514+                        return r;
 515+        }
 516+
 517+        for (p = tp->deps; p && *p; ++p) {
 518+                r = touch((*p)->name, silent, ignore);
 519+                if (r)
 520+                        return r;
 521+        }
 522+
 523+        return 0;
 524 }
 525 
 526 static int
 527 run(Target *tp)
 528 {
 529-	int r, i, ignore, silent;
 530-	char *s;
 531-	Target *p, **q;
 532-
 533-	silent = 0;
 534-	p = lookup(".SILENT");
 535-	for (q = p->deps; q && *q; ++q) {
 536-		if (strcmp((*q)->name, tp->name) == 0) {
 537-			debug("target %s error silent by .SILENT", tp->name);
 538-			silent = 1;
 539-		}
 540-	}
 541-
 542-	ignore = 0;
 543-	p = lookup(".IGNORE");
 544-	for (q = p->deps; q && *q; ++q) {
 545-		if (strcmp((*q)->name, tp->name) == 0) {
 546-			debug("target %s error ignored by .IGNORE", tp->name);
 547-			ignore = 1;
 548-		}
 549-	}
 550-
 551-	if (tflag) {
 552-		r = touchdeps(tp, ignore, silent);
 553-		if (r)
 554-			return r;
 555-	}
 556-
 557-	for (i = 0; i < tp->nactions; i++) {
 558-		struct action *p;
 559-
 560-		if (stop)
 561-			cleanup(tp);
 562-
 563-		p = &tp->actions[i];
 564-		debug("executing action '%s'", p->line);
 565-		s = expandstring(p->line, tp, &p->loc);
 566-		r = execline(tp, s, ignore, silent);
 567-		free(s);
 568-
 569-		if (r)
 570-			return r;
 571-	}
 572-
 573-	if (tflag) {
 574-		r = touch(tp->target, ignore, silent);
 575-		if (r)
 576-			return r;
 577-	}
 578-
 579-	return 0;
 580+        int r, i, ignore, silent;
 581+        char *s;
 582+        Target *p, **q;
 583+
 584+        silent = 0;
 585+        p = lookup(".SILENT");
 586+        for (q = p->deps; q && *q; ++q) {
 587+                if (strcmp((*q)->name, tp->name) == 0) {
 588+                        debug("target %s error silent by .SILENT", tp->name);
 589+                        silent = 1;
 590+                }
 591+        }
 592+
 593+        ignore = 0;
 594+        p = lookup(".IGNORE");
 595+        for (q = p->deps; q && *q; ++q) {
 596+                if (strcmp((*q)->name, tp->name) == 0) {
 597+                        debug("target %s error ignored by .IGNORE", tp->name);
 598+                        ignore = 1;
 599+                }
 600+        }
 601+
 602+        if (tflag) {
 603+                r = touchdeps(tp, ignore, silent);
 604+                if (r)
 605+                        return r;
 606+        }
 607+
 608+        for (i = 0; i < tp->nactions; i++) {
 609+                struct action *p;
 610+
 611+                if (stop)
 612+                        cleanup(tp);
 613+
 614+                p = &tp->actions[i];
 615+                debug("executing action '%s'", p->line);
 616+                s = expandstring(p->line, tp, &p->loc);
 617+                r = execline(tp, s, ignore, silent);
 618+                free(s);
 619+
 620+                if (r)
 621+                        return r;
 622+        }
 623+
 624+        if (tflag) {
 625+                r = touch(tp->target, ignore, silent);
 626+                if (r)
 627+                        return r;
 628+        }
 629+
 630+        return 0;
 631 }
 632 
 633 static int
 634 enabled(char *suffix)
 635 {
 636-	Target **p, *tp = lookup(".SUFFIXES");
 637+        Target **p, *tp = lookup(".SUFFIXES");
 638 
 639-	for (p = tp->deps; p && *p; ++p) {
 640-		if (strcmp(suffix, (*p)->name) == 0)
 641-			return 1;
 642-	}
 643+        for (p = tp->deps; p && *p; ++p) {
 644+                if (strcmp(suffix, (*p)->name) == 0)
 645+                        return 1;
 646+        }
 647 
 648-	return 0;
 649+        return 0;
 650 }
 651 
 652 static Target *
 653 inference(Target *tp, int force)
 654 {
 655-	time_t t;
 656-	int tolen, r;
 657-	char *to, *from;
 658-	Target *q, **p, *suffixes;
 659-	char buf[FILENAME_MAX], fname[FILENAME_MAX];
 660-
 661-	debug("searching an inference rule for %s", tp->name);
 662-
 663-	to = strrchr(tp->name, '.');
 664-	if (to && !enabled(to))
 665-		return NULL;
 666-	tolen = to ? (int)(to - tp->name) : (int)strlen(tp->name);
 667-
 668-	if (!to)
 669-		to = "";
 670-
 671-	suffixes = lookup(".SUFFIXES");
 672-	for (p = suffixes->deps; p && *p; ++p) {
 673-		from = (*p)->name;
 674-		debug("trying suffix %s", from);
 675-
 676-		r = snprintf(buf,
 677-		             sizeof(buf),
 678-		             "%s%s",
 679-		             from, to);
 680-
 681-		if (r < 0 || (size_t)r >= sizeof(buf))
 682-			error("suffixes too long %s %s", from, to);
 683-
 684-		q = lookup(buf);
 685-		if (!q->actions)
 686-			continue;
 687-
 688-		r = snprintf(fname,
 689-		             sizeof(fname),
 690-		             "%*.*s%s",
 691-		             tolen, tolen, tp->name, from);
 692-
 693-		if (r < 0 || (size_t)r >= sizeof(fname)) {
 694-			error("prerequisite name too long %s %s",
 695-			      tp->name, from);
 696-		}
 697-
 698-		debug("\tsearching prerequisite %s", fname);
 699-
 700-		t = stamp(fname);
 701-		if (t == -1) {
 702-			debug("\tprerequisite %s not found", fname);
 703-			continue;
 704-		}
 705-
 706-		if (!force && t <= tp->stamp) {
 707-			debug("\tdiscarded because is newer");
 708-			debug("\t%s: %s", tp->name, ctime(&tp->stamp));
 709-			debug("\t%s: %s", fname, ctime(&t));
 710-			continue;
 711-		}
 712-
 713-		free(q->req);
 714-		q->req = estrdup(fname);
 715-		q->deps = tp->deps;
 716-		q->target = tp->name;
 717-		q->stamp = tp->stamp;
 718-
 719-		debug("using inference rule %s with %s", q->name, fname);
 720-		return q;
 721-	}
 722-
 723-	return NULL;
 724+        time_t t;
 725+        int tolen, r;
 726+        char *to, *from;
 727+        Target *q, **p, *suffixes;
 728+        char buf[FILENAME_MAX], fname[FILENAME_MAX];
 729+
 730+        debug("searching an inference rule for %s", tp->name);
 731+
 732+        to = strrchr(tp->name, '.');
 733+        if (to && !enabled(to))
 734+                return NULL;
 735+        tolen = to ? (int)(to - tp->name) : (int)strlen(tp->name);
 736+
 737+        if (!to)
 738+                to = "";
 739+
 740+        suffixes = lookup(".SUFFIXES");
 741+        for (p = suffixes->deps; p && *p; ++p) {
 742+                from = (*p)->name;
 743+                debug("trying suffix %s", from);
 744+
 745+                r = snprintf(buf,
 746+                             sizeof(buf),
 747+                             "%s%s",
 748+                             from, to);
 749+
 750+                if (r < 0 || (size_t)r >= sizeof(buf))
 751+                        error("suffixes too long %s %s", from, to);
 752+
 753+                q = lookup(buf);
 754+                if (!q->actions)
 755+                        continue;
 756+
 757+                r = snprintf(fname,
 758+                             sizeof(fname),
 759+                             "%*.*s%s",
 760+                             tolen, tolen, tp->name, from);
 761+
 762+                if (r < 0 || (size_t)r >= sizeof(fname)) {
 763+                        error("prerequisite name too long %s %s",
 764+                              tp->name, from);
 765+                }
 766+
 767+                debug("\tsearching prerequisite %s", fname);
 768+
 769+                t = stamp(fname);
 770+                if (t == -1) {
 771+                        debug("\tprerequisite %s not found", fname);
 772+                        continue;
 773+                }
 774+
 775+                if (!force && t <= tp->stamp) {
 776+                        debug("\tdiscarded because is newer");
 777+                        debug("\t%s: %s", tp->name, ctime(&tp->stamp));
 778+                        debug("\t%s: %s", fname, ctime(&t));
 779+                        continue;
 780+                }
 781+
 782+                free(q->req);
 783+                q->req = estrdup(fname);
 784+                q->deps = tp->deps;
 785+                q->target = tp->name;
 786+                q->stamp = tp->stamp;
 787+
 788+                debug("using inference rule %s with %s", q->name, fname);
 789+                return q;
 790+        }
 791+
 792+        return NULL;
 793 }
 794 
 795 static int
 796 update(Target *tp)
 797 {
 798-	Target *p;
 799+        Target *p;
 800 
 801-	debug("%s needs to be updated", tp->name);
 802+        debug("%s needs to be updated", tp->name);
 803 
 804-	if (tp->actions) {
 805-		debug("using target rule to build %s", tp->name);
 806-		return run(tp);
 807-	}
 808+        if (tp->actions) {
 809+                debug("using target rule to build %s", tp->name);
 810+                return run(tp);
 811+        }
 812 
 813-	if ((p = inference(tp, FORCE)) != NULL) {
 814-		debug("using inference rule %s", p->name);
 815-		return run(p);
 816-	}
 817+        if ((p = inference(tp, FORCE)) != NULL) {
 818+                debug("using inference rule %s", p->name);
 819+                return run(p);
 820+        }
 821 
 822-	p = lookup(".DEFAULT");
 823-	if (p->defined) {
 824-		debug("using default rule");
 825-		return run(p);
 826-	}
 827+        p = lookup(".DEFAULT");
 828+        if (p->defined) {
 829+                debug("using default rule");
 830+                return run(p);
 831+        }
 832 
 833-	debug("not rule found to update %s", tp->name);
 834+        debug("not rule found to update %s", tp->name);
 835 
 836-	if (!tp->defined)
 837-		error("don't know how to make %s", tp->name);
 838+        if (!tp->defined)
 839+                error("don't know how to make %s", tp->name);
 840 
 841-	return 0;
 842+        return 0;
 843 }
 844 
 845-static int 
 846+static int
 847+is_phony(Target *tp)
 848+{
 849+        Target **p, *ph = lookup(".PHONY");
 850+        for (p = ph->deps; p && *p; ++p)
 851+                if (strcmp((*p)->name, tp->name) == 0)
 852+                        return 1;
 853+        return 0;
 854+}
 855+
 856+static int
 857 rebuild(Target *tp, int *buildp)
 858 {
 859-	Target **p, *q;
 860-	int r, need, build, err, def;
 861-
 862-	debug("checking rebuild of %s", tp->name);
 863-
 864-	tp->stamp = stamp(tp->name);
 865-
 866-	def = err = need = 0;
 867-	for (p = tp->deps; p && *p; ++p) {
 868-		if (stop)
 869-			cleanup(tp);
 870-
 871-		q = *p;
 872-		debug("checking dependency %s", q->name);
 873-
 874-		if (strcmp(q->name, tp->name) == 0 && q->actions)
 875-			def = 1;
 876-
 877-		build = 0;
 878-		if (rebuild(q, &build) != 0) {
 879-			err = 1;
 880-			continue;
 881-		}
 882-
 883-		if (build) {
 884-			debug("rebuild of %s forces rebuild of %s",
 885-			       q->name, tp->name);
 886-			need = 1;
 887-		} else if (q->stamp > tp->stamp) {
 888-			debug("dependency %s is newer than %s",
 889-			      q->name, tp->name);
 890-			need = 1;
 891-		}
 892-	}
 893-
 894-	if (tp->stamp == -1) {
 895-		need = 1;
 896-	} else if (!def)  {
 897-		debug("no action found for %s, looking a inference rule",
 898-		      tp->name);
 899-		if (inference(tp, NOFORCE))
 900-			need = 1;
 901-	}
 902-
 903-	if (err) {
 904-		warning("target %s not remade because of errors", tp->name);
 905-		return 1;
 906-	} else if (need) {
 907-		*buildp = 1;
 908-
 909-		debug("target %s needs updating", tp->name);
 910-		r = update(tp);
 911-		if (r == 0)
 912-			return 0;
 913-
 914-		if (stop)
 915-			cleanup(tp);
 916-
 917-		exitstatus = 1;
 918-
 919-		if (!kflag)
 920-			error("target %s: error %d", tp->name, r);
 921-		else
 922-			warning("target %s: error %d", tp->name, r);
 923-		return r;
 924-	}
 925-
 926-	return 0;
 927+        Target **p, *q;
 928+        int r, need, build, err, def;
 929+
 930+        debug("checking rebuild of %s", tp->name);
 931+
 932+        if (is_phony(tp))
 933+                tp->stamp = -1;
 934+        else
 935+                tp->stamp = stamp(tp->name);
 936+
 937+        def = err = need = 0;
 938+        for (p = tp->deps; p && *p; ++p) {
 939+                if (stop)
 940+                        cleanup(tp);
 941+
 942+                q = *p;
 943+                debug("checking dependency %s", q->name);
 944+
 945+                if (strcmp(q->name, tp->name) == 0 && q->actions)
 946+                        def = 1;
 947+
 948+                build = 0;
 949+                if (rebuild(q, &build) != 0) {
 950+                        err = 1;
 951+                        continue;
 952+                }
 953+
 954+                if (build) {
 955+                        debug("rebuild of %s forces rebuild of %s",
 956+                               q->name, tp->name);
 957+                        need = 1;
 958+                } else if (q->stamp > tp->stamp) {
 959+                        debug("dependency %s is newer than %s",
 960+                              q->name, tp->name);
 961+                        need = 1;
 962+                }
 963+        }
 964+
 965+        if (tp->stamp == -1) {
 966+                need = 1;
 967+        } else if (!def)  {
 968+                debug("no action found for %s, looking a inference rule",
 969+                      tp->name);
 970+                if (inference(tp, NOFORCE))
 971+                        need = 1;
 972+        }
 973+
 974+        if (err) {
 975+                warning("target %s not remade because of errors", tp->name);
 976+                return 1;
 977+        } else if (need) {
 978+                *buildp = 1;
 979+
 980+                debug("target %s needs updating", tp->name);
 981+                r = update(tp);
 982+                if (r == 0)
 983+                        return 0;
 984+
 985+                if (stop)
 986+                        cleanup(tp);
 987+
 988+                exitstatus = 1;
 989+
 990+                if (!kflag)
 991+                        error("target %s: error %d", tp->name, r);
 992+                else
 993+                        warning("target %s: error %d", tp->name, r);
 994+                return r;
 995+        }
 996+
 997+        return 0;
 998 }
 999 
1000 int
1001 build(char *name)
1002 {
1003-	int build;
1004+        int build;
1005 
1006-	if (!name) {
1007-		if (!deftarget) {
1008-			printf("make: no target to make\n");
1009-			return 0;
1010-		}
1011-		name = deftarget->name;
1012-	}
1013+        if (!name) {
1014+                if (!deftarget) {
1015+                        printf("make: no target to make\n");
1016+                        return 0;
1017+                }
1018+                name = deftarget->name;
1019+        }
1020 
1021-	debug("checking target %s", name);
1022+        debug("checking target %s", name);
1023 
1024-	build = 0;
1025-	return rebuild(lookup(name), &build);
1026+        build = 0;
1027+        return rebuild(lookup(name), &build);
1028 }
+3, -2
 1@@ -7,6 +7,7 @@
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 #ifndef PRIO_MIN
 9@@ -54,9 +55,9 @@ main(int argc, char *argv[])
10 	if (setpriority(PRIO_PROCESS, 0, val) < 0)
11 		weprintf("setpriority:");
12 
13-	execvp(argv[0], argv);
14+	wexecvp_self(argv[0], argv);
15 	savederrno = errno;
16-	weprintf("execvp %s:", argv[0]);
17+	weprintf("wexecvp %s:", argv[0]);
18 
19 	_exit(126 + (savederrno == ENOENT));
20 }
+3, -2
 1@@ -8,6 +8,7 @@
 2 #include <signal.h>
 3 #include <unistd.h>
 4 
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 static void
 9@@ -45,9 +46,9 @@ main(int argc, char *argv[])
10 	if (isatty(STDERR_FILENO) && dup2(STDOUT_FILENO, STDERR_FILENO) < 0)
11 		enprintf(127, "dup2:");
12 
13-	execvp(argv[0], argv);
14+	wexecvp_self(argv[0], argv);
15 	savederrno = errno;
16-	weprintf("execvp %s:", argv[0]);
17+	weprintf("wexecvp %s:", argv[0]);
18 
19 	_exit(126 + (savederrno == ENOENT));
20 }
+2407, -2438
   1@@ -1,4 +1,6 @@
   2 /* See LICENSE file for copyright and license details. */
   3+#include "wexec.h"
   4+#include "paths.h"
   5 #include "util.h"
   6 
   7 #include <sys/file.h>
   8@@ -9,13 +11,11 @@
   9 
  10 #include <ctype.h>
  11 #include <dirent.h>
  12-#include <err.h>
  13 #include <errno.h>
  14 #include <fcntl.h>
  15 #include <getopt.h>
  16 #include <libgen.h>
  17 #include <limits.h>
  18-#include <paths.h>
  19 #include <stdarg.h>
  20 #include <stddef.h>
  21 #include <stdint.h>
  22@@ -37,8 +37,8 @@
  23 #define SCCSDIFF "get -p %s | diff - %s >/dev/null"
  24 
  25 #define RCSSUFFIX ",v"
  26-#define CHECKOUT "/usr/bin/co"
  27-#define RCSDIFF "/usr/bin/rcsdiff"
  28+#define CHECKOUT "co"
  29+#define RCSDIFF "rcsdiff"
  30 
  31 #define ORIGEXT ".orig"
  32 #define REJEXT ".rej"
  33@@ -59,7 +59,7 @@
  34 #define NEW_CONTEXT_DIFF 4
  35 #define UNI_DIFF 5
  36 
  37-#define _PATH_ED "/bin/ed"
  38+#define _PATH_ED "ed"
  39 
  40 #define ISDIGIT(c) (isascii((unsigned char)c) && isdigit((unsigned char)c))
  41 
  42@@ -74,16 +74,16 @@
  43 typedef long LINENUM;
  44 
  45 enum BackupType {
  46-	BACKUP_UNDEFINED,
  47-	BACKUP_NONE,
  48-	BACKUP_SIMPLE,
  49-	BACKUP_NUMBERED_EXISTING,
  50-	BACKUP_NUMBERED
  51+        BACKUP_UNDEFINED,
  52+        BACKUP_NONE,
  53+        BACKUP_SIMPLE,
  54+        BACKUP_NUMBERED_EXISTING,
  55+        BACKUP_NUMBERED
  56 };
  57 
  58 struct FileName {
  59-	char *path;
  60-	int exists;
  61+        char *path;
  62+        int exists;
  63 };
  64 
  65 mode_t filemode = 0644;
  66@@ -154,7 +154,6 @@ static void reinitialize_almost_everything(void);
  67 static void get_some_switches(void);
  68 static void reset_getopt_state(void);
  69 static LINENUM locate_hunk(LINENUM);
  70-static void abort_context_hunk(void);
  71 static void rej_line(int, LINENUM);
  72 static void abort_hunk(void);
  73 static void apply_hunk(LINENUM);
  74@@ -162,7 +161,6 @@ static void init_output(const char *);
  75 static void init_reject(const char *);
  76 static void copy_till(LINENUM, int);
  77 static int spew_output(void);
  78-static void dump_patch_line(LINENUM, int);
  79 static void dump_input_line(LINENUM, int);
  80 static int patch_match(LINENUM, LINENUM, LINENUM);
  81 static int similar(const char *, const char *, ssize_t);
  82@@ -268,11 +266,11 @@ static int argmatch(const char *, const char **);
  83 static void invalid_arg(const char *, const char *, int);
  84 
  85 static const char *backup_args[] = {
  86-	"none", "never", "simple", "nil", "existing", "t", "numbered", 0
  87+        "none", "never", "simple", "nil", "existing", "t", "numbered", 0
  88 };
  89 static enum BackupType backup_types[] = {
  90-	BACKUP_NONE, BACKUP_SIMPLE, BACKUP_SIMPLE, BACKUP_NUMBERED_EXISTING,
  91-	BACKUP_NUMBERED_EXISTING, BACKUP_NUMBERED, BACKUP_NUMBERED
  92+        BACKUP_NONE, BACKUP_SIMPLE, BACKUP_SIMPLE, BACKUP_NUMBERED_EXISTING,
  93+        BACKUP_NUMBERED_EXISTING, BACKUP_NUMBERED, BACKUP_NUMBERED
  94 };
  95 
  96 /* implementation */
  97@@ -281,675 +279,660 @@ static enum BackupType backup_types[] = {
  98 int
  99 main(int argc, char *argv[])
 100 {
 101-	int error, hunk, failed, i, fd;
 102-	LINENUM where, newwhere, fuzz, mymaxfuzz;
 103-	const char *tmpdir;
 104-	char *v;
 105-
 106-	error = 0;
 107-	where = 0;
 108-	bufsz = INITLINELEN;
 109-	if ((buf = malloc(bufsz)) == NULL)
 110-		pfatal("allocating input buffer");
 111-	buf[0] = '\0';
 112-
 113-	setbuf(stderr, serrbuf);
 114-	for (i = 0; i < MAXFILEC; i++)
 115-		filearg[i] = NULL;
 116-
 117-	if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0')
 118-		tmpdir = _PATH_TMP;
 119-	for (i = strlen(tmpdir) - 1; i > 0 && tmpdir[i] == '/'; i--)
 120-		;
 121-	i++;
 122-	if (asprintf(&TMPOUTNAME, "%.*s/patchoXXXXXXXXXX", i, tmpdir) == -1)
 123-		fatal("cannot allocate memory");
 124-	if ((fd = mkstemp(TMPOUTNAME)) < 0)
 125-		pfatal("cant create %s", TMPOUTNAME);
 126-	close(fd);
 127-
 128-	if (asprintf(&TMPINNAME, "%.*s/patchiXXXXXXXXXX", i, tmpdir) == -1)
 129-		fatal("cannot allocate memory");
 130-	if ((fd = mkstemp(TMPINNAME)) < 0)
 131-		pfatal("cant create %s", TMPINNAME);
 132-	close(fd);
 133-
 134-	if (asprintf(&TMPREJNAME, "%.*s/patchrXXXXXXXXXX", i, tmpdir) == -1)
 135-		fatal("cannot allocate memory");
 136-	if ((fd = mkstemp(TMPREJNAME)) < 0)
 137-		pfatal("cant create %s", TMPREJNAME);
 138-	close(fd);
 139-
 140-	if (asprintf(&TMPPATNAME, "%.*s/patchpXXXXXXXXXX", i, tmpdir) == -1)
 141-		fatal("cannot allocate memory");
 142-	if ((fd = mkstemp(TMPPATNAME)) < 0)
 143-		pfatal("cant create %s", TMPPATNAME);
 144-	close(fd);
 145-
 146-	v = getenv("SIMPLE_BACKUP_SUFFIX");
 147-	if (v)
 148-		simple_backup_suffix = v;
 149-	else
 150-		simple_backup_suffix = ORIGEXT;
 151-
 152-	if ((v = getenv("PATCH_VERSION_CONTROL")) == NULL)
 153-		v = getenv("VERSION_CONTROL");
 154-	if (v != NULL)
 155-		backup_type = get_version(v);
 156-
 157-	Argc = argc;
 158-	Argv = argv;
 159-	get_some_switches();
 160-
 161-	if (backup_type == BACKUP_UNDEFINED)
 162-		backup_type = posix ? BACKUP_NONE : BACKUP_NUMBERED_EXISTING;
 163-
 164-	set_signals(0);
 165-
 166-	for (open_patch_file(filearg[1]); there_is_another_patch(); reinitialize_almost_everything()) {
 167-		warn_on_invalid_line = 1;
 168-		if (outname == NULL)
 169-			outname = savestr(filearg[0]);
 170-
 171-		if (diff_type == ED_DIFF) {
 172-			do_ed_script();
 173-			continue;
 174-		}
 175-		if (!skip_rest_of_patch)
 176-			init_output(TMPOUTNAME);
 177-
 178-		init_reject(TMPREJNAME);
 179-
 180-		if (!skip_rest_of_patch)
 181-			scan_input(filearg[0]);
 182-
 183-		hunk = 0;
 184-		failed = 0;
 185-		out_of_mem = 0;
 186-		while (another_hunk()) {
 187-			hunk++;
 188-			fuzz = 0;
 189-			mymaxfuzz = pch_context();
 190-			if (maxfuzz < mymaxfuzz)
 191-				mymaxfuzz = maxfuzz;
 192-			if (!skip_rest_of_patch) {
 193-				do {
 194-					where = locate_hunk(fuzz);
 195-					if (hunk == 1 && where == 0 && !force) {
 196-						if (!pch_swap()) {
 197-							if (fuzz == 0)
 198-								say("Not enough memory to try swapped hunk! Assuming unswapped.\n");
 199-							continue;
 200-						}
 201-						reverse = !reverse;
 202-						where = locate_hunk(fuzz);
 203-						if (where == 0) {
 204-							if (!pch_swap())
 205-								fatal("lost hunk on alloc error!\n");
 206-							reverse = !reverse;
 207-						} else if (noreverse) {
 208-							if (!pch_swap())
 209-								fatal("lost hunk on alloc error!\n");
 210-							reverse = !reverse;
 211-							say("Ignoring previously applied (or reversed) patch.\n");
 212-							skip_rest_of_patch = 1;
 213-						} else if (batch) {
 214-							if (verbose)
 215-								say("%seversed (or %spreviously applied) patch detected! %s -R.",
 216-								    reverse ? "R" : "Unr",
 217-								    reverse ? "" : "not ",
 218-								    reverse ? "Assuming" : "Ignoring");
 219-						} else {
 220-							ask("%seversed (or %spreviously applied) patch detected! %s -R? [y] ",
 221-							    reverse ? "R" : "Unr",
 222-							    reverse ? "" : "not ",
 223-							    reverse ? "Assume" : "Ignore");
 224-							if (*buf == 'n') {
 225-								ask("Apply anyway? [n] ");
 226-								if (*buf != 'y')
 227-									skip_rest_of_patch = 1;
 228-								where = 0;
 229-								reverse = !reverse;
 230-								if (!pch_swap())
 231-									fatal("lost hunk on alloc error!\n");
 232-							}
 233-						}
 234-					}
 235-				} while (!skip_rest_of_patch && where == 0 && ++fuzz <= mymaxfuzz);
 236-
 237-				if (skip_rest_of_patch) {
 238-					if (ferror(ofp) || fclose(ofp)) {
 239-						say("Error writing %s\n", TMPOUTNAME);
 240-						error = 1;
 241-					}
 242-					ofp = NULL;
 243-				}
 244-			}
 245-			newwhere = pch_newfirst() + last_offset;
 246-			if (skip_rest_of_patch) {
 247-				abort_hunk();
 248-				failed++;
 249-				if (verbose)
 250-					say("Hunk #%d ignored at %ld.\n", hunk, newwhere);
 251-			} else if (where == 0) {
 252-				abort_hunk();
 253-				failed++;
 254-				if (verbose)
 255-					say("Hunk #%d failed at %ld.\n", hunk, newwhere);
 256-			} else {
 257-				apply_hunk(where);
 258-				if (verbose) {
 259-					say("Hunk #%d succeeded at %ld", hunk, newwhere);
 260-					if (fuzz != 0)
 261-						say(" with fuzz %ld", fuzz);
 262-					if (last_offset)
 263-						say(" (offset %ld line%s)", last_offset, last_offset == 1L ? "" : "s");
 264-					say(".\n");
 265-				}
 266-			}
 267-		}
 268-
 269-		if (out_of_mem && using_plan_a) {
 270-			Argc = Argc_last;
 271-			Argv = Argv_last;
 272-			say("\n\nRan out of memory using Plan A--trying again...\n\n");
 273-			if (ofp)
 274-				fclose(ofp);
 275-			ofp = NULL;
 276-			if (rejfp)
 277-				fclose(rejfp);
 278-			rejfp = NULL;
 279-			continue;
 280-		}
 281-		if (hunk == 0)
 282-			fatal("internal error: hunk should not be 0\n");
 283-
 284-		if (!skip_rest_of_patch && !spew_output()) {
 285-			say("cant write %s\n", TMPOUTNAME);
 286-			error = 1;
 287-		}
 288-
 289-		ignore_signals();
 290-		if (!skip_rest_of_patch) {
 291-			struct stat statbuf;
 292-			char *realout = outname;
 293-
 294-			if (!check_only) {
 295-				enum BackupType saved = backup_type;
 296-				if (failed > 0 && backup_if_mismatch > 0 && backup_type == BACKUP_NONE)
 297-					backup_type = BACKUP_SIMPLE;
 298-				if (move_file(TMPOUTNAME, outname) < 0) {
 299-					toutkeep = 1;
 300-					realout = TMPOUTNAME;
 301-					chmod(TMPOUTNAME, filemode);
 302-				} else
 303-					chmod(outname, filemode);
 304-				backup_type = saved;
 305-
 306-				if (remove_empty_files && stat(realout, &statbuf) == 0 && statbuf.st_size == 0) {
 307-					if (verbose)
 308-						say("Removing %s (empty after patching).\n", realout);
 309-					unlink(realout);
 310-				}
 311-			}
 312-		}
 313-		if (ferror(rejfp) || fclose(rejfp)) {
 314-			say("Error writing %s\n", rejname);
 315-			error = 1;
 316-		}
 317-		rejfp = NULL;
 318-		if (failed) {
 319-			error = 1;
 320-			if (*rejname == '\0') {
 321-				if (strlcpy(rejname, outname, sizeof(rejname)) >= sizeof(rejname))
 322-					fatal("filename %s is too long\n", outname);
 323-				if (strlcat(rejname, REJEXT, sizeof(rejname)) >= sizeof(rejname))
 324-					fatal("filename %s is too long\n", outname);
 325-			}
 326-			if (skip_rest_of_patch) {
 327-				say("%d out of %d hunks ignored--saving rejects to %s\n", failed, hunk, rejname);
 328-			} else {
 329-				say("%d out of %d hunks FAILED -- saving rejects to %s\n", failed, hunk, rejname);
 330-			}
 331-			if (!check_only && move_file(TMPREJNAME, rejname) < 0)
 332-				trejkeep = 1;
 333-		}
 334-		set_signals(1);
 335-	}
 336-	my_exit(error);
 337+        int error, hunk, failed, i, fd;
 338+        LINENUM where, newwhere, fuzz, mymaxfuzz;
 339+        const char *tmpdir;
 340+        char *v;
 341+
 342+        error = 0;
 343+        where = 0;
 344+        bufsz = INITLINELEN;
 345+        if ((buf = malloc(bufsz)) == NULL)
 346+                pfatal("allocating input buffer");
 347+        buf[0] = '\0';
 348+
 349+        setbuf(stderr, serrbuf);
 350+        for (i = 0; i < MAXFILEC; i++)
 351+                filearg[i] = NULL;
 352+
 353+        if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0')
 354+                tmpdir = ARUU_PATH_TMP;
 355+        for (i = strlen(tmpdir) - 1; i > 0 && tmpdir[i] == '/'; i--)
 356+                ;
 357+        i++;
 358+        if (asprintf(&TMPOUTNAME, "%.*s/patchoXXXXXXXXXX", i, tmpdir) == -1)
 359+                fatal("cannot allocate memory");
 360+        if ((fd = mkstemp(TMPOUTNAME)) < 0)
 361+                pfatal("cant create %s", TMPOUTNAME);
 362+        close(fd);
 363+
 364+        if (asprintf(&TMPINNAME, "%.*s/patchiXXXXXXXXXX", i, tmpdir) == -1)
 365+                fatal("cannot allocate memory");
 366+        if ((fd = mkstemp(TMPINNAME)) < 0)
 367+                pfatal("cant create %s", TMPINNAME);
 368+        close(fd);
 369+
 370+        if (asprintf(&TMPREJNAME, "%.*s/patchrXXXXXXXXXX", i, tmpdir) == -1)
 371+                fatal("cannot allocate memory");
 372+        if ((fd = mkstemp(TMPREJNAME)) < 0)
 373+                pfatal("cant create %s", TMPREJNAME);
 374+        close(fd);
 375+
 376+        if (asprintf(&TMPPATNAME, "%.*s/patchpXXXXXXXXXX", i, tmpdir) == -1)
 377+                fatal("cannot allocate memory");
 378+        if ((fd = mkstemp(TMPPATNAME)) < 0)
 379+                pfatal("cant create %s", TMPPATNAME);
 380+        close(fd);
 381+
 382+        v = getenv("SIMPLE_BACKUP_SUFFIX");
 383+        if (v)
 384+                simple_backup_suffix = v;
 385+        else
 386+                simple_backup_suffix = ORIGEXT;
 387+
 388+        if ((v = getenv("PATCH_VERSION_CONTROL")) == NULL)
 389+                v = getenv("VERSION_CONTROL");
 390+        if (v != NULL)
 391+                backup_type = get_version(v);
 392+
 393+        Argc = argc;
 394+        Argv = argv;
 395+        get_some_switches();
 396+
 397+        if (backup_type == BACKUP_UNDEFINED)
 398+                backup_type = posix ? BACKUP_NONE : BACKUP_NUMBERED_EXISTING;
 399+
 400+        set_signals(0);
 401+
 402+        for (open_patch_file(filearg[1]); there_is_another_patch(); reinitialize_almost_everything()) {
 403+                warn_on_invalid_line = 1;
 404+                if (outname == NULL)
 405+                        outname = savestr(filearg[0]);
 406+
 407+                if (diff_type == ED_DIFF) {
 408+                        do_ed_script();
 409+                        continue;
 410+                }
 411+                if (!skip_rest_of_patch)
 412+                        init_output(TMPOUTNAME);
 413+
 414+                init_reject(TMPREJNAME);
 415+
 416+                if (!skip_rest_of_patch)
 417+                        scan_input(filearg[0]);
 418+
 419+                hunk = 0;
 420+                failed = 0;
 421+                out_of_mem = 0;
 422+                while (another_hunk()) {
 423+                        hunk++;
 424+                        fuzz = 0;
 425+                        mymaxfuzz = pch_context();
 426+                        if (maxfuzz < mymaxfuzz)
 427+                                mymaxfuzz = maxfuzz;
 428+                        if (!skip_rest_of_patch) {
 429+                                do {
 430+                                        where = locate_hunk(fuzz);
 431+                                        if (hunk == 1 && where == 0 && !force) {
 432+                                                if (!pch_swap()) {
 433+                                                        if (fuzz == 0)
 434+                                                                say("Not enough memory to try swapped hunk! Assuming unswapped.\n");
 435+                                                        continue;
 436+                                                }
 437+                                                reverse = !reverse;
 438+                                                where = locate_hunk(fuzz);
 439+                                                if (where == 0) {
 440+                                                        if (!pch_swap())
 441+                                                                fatal("lost hunk on alloc error!\n");
 442+                                                        reverse = !reverse;
 443+                                                } else if (noreverse) {
 444+                                                        if (!pch_swap())
 445+                                                                fatal("lost hunk on alloc error!\n");
 446+                                                        reverse = !reverse;
 447+                                                        say("Ignoring previously applied (or reversed) patch.\n");
 448+                                                        skip_rest_of_patch = 1;
 449+                                                } else if (batch) {
 450+                                                        if (verbose)
 451+                                                                say("%seversed (or %spreviously applied) patch detected! %s -R.",
 452+                                                                    reverse ? "R" : "Unr",
 453+                                                                    reverse ? "" : "not ",
 454+                                                                    reverse ? "Assuming" : "Ignoring");
 455+                                                } else {
 456+                                                        ask("%seversed (or %spreviously applied) patch detected! %s -R? [y] ",
 457+                                                            reverse ? "R" : "Unr",
 458+                                                            reverse ? "" : "not ",
 459+                                                            reverse ? "Assume" : "Ignore");
 460+                                                        if (*buf == 'n') {
 461+                                                                ask("Apply anyway? [n] ");
 462+                                                                if (*buf != 'y')
 463+                                                                        skip_rest_of_patch = 1;
 464+                                                                where = 0;
 465+                                                                reverse = !reverse;
 466+                                                                if (!pch_swap())
 467+                                                                        fatal("lost hunk on alloc error!\n");
 468+                                                        }
 469+                                                }
 470+                                        }
 471+                                } while (!skip_rest_of_patch && where == 0 && ++fuzz <= mymaxfuzz);
 472+
 473+                                if (skip_rest_of_patch) {
 474+                                        if (ferror(ofp) || fclose(ofp)) {
 475+                                                say("Error writing %s\n", TMPOUTNAME);
 476+                                                error = 1;
 477+                                        }
 478+                                        ofp = NULL;
 479+                                }
 480+                        }
 481+                        newwhere = pch_newfirst() + last_offset;
 482+                        if (skip_rest_of_patch) {
 483+                                abort_hunk();
 484+                                failed++;
 485+                                if (verbose)
 486+                                        say("Hunk #%d ignored at %ld.\n", hunk, newwhere);
 487+                        } else if (where == 0) {
 488+                                abort_hunk();
 489+                                failed++;
 490+                                if (verbose)
 491+                                        say("Hunk #%d failed at %ld.\n", hunk, newwhere);
 492+                        } else {
 493+                                apply_hunk(where);
 494+                                if (verbose) {
 495+                                        say("Hunk #%d succeeded at %ld", hunk, newwhere);
 496+                                        if (fuzz != 0)
 497+                                                say(" with fuzz %ld", fuzz);
 498+                                        if (last_offset)
 499+                                                say(" (offset %ld line%s)", last_offset, last_offset == 1L ? "" : "s");
 500+                                        say(".\n");
 501+                                }
 502+                        }
 503+                }
 504+
 505+                if (out_of_mem && using_plan_a) {
 506+                        Argc = Argc_last;
 507+                        Argv = Argv_last;
 508+                        say("\n\nRan out of memory using Plan A--trying again...\n\n");
 509+                        if (ofp)
 510+                                fclose(ofp);
 511+                        ofp = NULL;
 512+                        if (rejfp)
 513+                                fclose(rejfp);
 514+                        rejfp = NULL;
 515+                        continue;
 516+                }
 517+                if (hunk == 0)
 518+                        fatal("internal error: hunk should not be 0\n");
 519+
 520+                if (!skip_rest_of_patch && !spew_output()) {
 521+                        say("cant write %s\n", TMPOUTNAME);
 522+                        error = 1;
 523+                }
 524+
 525+                ignore_signals();
 526+                if (!skip_rest_of_patch) {
 527+                        struct stat statbuf;
 528+                        char *realout = outname;
 529+
 530+                        if (!check_only) {
 531+                                enum BackupType saved = backup_type;
 532+                                if (failed > 0 && backup_if_mismatch > 0 && backup_type == BACKUP_NONE)
 533+                                        backup_type = BACKUP_SIMPLE;
 534+                                if (move_file(TMPOUTNAME, outname) < 0) {
 535+                                        toutkeep = 1;
 536+                                        realout = TMPOUTNAME;
 537+                                        chmod(TMPOUTNAME, filemode);
 538+                                } else
 539+                                        chmod(outname, filemode);
 540+                                backup_type = saved;
 541+
 542+                                if (remove_empty_files && stat(realout, &statbuf) == 0 && statbuf.st_size == 0) {
 543+                                        if (verbose)
 544+                                                say("Removing %s (empty after patching).\n", realout);
 545+                                        unlink(realout);
 546+                                }
 547+                        }
 548+                }
 549+                if (ferror(rejfp) || fclose(rejfp)) {
 550+                        say("Error writing %s\n", rejname);
 551+                        error = 1;
 552+                }
 553+                rejfp = NULL;
 554+                if (failed) {
 555+                        error = 1;
 556+                        if (*rejname == '\0') {
 557+                                if (strlcpy(rejname, outname, sizeof(rejname)) >= sizeof(rejname))
 558+                                        fatal("filename %s is too long\n", outname);
 559+                                if (strlcat(rejname, REJEXT, sizeof(rejname)) >= sizeof(rejname))
 560+                                        fatal("filename %s is too long\n", outname);
 561+                        }
 562+                        if (skip_rest_of_patch) {
 563+                                say("%d out of %d hunks ignored--saving rejects to %s\n", failed, hunk, rejname);
 564+                        } else {
 565+                                say("%d out of %d hunks FAILED -- saving rejects to %s\n", failed, hunk, rejname);
 566+                        }
 567+                        if (!check_only && move_file(TMPREJNAME, rejname) < 0)
 568+                                trejkeep = 1;
 569+                }
 570+                set_signals(1);
 571+        }
 572+        my_exit(error);
 573 }
 574 
 575 static void
 576 reset_getopt_state(void)
 577 {
 578 #if defined(__GLIBC__) || defined(__linux__)
 579-	optind = 0;
 580+        optind = 0;
 581 #else
 582-	optreset = 1;
 583-	optind = 1;
 584+        optreset = 1;
 585+        optind = 1;
 586 #endif
 587 }
 588 
 589 static void
 590 reinitialize_almost_everything(void)
 591 {
 592-	re_patch();
 593-	re_input();
 594-
 595-	input_lines = 0;
 596-	last_frozen_line = 0;
 597-	filec = 0;
 598-	if (!out_of_mem) {
 599-		free(filearg[0]);
 600-		filearg[0] = NULL;
 601-	}
 602-	free(outname);
 603-	outname = NULL;
 604-	last_offset = 0;
 605-	diff_type = 0;
 606-	free(revision);
 607-	revision = NULL;
 608-	reverse = reverse_flag_specified;
 609-	skip_rest_of_patch = 0;
 610-	get_some_switches();
 611+        re_patch();
 612+        re_input();
 613+
 614+        input_lines = 0;
 615+        last_frozen_line = 0;
 616+        filec = 0;
 617+        if (!out_of_mem) {
 618+                free(filearg[0]);
 619+                filearg[0] = NULL;
 620+        }
 621+        free(outname);
 622+        outname = NULL;
 623+        last_offset = 0;
 624+        diff_type = 0;
 625+        free(revision);
 626+        revision = NULL;
 627+        reverse = reverse_flag_specified;
 628+        skip_rest_of_patch = 0;
 629+        get_some_switches();
 630 }
 631 
 632 static void
 633 get_some_switches(void)
 634 {
 635-	const char *options = "b::B:cCd:D:eEfF:i:lnNo:p:r:RstuvV:x:z:";
 636-	static struct option longopts[] = {
 637-		{"backup",              no_argument,            0,      'b'},
 638-		{"backup-if-mismatch",  no_argument,            &backup_if_mismatch, 1},
 639-		{"batch",               no_argument,            0,      't'},
 640-		{"check",               no_argument,            0,      'C'},
 641-		{"context",             no_argument,            0,      'c'},
 642-		{"debug",               required_argument,      0,      'x'},
 643-		{"directory",           required_argument,      0,      'd'},
 644-		{"ed",                  no_argument,            0,      'e'},
 645-		{"force",               no_argument,            0,      'f'},
 646-		{"forward",             no_argument,            0,      'N'},
 647-		{"fuzz",                required_argument,      0,      'F'},
 648-		{"ifdef",               required_argument,      0,      'D'},
 649-		{"input",               required_argument,      0,      'i'},
 650-		{"ignore-whitespace",   no_argument,            0,      'l'},
 651-		{"no-backup-if-mismatch",       no_argument,    &backup_if_mismatch, 0},
 652-		{"normal",              no_argument,            0,      'n'},
 653-		{"output",              required_argument,      0,      'o'},
 654-		{"prefix",              required_argument,      0,      'B'},
 655-		{"quiet",               no_argument,            0,      's'},
 656-		{"reject-file",         required_argument,      0,      'r'},
 657-		{"remove-empty-files",  no_argument,            0,      'E'},
 658-		{"reverse",             no_argument,            0,      'R'},
 659-		{"silent",              no_argument,            0,      's'},
 660-		{"strip",               required_argument,      0,      'p'},
 661-		{"suffix",              required_argument,      0,      'z'},
 662-		{"unified",             no_argument,            0,      'u'},
 663-		{"version",             no_argument,            0,      'v'},
 664-		{"version-control",     required_argument,      0,      'V'},
 665-		{"posix",               no_argument,            &posix, 1},
 666-		{NULL,                  0,                      0,      0}
 667-	};
 668-	int ch;
 669-
 670-	rejname[0] = '\0';
 671-	Argc_last = Argc;
 672-	Argv_last = Argv;
 673-	if (!Argc)
 674-		return;
 675-	reset_getopt_state();
 676-	while ((ch = getopt_long(Argc, Argv, options, longopts, NULL)) != -1) {
 677-		switch (ch) {
 678-		case 'b':
 679-			if (backup_type == BACKUP_UNDEFINED)
 680-				backup_type = BACKUP_NUMBERED_EXISTING;
 681-			if (optarg == NULL)
 682-				break;
 683-			if (verbose)
 684-				say("Warning, the -b suffix option has been obsoleted by the -z option\n");
 685-			/* FALLTHROUGH */
 686-		case 'z':
 687-			simple_backup_suffix = savestr(optarg);
 688-			break;
 689-		case 'B':
 690-			origprae = savestr(optarg);
 691-			break;
 692-		case 'c':
 693-			diff_type = CONTEXT_DIFF;
 694-			break;
 695-		case 'C':
 696-			check_only = 1;
 697-			break;
 698-		case 'd':
 699-			if (chdir(optarg) < 0)
 700-				pfatal("cant cd to %s", optarg);
 701-			break;
 702-		case 'D':
 703-			do_defines = 1;
 704-			if (!isalpha((unsigned char)*optarg) && *optarg != '_')
 705-				fatal("argument to -D is not an identifier\n");
 706-			snprintf(if_defined, sizeof if_defined, "#ifdef %s\n", optarg);
 707-			snprintf(not_defined, sizeof not_defined, "#ifndef %s\n", optarg);
 708-			snprintf(end_defined, sizeof end_defined, "#endif /* %s */\n", optarg);
 709-			break;
 710-		case 'e':
 711-			diff_type = ED_DIFF;
 712-			break;
 713-		case 'E':
 714-			remove_empty_files = 1;
 715-			break;
 716-		case 'f':
 717-			force = 1;
 718-			break;
 719-		case 'F':
 720-			maxfuzz = strtolinenum(optarg, NULL);
 721-			break;
 722-		case 'i':
 723-			free(filearg[1]);
 724-			filearg[1] = fetchname(optarg, &warn_on_invalid_line, 0);
 725-			break;
 726-		case 'l':
 727-			canonicalize = 1;
 728-			break;
 729-		case 'n':
 730-			diff_type = NORMAL_DIFF;
 731-			break;
 732-		case 'N':
 733-			noreverse = 1;
 734-			break;
 735-		case 'o':
 736-			outname = savestr(optarg);
 737-			break;
 738-		case 'p':
 739-			strippath = (int)strtolinenum(optarg, NULL);
 740-			break;
 741-		case 'r':
 742-			if (strlcpy(rejname, optarg, sizeof(rejname)) >= sizeof(rejname))
 743-				fatal("reject filename %s too long\n", optarg);
 744-			break;
 745-		case 'R':
 746-			reverse = 1;
 747-			reverse_flag_specified = 1;
 748-			break;
 749-		case 's':
 750-			verbose = 0;
 751-			break;
 752-		case 't':
 753-			batch = 1;
 754-			break;
 755-		case 'u':
 756-			diff_type = UNI_DIFF;
 757-			break;
 758-		case 'v':
 759-			version();
 760-			break;
 761-		case 'V':
 762-			backup_type = get_version(optarg);
 763-			break;
 764-		case 'x':
 765+        const char *options = "b::B:cCd:D:eEfF:i:lnNo:p:r:RstuvV:x:z:";
 766+        static struct option longopts[] = {
 767+                {"backup",              no_argument,            0,      'b'},
 768+                {"backup-if-mismatch",  no_argument,            &backup_if_mismatch, 1},
 769+                {"batch",               no_argument,            0,      't'},
 770+                {"check",               no_argument,            0,      'C'},
 771+                {"context",             no_argument,            0,      'c'},
 772+                {"debug",               required_argument,      0,      'x'},
 773+                {"directory",           required_argument,      0,      'd'},
 774+                {"ed",                  no_argument,            0,      'e'},
 775+                {"force",               no_argument,            0,      'f'},
 776+                {"forward",             no_argument,            0,      'N'},
 777+                {"fuzz",                required_argument,      0,      'F'},
 778+                {"ifdef",               required_argument,      0,      'D'},
 779+                {"input",               required_argument,      0,      'i'},
 780+                {"ignore-whitespace",   no_argument,            0,      'l'},
 781+                {"no-backup-if-mismatch",       no_argument,    &backup_if_mismatch, 0},
 782+                {"normal",              no_argument,            0,      'n'},
 783+                {"output",              required_argument,      0,      'o'},
 784+                {"prefix",              required_argument,      0,      'B'},
 785+                {"quiet",               no_argument,            0,      's'},
 786+                {"reject-file",         required_argument,      0,      'r'},
 787+                {"remove-empty-files",  no_argument,            0,      'E'},
 788+                {"reverse",             no_argument,            0,      'R'},
 789+                {"silent",              no_argument,            0,      's'},
 790+                {"strip",               required_argument,      0,      'p'},
 791+                {"suffix",              required_argument,      0,      'z'},
 792+                {"unified",             no_argument,            0,      'u'},
 793+                {"version",             no_argument,            0,      'v'},
 794+                {"version-control",     required_argument,      0,      'V'},
 795+                {"posix",               no_argument,            &posix, 1},
 796+                {NULL,                  0,                      0,      0}
 797+        };
 798+        int ch;
 799+
 800+        rejname[0] = '\0';
 801+        Argc_last = Argc;
 802+        Argv_last = Argv;
 803+        if (!Argc)
 804+                return;
 805+        reset_getopt_state();
 806+        while ((ch = getopt_long(Argc, Argv, options, longopts, NULL)) != -1) {
 807+                switch (ch) {
 808+                case 'b':
 809+                        if (backup_type == BACKUP_UNDEFINED)
 810+                                backup_type = BACKUP_NUMBERED_EXISTING;
 811+                        if (optarg == NULL)
 812+                                break;
 813+                        if (verbose)
 814+                                say("Warning, the -b suffix option has been obsoleted by the -z option\n");
 815+                        /* FALLTHROUGH */
 816+                case 'z':
 817+                        simple_backup_suffix = savestr(optarg);
 818+                        break;
 819+                case 'B':
 820+                        origprae = savestr(optarg);
 821+                        break;
 822+                case 'c':
 823+                        diff_type = CONTEXT_DIFF;
 824+                        break;
 825+                case 'C':
 826+                        check_only = 1;
 827+                        break;
 828+                case 'd':
 829+                        if (chdir(optarg) < 0)
 830+                                pfatal("cant cd to %s", optarg);
 831+                        break;
 832+                case 'D':
 833+                        do_defines = 1;
 834+                        if (!isalpha((unsigned char)*optarg) && *optarg != '_')
 835+                                fatal("argument to -D is not an identifier\n");
 836+                        snprintf(if_defined, sizeof if_defined, "#ifdef %s\n", optarg);
 837+                        snprintf(not_defined, sizeof not_defined, "#ifndef %s\n", optarg);
 838+                        snprintf(end_defined, sizeof end_defined, "#endif /* %s */\n", optarg);
 839+                        break;
 840+                case 'e':
 841+                        diff_type = ED_DIFF;
 842+                        break;
 843+                case 'E':
 844+                        remove_empty_files = 1;
 845+                        break;
 846+                case 'f':
 847+                        force = 1;
 848+                        break;
 849+                case 'F':
 850+                        maxfuzz = strtolinenum(optarg, NULL);
 851+                        break;
 852+                case 'i':
 853+                        free(filearg[1]);
 854+                        filearg[1] = fetchname(optarg, &warn_on_invalid_line, 0);
 855+                        break;
 856+                case 'l':
 857+                        canonicalize = 1;
 858+                        break;
 859+                case 'n':
 860+                        diff_type = NORMAL_DIFF;
 861+                        break;
 862+                case 'N':
 863+                        noreverse = 1;
 864+                        break;
 865+                case 'o':
 866+                        outname = savestr(optarg);
 867+                        break;
 868+                case 'p':
 869+                        strippath = (int)strtolinenum(optarg, NULL);
 870+                        break;
 871+                case 'r':
 872+                        if (strlcpy(rejname, optarg, sizeof(rejname)) >= sizeof(rejname))
 873+                                fatal("reject filename %s too long\n", optarg);
 874+                        break;
 875+                case 'R':
 876+                        reverse = 1;
 877+                        reverse_flag_specified = 1;
 878+                        break;
 879+                case 's':
 880+                        verbose = 0;
 881+                        break;
 882+                case 't':
 883+                        batch = 1;
 884+                        break;
 885+                case 'u':
 886+                        diff_type = UNI_DIFF;
 887+                        break;
 888+                case 'v':
 889+                        version();
 890+                        break;
 891+                case 'V':
 892+                        backup_type = get_version(optarg);
 893+                        break;
 894+                case 'x':
 895 #ifdef DEBUGGING
 896-			debug = (int)strtolinenum(optarg, NULL);
 897+                        debug = (int)strtolinenum(optarg, NULL);
 898 #endif
 899-			break;
 900-		default:
 901-			if (ch == 0)
 902-				break;
 903-			usage();
 904-		}
 905-	}
 906-	Argc -= optind;
 907-	Argv += optind;
 908-
 909-	for (ch = 0; ch < Argc; ch++) {
 910-		if (filec >= MAXFILEC)
 911-			usage();
 912-		filearg[filec++] = savestr(Argv[ch]);
 913-	}
 914+                        break;
 915+                default:
 916+                        if (ch == 0)
 917+                                break;
 918+                        usage();
 919+                }
 920+        }
 921+        Argc -= optind;
 922+        Argv += optind;
 923+
 924+        for (ch = 0; ch < Argc; ch++) {
 925+                if (filec >= MAXFILEC)
 926+                        usage();
 927+                filearg[filec++] = savestr(Argv[ch]);
 928+        }
 929 }
 930 
 931 static void
 932 usage(void)
 933 {
 934-	fprintf(stderr, "usage: patch [-bCcEeflNnRstuv] [-B backup-prefix] [-D symbol] "
 935-	    "[-d directory] [-F max-fuzz] [-i patchfile] [-o out-file] "
 936-	    "[-p strip-count] [-r rej-name] [-V method] [-x number] "
 937-	    "[-z backup-ext] [origfile [patchfile]]\n");
 938-	my_exit(2);
 939+        fprintf(stderr, "usage: patch [-bCcEeflNnRstuv] [-B backup-prefix] [-D symbol] "
 940+            "[-d directory] [-F max-fuzz] [-i patchfile] [-o out-file] "
 941+            "[-p strip-count] [-r rej-name] [-V method] [-x number] "
 942+            "[-z backup-ext] [origfile [patchfile]]\n");
 943+        my_exit(2);
 944 }
 945 
 946 static LINENUM
 947 locate_hunk(LINENUM fuzz)
 948 {
 949-	LINENUM first_hunk_line = pch_first();
 950-	LINENUM count = pch_ptrn_lines();
 951-	LINENUM max_line = input_lines - count + 1;
 952-	LINENUM line;
 953-	LINENUM offset;
 954-
 955-	if (!count)
 956-		return first_hunk_line + last_offset;
 957-
 958-	if (first_hunk_line + last_offset <= 0)
 959-		offset = 1 - first_hunk_line;
 960-	else if (first_hunk_line + last_offset > max_line)
 961-		offset = max_line - first_hunk_line;
 962-	else
 963-		offset = last_offset;
 964-
 965-	for (line = first_hunk_line + offset; line <= max_line; line++) {
 966-		if (patch_match(line, count, fuzz)) {
 967-			last_offset = line - first_hunk_line;
 968-			return line;
 969-		}
 970-	}
 971-	for (line = first_hunk_line + offset - 1; line >= 1; line--) {
 972-		if (patch_match(line, count, fuzz)) {
 973-			last_offset = line - first_hunk_line;
 974-			return line;
 975-		}
 976-	}
 977-	return 0;
 978+        LINENUM first_hunk_line = pch_first();
 979+        LINENUM count = pch_ptrn_lines();
 980+        LINENUM max_line = input_lines - count + 1;
 981+        LINENUM line;
 982+        LINENUM offset;
 983+
 984+        if (!count)
 985+                return first_hunk_line + last_offset;
 986+
 987+        if (first_hunk_line + last_offset <= 0)
 988+                offset = 1 - first_hunk_line;
 989+        else if (first_hunk_line + last_offset > max_line)
 990+                offset = max_line - first_hunk_line;
 991+        else
 992+                offset = last_offset;
 993+
 994+        for (line = first_hunk_line + offset; line <= max_line; line++) {
 995+                if (patch_match(line, count, fuzz)) {
 996+                        last_offset = line - first_hunk_line;
 997+                        return line;
 998+                }
 999+        }
1000+        for (line = first_hunk_line + offset - 1; line >= 1; line--) {
1001+                if (patch_match(line, count, fuzz)) {
1002+                        last_offset = line - first_hunk_line;
1003+                        return line;
1004+                }
1005+        }
1006+        return 0;
1007 }
1008 
1009 static int
1010 patch_match(LINENUM line, LINENUM count, LINENUM fuzz)
1011 {
1012-	LINENUM i;
1013-	LINENUM pat_line;
1014-	char *str;
1015-	char *pat;
1016-	ssize_t len;
1017-
1018-	for (i = 1; i <= count; i++) {
1019-		pat_line = i;
1020-		if (i <= fuzz)
1021-			continue;
1022-		if (i > count - fuzz)
1023-			continue;
1024-		str = ifetch(line + i - 1 - fuzz, 0);
1025-		if (str == NULL)
1026-			return 0;
1027-		pat = pfetch(pat_line);
1028-		len = pch_line_len(pat_line);
1029-		if (canonicalize) {
1030-			if (!similar(str, pat, len))
1031-				return 0;
1032-		} else if (strncmp(str, pat, len) != 0)
1033-			return 0;
1034-	}
1035-	return 1;
1036+        LINENUM i;
1037+        LINENUM pat_line;
1038+        char *str;
1039+        char *pat;
1040+        ssize_t len;
1041+
1042+        for (i = 1; i <= count; i++) {
1043+                pat_line = i;
1044+                if (i <= fuzz)
1045+                        continue;
1046+                if (i > count - fuzz)
1047+                        continue;
1048+                str = ifetch(line + i - 1 - fuzz, 0);
1049+                if (str == NULL)
1050+                        return 0;
1051+                pat = pfetch(pat_line);
1052+                len = pch_line_len(pat_line);
1053+                if (canonicalize) {
1054+                        if (!similar(str, pat, len))
1055+                                return 0;
1056+                } else if (strncmp(str, pat, len) != 0)
1057+                        return 0;
1058+        }
1059+        return 1;
1060 }
1061 
1062 static int
1063 similar(const char *a, const char *b, ssize_t len)
1064 {
1065-	while (len > 0) {
1066-		if (isspace((unsigned char)*b)) {
1067-			if (!isspace((unsigned char)*a))
1068-				return 0;
1069-			while (len > 0 && isspace((unsigned char)*b)) {
1070-				b++;
1071-				len--;
1072-			}
1073-			while (isspace((unsigned char)*a) && *a != '\n')
1074-				a++;
1075-		} else {
1076-			if (*a != *b)
1077-				return 0;
1078-			a++;
1079-			b++;
1080-			len--;
1081-		}
1082-	}
1083-	if (*a == '\n' || *a == '\r') {
1084-		while (*a == '\n' || *a == '\r')
1085-			a++;
1086-		return *a == '\0';
1087-	}
1088-	return *a == '\0' || isspace((unsigned char)*a);
1089+        while (len > 0) {
1090+                if (isspace((unsigned char)*b)) {
1091+                        if (!isspace((unsigned char)*a))
1092+                                return 0;
1093+                        while (len > 0 && isspace((unsigned char)*b)) {
1094+                                b++;
1095+                                len--;
1096+                        }
1097+                        while (isspace((unsigned char)*a) && *a != '\n')
1098+                                a++;
1099+                } else {
1100+                        if (*a != *b)
1101+                                return 0;
1102+                        a++;
1103+                        b++;
1104+                        len--;
1105+                }
1106+        }
1107+        if (*a == '\n' || *a == '\r') {
1108+                while (*a == '\n' || *a == '\r')
1109+                        a++;
1110+                return *a == '\0';
1111+        }
1112+        return *a == '\0' || isspace((unsigned char)*a);
1113 }
1114 
1115 static void
1116 abort_hunk(void)
1117 {
1118-	LINENUM i;
1119-	LINENUM pat_line;
1120-	char *str;
1121-	ssize_t len;
1122+        LINENUM i;
1123 
1124-	for (i = 1; i <= pch_end(); i++) {
1125-		pat_line = i;
1126-		str = pfetch(pat_line);
1127-		len = pch_line_len(pat_line);
1128-		rej_line(pat_line, i);
1129-	}
1130+        for (i = 1; i <= pch_end(); i++)
1131+                rej_line(i, i);
1132 }
1133 
1134 static void
1135 rej_line(int pat_line, LINENUM i)
1136 {
1137-	char *str = pfetch(pat_line);
1138-	char ch = pch_char(pat_line);
1139-	if (rejfp != NULL) {
1140-		if (ch == ' ')
1141-			fprintf(rejfp, " %s", str);
1142-		else
1143-			fprintf(rejfp, "%c%s", ch, str);
1144-	}
1145-}
1146-
1147-static void
1148-abort_context_hunk(void)
1149-{
1150-	LINENUM i;
1151-	for (i = 0; i <= pch_end(); i++) {
1152-		rej_line(i, i);
1153-	}
1154+        char *str = pfetch(pat_line);
1155+        char ch = pch_char(pat_line);
1156+        (void)i;
1157+        if (rejfp != NULL) {
1158+                if (ch == ' ')
1159+                        fprintf(rejfp, " %s", str);
1160+                else
1161+                        fprintf(rejfp, "%c%s", ch, str);
1162+        }
1163 }
1164 
1165 static void
1166 apply_hunk(LINENUM where)
1167 {
1168-	LINENUM old = 1;
1169-	const LINENUM lastline = pch_ptrn_lines();
1170-	LINENUM new = lastline + 1;
1171+        LINENUM old = 1;
1172+        const LINENUM lastline = pch_ptrn_lines();
1173+        LINENUM new = lastline + 1;
1174 #define OUTSIDE 0
1175 #define IN_IFNDEF 1
1176 #define IN_IFDEF 2
1177 #define IN_ELSE 3
1178-	int def_state = OUTSIDE;
1179-	const LINENUM pat_end = pch_end();
1180-
1181-	where--;
1182-	while (pch_char(new) == '=' || pch_char(new) == '\n')
1183-		new++;
1184-
1185-	while (old <= lastline) {
1186-		if (pch_char(old) == '-') {
1187-			copy_till(where + old - 1, 0);
1188-			if (do_defines) {
1189-				if (def_state == OUTSIDE) {
1190-					fputs(not_defined, ofp);
1191-					def_state = IN_IFNDEF;
1192-				} else if (def_state == IN_IFDEF) {
1193-					fputs(else_defined, ofp);
1194-					def_state = IN_ELSE;
1195-				}
1196-				fputs(pfetch(old), ofp);
1197-			}
1198-			last_frozen_line++;
1199-			old++;
1200-		} else if (new > pat_end) {
1201-			break;
1202-		} else if (pch_char(new) == '+') {
1203-			copy_till(where + old - 1, 0);
1204-			if (do_defines) {
1205-				if (def_state == IN_IFNDEF) {
1206-					fputs(else_defined, ofp);
1207-					def_state = IN_ELSE;
1208-				} else if (def_state == OUTSIDE) {
1209-					fputs(if_defined, ofp);
1210-					def_state = IN_IFDEF;
1211-				}
1212-			}
1213-			fputs(pfetch(new), ofp);
1214-			new++;
1215-		} else if (pch_char(new) != pch_char(old)) {
1216-			say("Out-of-sync patch, lines %ld,%ld--mangled text or line numbers, maybe?\n",
1217-			    pch_hunk_beg() + old,
1218-			    pch_hunk_beg() + new);
1219-			my_exit(2);
1220-		} else if (pch_char(new) == '!') {
1221-			copy_till(where + old - 1, 0);
1222-			if (do_defines) {
1223-				fputs(not_defined, ofp);
1224-				def_state = IN_IFNDEF;
1225-			}
1226-			while (pch_char(old) == '!') {
1227-				if (do_defines) {
1228-					fputs(pfetch(old), ofp);
1229-				}
1230-				last_frozen_line++;
1231-				old++;
1232-			}
1233-			if (do_defines) {
1234-				fputs(else_defined, ofp);
1235-				def_state = IN_ELSE;
1236-			}
1237-			while (pch_char(new) == '!') {
1238-				fputs(pfetch(new), ofp);
1239-				new++;
1240-			}
1241-		} else {
1242-			if (pch_char(new) != ' ')
1243-				fatal("Internal error: expected ' '\n");
1244-			old++;
1245-			new++;
1246-			if (do_defines && def_state != OUTSIDE) {
1247-				fputs(end_defined, ofp);
1248-				def_state = OUTSIDE;
1249-			}
1250-		}
1251-	}
1252-	if (new <= pat_end && pch_char(new) == '+') {
1253-		copy_till(where + old - 1, 0);
1254-		if (do_defines) {
1255-			if (def_state == OUTSIDE) {
1256-				fputs(if_defined, ofp);
1257-				def_state = IN_IFDEF;
1258-			} else if (def_state == IN_IFNDEF) {
1259-				fputs(else_defined, ofp);
1260-				def_state = IN_ELSE;
1261-			}
1262-		}
1263-		while (new <= pat_end && pch_char(new) == '+') {
1264-			fputs(pfetch(new), ofp);
1265-			new++;
1266-		}
1267-	}
1268-	if (do_defines && def_state != OUTSIDE) {
1269-		fputs(end_defined, ofp);
1270-	}
1271+        int def_state = OUTSIDE;
1272+        const LINENUM pat_end = pch_end();
1273+
1274+        where--;
1275+        while (pch_char(new) == '=' || pch_char(new) == '\n')
1276+                new++;
1277+
1278+        while (old <= lastline) {
1279+                if (pch_char(old) == '-') {
1280+                        copy_till(where + old - 1, 0);
1281+                        if (do_defines) {
1282+                                if (def_state == OUTSIDE) {
1283+                                        fputs(not_defined, ofp);
1284+                                        def_state = IN_IFNDEF;
1285+                                } else if (def_state == IN_IFDEF) {
1286+                                        fputs(else_defined, ofp);
1287+                                        def_state = IN_ELSE;
1288+                                }
1289+                                fputs(pfetch(old), ofp);
1290+                        }
1291+                        last_frozen_line++;
1292+                        old++;
1293+                } else if (new > pat_end) {
1294+                        break;
1295+                } else if (pch_char(new) == '+') {
1296+                        copy_till(where + old - 1, 0);
1297+                        if (do_defines) {
1298+                                if (def_state == IN_IFNDEF) {
1299+                                        fputs(else_defined, ofp);
1300+                                        def_state = IN_ELSE;
1301+                                } else if (def_state == OUTSIDE) {
1302+                                        fputs(if_defined, ofp);
1303+                                        def_state = IN_IFDEF;
1304+                                }
1305+                        }
1306+                        fputs(pfetch(new), ofp);
1307+                        new++;
1308+                } else if (pch_char(new) != pch_char(old)) {
1309+                        say("Out-of-sync patch, lines %ld,%ld--mangled text or line numbers, maybe?\n",
1310+                            pch_hunk_beg() + old,
1311+                            pch_hunk_beg() + new);
1312+                        my_exit(2);
1313+                } else if (pch_char(new) == '!') {
1314+                        copy_till(where + old - 1, 0);
1315+                        if (do_defines) {
1316+                                fputs(not_defined, ofp);
1317+                                def_state = IN_IFNDEF;
1318+                        }
1319+                        while (pch_char(old) == '!') {
1320+                                if (do_defines) {
1321+                                        fputs(pfetch(old), ofp);
1322+                                }
1323+                                last_frozen_line++;
1324+                                old++;
1325+                        }
1326+                        if (do_defines) {
1327+                                fputs(else_defined, ofp);
1328+                                def_state = IN_ELSE;
1329+                        }
1330+                        while (pch_char(new) == '!') {
1331+                                fputs(pfetch(new), ofp);
1332+                                new++;
1333+                        }
1334+                } else {
1335+                        if (pch_char(new) != ' ')
1336+                                fatal("Internal error: expected ' '\n");
1337+                        old++;
1338+                        new++;
1339+                        if (do_defines && def_state != OUTSIDE) {
1340+                                fputs(end_defined, ofp);
1341+                                def_state = OUTSIDE;
1342+                        }
1343+                }
1344+        }
1345+        if (new <= pat_end && pch_char(new) == '+') {
1346+                copy_till(where + old - 1, 0);
1347+                if (do_defines) {
1348+                        if (def_state == OUTSIDE) {
1349+                                fputs(if_defined, ofp);
1350+                                def_state = IN_IFDEF;
1351+                        } else if (def_state == IN_IFNDEF) {
1352+                                fputs(else_defined, ofp);
1353+                                def_state = IN_ELSE;
1354+                        }
1355+                }
1356+                while (new <= pat_end && pch_char(new) == '+') {
1357+                        fputs(pfetch(new), ofp);
1358+                        new++;
1359+                }
1360+        }
1361+        if (do_defines && def_state != OUTSIDE) {
1362+                fputs(end_defined, ofp);
1363+        }
1364 #undef OUTSIDE
1365 #undef IN_IFNDEF
1366 #undef IN_IFDEF
1367@@ -959,2192 +942,2178 @@ apply_hunk(LINENUM where)
1368 static void
1369 dump_input_line(LINENUM line, int write_newline)
1370 {
1371-	char *s = ifetch(line, 0);
1372-	if (s == NULL)
1373-		return;
1374-	for (; *s != '\n' && *s != '\0'; s++)
1375-		putc(*s, ofp);
1376-	if (write_newline)
1377-		putc('\n', ofp);
1378+        char *s = ifetch(line, 0);
1379+        if (s == NULL)
1380+                return;
1381+        for (; *s != '\n' && *s != '\0'; s++)
1382+                putc(*s, ofp);
1383+        if (write_newline)
1384+                putc('\n', ofp);
1385 }
1386 
1387 static void
1388 copy_till(LINENUM line, int end)
1389 {
1390-	if (last_frozen_line > line)
1391-		fatal("misordered hunks! output would be garbled\n");
1392-	while (last_frozen_line < line) {
1393-		if (++last_frozen_line == line && end)
1394-			dump_input_line(last_frozen_line, !last_line_missing_eol);
1395-		else
1396-			dump_input_line(last_frozen_line, 1);
1397-	}
1398+        if (last_frozen_line > line)
1399+                fatal("misordered hunks! output would be garbled\n");
1400+        while (last_frozen_line < line) {
1401+                if (++last_frozen_line == line && end)
1402+                        dump_input_line(last_frozen_line, !last_line_missing_eol);
1403+                else
1404+                        dump_input_line(last_frozen_line, 1);
1405+        }
1406 }
1407 
1408 static int
1409 spew_output(void)
1410 {
1411-	if (input_lines)
1412-		copy_till(input_lines, 1);
1413-	if (ferror(ofp) || fclose(ofp))
1414-		return 0;
1415-	ofp = NULL;
1416-	return 1;
1417+        if (input_lines)
1418+                copy_till(input_lines, 1);
1419+        if (ferror(ofp) || fclose(ofp))
1420+                return 0;
1421+        ofp = NULL;
1422+        return 1;
1423 }
1424 
1425 static void
1426 init_output(const char *name)
1427 {
1428-	ofp = fopen(name, "w");
1429-	if (ofp == NULL)
1430-		pfatal("cant create %s", name);
1431+        ofp = fopen(name, "w");
1432+        if (ofp == NULL)
1433+                pfatal("cant create %s", name);
1434 }
1435 
1436 static void
1437 init_reject(const char *name)
1438 {
1439-	rejfp = fopen(name, "w");
1440-	if (rejfp == NULL)
1441-		pfatal("cant create %s", name);
1442+        rejfp = fopen(name, "w");
1443+        if (rejfp == NULL)
1444+                pfatal("cant create %s", name);
1445 }
1446 
1447 void
1448 re_input(void)
1449 {
1450-	if (using_plan_a) {
1451-		i_size = 0;
1452-		free(i_ptr);
1453-		i_ptr = NULL;
1454-		if (i_womp != NULL) {
1455-			munmap(i_womp, i_size);
1456-			i_womp = NULL;
1457-		}
1458-	} else {
1459-		using_plan_a = 1;
1460-		close(tifd);
1461-		tifd = -1;
1462-		free(tibuf[0]);
1463-		free(tibuf[1]);
1464-		tibuf[0] = tibuf[1] = NULL;
1465-		tiline[0] = tiline[1] = -1;
1466-		tireclen = 0;
1467-	}
1468+        if (using_plan_a) {
1469+                i_size = 0;
1470+                free(i_ptr);
1471+                i_ptr = NULL;
1472+                if (i_womp != NULL) {
1473+                        munmap(i_womp, i_size);
1474+                        i_womp = NULL;
1475+                }
1476+        } else {
1477+                using_plan_a = 1;
1478+                close(tifd);
1479+                tifd = -1;
1480+                free(tibuf[0]);
1481+                free(tibuf[1]);
1482+                tibuf[0] = tibuf[1] = NULL;
1483+                tiline[0] = tiline[1] = -1;
1484+                tireclen = 0;
1485+        }
1486 }
1487 
1488 void
1489 scan_input(const char *filename)
1490 {
1491-	if (!plan_a(filename))
1492-		plan_b(filename);
1493-	if (verbose) {
1494-		say("Patching file %s using Plan %s...\n", filename, (using_plan_a ? "A" : "B"));
1495-	}
1496+        if (!plan_a(filename))
1497+                plan_b(filename);
1498+        if (verbose) {
1499+                say("Patching file %s using Plan %s...\n", filename, (using_plan_a ? "A" : "B"));
1500+        }
1501 }
1502 
1503 static int
1504 reallocate_lines(size_t *lines_allocated)
1505 {
1506-	char **p;
1507-	size_t new_size;
1508+        char **p;
1509+        size_t new_size;
1510 
1511-	new_size = *lines_allocated * 3 / 2;
1512-	p = pch_realloc(i_ptr, new_size + 2, sizeof(char *));
1513-	if (p == NULL) {
1514-		munmap(i_womp, i_size);
1515-		i_womp = NULL;
1516-		free(i_ptr);
1517-		i_ptr = NULL;
1518-		*lines_allocated = 0;
1519-		return 0;
1520-	}
1521-	*lines_allocated = new_size;
1522-	i_ptr = p;
1523-	return 1;
1524+        new_size = *lines_allocated * 3 / 2;
1525+        p = pch_realloc(i_ptr, new_size + 2, sizeof(char *));
1526+        if (p == NULL) {
1527+                munmap(i_womp, i_size);
1528+                i_womp = NULL;
1529+                free(i_ptr);
1530+                i_ptr = NULL;
1531+                *lines_allocated = 0;
1532+                return 0;
1533+        }
1534+        *lines_allocated = new_size;
1535+        i_ptr = p;
1536+        return 1;
1537 }
1538 
1539 static int
1540 plan_a(const char *filename)
1541 {
1542-	int ifd, statfailed, devnull, pstat;
1543-	char *p, *s, *lbuf;
1544-	struct stat filestat;
1545-	off_t i;
1546-	ptrdiff_t sz;
1547-	size_t iline, lines_allocated, lbufsz;
1548-	pid_t pid;
1549-	char *argp[4] = {NULL};
1550+        int ifd, statfailed;
1551+        char *p, *s, *lbuf;
1552+        struct stat filestat;
1553+        off_t i;
1554+        ptrdiff_t sz;
1555+        size_t iline, lines_allocated, lbufsz;
1556 
1557 #ifdef DEBUGGING
1558-	if (debug & 8)
1559-		return 0;
1560+        if (debug & 8)
1561+                return 0;
1562 #endif
1563 
1564-	if (filename == NULL || *filename == '\0')
1565-		return 0;
1566-
1567-	statfailed = stat(filename, &filestat);
1568-	if (statfailed && ok_to_create_file) {
1569-		if (verbose)
1570-			say("(Creating file %s...)\n", filename);
1571-		if (check_only)
1572-			return 1;
1573-		makedirs(filename, 1);
1574-		close(creat(filename, 0666));
1575-		statfailed = stat(filename, &filestat);
1576-	}
1577-	if (statfailed && check_only)
1578-		fatal("%s not found, -C mode, cant probe further\n", filename);
1579-
1580-	if (statfailed || (filestat.st_mode & 0222) == 0 ||
1581-	    ((filestat.st_mode & 0022) == 0 && filestat.st_uid != getuid())) {
1582-		char *filebase, *filedir;
1583-		struct stat cstat;
1584-		char *tmp_filename1, *tmp_filename2;
1585-
1586-		tmp_filename1 = strdup(filename);
1587-		tmp_filename2 = strdup(filename);
1588-		if (tmp_filename1 == NULL || tmp_filename2 == NULL)
1589-			fatal("strdupping filename");
1590-		filebase = basename(tmp_filename1);
1591-		filedir = dirname(tmp_filename2);
1592-
1593-		lbufsz = INITLINELEN;
1594-		if ((lbuf = malloc(bufsz)) == NULL)
1595-			pfatal("allocating line buffer");
1596-		lbuf[0] = '\0';
1597+        if (filename == NULL || *filename == '\0')
1598+                return 0;
1599+
1600+        statfailed = stat(filename, &filestat);
1601+        if (statfailed && ok_to_create_file) {
1602+                if (verbose)
1603+                        say("(Creating file %s...)\n", filename);
1604+                if (check_only)
1605+                        return 1;
1606+                makedirs(filename, 1);
1607+                close(creat(filename, 0666));
1608+                statfailed = stat(filename, &filestat);
1609+        }
1610+        if (statfailed && check_only)
1611+                fatal("%s not found, -C mode, cant probe further\n", filename);
1612+
1613+        if (statfailed || (filestat.st_mode & 0222) == 0 ||
1614+            ((filestat.st_mode & 0022) == 0 && filestat.st_uid != getuid())) {
1615+                char *filebase, *filedir;
1616+                struct stat cstat;
1617+                char *tmp_filename1, *tmp_filename2;
1618+
1619+                tmp_filename1 = strdup(filename);
1620+                tmp_filename2 = strdup(filename);
1621+                if (tmp_filename1 == NULL || tmp_filename2 == NULL)
1622+                        fatal("strdupping filename");
1623+                filebase = basename(tmp_filename1);
1624+                filedir = dirname(tmp_filename2);
1625+
1626+                lbufsz = INITLINELEN;
1627+                if ((lbuf = malloc(bufsz)) == NULL)
1628+                        pfatal("allocating line buffer");
1629+                lbuf[0] = '\0';
1630 
1631 #define try(f, a1, a2, a3) \
1632-	(snprintf(lbuf, lbufsz, f, a1, a2, a3), stat(lbuf, &cstat) == 0)
1633-
1634-		if (try("%s/RCS/%s%s", filedir, filebase, RCSSUFFIX) ||
1635-		    try("%s/RCS/%s%s", filedir, filebase, "") ||
1636-		    try("%s/%s%s", filedir, filebase, RCSSUFFIX)) {
1637-			if (!statfailed) {
1638-				if ((filestat.st_mode & 0222) != 0)
1639-					fatal("file %s seems to be locked by somebody else under RCS\n", filename);
1640-				if (verbose)
1641-					say("Comparing file %s to default RCS version...\n", filename);
1642-				switch (pid = fork()) {
1643-				case -1:
1644-					fatal("cant fork: %s\n", strerror(errno));
1645-				case 0:
1646-					devnull = open("/dev/null", O_RDONLY);
1647-					if (devnull == -1)
1648-						fatal("cant open /dev/null: %s", strerror(errno));
1649-					dup2(devnull, STDOUT_FILENO);
1650-					argp[0] = __UNCONST(RCSDIFF);
1651-					argp[1] = __UNCONST(filename);
1652-					execv(RCSDIFF, argp);
1653-					exit(127);
1654-				}
1655-				pid = waitpid(pid, &pstat, 0);
1656-				if (pid == -1 || WEXITSTATUS(pstat) != 0)
1657-					fatal("cant check out file %s: differs from default RCS version\n", filename);
1658-			}
1659-			if (verbose)
1660-				say("Checking out file %s from RCS...\n", filename);
1661-			switch (pid = fork()) {
1662-			case -1:
1663-				fatal("cant fork: %s\n", strerror(errno));
1664-			case 0:
1665-				argp[0] = __UNCONST(CHECKOUT);
1666-				argp[1] = __UNCONST("-l");
1667-				argp[2] = __UNCONST(filename);
1668-				execv(CHECKOUT, argp);
1669-				exit(127);
1670-			}
1671-			pid = waitpid(pid, &pstat, 0);
1672-			if (pid == -1 || WEXITSTATUS(pstat) != 0 || stat(filename, &filestat))
1673-				fatal("cant check out file %s from RCS\n", filename);
1674-		} else if (statfailed) {
1675-			fatal("cant find %s\n", filename);
1676-		}
1677+        (snprintf(lbuf, lbufsz, f, a1, a2, a3), stat(lbuf, &cstat) == 0)
1678+
1679+                if (try("%s/RCS/%s%s", filedir, filebase, RCSSUFFIX) ||
1680+                    try("%s/RCS/%s%s", filedir, filebase, "") ||
1681+                    try("%s/%s%s", filedir, filebase, RCSSUFFIX)) {
1682+                        if (!statfailed) {
1683+                                if ((filestat.st_mode & 0222) != 0)
1684+                                        fatal("file %s seems to be locked by somebody else under RCS\n", filename);
1685+                                if (verbose)
1686+                                        say("Comparing file %s to default RCS version...\n", filename);
1687+                                {
1688+                                        char *rcsdiff_argv[3];
1689+                                        rcsdiff_argv[0] = __UNCONST(RCSDIFF);
1690+                                        rcsdiff_argv[1] = __UNCONST(filename);
1691+                                        rcsdiff_argv[2] = NULL;
1692+                                        if (wexecvp(RCSDIFF, rcsdiff_argv) != 0)
1693+                                                fatal("cant check out file %s: differs from default RCS version\n", filename);
1694+                                }
1695+                        }
1696+                        if (verbose)
1697+                                say("Checking out file %s from RCS...\n", filename);
1698+                        {
1699+                                char *co_argv[4];
1700+                                co_argv[0] = __UNCONST(CHECKOUT);
1701+                                co_argv[1] = __UNCONST("-l");
1702+                                co_argv[2] = __UNCONST(filename);
1703+                                co_argv[3] = NULL;
1704+                                if (wexecvp(CHECKOUT, co_argv) != 0 || stat(filename, &filestat))
1705+                                        fatal("cant check out file %s from RCS\n", filename);
1706+                        }
1707+                } else if (statfailed) {
1708+                        fatal("cant find %s\n", filename);
1709+                }
1710 #undef try
1711-		free(lbuf);
1712-		free(tmp_filename1);
1713-		free(tmp_filename2);
1714-	}
1715-
1716-	filemode = filestat.st_mode;
1717-	if (!S_ISREG(filemode))
1718-		fatal("%s is not a normal file--cant patch\n", filename);
1719-	i_size = filestat.st_size;
1720-	if (out_of_mem) {
1721-		set_hunkmax();
1722-		out_of_mem = 0;
1723-		return 0;
1724-	}
1725-	if ((uintmax_t)i_size > (uintmax_t)SIZE_MAX) {
1726-		say("block too large to mmap\n");
1727-		return 0;
1728-	}
1729-	if ((ifd = open(filename, O_RDONLY)) < 0)
1730-		pfatal("cant open file %s", filename);
1731-
1732-	if (i_size) {
1733-		i_womp = mmap(NULL, i_size, PROT_READ, MAP_PRIVATE, ifd, 0);
1734-		if (i_womp == MAP_FAILED) {
1735-			perror("mmap failed");
1736-			i_womp = NULL;
1737-			close(ifd);
1738-			return 0;
1739-		}
1740-	} else
1741-		i_womp = NULL;
1742-
1743-	close(ifd);
1744-	if (i_size)
1745-		madvise(i_womp, i_size, MADV_SEQUENTIAL);
1746-
1747-	lines_allocated = i_size / 25;
1748-	if (lines_allocated < 100)
1749-		lines_allocated = 100;
1750-
1751-	if (!reallocate_lines(&lines_allocated))
1752-		return 0;
1753-
1754-	iline = 1;
1755-	i_ptr[iline] = i_womp;
1756-	for (s = i_womp, i = 0; i < i_size && *s != '\0'; s++, i++) {
1757-		if (*s == '\n') {
1758-			if (iline == lines_allocated) {
1759-				if (!reallocate_lines(&lines_allocated))
1760-					return 0;
1761-			}
1762-			i_ptr[++iline] = s + 1;
1763-		}
1764-	}
1765-	if (i_size > 0 && i_womp[i_size - 1] != '\n') {
1766-		last_line_missing_eol = 1;
1767-		sz = s - i_ptr[iline];
1768-		p = malloc(sz + 1);
1769-		if (p == NULL) {
1770-			free(i_ptr);
1771-			i_ptr = NULL;
1772-			munmap(i_womp, i_size);
1773-			i_womp = NULL;
1774-			return 0;
1775-		}
1776-		memcpy(p, i_ptr[iline], sz);
1777-		p[sz] = '\n';
1778-		i_ptr[iline] = p;
1779-		i_ptr[++iline] = empty_line;
1780-	} else
1781-		last_line_missing_eol = 0;
1782-
1783-	input_lines = iline - 1;
1784-
1785-	if (revision != NULL) {
1786-		if (!rev_in_string(i_womp)) {
1787-			if (force) {
1788-				if (verbose)
1789-					say("Warning: this file doesnt appear to be the %s version--patching anyway\n", revision);
1790-			} else if (batch) {
1791-				fatal("this file doesnt appear to be the %s version--aborting\n", revision);
1792-			} else {
1793-				ask("This file doesnt appear to be the %s version--patch anyway? [n] ", revision);
1794-				if (*buf != 'y')
1795-					fatal("aborted\n");
1796-			}
1797-		} else if (verbose)
1798-			say("Good. This file appears to be the %s version.\n", revision);
1799-	}
1800-	return 1;
1801+                free(lbuf);
1802+                free(tmp_filename1);
1803+                free(tmp_filename2);
1804+        }
1805+
1806+        filemode = filestat.st_mode;
1807+        if (!S_ISREG(filemode))
1808+                fatal("%s is not a normal file--cant patch\n", filename);
1809+        i_size = filestat.st_size;
1810+        if (out_of_mem) {
1811+                set_hunkmax();
1812+                out_of_mem = 0;
1813+                return 0;
1814+        }
1815+        if ((uintmax_t)i_size > (uintmax_t)SIZE_MAX) {
1816+                say("block too large to mmap\n");
1817+                return 0;
1818+        }
1819+        if ((ifd = open(filename, O_RDONLY)) < 0)
1820+                pfatal("cant open file %s", filename);
1821+
1822+        if (i_size) {
1823+                i_womp = mmap(NULL, i_size, PROT_READ, MAP_PRIVATE, ifd, 0);
1824+                if (i_womp == MAP_FAILED) {
1825+                        perror("mmap failed");
1826+                        i_womp = NULL;
1827+                        close(ifd);
1828+                        return 0;
1829+                }
1830+        } else
1831+                i_womp = NULL;
1832+
1833+        close(ifd);
1834+        if (i_size)
1835+                madvise(i_womp, i_size, MADV_SEQUENTIAL);
1836+
1837+        lines_allocated = i_size / 25;
1838+        if (lines_allocated < 100)
1839+                lines_allocated = 100;
1840+
1841+        if (!reallocate_lines(&lines_allocated))
1842+                return 0;
1843+
1844+        iline = 1;
1845+        i_ptr[iline] = i_womp;
1846+        for (s = i_womp, i = 0; i < i_size && *s != '\0'; s++, i++) {
1847+                if (*s == '\n') {
1848+                        if (iline == lines_allocated) {
1849+                                if (!reallocate_lines(&lines_allocated))
1850+                                        return 0;
1851+                        }
1852+                        i_ptr[++iline] = s + 1;
1853+                }
1854+        }
1855+        if (i_size > 0 && i_womp[i_size - 1] != '\n') {
1856+                last_line_missing_eol = 1;
1857+                sz = s - i_ptr[iline];
1858+                p = malloc(sz + 1);
1859+                if (p == NULL) {
1860+                        free(i_ptr);
1861+                        i_ptr = NULL;
1862+                        munmap(i_womp, i_size);
1863+                        i_womp = NULL;
1864+                        return 0;
1865+                }
1866+                memcpy(p, i_ptr[iline], sz);
1867+                p[sz] = '\n';
1868+                i_ptr[iline] = p;
1869+                i_ptr[++iline] = empty_line;
1870+        } else
1871+                last_line_missing_eol = 0;
1872+
1873+        input_lines = iline - 1;
1874+
1875+        if (revision != NULL) {
1876+                if (!rev_in_string(i_womp)) {
1877+                        if (force) {
1878+                                if (verbose)
1879+                                        say("Warning: this file doesnt appear to be the %s version--patching anyway\n", revision);
1880+                        } else if (batch) {
1881+                                fatal("this file doesnt appear to be the %s version--aborting\n", revision);
1882+                        } else {
1883+                                ask("This file doesnt appear to be the %s version--patch anyway? [n] ", revision);
1884+                                if (*buf != 'y')
1885+                                        fatal("aborted\n");
1886+                        }
1887+                } else if (verbose)
1888+                        say("Good. This file appears to be the %s version.\n", revision);
1889+        }
1890+        return 1;
1891 }
1892 
1893 static void
1894 plan_b(const char *filename)
1895 {
1896-	FILE *ifp;
1897-	size_t i = 0, j, maxlen = 1;
1898-	char *p;
1899-	int found_revision = (revision == NULL);
1900-
1901-	using_plan_a = 0;
1902-	if ((ifp = fopen(filename, "r")) == NULL)
1903-		pfatal("cant open file %s", filename);
1904-	unlink(TMPINNAME);
1905-	if ((tifd = open(TMPINNAME, O_EXCL | O_CREAT | O_WRONLY, 0666)) < 0)
1906-		pfatal("cant open file %s", TMPINNAME);
1907-	while (getline(&buf, &bufsz, ifp) != -1) {
1908-		if (revision != NULL && !found_revision && rev_in_string(buf))
1909-			found_revision = 1;
1910-		if ((i = strlen(buf)) > maxlen)
1911-			maxlen = i;
1912-	}
1913-	last_line_missing_eol = i > 0 && buf[i - 1] != '\n';
1914-	if (last_line_missing_eol && maxlen == i)
1915-		maxlen++;
1916-
1917-	if (revision != NULL) {
1918-		if (!found_revision) {
1919-			if (force) {
1920-				if (verbose)
1921-					say("Warning: this file doesnt appear to be the %s version--patching anyway\n", revision);
1922-			} else if (batch) {
1923-				fatal("this file doesnt appear to be the %s version--aborting\n", revision);
1924-			} else {
1925-				ask("This file doesnt appear to be the %s version--patch anyway? [n] ", revision);
1926-				if (*buf != 'y')
1927-					fatal("aborted\n");
1928-			}
1929-		} else if (verbose)
1930-			say("Good. This file appears to be the %s version.\n", revision);
1931-	}
1932-	fseek(ifp, 0L, SEEK_SET);
1933-	lines_per_buf = BUFFERSIZE / maxlen;
1934-	tireclen = maxlen;
1935-	tibuf[0] = malloc(BUFFERSIZE + 1);
1936-	if (tibuf[0] == NULL)
1937-		fatal("out of memory\n");
1938-	tibuf[1] = malloc(BUFFERSIZE + 1);
1939-	if (tibuf[1] == NULL)
1940-		fatal("out of memory\n");
1941-	for (i = 1;; i++) {
1942-		p = tibuf[0] + maxlen * (i % lines_per_buf);
1943-		if (i % lines_per_buf == 0) {
1944-			if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
1945-				pfatal("cant write temp file");
1946-		}
1947-		if (fgets(p, maxlen + 1, ifp) == NULL) {
1948-			input_lines = i - 1;
1949-			if (i % lines_per_buf != 0) {
1950-				if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
1951-					pfatal("cant write temp file");
1952-			}
1953-			break;
1954-		}
1955-		j = strlen(p);
1956-		if (j == 0 || p[j - 1] != '\n')
1957-			p[j] = '\n';
1958-	}
1959-	fclose(ifp);
1960-	close(tifd);
1961-	if ((tifd = open(TMPINNAME, O_RDONLY)) < 0)
1962-		pfatal("cant reopen file %s", TMPINNAME);
1963+        FILE *ifp;
1964+        size_t i = 0, j, maxlen = 1;
1965+        char *p;
1966+        int found_revision = (revision == NULL);
1967+
1968+        using_plan_a = 0;
1969+        if ((ifp = fopen(filename, "r")) == NULL)
1970+                pfatal("cant open file %s", filename);
1971+        unlink(TMPINNAME);
1972+        if ((tifd = open(TMPINNAME, O_EXCL | O_CREAT | O_WRONLY, 0666)) < 0)
1973+                pfatal("cant open file %s", TMPINNAME);
1974+        while (getline(&buf, &bufsz, ifp) != -1) {
1975+                if (revision != NULL && !found_revision && rev_in_string(buf))
1976+                        found_revision = 1;
1977+                if ((i = strlen(buf)) > maxlen)
1978+                        maxlen = i;
1979+        }
1980+        last_line_missing_eol = i > 0 && buf[i - 1] != '\n';
1981+        if (last_line_missing_eol && maxlen == i)
1982+                maxlen++;
1983+
1984+        if (revision != NULL) {
1985+                if (!found_revision) {
1986+                        if (force) {
1987+                                if (verbose)
1988+                                        say("Warning: this file doesnt appear to be the %s version--patching anyway\n", revision);
1989+                        } else if (batch) {
1990+                                fatal("this file doesnt appear to be the %s version--aborting\n", revision);
1991+                        } else {
1992+                                ask("This file doesnt appear to be the %s version--patch anyway? [n] ", revision);
1993+                                if (*buf != 'y')
1994+                                        fatal("aborted\n");
1995+                        }
1996+                } else if (verbose)
1997+                        say("Good. This file appears to be the %s version.\n", revision);
1998+        }
1999+        fseek(ifp, 0L, SEEK_SET);
2000+        lines_per_buf = BUFFERSIZE / maxlen;
2001+        tireclen = maxlen;
2002+        tibuf[0] = malloc(BUFFERSIZE + 1);
2003+        if (tibuf[0] == NULL)
2004+                fatal("out of memory\n");
2005+        tibuf[1] = malloc(BUFFERSIZE + 1);
2006+        if (tibuf[1] == NULL)
2007+                fatal("out of memory\n");
2008+        for (i = 1;; i++) {
2009+                p = tibuf[0] + maxlen * (i % lines_per_buf);
2010+                if (i % lines_per_buf == 0) {
2011+                        if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
2012+                                pfatal("cant write temp file");
2013+                }
2014+                if (fgets(p, maxlen + 1, ifp) == NULL) {
2015+                        input_lines = i - 1;
2016+                        if (i % lines_per_buf != 0) {
2017+                                if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
2018+                                        pfatal("cant write temp file");
2019+                        }
2020+                        break;
2021+                }
2022+                j = strlen(p);
2023+                if (j == 0 || p[j - 1] != '\n')
2024+                        p[j] = '\n';
2025+        }
2026+        fclose(ifp);
2027+        close(tifd);
2028+        if ((tifd = open(TMPINNAME, O_RDONLY)) < 0)
2029+                pfatal("cant reopen file %s", TMPINNAME);
2030 }
2031 
2032 char *
2033 ifetch(LINENUM line, int whichbuf)
2034 {
2035-	if (line < 1 || line > input_lines) {
2036-		if (warn_on_invalid_line) {
2037-			say("No such line %ld in input file, ignoring\n", line);
2038-			warn_on_invalid_line = 0;
2039-		}
2040-		return NULL;
2041-	}
2042-	if (using_plan_a)
2043-		return i_ptr[line];
2044-	else {
2045-		LINENUM offline = line % lines_per_buf;
2046-		LINENUM baseline = line - offline;
2047-
2048-		if (tiline[0] == baseline)
2049-			whichbuf = 0;
2050-		else if (tiline[1] == baseline)
2051-			whichbuf = 1;
2052-		else {
2053-			tiline[whichbuf] = baseline;
2054-			if (lseek(tifd, (off_t)(baseline / lines_per_buf * BUFFERSIZE), SEEK_SET) < 0)
2055-				pfatal("cannot seek in the temporary input file");
2056-			if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0)
2057-				pfatal("error reading tmp file %s", TMPINNAME);
2058-		}
2059-		return tibuf[whichbuf] + (tireclen * offline);
2060-	}
2061+        if (line < 1 || line > input_lines) {
2062+                if (warn_on_invalid_line) {
2063+                        say("No such line %ld in input file, ignoring\n", line);
2064+                        warn_on_invalid_line = 0;
2065+                }
2066+                return NULL;
2067+        }
2068+        if (using_plan_a)
2069+                return i_ptr[line];
2070+        else {
2071+                LINENUM offline = line % lines_per_buf;
2072+                LINENUM baseline = line - offline;
2073+
2074+                if (tiline[0] == baseline)
2075+                        whichbuf = 0;
2076+                else if (tiline[1] == baseline)
2077+                        whichbuf = 1;
2078+                else {
2079+                        tiline[whichbuf] = baseline;
2080+                        if (lseek(tifd, (off_t)(baseline / lines_per_buf * BUFFERSIZE), SEEK_SET) < 0)
2081+                                pfatal("cannot seek in the temporary input file");
2082+                        if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0)
2083+                                pfatal("error reading tmp file %s", TMPINNAME);
2084+                }
2085+                return tibuf[whichbuf] + (tireclen * offline);
2086+        }
2087 }
2088 
2089 static int
2090 rev_in_string(const char *string)
2091 {
2092-	const char *s;
2093-	size_t patlen;
2094+        const char *s;
2095+        size_t patlen;
2096 
2097-	if (revision == NULL)
2098-		return 1;
2099-	patlen = strlen(revision);
2100-	if (strnEQ(string, revision, patlen) && isspace((unsigned char)string[patlen]))
2101-		return 1;
2102-	for (s = string; *s; s++) {
2103-		if (isspace((unsigned char)*s) && strnEQ(s + 1, revision, patlen) &&
2104-		    isspace((unsigned char)s[patlen + 1]))
2105-			return 1;
2106-	}
2107-	return 0;
2108+        if (revision == NULL)
2109+                return 1;
2110+        patlen = strlen(revision);
2111+        if (strnEQ(string, revision, patlen) && isspace((unsigned char)string[patlen]))
2112+                return 1;
2113+        for (s = string; *s; s++) {
2114+                if (isspace((unsigned char)*s) && strnEQ(s + 1, revision, patlen) &&
2115+                    isspace((unsigned char)s[patlen + 1]))
2116+                        return 1;
2117+        }
2118+        return 0;
2119 }
2120 
2121 void
2122 re_patch(void)
2123 {
2124-	p_first = 0;
2125-	p_newfirst = 0;
2126-	p_ptrn_lines = 0;
2127-	p_repl_lines = 0;
2128-	p_end = (LINENUM)-1;
2129-	p_max = 0;
2130-	p_indent = 0;
2131+        p_first = 0;
2132+        p_newfirst = 0;
2133+        p_ptrn_lines = 0;
2134+        p_repl_lines = 0;
2135+        p_end = (LINENUM)-1;
2136+        p_max = 0;
2137+        p_indent = 0;
2138 }
2139 
2140 void
2141 open_patch_file(const char *filename)
2142 {
2143-	struct stat filestat;
2144-
2145-	if (filename == NULL || *filename == '\0' || strEQ(filename, "-")) {
2146-		pfp = fopen(TMPPATNAME, "w");
2147-		if (pfp == NULL)
2148-			pfatal("cant create %s", TMPPATNAME);
2149-		while (getline(&buf, &bufsz, stdin) != -1)
2150-			fprintf(pfp, "%s", buf);
2151-		if (ferror(pfp) || fclose(pfp))
2152-			pfatal("cant write %s", TMPPATNAME);
2153-		filename = TMPPATNAME;
2154-	}
2155-	pfp = fopen(filename, "r");
2156-	if (pfp == NULL)
2157-		pfatal("patch file %s not found", filename);
2158-	fstat(fileno(pfp), &filestat);
2159-	p_filesize = filestat.st_size;
2160-	next_intuit_at(0L, 1L);
2161-	set_hunkmax();
2162+        struct stat filestat;
2163+
2164+        if (filename == NULL || *filename == '\0' || strEQ(filename, "-")) {
2165+                pfp = fopen(TMPPATNAME, "w");
2166+                if (pfp == NULL)
2167+                        pfatal("cant create %s", TMPPATNAME);
2168+                while (getline(&buf, &bufsz, stdin) != -1)
2169+                        fprintf(pfp, "%s", buf);
2170+                if (ferror(pfp) || fclose(pfp))
2171+                        pfatal("cant write %s", TMPPATNAME);
2172+                filename = TMPPATNAME;
2173+        }
2174+        pfp = fopen(filename, "r");
2175+        if (pfp == NULL)
2176+                pfatal("patch file %s not found", filename);
2177+        fstat(fileno(pfp), &filestat);
2178+        p_filesize = filestat.st_size;
2179+        next_intuit_at(0L, 1L);
2180+        set_hunkmax();
2181 }
2182 
2183 void
2184 set_hunkmax(void)
2185 {
2186-	if (p_line == NULL)
2187-		p_line = calloc((size_t)hunkmax, sizeof(char *));
2188-	if (p_len == NULL)
2189-		p_len = calloc((size_t)hunkmax, sizeof(ssize_t));
2190-	if (p_char == NULL)
2191-		p_char = calloc((size_t)hunkmax, sizeof(char));
2192+        if (p_line == NULL)
2193+                p_line = calloc((size_t)hunkmax, sizeof(char *));
2194+        if (p_len == NULL)
2195+                p_len = calloc((size_t)hunkmax, sizeof(ssize_t));
2196+        if (p_char == NULL)
2197+                p_char = calloc((size_t)hunkmax, sizeof(char));
2198 }
2199 
2200 static void
2201 grow_hunkmax(void)
2202 {
2203-	int new_hunkmax;
2204-	char **new_p_line;
2205-	ssize_t *new_p_len;
2206-	char *new_p_char;
2207+        int new_hunkmax;
2208+        char **new_p_line;
2209+        ssize_t *new_p_len;
2210+        char *new_p_char;
2211 
2212-	new_hunkmax = hunkmax * 2;
2213-	if (p_line == NULL || p_len == NULL || p_char == NULL)
2214-		fatal("Internal memory allocation error\n");
2215+        new_hunkmax = hunkmax * 2;
2216+        if (p_line == NULL || p_len == NULL || p_char == NULL)
2217+                fatal("Internal memory allocation error\n");
2218 
2219-	new_p_line = pch_realloc(p_line, new_hunkmax, sizeof(char *));
2220-	if (new_p_line == NULL)
2221-		free(p_line);
2222-	new_p_len = pch_realloc(p_len, new_hunkmax, sizeof(ssize_t));
2223-	if (new_p_len == NULL)
2224-		free(p_len);
2225-	new_p_char = pch_realloc(p_char, new_hunkmax, sizeof(char));
2226-	if (new_p_char == NULL)
2227-		free(p_char);
2228+        new_p_line = pch_realloc(p_line, new_hunkmax, sizeof(char *));
2229+        if (new_p_line == NULL)
2230+                free(p_line);
2231+        new_p_len = pch_realloc(p_len, new_hunkmax, sizeof(ssize_t));
2232+        if (new_p_len == NULL)
2233+                free(p_len);
2234+        new_p_char = pch_realloc(p_char, new_hunkmax, sizeof(char));
2235+        if (new_p_char == NULL)
2236+                free(p_char);
2237 
2238-	p_char = new_p_char;
2239-	p_len = new_p_len;
2240-	p_line = new_p_line;
2241+        p_char = new_p_char;
2242+        p_len = new_p_len;
2243+        p_line = new_p_line;
2244 
2245-	if (p_line != NULL && p_len != NULL && p_char != NULL) {
2246-		hunkmax = new_hunkmax;
2247-		return;
2248-	}
2249+        if (p_line != NULL && p_len != NULL && p_char != NULL) {
2250+                hunkmax = new_hunkmax;
2251+                return;
2252+        }
2253 
2254-	if (!using_plan_a)
2255-		fatal("out of memory\n");
2256-	out_of_mem = 1;
2257+        if (!using_plan_a)
2258+                fatal("out of memory\n");
2259+        out_of_mem = 1;
2260 }
2261 
2262 int
2263 there_is_another_patch(void)
2264 {
2265-	int exists = 0;
2266-
2267-	if (p_base != 0L && p_base >= p_filesize) {
2268-		if (verbose)
2269-			say("done\n");
2270-		return 0;
2271-	}
2272-	if (verbose)
2273-		say("Hmm...");
2274-	diff_type = intuit_diff_type();
2275-	if (!diff_type) {
2276-		if (p_base != 0L) {
2277-			if (verbose)
2278-				say(" Ignoring the trailing garbage.\ndone\n");
2279-		} else
2280-			say(" I cant seem to find a patch in there anywhere\n");
2281-		return 0;
2282-	}
2283-	if (verbose) {
2284-		say(" %sooks like %s to me...\n",
2285-		    (p_base == 0L ? "L" : "The next patch l"),
2286-		    diff_type == UNI_DIFF ? "a unified diff" :
2287-		    diff_type == CONTEXT_DIFF ? "a context diff" :
2288-		    diff_type == NEW_CONTEXT_DIFF ? "a new-style context diff" :
2289-		    diff_type == NORMAL_DIFF ? "a normal diff" : "an ed script");
2290-	}
2291-	if (p_indent && verbose)
2292-		say("(Patch is indented %d space%s.)\n", p_indent, p_indent == 1 ? "" : "s");
2293-	skip_to(p_start, p_sline);
2294-	while (filearg[0] == NULL) {
2295-		if (force || batch) {
2296-			say("No file to patch. Skipping...\n");
2297-			filearg[0] = savestr(bestguess);
2298-			skip_rest_of_patch = 1;
2299-			return 1;
2300-		}
2301-		ask("File to patch: ");
2302-		if (*buf != '\n') {
2303-			free(bestguess);
2304-			bestguess = savestr(buf);
2305-			filearg[0] = fetchname(buf, &exists, 0);
2306-		}
2307-		if (!exists) {
2308-			ask("No file found--skip this patch? [n] ");
2309-			if (*buf != 'y')
2310-				continue;
2311-			if (verbose)
2312-				say("Skipping patch...\n");
2313-			free(filearg[0]);
2314-			filearg[0] = fetchname(bestguess, &exists, 0);
2315-			skip_rest_of_patch = 1;
2316-			return 1;
2317-		}
2318-	}
2319-	return 1;
2320+        int exists = 0;
2321+
2322+        if (p_base != 0L && p_base >= p_filesize) {
2323+                if (verbose)
2324+                        say("done\n");
2325+                return 0;
2326+        }
2327+        if (verbose)
2328+                say("Hmm...");
2329+        diff_type = intuit_diff_type();
2330+        if (!diff_type) {
2331+                if (p_base != 0L) {
2332+                        if (verbose)
2333+                                say(" Ignoring the trailing garbage.\ndone\n");
2334+                } else
2335+                        say(" I cant seem to find a patch in there anywhere\n");
2336+                return 0;
2337+        }
2338+        if (verbose) {
2339+                say(" %sooks like %s to me...\n",
2340+                    (p_base == 0L ? "L" : "The next patch l"),
2341+                    diff_type == UNI_DIFF ? "a unified diff" :
2342+                    diff_type == CONTEXT_DIFF ? "a context diff" :
2343+                    diff_type == NEW_CONTEXT_DIFF ? "a new-style context diff" :
2344+                    diff_type == NORMAL_DIFF ? "a normal diff" : "an ed script");
2345+        }
2346+        if (p_indent && verbose)
2347+                say("(Patch is indented %d space%s.)\n", p_indent, p_indent == 1 ? "" : "s");
2348+        skip_to(p_start, p_sline);
2349+        while (filearg[0] == NULL) {
2350+                if (force || batch) {
2351+                        say("No file to patch. Skipping...\n");
2352+                        filearg[0] = savestr(bestguess);
2353+                        skip_rest_of_patch = 1;
2354+                        return 1;
2355+                }
2356+                ask("File to patch: ");
2357+                if (*buf != '\n') {
2358+                        free(bestguess);
2359+                        bestguess = savestr(buf);
2360+                        filearg[0] = fetchname(buf, &exists, 0);
2361+                }
2362+                if (!exists) {
2363+                        ask("No file found--skip this patch? [n] ");
2364+                        if (*buf != 'y')
2365+                                continue;
2366+                        if (verbose)
2367+                                say("Skipping patch...\n");
2368+                        free(filearg[0]);
2369+                        filearg[0] = fetchname(bestguess, &exists, 0);
2370+                        skip_rest_of_patch = 1;
2371+                        return 1;
2372+                }
2373+        }
2374+        return 1;
2375 }
2376 
2377 static int
2378 intuit_diff_type(void)
2379 {
2380-	long this_line = 0, previous_line;
2381-	long first_command_line = -1;
2382-	LINENUM fcl_line = -1;
2383-	int last_line_was_command = 0, this_is_a_command = 0;
2384-	int stars_last_line = 0, stars_this_line = 0;
2385-	char *s, *t;
2386-	int indent, retval;
2387-	struct FileName names[MAX_FILE];
2388-
2389-	memset(names, 0, sizeof(names));
2390-	ok_to_create_file = 0;
2391-	fseek(pfp, p_base, SEEK_SET);
2392-	p_input_line = p_bline - 1;
2393-	for (;;) {
2394-		previous_line = this_line;
2395-		last_line_was_command = this_is_a_command;
2396-		stars_last_line = stars_this_line;
2397-		this_line = ftell(pfp);
2398-		indent = 0;
2399-		p_input_line++;
2400-		if (getline(&buf, &bufsz, pfp) == -1) {
2401-			if (first_command_line >= 0L) {
2402-				p_start = first_command_line;
2403-				p_sline = fcl_line;
2404-				retval = ED_DIFF;
2405-				goto scan_exit;
2406-			} else {
2407-				p_start = this_line;
2408-				p_sline = p_input_line;
2409-				retval = 0;
2410-				goto scan_exit;
2411-			}
2412-		}
2413-		for (s = buf; *s == ' ' || *s == '\t' || *s == 'X'; s++) {
2414-			if (*s == '\t')
2415-				indent += 8 - (indent % 8);
2416-			else
2417-				indent++;
2418-		}
2419-		for (t = s; isdigit((unsigned char)*t) || *t == ','; t++)
2420-			;
2421-		this_is_a_command = (isdigit((unsigned char)*s) && (*t == 'd' || *t == 'c' || *t == 'a'));
2422-		if (first_command_line < 0L && this_is_a_command) {
2423-			first_command_line = this_line;
2424-			fcl_line = p_input_line;
2425-			p_indent = indent;
2426-		}
2427-		if (!stars_last_line && strnEQ(s, "*** ", 4)) {
2428-			names[OLD_FILE].path = fetchname(s + 4, &names[OLD_FILE].exists, strippath);
2429-		} else if (strnEQ(s, "--- ", 4)) {
2430-			names[NEW_FILE].path = fetchname(s + 4, &names[NEW_FILE].exists, strippath);
2431-		} else if (strnEQ(s, "+++ ", 4)) {
2432-			names[OLD_FILE].path = fetchname(s + 4, &names[OLD_FILE].exists, strippath);
2433-		} else if (strnEQ(s, "Index:", 6)) {
2434-			names[INDEX_FILE].path = fetchname(s + 6, &names[INDEX_FILE].exists, strippath);
2435-		} else if (strnEQ(s, "Prereq:", 7)) {
2436-			for (t = s + 7; isspace((unsigned char)*t); t++)
2437-				;
2438-			revision = savestr(t);
2439-			for (t = revision; *t && !isspace((unsigned char)*t); t++)
2440-				;
2441-			*t = '\0';
2442-			if (*revision == '\0') {
2443-				free(revision);
2444-				revision = NULL;
2445-			}
2446-		}
2447-		if ((!diff_type || diff_type == ED_DIFF) && first_command_line >= 0L && strEQ(s, ".\n")) {
2448-			p_indent = indent;
2449-			p_start = first_command_line;
2450-			p_sline = fcl_line;
2451-			retval = ED_DIFF;
2452-			goto scan_exit;
2453-		}
2454-		if ((!diff_type || diff_type == UNI_DIFF) && strnEQ(s, "@@ -", 4)) {
2455-			if (strnEQ(s + 4, "0,0", 3))
2456-				ok_to_create_file = 1;
2457-			p_indent = indent;
2458-			p_start = this_line;
2459-			p_sline = p_input_line;
2460-			retval = UNI_DIFF;
2461-			goto scan_exit;
2462-		}
2463-		stars_this_line = strnEQ(s, "********", 8);
2464-		if ((!diff_type || diff_type == CONTEXT_DIFF) && stars_last_line && strnEQ(s, "*** ", 4)) {
2465-			if (atol(s + 4) == 0)
2466-				ok_to_create_file = 1;
2467-			while (*s != '\n')
2468-				s++;
2469-			p_indent = indent;
2470-			p_start = previous_line;
2471-			p_sline = p_input_line - 1;
2472-			retval = (*(s - 1) == '*' ? NEW_CONTEXT_DIFF : CONTEXT_DIFF);
2473-			goto scan_exit;
2474-		}
2475-		if ((!diff_type || diff_type == NORMAL_DIFF) && last_line_was_command &&
2476-		    (strnEQ(s, "< ", 2) || strnEQ(s, "> ", 2))) {
2477-			p_start = previous_line;
2478-			p_sline = p_input_line - 1;
2479-			p_indent = indent;
2480-			retval = NORMAL_DIFF;
2481-			goto scan_exit;
2482-		}
2483-	}
2484+        long this_line = 0, previous_line;
2485+        long first_command_line = -1;
2486+        LINENUM fcl_line = -1;
2487+        int last_line_was_command = 0, this_is_a_command = 0;
2488+        int stars_last_line = 0, stars_this_line = 0;
2489+        char *s, *t;
2490+        int indent, retval;
2491+        struct FileName names[MAX_FILE];
2492+
2493+        memset(names, 0, sizeof(names));
2494+        ok_to_create_file = 0;
2495+        fseek(pfp, p_base, SEEK_SET);
2496+        p_input_line = p_bline - 1;
2497+        for (;;) {
2498+                previous_line = this_line;
2499+                last_line_was_command = this_is_a_command;
2500+                stars_last_line = stars_this_line;
2501+                this_line = ftell(pfp);
2502+                indent = 0;
2503+                p_input_line++;
2504+                if (getline(&buf, &bufsz, pfp) == -1) {
2505+                        if (first_command_line >= 0L) {
2506+                                p_start = first_command_line;
2507+                                p_sline = fcl_line;
2508+                                retval = ED_DIFF;
2509+                                goto scan_exit;
2510+                        } else {
2511+                                p_start = this_line;
2512+                                p_sline = p_input_line;
2513+                                retval = 0;
2514+                                goto scan_exit;
2515+                        }
2516+                }
2517+                for (s = buf; *s == ' ' || *s == '\t' || *s == 'X'; s++) {
2518+                        if (*s == '\t')
2519+                                indent += 8 - (indent % 8);
2520+                        else
2521+                                indent++;
2522+                }
2523+                for (t = s; isdigit((unsigned char)*t) || *t == ','; t++)
2524+                        ;
2525+                this_is_a_command = (isdigit((unsigned char)*s) && (*t == 'd' || *t == 'c' || *t == 'a'));
2526+                if (first_command_line < 0L && this_is_a_command) {
2527+                        first_command_line = this_line;
2528+                        fcl_line = p_input_line;
2529+                        p_indent = indent;
2530+                }
2531+                if (!stars_last_line && strnEQ(s, "*** ", 4)) {
2532+                        names[OLD_FILE].path = fetchname(s + 4, &names[OLD_FILE].exists, strippath);
2533+                } else if (strnEQ(s, "--- ", 4)) {
2534+                        names[NEW_FILE].path = fetchname(s + 4, &names[NEW_FILE].exists, strippath);
2535+                } else if (strnEQ(s, "+++ ", 4)) {
2536+                        names[OLD_FILE].path = fetchname(s + 4, &names[OLD_FILE].exists, strippath);
2537+                } else if (strnEQ(s, "Index:", 6)) {
2538+                        names[INDEX_FILE].path = fetchname(s + 6, &names[INDEX_FILE].exists, strippath);
2539+                } else if (strnEQ(s, "Prereq:", 7)) {
2540+                        for (t = s + 7; isspace((unsigned char)*t); t++)
2541+                                ;
2542+                        revision = savestr(t);
2543+                        for (t = revision; *t && !isspace((unsigned char)*t); t++)
2544+                                ;
2545+                        *t = '\0';
2546+                        if (*revision == '\0') {
2547+                                free(revision);
2548+                                revision = NULL;
2549+                        }
2550+                }
2551+                if ((!diff_type || diff_type == ED_DIFF) && first_command_line >= 0L && strEQ(s, ".\n")) {
2552+                        p_indent = indent;
2553+                        p_start = first_command_line;
2554+                        p_sline = fcl_line;
2555+                        retval = ED_DIFF;
2556+                        goto scan_exit;
2557+                }
2558+                if ((!diff_type || diff_type == UNI_DIFF) && strnEQ(s, "@@ -", 4)) {
2559+                        if (strnEQ(s + 4, "0,0", 3))
2560+                                ok_to_create_file = 1;
2561+                        p_indent = indent;
2562+                        p_start = this_line;
2563+                        p_sline = p_input_line;
2564+                        retval = UNI_DIFF;
2565+                        goto scan_exit;
2566+                }
2567+                stars_this_line = strnEQ(s, "********", 8);
2568+                if ((!diff_type || diff_type == CONTEXT_DIFF) && stars_last_line && strnEQ(s, "*** ", 4)) {
2569+                        if (atol(s + 4) == 0)
2570+                                ok_to_create_file = 1;
2571+                        while (*s != '\n')
2572+                                s++;
2573+                        p_indent = indent;
2574+                        p_start = previous_line;
2575+                        p_sline = p_input_line - 1;
2576+                        retval = (*(s - 1) == '*' ? NEW_CONTEXT_DIFF : CONTEXT_DIFF);
2577+                        goto scan_exit;
2578+                }
2579+                if ((!diff_type || diff_type == NORMAL_DIFF) && last_line_was_command &&
2580+                    (strnEQ(s, "< ", 2) || strnEQ(s, "> ", 2))) {
2581+                        p_start = previous_line;
2582+                        p_sline = p_input_line - 1;
2583+                        p_indent = indent;
2584+                        retval = NORMAL_DIFF;
2585+                        goto scan_exit;
2586+                }
2587+        }
2588 scan_exit:
2589-	if (retval == UNI_DIFF) {
2590-		struct FileName tmp = names[OLD_FILE];
2591-		names[OLD_FILE] = names[NEW_FILE];
2592-		names[NEW_FILE] = tmp;
2593-	}
2594-	if (filearg[0] == NULL) {
2595-		if (posix)
2596-			filearg[0] = posix_name(names, ok_to_create_file);
2597-		else {
2598-			if (names[OLD_FILE].path != NULL || names[NEW_FILE].path != NULL) {
2599-				free(names[INDEX_FILE].path);
2600-				names[INDEX_FILE].path = NULL;
2601-			}
2602-			filearg[0] = best_name(names, ok_to_create_file);
2603-		}
2604-	}
2605-	free(bestguess);
2606-	bestguess = NULL;
2607-	if (filearg[0] != NULL)
2608-		bestguess = savestr(filearg[0]);
2609-	else if (!ok_to_create_file) {
2610-		if (posix)
2611-			bestguess = posix_name(names, 1);
2612-		else
2613-			bestguess = best_name(names, 1);
2614-	}
2615-	free(names[OLD_FILE].path);
2616-	free(names[NEW_FILE].path);
2617-	free(names[INDEX_FILE].path);
2618-	return retval;
2619+        if (retval == UNI_DIFF) {
2620+                struct FileName tmp = names[OLD_FILE];
2621+                names[OLD_FILE] = names[NEW_FILE];
2622+                names[NEW_FILE] = tmp;
2623+        }
2624+        if (filearg[0] == NULL) {
2625+                if (posix)
2626+                        filearg[0] = posix_name(names, ok_to_create_file);
2627+                else {
2628+                        if (names[OLD_FILE].path != NULL || names[NEW_FILE].path != NULL) {
2629+                                free(names[INDEX_FILE].path);
2630+                                names[INDEX_FILE].path = NULL;
2631+                        }
2632+                        filearg[0] = best_name(names, ok_to_create_file);
2633+                }
2634+        }
2635+        free(bestguess);
2636+        bestguess = NULL;
2637+        if (filearg[0] != NULL)
2638+                bestguess = savestr(filearg[0]);
2639+        else if (!ok_to_create_file) {
2640+                if (posix)
2641+                        bestguess = posix_name(names, 1);
2642+                else
2643+                        bestguess = best_name(names, 1);
2644+        }
2645+        free(names[OLD_FILE].path);
2646+        free(names[NEW_FILE].path);
2647+        free(names[INDEX_FILE].path);
2648+        return retval;
2649 }
2650 
2651 static void
2652 next_intuit_at(LINENUM file_pos, LINENUM file_line)
2653 {
2654-	p_base = file_pos;
2655-	p_bline = file_line;
2656+        p_base = file_pos;
2657+        p_bline = file_line;
2658 }
2659 
2660 static void
2661 skip_to(LINENUM file_pos, LINENUM file_line)
2662 {
2663-	int ret;
2664-
2665-	if (p_base > file_pos)
2666-		fatal("Internal error: seek %ld>%ld\n", p_base, file_pos);
2667-	if (verbose && p_base < file_pos) {
2668-		fseek(pfp, p_base, SEEK_SET);
2669-		say("The text leading up to this was:\n--------------------------\n");
2670-		while (ftell(pfp) < file_pos) {
2671-			ret = getline(&buf, &bufsz, pfp);
2672-			if (ret == -1)
2673-				fatal("Unexpected end of file\n");
2674-			say("|%s", buf);
2675-		}
2676-		say("--------------------------\n");
2677-	} else
2678-		fseek(pfp, file_pos, SEEK_SET);
2679-	p_input_line = file_line - 1;
2680+        int ret;
2681+
2682+        if (p_base > file_pos)
2683+                fatal("Internal error: seek %ld>%ld\n", p_base, file_pos);
2684+        if (verbose && p_base < file_pos) {
2685+                fseek(pfp, p_base, SEEK_SET);
2686+                say("The text leading up to this was:\n--------------------------\n");
2687+                while (ftell(pfp) < file_pos) {
2688+                        ret = getline(&buf, &bufsz, pfp);
2689+                        if (ret == -1)
2690+                                fatal("Unexpected end of file\n");
2691+                        say("|%s", buf);
2692+                }
2693+                say("--------------------------\n");
2694+        } else
2695+                fseek(pfp, file_pos, SEEK_SET);
2696+        p_input_line = file_line - 1;
2697 }
2698 
2699 __dead static void
2700 malformed(void)
2701 {
2702-	fatal("malformed patch at line %ld: %s", p_input_line, buf);
2703+        fatal("malformed patch at line %ld: %s", p_input_line, buf);
2704 }
2705 
2706 static LINENUM
2707 getlinenum(const char *s)
2708 {
2709-	LINENUM l = (LINENUM)atol(s);
2710-	if (l < 0) {
2711-		l = 0;
2712-		malformed();
2713-	}
2714-	return l;
2715+        LINENUM l = (LINENUM)atol(s);
2716+        if (l < 0) {
2717+                l = 0;
2718+                malformed();
2719+        }
2720+        return l;
2721 }
2722 
2723 static LINENUM
2724 getskiplinenum(char **p)
2725 {
2726-	char *s = *p;
2727-	LINENUM l = getlinenum(s);
2728-	while (isdigit((unsigned char)*s))
2729-		s++;
2730-	*p = s;
2731-	return l;
2732+        char *s = *p;
2733+        LINENUM l = getlinenum(s);
2734+        while (isdigit((unsigned char)*s))
2735+                s++;
2736+        *p = s;
2737+        return l;
2738 }
2739 
2740 static int
2741 remove_special_line(void)
2742 {
2743-	int c;
2744+        int c;
2745 
2746-	c = fgetc(pfp);
2747-	if (c == '\\') {
2748-		do {
2749-			c = fgetc(pfp);
2750-		} while (c != EOF && c != '\n');
2751-		return 1;
2752-	}
2753-	if (c != EOF)
2754-		fseek(pfp, -1L, SEEK_CUR);
2755-	return 0;
2756+        c = fgetc(pfp);
2757+        if (c == '\\') {
2758+                do {
2759+                        c = fgetc(pfp);
2760+                } while (c != EOF && c != '\n');
2761+                return 1;
2762+        }
2763+        if (c != EOF)
2764+                fseek(pfp, -1L, SEEK_CUR);
2765+        return 0;
2766 }
2767 
2768 int
2769 another_hunk(void)
2770 {
2771-	long line_beginning;
2772-	LINENUM repl_beginning;
2773-	LINENUM fillcnt;
2774-	LINENUM fillsrc;
2775-	LINENUM filldst;
2776-	int ptrn_spaces_eaten;
2777-	int repl_could_be_missing;
2778-	int repl_missing;
2779-	long repl_backtrack_position;
2780-	LINENUM repl_patch_line;
2781-	LINENUM ptrn_copiable;
2782-	char *s;
2783-	int context = 0;
2784-	int ret;
2785-
2786-	while (p_end >= 0) {
2787-		if (p_end == p_efake)
2788-			p_end = p_bfake;
2789-		else
2790-			free(p_line[p_end]);
2791-		p_end--;
2792-	}
2793-	p_efake = -1;
2794-	p_max = hunkmax;
2795-
2796-	if (diff_type == CONTEXT_DIFF || diff_type == NEW_CONTEXT_DIFF) {
2797-		line_beginning = ftell(pfp);
2798-		repl_beginning = 0;
2799-		fillcnt = 0;
2800-		fillsrc = 0;
2801-		filldst = 0;
2802-		ptrn_spaces_eaten = 0;
2803-		repl_could_be_missing = 1;
2804-		repl_missing = 0;
2805-		repl_backtrack_position = 0;
2806-		repl_patch_line = 0;
2807-		ptrn_copiable = 0;
2808-
2809-		ret = pgetline(&buf, &bufsz, pfp);
2810-		p_input_line++;
2811-		if (ret == -1 || strnNE(buf, "********", 8)) {
2812-			next_intuit_at(line_beginning, p_input_line);
2813-			return 0;
2814-		}
2815-		p_context = 100;
2816-		p_hunk_beg = p_input_line + 1;
2817-		while (p_end < p_max) {
2818-			ret = pgetline(&buf, &bufsz, pfp);
2819-			p_input_line++;
2820-			if (ret == -1) {
2821-				if (repl_beginning && repl_could_be_missing) {
2822-					repl_missing = 1;
2823-					goto hunk_done;
2824-				}
2825-				fatal("unexpected end of file in patch\n");
2826-			}
2827-			p_end++;
2828-			if (p_end >= hunkmax)
2829-				fatal("Internal error: hunk larger than hunk buffer size");
2830-			p_char[p_end] = *buf;
2831-			p_line[p_end] = NULL;
2832-			switch (*buf) {
2833-			case '*':
2834-				if (strnEQ(buf, "********", 8)) {
2835-					if (repl_beginning && repl_could_be_missing) {
2836-						repl_missing = 1;
2837-						goto hunk_done;
2838-					} else
2839-						fatal("unexpected end of hunk at line %ld\n", p_input_line);
2840-				}
2841-				if (p_end != 0) {
2842-					if (repl_beginning && repl_could_be_missing) {
2843-						repl_missing = 1;
2844-						goto hunk_done;
2845-					}
2846-					fatal("unexpected *** at line %ld: %s", p_input_line, buf);
2847-				}
2848-				context = 0;
2849-				p_line[p_end] = savestr(buf);
2850-				if (out_of_mem) {
2851-					p_end--;
2852-					return 0;
2853-				}
2854-				for (s = buf; *s && !isdigit((unsigned char)*s); s++)
2855-					;
2856-				if (!*s)
2857-					malformed();
2858-				if (strnEQ(s, "0,0", 3))
2859-					memmove(s, s + 2, strlen(s + 2) + 1);
2860-				p_first = getskiplinenum(&s);
2861-				if (*s == ',') {
2862-					for (; *s && !isdigit((unsigned char)*s); s++)
2863-						;
2864-					if (!*s)
2865-						malformed();
2866-					p_ptrn_lines = (getlinenum(s)) - p_first + 1;
2867-					if (p_ptrn_lines < 0)
2868-						malformed();
2869-				} else if (p_first)
2870-					p_ptrn_lines = 1;
2871-				else {
2872-					p_ptrn_lines = 0;
2873-					p_first = 1;
2874-				}
2875-				if (p_first >= LINENUM_MAX - p_ptrn_lines || p_ptrn_lines >= LINENUM_MAX - 6)
2876-					malformed();
2877-				p_max = p_ptrn_lines + 6;
2878-				while (p_max >= hunkmax)
2879-					grow_hunkmax();
2880-				p_max = hunkmax;
2881-				break;
2882-			case '-':
2883-				if (buf[1] == '-') {
2884-					if (repl_beginning || (p_end != p_ptrn_lines + 1 + (p_char[p_end - 1] == '\n'))) {
2885-						if (p_end == 1) {
2886-							p_end = p_ptrn_lines + 1;
2887-							fillsrc = p_end + 1;
2888-							filldst = 1;
2889-							fillcnt = p_ptrn_lines;
2890-						} else {
2891-							if (repl_beginning) {
2892-								if (repl_could_be_missing) {
2893-									repl_missing = 1;
2894-									goto hunk_done;
2895-								}
2896-								fatal("duplicate \"---\" at line %ld\n", p_input_line);
2897-							} else {
2898-								fatal("premature/overdue \"---\" at line %ld\n", p_input_line);
2899-							}
2900-						}
2901-					}
2902-					repl_beginning = p_end;
2903-					repl_backtrack_position = ftell(pfp);
2904-					repl_patch_line = p_input_line;
2905-					p_line[p_end] = savestr(buf);
2906-					if (out_of_mem) {
2907-						p_end--;
2908-						return 0;
2909-					}
2910-					p_char[p_end] = '=';
2911-					for (s = buf; *s && !isdigit((unsigned char)*s); s++)
2912-						;
2913-					if (!*s)
2914-						malformed();
2915-					p_newfirst = getskiplinenum(&s);
2916-					if (*s == ',') {
2917-						for (; *s && !isdigit((unsigned char)*s); s++)
2918-							;
2919-						if (!*s)
2920-							malformed();
2921-						p_repl_lines = (getlinenum(s)) - p_newfirst + 1;
2922-						if (p_repl_lines < 0)
2923-							malformed();
2924-					} else if (p_newfirst)
2925-						p_repl_lines = 1;
2926-					else {
2927-						p_repl_lines = 0;
2928-						p_newfirst = 1;
2929-					}
2930-					if (p_newfirst >= LINENUM_MAX - p_repl_lines || p_repl_lines >= LINENUM_MAX - p_end)
2931-						malformed();
2932-					p_max = p_repl_lines + p_end;
2933-					if (p_max > MAXHUNKSIZE)
2934-						fatal("hunk too large at line %ld\n", p_input_line);
2935-					while (p_max >= hunkmax)
2936-						grow_hunkmax();
2937-					if (p_repl_lines != ptrn_copiable && (p_context != 0 || p_repl_lines != 1))
2938-						repl_could_be_missing = 0;
2939-					break;
2940-				}
2941-				goto change_line;
2942-			case '+':
2943-			case '!':
2944-				repl_could_be_missing = 0;
2945-			change_line:
2946-				if (buf[1] == '\n' && canonicalize)
2947-					strlcpy(buf + 1, " \n", bufsz - 1);
2948-				if (!isspace((unsigned char)buf[1]) && buf[1] != '>' && buf[1] != '<' &&
2949-				    repl_beginning && repl_could_be_missing) {
2950-					repl_missing = 1;
2951-					goto hunk_done;
2952-				}
2953-				if (context >= 0) {
2954-					if (context < p_context)
2955-						p_context = context;
2956-					context = -1000;
2957-				}
2958-				p_line[p_end] = savestr(buf + 2);
2959-				if (out_of_mem) {
2960-					p_end--;
2961-					return 0;
2962-				}
2963-				if (p_end == p_ptrn_lines) {
2964-					if (remove_special_line()) {
2965-						int length = strlen(p_line[p_end]) - 1;
2966-						(p_line[p_end])[length] = 0;
2967-					}
2968-				}
2969-				break;
2970-			case '\t':
2971-			case '\n':
2972-				if (repl_beginning && repl_could_be_missing &&
2973-				    (!ptrn_spaces_eaten || diff_type == NEW_CONTEXT_DIFF)) {
2974-					repl_missing = 1;
2975-					goto hunk_done;
2976-				}
2977-				p_line[p_end] = savestr(buf);
2978-				if (out_of_mem) {
2979-					p_end--;
2980-					return 0;
2981-				}
2982-				if (p_end != p_ptrn_lines + 1) {
2983-					ptrn_spaces_eaten |= (repl_beginning != 0);
2984-					context++;
2985-					if (!repl_beginning)
2986-						ptrn_copiable++;
2987-					p_char[p_end] = ' ';
2988-				}
2989-				break;
2990-			case ' ':
2991-				if (!isspace((unsigned char)buf[1]) && repl_beginning && repl_could_be_missing) {
2992-					repl_missing = 1;
2993-					goto hunk_done;
2994-				}
2995-				context++;
2996-				if (!repl_beginning)
2997-					ptrn_copiable++;
2998-				p_line[p_end] = savestr(buf + 2);
2999-				if (out_of_mem) {
3000-					p_end--;
3001-					return 0;
3002-				}
3003-				break;
3004-			default:
3005-				if (repl_beginning && repl_could_be_missing) {
3006-					repl_missing = 1;
3007-					goto hunk_done;
3008-				}
3009-				malformed();
3010-			}
3011-			if (p_line[p_end])
3012-				p_len[p_end] = strlen(p_line[p_end]);
3013-			else
3014-				p_len[p_end] = 0;
3015-		}
3016+        long line_beginning;
3017+        LINENUM repl_beginning;
3018+        LINENUM fillcnt;
3019+        LINENUM fillsrc;
3020+        LINENUM filldst;
3021+        int ptrn_spaces_eaten;
3022+        int repl_could_be_missing;
3023+        int repl_missing;
3024+        long repl_backtrack_position;
3025+        LINENUM repl_patch_line;
3026+        LINENUM ptrn_copiable;
3027+        char *s;
3028+        int context = 0;
3029+        int ret;
3030+
3031+        while (p_end >= 0) {
3032+                if (p_end == p_efake)
3033+                        p_end = p_bfake;
3034+                else
3035+                        free(p_line[p_end]);
3036+                p_end--;
3037+        }
3038+        p_efake = -1;
3039+        p_max = hunkmax;
3040+
3041+        if (diff_type == CONTEXT_DIFF || diff_type == NEW_CONTEXT_DIFF) {
3042+                line_beginning = ftell(pfp);
3043+                repl_beginning = 0;
3044+                fillcnt = 0;
3045+                fillsrc = 0;
3046+                filldst = 0;
3047+                ptrn_spaces_eaten = 0;
3048+                repl_could_be_missing = 1;
3049+                repl_missing = 0;
3050+                repl_backtrack_position = 0;
3051+                repl_patch_line = 0;
3052+                ptrn_copiable = 0;
3053+
3054+                ret = pgetline(&buf, &bufsz, pfp);
3055+                p_input_line++;
3056+                if (ret == -1 || strnNE(buf, "********", 8)) {
3057+                        next_intuit_at(line_beginning, p_input_line);
3058+                        return 0;
3059+                }
3060+                p_context = 100;
3061+                p_hunk_beg = p_input_line + 1;
3062+                while (p_end < p_max) {
3063+                        ret = pgetline(&buf, &bufsz, pfp);
3064+                        p_input_line++;
3065+                        if (ret == -1) {
3066+                                if (repl_beginning && repl_could_be_missing) {
3067+                                        repl_missing = 1;
3068+                                        goto hunk_done;
3069+                                }
3070+                                fatal("unexpected end of file in patch\n");
3071+                        }
3072+                        p_end++;
3073+                        if (p_end >= hunkmax)
3074+                                fatal("Internal error: hunk larger than hunk buffer size");
3075+                        p_char[p_end] = *buf;
3076+                        p_line[p_end] = NULL;
3077+                        switch (*buf) {
3078+                        case '*':
3079+                                if (strnEQ(buf, "********", 8)) {
3080+                                        if (repl_beginning && repl_could_be_missing) {
3081+                                                repl_missing = 1;
3082+                                                goto hunk_done;
3083+                                        } else
3084+                                                fatal("unexpected end of hunk at line %ld\n", p_input_line);
3085+                                }
3086+                                if (p_end != 0) {
3087+                                        if (repl_beginning && repl_could_be_missing) {
3088+                                                repl_missing = 1;
3089+                                                goto hunk_done;
3090+                                        }
3091+                                        fatal("unexpected *** at line %ld: %s", p_input_line, buf);
3092+                                }
3093+                                context = 0;
3094+                                p_line[p_end] = savestr(buf);
3095+                                if (out_of_mem) {
3096+                                        p_end--;
3097+                                        return 0;
3098+                                }
3099+                                for (s = buf; *s && !isdigit((unsigned char)*s); s++)
3100+                                        ;
3101+                                if (!*s)
3102+                                        malformed();
3103+                                if (strnEQ(s, "0,0", 3))
3104+                                        memmove(s, s + 2, strlen(s + 2) + 1);
3105+                                p_first = getskiplinenum(&s);
3106+                                if (*s == ',') {
3107+                                        for (; *s && !isdigit((unsigned char)*s); s++)
3108+                                                ;
3109+                                        if (!*s)
3110+                                                malformed();
3111+                                        p_ptrn_lines = (getlinenum(s)) - p_first + 1;
3112+                                        if (p_ptrn_lines < 0)
3113+                                                malformed();
3114+                                } else if (p_first)
3115+                                        p_ptrn_lines = 1;
3116+                                else {
3117+                                        p_ptrn_lines = 0;
3118+                                        p_first = 1;
3119+                                }
3120+                                if (p_first >= LINENUM_MAX - p_ptrn_lines || p_ptrn_lines >= LINENUM_MAX - 6)
3121+                                        malformed();
3122+                                p_max = p_ptrn_lines + 6;
3123+                                while (p_max >= hunkmax)
3124+                                        grow_hunkmax();
3125+                                p_max = hunkmax;
3126+                                break;
3127+                        case '-':
3128+                                if (buf[1] == '-') {
3129+                                        if (repl_beginning || (p_end != p_ptrn_lines + 1 + (p_char[p_end - 1] == '\n'))) {
3130+                                                if (p_end == 1) {
3131+                                                        p_end = p_ptrn_lines + 1;
3132+                                                        fillsrc = p_end + 1;
3133+                                                        filldst = 1;
3134+                                                        fillcnt = p_ptrn_lines;
3135+                                                } else {
3136+                                                        if (repl_beginning) {
3137+                                                                if (repl_could_be_missing) {
3138+                                                                        repl_missing = 1;
3139+                                                                        goto hunk_done;
3140+                                                                }
3141+                                                                fatal("duplicate \"---\" at line %ld\n", p_input_line);
3142+                                                        } else {
3143+                                                                fatal("premature/overdue \"---\" at line %ld\n", p_input_line);
3144+                                                        }
3145+                                                }
3146+                                        }
3147+                                        repl_beginning = p_end;
3148+                                        repl_backtrack_position = ftell(pfp);
3149+                                        repl_patch_line = p_input_line;
3150+                                        p_line[p_end] = savestr(buf);
3151+                                        if (out_of_mem) {
3152+                                                p_end--;
3153+                                                return 0;
3154+                                        }
3155+                                        p_char[p_end] = '=';
3156+                                        for (s = buf; *s && !isdigit((unsigned char)*s); s++)
3157+                                                ;
3158+                                        if (!*s)
3159+                                                malformed();
3160+                                        p_newfirst = getskiplinenum(&s);
3161+                                        if (*s == ',') {
3162+                                                for (; *s && !isdigit((unsigned char)*s); s++)
3163+                                                        ;
3164+                                                if (!*s)
3165+                                                        malformed();
3166+                                                p_repl_lines = (getlinenum(s)) - p_newfirst + 1;
3167+                                                if (p_repl_lines < 0)
3168+                                                        malformed();
3169+                                        } else if (p_newfirst)
3170+                                                p_repl_lines = 1;
3171+                                        else {
3172+                                                p_repl_lines = 0;
3173+                                                p_newfirst = 1;
3174+                                        }
3175+                                        if (p_newfirst >= LINENUM_MAX - p_repl_lines || p_repl_lines >= LINENUM_MAX - p_end)
3176+                                                malformed();
3177+                                        p_max = p_repl_lines + p_end;
3178+                                        if (p_max > MAXHUNKSIZE)
3179+                                                fatal("hunk too large at line %ld\n", p_input_line);
3180+                                        while (p_max >= hunkmax)
3181+                                                grow_hunkmax();
3182+                                        if (p_repl_lines != ptrn_copiable && (p_context != 0 || p_repl_lines != 1))
3183+                                                repl_could_be_missing = 0;
3184+                                        break;
3185+                                }
3186+                                goto change_line;
3187+                        case '+':
3188+                        case '!':
3189+                                repl_could_be_missing = 0;
3190+                        change_line:
3191+                                if (buf[1] == '\n' && canonicalize)
3192+                                        strlcpy(buf + 1, " \n", bufsz - 1);
3193+                                if (!isspace((unsigned char)buf[1]) && buf[1] != '>' && buf[1] != '<' &&
3194+                                    repl_beginning && repl_could_be_missing) {
3195+                                        repl_missing = 1;
3196+                                        goto hunk_done;
3197+                                }
3198+                                if (context >= 0) {
3199+                                        if (context < p_context)
3200+                                                p_context = context;
3201+                                        context = -1000;
3202+                                }
3203+                                p_line[p_end] = savestr(buf + 2);
3204+                                if (out_of_mem) {
3205+                                        p_end--;
3206+                                        return 0;
3207+                                }
3208+                                if (p_end == p_ptrn_lines) {
3209+                                        if (remove_special_line()) {
3210+                                                int length = strlen(p_line[p_end]) - 1;
3211+                                                (p_line[p_end])[length] = 0;
3212+                                        }
3213+                                }
3214+                                break;
3215+                        case '\t':
3216+                        case '\n':
3217+                                if (repl_beginning && repl_could_be_missing &&
3218+                                    (!ptrn_spaces_eaten || diff_type == NEW_CONTEXT_DIFF)) {
3219+                                        repl_missing = 1;
3220+                                        goto hunk_done;
3221+                                }
3222+                                p_line[p_end] = savestr(buf);
3223+                                if (out_of_mem) {
3224+                                        p_end--;
3225+                                        return 0;
3226+                                }
3227+                                if (p_end != p_ptrn_lines + 1) {
3228+                                        ptrn_spaces_eaten |= (repl_beginning != 0);
3229+                                        context++;
3230+                                        if (!repl_beginning)
3231+                                                ptrn_copiable++;
3232+                                        p_char[p_end] = ' ';
3233+                                }
3234+                                break;
3235+                        case ' ':
3236+                                if (!isspace((unsigned char)buf[1]) && repl_beginning && repl_could_be_missing) {
3237+                                        repl_missing = 1;
3238+                                        goto hunk_done;
3239+                                }
3240+                                context++;
3241+                                if (!repl_beginning)
3242+                                        ptrn_copiable++;
3243+                                p_line[p_end] = savestr(buf + 2);
3244+                                if (out_of_mem) {
3245+                                        p_end--;
3246+                                        return 0;
3247+                                }
3248+                                break;
3249+                        default:
3250+                                if (repl_beginning && repl_could_be_missing) {
3251+                                        repl_missing = 1;
3252+                                        goto hunk_done;
3253+                                }
3254+                                malformed();
3255+                        }
3256+                        if (p_line[p_end])
3257+                                p_len[p_end] = strlen(p_line[p_end]);
3258+                        else
3259+                                p_len[p_end] = 0;
3260+                }
3261 
3262 hunk_done:
3263-		if (p_end >= 0 && !repl_beginning)
3264-			fatal("no --- found in patch at line %ld\n", pch_hunk_beg());
3265-
3266-		if (repl_missing) {
3267-			p_input_line = repl_patch_line;
3268-			for (p_end--; p_end > repl_beginning; p_end--)
3269-				free(p_line[p_end]);
3270-			fseek(pfp, repl_backtrack_position, SEEK_SET);
3271-
3272-			if (!p_context && p_repl_lines == 1) {
3273-				p_repl_lines = 0;
3274-				p_max--;
3275-			}
3276-			fillsrc = 1;
3277-			filldst = repl_beginning + 1;
3278-			fillcnt = p_repl_lines;
3279-			p_end = p_max;
3280-		} else if (!p_context && fillcnt == 1) {
3281-			while (filldst < p_end) {
3282-				p_line[filldst] = p_line[filldst + 1];
3283-				p_char[filldst] = p_char[filldst + 1];
3284-				p_len[filldst] = p_len[filldst + 1];
3285-				filldst++;
3286-			}
3287-			p_end--;
3288-			p_first++;
3289-			fillcnt = 0;
3290-			p_ptrn_lines = 0;
3291-		}
3292-		if (diff_type == CONTEXT_DIFF && (fillcnt || (p_first > 1 && ptrn_copiable > 2 * p_context))) {
3293-			diff_type = NEW_CONTEXT_DIFF;
3294-		}
3295-		if (fillcnt) {
3296-			p_bfake = filldst;
3297-			p_efake = filldst + fillcnt - 1;
3298-			while (fillcnt-- > 0) {
3299-				while (fillsrc <= p_end && p_char[fillsrc] != ' ')
3300-					fillsrc++;
3301-				if (fillsrc > p_end)
3302-					fatal("replacement text mangled in hunk at line %ld\n", p_hunk_beg);
3303-				p_line[filldst] = p_line[fillsrc];
3304-				p_char[filldst] = p_char[fillsrc];
3305-				p_len[filldst] = p_len[fillsrc];
3306-				fillsrc++;
3307-				filldst++;
3308-			}
3309-			while (fillsrc <= p_end && fillsrc != repl_beginning && p_char[fillsrc] != ' ')
3310-				fillsrc++;
3311-			if (fillsrc != p_end + 1 && fillsrc != repl_beginning)
3312-				malformed();
3313-			if (filldst != p_end + 1 && filldst != repl_beginning)
3314-				malformed();
3315-		}
3316-		if (p_line[p_end] != NULL) {
3317-			if (remove_special_line()) {
3318-				p_len[p_end] -= 1;
3319-				(p_line[p_end])[p_len[p_end]] = 0;
3320-			}
3321-		}
3322-	} else if (diff_type == UNI_DIFF) {
3323-		LINENUM fillold;
3324-		LINENUM fillnew;
3325-		char ch;
3326-
3327-		line_beginning = ftell(pfp);
3328-		ret = pgetline(&buf, &bufsz, pfp);
3329-		p_input_line++;
3330-		if (ret == -1 || strnNE(buf, "@@ -", 4)) {
3331-			next_intuit_at(line_beginning, p_input_line);
3332-			return 0;
3333-		}
3334-		s = buf + 4;
3335-		if (!*s)
3336-			malformed();
3337-		p_first = getskiplinenum(&s);
3338-		if (*s == ',') {
3339-			s++;
3340-			p_ptrn_lines = getskiplinenum(&s);
3341-		} else
3342-			p_ptrn_lines = 1;
3343-		if (p_first >= LINENUM_MAX - p_ptrn_lines)
3344-			malformed();
3345-		if (*s == ' ')
3346-			s++;
3347-		if (*s != '+' || !*++s)
3348-			malformed();
3349-		p_newfirst = getskiplinenum(&s);
3350-		if (*s == ',') {
3351-			s++;
3352-			p_repl_lines = getskiplinenum(&s);
3353-		} else
3354-			p_repl_lines = 1;
3355-		if (*s == ' ')
3356-			s++;
3357-		if (*s != '@')
3358-			malformed();
3359-		if (p_first >= LINENUM_MAX - p_ptrn_lines ||
3360-		    p_newfirst > LINENUM_MAX - p_repl_lines ||
3361-		    p_ptrn_lines >= LINENUM_MAX - p_repl_lines - 1)
3362-			malformed();
3363-		if (!p_ptrn_lines)
3364-			p_first++;
3365-		p_max = p_ptrn_lines + p_repl_lines + 1;
3366-		while (p_max >= hunkmax)
3367-			grow_hunkmax();
3368-		fillold = 1;
3369-		fillnew = fillold + p_ptrn_lines;
3370-		p_end = fillnew + p_repl_lines;
3371-		snprintf(buf, bufsz, "*** %ld,%ld ****\n", p_first, p_first + p_ptrn_lines - 1);
3372-		p_line[0] = savestr(buf);
3373-		if (out_of_mem) {
3374-			p_end = -1;
3375-			return 0;
3376-		}
3377-		p_char[0] = '*';
3378-		snprintf(buf, bufsz, "--- %ld,%ld ----\n", p_newfirst, p_newfirst + p_repl_lines - 1);
3379-		p_line[fillnew] = savestr(buf);
3380-		if (out_of_mem) {
3381-			p_end = 0;
3382-			return 0;
3383-		}
3384-		p_char[fillnew++] = '=';
3385-		p_context = 100;
3386-		context = 0;
3387-		p_hunk_beg = p_input_line + 1;
3388-		while (fillold <= p_ptrn_lines || fillnew <= p_end) {
3389-			ret = pgetline(&buf, &bufsz, pfp);
3390-			p_input_line++;
3391-			if (ret == -1) {
3392-				if (p_max - fillnew < 3)
3393-					strlcpy(buf, " \n", bufsz);
3394-				else
3395-					fatal("unexpected end of file in patch\n");
3396-			}
3397-			if (*buf == '\t' || *buf == '\n') {
3398-				ch = ' ';
3399-				s = savestr(buf);
3400-			} else {
3401-				ch = *buf;
3402-				s = savestr(buf + 1);
3403-			}
3404-			if (out_of_mem) {
3405-				while (--fillnew > p_ptrn_lines)
3406-					free(p_line[fillnew]);
3407-				p_end = fillold - 1;
3408-				return 0;
3409-			}
3410-			switch (ch) {
3411-			case '-':
3412-				if (fillold > p_ptrn_lines) {
3413-					free(s);
3414-					p_end = fillnew - 1;
3415-					malformed();
3416-				}
3417-				p_char[fillold] = ch;
3418-				p_line[fillold] = s;
3419-				p_len[fillold++] = strlen(s);
3420-				if (fillold > p_ptrn_lines) {
3421-					if (remove_special_line()) {
3422-						p_len[fillold - 1] -= 1;
3423-						s[p_len[fillold - 1]] = 0;
3424-					}
3425-				}
3426-				break;
3427-			case '=':
3428-				ch = ' ';
3429-				/* FALL THROUGH */
3430-			case ' ':
3431-				if (fillold > p_ptrn_lines) {
3432-					free(s);
3433-					while (--fillnew > p_ptrn_lines)
3434-						free(p_line[fillnew]);
3435-					p_end = fillold - 1;
3436-					malformed();
3437-				}
3438-				context++;
3439-				p_char[fillold] = ch;
3440-				p_line[fillold] = s;
3441-				p_len[fillold++] = strlen(s);
3442-				s = savestr(s);
3443-				if (out_of_mem) {
3444-					while (--fillnew > p_ptrn_lines)
3445-						free(p_line[fillnew]);
3446-					p_end = fillold - 1;
3447-					return 0;
3448-				}
3449-				if (fillold > p_ptrn_lines) {
3450-					if (remove_special_line()) {
3451-						p_len[fillold - 1] -= 1;
3452-						s[p_len[fillold - 1]] = 0;
3453-					}
3454-				}
3455-				/* FALL THROUGH */
3456-			case '+':
3457-				if (fillnew > p_end) {
3458-					free(s);
3459-					while (--fillnew > p_ptrn_lines)
3460-						free(p_line[fillnew]);
3461-					p_end = fillold - 1;
3462-					malformed();
3463-				}
3464-				p_char[fillnew] = ch;
3465-				p_line[fillnew] = s;
3466-				p_len[fillnew++] = strlen(s);
3467-				if (fillold > p_ptrn_lines) {
3468-					if (remove_special_line()) {
3469-						p_len[fillnew - 1] -= 1;
3470-						s[p_len[fillnew - 1]] = 0;
3471-					}
3472-				}
3473-				break;
3474-			default:
3475-				p_end = fillnew;
3476-				malformed();
3477-			}
3478-			if (ch != ' ' && context > 0) {
3479-				if (context < p_context)
3480-					p_context = context;
3481-				context = -1000;
3482-			}
3483-		}
3484-	} else {
3485-		char hunk_type;
3486-		int i;
3487-		LINENUM min, max;
3488-
3489-		line_beginning = ftell(pfp);
3490-		p_context = 0;
3491-		ret = pgetline(&buf, &bufsz, pfp);
3492-		p_input_line++;
3493-		if (ret == -1 || !isdigit((unsigned char)*buf)) {
3494-			next_intuit_at(line_beginning, p_input_line);
3495-			return 0;
3496-		}
3497-		s = buf;
3498-		p_first = getskiplinenum(&s);
3499-		if (*s == ',') {
3500-			s++;
3501-			p_ptrn_lines = getskiplinenum(&s) - p_first + 1;
3502-		} else
3503-			p_ptrn_lines = (*s != 'a');
3504-		if (p_first >= LINENUM_MAX - p_ptrn_lines)
3505-			malformed();
3506-		hunk_type = *s++;
3507-		if (hunk_type == 'a')
3508-			p_first++;
3509-		min = getskiplinenum(&s);
3510-		if (*s == ',')
3511-			max = getlinenum(++s);
3512-		else
3513-			max = min;
3514-		if (min < 0 || min > max || max - min == LINENUM_MAX)
3515-			malformed();
3516-		if (hunk_type == 'd')
3517-			min++;
3518-		p_end = p_ptrn_lines + p_repl_lines + 1;
3519-		p_newfirst = min;
3520-		p_repl_lines = max - min + 1;
3521-		if (p_newfirst > LINENUM_MAX - p_repl_lines || p_ptrn_lines >= LINENUM_MAX - p_repl_lines - 1)
3522-			malformed();
3523-		p_end = p_ptrn_lines + p_repl_lines + 1;
3524-		if (p_end > MAXHUNKSIZE)
3525-			fatal("hunk too large at line %ld\n", p_input_line);
3526-		while (p_end >= hunkmax)
3527-			grow_hunkmax();
3528-		snprintf(buf, bufsz, "*** %ld,%ld\n", p_first, p_first + p_ptrn_lines - 1);
3529-		p_line[0] = savestr(buf);
3530-		if (out_of_mem) {
3531-			p_end = -1;
3532-			return 0;
3533-		}
3534-		p_char[0] = '*';
3535-		for (i = 1; i <= p_ptrn_lines; i++) {
3536-			ret = pgetline(&buf, &bufsz, pfp);
3537-			p_input_line++;
3538-			if (ret == -1)
3539-				fatal("unexpected end of file in patch at line %ld\n", p_input_line);
3540-			if (*buf != '<')
3541-				fatal("< expected at line %ld of patch\n", p_input_line);
3542-			p_line[i] = savestr(buf + 2);
3543-			if (out_of_mem) {
3544-				p_end = i - 1;
3545-				return 0;
3546-			}
3547-			p_len[i] = strlen(p_line[i]);
3548-			p_char[i] = '-';
3549-		}
3550-		if (remove_special_line()) {
3551-			p_len[i - 1] -= 1;
3552-			(p_line[i - 1])[p_len[i - 1]] = 0;
3553-		}
3554-		if (hunk_type == 'c') {
3555-			ret = pgetline(&buf, &bufsz, pfp);
3556-			p_input_line++;
3557-			if (ret == -1)
3558-				fatal("unexpected end of file in patch at line %ld\n", p_input_line);
3559-			if (*buf != '-')
3560-				fatal("--- expected at line %ld of patch\n", p_input_line);
3561-		}
3562-		snprintf(buf, bufsz, "--- %ld,%ld\n", min, max);
3563-		p_line[i] = savestr(buf);
3564-		if (out_of_mem) {
3565-			p_end = i - 1;
3566-			return 0;
3567-		}
3568-		p_char[i] = '=';
3569-		for (i++; i <= p_end; i++) {
3570-			ret = pgetline(&buf, &bufsz, pfp);
3571-			p_input_line++;
3572-			if (ret == -1)
3573-				fatal("unexpected end of file in patch at line %ld\n", p_input_line);
3574-			if (*buf != '>')
3575-				fatal("> expected at line %ld of patch\n", p_input_line);
3576-			p_line[i] = savestr(buf + 2);
3577-			if (out_of_mem) {
3578-				p_end = i - 1;
3579-				return 0;
3580-			}
3581-			p_len[i] = strlen(p_line[i]);
3582-			p_char[i] = '+';
3583-		}
3584-		if (remove_special_line()) {
3585-			p_len[i - 1] -= 1;
3586-			(p_line[i - 1])[p_len[i - 1]] = 0;
3587-		}
3588-	}
3589-	if (reverse) {
3590-		if (!pch_swap())
3591-			say("Not enough memory to swap next hunk!\n");
3592-	}
3593-	if (p_end + 1 < hunkmax)
3594-		p_char[p_end + 1] = '^';
3595-	return 1;
3596+                if (p_end >= 0 && !repl_beginning)
3597+                        fatal("no --- found in patch at line %ld\n", pch_hunk_beg());
3598+
3599+                if (repl_missing) {
3600+                        p_input_line = repl_patch_line;
3601+                        for (p_end--; p_end > repl_beginning; p_end--)
3602+                                free(p_line[p_end]);
3603+                        fseek(pfp, repl_backtrack_position, SEEK_SET);
3604+
3605+                        if (!p_context && p_repl_lines == 1) {
3606+                                p_repl_lines = 0;
3607+                                p_max--;
3608+                        }
3609+                        fillsrc = 1;
3610+                        filldst = repl_beginning + 1;
3611+                        fillcnt = p_repl_lines;
3612+                        p_end = p_max;
3613+                } else if (!p_context && fillcnt == 1) {
3614+                        while (filldst < p_end) {
3615+                                p_line[filldst] = p_line[filldst + 1];
3616+                                p_char[filldst] = p_char[filldst + 1];
3617+                                p_len[filldst] = p_len[filldst + 1];
3618+                                filldst++;
3619+                        }
3620+                        p_end--;
3621+                        p_first++;
3622+                        fillcnt = 0;
3623+                        p_ptrn_lines = 0;
3624+                }
3625+                if (diff_type == CONTEXT_DIFF && (fillcnt || (p_first > 1 && ptrn_copiable > 2 * p_context))) {
3626+                        diff_type = NEW_CONTEXT_DIFF;
3627+                }
3628+                if (fillcnt) {
3629+                        p_bfake = filldst;
3630+                        p_efake = filldst + fillcnt - 1;
3631+                        while (fillcnt-- > 0) {
3632+                                while (fillsrc <= p_end && p_char[fillsrc] != ' ')
3633+                                        fillsrc++;
3634+                                if (fillsrc > p_end)
3635+                                        fatal("replacement text mangled in hunk at line %ld\n", p_hunk_beg);
3636+                                p_line[filldst] = p_line[fillsrc];
3637+                                p_char[filldst] = p_char[fillsrc];
3638+                                p_len[filldst] = p_len[fillsrc];
3639+                                fillsrc++;
3640+                                filldst++;
3641+                        }
3642+                        while (fillsrc <= p_end && fillsrc != repl_beginning && p_char[fillsrc] != ' ')
3643+                                fillsrc++;
3644+                        if (fillsrc != p_end + 1 && fillsrc != repl_beginning)
3645+                                malformed();
3646+                        if (filldst != p_end + 1 && filldst != repl_beginning)
3647+                                malformed();
3648+                }
3649+                if (p_line[p_end] != NULL) {
3650+                        if (remove_special_line()) {
3651+                                p_len[p_end] -= 1;
3652+                                (p_line[p_end])[p_len[p_end]] = 0;
3653+                        }
3654+                }
3655+        } else if (diff_type == UNI_DIFF) {
3656+                LINENUM fillold;
3657+                LINENUM fillnew;
3658+                char ch;
3659+
3660+                line_beginning = ftell(pfp);
3661+                ret = pgetline(&buf, &bufsz, pfp);
3662+                p_input_line++;
3663+                if (ret == -1 || strnNE(buf, "@@ -", 4)) {
3664+                        next_intuit_at(line_beginning, p_input_line);
3665+                        return 0;
3666+                }
3667+                s = buf + 4;
3668+                if (!*s)
3669+                        malformed();
3670+                p_first = getskiplinenum(&s);
3671+                if (*s == ',') {
3672+                        s++;
3673+                        p_ptrn_lines = getskiplinenum(&s);
3674+                } else
3675+                        p_ptrn_lines = 1;
3676+                if (p_first >= LINENUM_MAX - p_ptrn_lines)
3677+                        malformed();
3678+                if (*s == ' ')
3679+                        s++;
3680+                if (*s != '+' || !*++s)
3681+                        malformed();
3682+                p_newfirst = getskiplinenum(&s);
3683+                if (*s == ',') {
3684+                        s++;
3685+                        p_repl_lines = getskiplinenum(&s);
3686+                } else
3687+                        p_repl_lines = 1;
3688+                if (*s == ' ')
3689+                        s++;
3690+                if (*s != '@')
3691+                        malformed();
3692+                if (p_first >= LINENUM_MAX - p_ptrn_lines ||
3693+                    p_newfirst > LINENUM_MAX - p_repl_lines ||
3694+                    p_ptrn_lines >= LINENUM_MAX - p_repl_lines - 1)
3695+                        malformed();
3696+                if (!p_ptrn_lines)
3697+                        p_first++;
3698+                p_max = p_ptrn_lines + p_repl_lines + 1;
3699+                while (p_max >= hunkmax)
3700+                        grow_hunkmax();
3701+                fillold = 1;
3702+                fillnew = fillold + p_ptrn_lines;
3703+                p_end = fillnew + p_repl_lines;
3704+                snprintf(buf, bufsz, "*** %ld,%ld ****\n", p_first, p_first + p_ptrn_lines - 1);
3705+                p_line[0] = savestr(buf);
3706+                if (out_of_mem) {
3707+                        p_end = -1;
3708+                        return 0;
3709+                }
3710+                p_char[0] = '*';
3711+                snprintf(buf, bufsz, "--- %ld,%ld ----\n", p_newfirst, p_newfirst + p_repl_lines - 1);
3712+                p_line[fillnew] = savestr(buf);
3713+                if (out_of_mem) {
3714+                        p_end = 0;
3715+                        return 0;
3716+                }
3717+                p_char[fillnew++] = '=';
3718+                p_context = 100;
3719+                context = 0;
3720+                p_hunk_beg = p_input_line + 1;
3721+                while (fillold <= p_ptrn_lines || fillnew <= p_end) {
3722+                        ret = pgetline(&buf, &bufsz, pfp);
3723+                        p_input_line++;
3724+                        if (ret == -1) {
3725+                                if (p_max - fillnew < 3)
3726+                                        strlcpy(buf, " \n", bufsz);
3727+                                else
3728+                                        fatal("unexpected end of file in patch\n");
3729+                        }
3730+                        if (*buf == '\t' || *buf == '\n') {
3731+                                ch = ' ';
3732+                                s = savestr(buf);
3733+                        } else {
3734+                                ch = *buf;
3735+                                s = savestr(buf + 1);
3736+                        }
3737+                        if (out_of_mem) {
3738+                                while (--fillnew > p_ptrn_lines)
3739+                                        free(p_line[fillnew]);
3740+                                p_end = fillold - 1;
3741+                                return 0;
3742+                        }
3743+                        switch (ch) {
3744+                        case '-':
3745+                                if (fillold > p_ptrn_lines) {
3746+                                        free(s);
3747+                                        p_end = fillnew - 1;
3748+                                        malformed();
3749+                                }
3750+                                p_char[fillold] = ch;
3751+                                p_line[fillold] = s;
3752+                                p_len[fillold++] = strlen(s);
3753+                                if (fillold > p_ptrn_lines) {
3754+                                        if (remove_special_line()) {
3755+                                                p_len[fillold - 1] -= 1;
3756+                                                s[p_len[fillold - 1]] = 0;
3757+                                        }
3758+                                }
3759+                                break;
3760+                        case '=':
3761+                                ch = ' ';
3762+                                /* FALL THROUGH */
3763+                        case ' ':
3764+                                if (fillold > p_ptrn_lines) {
3765+                                        free(s);
3766+                                        while (--fillnew > p_ptrn_lines)
3767+                                                free(p_line[fillnew]);
3768+                                        p_end = fillold - 1;
3769+                                        malformed();
3770+                                }
3771+                                context++;
3772+                                p_char[fillold] = ch;
3773+                                p_line[fillold] = s;
3774+                                p_len[fillold++] = strlen(s);
3775+                                s = savestr(s);
3776+                                if (out_of_mem) {
3777+                                        while (--fillnew > p_ptrn_lines)
3778+                                                free(p_line[fillnew]);
3779+                                        p_end = fillold - 1;
3780+                                        return 0;
3781+                                }
3782+                                if (fillold > p_ptrn_lines) {
3783+                                        if (remove_special_line()) {
3784+                                                p_len[fillold - 1] -= 1;
3785+                                                s[p_len[fillold - 1]] = 0;
3786+                                        }
3787+                                }
3788+                                /* FALL THROUGH */
3789+                        case '+':
3790+                                if (fillnew > p_end) {
3791+                                        free(s);
3792+                                        while (--fillnew > p_ptrn_lines)
3793+                                                free(p_line[fillnew]);
3794+                                        p_end = fillold - 1;
3795+                                        malformed();
3796+                                }
3797+                                p_char[fillnew] = ch;
3798+                                p_line[fillnew] = s;
3799+                                p_len[fillnew++] = strlen(s);
3800+                                if (fillold > p_ptrn_lines) {
3801+                                        if (remove_special_line()) {
3802+                                                p_len[fillnew - 1] -= 1;
3803+                                                s[p_len[fillnew - 1]] = 0;
3804+                                        }
3805+                                }
3806+                                break;
3807+                        default:
3808+                                p_end = fillnew;
3809+                                malformed();
3810+                        }
3811+                        if (ch != ' ' && context > 0) {
3812+                                if (context < p_context)
3813+                                        p_context = context;
3814+                                context = -1000;
3815+                        }
3816+                }
3817+        } else {
3818+                char hunk_type;
3819+                int i;
3820+                LINENUM min, max;
3821+
3822+                line_beginning = ftell(pfp);
3823+                p_context = 0;
3824+                ret = pgetline(&buf, &bufsz, pfp);
3825+                p_input_line++;
3826+                if (ret == -1 || !isdigit((unsigned char)*buf)) {
3827+                        next_intuit_at(line_beginning, p_input_line);
3828+                        return 0;
3829+                }
3830+                s = buf;
3831+                p_first = getskiplinenum(&s);
3832+                if (*s == ',') {
3833+                        s++;
3834+                        p_ptrn_lines = getskiplinenum(&s) - p_first + 1;
3835+                } else
3836+                        p_ptrn_lines = (*s != 'a');
3837+                if (p_first >= LINENUM_MAX - p_ptrn_lines)
3838+                        malformed();
3839+                hunk_type = *s++;
3840+                if (hunk_type == 'a')
3841+                        p_first++;
3842+                min = getskiplinenum(&s);
3843+                if (*s == ',')
3844+                        max = getlinenum(++s);
3845+                else
3846+                        max = min;
3847+                if (min < 0 || min > max || max - min == LINENUM_MAX)
3848+                        malformed();
3849+                if (hunk_type == 'd')
3850+                        min++;
3851+                p_end = p_ptrn_lines + p_repl_lines + 1;
3852+                p_newfirst = min;
3853+                p_repl_lines = max - min + 1;
3854+                if (p_newfirst > LINENUM_MAX - p_repl_lines || p_ptrn_lines >= LINENUM_MAX - p_repl_lines - 1)
3855+                        malformed();
3856+                p_end = p_ptrn_lines + p_repl_lines + 1;
3857+                if (p_end > MAXHUNKSIZE)
3858+                        fatal("hunk too large at line %ld\n", p_input_line);
3859+                while (p_end >= hunkmax)
3860+                        grow_hunkmax();
3861+                snprintf(buf, bufsz, "*** %ld,%ld\n", p_first, p_first + p_ptrn_lines - 1);
3862+                p_line[0] = savestr(buf);
3863+                if (out_of_mem) {
3864+                        p_end = -1;
3865+                        return 0;
3866+                }
3867+                p_char[0] = '*';
3868+                for (i = 1; i <= p_ptrn_lines; i++) {
3869+                        ret = pgetline(&buf, &bufsz, pfp);
3870+                        p_input_line++;
3871+                        if (ret == -1)
3872+                                fatal("unexpected end of file in patch at line %ld\n", p_input_line);
3873+                        if (*buf != '<')
3874+                                fatal("< expected at line %ld of patch\n", p_input_line);
3875+                        p_line[i] = savestr(buf + 2);
3876+                        if (out_of_mem) {
3877+                                p_end = i - 1;
3878+                                return 0;
3879+                        }
3880+                        p_len[i] = strlen(p_line[i]);
3881+                        p_char[i] = '-';
3882+                }
3883+                if (remove_special_line()) {
3884+                        p_len[i - 1] -= 1;
3885+                        (p_line[i - 1])[p_len[i - 1]] = 0;
3886+                }
3887+                if (hunk_type == 'c') {
3888+                        ret = pgetline(&buf, &bufsz, pfp);
3889+                        p_input_line++;
3890+                        if (ret == -1)
3891+                                fatal("unexpected end of file in patch at line %ld\n", p_input_line);
3892+                        if (*buf != '-')
3893+                                fatal("--- expected at line %ld of patch\n", p_input_line);
3894+                }
3895+                snprintf(buf, bufsz, "--- %ld,%ld\n", min, max);
3896+                p_line[i] = savestr(buf);
3897+                if (out_of_mem) {
3898+                        p_end = i - 1;
3899+                        return 0;
3900+                }
3901+                p_char[i] = '=';
3902+                for (i++; i <= p_end; i++) {
3903+                        ret = pgetline(&buf, &bufsz, pfp);
3904+                        p_input_line++;
3905+                        if (ret == -1)
3906+                                fatal("unexpected end of file in patch at line %ld\n", p_input_line);
3907+                        if (*buf != '>')
3908+                                fatal("> expected at line %ld of patch\n", p_input_line);
3909+                        p_line[i] = savestr(buf + 2);
3910+                        if (out_of_mem) {
3911+                                p_end = i - 1;
3912+                                return 0;
3913+                        }
3914+                        p_len[i] = strlen(p_line[i]);
3915+                        p_char[i] = '+';
3916+                }
3917+                if (remove_special_line()) {
3918+                        p_len[i - 1] -= 1;
3919+                        (p_line[i - 1])[p_len[i - 1]] = 0;
3920+                }
3921+        }
3922+        if (reverse) {
3923+                if (!pch_swap())
3924+                        say("Not enough memory to swap next hunk!\n");
3925+        }
3926+        if (p_end + 1 < hunkmax)
3927+                p_char[p_end + 1] = '^';
3928+        return 1;
3929 }
3930 
3931 int
3932 pgetline(char **bf, size_t *sz, FILE *fp)
3933 {
3934-	char *s;
3935-	int indent = 0;
3936-	int ret;
3937+        char *s;
3938+        int indent = 0;
3939+        int ret;
3940 
3941-	ret = getline(bf, sz, fp);
3942-	if (p_indent && ret != -1) {
3943-		for (s = buf; indent < p_indent && (*s == ' ' || *s == '\t' || *s == 'X'); s++) {
3944-			if (*s == '\t')
3945-				indent += 8 - (indent % 7);
3946-			else
3947-				indent++;
3948-		}
3949-		if (buf != s && strlcpy(buf, s, bufsz) >= bufsz)
3950-			fatal("buffer too small in pgetline()\n");
3951-	}
3952-	return ret;
3953+        ret = getline(bf, sz, fp);
3954+        if (p_indent && ret != -1) {
3955+                for (s = buf; indent < p_indent && (*s == ' ' || *s == '\t' || *s == 'X'); s++) {
3956+                        if (*s == '\t')
3957+                                indent += 8 - (indent % 7);
3958+                        else
3959+                                indent++;
3960+                }
3961+                if (buf != s && strlcpy(buf, s, bufsz) >= bufsz)
3962+                        fatal("buffer too small in pgetline()\n");
3963+        }
3964+        return ret;
3965 }
3966 
3967 int
3968 pch_swap(void)
3969 {
3970-	char **tp_line;
3971-	ssize_t *tp_len;
3972-	char *tp_char;
3973-	LINENUM i;
3974-	LINENUM n;
3975-	int blankline = 0;
3976-	char *s;
3977-
3978-	i = p_first;
3979-	p_first = p_newfirst;
3980-	p_newfirst = i;
3981-
3982-	tp_line = p_line;
3983-	tp_len = p_len;
3984-	tp_char = p_char;
3985-	p_line = NULL;
3986-	p_len = NULL;
3987-	p_char = NULL;
3988-	set_hunkmax();
3989-	if (p_line == NULL || p_len == NULL || p_char == NULL) {
3990-		free(p_line);
3991-		p_line = tp_line;
3992-		free(p_len);
3993-		p_len = tp_len;
3994-		free(p_char);
3995-		p_char = tp_char;
3996-		return 0;
3997-	}
3998-
3999-	i = p_ptrn_lines + 1;
4000-	if (tp_char[i] == '\n') {
4001-		blankline = 1;
4002-		i++;
4003-	}
4004-	if (p_efake >= 0) {
4005-		if (p_efake <= i)
4006-			n = p_end - i + 1;
4007-		else
4008-			n = -i;
4009-		p_efake += n;
4010-		p_bfake += n;
4011-	}
4012-	for (n = 0; i <= p_end; i++, n++) {
4013-		p_line[n] = tp_line[i];
4014-		p_char[n] = tp_char[i];
4015-		if (p_char[n] == '+')
4016-			p_char[n] = '-';
4017-		p_len[n] = tp_len[i];
4018-	}
4019-	if (blankline) {
4020-		i = p_ptrn_lines + 1;
4021-		p_line[n] = tp_line[i];
4022-		p_char[n] = tp_char[i];
4023-		p_len[n] = tp_len[i];
4024-		n++;
4025-	}
4026-	if (p_char[0] != '=')
4027-		fatal("expected '=' found '%c'\n", p_char[0]);
4028-	p_char[0] = '*';
4029-	for (s = p_line[0]; *s; s++)
4030-		if (*s == '-')
4031-			*s = '*';
4032-
4033-	if (p_char[0] != '*')
4034-		fatal("expected '*' found '%c'\n", p_char[0]);
4035-	tp_char[0] = '=';
4036-	for (s = tp_line[0]; *s; s++)
4037-		if (*s == '*')
4038-			*s = '-';
4039-	for (i = 0; n <= p_end; i++, n++) {
4040-		p_line[n] = tp_line[i];
4041-		p_char[n] = tp_char[i];
4042-		if (p_char[n] == '-')
4043-			p_char[n] = '+';
4044-		p_len[n] = tp_len[i];
4045-	}
4046-	if (i != p_ptrn_lines + 1)
4047-		fatal("expected %ld lines, got %ld\n", p_ptrn_lines + 1, i);
4048-
4049-	i = p_ptrn_lines;
4050-	p_ptrn_lines = p_repl_lines;
4051-	p_repl_lines = i;
4052-
4053-	free(tp_line);
4054-	free(tp_len);
4055-	free(tp_char);
4056-	return 1;
4057+        char **tp_line;
4058+        ssize_t *tp_len;
4059+        char *tp_char;
4060+        LINENUM i;
4061+        LINENUM n;
4062+        int blankline = 0;
4063+        char *s;
4064+
4065+        i = p_first;
4066+        p_first = p_newfirst;
4067+        p_newfirst = i;
4068+
4069+        tp_line = p_line;
4070+        tp_len = p_len;
4071+        tp_char = p_char;
4072+        p_line = NULL;
4073+        p_len = NULL;
4074+        p_char = NULL;
4075+        set_hunkmax();
4076+        if (p_line == NULL || p_len == NULL || p_char == NULL) {
4077+                free(p_line);
4078+                p_line = tp_line;
4079+                free(p_len);
4080+                p_len = tp_len;
4081+                free(p_char);
4082+                p_char = tp_char;
4083+                return 0;
4084+        }
4085+
4086+        i = p_ptrn_lines + 1;
4087+        if (tp_char[i] == '\n') {
4088+                blankline = 1;
4089+                i++;
4090+        }
4091+        if (p_efake >= 0) {
4092+                if (p_efake <= i)
4093+                        n = p_end - i + 1;
4094+                else
4095+                        n = -i;
4096+                p_efake += n;
4097+                p_bfake += n;
4098+        }
4099+        for (n = 0; i <= p_end; i++, n++) {
4100+                p_line[n] = tp_line[i];
4101+                p_char[n] = tp_char[i];
4102+                if (p_char[n] == '+')
4103+                        p_char[n] = '-';
4104+                p_len[n] = tp_len[i];
4105+        }
4106+        if (blankline) {
4107+                i = p_ptrn_lines + 1;
4108+                p_line[n] = tp_line[i];
4109+                p_char[n] = tp_char[i];
4110+                p_len[n] = tp_len[i];
4111+                n++;
4112+        }
4113+        if (p_char[0] != '=')
4114+                fatal("expected '=' found '%c'\n", p_char[0]);
4115+        p_char[0] = '*';
4116+        for (s = p_line[0]; *s; s++)
4117+                if (*s == '-')
4118+                        *s = '*';
4119+
4120+        if (p_char[0] != '*')
4121+                fatal("expected '*' found '%c'\n", p_char[0]);
4122+        tp_char[0] = '=';
4123+        for (s = tp_line[0]; *s; s++)
4124+                if (*s == '*')
4125+                        *s = '-';
4126+        for (i = 0; n <= p_end; i++, n++) {
4127+                p_line[n] = tp_line[i];
4128+                p_char[n] = tp_char[i];
4129+                if (p_char[n] == '-')
4130+                        p_char[n] = '+';
4131+                p_len[n] = tp_len[i];
4132+        }
4133+        if (i != p_ptrn_lines + 1)
4134+                fatal("expected %ld lines, got %ld\n", p_ptrn_lines + 1, i);
4135+
4136+        i = p_ptrn_lines;
4137+        p_ptrn_lines = p_repl_lines;
4138+        p_repl_lines = i;
4139+
4140+        free(tp_line);
4141+        free(tp_len);
4142+        free(tp_char);
4143+        return 1;
4144 }
4145 
4146 LINENUM
4147 pch_first(void)
4148 {
4149-	return p_first;
4150+        return p_first;
4151 }
4152 
4153 LINENUM
4154 pch_ptrn_lines(void)
4155 {
4156-	return p_ptrn_lines;
4157+        return p_ptrn_lines;
4158 }
4159 
4160 LINENUM
4161 pch_newfirst(void)
4162 {
4163-	return p_newfirst;
4164+        return p_newfirst;
4165 }
4166 
4167 LINENUM
4168 pch_repl_lines(void)
4169 {
4170-	return p_repl_lines;
4171+        return p_repl_lines;
4172 }
4173 
4174 LINENUM
4175 pch_end(void)
4176 {
4177-	return p_end;
4178+        return p_end;
4179 }
4180 
4181 LINENUM
4182 pch_context(void)
4183 {
4184-	return p_context;
4185+        return p_context;
4186 }
4187 
4188 ssize_t
4189 pch_line_len(LINENUM line)
4190 {
4191-	return p_len[line];
4192+        return p_len[line];
4193 }
4194 
4195 char
4196 pch_char(LINENUM line)
4197 {
4198-	return p_char[line];
4199+        return p_char[line];
4200 }
4201 
4202 char *
4203 pfetch(LINENUM line)
4204 {
4205-	return p_line[line];
4206+        return p_line[line];
4207 }
4208 
4209 LINENUM
4210 pch_hunk_beg(void)
4211 {
4212-	return p_hunk_beg;
4213+        return p_hunk_beg;
4214 }
4215 
4216 void
4217 do_ed_script(void)
4218 {
4219-	char *t;
4220-	long beginning_of_this_line;
4221-	FILE *pipefp = NULL;
4222-	int continuation;
4223-
4224-	if (!skip_rest_of_patch) {
4225-		if (copy_file(filearg[0], TMPOUTNAME) < 0) {
4226-			unlink(TMPOUTNAME);
4227-			fatal("cant create temp file %s", TMPOUTNAME);
4228-		}
4229-		snprintf(buf, bufsz, "%s -S%s %s", _PATH_ED, verbose ? "" : "s", TMPOUTNAME);
4230-		pipefp = popen(buf, "w");
4231-	}
4232-	for (;;) {
4233-		beginning_of_this_line = ftell(pfp);
4234-		if (pgetline(&buf, &bufsz, pfp) == -1) {
4235-			next_intuit_at(beginning_of_this_line, p_input_line);
4236-			break;
4237-		}
4238-		p_input_line++;
4239-		for (t = buf; isdigit((unsigned char)*t) || *t == ','; t++)
4240-			;
4241-		if (isdigit((unsigned char)*buf) && (*t == 'a' || *t == 'c' || *t == 'd' || *t == 'i' || *t == 's')) {
4242-			if (pipefp != NULL)
4243-				fprintf(pipefp, "%s", buf);
4244-			if (*t == 's') {
4245-				for (;;) {
4246-					continuation = 0;
4247-					t = strchr(buf, '\0') - 1;
4248-					while (--t >= buf && *t == '\\')
4249-						continuation = !continuation;
4250-					if (!continuation || pgetline(&buf, &bufsz, pfp) == -1)
4251-						break;
4252-					if (pipefp != NULL)
4253-						fprintf(pipefp, "%s", buf);
4254-				}
4255-			} else if (*t != 'd') {
4256-				while (pgetline(&buf, &bufsz, pfp) != -1) {
4257-					p_input_line++;
4258-					if (pipefp != NULL)
4259-						fprintf(pipefp, "%s", buf);
4260-					if (strEQ(buf, ".\n"))
4261-						break;
4262-				}
4263-			}
4264-		} else {
4265-			next_intuit_at(beginning_of_this_line, p_input_line);
4266-			break;
4267-		}
4268-	}
4269-	if (pipefp == NULL)
4270-		return;
4271-	fprintf(pipefp, "w\n");
4272-	fprintf(pipefp, "q\n");
4273-	fflush(pipefp);
4274-	pclose(pipefp);
4275-	ignore_signals();
4276-	if (!check_only) {
4277-		if (move_file(TMPOUTNAME, outname) < 0) {
4278-			toutkeep = 1;
4279-			chmod(TMPOUTNAME, filemode);
4280-		} else
4281-			chmod(outname, filemode);
4282-	}
4283-	set_signals(1);
4284+        char *t;
4285+        long beginning_of_this_line;
4286+        FILE *pipefp = NULL;
4287+        int continuation;
4288+
4289+        if (!skip_rest_of_patch) {
4290+                if (copy_file(filearg[0], TMPOUTNAME) < 0) {
4291+                        unlink(TMPOUTNAME);
4292+                        fatal("cant create temp file %s", TMPOUTNAME);
4293+                }
4294+                snprintf(buf, bufsz, "%s -S%s %s", _PATH_ED, verbose ? "" : "s", TMPOUTNAME);
4295+                pipefp = wpopen(buf, NULL, "w");
4296+        }
4297+        for (;;) {
4298+                beginning_of_this_line = ftell(pfp);
4299+                if (pgetline(&buf, &bufsz, pfp) == -1) {
4300+                        next_intuit_at(beginning_of_this_line, p_input_line);
4301+                        break;
4302+                }
4303+                p_input_line++;
4304+                for (t = buf; isdigit((unsigned char)*t) || *t == ','; t++)
4305+                        ;
4306+                if (isdigit((unsigned char)*buf) && (*t == 'a' || *t == 'c' || *t == 'd' || *t == 'i' || *t == 's')) {
4307+                        if (pipefp != NULL)
4308+                                fprintf(pipefp, "%s", buf);
4309+                        if (*t == 's') {
4310+                                for (;;) {
4311+                                        continuation = 0;
4312+                                        t = strchr(buf, '\0') - 1;
4313+                                        while (--t >= buf && *t == '\\')
4314+                                                continuation = !continuation;
4315+                                        if (!continuation || pgetline(&buf, &bufsz, pfp) == -1)
4316+                                                break;
4317+                                        if (pipefp != NULL)
4318+                                                fprintf(pipefp, "%s", buf);
4319+                                }
4320+                        } else if (*t != 'd') {
4321+                                while (pgetline(&buf, &bufsz, pfp) != -1) {
4322+                                        p_input_line++;
4323+                                        if (pipefp != NULL)
4324+                                                fprintf(pipefp, "%s", buf);
4325+                                        if (strEQ(buf, ".\n"))
4326+                                                break;
4327+                                }
4328+                        }
4329+                } else {
4330+                        next_intuit_at(beginning_of_this_line, p_input_line);
4331+                        break;
4332+                }
4333+        }
4334+        if (pipefp == NULL)
4335+                return;
4336+        fprintf(pipefp, "w\n");
4337+        fprintf(pipefp, "q\n");
4338+        fflush(pipefp);
4339+        wpclose(pipefp);
4340+        ignore_signals();
4341+        if (!check_only) {
4342+                if (move_file(TMPOUTNAME, outname) < 0) {
4343+                        toutkeep = 1;
4344+                        chmod(TMPOUTNAME, filemode);
4345+                } else
4346+                        chmod(outname, filemode);
4347+        }
4348+        set_signals(1);
4349 }
4350 
4351 static char *
4352 posix_name(const struct FileName *names, int assume_exists)
4353 {
4354-	char *path = NULL;
4355-	int i;
4356-
4357-	for (i = 0; i < MAX_FILE; i++) {
4358-		if (names[i].path != NULL && names[i].exists) {
4359-			path = names[i].path;
4360-			break;
4361-		}
4362-	}
4363-	if (path == NULL && !assume_exists) {
4364-		for (i = 0; i < MAX_FILE; i++) {
4365-			if (names[i].path != NULL && (path = checked_in(names[i].path)) != NULL)
4366-				break;
4367-		}
4368-		if (path == NULL && ok_to_create_file && names[NEW_FILE].path != NULL)
4369-			path = names[NEW_FILE].path;
4370-	}
4371-	return path ? savestr(path) : NULL;
4372+        char *path = NULL;
4373+        int i;
4374+
4375+        for (i = 0; i < MAX_FILE; i++) {
4376+                if (names[i].path != NULL && names[i].exists) {
4377+                        path = names[i].path;
4378+                        break;
4379+                }
4380+        }
4381+        if (path == NULL && !assume_exists) {
4382+                for (i = 0; i < MAX_FILE; i++) {
4383+                        if (names[i].path != NULL && (path = checked_in(names[i].path)) != NULL)
4384+                                break;
4385+                }
4386+                if (path == NULL && ok_to_create_file && names[NEW_FILE].path != NULL)
4387+                        path = names[NEW_FILE].path;
4388+        }
4389+        return path ? savestr(path) : NULL;
4390 }
4391 
4392 static char *
4393 best_name(const struct FileName *names, int assume_exists)
4394 {
4395-	size_t min_components, min_baselen, min_len, tmp;
4396-	char *best = NULL;
4397-	int i;
4398-
4399-	min_components = min_baselen = min_len = SIZE_MAX;
4400-	for (i = INDEX_FILE; i >= OLD_FILE; i--) {
4401-		if (names[i].path == NULL || (!names[i].exists && !assume_exists))
4402-			continue;
4403-		if ((tmp = num_components(names[i].path)) > min_components)
4404-			continue;
4405-		min_components = tmp;
4406-		if ((tmp = strlen(basename(names[i].path))) > min_baselen)
4407-			continue;
4408-		min_baselen = tmp;
4409-		if ((tmp = strlen(names[i].path)) > min_len)
4410-			continue;
4411-		min_len = tmp;
4412-		best = names[i].path;
4413-	}
4414-	if (best == NULL) {
4415-		min_components = min_baselen = min_len = SIZE_MAX;
4416-		for (i = INDEX_FILE; i >= OLD_FILE; i--) {
4417-			if (names[i].path == NULL || checked_in(names[i].path) == NULL)
4418-				continue;
4419-			if ((tmp = num_components(names[i].path)) > min_components)
4420-				continue;
4421-			min_components = tmp;
4422-			if ((tmp = strlen(basename(names[i].path))) > min_baselen)
4423-				continue;
4424-			min_baselen = tmp;
4425-			if ((tmp = strlen(names[i].path)) > min_len)
4426-				continue;
4427-			min_len = tmp;
4428-			best = names[i].path;
4429-		}
4430-		if (best == NULL && ok_to_create_file && names[NEW_FILE].path != NULL)
4431-			best = names[NEW_FILE].path;
4432-	}
4433-	return best ? savestr(best) : NULL;
4434+        size_t min_components, min_baselen, min_len, tmp;
4435+        char *best = NULL;
4436+        int i;
4437+
4438+        min_components = min_baselen = min_len = SIZE_MAX;
4439+        for (i = INDEX_FILE; i >= OLD_FILE; i--) {
4440+                if (names[i].path == NULL || (!names[i].exists && !assume_exists))
4441+                        continue;
4442+                if ((tmp = num_components(names[i].path)) > min_components)
4443+                        continue;
4444+                min_components = tmp;
4445+                if ((tmp = strlen(basename(names[i].path))) > min_baselen)
4446+                        continue;
4447+                min_baselen = tmp;
4448+                if ((tmp = strlen(names[i].path)) > min_len)
4449+                        continue;
4450+                min_len = tmp;
4451+                best = names[i].path;
4452+        }
4453+        if (best == NULL) {
4454+                min_components = min_baselen = min_len = SIZE_MAX;
4455+                for (i = INDEX_FILE; i >= OLD_FILE; i--) {
4456+                        if (names[i].path == NULL || checked_in(names[i].path) == NULL)
4457+                                continue;
4458+                        if ((tmp = num_components(names[i].path)) > min_components)
4459+                                continue;
4460+                        min_components = tmp;
4461+                        if ((tmp = strlen(basename(names[i].path))) > min_baselen)
4462+                                continue;
4463+                        min_baselen = tmp;
4464+                        if ((tmp = strlen(names[i].path)) > min_len)
4465+                                continue;
4466+                        min_len = tmp;
4467+                        best = names[i].path;
4468+                }
4469+                if (best == NULL && ok_to_create_file && names[NEW_FILE].path != NULL)
4470+                        best = names[NEW_FILE].path;
4471+        }
4472+        return best ? savestr(best) : NULL;
4473 }
4474 
4475 static size_t
4476 num_components(const char *path)
4477 {
4478-	size_t n;
4479-	const char *cp;
4480+        size_t n;
4481+        const char *cp;
4482 
4483-	for (n = 0, cp = path; (cp = strchr(cp, '/')) != NULL; n++, cp++) {
4484-		while (*cp == '/')
4485-			cp++;
4486-	}
4487-	return n;
4488+        for (n = 0, cp = path; (cp = strchr(cp, '/')) != NULL; n++, cp++) {
4489+                while (*cp == '/')
4490+                        cp++;
4491+        }
4492+        return n;
4493 }
4494 
4495 LINENUM
4496 strtolinenum(char *nptr, char **endptr)
4497 {
4498-	LINENUM rv;
4499-	char c;
4500-	char *p;
4501-	const char *errstr;
4502+        LINENUM rv;
4503+        char c;
4504+        char *p;
4505+        const char *errstr;
4506 
4507-	for (p = nptr; isdigit((unsigned char)*p); p++)
4508-		;
4509+        for (p = nptr; isdigit((unsigned char)*p); p++)
4510+                ;
4511 
4512-	if (p == nptr)
4513-		malformed();
4514+        if (p == nptr)
4515+                malformed();
4516 
4517-	c = *p;
4518-	*p = '\0';
4519+        c = *p;
4520+        *p = '\0';
4521 
4522-	rv = strtonum(nptr, 0, LINENUM_MAX, &errstr);
4523-	if (errstr != NULL)
4524-		fatal("invalid line number at line %ld: `%s' is %s\n",
4525-		    p_input_line, nptr, errstr);
4526+        rv = strtonum(nptr, 0, LINENUM_MAX, &errstr);
4527+        if (errstr != NULL)
4528+                fatal("invalid line number at line %ld: `%s' is %s\n",
4529+                    p_input_line, nptr, errstr);
4530 
4531-	*p = c;
4532-	*endptr = p;
4533+        *p = c;
4534+        *endptr = p;
4535 
4536-	return rv;
4537+        return rv;
4538 }
4539 
4540 int
4541 move_file(const char *from, const char *to)
4542 {
4543-	int fromfd;
4544-	ssize_t i;
4545-
4546-	if (strEQ(to, "-")) {
4547-		fromfd = open(from, O_RDONLY);
4548-		if (fromfd < 0)
4549-			pfatal("internal error, cant reopen %s", from);
4550-		while ((i = read(fromfd, buf, bufsz)) > 0) {
4551-			if (write(STDOUT_FILENO, buf, i) != i)
4552-				pfatal("write failed");
4553-		}
4554-		close(fromfd);
4555-		return 0;
4556-	}
4557-	if (backup_file(to) < 0) {
4558-		say("Cant backup %s, output is in %s: %s\n", to, from, strerror(errno));
4559-		return -1;
4560-	}
4561-	if (rename(from, to) < 0) {
4562-		if (errno != EXDEV || copy_file(from, to) < 0) {
4563-			say("Cant create %s, output is in %s: %s\n", to, from, strerror(errno));
4564-			return -1;
4565-		}
4566-	}
4567-	return 0;
4568+        int fromfd;
4569+        ssize_t i;
4570+
4571+        if (strEQ(to, "-")) {
4572+                fromfd = open(from, O_RDONLY);
4573+                if (fromfd < 0)
4574+                        pfatal("internal error, cant reopen %s", from);
4575+                while ((i = read(fromfd, buf, bufsz)) > 0) {
4576+                        if (write(STDOUT_FILENO, buf, i) != i)
4577+                                pfatal("write failed");
4578+                }
4579+                close(fromfd);
4580+                return 0;
4581+        }
4582+        if (backup_file(to) < 0) {
4583+                say("Cant backup %s, output is in %s: %s\n", to, from, strerror(errno));
4584+                return -1;
4585+        }
4586+        if (rename(from, to) < 0) {
4587+                if (errno != EXDEV || copy_file(from, to) < 0) {
4588+                        say("Cant create %s, output is in %s: %s\n", to, from, strerror(errno));
4589+                        return -1;
4590+                }
4591+        }
4592+        return 0;
4593 }
4594 
4595 int
4596 backup_file(const char *orig)
4597 {
4598-	struct stat filestat;
4599-	char bakname[PATH_MAX], *s, *simplename;
4600-	dev_t orig_device;
4601-	ino_t orig_inode;
4602-
4603-	if (backup_type == BACKUP_NONE || stat(orig, &filestat) != 0)
4604-		return 0;
4605-	if ((origprae && *origprae == 0) || *simple_backup_suffix == 0) {
4606-		unlink(orig);
4607-		return 0;
4608-	}
4609-	orig_device = filestat.st_dev;
4610-	orig_inode = filestat.st_ino;
4611-
4612-	if (origprae) {
4613-		if (strlcpy(bakname, origprae, sizeof(bakname)) >= sizeof(bakname) ||
4614-		    strlcat(bakname, orig, sizeof(bakname)) >= sizeof(bakname))
4615-			fatal("filename too long\n");
4616-	} else {
4617-		if ((s = find_backup_file_name(orig)) == NULL)
4618-			fatal("out of memory\n");
4619-		if (strlcpy(bakname, s, sizeof(bakname)) >= sizeof(bakname))
4620-			fatal("filename too long\n");
4621-		free(s);
4622-	}
4623-
4624-	if ((simplename = strrchr(bakname, '/')) != NULL)
4625-		simplename = simplename + 1;
4626-	else
4627-		simplename = bakname;
4628-
4629-	while (stat(bakname, &filestat) == 0 && orig_device == filestat.st_dev && orig_inode == filestat.st_ino) {
4630-		for (s = simplename; *s && !islower((unsigned char)*s); s++)
4631-			;
4632-		if (*s)
4633-			*s = toupper((unsigned char)*s);
4634-		else
4635-			memmove(simplename, simplename + 1, strlen(simplename + 1) + 1);
4636-	}
4637-	if (rename(orig, bakname) < 0) {
4638-		if (errno != EXDEV || copy_file(orig, bakname) < 0)
4639-			return -1;
4640-	}
4641-	return 0;
4642+        struct stat filestat;
4643+        char bakname[PATH_MAX], *s, *simplename;
4644+        dev_t orig_device;
4645+        ino_t orig_inode;
4646+
4647+        if (backup_type == BACKUP_NONE || stat(orig, &filestat) != 0)
4648+                return 0;
4649+        if ((origprae && *origprae == 0) || *simple_backup_suffix == 0) {
4650+                unlink(orig);
4651+                return 0;
4652+        }
4653+        orig_device = filestat.st_dev;
4654+        orig_inode = filestat.st_ino;
4655+
4656+        if (origprae) {
4657+                if (strlcpy(bakname, origprae, sizeof(bakname)) >= sizeof(bakname) ||
4658+                    strlcat(bakname, orig, sizeof(bakname)) >= sizeof(bakname))
4659+                        fatal("filename too long\n");
4660+        } else {
4661+                if ((s = find_backup_file_name(orig)) == NULL)
4662+                        fatal("out of memory\n");
4663+                if (strlcpy(bakname, s, sizeof(bakname)) >= sizeof(bakname))
4664+                        fatal("filename too long\n");
4665+                free(s);
4666+        }
4667+
4668+        if ((simplename = strrchr(bakname, '/')) != NULL)
4669+                simplename = simplename + 1;
4670+        else
4671+                simplename = bakname;
4672+
4673+        while (stat(bakname, &filestat) == 0 && orig_device == filestat.st_dev && orig_inode == filestat.st_ino) {
4674+                for (s = simplename; *s && !islower((unsigned char)*s); s++)
4675+                        ;
4676+                if (*s)
4677+                        *s = toupper((unsigned char)*s);
4678+                else
4679+                        memmove(simplename, simplename + 1, strlen(simplename + 1) + 1);
4680+        }
4681+        if (rename(orig, bakname) < 0) {
4682+                if (errno != EXDEV || copy_file(orig, bakname) < 0)
4683+                        return -1;
4684+        }
4685+        return 0;
4686 }
4687 
4688 int
4689 copy_file(const char *from, const char *to)
4690 {
4691-	int tofd, fromfd;
4692-	ssize_t i;
4693+        int tofd, fromfd;
4694+        ssize_t i;
4695 
4696-	tofd = open(to, O_CREAT|O_TRUNC|O_WRONLY, 0666);
4697-	if (tofd < 0)
4698-		return -1;
4699-	fromfd = open(from, O_RDONLY, 0);
4700-	if (fromfd < 0)
4701-		pfatal("internal error, cant reopen %s", from);
4702-	while ((i = read(fromfd, buf, bufsz)) > 0) {
4703-		if (write(tofd, buf, i) != i)
4704-			pfatal("write to %s failed", to);
4705-	}
4706-	close(fromfd);
4707-	close(tofd);
4708-	return 0;
4709+        tofd = open(to, O_CREAT|O_TRUNC|O_WRONLY, 0666);
4710+        if (tofd < 0)
4711+                return -1;
4712+        fromfd = open(from, O_RDONLY, 0);
4713+        if (fromfd < 0)
4714+                pfatal("internal error, cant reopen %s", from);
4715+        while ((i = read(fromfd, buf, bufsz)) > 0) {
4716+                if (write(tofd, buf, i) != i)
4717+                        pfatal("write to %s failed", to);
4718+        }
4719+        close(fromfd);
4720+        close(tofd);
4721+        return 0;
4722 }
4723 
4724 char *
4725 savestr(const char *s)
4726 {
4727-	char *rv;
4728+        char *rv;
4729 
4730-	if (!s)
4731-		s = "Oops";
4732-	rv = strdup(s);
4733-	if (rv == NULL) {
4734-		if (using_plan_a)
4735-			out_of_mem = 1;
4736-		else
4737-			fatal("out of memory\n");
4738-	}
4739-	return rv;
4740+        if (!s)
4741+                s = "Oops";
4742+        rv = strdup(s);
4743+        if (rv == NULL) {
4744+                if (using_plan_a)
4745+                        out_of_mem = 1;
4746+                else
4747+                        fatal("out of memory\n");
4748+        }
4749+        return rv;
4750 }
4751 
4752 void
4753 say(const char *fmt, ...)
4754 {
4755-	va_list ap;
4756+        va_list ap;
4757 
4758-	va_start(ap, fmt);
4759-	vfprintf(stderr, fmt, ap);
4760-	va_end(ap);
4761-	fflush(stderr);
4762+        va_start(ap, fmt);
4763+        vfprintf(stderr, fmt, ap);
4764+        va_end(ap);
4765+        fflush(stderr);
4766 }
4767 
4768 __dead void
4769 fatal(const char *fmt, ...)
4770 {
4771-	va_list ap;
4772+        va_list ap;
4773 
4774-	va_start(ap, fmt);
4775-	fprintf(stderr, "patch: **** ");
4776-	vfprintf(stderr, fmt, ap);
4777-	va_end(ap);
4778-	my_exit(2);
4779+        va_start(ap, fmt);
4780+        fprintf(stderr, "patch: **** ");
4781+        vfprintf(stderr, fmt, ap);
4782+        va_end(ap);
4783+        my_exit(2);
4784 }
4785 
4786 __dead void
4787 pfatal(const char *fmt, ...)
4788 {
4789-	va_list ap;
4790-	int errnum = errno;
4791+        va_list ap;
4792+        int errnum = errno;
4793 
4794-	fprintf(stderr, "patch: **** ");
4795-	va_start(ap, fmt);
4796-	vfprintf(stderr, fmt, ap);
4797-	va_end(ap);
4798-	fprintf(stderr, ": %s\n", strerror(errnum));
4799-	my_exit(2);
4800+        fprintf(stderr, "patch: **** ");
4801+        va_start(ap, fmt);
4802+        vfprintf(stderr, fmt, ap);
4803+        va_end(ap);
4804+        fprintf(stderr, ": %s\n", strerror(errnum));
4805+        my_exit(2);
4806 }
4807 
4808 void
4809 ask(const char *fmt, ...)
4810 {
4811-	va_list ap;
4812-	ssize_t nr = 0;
4813-	static int ttyfd = -1;
4814-
4815-	va_start(ap, fmt);
4816-	vfprintf(stdout, fmt, ap);
4817-	va_end(ap);
4818-	fflush(stdout);
4819-	if (ttyfd < 0)
4820-		ttyfd = open(_PATH_TTY, O_RDONLY);
4821-	if (ttyfd >= 0) {
4822-		if ((nr = read(ttyfd, buf, bufsz)) > 0 && buf[nr - 1] == '\n')
4823-			buf[nr - 1] = '\0';
4824-	}
4825-	if (ttyfd < 0 || nr <= 0) {
4826-		putchar('\n');
4827-		buf[0] = '\0';
4828-	}
4829+        va_list ap;
4830+        ssize_t nr = 0;
4831+        static int ttyfd = -1;
4832+
4833+        va_start(ap, fmt);
4834+        vfprintf(stdout, fmt, ap);
4835+        va_end(ap);
4836+        fflush(stdout);
4837+        if (ttyfd < 0)
4838+                ttyfd = open(ARUU_PATH_DEVTTY, O_RDONLY);
4839+        if (ttyfd >= 0) {
4840+                if ((nr = read(ttyfd, buf, bufsz)) > 0 && buf[nr - 1] == '\n')
4841+                        buf[nr - 1] = '\0';
4842+        }
4843+        if (ttyfd < 0 || nr <= 0) {
4844+                putchar('\n');
4845+                buf[0] = '\0';
4846+        }
4847 }
4848 
4849 void
4850 set_signals(int reset)
4851 {
4852-	static sig_t hupval, intval;
4853+        static sig_t hupval, intval;
4854 
4855-	if (!reset) {
4856-		hupval = signal(SIGHUP, SIG_IGN);
4857-		if (hupval != SIG_IGN)
4858-			hupval = (sig_t)my_exit;
4859-		intval = signal(SIGINT, SIG_IGN);
4860-		if (intval != SIG_IGN)
4861-			intval = (sig_t)my_exit;
4862-	}
4863-	signal(SIGHUP, hupval);
4864-	signal(SIGINT, intval);
4865+        if (!reset) {
4866+                hupval = signal(SIGHUP, SIG_IGN);
4867+                if (hupval != SIG_IGN)
4868+                        hupval = (sig_t)my_exit;
4869+                intval = signal(SIGINT, SIG_IGN);
4870+                if (intval != SIG_IGN)
4871+                        intval = (sig_t)my_exit;
4872+        }
4873+        signal(SIGHUP, hupval);
4874+        signal(SIGINT, intval);
4875 }
4876 
4877 void
4878 ignore_signals(void)
4879 {
4880-	signal(SIGHUP, SIG_IGN);
4881-	signal(SIGINT, SIG_IGN);
4882+        signal(SIGHUP, SIG_IGN);
4883+        signal(SIGINT, SIG_IGN);
4884 }
4885 
4886 void
4887 makedirs(const char *filename, int striplast)
4888 {
4889-	char *tmpbuf;
4890+        char *tmpbuf;
4891 
4892-	if ((tmpbuf = strdup(filename)) == NULL)
4893-		fatal("out of memory\n");
4894+        if ((tmpbuf = strdup(filename)) == NULL)
4895+                fatal("out of memory\n");
4896 
4897-	if (striplast) {
4898-		char *s = strrchr(tmpbuf, '/');
4899-		if (s == NULL) {
4900-			free(tmpbuf);
4901-			return;
4902-		}
4903-		*s = '\0';
4904-	}
4905-	if (mkpath(tmpbuf) != 0)
4906-		pfatal("creation of %s failed", tmpbuf);
4907-	free(tmpbuf);
4908+        if (striplast) {
4909+                char *s = strrchr(tmpbuf, '/');
4910+                if (s == NULL) {
4911+                        free(tmpbuf);
4912+                        return;
4913+                }
4914+                *s = '\0';
4915+        }
4916+        if (mkpath(tmpbuf) != 0)
4917+                pfatal("creation of %s failed", tmpbuf);
4918+        free(tmpbuf);
4919 }
4920 
4921 char *
4922 fetchname(const char *at, int *exists, int strip_leading)
4923 {
4924-	char *fullname, *name, *t;
4925-	int sleading, tab;
4926-	struct stat filestat;
4927-
4928-	if (at == NULL || *at == '\0')
4929-		return NULL;
4930-	while (isspace((unsigned char)*at))
4931-		at++;
4932-	if (strnEQ(at, _PATH_DEVNULL, sizeof(_PATH_DEVNULL) - 1))
4933-		return NULL;
4934-	name = fullname = t = savestr(at);
4935-	tab = strchr(t, '\t') != NULL;
4936-	for (sleading = strip_leading; *t != '\0' && ((tab && *t != '\t') || !isspace((unsigned char)*t)); t++) {
4937-		if (t[0] == '/' && t[1] != '/' && t[1] != '\0') {
4938-			if (--sleading >= 0)
4939-				name = t + 1;
4940-		}
4941-	}
4942-	*t = '\0';
4943-
4944-	if (strip_leading == 957 && name != fullname && *fullname != '/') {
4945-		name[-1] = '\0';
4946-		if (stat(fullname, &filestat) == 0 && S_ISDIR(filestat.st_mode)) {
4947-			name[-1] = '/';
4948-			name = fullname;
4949-		}
4950-	}
4951-	name = savestr(name);
4952-	free(fullname);
4953-
4954-	*exists = stat(name, &filestat) == 0;
4955-	return name;
4956+        char *fullname, *name, *t;
4957+        int sleading, tab;
4958+        struct stat filestat;
4959+
4960+        if (at == NULL || *at == '\0')
4961+                return NULL;
4962+        while (isspace((unsigned char)*at))
4963+                at++;
4964+        if (strnEQ(at, ARUU_PATH_DEVNULL, sizeof(ARUU_PATH_DEVNULL) - 1))
4965+                return NULL;
4966+        name = fullname = t = savestr(at);
4967+        tab = strchr(t, '\t') != NULL;
4968+        for (sleading = strip_leading; *t != '\0' && ((tab && *t != '\t') || !isspace((unsigned char)*t)); t++) {
4969+                if (t[0] == '/' && t[1] != '/' && t[1] != '\0') {
4970+                        if (--sleading >= 0)
4971+                                name = t + 1;
4972+                }
4973+        }
4974+        *t = '\0';
4975+
4976+        if (strip_leading == 957 && name != fullname && *fullname != '/') {
4977+                name[-1] = '\0';
4978+                if (stat(fullname, &filestat) == 0 && S_ISDIR(filestat.st_mode)) {
4979+                        name[-1] = '/';
4980+                        name = fullname;
4981+                }
4982+        }
4983+        name = savestr(name);
4984+        free(fullname);
4985+
4986+        *exists = stat(name, &filestat) == 0;
4987+        return name;
4988 }
4989 
4990 char *
4991 checked_in(char *file)
4992 {
4993-	char *filebase, *filedir, tmpbuf[PATH_MAX];
4994-	struct stat filestat;
4995+        char *filebase, *filedir, tmpbuf[PATH_MAX];
4996+        struct stat filestat;
4997 
4998-	filebase = basename(file);
4999-	filedir = dirname(file);
5000+        filebase = basename(file);
5001+        filedir = dirname(file);
5002 
5003 #define try(f, a1, a2, a3) \
5004 (snprintf(tmpbuf, sizeof tmpbuf, f, a1, a2, a3), stat(tmpbuf, &filestat) == 0)
5005 
5006-	if (try("%s/RCS/%s%s", filedir, filebase, RCSSUFFIX) ||
5007-	    try("%s/RCS/%s%s", filedir, filebase, "") ||
5008-	    try("%s/%s%s", filedir, filebase, RCSSUFFIX) ||
5009-	    try("%s/SCCS/%s%s", filedir, SCCSPREFIX, filebase) ||
5010-	    try("%s/%s%s", filedir, SCCSPREFIX, filebase))
5011-		return file;
5012+        if (try("%s/RCS/%s%s", filedir, filebase, RCSSUFFIX) ||
5013+            try("%s/RCS/%s%s", filedir, filebase, "") ||
5014+            try("%s/%s%s", filedir, filebase, RCSSUFFIX) ||
5015+            try("%s/SCCS/%s%s", filedir, SCCSPREFIX, filebase) ||
5016+            try("%s/%s%s", filedir, SCCSPREFIX, filebase))
5017+                return file;
5018 
5019-	return NULL;
5020+        return NULL;
5021 }
5022 
5023 __dead void
5024 version(void)
5025 {
5026-	printf("Patch version 2.0-12u9-NetBSD\n");
5027-	my_exit(EXIT_SUCCESS);
5028+        printf("Patch version 2.0-12u9-NetBSD\n");
5029+        my_exit(EXIT_SUCCESS);
5030 }
5031 
5032 __dead void
5033 my_exit(int status)
5034 {
5035-	unlink(TMPINNAME);
5036-	if (!toutkeep)
5037-		unlink(TMPOUTNAME);
5038-	if (!trejkeep)
5039-		unlink(TMPREJNAME);
5040-	unlink(TMPPATNAME);
5041-	exit(status);
5042+        unlink(TMPINNAME);
5043+        if (!toutkeep)
5044+                unlink(TMPOUTNAME);
5045+        if (!trejkeep)
5046+                unlink(TMPREJNAME);
5047+        unlink(TMPPATNAME);
5048+        exit(status);
5049 }
5050 
5051 static void *
5052 pch_realloc(void *ptr, size_t number, size_t size)
5053 {
5054-	if (number > SIZE_MAX / size) {
5055-		errno = EOVERFLOW;
5056-		return NULL;
5057-	}
5058-	return realloc(ptr, number * size);
5059+        if (number > SIZE_MAX / size) {
5060+                errno = EOVERFLOW;
5061+                return NULL;
5062+        }
5063+        return realloc(ptr, number * size);
5064 }
5065 
5066 int
5067 mkpath(char *path)
5068 {
5069-	struct stat sb;
5070-	char *slash;
5071-	int done = 0;
5072-
5073-	slash = path;
5074-	while (!done) {
5075-		slash += strspn(slash, "/");
5076-		slash += strcspn(slash, "/");
5077-		done = (*slash == '\0');
5078-		*slash = '\0';
5079-		if (stat(path, &sb)) {
5080-			if (errno != ENOENT || (mkdir(path, 0777) && errno != EEXIST)) {
5081-				warn("%s", path);
5082-				return -1;
5083-			}
5084-		} else if (!S_ISDIR(sb.st_mode)) {
5085-			warnx("%s: %s", path, strerror(ENOTDIR));
5086-			return -1;
5087-		}
5088-		*slash = '/';
5089-	}
5090-	return 0;
5091+        struct stat sb;
5092+        char *slash;
5093+        int done = 0;
5094+
5095+        slash = path;
5096+        while (!done) {
5097+                slash += strspn(slash, "/");
5098+                slash += strcspn(slash, "/");
5099+                done = (*slash == '\0');
5100+                *slash = '\0';
5101+                if (stat(path, &sb)) {
5102+                        if (errno != ENOENT || (mkdir(path, 0777) && errno != EEXIST)) {
5103+                                weprintf("%s", path);
5104+                                return -1;
5105+                        }
5106+                } else if (!S_ISDIR(sb.st_mode)) {
5107+                        weprintf("%s: %s", path, strerror(ENOTDIR));
5108+                        return -1;
5109+                }
5110+                *slash = '/';
5111+        }
5112+        return 0;
5113 }
5114 
5115 char *
5116 find_backup_file_name(const char *file)
5117 {
5118-	char *dir, *base_versions, *tmp_file;
5119-	int highest_backup;
5120-
5121-	if (backup_type == BACKUP_SIMPLE)
5122-		return patch_concat(file, simple_backup_suffix);
5123-	tmp_file = strdup(file);
5124-	if (tmp_file == NULL)
5125-		return NULL;
5126-	base_versions = patch_concat(basename(tmp_file), ".~");
5127-	free(tmp_file);
5128-	if (base_versions == NULL)
5129-		return NULL;
5130-	tmp_file = strdup(file);
5131-	if (tmp_file == NULL) {
5132-		free(base_versions);
5133-		return NULL;
5134-	}
5135-	dir = dirname(tmp_file);
5136-	if (dir == NULL) {
5137-		free(base_versions);
5138-		free(tmp_file);
5139-		return NULL;
5140-	}
5141-	highest_backup = max_backup_version(base_versions, dir);
5142-	free(base_versions);
5143-	free(tmp_file);
5144-	if (backup_type == BACKUP_NUMBERED_EXISTING && highest_backup == 0)
5145-		return patch_concat(file, simple_backup_suffix);
5146-	return make_version_name(file, highest_backup + 1);
5147+        char *dir, *base_versions, *tmp_file;
5148+        int highest_backup;
5149+
5150+        if (backup_type == BACKUP_SIMPLE)
5151+                return patch_concat(file, simple_backup_suffix);
5152+        tmp_file = strdup(file);
5153+        if (tmp_file == NULL)
5154+                return NULL;
5155+        base_versions = patch_concat(basename(tmp_file), ".~");
5156+        free(tmp_file);
5157+        if (base_versions == NULL)
5158+                return NULL;
5159+        tmp_file = strdup(file);
5160+        if (tmp_file == NULL) {
5161+                free(base_versions);
5162+                return NULL;
5163+        }
5164+        dir = dirname(tmp_file);
5165+        if (dir == NULL) {
5166+                free(base_versions);
5167+                free(tmp_file);
5168+                return NULL;
5169+        }
5170+        highest_backup = max_backup_version(base_versions, dir);
5171+        free(base_versions);
5172+        free(tmp_file);
5173+        if (backup_type == BACKUP_NUMBERED_EXISTING && highest_backup == 0)
5174+                return patch_concat(file, simple_backup_suffix);
5175+        return make_version_name(file, highest_backup + 1);
5176 }
5177 
5178 static int
5179 max_backup_version(const char *file, const char *dir)
5180 {
5181-	DIR *dirp;
5182-	struct dirent *dp;
5183-	int highest_version, this_version;
5184-	size_t file_name_length;
5185+        DIR *dirp;
5186+        struct dirent *dp;
5187+        int highest_version, this_version;
5188+        size_t file_name_length;
5189 
5190-	dirp = opendir(dir);
5191-	if (dirp == NULL)
5192-		return 0;
5193+        dirp = opendir(dir);
5194+        if (dirp == NULL)
5195+                return 0;
5196 
5197-	highest_version = 0;
5198-	file_name_length = strlen(file);
5199-	while ((dp = readdir(dirp)) != NULL) {
5200-		if (strlen(dp->d_name) <= file_name_length)
5201-			continue;
5202-		this_version = version_number(file, dp->d_name, file_name_length);
5203-		if (this_version > highest_version)
5204-			highest_version = this_version;
5205-	}
5206-	closedir(dirp);
5207-	return highest_version;
5208+        highest_version = 0;
5209+        file_name_length = strlen(file);
5210+        while ((dp = readdir(dirp)) != NULL) {
5211+                if (strlen(dp->d_name) <= file_name_length)
5212+                        continue;
5213+                this_version = version_number(file, dp->d_name, file_name_length);
5214+                if (this_version > highest_version)
5215+                        highest_version = this_version;
5216+        }
5217+        closedir(dirp);
5218+        return highest_version;
5219 }
5220 
5221 static char *
5222 make_version_name(const char *file, int version_num)
5223 {
5224-	char *backup_name;
5225+        char *backup_name;
5226 
5227-	if (asprintf(&backup_name, "%s.~%d~", file, version_num) == -1)
5228-		return NULL;
5229-	return backup_name;
5230+        if (asprintf(&backup_name, "%s.~%d~", file, version_num) == -1)
5231+                return NULL;
5232+        return backup_name;
5233 }
5234 
5235 static int
5236 version_number(const char *base, const char *backup, size_t base_length)
5237 {
5238-	int version_num;
5239-	const char *p;
5240+        int version_num;
5241+        const char *p;
5242 
5243-	version_num = 0;
5244-	if (!strncmp(base, backup, base_length) && ISDIGIT(backup[base_length])) {
5245-		for (p = &backup[base_length]; ISDIGIT(*p); ++p)
5246-			version_num = version_num * 10 + *p - '0';
5247-		if (p[0] != '~' || p[1])
5248-			version_num = 0;
5249-	}
5250-	return version_num;
5251+        version_num = 0;
5252+        if (!strncmp(base, backup, base_length) && ISDIGIT(backup[base_length])) {
5253+                for (p = &backup[base_length]; ISDIGIT(*p); ++p)
5254+                        version_num = version_num * 10 + *p - '0';
5255+                if (p[0] != '~' || p[1])
5256+                        version_num = 0;
5257+        }
5258+        return version_num;
5259 }
5260 
5261 static char *
5262 patch_concat(const char *str1, const char *str2)
5263 {
5264-	char *newstr;
5265+        char *newstr;
5266 
5267-	if (asprintf(&newstr, "%s%s", str1, str2) == -1)
5268-		return NULL;
5269-	return newstr;
5270+        if (asprintf(&newstr, "%s%s", str1, str2) == -1)
5271+                return NULL;
5272+        return newstr;
5273 }
5274 
5275 static int
5276 argmatch(const char *arg, const char **optlist)
5277 {
5278-	int i;
5279-	size_t arglen;
5280-	int matchind = -1;
5281-	int ambiguous = 0;
5282-
5283-	arglen = strlen(arg);
5284-	for (i = 0; optlist[i]; i++) {
5285-		if (!strncmp(optlist[i], arg, arglen)) {
5286-			if (strlen(optlist[i]) == arglen)
5287-				return i;
5288-			else if (matchind == -1)
5289-				matchind = i;
5290-			else
5291-				ambiguous = 1;
5292-		}
5293-	}
5294-	if (ambiguous)
5295-		return -2;
5296-	else
5297-		return matchind;
5298+        int i;
5299+        size_t arglen;
5300+        int matchind = -1;
5301+        int ambiguous = 0;
5302+
5303+        arglen = strlen(arg);
5304+        for (i = 0; optlist[i]; i++) {
5305+                if (!strncmp(optlist[i], arg, arglen)) {
5306+                        if (strlen(optlist[i]) == arglen)
5307+                                return i;
5308+                        else if (matchind == -1)
5309+                                matchind = i;
5310+                        else
5311+                                ambiguous = 1;
5312+                }
5313+        }
5314+        if (ambiguous)
5315+                return -2;
5316+        else
5317+                return matchind;
5318 }
5319 
5320 static void
5321 invalid_arg(const char *kind, const char *value, int problem)
5322 {
5323-	fprintf(stderr, "patch: ");
5324-	if (problem == -1)
5325-		fprintf(stderr, "invalid");
5326-	else
5327-		fprintf(stderr, "ambiguous");
5328-	fprintf(stderr, " %s `%s'\n", kind, value);
5329+        fprintf(stderr, "patch: ");
5330+        if (problem == -1)
5331+                fprintf(stderr, "invalid");
5332+        else
5333+                fprintf(stderr, "ambiguous");
5334+        fprintf(stderr, " %s `%s'\n", kind, value);
5335 }
5336 
5337 enum BackupType
5338 get_version(const char *version_str)
5339 {
5340-	int i;
5341+        int i;
5342 
5343-	if (version_str == NULL || *version_str == '\0')
5344-		return BACKUP_NUMBERED_EXISTING;
5345-	i = argmatch(version_str, backup_args);
5346-	if (i >= 0)
5347-		return backup_types[i];
5348-	invalid_arg("version control type", version_str, i);
5349-	exit(2);
5350+        if (version_str == NULL || *version_str == '\0')
5351+                return BACKUP_NUMBERED_EXISTING;
5352+        i = argmatch(version_str, backup_args);
5353+        if (i >= 0)
5354+                return backup_types[i];
5355+        invalid_arg("version control type", version_str, i);
5356+        exit(2);
5357 }
+3, -3
 1@@ -32,7 +32,6 @@
 2  * SUCH DAMAGE.
 3  */
 4 
 5-#include <paths.h>
 6 #include <signal.h>
 7 #include <stdlib.h>
 8 #include <unistd.h>
 9@@ -43,6 +42,7 @@
10  * Evaluate a command.
11  */
12 
13+#include "../../../shared/paths.h"
14 #include "shell.h"
15 #include "nodes.h"
16 #include "syntax.h"
17@@ -989,7 +989,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
18 						argv += 2;
19 						argc -= 2;
20 					}
21-					path = _PATH_STDPATH;
22+					path = ARUU_PATH_STDPATH;
23 					clearcmdentry();
24 					do_clearcmdentry = 1;
25 				} else if (!strcmp(argv[1], "--")) {
26@@ -1318,7 +1318,7 @@ commandcmd(int argc __unused, char **argv __unused)
27 	while ((ch = nextopt("pvV")) != '\0') {
28 		switch (ch) {
29 		case 'p':
30-			path = _PATH_STDPATH;
31+			path = ARUU_PATH_STDPATH;
32 			break;
33 		case 'v':
34 			cmd = TYPECMD_SMALLV;
+3, -3
 1@@ -37,7 +37,6 @@
 2 #include <unistd.h>
 3 #include <fcntl.h>
 4 #include <errno.h>
 5-#include <paths.h>
 6 #include <stdlib.h>
 7 
 8 /*
 9@@ -49,6 +48,7 @@
10  * would make the command name "hash" a misnomer.
11  */
12 
13+#include "../../../shared/paths.h"
14 #include "shell.h"
15 #include "main.h"
16 #include "nodes.h"
17@@ -186,8 +186,8 @@ tryexec(char *cmd, char **argv, char **envp)
18 			}
19 		}
20 		*argv = cmd;
21-		*--argv = __DECONST(char *, _PATH_BSHELL);
22-		execve(_PATH_BSHELL, argv, envp);
23+		*--argv = __DECONST(char *, ARUU_PATH_BSHELL);
24+		execve(ARUU_PATH_BSHELL, argv, envp);
25 	}
26 	errno = e;
27 }
+6, -6
 1@@ -39,12 +39,12 @@
 2 #include <sys/wait.h>
 3 #include <errno.h>
 4 #include <fcntl.h>
 5-#include <paths.h>
 6 #include <signal.h>
 7 #include <stddef.h>
 8 #include <stdlib.h>
 9 #include <unistd.h>
10 
11+#include "../../../shared/paths.h"
12 #include "shell.h"
13 #if JOBS
14 #include <termios.h>
15@@ -179,7 +179,7 @@ setjobctl(int on)
16 	if (on) {
17 		if (ttyfd != -1)
18 			close(ttyfd);
19-		if ((ttyfd = open(_PATH_TTY, O_RDWR | O_CLOEXEC)) < 0) {
20+		if ((ttyfd = open(ARUU_PATH_DEVTTY, O_RDWR | O_CLOEXEC)) < 0) {
21 			i = 0;
22 			while (i <= 2 && !isatty(i))
23 				i++;
24@@ -942,9 +942,9 @@ forkshell(struct job *jp, union node *n, int mode)
25 			if ((jp == NULL || jp->nprocs == 0) &&
26 			    ! fd0_redirected_p ()) {
27 				close(0);
28-				if (open(_PATH_DEVNULL, O_RDONLY) != 0)
29+				if (open(ARUU_PATH_DEVNULL, O_RDONLY) != 0)
30 					error("cannot open %s: %s",
31-					    _PATH_DEVNULL, strerror(errno));
32+					    ARUU_PATH_DEVNULL, strerror(errno));
33 			}
34 		}
35 #else
36@@ -954,9 +954,9 @@ forkshell(struct job *jp, union node *n, int mode)
37 			if ((jp == NULL || jp->nprocs == 0) &&
38 			    ! fd0_redirected_p ()) {
39 				close(0);
40-				if (open(_PATH_DEVNULL, O_RDONLY) != 0)
41+				if (open(ARUU_PATH_DEVNULL, O_RDONLY) != 0)
42 					error("cannot open %s: %s",
43-					    _PATH_DEVNULL, strerror(errno));
44+					    ARUU_PATH_DEVNULL, strerror(errno));
45 			}
46 		}
47 #endif
+2, -2
 1@@ -39,6 +39,7 @@
 2 #endif
 3 
 4 #include "util.h"
 5+#include "../../../shared/paths.h"
 6 #include "shell.h"
 7 #include "alias.h"
 8 #include "builtins.h"
 9@@ -63,7 +64,6 @@
10 #include <errno.h>
11 #include <fcntl.h>
12 #include <limits.h>
13-#include <paths.h>
14 #include <pwd.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17@@ -693,7 +693,7 @@ operands:
18 	if (editor) {
19 		int fd;
20 		INTOFF;
21-		sprintf(editfilestr, "%s/_shXXXXXX", _PATH_TMP);
22+		sprintf(editfilestr, "%s/_shXXXXXX", ARUU_PATH_TMP);
23 		if ((fd = mkstemp(editfilestr)) < 0)
24 			error("can't create temporary file %s", editfile);
25 		editfile = editfilestr;
+2, -2
 1@@ -40,9 +40,9 @@
 2 #include <locale.h>
 3 #include <errno.h>
 4 #include <termios.h>
 5-#include <paths.h>
 6 #include <unistd.h>
 7 
 8+#include "../../../shared/paths.h"
 9 #include "shell.h"
10 #include "main.h"
11 #include "mail.h"
12@@ -134,7 +134,7 @@ main(int argc, char *argv[])
13 		 * file descriptors 0, 1, and 2 on /dev/console.
14 		 */
15 		if (fcntl(STDIN_FILENO, F_GETFL, NULL) == -1 && errno == EBADF) {
16-			(void)open(_PATH_CONSOLE, O_RDWR);
17+			(void)open(ARUU_PATH_DEVCONSOLE, O_RDWR);
18 			(void)setsid();
19 			(void)tcsetsid(STDIN_FILENO, rootpid);
20 		}
+2, -2
 1@@ -32,6 +32,7 @@
 2  * SUCH DAMAGE.
 3  */
 4 
 5+#include "../../../shared/paths.h"
 6 #include "shell.h"
 7 #include "output.h"
 8 #include "expand.h"
 9@@ -53,7 +54,6 @@
10 
11 #include <langinfo.h>
12 #include <locale.h>
13-#include <paths.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16 
17@@ -102,7 +102,7 @@ static const struct varinit varinit[] = {
18 	  NULL },
19 	{ &vmpath,	VUNSET,				"MAILPATH=",
20 	  NULL },
21-	{ &vpath,	0,				"PATH=" _PATH_DEFPATH,
22+	{ &vpath,	0,				"PATH=" ARUU_PATH_DEFPATH,
23 	  changepath },
24 	/*
25 	 * vps1 depends on uid
+3, -2
 1@@ -8,6 +8,7 @@
 2 #include <stdio.h>
 3 #include <unistd.h>
 4 
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 static void
 9@@ -50,9 +51,9 @@ main(int argc, char *argv[])
10 		eprintf("fork:");
11 		/* fallthrough */
12 	case 0:
13-		execvp(argv[0], argv);
14+		wexecvp_self(argv[0], argv);
15 		savederrno = errno;
16-		weprintf("execvp %s:", argv[0]);
17+		weprintf("wexecvp %s:", argv[0]);
18 		_exit(126 + (savederrno == ENOENT));
19 	default:
20 		break;
+3, -2
 1@@ -11,6 +11,7 @@
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 #define NARGS 10000
 9@@ -245,9 +246,9 @@ dospawn:
10 		eprintf("fork:");
11 		/* fallthrough */
12 	case 0:
13-		execvp(*cmd, cmd);
14+		wexecvp_self(*cmd, cmd);
15 		savederrno = errno;
16-		weprintf("execvp %s:", *cmd);
17+		weprintf("wexecvp %s:", *cmd);
18 		_exit(126 + (savederrno == ENOENT));
19 	}
20 	curprocs++;
+4, -3
 1@@ -5,6 +5,7 @@
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 static void
 9@@ -41,14 +42,14 @@ main(int argc, char *argv[])
10 
11 	if (argc == 1) {
12 		cmd = *shell;
13-		execvp(cmd, shell);
14+		wexecvp_self(cmd, shell);
15 	} else {
16 		cmd = argv[1];
17-		execvp(cmd, argv + 1);
18+		wexecvp_self(cmd, argv + 1);
19 	}
20 
21 	savederrno = errno;
22-	weprintf("execvp %s:", cmd);
23+	weprintf("wexecvp %s:", cmd);
24 
25 	_exit(126 + (savederrno == ENOENT));
26 }
+3, -1
 1@@ -17,6 +17,8 @@
 2 #include <unistd.h>
 3 
 4 #include "queue.h"
 5+#include "paths.h"
 6+#include "wexec.h"
 7 #include "util.h"
 8 
 9 struct field {
10@@ -121,7 +123,7 @@ runjob(char *cmd)
11 		setsid();
12 		loginfo("run: %s pid: %d at %s",
13 			cmd, getpid(), ctime(&t));
14-		execl("/bin/sh", "/bin/sh", "-c", cmd, (char *)NULL);
15+		wexecv_self(ARUU_PATH_BIN "/sh", (char *const[]){"sh", "-c", cmd, NULL});
16 		logerr("error: failed to execute job: %s time: %s",
17 		       cmd, ctime(&t));
18 		_exit(1);
+3, -2
 1@@ -9,6 +9,7 @@
 2 #include <stdio.h>
 3 #include <unistd.h>
 4 
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 static void
 9@@ -71,9 +72,9 @@ main(int argc, char *argv[])
10 		if (oflag && close(fd) < 0)
11 			eprintf("close:");
12 		argv++;
13-		execvp(*argv, argv);
14+		wexecvp_self(*argv, argv);
15 		savederrno = errno;
16-		weprintf("execvp %s:", *argv);
17+		weprintf("wexecvp %s:", *argv);
18 		_exit(126 + (savederrno == ENOENT));
19 	default:
20 		break;
+117, -114
  1@@ -15,6 +15,7 @@
  2 #include <utmp.h>
  3 
  4 #include "config.h"
  5+#include "wexec.h"
  6 #include "util.h"
  7 
  8 static char *tty = "/dev/tty1";
  9@@ -23,7 +24,7 @@ static char *defaultterm = "linux";
 10 static void
 11 usage(void)
 12 {
 13-	eprintf("usage: %s [tty] [term] [cmd] [args...]\n", argv0);
 14+        eprintf("usage: %s [tty] [term] [cmd] [args...]\n", argv0);
 15 }
 16 
 17 // ?man getty: set terminal mode
 18@@ -32,117 +33,119 @@ usage(void)
 19 int
 20 main(int argc, char *argv[])
 21 {
 22-	char term[128], logname[LOGIN_NAME_MAX], c;
 23-	char hostname[HOST_NAME_MAX + 1];
 24-	char ut_line_buf[UT_LINESIZE + 1];
 25-	struct utmp usr;
 26-	struct sigaction sa;
 27-	FILE *fp;
 28-	int fd;
 29-	unsigned int i = 0;
 30-	ssize_t n;
 31-	long pos;
 32-
 33-	ARGBEGIN {
 34-	default:
 35-		usage();
 36-	} ARGEND;
 37-
 38-	strlcpy(term, defaultterm, sizeof(term));
 39-	if (argc > 0) {
 40-		tty = argv[0];
 41-		if (argc > 1)
 42-			strlcpy(term, argv[1], sizeof(term));
 43-	}
 44-
 45-	sa.sa_handler = SIG_IGN;
 46-	sa.sa_flags = 0;
 47-	sigemptyset(&sa.sa_mask);
 48-	sigaction(SIGHUP, &sa, NULL);
 49-
 50-	setenv("TERM", term, 1);
 51-
 52-	setsid();
 53-
 54-	fd = open(tty, O_RDWR);
 55-	if (fd < 0)
 56-		eprintf("open %s:", tty);
 57-	if (isatty(fd) == 0)
 58-		eprintf("%s is not a tty\n", tty);
 59-
 60-	/* steal the controlling terminal if necessary */
 61-	if (ioctl(fd, TIOCSCTTY, (void *)1) != 0)
 62-		weprintf("TIOCSCTTY: could not set controlling tty\n");
 63-	vhangup();
 64-	close(fd);
 65-
 66-	fd = open(tty, O_RDWR);
 67-	if (fd < 0)
 68-		eprintf("open %s:", tty);
 69-	dup2(fd, 0);
 70-	dup2(fd, 1);
 71-	dup2(fd, 2);
 72-	if (fchown(fd, 0, 0) < 0)
 73-		weprintf("fchown %s:", tty);
 74-	if (fchmod(fd, 0600) < 0)
 75-		weprintf("fchmod %s:", tty);
 76-	if (fd > 2)
 77-		close(fd);
 78-
 79-	sa.sa_handler = SIG_DFL;
 80-	sa.sa_flags = 0;
 81-	sigemptyset(&sa.sa_mask);
 82-	sigaction(SIGHUP, &sa, NULL);
 83-
 84-	/* Clear all utmp entries for this tty */
 85-	fp = fopen(UTMP_PATH, "r+");
 86-	if (fp) {
 87-		do {
 88-			pos = ftell(fp);
 89-			if (fread(&usr, sizeof(usr), 1, fp) != 1)
 90-				break;
 91-			if (usr.ut_line[0] == '\0')
 92-				continue;
 93-			memcpy(ut_line_buf, usr.ut_line, UT_LINESIZE);
 94-			ut_line_buf[UT_LINESIZE] = '\0';
 95-			if (strcmp(ut_line_buf, tty) != 0)
 96-				continue;
 97-			memset(&usr, 0, sizeof(usr));
 98-			fseek(fp, pos, SEEK_SET);
 99-			if (fwrite(&usr, sizeof(usr), 1, fp) != 1)
100-				break;
101-		} while (1);
102-		if (ferror(fp))
103-			weprintf("%s: I/O error:", UTMP_PATH);
104-		fclose(fp);
105-	}
106-
107-	if (argc > 2)
108-		return execvp(argv[2], argv + 2);
109-
110-	if (gethostname(hostname, sizeof(hostname)) == 0)
111-		printf("%s ", hostname);
112-	printf("login: ");
113-	fflush(stdout);
114-
115-	/* Flush pending input */
116-	ioctl(0, TCFLSH, (void *)0);
117-	memset(logname, 0, sizeof(logname));
118-	while (1) {
119-		n = read(0, &c, 1);
120-		if (n < 0)
121-			eprintf("read:");
122-		if (n == 0)
123-			return 1;
124-		if (i >= sizeof(logname) - 1)
125-			eprintf("login name too long\n");
126-		if (c == '\n' || c == '\r')
127-			break;
128-		logname[i++] = c;
129-	}
130-	if (logname[0] == '-')
131-		eprintf("login name cannot start with '-'\n");
132-	if (logname[0] == '\0')
133-		return 1;
134-	return execlp("/bin/login", "login", "-p", logname, NULL);
135+        char term[128], logname[LOGIN_NAME_MAX], c;
136+        char hostname[HOST_NAME_MAX + 1];
137+        char ut_line_buf[UT_LINESIZE + 1];
138+        struct utmp usr;
139+        struct sigaction sa;
140+        FILE *fp;
141+        int fd;
142+        unsigned int i = 0;
143+        ssize_t n;
144+        long pos;
145+
146+        ARGBEGIN {
147+        default:
148+                usage();
149+        } ARGEND;
150+
151+        strlcpy(term, defaultterm, sizeof(term));
152+        if (argc > 0) {
153+                tty = argv[0];
154+                if (argc > 1)
155+                        strlcpy(term, argv[1], sizeof(term));
156+        }
157+
158+        sa.sa_handler = SIG_IGN;
159+        sa.sa_flags = 0;
160+        sigemptyset(&sa.sa_mask);
161+        sigaction(SIGHUP, &sa, NULL);
162+
163+        setenv("TERM", term, 1);
164+
165+        setsid();
166+
167+        fd = open(tty, O_RDWR);
168+        if (fd < 0)
169+                eprintf("open %s:", tty);
170+        if (isatty(fd) == 0)
171+                eprintf("%s is not a tty\n", tty);
172+
173+        /* steal the controlling terminal if necessary */
174+        if (ioctl(fd, TIOCSCTTY, (void *)1) != 0)
175+                weprintf("TIOCSCTTY: could not set controlling tty\n");
176+        vhangup();
177+        close(fd);
178+
179+        fd = open(tty, O_RDWR);
180+        if (fd < 0)
181+                eprintf("open %s:", tty);
182+        dup2(fd, 0);
183+        dup2(fd, 1);
184+        dup2(fd, 2);
185+        if (fchown(fd, 0, 0) < 0)
186+                weprintf("fchown %s:", tty);
187+        if (fchmod(fd, 0600) < 0)
188+                weprintf("fchmod %s:", tty);
189+        if (fd > 2)
190+                close(fd);
191+
192+        sa.sa_handler = SIG_DFL;
193+        sa.sa_flags = 0;
194+        sigemptyset(&sa.sa_mask);
195+        sigaction(SIGHUP, &sa, NULL);
196+
197+        /* Clear all utmp entries for this tty */
198+        fp = fopen(UTMP_PATH, "r+");
199+        if (fp) {
200+                do {
201+                        pos = ftell(fp);
202+                        if (fread(&usr, sizeof(usr), 1, fp) != 1)
203+                                break;
204+                        if (usr.ut_line[0] == '\0')
205+                                continue;
206+                        memcpy(ut_line_buf, usr.ut_line, UT_LINESIZE);
207+                        ut_line_buf[UT_LINESIZE] = '\0';
208+                        if (strcmp(ut_line_buf, tty) != 0)
209+                                continue;
210+                        memset(&usr, 0, sizeof(usr));
211+                        fseek(fp, pos, SEEK_SET);
212+                        if (fwrite(&usr, sizeof(usr), 1, fp) != 1)
213+                                break;
214+                } while (1);
215+                if (ferror(fp))
216+                        weprintf("%s: I/O error:", UTMP_PATH);
217+                fclose(fp);
218+        }
219+
220+        if (argc > 2) {
221+                wexecvp_self(argv[2], argv + 2);
222+                return 0;
223+        }
224+
225+        if (gethostname(hostname, sizeof(hostname)) == 0)
226+                printf("%s ", hostname);
227+        printf("login: ");
228+        fflush(stdout);
229+
230+        /* Flush pending input */
231+        ioctl(0, TCFLSH, (void *)0);
232+        memset(logname, 0, sizeof(logname));
233+        while (1) {
234+                n = read(0, &c, 1);
235+                if (n < 0)
236+                        eprintf("read:");
237+                if (n == 0)
238+                        return 1;
239+                if (i >= sizeof(logname) - 1)
240+                        eprintf("login name too long\n");
241+                if (c == '\n' || c == '\r')
242+                        break;
243+                logname[i++] = c;
244+        }
245+        if (logname[0] == '-')
246+                eprintf("login name cannot start with '-'\n");
247+        if (logname[0] == '\0')
248+                return 1;
249+        wexecvp_self("login", (char *const[]){"login", "-p", logname, NULL}); return 0;
250 }
+1, -1
 1@@ -3,7 +3,6 @@
 2 
 3 #include <errno.h>
 4 #include <libgen.h>
 5-#include <paths.h>
 6 #include <pwd.h>
 7 #include <stdio.h>
 8 #include <stdlib.h>
 9@@ -13,6 +12,7 @@
10 #include <unistd.h>
11 
12 #include "config.h"
13+#include "paths.h"
14 #include "util.h"
15 
16 static void
+5, -5
 1@@ -2,7 +2,6 @@
 2 
 3 
 4 #include <errno.h>
 5-#include <paths.h>
 6 #include <pwd.h>
 7 #include <stdio.h>
 8 #include <stdlib.h>
 9@@ -11,6 +10,7 @@
10 #include <utmp.h>
11 
12 #include "text.h"
13+#include "paths.h"
14 #include "util.h"
15 
16 #define PASSWD   "/etc/passwd"
17@@ -37,7 +37,7 @@ lastlog(char *user)
18 	fread(&ll, sizeof(struct lastlog), 1, last);
19 
20 	if (ferror(last))
21-		eprintf("%s: read error:", _PATH_LASTLOG);
22+		eprintf("%s: read error:", ARUU_PATH_LASTLOG);
23 
24 	/* on glibc `ll_time' can be an int32_t with compat32
25 	 * avoid compiler warning when calling ctime() */
26@@ -55,8 +55,8 @@ main(int argc, char **argv)
27 	char *line = NULL, *p;
28 	size_t sz = 0;
29 
30-	if ((last = fopen(_PATH_LASTLOG, "r")) == NULL)
31-		eprintf("fopen %s:", _PATH_LASTLOG);
32+	if ((last = fopen(ARUU_PATH_LASTLOG, "r")) == NULL)
33+		eprintf("fopen %s:", ARUU_PATH_LASTLOG);
34 
35 	if (argc > 1) {
36 		while (*++argv)
37@@ -76,7 +76,7 @@ main(int argc, char **argv)
38 	}
39 
40 	if (fclose(last))
41-		eprintf("fclose %s:", _PATH_LASTLOG);
42+		eprintf("fclose %s:", ARUU_PATH_LASTLOG);
43 
44 	return 0;
45 }
+3, -2
 1@@ -16,6 +16,7 @@
 2 
 3 #include "config.h"
 4 #include "passwd.h"
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 /* Write utmp entry */
 9@@ -58,8 +59,8 @@ dologin(struct passwd *pw, int preserve)
10 	setenv("PATH", ENV_PATH, 1);
11 	if (chdir(pw->pw_dir) < 0)
12 		eprintf("chdir %s:", pw->pw_dir);
13-	execlp(shell, shell, "-l", NULL);
14-	weprintf("execlp %s:", shell);
15+	wexecvp_self(shell, (char *const[]){shell, "-l", NULL});
16+	weprintf("wexecvp %s:", shell);
17 	return (errno == ENOENT) ? 127 : 126;
18 }
19 
+115, -143
  1@@ -1,8 +1,9 @@
  2 /* See LICENSE file for copyright and license details. */
  3+#include "passwd.h"
  4+#include "paths.h"
  5 #include "util.h"
  6 
  7 #include <ctype.h>
  8-#include <fcntl.h>
  9 #include <stdio.h>
 10 #include <stdlib.h>
 11 #include <string.h>
 12@@ -11,7 +12,7 @@
 13 static void
 14 usage(void)
 15 {
 16-	eprintf("usage: %s [-P fd] [-m type] [-S salt] [password] [salt]\n", argv0);
 17+        eprintf("usage: %s [-P fd] [-m type] [-S salt] [password] [salt]\n", argv0);
 18 }
 19 
 20 // ?man mkpasswd: encrypt the given password using salt
 21@@ -20,145 +21,116 @@ usage(void)
 22 int
 23 main(int argc, char *argv[])
 24 {
 25-	char *mflag;
 26-	char *sflag;
 27-	char *parg;
 28-	char *password;
 29-	char *cryptpass;
 30-	int pfd;
 31-	int fd;
 32-	int r;
 33-	int i;
 34-	int len;
 35-	int id;
 36-	char salt[128];
 37-	char rand_bytes[32];
 38-	char passbuf[1024];
 39-	static const char saltchars[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 40-
 41-	mflag = NULL;
 42-	sflag = NULL;
 43-	parg = NULL;
 44-	password = NULL;
 45-	cryptpass = NULL;
 46-	pfd = -1;
 47-
 48-	ARGBEGIN {
 49-	// ?man -P:fd: read password from file descriptor
 50-	case 'P':
 51-		parg = EARGF(usage());
 52-		pfd = estrtonum(parg, 0, INT_MAX);
 53-		break;
 54-	// ?man -m:type: encryption method (des, md5, sha256, sha512)
 55-	case 'm':
 56-		mflag = EARGF(usage());
 57-		break;
 58-	// ?man -S:salt: salt to use
 59-	case 'S':
 60-		sflag = EARGF(usage());
 61-		break;
 62-	default:
 63-		usage();
 64-	} ARGEND
 65-
 66-	if (argc > 2)
 67-		usage();
 68-
 69-	if (argc == 2) {
 70-		if (sflag)
 71-			eprintf("duplicate salt\n");
 72-		sflag = argv[1];
 73-	}
 74-
 75-	if (argc >= 1)
 76-		password = argv[0];
 77-
 78-	/* default type is des */
 79-	if (!mflag)
 80-		mflag = "des";
 81-
 82-	if (strcasecmp(mflag, "des") == 0) {
 83-		id = 0;
 84-		len = 2;
 85-	} else if (strcasecmp(mflag, "md5") == 0) {
 86-		id = 1;
 87-		len = 8;
 88-	} else if (strcasecmp(mflag, "sha256") == 0) {
 89-		id = 5;
 90-		len = 16;
 91-	} else if (strcasecmp(mflag, "sha512") == 0) {
 92-		id = 6;
 93-		len = 16;
 94-	} else {
 95-		eprintf("bad method: %s\n", mflag);
 96-	}
 97-
 98-	if (sflag) {
 99-		/* validate provided salt */
100-		char *s = sflag;
101-		while (*s) {
102-			if (!isalnum((unsigned char)*s) && *s != '.' && *s != '/')
103-				eprintf("bad SALT (need [a-zA-Z0-9./])\n");
104-			s++;
105-		}
106-		if (id > 0)
107-			snprintf(salt, sizeof(salt), "$%d$%s", id, sflag);
108-		else
109-			estrlcpy(salt, sflag, sizeof(salt));
110-	} else {
111-		/* generate random salt */
112-		fd = open("/dev/urandom", O_RDONLY);
113-		if (fd < 0)
114-			eprintf("open /dev/urandom:");
115-		r = read(fd, rand_bytes, len);
116-		if (r < len)
117-			eprintf("read /dev/urandom:");
118-		close(fd);
119-
120-		if (id > 0) {
121-			snprintf(salt, sizeof(salt), "$%d$", id);
122-			for (i = 0; i < len; i++)
123-				salt[3 + i] = saltchars[(unsigned char)rand_bytes[i] % 64];
124-			salt[3 + len] = '\0';
125-		} else {
126-			for (i = 0; i < len; i++)
127-				salt[i] = saltchars[(unsigned char)rand_bytes[i] % 64];
128-			salt[len] = '\0';
129-		}
130-	}
131-
132-	if (pfd >= 0) {
133-		if (dup2(pfd, 0) == -1)
134-			eprintf("dup2:");
135-		close(pfd);
136-	}
137-
138-	if (!password) {
139-		if (isatty(0)) {
140-			char *p = getpass("Password: ");
141-			if (!p)
142-				eprintf("getpass failed\n");
143-			estrlcpy(passbuf, p, sizeof(passbuf));
144-			password = passbuf;
145-		} else {
146-			/* read from stdin */
147-			int bytes = read(0, passbuf, sizeof(passbuf) - 1);
148-			if (bytes < 0)
149-				eprintf("read stdin:");
150-			/* strip trailing newline or cr */
151-			while (bytes > 0 && (passbuf[bytes - 1] == '\n' || passbuf[bytes - 1] == '\r'))
152-				bytes--;
153-			passbuf[bytes] = '\0';
154-			password = passbuf;
155-		}
156-	}
157-
158-	cryptpass = crypt(password, salt);
159-	if (!cryptpass)
160-		eprintf("crypt:");
161-	printf("%s\n", cryptpass);
162-
163-	if (fshut(stdout, "<stdout>"))
164-		return 2;
165-	return 0;
166+        char *mflag, *sflag, *parg, *password, *cryptpass;
167+        char *prefix;
168+        char salt[128];
169+        char passbuf[1024];
170+        int pfd, len;
171+
172+        mflag = NULL;
173+        sflag = NULL;
174+        parg = NULL;
175+        password = NULL;
176+        cryptpass = NULL;
177+        pfd = -1;
178+        len = 2;
179+        prefix = NULL;
180+
181+        ARGBEGIN {
182+        case 'P':
183+                // ?man -P:fd: read password from file descriptor
184+                parg = EARGF(usage());
185+                pfd = estrtonum(parg, 0, INT_MAX);
186+                break;
187+        case 'm':
188+                // ?man -m:type: encryption method (des, md5, sha256, sha512)
189+                mflag = EARGF(usage());
190+                break;
191+        case 'S':
192+                // ?man -S:salt: salt to use
193+                sflag = EARGF(usage());
194+                break;
195+        default:
196+                usage();
197+        } ARGEND
198+
199+        if (argc > 2)
200+                usage();
201+
202+        if (argc == 2) {
203+                if (sflag)
204+                        eprintf("duplicate salt\n");
205+                sflag = argv[1];
206+        }
207+
208+        if (argc >= 1)
209+                password = argv[0];
210+
211+        if (!mflag)
212+                mflag = "des";
213+
214+        if (strcasecmp(mflag, "des") == 0) {
215+                len = 2;
216+                prefix = NULL;
217+        } else if (strcasecmp(mflag, "md5") == 0) {
218+                len = 8;
219+                prefix = "$1$";
220+        } else if (strcasecmp(mflag, "sha256") == 0) {
221+                len = 16;
222+                prefix = "$5$";
223+        } else if (strcasecmp(mflag, "sha512") == 0) {
224+                len = 16;
225+                prefix = "$6$";
226+        } else {
227+                eprintf("bad method: %s\n", mflag);
228+        }
229+
230+        if (sflag) {
231+                char *s = sflag;
232+                while (*s) {
233+                        if (!isalnum((unsigned char)*s) && *s != '.' && *s != '/')
234+                                eprintf("bad SALT (need [a-zA-Z0-9./])\n");
235+                        s++;
236+                }
237+                if (prefix)
238+                        snprintf(salt, sizeof(salt), "%s%s", prefix, sflag);
239+                else
240+                        estrlcpy(salt, sflag, sizeof(salt));
241+        } else {
242+                if (pw_gensalt_cipher(salt, sizeof(salt), prefix, len) < 0)
243+                        eprintf("pw_gensalt_cipher:");
244+        }
245+
246+        if (pfd >= 0) {
247+                if (dup2(pfd, 0) == -1)
248+                        eprintf("dup2:");
249+                close(pfd);
250+        }
251+
252+        if (!password) {
253+                if (isatty(0)) {
254+                        char *p = getpass("Password: ");
255+                        if (!p)
256+                                eprintf("getpass failed\n");
257+                        estrlcpy(passbuf, p, sizeof(passbuf));
258+                        password = passbuf;
259+                } else {
260+                        int bytes = read(0, passbuf, sizeof(passbuf) - 1);
261+                        if (bytes < 0)
262+                                eprintf("read stdin:");
263+                        while (bytes > 0 && (passbuf[bytes - 1] == '\n' || passbuf[bytes - 1] == '\r'))
264+                                bytes--;
265+                        passbuf[bytes] = '\0';
266+                        password = passbuf;
267+                }
268+        }
269+
270+        cryptpass = crypt(password, salt);
271+        if (!cryptpass)
272+                eprintf("crypt:");
273+        printf("%s\n", cryptpass);
274+
275+        if (fshut(stdout, "<stdout>"))
276+                return 2;
277+        return 0;
278 }
+3, -2
 1@@ -14,6 +14,7 @@
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 static void
 9@@ -103,9 +104,9 @@ main(int argc, char *argv[])
10 			eprintf("fork:");
11 		switch (pid) {
12 		case 0:
13-			execvp(argv[0], argv);
14+			wexecvp_self(argv[0], argv);
15 			savederrno = errno;
16-			weprintf("execvp %s:", argv[0]);
17+			weprintf("wexecvp %s:", argv[0]);
18 			_exit(savederrno == ENOENT ? 127 : 126);
19 			break;
20 		default:
+3, -2
 1@@ -4,6 +4,7 @@
 2 #include <errno.h>
 3 #include <unistd.h>
 4 
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 static int fflag = 0;
 9@@ -46,9 +47,9 @@ main(int argc, char *argv[])
10 	}
11 	if (setsid() < 0)
12 		eprintf("setsid:");
13-	execvp(argv[0], argv);
14+	wexecvp_self(argv[0], argv);
15 	savederrno = errno;
16-	weprintf("execvp %s:", argv[0]);
17+	weprintf("wexecvp %s:", argv[0]);
18 
19 	_exit(126 + (savederrno == ENOENT));
20 }
+778, -765
   1@@ -3,6 +3,7 @@
   2 #include "config.h"
   3 #include "fs.h"
   4 #include "utf.h"
   5+#include "wexec.h"
   6 #include "util.h"
   7 
   8 #include <assert.h>
   9@@ -25,27 +26,27 @@
  10 static void
  11 safe_puts(const char *s)
  12 {
  13-	Rune r;
  14-	int n;
  15-
  16-	if (isatty(1)) {
  17-		while (*s) {
  18-			n = chartorune(&r, s);
  19-			if (r == Runeerror) {
  20-				putchar('?');
  21-				s++;
  22-			} else if (isprintrune(r)) {
  23-				fputrune(&r, stdout);
  24-				s += n;
  25-			} else {
  26-				putchar('?');
  27-				s += n;
  28-			}
  29-		}
  30-		putchar('\n');
  31-	} else {
  32-		puts(s);
  33-	}
  34+        Rune r;
  35+        int n;
  36+
  37+        if (isatty(1)) {
  38+                while (*s) {
  39+                        n = chartorune(&r, s);
  40+                        if (r == Runeerror) {
  41+                                putchar('?');
  42+                                s++;
  43+                        } else if (isprintrune(r)) {
  44+                                fputrune(&r, stdout);
  45+                                s += n;
  46+                        } else {
  47+                                putchar('?');
  48+                                s += n;
  49+                        }
  50+                }
  51+                putchar('\n');
  52+        } else {
  53+                puts(s);
  54+        }
  55 }
  56 #else
  57 #define safe_puts(s) puts(s)
  58@@ -54,40 +55,40 @@ safe_puts(const char *s)
  59 #define BLKSIZ (sizeof (struct header)) /* must equal 512 bytes */
  60 
  61 enum Type {
  62-	REG       = '0',
  63-	AREG      = '\0',
  64-	HARDLINK  = '1',
  65-	SYMLINK   = '2',
  66-	CHARDEV   = '3',
  67-	BLOCKDEV  = '4',
  68-	DIRECTORY = '5',
  69-	FIFO      = '6',
  70-	RESERVED  = '7'
  71+        REG       = '0',
  72+        AREG      = '\0',
  73+        HARDLINK  = '1',
  74+        SYMLINK   = '2',
  75+        CHARDEV   = '3',
  76+        BLOCKDEV  = '4',
  77+        DIRECTORY = '5',
  78+        FIFO      = '6',
  79+        RESERVED  = '7'
  80 };
  81 
  82 struct header {
  83-	char name[100];
  84-	char mode[8];
  85-	char uid[8];
  86-	char gid[8];
  87-	char size[12];
  88-	char mtime[12];
  89-	char chksum[8];
  90-	char type;
  91-	char linkname[100];
  92-	char magic[6];
  93-	char version[2];
  94-	char uname[32];
  95-	char gname[32];
  96-	char major[8];
  97-	char minor[8];
  98-	char prefix[155];
  99-	char padding[12];
 100+        char name[100];
 101+        char mode[8];
 102+        char uid[8];
 103+        char gid[8];
 104+        char size[12];
 105+        char mtime[12];
 106+        char chksum[8];
 107+        char type;
 108+        char linkname[100];
 109+        char magic[6];
 110+        char version[2];
 111+        char uname[32];
 112+        char gname[32];
 113+        char major[8];
 114+        char minor[8];
 115+        char prefix[155];
 116+        char padding[12];
 117 };
 118 
 119 static struct dirtime {
 120-	char *name;
 121-	time_t mtime;
 122+        char *name;
 123+        time_t mtime;
 124 } *dirtimes;
 125 
 126 static size_t dirtimeslen;
 127@@ -106,33 +107,33 @@ static size_t excludes_cnt = 0;
 128 static void
 129 add_exclude(const char *pattern)
 130 {
 131-	excludes = ereallocarray(excludes, excludes_cnt + 1, sizeof(*excludes));
 132-	excludes[excludes_cnt++] = estrdup(pattern);
 133+        excludes = ereallocarray(excludes, excludes_cnt + 1, sizeof(*excludes));
 134+        excludes[excludes_cnt++] = estrdup(pattern);
 135 }
 136 
 137 static int
 138 is_excluded(const char *path)
 139 {
 140-	size_t i;
 141-	const char *base = strrchr(path, '/');
 142-	base = base ? base + 1 : path;
 143-
 144-	for (i = 0; i < excludes_cnt; i++) {
 145-		if (fnmatch(excludes[i], path, 0) == 0 ||
 146-		    fnmatch(excludes[i], base, 0) == 0)
 147-			return 1;
 148-	}
 149-	return 0;
 150+        size_t i;
 151+        const char *base = strrchr(path, '/');
 152+        base = base ? base + 1 : path;
 153+
 154+        for (i = 0; i < excludes_cnt; i++) {
 155+                if (fnmatch(excludes[i], path, 0) == 0 ||
 156+                    fnmatch(excludes[i], base, 0) == 0)
 157+                        return 1;
 158+        }
 159+        return 0;
 160 }
 161 #endif
 162 static const char *filtertool;
 163 
 164 static const char *filtertools[] = {
 165-	['J'] = "xz",
 166-	['Z'] = "compress",
 167-	['a'] = "lzma",
 168-	['j'] = "bzip2",
 169-	['z'] = "gzip",
 170+        ['J'] = "xz",
 171+        ['Z'] = "compress",
 172+        ['a'] = "lzma",
 173+        ['j'] = "bzip2",
 174+        ['z'] = "gzip",
 175 };
 176 
 177 #if FEATURE_TAR_TO_STDOUT
 178@@ -153,17 +154,17 @@ static int strip_components_count = 0;
 179 static char *
 180 strip_components(char *path, int count)
 181 {
 182-	char *p = path;
 183-	int i;
 184-
 185-	for (i = 0; i < count; i++) {
 186-		p = strchr(p, '/');
 187-		if (!p)
 188-			return NULL;
 189-		while (*p == '/')
 190-			p++;
 191-	}
 192-	return p;
 193+        char *p = path;
 194+        int i;
 195+
 196+        for (i = 0; i < count; i++) {
 197+                p = strchr(p, '/');
 198+                if (!p)
 199+                        return NULL;
 200+                while (*p == '/')
 201+                        p++;
 202+        }
 203+        return p;
 204 }
 205 #else
 206 #define strip_components_count 0
 207@@ -176,27 +177,27 @@ static size_t files_from_cnt = 0;
 208 static void
 209 add_files_from(const char *path)
 210 {
 211-	files_from = ereallocarray(files_from, files_from_cnt + 1, sizeof(*files_from));
 212-	files_from[files_from_cnt++] = estrdup(path);
 213+        files_from = ereallocarray(files_from, files_from_cnt + 1, sizeof(*files_from));
 214+        files_from[files_from_cnt++] = estrdup(path);
 215 }
 216 
 217 static void
 218 load_files_from_file(const char *path)
 219 {
 220-	FILE *fp = fopen(path, "r");
 221-	char line[PATH_MAX];
 222-
 223-	if (!fp)
 224-		eprintf("open %s:", path);
 225-	while (fgets(line, sizeof(line), fp)) {
 226-		size_t len = strlen(line);
 227-		while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r'))
 228-			len--;
 229-		line[len] = '\0';
 230-		if (len > 0)
 231-			add_files_from(line);
 232-	}
 233-	fclose(fp);
 234+        FILE *fp = fopen(path, "r");
 235+        char line[PATH_MAX];
 236+
 237+        if (!fp)
 238+                eprintf("open %s:", path);
 239+        while (fgets(line, sizeof(line), fp)) {
 240+                size_t len = strlen(line);
 241+                while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r'))
 242+                        len--;
 243+                line[len] = '\0';
 244+                if (len > 0)
 245+                        add_files_from(line);
 246+        }
 247+        fclose(fp);
 248 }
 249 #else
 250 #define files_from_cnt 0
 251@@ -206,581 +207,593 @@ load_files_from_file(const char *path)
 252 static void
 253 load_excludes_from_file(const char *path)
 254 {
 255-	FILE *fp = fopen(path, "r");
 256-	char line[PATH_MAX];
 257-
 258-	if (!fp)
 259-		eprintf("open %s:", path);
 260-	while (fgets(line, sizeof(line), fp)) {
 261-		size_t len = strlen(line);
 262-		while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r'))
 263-			len--;
 264-		line[len] = '\0';
 265-		if (len > 0) {
 266+        FILE *fp = fopen(path, "r");
 267+        char line[PATH_MAX];
 268+
 269+        if (!fp)
 270+                eprintf("open %s:", path);
 271+        while (fgets(line, sizeof(line), fp)) {
 272+                size_t len = strlen(line);
 273+                while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r'))
 274+                        len--;
 275+                line[len] = '\0';
 276+                if (len > 0) {
 277 #if FEATURE_TAR_EXCLUDE
 278-			add_exclude(line);
 279+                        add_exclude(line);
 280 #else
 281-			(void)line;
 282+                        (void)line;
 283 #endif
 284-		}
 285-	}
 286-	fclose(fp);
 287+                }
 288+        }
 289+        fclose(fp);
 290 }
 291 #endif
 292 
 293 static void
 294 pushdirtime(char *name, time_t mtime)
 295 {
 296-	dirtimes = ereallocarray(dirtimes, dirtimeslen + 1, sizeof(*dirtimes));
 297-	dirtimes[dirtimeslen].name = estrdup(name);
 298-	dirtimes[dirtimeslen].mtime = mtime;
 299-	dirtimeslen++;
 300+        dirtimes = ereallocarray(dirtimes, dirtimeslen + 1, sizeof(*dirtimes));
 301+        dirtimes[dirtimeslen].name = estrdup(name);
 302+        dirtimes[dirtimeslen].mtime = mtime;
 303+        dirtimeslen++;
 304 }
 305 
 306 static struct dirtime *
 307 popdirtime(void)
 308 {
 309-	if (dirtimeslen) {
 310-		dirtimeslen--;
 311-		return &dirtimes[dirtimeslen];
 312-	}
 313-	return NULL;
 314+        if (dirtimeslen) {
 315+                dirtimeslen--;
 316+                return &dirtimes[dirtimeslen];
 317+        }
 318+        return NULL;
 319 }
 320 
 321 static int
 322 comp(int fd, const char *tool, const char *flags)
 323 {
 324-	int fds[2];
 325-
 326-	if (pipe(fds) < 0)
 327-		eprintf("pipe:");
 328-
 329-	switch (fork()) {
 330-	case -1:
 331-		eprintf("fork:");
 332-		/* fallthrough */
 333-	case 0:
 334-		dup2(fd, 1);
 335-		dup2(fds[0], 0);
 336-		close(fds[0]);
 337-		close(fds[1]);
 338-
 339-		execlp(tool, tool, flags, NULL);
 340-		weprintf("execlp %s:", tool);
 341-		_exit(1);
 342-	}
 343-	close(fds[0]);
 344-	return fds[1];
 345+        int fds[2];
 346+
 347+        if (pipe(fds) < 0)
 348+                eprintf("pipe:");
 349+
 350+        switch (fork()) {
 351+        case -1:
 352+                eprintf("fork:");
 353+                /* fallthrough */
 354+        case 0:
 355+                dup2(fd, 1);
 356+                dup2(fds[0], 0);
 357+                close(fds[0]);
 358+                close(fds[1]);
 359+
 360+                {
 361+                        char *tar_argv[3];
 362+                        tar_argv[0] = (char *)tool;
 363+                        tar_argv[1] = (char *)flags;
 364+                        tar_argv[2] = NULL;
 365+                        wexecvp_self(tool, tar_argv);
 366+                }
 367+                weprintf("wexecvp %s:", tool);
 368+                _exit(1);
 369+        }
 370+        close(fds[0]);
 371+        return fds[1];
 372 }
 373 
 374 static int
 375 decomp(int fd, const char *tool, const char *flags)
 376 {
 377-	int fds[2];
 378-
 379-	if (pipe(fds) < 0)
 380-		eprintf("pipe:");
 381-
 382-	switch (fork()) {
 383-	case -1:
 384-		eprintf("fork:");
 385-		/* fallthrough */
 386-	case 0:
 387-		dup2(fd, 0);
 388-		dup2(fds[1], 1);
 389-		close(fds[0]);
 390-		close(fds[1]);
 391-
 392-		execlp(tool, tool, flags, NULL);
 393-		weprintf("execlp %s:", tool);
 394-		_exit(1);
 395-	}
 396-	close(fds[1]);
 397-	return fds[0];
 398+        int fds[2];
 399+
 400+        if (pipe(fds) < 0)
 401+                eprintf("pipe:");
 402+
 403+        switch (fork()) {
 404+        case -1:
 405+                eprintf("fork:");
 406+                /* fallthrough */
 407+        case 0:
 408+                dup2(fd, 0);
 409+                dup2(fds[1], 1);
 410+                close(fds[0]);
 411+                close(fds[1]);
 412+
 413+                {
 414+                        char *tar_argv[3];
 415+                        tar_argv[0] = (char *)tool;
 416+                        tar_argv[1] = (char *)flags;
 417+                        tar_argv[2] = NULL;
 418+                        wexecvp_self(tool, tar_argv);
 419+                }
 420+                weprintf("wexecvp %s:", tool);
 421+                _exit(1);
 422+        }
 423+        close(fds[1]);
 424+        return fds[0];
 425 }
 426 
 427 static ssize_t
 428 eread(int fd, void *buf, size_t n)
 429 {
 430-	ssize_t r;
 431+        ssize_t r;
 432 
 433 again:
 434-	r = read(fd, buf, n);
 435-	if (r < 0) {
 436-		if (errno == EINTR)
 437-			goto again;
 438-		eprintf("read:");
 439-	}
 440-	return r;
 441+        r = read(fd, buf, n);
 442+        if (r < 0) {
 443+                if (errno == EINTR)
 444+                        goto again;
 445+                eprintf("read:");
 446+        }
 447+        return r;
 448 }
 449 
 450 static ssize_t
 451 ewrite(int fd, const void *buf, size_t n)
 452 {
 453-	ssize_t r;
 454+        ssize_t r;
 455 
 456-	if ((r = write(fd, buf, n)) < 0 || (size_t)r != n)
 457-		eprintf("write:");
 458-	return r;
 459+        if ((r = write(fd, buf, n)) < 0 || (size_t)r != n)
 460+                eprintf("write:");
 461+        return r;
 462 }
 463 
 464 static unsigned
 465 chksum(struct header *h)
 466 {
 467-	unsigned sum, i;
 468+        unsigned sum, i;
 469 
 470-	memset(h->chksum, ' ', sizeof(h->chksum));
 471-	for (i = 0, sum = 0, assert(BLKSIZ == 512); i < BLKSIZ; i++)
 472-		sum += *((unsigned char *)h + i);
 473-	return sum;
 474+        memset(h->chksum, ' ', sizeof(h->chksum));
 475+        for (i = 0, sum = 0, assert(BLKSIZ == 512); i < BLKSIZ; i++)
 476+                sum += *((unsigned char *)h + i);
 477+        return sum;
 478 }
 479 
 480 #if FEATURE_TAR_CREATE
 481 static void
 482 putoctal(char *dst, unsigned num, int size)
 483 {
 484-	if (snprintf(dst, size, "%.*o", size - 1, num) >= size)
 485-		eprintf("putoctal: input number '%o' too large\n", num);
 486+        if (snprintf(dst, size, "%.*o", size - 1, num) >= size)
 487+                eprintf("putoctal: input number '%o' too large\n", num);
 488 }
 489 
 490 static int
 491 archive(const char *path)
 492 {
 493-	static const struct header blank = {
 494-		.name = "././@LongLink",
 495-		.mode = "0000600",
 496-		.uid = "0000000",
 497-		.gid = "0000000",
 498-		.size = "00000000000",
 499-		.mtime = "00000000000",
 500-		.chksum = "       ",
 501-		.type = AREG,
 502-		.linkname = "",
 503-		.magic = "ustar",
 504-		.version = { '0', '0' }
 505-	};
 506-	char   b[BLKSIZ + BLKSIZ], *p;
 507-	struct header *h = (struct header *)b;
 508-	struct group  *gr;
 509-	struct passwd *pw;
 510-	struct stat st;
 511-	ssize_t l, n, r;
 512-	int fd = -1;
 513-
 514-	if (lstat(path, &st) < 0) {
 515-		weprintf("lstat %s:", path);
 516-		return 0;
 517-	} else if (st.st_ino == tarinode && st.st_dev == tardev) {
 518-		weprintf("ignoring %s\n", path);
 519-		return 0;
 520-	}
 521-	pw = getpwuid(st.st_uid);
 522-	gr = getgrgid(st.st_gid);
 523-
 524-	*h = blank;
 525-	n  = strlcpy(h->name, path, sizeof(h->name));
 526-	if ((size_t)n >= sizeof(h->name)) {
 527-		*++h = blank;
 528-		h->type = 'L';
 529-		putoctal(h->size,   n,         sizeof(h->size));
 530-		putoctal(h->chksum, chksum(h), sizeof(h->chksum));
 531-		ewrite(tarfd, (char *)h, BLKSIZ);
 532-
 533-		for (p = (char *)path; n > 0; n -= BLKSIZ, p += BLKSIZ) {
 534-			if ((size_t)n < BLKSIZ) {
 535-				p = memcpy(h--, p, n);
 536-				memset(p + n, 0, BLKSIZ - (size_t)n);
 537-			}
 538-			ewrite(tarfd, p, BLKSIZ);
 539-		}
 540-	}
 541-
 542-	putoctal(h->mode,    (unsigned)st.st_mode & 0777, sizeof(h->mode));
 543-	putoctal(h->uid,     (unsigned)st.st_uid,         sizeof(h->uid));
 544-	putoctal(h->gid,     (unsigned)st.st_gid,         sizeof(h->gid));
 545-	putoctal(h->mtime,   (unsigned)st.st_mtime,       sizeof(h->mtime));
 546-	estrlcpy(h->uname,   pw ? pw->pw_name : "",       sizeof(h->uname));
 547-	estrlcpy(h->gname,   gr ? gr->gr_name : "",       sizeof(h->gname));
 548-
 549-	if (S_ISREG(st.st_mode)) {
 550-		h->type = REG;
 551-		putoctal(h->size, st.st_size,  sizeof(h->size));
 552-		fd = open(path, O_RDONLY);
 553-		if (fd < 0)
 554-			eprintf("open %s:", path);
 555-	} else if (S_ISDIR(st.st_mode)) {
 556-		h->type = DIRECTORY;
 557-	} else if (S_ISLNK(st.st_mode)) {
 558-		h->type = SYMLINK;
 559-		if ((r = readlink(path, h->linkname, sizeof(h->linkname) - 1)) < 0)
 560-			eprintf("readlink %s:", path);
 561-		h->linkname[r] = '\0';
 562-	} else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
 563-		h->type = S_ISCHR(st.st_mode) ? CHARDEV : BLOCKDEV;
 564-		putoctal(h->major, (unsigned)major(st.st_dev), sizeof(h->major));
 565-		putoctal(h->minor, (unsigned)minor(st.st_dev), sizeof(h->minor));
 566-	} else if (S_ISFIFO(st.st_mode)) {
 567-		h->type = FIFO;
 568-	}
 569-
 570-	putoctal(h->chksum, chksum(h), sizeof(h->chksum));
 571-	ewrite(tarfd, b, BLKSIZ);
 572-
 573-	if (fd != -1) {
 574-		while ((l = eread(fd, b, BLKSIZ)) > 0) {
 575-			if ((size_t)l < BLKSIZ)
 576-				memset(b + l, 0, BLKSIZ - (size_t)l);
 577-			ewrite(tarfd, b, BLKSIZ);
 578-		}
 579-		close(fd);
 580-	}
 581-
 582-	return 0;
 583+        static const struct header blank = {
 584+                .name = "././@LongLink",
 585+                .mode = "0000600",
 586+                .uid = "0000000",
 587+                .gid = "0000000",
 588+                .size = "00000000000",
 589+                .mtime = "00000000000",
 590+                .chksum = "       ",
 591+                .type = AREG,
 592+                .linkname = "",
 593+                .magic = "ustar",
 594+                .version = { '0', '0' }
 595+        };
 596+        char   b[BLKSIZ + BLKSIZ], *p;
 597+        struct header *h = (struct header *)b;
 598+        struct group  *gr;
 599+        struct passwd *pw;
 600+        struct stat st;
 601+        ssize_t l, n, r;
 602+        int fd = -1;
 603+
 604+        if (lstat(path, &st) < 0) {
 605+                weprintf("lstat %s:", path);
 606+                return 0;
 607+        } else if (st.st_ino == tarinode && st.st_dev == tardev) {
 608+                weprintf("ignoring %s\n", path);
 609+                return 0;
 610+        }
 611+        pw = getpwuid(st.st_uid);
 612+        gr = getgrgid(st.st_gid);
 613+
 614+        *h = blank;
 615+        n  = strlcpy(h->name, path, sizeof(h->name));
 616+        if ((size_t)n >= sizeof(h->name)) {
 617+                *++h = blank;
 618+                h->type = 'L';
 619+                putoctal(h->size,   n,         sizeof(h->size));
 620+                putoctal(h->chksum, chksum(h), sizeof(h->chksum));
 621+                ewrite(tarfd, (char *)h, BLKSIZ);
 622+
 623+                for (p = (char *)path; n > 0; n -= BLKSIZ, p += BLKSIZ) {
 624+                        if ((size_t)n < BLKSIZ) {
 625+                                p = memcpy(h--, p, n);
 626+                                memset(p + n, 0, BLKSIZ - (size_t)n);
 627+                        }
 628+                        ewrite(tarfd, p, BLKSIZ);
 629+                }
 630+        }
 631+
 632+        putoctal(h->mode,    (unsigned)st.st_mode & 0777, sizeof(h->mode));
 633+        putoctal(h->uid,     (unsigned)st.st_uid,         sizeof(h->uid));
 634+        putoctal(h->gid,     (unsigned)st.st_gid,         sizeof(h->gid));
 635+        putoctal(h->mtime,   (unsigned)st.st_mtime,       sizeof(h->mtime));
 636+        estrlcpy(h->uname,   pw ? pw->pw_name : "",       sizeof(h->uname));
 637+        estrlcpy(h->gname,   gr ? gr->gr_name : "",       sizeof(h->gname));
 638+
 639+        if (S_ISREG(st.st_mode)) {
 640+                h->type = REG;
 641+                putoctal(h->size, st.st_size,  sizeof(h->size));
 642+                fd = open(path, O_RDONLY);
 643+                if (fd < 0)
 644+                        eprintf("open %s:", path);
 645+        } else if (S_ISDIR(st.st_mode)) {
 646+                h->type = DIRECTORY;
 647+        } else if (S_ISLNK(st.st_mode)) {
 648+                h->type = SYMLINK;
 649+                if ((r = readlink(path, h->linkname, sizeof(h->linkname) - 1)) < 0)
 650+                        eprintf("readlink %s:", path);
 651+                h->linkname[r] = '\0';
 652+        } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
 653+                h->type = S_ISCHR(st.st_mode) ? CHARDEV : BLOCKDEV;
 654+                putoctal(h->major, (unsigned)major(st.st_dev), sizeof(h->major));
 655+                putoctal(h->minor, (unsigned)minor(st.st_dev), sizeof(h->minor));
 656+        } else if (S_ISFIFO(st.st_mode)) {
 657+                h->type = FIFO;
 658+        }
 659+
 660+        putoctal(h->chksum, chksum(h), sizeof(h->chksum));
 661+        ewrite(tarfd, b, BLKSIZ);
 662+
 663+        if (fd != -1) {
 664+                while ((l = eread(fd, b, BLKSIZ)) > 0) {
 665+                        if ((size_t)l < BLKSIZ)
 666+                                memset(b + l, 0, BLKSIZ - (size_t)l);
 667+                        ewrite(tarfd, b, BLKSIZ);
 668+                }
 669+                close(fd);
 670+        }
 671+
 672+        return 0;
 673 }
 674 #endif
 675 
 676 static void
 677 skipblk(ssize_t l)
 678 {
 679-	char b[BLKSIZ];
 680+        char b[BLKSIZ];
 681 
 682-	for (; l > 0; l -= BLKSIZ)
 683-		if (!eread(tarfd, b, BLKSIZ))
 684-			break;
 685+        for (; l > 0; l -= BLKSIZ)
 686+                if (!eread(tarfd, b, BLKSIZ))
 687+                        break;
 688 }
 689 
 690 static int
 691 unarchive(char *fname, ssize_t l, char b[BLKSIZ])
 692 {
 693-	struct header *h = (struct header *)b;
 694-	struct timespec times[2];
 695-	struct stat st;
 696-	char lname[101], *tmp, *p;
 697-	long mode, major, minor, type, mtime, uid, gid;
 698-	int  fd = -1, lnk = h->type == SYMLINK;
 699-
 700-	if (kflag_keep && !Oflag_stdout) {
 701-		if (lstat(fname, &st) == 0) {
 702-			skipblk(l);
 703-			return 0;
 704-		}
 705-	}
 706-
 707-	if (!mflag && ((mtime = strtol(h->mtime, &p, 8)) < 0 || *p != '\0'))
 708-		eprintf("strtol %s: invalid mtime\n", h->mtime);
 709-
 710-	if (Oflag_stdout) {
 711-		if (h->type == REG || h->type == AREG || h->type == RESERVED) {
 712-			fd = 1;
 713-		} else {
 714-			return 0;
 715-		}
 716-	} else {
 717-		if (strcmp(fname, ".") && strcmp(fname, "./") && remove(fname) < 0)
 718-			if (errno != ENOENT) weprintf("remove %s:", fname);
 719-
 720-		tmp = estrdup(fname);
 721-		mkdirp(dirname(tmp), 0777, 0777);
 722-		free(tmp);
 723-
 724-		switch (h->type) {
 725-		case REG:
 726-		case AREG:
 727-		case RESERVED:
 728-			if ((mode = strtol(h->mode, &p, 8)) < 0 || *p != '\0')
 729-				eprintf("strtol %s: invalid mode\n", h->mode);
 730+        struct header *h = (struct header *)b;
 731+        struct timespec times[2];
 732+        struct stat st;
 733+        char lname[101], *tmp, *p;
 734+        long mode, major, minor, type, mtime, uid, gid;
 735+        int  fd = -1, lnk = h->type == SYMLINK;
 736+
 737+        if (kflag_keep && !Oflag_stdout) {
 738+                if (lstat(fname, &st) == 0) {
 739+                        skipblk(l);
 740+                        return 0;
 741+                }
 742+        }
 743+
 744+        if (!mflag && ((mtime = strtol(h->mtime, &p, 8)) < 0 || *p != '\0'))
 745+                eprintf("strtol %s: invalid mtime\n", h->mtime);
 746+
 747+        if (Oflag_stdout) {
 748+                if (h->type == REG || h->type == AREG || h->type == RESERVED) {
 749+                        fd = 1;
 750+                } else {
 751+                        return 0;
 752+                }
 753+        } else {
 754+                if (strcmp(fname, ".") && strcmp(fname, "./") && remove(fname) < 0)
 755+                        if (errno != ENOENT) weprintf("remove %s:", fname);
 756+
 757+                tmp = estrdup(fname);
 758+                mkdirp(dirname(tmp), 0777, 0777);
 759+                free(tmp);
 760+
 761+                switch (h->type) {
 762+                case REG:
 763+                case AREG:
 764+                case RESERVED:
 765+                        if ((mode = strtol(h->mode, &p, 8)) < 0 || *p != '\0')
 766+                                eprintf("strtol %s: invalid mode\n", h->mode);
 767 #if FEATURE_TAR_NOFOLLOW
 768-			fd = open(fname, O_WRONLY | O_TRUNC | O_CREAT | O_NOFOLLOW, 0600);
 769+                        fd = open(fname, O_WRONLY | O_TRUNC | O_CREAT | O_NOFOLLOW, 0600);
 770 #else
 771-			fd = open(fname, O_WRONLY | O_TRUNC | O_CREAT, 0600);
 772+                        fd = open(fname, O_WRONLY | O_TRUNC | O_CREAT, 0600);
 773 #endif
 774-			if (fd < 0)
 775-				eprintf("open %s:", fname);
 776-			break;
 777-		case HARDLINK:
 778-		case SYMLINK:
 779-			snprintf(lname, sizeof(lname), "%.*s", (int)sizeof(h->linkname),
 780-			         h->linkname);
 781-			if ((lnk ? symlink:link)(lname, fname) < 0)
 782-				eprintf("%s %s -> %s:", lnk ? "symlink":"link", fname, lname);
 783-			lnk++;
 784-			break;
 785-		case DIRECTORY:
 786-			if ((mode = strtol(h->mode, &p, 8)) < 0 || *p != '\0')
 787-				eprintf("strtol %s: invalid mode\n", h->mode);
 788-			if (mkdir(fname, (mode_t)mode) < 0 && errno != EEXIST)
 789-				eprintf("mkdir %s:", fname);
 790-			pushdirtime(fname, mtime);
 791-			break;
 792-		case CHARDEV:
 793-		case BLOCKDEV:
 794-			if ((mode = strtol(h->mode, &p, 8)) < 0 || *p != '\0')
 795-				eprintf("strtol %s: invalid mode\n", h->mode);
 796-			if ((major = strtol(h->major, &p, 8)) < 0 || *p != '\0')
 797-				eprintf("strtol %s: invalid major device\n", h->major);
 798-			if ((minor = strtol(h->minor, &p, 8)) < 0 || *p != '\0')
 799-				eprintf("strtol %s: invalid minor device\n", h->minor);
 800-			type = (h->type == CHARDEV) ? S_IFCHR : S_IFBLK;
 801-			if (mknod(fname, type | mode, makedev(major, minor)) < 0)
 802-				eprintf("mknod %s:", fname);
 803-			break;
 804-		case FIFO:
 805-			if ((mode = strtol(h->mode, &p, 8)) < 0 || *p != '\0')
 806-				eprintf("strtol %s: invalid mode\n", h->mode);
 807-			if (mknod(fname, S_IFIFO | mode, 0) < 0)
 808-				eprintf("mknod %s:", fname);
 809-			break;
 810-		default:
 811-			eprintf("unsupported tar-filetype %c\n", h->type);
 812-		}
 813-	}
 814-
 815-	if (!Oflag_stdout) {
 816-		if ((uid = strtol(h->uid, &p, 8)) < 0 || *p != '\0')
 817-			eprintf("strtol %s: invalid uid\n", h->uid);
 818-		if ((gid = strtol(h->gid, &p, 8)) < 0 || *p != '\0')
 819-			eprintf("strtol %s: invalid gid\n", h->gid);
 820-	}
 821-
 822-	if (fd != -1) {
 823-		for (; l > 0; l -= BLKSIZ)
 824-			if (eread(tarfd, b, BLKSIZ) > 0)
 825-				ewrite(fd, b, MIN(l, (ssize_t)BLKSIZ));
 826-		if (fd != 1)
 827-			close(fd);
 828-	}
 829-
 830-	if (Oflag_stdout)
 831-		return 0;
 832-
 833-	if (lnk == 1)
 834-		return 0;
 835-
 836-	times[0].tv_sec = times[1].tv_sec = mtime;
 837-	times[0].tv_nsec = times[1].tv_nsec = 0;
 838-	if (!mflag && utimensat(AT_FDCWD, fname, times, AT_SYMLINK_NOFOLLOW) < 0)
 839-		weprintf("utimensat %s:", fname);
 840-	if (lnk) {
 841-		if (!getuid() && lchown(fname, uid, gid))
 842-			weprintf("lchown %s:", fname);
 843-	} else {
 844-		if (!getuid() && chown(fname, uid, gid))
 845-			weprintf("chown %s:", fname);
 846-		if (chmod(fname, mode) < 0)
 847-			eprintf("fchmod %s:", fname);
 848-	}
 849-
 850-	return 0;
 851+                        if (fd < 0)
 852+                                eprintf("open %s:", fname);
 853+                        break;
 854+                case HARDLINK:
 855+                case SYMLINK:
 856+                        snprintf(lname, sizeof(lname), "%.*s", (int)sizeof(h->linkname),
 857+                                 h->linkname);
 858+                        if ((lnk ? symlink:link)(lname, fname) < 0)
 859+                                eprintf("%s %s -> %s:", lnk ? "symlink":"link", fname, lname);
 860+                        lnk++;
 861+                        break;
 862+                case DIRECTORY:
 863+                        if ((mode = strtol(h->mode, &p, 8)) < 0 || *p != '\0')
 864+                                eprintf("strtol %s: invalid mode\n", h->mode);
 865+                        if (mkdir(fname, (mode_t)mode) < 0 && errno != EEXIST)
 866+                                eprintf("mkdir %s:", fname);
 867+                        pushdirtime(fname, mtime);
 868+                        break;
 869+                case CHARDEV:
 870+                case BLOCKDEV:
 871+                        if ((mode = strtol(h->mode, &p, 8)) < 0 || *p != '\0')
 872+                                eprintf("strtol %s: invalid mode\n", h->mode);
 873+                        if ((major = strtol(h->major, &p, 8)) < 0 || *p != '\0')
 874+                                eprintf("strtol %s: invalid major device\n", h->major);
 875+                        if ((minor = strtol(h->minor, &p, 8)) < 0 || *p != '\0')
 876+                                eprintf("strtol %s: invalid minor device\n", h->minor);
 877+                        type = (h->type == CHARDEV) ? S_IFCHR : S_IFBLK;
 878+                        if (mknod(fname, type | mode, makedev(major, minor)) < 0)
 879+                                eprintf("mknod %s:", fname);
 880+                        break;
 881+                case FIFO:
 882+                        if ((mode = strtol(h->mode, &p, 8)) < 0 || *p != '\0')
 883+                                eprintf("strtol %s: invalid mode\n", h->mode);
 884+                        if (mknod(fname, S_IFIFO | mode, 0) < 0)
 885+                                eprintf("mknod %s:", fname);
 886+                        break;
 887+                default:
 888+                        eprintf("unsupported tar-filetype %c\n", h->type);
 889+                }
 890+        }
 891+
 892+        if (!Oflag_stdout) {
 893+                if ((uid = strtol(h->uid, &p, 8)) < 0 || *p != '\0')
 894+                        eprintf("strtol %s: invalid uid\n", h->uid);
 895+                if ((gid = strtol(h->gid, &p, 8)) < 0 || *p != '\0')
 896+                        eprintf("strtol %s: invalid gid\n", h->gid);
 897+        }
 898+
 899+        if (fd != -1) {
 900+                for (; l > 0; l -= BLKSIZ)
 901+                        if (eread(tarfd, b, BLKSIZ) > 0)
 902+                                ewrite(fd, b, MIN(l, (ssize_t)BLKSIZ));
 903+                if (fd != 1)
 904+                        close(fd);
 905+        }
 906+
 907+        if (Oflag_stdout)
 908+                return 0;
 909+
 910+        if (lnk == 1)
 911+                return 0;
 912+
 913+        times[0].tv_sec = times[1].tv_sec = mtime;
 914+        times[0].tv_nsec = times[1].tv_nsec = 0;
 915+        if (!mflag && utimensat(AT_FDCWD, fname, times, AT_SYMLINK_NOFOLLOW) < 0)
 916+                weprintf("utimensat %s:", fname);
 917+        if (lnk) {
 918+                if (!getuid() && lchown(fname, uid, gid))
 919+                        weprintf("lchown %s:", fname);
 920+        } else {
 921+                if (!getuid() && chown(fname, uid, gid))
 922+                        weprintf("chown %s:", fname);
 923+                if (chmod(fname, mode) < 0)
 924+                        eprintf("fchmod %s:", fname);
 925+        }
 926+
 927+        return 0;
 928 }
 929 
 930 
 931 static int
 932 print(char *fname, ssize_t l, char b[BLKSIZ])
 933 {
 934-	(void)b;
 935-	safe_puts(fname);
 936-	skipblk(l);
 937-	return 0;
 938+        (void)b;
 939+        safe_puts(fname);
 940+        skipblk(l);
 941+        return 0;
 942 }
 943 
 944 #if FEATURE_TAR_CREATE
 945 static void
 946 c(int dirfd, const char *name, struct stat *st, void *data, struct recursor *r)
 947 {
 948-	(void)data;
 949+        (void)data;
 950 #if FEATURE_TAR_EXCLUDE
 951-	if (is_excluded(r->path))
 952-		return;
 953+        if (is_excluded(r->path))
 954+                return;
 955 #endif
 956-	archive(r->path);
 957-	if (vflag)
 958-		safe_puts(r->path);
 959+        archive(r->path);
 960+        if (vflag)
 961+                safe_puts(r->path);
 962 
 963-	if (S_ISDIR(st->st_mode))
 964-		recurse(dirfd, name, NULL, r);
 965+        if (S_ISDIR(st->st_mode))
 966+                recurse(dirfd, name, NULL, r);
 967 }
 968 #endif
 969 
 970 static void
 971 sanitize(struct header *h)
 972 {
 973-	size_t i, j, l;
 974-	struct {
 975-		char  *f;
 976-		size_t l;
 977-	} fields[] = {
 978-		{ h->mode,   sizeof(h->mode)   },
 979-		{ h->uid,    sizeof(h->uid)    },
 980-		{ h->gid,    sizeof(h->gid)    },
 981-		{ h->size,   sizeof(h->size)   },
 982-		{ h->mtime,  sizeof(h->mtime)  },
 983-		{ h->chksum, sizeof(h->chksum) },
 984-		{ h->major,  sizeof(h->major)  },
 985-		{ h->minor,  sizeof(h->minor)  }
 986-	};
 987-
 988-	/* Numeric fields can be terminated with spaces instead of
 989-	 * NULs as per the ustar specification.  Patch all of them to
 990-	 * use NULs so we can perform string operations on them. */
 991-	for (i = 0; i < LEN(fields); i++){
 992-		j = 0, l = fields[i].l - 1;
 993-		for (; j < l && fields[i].f[j] == ' '; j++);
 994-		for (; j <= l; j++)
 995-			if (fields[i].f[j] == ' ')
 996-				fields[i].f[j] = '\0';
 997-		if (fields[i].f[l])
 998-			eprintf("numeric field #%d (%.*s) is not null or space terminated\n",
 999-			        i, l+1, fields[i].f);
1000-	}
1001+        size_t i, j, l;
1002+        struct {
1003+                char  *f;
1004+                size_t l;
1005+        } fields[] = {
1006+                { h->mode,   sizeof(h->mode)   },
1007+                { h->uid,    sizeof(h->uid)    },
1008+                { h->gid,    sizeof(h->gid)    },
1009+                { h->size,   sizeof(h->size)   },
1010+                { h->mtime,  sizeof(h->mtime)  },
1011+                { h->chksum, sizeof(h->chksum) },
1012+                { h->major,  sizeof(h->major)  },
1013+                { h->minor,  sizeof(h->minor)  }
1014+        };
1015+
1016+        /* Numeric fields can be terminated with spaces instead of
1017+         * NULs as per the ustar specification.  Patch all of them to
1018+         * use NULs so we can perform string operations on them. */
1019+        for (i = 0; i < LEN(fields); i++){
1020+                j = 0, l = fields[i].l - 1;
1021+                for (; j < l && fields[i].f[j] == ' '; j++);
1022+                for (; j <= l; j++)
1023+                        if (fields[i].f[j] == ' ')
1024+                                fields[i].f[j] = '\0';
1025+                if (fields[i].f[l])
1026+                        eprintf("numeric field #%d (%.*s) is not null or space terminated\n",
1027+                                i, l+1, fields[i].f);
1028+        }
1029 }
1030 
1031 static void
1032 chktar(struct header *h)
1033 {
1034-	const char *reason;
1035-	char tmp[sizeof h->chksum], *err;
1036-	long sum, i;
1037-
1038-	if (h->prefix[0] == '\0' && h->name[0] == '\0') {
1039-		reason = "empty filename";
1040-		goto bad;
1041-	}
1042-	if (h->magic[0] && strncmp("ustar", h->magic, 5)) {
1043-		reason = "not ustar format";
1044-		goto bad;
1045-	}
1046-	memcpy(tmp, h->chksum, sizeof(tmp));
1047-	for (i = sizeof(tmp)-1; i > 0 && tmp[i] == ' '; i--) {
1048-		tmp[i] = '\0';
1049-	}
1050-	sum = strtol(tmp, &err, 8);
1051-	if (sum < 0 || sum >= (long)(BLKSIZ*256) || *err != '\0') {
1052-		reason = "invalid checksum";
1053-		goto bad;
1054-	}
1055-	if (sum != chksum(h)) {
1056-		reason = "incorrect checksum";
1057-		goto bad;
1058-	}
1059-	memcpy(h->chksum, tmp, sizeof(tmp));
1060-	return;
1061+        const char *reason;
1062+        char tmp[sizeof h->chksum], *err;
1063+        long sum, i;
1064+
1065+        if (h->prefix[0] == '\0' && h->name[0] == '\0') {
1066+                reason = "empty filename";
1067+                goto bad;
1068+        }
1069+        if (h->magic[0] && strncmp("ustar", h->magic, 5)) {
1070+                reason = "not ustar format";
1071+                goto bad;
1072+        }
1073+        memcpy(tmp, h->chksum, sizeof(tmp));
1074+        for (i = sizeof(tmp)-1; i > 0 && tmp[i] == ' '; i--) {
1075+                tmp[i] = '\0';
1076+        }
1077+        sum = strtol(tmp, &err, 8);
1078+        if (sum < 0 || sum >= (long)(BLKSIZ*256) || *err != '\0') {
1079+                reason = "invalid checksum";
1080+                goto bad;
1081+        }
1082+        if (sum != chksum(h)) {
1083+                reason = "incorrect checksum";
1084+                goto bad;
1085+        }
1086+        memcpy(h->chksum, tmp, sizeof(tmp));
1087+        return;
1088 bad:
1089-	eprintf("malformed tar archive: %s\n", reason);
1090+        eprintf("malformed tar archive: %s\n", reason);
1091 }
1092 
1093 static void
1094 xt(int argc, char *argv[], int mode)
1095 {
1096-	long size;
1097-	char b[BLKSIZ], fname[PATH_MAX + 1], *p, *q = NULL, *stripped;
1098-	int i, m, n, match;
1099-	int (*fn)(char *, ssize_t, char[BLKSIZ]) = (mode == 'x') ? unarchive : print;
1100-	struct timespec times[2];
1101-	struct header *h = (struct header *)b;
1102-	struct dirtime *dirtime;
1103+        long size;
1104+        char b[BLKSIZ], fname[PATH_MAX + 1], *p, *q = NULL, *stripped;
1105+        int i, m, n, match;
1106+        int (*fn)(char *, ssize_t, char[BLKSIZ]) = (mode == 'x') ? unarchive : print;
1107+        struct timespec times[2];
1108+        struct header *h = (struct header *)b;
1109+        struct dirtime *dirtime;
1110 #if FEATURE_TAR_FILES_FROM
1111-	size_t idx;
1112+        size_t idx;
1113 #endif
1114 
1115-	while (eread(tarfd, b, BLKSIZ) > 0 && (h->name[0] || h->prefix[0])) {
1116-		chktar(h);
1117-		sanitize(h);
1118-
1119-		if ((size = strtol(h->size, &p, 8)) < 0 || *p != '\0')
1120-			eprintf("strtol %s: invalid size\n", h->size);
1121-
1122-		/* Long file path is read directly into fname*/
1123-		if (h->type == 'L' || h->type == 'x' || h->type == 'g') {
1124-
1125-			/* Read header only up to size of fname buffer */
1126-			for (q = fname; q < fname+size; q += BLKSIZ) {
1127-				if (q + BLKSIZ >= fname + sizeof fname)
1128-					eprintf("name exceeds buffer: %.*s\n", q-fname, fname);
1129-				eread(tarfd, q, BLKSIZ);
1130-			}
1131-
1132-			/* Convert pax x header with 'path=' field into L header */
1133-			if (h->type == 'x') for (q = fname; q < fname+size-16; q += n) {
1134-				if ((n = strtol(q, &p, 10)) < 0 || *p != ' ')
1135-					eprintf("strtol %.*s: invalid number\n", p+1-q, q);
1136-				if (n && strncmp(p+1, "path=", 5) == 0) {
1137-					memmove(fname, p+6, size = q+n - p-6 - 1);
1138-					h->type = 'L';
1139-					break;
1140-				}
1141-			}
1142-			fname[size] = '\0';
1143-
1144-			/* Non L-like header (eg. pax 'g') is skipped by setting q=null */
1145-			if (h->type != 'L')
1146-				q = NULL;
1147-			continue;
1148-		}
1149-
1150-		/* Ustar path is copied into fname if no L header (ie: q is NULL) */
1151-		if (!q) {
1152-			m = sizeof h->prefix, n = sizeof h->name;
1153-			p = "/" + !h->prefix[0];
1154-			snprintf(fname, sizeof fname, "%.*s%s%.*s", m, h->prefix, p, n, h->name);
1155-		}
1156-		q = NULL;
1157-
1158-		/* If argc > 0 or files_from_cnt > 0 then only extract the matching files/dirs */
1159-		if (argc || files_from_cnt) {
1160-			match = 0;
1161-			for (i = 0; i < argc; i++) {
1162-				if (strncmp(argv[i], fname, n = strlen(argv[i])) == 0) {
1163-					if (strchr("/", fname[n]) || argv[i][n-1] == '/') {
1164-						match = 1;
1165-						break;
1166-					}
1167-				}
1168-			}
1169+        while (eread(tarfd, b, BLKSIZ) > 0 && (h->name[0] || h->prefix[0])) {
1170+                chktar(h);
1171+                sanitize(h);
1172+
1173+                if ((size = strtol(h->size, &p, 8)) < 0 || *p != '\0')
1174+                        eprintf("strtol %s: invalid size\n", h->size);
1175+
1176+                /* Long file path is read directly into fname*/
1177+                if (h->type == 'L' || h->type == 'x' || h->type == 'g') {
1178+
1179+                        /* Read header only up to size of fname buffer */
1180+                        for (q = fname; q < fname+size; q += BLKSIZ) {
1181+                                if (q + BLKSIZ >= fname + sizeof fname)
1182+                                        eprintf("name exceeds buffer: %.*s\n", q-fname, fname);
1183+                                eread(tarfd, q, BLKSIZ);
1184+                        }
1185+
1186+                        /* Convert pax x header with 'path=' field into L header */
1187+                        if (h->type == 'x') for (q = fname; q < fname+size-16; q += n) {
1188+                                if ((n = strtol(q, &p, 10)) < 0 || *p != ' ')
1189+                                        eprintf("strtol %.*s: invalid number\n", p+1-q, q);
1190+                                if (n && strncmp(p+1, "path=", 5) == 0) {
1191+                                        memmove(fname, p+6, size = q+n - p-6 - 1);
1192+                                        h->type = 'L';
1193+                                        break;
1194+                                }
1195+                        }
1196+                        fname[size] = '\0';
1197+
1198+                        /* Non L-like header (eg. pax 'g') is skipped by setting q=null */
1199+                        if (h->type != 'L')
1200+                                q = NULL;
1201+                        continue;
1202+                }
1203+
1204+                /* Ustar path is copied into fname if no L header (ie: q is NULL) */
1205+                if (!q) {
1206+                        m = sizeof h->prefix, n = sizeof h->name;
1207+                        p = "/" + !h->prefix[0];
1208+                        snprintf(fname, sizeof fname, "%.*s%s%.*s", m, h->prefix, p, n, h->name);
1209+                }
1210+                q = NULL;
1211+
1212+                /* If argc > 0 or files_from_cnt > 0 then only extract the matching files/dirs */
1213+                if (argc || files_from_cnt) {
1214+                        match = 0;
1215+                        for (i = 0; i < argc; i++) {
1216+                                if (strncmp(argv[i], fname, n = strlen(argv[i])) == 0) {
1217+                                        if (strchr("/", fname[n]) || argv[i][n-1] == '/') {
1218+                                                match = 1;
1219+                                                break;
1220+                                        }
1221+                                }
1222+                        }
1223 #if FEATURE_TAR_FILES_FROM
1224-			if (!match) {
1225-				for (idx = 0; idx < files_from_cnt; idx++) {
1226-					if (strncmp(files_from[idx], fname, n = strlen(files_from[idx])) == 0) {
1227-						if (strchr("/", fname[n]) || files_from[idx][n-1] == '/') {
1228-							match = 1;
1229-							break;
1230-						}
1231-					}
1232-				}
1233-			}
1234+                        if (!match) {
1235+                                for (idx = 0; idx < files_from_cnt; idx++) {
1236+                                        if (strncmp(files_from[idx], fname, n = strlen(files_from[idx])) == 0) {
1237+                                                if (strchr("/", fname[n]) || files_from[idx][n-1] == '/') {
1238+                                                        match = 1;
1239+                                                        break;
1240+                                                }
1241+                                        }
1242+                                }
1243+                        }
1244 #endif
1245-			if (!match) {
1246-				skipblk(size);
1247-				continue;
1248-			}
1249-		}
1250+                        if (!match) {
1251+                                skipblk(size);
1252+                                continue;
1253+                        }
1254+                }
1255 
1256-		stripped = fname;
1257+                stripped = fname;
1258 #if FEATURE_TAR_STRIP_COMPONENTS
1259-		if (mode == 'x' && strip_components_count > 0) {
1260-			stripped = strip_components(fname, strip_components_count);
1261-			if (!stripped || *stripped == '\0') {
1262-				skipblk(size);
1263-				continue;
1264-			}
1265-		}
1266+                if (mode == 'x' && strip_components_count > 0) {
1267+                        stripped = strip_components(fname, strip_components_count);
1268+                        if (!stripped || *stripped == '\0') {
1269+                                skipblk(size);
1270+                                continue;
1271+                        }
1272+                }
1273 #endif
1274 
1275-		fn(stripped, size, b);
1276-		if (vflag && mode != 't')
1277-			safe_puts(fname);
1278-	}
1279-
1280-	if (mode == 'x' && !mflag) {
1281-		while ((dirtime = popdirtime())) {
1282-			times[0].tv_sec = times[1].tv_sec = dirtime->mtime;
1283-			times[0].tv_nsec = times[1].tv_nsec = 0;
1284-			if (utimensat(AT_FDCWD, dirtime->name, times, 0) < 0)
1285-				eprintf("utimensat %s:", fname);
1286-			free(dirtime->name);
1287-		}
1288-		free(dirtimes);
1289-		dirtimes = NULL;
1290-	}
1291+                fn(stripped, size, b);
1292+                if (vflag && mode != 't')
1293+                        safe_puts(fname);
1294+        }
1295+
1296+        if (mode == 'x' && !mflag) {
1297+                while ((dirtime = popdirtime())) {
1298+                        times[0].tv_sec = times[1].tv_sec = dirtime->mtime;
1299+                        times[0].tv_nsec = times[1].tv_nsec = 0;
1300+                        if (utimensat(AT_FDCWD, dirtime->name, times, 0) < 0)
1301+                                eprintf("utimensat %s:", fname);
1302+                        free(dirtime->name);
1303+                }
1304+                free(dirtimes);
1305+                dirtimes = NULL;
1306+        }
1307 }
1308 
1309 char **args;
1310@@ -790,13 +803,13 @@ static void
1311 usage(void)
1312 {
1313 #if FEATURE_TAR_CREATE
1314-	eprintf("usage: %s [x | t | -x | -t] [-C dir] [-J | -Z | -a | -j | -z] [-m] [-p] "
1315-	        "[-f file] [file ...]\n"
1316-	        "       %s [c | -c] [-C dir] [-J | -Z | -a | -j | -z] [-h] path ... "
1317-	        "[-f file]\n", argv0, argv0);
1318+        eprintf("usage: %s [x | t | -x | -t] [-C dir] [-J | -Z | -a | -j | -z] [-m] [-p] "
1319+                "[-f file] [file ...]\n"
1320+                "       %s [c | -c] [-C dir] [-J | -Z | -a | -j | -z] [-h] path ... "
1321+                "[-f file]\n", argv0, argv0);
1322 #else
1323-	eprintf("usage: %s [x | t | -x | -t] [-C dir] [-J | -Z | -a | -j | -z] [-m] [-p] "
1324-	        "[-f file] [file ...]\n", argv0);
1325+        eprintf("usage: %s [x | t | -x | -t] [-C dir] [-J | -Z | -a | -j | -z] [-m] [-p] "
1326+                "[-f file] [file ...]\n", argv0);
1327 #endif
1328 }
1329 
1330@@ -808,247 +821,247 @@ int
1331 main(int argc, char *argv[])
1332 {
1333 #if FEATURE_TAR_CREATE
1334-	struct recursor r = { .fn = c, .follow = 'P', .flags = DIRFIRST };
1335+        struct recursor r = { .fn = c, .follow = 'P', .flags = DIRFIRST };
1336 #endif
1337-	struct stat st;
1338-	char *file = NULL, *dir = ".", mode = '\0';
1339-	int fd;
1340-	size_t i;
1341+        struct stat st;
1342+        char *file = NULL, *dir = ".", mode = '\0';
1343+        int fd;
1344+        size_t i;
1345 
1346-	argv0 = argv[0];
1347+        argv0 = argv[0];
1348 #if FEATURE_TAR_CREATE
1349-	if (argc > 1 && strchr("cxt", mode = *argv[1]))
1350+        if (argc > 1 && strchr("cxt", mode = *argv[1]))
1351 #else
1352-	if (argc > 1 && strchr("xt", mode = *argv[1]))
1353+        if (argc > 1 && strchr("xt", mode = *argv[1]))
1354 #endif
1355-		*(argv[1]+1) ? *argv[1] = '-' : (*++argv = argv0, --argc);
1356+                *(argv[1]+1) ? *argv[1] = '-' : (*++argv = argv0, --argc);
1357 
1358-	ARGBEGIN {
1359-	// ?man -x: extract files from an archive
1360-	case 'x':
1361+        ARGBEGIN {
1362+        // ?man -x: extract files from an archive
1363+        case 'x':
1364 #if FEATURE_TAR_CREATE
1365-	// ?man -c: create a new archive
1366-	case 'c':
1367+        // ?man -c: create a new archive
1368+        case 'c':
1369 #endif
1370-	// ?man -t: list the contents of an archive
1371-	case 't':
1372-		mode = ARGC();
1373-		break;
1374-	// ?man -C:dir: specify option flag
1375-	case 'C':
1376-		dir = EARGF(usage());
1377-		break;
1378-	// ?man -f:file: specify archive file
1379-	case 'f':
1380-		file = EARGF(usage());
1381-		break;
1382-	// ?man -m: specify mode or limit
1383-	case 'm':
1384-		mflag = 1;
1385-		break;
1386-	// ?man -J: specify option flag
1387-	case 'J':
1388-	// ?man -Z: specify option flag
1389-	case 'Z':
1390-	// ?man -a: print or show all entries
1391-	case 'a':
1392-	// ?man -j: specify option flag
1393-	case 'j':
1394-	// ?man -z: specify option flag
1395-	case 'z':
1396-		filtermode = ARGC();
1397-		filtertool = filtertools[filtermode];
1398-		break;
1399-	// ?man -h: suppress headers or print help
1400-	case 'h':
1401+        // ?man -t: list the contents of an archive
1402+        case 't':
1403+                mode = ARGC();
1404+                break;
1405+        // ?man -C:dir: specify option flag
1406+        case 'C':
1407+                dir = EARGF(usage());
1408+                break;
1409+        // ?man -f:file: specify archive file
1410+        case 'f':
1411+                file = EARGF(usage());
1412+                break;
1413+        // ?man -m: specify mode or limit
1414+        case 'm':
1415+                mflag = 1;
1416+                break;
1417+        // ?man -J: specify option flag
1418+        case 'J':
1419+        // ?man -Z: specify option flag
1420+        case 'Z':
1421+        // ?man -a: print or show all entries
1422+        case 'a':
1423+        // ?man -j: specify option flag
1424+        case 'j':
1425+        // ?man -z: specify option flag
1426+        case 'z':
1427+                filtermode = ARGC();
1428+                filtertool = filtertools[filtermode];
1429+                break;
1430+        // ?man -h: suppress headers or print help
1431+        case 'h':
1432 #if FEATURE_TAR_CREATE
1433-		r.follow = 'L';
1434+                r.follow = 'L';
1435 #endif
1436-		break;
1437-	// ?man -v: verbosely list files processed
1438-	case 'v':
1439-		vflag = 1;
1440-		break;
1441-	// ?man -p: preserve file attributes
1442-	case 'p':
1443-		break;  /* do nothing as already default behaviour */
1444+                break;
1445+        // ?man -v: verbosely list files processed
1446+        case 'v':
1447+                vflag = 1;
1448+                break;
1449+        // ?man -p: preserve file attributes
1450+        case 'p':
1451+                break;  /* do nothing as already default behaviour */
1452 #if FEATURE_TAR_TO_STDOUT
1453-	// ?man -O: extract files to stdout
1454-	case 'O':
1455-		Oflag_stdout = 1;
1456-		break;
1457+        // ?man -O: extract files to stdout
1458+        case 'O':
1459+                Oflag_stdout = 1;
1460+                break;
1461 #endif
1462 #if FEATURE_TAR_KEEP_OLD
1463-	// ?man -k: keep existing files, do not overwrite
1464-	case 'k':
1465-		kflag_keep = 1;
1466-		break;
1467+        // ?man -k: keep existing files, do not overwrite
1468+        case 'k':
1469+                kflag_keep = 1;
1470+                break;
1471 #endif
1472 #if FEATURE_TAR_FILES_FROM
1473-	// ?man -T:file: -T file: read filenames from file
1474-	case 'T':
1475-		load_files_from_file(EARGF(usage()));
1476-		break;
1477+        // ?man -T:file: -T file: read filenames from file
1478+        case 'T':
1479+                load_files_from_file(EARGF(usage()));
1480+                break;
1481 #endif
1482 #if FEATURE_TAR_EXCLUDE_FROM
1483-	// ?man -X:file: -X file: exclude patterns in file
1484-	case 'X':
1485-		load_excludes_from_file(EARGF(usage()));
1486-		break;
1487+        // ?man -X:file: -X file: exclude patterns in file
1488+        case 'X':
1489+                load_excludes_from_file(EARGF(usage()));
1490+                break;
1491 #endif
1492 #if FEATURE_TAR_STRIP_COMPONENTS
1493-	// ?man -s:num: -strip-components num: strip num components
1494-	case 's':
1495-		if (strcmp(argv[0], "strip-components") == 0) {
1496-			argv[0] = "s";
1497-			strip_components_count = estrtonum(EARGF(usage()), 0, INT_MAX);
1498-			brk_ = 1;
1499-		} else if (strncmp(argv[0], "strip-components=", 17) == 0) {
1500-			strip_components_count = estrtonum(argv[0] + 17, 0, INT_MAX);
1501-			brk_ = 1;
1502-		} else {
1503-			usage();
1504-		}
1505-		break;
1506+        // ?man -s:num: -strip-components num: strip num components
1507+        case 's':
1508+                if (strcmp(argv[0], "strip-components") == 0) {
1509+                        argv[0] = "s";
1510+                        strip_components_count = estrtonum(EARGF(usage()), 0, INT_MAX);
1511+                        brk_ = 1;
1512+                } else if (strncmp(argv[0], "strip-components=", 17) == 0) {
1513+                        strip_components_count = estrtonum(argv[0] + 17, 0, INT_MAX);
1514+                        brk_ = 1;
1515+                } else {
1516+                        usage();
1517+                }
1518+                break;
1519 #endif
1520-	// ?man --:num: specify - option
1521-	case '-':
1522+        // ?man --:num: specify - option
1523+        case '-':
1524 #if FEATURE_TAR_EXCLUDE
1525-		if (strncmp(argv[0], "-exclude=", 9) == 0) {
1526-			add_exclude(argv[0] + 9);
1527-			brk_ = 1;
1528-			break;
1529-		} else if (strcmp(argv[0], "-exclude") == 0) {
1530-			argv[0] = "-";
1531-			add_exclude(EARGF(usage()));
1532-			brk_ = 1;
1533-			break;
1534-		}
1535+                if (strncmp(argv[0], "-exclude=", 9) == 0) {
1536+                        add_exclude(argv[0] + 9);
1537+                        brk_ = 1;
1538+                        break;
1539+                } else if (strcmp(argv[0], "-exclude") == 0) {
1540+                        argv[0] = "-";
1541+                        add_exclude(EARGF(usage()));
1542+                        brk_ = 1;
1543+                        break;
1544+                }
1545 #endif
1546 #if FEATURE_TAR_EXCLUDE_FROM
1547-		if (strncmp(argv[0], "-exclude-from=", 14) == 0) {
1548-			load_excludes_from_file(argv[0] + 14);
1549-			brk_ = 1;
1550-			break;
1551-		} else if (strcmp(argv[0], "-exclude-from") == 0) {
1552-			argv[0] = "-";
1553-			load_excludes_from_file(EARGF(usage()));
1554-			brk_ = 1;
1555-			break;
1556-		}
1557+                if (strncmp(argv[0], "-exclude-from=", 14) == 0) {
1558+                        load_excludes_from_file(argv[0] + 14);
1559+                        brk_ = 1;
1560+                        break;
1561+                } else if (strcmp(argv[0], "-exclude-from") == 0) {
1562+                        argv[0] = "-";
1563+                        load_excludes_from_file(EARGF(usage()));
1564+                        brk_ = 1;
1565+                        break;
1566+                }
1567 #endif
1568 #if FEATURE_TAR_TO_STDOUT
1569-		if (strcmp(argv[0], "-to-stdout") == 0) {
1570-			Oflag_stdout = 1;
1571-			brk_ = 1;
1572-			break;
1573-		}
1574+                if (strcmp(argv[0], "-to-stdout") == 0) {
1575+                        Oflag_stdout = 1;
1576+                        brk_ = 1;
1577+                        break;
1578+                }
1579 #endif
1580 #if FEATURE_TAR_KEEP_OLD
1581-		if (strcmp(argv[0], "-keep-old-files") == 0) {
1582-			kflag_keep = 1;
1583-			brk_ = 1;
1584-			break;
1585-		}
1586+                if (strcmp(argv[0], "-keep-old-files") == 0) {
1587+                        kflag_keep = 1;
1588+                        brk_ = 1;
1589+                        break;
1590+                }
1591 #endif
1592 #if FEATURE_TAR_STRIP_COMPONENTS
1593-		if (strncmp(argv[0], "-strip-components=", 18) == 0) {
1594-			strip_components_count = estrtonum(argv[0] + 18, 0, INT_MAX);
1595-			brk_ = 1;
1596-			break;
1597-		} else if (strcmp(argv[0], "-strip-components") == 0) {
1598-			argv[0] = "-";
1599-			strip_components_count = estrtonum(EARGF(usage()), 0, INT_MAX);
1600-			brk_ = 1;
1601-			break;
1602-		}
1603+                if (strncmp(argv[0], "-strip-components=", 18) == 0) {
1604+                        strip_components_count = estrtonum(argv[0] + 18, 0, INT_MAX);
1605+                        brk_ = 1;
1606+                        break;
1607+                } else if (strcmp(argv[0], "-strip-components") == 0) {
1608+                        argv[0] = "-";
1609+                        strip_components_count = estrtonum(EARGF(usage()), 0, INT_MAX);
1610+                        brk_ = 1;
1611+                        break;
1612+                }
1613 #endif
1614 #if FEATURE_TAR_FILES_FROM
1615-		if (strncmp(argv[0], "-files-from=", 12) == 0) {
1616-			load_files_from_file(argv[0] + 12);
1617-			brk_ = 1;
1618-			break;
1619-		} else if (strcmp(argv[0], "-files-from") == 0) {
1620-			argv[0] = "-";
1621-			load_files_from_file(EARGF(usage()));
1622-			brk_ = 1;
1623-			break;
1624-		}
1625+                if (strncmp(argv[0], "-files-from=", 12) == 0) {
1626+                        load_files_from_file(argv[0] + 12);
1627+                        brk_ = 1;
1628+                        break;
1629+                } else if (strcmp(argv[0], "-files-from") == 0) {
1630+                        argv[0] = "-";
1631+                        load_files_from_file(EARGF(usage()));
1632+                        brk_ = 1;
1633+                        break;
1634+                }
1635 #endif
1636-		usage();
1637-		break;
1638-	default:
1639-		usage();
1640-	} ARGEND
1641+                usage();
1642+                break;
1643+        default:
1644+                usage();
1645+        } ARGEND
1646 
1647-	switch (mode) {
1648+        switch (mode) {
1649 #if FEATURE_TAR_CREATE
1650-	// ?man -c: create a new archive
1651-	case 'c':
1652-		if (!argc && !files_from_cnt)
1653-			usage();
1654-		tarfd = 1;
1655-		if (file && *file != '-') {
1656-			tarfd = open(file, O_WRONLY | O_TRUNC | O_CREAT, 0644);
1657-			if (tarfd < 0)
1658-				eprintf("open %s:", file);
1659-			if (lstat(file, &st) < 0)
1660-				eprintf("lstat %s:", file);
1661-			tarinode = st.st_ino;
1662-			tardev = st.st_dev;
1663-		}
1664-
1665-		if (filtertool)
1666-			tarfd = comp(tarfd, filtertool, "-cf");
1667-
1668-		if (chdir(dir) < 0)
1669-			eprintf("chdir %s:", dir);
1670-		for (; *argv; argc--, argv++)
1671-			recurse(AT_FDCWD, *argv, NULL, &r);
1672+        // ?man -c: create a new archive
1673+        case 'c':
1674+                if (!argc && !files_from_cnt)
1675+                        usage();
1676+                tarfd = 1;
1677+                if (file && *file != '-') {
1678+                        tarfd = open(file, O_WRONLY | O_TRUNC | O_CREAT, 0644);
1679+                        if (tarfd < 0)
1680+                                eprintf("open %s:", file);
1681+                        if (lstat(file, &st) < 0)
1682+                                eprintf("lstat %s:", file);
1683+                        tarinode = st.st_ino;
1684+                        tardev = st.st_dev;
1685+                }
1686+
1687+                if (filtertool)
1688+                        tarfd = comp(tarfd, filtertool, "-cf");
1689+
1690+                if (chdir(dir) < 0)
1691+                        eprintf("chdir %s:", dir);
1692+                for (; *argv; argc--, argv++)
1693+                        recurse(AT_FDCWD, *argv, NULL, &r);
1694 #if FEATURE_TAR_FILES_FROM
1695-		for (i = 0; i < files_from_cnt; i++)
1696-			recurse(AT_FDCWD, files_from[i], NULL, &r);
1697+                for (i = 0; i < files_from_cnt; i++)
1698+                        recurse(AT_FDCWD, files_from[i], NULL, &r);
1699 #endif
1700-		break;
1701+                break;
1702 #endif
1703-	// ?man -t: list the contents of an archive
1704-	case 't':
1705-	// ?man -x: extract files from an archive
1706-	case 'x':
1707-		tarfd = 0;
1708-		if (file && *file != '-') {
1709-			tarfd = open(file, O_RDONLY);
1710-			if (tarfd < 0)
1711-				eprintf("open %s:", file);
1712-		}
1713-
1714-		if (filtertool) {
1715-			fd = tarfd;
1716-			tarfd = decomp(tarfd, filtertool, "-cdf");
1717-			close(fd);
1718-		}
1719-
1720-		if (chdir(dir) < 0)
1721-			eprintf("chdir %s:", dir);
1722-		xt(argc, argv, mode);
1723-		break;
1724-	default:
1725-		usage();
1726-	}
1727+        // ?man -t: list the contents of an archive
1728+        case 't':
1729+        // ?man -x: extract files from an archive
1730+        case 'x':
1731+                tarfd = 0;
1732+                if (file && *file != '-') {
1733+                        tarfd = open(file, O_RDONLY);
1734+                        if (tarfd < 0)
1735+                                eprintf("open %s:", file);
1736+                }
1737+
1738+                if (filtertool) {
1739+                        fd = tarfd;
1740+                        tarfd = decomp(tarfd, filtertool, "-cdf");
1741+                        close(fd);
1742+                }
1743+
1744+                if (chdir(dir) < 0)
1745+                        eprintf("chdir %s:", dir);
1746+                xt(argc, argv, mode);
1747+                break;
1748+        default:
1749+                usage();
1750+        }
1751 
1752 #if FEATURE_TAR_EXCLUDE
1753-	if (excludes) {
1754-		for (i = 0; i < excludes_cnt; i++)
1755-			free(excludes[i]);
1756-		free(excludes);
1757-	}
1758+        if (excludes) {
1759+                for (i = 0; i < excludes_cnt; i++)
1760+                        free(excludes[i]);
1761+                free(excludes);
1762+        }
1763 #endif
1764 #if FEATURE_TAR_FILES_FROM
1765-	if (files_from) {
1766-		for (i = 0; i < files_from_cnt; i++)
1767-			free(files_from[i]);
1768-		free(files_from);
1769-	}
1770+        if (files_from) {
1771+                for (i = 0; i < files_from_cnt; i++)
1772+                        free(files_from[i]);
1773+                free(files_from);
1774+        }
1775 #endif
1776-	return recurse_status;
1777+        return recurse_status;
1778 }
+2, -1
 1@@ -6,6 +6,7 @@
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 
 5+#include "wexec.h"
 6 #include "util.h"
 7 
 8 static void
 9@@ -58,7 +59,7 @@ main(int argc, char *argv[])
10 	for (;;) {
11 		printf("\x1b[2J\x1b[H"); /* clear */
12 		fflush(NULL);
13-		system(cmd);
14+		wsystem(cmd);
15 		usleep(interval);
16 	}
17 	return 0;
+13, -14
 1@@ -1,13 +1,7 @@
 2 /* See LICENSE file for copyright and license details. */
 3-
 4-
 5 #include <sys/stat.h>
 6 #include <sys/types.h>
 7-#ifndef makedev
 8-#include <sys/sysmacros.h>
 9-#endif
10 
11-#include <fcntl.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15@@ -15,17 +9,21 @@
16 
17 #include "util.h"
18 
19+#ifndef makedev
20+#include <sys/sysmacros.h>
21+#endif
22+
23 static void
24 usage(void)
25 {
26 	eprintf("usage: %s [-m mode] name b|c|u major minor\n"
27-	        "       %s [-m mode] name p\n",
28-	        argv0, argv0);
29+		"       %s [-m mode] name p\n",
30+		argv0, argv0);
31 }
32 
33 // ?man mknod: create special files
34-// ?man arguments: name b|c|u major minor
35-// ?man create block or character special files
36+// ?man arguments: name type [major minor]
37+// ?man create a block special, character special, or fifo file
38 int
39 main(int argc, char *argv[])
40 {
41@@ -33,13 +31,13 @@ main(int argc, char *argv[])
42 	dev_t dev;
43 
44 	ARGBEGIN {
45-// ?man -m:mode: specify mode or limit
46-case 'm':
47+	case 'm':
48+		// ?man -m:mode: set the file mode bits of the created node
49 		mode = parsemode(EARGF(usage()), mode, umask(0));
50 		break;
51 	default:
52 		usage();
53-	} ARGEND;
54+	} ARGEND
55 
56 	if (argc < 2)
57 		usage();
58@@ -69,7 +67,8 @@ case 'm':
59 	} else {
60 		if (argc != 4)
61 			usage();
62-		dev = makedev(estrtonum(argv[2], 0, LLONG_MAX), estrtonum(argv[3], 0, LLONG_MAX));
63+		dev = makedev(estrtonum(argv[2], 0, LLONG_MAX),
64+		              estrtonum(argv[3], 0, LLONG_MAX));
65 	}
66 
67 	if (mknod(argv[0], mode, dev) == -1)
+51, -228
  1@@ -1,185 +1,43 @@
  2 /* See LICENSE file for copyright and license details. */
  3-
  4-
  5-#include <sys/ioctl.h>
  6-#include <sys/stat.h>
  7-#include <sys/types.h>
  8-#include <sys/syscall.h>
  9+#include "config.h"
 10+#include "passwd.h"
 11+#include "text.h"
 12+#include "util.h"
 13 
 14 #include <errno.h>
 15-#include <fcntl.h>
 16-#include <limits.h>
 17 #include <pwd.h>
 18-#include <shadow.h>
 19-#include <stdint.h>
 20 #include <stdio.h>
 21 #include <stdlib.h>
 22 #include <string.h>
 23+#include <sys/stat.h>
 24 #include <unistd.h>
 25 
 26-#include "config.h"
 27-#include "passwd.h"
 28-#include "text.h"
 29-#include "util.h"
 30-
 31-static FILE *
 32-spw_get_file(const char *user)
 33-{
 34-	FILE *fp = NULL;
 35-	char file[PATH_MAX];
 36-	int r;
 37-
 38-	r = snprintf(file, sizeof(file), "/etc/tcb/%s/shadow", user);
 39-	if (r < 0 || (size_t)r >= sizeof(file))
 40-		eprintf("snprintf:");
 41-	fp = fopen(file, "r+");
 42-	if (!fp)
 43-		fp = fopen("/etc/shadow", "r+");
 44-	return fp;
 45-}
 46-
 47-static int
 48-spw_write_file(FILE *fp, const struct spwd *spw, char *pwhash)
 49-{
 50-	struct spwd *spwent;
 51-	int r = -1, w = 0;
 52-	FILE *tfp = NULL;
 53-
 54-	/* write to temporary file. */
 55-	tfp = tmpfile();
 56-	if (!tfp) {
 57-		weprintf("tmpfile:");
 58-		goto cleanup;
 59-	}
 60-	while ((spwent = fgetspent(fp))) {
 61-		/* update entry on name match */
 62-		if (strcmp(spwent->sp_namp, spw->sp_namp) == 0) {
 63-			spwent->sp_pwdp = pwhash;
 64-			w++;
 65-		}
 66-		errno = 0;
 67-		if (putspent(spwent, tfp) == -1) {
 68-			weprintf("putspent:");
 69-			goto cleanup;
 70-		}
 71-	}
 72-	if (!w) {
 73-		weprintf("shadow: no matching entry to write to\n");
 74-		goto cleanup;
 75-	}
 76-	fflush(tfp);
 77-
 78-	if (fseek(fp, 0, SEEK_SET) == -1 || fseek(tfp, 0, SEEK_SET) == -1) {
 79-		weprintf("fseek:");
 80-		goto cleanup;
 81-	}
 82-
 83-	/* write temporary file to (tcb) shadow file */
 84-	fconcat(tfp, "tmpfile", fp, "shadow");
 85-	ftruncate(fileno(fp), ftell(tfp));
 86-
 87-	r = 0; /* success */
 88-cleanup:
 89-	if (tfp)
 90-		fclose(tfp);
 91-	return r;
 92-}
 93-
 94-static int
 95-pw_write_file(FILE *fp, const struct passwd *pw, char *pwhash) {
 96-	struct passwd *pwent;
 97-	int r = -1, w = 0;
 98-	FILE *tfp = NULL;
 99-
100-	/* write to temporary file. */
101-	tfp = tmpfile();
102-	if (!tfp) {
103-		weprintf("tmpfile:");
104-		goto cleanup;
105-	}
106-	while ((pwent = fgetpwent(fp))) {
107-		/* update entry on name match */
108-		if (strcmp(pwent->pw_name, pw->pw_name) == 0) {
109-			pwent->pw_passwd = pwhash;
110-			w++;
111-		}
112-		errno = 0;
113-		if (putpwent(pwent, tfp) == -1) {
114-			weprintf("putpwent:");
115-			goto cleanup;
116-		}
117-	}
118-	if (!w) {
119-		weprintf("passwd: no matching entry to write to\n");
120-		goto cleanup;
121-	}
122-	fflush(tfp);
123-
124-	if (fseek(fp, 0, SEEK_SET) == -1 || fseek(tfp, 0, SEEK_SET) == -1) {
125-		weprintf("fseek:");
126-		goto cleanup;
127-	}
128-
129-	/* write to passwd file. */
130-	fconcat(tfp, "tmpfile", fp, "passwd");
131-	ftruncate(fileno(fp), ftell(tfp));
132-
133-	r = 0; /* success */
134-cleanup:
135-	if (tfp)
136-		fclose(tfp);
137-	return r;
138-}
139-
140-/* generates a random base64-encoded salt string of length 16 */
141-static void
142-gensalt(char *s)
143-{
144-	static const char b64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
145-	uint8_t buf[12];
146-	uint32_t n;
147-	int i;
148-
149-	if (syscall(SYS_getrandom, buf, sizeof(buf), 0) < 0)
150-		eprintf("getrandom:");
151-	for (i = 0; i < 12; i += 3) {
152-		n = buf[i] << 16 | buf[i+1] << 8 | buf[i+2];
153-		*s++ = b64[n%64]; n /= 64;
154-		*s++ = b64[n%64]; n /= 64;
155-		*s++ = b64[n%64]; n /= 64;
156-		*s++ = b64[n];
157-	}
158-	*s++ = '\0';
159-}
160-
161 static void
162 usage(void)
163 {
164 	eprintf("usage: %s [username]\n", argv0);
165 }
166 
167-// ?man passwd: change user password
168-// ?man arguments: username
169-// ?man update a user authentication password
170+// ?man passwd: change a user password
171+// ?man arguments: [username]
172+// ?man change the password associated with the calling user or with username
173 int
174 main(int argc, char *argv[])
175 {
176-	char *cryptpass1 = NULL, *cryptpass2 = NULL, *cryptpass3 = NULL;
177-	char *inpass, *p, *prevhash = NULL, salt[sizeof(PW_CIPHER) + 16] = PW_CIPHER;
178+	struct pwdb_entry ent;
179 	struct passwd *pw;
180-	struct spwd *spw = NULL;
181-	FILE *fp = NULL;
182-	int r = -1, status = 1;
183+	char *inpass, *prevhash = NULL, *newhash = NULL, salt[PW_SALT_MAX];
184+	char *c1, *c2;
185+	int status = 1;
186 
187 	ARGBEGIN {
188 	default:
189 		usage();
190-	} ARGEND;
191+	} ARGEND
192 
193 	pw_init();
194 	umask(077);
195 
196-	errno = 0;
197 	if (argc == 0)
198 		pw = getpwuid(getuid());
199 	else
200@@ -191,103 +49,68 @@ main(int argc, char *argv[])
201 			eprintf("who are you?\n");
202 	}
203 
204-	/* is using shadow entry ? */
205-	if (pw->pw_passwd[0] == 'x' && pw->pw_passwd[1] == '\0') {
206-		errno = 0;
207-		spw = getspnam(pw->pw_name);
208-		if (!spw) {
209-			if (errno)
210-				eprintf("getspnam: %s:", pw->pw_name);
211-			else
212-				eprintf("who are you?\n");
213-		}
214-	}
215+	if (pwdb_lookup(&ent, pw->pw_name) < 0)
216+		return 1;
217+	prevhash = ent.hash;
218 
219-	/* Flush pending input */
220-	ioctl(0, TCFLSH, (void *)0);
221-
222-	if (getuid() == 0) {
223-		goto newpass;
224-	} else {
225-		if (pw->pw_passwd[0] == '!' ||
226-		    pw->pw_passwd[0] == '*')
227+	if (getuid() != 0) {
228+		if (prevhash[0] == '!' || prevhash[0] == '*')
229 			eprintf("denied\n");
230-		if (pw->pw_passwd[0] == '\0') {
231-			goto newpass;
232+		if (prevhash[0] == '\0') {
233+			/* no password set */
234+		} else {
235+			printf("Changing password for %s\n", pw->pw_name);
236+			inpass = getpass("Old password: ");
237+			if (!inpass)
238+				eprintf("getpass:");
239+			if (inpass[0] == '\0')
240+				eprintf("no password supplied\n");
241+			c1 = crypt(inpass, prevhash);
242+			if (!c1)
243+				eprintf("crypt:");
244+			if (strcmp(c1, prevhash) != 0)
245+				eprintf("incorrect password\n");
246+			explicit_bzero(inpass, strlen(inpass));
247 		}
248-		if (pw->pw_passwd[0] == 'x' &&
249-		    pw->pw_passwd[1] == '\0')
250-			prevhash = spw->sp_pwdp;
251-		else
252-			prevhash = pw->pw_passwd;
253 	}
254 
255-	printf("Changing password for %s\n", pw->pw_name);
256-	inpass = getpass("Old password: ");
257-	if (!inpass)
258-		eprintf("getpass:");
259-	if (inpass[0] == '\0')
260-		eprintf("no password supplied\n");
261-	p = crypt(inpass, prevhash);
262-	if (!p)
263-		eprintf("crypt:");
264-	cryptpass1 = estrdup(p);
265-	if (strcmp(cryptpass1, prevhash) != 0)
266-		eprintf("incorrect password\n");
267-
268-newpass:
269 	inpass = getpass("Enter new password: ");
270 	if (!inpass)
271 		eprintf("getpass:");
272 	if (inpass[0] == '\0')
273 		eprintf("no password supplied\n");
274 
275-	if(prevhash) {
276-		p = crypt(inpass, prevhash);
277-		if (!p)
278-			eprintf("crypt:");
279-		if (cryptpass1 && strcmp(cryptpass1, p) == 0)
280+	if (prevhash && prevhash[0] != '\0') {
281+		c1 = crypt(inpass, prevhash);
282+		if (c1 && strcmp(c1, prevhash) == 0)
283 			eprintf("password left unchanged\n");
284 	}
285-	gensalt(salt + strlen(salt));
286-	p = crypt(inpass, salt);
287-	if (!p)
288-		eprintf("crypt:");
289-	cryptpass2 = estrdup(p);
290 
291-	/* Flush pending input */
292-	ioctl(0, TCFLSH, (void *)0);
293+	if (pw_gensalt(salt, sizeof(salt)) < 0)
294+		eprintf("pw_gensalt:");
295+	c1 = crypt(inpass, salt);
296+	if (!c1)
297+		eprintf("crypt:");
298+	newhash = estrdup(c1);
299+	explicit_bzero(inpass, strlen(inpass));
300 
301 	inpass = getpass("Retype new password: ");
302 	if (!inpass)
303 		eprintf("getpass:");
304 	if (inpass[0] == '\0')
305 		eprintf("no password supplied\n");
306-	p = crypt(inpass, salt);
307-	if (!p)
308+	c2 = crypt(inpass, salt);
309+	if (!c2)
310 		eprintf("crypt:");
311-	cryptpass3 = estrdup(p);
312-	if (strcmp(cryptpass2, cryptpass3) != 0)
313+	if (strcmp(c2, newhash) != 0)
314 		eprintf("passwords don't match\n");
315+	explicit_bzero(inpass, strlen(inpass));
316 
317-	fp = spw_get_file(pw->pw_name);
318-	if (fp) {
319-		r = spw_write_file(fp, spw, cryptpass3);
320-	} else {
321-		fp = fopen("/etc/passwd", "r+");
322-		if (fp)
323-			r = pw_write_file(fp, pw, cryptpass3);
324-		else
325-			weprintf("fopen:");
326-	}
327-	if (!r)
328+	if (pwdb_update(pw->pw_name, newhash) == 0)
329 		status = 0;
330 
331-	if (fp)
332-		fclose(fp);
333-	free(cryptpass3);
334-	free(cryptpass2);
335-	free(cryptpass1);
336-
337+	free(newhash);
338+	free(ent.name);
339+	free(ent.hash);
340 	return status;
341 }
+18, -14
 1@@ -1,7 +1,7 @@
 2 /* See LICENSE file for copyright and license details. */
 3-
 4-
 5-#include <sys/types.h>
 6+#include "config.h"
 7+#include "passwd.h"
 8+#include "util.h"
 9 
10 #include <errno.h>
11 #include <grp.h>
12@@ -9,13 +9,15 @@
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16+#include <sys/types.h>
17 #include <unistd.h>
18 
19-#include "passwd.h"
20-#include "util.h"
21-
22 extern char **environ;
23 
24+#ifndef ENV_PATH_SHELL
25+#define ENV_PATH_SHELL "/bin/sh"
26+#endif
27+
28 static int lflag = 0;
29 static int pflag = 0;
30 
31@@ -25,9 +27,9 @@ usage(void)
32 	eprintf("usage: %s [-lp] [username]\n", argv0);
33 }
34 
35-// ?man su: run command with substitute user id
36-// ?man arguments: username
37-// ?man run a shell or command with another user id
38+// ?man su: run a command with substitute user and group id
39+// ?man arguments: [username]
40+// ?man run a shell or command as the named user. defaults to root
41 int
42 main(int argc, char *argv[])
43 {
44@@ -38,17 +40,17 @@ main(int argc, char *argv[])
45 	uid_t uid;
46 
47 	ARGBEGIN {
48-	// ?man -l: list in long format
49 	case 'l':
50+		// ?man -l: make the shell a login shell
51 		lflag = 1;
52 		break;
53-	// ?man -p: preserve file attributes
54 	case 'p':
55+		// ?man -p: preserve the current environment
56 		pflag = 1;
57 		break;
58 	default:
59 		usage();
60-	} ARGEND;
61+	} ARGEND
62 
63 	if (argc > 1)
64 		usage();
65@@ -70,6 +72,7 @@ main(int argc, char *argv[])
66 			eprintf("getpass:");
67 		if (pw_check(pw, pass) <= 0)
68 			exit(1);
69+		explicit_bzero(pass, strlen(pass));
70 	}
71 
72 	if (initgroups(usr, pw->pw_gid) < 0)
73@@ -79,7 +82,7 @@ main(int argc, char *argv[])
74 	if (setuid(pw->pw_uid) < 0)
75 		eprintf("setuid:");
76 
77-	shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell;
78+	shell = pw->pw_shell[0] == '\0' ? ENV_PATH_SHELL : pw->pw_shell;
79 	if (lflag) {
80 		term = getenv("TERM");
81 		clearenv();
82@@ -87,7 +90,8 @@ main(int argc, char *argv[])
83 		setenv("SHELL", shell, 1);
84 		setenv("USER", pw->pw_name, 1);
85 		setenv("LOGNAME", pw->pw_name, 1);
86-		setenv("TERM", term ? term : "linux", 1);
87+		setenv("TERM", term ? term : "dumb", 1);
88+		setenv("PATH", ENV_PATH, 1);
89 		if (chdir(pw->pw_dir) < 0)
90 			eprintf("chdir %s:", pw->pw_dir);
91 		newargv[0] = shell;
+84, -62
  1@@ -232,6 +232,17 @@ FEATURE_SH_WORDEXP      = 1
  2 FEATURE_CAL_EXT         = 1
  3 FEATURE_SED_PRESERVE_NEWLINE = 1
  4 FEATURE_LS_COLOR             = 1
  5+FEATURE_DIFF3_MERGE          = 1
  6+FEATURE_DIFF3_EDSCRIPT       = 1
  7+FEATURE_DIFF_CONTEXT         = 1
  8+FEATURE_DIFF_UNIFIED         = 1
  9+FEATURE_DIFF_ED              = 1
 10+FEATURE_DIFF_BRIEF           = 1
 11+FEATURE_DIFF_SIDEBYSIDE      = 1
 12+FEATURE_PATCH_BACKUP         = 1
 13+FEATURE_PATCH_FUZZ           = 1
 14+FEATURE_PATCH_STRIP_CR       = 1
 15+FEATURE_INPROC_EXEC          = 0
 16 FEATURE_MODPROBE_SHOW_DEPENDS = 1
 17 FEATURE_MODPROBE_BLACKLIST   = 1
 18 FEATURE_MODPROBE_SYSLOG      = 1
 19@@ -255,68 +266,79 @@ FEATURE_IP_LINK_SET = 1
 20 FEATURE_IP_ADDR_FLUSH = 1
 21 
 22 CPPFLAGS =\
 23-	-Ishared\
 24-	-DPREFIX=\"\$(PREFIX)\"\
 25-	-D_DEFAULT_SOURCE\
 26-	-D_GNU_SOURCE\
 27-	-D_NETBSD_SOURCE\
 28-	-D_BSD_SOURCE\
 29-	-D_XOPEN_SOURCE=700\
 30-	-D_FILE_OFFSET_BITS=64\
 31-	-DFEATURE_FIND_DELETE=$(FEATURE_FIND_DELETE)\
 32-	-DFEATURE_FIND_QUIT=$(FEATURE_FIND_QUIT)\
 33-	-DFEATURE_FIND_EMPTY=$(FEATURE_FIND_EMPTY)\
 34-	-DFEATURE_FIND_INUM=$(FEATURE_FIND_INUM)\
 35-	-DFEATURE_FIND_SAMEFILE=$(FEATURE_FIND_SAMEFILE)\
 36-	-DFEATURE_FIND_MAXDEPTH=$(FEATURE_FIND_MAXDEPTH)\
 37-	-DFEATURE_FIND_MINDEPTH=$(FEATURE_FIND_MINDEPTH)\
 38-	-DFEATURE_FIND_MMIN=$(FEATURE_FIND_MMIN)\
 39-	-DFEATURE_FIND_AMIN=$(FEATURE_FIND_AMIN)\
 40-	-DFEATURE_FIND_CMIN=$(FEATURE_FIND_CMIN)\
 41-	-DFEATURE_FIND_INAME=$(FEATURE_FIND_INAME)\
 42-	-DFEATURE_FIND_IPATH=$(FEATURE_FIND_IPATH)\
 43-	-DFEATURE_FIND_REGEX=$(FEATURE_FIND_REGEX)\
 44-	-DFEATURE_FIND_PRINT0=$(FEATURE_FIND_PRINT0)\
 45-	-DFEATURE_SED_INPLACE=$(FEATURE_SED_INPLACE)\
 46-	-DFEATURE_GREP_CONTEXT=$(FEATURE_GREP_CONTEXT)\
 47-	-DFEATURE_GREP_MAX_COUNT=$(FEATURE_GREP_MAX_COUNT)\
 48-	-DFEATURE_TAR_CREATE=$(FEATURE_TAR_CREATE)\
 49-	-DFEATURE_TAR_EXCLUDE=$(FEATURE_TAR_EXCLUDE)\
 50-	-DFEATURE_STAT_FILESYSTEM=$(FEATURE_STAT_FILESYSTEM)\
 51-	-DFEATURE_STAT_FORMAT=$(FEATURE_STAT_FORMAT)\
 52-	-DFEATURE_SORT_BIG=$(FEATURE_SORT_BIG)\
 53-	-DFEATURE_SORT_STABLE=$(FEATURE_SORT_STABLE)\
 54-	-DFEATURE_OD_ENDIAN=$(FEATURE_OD_ENDIAN)\
 55-	-DFEATURE_SH_HISTEDIT=$(FEATURE_SH_HISTEDIT)\
 56-	-DFEATURE_SH_LOCAL=$(FEATURE_SH_LOCAL)\
 57-	-DFEATURE_SH_LET=$(FEATURE_SH_LET)\
 58-	-DFEATURE_SH_ULIMIT=$(FEATURE_SH_ULIMIT)\
 59-	-DFEATURE_SH_SETVAR=$(FEATURE_SH_SETVAR)\
 60-	-DFEATURE_SH_WORDEXP=$(FEATURE_SH_WORDEXP)\
 61-	-DFEATURE_CAL_EXT=$(FEATURE_CAL_EXT)\
 62-	-DFEATURE_SED_PRESERVE_NEWLINE=$(FEATURE_SED_PRESERVE_NEWLINE)\
 63-	-DFEATURE_LS_COLOR=$(FEATURE_LS_COLOR)\
 64-	-DFEATURE_MODPROBE_SHOW_DEPENDS=$(FEATURE_MODPROBE_SHOW_DEPENDS)\
 65-	-DFEATURE_MODPROBE_BLACKLIST=$(FEATURE_MODPROBE_BLACKLIST)\
 66-	-DFEATURE_MODPROBE_SYSLOG=$(FEATURE_MODPROBE_SYSLOG)\
 67-	-DFEATURE_MODPROBE_DIR_OVERRIDE=$(FEATURE_MODPROBE_DIR_OVERRIDE)\
 68-	-DFEATURE_DEPMOD_ALIAS=$(FEATURE_DEPMOD_ALIAS)\
 69-	-DFEATURE_DEPMOD_SYMBOLS=$(FEATURE_DEPMOD_SYMBOLS)\
 70-	-DFEATURE_USE_LIBRESSL=$(FEATURE_USE_LIBRESSL)\
 71-	-DFEATURE_USE_BEARSSL=$(FEATURE_USE_BEARSSL)\
 72-	-DFEATURE_USE_OPENSSL=$(FEATURE_USE_OPENSSL)\
 73-	-DFEATURE_TAR_TTY_SAFE=$(FEATURE_TAR_TTY_SAFE)\
 74-	-DFEATURE_TAR_NOFOLLOW=$(FEATURE_TAR_NOFOLLOW)\
 75-	-DFEATURE_READLINK_REALPATH=$(FEATURE_READLINK_REALPATH)\
 76-	-DFEATURE_UMOUNT_OPTIONS=$(FEATURE_UMOUNT_OPTIONS)\
 77-	-DFEATURE_TAR_TO_STDOUT=$(FEATURE_TAR_TO_STDOUT)\
 78-	-DFEATURE_TAR_KEEP_OLD=$(FEATURE_TAR_KEEP_OLD)\
 79-	-DFEATURE_TAR_STRIP_COMPONENTS=$(FEATURE_TAR_STRIP_COMPONENTS)\
 80-	-DFEATURE_TAR_FILES_FROM=$(FEATURE_TAR_FILES_FROM)\
 81-	-DFEATURE_TAR_EXCLUDE_FROM=$(FEATURE_TAR_EXCLUDE_FROM)\
 82-	-DFEATURE_IP_ROUTE_ADD_DEL=$(FEATURE_IP_ROUTE_ADD_DEL)\
 83-	-DFEATURE_IP_LINK_SET=$(FEATURE_IP_LINK_SET)\
 84-	-DFEATURE_IP_ADDR_FLUSH=$(FEATURE_IP_ADDR_FLUSH) $(CPPFLAGS_TLS)
 85+        -Ishared\
 86+        -DPREFIX=\"\$(PREFIX)\"\
 87+        -D_DEFAULT_SOURCE\
 88+        -D_GNU_SOURCE\
 89+        -D_NETBSD_SOURCE\
 90+        -D_BSD_SOURCE\
 91+        -D_XOPEN_SOURCE=700\
 92+        -D_FILE_OFFSET_BITS=64\
 93+        -DFEATURE_FIND_DELETE=$(FEATURE_FIND_DELETE)\
 94+        -DFEATURE_FIND_QUIT=$(FEATURE_FIND_QUIT)\
 95+        -DFEATURE_FIND_EMPTY=$(FEATURE_FIND_EMPTY)\
 96+        -DFEATURE_FIND_INUM=$(FEATURE_FIND_INUM)\
 97+        -DFEATURE_FIND_SAMEFILE=$(FEATURE_FIND_SAMEFILE)\
 98+        -DFEATURE_FIND_MAXDEPTH=$(FEATURE_FIND_MAXDEPTH)\
 99+        -DFEATURE_FIND_MINDEPTH=$(FEATURE_FIND_MINDEPTH)\
100+        -DFEATURE_FIND_MMIN=$(FEATURE_FIND_MMIN)\
101+        -DFEATURE_FIND_AMIN=$(FEATURE_FIND_AMIN)\
102+        -DFEATURE_FIND_CMIN=$(FEATURE_FIND_CMIN)\
103+        -DFEATURE_FIND_INAME=$(FEATURE_FIND_INAME)\
104+        -DFEATURE_FIND_IPATH=$(FEATURE_FIND_IPATH)\
105+        -DFEATURE_FIND_REGEX=$(FEATURE_FIND_REGEX)\
106+        -DFEATURE_FIND_PRINT0=$(FEATURE_FIND_PRINT0)\
107+        -DFEATURE_SED_INPLACE=$(FEATURE_SED_INPLACE)\
108+        -DFEATURE_GREP_CONTEXT=$(FEATURE_GREP_CONTEXT)\
109+        -DFEATURE_GREP_MAX_COUNT=$(FEATURE_GREP_MAX_COUNT)\
110+        -DFEATURE_TAR_CREATE=$(FEATURE_TAR_CREATE)\
111+        -DFEATURE_TAR_EXCLUDE=$(FEATURE_TAR_EXCLUDE)\
112+        -DFEATURE_STAT_FILESYSTEM=$(FEATURE_STAT_FILESYSTEM)\
113+        -DFEATURE_STAT_FORMAT=$(FEATURE_STAT_FORMAT)\
114+        -DFEATURE_SORT_BIG=$(FEATURE_SORT_BIG)\
115+        -DFEATURE_SORT_STABLE=$(FEATURE_SORT_STABLE)\
116+        -DFEATURE_OD_ENDIAN=$(FEATURE_OD_ENDIAN)\
117+        -DFEATURE_SH_HISTEDIT=$(FEATURE_SH_HISTEDIT)\
118+        -DFEATURE_SH_LOCAL=$(FEATURE_SH_LOCAL)\
119+        -DFEATURE_SH_LET=$(FEATURE_SH_LET)\
120+        -DFEATURE_SH_ULIMIT=$(FEATURE_SH_ULIMIT)\
121+        -DFEATURE_SH_SETVAR=$(FEATURE_SH_SETVAR)\
122+        -DFEATURE_SH_WORDEXP=$(FEATURE_SH_WORDEXP)\
123+        -DFEATURE_CAL_EXT=$(FEATURE_CAL_EXT)\
124+        -DFEATURE_SED_PRESERVE_NEWLINE=$(FEATURE_SED_PRESERVE_NEWLINE)\
125+        -DFEATURE_LS_COLOR=$(FEATURE_LS_COLOR)\
126+        -DFEATURE_DIFF3_MERGE=$(FEATURE_DIFF3_MERGE)\
127+        -DFEATURE_DIFF3_EDSCRIPT=$(FEATURE_DIFF3_EDSCRIPT)\
128+        -DFEATURE_DIFF_CONTEXT=$(FEATURE_DIFF_CONTEXT)\
129+        -DFEATURE_DIFF_UNIFIED=$(FEATURE_DIFF_UNIFIED)\
130+        -DFEATURE_DIFF_ED=$(FEATURE_DIFF_ED)\
131+        -DFEATURE_DIFF_BRIEF=$(FEATURE_DIFF_BRIEF)\
132+        -DFEATURE_DIFF_SIDEBYSIDE=$(FEATURE_DIFF_SIDEBYSIDE)\
133+        -DFEATURE_PATCH_BACKUP=$(FEATURE_PATCH_BACKUP)\
134+        -DFEATURE_PATCH_FUZZ=$(FEATURE_PATCH_FUZZ)\
135+        -DFEATURE_PATCH_STRIP_CR=$(FEATURE_PATCH_STRIP_CR)\
136+        -DFEATURE_INPROC_EXEC=$(FEATURE_INPROC_EXEC)\
137+        -DFEATURE_MODPROBE_SHOW_DEPENDS=$(FEATURE_MODPROBE_SHOW_DEPENDS)\
138+        -DFEATURE_MODPROBE_BLACKLIST=$(FEATURE_MODPROBE_BLACKLIST)\
139+        -DFEATURE_MODPROBE_SYSLOG=$(FEATURE_MODPROBE_SYSLOG)\
140+        -DFEATURE_MODPROBE_DIR_OVERRIDE=$(FEATURE_MODPROBE_DIR_OVERRIDE)\
141+        -DFEATURE_DEPMOD_ALIAS=$(FEATURE_DEPMOD_ALIAS)\
142+        -DFEATURE_DEPMOD_SYMBOLS=$(FEATURE_DEPMOD_SYMBOLS)\
143+        -DFEATURE_USE_LIBRESSL=$(FEATURE_USE_LIBRESSL)\
144+        -DFEATURE_USE_BEARSSL=$(FEATURE_USE_BEARSSL)\
145+        -DFEATURE_USE_OPENSSL=$(FEATURE_USE_OPENSSL)\
146+        -DFEATURE_TAR_TTY_SAFE=$(FEATURE_TAR_TTY_SAFE)\
147+        -DFEATURE_TAR_NOFOLLOW=$(FEATURE_TAR_NOFOLLOW)\
148+        -DFEATURE_READLINK_REALPATH=$(FEATURE_READLINK_REALPATH)\
149+        -DFEATURE_UMOUNT_OPTIONS=$(FEATURE_UMOUNT_OPTIONS)\
150+        -DFEATURE_TAR_TO_STDOUT=$(FEATURE_TAR_TO_STDOUT)\
151+        -DFEATURE_TAR_KEEP_OLD=$(FEATURE_TAR_KEEP_OLD)\
152+        -DFEATURE_TAR_STRIP_COMPONENTS=$(FEATURE_TAR_STRIP_COMPONENTS)\
153+        -DFEATURE_TAR_FILES_FROM=$(FEATURE_TAR_FILES_FROM)\
154+        -DFEATURE_TAR_EXCLUDE_FROM=$(FEATURE_TAR_EXCLUDE_FROM)\
155+        -DFEATURE_IP_ROUTE_ADD_DEL=$(FEATURE_IP_ROUTE_ADD_DEL)\
156+        -DFEATURE_IP_LINK_SET=$(FEATURE_IP_LINK_SET)\
157+        -DFEATURE_IP_ADDR_FLUSH=$(FEATURE_IP_ADDR_FLUSH) $(CPPFLAGS_TLS)
158 
159 CC       = cc
160 CFLAGS   =
+985, -1267
   1@@ -1,75 +1,71 @@
   2 
   3 #AUTOGENERATED
   4-cmd/extra/b3sum.o: cmd/extra/b3sum.c
   5-cmd/extra/b3sum.o: shared/util.h
   6-cmd/extra/b3sum.o: shared/arg.h
   7-cmd/extra/b3sum.o: shared/compat.h
   8-cmd/extra/b3sum.o: shared/arg.h
   9-cmd/extra/blkid.o: cmd/extra/blkid.c
  10-cmd/extra/blkid.o: shared/util.h
  11-cmd/extra/blkid.o: shared/arg.h
  12-cmd/extra/blkid.o: shared/compat.h
  13-cmd/extra/blkid.o: shared/diskutil.h
  14-cmd/extra/fdisk.o: cmd/extra/fdisk.c
  15-cmd/extra/fdisk.o: shared/util.h
  16-cmd/extra/fdisk.o: shared/arg.h
  17-cmd/extra/fdisk.o: shared/compat.h
  18-cmd/extra/fdisk.o: shared/diskutil.h
  19-cmd/extra/lsblk.o: cmd/extra/lsblk.c
  20-cmd/extra/lsblk.o: shared/util.h
  21-cmd/extra/lsblk.o: shared/arg.h
  22-cmd/extra/lsblk.o: shared/compat.h
  23-cmd/extra/lsblk.o: shared/diskutil.h
  24-cmd/extra/sync.o: cmd/extra/sync.c
  25-cmd/extra/sync.o: shared/arg.h
  26-cmd/extra/sync.o: shared/util.h
  27-cmd/extra/sync.o: shared/arg.h
  28-cmd/extra/sync.o: shared/compat.h
  29-cmd/linux/blkdiscard.o: cmd/linux/blkdiscard.c
  30-cmd/linux/blkdiscard.o: shared/util.h
  31-cmd/linux/blkdiscard.o: shared/arg.h
  32-cmd/linux/blkdiscard.o: shared/compat.h
  33-cmd/linux/chvt.o: cmd/linux/chvt.c
  34-cmd/linux/chvt.o: shared/util.h
  35-cmd/linux/chvt.o: shared/arg.h
  36-cmd/linux/chvt.o: shared/compat.h
  37-cmd/linux/ctrlaltdel.o: cmd/linux/ctrlaltdel.c
  38-cmd/linux/ctrlaltdel.o: shared/reboot.h
  39-cmd/linux/ctrlaltdel.o: shared/util.h
  40-cmd/linux/ctrlaltdel.o: shared/arg.h
  41-cmd/linux/ctrlaltdel.o: shared/compat.h
  42-cmd/linux/depmod.o: cmd/linux/depmod.c
  43-cmd/linux/depmod.o: shared/fs.h
  44-cmd/linux/depmod.o: shared/util.h
  45-cmd/linux/depmod.o: shared/arg.h
  46-cmd/linux/depmod.o: shared/compat.h
  47-cmd/linux/eject.o: cmd/linux/eject.c
  48-cmd/linux/eject.o: shared/util.h
  49-cmd/linux/eject.o: shared/arg.h
  50-cmd/linux/eject.o: shared/compat.h
  51-cmd/linux/freeramdisk.o: cmd/linux/freeramdisk.c
  52-cmd/linux/freeramdisk.o: shared/util.h
  53-cmd/linux/freeramdisk.o: shared/arg.h
  54-cmd/linux/freeramdisk.o: shared/compat.h
  55-cmd/linux/fsfreeze.o: cmd/linux/fsfreeze.c
  56-cmd/linux/fsfreeze.o: shared/util.h
  57-cmd/linux/fsfreeze.o: shared/arg.h
  58-cmd/linux/fsfreeze.o: shared/compat.h
  59+cmd/linux/switch_root.o: cmd/linux/switch_root.c
  60+cmd/linux/switch_root.o: shared/util.h
  61+cmd/linux/switch_root.o: shared/arg.h
  62+cmd/linux/switch_root.o: shared/compat.h
  63+cmd/linux/unshare.o: cmd/linux/unshare.c
  64+cmd/linux/unshare.o: shared/wexec.h
  65+cmd/linux/unshare.o: shared/util.h
  66+cmd/linux/unshare.o: shared/arg.h
  67+cmd/linux/unshare.o: shared/compat.h
  68+cmd/linux/mount.o: cmd/linux/mount.c
  69+cmd/linux/mount.o: shared/text.h
  70+cmd/linux/mount.o: shared/wexec.h
  71+cmd/linux/mount.o: shared/util.h
  72+cmd/linux/mount.o: shared/arg.h
  73+cmd/linux/mount.o: shared/compat.h
  74+cmd/linux/pivot_root.o: cmd/linux/pivot_root.c
  75+cmd/linux/pivot_root.o: shared/util.h
  76+cmd/linux/pivot_root.o: shared/arg.h
  77+cmd/linux/pivot_root.o: shared/compat.h
  78+cmd/linux/umount.o: cmd/linux/umount.c
  79+cmd/linux/umount.o: shared/util.h
  80+cmd/linux/umount.o: shared/arg.h
  81+cmd/linux/umount.o: shared/compat.h
  82+cmd/linux/rmmod.o: cmd/linux/rmmod.c
  83+cmd/linux/rmmod.o: shared/util.h
  84+cmd/linux/rmmod.o: shared/arg.h
  85+cmd/linux/rmmod.o: shared/compat.h
  86 cmd/linux/hwclock.o: cmd/linux/hwclock.c
  87 cmd/linux/hwclock.o: shared/rtc.h
  88+cmd/linux/hwclock.o: shared/paths.h
  89 cmd/linux/hwclock.o: shared/util.h
  90 cmd/linux/hwclock.o: shared/arg.h
  91 cmd/linux/hwclock.o: shared/compat.h
  92-cmd/linux/lsmod.o: cmd/linux/lsmod.c
  93-cmd/linux/lsmod.o: shared/text.h
  94-cmd/linux/lsmod.o: shared/util.h
  95-cmd/linux/lsmod.o: shared/arg.h
  96-cmd/linux/lsmod.o: shared/compat.h
  97+cmd/linux/sysctl.o: cmd/linux/sysctl.c
  98+cmd/linux/sysctl.o: shared/text.h
  99+cmd/linux/sysctl.o: shared/paths.h
 100+cmd/linux/sysctl.o: shared/util.h
 101+cmd/linux/sysctl.o: shared/arg.h
 102+cmd/linux/sysctl.o: shared/compat.h
 103+cmd/linux/tunctl.o: cmd/linux/tunctl.c
 104+cmd/linux/tunctl.o: shared/paths.h
 105+cmd/linux/tunctl.o: shared/util.h
 106+cmd/linux/tunctl.o: shared/arg.h
 107+cmd/linux/tunctl.o: shared/compat.h
 108+cmd/linux/fsfreeze.o: cmd/linux/fsfreeze.c
 109+cmd/linux/fsfreeze.o: shared/util.h
 110+cmd/linux/fsfreeze.o: shared/arg.h
 111+cmd/linux/fsfreeze.o: shared/compat.h
 112+cmd/linux/blkdiscard.o: cmd/linux/blkdiscard.c
 113+cmd/linux/blkdiscard.o: shared/util.h
 114+cmd/linux/blkdiscard.o: shared/arg.h
 115+cmd/linux/blkdiscard.o: shared/compat.h
 116+cmd/linux/swaplabel.o: cmd/linux/swaplabel.c
 117+cmd/linux/swaplabel.o: shared/util.h
 118+cmd/linux/swaplabel.o: shared/arg.h
 119+cmd/linux/swaplabel.o: shared/compat.h
 120 cmd/linux/lsusb.o: cmd/linux/lsusb.c
 121 cmd/linux/lsusb.o: shared/text.h
 122+cmd/linux/lsusb.o: shared/paths.h
 123 cmd/linux/lsusb.o: shared/util.h
 124 cmd/linux/lsusb.o: shared/arg.h
 125 cmd/linux/lsusb.o: shared/compat.h
 126+cmd/linux/readahead.o: cmd/linux/readahead.c
 127+cmd/linux/readahead.o: shared/util.h
 128+cmd/linux/readahead.o: shared/arg.h
 129+cmd/linux/readahead.o: shared/compat.h
 130 cmd/linux/mkswap.o: cmd/linux/mkswap.c
 131 cmd/linux/mkswap.o: shared/util.h
 132 cmd/linux/mkswap.o: shared/arg.h
 133@@ -78,952 +74,171 @@ cmd/linux/mountpoint.o: cmd/linux/mountpoint.c
 134 cmd/linux/mountpoint.o: shared/util.h
 135 cmd/linux/mountpoint.o: shared/arg.h
 136 cmd/linux/mountpoint.o: shared/compat.h
 137-cmd/linux/pivot_root.o: cmd/linux/pivot_root.c
 138-cmd/linux/pivot_root.o: shared/util.h
 139-cmd/linux/pivot_root.o: shared/arg.h
 140-cmd/linux/pivot_root.o: shared/compat.h
 141-cmd/linux/readahead.o: cmd/linux/readahead.c
 142-cmd/linux/readahead.o: shared/util.h
 143-cmd/linux/readahead.o: shared/arg.h
 144-cmd/linux/readahead.o: shared/compat.h
 145-cmd/linux/rmmod.o: cmd/linux/rmmod.c
 146-cmd/linux/rmmod.o: shared/util.h
 147-cmd/linux/rmmod.o: shared/arg.h
 148-cmd/linux/rmmod.o: shared/compat.h
 149-cmd/linux/swaplabel.o: cmd/linux/swaplabel.c
 150-cmd/linux/swaplabel.o: shared/util.h
 151-cmd/linux/swaplabel.o: shared/arg.h
 152-cmd/linux/swaplabel.o: shared/compat.h
 153+cmd/linux/lsmod.o: cmd/linux/lsmod.c
 154+cmd/linux/lsmod.o: shared/text.h
 155+cmd/linux/lsmod.o: shared/paths.h
 156+cmd/linux/lsmod.o: shared/util.h
 157+cmd/linux/lsmod.o: shared/arg.h
 158+cmd/linux/lsmod.o: shared/compat.h
 159+cmd/linux/chvt.o: cmd/linux/chvt.c
 160+cmd/linux/chvt.o: shared/paths.h
 161+cmd/linux/chvt.o: shared/util.h
 162+cmd/linux/chvt.o: shared/arg.h
 163+cmd/linux/chvt.o: shared/compat.h
 164 cmd/linux/swapoff.o: cmd/linux/swapoff.c
 165 cmd/linux/swapoff.o: shared/util.h
 166 cmd/linux/swapoff.o: shared/arg.h
 167 cmd/linux/swapoff.o: shared/compat.h
 168-cmd/linux/swapon.o: cmd/linux/swapon.c
 169-cmd/linux/swapon.o: shared/util.h
 170-cmd/linux/swapon.o: shared/arg.h
 171-cmd/linux/swapon.o: shared/compat.h
 172-cmd/linux/sysctl.o: cmd/linux/sysctl.c
 173-cmd/linux/sysctl.o: shared/text.h
 174-cmd/linux/sysctl.o: shared/util.h
 175-cmd/linux/sysctl.o: shared/arg.h
 176-cmd/linux/sysctl.o: shared/compat.h
 177-cmd/linux/tunctl.o: cmd/linux/tunctl.c
 178-cmd/linux/tunctl.o: shared/util.h
 179-cmd/linux/tunctl.o: shared/arg.h
 180-cmd/linux/tunctl.o: shared/compat.h
 181-cmd/linux/umount.o: cmd/linux/umount.c
 182-cmd/linux/umount.o: shared/util.h
 183-cmd/linux/umount.o: shared/arg.h
 184-cmd/linux/umount.o: shared/compat.h
 185+cmd/linux/eject.o: cmd/linux/eject.c
 186+cmd/linux/eject.o: shared/paths.h
 187+cmd/linux/eject.o: shared/util.h
 188+cmd/linux/eject.o: shared/arg.h
 189+cmd/linux/eject.o: shared/compat.h
 190+cmd/linux/depmod.o: cmd/linux/depmod.c
 191+cmd/linux/depmod.o: shared/fs.h
 192+cmd/linux/depmod.o: shared/wexec.h
 193+cmd/linux/depmod.o: shared/util.h
 194+cmd/linux/depmod.o: shared/arg.h
 195+cmd/linux/depmod.o: shared/compat.h
 196 cmd/linux/vtallow.o: cmd/linux/vtallow.c
 197+cmd/linux/vtallow.o: shared/paths.h
 198 cmd/linux/vtallow.o: shared/util.h
 199 cmd/linux/vtallow.o: shared/arg.h
 200 cmd/linux/vtallow.o: shared/compat.h
 201-cmd/linux/insmod.o: cmd/linux/insmod.c
 202-cmd/linux/insmod.o: shared/util.h
 203-cmd/linux/insmod.o: shared/arg.h
 204-cmd/linux/insmod.o: shared/compat.h
 205+cmd/linux/freeramdisk.o: cmd/linux/freeramdisk.c
 206+cmd/linux/freeramdisk.o: shared/paths.h
 207+cmd/linux/freeramdisk.o: shared/util.h
 208+cmd/linux/freeramdisk.o: shared/arg.h
 209+cmd/linux/freeramdisk.o: shared/compat.h
 210+cmd/linux/swapon.o: cmd/linux/swapon.c
 211+cmd/linux/swapon.o: shared/util.h
 212+cmd/linux/swapon.o: shared/arg.h
 213+cmd/linux/swapon.o: shared/compat.h
 214+cmd/linux/ctrlaltdel.o: cmd/linux/ctrlaltdel.c
 215+cmd/linux/ctrlaltdel.o: shared/reboot.h
 216+cmd/linux/ctrlaltdel.o: shared/util.h
 217+cmd/linux/ctrlaltdel.o: shared/arg.h
 218+cmd/linux/ctrlaltdel.o: shared/compat.h
 219 cmd/linux/modprobe.o: cmd/linux/modprobe.c
 220 cmd/linux/modprobe.o: shared/arg.h
 221 cmd/linux/modprobe.o: shared/fs.h
 222+cmd/linux/modprobe.o: shared/paths.h
 223 cmd/linux/modprobe.o: shared/util.h
 224 cmd/linux/modprobe.o: shared/arg.h
 225 cmd/linux/modprobe.o: shared/compat.h
 226-cmd/linux/mount.o: cmd/linux/mount.c
 227-cmd/linux/mount.o: shared/text.h
 228-cmd/linux/mount.o: shared/util.h
 229-cmd/linux/mount.o: shared/arg.h
 230-cmd/linux/mount.o: shared/compat.h
 231-cmd/linux/switch_root.o: cmd/linux/switch_root.c
 232-cmd/linux/switch_root.o: shared/util.h
 233-cmd/linux/switch_root.o: shared/arg.h
 234-cmd/linux/switch_root.o: shared/compat.h
 235-cmd/linux/unshare.o: cmd/linux/unshare.c
 236-cmd/linux/unshare.o: shared/util.h
 237-cmd/linux/unshare.o: shared/arg.h
 238-cmd/linux/unshare.o: shared/compat.h
 239-cmd/net/httpd.o: cmd/net/httpd.c
 240-cmd/net/httpd.o: shared/util.h
 241-cmd/net/httpd.o: shared/arg.h
 242-cmd/net/httpd.o: shared/compat.h
 243-cmd/net/httpd.o: shared/arg.h
 244-cmd/net/ping.o: cmd/net/ping.c
 245-cmd/net/ping.o: shared/util.h
 246-cmd/net/ping.o: shared/arg.h
 247-cmd/net/ping.o: shared/compat.h
 248-cmd/net/ping.o: shared/arg.h
 249-cmd/net/sdhcp.o: cmd/net/sdhcp.c
 250-cmd/net/sdhcp.o: shared/arg.h
 251-cmd/net/sdhcp.o: shared/util.h
 252-cmd/net/sdhcp.o: shared/arg.h
 253-cmd/net/sdhcp.o: shared/compat.h
 254-cmd/net/tftp.o: cmd/net/tftp.c
 255-cmd/net/tftp.o: shared/util.h
 256-cmd/net/tftp.o: shared/arg.h
 257-cmd/net/tftp.o: shared/compat.h
 258-cmd/net/wget.o: cmd/net/wget.c
 259-cmd/net/wget.o: shared/util.h
 260-cmd/net/wget.o: shared/arg.h
 261-cmd/net/wget.o: shared/compat.h
 262-cmd/net/wget.o: shared/arg.h
 263-cmd/net/wget.o: shared/tls.h
 264-cmd/net/host.o: cmd/net/host.c
 265-cmd/net/host.o: shared/util.h
 266-cmd/net/host.o: shared/arg.h
 267-cmd/net/host.o: shared/compat.h
 268-cmd/net/host.o: shared/arg.h
 269-cmd/net/ifconfig.o: cmd/net/ifconfig.c
 270-cmd/net/ifconfig.o: shared/util.h
 271-cmd/net/ifconfig.o: shared/arg.h
 272-cmd/net/ifconfig.o: shared/compat.h
 273-cmd/net/ip.o: cmd/net/ip.c
 274-cmd/net/ip.o: shared/util.h
 275-cmd/net/ip.o: shared/arg.h
 276-cmd/net/ip.o: shared/compat.h
 277-cmd/net/netcat.o: cmd/net/netcat.c
 278-cmd/net/netcat.o: shared/util.h
 279-cmd/net/netcat.o: shared/arg.h
 280-cmd/net/netcat.o: shared/compat.h
 281-cmd/posix/awk/b.o: cmd/posix/awk/b.c
 282-cmd/posix/awk/b.o: cmd/posix/awk/awk.h
 283-cmd/posix/awk/b.o: cmd/posix/awk/proto.h
 284-cmd/posix/awk/b.o: cmd/posix/awk/awkgram.tab.h
 285-cmd/posix/awk/lex.o: cmd/posix/awk/lex.c
 286-cmd/posix/awk/lex.o: cmd/posix/awk/awk.h
 287-cmd/posix/awk/lex.o: cmd/posix/awk/proto.h
 288-cmd/posix/awk/lex.o: cmd/posix/awk/awkgram.tab.h
 289-cmd/posix/awk/lib.o: cmd/posix/awk/lib.c
 290-cmd/posix/awk/lib.o: cmd/posix/awk/awk.h
 291-cmd/posix/awk/lib.o: cmd/posix/awk/proto.h
 292-cmd/posix/awk/main.o: cmd/posix/awk/main.c
 293-cmd/posix/awk/main.o: cmd/posix/awk/awk.h
 294-cmd/posix/awk/main.o: cmd/posix/awk/proto.h
 295-cmd/posix/awk/maketab.o: cmd/posix/awk/maketab.c
 296-cmd/posix/awk/maketab.o: cmd/posix/awk/awk.h
 297-cmd/posix/awk/maketab.o: cmd/posix/awk/proto.h
 298-cmd/posix/awk/maketab.o: cmd/posix/awk/awkgram.tab.h
 299-cmd/posix/awk/math.o: cmd/posix/awk/math.c
 300-cmd/posix/awk/math.o: cmd/posix/awk/awk.h
 301-cmd/posix/awk/math.o: cmd/posix/awk/proto.h
 302-cmd/posix/awk/parse.o: cmd/posix/awk/parse.c
 303-cmd/posix/awk/parse.o: cmd/posix/awk/awk.h
 304-cmd/posix/awk/parse.o: cmd/posix/awk/proto.h
 305-cmd/posix/awk/parse.o: cmd/posix/awk/awkgram.tab.h
 306-cmd/posix/awk/run.o: cmd/posix/awk/run.c
 307-cmd/posix/awk/run.o: cmd/posix/awk/awk.h
 308-cmd/posix/awk/run.o: cmd/posix/awk/proto.h
 309-cmd/posix/awk/run.o: cmd/posix/awk/awkgram.tab.h
 310-cmd/posix/awk/tran.o: cmd/posix/awk/tran.c
 311-cmd/posix/awk/tran.o: cmd/posix/awk/awk.h
 312-cmd/posix/awk/tran.o: cmd/posix/awk/proto.h
 313-cmd/posix/awk/awkgram.tab.o: cmd/posix/awk/awkgram.tab.c
 314-cmd/posix/awk/awkgram.tab.o: cmd/posix/awk/awk.h
 315-cmd/posix/awk/awkgram.tab.o: cmd/posix/awk/proto.h
 316-cmd/posix/awk/awkgram.tab.o: cmd/posix/awk/awkgram.tab.h
 317-cmd/posix/awk/proctab.o: cmd/posix/awk/proctab.c
 318-cmd/posix/awk/proctab.o: cmd/posix/awk/awk.h
 319-cmd/posix/awk/proctab.o: cmd/posix/awk/proto.h
 320-cmd/posix/awk/proctab.o: cmd/posix/awk/awkgram.tab.h
 321-cmd/posix/cal.o: cmd/posix/cal.c
 322-cmd/posix/cal.o: shared/util.h
 323-cmd/posix/cal.o: shared/arg.h
 324-cmd/posix/cal.o: shared/compat.h
 325-cmd/posix/cat.o: cmd/posix/cat.c
 326-cmd/posix/cat.o: shared/util.h
 327-cmd/posix/cat.o: shared/arg.h
 328-cmd/posix/cat.o: shared/compat.h
 329-cmd/posix/chgrp.o: cmd/posix/chgrp.c
 330-cmd/posix/chgrp.o: shared/fs.h
 331-cmd/posix/chgrp.o: shared/util.h
 332-cmd/posix/chgrp.o: shared/arg.h
 333-cmd/posix/chgrp.o: shared/compat.h
 334-cmd/posix/chmod.o: cmd/posix/chmod.c
 335-cmd/posix/chmod.o: shared/fs.h
 336-cmd/posix/chmod.o: shared/util.h
 337-cmd/posix/chmod.o: shared/arg.h
 338-cmd/posix/chmod.o: shared/compat.h
 339-cmd/posix/chown.o: cmd/posix/chown.c
 340-cmd/posix/chown.o: shared/fs.h
 341-cmd/posix/chown.o: shared/util.h
 342-cmd/posix/chown.o: shared/arg.h
 343-cmd/posix/chown.o: shared/compat.h
 344-cmd/posix/cksum.o: cmd/posix/cksum.c
 345-cmd/posix/cksum.o: shared/util.h
 346-cmd/posix/cksum.o: shared/arg.h
 347-cmd/posix/cksum.o: shared/compat.h
 348-cmd/posix/cmp.o: cmd/posix/cmp.c
 349-cmd/posix/cmp.o: shared/util.h
 350-cmd/posix/cmp.o: shared/arg.h
 351-cmd/posix/cmp.o: shared/compat.h
 352-cmd/posix/comm.o: cmd/posix/comm.c
 353-cmd/posix/comm.o: shared/text.h
 354-cmd/posix/comm.o: shared/util.h
 355-cmd/posix/comm.o: shared/arg.h
 356-cmd/posix/comm.o: shared/compat.h
 357-cmd/posix/cp.o: cmd/posix/cp.c
 358-cmd/posix/cp.o: shared/fs.h
 359-cmd/posix/cp.o: shared/util.h
 360-cmd/posix/cp.o: shared/arg.h
 361-cmd/posix/cp.o: shared/compat.h
 362-cmd/posix/dd.o: cmd/posix/dd.c
 363-cmd/posix/dd.o: shared/util.h
 364-cmd/posix/dd.o: shared/arg.h
 365-cmd/posix/dd.o: shared/compat.h
 366-cmd/posix/df.o: cmd/posix/df.c
 367-cmd/posix/df.o: shared/util.h
 368-cmd/posix/df.o: shared/arg.h
 369-cmd/posix/df.o: shared/compat.h
 370-cmd/posix/dirname.o: cmd/posix/dirname.c
 371-cmd/posix/dirname.o: shared/util.h
 372-cmd/posix/dirname.o: shared/arg.h
 373-cmd/posix/dirname.o: shared/compat.h
 374-cmd/posix/du.o: cmd/posix/du.c
 375-cmd/posix/du.o: shared/fs.h
 376-cmd/posix/du.o: shared/util.h
 377-cmd/posix/du.o: shared/arg.h
 378-cmd/posix/du.o: shared/compat.h
 379-cmd/posix/echo.o: cmd/posix/echo.c
 380-cmd/posix/echo.o: shared/util.h
 381-cmd/posix/echo.o: shared/arg.h
 382-cmd/posix/echo.o: shared/compat.h
 383-cmd/posix/ed.o: cmd/posix/ed.c
 384-cmd/posix/ed.o: shared/util.h
 385-cmd/posix/ed.o: shared/arg.h
 386-cmd/posix/ed.o: shared/compat.h
 387-cmd/posix/expand.o: cmd/posix/expand.c
 388-cmd/posix/expand.o: shared/utf.h
 389-cmd/posix/expand.o: shared/util.h
 390-cmd/posix/expand.o: shared/arg.h
 391-cmd/posix/expand.o: shared/compat.h
 392-cmd/posix/expr.o: cmd/posix/expr.c
 393-cmd/posix/expr.o: shared/utf.h
 394-cmd/posix/expr.o: shared/util.h
 395-cmd/posix/expr.o: shared/arg.h
 396-cmd/posix/expr.o: shared/compat.h
 397-cmd/posix/false.o: cmd/posix/false.c
 398-cmd/posix/fold.o: cmd/posix/fold.c
 399-cmd/posix/fold.o: shared/text.h
 400-cmd/posix/fold.o: shared/util.h
 401-cmd/posix/fold.o: shared/arg.h
 402-cmd/posix/fold.o: shared/compat.h
 403-cmd/posix/fold.o: shared/utf.h
 404-cmd/posix/head.o: cmd/posix/head.c
 405-cmd/posix/head.o: shared/util.h
 406-cmd/posix/head.o: shared/arg.h
 407-cmd/posix/head.o: shared/compat.h
 408-cmd/posix/id.o: cmd/posix/id.c
 409-cmd/posix/id.o: shared/util.h
 410-cmd/posix/id.o: shared/arg.h
 411-cmd/posix/id.o: shared/compat.h
 412-cmd/posix/join.o: cmd/posix/join.c
 413-cmd/posix/join.o: shared/text.h
 414-cmd/posix/join.o: shared/utf.h
 415-cmd/posix/join.o: shared/util.h
 416-cmd/posix/join.o: shared/arg.h
 417-cmd/posix/join.o: shared/compat.h
 418-cmd/posix/kill.o: cmd/posix/kill.c
 419-cmd/posix/kill.o: shared/sig.h
 420-cmd/posix/kill.o: shared/util.h
 421-cmd/posix/kill.o: shared/arg.h
 422-cmd/posix/kill.o: shared/compat.h
 423-cmd/posix/link.o: cmd/posix/link.c
 424-cmd/posix/link.o: shared/util.h
 425-cmd/posix/link.o: shared/arg.h
 426-cmd/posix/link.o: shared/compat.h
 427-cmd/posix/logger.o: cmd/posix/logger.c
 428-cmd/posix/logger.o: shared/util.h
 429-cmd/posix/logger.o: shared/arg.h
 430-cmd/posix/logger.o: shared/compat.h
 431-cmd/posix/logname.o: cmd/posix/logname.c
 432-cmd/posix/logname.o: shared/util.h
 433-cmd/posix/logname.o: shared/arg.h
 434-cmd/posix/logname.o: shared/compat.h
 435-cmd/posix/make/defaults.o: cmd/posix/make/defaults.c
 436-cmd/posix/make/main.o: cmd/posix/make/main.c
 437-cmd/posix/make/main.o: cmd/posix/make/make.h
 438-cmd/posix/make/parser.o: cmd/posix/make/parser.c
 439-cmd/posix/make/parser.o: cmd/posix/make/make.h
 440-cmd/posix/make/posix.o: cmd/posix/make/posix.c
 441-cmd/posix/make/posix.o: cmd/posix/make/make.h
 442-cmd/posix/make/rules.o: cmd/posix/make/rules.c
 443-cmd/posix/make/rules.o: cmd/posix/make/make.h
 444-cmd/posix/mesg.o: cmd/posix/mesg.c
 445-cmd/posix/mesg.o: shared/util.h
 446-cmd/posix/mesg.o: shared/arg.h
 447-cmd/posix/mesg.o: shared/compat.h
 448-cmd/posix/mkdir.o: cmd/posix/mkdir.c
 449-cmd/posix/mkdir.o: shared/util.h
 450-cmd/posix/mkdir.o: shared/arg.h
 451-cmd/posix/mkdir.o: shared/compat.h
 452-cmd/posix/mkfifo.o: cmd/posix/mkfifo.c
 453-cmd/posix/mkfifo.o: shared/util.h
 454-cmd/posix/mkfifo.o: shared/arg.h
 455-cmd/posix/mkfifo.o: shared/compat.h
 456-cmd/posix/mv.o: cmd/posix/mv.c
 457-cmd/posix/mv.o: shared/fs.h
 458-cmd/posix/mv.o: shared/util.h
 459-cmd/posix/mv.o: shared/arg.h
 460-cmd/posix/mv.o: shared/compat.h
 461-cmd/posix/nl.o: cmd/posix/nl.c
 462-cmd/posix/nl.o: shared/text.h
 463-cmd/posix/nl.o: shared/utf.h
 464-cmd/posix/nl.o: shared/util.h
 465-cmd/posix/nl.o: shared/arg.h
 466-cmd/posix/nl.o: shared/compat.h
 467-cmd/posix/od.o: cmd/posix/od.c
 468-cmd/posix/od.o: shared/queue.h
 469-cmd/posix/od.o: shared/util.h
 470-cmd/posix/od.o: shared/arg.h
 471-cmd/posix/od.o: shared/compat.h
 472-cmd/posix/paste.o: cmd/posix/paste.c
 473-cmd/posix/paste.o: shared/utf.h
 474-cmd/posix/paste.o: shared/util.h
 475-cmd/posix/paste.o: shared/arg.h
 476-cmd/posix/paste.o: shared/compat.h
 477-cmd/posix/pathchk.o: cmd/posix/pathchk.c
 478-cmd/posix/pathchk.o: shared/util.h
 479-cmd/posix/pathchk.o: shared/arg.h
 480-cmd/posix/pathchk.o: shared/compat.h
 481-cmd/posix/pax.o: cmd/posix/pax.c
 482-cmd/posix/pax.o: shared/arg.h
 483-cmd/posix/ps.o: cmd/posix/ps.c
 484-cmd/posix/ps.o: shared/proc.h
 485-cmd/posix/ps.o: shared/util.h
 486-cmd/posix/ps.o: shared/arg.h
 487-cmd/posix/ps.o: shared/compat.h
 488-cmd/posix/pwd.o: cmd/posix/pwd.c
 489-cmd/posix/pwd.o: shared/util.h
 490-cmd/posix/pwd.o: shared/arg.h
 491-cmd/posix/pwd.o: shared/compat.h
 492-cmd/posix/readlink.o: cmd/posix/readlink.c
 493-cmd/posix/readlink.o: shared/util.h
 494-cmd/posix/readlink.o: shared/arg.h
 495-cmd/posix/readlink.o: shared/compat.h
 496-cmd/posix/renice.o: cmd/posix/renice.c
 497-cmd/posix/renice.o: shared/util.h
 498-cmd/posix/renice.o: shared/arg.h
 499-cmd/posix/renice.o: shared/compat.h
 500-cmd/posix/rm.o: cmd/posix/rm.c
 501-cmd/posix/rm.o: shared/fs.h
 502-cmd/posix/rm.o: shared/util.h
 503-cmd/posix/rm.o: shared/arg.h
 504-cmd/posix/rm.o: shared/compat.h
 505-cmd/posix/rmdir.o: cmd/posix/rmdir.c
 506-cmd/posix/rmdir.o: shared/util.h
 507-cmd/posix/rmdir.o: shared/arg.h
 508-cmd/posix/rmdir.o: shared/compat.h
 509-cmd/posix/sh/alias.o: cmd/posix/sh/alias.c
 510-cmd/posix/sh/alias.o: cmd/posix/sh/shell.h
 511-cmd/posix/sh/alias.o: shared/sig.h
 512-cmd/posix/sh/alias.o: cmd/posix/sh/output.h
 513-cmd/posix/sh/alias.o: cmd/posix/sh/error.h
 514-cmd/posix/sh/alias.o: cmd/posix/sh/memalloc.h
 515-cmd/posix/sh/alias.o: cmd/posix/sh/mystring.h
 516-cmd/posix/sh/alias.o: cmd/posix/sh/alias.h
 517-cmd/posix/sh/alias.o: cmd/posix/sh/options.h
 518-cmd/posix/sh/alias.o: cmd/posix/sh/builtins.h
 519-cmd/posix/sh/arith_yacc.o: cmd/posix/sh/arith_yacc.c
 520-cmd/posix/sh/arith_yacc.o: cmd/posix/sh/arith.h
 521-cmd/posix/sh/arith_yacc.o: cmd/posix/sh/shell.h
 522-cmd/posix/sh/arith_yacc.o: shared/sig.h
 523-cmd/posix/sh/arith_yacc.o: cmd/posix/sh/arith_yacc.h
 524-cmd/posix/sh/arith_yacc.o: cmd/posix/sh/expand.h
 525-cmd/posix/sh/arith_yacc.o: cmd/posix/sh/error.h
 526-cmd/posix/sh/arith_yacc.o: cmd/posix/sh/memalloc.h
 527-cmd/posix/sh/arith_yacc.o: cmd/posix/sh/output.h
 528-cmd/posix/sh/arith_yacc.o: cmd/posix/sh/options.h
 529-cmd/posix/sh/arith_yacc.o: cmd/posix/sh/var.h
 530-cmd/posix/sh/arith_yylex.o: cmd/posix/sh/arith_yylex.c
 531-cmd/posix/sh/arith_yylex.o: cmd/posix/sh/shell.h
 532-cmd/posix/sh/arith_yylex.o: shared/sig.h
 533-cmd/posix/sh/arith_yylex.o: cmd/posix/sh/arith_yacc.h
 534-cmd/posix/sh/arith_yylex.o: cmd/posix/sh/expand.h
 535-cmd/posix/sh/arith_yylex.o: cmd/posix/sh/error.h
 536-cmd/posix/sh/arith_yylex.o: cmd/posix/sh/memalloc.h
 537-cmd/posix/sh/arith_yylex.o: cmd/posix/sh/parser.h
 538-cmd/posix/sh/arith_yylex.o: cmd/posix/sh/syntax.h
 539-cmd/posix/sh/cd.o: cmd/posix/sh/cd.c
 540-cmd/posix/sh/cd.o: cmd/posix/sh/shell.h
 541-cmd/posix/sh/cd.o: shared/sig.h
 542-cmd/posix/sh/cd.o: cmd/posix/sh/var.h
 543-cmd/posix/sh/cd.o: cmd/posix/sh/nodes.h
 544-cmd/posix/sh/cd.o: cmd/posix/sh/jobs.h
 545-cmd/posix/sh/cd.o: cmd/posix/sh/options.h
 546-cmd/posix/sh/cd.o: cmd/posix/sh/output.h
 547-cmd/posix/sh/cd.o: cmd/posix/sh/memalloc.h
 548-cmd/posix/sh/cd.o: cmd/posix/sh/error.h
 549-cmd/posix/sh/cd.o: cmd/posix/sh/exec.h
 550-cmd/posix/sh/cd.o: cmd/posix/sh/redir.h
 551-cmd/posix/sh/cd.o: cmd/posix/sh/mystring.h
 552-cmd/posix/sh/cd.o: cmd/posix/sh/show.h
 553-cmd/posix/sh/cd.o: cmd/posix/sh/cd.h
 554-cmd/posix/sh/cd.o: cmd/posix/sh/builtins.h
 555-cmd/posix/sh/echo.o: cmd/posix/sh/echo.c
 556-cmd/posix/sh/echo.o: cmd/posix/sh/bltin.h
 557-cmd/posix/sh/echo.o: cmd/posix/sh/shell.h
 558-cmd/posix/sh/echo.o: shared/sig.h
 559-cmd/posix/sh/echo.o: cmd/posix/sh/mystring.h
 560-cmd/posix/sh/error.o: cmd/posix/sh/error.c
 561-cmd/posix/sh/error.o: cmd/posix/sh/shell.h
 562-cmd/posix/sh/error.o: shared/sig.h
 563-cmd/posix/sh/error.o: cmd/posix/sh/eval.h
 564-cmd/posix/sh/error.o: cmd/posix/sh/main.h
 565-cmd/posix/sh/error.o: cmd/posix/sh/options.h
 566-cmd/posix/sh/error.o: cmd/posix/sh/output.h
 567-cmd/posix/sh/error.o: cmd/posix/sh/error.h
 568-cmd/posix/sh/error.o: cmd/posix/sh/nodes.h
 569-cmd/posix/sh/error.o: cmd/posix/sh/show.h
 570-cmd/posix/sh/error.o: cmd/posix/sh/trap.h
 571-cmd/posix/sh/eval.o: cmd/posix/sh/eval.c
 572-cmd/posix/sh/eval.o: cmd/posix/sh/shell.h
 573-cmd/posix/sh/eval.o: shared/sig.h
 574-cmd/posix/sh/eval.o: cmd/posix/sh/nodes.h
 575-cmd/posix/sh/eval.o: cmd/posix/sh/syntax.h
 576-cmd/posix/sh/eval.o: cmd/posix/sh/expand.h
 577-cmd/posix/sh/eval.o: cmd/posix/sh/parser.h
 578-cmd/posix/sh/eval.o: cmd/posix/sh/jobs.h
 579-cmd/posix/sh/eval.o: cmd/posix/sh/eval.h
 580-cmd/posix/sh/eval.o: cmd/posix/sh/builtins.h
 581-cmd/posix/sh/eval.o: cmd/posix/sh/options.h
 582-cmd/posix/sh/eval.o: cmd/posix/sh/exec.h
 583-cmd/posix/sh/eval.o: cmd/posix/sh/redir.h
 584-cmd/posix/sh/eval.o: cmd/posix/sh/input.h
 585-cmd/posix/sh/eval.o: cmd/posix/sh/output.h
 586-cmd/posix/sh/eval.o: cmd/posix/sh/trap.h
 587-cmd/posix/sh/eval.o: cmd/posix/sh/var.h
 588-cmd/posix/sh/eval.o: cmd/posix/sh/memalloc.h
 589-cmd/posix/sh/eval.o: cmd/posix/sh/error.h
 590-cmd/posix/sh/eval.o: cmd/posix/sh/show.h
 591-cmd/posix/sh/eval.o: cmd/posix/sh/mystring.h
 592-cmd/posix/sh/exec.o: cmd/posix/sh/exec.c
 593-cmd/posix/sh/exec.o: cmd/posix/sh/shell.h
 594-cmd/posix/sh/exec.o: shared/sig.h
 595-cmd/posix/sh/exec.o: cmd/posix/sh/main.h
 596-cmd/posix/sh/exec.o: cmd/posix/sh/nodes.h
 597-cmd/posix/sh/exec.o: cmd/posix/sh/parser.h
 598-cmd/posix/sh/exec.o: cmd/posix/sh/redir.h
 599-cmd/posix/sh/exec.o: cmd/posix/sh/eval.h
 600-cmd/posix/sh/exec.o: cmd/posix/sh/exec.h
 601-cmd/posix/sh/exec.o: cmd/posix/sh/builtins.h
 602-cmd/posix/sh/exec.o: cmd/posix/sh/var.h
 603-cmd/posix/sh/exec.o: cmd/posix/sh/options.h
 604-cmd/posix/sh/exec.o: cmd/posix/sh/input.h
 605-cmd/posix/sh/exec.o: cmd/posix/sh/output.h
 606-cmd/posix/sh/exec.o: cmd/posix/sh/syntax.h
 607-cmd/posix/sh/exec.o: cmd/posix/sh/memalloc.h
 608-cmd/posix/sh/exec.o: cmd/posix/sh/error.h
 609-cmd/posix/sh/exec.o: cmd/posix/sh/mystring.h
 610-cmd/posix/sh/exec.o: cmd/posix/sh/show.h
 611-cmd/posix/sh/exec.o: cmd/posix/sh/jobs.h
 612-cmd/posix/sh/exec.o: cmd/posix/sh/alias.h
 613-cmd/posix/sh/expand.o: cmd/posix/sh/expand.c
 614-cmd/posix/sh/expand.o: cmd/posix/sh/shell.h
 615-cmd/posix/sh/expand.o: shared/sig.h
 616-cmd/posix/sh/expand.o: cmd/posix/sh/main.h
 617-cmd/posix/sh/expand.o: cmd/posix/sh/nodes.h
 618-cmd/posix/sh/expand.o: cmd/posix/sh/eval.h
 619-cmd/posix/sh/expand.o: cmd/posix/sh/expand.h
 620-cmd/posix/sh/expand.o: cmd/posix/sh/syntax.h
 621-cmd/posix/sh/expand.o: cmd/posix/sh/parser.h
 622-cmd/posix/sh/expand.o: cmd/posix/sh/jobs.h
 623-cmd/posix/sh/expand.o: cmd/posix/sh/options.h
 624-cmd/posix/sh/expand.o: cmd/posix/sh/var.h
 625-cmd/posix/sh/expand.o: cmd/posix/sh/input.h
 626-cmd/posix/sh/expand.o: cmd/posix/sh/output.h
 627-cmd/posix/sh/expand.o: cmd/posix/sh/memalloc.h
 628-cmd/posix/sh/expand.o: cmd/posix/sh/error.h
 629-cmd/posix/sh/expand.o: cmd/posix/sh/mystring.h
 630-cmd/posix/sh/expand.o: cmd/posix/sh/arith.h
 631-cmd/posix/sh/expand.o: cmd/posix/sh/show.h
 632-cmd/posix/sh/expand.o: cmd/posix/sh/builtins.h
 633-cmd/posix/sh/input.o: cmd/posix/sh/input.c
 634-cmd/posix/sh/input.o: cmd/posix/sh/shell.h
 635-cmd/posix/sh/input.o: shared/sig.h
 636-cmd/posix/sh/input.o: cmd/posix/sh/redir.h
 637-cmd/posix/sh/input.o: cmd/posix/sh/syntax.h
 638-cmd/posix/sh/input.o: cmd/posix/sh/input.h
 639-cmd/posix/sh/input.o: cmd/posix/sh/output.h
 640-cmd/posix/sh/input.o: cmd/posix/sh/options.h
 641-cmd/posix/sh/input.o: cmd/posix/sh/memalloc.h
 642-cmd/posix/sh/input.o: cmd/posix/sh/error.h
 643-cmd/posix/sh/input.o: cmd/posix/sh/alias.h
 644-cmd/posix/sh/input.o: cmd/posix/sh/parser.h
 645-cmd/posix/sh/input.o: cmd/posix/sh/trap.h
 646-cmd/posix/sh/jobs.o: cmd/posix/sh/jobs.c
 647-cmd/posix/sh/jobs.o: cmd/posix/sh/shell.h
 648-cmd/posix/sh/jobs.o: shared/sig.h
 649-cmd/posix/sh/jobs.o: cmd/posix/sh/redir.h
 650-cmd/posix/sh/jobs.o: cmd/posix/sh/exec.h
 651-cmd/posix/sh/jobs.o: cmd/posix/sh/show.h
 652-cmd/posix/sh/jobs.o: cmd/posix/sh/main.h
 653-cmd/posix/sh/jobs.o: cmd/posix/sh/parser.h
 654-cmd/posix/sh/jobs.o: cmd/posix/sh/nodes.h
 655-cmd/posix/sh/jobs.o: cmd/posix/sh/jobs.h
 656-cmd/posix/sh/jobs.o: cmd/posix/sh/options.h
 657-cmd/posix/sh/jobs.o: cmd/posix/sh/trap.h
 658-cmd/posix/sh/jobs.o: cmd/posix/sh/syntax.h
 659-cmd/posix/sh/jobs.o: cmd/posix/sh/input.h
 660-cmd/posix/sh/jobs.o: cmd/posix/sh/output.h
 661-cmd/posix/sh/jobs.o: cmd/posix/sh/memalloc.h
 662-cmd/posix/sh/jobs.o: cmd/posix/sh/error.h
 663-cmd/posix/sh/jobs.o: cmd/posix/sh/mystring.h
 664-cmd/posix/sh/jobs.o: cmd/posix/sh/var.h
 665-cmd/posix/sh/jobs.o: cmd/posix/sh/builtins.h
 666-cmd/posix/sh/jobs.o: cmd/posix/sh/eval.h
 667-cmd/posix/sh/kill.o: cmd/posix/sh/kill.c
 668-cmd/posix/sh/kill.o: shared/sig.h
 669-cmd/posix/sh/lineedit.o: cmd/posix/sh/lineedit.c
 670-cmd/posix/sh/lineedit.o: shared/util.h
 671-cmd/posix/sh/lineedit.o: shared/arg.h
 672-cmd/posix/sh/lineedit.o: shared/compat.h
 673-cmd/posix/sh/lineedit.o: cmd/posix/sh/shell.h
 674-cmd/posix/sh/lineedit.o: shared/sig.h
 675-cmd/posix/sh/lineedit.o: cmd/posix/sh/alias.h
 676-cmd/posix/sh/lineedit.o: cmd/posix/sh/builtins.h
 677-cmd/posix/sh/lineedit.o: cmd/posix/sh/error.h
 678-cmd/posix/sh/lineedit.o: cmd/posix/sh/eval.h
 679-cmd/posix/sh/lineedit.o: cmd/posix/sh/exec.h
 680-cmd/posix/sh/lineedit.o: cmd/posix/sh/main.h
 681-cmd/posix/sh/lineedit.o: cmd/posix/sh/memalloc.h
 682-cmd/posix/sh/lineedit.o: cmd/posix/sh/mystring.h
 683-cmd/posix/sh/lineedit.o: cmd/posix/sh/options.h
 684-cmd/posix/sh/lineedit.o: cmd/posix/sh/output.h
 685-cmd/posix/sh/lineedit.o: cmd/posix/sh/parser.h
 686-cmd/posix/sh/lineedit.o: cmd/posix/sh/var.h
 687-cmd/posix/sh/mail.o: cmd/posix/sh/mail.c
 688-cmd/posix/sh/mail.o: cmd/posix/sh/shell.h
 689-cmd/posix/sh/mail.o: shared/sig.h
 690-cmd/posix/sh/mail.o: cmd/posix/sh/mail.h
 691-cmd/posix/sh/mail.o: cmd/posix/sh/var.h
 692-cmd/posix/sh/mail.o: cmd/posix/sh/output.h
 693-cmd/posix/sh/mail.o: cmd/posix/sh/memalloc.h
 694-cmd/posix/sh/mail.o: cmd/posix/sh/error.h
 695-cmd/posix/sh/main.o: cmd/posix/sh/main.c
 696-cmd/posix/sh/main.o: cmd/posix/sh/shell.h
 697-cmd/posix/sh/main.o: shared/sig.h
 698-cmd/posix/sh/main.o: cmd/posix/sh/main.h
 699-cmd/posix/sh/main.o: cmd/posix/sh/mail.h
 700-cmd/posix/sh/main.o: cmd/posix/sh/options.h
 701-cmd/posix/sh/main.o: cmd/posix/sh/output.h
 702-cmd/posix/sh/main.o: cmd/posix/sh/parser.h
 703-cmd/posix/sh/main.o: cmd/posix/sh/nodes.h
 704-cmd/posix/sh/main.o: cmd/posix/sh/expand.h
 705-cmd/posix/sh/main.o: cmd/posix/sh/eval.h
 706-cmd/posix/sh/main.o: cmd/posix/sh/jobs.h
 707-cmd/posix/sh/main.o: cmd/posix/sh/input.h
 708-cmd/posix/sh/main.o: cmd/posix/sh/trap.h
 709-cmd/posix/sh/main.o: cmd/posix/sh/var.h
 710-cmd/posix/sh/main.o: cmd/posix/sh/show.h
 711-cmd/posix/sh/main.o: cmd/posix/sh/memalloc.h
 712-cmd/posix/sh/main.o: cmd/posix/sh/error.h
 713-cmd/posix/sh/main.o: cmd/posix/sh/mystring.h
 714-cmd/posix/sh/main.o: cmd/posix/sh/exec.h
 715-cmd/posix/sh/main.o: cmd/posix/sh/cd.h
 716-cmd/posix/sh/main.o: cmd/posix/sh/redir.h
 717-cmd/posix/sh/main.o: cmd/posix/sh/builtins.h
 718-cmd/posix/sh/memalloc.o: cmd/posix/sh/memalloc.c
 719-cmd/posix/sh/memalloc.o: cmd/posix/sh/shell.h
 720-cmd/posix/sh/memalloc.o: shared/sig.h
 721-cmd/posix/sh/memalloc.o: cmd/posix/sh/output.h
 722-cmd/posix/sh/memalloc.o: cmd/posix/sh/memalloc.h
 723-cmd/posix/sh/memalloc.o: cmd/posix/sh/error.h
 724-cmd/posix/sh/memalloc.o: cmd/posix/sh/mystring.h
 725-cmd/posix/sh/memalloc.o: cmd/posix/sh/expand.h
 726-cmd/posix/sh/miscbltin.o: cmd/posix/sh/miscbltin.c
 727-cmd/posix/sh/miscbltin.o: cmd/posix/sh/shell.h
 728-cmd/posix/sh/miscbltin.o: shared/sig.h
 729-cmd/posix/sh/miscbltin.o: shared/redline.h
 730-cmd/posix/sh/miscbltin.o: cmd/posix/sh/options.h
 731-cmd/posix/sh/miscbltin.o: cmd/posix/sh/var.h
 732-cmd/posix/sh/miscbltin.o: cmd/posix/sh/output.h
 733-cmd/posix/sh/miscbltin.o: cmd/posix/sh/memalloc.h
 734-cmd/posix/sh/miscbltin.o: cmd/posix/sh/error.h
 735-cmd/posix/sh/miscbltin.o: cmd/posix/sh/mystring.h
 736-cmd/posix/sh/miscbltin.o: cmd/posix/sh/syntax.h
 737-cmd/posix/sh/miscbltin.o: cmd/posix/sh/trap.h
 738-cmd/posix/sh/mknodes.o: cmd/posix/sh/mknodes.c
 739-cmd/posix/sh/mksyntax.o: cmd/posix/sh/mksyntax.c
 740-cmd/posix/sh/mksyntax.o: cmd/posix/sh/parser.h
 741-cmd/posix/sh/mystring.o: cmd/posix/sh/mystring.c
 742-cmd/posix/sh/mystring.o: cmd/posix/sh/shell.h
 743-cmd/posix/sh/mystring.o: shared/sig.h
 744-cmd/posix/sh/mystring.o: cmd/posix/sh/syntax.h
 745-cmd/posix/sh/mystring.o: cmd/posix/sh/error.h
 746-cmd/posix/sh/mystring.o: cmd/posix/sh/mystring.h
 747-cmd/posix/sh/options.o: cmd/posix/sh/options.c
 748-cmd/posix/sh/options.o: cmd/posix/sh/shell.h
 749-cmd/posix/sh/options.o: shared/sig.h
 750-cmd/posix/sh/options.o: cmd/posix/sh/options.h
 751-cmd/posix/sh/options.o: cmd/posix/sh/nodes.h
 752-cmd/posix/sh/options.o: cmd/posix/sh/eval.h
 753-cmd/posix/sh/options.o: cmd/posix/sh/jobs.h
 754-cmd/posix/sh/options.o: cmd/posix/sh/input.h
 755-cmd/posix/sh/options.o: cmd/posix/sh/output.h
 756-cmd/posix/sh/options.o: cmd/posix/sh/trap.h
 757-cmd/posix/sh/options.o: cmd/posix/sh/var.h
 758-cmd/posix/sh/options.o: cmd/posix/sh/memalloc.h
 759-cmd/posix/sh/options.o: cmd/posix/sh/error.h
 760-cmd/posix/sh/options.o: cmd/posix/sh/mystring.h
 761-cmd/posix/sh/options.o: cmd/posix/sh/builtins.h
 762-cmd/posix/sh/output.o: cmd/posix/sh/output.c
 763-cmd/posix/sh/output.o: cmd/posix/sh/shell.h
 764-cmd/posix/sh/output.o: shared/sig.h
 765-cmd/posix/sh/output.o: cmd/posix/sh/syntax.h
 766-cmd/posix/sh/output.o: cmd/posix/sh/output.h
 767-cmd/posix/sh/output.o: cmd/posix/sh/memalloc.h
 768-cmd/posix/sh/output.o: cmd/posix/sh/error.h
 769-cmd/posix/sh/output.o: cmd/posix/sh/var.h
 770-cmd/posix/sh/parser.o: cmd/posix/sh/parser.c
 771-cmd/posix/sh/parser.o: cmd/posix/sh/shell.h
 772-cmd/posix/sh/parser.o: shared/sig.h
 773-cmd/posix/sh/parser.o: cmd/posix/sh/parser.h
 774-cmd/posix/sh/parser.o: cmd/posix/sh/nodes.h
 775-cmd/posix/sh/parser.o: cmd/posix/sh/expand.h
 776-cmd/posix/sh/parser.o: cmd/posix/sh/syntax.h
 777-cmd/posix/sh/parser.o: cmd/posix/sh/options.h
 778-cmd/posix/sh/parser.o: cmd/posix/sh/input.h
 779-cmd/posix/sh/parser.o: cmd/posix/sh/output.h
 780-cmd/posix/sh/parser.o: cmd/posix/sh/var.h
 781-cmd/posix/sh/parser.o: cmd/posix/sh/error.h
 782-cmd/posix/sh/parser.o: cmd/posix/sh/memalloc.h
 783-cmd/posix/sh/parser.o: cmd/posix/sh/mystring.h
 784-cmd/posix/sh/parser.o: cmd/posix/sh/alias.h
 785-cmd/posix/sh/parser.o: cmd/posix/sh/show.h
 786-cmd/posix/sh/parser.o: cmd/posix/sh/eval.h
 787-cmd/posix/sh/parser.o: cmd/posix/sh/exec.h
 788-cmd/posix/sh/parser.o: cmd/posix/sh/main.h
 789-cmd/posix/sh/parser.o: cmd/posix/sh/jobs.h
 790-cmd/posix/sh/parser.o: cmd/posix/sh/token.h
 791-cmd/posix/sh/printf.o: cmd/posix/sh/printf.c
 792-cmd/posix/sh/redir.o: cmd/posix/sh/redir.c
 793-cmd/posix/sh/redir.o: cmd/posix/sh/shell.h
 794-cmd/posix/sh/redir.o: shared/sig.h
 795-cmd/posix/sh/redir.o: cmd/posix/sh/nodes.h
 796-cmd/posix/sh/redir.o: cmd/posix/sh/jobs.h
 797-cmd/posix/sh/redir.o: cmd/posix/sh/expand.h
 798-cmd/posix/sh/redir.o: cmd/posix/sh/redir.h
 799-cmd/posix/sh/redir.o: cmd/posix/sh/output.h
 800-cmd/posix/sh/redir.o: cmd/posix/sh/memalloc.h
 801-cmd/posix/sh/redir.o: cmd/posix/sh/error.h
 802-cmd/posix/sh/redir.o: cmd/posix/sh/options.h
 803-cmd/posix/sh/show.o: cmd/posix/sh/show.c
 804-cmd/posix/sh/show.o: cmd/posix/sh/shell.h
 805-cmd/posix/sh/show.o: shared/sig.h
 806-cmd/posix/sh/show.o: cmd/posix/sh/parser.h
 807-cmd/posix/sh/show.o: cmd/posix/sh/nodes.h
 808-cmd/posix/sh/show.o: cmd/posix/sh/mystring.h
 809-cmd/posix/sh/show.o: cmd/posix/sh/show.h
 810-cmd/posix/sh/test.o: cmd/posix/sh/test.c
 811-cmd/posix/sh/trap.o: cmd/posix/sh/trap.c
 812-cmd/posix/sh/trap.o: cmd/posix/sh/shell.h
 813-cmd/posix/sh/trap.o: shared/sig.h
 814-cmd/posix/sh/trap.o: cmd/posix/sh/main.h
 815-cmd/posix/sh/trap.o: cmd/posix/sh/nodes.h
 816-cmd/posix/sh/trap.o: cmd/posix/sh/eval.h
 817-cmd/posix/sh/trap.o: cmd/posix/sh/jobs.h
 818-cmd/posix/sh/trap.o: cmd/posix/sh/show.h
 819-cmd/posix/sh/trap.o: cmd/posix/sh/options.h
 820-cmd/posix/sh/trap.o: cmd/posix/sh/syntax.h
 821-cmd/posix/sh/trap.o: cmd/posix/sh/output.h
 822-cmd/posix/sh/trap.o: cmd/posix/sh/memalloc.h
 823-cmd/posix/sh/trap.o: cmd/posix/sh/error.h
 824-cmd/posix/sh/trap.o: cmd/posix/sh/trap.h
 825-cmd/posix/sh/trap.o: cmd/posix/sh/mystring.h
 826-cmd/posix/sh/trap.o: cmd/posix/sh/builtins.h
 827-cmd/posix/sh/var.o: cmd/posix/sh/var.c
 828-cmd/posix/sh/var.o: cmd/posix/sh/shell.h
 829-cmd/posix/sh/var.o: shared/sig.h
 830-cmd/posix/sh/var.o: cmd/posix/sh/output.h
 831-cmd/posix/sh/var.o: cmd/posix/sh/expand.h
 832-cmd/posix/sh/var.o: cmd/posix/sh/nodes.h
 833-cmd/posix/sh/var.o: cmd/posix/sh/eval.h
 834-cmd/posix/sh/var.o: cmd/posix/sh/exec.h
 835-cmd/posix/sh/var.o: cmd/posix/sh/syntax.h
 836-cmd/posix/sh/var.o: cmd/posix/sh/options.h
 837-cmd/posix/sh/var.o: cmd/posix/sh/mail.h
 838-cmd/posix/sh/var.o: cmd/posix/sh/var.h
 839-cmd/posix/sh/var.o: cmd/posix/sh/memalloc.h
 840-cmd/posix/sh/var.o: cmd/posix/sh/error.h
 841-cmd/posix/sh/var.o: cmd/posix/sh/mystring.h
 842-cmd/posix/sh/var.o: cmd/posix/sh/parser.h
 843-cmd/posix/sh/var.o: cmd/posix/sh/builtins.h
 844-cmd/posix/sh/syntax.o: cmd/posix/sh/syntax.c
 845-cmd/posix/sh/syntax.o: cmd/posix/sh/parser.h
 846-cmd/posix/sh/syntax.o: cmd/posix/sh/shell.h
 847-cmd/posix/sh/syntax.o: shared/sig.h
 848-cmd/posix/sh/syntax.o: cmd/posix/sh/syntax.h
 849-cmd/posix/sh/nodes.o: cmd/posix/sh/nodes.c
 850-cmd/posix/sh/nodes.o: cmd/posix/sh/shell.h
 851-cmd/posix/sh/nodes.o: shared/sig.h
 852-cmd/posix/sh/nodes.o: cmd/posix/sh/nodes.h
 853-cmd/posix/sh/nodes.o: cmd/posix/sh/memalloc.h
 854-cmd/posix/sh/nodes.o: cmd/posix/sh/mystring.h
 855-cmd/posix/sh/builtins.o: cmd/posix/sh/builtins.c
 856-cmd/posix/sh/builtins.o: cmd/posix/sh/shell.h
 857-cmd/posix/sh/builtins.o: shared/sig.h
 858-cmd/posix/sh/builtins.o: cmd/posix/sh/builtins.h
 859-cmd/posix/sleep.o: cmd/posix/sleep.c
 860-cmd/posix/sleep.o: shared/util.h
 861-cmd/posix/sleep.o: shared/arg.h
 862-cmd/posix/sleep.o: shared/compat.h
 863-cmd/posix/sort.o: cmd/posix/sort.c
 864-cmd/posix/sort.o: shared/queue.h
 865-cmd/posix/sort.o: shared/text.h
 866-cmd/posix/sort.o: shared/utf.h
 867-cmd/posix/sort.o: shared/util.h
 868-cmd/posix/sort.o: shared/arg.h
 869-cmd/posix/sort.o: shared/compat.h
 870-cmd/posix/split.o: cmd/posix/split.c
 871-cmd/posix/split.o: shared/util.h
 872-cmd/posix/split.o: shared/arg.h
 873-cmd/posix/split.o: shared/compat.h
 874-cmd/posix/tail.o: cmd/posix/tail.c
 875-cmd/posix/tail.o: shared/utf.h
 876-cmd/posix/tail.o: shared/util.h
 877-cmd/posix/tail.o: shared/arg.h
 878-cmd/posix/tail.o: shared/compat.h
 879-cmd/posix/tee.o: cmd/posix/tee.c
 880-cmd/posix/tee.o: shared/util.h
 881-cmd/posix/tee.o: shared/arg.h
 882-cmd/posix/tee.o: shared/compat.h
 883-cmd/posix/test.o: cmd/posix/test.c
 884-cmd/posix/test.o: shared/util.h
 885-cmd/posix/test.o: shared/arg.h
 886-cmd/posix/test.o: shared/compat.h
 887-cmd/posix/touch.o: cmd/posix/touch.c
 888-cmd/posix/touch.o: shared/util.h
 889-cmd/posix/touch.o: shared/arg.h
 890-cmd/posix/touch.o: shared/compat.h
 891-cmd/posix/true.o: cmd/posix/true.c
 892-cmd/posix/tsort.o: cmd/posix/tsort.c
 893-cmd/posix/tsort.o: shared/util.h
 894-cmd/posix/tsort.o: shared/arg.h
 895-cmd/posix/tsort.o: shared/compat.h
 896-cmd/posix/tty.o: cmd/posix/tty.c
 897-cmd/posix/tty.o: shared/util.h
 898-cmd/posix/tty.o: shared/arg.h
 899-cmd/posix/tty.o: shared/compat.h
 900-cmd/posix/uname.o: cmd/posix/uname.c
 901-cmd/posix/uname.o: shared/util.h
 902-cmd/posix/uname.o: shared/arg.h
 903-cmd/posix/uname.o: shared/compat.h
 904-cmd/posix/unexpand.o: cmd/posix/unexpand.c
 905-cmd/posix/unexpand.o: shared/utf.h
 906-cmd/posix/unexpand.o: shared/util.h
 907-cmd/posix/unexpand.o: shared/arg.h
 908-cmd/posix/unexpand.o: shared/compat.h
 909-cmd/posix/uniq.o: cmd/posix/uniq.c
 910-cmd/posix/uniq.o: shared/text.h
 911-cmd/posix/uniq.o: shared/util.h
 912-cmd/posix/uniq.o: shared/arg.h
 913-cmd/posix/uniq.o: shared/compat.h
 914-cmd/posix/unlink.o: cmd/posix/unlink.c
 915-cmd/posix/unlink.o: shared/util.h
 916-cmd/posix/unlink.o: shared/arg.h
 917-cmd/posix/unlink.o: shared/compat.h
 918-cmd/posix/uudecode.o: cmd/posix/uudecode.c
 919-cmd/posix/uudecode.o: shared/util.h
 920-cmd/posix/uudecode.o: shared/arg.h
 921-cmd/posix/uudecode.o: shared/compat.h
 922-cmd/posix/wc.o: cmd/posix/wc.c
 923-cmd/posix/wc.o: shared/utf.h
 924-cmd/posix/wc.o: shared/util.h
 925-cmd/posix/wc.o: shared/arg.h
 926-cmd/posix/wc.o: shared/compat.h
 927-cmd/posix/who.o: cmd/posix/who.c
 928-cmd/posix/who.o: shared/config.h
 929-cmd/posix/who.o: shared/util.h
 930-cmd/posix/who.o: shared/arg.h
 931-cmd/posix/who.o: shared/compat.h
 932-cmd/posix/xargs.o: cmd/posix/xargs.c
 933-cmd/posix/xargs.o: shared/util.h
 934-cmd/posix/xargs.o: shared/arg.h
 935-cmd/posix/xargs.o: shared/compat.h
 936-cmd/posix/basename.o: cmd/posix/basename.c
 937-cmd/posix/basename.o: shared/util.h
 938-cmd/posix/basename.o: shared/arg.h
 939-cmd/posix/basename.o: shared/compat.h
 940-cmd/posix/cut.o: cmd/posix/cut.c
 941-cmd/posix/cut.o: shared/text.h
 942-cmd/posix/cut.o: shared/utf.h
 943-cmd/posix/cut.o: shared/util.h
 944-cmd/posix/cut.o: shared/arg.h
 945-cmd/posix/cut.o: shared/compat.h
 946-cmd/posix/date.o: cmd/posix/date.c
 947-cmd/posix/date.o: shared/util.h
 948-cmd/posix/date.o: shared/arg.h
 949-cmd/posix/date.o: shared/compat.h
 950-cmd/posix/diff.o: cmd/posix/diff.c shared/util.h shared/arg.h shared/compat.h
 951-cmd/posix/env.o: cmd/posix/env.c
 952-cmd/posix/env.o: shared/util.h
 953-cmd/posix/env.o: shared/arg.h
 954-cmd/posix/env.o: shared/compat.h
 955-cmd/posix/find.o: cmd/posix/find.c
 956-cmd/posix/find.o: shared/config.h
 957-cmd/posix/find.o: shared/util.h
 958-cmd/posix/find.o: shared/arg.h
 959-cmd/posix/find.o: shared/compat.h
 960-cmd/posix/getconf.o: cmd/posix/getconf.c
 961-cmd/posix/getconf.o: shared/util.h
 962-cmd/posix/getconf.o: shared/arg.h
 963-cmd/posix/getconf.o: shared/compat.h
 964-cmd/posix/getconf.o: cmd/posix/getconf.h
 965-cmd/posix/grep.o: cmd/posix/grep.c
 966-cmd/posix/grep.o: shared/config.h
 967-cmd/posix/grep.o: shared/queue.h
 968-cmd/posix/grep.o: shared/util.h
 969-cmd/posix/grep.o: shared/arg.h
 970-cmd/posix/grep.o: shared/compat.h
 971-cmd/posix/ln.o: cmd/posix/ln.c
 972-cmd/posix/ln.o: shared/util.h
 973-cmd/posix/ln.o: shared/arg.h
 974-cmd/posix/ln.o: shared/compat.h
 975-cmd/posix/ls.o: cmd/posix/ls.c
 976-cmd/posix/ls.o: shared/utf.h
 977-cmd/posix/ls.o: shared/util.h
 978-cmd/posix/ls.o: shared/arg.h
 979-cmd/posix/ls.o: shared/compat.h
 980-cmd/posix/nice.o: cmd/posix/nice.c
 981-cmd/posix/nice.o: shared/util.h
 982-cmd/posix/nice.o: shared/arg.h
 983-cmd/posix/nice.o: shared/compat.h
 984-cmd/posix/nohup.o: cmd/posix/nohup.c
 985-cmd/posix/nohup.o: shared/util.h
 986-cmd/posix/nohup.o: shared/arg.h
 987-cmd/posix/nohup.o: shared/compat.h
 988-cmd/posix/printf.o: cmd/posix/printf.c
 989-cmd/posix/printf.o: shared/utf.h
 990-cmd/posix/printf.o: shared/util.h
 991-cmd/posix/printf.o: shared/arg.h
 992-cmd/posix/printf.o: shared/compat.h
 993-cmd/posix/sed.o: cmd/posix/sed.c
 994-cmd/posix/sed.o: shared/config.h
 995-cmd/posix/sed.o: shared/utf.h
 996-cmd/posix/sed.o: shared/util.h
 997-cmd/posix/sed.o: shared/arg.h
 998-cmd/posix/sed.o: shared/compat.h
 999-cmd/posix/time.o: cmd/posix/time.c
1000-cmd/posix/time.o: shared/util.h
1001-cmd/posix/time.o: shared/arg.h
1002-cmd/posix/time.o: shared/compat.h
1003-cmd/posix/tr.o: cmd/posix/tr.c
1004-cmd/posix/tr.o: shared/utf.h
1005-cmd/posix/tr.o: shared/util.h
1006-cmd/posix/tr.o: shared/arg.h
1007-cmd/posix/tr.o: shared/compat.h
1008-cmd/posix/uuencode.o: cmd/posix/uuencode.c
1009-cmd/posix/uuencode.o: shared/util.h
1010-cmd/posix/uuencode.o: shared/arg.h
1011-cmd/posix/uuencode.o: shared/compat.h
1012-cmd/posix/patch.o: cmd/posix/patch.c shared/util.h shared/arg.h shared/compat.h
1013-cmd/posix/diff3.o: cmd/posix/diff3.c shared/util.h shared/arg.h shared/compat.h
1014-cmd/pseudo/mkpasswd.o: cmd/pseudo/mkpasswd.c shared/util.h shared/arg.h shared/compat.h
1015-cmd/pseudo/base64.o: cmd/pseudo/base64.c
1016-cmd/pseudo/base64.o: shared/util.h
1017-cmd/pseudo/base64.o: shared/arg.h
1018-cmd/pseudo/base64.o: shared/compat.h
1019-cmd/pseudo/base64.o: shared/arg.h
1020+cmd/linux/insmod.o: cmd/linux/insmod.c
1021+cmd/linux/insmod.o: shared/util.h
1022+cmd/linux/insmod.o: shared/arg.h
1023+cmd/linux/insmod.o: shared/compat.h
1024 cmd/pseudo/clear.o: cmd/pseudo/clear.c
1025 cmd/pseudo/clear.o: shared/util.h
1026 cmd/pseudo/clear.o: shared/arg.h
1027 cmd/pseudo/clear.o: shared/compat.h
1028-cmd/pseudo/cols.o: cmd/pseudo/cols.c
1029-cmd/pseudo/cols.o: shared/text.h
1030-cmd/pseudo/cols.o: shared/util.h
1031-cmd/pseudo/cols.o: shared/arg.h
1032-cmd/pseudo/cols.o: shared/compat.h
1033-cmd/pseudo/cron.o: cmd/pseudo/cron.c
1034-cmd/pseudo/cron.o: shared/queue.h
1035-cmd/pseudo/cron.o: shared/util.h
1036-cmd/pseudo/cron.o: shared/arg.h
1037-cmd/pseudo/cron.o: shared/compat.h
1038-cmd/pseudo/dmesg.o: cmd/pseudo/dmesg.c
1039-cmd/pseudo/dmesg.o: shared/util.h
1040-cmd/pseudo/dmesg.o: shared/arg.h
1041-cmd/pseudo/dmesg.o: shared/compat.h
1042-cmd/pseudo/fallocate.o: cmd/pseudo/fallocate.c
1043-cmd/pseudo/fallocate.o: shared/util.h
1044-cmd/pseudo/fallocate.o: shared/arg.h
1045-cmd/pseudo/fallocate.o: shared/compat.h
1046-cmd/pseudo/free.o: cmd/pseudo/free.c
1047-cmd/pseudo/free.o: shared/util.h
1048-cmd/pseudo/free.o: shared/arg.h
1049-cmd/pseudo/free.o: shared/compat.h
1050-cmd/pseudo/halt.o: cmd/pseudo/halt.c
1051-cmd/pseudo/halt.o: shared/reboot.h
1052-cmd/pseudo/halt.o: shared/util.h
1053-cmd/pseudo/halt.o: shared/arg.h
1054-cmd/pseudo/halt.o: shared/compat.h
1055-cmd/pseudo/hostname.o: cmd/pseudo/hostname.c
1056-cmd/pseudo/hostname.o: shared/util.h
1057-cmd/pseudo/hostname.o: shared/arg.h
1058-cmd/pseudo/hostname.o: shared/compat.h
1059-cmd/pseudo/killall5.o: cmd/pseudo/killall5.c
1060-cmd/pseudo/killall5.o: shared/proc.h
1061-cmd/pseudo/killall5.o: shared/queue.h
1062-cmd/pseudo/killall5.o: shared/util.h
1063-cmd/pseudo/killall5.o: shared/arg.h
1064-cmd/pseudo/killall5.o: shared/compat.h
1065+cmd/pseudo/yes.o: cmd/pseudo/yes.c
1066+cmd/pseudo/yes.o: shared/util.h
1067+cmd/pseudo/yes.o: shared/arg.h
1068+cmd/pseudo/yes.o: shared/compat.h
1069+cmd/pseudo/sponge.o: cmd/pseudo/sponge.c
1070+cmd/pseudo/sponge.o: shared/util.h
1071+cmd/pseudo/sponge.o: shared/arg.h
1072+cmd/pseudo/sponge.o: shared/compat.h
1073 cmd/pseudo/last.o: cmd/pseudo/last.c
1074 cmd/pseudo/last.o: shared/config.h
1075+cmd/pseudo/last.o: shared/paths.h
1076 cmd/pseudo/last.o: shared/util.h
1077 cmd/pseudo/last.o: shared/arg.h
1078 cmd/pseudo/last.o: shared/compat.h
1079+cmd/pseudo/truncate.o: cmd/pseudo/truncate.c
1080+cmd/pseudo/truncate.o: shared/util.h
1081+cmd/pseudo/truncate.o: shared/arg.h
1082+cmd/pseudo/truncate.o: shared/compat.h
1083+cmd/pseudo/xinstall.o: cmd/pseudo/xinstall.c
1084+cmd/pseudo/xinstall.o: shared/util.h
1085+cmd/pseudo/xinstall.o: shared/arg.h
1086+cmd/pseudo/xinstall.o: shared/compat.h
1087 cmd/pseudo/lastlog.o: cmd/pseudo/lastlog.c
1088 cmd/pseudo/lastlog.o: shared/text.h
1089 cmd/pseudo/lastlog.o: shared/util.h
1090 cmd/pseudo/lastlog.o: shared/arg.h
1091 cmd/pseudo/lastlog.o: shared/compat.h
1092+cmd/pseudo/base64.o: cmd/pseudo/base64.c
1093+cmd/pseudo/base64.o: shared/util.h
1094+cmd/pseudo/base64.o: shared/arg.h
1095+cmd/pseudo/base64.o: shared/compat.h
1096+cmd/pseudo/base64.o: shared/arg.h
1097+cmd/pseudo/sha384sum.o: cmd/pseudo/sha384sum.c
1098+cmd/pseudo/sha384sum.o: shared/crypt.h
1099+cmd/pseudo/sha384sum.o: shared/sha384.h
1100+cmd/pseudo/sha384sum.o: shared/sha512.h
1101+cmd/pseudo/sha384sum.o: shared/util.h
1102+cmd/pseudo/sha384sum.o: shared/arg.h
1103+cmd/pseudo/sha384sum.o: shared/compat.h
1104+cmd/pseudo/getty.o: cmd/pseudo/getty.c
1105+cmd/pseudo/getty.o: shared/config.h
1106+cmd/pseudo/getty.o: shared/paths.h
1107+cmd/pseudo/getty.o: shared/wexec.h
1108+cmd/pseudo/getty.o: shared/util.h
1109+cmd/pseudo/getty.o: shared/arg.h
1110+cmd/pseudo/getty.o: shared/compat.h
1111+cmd/pseudo/flock.o: cmd/pseudo/flock.c
1112+cmd/pseudo/flock.o: shared/wexec.h
1113+cmd/pseudo/flock.o: shared/util.h
1114+cmd/pseudo/flock.o: shared/arg.h
1115+cmd/pseudo/flock.o: shared/compat.h
1116+cmd/pseudo/pwdx.o: cmd/pseudo/pwdx.c
1117+cmd/pseudo/pwdx.o: shared/util.h
1118+cmd/pseudo/pwdx.o: shared/arg.h
1119+cmd/pseudo/pwdx.o: shared/compat.h
1120+cmd/pseudo/sha512sum.o: cmd/pseudo/sha512sum.c
1121+cmd/pseudo/sha512sum.o: shared/crypt.h
1122+cmd/pseudo/sha512sum.o: shared/sha512.h
1123+cmd/pseudo/sha512sum.o: shared/util.h
1124+cmd/pseudo/sha512sum.o: shared/arg.h
1125+cmd/pseudo/sha512sum.o: shared/compat.h
1126+cmd/pseudo/hostname.o: cmd/pseudo/hostname.c
1127+cmd/pseudo/hostname.o: shared/util.h
1128+cmd/pseudo/hostname.o: shared/arg.h
1129+cmd/pseudo/hostname.o: shared/compat.h
1130 cmd/pseudo/login.o: cmd/pseudo/login.c
1131 cmd/pseudo/login.o: shared/config.h
1132+cmd/pseudo/login.o: shared/paths.h
1133 cmd/pseudo/login.o: shared/passwd.h
1134+cmd/pseudo/login.o: shared/wexec.h
1135 cmd/pseudo/login.o: shared/util.h
1136 cmd/pseudo/login.o: shared/arg.h
1137 cmd/pseudo/login.o: shared/compat.h
1138-cmd/pseudo/md5sum.o: cmd/pseudo/md5sum.c
1139-cmd/pseudo/md5sum.o: shared/crypt.h
1140-cmd/pseudo/md5sum.o: shared/md5.h
1141-cmd/pseudo/md5sum.o: shared/util.h
1142-cmd/pseudo/md5sum.o: shared/arg.h
1143-cmd/pseudo/md5sum.o: shared/compat.h
1144-cmd/pseudo/mktemp.o: cmd/pseudo/mktemp.c
1145-cmd/pseudo/mktemp.o: shared/util.h
1146-cmd/pseudo/mktemp.o: shared/arg.h
1147-cmd/pseudo/mktemp.o: shared/compat.h
1148-cmd/pseudo/nologin.o: cmd/pseudo/nologin.c
1149-cmd/pseudo/pagesize.o: cmd/pseudo/pagesize.c
1150-cmd/pseudo/pagesize.o: shared/util.h
1151-cmd/pseudo/pagesize.o: shared/arg.h
1152-cmd/pseudo/pagesize.o: shared/compat.h
1153-cmd/pseudo/pidof.o: cmd/pseudo/pidof.c
1154-cmd/pseudo/pidof.o: shared/proc.h
1155-cmd/pseudo/pidof.o: shared/queue.h
1156-cmd/pseudo/pidof.o: shared/util.h
1157-cmd/pseudo/pidof.o: shared/arg.h
1158-cmd/pseudo/pidof.o: shared/compat.h
1159+cmd/pseudo/chroot.o: cmd/pseudo/chroot.c
1160+cmd/pseudo/chroot.o: shared/wexec.h
1161+cmd/pseudo/chroot.o: shared/util.h
1162+cmd/pseudo/chroot.o: shared/arg.h
1163+cmd/pseudo/chroot.o: shared/compat.h
1164 cmd/pseudo/printenv.o: cmd/pseudo/printenv.c
1165 cmd/pseudo/printenv.o: shared/util.h
1166 cmd/pseudo/printenv.o: shared/arg.h
1167 cmd/pseudo/printenv.o: shared/compat.h
1168-cmd/pseudo/pwdx.o: cmd/pseudo/pwdx.c
1169-cmd/pseudo/pwdx.o: shared/util.h
1170-cmd/pseudo/pwdx.o: shared/arg.h
1171-cmd/pseudo/pwdx.o: shared/compat.h
1172-cmd/pseudo/rev.o: cmd/pseudo/rev.c
1173-cmd/pseudo/rev.o: shared/text.h
1174-cmd/pseudo/rev.o: shared/util.h
1175-cmd/pseudo/rev.o: shared/arg.h
1176-cmd/pseudo/rev.o: shared/compat.h
1177-cmd/pseudo/seq.o: cmd/pseudo/seq.c
1178-cmd/pseudo/seq.o: shared/util.h
1179-cmd/pseudo/seq.o: shared/arg.h
1180-cmd/pseudo/seq.o: shared/compat.h
1181 cmd/pseudo/sha1sum.o: cmd/pseudo/sha1sum.c
1182 cmd/pseudo/sha1sum.o: shared/crypt.h
1183 cmd/pseudo/sha1sum.o: shared/sha1.h
1184 cmd/pseudo/sha1sum.o: shared/util.h
1185 cmd/pseudo/sha1sum.o: shared/arg.h
1186 cmd/pseudo/sha1sum.o: shared/compat.h
1187+cmd/pseudo/sha256sum.o: cmd/pseudo/sha256sum.c
1188+cmd/pseudo/sha256sum.o: shared/crypt.h
1189+cmd/pseudo/sha256sum.o: shared/sha256.h
1190+cmd/pseudo/sha256sum.o: shared/util.h
1191+cmd/pseudo/sha256sum.o: shared/arg.h
1192+cmd/pseudo/sha256sum.o: shared/compat.h
1193+cmd/pseudo/nologin.o: cmd/pseudo/nologin.c
1194+cmd/pseudo/mktemp.o: cmd/pseudo/mktemp.c
1195+cmd/pseudo/mktemp.o: shared/util.h
1196+cmd/pseudo/mktemp.o: shared/arg.h
1197+cmd/pseudo/mktemp.o: shared/compat.h
1198+cmd/pseudo/uptime.o: cmd/pseudo/uptime.c
1199+cmd/pseudo/uptime.o: shared/config.h
1200+cmd/pseudo/uptime.o: shared/paths.h
1201+cmd/pseudo/uptime.o: shared/util.h
1202+cmd/pseudo/uptime.o: shared/arg.h
1203+cmd/pseudo/uptime.o: shared/compat.h
1204 cmd/pseudo/sha224sum.o: cmd/pseudo/sha224sum.c
1205 cmd/pseudo/sha224sum.o: shared/crypt.h
1206 cmd/pseudo/sha224sum.o: shared/sha224.h
1207@@ -1031,26 +246,39 @@ cmd/pseudo/sha224sum.o: shared/sha256.h
1208 cmd/pseudo/sha224sum.o: shared/util.h
1209 cmd/pseudo/sha224sum.o: shared/arg.h
1210 cmd/pseudo/sha224sum.o: shared/compat.h
1211-cmd/pseudo/sha256sum.o: cmd/pseudo/sha256sum.c
1212-cmd/pseudo/sha256sum.o: shared/crypt.h
1213-cmd/pseudo/sha256sum.o: shared/sha256.h
1214-cmd/pseudo/sha256sum.o: shared/util.h
1215-cmd/pseudo/sha256sum.o: shared/arg.h
1216-cmd/pseudo/sha256sum.o: shared/compat.h
1217-cmd/pseudo/sha384sum.o: cmd/pseudo/sha384sum.c
1218-cmd/pseudo/sha384sum.o: shared/crypt.h
1219-cmd/pseudo/sha384sum.o: shared/sha384.h
1220-cmd/pseudo/sha384sum.o: shared/sha512.h
1221-cmd/pseudo/sha384sum.o: shared/util.h
1222-cmd/pseudo/sha384sum.o: shared/arg.h
1223-cmd/pseudo/sha384sum.o: shared/compat.h
1224-cmd/pseudo/sha512-224sum.o: cmd/pseudo/sha512-224sum.c
1225-cmd/pseudo/sha512-224sum.o: shared/crypt.h
1226-cmd/pseudo/sha512-224sum.o: shared/sha512-224.h
1227-cmd/pseudo/sha512-224sum.o: shared/sha512.h
1228-cmd/pseudo/sha512-224sum.o: shared/util.h
1229-cmd/pseudo/sha512-224sum.o: shared/arg.h
1230-cmd/pseudo/sha512-224sum.o: shared/compat.h
1231+cmd/pseudo/halt.o: cmd/pseudo/halt.c
1232+cmd/pseudo/halt.o: shared/reboot.h
1233+cmd/pseudo/halt.o: shared/util.h
1234+cmd/pseudo/halt.o: shared/arg.h
1235+cmd/pseudo/halt.o: shared/compat.h
1236+cmd/pseudo/mkpasswd.o: cmd/pseudo/mkpasswd.c
1237+cmd/pseudo/mkpasswd.o: shared/passwd.h
1238+cmd/pseudo/mkpasswd.o: shared/paths.h
1239+cmd/pseudo/mkpasswd.o: shared/util.h
1240+cmd/pseudo/mkpasswd.o: shared/arg.h
1241+cmd/pseudo/mkpasswd.o: shared/compat.h
1242+cmd/pseudo/setsid.o: cmd/pseudo/setsid.c
1243+cmd/pseudo/setsid.o: shared/wexec.h
1244+cmd/pseudo/setsid.o: shared/util.h
1245+cmd/pseudo/setsid.o: shared/arg.h
1246+cmd/pseudo/setsid.o: shared/compat.h
1247+cmd/pseudo/fallocate.o: cmd/pseudo/fallocate.c
1248+cmd/pseudo/fallocate.o: shared/util.h
1249+cmd/pseudo/fallocate.o: shared/arg.h
1250+cmd/pseudo/fallocate.o: shared/compat.h
1251+cmd/pseudo/seq.o: cmd/pseudo/seq.c
1252+cmd/pseudo/seq.o: shared/util.h
1253+cmd/pseudo/seq.o: shared/arg.h
1254+cmd/pseudo/seq.o: shared/compat.h
1255+cmd/pseudo/cols.o: cmd/pseudo/cols.c
1256+cmd/pseudo/cols.o: shared/text.h
1257+cmd/pseudo/cols.o: shared/util.h
1258+cmd/pseudo/cols.o: shared/arg.h
1259+cmd/pseudo/cols.o: shared/compat.h
1260+cmd/pseudo/whoami.o: cmd/pseudo/whoami.c
1261+cmd/pseudo/whoami.o: shared/util.h
1262+cmd/pseudo/whoami.o: shared/arg.h
1263+cmd/pseudo/whoami.o: shared/compat.h
1264 cmd/pseudo/sha512-256sum.o: cmd/pseudo/sha512-256sum.c
1265 cmd/pseudo/sha512-256sum.o: shared/crypt.h
1266 cmd/pseudo/sha512-256sum.o: shared/sha512-256.h
1267@@ -1058,360 +286,850 @@ cmd/pseudo/sha512-256sum.o: shared/sha512.h
1268 cmd/pseudo/sha512-256sum.o: shared/util.h
1269 cmd/pseudo/sha512-256sum.o: shared/arg.h
1270 cmd/pseudo/sha512-256sum.o: shared/compat.h
1271-cmd/pseudo/sha512sum.o: cmd/pseudo/sha512sum.c
1272-cmd/pseudo/sha512sum.o: shared/crypt.h
1273-cmd/pseudo/sha512sum.o: shared/sha512.h
1274-cmd/pseudo/sha512sum.o: shared/util.h
1275-cmd/pseudo/sha512sum.o: shared/arg.h
1276-cmd/pseudo/sha512sum.o: shared/compat.h
1277-cmd/pseudo/sponge.o: cmd/pseudo/sponge.c
1278-cmd/pseudo/sponge.o: shared/util.h
1279-cmd/pseudo/sponge.o: shared/arg.h
1280-cmd/pseudo/sponge.o: shared/compat.h
1281+cmd/pseudo/pidof.o: cmd/pseudo/pidof.c
1282+cmd/pseudo/pidof.o: shared/proc.h
1283+cmd/pseudo/pidof.o: shared/queue.h
1284+cmd/pseudo/pidof.o: shared/util.h
1285+cmd/pseudo/pidof.o: shared/arg.h
1286+cmd/pseudo/pidof.o: shared/compat.h
1287+cmd/pseudo/pagesize.o: cmd/pseudo/pagesize.c
1288+cmd/pseudo/pagesize.o: shared/util.h
1289+cmd/pseudo/pagesize.o: shared/arg.h
1290+cmd/pseudo/pagesize.o: shared/compat.h
1291+cmd/pseudo/killall5.o: cmd/pseudo/killall5.c
1292+cmd/pseudo/killall5.o: shared/proc.h
1293+cmd/pseudo/killall5.o: shared/queue.h
1294+cmd/pseudo/killall5.o: shared/util.h
1295+cmd/pseudo/killall5.o: shared/arg.h
1296+cmd/pseudo/killall5.o: shared/compat.h
1297+cmd/pseudo/sha512-224sum.o: cmd/pseudo/sha512-224sum.c
1298+cmd/pseudo/sha512-224sum.o: shared/crypt.h
1299+cmd/pseudo/sha512-224sum.o: shared/sha512-224.h
1300+cmd/pseudo/sha512-224sum.o: shared/sha512.h
1301+cmd/pseudo/sha512-224sum.o: shared/util.h
1302+cmd/pseudo/sha512-224sum.o: shared/arg.h
1303+cmd/pseudo/sha512-224sum.o: shared/compat.h
1304 cmd/pseudo/stat.o: cmd/pseudo/stat.c
1305 cmd/pseudo/stat.o: shared/config.h
1306+cmd/pseudo/stat.o: shared/paths.h
1307 cmd/pseudo/stat.o: shared/util.h
1308 cmd/pseudo/stat.o: shared/arg.h
1309 cmd/pseudo/stat.o: shared/compat.h
1310-cmd/pseudo/truncate.o: cmd/pseudo/truncate.c
1311-cmd/pseudo/truncate.o: shared/util.h
1312-cmd/pseudo/truncate.o: shared/arg.h
1313-cmd/pseudo/truncate.o: shared/compat.h
1314-cmd/pseudo/uptime.o: cmd/pseudo/uptime.c
1315-cmd/pseudo/uptime.o: shared/config.h
1316-cmd/pseudo/uptime.o: shared/util.h
1317-cmd/pseudo/uptime.o: shared/arg.h
1318-cmd/pseudo/uptime.o: shared/compat.h
1319-cmd/pseudo/watch.o: cmd/pseudo/watch.c
1320-cmd/pseudo/watch.o: shared/util.h
1321-cmd/pseudo/watch.o: shared/arg.h
1322-cmd/pseudo/watch.o: shared/compat.h
1323+cmd/pseudo/md5sum.o: cmd/pseudo/md5sum.c
1324+cmd/pseudo/md5sum.o: shared/crypt.h
1325+cmd/pseudo/md5sum.o: shared/md5.h
1326+cmd/pseudo/md5sum.o: shared/util.h
1327+cmd/pseudo/md5sum.o: shared/arg.h
1328+cmd/pseudo/md5sum.o: shared/compat.h
1329+cmd/pseudo/cron.o: cmd/pseudo/cron.c
1330+cmd/pseudo/cron.o: shared/queue.h
1331+cmd/pseudo/cron.o: shared/paths.h
1332+cmd/pseudo/cron.o: shared/wexec.h
1333+cmd/pseudo/cron.o: shared/util.h
1334+cmd/pseudo/cron.o: shared/arg.h
1335+cmd/pseudo/cron.o: shared/compat.h
1336 cmd/pseudo/which.o: cmd/pseudo/which.c
1337 cmd/pseudo/which.o: shared/util.h
1338 cmd/pseudo/which.o: shared/arg.h
1339 cmd/pseudo/which.o: shared/compat.h
1340-cmd/pseudo/whoami.o: cmd/pseudo/whoami.c
1341-cmd/pseudo/whoami.o: shared/util.h
1342-cmd/pseudo/whoami.o: shared/arg.h
1343-cmd/pseudo/whoami.o: shared/compat.h
1344-cmd/pseudo/xinstall.o: cmd/pseudo/xinstall.c
1345-cmd/pseudo/xinstall.o: shared/util.h
1346-cmd/pseudo/xinstall.o: shared/arg.h
1347-cmd/pseudo/xinstall.o: shared/compat.h
1348-cmd/pseudo/yes.o: cmd/pseudo/yes.c
1349-cmd/pseudo/yes.o: shared/util.h
1350-cmd/pseudo/yes.o: shared/arg.h
1351-cmd/pseudo/yes.o: shared/compat.h
1352-cmd/pseudo/chroot.o: cmd/pseudo/chroot.c
1353-cmd/pseudo/chroot.o: shared/util.h
1354-cmd/pseudo/chroot.o: shared/arg.h
1355-cmd/pseudo/chroot.o: shared/compat.h
1356-cmd/pseudo/flock.o: cmd/pseudo/flock.c
1357-cmd/pseudo/flock.o: shared/util.h
1358-cmd/pseudo/flock.o: shared/arg.h
1359-cmd/pseudo/flock.o: shared/compat.h
1360-cmd/pseudo/getty.o: cmd/pseudo/getty.c
1361-cmd/pseudo/getty.o: shared/config.h
1362-cmd/pseudo/getty.o: shared/util.h
1363-cmd/pseudo/getty.o: shared/arg.h
1364-cmd/pseudo/getty.o: shared/compat.h
1365 cmd/pseudo/respawn.o: cmd/pseudo/respawn.c
1366+cmd/pseudo/respawn.o: shared/wexec.h
1367 cmd/pseudo/respawn.o: shared/util.h
1368 cmd/pseudo/respawn.o: shared/arg.h
1369 cmd/pseudo/respawn.o: shared/compat.h
1370-cmd/pseudo/setsid.o: cmd/pseudo/setsid.c
1371-cmd/pseudo/setsid.o: shared/util.h
1372-cmd/pseudo/setsid.o: shared/arg.h
1373-cmd/pseudo/setsid.o: shared/compat.h
1374+cmd/pseudo/free.o: cmd/pseudo/free.c
1375+cmd/pseudo/free.o: shared/util.h
1376+cmd/pseudo/free.o: shared/arg.h
1377+cmd/pseudo/free.o: shared/compat.h
1378+cmd/pseudo/watch.o: cmd/pseudo/watch.c
1379+cmd/pseudo/watch.o: shared/wexec.h
1380+cmd/pseudo/watch.o: shared/util.h
1381+cmd/pseudo/watch.o: shared/arg.h
1382+cmd/pseudo/watch.o: shared/compat.h
1383+cmd/pseudo/dmesg.o: cmd/pseudo/dmesg.c
1384+cmd/pseudo/dmesg.o: shared/util.h
1385+cmd/pseudo/dmesg.o: shared/arg.h
1386+cmd/pseudo/dmesg.o: shared/compat.h
1387+cmd/pseudo/rev.o: cmd/pseudo/rev.c
1388+cmd/pseudo/rev.o: shared/text.h
1389+cmd/pseudo/rev.o: shared/util.h
1390+cmd/pseudo/rev.o: shared/arg.h
1391+cmd/pseudo/rev.o: shared/compat.h
1392 cmd/pseudo/tar.o: cmd/pseudo/tar.c
1393 cmd/pseudo/tar.o: shared/config.h
1394+cmd/pseudo/tar.o: shared/paths.h
1395 cmd/pseudo/tar.o: shared/fs.h
1396 cmd/pseudo/tar.o: shared/utf.h
1397+cmd/pseudo/tar.o: shared/wexec.h
1398 cmd/pseudo/tar.o: shared/util.h
1399 cmd/pseudo/tar.o: shared/arg.h
1400 cmd/pseudo/tar.o: shared/compat.h
1401+cmd/posix/true.o: cmd/posix/true.c
1402+cmd/posix/paste.o: cmd/posix/paste.c
1403+cmd/posix/paste.o: shared/utf.h
1404+cmd/posix/paste.o: shared/util.h
1405+cmd/posix/paste.o: shared/arg.h
1406+cmd/posix/paste.o: shared/compat.h
1407+cmd/posix/logger.o: cmd/posix/logger.c
1408+cmd/posix/logger.o: shared/util.h
1409+cmd/posix/logger.o: shared/arg.h
1410+cmd/posix/logger.o: shared/compat.h
1411+cmd/posix/pathchk.o: cmd/posix/pathchk.c
1412+cmd/posix/pathchk.o: shared/util.h
1413+cmd/posix/pathchk.o: shared/arg.h
1414+cmd/posix/pathchk.o: shared/compat.h
1415+cmd/posix/make/main.o: cmd/posix/make/main.c
1416+cmd/posix/make/main.o: cmd/posix/make/make.h
1417+cmd/posix/make/main.o: shared/util.h
1418+cmd/posix/make/main.o: shared/arg.h
1419+cmd/posix/make/main.o: shared/compat.h
1420+cmd/posix/make/main.o: shared/wexec.h
1421+cmd/posix/make/parser.o: cmd/posix/make/parser.c
1422+cmd/posix/make/parser.o: cmd/posix/make/make.h
1423+cmd/posix/make/parser.o: shared/util.h
1424+cmd/posix/make/parser.o: shared/arg.h
1425+cmd/posix/make/parser.o: shared/compat.h
1426+cmd/posix/make/parser.o: shared/wexec.h
1427+cmd/posix/make/posix.o: cmd/posix/make/posix.c
1428+cmd/posix/make/posix.o: cmd/posix/make/make.h
1429+cmd/posix/make/posix.o: shared/util.h
1430+cmd/posix/make/posix.o: shared/arg.h
1431+cmd/posix/make/posix.o: shared/compat.h
1432+cmd/posix/make/posix.o: shared/wexec.h
1433+cmd/posix/make/defaults.o: cmd/posix/make/defaults.c
1434+cmd/posix/make/rules.o: cmd/posix/make/rules.c
1435+cmd/posix/make/rules.o: cmd/posix/make/make.h
1436+cmd/posix/make/rules.o: shared/util.h
1437+cmd/posix/make/rules.o: shared/arg.h
1438+cmd/posix/make/rules.o: shared/compat.h
1439+cmd/posix/make/rules.o: shared/wexec.h
1440+cmd/posix/tty.o: cmd/posix/tty.c
1441+cmd/posix/tty.o: shared/util.h
1442+cmd/posix/tty.o: shared/arg.h
1443+cmd/posix/tty.o: shared/compat.h
1444+cmd/posix/od.o: cmd/posix/od.c
1445+cmd/posix/od.o: shared/queue.h
1446+cmd/posix/od.o: shared/util.h
1447+cmd/posix/od.o: shared/arg.h
1448+cmd/posix/od.o: shared/compat.h
1449+cmd/posix/df.o: cmd/posix/df.c
1450+cmd/posix/df.o: shared/util.h
1451+cmd/posix/df.o: shared/arg.h
1452+cmd/posix/df.o: shared/compat.h
1453+cmd/posix/uudecode.o: cmd/posix/uudecode.c
1454+cmd/posix/uudecode.o: shared/util.h
1455+cmd/posix/uudecode.o: shared/arg.h
1456+cmd/posix/uudecode.o: shared/compat.h
1457+cmd/posix/uuencode.o: cmd/posix/uuencode.c
1458+cmd/posix/uuencode.o: shared/util.h
1459+cmd/posix/uuencode.o: shared/arg.h
1460+cmd/posix/uuencode.o: shared/compat.h
1461+cmd/posix/mv.o: cmd/posix/mv.c
1462+cmd/posix/mv.o: shared/fs.h
1463+cmd/posix/mv.o: shared/util.h
1464+cmd/posix/mv.o: shared/arg.h
1465+cmd/posix/mv.o: shared/compat.h
1466+cmd/posix/sed.o: cmd/posix/sed.c
1467+cmd/posix/sed.o: shared/config.h
1468+cmd/posix/sed.o: shared/paths.h
1469+cmd/posix/sed.o: shared/utf.h
1470+cmd/posix/sed.o: shared/util.h
1471+cmd/posix/sed.o: shared/arg.h
1472+cmd/posix/sed.o: shared/compat.h
1473+cmd/posix/nl.o: cmd/posix/nl.c
1474+cmd/posix/nl.o: shared/text.h
1475+cmd/posix/nl.o: shared/utf.h
1476+cmd/posix/nl.o: shared/util.h
1477+cmd/posix/nl.o: shared/arg.h
1478+cmd/posix/nl.o: shared/compat.h
1479+cmd/posix/mesg.o: cmd/posix/mesg.c
1480+cmd/posix/mesg.o: shared/util.h
1481+cmd/posix/mesg.o: shared/arg.h
1482+cmd/posix/mesg.o: shared/compat.h
1483+cmd/posix/id.o: cmd/posix/id.c
1484+cmd/posix/id.o: shared/util.h
1485+cmd/posix/id.o: shared/arg.h
1486+cmd/posix/id.o: shared/compat.h
1487+cmd/posix/find.o: cmd/posix/find.c
1488+cmd/posix/find.o: shared/config.h
1489+cmd/posix/find.o: shared/paths.h
1490+cmd/posix/find.o: shared/wexec.h
1491+cmd/posix/find.o: shared/util.h
1492+cmd/posix/find.o: shared/arg.h
1493+cmd/posix/find.o: shared/compat.h
1494+cmd/posix/ed.o: cmd/posix/ed.c
1495+cmd/posix/ed.o: shared/wexec.h
1496+cmd/posix/ed.o: shared/util.h
1497+cmd/posix/ed.o: shared/arg.h
1498+cmd/posix/ed.o: shared/compat.h
1499+cmd/posix/echo.o: cmd/posix/echo.c
1500+cmd/posix/echo.o: shared/util.h
1501+cmd/posix/echo.o: shared/arg.h
1502+cmd/posix/echo.o: shared/compat.h
1503+cmd/posix/touch.o: cmd/posix/touch.c
1504+cmd/posix/touch.o: shared/util.h
1505+cmd/posix/touch.o: shared/arg.h
1506+cmd/posix/touch.o: shared/compat.h
1507+cmd/posix/chmod.o: cmd/posix/chmod.c
1508+cmd/posix/chmod.o: shared/fs.h
1509+cmd/posix/chmod.o: shared/util.h
1510+cmd/posix/chmod.o: shared/arg.h
1511+cmd/posix/chmod.o: shared/compat.h
1512+cmd/posix/basename.o: cmd/posix/basename.c
1513+cmd/posix/basename.o: shared/util.h
1514+cmd/posix/basename.o: shared/arg.h
1515+cmd/posix/basename.o: shared/compat.h
1516+cmd/posix/sort.o: cmd/posix/sort.c
1517+cmd/posix/sort.o: shared/queue.h
1518+cmd/posix/sort.o: shared/text.h
1519+cmd/posix/sort.o: shared/utf.h
1520+cmd/posix/sort.o: shared/util.h
1521+cmd/posix/sort.o: shared/arg.h
1522+cmd/posix/sort.o: shared/compat.h
1523+cmd/posix/mkfifo.o: cmd/posix/mkfifo.c
1524+cmd/posix/mkfifo.o: shared/util.h
1525+cmd/posix/mkfifo.o: shared/arg.h
1526+cmd/posix/mkfifo.o: shared/compat.h
1527+cmd/posix/getconf.o: cmd/posix/getconf.c
1528+cmd/posix/getconf.o: shared/util.h
1529+cmd/posix/getconf.o: shared/arg.h
1530+cmd/posix/getconf.o: shared/compat.h
1531+cmd/posix/getconf.o: cmd/posix/getconf.h
1532+cmd/posix/tsort.o: cmd/posix/tsort.c
1533+cmd/posix/tsort.o: shared/util.h
1534+cmd/posix/tsort.o: shared/arg.h
1535+cmd/posix/tsort.o: shared/compat.h
1536+cmd/posix/pax.o: cmd/posix/pax.c
1537+cmd/posix/pax.o: shared/arg.h
1538+cmd/posix/grep.o: cmd/posix/grep.c
1539+cmd/posix/grep.o: shared/config.h
1540+cmd/posix/grep.o: shared/paths.h
1541+cmd/posix/grep.o: shared/queue.h
1542+cmd/posix/grep.o: shared/util.h
1543+cmd/posix/grep.o: shared/arg.h
1544+cmd/posix/grep.o: shared/compat.h
1545+cmd/posix/tr.o: cmd/posix/tr.c
1546+cmd/posix/tr.o: shared/utf.h
1547+cmd/posix/tr.o: shared/util.h
1548+cmd/posix/tr.o: shared/arg.h
1549+cmd/posix/tr.o: shared/compat.h
1550+cmd/posix/cmp.o: cmd/posix/cmp.c
1551+cmd/posix/cmp.o: shared/util.h
1552+cmd/posix/cmp.o: shared/arg.h
1553+cmd/posix/cmp.o: shared/compat.h
1554+cmd/posix/diff.o: cmd/posix/diff.c
1555+cmd/posix/diff.o: shared/paths.h
1556+cmd/posix/diff.o: shared/util.h
1557+cmd/posix/diff.o: shared/arg.h
1558+cmd/posix/diff.o: shared/compat.h
1559+cmd/posix/diff.o: shared/wexec.h
1560+cmd/posix/uniq.o: cmd/posix/uniq.c
1561+cmd/posix/uniq.o: shared/text.h
1562+cmd/posix/uniq.o: shared/util.h
1563+cmd/posix/uniq.o: shared/arg.h
1564+cmd/posix/uniq.o: shared/compat.h
1565+cmd/posix/time.o: cmd/posix/time.c
1566+cmd/posix/time.o: shared/wexec.h
1567+cmd/posix/time.o: shared/util.h
1568+cmd/posix/time.o: shared/arg.h
1569+cmd/posix/time.o: shared/compat.h
1570+cmd/posix/renice.o: cmd/posix/renice.c
1571+cmd/posix/renice.o: shared/util.h
1572+cmd/posix/renice.o: shared/arg.h
1573+cmd/posix/renice.o: shared/compat.h
1574+cmd/posix/nice.o: cmd/posix/nice.c
1575+cmd/posix/nice.o: shared/wexec.h
1576+cmd/posix/nice.o: shared/util.h
1577+cmd/posix/nice.o: shared/arg.h
1578+cmd/posix/nice.o: shared/compat.h
1579+cmd/posix/cal.o: cmd/posix/cal.c
1580+cmd/posix/cal.o: shared/util.h
1581+cmd/posix/cal.o: shared/arg.h
1582+cmd/posix/cal.o: shared/compat.h
1583+cmd/posix/cut.o: cmd/posix/cut.c
1584+cmd/posix/cut.o: shared/text.h
1585+cmd/posix/cut.o: shared/utf.h
1586+cmd/posix/cut.o: shared/util.h
1587+cmd/posix/cut.o: shared/arg.h
1588+cmd/posix/cut.o: shared/compat.h
1589+cmd/posix/comm.o: cmd/posix/comm.c
1590+cmd/posix/comm.o: shared/text.h
1591+cmd/posix/comm.o: shared/util.h
1592+cmd/posix/comm.o: shared/arg.h
1593+cmd/posix/comm.o: shared/compat.h
1594+cmd/posix/env.o: cmd/posix/env.c
1595+cmd/posix/env.o: shared/wexec.h
1596+cmd/posix/env.o: shared/util.h
1597+cmd/posix/env.o: shared/arg.h
1598+cmd/posix/env.o: shared/compat.h
1599+cmd/posix/sleep.o: cmd/posix/sleep.c
1600+cmd/posix/sleep.o: shared/util.h
1601+cmd/posix/sleep.o: shared/arg.h
1602+cmd/posix/sleep.o: shared/compat.h
1603+cmd/posix/cksum.o: cmd/posix/cksum.c
1604+cmd/posix/cksum.o: shared/util.h
1605+cmd/posix/cksum.o: shared/arg.h
1606+cmd/posix/cksum.o: shared/compat.h
1607+cmd/posix/diff3.o: cmd/posix/diff3.c
1608+cmd/posix/diff3.o: shared/config.h
1609+cmd/posix/diff3.o: shared/paths.h
1610+cmd/posix/diff3.o: shared/diffutil.h
1611+cmd/posix/diff3.o: shared/util.h
1612+cmd/posix/diff3.o: shared/arg.h
1613+cmd/posix/diff3.o: shared/compat.h
1614+cmd/posix/link.o: cmd/posix/link.c
1615+cmd/posix/link.o: shared/util.h
1616+cmd/posix/link.o: shared/arg.h
1617+cmd/posix/link.o: shared/compat.h
1618+cmd/posix/kill.o: cmd/posix/kill.c
1619+cmd/posix/kill.o: shared/sig.h
1620+cmd/posix/kill.o: shared/util.h
1621+cmd/posix/kill.o: shared/arg.h
1622+cmd/posix/kill.o: shared/compat.h
1623+cmd/posix/mkdir.o: cmd/posix/mkdir.c
1624+cmd/posix/mkdir.o: shared/util.h
1625+cmd/posix/mkdir.o: shared/arg.h
1626+cmd/posix/mkdir.o: shared/compat.h
1627+cmd/posix/chgrp.o: cmd/posix/chgrp.c
1628+cmd/posix/chgrp.o: shared/fs.h
1629+cmd/posix/chgrp.o: shared/util.h
1630+cmd/posix/chgrp.o: shared/arg.h
1631+cmd/posix/chgrp.o: shared/compat.h
1632+cmd/posix/dirname.o: cmd/posix/dirname.c
1633+cmd/posix/dirname.o: shared/util.h
1634+cmd/posix/dirname.o: shared/arg.h
1635+cmd/posix/dirname.o: shared/compat.h
1636+cmd/posix/date.o: cmd/posix/date.c
1637+cmd/posix/date.o: shared/util.h
1638+cmd/posix/date.o: shared/arg.h
1639+cmd/posix/date.o: shared/compat.h
1640+cmd/posix/expand.o: cmd/posix/expand.c
1641+cmd/posix/expand.o: shared/utf.h
1642+cmd/posix/expand.o: shared/util.h
1643+cmd/posix/expand.o: shared/arg.h
1644+cmd/posix/expand.o: shared/compat.h
1645+cmd/posix/du.o: cmd/posix/du.c
1646+cmd/posix/du.o: shared/fs.h
1647+cmd/posix/du.o: shared/util.h
1648+cmd/posix/du.o: shared/arg.h
1649+cmd/posix/du.o: shared/compat.h
1650+cmd/posix/nohup.o: cmd/posix/nohup.c
1651+cmd/posix/nohup.o: shared/wexec.h
1652+cmd/posix/nohup.o: shared/util.h
1653+cmd/posix/nohup.o: shared/arg.h
1654+cmd/posix/nohup.o: shared/compat.h
1655+cmd/posix/split.o: cmd/posix/split.c
1656+cmd/posix/split.o: shared/util.h
1657+cmd/posix/split.o: shared/arg.h
1658+cmd/posix/split.o: shared/compat.h
1659+cmd/posix/xargs.o: cmd/posix/xargs.c
1660+cmd/posix/xargs.o: shared/wexec.h
1661+cmd/posix/xargs.o: shared/util.h
1662+cmd/posix/xargs.o: shared/arg.h
1663+cmd/posix/xargs.o: shared/compat.h
1664+cmd/posix/tee.o: cmd/posix/tee.c
1665+cmd/posix/tee.o: shared/util.h
1666+cmd/posix/tee.o: shared/arg.h
1667+cmd/posix/tee.o: shared/compat.h
1668+cmd/posix/false.o: cmd/posix/false.c
1669+cmd/posix/ln.o: cmd/posix/ln.c
1670+cmd/posix/ln.o: shared/util.h
1671+cmd/posix/ln.o: shared/arg.h
1672+cmd/posix/ln.o: shared/compat.h
1673+cmd/posix/wc.o: cmd/posix/wc.c
1674+cmd/posix/wc.o: shared/utf.h
1675+cmd/posix/wc.o: shared/util.h
1676+cmd/posix/wc.o: shared/arg.h
1677+cmd/posix/wc.o: shared/compat.h
1678+cmd/posix/logname.o: cmd/posix/logname.c
1679+cmd/posix/logname.o: shared/util.h
1680+cmd/posix/logname.o: shared/arg.h
1681+cmd/posix/logname.o: shared/compat.h
1682+cmd/posix/fold.o: cmd/posix/fold.c
1683+cmd/posix/fold.o: shared/text.h
1684+cmd/posix/fold.o: shared/util.h
1685+cmd/posix/fold.o: shared/arg.h
1686+cmd/posix/fold.o: shared/compat.h
1687+cmd/posix/fold.o: shared/utf.h
1688+cmd/posix/unlink.o: cmd/posix/unlink.c
1689+cmd/posix/unlink.o: shared/util.h
1690+cmd/posix/unlink.o: shared/arg.h
1691+cmd/posix/unlink.o: shared/compat.h
1692+cmd/posix/printf.o: cmd/posix/printf.c
1693+cmd/posix/printf.o: shared/utf.h
1694+cmd/posix/printf.o: shared/util.h
1695+cmd/posix/printf.o: shared/arg.h
1696+cmd/posix/printf.o: shared/compat.h
1697+cmd/posix/head.o: cmd/posix/head.c
1698+cmd/posix/head.o: shared/util.h
1699+cmd/posix/head.o: shared/arg.h
1700+cmd/posix/head.o: shared/compat.h
1701+cmd/posix/patch.o: cmd/posix/patch.c
1702+cmd/posix/patch.o: shared/wexec.h
1703+cmd/posix/patch.o: shared/paths.h
1704+cmd/posix/patch.o: shared/util.h
1705+cmd/posix/patch.o: shared/arg.h
1706+cmd/posix/patch.o: shared/compat.h
1707+cmd/posix/readlink.o: cmd/posix/readlink.c
1708+cmd/posix/readlink.o: shared/util.h
1709+cmd/posix/readlink.o: shared/arg.h
1710+cmd/posix/readlink.o: shared/compat.h
1711+cmd/posix/rmdir.o: cmd/posix/rmdir.c
1712+cmd/posix/rmdir.o: shared/util.h
1713+cmd/posix/rmdir.o: shared/arg.h
1714+cmd/posix/rmdir.o: shared/compat.h
1715+cmd/posix/tail.o: cmd/posix/tail.c
1716+cmd/posix/tail.o: shared/utf.h
1717+cmd/posix/tail.o: shared/util.h
1718+cmd/posix/tail.o: shared/arg.h
1719+cmd/posix/tail.o: shared/compat.h
1720+cmd/posix/who.o: cmd/posix/who.c
1721+cmd/posix/who.o: shared/config.h
1722+cmd/posix/who.o: shared/paths.h
1723+cmd/posix/who.o: shared/util.h
1724+cmd/posix/who.o: shared/arg.h
1725+cmd/posix/who.o: shared/compat.h
1726+cmd/posix/cat.o: cmd/posix/cat.c
1727+cmd/posix/cat.o: shared/util.h
1728+cmd/posix/cat.o: shared/arg.h
1729+cmd/posix/cat.o: shared/compat.h
1730+cmd/posix/ls.o: cmd/posix/ls.c
1731+cmd/posix/ls.o: shared/utf.h
1732+cmd/posix/ls.o: shared/util.h
1733+cmd/posix/ls.o: shared/arg.h
1734+cmd/posix/ls.o: shared/compat.h
1735+cmd/posix/cp.o: cmd/posix/cp.c
1736+cmd/posix/cp.o: shared/fs.h
1737+cmd/posix/cp.o: shared/util.h
1738+cmd/posix/cp.o: shared/arg.h
1739+cmd/posix/cp.o: shared/compat.h
1740+cmd/posix/chown.o: cmd/posix/chown.c
1741+cmd/posix/chown.o: shared/fs.h
1742+cmd/posix/chown.o: shared/util.h
1743+cmd/posix/chown.o: shared/arg.h
1744+cmd/posix/chown.o: shared/compat.h
1745+cmd/posix/ps.o: cmd/posix/ps.c
1746+cmd/posix/ps.o: shared/proc.h
1747+cmd/posix/ps.o: shared/util.h
1748+cmd/posix/ps.o: shared/arg.h
1749+cmd/posix/ps.o: shared/compat.h
1750+cmd/posix/unexpand.o: cmd/posix/unexpand.c
1751+cmd/posix/unexpand.o: shared/utf.h
1752+cmd/posix/unexpand.o: shared/util.h
1753+cmd/posix/unexpand.o: shared/arg.h
1754+cmd/posix/unexpand.o: shared/compat.h
1755+cmd/posix/test.o: cmd/posix/test.c
1756+cmd/posix/test.o: shared/util.h
1757+cmd/posix/test.o: shared/arg.h
1758+cmd/posix/test.o: shared/compat.h
1759+cmd/posix/rm.o: cmd/posix/rm.c
1760+cmd/posix/rm.o: shared/fs.h
1761+cmd/posix/rm.o: shared/util.h
1762+cmd/posix/rm.o: shared/arg.h
1763+cmd/posix/rm.o: shared/compat.h
1764+cmd/posix/uname.o: cmd/posix/uname.c
1765+cmd/posix/uname.o: shared/util.h
1766+cmd/posix/uname.o: shared/arg.h
1767+cmd/posix/uname.o: shared/compat.h
1768+cmd/posix/join.o: cmd/posix/join.c
1769+cmd/posix/join.o: shared/text.h
1770+cmd/posix/join.o: shared/utf.h
1771+cmd/posix/join.o: shared/util.h
1772+cmd/posix/join.o: shared/arg.h
1773+cmd/posix/join.o: shared/compat.h
1774+cmd/posix/dd.o: cmd/posix/dd.c
1775+cmd/posix/dd.o: shared/util.h
1776+cmd/posix/dd.o: shared/arg.h
1777+cmd/posix/dd.o: shared/compat.h
1778+cmd/posix/expr.o: cmd/posix/expr.c
1779+cmd/posix/expr.o: shared/utf.h
1780+cmd/posix/expr.o: shared/util.h
1781+cmd/posix/expr.o: shared/arg.h
1782+cmd/posix/expr.o: shared/compat.h
1783+cmd/posix/pwd.o: cmd/posix/pwd.c
1784+cmd/posix/pwd.o: shared/util.h
1785+cmd/posix/pwd.o: shared/arg.h
1786+cmd/posix/pwd.o: shared/compat.h
1787+cmd/extra/blkid.o: cmd/extra/blkid.c
1788+cmd/extra/blkid.o: shared/util.h
1789+cmd/extra/blkid.o: shared/arg.h
1790+cmd/extra/blkid.o: shared/compat.h
1791+cmd/extra/blkid.o: shared/diskutil.h
1792+cmd/extra/blkid.o: shared/paths.h
1793+cmd/extra/b3sum.o: cmd/extra/b3sum.c
1794+cmd/extra/b3sum.o: shared/util.h
1795+cmd/extra/b3sum.o: shared/arg.h
1796+cmd/extra/b3sum.o: shared/compat.h
1797+cmd/extra/b3sum.o: shared/arg.h
1798+cmd/extra/sync.o: cmd/extra/sync.c
1799+cmd/extra/sync.o: shared/arg.h
1800+cmd/extra/sync.o: shared/util.h
1801+cmd/extra/sync.o: shared/arg.h
1802+cmd/extra/sync.o: shared/compat.h
1803+cmd/extra/fdisk.o: cmd/extra/fdisk.c
1804+cmd/extra/fdisk.o: shared/util.h
1805+cmd/extra/fdisk.o: shared/arg.h
1806+cmd/extra/fdisk.o: shared/compat.h
1807+cmd/extra/fdisk.o: shared/diskutil.h
1808+cmd/extra/fdisk.o: shared/paths.h
1809+cmd/extra/lsblk.o: cmd/extra/lsblk.c
1810+cmd/extra/lsblk.o: shared/util.h
1811+cmd/extra/lsblk.o: shared/arg.h
1812+cmd/extra/lsblk.o: shared/compat.h
1813+cmd/extra/lsblk.o: shared/diskutil.h
1814+cmd/extra/lsblk.o: shared/paths.h
1815 cmd/xsi/mknod.o: cmd/xsi/mknod.c
1816 cmd/xsi/mknod.o: shared/util.h
1817 cmd/xsi/mknod.o: shared/arg.h
1818 cmd/xsi/mknod.o: shared/compat.h
1819+cmd/xsi/su.o: cmd/xsi/su.c
1820+cmd/xsi/su.o: shared/config.h
1821+cmd/xsi/su.o: shared/paths.h
1822+cmd/xsi/su.o: shared/passwd.h
1823+cmd/xsi/su.o: shared/util.h
1824+cmd/xsi/su.o: shared/arg.h
1825+cmd/xsi/su.o: shared/compat.h
1826 cmd/xsi/passwd.o: cmd/xsi/passwd.c
1827 cmd/xsi/passwd.o: shared/config.h
1828+cmd/xsi/passwd.o: shared/paths.h
1829 cmd/xsi/passwd.o: shared/passwd.h
1830 cmd/xsi/passwd.o: shared/text.h
1831 cmd/xsi/passwd.o: shared/util.h
1832 cmd/xsi/passwd.o: shared/arg.h
1833 cmd/xsi/passwd.o: shared/compat.h
1834-cmd/xsi/su.o: cmd/xsi/su.c
1835-cmd/xsi/su.o: shared/passwd.h
1836-cmd/xsi/su.o: shared/util.h
1837-cmd/xsi/su.o: shared/arg.h
1838-cmd/xsi/su.o: shared/compat.h
1839-shared/libredline/redline.o: shared/libredline/redline.c
1840-shared/libredline/redline.o: shared/redline.h
1841-shared/libutf/fgetrune.o: shared/libutf/fgetrune.c
1842-shared/libutf/fgetrune.o: shared/libutf/../utf.h
1843-shared/libutf/fputrune.o: shared/libutf/fputrune.c
1844-shared/libutf/fputrune.o: shared/libutf/../utf.h
1845-shared/libutf/isalnumrune.o: shared/libutf/isalnumrune.c
1846-shared/libutf/isalnumrune.o: shared/libutf/../utf.h
1847-shared/libutf/isalnumrune.o: shared/libutf/runetype.h
1848-shared/libutf/isalpharune.o: shared/libutf/isalpharune.c
1849-shared/libutf/isalpharune.o: shared/libutf/../utf.h
1850-shared/libutf/isalpharune.o: shared/libutf/runetype.h
1851-shared/libutf/isblankrune.o: shared/libutf/isblankrune.c
1852-shared/libutf/isblankrune.o: shared/libutf/../utf.h
1853-shared/libutf/isblankrune.o: shared/libutf/runetype.h
1854-shared/libutf/iscntrlrune.o: shared/libutf/iscntrlrune.c
1855-shared/libutf/iscntrlrune.o: shared/libutf/../utf.h
1856-shared/libutf/iscntrlrune.o: shared/libutf/runetype.h
1857-shared/libutf/isdigitrune.o: shared/libutf/isdigitrune.c
1858-shared/libutf/isdigitrune.o: shared/libutf/../utf.h
1859-shared/libutf/isdigitrune.o: shared/libutf/runetype.h
1860-shared/libutf/isgraphrune.o: shared/libutf/isgraphrune.c
1861-shared/libutf/isgraphrune.o: shared/libutf/../utf.h
1862-shared/libutf/isgraphrune.o: shared/libutf/runetype.h
1863-shared/libutf/isprintrune.o: shared/libutf/isprintrune.c
1864-shared/libutf/isprintrune.o: shared/libutf/../utf.h
1865-shared/libutf/isprintrune.o: shared/libutf/runetype.h
1866-shared/libutf/ispunctrune.o: shared/libutf/ispunctrune.c
1867-shared/libutf/ispunctrune.o: shared/libutf/../utf.h
1868-shared/libutf/ispunctrune.o: shared/libutf/runetype.h
1869-shared/libutf/isspacerune.o: shared/libutf/isspacerune.c
1870-shared/libutf/isspacerune.o: shared/libutf/../utf.h
1871-shared/libutf/isspacerune.o: shared/libutf/runetype.h
1872-shared/libutf/istitlerune.o: shared/libutf/istitlerune.c
1873-shared/libutf/istitlerune.o: shared/libutf/../utf.h
1874-shared/libutf/istitlerune.o: shared/libutf/runetype.h
1875-shared/libutf/isxdigitrune.o: shared/libutf/isxdigitrune.c
1876-shared/libutf/isxdigitrune.o: shared/libutf/../utf.h
1877-shared/libutf/isxdigitrune.o: shared/libutf/runetype.h
1878-shared/libutf/lowerrune.o: shared/libutf/lowerrune.c
1879-shared/libutf/lowerrune.o: shared/libutf/../utf.h
1880-shared/libutf/lowerrune.o: shared/libutf/runetype.h
1881-shared/libutf/rune.o: shared/libutf/rune.c
1882-shared/libutf/rune.o: shared/libutf/../utf.h
1883-shared/libutf/runetype.o: shared/libutf/runetype.c
1884-shared/libutf/runetype.o: shared/libutf/../utf.h
1885-shared/libutf/upperrune.o: shared/libutf/upperrune.c
1886-shared/libutf/upperrune.o: shared/libutf/../utf.h
1887-shared/libutf/upperrune.o: shared/libutf/runetype.h
1888-shared/libutf/utf.o: shared/libutf/utf.c
1889-shared/libutf/utf.o: shared/libutf/../utf.h
1890-shared/libutf/utftorunestr.o: shared/libutf/utftorunestr.c
1891-shared/libutf/utftorunestr.o: shared/libutf/../utf.h
1892-shared/libutil/agetcwd.o: shared/libutil/agetcwd.c
1893-shared/libutil/agetcwd.o: shared/libutil/../util.h
1894-shared/libutil/agetcwd.o: shared/libutil/../arg.h
1895-shared/libutil/agetcwd.o: shared/libutil/../compat.h
1896-shared/libutil/agetline.o: shared/libutil/agetline.c
1897-shared/libutil/agetline.o: shared/libutil/../text.h
1898-shared/libutil/agetline.o: shared/libutil/../util.h
1899-shared/libutil/agetline.o: shared/libutil/../arg.h
1900-shared/libutil/agetline.o: shared/libutil/../compat.h
1901+cmd/net/tftp.o: cmd/net/tftp.c
1902+cmd/net/tftp.o: shared/util.h
1903+cmd/net/tftp.o: shared/arg.h
1904+cmd/net/tftp.o: shared/compat.h
1905+cmd/net/httpd.o: cmd/net/httpd.c
1906+cmd/net/httpd.o: shared/util.h
1907+cmd/net/httpd.o: shared/arg.h
1908+cmd/net/httpd.o: shared/compat.h
1909+cmd/net/httpd.o: shared/arg.h
1910+cmd/net/host.o: cmd/net/host.c
1911+cmd/net/host.o: shared/util.h
1912+cmd/net/host.o: shared/arg.h
1913+cmd/net/host.o: shared/compat.h
1914+cmd/net/host.o: shared/arg.h
1915+cmd/net/ping.o: cmd/net/ping.c
1916+cmd/net/ping.o: shared/util.h
1917+cmd/net/ping.o: shared/arg.h
1918+cmd/net/ping.o: shared/compat.h
1919+cmd/net/ping.o: shared/arg.h
1920+cmd/net/ip.o: cmd/net/ip.c
1921+cmd/net/ip.o: shared/util.h
1922+cmd/net/ip.o: shared/arg.h
1923+cmd/net/ip.o: shared/compat.h
1924+cmd/net/wget.o: cmd/net/wget.c
1925+cmd/net/wget.o: shared/util.h
1926+cmd/net/wget.o: shared/arg.h
1927+cmd/net/wget.o: shared/compat.h
1928+cmd/net/wget.o: shared/arg.h
1929+cmd/net/wget.o: shared/tls.h
1930+cmd/net/sdhcp.o: cmd/net/sdhcp.c
1931+cmd/net/sdhcp.o: shared/arg.h
1932+cmd/net/sdhcp.o: shared/wexec.h
1933+cmd/net/sdhcp.o: shared/util.h
1934+cmd/net/sdhcp.o: shared/arg.h
1935+cmd/net/sdhcp.o: shared/compat.h
1936+cmd/net/netcat.o: cmd/net/netcat.c
1937+cmd/net/netcat.o: shared/util.h
1938+cmd/net/netcat.o: shared/arg.h
1939+cmd/net/netcat.o: shared/compat.h
1940+cmd/net/ifconfig.o: cmd/net/ifconfig.c
1941+cmd/net/ifconfig.o: shared/util.h
1942+cmd/net/ifconfig.o: shared/arg.h
1943+cmd/net/ifconfig.o: shared/compat.h
1944+shared/libutil/memmem.o: shared/libutil/memmem.c
1945+shared/libutil/memmem.o: shared/libutil/../util.h
1946+shared/libutil/memmem.o: shared/libutil/../arg.h
1947+shared/libutil/memmem.o: shared/libutil/../compat.h
1948+shared/libutil/estrtoul.o: shared/libutil/estrtoul.c
1949+shared/libutil/estrtoul.o: shared/libutil/../util.h
1950+shared/libutil/estrtoul.o: shared/libutil/../arg.h
1951+shared/libutil/estrtoul.o: shared/libutil/../compat.h
1952+shared/libutil/proc.o: shared/libutil/proc.c
1953+shared/libutil/proc.o: shared/libutil/../proc.h
1954+shared/libutil/proc.o: shared/libutil/../paths.h
1955+shared/libutil/proc.o: shared/libutil/../util.h
1956+shared/libutil/proc.o: shared/libutil/../arg.h
1957+shared/libutil/proc.o: shared/libutil/../compat.h
1958+shared/libutil/estrtod.o: shared/libutil/estrtod.c
1959+shared/libutil/estrtod.o: shared/libutil/../util.h
1960+shared/libutil/estrtod.o: shared/libutil/../arg.h
1961+shared/libutil/estrtod.o: shared/libutil/../compat.h
1962+shared/libutil/tty.o: shared/libutil/tty.c
1963+shared/libutil/tty.o: shared/libutil/../paths.h
1964+shared/libutil/tty.o: shared/libutil/../util.h
1965+shared/libutil/tty.o: shared/libutil/../arg.h
1966+shared/libutil/tty.o: shared/libutil/../compat.h
1967+shared/libutil/getlines.o: shared/libutil/getlines.c
1968+shared/libutil/getlines.o: shared/libutil/../text.h
1969+shared/libutil/getlines.o: shared/libutil/../util.h
1970+shared/libutil/getlines.o: shared/libutil/../arg.h
1971+shared/libutil/getlines.o: shared/libutil/../compat.h
1972+shared/libutil/eregcomp.o: shared/libutil/eregcomp.c
1973+shared/libutil/eregcomp.o: shared/libutil/../util.h
1974+shared/libutil/eregcomp.o: shared/libutil/../arg.h
1975+shared/libutil/eregcomp.o: shared/libutil/../compat.h
1976+shared/libutil/strlcat.o: shared/libutil/strlcat.c
1977+shared/libutil/strlcat.o: shared/libutil/../util.h
1978+shared/libutil/strlcat.o: shared/libutil/../arg.h
1979+shared/libutil/strlcat.o: shared/libutil/../compat.h
1980+shared/libutil/unescape.o: shared/libutil/unescape.c
1981+shared/libutil/unescape.o: shared/libutil/../util.h
1982+shared/libutil/unescape.o: shared/libutil/../arg.h
1983+shared/libutil/unescape.o: shared/libutil/../compat.h
1984+shared/libutil/strtonum.o: shared/libutil/strtonum.c
1985+shared/libutil/strtonum.o: shared/libutil/../util.h
1986+shared/libutil/strtonum.o: shared/libutil/../arg.h
1987+shared/libutil/strtonum.o: shared/libutil/../compat.h
1988+shared/libutil/sig.o: shared/libutil/sig.c
1989+shared/libutil/sig.o: shared/libutil/../sig.h
1990 shared/libutil/apathmax.o: shared/libutil/apathmax.c
1991 shared/libutil/apathmax.o: shared/libutil/../util.h
1992 shared/libutil/apathmax.o: shared/libutil/../arg.h
1993 shared/libutil/apathmax.o: shared/libutil/../compat.h
1994-shared/libutil/concat.o: shared/libutil/concat.c
1995-shared/libutil/concat.o: shared/libutil/../util.h
1996-shared/libutil/concat.o: shared/libutil/../arg.h
1997-shared/libutil/concat.o: shared/libutil/../compat.h
1998-shared/libutil/confirm.o: shared/libutil/confirm.c
1999-shared/libutil/confirm.o: shared/libutil/../util.h
2000-shared/libutil/confirm.o: shared/libutil/../arg.h
2001-shared/libutil/confirm.o: shared/libutil/../compat.h
2002-shared/libutil/cp.o: shared/libutil/cp.c
2003-shared/libutil/cp.o: shared/libutil/../fs.h
2004-shared/libutil/cp.o: shared/libutil/../util.h
2005-shared/libutil/cp.o: shared/libutil/../arg.h
2006-shared/libutil/cp.o: shared/libutil/../compat.h
2007-shared/libutil/crypt.o: shared/libutil/crypt.c
2008-shared/libutil/crypt.o: shared/libutil/../crypt.h
2009-shared/libutil/crypt.o: shared/libutil/../text.h
2010-shared/libutil/crypt.o: shared/libutil/../util.h
2011-shared/libutil/crypt.o: shared/libutil/../arg.h
2012-shared/libutil/crypt.o: shared/libutil/../compat.h
2013+shared/libutil/strnsubst.o: shared/libutil/strnsubst.c
2014+shared/libutil/strnsubst.o: shared/libutil/../util.h
2015+shared/libutil/strnsubst.o: shared/libutil/../arg.h
2016+shared/libutil/strnsubst.o: shared/libutil/../compat.h
2017 shared/libutil/diskutil.o: shared/libutil/diskutil.c
2018 shared/libutil/diskutil.o: shared/libutil/../diskutil.h
2019+shared/libutil/diskutil.o: shared/libutil/../paths.h
2020 shared/libutil/diskutil.o: shared/libutil/../util.h
2021 shared/libutil/diskutil.o: shared/libutil/../arg.h
2022 shared/libutil/diskutil.o: shared/libutil/../compat.h
2023-shared/libutil/ealloc.o: shared/libutil/ealloc.c
2024-shared/libutil/ealloc.o: shared/libutil/../util.h
2025-shared/libutil/ealloc.o: shared/libutil/../arg.h
2026-shared/libutil/ealloc.o: shared/libutil/../compat.h
2027-shared/libutil/enmasse.o: shared/libutil/enmasse.c
2028-shared/libutil/enmasse.o: shared/libutil/../util.h
2029-shared/libutil/enmasse.o: shared/libutil/../arg.h
2030-shared/libutil/enmasse.o: shared/libutil/../compat.h
2031-shared/libutil/eprintf.o: shared/libutil/eprintf.c
2032-shared/libutil/eprintf.o: shared/libutil/../util.h
2033-shared/libutil/eprintf.o: shared/libutil/../arg.h
2034-shared/libutil/eprintf.o: shared/libutil/../compat.h
2035-shared/libutil/eregcomp.o: shared/libutil/eregcomp.c
2036-shared/libutil/eregcomp.o: shared/libutil/../util.h
2037-shared/libutil/eregcomp.o: shared/libutil/../arg.h
2038-shared/libutil/eregcomp.o: shared/libutil/../compat.h
2039-shared/libutil/estrtod.o: shared/libutil/estrtod.c
2040-shared/libutil/estrtod.o: shared/libutil/../util.h
2041-shared/libutil/estrtod.o: shared/libutil/../arg.h
2042-shared/libutil/estrtod.o: shared/libutil/../compat.h
2043-shared/libutil/estrtol.o: shared/libutil/estrtol.c
2044-shared/libutil/estrtol.o: shared/libutil/../util.h
2045-shared/libutil/estrtol.o: shared/libutil/../arg.h
2046-shared/libutil/estrtol.o: shared/libutil/../compat.h
2047-shared/libutil/estrtoul.o: shared/libutil/estrtoul.c
2048-shared/libutil/estrtoul.o: shared/libutil/../util.h
2049-shared/libutil/estrtoul.o: shared/libutil/../arg.h
2050-shared/libutil/estrtoul.o: shared/libutil/../compat.h
2051+shared/libutil/confirm.o: shared/libutil/confirm.c
2052+shared/libutil/confirm.o: shared/libutil/../util.h
2053+shared/libutil/confirm.o: shared/libutil/../arg.h
2054+shared/libutil/confirm.o: shared/libutil/../compat.h
2055 shared/libutil/explicit_bzero.o: shared/libutil/explicit_bzero.c
2056 shared/libutil/explicit_bzero.o: shared/libutil/../util.h
2057-shared/libutil/explicit_bzero.o: shared/libutil/../arg.h
2058-shared/libutil/explicit_bzero.o: shared/libutil/../compat.h
2059-shared/libutil/fconcat.o: shared/libutil/fconcat.c
2060-shared/libutil/fconcat.o: shared/libutil/../text.h
2061-shared/libutil/fconcat.o: shared/libutil/../util.h
2062-shared/libutil/fconcat.o: shared/libutil/../arg.h
2063-shared/libutil/fconcat.o: shared/libutil/../compat.h
2064-shared/libutil/fnck.o: shared/libutil/fnck.c
2065-shared/libutil/fnck.o: shared/libutil/../util.h
2066-shared/libutil/fnck.o: shared/libutil/../arg.h
2067-shared/libutil/fnck.o: shared/libutil/../compat.h
2068-shared/libutil/fshut.o: shared/libutil/fshut.c
2069-shared/libutil/fshut.o: shared/libutil/../util.h
2070-shared/libutil/fshut.o: shared/libutil/../arg.h
2071-shared/libutil/fshut.o: shared/libutil/../compat.h
2072-shared/libutil/getlines.o: shared/libutil/getlines.c
2073-shared/libutil/getlines.o: shared/libutil/../text.h
2074-shared/libutil/getlines.o: shared/libutil/../util.h
2075-shared/libutil/getlines.o: shared/libutil/../arg.h
2076-shared/libutil/getlines.o: shared/libutil/../compat.h
2077-shared/libutil/human.o: shared/libutil/human.c
2078-shared/libutil/human.o: shared/libutil/../util.h
2079-shared/libutil/human.o: shared/libutil/../arg.h
2080-shared/libutil/human.o: shared/libutil/../compat.h
2081-shared/libutil/linecmp.o: shared/libutil/linecmp.c
2082-shared/libutil/linecmp.o: shared/libutil/../text.h
2083-shared/libutil/linecmp.o: shared/libutil/../util.h
2084-shared/libutil/linecmp.o: shared/libutil/../arg.h
2085-shared/libutil/linecmp.o: shared/libutil/../compat.h
2086-shared/libutil/md5.o: shared/libutil/md5.c
2087-shared/libutil/md5.o: shared/libutil/../md5.h
2088-shared/libutil/memmem.o: shared/libutil/memmem.c
2089-shared/libutil/memmem.o: shared/libutil/../util.h
2090-shared/libutil/memmem.o: shared/libutil/../arg.h
2091-shared/libutil/memmem.o: shared/libutil/../compat.h
2092-shared/libutil/mkdirp.o: shared/libutil/mkdirp.c
2093-shared/libutil/mkdirp.o: shared/libutil/../util.h
2094-shared/libutil/mkdirp.o: shared/libutil/../arg.h
2095-shared/libutil/mkdirp.o: shared/libutil/../compat.h
2096+shared/libutil/explicit_bzero.o: shared/libutil/../arg.h
2097+shared/libutil/explicit_bzero.o: shared/libutil/../compat.h
2098+shared/libutil/sha224.o: shared/libutil/sha224.c
2099+shared/libutil/sha224.o: shared/libutil/../sha224.h
2100+shared/libutil/sha224.o: shared/libutil/../sha256.h
2101+shared/libutil/estrtol.o: shared/libutil/estrtol.c
2102+shared/libutil/estrtol.o: shared/libutil/../util.h
2103+shared/libutil/estrtol.o: shared/libutil/../arg.h
2104+shared/libutil/estrtol.o: shared/libutil/../compat.h
2105+shared/libutil/strlcpy.o: shared/libutil/strlcpy.c
2106+shared/libutil/strlcpy.o: shared/libutil/../util.h
2107+shared/libutil/strlcpy.o: shared/libutil/../arg.h
2108+shared/libutil/strlcpy.o: shared/libutil/../compat.h
2109 shared/libutil/mode.o: shared/libutil/mode.c
2110 shared/libutil/mode.o: shared/libutil/../util.h
2111 shared/libutil/mode.o: shared/libutil/../arg.h
2112 shared/libutil/mode.o: shared/libutil/../compat.h
2113 shared/libutil/net.o: shared/libutil/net.c
2114+shared/libutil/net.o: shared/libutil/../paths.h
2115 shared/libutil/net.o: shared/libutil/../util.h
2116 shared/libutil/net.o: shared/libutil/../arg.h
2117 shared/libutil/net.o: shared/libutil/../compat.h
2118+shared/libutil/wexec.o: shared/libutil/wexec.c
2119+shared/libutil/wexec.o: shared/libutil/../config.h
2120+shared/libutil/wexec.o: shared/libutil/../paths.h
2121+shared/libutil/wexec.o: shared/libutil/../wexec.h
2122+shared/libutil/wexec.o: shared/libutil/../paths.h
2123+shared/libutil/wexec.o: shared/libutil/../util.h
2124+shared/libutil/wexec.o: shared/libutil/../arg.h
2125+shared/libutil/wexec.o: shared/libutil/../compat.h
2126+shared/libutil/crypt.o: shared/libutil/crypt.c
2127+shared/libutil/crypt.o: shared/libutil/../crypt.h
2128+shared/libutil/crypt.o: shared/libutil/../text.h
2129+shared/libutil/crypt.o: shared/libutil/../util.h
2130+shared/libutil/crypt.o: shared/libutil/../arg.h
2131+shared/libutil/crypt.o: shared/libutil/../compat.h
2132 shared/libutil/parseoffset.o: shared/libutil/parseoffset.c
2133 shared/libutil/parseoffset.o: shared/libutil/../util.h
2134 shared/libutil/parseoffset.o: shared/libutil/../arg.h
2135 shared/libutil/parseoffset.o: shared/libutil/../compat.h
2136-shared/libutil/passwd.o: shared/libutil/passwd.c
2137-shared/libutil/passwd.o: shared/libutil/../passwd.h
2138-shared/libutil/passwd.o: shared/libutil/../text.h
2139-shared/libutil/passwd.o: shared/libutil/../util.h
2140-shared/libutil/passwd.o: shared/libutil/../arg.h
2141-shared/libutil/passwd.o: shared/libutil/../compat.h
2142-shared/libutil/proc.o: shared/libutil/proc.c
2143-shared/libutil/proc.o: shared/libutil/../proc.h
2144-shared/libutil/proc.o: shared/libutil/../util.h
2145-shared/libutil/proc.o: shared/libutil/../arg.h
2146-shared/libutil/proc.o: shared/libutil/../compat.h
2147-shared/libutil/putword.o: shared/libutil/putword.c
2148-shared/libutil/putword.o: shared/libutil/../util.h
2149-shared/libutil/putword.o: shared/libutil/../arg.h
2150-shared/libutil/putword.o: shared/libutil/../compat.h
2151-shared/libutil/reallocarray.o: shared/libutil/reallocarray.c
2152-shared/libutil/reallocarray.o: shared/libutil/../util.h
2153-shared/libutil/reallocarray.o: shared/libutil/../arg.h
2154-shared/libutil/reallocarray.o: shared/libutil/../compat.h
2155+shared/libutil/strsep.o: shared/libutil/strsep.c
2156+shared/libutil/strsep.o: shared/libutil/../util.h
2157+shared/libutil/strsep.o: shared/libutil/../arg.h
2158+shared/libutil/strsep.o: shared/libutil/../compat.h
2159+shared/libutil/concat.o: shared/libutil/concat.c
2160+shared/libutil/concat.o: shared/libutil/../util.h
2161+shared/libutil/concat.o: shared/libutil/../arg.h
2162+shared/libutil/concat.o: shared/libutil/../compat.h
2163+shared/libutil/human.o: shared/libutil/human.c
2164+shared/libutil/human.o: shared/libutil/../util.h
2165+shared/libutil/human.o: shared/libutil/../arg.h
2166+shared/libutil/human.o: shared/libutil/../compat.h
2167+shared/libutil/tls.o: shared/libutil/tls.c
2168+shared/libutil/tls.o: shared/libutil/../tls.h
2169+shared/libutil/tls.o: shared/libutil/../paths.h
2170+shared/libutil/tls.o: shared/libutil/../util.h
2171+shared/libutil/tls.o: shared/libutil/../arg.h
2172+shared/libutil/tls.o: shared/libutil/../compat.h
2173+shared/libutil/sha384.o: shared/libutil/sha384.c
2174+shared/libutil/sha384.o: shared/libutil/../sha384.h
2175+shared/libutil/sha384.o: shared/libutil/../sha512.h
2176+shared/libutil/fnck.o: shared/libutil/fnck.c
2177+shared/libutil/fnck.o: shared/libutil/../util.h
2178+shared/libutil/fnck.o: shared/libutil/../arg.h
2179+shared/libutil/fnck.o: shared/libutil/../compat.h
2180+shared/libutil/agetcwd.o: shared/libutil/agetcwd.c
2181+shared/libutil/agetcwd.o: shared/libutil/../util.h
2182+shared/libutil/agetcwd.o: shared/libutil/../arg.h
2183+shared/libutil/agetcwd.o: shared/libutil/../compat.h
2184+shared/libutil/linecmp.o: shared/libutil/linecmp.c
2185+shared/libutil/linecmp.o: shared/libutil/../text.h
2186+shared/libutil/linecmp.o: shared/libutil/../util.h
2187+shared/libutil/linecmp.o: shared/libutil/../arg.h
2188+shared/libutil/linecmp.o: shared/libutil/../compat.h
2189 shared/libutil/recurse.o: shared/libutil/recurse.c
2190 shared/libutil/recurse.o: shared/libutil/../fs.h
2191 shared/libutil/recurse.o: shared/libutil/../util.h
2192 shared/libutil/recurse.o: shared/libutil/../arg.h
2193 shared/libutil/recurse.o: shared/libutil/../compat.h
2194-shared/libutil/recurse_dir.o: shared/libutil/recurse_dir.c
2195-shared/libutil/recurse_dir.o: shared/libutil/../util.h
2196-shared/libutil/recurse_dir.o: shared/libutil/../arg.h
2197-shared/libutil/recurse_dir.o: shared/libutil/../compat.h
2198-shared/libutil/rm.o: shared/libutil/rm.c
2199-shared/libutil/rm.o: shared/libutil/../fs.h
2200-shared/libutil/rm.o: shared/libutil/../util.h
2201-shared/libutil/rm.o: shared/libutil/../arg.h
2202-shared/libutil/rm.o: shared/libutil/../compat.h
2203+shared/libutil/fshut.o: shared/libutil/fshut.c
2204+shared/libutil/fshut.o: shared/libutil/../util.h
2205+shared/libutil/fshut.o: shared/libutil/../arg.h
2206+shared/libutil/fshut.o: shared/libutil/../compat.h
2207+shared/libutil/agetline.o: shared/libutil/agetline.c
2208+shared/libutil/agetline.o: shared/libutil/../text.h
2209+shared/libutil/agetline.o: shared/libutil/../util.h
2210+shared/libutil/agetline.o: shared/libutil/../arg.h
2211+shared/libutil/agetline.o: shared/libutil/../compat.h
2212+shared/libutil/reallocarray.o: shared/libutil/reallocarray.c
2213+shared/libutil/reallocarray.o: shared/libutil/../util.h
2214+shared/libutil/reallocarray.o: shared/libutil/../arg.h
2215+shared/libutil/reallocarray.o: shared/libutil/../compat.h
2216+shared/libutil/fconcat.o: shared/libutil/fconcat.c
2217+shared/libutil/fconcat.o: shared/libutil/../text.h
2218+shared/libutil/fconcat.o: shared/libutil/../util.h
2219+shared/libutil/fconcat.o: shared/libutil/../arg.h
2220+shared/libutil/fconcat.o: shared/libutil/../compat.h
2221+shared/libutil/cp.o: shared/libutil/cp.c
2222+shared/libutil/cp.o: shared/libutil/../fs.h
2223+shared/libutil/cp.o: shared/libutil/../util.h
2224+shared/libutil/cp.o: shared/libutil/../arg.h
2225+shared/libutil/cp.o: shared/libutil/../compat.h
2226 shared/libutil/sha1.o: shared/libutil/sha1.c
2227 shared/libutil/sha1.o: shared/libutil/../sha1.h
2228-shared/libutil/sha224.o: shared/libutil/sha224.c
2229-shared/libutil/sha224.o: shared/libutil/../sha224.h
2230-shared/libutil/sha224.o: shared/libutil/../sha256.h
2231-shared/libutil/sha256.o: shared/libutil/sha256.c
2232-shared/libutil/sha256.o: shared/libutil/../sha256.h
2233-shared/libutil/sha384.o: shared/libutil/sha384.c
2234-shared/libutil/sha384.o: shared/libutil/../sha384.h
2235-shared/libutil/sha384.o: shared/libutil/../sha512.h
2236-shared/libutil/sha512-224.o: shared/libutil/sha512-224.c
2237-shared/libutil/sha512-224.o: shared/libutil/../sha512-224.h
2238-shared/libutil/sha512-224.o: shared/libutil/../sha512.h
2239+shared/libutil/sysinfo.o: shared/libutil/sysinfo.c
2240+shared/libutil/sysinfo.o: shared/libutil/../util.h
2241+shared/libutil/sysinfo.o: shared/libutil/../arg.h
2242+shared/libutil/sysinfo.o: shared/libutil/../compat.h
2243+shared/libutil/diffutil.o: shared/libutil/diffutil.c
2244+shared/libutil/diffutil.o: shared/libutil/../diffutil.h
2245+shared/libutil/diffutil.o: shared/libutil/../text.h
2246+shared/libutil/diffutil.o: shared/libutil/../util.h
2247+shared/libutil/diffutil.o: shared/libutil/../arg.h
2248+shared/libutil/diffutil.o: shared/libutil/../compat.h
2249+shared/libutil/md5.o: shared/libutil/md5.c
2250+shared/libutil/md5.o: shared/libutil/../md5.h
2251 shared/libutil/sha512-256.o: shared/libutil/sha512-256.c
2252 shared/libutil/sha512-256.o: shared/libutil/../sha512-256.h
2253 shared/libutil/sha512-256.o: shared/libutil/../sha512.h
2254-shared/libutil/sha512.o: shared/libutil/sha512.c
2255-shared/libutil/sha512.o: shared/libutil/../sha512.h
2256-shared/libutil/sig.o: shared/libutil/sig.c
2257-shared/libutil/sig.o: shared/libutil/../sig.h
2258 shared/libutil/strcasestr.o: shared/libutil/strcasestr.c
2259 shared/libutil/strcasestr.o: shared/libutil/../util.h
2260 shared/libutil/strcasestr.o: shared/libutil/../arg.h
2261 shared/libutil/strcasestr.o: shared/libutil/../compat.h
2262-shared/libutil/strlcat.o: shared/libutil/strlcat.c
2263-shared/libutil/strlcat.o: shared/libutil/../util.h
2264-shared/libutil/strlcat.o: shared/libutil/../arg.h
2265-shared/libutil/strlcat.o: shared/libutil/../compat.h
2266-shared/libutil/strlcpy.o: shared/libutil/strlcpy.c
2267-shared/libutil/strlcpy.o: shared/libutil/../util.h
2268-shared/libutil/strlcpy.o: shared/libutil/../arg.h
2269-shared/libutil/strlcpy.o: shared/libutil/../compat.h
2270-shared/libutil/strnsubst.o: shared/libutil/strnsubst.c
2271-shared/libutil/strnsubst.o: shared/libutil/../util.h
2272-shared/libutil/strnsubst.o: shared/libutil/../arg.h
2273-shared/libutil/strnsubst.o: shared/libutil/../compat.h
2274-shared/libutil/strsep.o: shared/libutil/strsep.c
2275-shared/libutil/strsep.o: shared/libutil/../util.h
2276-shared/libutil/strsep.o: shared/libutil/../arg.h
2277-shared/libutil/strsep.o: shared/libutil/../compat.h
2278-shared/libutil/strtonum.o: shared/libutil/strtonum.c
2279-shared/libutil/strtonum.o: shared/libutil/../util.h
2280-shared/libutil/strtonum.o: shared/libutil/../arg.h
2281-shared/libutil/strtonum.o: shared/libutil/../compat.h
2282-shared/libutil/sysinfo.o: shared/libutil/sysinfo.c
2283-shared/libutil/sysinfo.o: shared/libutil/../util.h
2284-shared/libutil/sysinfo.o: shared/libutil/../arg.h
2285-shared/libutil/sysinfo.o: shared/libutil/../compat.h
2286-shared/libutil/tls.o: shared/libutil/tls.c
2287-shared/libutil/tls.o: shared/libutil/../tls.h
2288-shared/libutil/tls.o: shared/libutil/../util.h
2289-shared/libutil/tls.o: shared/libutil/../arg.h
2290-shared/libutil/tls.o: shared/libutil/../compat.h
2291-shared/libutil/tty.o: shared/libutil/tty.c
2292-shared/libutil/tty.o: shared/libutil/../util.h
2293-shared/libutil/tty.o: shared/libutil/../arg.h
2294-shared/libutil/tty.o: shared/libutil/../compat.h
2295-shared/libutil/unescape.o: shared/libutil/unescape.c
2296-shared/libutil/unescape.o: shared/libutil/../util.h
2297-shared/libutil/unescape.o: shared/libutil/../arg.h
2298-shared/libutil/unescape.o: shared/libutil/../compat.h
2299+shared/libutil/putword.o: shared/libutil/putword.c
2300+shared/libutil/putword.o: shared/libutil/../util.h
2301+shared/libutil/putword.o: shared/libutil/../arg.h
2302+shared/libutil/putword.o: shared/libutil/../compat.h
2303 shared/libutil/writeall.o: shared/libutil/writeall.c
2304 shared/libutil/writeall.o: shared/libutil/../util.h
2305 shared/libutil/writeall.o: shared/libutil/../arg.h
2306 shared/libutil/writeall.o: shared/libutil/../compat.h
2307+shared/libutil/sha512-224.o: shared/libutil/sha512-224.c
2308+shared/libutil/sha512-224.o: shared/libutil/../sha512-224.h
2309+shared/libutil/sha512-224.o: shared/libutil/../sha512.h
2310+shared/libutil/sha512.o: shared/libutil/sha512.c
2311+shared/libutil/sha512.o: shared/libutil/../sha512.h
2312+shared/libutil/rm.o: shared/libutil/rm.c
2313+shared/libutil/rm.o: shared/libutil/../fs.h
2314+shared/libutil/rm.o: shared/libutil/../util.h
2315+shared/libutil/rm.o: shared/libutil/../arg.h
2316+shared/libutil/rm.o: shared/libutil/../compat.h
2317+shared/libutil/eprintf.o: shared/libutil/eprintf.c
2318+shared/libutil/eprintf.o: shared/libutil/../util.h
2319+shared/libutil/eprintf.o: shared/libutil/../arg.h
2320+shared/libutil/eprintf.o: shared/libutil/../compat.h
2321+shared/libutil/enmasse.o: shared/libutil/enmasse.c
2322+shared/libutil/enmasse.o: shared/libutil/../util.h
2323+shared/libutil/enmasse.o: shared/libutil/../arg.h
2324+shared/libutil/enmasse.o: shared/libutil/../compat.h
2325+shared/libutil/recurse_dir.o: shared/libutil/recurse_dir.c
2326+shared/libutil/recurse_dir.o: shared/libutil/../util.h
2327+shared/libutil/recurse_dir.o: shared/libutil/../arg.h
2328+shared/libutil/recurse_dir.o: shared/libutil/../compat.h
2329+shared/libutil/passwd.o: shared/libutil/passwd.c
2330+shared/libutil/passwd.o: shared/libutil/../passwd.h
2331+shared/libutil/passwd.o: shared/libutil/../paths.h
2332+shared/libutil/passwd.o: shared/libutil/../text.h
2333+shared/libutil/passwd.o: shared/libutil/../util.h
2334+shared/libutil/passwd.o: shared/libutil/../arg.h
2335+shared/libutil/passwd.o: shared/libutil/../compat.h
2336+shared/libutil/passwd.o: shared/libutil/../config.h
2337+shared/libutil/passwd.o: shared/libutil/../paths.h
2338+shared/libutil/passwd.o: shared/crypt.h
2339+shared/libutil/sha256.o: shared/libutil/sha256.c
2340+shared/libutil/sha256.o: shared/libutil/../sha256.h
2341+shared/libutil/ealloc.o: shared/libutil/ealloc.c
2342+shared/libutil/ealloc.o: shared/libutil/../util.h
2343+shared/libutil/ealloc.o: shared/libutil/../arg.h
2344+shared/libutil/ealloc.o: shared/libutil/../compat.h
2345+shared/libutil/mkdirp.o: shared/libutil/mkdirp.c
2346+shared/libutil/mkdirp.o: shared/libutil/../util.h
2347+shared/libutil/mkdirp.o: shared/libutil/../arg.h
2348+shared/libutil/mkdirp.o: shared/libutil/../compat.h
2349+shared/libredline/redline.o: shared/libredline/redline.c
2350+shared/libredline/redline.o: shared/libredline/../paths.h
2351+shared/libredline/redline.o: shared/redline.h
2352+shared/libutf/isdigitrune.o: shared/libutf/isdigitrune.c
2353+shared/libutf/isdigitrune.o: shared/libutf/../utf.h
2354+shared/libutf/isdigitrune.o: shared/libutf/runetype.h
2355+shared/libutf/lowerrune.o: shared/libutf/lowerrune.c
2356+shared/libutf/lowerrune.o: shared/libutf/../utf.h
2357+shared/libutf/lowerrune.o: shared/libutf/runetype.h
2358+shared/libutf/isblankrune.o: shared/libutf/isblankrune.c
2359+shared/libutf/isblankrune.o: shared/libutf/../utf.h
2360+shared/libutf/isblankrune.o: shared/libutf/runetype.h
2361+shared/libutf/runetype.o: shared/libutf/runetype.c
2362+shared/libutf/runetype.o: shared/libutf/../utf.h
2363+shared/libutf/ispunctrune.o: shared/libutf/ispunctrune.c
2364+shared/libutf/ispunctrune.o: shared/libutf/../utf.h
2365+shared/libutf/ispunctrune.o: shared/libutf/runetype.h
2366+shared/libutf/isalpharune.o: shared/libutf/isalpharune.c
2367+shared/libutf/isalpharune.o: shared/libutf/../utf.h
2368+shared/libutf/isalpharune.o: shared/libutf/runetype.h
2369+shared/libutf/fgetrune.o: shared/libutf/fgetrune.c
2370+shared/libutf/fgetrune.o: shared/libutf/../utf.h
2371+shared/libutf/isprintrune.o: shared/libutf/isprintrune.c
2372+shared/libutf/isprintrune.o: shared/libutf/../utf.h
2373+shared/libutf/isprintrune.o: shared/libutf/runetype.h
2374+shared/libutf/upperrune.o: shared/libutf/upperrune.c
2375+shared/libutf/upperrune.o: shared/libutf/../utf.h
2376+shared/libutf/upperrune.o: shared/libutf/runetype.h
2377+shared/libutf/isalnumrune.o: shared/libutf/isalnumrune.c
2378+shared/libutf/isalnumrune.o: shared/libutf/../utf.h
2379+shared/libutf/isalnumrune.o: shared/libutf/runetype.h
2380+shared/libutf/utftorunestr.o: shared/libutf/utftorunestr.c
2381+shared/libutf/utftorunestr.o: shared/libutf/../utf.h
2382+shared/libutf/isxdigitrune.o: shared/libutf/isxdigitrune.c
2383+shared/libutf/isxdigitrune.o: shared/libutf/../utf.h
2384+shared/libutf/isxdigitrune.o: shared/libutf/runetype.h
2385+shared/libutf/isspacerune.o: shared/libutf/isspacerune.c
2386+shared/libutf/isspacerune.o: shared/libutf/../utf.h
2387+shared/libutf/isspacerune.o: shared/libutf/runetype.h
2388+shared/libutf/rune.o: shared/libutf/rune.c
2389+shared/libutf/rune.o: shared/libutf/../utf.h
2390+shared/libutf/iscntrlrune.o: shared/libutf/iscntrlrune.c
2391+shared/libutf/iscntrlrune.o: shared/libutf/../utf.h
2392+shared/libutf/iscntrlrune.o: shared/libutf/runetype.h
2393+shared/libutf/istitlerune.o: shared/libutf/istitlerune.c
2394+shared/libutf/istitlerune.o: shared/libutf/../utf.h
2395+shared/libutf/istitlerune.o: shared/libutf/runetype.h
2396+shared/libutf/utf.o: shared/libutf/utf.c
2397+shared/libutf/utf.o: shared/libutf/../utf.h
2398+shared/libutf/isgraphrune.o: shared/libutf/isgraphrune.c
2399+shared/libutf/isgraphrune.o: shared/libutf/../utf.h
2400+shared/libutf/isgraphrune.o: shared/libutf/runetype.h
2401+shared/libutf/fputrune.o: shared/libutf/fputrune.c
2402+shared/libutf/fputrune.o: shared/libutf/../utf.h
+345, -341
  1@@ -9,7 +9,7 @@
  2 set -e
  3 
  4 : "${CC:=cc}"
  5-: "${CPPFLAGS:=-Ishared -D_DEFAULT_SOURCE -D_GNU_SOURCE -D_NETBSD_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_FILE_OFFSET_BITS=64}"
  6+: "${CPPFLAGS:=-Ishared -D_DEFAULT_SOURCE -D_GNU_SOURCE -D_NETBSD_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_FILE_OFFSET_BITS=64 -DFEATURE_INPROC_EXEC=1}"
  7 : "${CFLAGS:=-std=c99 -Wall -Wextra -pedantic}"
  8 : "${LDFLAGS:=}"
  9 : "${LDLIBS:=-lcrypt -lresolv}"
 10@@ -24,8 +24,8 @@ LIBUTIL="${ROOT}/shared/libutil/libutil.a"
 11 LIBUTF="${ROOT}/shared/libutf/libutf.a"
 12 
 13 die() {
 14-	printf 'mkbox: %s\n' "$*" >&2
 15-	exit 1
 16+        printf 'mkbox: %s\n' "$*" >&2
 17+        exit 1
 18 }
 19 
 20 # Clean up build directory on exit or signal termination
 21@@ -36,9 +36,9 @@ trap 'rm -rf "${BDIR}"' EXIT INT QUIT TERM
 22 [ -f "${LIBUTF}" ]  || die "libutf.a not found; run 'make' first"
 23 
 24 [ -f "${ROOT}/cmd/posix/getconf.h" ] || {
 25-	printf 'mkbox: generating getconf.h\n'
 26-	"${ROOT}/scripts/getconf.sh" > "${ROOT}/cmd/posix/getconf.h" ||
 27-		die "scripts/getconf.sh failed"
 28+        printf 'mkbox: generating getconf.h\n'
 29+        "${ROOT}/scripts/getconf.sh" > "${ROOT}/cmd/posix/getconf.h" ||
 30+                die "scripts/getconf.sh failed"
 31 }
 32 
 33 rm -rf "${BDIR}"
 34@@ -48,284 +48,284 @@ OBJS=""
 35 DECL_F="${BDIR}/decls.inc"
 36 : > "${DECL_F}"
 37 for _c in posix linux net pseudo xsi extra; do
 38-	: > "${BDIR}/entries_${_c}.inc"
 39+        : > "${BDIR}/entries_${_c}.inc"
 40 done
 41 unset _c
 42 
 43 alias_entry() {
 44-	printf '\t{ "%s", %s_main, "%s" },\n' "$1" "$2" "$3" \
 45-		>> "${BDIR}/entries_${3}.inc"
 46+        printf '\t{ "%s", %s_main, "%s" },\n' "$1" "$2" "$3" \
 47+                >> "${BDIR}/entries_${3}.inc"
 48 }
 49 
 50 compile_tool() {
 51-	src="$1"
 52-	name="$2"
 53-	fn="$3"
 54-	catg="$4"
 55-	extra="${5:-}"
 56-	out="${BDIR}/${fn}.o"
 57-	symf="${BDIR}/${fn}.syms"
 58-
 59-	printf 'mkbox: cc %s\n' "${name}"
 60-	eval "${CC} ${CPPFLAGS} ${extra} ${CFLAGS} -c \"\$src\" -o \"\$out\"" ||
 61-		die "compile failed: ${src}"
 62-	printf 'main %s_main\n' "${fn}" > "${symf}"
 63-	${OBJCOPY} --redefine-syms="${symf}" "${out}" ||
 64-		die "objcopy failed: ${name}"
 65-	${OBJCOPY} --keep-global-symbol="${fn}_main" "${out}" ||
 66-		die "objcopy localize failed: ${name}"
 67-	rm -f "${symf}"
 68-	OBJS="${OBJS} ${out}"
 69-	printf 'int %s_main(int, char **);\n' "${fn}" >> "${DECL_F}"
 70-	printf '\t{ "%s", %s_main, "%s" },\n' "${name}" "${fn}" "${catg}" \
 71-		>> "${BDIR}/entries_${catg}.inc"
 72+        src="$1"
 73+        name="$2"
 74+        fn="$3"
 75+        catg="$4"
 76+        extra="${5:-}"
 77+        out="${BDIR}/${fn}.o"
 78+        symf="${BDIR}/${fn}.syms"
 79+
 80+        printf 'mkbox: cc %s\n' "${name}"
 81+        eval "${CC} ${CPPFLAGS} ${extra} ${CFLAGS} -c \"\$src\" -o \"\$out\"" ||
 82+                die "compile failed: ${src}"
 83+        printf 'main %s_main\n' "${fn}" > "${symf}"
 84+        ${OBJCOPY} --redefine-syms="${symf}" "${out}" ||
 85+                die "objcopy failed: ${name}"
 86+        ${OBJCOPY} --keep-global-symbol="${fn}_main" "${out}" ||
 87+                die "objcopy localize failed: ${name}"
 88+        rm -f "${symf}"
 89+        OBJS="${OBJS} ${out}"
 90+        printf 'int %s_main(int, char **);\n' "${fn}" >> "${DECL_F}"
 91+        printf '\t{ "%s", %s_main, "%s" },\n' "${name}" "${fn}" "${catg}" \
 92+                >> "${BDIR}/entries_${catg}.inc"
 93 }
 94 
 95 compile_make() {
 96-	mdir="${ROOT}/cmd/posix/make"
 97-	symf="${BDIR}/make.syms"
 98-	printf 'mkbox: cc make (multi)\n'
 99-	make_objs=""
100-	for s in defaults parser posix rules; do
101-		out="${BDIR}/make_${s}.o"
102-		eval "${CC} ${CPPFLAGS} ${CFLAGS} -I\"\$mdir\" -c \"\$mdir/\$s.c\" -o \"\$out\"" ||
103-			die "compile failed: make/${s}.c"
104-		make_objs="${make_objs} ${out}"
105-	done
106-	out_main="${BDIR}/make_main.o"
107-	eval "${CC} ${CPPFLAGS} ${CFLAGS} -I\"\$mdir\" -c \"\$mdir/main.c\" -o \"\${out_main}\"" ||
108-		die "compile failed: make/main.c"
109-	make_objs="${make_objs} ${out_main}"
110-
111-	# Combined incremental link to resolve internal symbols cleanly
112-	combined="${BDIR}/make_combined.o"
113-	${LD:-ld} -r -o "${combined}" ${make_objs} ||
114-		die "ld -r failed: make"
115-
116-	printf 'main make_main\n' > "${symf}"
117-	${OBJCOPY} --redefine-syms="${symf}" "${combined}" ||
118-		die "objcopy failed: make"
119-	${OBJCOPY} --keep-global-symbol=make_main "${combined}" ||
120-		die "objcopy localize failed: make"
121-	rm -f "${symf}" ${make_objs}
122-
123-	OBJS="${OBJS} ${combined}"
124-	printf 'int make_main(int, char **);\n' >> "${DECL_F}"
125-	printf '\t{ "make", make_main, "posix" },\n' >> "${BDIR}/entries_posix.inc"
126+        mdir="${ROOT}/cmd/posix/make"
127+        symf="${BDIR}/make.syms"
128+        printf 'mkbox: cc make (multi)\n'
129+        make_objs=""
130+        for s in defaults parser posix rules; do
131+                out="${BDIR}/make_${s}.o"
132+                eval "${CC} ${CPPFLAGS} ${CFLAGS} -I\"\$mdir\" -c \"\$mdir/\$s.c\" -o \"\$out\"" ||
133+                        die "compile failed: make/${s}.c"
134+                make_objs="${make_objs} ${out}"
135+        done
136+        out_main="${BDIR}/make_main.o"
137+        eval "${CC} ${CPPFLAGS} ${CFLAGS} -I\"\$mdir\" -c \"\$mdir/main.c\" -o \"\${out_main}\"" ||
138+                die "compile failed: make/main.c"
139+        make_objs="${make_objs} ${out_main}"
140+
141+        # Combined incremental link to resolve internal symbols cleanly
142+        combined="${BDIR}/make_combined.o"
143+        ${LD:-ld} -r -o "${combined}" ${make_objs} ||
144+                die "ld -r failed: make"
145+
146+        printf 'main make_main\n' > "${symf}"
147+        ${OBJCOPY} --redefine-syms="${symf}" "${combined}" ||
148+                die "objcopy failed: make"
149+        ${OBJCOPY} --keep-global-symbol=make_main "${combined}" ||
150+                die "objcopy localize failed: make"
151+        rm -f "${symf}" ${make_objs}
152+
153+        OBJS="${OBJS} ${combined}"
154+        printf 'int make_main(int, char **);\n' >> "${DECL_F}"
155+        printf '\t{ "make", make_main, "posix" },\n' >> "${BDIR}/entries_posix.inc"
156 }
157 
158 compile_diff() {
159-	ddir="${ROOT}/cmd/posix/diff"
160-	symf="${BDIR}/diff.syms"
161-	diff_objs=""
162-
163-	printf 'mkbox: cc diff (multi)\n'
164-	for s in diff diffdir diffreg pr xmalloc; do
165-		out="${BDIR}/diff_${s}.o"
166-		eval "${CC} ${CPPFLAGS} -I\"\$ddir\" ${CFLAGS} -c \"\$ddir/\$s.c\" -o \"\$out\"" ||
167-			die "compile failed: diff/${s}.c"
168-		diff_objs="${diff_objs} ${out}"
169-	done
170-
171-	combined="${BDIR}/diff_combined.o"
172-	${LD:-ld} -r -o "${combined}" ${diff_objs} ||
173-		die "ld -r failed: diff"
174-
175-	printf 'main diff_main\n' > "${symf}"
176-	${OBJCOPY} --redefine-syms="${symf}" "${combined}" ||
177-		die "objcopy failed: diff"
178-	${OBJCOPY} --keep-global-symbol=diff_main "${combined}" ||
179-		die "objcopy localize failed: diff"
180-	rm -f "${symf}" ${diff_objs}
181-
182-	OBJS="${OBJS} ${combined}"
183-	LDLIBS="${LDLIBS} -lm"
184-	printf 'int diff_main(int, char **);\n' >> "${DECL_F}"
185-	printf '\t{ "diff", diff_main, "posix" },\n' >> "${BDIR}/entries_posix.inc"
186+        ddir="${ROOT}/cmd/posix/diff"
187+        symf="${BDIR}/diff.syms"
188+        diff_objs=""
189+
190+        printf 'mkbox: cc diff (multi)\n'
191+        for s in diff diffdir diffreg pr xmalloc; do
192+                out="${BDIR}/diff_${s}.o"
193+                eval "${CC} ${CPPFLAGS} -I\"\$ddir\" ${CFLAGS} -c \"\$ddir/\$s.c\" -o \"\$out\"" ||
194+                        die "compile failed: diff/${s}.c"
195+                diff_objs="${diff_objs} ${out}"
196+        done
197+
198+        combined="${BDIR}/diff_combined.o"
199+        ${LD:-ld} -r -o "${combined}" ${diff_objs} ||
200+                die "ld -r failed: diff"
201+
202+        printf 'main diff_main\n' > "${symf}"
203+        ${OBJCOPY} --redefine-syms="${symf}" "${combined}" ||
204+                die "objcopy failed: diff"
205+        ${OBJCOPY} --keep-global-symbol=diff_main "${combined}" ||
206+                die "objcopy localize failed: diff"
207+        rm -f "${symf}" ${diff_objs}
208+
209+        OBJS="${OBJS} ${combined}"
210+        LDLIBS="${LDLIBS} -lm"
211+        printf 'int diff_main(int, char **);\n' >> "${DECL_F}"
212+        printf '\t{ "diff", diff_main, "posix" },\n' >> "${BDIR}/entries_posix.inc"
213 }
214 
215 compile_patch() {
216-	pdir="${ROOT}/cmd/posix/patch"
217-	symf="${BDIR}/patch.syms"
218-	patch_objs=""
219-
220-	printf 'mkbox: cc patch (multi)\n'
221-	for s in patch pch inp util backupfile mkpath; do
222-		out="${BDIR}/patch_${s}.o"
223-		eval "${CC} ${CPPFLAGS} -I\"\$pdir\" ${CFLAGS} -c \"\$pdir/\$s.c\" -o \"\$out\"" ||
224-			die "compile failed: patch/${s}.c"
225-		patch_objs="${patch_objs} ${out}"
226-	done
227-
228-	combined="${BDIR}/patch_combined.o"
229-	${LD:-ld} -r -o "${combined}" ${patch_objs} ||
230-		die "ld -r failed: patch"
231-
232-	printf 'main patch_main\n' > "${symf}"
233-	${OBJCOPY} --redefine-syms="${symf}" "${combined}" ||
234-		die "objcopy failed: patch"
235-	${OBJCOPY} --keep-global-symbol=patch_main "${combined}" ||
236-		die "objcopy localize failed: patch"
237-	rm -f "${symf}" ${patch_objs}
238-
239-	OBJS="${OBJS} ${combined}"
240-	printf 'int patch_main(int, char **);\n' >> "${DECL_F}"
241-	printf '\t{ "patch", patch_main, "posix" },\n' >> "${BDIR}/entries_posix.inc"
242+        pdir="${ROOT}/cmd/posix/patch"
243+        symf="${BDIR}/patch.syms"
244+        patch_objs=""
245+
246+        printf 'mkbox: cc patch (multi)\n'
247+        for s in patch pch inp util backupfile mkpath; do
248+                out="${BDIR}/patch_${s}.o"
249+                eval "${CC} ${CPPFLAGS} -I\"\$pdir\" ${CFLAGS} -c \"\$pdir/\$s.c\" -o \"\$out\"" ||
250+                        die "compile failed: patch/${s}.c"
251+                patch_objs="${patch_objs} ${out}"
252+        done
253+
254+        combined="${BDIR}/patch_combined.o"
255+        ${LD:-ld} -r -o "${combined}" ${patch_objs} ||
256+                die "ld -r failed: patch"
257+
258+        printf 'main patch_main\n' > "${symf}"
259+        ${OBJCOPY} --redefine-syms="${symf}" "${combined}" ||
260+                die "objcopy failed: patch"
261+        ${OBJCOPY} --keep-global-symbol=patch_main "${combined}" ||
262+                die "objcopy localize failed: patch"
263+        rm -f "${symf}" ${patch_objs}
264+
265+        OBJS="${OBJS} ${combined}"
266+        printf 'int patch_main(int, char **);\n' >> "${DECL_F}"
267+        printf '\t{ "patch", patch_main, "posix" },\n' >> "${BDIR}/entries_posix.inc"
268 }
269 
270 compile_diff3() {
271-	ddir="${ROOT}/cmd/extra/diff3"
272-	pdir="${ROOT}/cmd/posix/diff"
273-	symf="${BDIR}/diff3.syms"
274-	diff3_objs=""
275-
276-	printf 'mkbox: cc diff3 (multi)\n'
277-	for s in diff3; do
278-		out="${BDIR}/diff3_${s}.o"
279-		eval "${CC} ${CPPFLAGS} -I\"\$pdir\" ${CFLAGS} -c \"\$ddir/\$s.c\" -o \"\$out\"" ||
280-			die "compile failed: diff3/${s}.c"
281-		diff3_objs="${diff3_objs} ${out}"
282-	done
283-	out="${BDIR}/diff3_xmalloc.o"
284-	eval "${CC} ${CPPFLAGS} -I\"\$pdir\" ${CFLAGS} -c \"\$pdir/xmalloc.c\" -o \"\$out\"" ||
285-		die "compile failed: diff/xmalloc.c"
286-	diff3_objs="${diff3_objs} ${out}"
287-
288-	combined="${BDIR}/diff3_combined.o"
289-	${LD:-ld} -r -o "${combined}" ${diff3_objs} ||
290-		die "ld -r failed: diff3"
291-
292-	printf 'main diff3_main\n' > "${symf}"
293-	${OBJCOPY} --redefine-syms="${symf}" "${combined}" ||
294-		die "objcopy failed: diff3"
295-	${OBJCOPY} --keep-global-symbol=diff3_main "${combined}" ||
296-		die "objcopy localize failed: diff3"
297-	rm -f "${symf}" ${diff3_objs}
298-
299-	OBJS="${OBJS} ${combined}"
300-	printf 'int diff3_main(int, char **);\n' >> "${DECL_F}"
301-	printf '\t{ "diff3", diff3_main, "extra" },\n' >> "${BDIR}/entries_extra.inc"
302+        ddir="${ROOT}/cmd/extra/diff3"
303+        pdir="${ROOT}/cmd/posix/diff"
304+        symf="${BDIR}/diff3.syms"
305+        diff3_objs=""
306+
307+        printf 'mkbox: cc diff3 (multi)\n'
308+        for s in diff3; do
309+                out="${BDIR}/diff3_${s}.o"
310+                eval "${CC} ${CPPFLAGS} -I\"\$pdir\" ${CFLAGS} -c \"\$ddir/\$s.c\" -o \"\$out\"" ||
311+                        die "compile failed: diff3/${s}.c"
312+                diff3_objs="${diff3_objs} ${out}"
313+        done
314+        out="${BDIR}/diff3_xmalloc.o"
315+        eval "${CC} ${CPPFLAGS} -I\"\$pdir\" ${CFLAGS} -c \"\$pdir/xmalloc.c\" -o \"\$out\"" ||
316+                die "compile failed: diff/xmalloc.c"
317+        diff3_objs="${diff3_objs} ${out}"
318+
319+        combined="${BDIR}/diff3_combined.o"
320+        ${LD:-ld} -r -o "${combined}" ${diff3_objs} ||
321+                die "ld -r failed: diff3"
322+
323+        printf 'main diff3_main\n' > "${symf}"
324+        ${OBJCOPY} --redefine-syms="${symf}" "${combined}" ||
325+                die "objcopy failed: diff3"
326+        ${OBJCOPY} --keep-global-symbol=diff3_main "${combined}" ||
327+                die "objcopy localize failed: diff3"
328+        rm -f "${symf}" ${diff3_objs}
329+
330+        OBJS="${OBJS} ${combined}"
331+        printf 'int diff3_main(int, char **);\n' >> "${DECL_F}"
332+        printf '\t{ "diff3", diff3_main, "extra" },\n' >> "${BDIR}/entries_extra.inc"
333 }
334 
335 compile_awk() {
336-	adir="${ROOT}/cmd/posix/awk"
337-	symf="${BDIR}/awk.syms"
338-	awk_objs=""
339-
340-	printf 'mkbox: yacc awk/awkgram.y\n'
341-	${YACC} -d -o "${adir}/awkgram.tab.c" "${adir}/awkgram.y" ||
342-		die "yacc failed: awk/awkgram.y"
343-
344-	# maketab is a host code-generator, only needs CFLAGS, no CPPFLAGS
345-	printf 'mkbox: cc awk/maketab\n'
346-	${CC} ${CFLAGS} -o "${BDIR}/awk_maketab" "${adir}/maketab.c" ||
347-		die "compile failed: awk/maketab.c"
348-
349-	printf 'mkbox: gen awk/proctab.c\n'
350-	"${BDIR}/awk_maketab" "${adir}/awkgram.tab.h" > "${adir}/proctab.c" ||
351-		die "maketab failed"
352-
353-	for s in b main parse proctab tran lib run lex math; do
354-		out="${BDIR}/awk_${s}.o"
355-		eval "${CC} ${CPPFLAGS} -I\"\$adir\" ${CFLAGS} -c \"\$adir/${s}.c\" -o \"\$out\"" ||
356-			die "compile failed: awk/${s}.c"
357-		awk_objs="${awk_objs} ${out}"
358-	done
359-	out="${BDIR}/awk_awkgram.tab.o"
360-	eval "${CC} ${CPPFLAGS} -I\"\$adir\" ${CFLAGS} -c \"\$adir/awkgram.tab.c\" -o \"\$out\"" ||
361-		die "compile failed: awk/awkgram.tab.c"
362-	awk_objs="${awk_objs} ${out}"
363-
364-	combined="${BDIR}/awk_combined.o"
365-	${LD:-ld} -r -o "${combined}" ${awk_objs} ||
366-		die "ld -r failed: awk"
367-
368-	printf 'main awk_main\n' > "${symf}"
369-	${OBJCOPY} --redefine-syms="${symf}" "${combined}" ||
370-		die "objcopy failed: awk"
371-	${OBJCOPY} --keep-global-symbol=awk_main "${combined}" ||
372-		die "objcopy localize failed: awk"
373-	rm -f "${symf}" ${awk_objs}
374-
375-	OBJS="${OBJS} ${combined}"
376-	LDLIBS="${LDLIBS} -lm"
377-	printf 'int awk_main(int, char **);\n' >> "${DECL_F}"
378-	printf '\t{ "awk", awk_main, "posix" },\n' >> "${BDIR}/entries_posix.inc"
379+        adir="${ROOT}/cmd/posix/awk"
380+        symf="${BDIR}/awk.syms"
381+        awk_objs=""
382+
383+        printf 'mkbox: yacc awk/awkgram.y\n'
384+        ${YACC} -d -o "${adir}/awkgram.tab.c" "${adir}/awkgram.y" ||
385+                die "yacc failed: awk/awkgram.y"
386+
387+        # maketab is a host code-generator, only needs CFLAGS, no CPPFLAGS
388+        printf 'mkbox: cc awk/maketab\n'
389+        ${CC} ${CFLAGS} -o "${BDIR}/awk_maketab" "${adir}/maketab.c" ||
390+                die "compile failed: awk/maketab.c"
391+
392+        printf 'mkbox: gen awk/proctab.c\n'
393+        "${BDIR}/awk_maketab" "${adir}/awkgram.tab.h" > "${adir}/proctab.c" ||
394+                die "maketab failed"
395+
396+        for s in b main parse proctab tran lib run lex math; do
397+                out="${BDIR}/awk_${s}.o"
398+                eval "${CC} ${CPPFLAGS} -I\"\$adir\" ${CFLAGS} -c \"\$adir/${s}.c\" -o \"\$out\"" ||
399+                        die "compile failed: awk/${s}.c"
400+                awk_objs="${awk_objs} ${out}"
401+        done
402+        out="${BDIR}/awk_awkgram.tab.o"
403+        eval "${CC} ${CPPFLAGS} -I\"\$adir\" ${CFLAGS} -c \"\$adir/awkgram.tab.c\" -o \"\$out\"" ||
404+                die "compile failed: awk/awkgram.tab.c"
405+        awk_objs="${awk_objs} ${out}"
406+
407+        combined="${BDIR}/awk_combined.o"
408+        ${LD:-ld} -r -o "${combined}" ${awk_objs} ||
409+                die "ld -r failed: awk"
410+
411+        printf 'main awk_main\n' > "${symf}"
412+        ${OBJCOPY} --redefine-syms="${symf}" "${combined}" ||
413+                die "objcopy failed: awk"
414+        ${OBJCOPY} --keep-global-symbol=awk_main "${combined}" ||
415+                die "objcopy localize failed: awk"
416+        rm -f "${symf}" ${awk_objs}
417+
418+        OBJS="${OBJS} ${combined}"
419+        LDLIBS="${LDLIBS} -lm"
420+        printf 'int awk_main(int, char **);\n' >> "${DECL_F}"
421+        printf '\t{ "awk", awk_main, "posix" },\n' >> "${BDIR}/entries_posix.inc"
422 }
423 
424 compile_sh() {
425-	sdir="${ROOT}/cmd/posix/sh"
426-	symf="${BDIR}/sh.syms"
427-	sh_objs=""
428-
429-	# mknodes and mksyntax are host code-generators, not part of the shell
430-	printf 'mkbox: cc sh/mknodes\n'
431-	${CC} ${CFLAGS} -o "${BDIR}/sh_mknodes" "${sdir}/mknodes.c" ||
432-		die "compile failed: sh/mknodes.c"
433-
434-	printf 'mkbox: cc sh/mksyntax\n'
435-	${CC} ${CPPFLAGS} -I"${sdir}" ${CFLAGS} -o "${BDIR}/sh_mksyntax" "${sdir}/mksyntax.c" ||
436-		die "compile failed: sh/mksyntax.c"
437-
438-	printf 'mkbox: gen sh/nodes.{c,h}\n'
439-	(cd "${sdir}" && "${BDIR}/sh_mknodes" nodetypes nodes.c.pat) ||
440-		die "mknodes failed"
441-
442-	printf 'mkbox: gen sh/syntax.{c,h}\n'
443-	(cd "${sdir}" && "${BDIR}/sh_mksyntax") ||
444-		die "mksyntax failed"
445-
446-	printf 'mkbox: gen sh/builtins.{c,h}\n'
447-	(cd "${sdir}" && sh mkbuiltins .) ||
448-		die "mkbuiltins failed"
449-
450-	printf 'mkbox: gen sh/token.h\n'
451-	(cd "${sdir}" && sh mktokens) ||
452-		die "mktokens failed"
453-
454-	for s in alias arith_yacc arith_yylex cd echo error eval exec \
455-	          expand lineedit input jobs kill mail main memalloc \
456-	          miscbltin mystring options output parser printf redir \
457-	          show test trap var builtins nodes syntax; do
458-		out="${BDIR}/sh_${s}.o"
459-		eval "${CC} ${CPPFLAGS} -DSHELL -I\"\$sdir\" ${CFLAGS} -c \"\$sdir/${s}.c\" -o \"\$out\"" ||
460-			die "compile failed: sh/${s}.c"
461-		sh_objs="${sh_objs} ${out}"
462-	done
463-
464-	combined="${BDIR}/sh_combined.o"
465-	${LD:-ld} -r -o "${combined}" ${sh_objs} ||
466-		die "ld -r failed: sh"
467-
468-	printf 'main sh_main\n' > "${symf}"
469-	${OBJCOPY} --redefine-syms="${symf}" "${combined}" ||
470-		die "objcopy failed: sh"
471-	${OBJCOPY} --keep-global-symbol=sh_main "${combined}" ||
472-		die "objcopy localize failed: sh"
473-	rm -f "${symf}" ${sh_objs}
474-
475-	OBJS="${OBJS} ${combined}"
476-	printf 'int sh_main(int, char **);\n' >> "${DECL_F}"
477-	printf '\t{ "sh", sh_main, "posix" },\n' >> "${BDIR}/entries_posix.inc"
478+        sdir="${ROOT}/cmd/posix/sh"
479+        symf="${BDIR}/sh.syms"
480+        sh_objs=""
481+
482+        # mknodes and mksyntax are host code-generators, not part of the shell
483+        printf 'mkbox: cc sh/mknodes\n'
484+        ${CC} ${CFLAGS} -o "${BDIR}/sh_mknodes" "${sdir}/mknodes.c" ||
485+                die "compile failed: sh/mknodes.c"
486+
487+        printf 'mkbox: cc sh/mksyntax\n'
488+        ${CC} ${CPPFLAGS} -I"${sdir}" ${CFLAGS} -o "${BDIR}/sh_mksyntax" "${sdir}/mksyntax.c" ||
489+                die "compile failed: sh/mksyntax.c"
490+
491+        printf 'mkbox: gen sh/nodes.{c,h}\n'
492+        (cd "${sdir}" && "${BDIR}/sh_mknodes" nodetypes nodes.c.pat) ||
493+                die "mknodes failed"
494+
495+        printf 'mkbox: gen sh/syntax.{c,h}\n'
496+        (cd "${sdir}" && "${BDIR}/sh_mksyntax") ||
497+                die "mksyntax failed"
498+
499+        printf 'mkbox: gen sh/builtins.{c,h}\n'
500+        (cd "${sdir}" && sh mkbuiltins .) ||
501+                die "mkbuiltins failed"
502+
503+        printf 'mkbox: gen sh/token.h\n'
504+        (cd "${sdir}" && sh mktokens) ||
505+                die "mktokens failed"
506+
507+        for s in alias arith_yacc arith_yylex cd echo error eval exec \
508+                  expand lineedit input jobs kill mail main memalloc \
509+                  miscbltin mystring options output parser printf redir \
510+                  show test trap var builtins nodes syntax; do
511+                out="${BDIR}/sh_${s}.o"
512+                eval "${CC} ${CPPFLAGS} -DSHELL -I\"\$sdir\" ${CFLAGS} -c \"\$sdir/${s}.c\" -o \"\$out\"" ||
513+                        die "compile failed: sh/${s}.c"
514+                sh_objs="${sh_objs} ${out}"
515+        done
516+
517+        combined="${BDIR}/sh_combined.o"
518+        ${LD:-ld} -r -o "${combined}" ${sh_objs} ||
519+                die "ld -r failed: sh"
520+
521+        printf 'main sh_main\n' > "${symf}"
522+        ${OBJCOPY} --redefine-syms="${symf}" "${combined}" ||
523+                die "objcopy failed: sh"
524+        ${OBJCOPY} --keep-global-symbol=sh_main "${combined}" ||
525+                die "objcopy localize failed: sh"
526+        rm -f "${symf}" ${sh_objs}
527+
528+        OBJS="${OBJS} ${combined}"
529+        printf 'int sh_main(int, char **);\n' >> "${DECL_F}"
530+        printf '\t{ "sh", sh_main, "posix" },\n' >> "${BDIR}/entries_posix.inc"
531 }
532 
533 process_dir() {
534-	dir="$1"
535-	catg="$2"
536-	extra="${3:-}"
537-	for src in "${dir}"/*.c; do
538-		[ -f "${src}" ] || continue
539-		name=${src##*/}
540-		name=${name%.c}
541-		fn=$(printf '%s' "${name}" | tr '.-' '__')
542-		compile_tool "${src}" "${name}" "${fn}" "${catg}" "${extra}"
543-		if [ "${name}" = "test" ]; then
544-			alias_entry "[" "test" "${catg}"
545-		fi
546-		if [ "${name}" = "xinstall" ]; then
547-			alias_entry "install" "xinstall" "${catg}"
548-		fi
549-	done
550+        dir="$1"
551+        catg="$2"
552+        extra="${3:-}"
553+        for src in "${dir}"/*.c; do
554+                [ -f "${src}" ] || continue
555+                name=${src##*/}
556+                name=${name%.c}
557+                fn=$(printf '%s' "${name}" | tr '.-' '__')
558+                compile_tool "${src}" "${name}" "${fn}" "${catg}" "${extra}"
559+                if [ "${name}" = "test" ]; then
560+                        alias_entry "[" "test" "${catg}"
561+                fi
562+                if [ "${name}" = "xinstall" ]; then
563+                        alias_entry "install" "xinstall" "${catg}"
564+                fi
565+        done
566 }
567 
568 process_dir "${ROOT}/cmd/posix" "posix"
569@@ -350,6 +350,7 @@ cat > "${DISP}" << 'DISPATCH_HEAD'
570    2026 xplshn [anto@xplshn.com.ar](mailto:anto@xplshn.com.ar) */
571 
572 /* routes argv[0] to the appropriate tool main */
573+#include "wexec.h"
574 #include "util.h"
575 
576 #include <stdio.h>
577@@ -366,9 +367,9 @@ cat "${DECL_F}" >> "${DISP}"
578 cat >> "${DISP}" << 'DISPATCH_STRUCT'
579 
580 struct Cmd {
581-	const char *name;
582-	int (*fn)(int, char **);
583-	const char *cat;
584+        const char *name;
585+        int (*fn)(int, char **);
586+        const char *cat;
587 };
588 
589 static struct Cmd cmds[] = {
590@@ -378,115 +379,118 @@ DISPATCH_STRUCT
591 # entries have the form: \t{ "name", fn_main, "cat" },
592 # splitting on " makes field 2 the tool name
593 for _c in posix linux net pseudo xsi extra; do
594-	sort -t'"' -k2,2 "${BDIR}/entries_${_c}.inc"
595+        sort -t'"' -k2,2 "${BDIR}/entries_${_c}.inc"
596 done >> "${DISP}"
597 unset _c
598 
599 cat >> "${DISP}" << 'DISPATCH_TAIL'
600-	{ NULL, NULL, NULL }
601+        { NULL, NULL, NULL }
602 };
603 
604 static void
605 usage(void)
606 {
607-	struct Cmd *c;
608-	const char *last;
609-	int col;
610-
611-	last = NULL;
612-	col = 0;
613-	fprintf(stderr, "usage: %s [-i path] [command [args...]]\n", argv0);
614-	for (c = cmds; c->name; c++) {
615-		if (!last || strcmp(c->cat, last) != 0) {
616-			if (last)
617-				fprintf(stderr, "\n\n");
618-			last = c->cat;
619-			fprintf(stderr, "%s:\n", last);
620-			col = 0;
621-		}
622-		if (col == 0) {
623-			fprintf(stderr, "\t%s", c->name);
624-			col = 8 + strlen(c->name);
625-		} else if (col + 2 + strlen(c->name) >= 78) {
626-			fprintf(stderr, ",\n\t%s", c->name);
627-			col = 8 + strlen(c->name);
628-		} else {
629-			fprintf(stderr, ", %s", c->name);
630-			col += 2 + strlen(c->name);
631-		}
632-	}
633-	if (last)
634-		fputc('\n', stderr);
635-	exit(1);
636+        struct Cmd *c;
637+        const char *last;
638+        int col;
639+
640+        last = NULL;
641+        col = 0;
642+        fprintf(stderr, "usage: %s [-i path] [command [args...]]\n", argv0);
643+        for (c = cmds; c->name; c++) {
644+                if (!last || strcmp(c->cat, last) != 0) {
645+                        if (last)
646+                                fprintf(stderr, "\n\n");
647+                        last = c->cat;
648+                        fprintf(stderr, "%s:\n", last);
649+                        col = 0;
650+                }
651+                if (col == 0) {
652+                        fprintf(stderr, "\t%s", c->name);
653+                        col = 8 + strlen(c->name);
654+                } else if (col + 2 + strlen(c->name) >= 78) {
655+                        fprintf(stderr, ",\n\t%s", c->name);
656+                        col = 8 + strlen(c->name);
657+                } else {
658+                        fprintf(stderr, ", %s", c->name);
659+                        col += 2 + strlen(c->name);
660+                }
661+        }
662+        if (last)
663+                fputc('\n', stderr);
664+        exit(1);
665 }
666 
667 static void
668 x_install(const char *path)
669 {
670-	struct Cmd *c;
671-	char buf[4096];
672-	int r;
673-
674-	for (c = cmds; c->name; c++) {
675-		r = snprintf(buf, sizeof buf, "%s/%s", path, c->name);
676-		if (r < 0 || r >= (int)sizeof buf)
677-			eprintf("install: '%s/%s': path too long\n", path, c->name);
678-		remove(buf);
679-		if (symlink("aruu-box", buf) < 0)
680-			eprintf("install: symlink '%s':", buf);
681-	}
682+        struct Cmd *c;
683+        char buf[4096];
684+        int r;
685+
686+        for (c = cmds; c->name; c++) {
687+                r = snprintf(buf, sizeof buf, "%s/%s", path, c->name);
688+                if (r < 0 || r >= (int)sizeof buf)
689+                        eprintf("install: '%s/%s': path too long\n", path, c->name);
690+                remove(buf);
691+                if (symlink("aruu-box", buf) < 0)
692+                        eprintf("install: symlink '%s':", buf);
693+        }
694 }
695 
696 int
697 main(int argc, char *argv[])
698 {
699-	struct Cmd *c;
700-	char *s;
701-
702-	argv0 = argv[0];
703-
704-	s = strrchr(argv[0], '/');
705-	if (s)
706-		s++;
707-	else
708-		s = argv[0];
709-
710-	if (strcmp(s, "aruu-box") == 0) {
711-		if (argc < 2)
712-			usage();
713-		argc--;
714-		argv++;
715-		if (strcmp(argv[0], "-i") == 0) {
716-			if (argc < 2)
717-				eprintf("usage: aruu-box -i path\n");
718-			x_install(argv[1]);
719-			return 0;
720-		}
721-		s = strrchr(argv[0], '/');
722-		if (s)
723-			s++;
724-		else
725-			s = argv[0];
726-	}
727-	for (c = cmds; c->name; c++) {
728-		if (strcmp(c->name, s) == 0) {
729-			argv0 = (char *)c->name;
730-			argv[0] = (char *)c->name;
731-			return c->fn(argc, argv);
732-		}
733-	}
734-	enprintf(127, "%s: not found\n", s);
735-	return 1;
736+        struct Cmd *c;
737+        char *s;
738+
739+        argv0 = argv[0];
740+
741+        for (c = cmds; c->name; c++)
742+                wexec_register(c->name, c->fn);
743+
744+        s = strrchr(argv[0], '/');
745+        if (s)
746+                s++;
747+        else
748+                s = argv[0];
749+
750+        if (strcmp(s, "aruu-box") == 0) {
751+                if (argc < 2)
752+                        usage();
753+                argc--;
754+                argv++;
755+                if (strcmp(argv[0], "-i") == 0) {
756+                        if (argc < 2)
757+                                eprintf("usage: aruu-box -i path\n");
758+                        x_install(argv[1]);
759+                        return 0;
760+                }
761+                s = strrchr(argv[0], '/');
762+                if (s)
763+                        s++;
764+                else
765+                        s = argv[0];
766+        }
767+        for (c = cmds; c->name; c++) {
768+                if (strcmp(c->name, s) == 0) {
769+                        argv0 = (char *)c->name;
770+                        argv[0] = (char *)c->name;
771+                        return c->fn(argc, argv);
772+                }
773+        }
774+        enprintf(127, "%s: not found\n", s);
775+        return 1;
776 }
777 DISPATCH_TAIL
778 
779 printf 'mkbox: cc dispatch\n'
780 eval "${CC} ${CPPFLAGS} ${CFLAGS} -c \"\$DISP\" -o \"\${BDIR}/aruu-box.o\"" ||
781-	die "compile failed: dispatch"
782+        die "compile failed: dispatch"
783 OBJS="${OBJS} ${BDIR}/aruu-box.o"
784 
785 printf 'mkbox: ld aruu-box\n'
786 eval "${CC} ${LDFLAGS} -o \"\$BOX\" \$OBJS \"\$LIBREDLINE\" \"\$LIBUTIL\" \"\$LIBUTF\" \${LDLIBS}" ||
787-	die "link failed"
788+        die "link failed"
789 
790 printf 'mkbox: done => %s\n' "${BOX}"
+39, -5
 1@@ -1,13 +1,14 @@
 2 /* See LICENSE file for copyright and license details. */
 3+#include "paths.h"
 4 
 5-#define ENV_PATH "/bin"
 6-#define PW_CIPHER "$6$" /* sha-512 */
 7+#define ENV_PATH ARUU_PATH_BIN
 8+#define PW_CIPHER "$6$"
 9 #undef UTMP_PATH
10-#define UTMP_PATH "/var/run/utmp"
11+#define UTMP_PATH ARUU_PATH_UTMP
12 #undef BTMP_PATH
13-#define BTMP_PATH "/var/log/btmp"
14+#define BTMP_PATH ARUU_PATH_BTMP
15 #undef WTMP_PATH
16-#define WTMP_PATH "/var/log/wtmp"
17+#define WTMP_PATH ARUU_PATH_WTMP
18 
19 #ifndef FEATURE_FIND_DELETE
20 #define FEATURE_FIND_DELETE     1
21@@ -87,3 +88,36 @@
22 #ifndef FEATURE_LS_COLOR
23 #define FEATURE_LS_COLOR             1
24 #endif
25+#ifndef FEATURE_DIFF3_MERGE
26+#define FEATURE_DIFF3_MERGE          1
27+#endif
28+#ifndef FEATURE_DIFF3_EDSCRIPT
29+#define FEATURE_DIFF3_EDSCRIPT       1
30+#endif
31+#ifndef FEATURE_DIFF_CONTEXT
32+#define FEATURE_DIFF_CONTEXT         1
33+#endif
34+#ifndef FEATURE_DIFF_UNIFIED
35+#define FEATURE_DIFF_UNIFIED         1
36+#endif
37+#ifndef FEATURE_DIFF_ED
38+#define FEATURE_DIFF_ED              1
39+#endif
40+#ifndef FEATURE_DIFF_BRIEF
41+#define FEATURE_DIFF_BRIEF           1
42+#endif
43+#ifndef FEATURE_DIFF_SIDEBYSIDE
44+#define FEATURE_DIFF_SIDEBYSIDE      1
45+#endif
46+#ifndef FEATURE_PATCH_BACKUP
47+#define FEATURE_PATCH_BACKUP         1
48+#endif
49+#ifndef FEATURE_PATCH_FUZZ
50+#define FEATURE_PATCH_FUZZ           1
51+#endif
52+#ifndef FEATURE_PATCH_STRIP_CR
53+#define FEATURE_PATCH_STRIP_CR       1
54+#endif
55+#ifndef FEATURE_INPROC_EXEC
56+#define FEATURE_INPROC_EXEC          0
57+#endif
+66, -0
 1@@ -0,0 +1,66 @@
 2+/* See LICENSE file for copyright and license details. */
 3+#ifndef ARUU_DIFFUTIL_H
 4+#define ARUU_DIFFUTIL_H
 5+
 6+#include <stdio.h>
 7+#include <sys/types.h>
 8+
 9+struct diffline {
10+	char *data;
11+	size_t len;
12+};
13+
14+struct difffile {
15+	struct diffline *lines;
16+	size_t nlines;
17+};
18+
19+struct diffrange {
20+	size_t from;
21+	size_t to;
22+};
23+
24+struct diffhunk {
25+	struct diffrange old;
26+	struct diffrange new;
27+};
28+
29+struct diffhunks {
30+	struct diffhunk *v;
31+	size_t n;
32+};
33+
34+enum diffformat {
35+	DIFF_NORMAL,
36+	DIFF_UNIFIED,
37+	DIFF_CONTEXT,
38+	DIFF_ED,
39+	DIFF_RCSED,
40+	DIFF_BRIEF,
41+};
42+
43+struct diffopts {
44+	enum diffformat format;
45+	size_t context;
46+	int ignore_case;
47+	int ignore_blanks;
48+	int strip_cr;
49+	int treat_binary;
50+};
51+
52+#define DIFF_SAME   0
53+#define DIFF_DIFFER 1
54+#define DIFF_ERROR  2
55+
56+int diff_load(struct difffile *df, const char *path);
57+void diff_free(struct difffile *df);
58+int diff_compute(struct diffhunks *hunks, const struct difffile *old,
59+                 const struct difffile *new, const struct diffopts *opts);
60+void diff_hunks_free(struct diffhunks *hunks);
61+int diff_format(FILE *out, const struct diffhunks *hunks,
62+                const struct difffile *old, const struct difffile *new,
63+                const char *oldlabel, const char *newlabel,
64+                const struct diffopts *opts);
65+int diff_looks_binary(const struct difffile *df);
66+
67+#endif
+10, -19
 1@@ -2,30 +2,21 @@
 2 #ifndef ARUU_DISKUTIL_H
 3 #define ARUU_DISKUTIL_H
 4 
 5+#include "paths.h"
 6+
 7 #include <stddef.h>
 8 #include <stdint.h>
 9 
10-#ifndef PATH_DEV
11-#define PATH_DEV "/dev"
12-#endif
13-
14-#ifndef PATH_PROC
15-#define PATH_PROC "/proc"
16-#endif
17-
18-#define PATH_PARTITIONS PATH_PROC "/partitions"
19-#define PATH_MOUNTS PATH_PROC "/mounts"
20-
21 struct BlockDev {
22 	int fd;
23-	uint64_t size;	 /* size in bytes */
24-	size_t sec_size; /* sector size */
25+	uint64_t size;
26+	size_t sec_size;
27 };
28 
29 struct BlockDevInfo {
30 	char name[32];
31-	char path[128]; /* absolute path to device node */
32-	char type[16];	/* disk, part, loop */
33+	char path[128];
34+	char type[16];
35 	uint64_t size;
36 	int major;
37 	int minor;
38@@ -37,14 +28,14 @@ struct BlockDevInfo {
39 
40 int blockdev_open(struct BlockDev *dev, const char *path, int writable);
41 int blockdev_read(struct BlockDev *dev, uint64_t sector, void *buf,
42-		  size_t sector_count);
43+                  size_t sector_count);
44 int blockdev_write(struct BlockDev *dev, uint64_t sector, const void *buf,
45-		   size_t sector_count);
46+                   size_t sector_count);
47 void blockdev_close(struct BlockDev *dev);
48 
49 int blockdev_detect_fs(struct BlockDev *dev, char *type, size_t type_sz,
50-		       char *label, size_t label_sz, char *uuid,
51-		       size_t uuid_sz);
52+                       char *label, size_t label_sz, char *uuid,
53+                       size_t uuid_sz);
54 
55 struct BlockDevInfo *blockdev_get_list(void);
56 void blockdev_free_list(struct BlockDevInfo *list);
+1038, -1037
   1@@ -1,5 +1,6 @@
   2 /* see license file for copyright and license details */
   3 
   4+#include "../paths.h"
   5 #include "redline.h"
   6 
   7 #include <ctype.h>
   8@@ -41,26 +42,26 @@
   9 #define ESC 27
  10 
  11 struct redlineState {
  12-	int in_completion;
  13-	int ifd;
  14-	int ofd;
  15-	char *buf;
  16-	size_t buflen;
  17-	const char *prompt;
  18-	size_t plen;
  19-	size_t pos;
  20-	size_t oldpos;
  21-	size_t len;
  22-	size_t cols;
  23-	size_t oldrows;
  24-	int oldrpos;
  25-	int history_index;
  26+        int in_completion;
  27+        int ifd;
  28+        int ofd;
  29+        char *buf;
  30+        size_t buflen;
  31+        const char *prompt;
  32+        size_t plen;
  33+        size_t pos;
  34+        size_t oldpos;
  35+        size_t len;
  36+        size_t cols;
  37+        size_t oldrows;
  38+        int oldrpos;
  39+        int history_index;
  40 };
  41 
  42 
  43 struct abuf {
  44-	char *b;
  45-	int len;
  46+        char *b;
  47+        int len;
  48 };
  49 
  50 static struct termios orig_termios;
  51@@ -79,1334 +80,1334 @@ static void (*completionCallback)(const char *, struct redlineCompletions *) = N
  52 static int
  53 utf8ByteLen(char c)
  54 {
  55-	unsigned char uc = (unsigned char)c;
  56-	if ((uc & 0x80) == 0)    return 1;
  57-	if ((uc & 0xE0) == 0xC0) return 2;
  58-	if ((uc & 0xF0) == 0xE0) return 3;
  59-	if ((uc & 0xF8) == 0xF0) return 4;
  60-	return 1;
  61+        unsigned char uc = (unsigned char)c;
  62+        if ((uc & 0x80) == 0)    return 1;
  63+        if ((uc & 0xE0) == 0xC0) return 2;
  64+        if ((uc & 0xF0) == 0xE0) return 3;
  65+        if ((uc & 0xF8) == 0xF0) return 4;
  66+        return 1;
  67 }
  68 
  69 /* decode character starting at s */
  70 static uint32_t
  71 utf8DecodeChar(const char *s, size_t *len)
  72 {
  73-	uint32_t cp = 0;
  74-	int l = utf8ByteLen(*s);
  75-	*len = l;
  76-	if (l == 1) {
  77-		cp = ((unsigned char)*s);
  78-	} else if (l == 2) {
  79-		cp = ((unsigned char)*s & 0x1F) << 6;
  80-		cp |= ((unsigned char)*(s+1) & 0x3F);
  81-	} else if (l == 3) {
  82-		cp = ((unsigned char)*s & 0x0F) << 12;
  83-		cp |= ((unsigned char)*(s+1) & 0x3F) << 6;
  84-		cp |= ((unsigned char)*(s+2) & 0x3F);
  85-	} else if (l == 4) {
  86-		cp = ((unsigned char)*s & 0x07) << 18;
  87-		cp |= ((unsigned char)*(s+1) & 0x3F) << 12;
  88-		cp |= ((unsigned char)*(s+2) & 0x3F) << 6;
  89-		cp |= ((unsigned char)*(s+3) & 0x3F);
  90-	}
  91-	return cp;
  92+        uint32_t cp = 0;
  93+        int l = utf8ByteLen(*s);
  94+        *len = l;
  95+        if (l == 1) {
  96+                cp = ((unsigned char)*s);
  97+        } else if (l == 2) {
  98+                cp = ((unsigned char)*s & 0x1F) << 6;
  99+                cp |= ((unsigned char)*(s+1) & 0x3F);
 100+        } else if (l == 3) {
 101+                cp = ((unsigned char)*s & 0x0F) << 12;
 102+                cp |= ((unsigned char)*(s+1) & 0x3F) << 6;
 103+                cp |= ((unsigned char)*(s+2) & 0x3F);
 104+        } else if (l == 4) {
 105+                cp = ((unsigned char)*s & 0x07) << 18;
 106+                cp |= ((unsigned char)*(s+1) & 0x3F) << 12;
 107+                cp |= ((unsigned char)*(s+2) & 0x3F) << 6;
 108+                cp |= ((unsigned char)*(s+3) & 0x3F);
 109+        }
 110+        return cp;
 111 }
 112 
 113 static int
 114 isZWJ(uint32_t cp)
 115 {
 116-	return cp == 0x200D;
 117+        return cp == 0x200D;
 118 }
 119 
 120 static int
 121 isCombiningMark(uint32_t cp)
 122 {
 123-	return (cp >= 0x0300 && cp <= 0x036F) || (cp >= 0x1DC0 && cp <= 0x1DFF) ||
 124-	       (cp >= 0x20D0 && cp <= 0x20FF) || (cp >= 0xFE20 && cp <= 0xFE2F);
 125+        return (cp >= 0x0300 && cp <= 0x036F) || (cp >= 0x1DC0 && cp <= 0x1DFF) ||
 126+               (cp >= 0x20D0 && cp <= 0x20FF) || (cp >= 0xFE20 && cp <= 0xFE2F);
 127 }
 128 
 129 static int
 130 isVariationSelector(uint32_t cp)
 131 {
 132-	return (cp >= 0xFE00 && cp <= 0xFE0F) || (cp >= 0xE0100 && cp <= 0xE01EF);
 133+        return (cp >= 0xFE00 && cp <= 0xFE0F) || (cp >= 0xE0100 && cp <= 0xE01EF);
 134 }
 135 
 136 static int
 137 isSkinToneModifier(uint32_t cp)
 138 {
 139-	return cp >= 0x1F3FB && cp <= 0x1F3FF;
 140+        return cp >= 0x1F3FB && cp <= 0x1F3FF;
 141 }
 142 
 143 
 144 static int
 145 isGraphemeExtend(uint32_t cp)
 146 {
 147-	return isCombiningMark(cp) || isVariationSelector(cp) || isSkinToneModifier(cp);
 148+        return isCombiningMark(cp) || isVariationSelector(cp) || isSkinToneModifier(cp);
 149 }
 150 
 151 /* decode character going backward from pos */
 152 static uint32_t
 153 utf8DecodePrev(const char *buf, size_t pos, size_t *cplen)
 154 {
 155-	size_t i = 1;
 156-	while (pos >= i && i <= 4) {
 157-		unsigned char uc = (unsigned char)buf[pos-i];
 158-		if ((uc & 0x80) == 0) {
 159-			if (i == 1) {
 160-				*cplen = 1;
 161-				return uc;
 162-			}
 163-			break;
 164-		}
 165-		if ((uc & 0xC0) == 0xC0) {
 166-			int l = utf8ByteLen(buf[pos-i]);
 167-			if ((size_t)l == i) {
 168-				*cplen = i;
 169-				return utf8DecodeChar(buf + pos - i, cplen);
 170-			}
 171-			break;
 172-		}
 173-		i++;
 174-	}
 175-	*cplen = 1;
 176-	return (unsigned char)buf[pos-1];
 177+        size_t i = 1;
 178+        while (pos >= i && i <= 4) {
 179+                unsigned char uc = (unsigned char)buf[pos-i];
 180+                if ((uc & 0x80) == 0) {
 181+                        if (i == 1) {
 182+                                *cplen = 1;
 183+                                return uc;
 184+                        }
 185+                        break;
 186+                }
 187+                if ((uc & 0xC0) == 0xC0) {
 188+                        int l = utf8ByteLen(buf[pos-i]);
 189+                        if ((size_t)l == i) {
 190+                                *cplen = i;
 191+                                return utf8DecodeChar(buf + pos - i, cplen);
 192+                        }
 193+                        break;
 194+                }
 195+                i++;
 196+        }
 197+        *cplen = 1;
 198+        return (unsigned char)buf[pos-1];
 199 }
 200 
 201 /* calculate width of utf-8 char pos */
 202 static size_t
 203 utf8PrevCharLen(const char *buf, size_t pos)
 204 {
 205-	size_t len = 0;
 206-	size_t next_len = 0;
 207-	uint32_t cp;
 208-	if (pos == 0) return 0;
 209-	cp = utf8DecodePrev(buf, pos, &len);
 210-	pos -= len;
 211-	while (pos > 0 && isGraphemeExtend(cp)) {
 212-		cp = utf8DecodePrev(buf, pos, &next_len);
 213-		len += next_len;
 214-		pos -= next_len;
 215-	}
 216-	if (pos > 0 && isZWJ(cp)) {
 217-		size_t j = utf8PrevCharLen(buf, pos);
 218-		if (j > 0) len += j;
 219-	}
 220-	return len;
 221+        size_t len = 0;
 222+        size_t next_len = 0;
 223+        uint32_t cp;
 224+        if (pos == 0) return 0;
 225+        cp = utf8DecodePrev(buf, pos, &len);
 226+        pos -= len;
 227+        while (pos > 0 && isGraphemeExtend(cp)) {
 228+                cp = utf8DecodePrev(buf, pos, &next_len);
 229+                len += next_len;
 230+                pos -= next_len;
 231+        }
 232+        if (pos > 0 && isZWJ(cp)) {
 233+                size_t j = utf8PrevCharLen(buf, pos);
 234+                if (j > 0) len += j;
 235+        }
 236+        return len;
 237 }
 238 
 239 /* calculate width of next utf-8 char */
 240 static size_t
 241 utf8NextCharLen(const char *buf, size_t pos, size_t len)
 242 {
 243-	size_t clen = 0;
 244-	size_t offset = 0;
 245-	uint32_t cp;
 246-	if (pos >= len) return 0;
 247-	cp = utf8DecodeChar(buf + pos, &clen);
 248-	offset = clen;
 249-	while (pos + offset < len) {
 250-		size_t next_len = 0;
 251-		uint32_t next_cp = utf8DecodeChar(buf + pos + offset, &next_len);
 252-		if (isGraphemeExtend(next_cp)) {
 253-			offset += next_len;
 254-		} else if (isZWJ(cp)) {
 255-			offset += next_len;
 256-			cp = next_cp;
 257-		} else {
 258-			break;
 259-		}
 260-	}
 261-	return offset;
 262+        size_t clen = 0;
 263+        size_t offset = 0;
 264+        uint32_t cp;
 265+        if (pos >= len) return 0;
 266+        cp = utf8DecodeChar(buf + pos, &clen);
 267+        offset = clen;
 268+        while (pos + offset < len) {
 269+                size_t next_len = 0;
 270+                uint32_t next_cp = utf8DecodeChar(buf + pos + offset, &next_len);
 271+                if (isGraphemeExtend(next_cp)) {
 272+                        offset += next_len;
 273+                } else if (isZWJ(cp)) {
 274+                        offset += next_len;
 275+                        cp = next_cp;
 276+                } else {
 277+                        break;
 278+                }
 279+        }
 280+        return offset;
 281 }
 282 
 283 /* get columns needed to display char */
 284 static int
 285 utf8CharWidth(uint32_t cp)
 286 {
 287-	if (cp == 0) return 0;
 288-	if (cp < 0x20 || (cp >= 0x7f && cp < 0xa0)) return 0;
 289-	if ((cp >= 0x1100 && cp <= 0x115f) ||
 290-	    (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) ||
 291-	    (cp >= 0xac00 && cp <= 0xd7a3) ||
 292-	    (cp >= 0xf900 && cp <= 0xfaff) ||
 293-	    (cp >= 0xfe10 && cp <= 0xfe19) ||
 294-	    (cp >= 0xfe30 && cp <= 0xfe6f) ||
 295-	    (cp >= 0xff00 && cp <= 0xff60) ||
 296-	    (cp >= 0xffe0 && cp <= 0xffe6) ||
 297-	    (cp >= 0x20000 && cp <= 0x2fffd) ||
 298-	    (cp >= 0x30000 && cp <= 0x3fffd)) {
 299-		return 2;
 300-	}
 301-	return 1;
 302+        if (cp == 0) return 0;
 303+        if (cp < 0x20 || (cp >= 0x7f && cp < 0xa0)) return 0;
 304+        if ((cp >= 0x1100 && cp <= 0x115f) ||
 305+            (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) ||
 306+            (cp >= 0xac00 && cp <= 0xd7a3) ||
 307+            (cp >= 0xf900 && cp <= 0xfaff) ||
 308+            (cp >= 0xfe10 && cp <= 0xfe19) ||
 309+            (cp >= 0xfe30 && cp <= 0xfe6f) ||
 310+            (cp >= 0xff00 && cp <= 0xff60) ||
 311+            (cp >= 0xffe0 && cp <= 0xffe6) ||
 312+            (cp >= 0x20000 && cp <= 0x2fffd) ||
 313+            (cp >= 0x30000 && cp <= 0x3fffd)) {
 314+                return 2;
 315+        }
 316+        return 1;
 317 }
 318 
 319 /* get ansi escape sequence length */
 320 static size_t
 321 ansiEscapeLen(const char *s, size_t len)
 322 {
 323-	size_t i = 0;
 324-	if (len < 2 || s[0] != '\x1b' || s[1] != '[') return 0;
 325-	i = 2;
 326-	while (i < len) {
 327-		char c = s[i];
 328-		if ((c >= '0' && c <= '9') || c == ';' || c == '?' || c == '"') {
 329-			i++;
 330-		} else if (c >= 'A' && c <= 'Z') {
 331-			return i + 1;
 332-		} else if (c >= 'a' && c <= 'z') {
 333-			return i + 1;
 334-		} else {
 335-			break;
 336-		}
 337-	}
 338-	return 0;
 339+        size_t i = 0;
 340+        if (len < 2 || s[0] != '\x1b' || s[1] != '[') return 0;
 341+        i = 2;
 342+        while (i < len) {
 343+                char c = s[i];
 344+                if ((c >= '0' && c <= '9') || c == ';' || c == '?' || c == '"') {
 345+                        i++;
 346+                } else if (c >= 'A' && c <= 'Z') {
 347+                        return i + 1;
 348+                } else if (c >= 'a' && c <= 'z') {
 349+                        return i + 1;
 350+                } else {
 351+                        break;
 352+                }
 353+        }
 354+        return 0;
 355 }
 356 
 357 /* calculate width of string */
 358 static size_t
 359 utf8StrWidth(const char *s, size_t len)
 360 {
 361-	size_t width = 0;
 362-	size_t i = 0;
 363-	while (i < len) {
 364-		size_t elen = ansiEscapeLen(s + i, len - i);
 365-		if (elen > 0) {
 366-			i += elen;
 367-			continue;
 368-		}
 369-		size_t clen = 0;
 370-		uint32_t cp = utf8DecodeChar(s + i, &clen);
 371-		width += utf8CharWidth(cp);
 372-		i += clen;
 373-	}
 374-	return width;
 375+        size_t width = 0;
 376+        size_t i = 0;
 377+        while (i < len) {
 378+                size_t elen = ansiEscapeLen(s + i, len - i);
 379+                if (elen > 0) {
 380+                        i += elen;
 381+                        continue;
 382+                }
 383+                size_t clen = 0;
 384+                uint32_t cp = utf8DecodeChar(s + i, &clen);
 385+                width += utf8CharWidth(cp);
 386+                i += clen;
 387+        }
 388+        return width;
 389 }
 390 
 391 /* get single character width */
 392 static int
 393 utf8SingleCharWidth(const char *s, size_t len)
 394 {
 395-	size_t clen = 0;
 396-	uint32_t cp = utf8DecodeChar(s, &clen);
 397-	(void)len;
 398-	return utf8CharWidth(cp);
 399+        size_t clen = 0;
 400+        uint32_t cp = utf8DecodeChar(s, &clen);
 401+        (void)len;
 402+        return utf8CharWidth(cp);
 403 }
 404 
 405 static int
 406 isUnsupportedTerm(void)
 407 {
 408-	char *term = getenv("TERM");
 409-	int i;
 410-	static char *unsupported[] = {"dumb", "cons25", "emacs", NULL};
 411-	if (term == NULL) return 0;
 412-	for (i = 0; unsupported[i]; i++) {
 413-		if (strcasecmp(term, unsupported[i]) == 0)
 414-			return 1;
 415-	}
 416-	return 0;
 417+        char *term = getenv("TERM");
 418+        int i;
 419+        static char *unsupported[] = {"dumb", "cons25", "emacs", NULL};
 420+        if (term == NULL) return 0;
 421+        for (i = 0; unsupported[i]; i++) {
 422+                if (strcasecmp(term, unsupported[i]) == 0)
 423+                        return 1;
 424+        }
 425+        return 0;
 426 }
 427 
 428 static void
 429 sigwinchHandler(int sig)
 430 {
 431-	(void)sig;
 432-	winch_received = 1;
 433+        (void)sig;
 434+        winch_received = 1;
 435 }
 436 
 437 static int
 438 enableRawMode(int fd)
 439 {
 440-	struct termios raw;
 441-	struct sigaction sa;
 442-
 443-	if (!isatty(STDIN_FILENO))
 444-		return -1;
 445-	if (tcgetattr(fd, &orig_termios) == -1)
 446-		return -1;
 447-
 448-	raw = orig_termios;
 449-	raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
 450-	raw.c_oflag &= ~(OPOST);
 451-	raw.c_cflag |= (CS8);
 452-	raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
 453-	raw.c_cc[VMIN] = 1;
 454-	raw.c_cc[VTIME] = 0;
 455-
 456-	if (tcsetattr(fd, TCSAFLUSH, &raw) < 0)
 457-		return -1;
 458-
 459-	rawmode = 1;
 460-
 461-	/* register sigwinch handler */
 462-	sa.sa_handler = sigwinchHandler;
 463-	sigemptyset(&sa.sa_mask);
 464-	sa.sa_flags = 0;
 465-	sigaction(SIGWINCH, &sa, &orig_sigwinch);
 466-
 467-	return 0;
 468+        struct termios raw;
 469+        struct sigaction sa;
 470+
 471+        if (!isatty(STDIN_FILENO))
 472+                return -1;
 473+        if (tcgetattr(fd, &orig_termios) == -1)
 474+                return -1;
 475+
 476+        raw = orig_termios;
 477+        raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
 478+        raw.c_oflag &= ~(OPOST);
 479+        raw.c_cflag |= (CS8);
 480+        raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
 481+        raw.c_cc[VMIN] = 1;
 482+        raw.c_cc[VTIME] = 0;
 483+
 484+        if (tcsetattr(fd, TCSAFLUSH, &raw) < 0)
 485+                return -1;
 486+
 487+        rawmode = 1;
 488+
 489+        /* register sigwinch handler */
 490+        sa.sa_handler = sigwinchHandler;
 491+        sigemptyset(&sa.sa_mask);
 492+        sa.sa_flags = 0;
 493+        sigaction(SIGWINCH, &sa, &orig_sigwinch);
 494+
 495+        return 0;
 496 }
 497 
 498 static void
 499 disableRawMode(int fd)
 500 {
 501-	if (rawmode) {
 502-		tcsetattr(fd, TCSAFLUSH, &orig_termios);
 503-		sigaction(SIGWINCH, &orig_sigwinch, NULL);
 504-		rawmode = 0;
 505-	}
 506+        if (rawmode) {
 507+                tcsetattr(fd, TCSAFLUSH, &orig_termios);
 508+                sigaction(SIGWINCH, &orig_sigwinch, NULL);
 509+                rawmode = 0;
 510+        }
 511 }
 512 
 513 static int
 514 getCursorPosition(int ifd, int ofd)
 515 {
 516-	char buf[32];
 517-	int cols, rows;
 518-	unsigned int i = 0;
 519-
 520-	if (write(ofd, "\x1b[6n", 4) != 4) return -1;
 521-
 522-	while (i < sizeof(buf)-1) {
 523-		if (read(ifd,buf+i,1) != 1) break;
 524-		if (buf[i] == 'R') break;
 525-		i++;
 526-	}
 527-	buf[i] = '\0';
 528-
 529-	if (buf[0] != 27 || buf[1] != '[') return -1;
 530-	if (sscanf(buf+2,"%d;%d",&rows,&cols) != 2) return -1;
 531-	return cols;
 532+        char buf[32];
 533+        int cols, rows;
 534+        unsigned int i = 0;
 535+
 536+        if (write(ofd, "\x1b[6n", 4) != 4) return -1;
 537+
 538+        while (i < sizeof(buf)-1) {
 539+                if (read(ifd,buf+i,1) != 1) break;
 540+                if (buf[i] == 'R') break;
 541+                i++;
 542+        }
 543+        buf[i] = '\0';
 544+
 545+        if (buf[0] != 27 || buf[1] != '[') return -1;
 546+        if (sscanf(buf+2,"%d;%d",&rows,&cols) != 2) return -1;
 547+        return cols;
 548 }
 549 
 550 static int
 551 getColumns(int ifd, int ofd)
 552 {
 553-	struct winsize ws;
 554-	char *cols_env;
 555-	int tty_fd;
 556-	int cols = 0;
 557-
 558-	if (ioctl(ofd, TIOCGWINSZ, &ws) == 0 && ws.ws_col >= 20)
 559-		return ws.ws_col;
 560-	if (ioctl(ifd, TIOCGWINSZ, &ws) == 0 && ws.ws_col >= 20)
 561-		return ws.ws_col;
 562-	if (ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col >= 20)
 563-		return ws.ws_col;
 564-	if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col >= 20)
 565-		return ws.ws_col;
 566-	if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col >= 20)
 567-		return ws.ws_col;
 568-
 569-	tty_fd = open("/dev/tty", O_RDWR | O_NOCTTY);
 570-	if (tty_fd >= 0) {
 571-		if (ioctl(tty_fd, TIOCGWINSZ, &ws) == 0 && ws.ws_col >= 20) {
 572-			cols = ws.ws_col;
 573-		}
 574-		close(tty_fd);
 575-		if (cols >= 20) return cols;
 576-	}
 577-
 578-	cols_env = getenv("COLUMNS");
 579-	if (cols_env) {
 580-		cols = atoi(cols_env);
 581-		if (cols >= 20) return cols;
 582-	}
 583-
 584-	/* fallback to cursor position query */
 585-	int start;
 586-
 587-	if (!isatty(ifd) || !isatty(ofd)) return 80;
 588-
 589-	start = getCursorPosition(ifd,ofd);
 590-	if (start == -1) return 80;
 591-
 592-	if (write(ofd,"\x1b[999C",6) != 6) return 80;
 593-	cols = getCursorPosition(ifd,ofd);
 594-	if (cols == -1) return 80;
 595-
 596-	if (cols > start) {
 597-		char seq[32];
 598-		snprintf(seq,sizeof(seq),"\x1b[%dD",cols-start);
 599-		if (write(ofd,seq,strlen(seq)) == -1) {}
 600-	}
 601-	if (cols < 20) return 80;
 602-	return cols;
 603+        struct winsize ws;
 604+        char *cols_env;
 605+        int tty_fd;
 606+        int cols = 0;
 607+
 608+        if (ioctl(ofd, TIOCGWINSZ, &ws) == 0 && ws.ws_col >= 20)
 609+                return ws.ws_col;
 610+        if (ioctl(ifd, TIOCGWINSZ, &ws) == 0 && ws.ws_col >= 20)
 611+                return ws.ws_col;
 612+        if (ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col >= 20)
 613+                return ws.ws_col;
 614+        if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col >= 20)
 615+                return ws.ws_col;
 616+        if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col >= 20)
 617+                return ws.ws_col;
 618+
 619+        tty_fd = open(ARUU_PATH_DEVTTY, O_RDWR | O_NOCTTY);
 620+        if (tty_fd >= 0) {
 621+                if (ioctl(tty_fd, TIOCGWINSZ, &ws) == 0 && ws.ws_col >= 20) {
 622+                        cols = ws.ws_col;
 623+                }
 624+                close(tty_fd);
 625+                if (cols >= 20) return cols;
 626+        }
 627+
 628+        cols_env = getenv("COLUMNS");
 629+        if (cols_env) {
 630+                cols = atoi(cols_env);
 631+                if (cols >= 20) return cols;
 632+        }
 633+
 634+        /* fallback to cursor position query */
 635+        int start;
 636+
 637+        if (!isatty(ifd) || !isatty(ofd)) return 80;
 638+
 639+        start = getCursorPosition(ifd,ofd);
 640+        if (start == -1) return 80;
 641+
 642+        if (write(ofd,"\x1b[999C",6) != 6) return 80;
 643+        cols = getCursorPosition(ifd,ofd);
 644+        if (cols == -1) return 80;
 645+
 646+        if (cols > start) {
 647+                char seq[32];
 648+                snprintf(seq,sizeof(seq),"\x1b[%dD",cols-start);
 649+                if (write(ofd,seq,strlen(seq)) == -1) {}
 650+        }
 651+        if (cols < 20) return 80;
 652+        return cols;
 653 }
 654 
 655 static void
 656 redlineBeep(void)
 657 {
 658-	fprintf(stderr, "\x7");
 659-	fflush(stderr);
 660+        fprintf(stderr, "\x7");
 661+        fflush(stderr);
 662 }
 663 
 664 static void
 665 freeCompletions(struct redlineCompletions *lc)
 666 {
 667-	size_t i;
 668-	if (lc->cvec) {
 669-		for (i = 0; i < lc->len; i++) {
 670-			free(lc->cvec[i]);
 671-		}
 672-		free(lc->cvec);
 673-	}
 674+        size_t i;
 675+        if (lc->cvec) {
 676+                for (i = 0; i < lc->len; i++) {
 677+                        free(lc->cvec[i]);
 678+                }
 679+                free(lc->cvec);
 680+        }
 681 }
 682 
 683 static size_t
 684 longestCommonPrefix(struct redlineCompletions *lc)
 685 {
 686-	size_t i, j;
 687-	if (lc->len == 0) return 0;
 688-	for (i = 0; ; i++) {
 689-		char c = lc->cvec[0][i];
 690-		if (c == '\0') return i;
 691-		for (j = 1; j < lc->len; j++) {
 692-			if (lc->cvec[j][i] != c) {
 693-				return i;
 694-			}
 695-		}
 696-	}
 697+        size_t i, j;
 698+        if (lc->len == 0) return 0;
 699+        for (i = 0; ; i++) {
 700+                char c = lc->cvec[0][i];
 701+                if (c == '\0') return i;
 702+                for (j = 1; j < lc->len; j++) {
 703+                        if (lc->cvec[j][i] != c) {
 704+                                return i;
 705+                        }
 706+                }
 707+        }
 708 }
 709 
 710 static void
 711 printCompletions(struct redlineState *ls, struct redlineCompletions *lc)
 712 {
 713-	size_t max_len = 0;
 714-	size_t i, j, k;
 715-	size_t col_width, num_cols, num_rows;
 716-	size_t sp, len, idx;
 717-	const char *comp;
 718-	const char *name;
 719-
 720-	for (i = 0; i < lc->len; i++) {
 721-		comp = lc->cvec[i];
 722-		sp = strlen(comp);
 723-		if (sp > 0 && comp[sp-1] == ' ') {
 724-			sp--;
 725-		}
 726-		while (sp > 0 && comp[sp-1] != ' ') {
 727-			sp--;
 728-		}
 729-		len = strlen(comp + sp);
 730-		if (len > 0 && (comp + sp)[len-1] == ' ') {
 731-			len--;
 732-		}
 733-		if (len > max_len) {
 734-			max_len = len;
 735-		}
 736-	}
 737-
 738-	col_width = max_len + 2;
 739-	num_cols = ls->cols / col_width;
 740-	if (num_cols == 0) num_cols = 1;
 741-	num_rows = (lc->len + num_cols - 1) / num_cols;
 742-
 743-	if (write(ls->ofd, "\r\n", 2) == -1) {}
 744-	for (i = 0; i < num_rows; i++) {
 745-		for (j = 0; j < num_cols; j++) {
 746-			idx = j * num_rows + i;
 747-			if (idx < lc->len) {
 748-				comp = lc->cvec[idx];
 749-				sp = strlen(comp);
 750-				if (sp > 0 && comp[sp-1] == ' ') {
 751-					sp--;
 752-				}
 753-				while (sp > 0 && comp[sp-1] != ' ') {
 754-					sp--;
 755-				}
 756-				name = comp + sp;
 757-				len = strlen(name);
 758-				if (len > 0 && name[len-1] == ' ') {
 759-					len--;
 760-				}
 761-				if (write(ls->ofd, name, len) == -1) {}
 762-				if (j < num_cols - 1) {
 763-					for (k = len; k < col_width; k++) {
 764-						if (write(ls->ofd, " ", 1) == -1) {}
 765-					}
 766-				}
 767-			}
 768-		}
 769-		if (write(ls->ofd, "\r\n", 2) == -1) {}
 770-	}
 771+        size_t max_len = 0;
 772+        size_t i, j, k;
 773+        size_t col_width, num_cols, num_rows;
 774+        size_t sp, len, idx;
 775+        const char *comp;
 776+        const char *name;
 777+
 778+        for (i = 0; i < lc->len; i++) {
 779+                comp = lc->cvec[i];
 780+                sp = strlen(comp);
 781+                if (sp > 0 && comp[sp-1] == ' ') {
 782+                        sp--;
 783+                }
 784+                while (sp > 0 && comp[sp-1] != ' ') {
 785+                        sp--;
 786+                }
 787+                len = strlen(comp + sp);
 788+                if (len > 0 && (comp + sp)[len-1] == ' ') {
 789+                        len--;
 790+                }
 791+                if (len > max_len) {
 792+                        max_len = len;
 793+                }
 794+        }
 795+
 796+        col_width = max_len + 2;
 797+        num_cols = ls->cols / col_width;
 798+        if (num_cols == 0) num_cols = 1;
 799+        num_rows = (lc->len + num_cols - 1) / num_cols;
 800+
 801+        if (write(ls->ofd, "\r\n", 2) == -1) {}
 802+        for (i = 0; i < num_rows; i++) {
 803+                for (j = 0; j < num_cols; j++) {
 804+                        idx = j * num_rows + i;
 805+                        if (idx < lc->len) {
 806+                                comp = lc->cvec[idx];
 807+                                sp = strlen(comp);
 808+                                if (sp > 0 && comp[sp-1] == ' ') {
 809+                                        sp--;
 810+                                }
 811+                                while (sp > 0 && comp[sp-1] != ' ') {
 812+                                        sp--;
 813+                                }
 814+                                name = comp + sp;
 815+                                len = strlen(name);
 816+                                if (len > 0 && name[len-1] == ' ') {
 817+                                        len--;
 818+                                }
 819+                                if (write(ls->ofd, name, len) == -1) {}
 820+                                if (j < num_cols - 1) {
 821+                                        for (k = len; k < col_width; k++) {
 822+                                                if (write(ls->ofd, " ", 1) == -1) {}
 823+                                        }
 824+                                }
 825+                        }
 826+                }
 827+                if (write(ls->ofd, "\r\n", 2) == -1) {}
 828+        }
 829 }
 830 
 831 static void
 832 abInit(struct abuf *ab)
 833 {
 834-	ab->b = NULL;
 835-	ab->len = 0;
 836+        ab->b = NULL;
 837+        ab->len = 0;
 838 }
 839 
 840 static void
 841 abAppend(struct abuf *ab, const char *s, int len)
 842 {
 843-	char *new = realloc(ab->b,ab->len+len);
 844-	if (new == NULL) return;
 845-	memcpy(new+ab->len,s,len);
 846-	ab->b = new;
 847-	ab->len += len;
 848+        char *new = realloc(ab->b,ab->len+len);
 849+        if (new == NULL) return;
 850+        memcpy(new+ab->len,s,len);
 851+        ab->b = new;
 852+        ab->len += len;
 853 }
 854 
 855 static void
 856 abFree(struct abuf *ab)
 857 {
 858-	free(ab->b);
 859+        free(ab->b);
 860 }
 861 
 862 static void
 863 refreshSingleLine(struct redlineState *l, int flags)
 864 {
 865-	char seq[64];
 866-	size_t pwidth = utf8StrWidth(l->prompt, l->plen);
 867-	int fd = l->ofd;
 868-	char *buf = l->buf;
 869-	size_t len = l->len;
 870-	size_t pos = l->pos;
 871-	size_t poscol;
 872-	size_t lencol;
 873-	struct abuf ab;
 874-
 875-	poscol = utf8StrWidth(buf, pos);
 876-	lencol = utf8StrWidth(buf, len);
 877-
 878-	while (pwidth + poscol >= l->cols) {
 879-		size_t clen = utf8NextCharLen(buf, 0, len);
 880-		int cwidth = utf8SingleCharWidth(buf, clen);
 881-		buf += clen;
 882-		len -= clen;
 883-		pos -= clen;
 884-		poscol -= cwidth;
 885-		lencol -= cwidth;
 886-	}
 887-
 888-	while (pwidth + lencol > l->cols) {
 889-		size_t clen = utf8PrevCharLen(buf, len);
 890-		int cwidth = utf8SingleCharWidth(buf + len - clen, clen);
 891-		len -= clen;
 892-		lencol -= cwidth;
 893-	}
 894-
 895-	abInit(&ab);
 896-	snprintf(seq,sizeof(seq),"\r");
 897-	abAppend(&ab,seq,strlen(seq));
 898-
 899-	if (flags & 1) {
 900-		abAppend(&ab,l->prompt,l->plen);
 901-		abAppend(&ab,buf,len);
 902-	}
 903-
 904-	snprintf(seq,sizeof(seq),"\x1b[0K");
 905-	abAppend(&ab,seq,strlen(seq));
 906-
 907-	if (flags & 1) {
 908-		snprintf(seq,sizeof(seq),"\r\x1b[%dC", (int)(poscol+pwidth));
 909-		abAppend(&ab,seq,strlen(seq));
 910-	}
 911-
 912-	if (write(fd,ab.b,ab.len) == -1) {}
 913-	abFree(&ab);
 914+        char seq[64];
 915+        size_t pwidth = utf8StrWidth(l->prompt, l->plen);
 916+        int fd = l->ofd;
 917+        char *buf = l->buf;
 918+        size_t len = l->len;
 919+        size_t pos = l->pos;
 920+        size_t poscol;
 921+        size_t lencol;
 922+        struct abuf ab;
 923+
 924+        poscol = utf8StrWidth(buf, pos);
 925+        lencol = utf8StrWidth(buf, len);
 926+
 927+        while (pwidth + poscol >= l->cols) {
 928+                size_t clen = utf8NextCharLen(buf, 0, len);
 929+                int cwidth = utf8SingleCharWidth(buf, clen);
 930+                buf += clen;
 931+                len -= clen;
 932+                pos -= clen;
 933+                poscol -= cwidth;
 934+                lencol -= cwidth;
 935+        }
 936+
 937+        while (pwidth + lencol > l->cols) {
 938+                size_t clen = utf8PrevCharLen(buf, len);
 939+                int cwidth = utf8SingleCharWidth(buf + len - clen, clen);
 940+                len -= clen;
 941+                lencol -= cwidth;
 942+        }
 943+
 944+        abInit(&ab);
 945+        snprintf(seq,sizeof(seq),"\r");
 946+        abAppend(&ab,seq,strlen(seq));
 947+
 948+        if (flags & 1) {
 949+                abAppend(&ab,l->prompt,l->plen);
 950+                abAppend(&ab,buf,len);
 951+        }
 952+
 953+        snprintf(seq,sizeof(seq),"\x1b[0K");
 954+        abAppend(&ab,seq,strlen(seq));
 955+
 956+        if (flags & 1) {
 957+                snprintf(seq,sizeof(seq),"\r\x1b[%dC", (int)(poscol+pwidth));
 958+                abAppend(&ab,seq,strlen(seq));
 959+        }
 960+
 961+        if (write(fd,ab.b,ab.len) == -1) {}
 962+        abFree(&ab);
 963 }
 964 
 965 static void
 966 refreshMultiLine(struct redlineState *l, int flags)
 967 {
 968-	char seq[64];
 969-	size_t pwidth = utf8StrWidth(l->prompt, l->plen);
 970-	size_t bufwidth;
 971-	size_t poswidth;
 972-	int rows;
 973-	int rpos2;
 974-	int col;
 975-	int old_rows = l->oldrows;
 976-	int rpos = l->oldrpos;
 977-	int fd = l->ofd, j;
 978-	struct abuf ab;
 979-
 980-	(void)flags;
 981-
 982-	bufwidth = utf8StrWidth(l->buf, l->len);
 983-	poswidth = utf8StrWidth(l->buf, l->pos);
 984-	rows = (pwidth+bufwidth+l->cols-1)/l->cols;
 985-	l->oldrows = rows;
 986-
 987-	abInit(&ab);
 988-
 989-	/* move cursor up to the first row, column 0 of the input area */
 990-	if (rpos > 1) {
 991-		snprintf(seq, 64, "\r\x1b[%dA", rpos - 1);
 992-		abAppend(&ab, seq, strlen(seq));
 993-	} else {
 994-		abAppend(&ab, "\r", 1);
 995-	}
 996-
 997-	/* clear all old rows */
 998-	for (j = 0; j < old_rows; j++) {
 999-		abAppend(&ab, "\x1b[0K", 4);
1000-		if (j < old_rows - 1) {
1001-			abAppend(&ab, "\n\r", 2);
1002-		}
1003-	}
1004-
1005-	/* move cursor back to the first row, column 0 */
1006-	if (old_rows > 1) {
1007-		snprintf(seq, 64, "\r\x1b[%dA", old_rows - 1);
1008-		abAppend(&ab, seq, strlen(seq));
1009-	} else {
1010-		abAppend(&ab, "\r", 1);
1011-	}
1012-
1013-	/* print prompt and new buffer */
1014-	abAppend(&ab, l->prompt, l->plen);
1015-	abAppend(&ab, l->buf, l->len);
1016-
1017-	/* if cursor is at the end of the line and wraps, print a newline */
1018-	if (l->pos && l->pos == l->len && (poswidth+pwidth) % l->cols == 0) {
1019-		abAppend(&ab, "\n\r", 2);
1020-		rows++;
1021-		if (rows > (int)l->oldrows) l->oldrows = rows;
1022-	}
1023-
1024-	/* calculate cursor row and column */
1025-	rpos2 = (pwidth+poswidth+l->cols)/l->cols;
1026-	col = (pwidth+poswidth) % l->cols;
1027-
1028-	/* move cursor to the correct row and column */
1029-	if (rows - rpos2 > 0) {
1030-		snprintf(seq, 64, "\x1b[%dA", rows - rpos2);
1031-		abAppend(&ab, seq, strlen(seq));
1032-	}
1033-	if (col) {
1034-		snprintf(seq, 64, "\r\x1b[%dC", col);
1035-		abAppend(&ab, seq, strlen(seq));
1036-	} else {
1037-		abAppend(&ab, "\r", 1);
1038-	}
1039-
1040-	l->oldpos = l->pos;
1041-	l->oldrpos = rpos2;
1042-
1043-	if (write(fd, ab.b, ab.len) == -1) {}
1044-	abFree(&ab);
1045+        char seq[64];
1046+        size_t pwidth = utf8StrWidth(l->prompt, l->plen);
1047+        size_t bufwidth;
1048+        size_t poswidth;
1049+        int rows;
1050+        int rpos2;
1051+        int col;
1052+        int old_rows = l->oldrows;
1053+        int rpos = l->oldrpos;
1054+        int fd = l->ofd, j;
1055+        struct abuf ab;
1056+
1057+        (void)flags;
1058+
1059+        bufwidth = utf8StrWidth(l->buf, l->len);
1060+        poswidth = utf8StrWidth(l->buf, l->pos);
1061+        rows = (pwidth+bufwidth+l->cols-1)/l->cols;
1062+        l->oldrows = rows;
1063+
1064+        abInit(&ab);
1065+
1066+        /* move cursor up to the first row, column 0 of the input area */
1067+        if (rpos > 1) {
1068+                snprintf(seq, 64, "\r\x1b[%dA", rpos - 1);
1069+                abAppend(&ab, seq, strlen(seq));
1070+        } else {
1071+                abAppend(&ab, "\r", 1);
1072+        }
1073+
1074+        /* clear all old rows */
1075+        for (j = 0; j < old_rows; j++) {
1076+                abAppend(&ab, "\x1b[0K", 4);
1077+                if (j < old_rows - 1) {
1078+                        abAppend(&ab, "\n\r", 2);
1079+                }
1080+        }
1081+
1082+        /* move cursor back to the first row, column 0 */
1083+        if (old_rows > 1) {
1084+                snprintf(seq, 64, "\r\x1b[%dA", old_rows - 1);
1085+                abAppend(&ab, seq, strlen(seq));
1086+        } else {
1087+                abAppend(&ab, "\r", 1);
1088+        }
1089+
1090+        /* print prompt and new buffer */
1091+        abAppend(&ab, l->prompt, l->plen);
1092+        abAppend(&ab, l->buf, l->len);
1093+
1094+        /* if cursor is at the end of the line and wraps, print a newline */
1095+        if (l->pos && l->pos == l->len && (poswidth+pwidth) % l->cols == 0) {
1096+                abAppend(&ab, "\n\r", 2);
1097+                rows++;
1098+                if (rows > (int)l->oldrows) l->oldrows = rows;
1099+        }
1100+
1101+        /* calculate cursor row and column */
1102+        rpos2 = (pwidth+poswidth+l->cols)/l->cols;
1103+        col = (pwidth+poswidth) % l->cols;
1104+
1105+        /* move cursor to the correct row and column */
1106+        if (rows - rpos2 > 0) {
1107+                snprintf(seq, 64, "\x1b[%dA", rows - rpos2);
1108+                abAppend(&ab, seq, strlen(seq));
1109+        }
1110+        if (col) {
1111+                snprintf(seq, 64, "\r\x1b[%dC", col);
1112+                abAppend(&ab, seq, strlen(seq));
1113+        } else {
1114+                abAppend(&ab, "\r", 1);
1115+        }
1116+
1117+        l->oldpos = l->pos;
1118+        l->oldrpos = rpos2;
1119+
1120+        if (write(fd, ab.b, ab.len) == -1) {}
1121+        abFree(&ab);
1122 }
1123 
1124 static void
1125 refreshLineWithFlags(struct redlineState *l, int flags)
1126 {
1127-	if (mlmode)
1128-		refreshMultiLine(l,flags);
1129-	else
1130-		refreshSingleLine(l,flags);
1131+        if (mlmode)
1132+                refreshMultiLine(l,flags);
1133+        else
1134+                refreshSingleLine(l,flags);
1135 }
1136 
1137 static void
1138 refreshLine(struct redlineState *l)
1139 {
1140-	refreshLineWithFlags(l, 1);
1141+        refreshLineWithFlags(l, 1);
1142 }
1143 
1144 static int
1145 completeLine(struct redlineState *ls, int keypressed)
1146 {
1147-	struct redlineCompletions lc = { 0, NULL };
1148-	size_t lcp_len;
1149-	int c = keypressed;
1150-	int proceed = 1;
1151-	char query[128];
1152-	char answer = 0;
1153-
1154-	if (c != 9) {
1155-		ls->in_completion = 0;
1156-		return c;
1157-	}
1158-
1159-	completionCallback(ls->buf, &lc);
1160-	if (lc.len == 0) {
1161-		redlineBeep();
1162-		ls->in_completion = 0;
1163-		c = 0;
1164-	} else if (lc.len == 1) {
1165-		size_t nwritten = snprintf(ls->buf, ls->buflen, "%s", lc.cvec[0]);
1166-		ls->len = ls->pos = nwritten;
1167-		refreshLine(ls);
1168-		ls->in_completion = 0;
1169-		c = 0;
1170-	} else {
1171-		lcp_len = longestCommonPrefix(&lc);
1172-		if (lcp_len > ls->len) {
1173-			size_t nwritten = snprintf(ls->buf, ls->buflen, "%.*s", (int)lcp_len, lc.cvec[0]);
1174-			ls->len = ls->pos = nwritten;
1175-			refreshLine(ls);
1176-			ls->in_completion = 1;
1177-			c = 0;
1178-		} else {
1179-			/* prefix cannot be expanded further */
1180-			if (ls->in_completion == 0) {
1181-				/* first tab: beep and wait for the second tab */
1182-				redlineBeep();
1183-				ls->in_completion = 1;
1184-				c = 0;
1185-			} else {
1186-				/* second tab: display possibilities */
1187-				if (lc.len > 100) {
1188-					snprintf(query, sizeof(query), "\r\nDisplay all %d possibilities? (y or n) ", (int)lc.len);
1189-					if (write(ls->ofd, query, strlen(query)) == -1) {}
1190-					while (1) {
1191-						if (read(ls->ifd, &answer, 1) != 1) {
1192-							proceed = 0;
1193-							break;
1194-						}
1195-						if (answer == 'y' || answer == 'Y' || answer == ' ' || answer == '\t') {
1196-							proceed = 1;
1197-							break;
1198-						}
1199-						if (answer == 'n' || answer == 'N' || answer == 27 || answer == 3 || answer == 4) {
1200-							proceed = 0;
1201-							break;
1202-						}
1203-						redlineBeep();
1204-					}
1205-				}
1206-				if (proceed) {
1207-					printCompletions(ls, &lc);
1208-				} else {
1209-					if (write(ls->ofd, "\r\n", 2) == -1) {}
1210-				}
1211-				ls->oldrows = 0;
1212-				refreshLine(ls);
1213-				ls->in_completion = 0;
1214-				c = 0;
1215-			}
1216-		}
1217-	}
1218-
1219-	freeCompletions(&lc);
1220-	return c;
1221+        struct redlineCompletions lc = { 0, NULL };
1222+        size_t lcp_len;
1223+        int c = keypressed;
1224+        int proceed = 1;
1225+        char query[128];
1226+        char answer = 0;
1227+
1228+        if (c != 9) {
1229+                ls->in_completion = 0;
1230+                return c;
1231+        }
1232+
1233+        completionCallback(ls->buf, &lc);
1234+        if (lc.len == 0) {
1235+                redlineBeep();
1236+                ls->in_completion = 0;
1237+                c = 0;
1238+        } else if (lc.len == 1) {
1239+                size_t nwritten = snprintf(ls->buf, ls->buflen, "%s", lc.cvec[0]);
1240+                ls->len = ls->pos = nwritten;
1241+                refreshLine(ls);
1242+                ls->in_completion = 0;
1243+                c = 0;
1244+        } else {
1245+                lcp_len = longestCommonPrefix(&lc);
1246+                if (lcp_len > ls->len) {
1247+                        size_t nwritten = snprintf(ls->buf, ls->buflen, "%.*s", (int)lcp_len, lc.cvec[0]);
1248+                        ls->len = ls->pos = nwritten;
1249+                        refreshLine(ls);
1250+                        ls->in_completion = 1;
1251+                        c = 0;
1252+                } else {
1253+                        /* prefix cannot be expanded further */
1254+                        if (ls->in_completion == 0) {
1255+                                /* first tab: beep and wait for the second tab */
1256+                                redlineBeep();
1257+                                ls->in_completion = 1;
1258+                                c = 0;
1259+                        } else {
1260+                                /* second tab: display possibilities */
1261+                                if (lc.len > 100) {
1262+                                        snprintf(query, sizeof(query), "\r\nDisplay all %d possibilities? (y or n) ", (int)lc.len);
1263+                                        if (write(ls->ofd, query, strlen(query)) == -1) {}
1264+                                        while (1) {
1265+                                                if (read(ls->ifd, &answer, 1) != 1) {
1266+                                                        proceed = 0;
1267+                                                        break;
1268+                                                }
1269+                                                if (answer == 'y' || answer == 'Y' || answer == ' ' || answer == '\t') {
1270+                                                        proceed = 1;
1271+                                                        break;
1272+                                                }
1273+                                                if (answer == 'n' || answer == 'N' || answer == 27 || answer == 3 || answer == 4) {
1274+                                                        proceed = 0;
1275+                                                        break;
1276+                                                }
1277+                                                redlineBeep();
1278+                                        }
1279+                                }
1280+                                if (proceed) {
1281+                                        printCompletions(ls, &lc);
1282+                                } else {
1283+                                        if (write(ls->ofd, "\r\n", 2) == -1) {}
1284+                                }
1285+                                ls->oldrows = 0;
1286+                                refreshLine(ls);
1287+                                ls->in_completion = 0;
1288+                                c = 0;
1289+                        }
1290+                }
1291+        }
1292+
1293+        freeCompletions(&lc);
1294+        return c;
1295 }
1296 
1297 static int
1298 redlineEditInsert(struct redlineState *l, const char *c, int clen)
1299 {
1300-	if (l->len + clen >= l->buflen) {
1301-		return 0;
1302-	}
1303-	if (l->len == l->pos) {
1304-		memcpy(l->buf + l->pos, c, clen);
1305-		l->pos += clen;
1306-		l->len += clen;
1307-		l->buf[l->len] = '\0';
1308-		refreshLine(l);
1309-	} else {
1310-		memmove(l->buf + l->pos + clen, l->buf + l->pos, l->len - l->pos);
1311-		memcpy(l->buf + l->pos, c, clen);
1312-		l->pos += clen;
1313-		l->len += clen;
1314-		l->buf[l->len] = '\0';
1315-		refreshLine(l);
1316-	}
1317-	return 1;
1318+        if (l->len + clen >= l->buflen) {
1319+                return 0;
1320+        }
1321+        if (l->len == l->pos) {
1322+                memcpy(l->buf + l->pos, c, clen);
1323+                l->pos += clen;
1324+                l->len += clen;
1325+                l->buf[l->len] = '\0';
1326+                refreshLine(l);
1327+        } else {
1328+                memmove(l->buf + l->pos + clen, l->buf + l->pos, l->len - l->pos);
1329+                memcpy(l->buf + l->pos, c, clen);
1330+                l->pos += clen;
1331+                l->len += clen;
1332+                l->buf[l->len] = '\0';
1333+                refreshLine(l);
1334+        }
1335+        return 1;
1336 }
1337 
1338 static void
1339 redlineEditBackspace(struct redlineState *l)
1340 {
1341-	if (l->pos > 0 && l->len > 0) {
1342-		size_t clen = utf8PrevCharLen(l->buf, l->pos);
1343-		memmove(l->buf+l->pos-clen, l->buf+l->pos, l->len-l->pos);
1344-		l->pos -= clen;
1345-		l->len -= clen;
1346-		l->buf[l->len] = '\0';
1347-		refreshLine(l);
1348-	}
1349+        if (l->pos > 0 && l->len > 0) {
1350+                size_t clen = utf8PrevCharLen(l->buf, l->pos);
1351+                memmove(l->buf+l->pos-clen, l->buf+l->pos, l->len-l->pos);
1352+                l->pos -= clen;
1353+                l->len -= clen;
1354+                l->buf[l->len] = '\0';
1355+                refreshLine(l);
1356+        }
1357 }
1358 
1359 static void
1360 redlineEditDelete(struct redlineState *l)
1361 {
1362-	if (l->len > 0 && l->pos < l->len) {
1363-		size_t clen = utf8NextCharLen(l->buf, l->pos, l->len);
1364-		memmove(l->buf+l->pos, l->buf+l->pos+clen, l->len-l->pos-clen);
1365-		l->len -= clen;
1366-		l->buf[l->len] = '\0';
1367-		refreshLine(l);
1368-	}
1369+        if (l->len > 0 && l->pos < l->len) {
1370+                size_t clen = utf8NextCharLen(l->buf, l->pos, l->len);
1371+                memmove(l->buf+l->pos, l->buf+l->pos+clen, l->len-l->pos-clen);
1372+                l->len -= clen;
1373+                l->buf[l->len] = '\0';
1374+                refreshLine(l);
1375+        }
1376 }
1377 
1378 static void
1379 redlineEditMoveLeft(struct redlineState *l)
1380 {
1381-	if (l->pos > 0) {
1382-		l->pos -= utf8PrevCharLen(l->buf, l->pos);
1383-		refreshLine(l);
1384-	}
1385+        if (l->pos > 0) {
1386+                l->pos -= utf8PrevCharLen(l->buf, l->pos);
1387+                refreshLine(l);
1388+        }
1389 }
1390 
1391 static void
1392 redlineEditMoveRight(struct redlineState *l)
1393 {
1394-	if (l->pos != l->len) {
1395-		l->pos += utf8NextCharLen(l->buf, l->pos, l->len);
1396-		refreshLine(l);
1397-	}
1398+        if (l->pos != l->len) {
1399+                l->pos += utf8NextCharLen(l->buf, l->pos, l->len);
1400+                refreshLine(l);
1401+        }
1402 }
1403 
1404 static void
1405 redlineEditMoveHome(struct redlineState *l)
1406 {
1407-	if (l->pos != 0) {
1408-		l->pos = 0;
1409-		refreshLine(l);
1410-	}
1411+        if (l->pos != 0) {
1412+                l->pos = 0;
1413+                refreshLine(l);
1414+        }
1415 }
1416 
1417 static void
1418 redlineEditMoveEnd(struct redlineState *l)
1419 {
1420-	if (l->pos != l->len) {
1421-		l->pos = l->len;
1422-		refreshLine(l);
1423-	}
1424+        if (l->pos != l->len) {
1425+                l->pos = l->len;
1426+                refreshLine(l);
1427+        }
1428 }
1429 
1430 static void
1431 redlineEditMoveWordLeft(struct redlineState *l)
1432 {
1433-	if (l->pos > 0) {
1434-		while (l->pos > 0 && l->buf[l->pos-1] == ' ')
1435-			l->pos -= utf8PrevCharLen(l->buf, l->pos);
1436-		while (l->pos > 0 && l->buf[l->pos-1] != ' ')
1437-			l->pos -= utf8PrevCharLen(l->buf, l->pos);
1438-		refreshLine(l);
1439-	}
1440+        if (l->pos > 0) {
1441+                while (l->pos > 0 && l->buf[l->pos-1] == ' ')
1442+                        l->pos -= utf8PrevCharLen(l->buf, l->pos);
1443+                while (l->pos > 0 && l->buf[l->pos-1] != ' ')
1444+                        l->pos -= utf8PrevCharLen(l->buf, l->pos);
1445+                refreshLine(l);
1446+        }
1447 }
1448 
1449 static void
1450 redlineEditMoveWordRight(struct redlineState *l)
1451 {
1452-	if (l->pos < l->len) {
1453-		while (l->pos < l->len && l->buf[l->pos] == ' ')
1454-			l->pos += utf8NextCharLen(l->buf, l->pos, l->len);
1455-		while (l->pos < l->len && l->buf[l->pos] != ' ')
1456-			l->pos += utf8NextCharLen(l->buf, l->pos, l->len);
1457-		refreshLine(l);
1458-	}
1459+        if (l->pos < l->len) {
1460+                while (l->pos < l->len && l->buf[l->pos] == ' ')
1461+                        l->pos += utf8NextCharLen(l->buf, l->pos, l->len);
1462+                while (l->pos < l->len && l->buf[l->pos] != ' ')
1463+                        l->pos += utf8NextCharLen(l->buf, l->pos, l->len);
1464+                refreshLine(l);
1465+        }
1466 }
1467 
1468 static void
1469 killBufferSave(const char *text, size_t len)
1470 {
1471-	free(kill_buffer);
1472-	kill_buffer = malloc(len + 1);
1473-	if (kill_buffer) {
1474-		memcpy(kill_buffer, text, len);
1475-		kill_buffer[len] = '\0';
1476-	}
1477+        free(kill_buffer);
1478+        kill_buffer = malloc(len + 1);
1479+        if (kill_buffer) {
1480+                memcpy(kill_buffer, text, len);
1481+                kill_buffer[len] = '\0';
1482+        }
1483 }
1484 
1485 static void
1486 redlineEditDeleteWordRight(struct redlineState *l)
1487 {
1488-	size_t old_pos = l->pos;
1489-	size_t diff;
1490-	if (l->pos < l->len) {
1491-		while (l->pos < l->len && l->buf[l->pos] == ' ')
1492-			l->pos += utf8NextCharLen(l->buf, l->pos, l->len);
1493-		while (l->pos < l->len && l->buf[l->pos] != ' ')
1494-			l->pos += utf8NextCharLen(l->buf, l->pos, l->len);
1495-		diff = l->pos - old_pos;
1496-		l->pos = old_pos;
1497-		killBufferSave(l->buf + l->pos, diff);
1498-		memmove(l->buf + l->pos, l->buf + l->pos + diff, l->len - l->pos - diff + 1);
1499-		l->len -= diff;
1500-		refreshLine(l);
1501-	}
1502+        size_t old_pos = l->pos;
1503+        size_t diff;
1504+        if (l->pos < l->len) {
1505+                while (l->pos < l->len && l->buf[l->pos] == ' ')
1506+                        l->pos += utf8NextCharLen(l->buf, l->pos, l->len);
1507+                while (l->pos < l->len && l->buf[l->pos] != ' ')
1508+                        l->pos += utf8NextCharLen(l->buf, l->pos, l->len);
1509+                diff = l->pos - old_pos;
1510+                l->pos = old_pos;
1511+                killBufferSave(l->buf + l->pos, diff);
1512+                memmove(l->buf + l->pos, l->buf + l->pos + diff, l->len - l->pos - diff + 1);
1513+                l->len -= diff;
1514+                refreshLine(l);
1515+        }
1516 }
1517 
1518 static void
1519 redlineEditDeletePrevWord(struct redlineState *l)
1520 {
1521-	size_t old_pos = l->pos;
1522-	size_t diff;
1523-	if (l->pos > 0) {
1524-		while (l->pos > 0 && l->buf[l->pos-1] == ' ')
1525-			l->pos -= utf8PrevCharLen(l->buf, l->pos);
1526-		while (l->pos > 0 && l->buf[l->pos-1] != ' ')
1527-			l->pos -= utf8PrevCharLen(l->buf, l->pos);
1528-		diff = old_pos - l->pos;
1529-		killBufferSave(l->buf + l->pos, diff);
1530-		memmove(l->buf + l->pos, l->buf + old_pos, l->len - old_pos + 1);
1531-		l->len -= diff;
1532-		refreshLine(l);
1533-	}
1534+        size_t old_pos = l->pos;
1535+        size_t diff;
1536+        if (l->pos > 0) {
1537+                while (l->pos > 0 && l->buf[l->pos-1] == ' ')
1538+                        l->pos -= utf8PrevCharLen(l->buf, l->pos);
1539+                while (l->pos > 0 && l->buf[l->pos-1] != ' ')
1540+                        l->pos -= utf8PrevCharLen(l->buf, l->pos);
1541+                diff = old_pos - l->pos;
1542+                killBufferSave(l->buf + l->pos, diff);
1543+                memmove(l->buf + l->pos, l->buf + old_pos, l->len - old_pos + 1);
1544+                l->len -= diff;
1545+                refreshLine(l);
1546+        }
1547 }
1548 
1549 void
1550 redlineHistoryAdd(const char *line)
1551 {
1552-	char *linecopy;
1553-	if (history_max_len == 0) return;
1554-	if (history == NULL) {
1555-		history = malloc(sizeof(char*) * history_max_len);
1556-		if (history == NULL) return;
1557-		memset(history,0,sizeof(char*)*history_max_len);
1558-	}
1559-	if (history_len && strcmp(history[history_len-1], line) == 0) return;
1560-	linecopy = strdup(line);
1561-	if (!linecopy) return;
1562-	if (history_len == history_max_len) {
1563-		free(history[0]);
1564-		memmove(history,history+1,sizeof(char*)*(history_max_len-1));
1565-		history_len--;
1566-	}
1567-	history[history_len] = linecopy;
1568-	history_len++;
1569+        char *linecopy;
1570+        if (history_max_len == 0) return;
1571+        if (history == NULL) {
1572+                history = malloc(sizeof(char*) * history_max_len);
1573+                if (history == NULL) return;
1574+                memset(history,0,sizeof(char*)*history_max_len);
1575+        }
1576+        if (history_len && strcmp(history[history_len-1], line) == 0) return;
1577+        linecopy = strdup(line);
1578+        if (!linecopy) return;
1579+        if (history_len == history_max_len) {
1580+                free(history[0]);
1581+                memmove(history,history+1,sizeof(char*)*(history_max_len-1));
1582+                history_len--;
1583+        }
1584+        history[history_len] = linecopy;
1585+        history_len++;
1586 }
1587 
1588 void
1589 redlineHistorySetMaxLen(int len)
1590 {
1591-	char **new;
1592-	if (len < 1) return;
1593-	if (history) {
1594-		int tocopy = history_len;
1595-		new = malloc(sizeof(char*)*len);
1596-		if (new == NULL) return;
1597-		if (len < tocopy) {
1598-			int j;
1599-			for (j = 0; j < tocopy-len; j++) free(history[j]);
1600-			tocopy = len;
1601-		}
1602-		memset(new,0,sizeof(char*)*len);
1603-		memcpy(new,history+(history_len-tocopy), sizeof(char*)*tocopy);
1604-		free(history);
1605-		history = new;
1606-	}
1607-	history_max_len = len;
1608-	if (history_len > history_max_len)
1609-		history_len = history_max_len;
1610+        char **new;
1611+        if (len < 1) return;
1612+        if (history) {
1613+                int tocopy = history_len;
1614+                new = malloc(sizeof(char*)*len);
1615+                if (new == NULL) return;
1616+                if (len < tocopy) {
1617+                        int j;
1618+                        for (j = 0; j < tocopy-len; j++) free(history[j]);
1619+                        tocopy = len;
1620+                }
1621+                memset(new,0,sizeof(char*)*len);
1622+                memcpy(new,history+(history_len-tocopy), sizeof(char*)*tocopy);
1623+                free(history);
1624+                history = new;
1625+        }
1626+        history_max_len = len;
1627+        if (history_len > history_max_len)
1628+                history_len = history_max_len;
1629 }
1630 
1631 int
1632 redlineHistorySave(const char *filename)
1633 {
1634-	mode_t old_umask = umask(S_IXUSR|S_IRWXG|S_IRWXO);
1635-	FILE *fp;
1636-	int j;
1637-
1638-	fp = fopen(filename,"w");
1639-	umask(old_umask);
1640-	if (fp == NULL) return -1;
1641-	chmod(filename,S_IRUSR|S_IWUSR);
1642-	for (j = 0; j < history_len; j++) {
1643-		fprintf(fp,"%s\n",history[j]);
1644-	}
1645-	fclose(fp);
1646-	return 0;
1647+        mode_t old_umask = umask(S_IXUSR|S_IRWXG|S_IRWXO);
1648+        FILE *fp;
1649+        int j;
1650+
1651+        fp = fopen(filename,"w");
1652+        umask(old_umask);
1653+        if (fp == NULL) return -1;
1654+        chmod(filename,S_IRUSR|S_IWUSR);
1655+        for (j = 0; j < history_len; j++) {
1656+                fprintf(fp,"%s\n",history[j]);
1657+        }
1658+        fclose(fp);
1659+        return 0;
1660 }
1661 
1662 int
1663 redlineHistoryLoad(const char *filename)
1664 {
1665-	FILE *fp = fopen(filename,"r");
1666-	char buf[REDLINE_INITIAL_BUFLEN];
1667-	if (fp == NULL) return -1;
1668-	while (fgets(buf,sizeof(buf),fp) != NULL) {
1669-		char *p = strchr(buf,'\r');
1670-		if (!p) p = strchr(buf,'\n');
1671-		if (p) *p = '\0';
1672-		redlineHistoryAdd(buf);
1673-	}
1674-	fclose(fp);
1675-	return 0;
1676+        FILE *fp = fopen(filename,"r");
1677+        char buf[REDLINE_INITIAL_BUFLEN];
1678+        if (fp == NULL) return -1;
1679+        while (fgets(buf,sizeof(buf),fp) != NULL) {
1680+                char *p = strchr(buf,'\r');
1681+                if (!p) p = strchr(buf,'\n');
1682+                if (p) *p = '\0';
1683+                redlineHistoryAdd(buf);
1684+        }
1685+        fclose(fp);
1686+        return 0;
1687 }
1688 
1689 char *
1690 redlineHistoryGet(int idx)
1691 {
1692-	if (idx >= 0 && idx < history_len)
1693-		return history[idx];
1694-	return NULL;
1695+        if (idx >= 0 && idx < history_len)
1696+                return history[idx];
1697+        return NULL;
1698 }
1699 
1700 int
1701 redlineHistoryLen(void)
1702 {
1703-	return history_len;
1704+        return history_len;
1705 }
1706 
1707 static void
1708 redlineEditHistoryNext(struct redlineState *l, int dir)
1709 {
1710-	if (history_len > 1) {
1711-		const char *src;
1712-		size_t len;
1713-		free(history[history_len - 1 - l->history_index]);
1714-		history[history_len - 1 - l->history_index] = strdup(l->buf);
1715-		l->history_index += (dir == 1) ? 1 : -1;
1716-		if (l->history_index < 0) {
1717-			l->history_index = 0;
1718-			return;
1719-		} else if (l->history_index >= history_len) {
1720-			l->history_index = history_len - 1;
1721-			return;
1722-		}
1723-		src = history[history_len - 1 - l->history_index];
1724-		len = strlen(src);
1725-		if (len >= l->buflen) len = l->buflen - 1;
1726-		memcpy(l->buf, src, len);
1727-		l->buf[len] = '\0';
1728-		l->len = l->pos = len;
1729-		refreshLine(l);
1730-	}
1731+        if (history_len > 1) {
1732+                const char *src;
1733+                size_t len;
1734+                free(history[history_len - 1 - l->history_index]);
1735+                history[history_len - 1 - l->history_index] = strdup(l->buf);
1736+                l->history_index += (dir == 1) ? 1 : -1;
1737+                if (l->history_index < 0) {
1738+                        l->history_index = 0;
1739+                        return;
1740+                } else if (l->history_index >= history_len) {
1741+                        l->history_index = history_len - 1;
1742+                        return;
1743+                }
1744+                src = history[history_len - 1 - l->history_index];
1745+                len = strlen(src);
1746+                if (len >= l->buflen) len = l->buflen - 1;
1747+                memcpy(l->buf, src, len);
1748+                l->buf[len] = '\0';
1749+                l->len = l->pos = len;
1750+                refreshLine(l);
1751+        }
1752 }
1753 
1754 static char *
1755 redlineReadLine(FILE *fp)
1756 {
1757-	char *line = NULL;
1758-	size_t len = 0, cap = 0;
1759-	while (1) {
1760-		if (len+1 >= cap) {
1761-			size_t newcap = cap ? cap*2 : 16;
1762-			char *new = realloc(line, newcap);
1763-			if (!new) {
1764-				free(line);
1765-				return NULL;
1766-			}
1767-			line = new;
1768-			cap = newcap;
1769-		}
1770-		int c = fgetc(fp);
1771-		if (c == EOF || c == '\n') {
1772-			if (c == EOF && len == 0) {
1773-				free(line);
1774-				return NULL;
1775-			}
1776-			line[len] = '\0';
1777-			return line;
1778-		}
1779-		line[len++] = c;
1780-	}
1781+        char *line = NULL;
1782+        size_t len = 0, cap = 0;
1783+        while (1) {
1784+                if (len+1 >= cap) {
1785+                        size_t newcap = cap ? cap*2 : 16;
1786+                        char *new = realloc(line, newcap);
1787+                        if (!new) {
1788+                                free(line);
1789+                                return NULL;
1790+                        }
1791+                        line = new;
1792+                        cap = newcap;
1793+                }
1794+                int c = fgetc(fp);
1795+                if (c == EOF || c == '\n') {
1796+                        if (c == EOF && len == 0) {
1797+                                free(line);
1798+                                return NULL;
1799+                        }
1800+                        line[len] = '\0';
1801+                        return line;
1802+                }
1803+                line[len++] = c;
1804+        }
1805 }
1806 
1807 static char *
1808 redlineNoTTY(void)
1809 {
1810-	return redlineReadLine(stdin);
1811+        return redlineReadLine(stdin);
1812 }
1813 
1814 void
1815 redlineClearScreen(void)
1816 {
1817-	if (write(STDOUT_FILENO, "\x1b[H\x1b[2J", 7) == -1) {}
1818+        if (write(STDOUT_FILENO, "\x1b[H\x1b[2J", 7) == -1) {}
1819 }
1820 
1821 static char *
1822 redlineEditFeed(struct redlineState *l)
1823 {
1824-	char c;
1825-	int nread;
1826-	char seq[3];
1827-	char param[8];
1828-	size_t plen;
1829-	char final;
1830-	char p;
1831-	int is_word_jump;
1832-	char tmp[32];
1833-	size_t prevlen;
1834-	size_t currlen;
1835-	size_t prevstart;
1836-	char utf8[4];
1837-	int utf8len;
1838-	int i;
1839-
1840-	if (!isatty(l->ifd) && !getenv("REDLINE_ASSUME_TTY")) return redlineNoTTY();
1841-
1842-	while (1) {
1843-		nread = read(l->ifd, &c, 1);
1844-		if (nread < 0) {
1845-			if (errno == EINTR) {
1846-				if (winch_received) {
1847-					winch_received = 0;
1848-					l->cols = getColumns(l->ifd, l->ofd);
1849-					refreshLine(l);
1850-				}
1851-				continue;
1852-			}
1853-			return (errno == EAGAIN || errno == EWOULDBLOCK) ? "more" : NULL;
1854-		} else if (nread == 0) {
1855-			return NULL;
1856-		}
1857-		break;
1858-	}
1859-
1860-	if ((l->in_completion || c == 9) && completionCallback != NULL) {
1861-		int retval = completeLine(l, c);
1862-		if (retval == 0) return "more";
1863-		c = retval;
1864-	}
1865-
1866-	switch (c) {
1867-	case ENTER:
1868-		if (mlmode) redlineEditMoveEnd(l);
1869-		return strdup(l->buf);
1870-	case CTRL_C:
1871-		errno = EAGAIN;
1872-		return NULL;
1873-	case BACKSPACE:
1874-	case 8:
1875-		redlineEditBackspace(l);
1876-		break;
1877-	case CTRL_D:
1878-		if (l->len > 0) {
1879-			redlineEditDelete(l);
1880-		} else {
1881-			errno = ENOENT;
1882-			return NULL;
1883-		}
1884-		break;
1885-	case CTRL_T:
1886-		if (l->pos > 0 && l->pos < l->len) {
1887-			prevlen = utf8PrevCharLen(l->buf, l->pos);
1888-			currlen = utf8NextCharLen(l->buf, l->pos, l->len);
1889-			prevstart = l->pos - prevlen;
1890-			if (prevlen > sizeof(tmp) || currlen > sizeof(tmp)) break;
1891-			memcpy(tmp, l->buf + l->pos, currlen);
1892-			memmove(l->buf + prevstart + currlen, l->buf + prevstart, prevlen);
1893-			memcpy(l->buf + prevstart, tmp, currlen);
1894-			if (l->pos + currlen <= l->len) l->pos += currlen;
1895-			refreshLine(l);
1896-		}
1897-		break;
1898-	case CTRL_B:
1899-		redlineEditMoveLeft(l);
1900-		break;
1901-	case CTRL_F:
1902-		redlineEditMoveRight(l);
1903-		break;
1904-	case CTRL_P:
1905-		redlineEditHistoryNext(l, 1);
1906-		break;
1907-	case CTRL_N:
1908-		redlineEditHistoryNext(l, 0);
1909-		break;
1910-	case ESC:
1911-		if (read(l->ifd, seq, 1) == -1) break;
1912-		if (seq[0] == '[' || seq[0] == 'O') {
1913-			if (read(l->ifd, seq+1, 1) == -1) break;
1914-			if (seq[0] == '[') {
1915-				if (seq[1] >= '0' && seq[1] <= '9') {
1916-					plen = 1;
1917-					final = 0;
1918-					param[0] = seq[1];
1919-					while (plen < sizeof(param)) {
1920-						if (read(l->ifd, &p, 1) != 1) break;
1921-						if ((p >= '0' && p <= '9') || p == ';') {
1922-							param[plen++] = p;
1923-						} else {
1924-							final = p;
1925-							break;
1926-						}
1927-					}
1928-					if (final == '~') {
1929-						if (plen == 1 && param[0] == '3') {
1930-							redlineEditDelete(l);
1931-						}
1932-					} else if (final == 'D' || final == 'C') {
1933-						is_word_jump = 0;
1934-						if (plen == 3 && param[0] == '1' && param[1] == ';' && (param[2] == '5' || param[2] == '3')) {
1935-							is_word_jump = 1;
1936-						} else if (plen == 1 && (param[0] == '5' || param[0] == '3')) {
1937-							is_word_jump = 1;
1938-						}
1939-						if (is_word_jump) {
1940-							if (final == 'D') {
1941-								redlineEditMoveWordLeft(l);
1942-							} else {
1943-								redlineEditMoveWordRight(l);
1944-							}
1945-						}
1946-					}
1947-				} else {
1948-					switch (seq[1]) {
1949-					case 'A':
1950-						redlineEditHistoryNext(l, 1);
1951-						break;
1952-					case 'B':
1953-						redlineEditHistoryNext(l, 0);
1954-						break;
1955-					case 'C':
1956-						redlineEditMoveRight(l);
1957-						break;
1958-					case 'D':
1959-						redlineEditMoveLeft(l);
1960-						break;
1961-					case 'H':
1962-						redlineEditMoveHome(l);
1963-						break;
1964-					case 'F':
1965-						redlineEditMoveEnd(l);
1966-						break;
1967-					}
1968-				}
1969-			} else if (seq[0] == 'O') {
1970-				switch (seq[1]) {
1971-				case 'H':
1972-					redlineEditMoveHome(l);
1973-					break;
1974-				case 'F':
1975-					redlineEditMoveEnd(l);
1976-					break;
1977-				}
1978-			}
1979-		} else {
1980-			if (seq[0] == 'b' || seq[0] == 'B') {
1981-				redlineEditMoveWordLeft(l);
1982-			} else if (seq[0] == 'f' || seq[0] == 'F') {
1983-				redlineEditMoveWordRight(l);
1984-			} else if (seq[0] == 'd' || seq[0] == 'D') {
1985-				redlineEditDeleteWordRight(l);
1986-			} else if (seq[0] == 127 || seq[0] == 8) {
1987-				redlineEditDeletePrevWord(l);
1988-			}
1989-		}
1990-		break;
1991-	default:
1992-		utf8len = utf8ByteLen(c);
1993-		utf8[0] = c;
1994-		if (utf8len > 1) {
1995-			for (i = 1; i < utf8len; i++) {
1996-				if (read(l->ifd, utf8+i, 1) != 1) break;
1997-			}
1998-		}
1999-		if (redlineEditInsert(l, utf8, utf8len) == 0) return NULL;
2000-		break;
2001-	case CTRL_U:
2002-		killBufferSave(l->buf, l->pos);
2003-		memmove(l->buf, l->buf + l->pos, l->len - l->pos + 1);
2004-		l->len -= l->pos;
2005-		l->pos = 0;
2006-		refreshLine(l);
2007-		break;
2008-	case CTRL_K:
2009-		killBufferSave(l->buf + l->pos, l->len - l->pos);
2010-		l->buf[l->pos] = '\0';
2011-		l->len = l->pos;
2012-		refreshLine(l);
2013-		break;
2014-	case CTRL_A:
2015-		redlineEditMoveHome(l);
2016-		break;
2017-	case CTRL_E:
2018-		redlineEditMoveEnd(l);
2019-		break;
2020-	case CTRL_L:
2021-		redlineClearScreen();
2022-		refreshLine(l);
2023-		break;
2024-	case CTRL_W:
2025-		redlineEditDeletePrevWord(l);
2026-		break;
2027-	case CTRL_Y:
2028-		if (kill_buffer) {
2029-			redlineEditInsert(l, kill_buffer, strlen(kill_buffer));
2030-		}
2031-		break;
2032-	}
2033-	return "more";
2034+        char c;
2035+        int nread;
2036+        char seq[3];
2037+        char param[8];
2038+        size_t plen;
2039+        char final;
2040+        char p;
2041+        int is_word_jump;
2042+        char tmp[32];
2043+        size_t prevlen;
2044+        size_t currlen;
2045+        size_t prevstart;
2046+        char utf8[4];
2047+        int utf8len;
2048+        int i;
2049+
2050+        if (!isatty(l->ifd) && !getenv("REDLINE_ASSUME_TTY")) return redlineNoTTY();
2051+
2052+        while (1) {
2053+                nread = read(l->ifd, &c, 1);
2054+                if (nread < 0) {
2055+                        if (errno == EINTR) {
2056+                                if (winch_received) {
2057+                                        winch_received = 0;
2058+                                        l->cols = getColumns(l->ifd, l->ofd);
2059+                                        refreshLine(l);
2060+                                }
2061+                                continue;
2062+                        }
2063+                        return (errno == EAGAIN || errno == EWOULDBLOCK) ? "more" : NULL;
2064+                } else if (nread == 0) {
2065+                        return NULL;
2066+                }
2067+                break;
2068+        }
2069+
2070+        if ((l->in_completion || c == 9) && completionCallback != NULL) {
2071+                int retval = completeLine(l, c);
2072+                if (retval == 0) return "more";
2073+                c = retval;
2074+        }
2075+
2076+        switch (c) {
2077+        case ENTER:
2078+                if (mlmode) redlineEditMoveEnd(l);
2079+                return strdup(l->buf);
2080+        case CTRL_C:
2081+                errno = EAGAIN;
2082+                return NULL;
2083+        case BACKSPACE:
2084+        case 8:
2085+                redlineEditBackspace(l);
2086+                break;
2087+        case CTRL_D:
2088+                if (l->len > 0) {
2089+                        redlineEditDelete(l);
2090+                } else {
2091+                        errno = ENOENT;
2092+                        return NULL;
2093+                }
2094+                break;
2095+        case CTRL_T:
2096+                if (l->pos > 0 && l->pos < l->len) {
2097+                        prevlen = utf8PrevCharLen(l->buf, l->pos);
2098+                        currlen = utf8NextCharLen(l->buf, l->pos, l->len);
2099+                        prevstart = l->pos - prevlen;
2100+                        if (prevlen > sizeof(tmp) || currlen > sizeof(tmp)) break;
2101+                        memcpy(tmp, l->buf + l->pos, currlen);
2102+                        memmove(l->buf + prevstart + currlen, l->buf + prevstart, prevlen);
2103+                        memcpy(l->buf + prevstart, tmp, currlen);
2104+                        if (l->pos + currlen <= l->len) l->pos += currlen;
2105+                        refreshLine(l);
2106+                }
2107+                break;
2108+        case CTRL_B:
2109+                redlineEditMoveLeft(l);
2110+                break;
2111+        case CTRL_F:
2112+                redlineEditMoveRight(l);
2113+                break;
2114+        case CTRL_P:
2115+                redlineEditHistoryNext(l, 1);
2116+                break;
2117+        case CTRL_N:
2118+                redlineEditHistoryNext(l, 0);
2119+                break;
2120+        case ESC:
2121+                if (read(l->ifd, seq, 1) == -1) break;
2122+                if (seq[0] == '[' || seq[0] == 'O') {
2123+                        if (read(l->ifd, seq+1, 1) == -1) break;
2124+                        if (seq[0] == '[') {
2125+                                if (seq[1] >= '0' && seq[1] <= '9') {
2126+                                        plen = 1;
2127+                                        final = 0;
2128+                                        param[0] = seq[1];
2129+                                        while (plen < sizeof(param)) {
2130+                                                if (read(l->ifd, &p, 1) != 1) break;
2131+                                                if ((p >= '0' && p <= '9') || p == ';') {
2132+                                                        param[plen++] = p;
2133+                                                } else {
2134+                                                        final = p;
2135+                                                        break;
2136+                                                }
2137+                                        }
2138+                                        if (final == '~') {
2139+                                                if (plen == 1 && param[0] == '3') {
2140+                                                        redlineEditDelete(l);
2141+                                                }
2142+                                        } else if (final == 'D' || final == 'C') {
2143+                                                is_word_jump = 0;
2144+                                                if (plen == 3 && param[0] == '1' && param[1] == ';' && (param[2] == '5' || param[2] == '3')) {
2145+                                                        is_word_jump = 1;
2146+                                                } else if (plen == 1 && (param[0] == '5' || param[0] == '3')) {
2147+                                                        is_word_jump = 1;
2148+                                                }
2149+                                                if (is_word_jump) {
2150+                                                        if (final == 'D') {
2151+                                                                redlineEditMoveWordLeft(l);
2152+                                                        } else {
2153+                                                                redlineEditMoveWordRight(l);
2154+                                                        }
2155+                                                }
2156+                                        }
2157+                                } else {
2158+                                        switch (seq[1]) {
2159+                                        case 'A':
2160+                                                redlineEditHistoryNext(l, 1);
2161+                                                break;
2162+                                        case 'B':
2163+                                                redlineEditHistoryNext(l, 0);
2164+                                                break;
2165+                                        case 'C':
2166+                                                redlineEditMoveRight(l);
2167+                                                break;
2168+                                        case 'D':
2169+                                                redlineEditMoveLeft(l);
2170+                                                break;
2171+                                        case 'H':
2172+                                                redlineEditMoveHome(l);
2173+                                                break;
2174+                                        case 'F':
2175+                                                redlineEditMoveEnd(l);
2176+                                                break;
2177+                                        }
2178+                                }
2179+                        } else if (seq[0] == 'O') {
2180+                                switch (seq[1]) {
2181+                                case 'H':
2182+                                        redlineEditMoveHome(l);
2183+                                        break;
2184+                                case 'F':
2185+                                        redlineEditMoveEnd(l);
2186+                                        break;
2187+                                }
2188+                        }
2189+                } else {
2190+                        if (seq[0] == 'b' || seq[0] == 'B') {
2191+                                redlineEditMoveWordLeft(l);
2192+                        } else if (seq[0] == 'f' || seq[0] == 'F') {
2193+                                redlineEditMoveWordRight(l);
2194+                        } else if (seq[0] == 'd' || seq[0] == 'D') {
2195+                                redlineEditDeleteWordRight(l);
2196+                        } else if (seq[0] == 127 || seq[0] == 8) {
2197+                                redlineEditDeletePrevWord(l);
2198+                        }
2199+                }
2200+                break;
2201+        default:
2202+                utf8len = utf8ByteLen(c);
2203+                utf8[0] = c;
2204+                if (utf8len > 1) {
2205+                        for (i = 1; i < utf8len; i++) {
2206+                                if (read(l->ifd, utf8+i, 1) != 1) break;
2207+                        }
2208+                }
2209+                if (redlineEditInsert(l, utf8, utf8len) == 0) return NULL;
2210+                break;
2211+        case CTRL_U:
2212+                killBufferSave(l->buf, l->pos);
2213+                memmove(l->buf, l->buf + l->pos, l->len - l->pos + 1);
2214+                l->len -= l->pos;
2215+                l->pos = 0;
2216+                refreshLine(l);
2217+                break;
2218+        case CTRL_K:
2219+                killBufferSave(l->buf + l->pos, l->len - l->pos);
2220+                l->buf[l->pos] = '\0';
2221+                l->len = l->pos;
2222+                refreshLine(l);
2223+                break;
2224+        case CTRL_A:
2225+                redlineEditMoveHome(l);
2226+                break;
2227+        case CTRL_E:
2228+                redlineEditMoveEnd(l);
2229+                break;
2230+        case CTRL_L:
2231+                redlineClearScreen();
2232+                refreshLine(l);
2233+                break;
2234+        case CTRL_W:
2235+                redlineEditDeletePrevWord(l);
2236+                break;
2237+        case CTRL_Y:
2238+                if (kill_buffer) {
2239+                        redlineEditInsert(l, kill_buffer, strlen(kill_buffer));
2240+                }
2241+                break;
2242+        }
2243+        return "more";
2244 }
2245 
2246 static int
2247 redlineEditStart(struct redlineState *l, int stdin_fd, int stdout_fd, char *buf, size_t buflen, const char *prompt)
2248 {
2249-	l->in_completion = 0;
2250-	l->ifd = stdin_fd;
2251-	l->ofd = stdout_fd;
2252-	l->buf = buf;
2253-	l->buflen = buflen;
2254-	l->prompt = prompt;
2255-	l->plen = strlen(prompt);
2256-	l->pos = 0;
2257-	l->oldpos = 0;
2258-	l->len = 0;
2259-	l->cols = getColumns(stdin_fd, stdout_fd);
2260-	l->oldrows = 0;
2261-	l->oldrpos = 0;
2262-	l->history_index = 0;
2263-	l->buf[0] = '\0';
2264-
2265-	if (enableRawMode(l->ifd) == -1) return -1;
2266-	refreshLine(l);
2267-	return 0;
2268+        l->in_completion = 0;
2269+        l->ifd = stdin_fd;
2270+        l->ofd = stdout_fd;
2271+        l->buf = buf;
2272+        l->buflen = buflen;
2273+        l->prompt = prompt;
2274+        l->plen = strlen(prompt);
2275+        l->pos = 0;
2276+        l->oldpos = 0;
2277+        l->len = 0;
2278+        l->cols = getColumns(stdin_fd, stdout_fd);
2279+        l->oldrows = 0;
2280+        l->oldrpos = 0;
2281+        l->history_index = 0;
2282+        l->buf[0] = '\0';
2283+
2284+        if (enableRawMode(l->ifd) == -1) return -1;
2285+        refreshLine(l);
2286+        return 0;
2287 }
2288 
2289 static void
2290 redlineEditStop(struct redlineState *l)
2291 {
2292-	if (!isatty(l->ifd) && !getenv("REDLINE_ASSUME_TTY")) return;
2293-	disableRawMode(l->ifd);
2294-	printf("\n");
2295+        if (!isatty(l->ifd) && !getenv("REDLINE_ASSUME_TTY")) return;
2296+        disableRawMode(l->ifd);
2297+        printf("\n");
2298 }
2299 
2300 char *
2301 redline(const char *prompt)
2302 {
2303-	struct redlineState l;
2304-	char *buf;
2305-	char *res;
2306-
2307-	if (!isatty(STDIN_FILENO) || isUnsupportedTerm()) {
2308-		if (write(STDOUT_FILENO, prompt, strlen(prompt)) == -1) {}
2309-		return redlineNoTTY();
2310-	}
2311-
2312-	buf = malloc(REDLINE_INITIAL_BUFLEN);
2313-	if (buf == NULL) return NULL;
2314-	if (redlineEditStart(&l, STDIN_FILENO, STDOUT_FILENO, buf, REDLINE_INITIAL_BUFLEN, prompt) == -1) {
2315-		free(buf);
2316-		return NULL;
2317-	}
2318-	redlineHistoryAdd("");
2319-	while (1) {
2320-		res = redlineEditFeed(&l);
2321-		if (res == NULL || strcmp(res, "more") != 0) {
2322-			break;
2323-		}
2324-	}
2325-	redlineEditStop(&l);
2326-	if (history_len > 0) {
2327-		history_len--;
2328-		free(history[history_len]);
2329-	}
2330-	free(l.buf);
2331-	return res;
2332+        struct redlineState l;
2333+        char *buf;
2334+        char *res;
2335+
2336+        if (!isatty(STDIN_FILENO) || isUnsupportedTerm()) {
2337+                if (write(STDOUT_FILENO, prompt, strlen(prompt)) == -1) {}
2338+                return redlineNoTTY();
2339+        }
2340+
2341+        buf = malloc(REDLINE_INITIAL_BUFLEN);
2342+        if (buf == NULL) return NULL;
2343+        if (redlineEditStart(&l, STDIN_FILENO, STDOUT_FILENO, buf, REDLINE_INITIAL_BUFLEN, prompt) == -1) {
2344+                free(buf);
2345+                return NULL;
2346+        }
2347+        redlineHistoryAdd("");
2348+        while (1) {
2349+                res = redlineEditFeed(&l);
2350+                if (res == NULL || strcmp(res, "more") != 0) {
2351+                        break;
2352+                }
2353+        }
2354+        redlineEditStop(&l);
2355+        if (history_len > 0) {
2356+                history_len--;
2357+                free(history[history_len]);
2358+        }
2359+        free(l.buf);
2360+        return res;
2361 }
2362 
2363 void
2364 redlineSetCompletionCallback(void (*cb)(const char *, struct redlineCompletions *))
2365 {
2366-	completionCallback = cb;
2367+        completionCallback = cb;
2368 }
2369 
2370 void
2371 redlineAddCompletion(struct redlineCompletions *lc, const char *str)
2372 {
2373-	size_t len = strlen(str);
2374-	char *copy, **cvec;
2375-
2376-	copy = malloc(len+1);
2377-	if (copy == NULL) return;
2378-	memcpy(copy,str,len+1);
2379-	cvec = realloc(lc->cvec,sizeof(char*)*(lc->len+1));
2380-	if (cvec == NULL) {
2381-		free(copy);
2382-		return;
2383-	}
2384-	lc->cvec = cvec;
2385-	lc->cvec[lc->len++] = copy;
2386+        size_t len = strlen(str);
2387+        char *copy, **cvec;
2388+
2389+        copy = malloc(len+1);
2390+        if (copy == NULL) return;
2391+        memcpy(copy,str,len+1);
2392+        cvec = realloc(lc->cvec,sizeof(char*)*(lc->len+1));
2393+        if (cvec == NULL) {
2394+                free(copy);
2395+                return;
2396+        }
2397+        lc->cvec = cvec;
2398+        lc->cvec[lc->len++] = copy;
2399 }
2400 
2401 void
2402 redlineSetMultiLine(int ml)
2403 {
2404-	mlmode = ml;
2405+        mlmode = ml;
2406 }
+586, -0
  1@@ -0,0 +1,586 @@
  2+/* See LICENSE file for copyright and license details. */
  3+#include "../diffutil.h"
  4+#include "../text.h"
  5+#include "../util.h"
  6+
  7+#include <ctype.h>
  8+#include <stdio.h>
  9+#include <stdlib.h>
 10+#include <string.h>
 11+
 12+static int
 13+read_all(FILE *fp, char **out, size_t *outlen, const char *path)
 14+{
 15+	char buf[8192];
 16+	char *data;
 17+	size_t cap, len;
 18+	ssize_t n;
 19+
 20+	data = NULL;
 21+	cap = len = 0;
 22+	while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
 23+		if (len + (size_t)n > cap) {
 24+			cap = (len + (size_t)n) * 2 + 64;
 25+			data = erealloc(data, cap);
 26+		}
 27+		memcpy(data + len, buf, (size_t)n);
 28+		len += (size_t)n;
 29+	}
 30+	if (ferror(fp)) {
 31+		weprintf("read %s:", path);
 32+		free(data);
 33+		return -1;
 34+	}
 35+	if (!data) {
 36+		data = emalloc(1);
 37+		data[0] = '\0';
 38+	} else if (len == cap) {
 39+		data = erealloc(data, cap + 1);
 40+		data[len] = '\0';
 41+	}
 42+	*out = data;
 43+	*outlen = len;
 44+	return 0;
 45+}
 46+
 47+static void
 48+split_lines(struct diffline **out, size_t *outn, char *data, size_t len)
 49+{
 50+	struct diffline *lines;
 51+	size_t i, n, start;
 52+
 53+	n = 0;
 54+	for (i = 0; i < len; i++)
 55+		if (data[i] == '\n')
 56+			n++;
 57+	if (len > 0 && (len == 0 || data[len - 1] != '\n'))
 58+		n++;
 59+	if (n == 0) {
 60+		*out = NULL;
 61+		*outn = 0;
 62+		return;
 63+	}
 64+	lines = ecalloc(n, sizeof(*lines));
 65+	i = 0;
 66+	start = 0;
 67+	for (n = 0; n < (size_t)len; n++) {
 68+		if (data[n] == '\n') {
 69+			lines[i].data = data + start;
 70+			lines[i].len = n - start;
 71+			i++;
 72+			start = n + 1;
 73+		}
 74+	}
 75+	if (start < len) {
 76+		lines[i].data = data + start;
 77+		lines[i].len = len - start;
 78+		i++;
 79+	}
 80+	*out = lines;
 81+	*outn = i;
 82+}
 83+
 84+int
 85+diff_load(struct difffile *df, const char *path)
 86+{
 87+	FILE *fp;
 88+	char *data;
 89+	size_t len;
 90+
 91+	if (!strcmp(path, "-")) {
 92+		fp = stdin;
 93+	} else if (!(fp = fopen(path, "r"))) {
 94+		weprintf("open %s:", path);
 95+		return -1;
 96+	}
 97+	if (read_all(fp, &data, &len, path) < 0) {
 98+		if (fp != stdin)
 99+			fclose(fp);
100+		return -1;
101+	}
102+	if (fp != stdin)
103+		fclose(fp);
104+	df->lines = NULL;
105+	df->nlines = 0;
106+	if (len == 0) {
107+		df->lines = ecalloc(1, sizeof(*df->lines));
108+		df->lines[0].data = data;
109+		df->lines[0].len = 0;
110+		df->nlines = 0;
111+		return 0;
112+	}
113+	split_lines(&df->lines, &df->nlines, data, len);
114+	{
115+		struct diffline *grown;
116+		grown = erealloc(df->lines, (df->nlines + 1) * sizeof(*grown));
117+		grown[df->nlines].data = data;
118+		grown[df->nlines].len = 0;
119+		df->lines = grown;
120+	}
121+	return 0;
122+}
123+
124+void
125+diff_free(struct difffile *df)
126+{
127+	char *base;
128+
129+	if (!df->lines)
130+		return;
131+	if (df->nlines == 0) {
132+		free(df->lines[0].data);
133+		free(df->lines);
134+		df->lines = NULL;
135+		df->nlines = 0;
136+		return;
137+	}
138+	base = df->lines[df->nlines].data;
139+	free(base);
140+	free(df->lines);
141+	df->lines = NULL;
142+	df->nlines = 0;
143+}
144+
145+static int
146+lines_equal(const struct diffline *a, const struct diffline *b,
147+            const struct diffopts *opts)
148+{
149+	size_t i, j;
150+
151+	if (opts && opts->ignore_blanks) {
152+		i = j = 0;
153+		while (i < a->len && j < b->len) {
154+			while (i < a->len && isspace((unsigned char)a->data[i]))
155+				i++;
156+			while (j < b->len && isspace((unsigned char)b->data[j]))
157+				j++;
158+			if (i >= a->len || j >= b->len)
159+				break;
160+			if (opts->ignore_case) {
161+				if (tolower((unsigned char)a->data[i]) !=
162+				    tolower((unsigned char)b->data[j]))
163+					return 0;
164+			} else if (a->data[i] != b->data[j]) {
165+				return 0;
166+			}
167+			i++;
168+			j++;
169+		}
170+		while (i < a->len && isspace((unsigned char)a->data[i]))
171+			i++;
172+		while (j < b->len && isspace((unsigned char)b->data[j]))
173+			j++;
174+		return i == a->len && j == b->len;
175+	}
176+
177+	if (opts && opts->ignore_case) {
178+		if (a->len != b->len)
179+			return 0;
180+		for (i = 0; i < a->len; i++) {
181+			if (tolower((unsigned char)a->data[i]) !=
182+			    tolower((unsigned char)b->data[i]))
183+				return 0;
184+		}
185+		return 1;
186+	}
187+
188+	if (a->len != b->len)
189+		return 0;
190+	return memcmp(a->data, b->data, a->len) == 0;
191+}
192+
193+struct lcs_cell {
194+	int diag;
195+	int up;
196+	int left;
197+};
198+
199+int
200+diff_compute(struct diffhunks *hunks, const struct difffile *old,
201+             const struct difffile *new, const struct diffopts *opts)
202+{
203+	struct lcs_cell *c;
204+	size_t n, m, i, j, k, cap;
205+	struct diffhunk *h;
206+	int *xs, *ys;
207+	size_t hfrom, hto, vfrom, vto;
208+	struct diffopts default_opts;
209+
210+	if (!opts) {
211+		memset(&default_opts, 0, sizeof(default_opts));
212+		default_opts.context = 3;
213+		opts = &default_opts;
214+	}
215+
216+	n = old->nlines;
217+	m = new->nlines;
218+
219+	if (n == 0 && m == 0) {
220+		hunks->v = NULL;
221+		hunks->n = 0;
222+		return 0;
223+	}
224+
225+	c = ecalloc((n + 1) * (m + 1), sizeof(*c));
226+	for (i = 0; i <= n; i++) {
227+		for (j = 0; j <= m; j++) {
228+			if (i == 0 && j == 0) {
229+				c[i * (m + 1) + j].diag = 0;
230+				continue;
231+			}
232+			if (i > 0 && j > 0 &&
233+			    lines_equal(&old->lines[i - 1], &new->lines[j - 1], opts)) {
234+				c[i * (m + 1) + j].diag = c[(i - 1) * (m + 1) + (j - 1)].diag + 1;
235+				c[i * (m + 1) + j].up = 0;
236+				c[i * (m + 1) + j].left = 0;
237+				continue;
238+			}
239+			if (i > 0 && (j == 0 || c[(i - 1) * (m + 1) + j].diag >=
240+				      c[i * (m + 1) + (j - 1)].diag)) {
241+				c[i * (m + 1) + j].diag = c[(i - 1) * (m + 1) + j].diag;
242+				c[i * (m + 1) + j].up = 1;
243+				c[i * (m + 1) + j].left = 0;
244+			} else {
245+				c[i * (m + 1) + j].diag = c[i * (m + 1) + (j - 1)].diag;
246+				c[i * (m + 1) + j].up = 0;
247+				c[i * (m + 1) + j].left = 1;
248+			}
249+		}
250+	}
251+
252+	cap = n + m + 16;
253+	xs = ecalloc(cap, sizeof(*xs));
254+	ys = ecalloc(cap, sizeof(*ys));
255+	k = 0;
256+	i = n;
257+	j = m;
258+	while (i > 0 || j > 0) {
259+		if (i > 0 && j > 0 &&
260+		    lines_equal(&old->lines[i - 1], &new->lines[j - 1], opts)) {
261+			xs[k] = 0;
262+			ys[k] = 0;
263+			i--;
264+			j--;
265+		} else if (i > 0 && c[i * (m + 1) + j].up) {
266+			xs[k] = 1;
267+			ys[k] = 0;
268+			i--;
269+		} else {
270+			xs[k] = 0;
271+			ys[k] = 2;
272+			j--;
273+		}
274+		k++;
275+	}
276+	hunks->v = NULL;
277+	hunks->n = 0;
278+	h = NULL;
279+	i = 0;
280+	j = 0;
281+	{
282+		size_t step, idx;
283+		int op;
284+		step = k;
285+		while (step > 0) {
286+			idx = step - 1;
287+			op = xs[idx] | ys[idx];
288+			if (op == 0) {
289+				step--;
290+				i++;
291+				j++;
292+				continue;
293+			}
294+			hfrom = i;
295+			vfrom = j;
296+			hto = i;
297+			vto = j;
298+			while (step > 0) {
299+				idx = step - 1;
300+				op = xs[idx] | ys[idx];
301+				if (op == 0)
302+					break;
303+				if (xs[idx] == 1)
304+					hto++;
305+				if (ys[idx] == 2)
306+					vto++;
307+				step--;
308+			}
309+			i = hto;
310+			j = vto;
311+			hunks->v = erealloc(hunks->v, (hunks->n + 1) * sizeof(*h));
312+			h = &hunks->v[hunks->n];
313+			h->old.from = hfrom;
314+			h->old.to = hto;
315+			h->new.from = vfrom;
316+			h->new.to = vto;
317+			hunks->n++;
318+		}
319+	}
320+	free(c);
321+	free(xs);
322+	free(ys);
323+	return 0;
324+}
325+
326+void
327+diff_hunks_free(struct diffhunks *hunks)
328+{
329+	if (!hunks)
330+		return;
331+	free(hunks->v);
332+	hunks->v = NULL;
333+	hunks->n = 0;
334+}
335+
336+int
337+diff_looks_binary(const struct difffile *df)
338+{
339+	size_t i, scan;
340+
341+	scan = 4096;
342+	for (i = 0; i < df->nlines && scan > 0; i++) {
343+		size_t take = df->lines[i].len < scan ? df->lines[i].len : scan;
344+		if (memchr(df->lines[i].data, '\0', take))
345+			return 1;
346+		scan -= take;
347+	}
348+	return 0;
349+}
350+
351+static void
352+print_range(FILE *out, size_t from, size_t to)
353+{
354+	if (to - from <= 1)
355+		fprintf(out, "%zu", from + 1);
356+	else
357+		fprintf(out, "%zu,%zu", from + 1, to);
358+}
359+
360+static void
361+print_lines(FILE *out, const struct diffline *lines, size_t from, size_t to,
362+            char prefix)
363+{
364+	size_t i;
365+	for (i = from; i < to; i++) {
366+		fputc(prefix, out);
367+		fwrite(lines[i].data, 1, lines[i].len, out);
368+		fputc('\n', out);
369+	}
370+}
371+
372+static int
373+format_normal(FILE *out, const struct diffhunks *hunks,
374+              const struct difffile *old, const struct difffile *new)
375+{
376+	size_t i;
377+	for (i = 0; i < hunks->n; i++) {
378+		struct diffhunk *h = &hunks->v[i];
379+		size_t oldn = h->old.to - h->old.from;
380+		size_t newn = h->new.to - h->new.from;
381+		char oc;
382+
383+		oc = oldn == 0 ? 'a' : (newn == 0 ? 'd' : 'c');
384+		print_range(out, h->old.from, h->old.to);
385+		fputc(oc, out);
386+		print_range(out, h->new.from, h->new.to);
387+		fputc('\n', out);
388+		if (oldn && newn) {
389+			print_lines(out, old->lines, h->old.from, h->old.to, '<');
390+			fprintf(out, "---\n");
391+			print_lines(out, new->lines, h->new.from, h->new.to, '>');
392+		} else if (oldn) {
393+			print_lines(out, old->lines, h->old.from, h->old.to, '<');
394+		} else {
395+			print_lines(out, new->lines, h->new.from, h->new.to, '>');
396+		}
397+	}
398+	return 0;
399+}
400+
401+static void
402+emit_unified_hunk(FILE *out, const struct diffhunk *h,
403+                  const struct difffile *old, const struct difffile *new,
404+                  size_t ctx)
405+{
406+	size_t oldfrom, oldto, newfrom, newto;
407+	size_t i;
408+
409+	oldfrom = h->old.from < ctx ? 0 : h->old.from - ctx;
410+	oldto = h->old.to + ctx;
411+	if (oldto > old->nlines)
412+		oldto = old->nlines;
413+	newfrom = h->new.from < ctx ? 0 : h->new.from - ctx;
414+	newto = h->new.to + ctx;
415+	if (newto > new->nlines)
416+		newto = new->nlines;
417+
418+	if (oldto - oldfrom <= 1)
419+		fprintf(out, "@@ -%zu +%zu,%zu @@\n", oldfrom + 1, newfrom + 1,
420+		        newto - newfrom);
421+	else if (newto - newfrom <= 1)
422+		fprintf(out, "@@ -%zu,%zu +%zu @@\n", oldfrom + 1, oldto - oldfrom,
423+		        newfrom + 1);
424+	else
425+		fprintf(out, "@@ -%zu,%zu +%zu,%zu @@\n", oldfrom + 1,
426+		        oldto - oldfrom, newfrom + 1, newto - newfrom);
427+
428+	for (i = oldfrom; i < h->old.from; i++) {
429+		fputc(' ', out);
430+		fwrite(old->lines[i].data, 1, old->lines[i].len, out);
431+		fputc('\n', out);
432+	}
433+	print_lines(out, old->lines, h->old.from, h->old.to, '-');
434+	print_lines(out, new->lines, h->new.from, h->new.to, '+');
435+	for (i = h->old.to; i < oldto; i++) {
436+		fputc(' ', out);
437+		fwrite(old->lines[i].data, 1, old->lines[i].len, out);
438+		fputc('\n', out);
439+	}
440+}
441+
442+static int
443+format_unified(FILE *out, const struct diffhunks *hunks,
444+               const struct difffile *old, const struct difffile *new,
445+               const char *oldlabel, const char *newlabel, size_t ctx)
446+{
447+	size_t i;
448+	if (oldlabel)
449+		fprintf(out, "--- %s\n", oldlabel);
450+	if (newlabel)
451+		fprintf(out, "+++ %s\n", newlabel);
452+	for (i = 0; i < hunks->n; i++)
453+		emit_unified_hunk(out, &hunks->v[i], old, new, ctx);
454+	return 0;
455+}
456+
457+static void
458+emit_context_hunk(FILE *out, const struct diffhunk *h,
459+                  const struct difffile *old, const struct difffile *new,
460+                  size_t ctx)
461+{
462+	size_t oldfrom, oldto, newfrom, newto;
463+	size_t i;
464+
465+	oldfrom = h->old.from < ctx ? 0 : h->old.from - ctx;
466+	oldto = h->old.to + ctx;
467+	if (oldto > old->nlines)
468+		oldto = old->nlines;
469+	newfrom = h->new.from < ctx ? 0 : h->new.from - ctx;
470+	newto = h->new.to + ctx;
471+	if (newto > new->nlines)
472+		newto = new->nlines;
473+
474+	fprintf(out, "***************\n");
475+	if (oldto - oldfrom <= 1)
476+		fprintf(out, "*** %zu ****\n", oldfrom + 1);
477+	else
478+		fprintf(out, "*** %zu,%zu ****\n", oldfrom + 1, oldto - oldfrom);
479+	for (i = oldfrom; i < h->old.from; i++) {
480+		fputc(' ', out);
481+		fwrite(old->lines[i].data, 1, old->lines[i].len, out);
482+		fputc('\n', out);
483+	}
484+	print_lines(out, old->lines, h->old.from, h->old.to, '-');
485+	for (i = h->old.to; i < oldto; i++) {
486+		fputc(' ', out);
487+		fwrite(old->lines[i].data, 1, old->lines[i].len, out);
488+		fputc('\n', out);
489+	}
490+	if (newto - newfrom <= 1)
491+		fprintf(out, "--- %zu ----\n", newfrom + 1);
492+	else
493+		fprintf(out, "--- %zu,%zu ----\n", newfrom + 1, newto - newfrom);
494+	for (i = newfrom; i < h->new.from; i++) {
495+		fputc(' ', out);
496+		fwrite(new->lines[i].data, 1, new->lines[i].len, out);
497+		fputc('\n', out);
498+	}
499+	print_lines(out, new->lines, h->new.from, h->new.to, '+');
500+	for (i = h->new.to; i < newto; i++) {
501+		fputc(' ', out);
502+		fwrite(new->lines[i].data, 1, new->lines[i].len, out);
503+		fputc('\n', out);
504+	}
505+}
506+
507+static int
508+format_context(FILE *out, const struct diffhunks *hunks,
509+               const struct difffile *old, const struct difffile *new,
510+               const char *oldlabel, const char *newlabel, size_t ctx)
511+{
512+	size_t i;
513+	if (oldlabel)
514+		fprintf(out, "*** %s\n", oldlabel);
515+	if (newlabel)
516+		fprintf(out, "--- %s\n", newlabel);
517+	for (i = 0; i < hunks->n; i++)
518+		emit_context_hunk(out, &hunks->v[i], old, new, ctx);
519+	return 0;
520+}
521+
522+static int
523+format_ed(FILE *out, const struct diffhunks *hunks,
524+          const struct difffile *old, const struct difffile *new)
525+{
526+	size_t i;
527+	(void)old;
528+	for (i = 0; i < hunks->n; i++) {
529+		struct diffhunk *h = &hunks->v[i];
530+		size_t oldn = h->old.to - h->old.from;
531+		size_t newn = h->new.to - h->new.from;
532+		char op;
533+
534+		op = oldn == 0 ? 'a' : (newn == 0 ? 'd' : 'c');
535+		print_range(out, h->old.from, h->old.to);
536+		fputc(op, out);
537+		fputc('\n', out);
538+		if (op == 'a' || op == 'c') {
539+			size_t j;
540+			for (j = h->new.from; j < h->new.to; j++) {
541+				if (new->lines[j].len == 1 && new->lines[j].data[0] == '.')
542+					fprintf(out, "..\n");
543+				else if (new->lines[j].len == 0)
544+					fprintf(out, ".\n");
545+				else {
546+					fwrite(new->lines[j].data, 1, new->lines[j].len, out);
547+					fputc('\n', out);
548+				}
549+			}
550+			fprintf(out, ".\n");
551+		}
552+	}
553+	return 0;
554+}
555+
556+int
557+diff_format(FILE *out, const struct diffhunks *hunks,
558+            const struct difffile *old, const struct difffile *new,
559+            const char *oldlabel, const char *newlabel,
560+            const struct diffopts *opts)
561+{
562+	struct diffopts default_opts;
563+	size_t ctx;
564+
565+	if (!opts) {
566+		memset(&default_opts, 0, sizeof(default_opts));
567+		default_opts.context = 3;
568+		opts = &default_opts;
569+	}
570+	ctx = opts->context ? opts->context : 3;
571+	switch (opts->format) {
572+	case DIFF_NORMAL:
573+		return format_normal(out, hunks, old, new);
574+	case DIFF_UNIFIED:
575+		return format_unified(out, hunks, old, new, oldlabel, newlabel, ctx);
576+	case DIFF_CONTEXT:
577+		return format_context(out, hunks, old, new, oldlabel, newlabel, ctx);
578+	case DIFF_ED:
579+	case DIFF_RCSED:
580+		return format_ed(out, hunks, old, new);
581+	case DIFF_BRIEF:
582+		if (hunks->n > 0)
583+			return 1;
584+		return 0;
585+	}
586+	return 0;
587+}
+619, -616
   1@@ -31,711 +31,714 @@
   2 int
   3 blockdev_open(struct BlockDev *dev, const char *path, int writable)
   4 {
   5-	struct stat st;
   6-	int fd, flags;
   7+        struct stat st;
   8+        int fd, flags;
   9 
  10-	flags = writable ? O_RDWR : O_RDONLY;
  11-	fd = open(path, flags);
  12-	if (fd < 0)
  13-		return -1;
  14+        flags = writable ? O_RDWR : O_RDONLY;
  15+        fd = open(path, flags);
  16+        if (fd < 0)
  17+                return -1;
  18 
  19-	if (fstat(fd, &st) < 0) {
  20-		close(fd);
  21-		return -1;
  22-	}
  23+        if (fstat(fd, &st) < 0) {
  24+                close(fd);
  25+                return -1;
  26+        }
  27 
  28-	dev->fd = fd;
  29-	dev->size = st.st_size;
  30-	dev->sec_size = 512;
  31+        dev->fd = fd;
  32+        dev->size = st.st_size;
  33+        dev->sec_size = 512;
  34 
  35-	if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) {
  36+        if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) {
  37 #if defined(__linux__)
  38-		uint64_t size_bytes = 0;
  39-		int sec_size = 0;
  40-		if (ioctl(fd, BLKGETSIZE64, &size_bytes) >= 0)
  41-			dev->size = size_bytes;
  42-		if (ioctl(fd, BLKSSZGET, &sec_size) >= 0)
  43-			dev->sec_size = sec_size;
  44+                uint64_t size_bytes = 0;
  45+                int sec_size = 0;
  46+#pragma GCC diagnostic push
  47+#pragma GCC diagnostic ignored "-Woverflow"
  48+                if (ioctl(fd, BLKGETSIZE64, &size_bytes) >= 0)
  49+                        dev->size = size_bytes;
  50+                if (ioctl(fd, BLKSSZGET, &sec_size) >= 0)
  51+                        dev->sec_size = sec_size;
  52+#pragma GCC diagnostic pop
  53 #elif defined(__FreeBSD__)
  54-		off_t size_bytes = 0;
  55-		unsigned int sec_size = 0;
  56-		if (ioctl(fd, DIOCGMEDIASIZE, &size_bytes) >= 0)
  57-			dev->size = size_bytes;
  58-		if (ioctl(fd, DIOCGSECTORSIZE, &sec_size) >= 0)
  59-			dev->sec_size = sec_size;
  60+                off_t size_bytes = 0;
  61+                unsigned int sec_size = 0;
  62+                if (ioctl(fd, DIOCGMEDIASIZE, &size_bytes) >= 0)
  63+                        dev->size = size_bytes;
  64+                if (ioctl(fd, DIOCGSECTORSIZE, &sec_size) >= 0)
  65+                        dev->sec_size = sec_size;
  66 #elif defined(__OpenBSD__) || defined(__NetBSD__)
  67-		struct disklabel dl;
  68-		if (ioctl(fd, DIOCGDINFO, &dl) >= 0) {
  69-			dev->size = (uint64_t)dl.d_secsize * DL_GETDSIZE(&dl);
  70-			dev->sec_size = dl.d_secsize;
  71-		}
  72+                struct disklabel dl;
  73+                if (ioctl(fd, DIOCGDINFO, &dl) >= 0) {
  74+                        dev->size = (uint64_t)dl.d_secsize * DL_GETDSIZE(&dl);
  75+                        dev->sec_size = dl.d_secsize;
  76+                }
  77 #endif
  78-	}
  79+        }
  80 
  81-	return 0;
  82+        return 0;
  83 }
  84 
  85 int
  86 blockdev_read(struct BlockDev *dev, uint64_t sector, void *buf, size_t sector_count)
  87 {
  88-	off_t offset = (off_t)sector * dev->sec_size;
  89-	size_t size = sector_count * dev->sec_size;
  90-	ssize_t n;
  91+        off_t offset = (off_t)sector * dev->sec_size;
  92+        size_t size = sector_count * dev->sec_size;
  93+        ssize_t n;
  94 
  95-	if (lseek(dev->fd, offset, SEEK_SET) == (off_t)-1)
  96-		return -1;
  97+        if (lseek(dev->fd, offset, SEEK_SET) == (off_t)-1)
  98+                return -1;
  99 
 100-	n = read(dev->fd, buf, size);
 101-	if (n < 0 || (size_t)n != size)
 102-		return -1;
 103+        n = read(dev->fd, buf, size);
 104+        if (n < 0 || (size_t)n != size)
 105+                return -1;
 106 
 107-	return 0;
 108+        return 0;
 109 }
 110 
 111 int
 112 blockdev_write(struct BlockDev *dev, uint64_t sector, const void *buf, size_t sector_count)
 113 {
 114-	off_t offset = (off_t)sector * dev->sec_size;
 115-	size_t size = sector_count * dev->sec_size;
 116-	ssize_t n;
 117+        off_t offset = (off_t)sector * dev->sec_size;
 118+        size_t size = sector_count * dev->sec_size;
 119+        ssize_t n;
 120 
 121-	if (lseek(dev->fd, offset, SEEK_SET) == (off_t)-1)
 122-		return -1;
 123+        if (lseek(dev->fd, offset, SEEK_SET) == (off_t)-1)
 124+                return -1;
 125 
 126-	n = write(dev->fd, buf, size);
 127-	if (n < 0 || (size_t)n != size)
 128-		return -1;
 129+        n = write(dev->fd, buf, size);
 130+        if (n < 0 || (size_t)n != size)
 131+                return -1;
 132 
 133-	return 0;
 134+        return 0;
 135 }
 136 
 137 void
 138 blockdev_close(struct BlockDev *dev)
 139 {
 140-	if (dev->fd >= 0) {
 141-		close(dev->fd);
 142-		dev->fd = -1;
 143-	}
 144+        if (dev->fd >= 0) {
 145+                close(dev->fd);
 146+                dev->fd = -1;
 147+        }
 148 }
 149 
 150 struct BlockDevInfo *
 151 blockdev_get_list(void)
 152 {
 153 #if defined(__linux__)
 154-	FILE *fp;
 155-	FILE *mfile;
 156-	char line[256];
 157-	char mline[512];
 158-	char devpath[128];
 159-	char mnt[256];
 160-	char fs[64];
 161-	struct BlockDevInfo *head = NULL;
 162-	struct BlockDevInfo *tail = NULL;
 163-	struct BlockDevInfo *info;
 164-	struct BlockDevInfo *curr;
 165-	unsigned int major, minor;
 166-	unsigned long long blocks;
 167-	char name[64];
 168-	int is_part;
 169-
 170-	fp = fopen(PATH_PARTITIONS, "r");
 171-	if (!fp)
 172-		return NULL;
 173-
 174-	while (fgets(line, sizeof(line), fp)) {
 175-		if (sscanf(line, " %u %u %llu %63s", &major, &minor, &blocks, name) != 4)
 176-			continue;
 177-
 178-		info = ecalloc(1, sizeof(*info));
 179-
 180-		strlcpy(info->name, name, sizeof(info->name));
 181-		snprintf(info->path, sizeof(info->path), "%s/%s", PATH_DEV, name);
 182-		info->size = blocks * 1024;
 183-		info->major = major;
 184-		info->minor = minor;
 185-
 186-		/* search tree topology to link partition node under proper target parent disk */
 187-		is_part = 0;
 188-		for (curr = head; curr; curr = curr->next) {
 189-			size_t len = strlen(curr->name);
 190-			if (strncmp(name, curr->name, len) == 0) {
 191-				char c = name[len];
 192-				if (curr->name[len - 1] >= '0' && curr->name[len - 1] <= '9') {
 193-					if (c == 'p' && name[len + 1] >= '0' && name[len + 1] <= '9')
 194-						is_part = 1;
 195-				} else {
 196-					if (c >= '0' && c <= '9')
 197-						is_part = 1;
 198-				}
 199-				if (is_part) {
 200-					strlcpy(info->type, "part", sizeof(info->type));
 201-					struct BlockDevInfo *p = curr->parts;
 202-					if (!p) {
 203-						curr->parts = info;
 204-					} else {
 205-						while (p->next)
 206-							p = p->next;
 207-						p->next = info;
 208-					}
 209-					break;
 210-				}
 211-			}
 212-		}
 213-
 214-		if (!is_part) {
 215-			strlcpy(info->type, "disk", sizeof(info->type));
 216-			if (!head) {
 217-				head = info;
 218-			} else {
 219-				tail->next = info;
 220-			}
 221-			tail = info;
 222-		}
 223-	}
 224-	fclose(fp);
 225-
 226-	mfile = fopen(PATH_MOUNTS, "r");
 227-	if (mfile) {
 228-		while (fgets(mline, sizeof(mline), mfile)) {
 229-			if (sscanf(mline, "%127s %255s %63s", devpath, mnt, fs) == 3) {
 230-				char *devname = devpath;
 231-				size_t dev_len = strlen(PATH_DEV);
 232-				if (strncmp(devpath, PATH_DEV, dev_len) == 0 && devpath[dev_len] == '/')
 233-					devname = devpath + dev_len + 1;
 234-				struct BlockDevInfo *curr;
 235-				for (curr = head; curr; curr = curr->next) {
 236-					if (strcmp(curr->name, devname) == 0) {
 237-						strlcpy(curr->mountpoint, mnt, sizeof(curr->mountpoint));
 238-						strlcpy(curr->fstype, fs, sizeof(curr->fstype));
 239-					}
 240-					struct BlockDevInfo *part;
 241-					for (part = curr->parts; part; part = part->next) {
 242-						if (strcmp(part->name, devname) == 0) {
 243-							strlcpy(part->mountpoint, mnt, sizeof(part->mountpoint));
 244-							strlcpy(part->fstype, fs, sizeof(part->fstype));
 245-						}
 246-					}
 247-				}
 248-			}
 249-		}
 250-		fclose(mfile);
 251-	}
 252-
 253-	return head;
 254+        FILE *fp;
 255+        FILE *mfile;
 256+        char line[256];
 257+        char mline[512];
 258+        char devpath[128];
 259+        char mnt[256];
 260+        char fs[64];
 261+        struct BlockDevInfo *head = NULL;
 262+        struct BlockDevInfo *tail = NULL;
 263+        struct BlockDevInfo *info;
 264+        struct BlockDevInfo *curr;
 265+        unsigned int major, minor;
 266+        unsigned long long blocks;
 267+        char name[64];
 268+        int is_part;
 269+
 270+        fp = fopen(ARUU_LINUX_PATH_PROC_PARTITIONS, "r");
 271+        if (!fp)
 272+                return NULL;
 273+
 274+        while (fgets(line, sizeof(line), fp)) {
 275+                if (sscanf(line, " %u %u %llu %63s", &major, &minor, &blocks, name) != 4)
 276+                        continue;
 277+
 278+                info = ecalloc(1, sizeof(*info));
 279+
 280+                strlcpy(info->name, name, sizeof(info->name));
 281+                snprintf(info->path, sizeof(info->path), "%s/%s", ARUU_PATH_DEV, name);
 282+                info->size = blocks * 1024;
 283+                info->major = major;
 284+                info->minor = minor;
 285+
 286+                /* search tree topology to link partition node under proper target parent disk */
 287+                is_part = 0;
 288+                for (curr = head; curr; curr = curr->next) {
 289+                        size_t len = strlen(curr->name);
 290+                        if (strncmp(name, curr->name, len) == 0) {
 291+                                char c = name[len];
 292+                                if (curr->name[len - 1] >= '0' && curr->name[len - 1] <= '9') {
 293+                                        if (c == 'p' && name[len + 1] >= '0' && name[len + 1] <= '9')
 294+                                                is_part = 1;
 295+                                } else {
 296+                                        if (c >= '0' && c <= '9')
 297+                                                is_part = 1;
 298+                                }
 299+                                if (is_part) {
 300+                                        strlcpy(info->type, "part", sizeof(info->type));
 301+                                        struct BlockDevInfo *p = curr->parts;
 302+                                        if (!p) {
 303+                                                curr->parts = info;
 304+                                        } else {
 305+                                                while (p->next)
 306+                                                        p = p->next;
 307+                                                p->next = info;
 308+                                        }
 309+                                        break;
 310+                                }
 311+                        }
 312+                }
 313+
 314+                if (!is_part) {
 315+                        strlcpy(info->type, "disk", sizeof(info->type));
 316+                        if (!head) {
 317+                                head = info;
 318+                        } else {
 319+                                tail->next = info;
 320+                        }
 321+                        tail = info;
 322+                }
 323+        }
 324+        fclose(fp);
 325+
 326+        mfile = fopen(ARUU_LINUX_PATH_PROC_MOUNTS, "r");
 327+        if (mfile) {
 328+                while (fgets(mline, sizeof(mline), mfile)) {
 329+                        if (sscanf(mline, "%127s %255s %63s", devpath, mnt, fs) == 3) {
 330+                                char *devname = devpath;
 331+                                size_t dev_len = strlen(ARUU_PATH_DEV);
 332+                                if (strncmp(devpath, ARUU_PATH_DEV, dev_len) == 0 && devpath[dev_len] == '/')
 333+                                        devname = devpath + dev_len + 1;
 334+                                struct BlockDevInfo *curr;
 335+                                for (curr = head; curr; curr = curr->next) {
 336+                                        if (strcmp(curr->name, devname) == 0) {
 337+                                                strlcpy(curr->mountpoint, mnt, sizeof(curr->mountpoint));
 338+                                                strlcpy(curr->fstype, fs, sizeof(curr->fstype));
 339+                                        }
 340+                                        struct BlockDevInfo *part;
 341+                                        for (part = curr->parts; part; part = part->next) {
 342+                                                if (strcmp(part->name, devname) == 0) {
 343+                                                        strlcpy(part->mountpoint, mnt, sizeof(part->mountpoint));
 344+                                                        strlcpy(part->fstype, fs, sizeof(part->fstype));
 345+                                                }
 346+                                        }
 347+                                }
 348+                        }
 349+                }
 350+                fclose(mfile);
 351+        }
 352+
 353+        return head;
 354 
 355 #elif defined(__FreeBSD__)
 356-	char disks[1024];
 357-	char devpath[128];
 358-	char *tok;
 359-	char *ptr;
 360-	struct BlockDevInfo *head = NULL;
 361-	struct BlockDevInfo *tail = NULL;
 362-	struct BlockDevInfo *info;
 363-	struct BlockDevInfo *part;
 364-	struct BlockDevInfo *p;
 365-	struct BlockDev dev;
 366-	DIR *dir;
 367-	struct dirent *de;
 368-	size_t disk_len;
 369-	size_t len;
 370-	struct statfs *mntbuf;
 371-	int mntsize;
 372-	int i;
 373-
 374-	len = sizeof(disks);
 375-	if (sysctlbyname("kern.disks", disks, &len, NULL, 0) < 0)
 376-		return NULL;
 377-
 378-	ptr = disks;
 379-	while ((tok = strsep(&ptr, " \t")) != NULL) {
 380-		if (!*tok)
 381-			continue;
 382-
 383-		info = ecalloc(1, sizeof(*info));
 384-
 385-		strlcpy(info->name, tok, sizeof(info->name));
 386-		snprintf(info->path, sizeof(info->path), "%s/%s", PATH_DEV, tok);
 387-		strlcpy(info->type, "disk", sizeof(info->type));
 388-
 389-		snprintf(devpath, sizeof(devpath), "%s/%s", PATH_DEV, tok);
 390-		if (blockdev_open(&dev, devpath, 0) == 0) {
 391-			info->size = dev.size;
 392-			blockdev_close(&dev);
 393-		}
 394-
 395-		dir = opendir(PATH_DEV);
 396-		if (dir) {
 397-			disk_len = strlen(tok);
 398-			while ((de = readdir(dir)) != NULL) {
 399-				if (strncmp(de->d_name, tok, disk_len) == 0) {
 400-					char c = de->d_name[disk_len];
 401-					if (c == 's' || c == 'p') {
 402-						part = ecalloc(1, sizeof(*part));
 403-						strlcpy(part->name, de->d_name, sizeof(part->name));
 404-						snprintf(part->path, sizeof(part->path), "%s/%s", PATH_DEV, de->d_name);
 405-						strlcpy(part->type, "part", sizeof(part->type));
 406-						snprintf(devpath, sizeof(devpath), "%s/%s", PATH_DEV, de->d_name);
 407-						if (blockdev_open(&dev, devpath, 0) == 0) {
 408-							part->size = dev.size;
 409-							blockdev_close(&dev);
 410-						}
 411-						p = info->parts;
 412-						if (!p) {
 413-							info->parts = part;
 414-						} else {
 415-							while (p->next)
 416-								p = p->next;
 417-							p->next = part;
 418-						}
 419-					}
 420-				}
 421-			}
 422-			closedir(dir);
 423-		}
 424-
 425-		if (!head) {
 426-			head = info;
 427-		} else {
 428-			tail->next = info;
 429-		}
 430-		tail = info;
 431-	}
 432-
 433-	mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
 434-	for (i = 0; i < mntsize; i++) {
 435-		char *frompath = mntbuf[i].f_mntfromname;
 436-		char *devname = frompath;
 437-		size_t dev_len = strlen(PATH_DEV);
 438-		if (strncmp(frompath, PATH_DEV, dev_len) == 0 && frompath[dev_len] == '/')
 439-			devname = frompath + dev_len + 1;
 440-		struct BlockDevInfo *curr;
 441-		for (curr = head; curr; curr = curr->next) {
 442-			if (strcmp(curr->name, devname) == 0) {
 443-				strlcpy(curr->mountpoint, mntbuf[i].f_mntonname, sizeof(curr->mountpoint));
 444-				strlcpy(curr->fstype, mntbuf[i].f_fstypename, sizeof(curr->fstype));
 445-			}
 446-			struct BlockDevInfo *part;
 447-			for (part = curr->parts; part; part = part->next) {
 448-				if (strcmp(part->name, devname) == 0) {
 449-					strlcpy(part->mountpoint, mntbuf[i].f_mntonname, sizeof(part->mountpoint));
 450-					strlcpy(part->fstype, mntbuf[i].f_fstypename, sizeof(part->fstype));
 451-				}
 452-			}
 453-		}
 454-	}
 455-
 456-	return head;
 457+        char disks[1024];
 458+        char devpath[128];
 459+        char *tok;
 460+        char *ptr;
 461+        struct BlockDevInfo *head = NULL;
 462+        struct BlockDevInfo *tail = NULL;
 463+        struct BlockDevInfo *info;
 464+        struct BlockDevInfo *part;
 465+        struct BlockDevInfo *p;
 466+        struct BlockDev dev;
 467+        DIR *dir;
 468+        struct dirent *de;
 469+        size_t disk_len;
 470+        size_t len;
 471+        struct statfs *mntbuf;
 472+        int mntsize;
 473+        int i;
 474+
 475+        len = sizeof(disks);
 476+        if (sysctlbyname("kern.disks", disks, &len, NULL, 0) < 0)
 477+                return NULL;
 478+
 479+        ptr = disks;
 480+        while ((tok = strsep(&ptr, " \t")) != NULL) {
 481+                if (!*tok)
 482+                        continue;
 483+
 484+                info = ecalloc(1, sizeof(*info));
 485+
 486+                strlcpy(info->name, tok, sizeof(info->name));
 487+                snprintf(info->path, sizeof(info->path), "%s/%s", ARUU_PATH_DEV, tok);
 488+                strlcpy(info->type, "disk", sizeof(info->type));
 489+
 490+                snprintf(devpath, sizeof(devpath), "%s/%s", ARUU_PATH_DEV, tok);
 491+                if (blockdev_open(&dev, devpath, 0) == 0) {
 492+                        info->size = dev.size;
 493+                        blockdev_close(&dev);
 494+                }
 495+
 496+                dir = opendir(ARUU_PATH_DEV);
 497+                if (dir) {
 498+                        disk_len = strlen(tok);
 499+                        while ((de = readdir(dir)) != NULL) {
 500+                                if (strncmp(de->d_name, tok, disk_len) == 0) {
 501+                                        char c = de->d_name[disk_len];
 502+                                        if (c == 's' || c == 'p') {
 503+                                                part = ecalloc(1, sizeof(*part));
 504+                                                strlcpy(part->name, de->d_name, sizeof(part->name));
 505+                                                snprintf(part->path, sizeof(part->path), "%s/%s", ARUU_PATH_DEV, de->d_name);
 506+                                                strlcpy(part->type, "part", sizeof(part->type));
 507+                                                snprintf(devpath, sizeof(devpath), "%s/%s", ARUU_PATH_DEV, de->d_name);
 508+                                                if (blockdev_open(&dev, devpath, 0) == 0) {
 509+                                                        part->size = dev.size;
 510+                                                        blockdev_close(&dev);
 511+                                                }
 512+                                                p = info->parts;
 513+                                                if (!p) {
 514+                                                        info->parts = part;
 515+                                                } else {
 516+                                                        while (p->next)
 517+                                                                p = p->next;
 518+                                                        p->next = part;
 519+                                                }
 520+                                        }
 521+                                }
 522+                        }
 523+                        closedir(dir);
 524+                }
 525+
 526+                if (!head) {
 527+                        head = info;
 528+                } else {
 529+                        tail->next = info;
 530+                }
 531+                tail = info;
 532+        }
 533+
 534+        mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
 535+        for (i = 0; i < mntsize; i++) {
 536+                char *frompath = mntbuf[i].f_mntfromname;
 537+                char *devname = frompath;
 538+                size_t dev_len = strlen(ARUU_PATH_DEV);
 539+                if (strncmp(frompath, ARUU_PATH_DEV, dev_len) == 0 && frompath[dev_len] == '/')
 540+                        devname = frompath + dev_len + 1;
 541+                struct BlockDevInfo *curr;
 542+                for (curr = head; curr; curr = curr->next) {
 543+                        if (strcmp(curr->name, devname) == 0) {
 544+                                strlcpy(curr->mountpoint, mntbuf[i].f_mntonname, sizeof(curr->mountpoint));
 545+                                strlcpy(curr->fstype, mntbuf[i].f_fstypename, sizeof(curr->fstype));
 546+                        }
 547+                        struct BlockDevInfo *part;
 548+                        for (part = curr->parts; part; part = part->next) {
 549+                                if (strcmp(part->name, devname) == 0) {
 550+                                        strlcpy(part->mountpoint, mntbuf[i].f_mntonname, sizeof(part->mountpoint));
 551+                                        strlcpy(part->fstype, mntbuf[i].f_fstypename, sizeof(part->fstype));
 552+                                }
 553+                        }
 554+                }
 555+        }
 556+
 557+        return head;
 558 
 559 #elif defined(__OpenBSD__)
 560-	char disknames[1024];
 561-	char devpath[128];
 562-	char *tok;
 563-	char *ptr;
 564-	char *colon;
 565-	struct BlockDevInfo *head = NULL;
 566-	struct BlockDevInfo *tail = NULL;
 567-	struct BlockDevInfo *info;
 568-	struct BlockDevInfo *part;
 569-	struct BlockDevInfo *p;
 570-	struct BlockDev dev;
 571-	size_t len;
 572-	int mib[2];
 573-	char c;
 574-	struct statfs *mntbuf;
 575-	int mntsize;
 576-	int i;
 577-
 578-	mib[0] = CTL_HW;
 579-	mib[1] = HW_DISKNAMES;
 580-	len = sizeof(disknames);
 581-	if (sysctl(mib, 2, disknames, &len, NULL, 0) < 0)
 582-		return NULL;
 583-
 584-	ptr = disknames;
 585-	while ((tok = strsep(&ptr, ",")) != NULL) {
 586-		colon = strchr(tok, ':');
 587-		if (colon)
 588-			*colon = '\0';
 589-		if (!*tok)
 590-			continue;
 591-
 592-		info = ecalloc(1, sizeof(*info));
 593-
 594-		strlcpy(info->name, tok, sizeof(info->name));
 595-		snprintf(info->path, sizeof(info->path), "%s/r%sc", PATH_DEV, tok);
 596-		strlcpy(info->type, "disk", sizeof(info->type));
 597-
 598-		snprintf(devpath, sizeof(devpath), "%s/r%sc", PATH_DEV, tok);
 599-		if (blockdev_open(&dev, devpath, 0) == 0) {
 600-			info->size = dev.size;
 601-			blockdev_close(&dev);
 602-		}
 603-
 604-		for (c = 'a'; c <= 'p'; c++) {
 605-			if (c == 'c')
 606-				continue;
 607-			snprintf(devpath, sizeof(devpath), "%s/r%s%c", PATH_DEV, tok, c);
 608-			if (blockdev_open(&dev, devpath, 0) == 0) {
 609-				part = ecalloc(1, sizeof(*part));
 610-				snprintf(part->name, sizeof(part->name), "%s%c", tok, c);
 611-				snprintf(part->path, sizeof(part->path), "%s/r%s%c", PATH_DEV, tok, c);
 612-				strlcpy(part->type, "part", sizeof(part->type));
 613-				part->size = dev.size;
 614-				p = info->parts;
 615-				if (!p) {
 616-					info->parts = part;
 617-				} else {
 618-					while (p->next)
 619-						p = p->next;
 620-					p->next = part;
 621-				}
 622-				blockdev_close(&dev);
 623-			}
 624-		}
 625-
 626-		if (!head) {
 627-			head = info;
 628-		} else {
 629-			tail->next = info;
 630-		}
 631-		tail = info;
 632-	}
 633-
 634-	mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
 635-	for (i = 0; i < mntsize; i++) {
 636-		char *frompath = mntbuf[i].f_mntfromname;
 637-		char *devname = frompath;
 638-		size_t dev_len = strlen(PATH_DEV);
 639-		if (strncmp(frompath, PATH_DEV, dev_len) == 0 && frompath[dev_len] == '/')
 640-			devname = frompath + dev_len + 1;
 641-		struct BlockDevInfo *curr;
 642-		for (curr = head; curr; curr = curr->next) {
 643-			if (strcmp(curr->name, devname) == 0) {
 644-				strlcpy(curr->mountpoint, mntbuf[i].f_mntonname, sizeof(curr->mountpoint));
 645-				strlcpy(curr->fstype, mntbuf[i].f_fstypename, sizeof(curr->fstype));
 646-			}
 647-			struct BlockDevInfo *part;
 648-			for (part = curr->parts; part; part = part->next) {
 649-				if (strcmp(part->name, devname) == 0) {
 650-					strlcpy(part->mountpoint, mntbuf[i].f_mntonname, sizeof(part->mountpoint));
 651-					strlcpy(part->fstype, mntbuf[i].f_fstypename, sizeof(part->fstype));
 652-				}
 653-			}
 654-		}
 655-	}
 656-
 657-	return head;
 658+        char disknames[1024];
 659+        char devpath[128];
 660+        char *tok;
 661+        char *ptr;
 662+        char *colon;
 663+        struct BlockDevInfo *head = NULL;
 664+        struct BlockDevInfo *tail = NULL;
 665+        struct BlockDevInfo *info;
 666+        struct BlockDevInfo *part;
 667+        struct BlockDevInfo *p;
 668+        struct BlockDev dev;
 669+        size_t len;
 670+        int mib[2];
 671+        char c;
 672+        struct statfs *mntbuf;
 673+        int mntsize;
 674+        int i;
 675+
 676+        mib[0] = CTL_HW;
 677+        mib[1] = HW_DISKNAMES;
 678+        len = sizeof(disknames);
 679+        if (sysctl(mib, 2, disknames, &len, NULL, 0) < 0)
 680+                return NULL;
 681+
 682+        ptr = disknames;
 683+        while ((tok = strsep(&ptr, ",")) != NULL) {
 684+                colon = strchr(tok, ':');
 685+                if (colon)
 686+                        *colon = '\0';
 687+                if (!*tok)
 688+                        continue;
 689+
 690+                info = ecalloc(1, sizeof(*info));
 691+
 692+                strlcpy(info->name, tok, sizeof(info->name));
 693+                snprintf(info->path, sizeof(info->path), "%s/r%sc", ARUU_PATH_DEV, tok);
 694+                strlcpy(info->type, "disk", sizeof(info->type));
 695+
 696+                snprintf(devpath, sizeof(devpath), "%s/r%sc", ARUU_PATH_DEV, tok);
 697+                if (blockdev_open(&dev, devpath, 0) == 0) {
 698+                        info->size = dev.size;
 699+                        blockdev_close(&dev);
 700+                }
 701+
 702+                for (c = 'a'; c <= 'p'; c++) {
 703+                        if (c == 'c')
 704+                                continue;
 705+                        snprintf(devpath, sizeof(devpath), "%s/r%s%c", ARUU_PATH_DEV, tok, c);
 706+                        if (blockdev_open(&dev, devpath, 0) == 0) {
 707+                                part = ecalloc(1, sizeof(*part));
 708+                                snprintf(part->name, sizeof(part->name), "%s%c", tok, c);
 709+                                snprintf(part->path, sizeof(part->path), "%s/r%s%c", ARUU_PATH_DEV, tok, c);
 710+                                strlcpy(part->type, "part", sizeof(part->type));
 711+                                part->size = dev.size;
 712+                                p = info->parts;
 713+                                if (!p) {
 714+                                        info->parts = part;
 715+                                } else {
 716+                                        while (p->next)
 717+                                                p = p->next;
 718+                                        p->next = part;
 719+                                }
 720+                                blockdev_close(&dev);
 721+                        }
 722+                }
 723+
 724+                if (!head) {
 725+                        head = info;
 726+                } else {
 727+                        tail->next = info;
 728+                }
 729+                tail = info;
 730+        }
 731+
 732+        mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
 733+        for (i = 0; i < mntsize; i++) {
 734+                char *frompath = mntbuf[i].f_mntfromname;
 735+                char *devname = frompath;
 736+                size_t dev_len = strlen(ARUU_PATH_DEV);
 737+                if (strncmp(frompath, ARUU_PATH_DEV, dev_len) == 0 && frompath[dev_len] == '/')
 738+                        devname = frompath + dev_len + 1;
 739+                struct BlockDevInfo *curr;
 740+                for (curr = head; curr; curr = curr->next) {
 741+                        if (strcmp(curr->name, devname) == 0) {
 742+                                strlcpy(curr->mountpoint, mntbuf[i].f_mntonname, sizeof(curr->mountpoint));
 743+                                strlcpy(curr->fstype, mntbuf[i].f_fstypename, sizeof(curr->fstype));
 744+                        }
 745+                        struct BlockDevInfo *part;
 746+                        for (part = curr->parts; part; part = part->next) {
 747+                                if (strcmp(part->name, devname) == 0) {
 748+                                        strlcpy(part->mountpoint, mntbuf[i].f_mntonname, sizeof(part->mountpoint));
 749+                                        strlcpy(part->fstype, mntbuf[i].f_fstypename, sizeof(part->fstype));
 750+                                }
 751+                        }
 752+                }
 753+        }
 754+
 755+        return head;
 756 
 757 #else
 758-	struct BlockDevInfo *head = NULL;
 759-	struct BlockDevInfo *tail = NULL;
 760-	struct BlockDevInfo *info;
 761-	struct BlockDev dev;
 762-	char devname[16];
 763-	char devpath[128];
 764-	char c;
 765-
 766-	for (c = 'a'; c <= 'z'; c++) {
 767-		snprintf(devname, sizeof(devname), "sd%c", c);
 768-		snprintf(devpath, sizeof(devpath), "%s/%s", PATH_DEV, devname);
 769-		if (blockdev_open(&dev, devpath, 0) == 0) {
 770-			info = ecalloc(1, sizeof(*info));
 771-			strlcpy(info->name, devname, sizeof(info->name));
 772-			snprintf(info->path, sizeof(info->path), "%s/%s", PATH_DEV, devname);
 773-			strlcpy(info->type, "disk", sizeof(info->type));
 774-			info->size = dev.size;
 775-			if (!head) {
 776-				head = info;
 777-			} else {
 778-				tail->next = info;
 779-			}
 780-			tail = info;
 781-			blockdev_close(&dev);
 782-		}
 783-	}
 784-	return head;
 785+        struct BlockDevInfo *head = NULL;
 786+        struct BlockDevInfo *tail = NULL;
 787+        struct BlockDevInfo *info;
 788+        struct BlockDev dev;
 789+        char devname[16];
 790+        char devpath[128];
 791+        char c;
 792+
 793+        for (c = 'a'; c <= 'z'; c++) {
 794+                snprintf(devname, sizeof(devname), "sd%c", c);
 795+                snprintf(devpath, sizeof(devpath), "%s/%s", ARUU_PATH_DEV, devname);
 796+                if (blockdev_open(&dev, devpath, 0) == 0) {
 797+                        info = ecalloc(1, sizeof(*info));
 798+                        strlcpy(info->name, devname, sizeof(info->name));
 799+                        snprintf(info->path, sizeof(info->path), "%s/%s", ARUU_PATH_DEV, devname);
 800+                        strlcpy(info->type, "disk", sizeof(info->type));
 801+                        info->size = dev.size;
 802+                        if (!head) {
 803+                                head = info;
 804+                        } else {
 805+                                tail->next = info;
 806+                        }
 807+                        tail = info;
 808+                        blockdev_close(&dev);
 809+                }
 810+        }
 811+        return head;
 812 #endif
 813 }
 814 
 815 void
 816 blockdev_free_list(struct BlockDevInfo *list)
 817 {
 818-	struct BlockDevInfo *curr = list;
 819-	while (curr) {
 820-		struct BlockDevInfo *next = curr->next;
 821-		struct BlockDevInfo *part = curr->parts;
 822-		while (part) {
 823-			struct BlockDevInfo *next_part = part->next;
 824-			free(part);
 825-			part = next_part;
 826-		}
 827-		free(curr);
 828-		curr = next;
 829-	}
 830+        struct BlockDevInfo *curr = list;
 831+        while (curr) {
 832+                struct BlockDevInfo *next = curr->next;
 833+                struct BlockDevInfo *part = curr->parts;
 834+                while (part) {
 835+                        struct BlockDevInfo *next_part = part->next;
 836+                        free(part);
 837+                        part = next_part;
 838+                }
 839+                free(curr);
 840+                curr = next;
 841+        }
 842 }
 843 
 844 struct FsType {
 845-	const char *name;
 846-	size_t magic_offset;
 847-	size_t magic_len;
 848-	uint64_t magic1;
 849-	uint64_t magic2;
 850-	size_t uuid_offset;
 851-	size_t uuid_len;
 852-	size_t label_offset;
 853-	size_t label_len;
 854+        const char *name;
 855+        size_t magic_offset;
 856+        size_t magic_len;
 857+        uint64_t magic1;
 858+        uint64_t magic2;
 859+        size_t uuid_offset;
 860+        size_t uuid_len;
 861+        size_t label_offset;
 862+        size_t label_len;
 863 };
 864 
 865 static const struct FsType fstypes[] = {
 866-	/* ext2/3/4 */
 867-	{ "ext", 1080, 2, 0xEF53, 0x53EF, 1128, 16, 1144, 16 },
 868-	/* vfat / fat32 */
 869-	{ "vfat", 82, 5, 0x3233544146ULL, 0, 67, 4, 71, 11 },
 870-	/* vfat / fat12/16 */
 871-	{ "vfat", 54, 4, 0x31544146, 0, 39, 4, 43, 11 },
 872-	/* ntfs */
 873-	{ "ntfs", 3, 4, 0x5346544e, 0, 72, 8, 0, 0 },
 874-	/* xfs */
 875-	{ "xfs", 0, 4, 0x42534658, 0x58465342, 32, 16, 108, 12 },
 876-	/* btrfs */
 877-	{ "btrfs", 65600, 8, 0x4D5F53665248425FULL, 0, 65803, 16, 65819, 256 },
 878-	/* f2fs */
 879-	{ "f2fs", 1024, 4, 0xF2F52010, 0x1020F5F2, 1132, 16, 1148, 512 },
 880-	/* ufs1 */
 881-	{ "ufs1", 9564, 4, 0x011954, 0x54190100, 8428, 8, 0, 0 },
 882-	/* ufs2 */
 883-	{ "ufs2", 66908, 4, 0x19540119, 0x19015419, 65772, 8, 66216, 32 },
 884-	/* fossil */
 885-	{ "fossil", 131200, 4, 0x2340A3B1, 0xB1A34023, 0, 0, 131072, 127 },
 886+        /* ext2/3/4 */
 887+        { "ext", 1080, 2, 0xEF53, 0x53EF, 1128, 16, 1144, 16 },
 888+        /* vfat / fat32 */
 889+        { "vfat", 82, 5, 0x3233544146ULL, 0, 67, 4, 71, 11 },
 890+        /* vfat / fat12/16 */
 891+        { "vfat", 54, 4, 0x31544146, 0, 39, 4, 43, 11 },
 892+        /* ntfs */
 893+        { "ntfs", 3, 4, 0x5346544e, 0, 72, 8, 0, 0 },
 894+        /* xfs */
 895+        { "xfs", 0, 4, 0x42534658, 0x58465342, 32, 16, 108, 12 },
 896+        /* btrfs */
 897+        { "btrfs", 65600, 8, 0x4D5F53665248425FULL, 0, 65803, 16, 65819, 256 },
 898+        /* f2fs */
 899+        { "f2fs", 1024, 4, 0xF2F52010, 0x1020F5F2, 1132, 16, 1148, 512 },
 900+        /* ufs1 */
 901+        { "ufs1", 9564, 4, 0x011954, 0x54190100, 8428, 8, 0, 0 },
 902+        /* ufs2 */
 903+        { "ufs2", 66908, 4, 0x19540119, 0x19015419, 65772, 8, 66216, 32 },
 904+        /* fossil */
 905+        { "fossil", 131200, 4, 0x2340A3B1, 0xB1A34023, 0, 0, 131072, 127 },
 906 };
 907 
 908 static void
 909 format_uuid(const unsigned char *buf, size_t len, const char *type, char *out, size_t out_len)
 910 {
 911-	size_t i;
 912-	char *p;
 913-
 914-	p = out;
 915-	if (strcmp(type, "vfat") == 0) {
 916-		snprintf(out, out_len, "%02X%02X-%02X%02X", buf[3], buf[2], buf[1], buf[0]);
 917-		return;
 918-	}
 919-
 920-	if (strcmp(type, "ntfs") == 0) {
 921-		for (i = 8; i > 0; i--) {
 922-			snprintf(p, out_len - (p - out), "%02X", buf[i - 1]);
 923-			p += 2;
 924-		}
 925-		return;
 926-	}
 927-
 928-	for (i = 0; i < len; i++) {
 929-		if (i == 4 || i == 6 || i == 8 || i == 10) {
 930-			*p++ = '-';
 931-		}
 932-		snprintf(p, out_len - (p - out), "%02x", buf[i]);
 933-		p += 2;
 934-	}
 935-	*p = '\0';
 936+        size_t i;
 937+        char *p;
 938+
 939+        p = out;
 940+        if (strcmp(type, "vfat") == 0) {
 941+                snprintf(out, out_len, "%02X%02X-%02X%02X", buf[3], buf[2], buf[1], buf[0]);
 942+                return;
 943+        }
 944+
 945+        if (strcmp(type, "ntfs") == 0) {
 946+                for (i = 8; i > 0; i--) {
 947+                        snprintf(p, out_len - (p - out), "%02X", buf[i - 1]);
 948+                        p += 2;
 949+                }
 950+                return;
 951+        }
 952+
 953+        for (i = 0; i < len; i++) {
 954+                if (i == 4 || i == 6 || i == 8 || i == 10) {
 955+                        *p++ = '-';
 956+                }
 957+                snprintf(p, out_len - (p - out), "%02x", buf[i]);
 958+                p += 2;
 959+        }
 960+        *p = '\0';
 961 }
 962 
 963 static int
 964 zfs_detect(const unsigned char *buf, size_t len)
 965 {
 966-	size_t offset;
 967-	uint64_t magic;
 968-
 969-	for (offset = 131072; offset + 8 <= len; offset += 1024) {
 970-		magic = ((uint64_t)buf[offset + 7] << 56) |
 971-		        ((uint64_t)buf[offset + 6] << 48) |
 972-		        ((uint64_t)buf[offset + 5] << 40) |
 973-		        ((uint64_t)buf[offset + 4] << 32) |
 974-		        ((uint64_t)buf[offset + 3] << 24) |
 975-		        ((uint64_t)buf[offset + 2] << 16) |
 976-		        ((uint64_t)buf[offset + 1] << 8)  |
 977-		        (uint64_t)buf[offset];
 978-
 979-		if (magic == 0x00bab10c00000000ULL || magic == 0x0cb1ba0000000000ULL ||
 980-		    magic == 0x00bab10cULL || magic == 0x0cb1ba00ULL)
 981-			return 1;
 982-	}
 983-	return 0;
 984+        size_t offset;
 985+        uint64_t magic;
 986+
 987+        for (offset = 131072; offset + 8 <= len; offset += 1024) {
 988+                magic = ((uint64_t)buf[offset + 7] << 56) |
 989+                        ((uint64_t)buf[offset + 6] << 48) |
 990+                        ((uint64_t)buf[offset + 5] << 40) |
 991+                        ((uint64_t)buf[offset + 4] << 32) |
 992+                        ((uint64_t)buf[offset + 3] << 24) |
 993+                        ((uint64_t)buf[offset + 2] << 16) |
 994+                        ((uint64_t)buf[offset + 1] << 8)  |
 995+                        (uint64_t)buf[offset];
 996+
 997+                if (magic == 0x00bab10c00000000ULL || magic == 0x0cb1ba0000000000ULL ||
 998+                    magic == 0x00bab10cULL || magic == 0x0cb1ba00ULL)
 999+                        return 1;
1000+        }
1001+        return 0;
1002 }
1003 
1004 struct Plan9FsDef {
1005-	const char *name;
1006-	int blocksize;
1007-	int namelen;
1008-	int dirblks;
1009-	int indirblks;
1010-	int daddrbits;
1011+        const char *name;
1012+        int blocksize;
1013+        int namelen;
1014+        int dirblks;
1015+        int indirblks;
1016+        int daddrbits;
1017 };
1018 
1019 static const struct Plan9FsDef p9_fs_defs[] = {
1020-	{ "cwfs64x", 16384, 144, 6, 4, 64 },
1021-	{ "cwfs64",  16384,  56, 6, 4, 64 },
1022-	{ "cwfs",    16384,  28, 6, 2, 32 },
1023-	{ "fs64",     8192,  56, 6, 4, 64 },
1024-	{ "fs",       4096,  28, 6, 2, 32 },
1025+        { "cwfs64x", 16384, 144, 6, 4, 64 },
1026+        { "cwfs64",  16384,  56, 6, 4, 64 },
1027+        { "cwfs",    16384,  28, 6, 2, 32 },
1028+        { "fs64",     8192,  56, 6, 4, 64 },
1029+        { "fs",       4096,  28, 6, 2, 32 },
1030 };
1031 
1032 static int
1033 plan9_magic_check(const unsigned char *p, const char **name)
1034 {
1035-	if (memcmp(p, "\x01\x1c\xe5\x0d", 4) == 0 || memcmp(p, "\x0d\xe5\x1c\x01", 4) == 0) {
1036-		*name = "hjfs";
1037-		return 1;
1038-	}
1039-	if (memcmp(p, "gefs", 4) == 0 || memcmp(p, "sfeg", 4) == 0) {
1040-		*name = "gefs";
1041-		return 1;
1042-	}
1043-	return 0;
1044+        if (memcmp(p, "\x01\x1c\xe5\x0d", 4) == 0 || memcmp(p, "\x0d\xe5\x1c\x01", 4) == 0) {
1045+                *name = "hjfs";
1046+                return 1;
1047+        }
1048+        if (memcmp(p, "gefs", 4) == 0 || memcmp(p, "sfeg", 4) == 0) {
1049+                *name = "gefs";
1050+                return 1;
1051+        }
1052+        return 0;
1053 }
1054 
1055 static int
1056 plan9_detect_other(const unsigned char *buf, size_t len, const char **name)
1057 {
1058-	if (len >= 4 && plan9_magic_check(buf, name))
1059-		return 1;
1060-	if (len >= 516 && plan9_magic_check(buf + 512, name))
1061-		return 1;
1062-	return 0;
1063+        if (len >= 4 && plan9_magic_check(buf, name))
1064+                return 1;
1065+        if (len >= 516 && plan9_magic_check(buf + 512, name))
1066+                return 1;
1067+        return 0;
1068 }
1069 
1070 static int
1071 plan9_detect_text(const unsigned char *buf, size_t len, const char **name)
1072 {
1073-	int blocksize = 0, namelen = 0, dirblks = 0, indirblks = 0, daddrbits = 0;
1074-	char line[128];
1075-	char key[64];
1076-	int val;
1077-	size_t i = 0, j;
1078-
1079-	if (len >= 256 + 15) {
1080-		if (memcmp(buf + 256, "kfs wren device", 15) == 0) {
1081-			*name = "kfs";
1082-			return 1;
1083-		}
1084-	}
1085-
1086-	if (len < 512)
1087-		return 0;
1088-	i = 512;
1089-	if (len > 1536)
1090-		len = 1536;
1091-
1092-	while (i < len) {
1093-		size_t k = 0;
1094-		while (i < len && buf[i] != '\n' && k < sizeof(line) - 1) {
1095-			line[k++] = buf[i++];
1096-		}
1097-		if (i < len && buf[i] == '\n')
1098-			i++;
1099-		line[k] = '\0';
1100-
1101-		if (sscanf(line, "%63s %d", key, &val) == 2) {
1102-			if (strcmp(key, "blocksize") == 0) blocksize = val;
1103-			else if (strcmp(key, "namelen") == 0) namelen = val;
1104-			else if (strcmp(key, "dirblks") == 0) dirblks = val;
1105-			else if (strcmp(key, "indirblks") == 0) indirblks = val;
1106-			else if (strcmp(key, "daddrbits") == 0) daddrbits = val;
1107-		}
1108-	}
1109-
1110-	for (j = 0; j < LEN(p9_fs_defs); j++) {
1111-		if (blocksize == p9_fs_defs[j].blocksize &&
1112-		    namelen == p9_fs_defs[j].namelen &&
1113-		    dirblks == p9_fs_defs[j].dirblks &&
1114-		    indirblks == p9_fs_defs[j].indirblks &&
1115-		    daddrbits == p9_fs_defs[j].daddrbits) {
1116-			*name = p9_fs_defs[j].name;
1117-			return 1;
1118-		}
1119-	}
1120-
1121-	return 0;
1122+        int blocksize = 0, namelen = 0, dirblks = 0, indirblks = 0, daddrbits = 0;
1123+        char line[128];
1124+        char key[64];
1125+        int val;
1126+        size_t i = 0, j;
1127+
1128+        if (len >= 256 + 15) {
1129+                if (memcmp(buf + 256, "kfs wren device", 15) == 0) {
1130+                        *name = "kfs";
1131+                        return 1;
1132+                }
1133+        }
1134+
1135+        if (len < 512)
1136+                return 0;
1137+        i = 512;
1138+        if (len > 1536)
1139+                len = 1536;
1140+
1141+        while (i < len) {
1142+                size_t k = 0;
1143+                while (i < len && buf[i] != '\n' && k < sizeof(line) - 1) {
1144+                        line[k++] = buf[i++];
1145+                }
1146+                if (i < len && buf[i] == '\n')
1147+                        i++;
1148+                line[k] = '\0';
1149+
1150+                if (sscanf(line, "%63s %d", key, &val) == 2) {
1151+                        if (strcmp(key, "blocksize") == 0) blocksize = val;
1152+                        else if (strcmp(key, "namelen") == 0) namelen = val;
1153+                        else if (strcmp(key, "dirblks") == 0) dirblks = val;
1154+                        else if (strcmp(key, "indirblks") == 0) indirblks = val;
1155+                        else if (strcmp(key, "daddrbits") == 0) daddrbits = val;
1156+                }
1157+        }
1158+
1159+        for (j = 0; j < LEN(p9_fs_defs); j++) {
1160+                if (blocksize == p9_fs_defs[j].blocksize &&
1161+                    namelen == p9_fs_defs[j].namelen &&
1162+                    dirblks == p9_fs_defs[j].dirblks &&
1163+                    indirblks == p9_fs_defs[j].indirblks &&
1164+                    daddrbits == p9_fs_defs[j].daddrbits) {
1165+                        *name = p9_fs_defs[j].name;
1166+                        return 1;
1167+                }
1168+        }
1169+
1170+        return 0;
1171 }
1172 
1173 int
1174 blockdev_detect_fs(struct BlockDev *dev, char *type, size_t type_sz,
1175                    char *label, size_t label_sz, char *uuid, size_t uuid_sz)
1176 {
1177-	unsigned char *buf;
1178-	size_t read_size = 262144; /* 256kb */
1179-	size_t sectors_to_read;
1180-	size_t i, j;
1181-	int found = 0;
1182-
1183-	if (dev->size < read_size)
1184-		read_size = dev->size;
1185-
1186-	buf = emalloc(read_size);
1187-	sectors_to_read = (read_size + dev->sec_size - 1) / dev->sec_size;
1188-	if (blockdev_read(dev, 0, buf, sectors_to_read) < 0) {
1189-		free(buf);
1190-		return -2;
1191-	}
1192-
1193-	for (i = 0; i < LEN(fstypes); i++) {
1194-		const struct FsType *fs = &fstypes[i];
1195-		if (fs->magic_offset + fs->magic_len > read_size)
1196-			continue;
1197-
1198-		uint64_t val = 0;
1199-		for (j = 0; j < fs->magic_len; j++) {
1200-			val |= ((uint64_t)buf[fs->magic_offset + j]) << (8 * j);
1201-		}
1202-
1203-		if (val == fs->magic1 || (fs->magic2 && val == fs->magic2)) {
1204-			const char *type_name = fs->name;
1205-			if (strcmp(fs->name, "ext") == 0) {
1206-				if (buf[1116] & 4)
1207-					type_name = "ext3";
1208-				else if (buf[1120] & 64)
1209-					type_name = "ext4";
1210-				else
1211-					type_name = "ext2";
1212-			}
1213-
1214-			if (type && type_sz)
1215-				strlcpy(type, type_name, type_sz);
1216-
1217-			if (label && label_sz && fs->label_len && fs->label_offset + fs->label_len <= read_size) {
1218-				snprintf(label, label_sz, "%.*s", (int)fs->label_len, buf + fs->label_offset);
1219-				/* strip trailing spaces */
1220-				char *end = label + strlen(label) - 1;
1221-				while (end >= label && *end == ' ') {
1222-					*end = '\0';
1223-					end--;
1224-				}
1225-			}
1226-
1227-			if (uuid && uuid_sz && fs->uuid_len && fs->uuid_offset + fs->uuid_len <= read_size) {
1228-				format_uuid(buf + fs->uuid_offset, fs->uuid_len, fs->name, uuid, uuid_sz);
1229-			}
1230-
1231-			found = 1;
1232-			break;
1233-		}
1234-	}
1235-
1236-	if (!found && zfs_detect(buf, read_size)) {
1237-		if (type && type_sz)
1238-			strlcpy(type, "zfs_member", type_sz);
1239-		found = 1;
1240-	}
1241-
1242-	if (!found) {
1243-		const char *p9_name = NULL;
1244-		if (plan9_detect_other(buf, read_size, &p9_name) ||
1245-		    plan9_detect_text(buf, read_size, &p9_name)) {
1246-			if (type && type_sz)
1247-				strlcpy(type, p9_name, type_sz);
1248-			found = 1;
1249-		}
1250-	}
1251-
1252-	free(buf);
1253-	return found ? 0 : -1;
1254+        unsigned char *buf;
1255+        size_t read_size = 262144; /* 256kb */
1256+        size_t sectors_to_read;
1257+        size_t i, j;
1258+        int found = 0;
1259+
1260+        if (dev->size < read_size)
1261+                read_size = dev->size;
1262+
1263+        buf = emalloc(read_size);
1264+        sectors_to_read = (read_size + dev->sec_size - 1) / dev->sec_size;
1265+        if (blockdev_read(dev, 0, buf, sectors_to_read) < 0) {
1266+                free(buf);
1267+                return -2;
1268+        }
1269+
1270+        for (i = 0; i < LEN(fstypes); i++) {
1271+                const struct FsType *fs = &fstypes[i];
1272+                if (fs->magic_offset + fs->magic_len > read_size)
1273+                        continue;
1274+
1275+                uint64_t val = 0;
1276+                for (j = 0; j < fs->magic_len; j++) {
1277+                        val |= ((uint64_t)buf[fs->magic_offset + j]) << (8 * j);
1278+                }
1279+
1280+                if (val == fs->magic1 || (fs->magic2 && val == fs->magic2)) {
1281+                        const char *type_name = fs->name;
1282+                        if (strcmp(fs->name, "ext") == 0) {
1283+                                if (buf[1116] & 4)
1284+                                        type_name = "ext3";
1285+                                else if (buf[1120] & 64)
1286+                                        type_name = "ext4";
1287+                                else
1288+                                        type_name = "ext2";
1289+                        }
1290+
1291+                        if (type && type_sz)
1292+                                strlcpy(type, type_name, type_sz);
1293+
1294+                        if (label && label_sz && fs->label_len && fs->label_offset + fs->label_len <= read_size) {
1295+                                snprintf(label, label_sz, "%.*s", (int)fs->label_len, buf + fs->label_offset);
1296+                                /* strip trailing spaces */
1297+                                char *end = label + strlen(label) - 1;
1298+                                while (end >= label && *end == ' ') {
1299+                                        *end = '\0';
1300+                                        end--;
1301+                                }
1302+                        }
1303+
1304+                        if (uuid && uuid_sz && fs->uuid_len && fs->uuid_offset + fs->uuid_len <= read_size) {
1305+                                format_uuid(buf + fs->uuid_offset, fs->uuid_len, fs->name, uuid, uuid_sz);
1306+                        }
1307+
1308+                        found = 1;
1309+                        break;
1310+                }
1311+        }
1312+
1313+        if (!found && zfs_detect(buf, read_size)) {
1314+                if (type && type_sz)
1315+                        strlcpy(type, "zfs_member", type_sz);
1316+                found = 1;
1317+        }
1318+
1319+        if (!found) {
1320+                const char *p9_name = NULL;
1321+                if (plan9_detect_other(buf, read_size, &p9_name) ||
1322+                    plan9_detect_text(buf, read_size, &p9_name)) {
1323+                        if (type && type_sz)
1324+                                strlcpy(type, p9_name, type_sz);
1325+                        found = 1;
1326+                }
1327+        }
1328+
1329+        free(buf);
1330+        return found ? 0 : -1;
1331 }
+454, -453
   1@@ -1,3 +1,4 @@
   2+#include "../paths.h"
   3 #include "../util.h"
   4 
   5 #include <arpa/inet.h>
   6@@ -23,162 +24,162 @@
   7 static void
   8 get_mtu_metric(const char *name, int *mtu, int *metric)
   9 {
  10-	struct ifreq ifr;
  11-	int sock;
  12-
  13-	*mtu = 0;
  14-	*metric = 0;
  15-	sock = socket(AF_INET, SOCK_DGRAM, 0);
  16-	if (sock < 0)
  17-		return;
  18-	memset(&ifr, 0, sizeof(ifr));
  19-	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
  20-	if (ioctl(sock, SIOCGIFMTU, &ifr) >= 0)
  21-		*mtu = ifr.ifr_mtu;
  22-	if (ioctl(sock, SIOCGIFMETRIC, &ifr) >= 0)
  23-		*metric = ifr.ifr_metric;
  24-	close(sock);
  25+        struct ifreq ifr;
  26+        int sock;
  27+
  28+        *mtu = 0;
  29+        *metric = 0;
  30+        sock = socket(AF_INET, SOCK_DGRAM, 0);
  31+        if (sock < 0)
  32+                return;
  33+        memset(&ifr, 0, sizeof(ifr));
  34+        strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
  35+        if (ioctl(sock, SIOCGIFMTU, &ifr) >= 0)
  36+                *mtu = ifr.ifr_mtu;
  37+        if (ioctl(sock, SIOCGIFMETRIC, &ifr) >= 0)
  38+                *metric = ifr.ifr_metric;
  39+        close(sock);
  40 }
  41 
  42 int
  43 net_get_interfaces(struct NetInterface **ifaces, int *count)
  44 {
  45-	struct ifaddrs *ifaddr, *ifa;
  46-	struct NetInterface *list = NULL;
  47-	struct NetInterface *iface;
  48-	int found_count = 0;
  49-	int i;
  50-
  51-	if (getifaddrs(&ifaddr) < 0)
  52-		return -1;
  53-
  54-	for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
  55-		iface = NULL;
  56-		for (i = 0; i < found_count; i++) {
  57-			if (strcmp(list[i].name, ifa->ifa_name) == 0) {
  58-				iface = &list[i];
  59-				break;
  60-			}
  61-		}
  62-		if (!iface) {
  63-			list = reallocarray(list, found_count + 1, sizeof(*list));
  64-			if (!list) {
  65-				freeifaddrs(ifaddr);
  66-				return -1;
  67-			}
  68-			iface = &list[found_count];
  69-			memset(iface, 0, sizeof(*iface));
  70-			strlcpy(iface->name, ifa->ifa_name, sizeof(iface->name));
  71-			iface->flags = ifa->ifa_flags;
  72-			get_mtu_metric(iface->name, &iface->mtu, &iface->metric);
  73-			found_count++;
  74-		}
  75-
  76-		if (!ifa->ifa_addr)
  77-			continue;
  78-
  79-		if (ifa->ifa_addr->sa_family == AF_INET) {
  80-			memcpy(&iface->ipv4_addr, ifa->ifa_addr, sizeof(struct sockaddr_in));
  81-			iface->has_ipv4 = 1;
  82-			if (ifa->ifa_netmask)
  83-				memcpy(&iface->ipv4_mask, ifa->ifa_netmask, sizeof(struct sockaddr_in));
  84-			if (ifa->ifa_dstaddr)
  85-				memcpy(&iface->ipv4_brd, ifa->ifa_dstaddr, sizeof(struct sockaddr_in));
  86-		} else if (ifa->ifa_addr->sa_family == AF_INET6) {
  87-			memcpy(&iface->ipv6_addr, ifa->ifa_addr, sizeof(struct sockaddr_in6));
  88-			iface->has_ipv6 = 1;
  89-			/* scope id could be set here from sin6_scope_id */
  90-		}
  91+        struct ifaddrs *ifaddr, *ifa;
  92+        struct NetInterface *list = NULL;
  93+        struct NetInterface *iface;
  94+        int found_count = 0;
  95+        int i;
  96+
  97+        if (getifaddrs(&ifaddr) < 0)
  98+                return -1;
  99+
 100+        for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
 101+                iface = NULL;
 102+                for (i = 0; i < found_count; i++) {
 103+                        if (strcmp(list[i].name, ifa->ifa_name) == 0) {
 104+                                iface = &list[i];
 105+                                break;
 106+                        }
 107+                }
 108+                if (!iface) {
 109+                        list = reallocarray(list, found_count + 1, sizeof(*list));
 110+                        if (!list) {
 111+                                freeifaddrs(ifaddr);
 112+                                return -1;
 113+                        }
 114+                        iface = &list[found_count];
 115+                        memset(iface, 0, sizeof(*iface));
 116+                        strlcpy(iface->name, ifa->ifa_name, sizeof(iface->name));
 117+                        iface->flags = ifa->ifa_flags;
 118+                        get_mtu_metric(iface->name, &iface->mtu, &iface->metric);
 119+                        found_count++;
 120+                }
 121+
 122+                if (!ifa->ifa_addr)
 123+                        continue;
 124+
 125+                if (ifa->ifa_addr->sa_family == AF_INET) {
 126+                        memcpy(&iface->ipv4_addr, ifa->ifa_addr, sizeof(struct sockaddr_in));
 127+                        iface->has_ipv4 = 1;
 128+                        if (ifa->ifa_netmask)
 129+                                memcpy(&iface->ipv4_mask, ifa->ifa_netmask, sizeof(struct sockaddr_in));
 130+                        if (ifa->ifa_dstaddr)
 131+                                memcpy(&iface->ipv4_brd, ifa->ifa_dstaddr, sizeof(struct sockaddr_in));
 132+                } else if (ifa->ifa_addr->sa_family == AF_INET6) {
 133+                        memcpy(&iface->ipv6_addr, ifa->ifa_addr, sizeof(struct sockaddr_in6));
 134+                        iface->has_ipv6 = 1;
 135+                        /* scope id could be set here from sin6_scope_id */
 136+                }
 137 #ifdef __linux__
 138-		else if (ifa->ifa_addr->sa_family == AF_PACKET) {
 139-			struct sockaddr_ll *sll = (struct sockaddr_ll *)ifa->ifa_addr;
 140-			if (sll->sll_halen == 6) {
 141-				memcpy(iface->mac, sll->sll_addr, 6);
 142-				iface->has_mac = 1;
 143-			}
 144-		}
 145+                else if (ifa->ifa_addr->sa_family == AF_PACKET) {
 146+                        struct sockaddr_ll *sll = (struct sockaddr_ll *)ifa->ifa_addr;
 147+                        if (sll->sll_halen == 6) {
 148+                                memcpy(iface->mac, sll->sll_addr, 6);
 149+                                iface->has_mac = 1;
 150+                        }
 151+                }
 152 #else
 153-		else if (ifa->ifa_addr->sa_family == AF_LINK) {
 154-			struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr;
 155-			if (sdl->sdl_alen == 6) {
 156-				memcpy(iface->mac, LLADDR(sdl), 6);
 157-				iface->has_mac = 1;
 158-			}
 159-		}
 160+                else if (ifa->ifa_addr->sa_family == AF_LINK) {
 161+                        struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr;
 162+                        if (sdl->sdl_alen == 6) {
 163+                                memcpy(iface->mac, LLADDR(sdl), 6);
 164+                                iface->has_mac = 1;
 165+                        }
 166+                }
 167 #endif
 168-	}
 169+        }
 170 
 171-	freeifaddrs(ifaddr);
 172-	*ifaces = list;
 173-	*count = found_count;
 174-	return 0;
 175+        freeifaddrs(ifaddr);
 176+        *ifaces = list;
 177+        *count = found_count;
 178+        return 0;
 179 }
 180 
 181 #ifdef __linux__
 182 int
 183 net_get_stats(const char *ifname, struct NetStats *stats)
 184 {
 185-	FILE *fp;
 186-	char line[256];
 187-	char *p, *name;
 188-	int found = 0;
 189-
 190-	memset(stats, 0, sizeof(*stats));
 191-	fp = fopen("/proc/net/dev", "r");
 192-	if (!fp)
 193-		return -1;
 194-
 195-	while (fgets(line, sizeof(line), fp)) {
 196-		p = strchr(line, ':');
 197-		if (p) {
 198-			*p = '\0';
 199-			name = line;
 200-			while (isspace(*name))
 201-				name++;
 202-			if (strcmp(name, ifname) == 0) {
 203-				if (sscanf(p + 1, "%llu %llu %llu %llu %*u %*u %*u %*u %llu %llu %llu %llu",
 204-				           &stats->rx_bytes, &stats->rx_packets, &stats->rx_errs, &stats->rx_drop,
 205-				           &stats->tx_bytes, &stats->tx_packets, &stats->tx_errs, &stats->tx_drop) == 8) {
 206-					found = 1;
 207-				}
 208-				break;
 209-			}
 210-		}
 211-	}
 212-	fclose(fp);
 213-	return found ? 0 : -1;
 214+        FILE *fp;
 215+        char line[256];
 216+        char *p, *name;
 217+        int found = 0;
 218+
 219+        memset(stats, 0, sizeof(*stats));
 220+        fp = fopen(ARUU_LINUX_PATH_PROC "/net/dev", "r");
 221+        if (!fp)
 222+                return -1;
 223+
 224+        while (fgets(line, sizeof(line), fp)) {
 225+                p = strchr(line, ':');
 226+                if (p) {
 227+                        *p = '\0';
 228+                        name = line;
 229+                        while (isspace(*name))
 230+                                name++;
 231+                        if (strcmp(name, ifname) == 0) {
 232+                                if (sscanf(p + 1, "%llu %llu %llu %llu %*u %*u %*u %*u %llu %llu %llu %llu",
 233+                                           &stats->rx_bytes, &stats->rx_packets, &stats->rx_errs, &stats->rx_drop,
 234+                                           &stats->tx_bytes, &stats->tx_packets, &stats->tx_errs, &stats->tx_drop) == 8) {
 235+                                        found = 1;
 236+                                }
 237+                                break;
 238+                        }
 239+                }
 240+        }
 241+        fclose(fp);
 242+        return found ? 0 : -1;
 243 }
 244 #else
 245 int
 246 net_get_stats(const char *ifname, struct NetStats *stats)
 247 {
 248-	struct ifaddrs *ifaddr, *ifa;
 249-	int found = 0;
 250-
 251-	memset(stats, 0, sizeof(*stats));
 252-	if (getifaddrs(&ifaddr) < 0)
 253-		return -1;
 254-
 255-	for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
 256-		if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_LINK &&
 257-		    strcmp(ifa->ifa_name, ifname) == 0) {
 258-			struct if_data *ifd = (struct if_data *)ifa->ifa_data;
 259-			if (ifd) {
 260-				stats->rx_bytes = ifd->ifi_ibytes;
 261-				stats->rx_packets = ifd->ifi_ipackets;
 262-				stats->rx_errs = ifd->ifi_ierrors;
 263-				stats->rx_drop = ifd->ifi_iqdrops;
 264-				stats->tx_bytes = ifd->ifi_obytes;
 265-				stats->tx_packets = ifd->ifi_opackets;
 266-				stats->tx_errs = ifd->ifi_oerrors;
 267-				stats->tx_drop = 0;
 268-				found = 1;
 269-				break;
 270-			}
 271-		}
 272-	}
 273-	freeifaddrs(ifaddr);
 274-	return found ? 0 : -1;
 275+        struct ifaddrs *ifaddr, *ifa;
 276+        int found = 0;
 277+
 278+        memset(stats, 0, sizeof(*stats));
 279+        if (getifaddrs(&ifaddr) < 0)
 280+                return -1;
 281+
 282+        for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
 283+                if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_LINK &&
 284+                    strcmp(ifa->ifa_name, ifname) == 0) {
 285+                        struct if_data *ifd = (struct if_data *)ifa->ifa_data;
 286+                        if (ifd) {
 287+                                stats->rx_bytes = ifd->ifi_ibytes;
 288+                                stats->rx_packets = ifd->ifi_ipackets;
 289+                                stats->rx_errs = ifd->ifi_ierrors;
 290+                                stats->rx_drop = ifd->ifi_iqdrops;
 291+                                stats->tx_bytes = ifd->ifi_obytes;
 292+                                stats->tx_packets = ifd->ifi_opackets;
 293+                                stats->tx_errs = ifd->ifi_oerrors;
 294+                                stats->tx_drop = 0;
 295+                                found = 1;
 296+                                break;
 297+                        }
 298+                }
 299+        }
 300+        freeifaddrs(ifaddr);
 301+        return found ? 0 : -1;
 302 }
 303 #endif
 304 
 305@@ -186,385 +187,385 @@ net_get_stats(const char *ifname, struct NetStats *stats)
 306 int
 307 net_set_txqueuelen(const char *name, int qlen)
 308 {
 309-	struct ifreq ifr;
 310-	int sock;
 311-
 312-	sock = socket(AF_INET, SOCK_DGRAM, 0);
 313-	if (sock < 0)
 314-		return -1;
 315-	memset(&ifr, 0, sizeof(ifr));
 316-	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 317-	ifr.ifr_qlen = qlen;
 318-	if (ioctl(sock, SIOCSIFTXQLEN, &ifr) < 0) {
 319-		close(sock);
 320-		return -1;
 321-	}
 322-	close(sock);
 323-	return 0;
 324+        struct ifreq ifr;
 325+        int sock;
 326+
 327+        sock = socket(AF_INET, SOCK_DGRAM, 0);
 328+        if (sock < 0)
 329+                return -1;
 330+        memset(&ifr, 0, sizeof(ifr));
 331+        strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 332+        ifr.ifr_qlen = qlen;
 333+        if (ioctl(sock, SIOCSIFTXQLEN, &ifr) < 0) {
 334+                close(sock);
 335+                return -1;
 336+        }
 337+        close(sock);
 338+        return 0;
 339 }
 340 #else
 341 int
 342 net_set_txqueuelen(const char *name, int qlen)
 343 {
 344-	(void)name;
 345-	(void)qlen;
 346-	return -1;
 347+        (void)name;
 348+        (void)qlen;
 349+        return -1;
 350 }
 351 #endif
 352 
 353 int
 354 net_set_flags(const char *name, unsigned int flags, int set)
 355 {
 356-	struct ifreq ifr;
 357-	int sock;
 358-
 359-	sock = socket(AF_INET, SOCK_DGRAM, 0);
 360-	if (sock < 0)
 361-		return -1;
 362-	memset(&ifr, 0, sizeof(ifr));
 363-	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 364-	if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
 365-		close(sock);
 366-		return -1;
 367-	}
 368-	if (set)
 369-		ifr.ifr_flags |= flags;
 370-	else
 371-		ifr.ifr_flags &= ~flags;
 372-	if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
 373-		close(sock);
 374-		return -1;
 375-	}
 376-	close(sock);
 377-	return 0;
 378+        struct ifreq ifr;
 379+        int sock;
 380+
 381+        sock = socket(AF_INET, SOCK_DGRAM, 0);
 382+        if (sock < 0)
 383+                return -1;
 384+        memset(&ifr, 0, sizeof(ifr));
 385+        strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 386+        if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
 387+                close(sock);
 388+                return -1;
 389+        }
 390+        if (set)
 391+                ifr.ifr_flags |= flags;
 392+        else
 393+                ifr.ifr_flags &= ~flags;
 394+        if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
 395+                close(sock);
 396+                return -1;
 397+        }
 398+        close(sock);
 399+        return 0;
 400 }
 401 
 402 int
 403 net_set_mtu(const char *name, int mtu)
 404 {
 405-	struct ifreq ifr;
 406-	int sock;
 407-
 408-	sock = socket(AF_INET, SOCK_DGRAM, 0);
 409-	if (sock < 0)
 410-		return -1;
 411-	memset(&ifr, 0, sizeof(ifr));
 412-	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 413-	ifr.ifr_mtu = mtu;
 414-	if (ioctl(sock, SIOCSIFMTU, &ifr) < 0) {
 415-		close(sock);
 416-		return -1;
 417-	}
 418-	close(sock);
 419-	return 0;
 420+        struct ifreq ifr;
 421+        int sock;
 422+
 423+        sock = socket(AF_INET, SOCK_DGRAM, 0);
 424+        if (sock < 0)
 425+                return -1;
 426+        memset(&ifr, 0, sizeof(ifr));
 427+        strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 428+        ifr.ifr_mtu = mtu;
 429+        if (ioctl(sock, SIOCSIFMTU, &ifr) < 0) {
 430+                close(sock);
 431+                return -1;
 432+        }
 433+        close(sock);
 434+        return 0;
 435 }
 436 
 437 int
 438-net_set_mac(const char *name, const unsigned char mac[6])
 439+net_set_mac(const char *name, const unsigned char *mac)
 440 {
 441 #ifdef __linux__
 442-	struct ifreq ifr;
 443-	int sock;
 444-
 445-	sock = socket(AF_INET, SOCK_DGRAM, 0);
 446-	if (sock < 0)
 447-		return -1;
 448-	memset(&ifr, 0, sizeof(ifr));
 449-	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 450-	ifr.ifr_hwaddr.sa_family = 1;
 451-	memcpy(ifr.ifr_hwaddr.sa_data, mac, 6);
 452-	if (ioctl(sock, SIOCSIFHWADDR, &ifr) < 0) {
 453-		close(sock);
 454-		return -1;
 455-	}
 456-	close(sock);
 457-	return 0;
 458+        struct ifreq ifr;
 459+        int sock;
 460+
 461+        sock = socket(AF_INET, SOCK_DGRAM, 0);
 462+        if (sock < 0)
 463+                return -1;
 464+        memset(&ifr, 0, sizeof(ifr));
 465+        strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 466+        ifr.ifr_hwaddr.sa_family = 1;
 467+        memcpy(ifr.ifr_hwaddr.sa_data, mac, 6);
 468+        if (ioctl(sock, SIOCSIFHWADDR, &ifr) < 0) {
 469+                close(sock);
 470+                return -1;
 471+        }
 472+        close(sock);
 473+        return 0;
 474 #else
 475-	(void)name;
 476-	(void)mac;
 477-	return -1;
 478+        (void)name;
 479+        (void)mac;
 480+        return -1;
 481 #endif
 482 }
 483 
 484 int
 485 net_add_addr(const char *name, const char *addr, int prefix)
 486 {
 487-	struct ifreq ifr;
 488-	struct sockaddr_in *sin;
 489-	int sock;
 490-	unsigned int mask;
 491-
 492-	sock = socket(AF_INET, SOCK_DGRAM, 0);
 493-	if (sock < 0)
 494-		return -1;
 495-
 496-	memset(&ifr, 0, sizeof(ifr));
 497-	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 498-
 499-	sin = (struct sockaddr_in *)&ifr.ifr_addr;
 500-	sin->sin_family = AF_INET;
 501-	if (inet_pton(AF_INET, addr, &sin->sin_addr) <= 0) {
 502-		close(sock);
 503-		return -1;
 504-	}
 505-
 506-	if (ioctl(sock, SIOCSIFADDR, &ifr) < 0) {
 507-		close(sock);
 508-		return -1;
 509-	}
 510-
 511-	if (prefix >= 0) {
 512-		mask = 0;
 513-		if (prefix > 0)
 514-			mask = htonl(~0U << (32 - prefix));
 515-		sin = (struct sockaddr_in *)&ifr.ifr_netmask;
 516-		sin->sin_family = AF_INET;
 517-		sin->sin_addr.s_addr = mask;
 518-		if (ioctl(sock, SIOCSIFNETMASK, &ifr) < 0) {
 519-			close(sock);
 520-			return -1;
 521-		}
 522-	}
 523-
 524-	memset(&ifr, 0, sizeof(ifr));
 525-	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 526-	if (ioctl(sock, SIOCGIFFLAGS, &ifr) >= 0) {
 527-		ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
 528-		ioctl(sock, SIOCSIFFLAGS, &ifr);
 529-	}
 530-
 531-	close(sock);
 532-	return 0;
 533+        struct ifreq ifr;
 534+        struct sockaddr_in *sin;
 535+        int sock;
 536+        unsigned int mask;
 537+
 538+        sock = socket(AF_INET, SOCK_DGRAM, 0);
 539+        if (sock < 0)
 540+                return -1;
 541+
 542+        memset(&ifr, 0, sizeof(ifr));
 543+        strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 544+
 545+        sin = (struct sockaddr_in *)&ifr.ifr_addr;
 546+        sin->sin_family = AF_INET;
 547+        if (inet_pton(AF_INET, addr, &sin->sin_addr) <= 0) {
 548+                close(sock);
 549+                return -1;
 550+        }
 551+
 552+        if (ioctl(sock, SIOCSIFADDR, &ifr) < 0) {
 553+                close(sock);
 554+                return -1;
 555+        }
 556+
 557+        if (prefix >= 0) {
 558+                mask = 0;
 559+                if (prefix > 0)
 560+                        mask = htonl(~0U << (32 - prefix));
 561+                sin = (struct sockaddr_in *)&ifr.ifr_netmask;
 562+                sin->sin_family = AF_INET;
 563+                sin->sin_addr.s_addr = mask;
 564+                if (ioctl(sock, SIOCSIFNETMASK, &ifr) < 0) {
 565+                        close(sock);
 566+                        return -1;
 567+                }
 568+        }
 569+
 570+        memset(&ifr, 0, sizeof(ifr));
 571+        strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 572+        if (ioctl(sock, SIOCGIFFLAGS, &ifr) >= 0) {
 573+                ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
 574+                ioctl(sock, SIOCSIFFLAGS, &ifr);
 575+        }
 576+
 577+        close(sock);
 578+        return 0;
 579 }
 580 
 581 int
 582 net_del_addr(const char *name, const char *addr, int prefix)
 583 {
 584-	struct ifreq ifr;
 585-	struct sockaddr_in *sin;
 586-	int sock;
 587-
 588-	(void)prefix;
 589-	sock = socket(AF_INET, SOCK_DGRAM, 0);
 590-	if (sock < 0)
 591-		return -1;
 592-
 593-	memset(&ifr, 0, sizeof(ifr));
 594-	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 595-
 596-	sin = (struct sockaddr_in *)&ifr.ifr_addr;
 597-	sin->sin_family = AF_INET;
 598-	if (inet_pton(AF_INET, addr, &sin->sin_addr) <= 0) {
 599-		close(sock);
 600-		return -1;
 601-	}
 602-
 603-	if (ioctl(sock, SIOCDIFADDR, &ifr) < 0) {
 604-		close(sock);
 605-		return -1;
 606-	}
 607-	close(sock);
 608-	return 0;
 609+        struct ifreq ifr;
 610+        struct sockaddr_in *sin;
 611+        int sock;
 612+
 613+        (void)prefix;
 614+        sock = socket(AF_INET, SOCK_DGRAM, 0);
 615+        if (sock < 0)
 616+                return -1;
 617+
 618+        memset(&ifr, 0, sizeof(ifr));
 619+        strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 620+
 621+        sin = (struct sockaddr_in *)&ifr.ifr_addr;
 622+        sin->sin_family = AF_INET;
 623+        if (inet_pton(AF_INET, addr, &sin->sin_addr) <= 0) {
 624+                close(sock);
 625+                return -1;
 626+        }
 627+
 628+        if (ioctl(sock, SIOCDIFADDR, &ifr) < 0) {
 629+                close(sock);
 630+                return -1;
 631+        }
 632+        close(sock);
 633+        return 0;
 634 }
 635 
 636 int
 637 net_show_routes(void)
 638 {
 639 #ifdef __linux__
 640-	FILE *fp;
 641-	char line[256];
 642-	char iface[16], dest[16], gateway[16], mask[16];
 643-	unsigned int d, g, m, flags, metric;
 644-
 645-	fp = fopen("/proc/net/route", "r");
 646-	if (!fp)
 647-		return -1;
 648-
 649-	printf("%-10s %-15s %-15s %-15s %-6s %-6s\n", "Iface", "Destination", "Gateway", "Genmask", "Flags", "Metric");
 650-	if (fgets(line, sizeof(line), fp)) {
 651-		while (fgets(line, sizeof(line), fp)) {
 652-			if (sscanf(line, "%15s %x %x %x %*u %*u %u %x", iface, &d, &g, &m, &metric, &flags) == 6) {
 653-				struct in_addr dest_addr, gw_addr, mask_addr;
 654-				dest_addr.s_addr = d;
 655-				gw_addr.s_addr = g;
 656-				mask_addr.s_addr = m;
 657-				strlcpy(dest, inet_ntoa(dest_addr), sizeof(dest));
 658-				strlcpy(gateway, inet_ntoa(gw_addr), sizeof(gateway));
 659-				strlcpy(mask, inet_ntoa(mask_addr), sizeof(mask));
 660-				printf("%-10s %-15s %-15s %-15s 0x%04X %-6u\n", iface, dest, gateway, mask, flags, metric);
 661-			}
 662-		}
 663-	}
 664-	fclose(fp);
 665-	return 0;
 666+        FILE *fp;
 667+        char line[256];
 668+        char iface[16], dest[16], gateway[16], mask[16];
 669+        unsigned int d, g, m, flags, metric;
 670+
 671+        fp = fopen(ARUU_LINUX_PATH_PROC "/net/route", "r");
 672+        if (!fp)
 673+                return -1;
 674+
 675+        printf("%-10s %-15s %-15s %-15s %-6s %-6s\n", "Iface", "Destination", "Gateway", "Genmask", "Flags", "Metric");
 676+        if (fgets(line, sizeof(line), fp)) {
 677+                while (fgets(line, sizeof(line), fp)) {
 678+                        if (sscanf(line, "%15s %x %x %x %*u %*u %u %x", iface, &d, &g, &m, &metric, &flags) == 6) {
 679+                                struct in_addr dest_addr, gw_addr, mask_addr;
 680+                                dest_addr.s_addr = d;
 681+                                gw_addr.s_addr = g;
 682+                                mask_addr.s_addr = m;
 683+                                strlcpy(dest, inet_ntoa(dest_addr), sizeof(dest));
 684+                                strlcpy(gateway, inet_ntoa(gw_addr), sizeof(gateway));
 685+                                strlcpy(mask, inet_ntoa(mask_addr), sizeof(mask));
 686+                                printf("%-10s %-15s %-15s %-15s 0x%04X %-6u\n", iface, dest, gateway, mask, flags, metric);
 687+                        }
 688+                }
 689+        }
 690+        fclose(fp);
 691+        return 0;
 692 #else
 693-	printf("route listing not implemented on this OS\n");
 694-	return 0;
 695+        printf("route listing not implemented on this OS\n");
 696+        return 0;
 697 #endif
 698 }
 699 
 700 int
 701 net_add_route(const char *dst, const char *gateway, const char *mask, const char *dev, int metric)
 702 {
 703-	struct rtentry rt;
 704-	struct sockaddr_in *sin;
 705-	int sock;
 706-
 707-	sock = socket(AF_INET, SOCK_DGRAM, 0);
 708-	if (sock < 0)
 709-		return -1;
 710-
 711-	memset(&rt, 0, sizeof(rt));
 712-
 713-	sin = (struct sockaddr_in *)&rt.rt_dst;
 714-	sin->sin_family = AF_INET;
 715-	if (strcmp(dst, "default") == 0) {
 716-		sin->sin_addr.s_addr = INADDR_ANY;
 717-	} else {
 718-		if (inet_pton(AF_INET, dst, &sin->sin_addr) <= 0) {
 719-			close(sock);
 720-			return -1;
 721-		}
 722-	}
 723-
 724-	if (gateway) {
 725-		sin = (struct sockaddr_in *)&rt.rt_gateway;
 726-		sin->sin_family = AF_INET;
 727-		if (inet_pton(AF_INET, gateway, &sin->sin_addr) <= 0) {
 728-			close(sock);
 729-			return -1;
 730-		}
 731-		rt.rt_flags |= RTF_GATEWAY;
 732-	}
 733-
 734-	if (mask) {
 735-		sin = (struct sockaddr_in *)&rt.rt_genmask;
 736-		sin->sin_family = AF_INET;
 737-		if (inet_pton(AF_INET, mask, &sin->sin_addr) <= 0) {
 738-			close(sock);
 739-			return -1;
 740-		}
 741-	}
 742-
 743-	rt.rt_flags |= RTF_UP;
 744-	if (dev)
 745-		rt.rt_dev = (char *)dev;
 746-	if (metric >= 0)
 747-		rt.rt_metric = metric + 1;
 748-
 749-	if (ioctl(sock, SIOCADDRT, &rt) < 0) {
 750-		close(sock);
 751-		return -1;
 752-	}
 753-
 754-	close(sock);
 755-	return 0;
 756+        struct rtentry rt;
 757+        struct sockaddr_in *sin;
 758+        int sock;
 759+
 760+        sock = socket(AF_INET, SOCK_DGRAM, 0);
 761+        if (sock < 0)
 762+                return -1;
 763+
 764+        memset(&rt, 0, sizeof(rt));
 765+
 766+        sin = (struct sockaddr_in *)&rt.rt_dst;
 767+        sin->sin_family = AF_INET;
 768+        if (strcmp(dst, "default") == 0) {
 769+                sin->sin_addr.s_addr = INADDR_ANY;
 770+        } else {
 771+                if (inet_pton(AF_INET, dst, &sin->sin_addr) <= 0) {
 772+                        close(sock);
 773+                        return -1;
 774+                }
 775+        }
 776+
 777+        if (gateway) {
 778+                sin = (struct sockaddr_in *)&rt.rt_gateway;
 779+                sin->sin_family = AF_INET;
 780+                if (inet_pton(AF_INET, gateway, &sin->sin_addr) <= 0) {
 781+                        close(sock);
 782+                        return -1;
 783+                }
 784+                rt.rt_flags |= RTF_GATEWAY;
 785+        }
 786+
 787+        if (mask) {
 788+                sin = (struct sockaddr_in *)&rt.rt_genmask;
 789+                sin->sin_family = AF_INET;
 790+                if (inet_pton(AF_INET, mask, &sin->sin_addr) <= 0) {
 791+                        close(sock);
 792+                        return -1;
 793+                }
 794+        }
 795+
 796+        rt.rt_flags |= RTF_UP;
 797+        if (dev)
 798+                rt.rt_dev = (char *)dev;
 799+        if (metric >= 0)
 800+                rt.rt_metric = metric + 1;
 801+
 802+        if (ioctl(sock, SIOCADDRT, &rt) < 0) {
 803+                close(sock);
 804+                return -1;
 805+        }
 806+
 807+        close(sock);
 808+        return 0;
 809 }
 810 
 811 int
 812 net_del_route(const char *dst, const char *gateway, const char *mask, const char *dev, int metric)
 813 {
 814-	struct rtentry rt;
 815-	struct sockaddr_in *sin;
 816-	int sock;
 817-
 818-	sock = socket(AF_INET, SOCK_DGRAM, 0);
 819-	if (sock < 0)
 820-		return -1;
 821-
 822-	memset(&rt, 0, sizeof(rt));
 823-
 824-	sin = (struct sockaddr_in *)&rt.rt_dst;
 825-	sin->sin_family = AF_INET;
 826-	if (strcmp(dst, "default") == 0) {
 827-		sin->sin_addr.s_addr = INADDR_ANY;
 828-	} else {
 829-		if (inet_pton(AF_INET, dst, &sin->sin_addr) <= 0) {
 830-			close(sock);
 831-			return -1;
 832-		}
 833-	}
 834-
 835-	if (gateway) {
 836-		sin = (struct sockaddr_in *)&rt.rt_gateway;
 837-		sin->sin_family = AF_INET;
 838-		if (inet_pton(AF_INET, gateway, &sin->sin_addr) <= 0) {
 839-			close(sock);
 840-			return -1;
 841-		}
 842-		rt.rt_flags |= RTF_GATEWAY;
 843-	}
 844-
 845-	if (mask) {
 846-		sin = (struct sockaddr_in *)&rt.rt_genmask;
 847-		sin->sin_family = AF_INET;
 848-		if (inet_pton(AF_INET, mask, &sin->sin_addr) <= 0) {
 849-			close(sock);
 850-			return -1;
 851-		}
 852-	}
 853-
 854-	rt.rt_flags |= RTF_UP;
 855-	if (dev)
 856-		rt.rt_dev = (char *)dev;
 857-	if (metric >= 0)
 858-		rt.rt_metric = metric + 1;
 859-
 860-	if (ioctl(sock, SIOCDELRT, &rt) < 0) {
 861-		close(sock);
 862-		return -1;
 863-	}
 864-
 865-	close(sock);
 866-	return 0;
 867+        struct rtentry rt;
 868+        struct sockaddr_in *sin;
 869+        int sock;
 870+
 871+        sock = socket(AF_INET, SOCK_DGRAM, 0);
 872+        if (sock < 0)
 873+                return -1;
 874+
 875+        memset(&rt, 0, sizeof(rt));
 876+
 877+        sin = (struct sockaddr_in *)&rt.rt_dst;
 878+        sin->sin_family = AF_INET;
 879+        if (strcmp(dst, "default") == 0) {
 880+                sin->sin_addr.s_addr = INADDR_ANY;
 881+        } else {
 882+                if (inet_pton(AF_INET, dst, &sin->sin_addr) <= 0) {
 883+                        close(sock);
 884+                        return -1;
 885+                }
 886+        }
 887+
 888+        if (gateway) {
 889+                sin = (struct sockaddr_in *)&rt.rt_gateway;
 890+                sin->sin_family = AF_INET;
 891+                if (inet_pton(AF_INET, gateway, &sin->sin_addr) <= 0) {
 892+                        close(sock);
 893+                        return -1;
 894+                }
 895+                rt.rt_flags |= RTF_GATEWAY;
 896+        }
 897+
 898+        if (mask) {
 899+                sin = (struct sockaddr_in *)&rt.rt_genmask;
 900+                sin->sin_family = AF_INET;
 901+                if (inet_pton(AF_INET, mask, &sin->sin_addr) <= 0) {
 902+                        close(sock);
 903+                        return -1;
 904+                }
 905+        }
 906+
 907+        rt.rt_flags |= RTF_UP;
 908+        if (dev)
 909+                rt.rt_dev = (char *)dev;
 910+        if (metric >= 0)
 911+                rt.rt_metric = metric + 1;
 912+
 913+        if (ioctl(sock, SIOCDELRT, &rt) < 0) {
 914+                close(sock);
 915+                return -1;
 916+        }
 917+
 918+        close(sock);
 919+        return 0;
 920 }
 921 
 922 int
 923 net_flush_addrs(const char *dev)
 924 {
 925-	struct NetInterface *ifaces = NULL;
 926-	int count = 0, i, r = 0;
 927-
 928-	if (net_get_interfaces(&ifaces, &count) < 0)
 929-		return -1;
 930-
 931-	for (i = 0; i < count; i++) {
 932-		if (strcmp(ifaces[i].name, dev) == 0) {
 933-			if (ifaces[i].has_ipv4) {
 934-				char addr_str[16];
 935-				struct sockaddr_in *sin = &ifaces[i].ipv4_addr;
 936-				inet_ntop(AF_INET, &sin->sin_addr, addr_str, sizeof(addr_str));
 937-				if (net_del_addr(dev, addr_str, -1) < 0)
 938-					r = -1;
 939-			}
 940-		}
 941-	}
 942-	free(ifaces);
 943-	return r;
 944+        struct NetInterface *ifaces = NULL;
 945+        int count = 0, i, r = 0;
 946+
 947+        if (net_get_interfaces(&ifaces, &count) < 0)
 948+                return -1;
 949+
 950+        for (i = 0; i < count; i++) {
 951+                if (strcmp(ifaces[i].name, dev) == 0) {
 952+                        if (ifaces[i].has_ipv4) {
 953+                                char addr_str[16];
 954+                                struct sockaddr_in *sin = &ifaces[i].ipv4_addr;
 955+                                inet_ntop(AF_INET, &sin->sin_addr, addr_str, sizeof(addr_str));
 956+                                if (net_del_addr(dev, addr_str, -1) < 0)
 957+                                        r = -1;
 958+                        }
 959+                }
 960+        }
 961+        free(ifaces);
 962+        return r;
 963 }
 964 
 965 int
 966 net_set_name(const char *name, const char *newname)
 967 {
 968 #ifdef __linux__
 969-	struct ifreq ifr;
 970-	int sock;
 971-
 972-	sock = socket(AF_INET, SOCK_DGRAM, 0);
 973-	if (sock < 0)
 974-		return -1;
 975-	memset(&ifr, 0, sizeof(ifr));
 976-	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 977-	strlcpy(ifr.ifr_newname, newname, sizeof(ifr.ifr_newname));
 978-	if (ioctl(sock, SIOCSIFNAME, &ifr) < 0) {
 979-		close(sock);
 980-		return -1;
 981-	}
 982-	close(sock);
 983-	return 0;
 984+        struct ifreq ifr;
 985+        int sock;
 986+
 987+        sock = socket(AF_INET, SOCK_DGRAM, 0);
 988+        if (sock < 0)
 989+                return -1;
 990+        memset(&ifr, 0, sizeof(ifr));
 991+        strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 992+        strlcpy(ifr.ifr_newname, newname, sizeof(ifr.ifr_newname));
 993+        if (ioctl(sock, SIOCSIFNAME, &ifr) < 0) {
 994+                close(sock);
 995+                return -1;
 996+        }
 997+        close(sock);
 998+        return 0;
 999 #else
1000-	(void)name;
1001-	(void)newname;
1002-	return -1;
1003+        (void)name;
1004+        (void)newname;
1005+        return -1;
1006 #endif
1007 }
+365, -58
  1@@ -1,77 +1,384 @@
  2 /* See LICENSE file for copyright and license details. */
  3-#include <sys/resource.h>
  4-#include <sys/time.h>
  5+#include "../passwd.h"
  6+#include "../paths.h"
  7+#include "../text.h"
  8+#include "../util.h"
  9 
 10 #include <errno.h>
 11+#include <fcntl.h>
 12 #include <pwd.h>
 13-#include <shadow.h>
 14 #include <stdio.h>
 15 #include <stdlib.h>
 16 #include <string.h>
 17+#include <sys/resource.h>
 18+#include <sys/stat.h>
 19+#include <sys/wait.h>
 20 #include <unistd.h>
 21 
 22-#include "../passwd.h"
 23-#include "../text.h"
 24-#include "../util.h"
 25+#include "../config.h"
 26+
 27+#if defined(__linux__) || defined(__GLIBC__)
 28+#include <crypt.h>
 29+#endif
 30+
 31+#if defined(__linux__) && !defined(__ANDROID__)
 32+#define HAVE_SHADOW 1
 33+#include <shadow.h>
 34+#endif
 35+
 36+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
 37+#define HAVE_MASTER_PASSWD 1
 38+#endif
 39+
 40+int
 41+pw_init(void)
 42+{
 43+        struct rlimit rlim;
 44+
 45+        rlim.rlim_cur = 0;
 46+        rlim.rlim_max = 0;
 47+        if (setrlimit(RLIMIT_CORE, &rlim) < 0)
 48+                eprintf("setrlimit:");
 49+        return 0;
 50+}
 51 
 52-/* Returns -1 on error, 0 for incorrect password
 53- * and 1 if all went OK */
 54 int
 55 pw_check(const struct passwd *pw, const char *pass)
 56 {
 57-	char *cryptpass, *p;
 58-	struct spwd *spw;
 59-
 60-	p = pw->pw_passwd;
 61-	if (p[0] == '!' || p[0] == '*') {
 62-		weprintf("denied\n");
 63-		return -1;
 64-	}
 65-
 66-	if (pw->pw_passwd[0] == '\0') {
 67-		if (pass[0] == '\0')
 68-			return 1;
 69-		weprintf("incorrect password\n");
 70-		return 0;
 71-	}
 72-
 73-	if (pw->pw_passwd[0] == 'x' && pw->pw_passwd[1] == '\0') {
 74-		errno = 0;
 75-		spw = getspnam(pw->pw_name);
 76-		if (!spw) {
 77-			if (errno)
 78-				weprintf("getspnam: %s:", pw->pw_name);
 79-			else
 80-				weprintf("who are you?\n");
 81-			return -1;
 82-		}
 83-		p = spw->sp_pwdp;
 84-		if (p[0] == '!' || p[0] == '*') {
 85-			weprintf("denied\n");
 86-			return -1;
 87-		}
 88-	}
 89-
 90-	cryptpass = crypt(pass, p);
 91-	if (!cryptpass) {
 92-		weprintf("crypt:");
 93-		return -1;
 94-	}
 95-	if (strcmp(cryptpass, p) != 0) {
 96-		weprintf("incorrect password\n");
 97-		return 0;
 98-	}
 99-	return 1;
100+        char *cryptpass, *p;
101+        const char *stored;
102+
103+        stored = pw->pw_passwd;
104+        if (stored[0] == '!' || stored[0] == '*') {
105+                weprintf("denied\n");
106+                return -1;
107+        }
108+
109+        if (stored[0] == '\0') {
110+                if (pass[0] == '\0')
111+                        return 1;
112+                weprintf("incorrect password\n");
113+                return 0;
114+        }
115+
116+#if defined(HAVE_SHADOW)
117+        if (stored[0] == 'x' && stored[1] == '\0') {
118+                struct spwd *spw;
119+                errno = 0;
120+                spw = getspnam(pw->pw_name);
121+                if (!spw) {
122+                        if (errno)
123+                                weprintf("getspnam: %s:", pw->pw_name);
124+                        else
125+                                weprintf("who are you?\n");
126+                        return -1;
127+                }
128+                stored = spw->sp_pwdp;
129+                if (stored[0] == '!' || stored[0] == '*') {
130+                        weprintf("denied\n");
131+                        return -1;
132+                }
133+        }
134+#endif
135+
136+        cryptpass = crypt(pass, stored);
137+        if (!cryptpass) {
138+                weprintf("crypt:");
139+                return -1;
140+        }
141+        p = estrdup(cryptpass);
142+        if (strcmp(p, stored) != 0) {
143+                free(p);
144+                weprintf("incorrect password\n");
145+                return 0;
146+        }
147+        free(p);
148+        return 1;
149 }
150 
151 int
152-pw_init(void)
153+pwdb_lookup(struct pwdb_entry *ent, const char *name)
154 {
155-	struct rlimit rlim;
156+        struct passwd *pw;
157+        const char *hash;
158 
159-	rlim.rlim_cur = 0;
160-	rlim.rlim_max = 0;
161-	if (setrlimit(RLIMIT_CORE, &rlim) < 0)
162-		eprintf("setrlimit:");
163-	return 0;
164+        errno = 0;
165+        pw = getpwnam(name);
166+        if (!pw) {
167+                if (errno)
168+                        weprintf("getpwnam: %s:", name);
169+                else
170+                        weprintf("who are you?\n");
171+                return -1;
172+        }
173+
174+        ent->name = estrdup(pw->pw_name);
175+        ent->uid = pw->pw_uid;
176+        ent->gid = pw->pw_gid;
177+        hash = pw->pw_passwd;
178+
179+#if defined(HAVE_SHADOW)
180+        if (hash[0] == 'x' && hash[1] == '\0') {
181+                struct spwd *spw;
182+                errno = 0;
183+                spw = getspnam(name);
184+                if (spw)
185+                        hash = spw->sp_pwdp;
186+        }
187+#endif
188+
189+        ent->hash = estrdup(hash);
190+        return 0;
191+}
192+
193+static int
194+fill_random(void *buf, size_t n)
195+{
196+#if defined(__linux__)
197+        if (getentropy(buf, n) == 0)
198+                return 0;
199+#endif
200+        {
201+                int fd;
202+                size_t off;
203+                fd = open(ARUU_PATH_DEVURANDOM, O_RDONLY);
204+                if (fd < 0) {
205+                        weprintf("open /dev/urandom:");
206+                        return -1;
207+                }
208+                off = 0;
209+                while (off < n) {
210+                        ssize_t r = read(fd, (char *)buf + off, n - off);
211+                        if (r <= 0) {
212+                                close(fd);
213+                                weprintf("read /dev/urandom:");
214+                                return -1;
215+                        }
216+                        off += (size_t)r;
217+                }
218+                close(fd);
219+        }
220+        return 0;
221+}
222+
223+int
224+pw_gensalt_cipher(char *salt, size_t salt_sz, const char *prefix,
225+                  size_t rand_len)
226+{
227+        static const char b64[] =
228+                "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
229+        unsigned char raw[32];
230+        char body[48];
231+        size_t i, n, body_len;
232+        unsigned v;
233+        int prefix_len;
234+
235+        if (rand_len > sizeof(raw))
236+                rand_len = sizeof(raw);
237+        if (rand_len == 0) {
238+                salt[0] = '\0';
239+                return 0;
240+        }
241+
242+        prefix_len = 0;
243+        if (prefix) {
244+                prefix_len = snprintf(salt, salt_sz, "%s", prefix);
245+                if (prefix_len < 0 || (size_t)prefix_len >= salt_sz) {
246+                        weprintf("snprintf:");
247+                        return -1;
248+                }
249+        }
250+
251+        if (fill_random(raw, rand_len) < 0)
252+                return -1;
253+
254+        body_len = (rand_len * 4 + 2) / 3;
255+        if (body_len >= sizeof(body))
256+                body_len = sizeof(body) - 1;
257+        n = 0;
258+        for (i = 0; i + 3 <= rand_len; i += 3) {
259+                v = (raw[i] << 16) | (raw[i+1] << 8) | raw[i+2];
260+                body[n++] = b64[v & 0x3f]; v >>= 6;
261+                body[n++] = b64[v & 0x3f]; v >>= 6;
262+                body[n++] = b64[v & 0x3f]; v >>= 6;
263+                body[n++] = b64[v & 0x3f];
264+        }
265+        if (i < rand_len) {
266+                v = raw[i] << 16;
267+                if (i + 1 < rand_len)
268+                        v |= raw[i+1] << 8;
269+                body[n++] = b64[v & 0x3f]; v >>= 6;
270+                body[n++] = b64[v & 0x3f]; v >>= 6;
271+                if (i + 1 < rand_len)
272+                        body[n++] = b64[v & 0x3f];
273+        }
274+        body[n] = '\0';
275+
276+        if ((size_t)prefix_len + n + 1 >= salt_sz) {
277+                weprintf("salt buffer too small\n");
278+                return -1;
279+        }
280+        memcpy(salt + prefix_len, body, n + 1);
281+        return 0;
282+}
283+
284+int
285+pw_gensalt(char *salt, size_t salt_sz)
286+{
287+        return pw_gensalt_cipher(salt, salt_sz, PW_CIPHER, 16);
288+}
289+
290+#if defined(HAVE_SHADOW)
291+static int
292+update_shadow(const char *name, const char *newhash)
293+{
294+        struct spwd *spw, cur;
295+        FILE *fp, *tfp;
296+        int wrote = 0;
297+        char path[256];
298+
299+        snprintf(path, sizeof(path), ARUU_PATH_ETC "/tcb/%s/shadow", name);
300+        fp = fopen(path, "r+");
301+        if (!fp) {
302+                memcpy(path, ARUU_PATH_SHADOW, sizeof(ARUU_PATH_SHADOW));
303+                fp = fopen(path, "r+");
304+        }
305+        if (!fp) {
306+                weprintf("fopen %s:", path);
307+                return -1;
308+        }
309+
310+        tfp = tmpfile();
311+        if (!tfp) {
312+                weprintf("tmpfile:");
313+                fclose(fp);
314+                return -1;
315+        }
316+
317+        while ((spw = getspent())) {
318+                cur = *spw;
319+                if (strcmp(cur.sp_namp, name) == 0) {
320+                        cur.sp_pwdp = (char *)newhash;
321+                        wrote = 1;
322+                }
323+                errno = 0;
324+                if (putspent(&cur, tfp) == -1) {
325+                        weprintf("putspent:");
326+                        fclose(tfp);
327+                        fclose(fp);
328+                        return -1;
329+                }
330+        }
331+        if (!wrote) {
332+                weprintf("shadow: no matching entry\n");
333+                fclose(tfp);
334+                fclose(fp);
335+                return -1;
336+        }
337+        fflush(tfp);
338+        rewind(tfp);
339+        rewind(fp);
340+        fconcat(tfp, "tmpfile", fp, "shadow");
341+        ftruncate(fileno(fp), ftell(tfp));
342+        fclose(tfp);
343+        {
344+                int fd = fileno(fp);
345+                if (fd >= 0)
346+                        fsync(fd);
347+        }
348+        fclose(fp);
349+        return 0;
350+}
351+#endif
352+
353+static int
354+update_passwd_file(const char *path, const char *name, const char *newhash)
355+{
356+        struct passwd *pw, cur;
357+        FILE *fp, *tfp;
358+        int wrote = 0;
359+
360+        fp = fopen(path, "r+");
361+        if (!fp) {
362+                weprintf("fopen %s:", path);
363+                return -1;
364+        }
365+        tfp = tmpfile();
366+        if (!tfp) {
367+                weprintf("tmpfile:");
368+                fclose(fp);
369+                return -1;
370+        }
371+        while ((pw = fgetpwent(fp))) {
372+                cur = *pw;
373+                if (strcmp(cur.pw_name, name) == 0) {
374+                        cur.pw_passwd = (char *)newhash;
375+                        wrote = 1;
376+                }
377+                errno = 0;
378+                if (putpwent(&cur, tfp) == -1) {
379+                        weprintf("putpwent:");
380+                        fclose(tfp);
381+                        fclose(fp);
382+                        return -1;
383+                }
384+        }
385+        if (!wrote) {
386+                weprintf("passwd: no matching entry\n");
387+                fclose(tfp);
388+                fclose(fp);
389+                return -1;
390+        }
391+        fflush(tfp);
392+        rewind(tfp);
393+        rewind(fp);
394+        fconcat(tfp, "tmpfile", fp, path);
395+        ftruncate(fileno(fp), ftell(tfp));
396+        {
397+                int fd = fileno(fp);
398+                if (fd >= 0)
399+                        fsync(fd);
400+        }
401+        fclose(tfp);
402+        fclose(fp);
403+        return 0;
404+}
405+
406+#if defined(HAVE_MASTER_PASSWD)
407+static int
408+update_master_passwd(const char *name, const char *newhash)
409+{
410+        int r;
411+        pid_t pid;
412+        int st;
413+
414+        r = update_passwd_file(ARUU_BSD_PATH_MASTER_PASSWD, name, newhash);
415+        if (r != 0)
416+                return r;
417+        pid = fork();
418+        if (pid == 0) {
419+                execl(ARUU_BSD_PATH_PWD_MKDB, "pwd_mkdb", "-p", NULL);
420+                _exit(127);
421+        }
422+        if (pid > 0)
423+                waitpid(pid, &st, 0);
424+        return 0;
425+}
426+#endif
427+
428+int
429+pwdb_update(const char *name, const char *newhash)
430+{
431+#if defined(HAVE_SHADOW)
432+        {
433+                struct spwd *spw;
434+                errno = 0;
435+                spw = getspnam(name);
436+                if (spw)
437+                        return update_shadow(name, newhash);
438+        }
439+#elif defined(HAVE_MASTER_PASSWD)
440+        return update_master_passwd(name, newhash);
441+#endif
442+        return update_passwd_file(ARUU_PATH_PASSWD, name, newhash);
443 }
+4, -3
 1@@ -10,6 +10,7 @@
 2 #include <unistd.h>
 3 
 4 #include "../proc.h"
 5+#include "../paths.h"
 6 #include "../util.h"
 7 
 8 int
 9@@ -19,7 +20,7 @@ parsecmdline(pid_t pid, char *buf, size_t siz)
10 	char path[PATH_MAX];
11 	ssize_t n, i;
12 
13-	snprintf(path, sizeof(path), "/proc/%ld/cmdline", (long)pid);
14+	snprintf(path, sizeof(path), ARUU_LINUX_PATH_PROC "/%ld/cmdline", (long)pid);
15 	fd = open(path, O_RDONLY);
16 	if (fd < 0)
17 		return -1;
18@@ -48,7 +49,7 @@ parsestat(pid_t pid, struct procstat *ps)
19 	FILE *fp;
20 	size_t len;
21 
22-	snprintf(path, sizeof(path), "/proc/%d/stat", pid);
23+	snprintf(path, sizeof(path), ARUU_LINUX_PATH_PROC "/%d/stat", pid);
24 	if (!(fp = fopen(path, "r")))
25 		return -1;
26 	fscanf(fp, "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu",
27@@ -78,7 +79,7 @@ parsestatus(pid_t pid, struct procstatus *pstatus)
28 	int fd;
29 	ssize_t n;
30 
31-	snprintf(path, sizeof(path), "/proc/%d/status", pid);
32+	snprintf(path, sizeof(path), ARUU_LINUX_PATH_PROC "/%d/status", pid);
33 	fd = open(path, O_RDONLY);
34 	if (fd < 0)
35 		return -1;
+300, -295
  1@@ -1,5 +1,6 @@
  2 /* see license file for copyright and license details */
  3 #include "../tls.h"
  4+#include "../paths.h"
  5 #include "../util.h"
  6 
  7 #include <errno.h>
  8@@ -13,201 +14,201 @@
  9 #include <tls.h>
 10 
 11 struct TlsSocket {
 12-	int fd;
 13-	int is_tls;
 14-	struct tls *ctx;
 15+        int fd;
 16+        int is_tls;
 17+        struct tls *ctx;
 18 };
 19 
 20 #elif FEATURE_USE_BEARSSL
 21 #include <bearssl.h>
 22 
 23 struct my_x509_context {
 24-	const br_x509_class *vtable;
 25-	br_x509_minimal_context minimal;
 26+        const br_x509_class *vtable;
 27+        br_x509_minimal_context minimal;
 28 };
 29 
 30 struct TlsSocket {
 31-	int fd;
 32-	int is_tls;
 33-	br_ssl_client_context sc;
 34-	struct my_x509_context my_x509;
 35-	unsigned char iobuf[BR_SSL_BUFSIZE_BIDI];
 36-	br_sslio_context ioc;
 37+        int fd;
 38+        int is_tls;
 39+        br_ssl_client_context sc;
 40+        struct my_x509_context my_x509;
 41+        unsigned char iobuf[BR_SSL_BUFSIZE_BIDI];
 42+        br_sslio_context ioc;
 43 };
 44 
 45 struct dn_accum {
 46-	unsigned char *data;
 47-	size_t len;
 48-	size_t cap;
 49+        unsigned char *data;
 50+        size_t len;
 51+        size_t cap;
 52 };
 53 
 54 static void
 55 append_dn_callback(void *dn_ctx, const void *src, size_t len)
 56 {
 57-	struct dn_accum *accum = dn_ctx;
 58-	if (accum->len + len > accum->cap) {
 59-		accum->cap = accum->len + len + 256;
 60-		accum->data = erealloc(accum->data, accum->cap);
 61-	}
 62-	memcpy(accum->data + accum->len, src, len);
 63-	accum->len += len;
 64+        struct dn_accum *accum = dn_ctx;
 65+        if (accum->len + len > accum->cap) {
 66+                accum->cap = accum->len + len + 256;
 67+                accum->data = erealloc(accum->data, accum->cap);
 68+        }
 69+        memcpy(accum->data + accum->len, src, len);
 70+        accum->len += len;
 71 }
 72 
 73 static void
 74 my_start_chain(const br_x509_class **ctx, const char *server_name)
 75 {
 76-	struct my_x509_context *t = (struct my_x509_context *)ctx;
 77-	br_x509_minimal_vtable.start_chain((const br_x509_class **)&t->minimal, server_name);
 78+        struct my_x509_context *t = (struct my_x509_context *)ctx;
 79+        br_x509_minimal_vtable.start_chain((const br_x509_class **)&t->minimal, server_name);
 80 }
 81 
 82 static void
 83 my_start_cert(const br_x509_class **ctx, uint32_t length)
 84 {
 85-	struct my_x509_context *t = (struct my_x509_context *)ctx;
 86-	br_x509_minimal_vtable.start_cert((const br_x509_class **)&t->minimal, length);
 87+        struct my_x509_context *t = (struct my_x509_context *)ctx;
 88+        br_x509_minimal_vtable.start_cert((const br_x509_class **)&t->minimal, length);
 89 }
 90 
 91 static void
 92 my_append(const br_x509_class **ctx, const unsigned char *buf, size_t len)
 93 {
 94-	struct my_x509_context *t = (struct my_x509_context *)ctx;
 95-	br_x509_minimal_vtable.append((const br_x509_class **)&t->minimal, buf, len);
 96+        struct my_x509_context *t = (struct my_x509_context *)ctx;
 97+        br_x509_minimal_vtable.append((const br_x509_class **)&t->minimal, buf, len);
 98 }
 99 
100 static void
101 my_end_cert(const br_x509_class **ctx)
102 {
103-	struct my_x509_context *t = (struct my_x509_context *)ctx;
104-	br_x509_minimal_vtable.end_cert((const br_x509_class **)&t->minimal);
105+        struct my_x509_context *t = (struct my_x509_context *)ctx;
106+        br_x509_minimal_vtable.end_cert((const br_x509_class **)&t->minimal);
107 }
108 
109 static unsigned
110 my_end_chain(const br_x509_class **ctx)
111 {
112-	struct my_x509_context *t = (struct my_x509_context *)ctx;
113-	(void)br_x509_minimal_vtable.end_chain((const br_x509_class **)&t->minimal);
114-	/* always succeed and accept certificate when check_cert is 0 */
115-	return 0;
116+        struct my_x509_context *t = (struct my_x509_context *)ctx;
117+        (void)br_x509_minimal_vtable.end_chain((const br_x509_class **)&t->minimal);
118+        /* always succeed and accept certificate when check_cert is 0 */
119+        return 0;
120 }
121 
122 static const br_x509_pkey *
123 my_get_pkey(const br_x509_class *const *ctx, unsigned *usages)
124 {
125-	const struct my_x509_context *t = (const struct my_x509_context *)ctx;
126-	return br_x509_minimal_vtable.get_pkey((const br_x509_class *const *)&t->minimal, usages);
127+        const struct my_x509_context *t = (const struct my_x509_context *)ctx;
128+        return br_x509_minimal_vtable.get_pkey((const br_x509_class *const *)&t->minimal, usages);
129 }
130 
131 static const br_x509_class my_x509_vtable = {
132-	sizeof(struct my_x509_context),
133-	my_start_chain,
134-	my_start_cert,
135-	my_append,
136-	my_end_cert,
137-	my_end_chain,
138-	my_get_pkey
139+        sizeof(struct my_x509_context),
140+        my_start_chain,
141+        my_start_cert,
142+        my_append,
143+        my_end_cert,
144+        my_end_chain,
145+        my_get_pkey
146 };
147 
148 static int
149 sock_read(void *ctx, unsigned char *buf, size_t len)
150 {
151-	int fd = *(int *)ctx;
152-	for (;;) {
153-		ssize_t rlen = read(fd, buf, len);
154-		if (rlen <= 0) {
155-			if (rlen < 0 && errno == EINTR)
156-				continue;
157-			return -1;
158-		}
159-		return (int)rlen;
160-	}
161+        int fd = *(int *)ctx;
162+        for (;;) {
163+                ssize_t rlen = read(fd, buf, len);
164+                if (rlen <= 0) {
165+                        if (rlen < 0 && errno == EINTR)
166+                                continue;
167+                        return -1;
168+                }
169+                return (int)rlen;
170+        }
171 }
172 
173 static int
174 sock_write(void *ctx, const unsigned char *buf, size_t len)
175 {
176-	int fd = *(int *)ctx;
177-	for (;;) {
178-		ssize_t wlen = write(fd, buf, len);
179-		if (wlen <= 0) {
180-			if (wlen < 0 && errno == EINTR)
181-				continue;
182-			return -1;
183-		}
184-		return (int)wlen;
185-	}
186+        int fd = *(int *)ctx;
187+        for (;;) {
188+                ssize_t wlen = write(fd, buf, len);
189+                if (wlen <= 0) {
190+                        if (wlen < 0 && errno == EINTR)
191+                                continue;
192+                        return -1;
193+                }
194+                return (int)wlen;
195+        }
196 }
197 
198 static int
199 b64_decode_char(char c)
200 {
201-	if (c >= 'A' && c <= 'Z') return c - 'A';
202-	if (c >= 'a' && c <= 'z') return c - 'a' + 26;
203-	if (c >= '0' && c <= '9') return c - '0' + 52;
204-	if (c == '+') return 62;
205-	if (c == '/') return 63;
206-	return -1;
207+        if (c >= 'A' && c <= 'Z') return c - 'A';
208+        if (c >= 'a' && c <= 'z') return c - 'a' + 26;
209+        if (c >= '0' && c <= '9') return c - '0' + 52;
210+        if (c == '+') return 62;
211+        if (c == '/') return 63;
212+        return -1;
213 }
214 
215 static size_t
216 b64_decode(const char *src, size_t src_len, unsigned char *dst)
217 {
218-	size_t i, j = 0;
219-	int val = 0, valb = -8;
220-	for (i = 0; i < src_len; i++) {
221-		int c = b64_decode_char(src[i]);
222-		if (c >= 0) {
223-			val = (val << 6) | c;
224-			valb += 6;
225-			if (valb >= 0) {
226-				dst[j++] = (val >> valb) & 0xFF;
227-				valb -= 8;
228-			}
229-		}
230-	}
231-	return j;
232+        size_t i, j = 0;
233+        int val = 0, valb = -8;
234+        for (i = 0; i < src_len; i++) {
235+                int c = b64_decode_char(src[i]);
236+                if (c >= 0) {
237+                        val = (val << 6) | c;
238+                        valb += 6;
239+                        if (valb >= 0) {
240+                                dst[j++] = (val >> valb) & 0xFF;
241+                                valb -= 8;
242+                        }
243+                }
244+        }
245+        return j;
246 }
247 
248 static int
249 decode_cert_der(const unsigned char *der, size_t der_len, br_x509_trust_anchor *ta)
250 {
251-	br_x509_decoder_context dc;
252-	struct dn_accum accum = { NULL, 0, 0 };
253-	const br_x509_pkey *pk;
254-
255-	br_x509_decoder_init(&dc, append_dn_callback, &accum);
256-	br_x509_decoder_push(&dc, der, der_len);
257-	if (br_x509_decoder_last_error(&dc) != 0) {
258-		free(accum.data);
259-		return 0;
260-	}
261-	pk = br_x509_decoder_get_pkey(&dc);
262-	if (!pk) {
263-		free(accum.data);
264-		return 0;
265-	}
266-
267-	ta->dn.data = accum.data;
268-	ta->dn.len = accum.len;
269-	ta->flags = br_x509_decoder_isCA(&dc) ? BR_X509_TA_CA : 0;
270-	ta->pkey.key_type = pk->key_type;
271-
272-	if (pk->key_type == BR_KEYTYPE_RSA) {
273-		ta->pkey.key.rsa.nlen = pk->key.rsa.nlen;
274-		ta->pkey.key.rsa.n = emalloc(pk->key.rsa.nlen);
275-		memcpy(ta->pkey.key.rsa.n, pk->key.rsa.n, pk->key.rsa.nlen);
276-		ta->pkey.key.rsa.elen = pk->key.rsa.elen;
277-		ta->pkey.key.rsa.e = emalloc(pk->key.rsa.elen);
278-		memcpy(ta->pkey.key.rsa.e, pk->key.rsa.e, pk->key.rsa.elen);
279-	} else if (pk->key_type == BR_KEYTYPE_EC) {
280-		ta->pkey.key.ec.curve = pk->key.ec.curve;
281-		ta->pkey.key.ec.qlen = pk->key.ec.qlen;
282-		ta->pkey.key.ec.q = emalloc(pk->key.ec.qlen);
283-		memcpy(ta->pkey.key.ec.q, pk->key.ec.q, pk->key.ec.qlen);
284-	} else {
285-		free(accum.data);
286-		return 0;
287-	}
288-	return 1;
289+        br_x509_decoder_context dc;
290+        struct dn_accum accum = { NULL, 0, 0 };
291+        const br_x509_pkey *pk;
292+
293+        br_x509_decoder_init(&dc, append_dn_callback, &accum);
294+        br_x509_decoder_push(&dc, der, der_len);
295+        if (br_x509_decoder_last_error(&dc) != 0) {
296+                free(accum.data);
297+                return 0;
298+        }
299+        pk = br_x509_decoder_get_pkey(&dc);
300+        if (!pk) {
301+                free(accum.data);
302+                return 0;
303+        }
304+
305+        ta->dn.data = accum.data;
306+        ta->dn.len = accum.len;
307+        ta->flags = br_x509_decoder_isCA(&dc) ? BR_X509_TA_CA : 0;
308+        ta->pkey.key_type = pk->key_type;
309+
310+        if (pk->key_type == BR_KEYTYPE_RSA) {
311+                ta->pkey.key.rsa.nlen = pk->key.rsa.nlen;
312+                ta->pkey.key.rsa.n = emalloc(pk->key.rsa.nlen);
313+                memcpy(ta->pkey.key.rsa.n, pk->key.rsa.n, pk->key.rsa.nlen);
314+                ta->pkey.key.rsa.elen = pk->key.rsa.elen;
315+                ta->pkey.key.rsa.e = emalloc(pk->key.rsa.elen);
316+                memcpy(ta->pkey.key.rsa.e, pk->key.rsa.e, pk->key.rsa.elen);
317+        } else if (pk->key_type == BR_KEYTYPE_EC) {
318+                ta->pkey.key.ec.curve = pk->key.ec.curve;
319+                ta->pkey.key.ec.qlen = pk->key.ec.qlen;
320+                ta->pkey.key.ec.q = emalloc(pk->key.ec.qlen);
321+                memcpy(ta->pkey.key.ec.q, pk->key.ec.q, pk->key.ec.qlen);
322+        } else {
323+                free(accum.data);
324+                return 0;
325+        }
326+        return 1;
327 }
328 
329 static br_x509_trust_anchor *tas = NULL;
330@@ -216,222 +217,226 @@ static size_t tas_num = 0;
331 static void
332 load_ca_certs(void)
333 {
334-	static const char *ca_paths[] = {
335-		"/etc/ssl/certs/ca-certificates.crt",
336-		"/etc/ssl/cert.pem",
337-		"/etc/pki/tls/certs/ca-bundle.crt",
338-	};
339-	FILE *fp = NULL;
340-	size_t i;
341-	char line[512];
342-	struct {
343-		char *data;
344-		size_t len;
345-		size_t cap;
346-	} pem = { NULL, 0, 0 };
347-	int in_cert = 0;
348-
349-	for (i = 0; i < LEN(ca_paths); i++) {
350-		if ((fp = fopen(ca_paths[i], "r")))
351-			break;
352-	}
353-	if (!fp) {
354-		weprintf("no CA certificates found, TLS verification will fail\n");
355-		return;
356-	}
357-
358-	while (fgets(line, sizeof(line), fp)) {
359-		if (strncmp(line, "-----BEGIN CERTIFICATE-----", 27) == 0) {
360-			in_cert = 1;
361-			pem.len = 0;
362-		} else if (strncmp(line, "-----END CERTIFICATE-----", 25) == 0) {
363-			if (in_cert) {
364-				unsigned char *der = emalloc(pem.len);
365-				size_t der_len = b64_decode(pem.data, pem.len, der);
366-				br_x509_trust_anchor ta;
367-				if (decode_cert_der(der, der_len, &ta)) {
368-					tas = ereallocarray(tas, tas_num + 1, sizeof(*tas));
369-					tas[tas_num++] = ta;
370-				}
371-				free(der);
372-				in_cert = 0;
373-			}
374-		} else if (in_cert) {
375-			size_t llen = strlen(line);
376-			while (llen > 0 && (line[llen-1] == '\r' || line[llen-1] == '\n'))
377-				llen--;
378-			if (pem.len + llen > pem.cap) {
379-				pem.cap = pem.len + llen + 1024;
380-				pem.data = erealloc(pem.data, pem.cap);
381-			}
382-			memcpy(pem.data + pem.len, line, llen);
383-			pem.len += llen;
384-		}
385-	}
386-	free(pem.data);
387-	fclose(fp);
388+        static const char *ca_paths[] = {
389+                ARUU_PATH_ETC "/ssl/certs/ca-certificates.crt",
390+                ARUU_PATH_ETC "/ssl/cert.pem",
391+                ARUU_PATH_ETC "/pki/tls/certs/ca-bundle.crt",
392+        };
393+        FILE *fp = NULL;
394+        size_t i;
395+        char line[512];
396+        struct {
397+                char *data;
398+                size_t len;
399+                size_t cap;
400+        } pem = { NULL, 0, 0 };
401+        int in_cert = 0;
402+
403+        for (i = 0; i < LEN(ca_paths); i++) {
404+                if ((fp = fopen(ca_paths[i], "r")))
405+                        break;
406+        }
407+        if (!fp) {
408+                weprintf("no CA certificates found, TLS verification will fail\n");
409+                return;
410+        }
411+
412+        while (fgets(line, sizeof(line), fp)) {
413+                if (strncmp(line, "-----BEGIN CERTIFICATE-----", 27) == 0) {
414+                        in_cert = 1;
415+                        pem.len = 0;
416+                } else if (strncmp(line, "-----END CERTIFICATE-----", 25) == 0) {
417+                        if (in_cert) {
418+                                unsigned char *der = emalloc(pem.len);
419+                                size_t der_len = b64_decode(pem.data, pem.len, der);
420+                                br_x509_trust_anchor ta;
421+                                if (decode_cert_der(der, der_len, &ta)) {
422+                                        tas = ereallocarray(tas, tas_num + 1, sizeof(*tas));
423+                                        tas[tas_num++] = ta;
424+                                }
425+                                free(der);
426+                                in_cert = 0;
427+                        }
428+                } else if (in_cert) {
429+                        size_t llen = strlen(line);
430+                        while (llen > 0 && (line[llen-1] == '\r' || line[llen-1] == '\n'))
431+                                llen--;
432+                        if (pem.len + llen > pem.cap) {
433+                                pem.cap = pem.len + llen + 1024;
434+                                pem.data = erealloc(pem.data, pem.cap);
435+                        }
436+                        memcpy(pem.data + pem.len, line, llen);
437+                        pem.len += llen;
438+                }
439+        }
440+        free(pem.data);
441+        fclose(fp);
442 }
443 #else
444 struct TlsSocket {
445-	int fd;
446-	int is_tls;
447+        int fd;
448+        int is_tls;
449 };
450 #endif
451 
452 struct TlsSocket *
453 tls_connect(int fd, const char *host, int check_cert, int is_tls)
454 {
455-	struct TlsSocket *s;
456+        struct TlsSocket *s;
457 
458-	s = emalloc(sizeof(*s));
459-	s->fd = fd;
460-	s->is_tls = is_tls;
461+        s = emalloc(sizeof(*s));
462+        s->fd = fd;
463+        s->is_tls = is_tls;
464 
465-	if (!is_tls)
466-		return s;
467+        if (!is_tls)
468+                return s;
469+#if !FEATURE_USE_LIBRESSL && !FEATURE_USE_BEARSSL && !FEATURE_USE_OPENSSL
470+        (void)host;
471+        (void)check_cert;
472+#endif
473 
474 #if FEATURE_USE_LIBRESSL
475-	{
476-		struct tls_config *cfg;
477-
478-		s->ctx = tls_client();
479-		if (!s->ctx) {
480-			weprintf("tls_client failed\n");
481-			free(s);
482-			return NULL;
483-		}
484-		cfg = tls_config_new();
485-		if (!cfg) {
486-			weprintf("tls_config_new failed\n");
487-			tls_free(s->ctx);
488-			free(s);
489-			return NULL;
490-		}
491-		if (!check_cert) {
492-			tls_config_insecure_noverifycert(cfg);
493-			tls_config_insecure_noverifyname(cfg);
494-		}
495-		if (tls_configure(s->ctx, cfg) < 0) {
496-			weprintf("tls_configure: %s\n", tls_error(s->ctx));
497-			tls_config_free(cfg);
498-			tls_free(s->ctx);
499-			free(s);
500-			return NULL;
501-		}
502-		tls_config_free(cfg);
503-
504-		if (tls_connect_socket(s->ctx, fd, host) < 0) {
505-			weprintf("tls_connect_socket: %s\n", tls_error(s->ctx));
506-			tls_free(s->ctx);
507-			free(s);
508-			return NULL;
509-		}
510-	}
511+        {
512+                struct tls_config *cfg;
513+
514+                s->ctx = tls_client();
515+                if (!s->ctx) {
516+                        weprintf("tls_client failed\n");
517+                        free(s);
518+                        return NULL;
519+                }
520+                cfg = tls_config_new();
521+                if (!cfg) {
522+                        weprintf("tls_config_new failed\n");
523+                        tls_free(s->ctx);
524+                        free(s);
525+                        return NULL;
526+                }
527+                if (!check_cert) {
528+                        tls_config_insecure_noverifycert(cfg);
529+                        tls_config_insecure_noverifyname(cfg);
530+                }
531+                if (tls_configure(s->ctx, cfg) < 0) {
532+                        weprintf("tls_configure: %s\n", tls_error(s->ctx));
533+                        tls_config_free(cfg);
534+                        tls_free(s->ctx);
535+                        free(s);
536+                        return NULL;
537+                }
538+                tls_config_free(cfg);
539+
540+                if (tls_connect_socket(s->ctx, fd, host) < 0) {
541+                        weprintf("tls_connect_socket: %s\n", tls_error(s->ctx));
542+                        tls_free(s->ctx);
543+                        free(s);
544+                        return NULL;
545+                }
546+        }
547 #elif FEATURE_USE_BEARSSL
548-	{
549-		signal(SIGPIPE, SIG_IGN);
550-
551-		if (check_cert) {
552-			static int ca_loaded = 0;
553-			if (!ca_loaded) {
554-				load_ca_certs();
555-				ca_loaded = 1;
556-			}
557-			br_ssl_client_init_full(&s->sc, &s->my_x509.minimal, tas, tas_num);
558-		} else {
559-			br_ssl_client_init_full(&s->sc, &s->my_x509.minimal, NULL, 0);
560-			s->my_x509.vtable = &my_x509_vtable;
561-			br_ssl_engine_set_x509(&s->sc.eng, &s->my_x509.vtable);
562-		}
563-
564-		br_ssl_engine_set_buffer(&s->sc.eng, s->iobuf, sizeof(s->iobuf), 1);
565-		br_ssl_client_reset(&s->sc, host, 0);
566-		br_sslio_init(&s->ioc, &s->sc.eng, sock_read, &s->fd, sock_write, &s->fd);
567-
568-		if (br_sslio_flush(&s->ioc) < 0) {
569-			weprintf("TLS handshake failed with %s\n", host);
570-			free(s);
571-			return NULL;
572-		}
573-	}
574+        {
575+                signal(SIGPIPE, SIG_IGN);
576+
577+                if (check_cert) {
578+                        static int ca_loaded = 0;
579+                        if (!ca_loaded) {
580+                                load_ca_certs();
581+                                ca_loaded = 1;
582+                        }
583+                        br_ssl_client_init_full(&s->sc, &s->my_x509.minimal, tas, tas_num);
584+                } else {
585+                        br_ssl_client_init_full(&s->sc, &s->my_x509.minimal, NULL, 0);
586+                        s->my_x509.vtable = &my_x509_vtable;
587+                        br_ssl_engine_set_x509(&s->sc.eng, &s->my_x509.vtable);
588+                }
589+
590+                br_ssl_engine_set_buffer(&s->sc.eng, s->iobuf, sizeof(s->iobuf), 1);
591+                br_ssl_client_reset(&s->sc, host, 0);
592+                br_sslio_init(&s->ioc, &s->sc.eng, sock_read, &s->fd, sock_write, &s->fd);
593+
594+                if (br_sslio_flush(&s->ioc) < 0) {
595+                        weprintf("TLS handshake failed with %s\n", host);
596+                        free(s);
597+                        return NULL;
598+                }
599+        }
600 #else
601-	weprintf("TLS not supported, compile with FEATURE_USE_LIBRESSL or FEATURE_USE_BEARSSL\n");
602-	free(s);
603-	return NULL;
604+        weprintf("TLS not supported, compile with FEATURE_USE_LIBRESSL or FEATURE_USE_BEARSSL\n");
605+        free(s);
606+        return NULL;
607 #endif
608 
609-	return s;
610+        return s;
611 }
612 
613 ssize_t
614 tls_read(struct TlsSocket *s, void *buf, size_t len)
615 {
616-	if (!s->is_tls) {
617-		for (;;) {
618-			ssize_t r = read(s->fd, buf, len);
619-			if (r < 0 && errno == EINTR)
620-				continue;
621-			return r;
622-		}
623-	}
624+        if (!s->is_tls) {
625+                for (;;) {
626+                        ssize_t r = read(s->fd, buf, len);
627+                        if (r < 0 && errno == EINTR)
628+                                continue;
629+                        return r;
630+                }
631+        }
632 #if FEATURE_USE_LIBRESSL
633-	for (;;) {
634-		ssize_t r = tls_read(s->ctx, buf, len);
635-		if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT)
636-			continue;
637-		return r;
638-	}
639+        for (;;) {
640+                ssize_t r = tls_read(s->ctx, buf, len);
641+                if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT)
642+                        continue;
643+                return r;
644+        }
645 #elif FEATURE_USE_BEARSSL
646-	return br_sslio_read(&s->ioc, buf, len);
647+        return br_sslio_read(&s->ioc, buf, len);
648 #else
649-	return -1;
650+        return -1;
651 #endif
652 }
653 
654 ssize_t
655 tls_write(struct TlsSocket *s, const void *buf, size_t len)
656 {
657-	if (!s->is_tls) {
658-		for (;;) {
659-			ssize_t r = write(s->fd, buf, len);
660-			if (r < 0 && errno == EINTR)
661-				continue;
662-			return r;
663-		}
664-	}
665+        if (!s->is_tls) {
666+                for (;;) {
667+                        ssize_t r = write(s->fd, buf, len);
668+                        if (r < 0 && errno == EINTR)
669+                                continue;
670+                        return r;
671+                }
672+        }
673 #if FEATURE_USE_LIBRESSL
674-	for (;;) {
675-		ssize_t r = tls_write(s->ctx, buf, len);
676-		if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT)
677-			continue;
678-		return r;
679-	}
680+        for (;;) {
681+                ssize_t r = tls_write(s->ctx, buf, len);
682+                if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT)
683+                        continue;
684+                return r;
685+        }
686 #elif FEATURE_USE_BEARSSL
687-	{
688-		int r = br_sslio_write_all(&s->ioc, buf, len);
689-		if (r < 0)
690-			return -1;
691-		if (br_sslio_flush(&s->ioc) < 0)
692-			return -1;
693-		return len;
694-	}
695+        {
696+                int r = br_sslio_write_all(&s->ioc, buf, len);
697+                if (r < 0)
698+                        return -1;
699+                if (br_sslio_flush(&s->ioc) < 0)
700+                        return -1;
701+                return len;
702+        }
703 #else
704-	return -1;
705+        return -1;
706 #endif
707 }
708 
709 void
710 tls_close(struct TlsSocket *s, int close_fd)
711 {
712-	if (s->is_tls) {
713+        if (s->is_tls) {
714 #if FEATURE_USE_LIBRESSL
715-		tls_close(s->ctx);
716-		tls_free(s->ctx);
717+                tls_close(s->ctx);
718+                tls_free(s->ctx);
719 #elif FEATURE_USE_BEARSSL
720-		br_sslio_close(&s->ioc);
721+                br_sslio_close(&s->ioc);
722 #endif
723-	}
724-	if (close_fd)
725-		close(s->fd);
726-	free(s);
727+        }
728+        if (close_fd)
729+                close(s->fd);
730+        free(s);
731 }
+66, -65
  1@@ -11,88 +11,89 @@
  2 #include <string.h>
  3 #include <unistd.h>
  4 
  5+#include "../paths.h"
  6 #include "../util.h"
  7 
  8 void
  9 devtotty(int dev, int *tty_maj, int *tty_min)
 10 {
 11-	*tty_maj = (dev >> 8) & 0xfff;
 12-	*tty_min = (dev & 0xff) | ((dev >> 12) & 0xfff00);
 13+        *tty_maj = (dev >> 8) & 0xfff;
 14+        *tty_min = (dev & 0xff) | ((dev >> 12) & 0xfff00);
 15 }
 16 
 17 int
 18 ttytostr(int tty_maj, int tty_min, char *str, size_t n)
 19 {
 20-	struct stat sb;
 21-	struct dirent *dp;
 22-	DIR *dirp;
 23-	char path[PATH_MAX];
 24-	int fd;
 25-	int r = 0;
 26+        struct stat sb;
 27+        struct dirent *dp;
 28+        DIR *dirp;
 29+        char path[PATH_MAX];
 30+        int fd;
 31+        int r = 0;
 32 
 33-	switch (tty_maj) {
 34-	case 136:
 35-		snprintf(str, n, "pts/%d", tty_min);
 36-		return 0;
 37-	case 4:
 38-		snprintf(str, n, "tty%d", tty_min);
 39-		return 0;
 40-	default:
 41-		str[0] = '?';
 42-		str[1] = '\0';
 43-		break;
 44-	}
 45+        switch (tty_maj) {
 46+        case 136:
 47+                snprintf(str, n, "pts/%d", tty_min);
 48+                return 0;
 49+        case 4:
 50+                snprintf(str, n, "tty%d", tty_min);
 51+                return 0;
 52+        default:
 53+                str[0] = '?';
 54+                str[1] = '\0';
 55+                break;
 56+        }
 57 
 58-	dirp = opendir("/dev");
 59-	if (!dirp) {
 60-		weprintf("opendir /dev:");
 61-		return -1;
 62-	}
 63+        dirp = opendir("/dev");
 64+        if (!dirp) {
 65+                weprintf("opendir /dev:");
 66+                return -1;
 67+        }
 68 
 69-	while ((dp = readdir(dirp))) {
 70-		if (!strcmp(dp->d_name, ".") ||
 71-		    !strcmp(dp->d_name, ".."))
 72-			continue;
 73+        while ((dp = readdir(dirp))) {
 74+                if (!strcmp(dp->d_name, ".") ||
 75+                    !strcmp(dp->d_name, ".."))
 76+                        continue;
 77 
 78-		if (strlcpy(path, "/dev/", sizeof(path)) >= sizeof(path)) {
 79-			weprintf("path too long\n");
 80-			r = -1;
 81-			goto err0;
 82-		}
 83-		if (strlcat(path, dp->d_name, sizeof(path)) >= sizeof(path)) {
 84-			weprintf("path too long\n");
 85-			r = -1;
 86-			goto err0;
 87-		}
 88+                if (strlcpy(path, ARUU_PATH_DEV "/", sizeof(path)) >= sizeof(path)) {
 89+                        weprintf("path too long\n");
 90+                        r = -1;
 91+                        goto err0;
 92+                }
 93+                if (strlcat(path, dp->d_name, sizeof(path)) >= sizeof(path)) {
 94+                        weprintf("path too long\n");
 95+                        r = -1;
 96+                        goto err0;
 97+                }
 98 
 99-		if (stat(path, &sb) < 0) {
100-			weprintf("stat %s:", path);
101-			r = -1;
102-			goto err0;
103-		}
104+                if (stat(path, &sb) < 0) {
105+                        weprintf("stat %s:", path);
106+                        r = -1;
107+                        goto err0;
108+                }
109 
110-		if ((int)major(sb.st_rdev) == tty_maj &&
111-		    (int)minor(sb.st_rdev) == tty_min) {
112-			fd = open(path, O_RDONLY | O_NONBLOCK);
113-			if (fd < 0)
114-				continue;
115-			if (isatty(fd)) {
116-				strlcpy(str, dp->d_name, n);
117-				close(fd);
118-				break;
119-			} else {
120-				close(fd);
121-				r = -1;
122-				goto err0;
123-			}
124-		}
125-	}
126+                if ((int)major(sb.st_rdev) == tty_maj &&
127+                    (int)minor(sb.st_rdev) == tty_min) {
128+                        fd = open(path, O_RDONLY | O_NONBLOCK);
129+                        if (fd < 0)
130+                                continue;
131+                        if (isatty(fd)) {
132+                                strlcpy(str, dp->d_name, n);
133+                                close(fd);
134+                                break;
135+                        } else {
136+                                close(fd);
137+                                r = -1;
138+                                goto err0;
139+                        }
140+                }
141+        }
142 
143 err0:
144-	if (closedir(dirp) < 0) {
145-		weprintf("closedir /dev:");
146-		r = -1;
147-	}
148+        if (closedir(dirp) < 0) {
149+                weprintf("closedir /dev:");
150+                r = -1;
151+        }
152 
153-	return r;
154+        return r;
155 }
+343, -0
  1@@ -0,0 +1,343 @@
  2+/* See LICENSE file for copyright and license details. */
  3+#include "../config.h"
  4+#include "../wexec.h"
  5+#include "../paths.h"
  6+#include "../util.h"
  7+
  8+#include <errno.h>
  9+#include <signal.h>
 10+#include <stdlib.h>
 11+#include <string.h>
 12+#include <sys/wait.h>
 13+#include <unistd.h>
 14+
 15+#define MAX_BUILTINS 128
 16+#define MAX_POPEN 32
 17+
 18+struct builtin {
 19+        const char *name;
 20+        wexec_fn fn;
 21+};
 22+
 23+static struct builtin builtins[MAX_BUILTINS];
 24+static int nbuiltins;
 25+
 26+struct popen_entry {
 27+        FILE *fp;
 28+        pid_t pid;
 29+};
 30+
 31+static struct popen_entry popen_tab[MAX_POPEN];
 32+static int npopen;
 33+
 34+int
 35+wpopen_track(FILE *fp, pid_t pid)
 36+{
 37+        if (npopen >= MAX_POPEN)
 38+                return -1;
 39+        popen_tab[npopen].fp = fp;
 40+        popen_tab[npopen].pid = pid;
 41+        npopen++;
 42+        return 0;
 43+}
 44+
 45+pid_t
 46+wpopen_untrack(FILE *fp)
 47+{
 48+        int i;
 49+        pid_t pid = -1;
 50+        for (i = 0; i < npopen; i++) {
 51+                if (popen_tab[i].fp == fp) {
 52+                        pid = popen_tab[i].pid;
 53+                        popen_tab[i] = popen_tab[npopen - 1];
 54+                        npopen--;
 55+                        break;
 56+                }
 57+        }
 58+        return pid;
 59+}
 60+
 61+int
 62+wexec_register(const char *name, wexec_fn fn)
 63+{
 64+        int i;
 65+        for (i = 0; i < nbuiltins; i++) {
 66+                if (strcmp(builtins[i].name, name) == 0)
 67+                        return -1;
 68+        }
 69+        if (nbuiltins >= MAX_BUILTINS)
 70+                return -1;
 71+        builtins[nbuiltins].name = name;
 72+        builtins[nbuiltins].fn = fn;
 73+        nbuiltins++;
 74+        return 0;
 75+}
 76+
 77+int
 78+wexec_is_builtin(const char *name)
 79+{
 80+        int i;
 81+        for (i = 0; i < nbuiltins; i++) {
 82+                if (strcmp(builtins[i].name, name) == 0)
 83+                        return 1;
 84+        }
 85+        return 0;
 86+}
 87+
 88+#if FEATURE_INPROC_EXEC
 89+static int
 90+call_builtin(const char *name, char *const *argv)
 91+{
 92+        int i, argc;
 93+        char **p;
 94+
 95+        argc = 0;
 96+        for (p = (char **)argv; *p; p++)
 97+                argc++;
 98+        for (i = 0; i < nbuiltins; i++) {
 99+                if (strcmp(builtins[i].name, name) == 0) {
100+                        fflush(stdout);
101+                        fflush(stderr);
102+                        return builtins[i].fn(argc, (char **)argv);
103+                }
104+        }
105+        return -1;
106+}
107+#endif
108+
109+static int
110+fork_exec(const char *path, char *const *argv, int use_path)
111+{
112+        pid_t pid;
113+        int st;
114+
115+        pid = fork();
116+        if (pid < 0) {
117+                weprintf("fork:");
118+                return -1;
119+        }
120+        if (pid == 0) {
121+                if (use_path)
122+                        execvp(path, argv);
123+                else
124+                        execv(path, argv);
125+                _exit(127);
126+        }
127+        if (waitpid(pid, &st, 0) < 0) {
128+                weprintf("waitpid:");
129+                return -1;
130+        }
131+        if (WIFEXITED(st))
132+                return WEXITSTATUS(st);
133+        if (WIFSIGNALED(st))
134+                return 128 + WTERMSIG(st);
135+        return -1;
136+}
137+
138+int
139+wexecvp(const char *name, char *const *argv)
140+{
141+#if FEATURE_INPROC_EXEC
142+        if (wexec_is_builtin(name)) {
143+                fflush(stdout);
144+                fflush(stderr);
145+                return call_builtin(name, argv);
146+        }
147+#endif
148+        return fork_exec(name, argv, 1);
149+}
150+
151+int
152+wexecv(const char *path, char *const *argv)
153+{
154+#if FEATURE_INPROC_EXEC
155+        {
156+                const char *base = strrchr(path, '/');
157+                base = base ? base + 1 : path;
158+                if (wexec_is_builtin(base)) {
159+                        fflush(stdout);
160+                        fflush(stderr);
161+                        return call_builtin(base, argv);
162+                }
163+        }
164+#endif
165+        return fork_exec(path, argv, 0);
166+}
167+
168+FILE *
169+wpopen(const char *name, char *const *argv, const char *mode)
170+{
171+        int pfd[2];
172+        pid_t pid;
173+        int parent_end, child_end;
174+        char *sh_argv[4];
175+
176+        if (pipe(pfd) < 0) {
177+                weprintf("pipe:");
178+                return NULL;
179+        }
180+
181+        if (*mode == 'r') {
182+                parent_end = pfd[0];
183+                child_end = pfd[1];
184+        } else {
185+                parent_end = pfd[1];
186+                child_end = pfd[0];
187+        }
188+
189+        pid = fork();
190+        if (pid < 0) {
191+                weprintf("fork:");
192+                close(pfd[0]);
193+                close(pfd[1]);
194+                return NULL;
195+        }
196+
197+        if (pid == 0) {
198+                close(parent_end);
199+                if (child_end != (*mode == 'r' ? STDOUT_FILENO : STDIN_FILENO)) {
200+                        dup2(child_end, *mode == 'r' ? STDOUT_FILENO : STDIN_FILENO);
201+                        close(child_end);
202+                }
203+                if (argv) {
204+#if FEATURE_INPROC_EXEC
205+                        if (wexec_is_builtin(name)) {
206+                                int argc;
207+                                char **p;
208+                                argc = 0;
209+                                for (p = (char **)argv; *p; p++)
210+                                        argc++;
211+                                call_builtin(name, argv);
212+                                fflush(stdout);
213+                                fflush(stderr);
214+                                _exit(0);
215+                        }
216+#endif
217+                        execvp(name, argv);
218+                        _exit(127);
219+                } else {
220+                        sh_argv[0] = "sh";
221+                        sh_argv[1] = "-c";
222+                        sh_argv[2] = (char *)name;
223+                        sh_argv[3] = NULL;
224+#if FEATURE_INPROC_EXEC
225+                        if (wexec_is_builtin("sh")) {
226+                                call_builtin("sh", sh_argv);
227+                                fflush(stdout);
228+                                fflush(stderr);
229+                                _exit(0);
230+                        }
231+#endif
232+                        execvp("sh", sh_argv);
233+                        _exit(127);
234+                }
235+        }
236+
237+        close(child_end);
238+        {
239+                FILE *fp = fdopen(parent_end, mode);
240+                if (!fp) {
241+                        weprintf("fdopen:");
242+                        close(parent_end);
243+                        kill(pid, SIGTERM);
244+                        waitpid(pid, NULL, 0);
245+                        return NULL;
246+                }
247+                if (wpopen_track(fp, pid) < 0) {
248+                        fclose(fp);
249+                        kill(pid, SIGTERM);
250+                        waitpid(pid, NULL, 0);
251+                        return NULL;
252+                }
253+                return fp;
254+        }
255+}
256+
257+int
258+wpclose(FILE *fp)
259+{
260+        int st;
261+        pid_t pid;
262+
263+        pid = wpopen_untrack(fp);
264+        if (fclose(fp) == EOF)
265+                weprintf("fclose:");
266+        if (pid < 0)
267+                return -1;
268+        if (waitpid(pid, &st, 0) < 0) {
269+                weprintf("waitpid:");
270+                return -1;
271+        }
272+        if (WIFEXITED(st))
273+                return WEXITSTATUS(st);
274+        if (WIFSIGNALED(st))
275+                return 128 + WTERMSIG(st);
276+        return -1;
277+}
278+
279+int
280+wsystem(const char *cmd)
281+{
282+#if FEATURE_INPROC_EXEC
283+        if (wexec_is_builtin("sh")) {
284+                char *sh_argv[4];
285+                sh_argv[0] = "sh";
286+                sh_argv[1] = "-c";
287+                sh_argv[2] = (char *)cmd;
288+                sh_argv[3] = NULL;
289+                return wexecvp("sh", sh_argv);
290+        }
291+#endif
292+        {
293+                char *sh_argv[4];
294+                int ret;
295+                sh_argv[0] = "sh";
296+                sh_argv[1] = "-c";
297+                sh_argv[2] = (char *)cmd;
298+                sh_argv[3] = NULL;
299+                ret = fork_exec("sh", sh_argv, 1);
300+                return ret;
301+        }
302+}
303+
304+void
305+wexecvp_self(const char *name, char *const *argv)
306+{
307+#if FEATURE_INPROC_EXEC
308+        if (wexec_is_builtin(name)) {
309+                int ret;
310+                fflush(stdout);
311+                fflush(stderr);
312+                ret = call_builtin(name, argv);
313+                fflush(stdout);
314+                fflush(stderr);
315+                exit(ret);
316+        }
317+#endif
318+        execvp(name, argv);
319+        weprintf("execvp %s:", name);
320+        exit((errno == ENOENT) ? 127 : 126);
321+}
322+
323+void
324+wexecv_self(const char *path, char *const *argv)
325+{
326+#if FEATURE_INPROC_EXEC
327+        {
328+                const char *base = strrchr(path, '/');
329+                base = base ? base + 1 : path;
330+                if (wexec_is_builtin(base)) {
331+                        int ret;
332+                        fflush(stdout);
333+                        fflush(stderr);
334+                        ret = call_builtin(base, argv);
335+                        fflush(stdout);
336+                        fflush(stderr);
337+                        exit(ret);
338+                }
339+        }
340+#endif
341+        execv(path, argv);
342+        weprintf("execv %s:", path);
343+        exit((errno == ENOENT) ? 127 : 126);
344+}
+23, -2
 1@@ -1,4 +1,25 @@
 2 /* See LICENSE file for copyright and license details. */
 3-/* passwd.c */
 4-int pw_check(const struct passwd *, const char *);
 5+#ifndef ARUU_PASSWD_H
 6+#define ARUU_PASSWD_H
 7+
 8+#include <pwd.h>
 9+#include <sys/types.h>
10+
11+struct pwdb_entry {
12+        char *name;
13+        char *hash;
14+        uid_t uid;
15+        gid_t gid;
16+};
17+
18 int pw_init(void);
19+int pw_check(const struct passwd *pw, const char *pass);
20+int pwdb_lookup(struct pwdb_entry *ent, const char *name);
21+
22+#define PW_SALT_MAX 64
23+int pw_gensalt(char *salt, size_t salt_sz);
24+int pw_gensalt_cipher(char *salt, size_t salt_sz, const char *prefix,
25+                      size_t rand_len);
26+int pwdb_update(const char *name, const char *newhash);
27+
28+#endif
+96, -0
 1@@ -0,0 +1,96 @@
 2+/* See LICENSE file for copyright and license details. */
 3+#ifndef ARUU_PATHS_H
 4+#define ARUU_PATHS_H
 5+
 6+/*
 7+ * portable paths. override at compile time for non-FHS systems:
 8+ *   -DARUU_PATH_ETC="/config"
 9+ *
10+ * OS-specific paths (procfs, sysfs) are prefixed ARUU_LINUX_PATH_*
11+ * and only defined under __linux__. a util that reads /proc/modules
12+ * will fail to compile on BSD because ARUU_LINUX_PATH_PROC is not
13+ * defined there. this is intentional: the BSD code path must use
14+ * a different mechanism (sysctl, getmntinfo, etc)
15+ */
16+
17+#ifndef ARUU_PATH_ETC
18+#define ARUU_PATH_ETC "/etc"
19+#endif
20+
21+#ifndef ARUU_PATH_VAR
22+#define ARUU_PATH_VAR "/var"
23+#endif
24+
25+#ifndef ARUU_PATH_DEV
26+#define ARUU_PATH_DEV "/dev"
27+#endif
28+
29+#ifndef ARUU_PATH_RUN
30+#define ARUU_PATH_RUN "/run"
31+#endif
32+
33+#ifndef ARUU_PATH_TMP
34+#define ARUU_PATH_TMP "/tmp"
35+#endif
36+
37+#ifndef ARUU_PATH_BIN
38+#define ARUU_PATH_BIN "/bin"
39+#endif
40+
41+#ifndef ARUU_PATH_SBIN
42+#define ARUU_PATH_SBIN "/sbin"
43+#endif
44+
45+#ifndef ARUU_PATH_USR_BIN
46+#define ARUU_PATH_USR_BIN "/usr/bin"
47+#endif
48+
49+#ifndef ARUU_PATH_USR_SBIN
50+#define ARUU_PATH_USR_SBIN "/usr/sbin"
51+#endif
52+
53+#define ARUU_PATH_PASSWD         ARUU_PATH_ETC "/passwd"
54+#define ARUU_PATH_SHADOW         ARUU_PATH_ETC "/shadow"
55+#define ARUU_PATH_GROUP          ARUU_PATH_ETC "/group"
56+#define ARUU_PATH_DEVNULL        ARUU_PATH_DEV "/null"
57+#define ARUU_PATH_DEVURANDOM     ARUU_PATH_DEV "/urandom"
58+#define ARUU_PATH_DEVRANDOM      ARUU_PATH_DEV "/random"
59+#define ARUU_PATH_DEVTTY         ARUU_PATH_DEV "/tty"
60+#define ARUU_PATH_DEVCONSOLE     ARUU_PATH_DEV "/console"
61+#define ARUU_PATH_UTMP           ARUU_PATH_RUN "/utmp"
62+#define ARUU_PATH_WTMP           ARUU_PATH_VAR "/log/wtmp"
63+#define ARUU_PATH_BTMP           ARUU_PATH_VAR "/log/btmp"
64+#define ARUU_PATH_LASTLOG        ARUU_PATH_VAR "/log/lastlog"
65+#define ARUU_PATH_BSHELL         ARUU_PATH_BIN "/sh"
66+#define ARUU_PATH_STDPATH        ARUU_PATH_BIN ":/usr/bin"
67+#define ARUU_PATH_DEFPATH        ARUU_PATH_BIN ":/usr/bin"
68+
69+#if defined(__linux__)
70+#define ARUU_LINUX_PATH_PROC     "/proc"
71+#define ARUU_LINUX_PATH_SYS      "/sys"
72+#define ARUU_LINUX_PATH_PROC_MOUNTS     ARUU_LINUX_PATH_PROC "/mounts"
73+#define ARUU_LINUX_PATH_PROC_PARTITIONS ARUU_LINUX_PATH_PROC "/partitions"
74+#define ARUU_LINUX_PATH_PROC_MEMINFO    ARUU_LINUX_PATH_PROC "/meminfo"
75+#define ARUU_LINUX_PATH_PROC_LOADAVG    ARUU_LINUX_PATH_PROC "/loadavg"
76+#define ARUU_LINUX_PATH_PROC_CMDLINE    ARUU_LINUX_PATH_PROC "/cmdline"
77+#define ARUU_LINUX_PATH_PROC_VERSION    ARUU_LINUX_PATH_PROC "/version"
78+#define ARUU_LINUX_PATH_PROC_MODULES    ARUU_LINUX_PATH_PROC "/modules"
79+#define ARUU_LINUX_PATH_PROC_SYS        ARUU_LINUX_PATH_PROC "/sys"
80+#define ARUU_LINUX_PATH_SYS_MODULE      ARUU_LINUX_PATH_SYS "/module"
81+#define ARUU_LINUX_PATH_SYS_BLOCK       ARUU_LINUX_PATH_SYS "/block"
82+#define ARUU_LINUX_PATH_SYS_CLASS_NET   ARUU_LINUX_PATH_SYS "/class/net"
83+#define ARUU_LINUX_PATH_SYS_KERNEL      ARUU_LINUX_PATH_SYS "/kernel"
84+#define ARUU_LINUX_PATH_SYS_BUS_USB     ARUU_LINUX_PATH_SYS "/bus/usb/devices"
85+#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
86+/* BSD systems do not have procfs or sysfs. utils that need this data
87+ * must use sysctl(3), getmntinfo(3), or kvm(3) instead */
88+#else
89+#error "paths.h: unsupported platform. define ARUU_LINUX_PATH_* or ARUU_BSD_PATH_* manually"
90+#endif
91+
92+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
93+#define ARUU_BSD_PATH_MASTER_PASSWD ARUU_PATH_ETC "/master.passwd"
94+#define ARUU_BSD_PATH_PWD_MKDB      ARUU_PATH_USR_SBIN "/pwd_mkdb"
95+#endif
96+
97+#endif
+33, -33
 1@@ -116,45 +116,45 @@ int ttytostr(int, int, char *, size_t);
 2 #endif
 3 
 4 struct NetStats {
 5-	unsigned long long rx_bytes;
 6-	unsigned long long rx_packets;
 7-	unsigned long long rx_errs;
 8-	unsigned long long rx_drop;
 9-	unsigned long long tx_bytes;
10-	unsigned long long tx_packets;
11-	unsigned long long tx_errs;
12-	unsigned long long tx_drop;
13+        unsigned long long rx_bytes;
14+        unsigned long long rx_packets;
15+        unsigned long long rx_errs;
16+        unsigned long long rx_drop;
17+        unsigned long long tx_bytes;
18+        unsigned long long tx_packets;
19+        unsigned long long tx_errs;
20+        unsigned long long tx_drop;
21 };
22 
23 struct NetInterface {
24-	char name[IFNAMSIZ];
25-	unsigned int flags;
26-	int mtu;
27-	int metric;
28-	unsigned char mac[6];
29-	int has_mac;
30-
31-	/* ipv4 addresses */
32-	struct sockaddr_in ipv4_addr;
33-	int has_ipv4;
34-	struct sockaddr_in ipv4_mask;
35-	struct sockaddr_in ipv4_brd;
36-
37-	/* ipv6 addresses */
38-	struct sockaddr_in6 ipv6_addr;
39-	int has_ipv6;
40-	unsigned int ipv6_scope;
41-	unsigned int ipv6_prefix;
42+        char name[IFNAMSIZ];
43+        unsigned int flags;
44+        int mtu;
45+        int metric;
46+        unsigned char mac[6];
47+        int has_mac;
48+
49+        /* ipv4 addresses */
50+        struct sockaddr_in ipv4_addr;
51+        int has_ipv4;
52+        struct sockaddr_in ipv4_mask;
53+        struct sockaddr_in ipv4_brd;
54+
55+        /* ipv6 addresses */
56+        struct sockaddr_in6 ipv6_addr;
57+        int has_ipv6;
58+        unsigned int ipv6_scope;
59+        unsigned int ipv6_prefix;
60 };
61 
62 struct MemInfo {
63-	unsigned long long total;
64-	unsigned long long free;
65-	unsigned long long shared;
66-	unsigned long long buffers;
67-	unsigned long long cached;
68-	unsigned long long totalswap;
69-	unsigned long long freeswap;
70+        unsigned long long total;
71+        unsigned long long free;
72+        unsigned long long shared;
73+        unsigned long long buffers;
74+        unsigned long long cached;
75+        unsigned long long totalswap;
76+        unsigned long long freeswap;
77 };
78 
79 int net_get_interfaces(struct NetInterface **, int *);
+27, -0
 1@@ -0,0 +1,27 @@
 2+/* See LICENSE file for copyright and license details. */
 3+#ifndef ARUU_WEXEC_H
 4+#define ARUU_WEXEC_H
 5+
 6+#include <stdio.h>
 7+#include <sys/types.h>
 8+
 9+typedef int (*wexec_fn)(int argc, char **argv);
10+
11+int wexec_register(const char *name, wexec_fn fn);
12+int wexec_is_builtin(const char *name);
13+
14+int wexecvp(const char *name, char *const *argv);
15+int wexecv(const char *path, char *const *argv);
16+
17+FILE *wpopen(const char *name, char *const *argv, const char *mode);
18+int wpclose(FILE *fp);
19+
20+int wsystem(const char *cmd);
21+
22+void wexecvp_self(const char *name, char *const *argv);
23+void wexecv_self(const char *path, char *const *argv);
24+
25+int wpopen_track(FILE *fp, pid_t pid);
26+pid_t wpopen_untrack(FILE *fp);
27+
28+#endif