mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-22 18:08:23 +00:00
Add check for C99 compliant (v)snprintf function.
This commit is contained in:
parent
0a47860ef7
commit
42b1e4a9c4
1
MANIFEST
1
MANIFEST
@ -157,6 +157,7 @@ install-sh
|
|||||||
ltmain.sh
|
ltmain.sh
|
||||||
m4/ax_check_compile_flag.m4
|
m4/ax_check_compile_flag.m4
|
||||||
m4/ax_check_link_flag.m4
|
m4/ax_check_link_flag.m4
|
||||||
|
m4/ax_func_snprintf.m4
|
||||||
m4/libtool.m4
|
m4/libtool.m4
|
||||||
m4/ltoptions.m4
|
m4/ltoptions.m4
|
||||||
m4/ltsugar.m4
|
m4/ltsugar.m4
|
||||||
|
1
aclocal.m4
vendored
1
aclocal.m4
vendored
@ -128,6 +128,7 @@ AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET],
|
|||||||
|
|
||||||
m4_include([m4/ax_check_compile_flag.m4])
|
m4_include([m4/ax_check_compile_flag.m4])
|
||||||
m4_include([m4/ax_check_link_flag.m4])
|
m4_include([m4/ax_check_link_flag.m4])
|
||||||
|
m4_include([m4/ax_func_snprintf.m4])
|
||||||
m4_include([m4/libtool.m4])
|
m4_include([m4/libtool.m4])
|
||||||
m4_include([m4/ltoptions.m4])
|
m4_include([m4/ltoptions.m4])
|
||||||
m4_include([m4/ltsugar.m4])
|
m4_include([m4/ltsugar.m4])
|
||||||
|
@ -41,7 +41,9 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_SNPRINTF) || !defined(HAVE_VASPRINTF) || !defined(HAVE_ASPRINTF)
|
#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_SNPRINTF) || \
|
||||||
|
!defined(HAVE_VASPRINTF) || !defined(HAVE_ASPRINTF) || \
|
||||||
|
defined(PREFER_PORTABLE_SNPRINTF)
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -668,16 +670,16 @@ done:
|
|||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_VSNPRINTF
|
#if !defined(HAVE_VSNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
|
||||||
int
|
int
|
||||||
vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
|
vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
|
|
||||||
return xxxprintf(&str, n, 0, fmt, ap);
|
return xxxprintf(&str, n, 0, fmt, ap);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_VSNPRINTF */
|
#endif /* !HAVE_VSNPRINTF || PREFER_PORTABLE_SNPRINTF */
|
||||||
|
|
||||||
#ifndef HAVE_SNPRINTF
|
#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
|
||||||
int
|
int
|
||||||
snprintf(char *str, size_t n, char const *fmt, ...)
|
snprintf(char *str, size_t n, char const *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -689,18 +691,18 @@ snprintf(char *str, size_t n, char const *fmt, ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SNPRINTF */
|
#endif /* !HAVE_SNPRINTF || PREFER_PORTABLE_SNPRINTF */
|
||||||
|
|
||||||
#ifndef HAVE_VASPRINTF
|
#if !defined(HAVE_VASPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
|
||||||
int
|
int
|
||||||
vasprintf(char **str, const char *fmt, va_list ap)
|
vasprintf(char **str, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
|
|
||||||
return xxxprintf(str, 0, 1, fmt, ap);
|
return xxxprintf(str, 0, 1, fmt, ap);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_VASPRINTF */
|
#endif /* !HAVE_VASPRINTF || PREFER_PORTABLE_SNPRINTF */
|
||||||
|
|
||||||
#ifndef HAVE_ASPRINTF
|
#if !defined(HAVE_ASPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
|
||||||
int
|
int
|
||||||
asprintf(char **str, char const *fmt, ...)
|
asprintf(char **str, char const *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -712,6 +714,6 @@ asprintf(char **str, char const *fmt, ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_ASPRINTF */
|
#endif /* !HAVE_ASPRINTF || PREFER_PORTABLE_SNPRINTF */
|
||||||
|
|
||||||
#endif /* !HAVE_VSNPRINTF || !HAVE_SNPRINTF || !HAVE_VASPRINTF || !HAVE_ASPRINTF */
|
#endif /* !HAVE_VSNPRINTF || !HAVE_SNPRINTF || !HAVE_VASPRINTF || !HAVE_ASPRINTF || PREFER_PORTABLE_SNPRINTF */
|
||||||
|
@ -937,6 +937,9 @@
|
|||||||
ones. */
|
ones. */
|
||||||
#undef PC_INSULTS
|
#undef PC_INSULTS
|
||||||
|
|
||||||
|
/* Enable replacement (v)snprintf if system (v)snprintf is broken. */
|
||||||
|
#undef PREFER_PORTABLE_SNPRINTF
|
||||||
|
|
||||||
/* The syslog priority sudo will use for unsuccessful attempts/errors. */
|
/* The syslog priority sudo will use for unsuccessful attempts/errors. */
|
||||||
#undef PRI_FAILURE
|
#undef PRI_FAILURE
|
||||||
|
|
||||||
|
137
configure
vendored
137
configure
vendored
@ -17851,7 +17851,7 @@ esac
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
for ac_func in snprintf vsnprintf asprintf vasprintf
|
for ac_func in snprintf vsnprintf
|
||||||
do :
|
do :
|
||||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||||
@ -17860,11 +17860,134 @@ if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
|
|||||||
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
else
|
|
||||||
NEED_SNPRINTF=1
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working snprintf" >&5
|
||||||
|
$as_echo_n "checking for working snprintf... " >&6; }
|
||||||
|
if ${ac_cv_have_working_snprintf+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
if test "$cross_compiling" = yes; then :
|
||||||
|
ac_cv_have_working_snprintf=cross
|
||||||
|
else
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
char bufs[5] = { 'x', 'x', 'x', '\0', '\0' };
|
||||||
|
char bufd[5] = { 'x', 'x', 'x', '\0', '\0' };
|
||||||
|
int i;
|
||||||
|
i = snprintf (bufs, 2, "%s", "111");
|
||||||
|
if (strcmp (bufs, "1")) exit (1);
|
||||||
|
if (i != 3) exit (1);
|
||||||
|
i = snprintf (bufd, 2, "%d", 111);
|
||||||
|
if (strcmp (bufd, "1")) exit (1);
|
||||||
|
if (i != 3) exit (1);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_run "$LINENO"; then :
|
||||||
|
ac_cv_have_working_snprintf=yes
|
||||||
|
else
|
||||||
|
ac_cv_have_working_snprintf=no
|
||||||
|
fi
|
||||||
|
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
|
||||||
|
conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_working_snprintf" >&5
|
||||||
|
$as_echo "$ac_cv_have_working_snprintf" >&6; }
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vsnprintf" >&5
|
||||||
|
$as_echo_n "checking for working vsnprintf... " >&6; }
|
||||||
|
if ${ac_cv_have_working_vsnprintf+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
if test "$cross_compiling" = yes; then :
|
||||||
|
ac_cv_have_working_vsnprintf=cross
|
||||||
|
else
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
int my_vsnprintf (char *buf, const char *tmpl, ...)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
va_list args;
|
||||||
|
va_start (args, tmpl);
|
||||||
|
i = vsnprintf (buf, 2, tmpl, args);
|
||||||
|
va_end (args);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
char bufs[5] = { 'x', 'x', 'x', '\0', '\0' };
|
||||||
|
char bufd[5] = { 'x', 'x', 'x', '\0', '\0' };
|
||||||
|
int i;
|
||||||
|
i = my_vsnprintf (bufs, "%s", "111");
|
||||||
|
if (strcmp (bufs, "1")) exit (1);
|
||||||
|
if (i != 3) exit (1);
|
||||||
|
i = my_vsnprintf (bufd, "%d", 111);
|
||||||
|
if (strcmp (bufd, "1")) exit (1);
|
||||||
|
if (i != 3) exit (1);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_run "$LINENO"; then :
|
||||||
|
ac_cv_have_working_vsnprintf=yes
|
||||||
|
else
|
||||||
|
ac_cv_have_working_vsnprintf=no
|
||||||
|
fi
|
||||||
|
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
|
||||||
|
conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_working_vsnprintf" >&5
|
||||||
|
$as_echo "$ac_cv_have_working_vsnprintf" >&6; }
|
||||||
|
if test x$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf != "xyesyes"; then
|
||||||
|
case " $LIBOBJS " in
|
||||||
|
*" snprintf.$ac_objext "* ) ;;
|
||||||
|
*) LIBOBJS="$LIBOBJS snprintf.$ac_objext"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Replacing missing/broken (v)snprintf() with sudo's version." >&5
|
||||||
|
$as_echo "$as_me: WARNING: Replacing missing/broken (v)snprintf() with sudo's version." >&2;}
|
||||||
|
|
||||||
|
$as_echo "#define PREFER_PORTABLE_SNPRINTF 1" >>confdefs.h
|
||||||
|
|
||||||
|
fi
|
||||||
|
for ac_func in asprintf vasprintf
|
||||||
|
do :
|
||||||
|
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||||
|
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||||
|
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if test X"$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf" = X"yesyes"; then
|
||||||
|
# Don't add snprintf to LIBOBJS if it is already present.
|
||||||
|
if test X"$ac_cv_func_asprintf$ac_cv_func_vasprintf" != X"yesyes"; then
|
||||||
|
case " $LIBOBJS " in
|
||||||
|
*" snprintf.$ac_objext "* ) ;;
|
||||||
|
*) LIBOBJS="$LIBOBJS snprintf.$ac_objext"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
fi
|
||||||
|
fi
|
||||||
if test X"$ac_cv_type_struct_timespec" != X"no"; then
|
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"
|
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 :
|
if test "x$ac_cv_member_struct_stat_st_mtim" = xyes; then :
|
||||||
@ -18174,14 +18297,6 @@ _ACEOF
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -n "$NEED_SNPRINTF"; then
|
|
||||||
case " $LIBOBJS " in
|
|
||||||
*" snprintf.$ac_objext "* ) ;;
|
|
||||||
*) LIBOBJS="$LIBOBJS snprintf.$ac_objext"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
fi
|
|
||||||
ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket"
|
ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket"
|
||||||
if test "x$ac_cv_func_socket" = xyes; then :
|
if test "x$ac_cv_func_socket" = xyes; then :
|
||||||
|
|
||||||
|
16
configure.ac
16
configure.ac
@ -2401,7 +2401,14 @@ AC_CHECK_FUNCS(mkstemps mkdtemp, [], [
|
|||||||
AC_CHECK_FUNCS(random lrand48, [break])
|
AC_CHECK_FUNCS(random lrand48, [break])
|
||||||
AC_LIBOBJ(mktemp)
|
AC_LIBOBJ(mktemp)
|
||||||
])
|
])
|
||||||
AC_CHECK_FUNCS(snprintf vsnprintf asprintf vasprintf, , [NEED_SNPRINTF=1])
|
AX_FUNC_SNPRINTF
|
||||||
|
AC_CHECK_FUNCS(asprintf vasprintf)
|
||||||
|
if test X"$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf" = X"yesyes"; then
|
||||||
|
# Don't add snprintf to LIBOBJS if it is already present.
|
||||||
|
if test X"$ac_cv_func_asprintf$ac_cv_func_vasprintf" != X"yesyes"; then
|
||||||
|
AC_LIBOBJ(snprintf)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
if test X"$ac_cv_type_struct_timespec" != X"no"; then
|
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], [AC_DEFINE(HAVE_ST_MTIM)]
|
||||||
[AC_CHECK_MEMBER([struct stat.st_mtim.st__tim], AC_DEFINE(HAVE_ST__TIM))],
|
[AC_CHECK_MEMBER([struct stat.st_mtim.st__tim], AC_DEFINE(HAVE_ST__TIM))],
|
||||||
@ -2466,13 +2473,6 @@ AC_INCLUDES_DEFAULT
|
|||||||
#include <$ac_header_dirent>
|
#include <$ac_header_dirent>
|
||||||
])
|
])
|
||||||
dnl
|
dnl
|
||||||
dnl If NEED_SNPRINTF is set, add snprintf.c to LIBOBJS
|
|
||||||
dnl (it contains snprintf, vsnprintf, asprintf, and vasprintf)
|
|
||||||
dnl
|
|
||||||
if test -n "$NEED_SNPRINTF"; then
|
|
||||||
AC_LIBOBJ(snprintf)
|
|
||||||
fi
|
|
||||||
dnl
|
|
||||||
dnl If socket(2) not in libc, check -lsocket and -linet
|
dnl If socket(2) not in libc, check -lsocket and -linet
|
||||||
dnl May need to link with *both* -lnsl and -lsocket due to unresolved symbols
|
dnl May need to link with *both* -lnsl and -lsocket due to unresolved symbols
|
||||||
dnl
|
dnl
|
||||||
|
82
m4/ax_func_snprintf.m4
Normal file
82
m4/ax_func_snprintf.m4
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
# ===========================================================================
|
||||||
|
# http://www.gnu.org/software/autoconf-archive/ax_func_snprintf.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_FUNC_SNPRINTF
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# Checks for a fully C99 compliant snprintf, in particular checks whether
|
||||||
|
# it does bounds checking and returns the correct string length; does the
|
||||||
|
# same check for vsnprintf. If no working snprintf or vsnprintf is found,
|
||||||
|
# request a replacement and warn the user about it. Note: the mentioned
|
||||||
|
# replacement is freely available and may be used in any project
|
||||||
|
# regardless of it's license.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Ruediger Kuhlmann <info@ruediger-kuhlmann.de>
|
||||||
|
#
|
||||||
|
# Copying and distribution of this file, with or without modification, are
|
||||||
|
# permitted in any medium without royalty provided the copyright notice
|
||||||
|
# and this notice are preserved. This file is offered as-is, without any
|
||||||
|
# warranty.
|
||||||
|
|
||||||
|
#serial 5
|
||||||
|
|
||||||
|
AC_DEFUN([AX_FUNC_SNPRINTF],
|
||||||
|
[AC_CHECK_FUNCS(snprintf vsnprintf)
|
||||||
|
AC_MSG_CHECKING(for working snprintf)
|
||||||
|
AC_CACHE_VAL(ac_cv_have_working_snprintf,
|
||||||
|
[AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
char bufs[5] = { 'x', 'x', 'x', '\0', '\0' };
|
||||||
|
char bufd[5] = { 'x', 'x', 'x', '\0', '\0' };
|
||||||
|
int i;
|
||||||
|
i = snprintf (bufs, 2, "%s", "111");
|
||||||
|
if (strcmp (bufs, "1")) exit (1);
|
||||||
|
if (i != 3) exit (1);
|
||||||
|
i = snprintf (bufd, 2, "%d", 111);
|
||||||
|
if (strcmp (bufd, "1")) exit (1);
|
||||||
|
if (i != 3) exit (1);
|
||||||
|
exit(0);
|
||||||
|
}]])],[ac_cv_have_working_snprintf=yes],[ac_cv_have_working_snprintf=no],[ac_cv_have_working_snprintf=cross])])
|
||||||
|
AC_MSG_RESULT([$ac_cv_have_working_snprintf])
|
||||||
|
AC_MSG_CHECKING(for working vsnprintf)
|
||||||
|
AC_CACHE_VAL(ac_cv_have_working_vsnprintf,
|
||||||
|
[AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
int my_vsnprintf (char *buf, const char *tmpl, ...)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
va_list args;
|
||||||
|
va_start (args, tmpl);
|
||||||
|
i = vsnprintf (buf, 2, tmpl, args);
|
||||||
|
va_end (args);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
char bufs[5] = { 'x', 'x', 'x', '\0', '\0' };
|
||||||
|
char bufd[5] = { 'x', 'x', 'x', '\0', '\0' };
|
||||||
|
int i;
|
||||||
|
i = my_vsnprintf (bufs, "%s", "111");
|
||||||
|
if (strcmp (bufs, "1")) exit (1);
|
||||||
|
if (i != 3) exit (1);
|
||||||
|
i = my_vsnprintf (bufd, "%d", 111);
|
||||||
|
if (strcmp (bufd, "1")) exit (1);
|
||||||
|
if (i != 3) exit (1);
|
||||||
|
exit(0);
|
||||||
|
}]])],[ac_cv_have_working_vsnprintf=yes],[ac_cv_have_working_vsnprintf=no],[ac_cv_have_working_vsnprintf=cross])])
|
||||||
|
AC_MSG_RESULT([$ac_cv_have_working_vsnprintf])
|
||||||
|
if test x$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf != "xyesyes"; then
|
||||||
|
AC_LIBOBJ(snprintf)
|
||||||
|
AC_MSG_WARN([Replacing missing/broken (v)snprintf() with sudo's version.])
|
||||||
|
AC_DEFINE(PREFER_PORTABLE_SNPRINTF, 1, [Enable replacement (v)snprintf if system (v)snprintf is broken.])
|
||||||
|
fi])
|
Loading…
x
Reference in New Issue
Block a user