be translated usefully. Convert them to longer strings on error.
Also use the longer strings for atomode() and atoid().
}
if (!valid) {
if (errstr != NULL)
- *errstr = N_("invalid");
+ *errstr = N_("invalid value");
errno = EINVAL;
goto done;
}
if ((errno == ERANGE && lval == LONG_MAX) || lval > INT_MAX) {
errno = ERANGE;
if (errstr != NULL)
- *errstr = N_("too large");
+ *errstr = N_("value too large");
goto done;
}
if ((errno == ERANGE && lval == LONG_MIN) || lval < INT_MIN) {
errno = ERANGE;
if (errstr != NULL)
- *errstr = N_("too small");
+ *errstr = N_("value too small");
goto done;
}
rval = (id_t)lval;
}
if (!valid) {
if (errstr != NULL)
- *errstr = N_("invalid");
+ *errstr = N_("invalid value");
errno = EINVAL;
goto done;
}
if ((errno == ERANGE && ulval == ULONG_MAX) || ulval > UINT_MAX) {
errno = ERANGE;
if (errstr != NULL)
- *errstr = N_("too large");
+ *errstr = N_("value too large");
goto done;
}
rval = (id_t)ulval;
lval = strtol(cp, &ep, 8);
if (ep == cp || *ep != '\0') {
if (errstr != NULL)
- *errstr = N_("invalid");
+ *errstr = N_("invalid value");
errno = EINVAL;
debug_return_int(0);
}
if (lval < 0 || lval > 0777) {
if (errstr != NULL)
- *errstr = lval < 0 ? N_("too small") : N_("too large");
+ *errstr = lval < 0 ? N_("value too small") : N_("value too large");
errno = ERANGE;
debug_return_int(0);
}
#include <errno.h>
#include <limits.h>
#include <stdio.h>
-#ifdef HAVE_STDLIB_H
+#ifdef STDC_HEADERS
# include <stdlib.h>
-#endif
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
#include "missing.h"
#define DEFAULT_TEXT_DOMAIN "sudo"
#include "gettext.h"
+#ifdef HAVE_STRTONUM
+
+/*
+ * The OpenBSD strtonum error string too short to be translated sensibly.
+ * This wrapper just changes errstr as follows:
+ * invalid -> invalid value
+ * too large -> value too large
+ * too small -> value too small
+ */
+long long
+rpl_strtonum(const char *str, long long minval, long long maxval,
+ const char **errstrp)
+{
+ long long retval;
+ const char *errstr;
+
+# undef strtonum
+ retval = strtonum(str, minval, maxval, &errstr);
+ if (errstr != NULL) {
+ if (errno == EINVAL) {
+ errstr = N_("invalid value");
+ } else if (errno == ERANGE) {
+ errstr = strcmp(errstr, "too large") == 0 ?
+ N_("value too large") : N_("value too small");
+ }
+ }
+ if (errstrp != NULL)
+ *errstrp = errstr;
+ return retval;
+}
+
+#else
+
enum strtonum_err {
STN_VALID,
STN_INVALID,
* Convert a string to a number in the range [minval, maxval]
*/
long long
-strtonum(const char *str, long long minval, long long maxval,
+rpl_strtonum(const char *str, long long minval, long long maxval,
const char **errstrp)
{
const unsigned char *ustr = (const unsigned char *)str;
result = 0;
errno = EINVAL;
if (errstrp != NULL)
- *errstrp = N_("invalid");
+ *errstrp = N_("invalid value");
break;
case STN_TOOSMALL:
result = 0;
errno = ERANGE;
if (errstrp != NULL)
- *errstrp = N_("too small");
+ *errstrp = N_("value too small");
break;
case STN_TOOBIG:
result = 0;
errno = ERANGE;
if (errstrp != NULL)
- *errstrp = N_("too large");
+ *errstrp = N_("value too large");
break;
}
return result;
}
+#endif /* HAVE_STRTONUM */
fi
fi
+# We wrap OpenBSD's strtonum() to get translatable error strings.
+for ac_func in strtonum
+do :
+ ac_fn_c_check_func "$LINENO" "strtonum" "ac_cv_func_strtonum"
+if test "x$ac_cv_func_strtonum" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRTONUM 1
+_ACEOF
+
+fi
+done
+
+case " $LIBOBJS " in
+ *" strtonum.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS strtonum.$ac_objext"
+ ;;
+esac
+
if test X"$ac_cv_type_struct_timespec" != X"no"; then
ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim" "ac_cv_member_struct_stat_st_mtim" "$ac_includes_default"
if test "x$ac_cv_member_struct_stat_st_mtim" = xyes; then :
AC_LIBOBJ(snprintf)
fi
fi
+# We wrap OpenBSD's strtonum() to get translatable error strings.
+AC_CHECK_FUNCS(strtonum)
+AC_LIBOBJ(strtonum)
if test X"$ac_cv_type_struct_timespec" != X"no"; then
AC_CHECK_MEMBER([struct stat.st_mtim], [AC_DEFINE(HAVE_ST_MTIM)]
[AC_CHECK_MEMBER([struct stat.st_mtim.st__tim], AC_DEFINE(HAVE_ST__TIM))],
int sig2str(int, char *);
#endif
#ifndef HAVE_STRTONUM
-long long strtonum(const char *, long long, long long, const char **);
+long long rpl_strtonum(const char *, long long, long long, const char **);
+# undef strtonum
+# define strtonum rpl_strtonum
#endif
void initprogname(const char *);
i = strtonum(val, INT_MIN, INT_MAX, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
- "%s is %s", val, errstr);
+ "%s: %s", val, errstr);
debug_return_bool(false);
}
def->sd_un.ival = i;
u = strtonum(val, 0, UINT_MAX, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
- "%s is %s", val, errstr);
+ "%s: %s", val, errstr);
debug_return_bool(false);
}
/* XXX - should have uival */
if (errstr != NULL) {
if (errno != ERANGE) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
- "bad maxseq: %s is %s", maxval, errstr);
+ "bad maxseq: %s: %s", maxval, errstr);
debug_return_bool(false);
}
/* Out of range, clamp to SESSID_MAX as documented. */
case CONF_INT:
*(int *)(cur->valp) = strtonum(value, INT_MIN, INT_MAX, &errstr);
if (errstr != NULL) {
- warningx(U_("%s: %s: value %s out of range)"),
- path_ldap_conf, keyword, value);
+ warningx(U_("%s: %s: %s: %s"),
+ path_ldap_conf, keyword, value, U_(errstr));
}
break;
case CONF_STR:
li->tstamp = strtonum(cp, LLONG_MIN, LLONG_MAX, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
- "%s: timestamp %s is %s", logfile, cp, errstr);
+ "%s: timestamp %s: %s", logfile, cp, errstr);
goto bad;
}
li->rows = strtonum(cp, 1, INT_MAX, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
- "%s: tty rows %s is %s", logfile, cp, errstr);
+ "%s: tty rows %s: %s", logfile, cp, errstr);
}
if (ep != NULL) {
cp = ep + 1;
li->cols = strtonum(cp, 1, INT_MAX, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
- "%s: tty cols %s is %s", logfile, cp, errstr);
+ "%s: tty cols %s: %s", logfile, cp, errstr);
}
}
}
char *cp, **env_add, **settings;
const char *runas_user = NULL;
const char *runas_group = NULL;
- const char *debug_flags, *errstr;
+ const char *debug_flags;
int nenv = 0;
int env_size = 32;
debug_decl(parse_args, SUDO_DEBUG_ARGS)
SET(flags, MODE_BACKGROUND);
break;
case 'C':
- strtonum(optarg, 4, INT_MAX, &errstr);
- if (errstr != NULL) {
- warningx(U_("the argument to -C was %s"), U_(errstr));
+ if (strtonum(optarg, 3, INT_MAX, NULL) == 0) {
+ warningx(_("the argument to -C must be a number greater than or equal to 3"));
usage(1);
}
sudo_settings[ARG_CLOSEFROM].value = optarg;
dev_t tdev = strtonum(cp, INT_MIN, INT_MAX, &errstr);
if (errstr) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
- "%s: tty device number %s", path, errstr);
+ "%s: tty device %s: %s", path, cp, errstr);
}
if (tdev > 0)
tty = sudo_ttyname_dev(tdev);