From 51375f969fbdb842aca5cc2270c181a68af505c3 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" <Todd.Miller@courtesan.com> Date: Mon, 15 Nov 2004 15:53:53 +0000 Subject: [PATCH] Add local error/warning functions like err/warn but that call an additional cleanup routine in the error case. This means we no longer need to compile a special version of alloc.o for visudo. --- LICENSE | 4 +- Makefile.in | 35 ++++------ alloc.c | 29 ++++---- check.c | 9 +-- config.h.in | 3 - configure | 159 ------------------------------------------ configure.in | 1 - defaults.c | 43 +++++------- emul/err.h | 69 ------------------- env.c | 9 +-- err.c | 183 ------------------------------------------------- error.c | 133 +++++++++++++++++++++++++++++++++++ error.h | 44 ++++++++++++ find_path.c | 9 +-- interfaces.c | 7 +- logging.c | 13 ++-- mon_systrace.c | 41 +++++------ sudo.c | 60 ++++++++-------- sudo.h | 2 + sudo_edit.c | 43 +++++------- testsudoers.c | 15 ++-- visudo.c | 156 +++++++++++++---------------------------- 22 files changed, 363 insertions(+), 704 deletions(-) delete mode 100644 emul/err.h delete mode 100644 err.c create mode 100644 error.c create mode 100644 error.h diff --git a/LICENSE b/LICENSE index 5ecdb0ef8..39c0e8abf 100644 --- a/LICENSE +++ b/LICENSE @@ -18,8 +18,8 @@ Sudo is distributed under the following ISC-style license: Agency (DARPA) and Air Force Research Laboratory, Air Force Materiel Command, USAF, under agreement number F39502-99-1-0512. -Additionally, err.c, fnmatch.c, getcwd.c, glob.c, snprintf.c, strcasecmp.c, -fnmatch.h, glob.h err.h, and fnmatch.3 bear the following UCB license: +Additionally, fnmatch.c, getcwd.c, glob.c, snprintf.c, strcasecmp.c, +fnmatch.h, glob.h and fnmatch.3 bear the following UCB license: Copyright (c) 1987, 1989, 1990, 1991, 1993, 1994 The Regents of the University of California. All rights reserved. diff --git a/Makefile.in b/Makefile.in index 6c0846acd..42171b011 100644 --- a/Makefile.in +++ b/Makefile.in @@ -98,37 +98,36 @@ SHELL = /bin/sh PROGS = @PROGS@ -SRCS = alloc.c alloca.c check.c closefrom.c def_data.c defaults.c env.c err.c \ - fileops.c find_path.c fnmatch.c getcwd.c getprogname.c getspwuid.c \ - gettime.c goodpath.c gram.c gram.y interfaces.c ldap.c logging.c \ - match.c mon_systrace.c parse.c set_perms.c sigaction.c snprintf.c \ - strcasecmp.c strerror.c strlcat.c strlcpy.c sudo.c sudo_noexec.c \ - sudo_edit.c testsudoers.c tgetpass.c toke.c toke.l utimes.c visudo.c \ - zero_bytes.c redblack.c $(AUTH_SRCS) +SRCS = alloc.c alloca.c check.c closefrom.c def_data.c defaults.c env.c \ + error.c fileops.c find_path.c fnmatch.c getcwd.c getprogname.c \ + getspwuid.c gettime.c goodpath.c gram.c gram.y interfaces.c ldap.c \ + logging.c match.c mon_systrace.c parse.c set_perms.c sigaction.c \ + snprintf.c strcasecmp.c strerror.c strlcat.c strlcpy.c sudo.c \ + sudo_noexec.c sudo_edit.c testsudoers.c tgetpass.c toke.c toke.l \ + utimes.c visudo.c zero_bytes.c redblack.c $(AUTH_SRCS) AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \ auth/kerb4.c auth/kerb5.c auth/pam.c auth/passwd.c auth/rfc1938.c \ auth/secureware.c auth/securid.c auth/securid5.c auth/sia.c \ auth/sudo_auth.c -HDRS = compat.h def_data.h defaults.h ins_2001.h ins_classic.h ins_csops.h \ - ins_goons.h insults.h interfaces.h logging.h parse.h sudo.h gram.h \ - version.h auth/sudo_auth.h emul/err.h emul/fnmatch.h emul/utime.h \ +HDRS = compat.h def_data.h defaults.h error.h ins_2001.h ins_classic.h \ + ins_csops.h ins_goons.h insults.h interfaces.h logging.h parse.h \ + sudo.h gram.h version.h auth/sudo_auth.h emul/fnmatch.h emul/utime.h \ redblack.h AUTH_OBJS = sudo_auth.o @AUTH_OBJS@ -PARSEOBJS = gram.o toke.o match.o defaults.o redblack.o +PARSEOBJS = error.o alloc.o gram.o toke.o match.o defaults.o redblack.o -SUDOBJS = alloc.o check.o env.o getspwuid.o gettime.o goodpath.o fileops.o \ +SUDOBJS = check.o env.o getspwuid.o gettime.o goodpath.o fileops.o \ find_path.o interfaces.o logging.o parse.o set_perms.o sudo.o \ sudo_edit.o tgetpass.o zero_bytes.o @SUDO_OBJS@ $(AUTH_OBJS) \ $(PARSEOBJS) -VISUDOBJS = visudo.o fileops.o gettime.o goodpath.o find_path.o vsalloc.o \ - $(PARSEOBJS) +VISUDOBJS = visudo.o fileops.o gettime.o goodpath.o find_path.o $(PARSEOBJS) -TESTOBJS = alloc.o interfaces.o testsudoers.o $(PARSEOBJS) +TESTOBJS = interfaces.o testsudoers.o $(PARSEOBJS) LIBOBJS = @LIBOBJS@ @ALLOCA@ @@ -210,7 +209,7 @@ alloc.o: alloc.c $(SUDODEP) check.o: check.c $(SUDODEP) closefrom.o: closefrom.c config.h env.o: env.c $(SUDODEP) -err.o: err.c config.h compat.h emul/err.h +error.o: error.c config.h compat.h error.h fileops.o: fileops.c $(SUDODEP) find_path.o: find_path.c $(SUDODEP) getprogname.o: getprogname.c config.h @@ -239,10 +238,6 @@ utime.o: utime.c config.h pathnames.h compat.h emul/utime.h ldap.o: ldap.c $(SUDODEP) parse.h mon_systrace.o: mon_systrace.c $(SUDODEP) mon_systrace.h -# Build special copy of alloc.c for visudo that calls Exit() -vsalloc.o: alloc.c $(SUDODEP) - $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) '-Derr=Err' '-Derrx=Errx' $(srcdir)/alloc.c - # Authentication functions live in "auth" dir and so need extra care sudo_auth.o: $(authdir)/sudo_auth.c $(AUTHDEP) $(INSDEP) $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/sudo_auth.c diff --git a/alloc.c b/alloc.c index 7a9360469..d103a8c05 100644 --- a/alloc.c +++ b/alloc.c @@ -41,11 +41,6 @@ #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) # include <malloc.h> #endif /* HAVE_MALLOC_H && !STDC_HEADERS */ -#ifdef HAVE_ERR_H -# include <err.h> -#else -# include "emul/err.h" -#endif /* HAVE_ERR_H */ #include "sudo.h" @@ -78,10 +73,10 @@ emalloc(size) VOID *ptr; if (size == 0) - errx(1, "internal error, tried to emalloc(0)"); + errorx(1, "internal error, tried to emalloc(0)"); if ((ptr = (VOID *) malloc(size)) == NULL) - errx(1, "unable to allocate memory"); + errorx(1, "unable to allocate memory"); return(ptr); } @@ -97,13 +92,13 @@ emalloc2(nmemb, size) VOID *ptr; if (nmemb == 0 || size == 0) - errx(1, "internal error, tried to emalloc2(0)"); + errorx(1, "internal error, tried to emalloc2(0)"); if (nmemb > SIZE_MAX / size) - errx(1, "internal error, emalloc2() overflow"); + errorx(1, "internal error, emalloc2() overflow"); size *= nmemb; if ((ptr = (VOID *) malloc(size)) == NULL) - errx(1, "unable to allocate memory"); + errorx(1, "unable to allocate memory"); return(ptr); } @@ -119,11 +114,11 @@ erealloc(ptr, size) { if (size == 0) - errx(1, "internal error, tried to erealloc(0)"); + errorx(1, "internal error, tried to erealloc(0)"); ptr = ptr ? (VOID *) realloc(ptr, size) : (VOID *) malloc(size); if (ptr == NULL) - errx(1, "unable to allocate memory"); + errorx(1, "unable to allocate memory"); return(ptr); } @@ -141,14 +136,14 @@ erealloc3(ptr, nmemb, size) { if (nmemb == 0 || size == 0) - errx(1, "internal error, tried to erealloc3(0)"); + errorx(1, "internal error, tried to erealloc3(0)"); if (nmemb > SIZE_MAX / size) - errx(1, "internal error, erealloc3() overflow"); + errorx(1, "internal error, erealloc3() overflow"); size *= nmemb; ptr = ptr ? (VOID *) realloc(ptr, size) : (VOID *) malloc(size); if (ptr == NULL) - errx(1, "unable to allocate memory"); + errorx(1, "unable to allocate memory"); return(ptr); } @@ -199,7 +194,7 @@ easprintf(va_alist) va_end(ap); if (len == -1) - errx(1, "unable to allocate memory"); + errorx(1, "unable to allocate memory"); return(len); } @@ -216,6 +211,6 @@ evasprintf(ret, format, args) int len; if ((len = vasprintf(ret, format, args)) == -1) - errx(1, "unable to allocate memory"); + errorx(1, "unable to allocate memory"); return(len); } diff --git a/check.c b/check.c index 83bd15b11..511bec004 100644 --- a/check.c +++ b/check.c @@ -45,11 +45,6 @@ #ifdef HAVE_UNISTD_H # include <unistd.h> #endif /* HAVE_UNISTD_H */ -#ifdef HAVE_ERR_H -# include <err.h> -#else -# include "emul/err.h" -#endif /* HAVE_ERR_H */ #include <errno.h> #include <fcntl.h> #include <signal.h> @@ -273,7 +268,7 @@ expand_prompt(old_prompt, user, host) oflow: /* We pre-allocate enough space, so this should never happen. */ - errx(1, "internal error, expand_prompt() overflow"); + errorx(1, "internal error, expand_prompt() overflow"); } /* @@ -552,7 +547,7 @@ remove_timestamp(remove) } else { timespecclear(&ts); if (touch(-1, path, &ts) == -1) - err(1, "can't reset %s to Epoch", path); + error(1, "can't reset %s to Epoch", path); } } diff --git a/config.h.in b/config.h.in index e4ebc772c..7935afdde 100644 --- a/config.h.in +++ b/config.h.in @@ -88,9 +88,6 @@ /* Define to 1 if you have the `dispcrypt' function. */ #undef HAVE_DISPCRYPT -/* Define to 1 if you have the <err.h> header file. */ -#undef HAVE_ERR_H - /* [Define to 1 if your glob.h defines the GLOB_BRACE and GLOB_TILDE flags. */ #undef HAVE_EXTENDED_GLOB diff --git a/configure b/configure index d3df0d854..84a4e4422 100755 --- a/configure +++ b/configure @@ -24257,165 +24257,6 @@ fi done - -for ac_header in err.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------- ## -## Report this to the sudo lists. ## -## ------------------------------- ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -else - case $LIBOBJS in - "err.$ac_objext" | \ - *" err.$ac_objext" | \ - "err.$ac_objext "* | \ - *" err.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS err.$ac_objext" ;; -esac - -fi - -done - if test "$OS" != "ultrix"; then echo "$as_me:$LINENO: checking POSIX termios" >&5 echo $ECHO_N "checking POSIX termios... $ECHO_C" >&6 diff --git a/configure.in b/configure.in index 03ec6d324..3bdd03cfb 100644 --- a/configure.in +++ b/configure.in @@ -1628,7 +1628,6 @@ dnl AC_HEADER_STDC AC_HEADER_DIRENT AC_CHECK_HEADERS(malloc.h paths.h utime.h netgroup.h sys/sockio.h sys/bsdtypes.h sys/select.h) -AC_CHECK_HEADERS(err.h, , [AC_LIBOBJ(err)]) dnl ultrix termio/termios are broken if test "$OS" != "ultrix"; then AC_SYS_POSIX_TERMIOS diff --git a/defaults.c b/defaults.c index 68101e108..a081e48b2 100644 --- a/defaults.c +++ b/defaults.c @@ -42,11 +42,6 @@ #include <unistd.h> #endif /* HAVE_UNISTD_H */ #include <pwd.h> -#ifdef HAVE_ERR_H -# include <err.h> -#else -# include "emul/err.h" -#endif /* HAVE_ERR_H */ #include <ctype.h> #include "sudo.h" @@ -234,7 +229,7 @@ set_default(var, val, op) break; } if (!cur->name) { - warnx("unknown defaults entry `%s'", var); + warningx("unknown defaults entry `%s'", var); return(FALSE); } @@ -242,18 +237,18 @@ set_default(var, val, op) case T_LOGFAC: if (!store_syslogfac(val, cur, op)) { if (val) - warnx("value `%s' is invalid for option `%s'", val, var); + warningx("value `%s' is invalid for option `%s'", val, var); else - warnx("no value specified for `%s'", var); + warningx("no value specified for `%s'", var); return(FALSE); } break; case T_LOGPRI: if (!store_syslogpri(val, cur, op)) { if (val) - warnx("value `%s' is invalid for option `%s'", val, var); + warningx("value `%s' is invalid for option `%s'", val, var); else - warnx("no value specified for `%s'", var); + warningx("no value specified for `%s'", var); return(FALSE); } break; @@ -261,16 +256,16 @@ set_default(var, val, op) if (!val) { /* Check for bogus boolean usage or lack of a value. */ if (!ISSET(cur->type, T_BOOL) || op != FALSE) { - warnx("no value specified for `%s'", var); + warningx("no value specified for `%s'", var); return(FALSE); } } if (ISSET(cur->type, T_PATH) && val && *val != '/') { - warnx("values for `%s' must start with a '/'", var); + warningx("values for `%s' must start with a '/'", var); return(FALSE); } if (!store_str(val, cur, op)) { - warnx("value `%s' is invalid for option `%s'", val, var); + warningx("value `%s' is invalid for option `%s'", val, var); return(FALSE); } break; @@ -278,12 +273,12 @@ set_default(var, val, op) if (!val) { /* Check for bogus boolean usage or lack of a value. */ if (!ISSET(cur->type, T_BOOL) || op != FALSE) { - warnx("no value specified for `%s'", var); + warningx("no value specified for `%s'", var); return(FALSE); } } if (!store_int(val, cur, op)) { - warnx("value `%s' is invalid for option `%s'", val, var); + warningx("value `%s' is invalid for option `%s'", val, var); return(FALSE); } break; @@ -291,12 +286,12 @@ set_default(var, val, op) if (!val) { /* Check for bogus boolean usage or lack of a value. */ if (!ISSET(cur->type, T_BOOL) || op != FALSE) { - warnx("no value specified for `%s'", var); + warningx("no value specified for `%s'", var); return(FALSE); } } if (!store_uint(val, cur, op)) { - warnx("value `%s' is invalid for option `%s'", val, var); + warningx("value `%s' is invalid for option `%s'", val, var); return(FALSE); } break; @@ -304,18 +299,18 @@ set_default(var, val, op) if (!val) { /* Check for bogus boolean usage or lack of a value. */ if (!ISSET(cur->type, T_BOOL) || op != FALSE) { - warnx("no value specified for `%s'", var); + warningx("no value specified for `%s'", var); return(FALSE); } } if (!store_mode(val, cur, op)) { - warnx("value `%s' is invalid for option `%s'", val, var); + warningx("value `%s' is invalid for option `%s'", val, var); return(FALSE); } break; case T_FLAG: if (val) { - warnx("option `%s' does not take a value", var); + warningx("option `%s' does not take a value", var); return(FALSE); } cur->sd_un.flag = op; @@ -328,12 +323,12 @@ set_default(var, val, op) if (!val) { /* Check for bogus boolean usage or lack of a value. */ if (!ISSET(cur->type, T_BOOL) || op != FALSE) { - warnx("no value specified for `%s'", var); + warningx("no value specified for `%s'", var); return(FALSE); } } if (!store_list(val, cur, op)) { - warnx("value `%s' is invalid for option `%s'", val, var); + warningx("value `%s' is invalid for option `%s'", val, var); return(FALSE); } break; @@ -341,12 +336,12 @@ set_default(var, val, op) if (!val) { /* Check for bogus boolean usage or lack of a value. */ if (!ISSET(cur->type, T_BOOL) || op != FALSE) { - warnx("no value specified for `%s'", var); + warningx("no value specified for `%s'", var); return(FALSE); } } if (!store_tuple(val, cur, op)) { - warnx("value `%s' is invalid for option `%s'", val, var); + warningx("value `%s' is invalid for option `%s'", val, var); return(FALSE); } break; diff --git a/emul/err.h b/emul/err.h deleted file mode 100644 index 637740b9f..000000000 --- a/emul/err.h +++ /dev/null @@ -1,69 +0,0 @@ -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)err.h 8.1 (Berkeley) 6/2/93 - */ - -#ifndef _ERR_H_ -#define _ERR_H_ - -#ifdef __STDC__ -# include <stdarg.h> -#else -# include <varargs.h> -#endif - -#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 5 -#define __attribute__(x) -#endif - -#ifdef __STDC__ -void err(int, const char *, ...) __attribute__((__noreturn__)); -void verr(int, const char *, va_list) __attribute__((__noreturn__)); -void errx(int, const char *, ...) __attribute__((__noreturn__)); -void verrx(int, const char *, va_list) __attribute__((__noreturn__)); -void warn(const char *, ...); -void vwarn(const char *, va_list); -void warnx(const char *, ...); -void vwarnx(const char *, va_list); -#else -void err() __attribute__((__noreturn__)); -void verr() __attribute__((__noreturn__)); -void errx() __attribute__((__noreturn__)); -void verrx() __attribute__((__noreturn__)); -void warn(); -void vwarn(); -void warnx(); -void vwarnx(); -#endif /* __STDC__ */ - -#endif /* !_ERR_H_ */ diff --git a/env.c b/env.c index 2b58707e3..58f3ded33 100644 --- a/env.c +++ b/env.c @@ -42,11 +42,6 @@ #ifdef HAVE_UNISTD_H # include <unistd.h> #endif /* HAVE_UNISTD_H */ -#ifdef HAVE_ERR_H -# include <err.h> -#else -# include "emul/err.h" -#endif /* HAVE_ERR_H */ #include <pwd.h> #include "sudo.h" @@ -244,7 +239,7 @@ format_env(var, va_alist) if (strlcpy(estring, var, esize) >= esize || strlcat(estring, "=", esize) >= esize) { - errx(1, "internal error, format_env() overflow"); + errorx(1, "internal error, format_env() overflow"); } /* Now store the variable's value (if any) */ @@ -255,7 +250,7 @@ format_env(var, va_alist) #endif while ((val = va_arg(ap, char *)) != NULL) { if (strlcat(estring, val, esize) >= esize) - errx(1, "internal error, format_env() overflow"); + errorx(1, "internal error, format_env() overflow"); } va_end(ap); diff --git a/err.c b/err.c deleted file mode 100644 index e9f37abb4..000000000 --- a/err.c +++ /dev/null @@ -1,183 +0,0 @@ -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)err.c 8.1 (Berkeley) 6/4/93" - */ - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "config.h" -#include "compat.h" -#include "emul/err.h" - -#ifndef lint -static const char rcsid[] = "$Sudo$"; -#endif /* lint */ - -void -#ifdef __STDC__ -err(int eval, const char *fmt, ...) -#else -err(eval, fmt, va_alist) - int eval; - const char *fmt; - va_dcl -#endif -{ - va_list ap; -#ifdef __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - verr(eval, fmt, ap); - va_end(ap); -} - -void -verr(eval, fmt, ap) - int eval; - const char *fmt; - va_list ap; -{ - int sverrno; - - sverrno = errno; - (void)fprintf(stderr, "%s: ", getprogname()); - if (fmt != NULL) { - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, ": "); - } - (void)fprintf(stderr, "%s\n", strerror(sverrno)); - exit(eval); -} - -void -#ifdef __STDC__ -errx(int eval, const char *fmt, ...) -#else -errx(eval, fmt, va_alist) - int eval; - const char *fmt; - va_dcl -#endif -{ - va_list ap; -#ifdef __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - verrx(eval, fmt, ap); - va_end(ap); -} - -void -verrx(eval, fmt, ap) - int eval; - const char *fmt; - va_list ap; -{ - (void)fprintf(stderr, "%s: ", getprogname()); - if (fmt != NULL) - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, "\n"); - exit(eval); -} - -void -#ifdef __STDC__ -warn(const char *fmt, ...) -#else -warn(fmt, va_alist) - const char *fmt; - va_dcl -#endif -{ - va_list ap; -#ifdef __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - vwarn(fmt, ap); - va_end(ap); -} - -void -vwarn(fmt, ap) - const char *fmt; - va_list ap; -{ - int sverrno; - - sverrno = errno; - (void)fprintf(stderr, "%s: ", getprogname()); - if (fmt != NULL) { - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, ": "); - } - (void)fprintf(stderr, "%s\n", strerror(sverrno)); -} - -void -#ifdef __STDC__ -warnx(const char *fmt, ...) -#else -warnx(fmt, va_alist) - const char *fmt; - va_dcl -#endif -{ - va_list ap; -#ifdef __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - vwarnx(fmt, ap); - va_end(ap); -} - -void -vwarnx(fmt, ap) - const char *fmt; - va_list ap; -{ - (void)fprintf(stderr, "%s: ", getprogname()); - if (fmt != NULL) - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, "\n"); -} diff --git a/error.c b/error.c new file mode 100644 index 000000000..e70ded711 --- /dev/null +++ b/error.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2004 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "config.h" +#include "compat.h" +#include "error.h" + +#ifndef lint +static const char rcsid[] = "$Sudo$"; +#endif /* lint */ + +static void _warning __P((int, const char *, va_list)); + void cleanup __P((void)); + +void +#ifdef __STDC__ +error(int eval, const char *fmt, ...) +#else +error(eval, fmt, va_alist) + int eval; + const char *fmt; + va_dcl +#endif +{ + va_list ap; +#ifdef __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + _warning(1, fmt, ap); + va_end(ap); + cleanup(); + exit(eval); +} + +void +#ifdef __STDC__ +errorx(int eval, const char *fmt, ...) +#else +error(eval, fmt, va_alist) + int eval; + const char *fmt; + va_dcl +#endif +{ + va_list ap; +#ifdef __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + _warning(0, fmt, ap); + va_end(ap); + cleanup(); + exit(eval); +} + +void +#ifdef __STDC__ +warning(const char *fmt, ...) +#else +warning(fmt, va_alist) + const char *fmt; + va_dcl +#endif +{ + va_list ap; +#ifdef __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + _warning(1, fmt, ap); + va_end(ap); +} + +void +#ifdef __STDC__ +warningx(const char *fmt, ...) +#else +warning(fmt, va_alist) + const char *fmt; + va_dcl +#endif +{ + va_list ap; +#ifdef __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + _warning(0, fmt, ap); + va_end(ap); +} + +static void +_warning(use_errno, fmt, ap) + int use_errno; + const char *fmt; + va_list ap; +{ + int serrno = errno; + + fputs(getprogname(), stderr); + if (fmt != NULL) { + fputs(": ", stderr); + vfprintf(stderr, fmt, ap); + } + if (use_errno) { + fputs(": ", stderr); + fputs(strerror(serrno), stderr); + } + putc('\n', stderr); +} diff --git a/error.h b/error.h new file mode 100644 index 000000000..b42417941 --- /dev/null +++ b/error.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2004 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Sudo$ + */ + +#ifndef _SUDO_ERROR_H_ +#define _SUDO_ERROR_H_ + +#ifdef __STDC__ +# include <stdarg.h> +#else +# include <varargs.h> +#endif + +#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 5 +#define __attribute__(x) +#endif + +#ifdef __STDC__ +void error(int, const char *, ...) __attribute__((__noreturn__)); +void errorx(int, const char *, ...) __attribute__((__noreturn__)); +void warning(const char *, ...); +void warningx(const char *, ...); +#else +void error() __attribute__((__noreturn__)); +void errorx() __attribute__((__noreturn__)); +void warning(); +void warningx(); +#endif /* __STDC__ */ + +#endif /* _SUDO_ERROR_H_ */ diff --git a/find_path.c b/find_path.c index 38916c169..3045fd136 100644 --- a/find_path.c +++ b/find_path.c @@ -42,11 +42,6 @@ #ifdef HAVE_UNISTD_H # include <unistd.h> #endif /* HAVE_UNISTD_H */ -#ifdef HAVE_ERR_H -# include <err.h> -#else -# include "emul/err.h" -#endif /* HAVE_ERR_H */ #include "sudo.h" @@ -76,7 +71,7 @@ find_path(infile, outfile, sbp, path) int len; /* length parameter */ if (strlen(infile) >= PATH_MAX) - errx(1, "%s: File name too long", infile); + errorx(1, "%s: File name too long", infile); /* * If we were given a fully qualified or relative path @@ -118,7 +113,7 @@ find_path(infile, outfile, sbp, path) */ len = snprintf(command, sizeof(command), "%s/%s", path, infile); if (len <= 0 || len >= sizeof(command)) - errx(1, "%s: File name too long", infile); + errorx(1, "%s: File name too long", infile); if ((result = sudo_goodpath(command, sbp))) break; diff --git a/interfaces.c b/interfaces.c index 7ee1b7cbd..c2fb8349b 100644 --- a/interfaces.c +++ b/interfaces.c @@ -59,11 +59,6 @@ struct rtentry; #ifdef HAVE_UNISTD_H # include <unistd.h> #endif /* HAVE_UNISTD_H */ -#ifdef HAVE_ERR_H -# include <err.h> -#else -# include "emul/err.h" -#endif /* HAVE_ERR_H */ #include <netdb.h> #ifdef _ISC # include <sys/stream.h> @@ -176,7 +171,7 @@ load_interfaces() sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) - err(1, "cannot open socket"); + error(1, "cannot open socket"); /* * Get interface configuration or return (leaving num_interfaces == 0) diff --git a/logging.c b/logging.c index b99c95eea..381757f64 100644 --- a/logging.c +++ b/logging.c @@ -47,11 +47,6 @@ #ifdef HAVE_UNISTD_H # include <unistd.h> #endif /* HAVE_UNISTD_H */ -#ifdef HAVE_ERR_H -# include <err.h> -#else -# include "emul/err.h" -#endif /* HAVE_ERR_H */ #include <pwd.h> #include <grp.h> #include <signal.h> @@ -399,9 +394,9 @@ log_error(va_alist) */ if (!ISSET(flags, NO_STDERR)) { if (ISSET(flags, USE_ERRNO)) - warn("%s", message); + warning("%s", message); else - warnx("%s", message); + warningx("%s", message); } /* @@ -459,12 +454,12 @@ send_mail(line) (void) sigprocmask(SIG_BLOCK, &set, &oset); if (pipe(pfd) == -1) - err(1, "cannot open pipe"); + error(1, "cannot open pipe"); switch (pid = fork()) { case -1: /* Error. */ - err(1, "cannot fork"); + error(1, "cannot fork"); break; case 0: { diff --git a/mon_systrace.c b/mon_systrace.c index c7f727df9..a1d55fdc1 100644 --- a/mon_systrace.c +++ b/mon_systrace.c @@ -27,11 +27,6 @@ #include <pwd.h> #include <signal.h> #include <fcntl.h> -#ifdef HAVE_ERR_H -# include <err.h> -#else -# include "emul/err.h" -#endif /* HAVE_ERR_H */ #ifdef HAVE_DEV_SYSTRACE_H # include <dev/systrace.h> #else @@ -110,7 +105,7 @@ systrace_attach(pid) int fd, cookie; if ((fd = systrace_open()) == -1) - err(1, "unable to open systrace"); + error(1, "unable to open systrace"); fflush(stdout); /* @@ -119,16 +114,16 @@ systrace_attach(pid) */ sigfillset(&set); if (sigprocmask(SIG_BLOCK, &set, &oset) != 0) - err(1, "sigprocmask"); + error(1, "sigprocmask"); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = catchsig; if (sigaction(SIGUSR1, &sa, &osa) != 0) - err(1, "sigaction"); + error(1, "sigaction"); switch (fork()) { case -1: - err(1, "can't fork"); + error(1, "can't fork"); case 0: /* tracer */ break; @@ -138,7 +133,7 @@ systrace_attach(pid) sigdelset(&set, SIGUSR1); (void) sigsuspend(&set); if (sigprocmask(SIG_SETMASK, &oset, NULL) != 0) { - warn("sigprocmask"); + warning("sigprocmask"); exit(1); } return; @@ -154,14 +149,14 @@ systrace_attach(pid) sigaction(SIGINT, &sa, NULL) != 0 || sigaction(SIGTERM, &sa, NULL) != 0 || sigprocmask(SIG_SETMASK, &oset, NULL) != 0) { - warn("unable to setup signals for %s", user_cmnd); + warning("unable to setup signals for %s", user_cmnd); goto fail; } /* become a daemon */ set_perms(PERM_FULL_ROOT); if (setsid() == -1) { - warn("setsid"); + warning("setsid"); kill(pid, SIGKILL); _exit(1); } @@ -177,18 +172,18 @@ systrace_attach(pid) (void) kill(pid, SIGUSR1); _exit(0); } - warn("unable to systrace %s", user_cmnd); + warning("unable to systrace %s", user_cmnd); goto fail; } new_child(-1, pid); if (set_policy(fd, children.first) != 0) { - warn("failed to set policy for %s", user_cmnd); + warning("failed to set policy for %s", user_cmnd); goto fail; } if (kill(pid, SIGUSR1) != 0) { - warn("unable to wake up sleeping child"); + warning("unable to wake up sleeping child"); _exit(1); } @@ -259,7 +254,7 @@ systrace_attach(pid) if (switch_emulation(fd, &msg) == 0) ans.stra_policy = SYSTR_POLICY_PERMIT; else { - warnx("unsupported emulation \"%s\"", + warningx("unsupported emulation \"%s\"", msg.msg_data.msg_emul.emul); ans.stra_policy = SYSTR_POLICY_NEVER; } @@ -273,7 +268,7 @@ systrace_attach(pid) default: #ifdef SUDO_DEVEL - warnx("unexpected message type %d", msg.msg_type); + warningx("unexpected message type %d", msg.msg_type); #endif memset(&ans, 0, sizeof(ans)); ans.stra_pid = msg.msg_pid; @@ -314,7 +309,7 @@ new_child(ppid, pid) break; } if (emul == NULL) - errx(1, "unable to find native emulation!"); + errorx(1, "unable to find native emulation!"); } entry = (struct childinfo *) emalloc(sizeof(*entry)); entry->pid = pid; @@ -507,7 +502,7 @@ find_handler(pid, code) struct childinfo *child; if ((child = find_child(pid)) == NULL) { - warnx("unable to find child with pid %d", pid); + warningx("unable to find child with pid %d", pid); return(NULL); } for (sca = child->action; sca->code != -1; sca++) { @@ -572,7 +567,7 @@ update_env(fd, pid, seqnr, askp) envep = envbuf + (sizeof(envbuf) / sizeof(char *)); for (envp = envbuf; envp < envep; envp++, off += sizeof(char *)) { if (systrace_read(fd, pid, off, &ap, sizeof(ap)) != 0) { - warn("STRIOCIO"); + warning("STRIOCIO"); return(-1); } if ((*envp = ap) == NULL) @@ -703,7 +698,7 @@ update_env(fd, pid, seqnr, askp) continue; ap = inject.stri_addr + (replace[n] - buf); if (systrace_write(fd, pid, offsets[n], &ap, sizeof(ap)) != 0) { - warn("STRIOCIO"); + warning("STRIOCIO"); return(-1); } } @@ -782,7 +777,7 @@ decode_args(fd, pid, askp) off = (char *)askp->args[1]; for (cp = abuf, ep = abuf + sizeof(abuf); cp < ep; off += sizeof(char *)) { if (systrace_read(fd, pid, off, &ap, sizeof(ap)) != 0) { - warn("STRIOCIO"); + warning("STRIOCIO"); return(-1); } if (ap == NULL) { @@ -848,7 +843,7 @@ check_execv(fd, pid, seqnr, askp, cookie, policyp, errorp) /* Get processes's cwd. */ error = ioctl(fd, STRIOCGETCWD, &pid); if (error == -1 || !getcwd(user_cwd, sizeof(user_cwd))) { - warnx("cannot get working directory"); + warningx("cannot get working directory"); (void) strlcpy(user_cwd, "unknown", sizeof(user_cwd)); } diff --git a/sudo.c b/sudo.c index b4d6f8d21..5c8438dba 100644 --- a/sudo.c +++ b/sudo.c @@ -59,11 +59,6 @@ #ifdef HAVE_UNISTD_H # include <unistd.h> #endif /* HAVE_UNISTD_H */ -#ifdef HAVE_ERR_H -# include <err.h> -#else -# include "emul/err.h" -#endif /* HAVE_ERR_H */ #include <pwd.h> #include <errno.h> #include <fcntl.h> @@ -177,7 +172,7 @@ main(argc, argv, envp) environ = zero_env(envp); if (geteuid() != 0) - errx(1, "must be setuid root"); + errorx(1, "must be setuid root"); /* * Signal setup: @@ -356,10 +351,10 @@ main(argc, argv, envp) if (ISSET(validated, VALIDATE_OK)) { /* Finally tell the user if the command did not exist. */ if (cmnd_status == NOT_FOUND_DOT) { - warnx("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.", user_cmnd, user_cmnd, user_cmnd); + warningx("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.", user_cmnd, user_cmnd, user_cmnd); exit(1); } else if (cmnd_status == NOT_FOUND) { - warnx("%s: command not found", user_cmnd); + warningx("%s: command not found", user_cmnd); exit(1); } @@ -418,7 +413,7 @@ main(argc, argv, envp) /* Change to target user's homedir. */ if (chdir(runas_pw->pw_dir) == -1) - warn("unable to change directory to %s", runas_pw->pw_dir); + warning("unable to change directory to %s", runas_pw->pw_dir); } if (ISSET(sudo_mode, MODE_EDIT)) @@ -441,7 +436,7 @@ main(argc, argv, envp) /* * If we got here then the exec() failed... */ - warn("unable to execute %s", safe_cmnd); + warning("unable to execute %s", safe_cmnd); exit(127); } else if (ISSET(validated, FLAG_NO_USER) || (validated & FLAG_NO_HOST)) { log_auth(validated, 1); @@ -458,9 +453,9 @@ main(argc, argv, envp) log_auth(validated, !(cmnd_status == NOT_FOUND_DOT || cmnd_status == NOT_FOUND)); if (cmnd_status == NOT_FOUND) - warnx("%s: command not found", user_cmnd); + warningx("%s: command not found", user_cmnd); else if (cmnd_status == NOT_FOUND_DOT) - warnx("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.", user_cmnd, user_cmnd, user_cmnd); + warningx("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.", user_cmnd, user_cmnd, user_cmnd); } else { /* Just tell the user they are not allowed to run foo. */ log_auth(validated, 1); @@ -487,7 +482,7 @@ init_vars(sudo_mode) /* Sanity check command from user. */ if (user_cmnd == NULL && strlen(NewArgv[0]) >= PATH_MAX) - errx(1, "%s: File name too long", NewArgv[0]); + errorx(1, "%s: File name too long", NewArgv[0]); #ifdef HAVE_TZSET (void) tzset(); /* set the timezone if applicable */ @@ -552,7 +547,7 @@ init_vars(sudo_mode) * be run during reboot after the YP/NIS/NIS+/LDAP/etc daemon has died. */ if (sudo_mode & (MODE_INVALIDATE|MODE_KILL)) - errx(1, "uid %s does not exist in the passwd file!", pw_name); + errorx(1, "uid %s does not exist in the passwd file!", pw_name); log_error(0, "uid %s does not exist in the passwd file!", pw_name); } if (user_shell == NULL || *user_shell == '\0') @@ -577,7 +572,7 @@ init_vars(sudo_mode) if (!getcwd(user_cwd, sizeof(user_cwd))) { set_perms(PERM_ROOT); if (!getcwd(user_cwd, sizeof(user_cwd))) { - warnx("cannot get working directory"); + warningx("cannot get working directory"); (void) strlcpy(user_cwd, "unknown", sizeof(user_cwd)); } } else @@ -598,7 +593,7 @@ init_vars(sudo_mode) else if (user_shell && *user_shell) NewArgv[0] = user_shell; else - errx(1, "unable to determine shell"); + errorx(1, "unable to determine shell"); /* copy the args from NewArgv */ for (dst = NewArgv + 1; (*dst = *src) != NULL; ++src, ++dst) @@ -653,7 +648,7 @@ set_cmnd(sudo_mode) for (to = user_args, from = NewArgv + 1; *from; from++) { n = strlcpy(to, *from, size - (to - user_args)); if (n >= size - (to - user_args)) - errx(1, "internal error, init_vars() overflow"); + errorx(1, "internal error, init_vars() overflow"); to += n; *to++ = ' '; } @@ -696,7 +691,7 @@ parse_args(argc, argv) while (NewArgc > 0 && NewArgv[0][0] == '-') { if (NewArgv[0][1] != '\0' && NewArgv[0][2] != '\0') - warnx("please use single character options"); + warningx("please use single character options"); switch (NewArgv[0][1]) { case 'p': @@ -824,10 +819,10 @@ parse_args(argc, argv) SET(rval, (MODE_IMPLIED_SHELL | MODE_SHELL)); return(rval); case '\0': - warnx("'-' requires an argument"); + warningx("'-' requires an argument"); usage(1); default: - warnx("illegal option `%s'", NewArgv[0]); + warningx("illegal option `%s'", NewArgv[0]); usage(1); } NewArgc--; @@ -837,10 +832,10 @@ parse_args(argc, argv) if (user_runas != NULL) { if (rval == MODE_LIST) { if ((list_pw = sudo_getpwnam(*user_runas)) == NULL) - errx(1, "unknown user %s", *user_runas); + errorx(1, "unknown user %s", *user_runas); user_runas = NULL; } else if (!ISSET(rval, (MODE_EDIT|MODE_RUN))) { - warnx("the `-u' and '-%c' options may not be used together", excl); + warningx("the `-u' and '-%c' options may not be used together", excl); usage(1); } } @@ -874,17 +869,17 @@ open_sudoers(sudoers, keepopen) (statbuf.st_mode & 0007777) == 0400) { if (chmod(sudoers, SUDOERS_MODE) == 0) { - warnx("fixed mode on %s", sudoers); + warningx("fixed mode on %s", sudoers); SET(statbuf.st_mode, SUDOERS_MODE); if (statbuf.st_gid != SUDOERS_GID) { if (!chown(sudoers, (uid_t) -1, SUDOERS_GID)) { - warnx("set group on %s", sudoers); + warningx("set group on %s", sudoers); statbuf.st_gid = SUDOERS_GID; } else - warn("unable to set group on %s", sudoers); + warning("unable to set group on %s", sudoers); } } else - warn("unable to fix mode on %s", sudoers); + warning("unable to fix mode on %s", sudoers); } /* @@ -973,7 +968,7 @@ set_loginclass(pw) if (login_class && strcmp(login_class, "-") != 0) { if (strcmp(*user_runas, "root") != 0 && user_uid != 0) - errx(1, "only root can use -c %s", login_class); + errorx(1, "only root can use -c %s", login_class); } else { login_class = pw->pw_class; if (!login_class || !*login_class) @@ -1073,6 +1068,15 @@ get_authpw() return(pw); } +/* + * Stub for error()/errorx() + */ +void +cleanup() +{ + return; +} + /* * Tell which options are mutually exclusive and exit. */ @@ -1080,7 +1084,7 @@ static void usage_excl(exit_val) int exit_val; { - warnx("Only one of the -e, -h, -k, -K, -l, -s, -v or -V options may be used"); + warningx("Only one of the -e, -h, -k, -K, -l, -s, -v or -V options may be used"); usage(exit_val); } diff --git a/sudo.h b/sudo.h index d06c42f39..5f5c0c70c 100644 --- a/sudo.h +++ b/sudo.h @@ -26,6 +26,7 @@ #include <pathnames.h> #include <limits.h> #include "compat.h" +#include "error.h" #include "defaults.h" #include "logging.h" @@ -239,6 +240,7 @@ FILE *open_sudoers __P((const char *, int *)); void display_privs __P((struct passwd *)); void sudo_setpwent __P((void)); void sudo_endpwent __P((void)); +void cleanup __P((void)); #ifdef HAVE_SYSTRACE void systrace_attach __P((pid_t)); #endif diff --git a/sudo_edit.c b/sudo_edit.c index f335d2105..d8d136e49 100644 --- a/sudo_edit.c +++ b/sudo_edit.c @@ -41,11 +41,6 @@ #ifdef HAVE_UNISTD_H # include <unistd.h> #endif /* HAVE_UNISTD_H */ -#ifdef HAVE_ERR_H -# include <err.h> -#else -# include "emul/err.h" -#endif /* HAVE_ERR_H */ #include <ctype.h> #include <pwd.h> #include <signal.h> @@ -122,9 +117,9 @@ int sudo_edit(argc, argv) set_perms(PERM_ROOT); if (error || !S_ISREG(sb.st_mode)) { if (error) - warn("%s", *ap); + warning("%s", *ap); else - warnx("%s: not a regular file", *ap); + warningx("%s: not a regular file", *ap); if (ofd != -1) close(ofd); argc--; @@ -144,16 +139,16 @@ int sudo_edit(argc, argv) tfd = mkstemp(tf[i].tfile); set_perms(PERM_ROOT); if (tfd == -1) { - warn("mkstemp"); + warning("mkstemp"); goto cleanup; } if (ofd != -1) { while ((nread = read(ofd, buf, sizeof(buf))) != 0) { if ((nwritten = write(tfd, buf, nread)) != nread) { if (nwritten == -1) - warn("%s", tf[i].tfile); + warning("%s", tf[i].tfile); else - warnx("%s: short write", tf[i].tfile); + warningx("%s: short write", tf[i].tfile); goto cleanup; } } @@ -225,7 +220,7 @@ int sudo_edit(argc, argv) gettime(&ts1); kidpid = fork(); if (kidpid == -1) { - warn("fork"); + warning("fork"); goto cleanup; } else if (kidpid == 0) { /* child */ @@ -234,7 +229,7 @@ int sudo_edit(argc, argv) (void) sigaction(SIGCHLD, &saved_sa_chld, NULL); set_perms(PERM_FULL_USER); execvp(nargv[0], nargv); - warn("unable to execute %s", nargv[0]); + warning("unable to execute %s", nargv[0]); _exit(127); } @@ -278,10 +273,10 @@ int sudo_edit(argc, argv) set_perms(PERM_ROOT); if (error || !S_ISREG(sb.st_mode)) { if (error) - warn("%s", tf[i].tfile); + warning("%s", tf[i].tfile); else - warnx("%s: not a regular file", tf[i].tfile); - warnx("%s left unmodified", tf[i].ofile); + warningx("%s: not a regular file", tf[i].tfile); + warningx("%s left unmodified", tf[i].ofile); if (tfd != -1) close(tfd); continue; @@ -294,7 +289,7 @@ int sudo_edit(argc, argv) */ timespecsub(&ts1, &ts2, &ts2); if (timespecisset(&ts2)) { - warnx("%s unchanged", tf[i].ofile); + warningx("%s unchanged", tf[i].ofile); unlink(tf[i].tfile); close(tfd); continue; @@ -304,17 +299,17 @@ int sudo_edit(argc, argv) ofd = open(tf[i].ofile, O_WRONLY|O_TRUNC|O_CREAT, 0644); set_perms(PERM_ROOT); if (ofd == -1) { - warn("unable to write to %s", tf[i].ofile); - warnx("contents of edit session left in %s", tf[i].tfile); + warning("unable to write to %s", tf[i].ofile); + warningx("contents of edit session left in %s", tf[i].tfile); close(tfd); continue; } while ((nread = read(tfd, buf, sizeof(buf))) > 0) { if ((nwritten = write(ofd, buf, nread)) != nread) { if (nwritten == -1) - warn("%s", tf[i].ofile); + warning("%s", tf[i].ofile); else - warnx("%s: short write", tf[i].ofile); + warningx("%s: short write", tf[i].ofile); break; } } @@ -322,11 +317,11 @@ int sudo_edit(argc, argv) /* success, got EOF */ unlink(tf[i].tfile); } else if (nread < 0) { - warn("unable to read temporary file"); - warnx("contents of edit session left in %s", tf[i].tfile); + warning("unable to read temporary file"); + warningx("contents of edit session left in %s", tf[i].tfile); } else { - warn("unable to write to %s", tf[i].ofile); - warnx("contents of edit session left in %s", tf[i].tfile); + warning("unable to write to %s", tf[i].ofile); + warningx("contents of edit session left in %s", tf[i].tfile); } close(ofd); } diff --git a/testsudoers.c b/testsudoers.c index a12df6121..055fa2bbd 100644 --- a/testsudoers.c +++ b/testsudoers.c @@ -53,11 +53,6 @@ #ifdef HAVE_NETGROUP_H # include <netgroup.h> #endif /* HAVE_NETGROUP_H */ -#ifdef HAVE_ERR_H -# include <err.h> -#else -# include "emul/err.h" -#endif /* HAVE_ERR_H */ #include <ctype.h> #include <pwd.h> #include <grp.h> @@ -161,7 +156,7 @@ main(argc, argv) if (user_host == NULL) { if (gethostname(hbuf, sizeof(hbuf)) != 0) - err(1, "gethostname"); + error(1, "gethostname"); user_host = hbuf; } if ((p = strchr(user_host, '.'))) { @@ -183,7 +178,7 @@ main(argc, argv) for (to = user_args, from = NewArgv + 1; *from; from++) { n = strlcpy(to, *from, size - (to - user_args)); if (n >= size - (to - user_args)) - errx(1, "internal error, init_vars() overflow"); + errorx(1, "internal error, init_vars() overflow"); to += n; *to++ = ' '; } @@ -280,6 +275,12 @@ set_perms(perm) return; } +void +cleanup() +{ + return; +} + void print_member(m) struct member *m; diff --git a/visudo.c b/visudo.c index c6533f165..cb4248df1 100644 --- a/visudo.c +++ b/visudo.c @@ -58,11 +58,6 @@ #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ -#ifdef HAVE_ERR_H -# include <err.h> -#else -# include "emul/err.h" -#endif /* HAVE_ERR_H */ #include <ctype.h> #include <pwd.h> #include <time.h> @@ -100,7 +95,7 @@ struct sudoersfile { /* * Function prototypes */ -static RETSIGTYPE Exit __P((int)) __attribute__((__noreturn__)); +static RETSIGTYPE quit __P((int)) __attribute__((__noreturn__)); static char *get_editor __P((void)); static char whatnow __P((void)); static int check_aliases __P((int)); @@ -116,10 +111,6 @@ static void usage __P((void)) __attribute__((__noreturn__)); void yyerror __P((const char *)); void yyrestart __P((FILE *)); -void Err __P((int, const char *, ...)) - __attribute__((__noreturn__)); -void Errx __P((int, const char *, ...)) - __attribute__((__noreturn__)); /* * External globals exported by the parser @@ -193,7 +184,7 @@ main(argc, argv) /* Mock up a fake sudo_user struct. */ user_host = user_shost = user_cmnd = ""; if ((sudo_user.pw = getpwuid(getuid())) == NULL) - Errx(1, "you don't exist in the passwd database"); + errorx(1, "you don't exist in the passwd database"); /* Setup defaults data structures. */ init_defaults(); @@ -206,9 +197,9 @@ main(argc, argv) * existing errors and to pull in editor and env_editor conf values. */ if ((yyin = open_sudoers(sudoers_path, NULL)) == NULL) - Err(1, "%s", sudoers_path); + error(1, "%s", sudoers_path); if (!lock_file(fileno(yyin), SUDO_TLOCK)) - Errx(1, "%s busy, try again later", sudoers_path); + errorx(1, "%s busy, try again later", sudoers_path); init_parser(sudoers_path, 0); yyparse(); (void) update_defaults(); @@ -268,7 +259,7 @@ edit_sudoers(sp, editor, lineno) #else if (stat(sp->path, &sb) == -1) #endif - Err(1, "can't stat %s", sp->path); + error(1, "can't stat %s", sp->path); orig_size = sb.st_size; orig_mtim.tv_sec = mtim_getsec(sb); orig_mtim.tv_nsec = mtim_getnsec(sb); @@ -278,14 +269,14 @@ edit_sudoers(sp, editor, lineno) easprintf(&sp->tpath, "%s.tmp", sp->path); tfd = open(sp->tpath, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (tfd < 0) - Err(1, "%s", sp->tpath); + error(1, "%s", sp->tpath); /* Copy sp->path -> sp->tpath and reset the mtime. */ if (orig_size != 0) { (void) lseek(sp->fd, (off_t)0, SEEK_SET); while ((n = read(sp->fd, buf, sizeof(buf))) > 0) if (write(tfd, buf, n) != n) - Err(1, "write error"); + error(1, "write error"); /* Add missing newline at EOF if needed. */ if (n > 0 && buf[n - 1] != '\n') { @@ -323,18 +314,18 @@ edit_sudoers(sp, editor, lineno) * Sanity checks. */ if (stat(sp->tpath, &sb) < 0) { - warnx("cannot stat temporary file (%s), %s unchanged", + warningx("cannot stat temporary file (%s), %s unchanged", sp->tpath, sp->path); return(FALSE); } if (sb.st_size == 0 && orig_size != 0) { - warnx("zero length temporary file (%s), %s unchanged", + warningx("zero length temporary file (%s), %s unchanged", sp->tpath, sp->path); sp->modified = TRUE; return(FALSE); } } else { - warnx("editor (%s) failed, %s unchanged", editor, sp->path); + warningx("editor (%s) failed, %s unchanged", editor, sp->path); return(FALSE); } @@ -358,7 +349,7 @@ edit_sudoers(sp, editor, lineno) if (modified) sp->modified = modified; else - warnx("%s unchanged", sp->tpath); + warningx("%s unchanged", sp->tpath); return(TRUE); } @@ -383,11 +374,9 @@ reparse_sudoers(editor, strict, quiet) sp = sudoerslist.first; last = sudoerslist.last; fp = fopen(sp->tpath, "r+"); - if (fp == NULL) { - warnx("can't re-open temporary file (%s), %s unchanged.", + if (fp == NULL) + errorx(1, "can't re-open temporary file (%s), %s unchanged.", sp->tpath, sp->path); - Exit(-1); - } /* Clean slate for each parse */ user_runas = NULL; @@ -397,7 +386,7 @@ reparse_sudoers(editor, strict, quiet) /* Parse the sudoers temp file */ yyrestart(fp); if (yyparse() && parse_error != TRUE) { - warnx("unabled to parse temporary file (%s), unknown error", + warningx("unabled to parse temporary file (%s), unknown error", sp->tpath); parse_error = TRUE; } @@ -412,7 +401,8 @@ reparse_sudoers(editor, strict, quiet) switch (whatnow()) { case 'Q' : parse_error = FALSE; /* ignore parse error */ break; - case 'x' : Exit(0); + case 'x' : cleanup(); + exit(0); break; } } @@ -425,7 +415,7 @@ reparse_sudoers(editor, strict, quiet) } } if (sp == NULL) - Errx(1, "internal error, can't find %s in list!", sudoers); + errorx(1, "internal error, can't find %s in list!", sudoers); } /* If any new #include directives were added, edit them too. */ @@ -453,12 +443,12 @@ install_sudoers(sp) * we move it to sp->path things are kosher. */ if (chown(sp->tpath, SUDOERS_UID, SUDOERS_GID) != 0) { - warn("unable to set (uid, gid) of %s to (%d, %d)", + warning("unable to set (uid, gid) of %s to (%d, %d)", sp->tpath, SUDOERS_UID, SUDOERS_GID); return(FALSE); } if (chmod(sp->tpath, SUDOERS_MODE) != 0) { - warn("unable to change mode of %s to 0%o", sp->tpath, SUDOERS_MODE); + warning("unable to change mode of %s to 0%o", sp->tpath, SUDOERS_MODE); return(FALSE); } @@ -473,7 +463,7 @@ install_sudoers(sp) } else { if (errno == EXDEV) { char *av[4]; - warnx("%s and %s not on the same file system, using mv to rename", + warningx("%s and %s not on the same file system, using mv to rename", sp->tpath, sp->path); /* Build up argument vector for the command */ @@ -487,7 +477,7 @@ install_sudoers(sp) /* And run it... */ if (run_command(_PATH_MV, av)) { - warnx("command failed: '%s %s %s', %s unchanged", + warningx("command failed: '%s %s %s', %s unchanged", _PATH_MV, sp->tpath, sp->path, sp->path); (void) unlink(sp->tpath); free(sp->tpath); @@ -497,7 +487,7 @@ install_sudoers(sp) free(sp->tpath); sp->tpath = NULL; } else { - warn("error renaming %s, %s unchanged", sp->tpath, sp->path); + warning("error renaming %s, %s unchanged", sp->tpath, sp->path); (void) unlink(sp->tpath); return(FALSE); } @@ -579,7 +569,7 @@ setup_signals() */ sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; - sa.sa_handler = Exit; + sa.sa_handler = quit; (void) sigaction(SIGTERM, &sa, NULL); (void) sigaction(SIGHUP, &sa, NULL); (void) sigaction(SIGINT, &sa, NULL); @@ -601,13 +591,12 @@ run_command(path, argv) switch (pid = fork()) { case -1: - warn("unable to run %s", path); - Exit(-1); + error(1, "unable to run %s", path); break; /* NOTREACHED */ case 0: (void) sigprocmask(SIG_SETMASK, &oset, NULL); execv(path, argv); - warn("unable to run %s", path); + warning("unable to run %s", path); _exit(127); break; /* NOTREACHED */ } @@ -633,13 +622,13 @@ check_syntax(sudoers_path, quiet) if ((yyin = fopen(sudoers_path, "r")) == NULL) { if (!quiet) - warn("unable to open %s", sudoers_path); + warning("unable to open %s", sudoers_path); exit(1); } init_parser(sudoers_path, quiet); if (yyparse() && parse_error != TRUE) { if (!quiet) - warnx("failed to parse %s file, unknown error", sudoers_path); + warningx("failed to parse %s file, unknown error", sudoers_path); parse_error = TRUE; } if (!quiet){ @@ -674,14 +663,14 @@ open_sudoers(path, keepopen) entry->fd = open(entry->path, O_RDWR | O_CREAT, SUDOERS_MODE); entry->tpath = NULL; if (entry->fd == -1) { - warn("%s", entry->path); + warning("%s", entry->path); free(entry); return(NULL); } if (!lock_file(entry->fd, SUDO_TLOCK)) - Errx(1, "%s busy, try again later", entry->path); + errorx(1, "%s busy, try again later", entry->path); if ((fp = fdopen(entry->fd, "r")) == NULL) - Err(1, "%s", entry->path); + error(1, "%s", entry->path); if (sudoerslist.last == NULL) sudoerslist.first = sudoerslist.last = entry; else { @@ -694,10 +683,10 @@ open_sudoers(path, keepopen) /* Already exists, open .tmp version if there is one. */ if (entry->tpath != NULL) { if ((fp = fopen(entry->tpath, "r")) == NULL) - Err(1, "%s", entry->tpath); + error(1, "%s", entry->tpath); } else { if ((fp = fdopen(entry->fd, "r")) == NULL) - Err(1, "%s", entry->path); + error(1, "%s", entry->path); } } return(fp); @@ -724,8 +713,7 @@ get_editor() } else { if (def_env_editor) { /* If we are honoring $EDITOR this is a fatal error. */ - warnx("specified editor (%s) doesn't exist!", UserEditor); - Exit(-1); + errorx(1, "specified editor (%s) doesn't exist!", UserEditor); } else { /* Otherwise, just ignore $EDITOR. */ UserEditor = NULL; @@ -747,8 +735,7 @@ get_editor() if (stat(UserEditor, &user_editor_sb) != 0) { /* Should never happen since we already checked above. */ - warn("unable to stat editor (%s)", UserEditor); - Exit(-1); + error(1, "unable to stat editor (%s)", UserEditor); } EditorPath = estrdup(def_editor); Editor = strtok(EditorPath, ":"); @@ -794,10 +781,8 @@ get_editor() } while ((Editor = strtok(NULL, ":"))); /* Bleah, none of the editors existed! */ - if (Editor == NULL || *Editor == '\0') { - warnx("no editor found (editor path = %s)", def_editor); - Exit(-1); - } + if (Editor == NULL || *Editor == '\0') + errorx(1, "no editor found (editor path = %s)", def_editor); } return(Editor); } @@ -906,13 +891,10 @@ print_unused(v1, v2) } /* - * Unlink the sudoers temp file (if it exists) and exit. - * Used in place of a normal exit() and as a signal handler. - * A positive parameter indicates we were called as a signal handler. + * Unlink any sudoers temp files that remain. */ -static RETSIGTYPE -Exit(sig) - int sig; +void +cleanup() { struct sudoersfile *sp; @@ -920,62 +902,20 @@ Exit(sig) if (sp->tpath != NULL) (void) unlink(sp->tpath); } - -#define emsg " exiting due to signal.\n" - if (sig > 0) { - write(STDERR_FILENO, getprogname(), strlen(getprogname())); - write(STDERR_FILENO, emsg, sizeof(emsg) - 1); - _exit(sig); - } - exit(-sig); } /* - * Like err() but calls Exit() + * Unlink sudoers temp files (if any) and exit. */ -void -#ifdef __STDC__ -Err(int eval, const char *fmt, ...) -#else -Err(eval, fmt, va_alist) - int eval; - const char *fmt; - va_dcl -#endif -{ - va_list ap; -#ifdef __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - vwarn(fmt, ap); - va_end(ap); - Exit(-eval); -} - -/* - * Like errx() but calls Exit() - */ -void -#ifdef __STDC__ -Errx(int eval, const char *fmt, ...) -#else -Errx(eval, fmt, va_alist) - int eval; - const char *fmt; - va_dcl -#endif +static RETSIGTYPE +quit(signo) + int signo; { - va_list ap; -#ifdef __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - vwarnx(fmt, ap); - va_end(ap); - Exit(-eval); + cleanup(); +#define emsg " exiting due to signal.\n" + write(STDERR_FILENO, getprogname(), strlen(getprogname())); + write(STDERR_FILENO, emsg, sizeof(emsg) - 1); + _exit(signo); } static void -- 2.40.0