diff options
author | wiz <wiz@pkgsrc.org> | 2004-12-17 18:53:54 +0000 |
---|---|---|
committer | wiz <wiz@pkgsrc.org> | 2004-12-17 18:53:54 +0000 |
commit | 8bda91c73b5495b119f5ddba1e5cb7e2020d60a9 (patch) | |
tree | fb69e428def0a23325bb986fd4473e81aa5926c8 | |
parent | 076834489ad28d7aecd1ed06eec22743633b73c0 (diff) | |
download | pkgsrc-8bda91c73b5495b119f5ddba1e5cb7e2020d60a9.tar.gz |
Fix insecure temporary file handling in groffer. Bump PKGREVISION.
-rw-r--r-- | textproc/groff/Makefile | 4 | ||||
-rw-r--r-- | textproc/groff/distinfo | 3 | ||||
-rw-r--r-- | textproc/groff/patches/patch-ad | 723 |
3 files changed, 727 insertions, 3 deletions
diff --git a/textproc/groff/Makefile b/textproc/groff/Makefile index 81056f0a7ed..d77d2b7e726 100644 --- a/textproc/groff/Makefile +++ b/textproc/groff/Makefile @@ -1,8 +1,8 @@ -# $NetBSD: Makefile,v 1.20 2004/11/13 22:04:53 jlam Exp $ +# $NetBSD: Makefile,v 1.21 2004/12/17 18:53:54 wiz Exp $ # DISTNAME= groff-1.19.1 -PKGREVISION= 1 +PKGREVISION= 2 CATEGORIES= textproc MASTER_SITES= ${MASTER_SITE_GNU:=groff/} diff --git a/textproc/groff/distinfo b/textproc/groff/distinfo index 149ae38b0e5..887fe811f3f 100644 --- a/textproc/groff/distinfo +++ b/textproc/groff/distinfo @@ -1,10 +1,11 @@ -$NetBSD: distinfo,v 1.8 2004/08/02 16:14:24 wiz Exp $ +$NetBSD: distinfo,v 1.9 2004/12/17 18:53:55 wiz Exp $ SHA1 (groff-1.19.1.tar.gz) = 82ba1b29b01c36bf41149ce8813cea712e3e6cbf Size (groff-1.19.1.tar.gz) = 2629152 bytes SHA1 (patch-aa) = d0d1f387fefbb376eeec8ba824365cab2c1667fd SHA1 (patch-ab) = 3c50a8b758cf3ad9d31e449864bf07c09b396b92 SHA1 (patch-ac) = 38f75d8261ca39aff8a37771a283c99ad39142bd +SHA1 (patch-ad) = 3480c6ebf29aa986cffcf9bba705153e5335224d SHA1 (patch-ae) = 18d553fe99ca6915d42de5f6edf74fc56e2fc650 SHA1 (patch-ba) = cdafeefbde9490d0ed599a118fd34c06afac0f96 SHA1 (patch-bb) = ddd9ef807a09eaaf7b09a3c05be3443945c67379 diff --git a/textproc/groff/patches/patch-ad b/textproc/groff/patches/patch-ad new file mode 100644 index 00000000000..ff30832dce3 --- /dev/null +++ b/textproc/groff/patches/patch-ad @@ -0,0 +1,723 @@ +$NetBSD: patch-ad,v 1.3 2004/12/17 18:53:55 wiz Exp $ + +--- contrib/groffer/groffer.sh.orig 2004-05-04 07:03:01.000000000 +0200 ++++ contrib/groffer/groffer.sh +@@ -25,18 +25,21 @@ + # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + _PROGRAM_NAME='groffer'; +-_PROGRAM_VERSION='0.9.7'; +-_LAST_UPDATE='30 Apr 2004'; ++_PROGRAM_VERSION='0.9.12'; ++_LAST_UPDATE='15 November 2004'; + + + ######################################################################## +-# Determine the shell under which to run this script; +-# if `ash' is available restart the script using `ash'; +-# otherwise just go on. ++# Determine the shell under which to run this script from the command ++# line arguments or $GROFF_OPT; if none is specified, just go on with ++# the starting shell. + +-if test "${_groffer_run}" = ''; then ++if test _"${_groffer_run}"_ = __; then + # only reached during the first run of the script + ++ export _groffer_run; # counter for the runs of groffer ++ _groffer_run='first'; ++ + export _PROGRAM_NAME; + export _PROGRAM_VERSION; + export _LAST_UPDATE; +@@ -44,9 +47,9 @@ if test "${_groffer_run}" = ''; then + export GROFFER_OPT; # option environment for groffer + export _GROFFER_SH; # file name of this shell script + export _OUTPUT_FILE_NAME; # output generated, see main_set_res..() +- export _groffer_run; # counter for the runs of groffer + +- _groffer_run='first'; ++ export _CONFFILES; # configuration files ++ _CONFFILES="/etc/groff/groffer.conf ${HOME}/.groff/groffer.conf"; + + case "$0" in + *${_PROGRAM_NAME}*) +@@ -103,18 +106,33 @@ if test "${_groffer_run}" = ''; then + # + _test_on_shell() + { +- if test "$#" -le 0 || test "$1" = ''; then ++ if test "$#" -le 0 || test _"$1"_ = __; then + return 1; + fi; + # do not quote $1 to allow arguments +- test "$($1 -c 's=ok; echo -n "$s"' 2>/dev/null)" = 'ok'; ++ test _"$($1 -c 's=ok; echo -n "$s"' 2>/dev/null)"_ = _ok_; + } + +- # do the shell determination ++ # do the shell determination from command line and $GROFFER_OPT + _shell="$(_get_opt_shell "$@")"; +- if test "${_shell}" = ''; then +- _shell='ash'; ++ ++ if test _"${_shell}"_ = __; then ++ # none found, so look at the `--shell' lines in configuration files ++ export f; ++ for f in ${_CONFFILES}; do ++ if test -f $f; then ++ _all="$(cat $f | sed -n -e '/^--shell[= ] *\([^ ]*\)$/s//\1/p')" ++ for s in ${_all}; do ++ _shell=$s; ++ done; ++ fi; ++ done; ++ unset f; ++ unset s; ++ unset _all; + fi; ++ ++ # restart the script with the last found $_shell, if it is a shell + if _test_on_shell "${_shell}"; then + _groffer_run='second'; + # do not quote $_shell to allow arguments +@@ -122,26 +140,17 @@ if test "${_groffer_run}" = ''; then + exit; + fi; + +- # clean-up of shell determination ++ _groffer_run='second'; + unset _shell; +- unset _GROFFER_SH; +- unset _groffer_run; +- _get_opt_shell() +- { +- return 0; +- } +- _test_on_shell() +- { +- return 0; +- } + + fi; # end of first run + +-if test "${_groffer_run}" != 'second'; ++if test _"${_groffer_run}"_ != _second_; + then + echo "$_groffer_run should be 'second' here." >&2 + exit 1 + fi; ++ + unset _groffer_run + + +@@ -241,9 +250,6 @@ return_no="func_pop; return ${_NO}"; + return_error="func_pop; return ${_ERROR}"; + + +-export _CONFFILES; +-_CONFFILES="/etc/groff/groffer.conf ${HOME}/.groff/groffer.conf"; +- + export _DEFAULT_MODES; + _DEFAULT_MODES='x,ps,tty'; + export _DEFAULT_RESOLUTION; +@@ -328,18 +334,18 @@ _OPTS_GROFFER_LONG_NA="'auto' 'debug' 'd + + _OPTS_GROFFER_LONG_ARG="\ + 'apropos' 'apropos-data' 'apropos-devel' 'apropos-progs' \ +-'default-modes' 'dvi-viewer' 'extension' 'fg' 'fn' 'font' \ ++'default-modes' 'device' 'dvi-viewer' 'extension' 'fg' 'fn' 'font' \ + 'foreground' 'html-viewer' 'mode' 'pdf-viewer' 'ps-viewer' 'shell' \ + 'tty-viewer' 'www-viewer' 'x-viewer' 'X-viewer'"; + + ##### groffer options inhereted from groff + + _OPTS_GROFF_SHORT_NA="'a' 'b' 'c' 'C' 'e' 'E' 'g' 'G' 'i' 'l' 'N' 'p' \ +-'R' 's' 'S' 't' 'U' 'V' 'z'"; ++'R' 's' 'S' 't' 'U' 'z'"; + _OPTS_GROFF_SHORT_ARG="'d' 'f' 'F' 'I' 'L' 'm' 'M' 'n' 'o' 'P' 'r' \ + 'w' 'W'"; +-_OPTS_GROFF_LONG_NA="'source'"; +-_OPTS_GROFF_LONG_ARG="'device' 'macro-file'"; ++_OPTS_GROFF_LONG_NA=""; ++_OPTS_GROFF_LONG_ARG=""; + + ##### groffer options inhereted from the X Window toolkit + +@@ -467,8 +473,7 @@ export _OPT_WHATIS; # print the one-lin + export _OPT_XRM; # specify X resource. + export _OPT_Z; # groff option -Z. + # _TMP_* temporary files +-export _TMP_DIR; # groff directory for temporary files +-export _TMP_DIR_SUB; # groffer directory for temporary files ++export _TMP_DIR; # groffer directory for temporary files + export _TMP_CAT; # stores concatenation of everything + export _TMP_STDIN; # stores stdin, if any + +@@ -490,7 +495,7 @@ test "a" = "a" || exit 1; + # Test of `echo' and the `$()' construct. + # + echo -n '' >/dev/null || exit "${_ERROR}"; +-if test "$(echo -n 'te' && echo -n '' && echo -n 'st')" != "test"; then ++if test _"$(echo -n 'te' && echo -n '' && echo -n 'st')"_ != _test_; then + exit "${_ERROR}"; + fi; + +@@ -527,7 +532,6 @@ _HAS_OPTS_POSIX=''; + + # _TMP_* temporary files + _TMP_DIR=''; +-_TMP_DIR_SUB=''; + _TMP_CAT=''; + _TMP_STDIN=''; + +@@ -631,7 +635,7 @@ reset; + # + landmark() + { +- if test "${_DEBUG_LM}" = 'yes'; then ++ if test _"${_DEBUG_LM}"_ = _yes_; then + echo ">>> $*" >&2; + fi; + } +@@ -647,8 +651,7 @@ landmark "1: debugging functions"; + clean_up() + { + if test -d "${_TMP_DIR}"; then +- rm -f "${_TMP_DIR}"/*; +- rmdir "${_TMP_DIR}"; ++ rm -f -r "${_TMP_DIR}"; + fi; + } + +@@ -709,7 +712,7 @@ error() + ;; + *) echo2 'groffer error: wrong number of arguments in error().'; ;; + esac; +- if test "${_DEBUG}" = 'yes'; then ++ if test _"${_DEBUG}"_ = _yes_; then + func_stack_dump; + fi; + clean_up; +@@ -803,7 +806,7 @@ func_check() + error \ + "${_fname}"'() needs '"${_comp} ${_nargs}"' argument'"${_s}"'.'; + fi; +- if test "${_DEBUG}" = 'yes'; then ++ if test _"${_DEBUG}"_ = _yes_; then + func_push "${_fname} $*"; + fi; + } +@@ -822,7 +825,7 @@ func_check() + # + func_pop() + { +- if test "${_DEBUG}" = 'yes'; then ++ if test _"${_DEBUG}"_ = _yes_; then + if test "$#" -ne 0; then + error 'func_pop() does not have arguments.'; + fi; +@@ -856,7 +859,7 @@ func_pop() + func_push() + { + local _element; +- if test "${_DEBUG}" = 'yes'; then ++ if test _"${_DEBUG}"_ = _yes_; then + if test "$#" -ne 1; then + error 'func_push() needs 1 argument.'; + fi; +@@ -869,7 +872,7 @@ func_push() + _element="$1"; + ;; + esac; +- if test "${_FUNC_STACK}" = ''; then ++ if test _"${_FUNC_STACK}"_ = __; then + _FUNC_STACK="${_element}"; + else + _FUNC_STACK="${_element}!${_FUNC_STACK}"; +@@ -889,7 +892,7 @@ func_stack_dump() + case "${_FUNC_STACK}" in + *!*) + _rest="${_FUNC_STACK}"; +- while test "${_rest}" != ''; do ++ while test _"${_rest}"_ != __; do + # get part before the first bang `!'. + diag "$(echo -n "${_rest}" | sed -e 's/!.*$//')"; + # delete part before and including the first bang `!'. +@@ -934,7 +937,7 @@ fi; + # Test of `unset'. + # + _test='test'; +-if unset _test >/dev/null 2>&1 && test "${_test}" = ''; then ++if unset _test >/dev/null 2>&1 && test _"${_test}"_ = __; then + true; + else + unset() +@@ -960,7 +963,7 @@ if _t_e_s_t_f_u_n_c_; then + else + local() + { +- if test "$1" != ''; then ++ if test _"$1"_ != __; then + error "overriding global variable \`$1' with local value."; + fi; + } +@@ -981,7 +984,7 @@ _t_e_s_t_f_u_n_c_() + } + + _t_e_s_t_f_u_n_c_; +-if test "${_global}" != 'inside' || test "${_clobber}" != 'outside'; ++if test _"${_global}"_ != _inside_ || test _"${_clobber}"_ != _outside_; + then + error "Cannot assign to global variables from within functions."; + fi; +@@ -993,9 +996,10 @@ unset _clobber; + ######################################################################## + # Test of function `sed'. + # +-if test "$(echo xTesTx \ ++ ++if test _"$(echo xTesTx \ + | sed -e 's/^.\([Tt]e*x*sTT*\).*$/\1/' \ +- | sed -e '\|T|s||t|g')" != 'test'; ++ | sed -e '\|T|s|T|t|g')"_ != _test_; + then + error 'Test of "sed" command failed.'; + fi; +@@ -1004,7 +1008,7 @@ fi; + ######################################################################## + # Test of function `cat'. + # +-if test "$(echo test | cat)" != "test"; then ++if test _"$(echo test | cat)"_ != _test_; then + error 'Test of "cat" command failed.'; + fi; + +@@ -1012,12 +1016,12 @@ fi; + ######################################################################## + # Test for compression. + # +-if test "$(echo 'test' | gzip -c -d -f - 2>/dev/null)" = 'test'; then ++if test _"$(echo 'test' | gzip -c -d -f - 2>/dev/null)"_ = _test_; then + _HAS_COMPRESSION='yes'; + if echo 'test' | bzip2 -c 2>/dev/null | bzip2 -t 2>/dev/null \ +- && test "$(echo 'test' | bzip2 -c 2>/dev/null \ +- | bzip2 -d -c 2>/dev/null)" \ +- = 'test'; then ++ && test _"$(echo 'test' | bzip2 -c 2>/dev/null \ ++ | bzip2 -d -c 2>/dev/null)"_ \ ++ = _test_; then + _HAS_BZIP='yes'; + else + _HAS_BZIP='no'; +@@ -1083,7 +1087,7 @@ base_name() + case "$f" in + */) + # delete all final slashes +- f="$(echo -n "$f" | sed -e '\|//*$|s|||')"; ++ f="$(echo -n "$f" | sed -e '\|.*|s|//*$||')"; + ;; + esac; + case "$f" in +@@ -1092,7 +1096,7 @@ base_name() + ;; + */*) + # delete everything before and including the last slash `/'. +- echo -n "$f" | sed -e '\|^.*//*\([^/]*\)$|s||\1|'; ++ echo -n "$f" | sed -e '\|.*|s|^.*//*\([^/]*\)$|\1|'; + ;; + *) + echo -n "$f"; +@@ -1112,7 +1116,7 @@ base_name() + # Arguments: 1, a file name. + # Output: the content of <file>, possibly decompressed. + # +-if test "${_HAS_COMPRESSION}" = 'yes'; then ++if test _"${_HAS_COMPRESSION}"_ = _yes_; then + catz() + { + func_check catz = 1 "$@"; +@@ -1202,11 +1206,11 @@ dirname_chop() + local _res; + local _sep; + # replace all multiple slashes by a single slash `/'. +- _res="$(echo -n "$1" | sed -e '\|///*|s||/|g')"; ++ _res="$(echo -n "$1" | sed -e '\|.*|s|///*|/|g')"; + case "${_res}" in + ?*/) + # remove trailing slash '/'; +- echo -n "${_res}" | sed -e '\|/$|s|||'; ++ echo -n "${_res}" | sed -e '\|.*|s|/$||'; + ;; + *) echo -n "${_res}"; ;; + esac; +@@ -1426,7 +1430,7 @@ is_dir() + is_empty() + { + func_check is_empty = 1 "$@"; +- if test "$1" = ''; then ++ if test _"$1"_ = __; then + eval "${return_yes}"; + fi; + eval "${return_no}"; +@@ -1444,7 +1448,25 @@ is_empty() + is_equal() + { + func_check is_equal = 2 "$@"; +- if test "$1" = "$2"; then ++ if test _"$1"_ = _"$2"_; then ++ eval "${return_yes}"; ++ fi; ++ eval "${return_no}"; ++} ++ ++ ++######################################################################## ++# is_existing (<name>) ++# ++# Test whether `name' is an existing file or directory. ++# ++# Arguments : 1 ++# Return : `0' if arg1 exists, `1' otherwise. ++# ++is_existing() ++{ ++ func_check is_existing = 1 "$@"; ++ if test -e "$1"; then + eval "${return_yes}"; + fi; + eval "${return_no}"; +@@ -1481,11 +1503,9 @@ is_file() + # + is_non_empty_file() + { +- func_check is_empty = 1 "$@"; +- if is_file "$1"; then +- if is_not_empty "$(cat "$1" | sed -e '/./q')"; then +- eval "${return_yes}"; +- fi; ++ func_check is_non_empty_file = 1 "$@"; ++ if is_file "$1" && test -s "$1"; then ++ eval "${return_yes}"; + fi; + eval "${return_no}"; + } +@@ -1754,7 +1774,7 @@ list_append() + + + ######################################################################## +-# list_from_cmdline (<s_n> <s_a> <l_n> <l_a> [<cmdline_arg>...]) ++# list_from_cmdline (<pre_name_of_opt_lists> [<cmdline_arg>...]) + # + # Transform command line arguments into a normalized form. + # +@@ -1762,32 +1782,25 @@ list_append() + # output each as a single-quoted argument of its own. Options and + # file parameters are separated by a '--' argument. + # +-# Arguments: >=4 +-# <s_n>: space-separated list of short options without an arg. +-# <s_a>: space-separated list of short options that have an arg. +-# <l_n>: space-separated list of long options without an arg. +-# <l_a>: space-separated list of long options that have an arg. ++# Arguments: >=1 ++# <pre_name>: common part of a set of 4 environment variable names: ++# $<pre_name>_SHORT_NA: list of short options without an arg. ++# $<pre_name>_SHORT_ARG: list of short options that have an arg. ++# $<pre_name>_LONG_NA: list of long options without an arg. ++# $<pre_name>_LONG_ARG: list of long options that have an arg. + # <cmdline_arg>...: the arguments from a command line, such as "$@", + # the content of a variable, or direct arguments. + # +-# Globals: $POSIXLY_CORRECT (only kept for compatibility). +-# + # Output: ['-[-]opt' ['optarg']]... '--' ['filename']... + # + # Example: +-# list_normalize 'a b' 'c' '' 'long' -a f1 -bcarg --long=larg f2 +-# will result in printing: ++# list_from_cmdline PRE 'a b' 'c' '' 'long' -a f1 -bcarg --long=larg f2 ++# If $PRE_SHORT_NA, $PRE_SHORT_ARG, $PRE_LONG_NA, and $PRE_LONG_ARG are ++# none-empty option lists, this will result in printing: + # '-a' '-b' '-c' 'arg' '--long' 'larg' '--' 'f1' 'f2' +-# If $POSIXLY_CORRECT is not empty, the result will be: +-# '-a' '--' 'f1' '-bcarg' '--long=larg' 'f2' +-# +-# Rationale: +-# In POSIX, the first non-option ends the option processing. +-# In GNU mode, used by default, non-option arguments are sorted +-# behind the options. + # +-# Use this function only in the following way: +-# eval set -- "$(args_norm '...' '...' '...' '...' "$@")"; ++# Use this function in the following way: ++# eval set -- "$(args_norm PRE_NAME "$@")"; + # while test "$1" != '--'; do + # case "$1" in + # ... +@@ -1799,19 +1812,31 @@ list_append() + # + list_from_cmdline() + { +- func_check list_from_cmdline '>=' 4 "$@"; ++ func_check list_from_cmdline '>=' 1 "$@"; + local _fparams; + local _fn; +- local _result; +- local _long_a; +- local _long_n; + local _short_a; + local _short_n; +- _short_n="$(list_get "$1")"; # short options, no argument +- _short_a="$(list_get "$2")"; # short options with argument +- _long_n="$(list_get "$3")"; # long options, no argument +- _long_a="$(list_get "$4")"; # long options with argument +- shift 4; ++ local _long_a; ++ local _long_n; ++ local _result; ++ _short_n="$(obj_data "$1"_SHORT_NA)"; # short options, no argument ++ _short_a="$(obj_data "$1"_SHORT_ARG)"; # short options, with argument ++ _long_n="$(obj_data "$1"_LONG_NA)"; # long options, no argument ++ _long_a="$(obj_data "$1"_LONG_ARG)"; # long options, with argument ++ if obj _short_n is_empty; then ++ error 'list_from_cmdline(): no $'"$1"'_SHORT_NA options.'; ++ fi; ++ if obj _short_a is_empty; then ++ error 'list_from_cmdline(): no $'"$1"'_SHORT_ARG options.'; ++ fi; ++ if obj _long_n is_empty; then ++ error 'list_from_cmdline(): no $'"$1"'_LONG_NA options.'; ++ fi; ++ if obj _long_a is_empty; then ++ error 'list_from_cmdline(): no $'"$1"'_LONG_ARG options.'; ++ fi; ++ shift; + _fn='list_from_cmdline():'; # for error messages + if is_equal "$#" 0; then + echo -n "'--'"; +@@ -1887,13 +1912,12 @@ list_from_cmdline() + ;; + *) + # Here, $_arg is not an option, so a file parameter. +- # When $POSIXLY_CORRECT is set this ends option parsing; +- # otherwise, the argument is stored as a file parameter and +- # option processing is continued. + list_append _fparams "${_arg}"; +- if obj POSIXLY_CORRECT is_not_empty; then +- break; +- fi; ++ ++ # Ignore the strange option handling of $POSIXLY_CORRECT to ++ # end option parsing after the first file name argument. To ++ # reuse it, do a `break' here if $POSIXLY_CORRECT is ++ # non-empty. + ;; + esac; + done; +@@ -1930,7 +1954,7 @@ list_from_split() + # replace split character of string by the list separator ` ' (space). + case "$2" in + /) # cannot use normal `sed' separator +- echo -n "${_s}" | sed -e '\|'"$2"'|s|| |g'; ++ echo -n "${_s}" | sed -e '\|.*|s|'"$2"'| |g'; + ;; + ?) # use normal `sed' separator + echo -n "${_s}" | sed -e 's/'"$2"'/ /g'; +@@ -1968,8 +1992,8 @@ list_get() + eval _list='"${'$1'}"'; + # remove leading and final space characters + _list="$(echo -n "${_list}" | \ +- sed -e '/^['"${_SPACE}${_TAB}"']*/s///' | \ +- sed -e '/['"${_SPACE}${_TAB}"']*$/s///')"; ++ sed -e 's/^['"${_SPACE}${_TAB}"']*//' | \ ++ sed -e 's/['"${_SPACE}${_TAB}"']*$//')"; + case "${_list}" in + '') + eval "${return_ok}"; +@@ -2483,7 +2507,7 @@ manpath_set_from_path() + eval set -- "$(path_split "${PATH}")"; + for d in "$@"; do + # delete the final `/bin' part +- _base="$(echo -n "$d" | sed -e '\|//*bin/*$|s|||')"; ++ _base="$(echo -n "$d" | sed -e '\|.*|s|//*bin/*$||')"; + for e in /share/man /man; do + _mandir="${_base}$e"; + if test -d "${_mandir}" && test -r "${_mandir}"; then +@@ -3200,7 +3224,7 @@ where() + # + # set exit trap and create temporary files + # +-# Globals: $_TMP_CAT, $_TMP_STDIN ++# Globals: $_TMP_DIR, $_TMP_CAT, $_TMP_STDIN + # + landmark '13: main_init()'; + main_init() +@@ -3209,32 +3233,52 @@ main_init() + # call clean_up() on any signal + trap_set clean_up; + +- # determine temporary directory +- umask 000; ++ # create temporary directory ++ umask 0022; + _TMP_DIR=''; + for d in "${GROFF_TMPDIR}" "${TMPDIR}" "${TMP}" "${TEMP}" \ + "${TEMPDIR}" "${HOME}"'/tmp' '/tmp' "${HOME}" '.'; + do +- if is_not_empty "$d"; then +- if obj d is_dir && obj d is_writable; then +- _TMP_DIR="${d}/${_PROGRAM_NAME}${_PROCESS_ID}"; +- if obj _TMP_DIR is_dir; then +- rm -f "${_TMP_DIR}"/*; +- break; +- else +- mkdir "${_TMP_DIR}"; +- if obj _TMP_DIR is_not_dir; then +- _TMP_DIR=''; +- continue; +- fi; +- break; +- fi; ++ if obj d is_empty || obj d is_not_dir || obj d is_not_writable; then ++ continue; ++ fi; ++ case "$d" in ++ */) ++ _TMP_DIR="${d}"; ++ ;; ++ *) ++ _TMP_DIR="${d}"'/'; ++ ;; ++ esac; ++ _TMP_DIR="${_TMP_DIR}${_PROGRAM_NAME}${_PROCESS_ID}"; ++ while obj _TMP_DIR is_existing; do ++ rm -f -r "${_TMP_DIR}" 2>/dev/null; ++ if obj _TMP_DIR is_existing; then ++ # $_TMP_DIR could not be removed ++ _TMP_DIR="${_TMP_DIR}"'X'; ++ continue; ++ else ++ # $_TMP_DIR was removed ++ break; + fi; +- if obj _TMP_DIR is_not_writable; then +- _TMP_DIR=''; +- continue; ++ done; ++ mkdir "${_TMP_DIR}"; ++ if is_not_equal "$?" 0; then ++ if obj _TMP_DIR is_existing; then ++ rm -f -r "${_TMP_DIR}" 2>/dev/null; + fi; ++ _TMP_DIR=''; ++ continue; ++ fi; ++ if obj _TMP_DIR is_dir && obj _TMP_DIR is_writable; then ++ # $_TMP_DIR can now be used as temporary directory ++ break; ++ fi; ++ if obj _TMP_DIR is_existing; then ++ rm -f -r "${_TMP_DIR}" 2>/dev/null; + fi; ++ _TMP_DIR=''; ++ continue; + done; + unset d; + if obj _TMP_DIR is_empty; then +@@ -3250,7 +3294,7 @@ main_init() + echo '_groffer_opt=""' >>${_TMP_CAT}; + # collect the lines starting with a minus + cat "$f" | sed -e \ +- '/^[ ]*\(-.*\)$/s//_groffer_opt="${_groffer_opt} \1"'/ \ ++ 's/^[ ]*\(-.*\)$/_groffer_opt="${_groffer_opt} \1"'/ \ + >>${_TMP_CAT}; + # prepend the collected information to $GROFFER_OPT + echo 'GROFFER_OPT="${_groffer_opt} ${GROFFER_OPT}"' >>${_TMP_CAT}; +@@ -3289,10 +3333,7 @@ main_parse_MANOPT() + eval "${return_ok}"; + fi; + # add arguments in $MANOPT by mapping them to groffer options +- eval set -- "$(list_from_cmdline \ +- _OPTS_MANOPT_SHORT_NA _OPTS_MANOPT_SHORT_ARG \ +- _OPTS_MANOPT_LONG_NA _OPTS_MANOPT_LONG_ARG \ +- "${MANOPT}")"; ++ eval set -- "$(list_from_cmdline _OPTS_MANOPT "${MANOPT}")"; + until test "$#" -le 0 || is_equal "$1" '--'; do + _opt="$1"; + shift; +@@ -3424,10 +3465,7 @@ main_parse_args() + + eval set -- "${GROFFER_OPT}" '"$@"'; + +- eval set -- "$(list_from_cmdline \ +- _OPTS_CMDLINE_SHORT_NA _OPTS_CMDLINE_SHORT_ARG \ +- _OPTS_CMDLINE_LONG_NA _OPTS_CMDLINE_LONG_ARG \ +- "$@")"; ++ eval set -- "$(list_from_cmdline _OPTS_CMDLINE "$@")"; + + # By the call of `eval', unnecessary quoting was removed. So the + # positional shell parameters ($1, $2, ...) are now guaranteed to +@@ -3484,12 +3522,6 @@ main_parse_args() + --all) + _OPT_ALL="yes"; + ;; +- --ascii) +- list_append _ADDOPTS_GROFF '-mtty-char'; +- if obj _mode is_empty; then +- _mode='text'; +- fi; +- ;; + --apropos) # run `apropos' + apropos_run "$1"; + _code="$?"; +@@ -3497,23 +3529,29 @@ main_parse_args() + exit "${_code}"; + ;; + --apropos-data) # run `apropos' for data sections +- apropos_run "$1" | grep '^[^(]*([457])'; ++ apropos_run "$1" | grep '^[^(]*([457][^)]*)'; + _code="$?"; + clean_up; + exit "${_code}"; + ;; + --apropos-devel) # run `apropos' for development sections +- apropos_run "$1" | grep '^[^(]*([239])'; ++ apropos_run "$1" | grep '^[^(]*([239][^)]*)'; + _code="$?"; + clean_up; + exit "${_code}"; + ;; + --apropos-progs) # run `apropos' for program sections +- apropos_run "$1" | grep '^[^(]*([168])'; ++ apropos_run "$1" | grep '^[^(]*([168][^)]*)'; + _code="$?"; + clean_up; + exit "${_code}"; + ;; ++ --ascii) ++ list_append _ADDOPTS_GROFF '-mtty-char'; ++ if obj _mode is_empty; then ++ _mode='text'; ++ fi; ++ ;; + --auto) # the default automatic mode + _mode=''; + ;; +@@ -3691,6 +3729,7 @@ main_parse_args() + shift; + ;; + --shell) ++ # already done during the first run; so ignore the argument + shift; + ;; + --systems) # man pages for different OS's, arg +@@ -4136,7 +4175,7 @@ main_set_resources() + continue; + ;; + ,*) +- n="$(echo -n "$1" | sed -e '/^,,*/s///')"; ++ n="$(echo -n "$1" | sed -e 's/^,,*//')"; + ;; + esac + if obj n is_empty; then |