aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/copyright.yml3
-rw-r--r--.github/workflows/depends.yml2
-rw-r--r--CMakeLists.txt11
-rw-r--r--Makefile2
-rw-r--r--contrib/depends/Makefile17
-rwxr-xr-xcontrib/depends/config.guess1687
-rwxr-xr-xcontrib/depends/config.sub2738
-rw-r--r--contrib/depends/hosts/android.mk1
-rw-r--r--contrib/depends/hosts/darwin.mk2
-rw-r--r--contrib/depends/hosts/freebsd.mk1
-rw-r--r--contrib/depends/hosts/linux.mk2
-rw-r--r--contrib/depends/hosts/mingw32.mk2
-rw-r--r--contrib/depends/toolchain.cmake.in2
-rw-r--r--contrib/epee/include/net/http_base.h1
-rw-r--r--contrib/epee/include/net/levin_protocol_handler.h193
-rw-r--r--contrib/epee/include/serialization/wire/write.h9
-rw-r--r--contrib/epee/include/storages/portable_storage_from_bin.h2
-rw-r--r--contrib/epee/src/http_auth.cpp6
-rw-r--r--src/common/dns_utils.cpp44
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.cpp20
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.h2
-rw-r--r--src/cryptonote_basic/merge_mining.cpp10
-rw-r--r--src/cryptonote_basic/merge_mining.h4
-rw-r--r--src/cryptonote_basic/tx_extra.h10
-rw-r--r--src/p2p/net_node.h1
-rw-r--r--src/rpc/core_rpc_server.cpp34
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h2
-rw-r--r--src/rpc/daemon_messages.cpp201
-rw-r--r--src/rpc/rpc_payment.h8
-rw-r--r--src/rpc/zmq_server.cpp23
-rw-r--r--src/serialization/container.h33
-rw-r--r--src/serialization/containers.h99
-rw-r--r--src/serialization/debug_archive.h10
-rw-r--r--src/serialization/difficulty_type.h2
-rw-r--r--src/serialization/pair.h4
-rw-r--r--src/serialization/serialization.h125
-rw-r--r--src/serialization/tuple.h2
-rw-r--r--src/serialization/variant.h45
-rw-r--r--src/simplewallet/simplewallet.cpp83
-rw-r--r--src/wallet/message_transporter.cpp13
-rw-r--r--src/wallet/wallet2.cpp245
-rw-r--r--src/wallet/wallet2.h65
-rw-r--r--src/wallet/wallet_errors.h10
-rw-r--r--src/wallet/wallet_rpc_server.cpp22
-rw-r--r--src/wallet/wallet_rpc_server.h4
-rw-r--r--src/wallet/wallet_rpc_server_commands_defs.h19
-rw-r--r--tests/CMakeLists.txt2
-rw-r--r--tests/core_proxy/CMakeLists.txt49
-rw-r--r--tests/core_proxy/core_proxy.cpp295
-rw-r--r--tests/core_proxy/core_proxy.h119
-rwxr-xr-xtests/functional_tests/transfer.py81
-rw-r--r--tests/unit_tests/crypto.cpp10
-rw-r--r--tests/unit_tests/epee_serialization.cpp87
-rw-r--r--tests/unit_tests/epee_utils.cpp57
-rw-r--r--tests/unit_tests/json_serialization.cpp7
-rw-r--r--tests/unit_tests/node_server.cpp4
-rw-r--r--tests/unit_tests/serialization.cpp39
-rw-r--r--utils/gpg_keys/0xfffc0000.asc13
-rw-r--r--utils/gpg_keys/tobtoht.asc51
-rw-r--r--utils/python-rpc/framework/wallet.py3
60 files changed, 3556 insertions, 3082 deletions
diff --git a/.github/workflows/copyright.yml b/.github/workflows/copyright.yml
index 16bd43ea7..27e0bb457 100644
--- a/.github/workflows/copyright.yml
+++ b/.github/workflows/copyright.yml
@@ -1,5 +1,6 @@
name: ci/gh-actions/copyright
on:
+ workflow_dispatch:
schedule:
- cron: '0 0 1 1 *'
jobs:
@@ -45,7 +46,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "Copyright: Update to ${{ env.YEAR }}"
committer: GitHub <noreply@github.com>
- author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
+ author: copyCat <copy@Cat.com>
signoff: false
branch: bump-copyright-year
delete-branch: true
diff --git a/.github/workflows/depends.yml b/.github/workflows/depends.yml
index 4827bb51d..c534965e8 100644
--- a/.github/workflows/depends.yml
+++ b/.github/workflows/depends.yml
@@ -105,7 +105,7 @@ jobs:
${{env.CCACHE_SETTINGS}}
make depends target=${{ matrix.toolchain.host }} -j2
- uses: actions/upload-artifact@v3
- if: ${{ matrix.toolchain.host == 'x86_64-w64-mingw32' || matrix.toolchain.host == 'x86_64-apple-darwin11' || matrix.toolchain.host == 'x86_64-unknown-linux-gnu' }}
+ if: ${{ matrix.toolchain.host == 'x86_64-w64-mingw32' || matrix.toolchain.host == 'x86_64-apple-darwin' || matrix.toolchain.host == 'x86_64-unknown-linux-gnu' }}
with:
name: ${{ matrix.toolchain.name }}
path: |
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 99baba2ba..83d760c66 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -28,6 +28,9 @@
#
# Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+cmake_minimum_required(VERSION 3.5)
+message(STATUS "CMake version ${CMAKE_VERSION}")
+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
list(INSERT CMAKE_MODULE_PATH 0
@@ -37,15 +40,15 @@ include(CheckCXXCompilerFlag)
include(CheckLinkerFlag)
include(CheckLibraryExists)
include(CheckFunctionExists)
+if (POLICY CMP0148)
+ cmake_policy(SET CMP0148 OLD) # https://cmake.org/cmake/help/latest/policy/CMP0148.html
+endif()
include(FindPythonInterp)
if (IOS)
INCLUDE(CmakeLists_IOS.txt)
endif()
-cmake_minimum_required(VERSION 3.5)
-message(STATUS "CMake version ${CMAKE_VERSION}")
-
project(monero)
option (USE_CCACHE "Use ccache if a usable instance is found" ON)
@@ -219,7 +222,7 @@ function(forbid_undefined_symbols)
file(MAKE_DIRECTORY "${TEST_PROJECT}")
file(WRITE "${TEST_PROJECT}/CMakeLists.txt"
[=[
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.5)
project(test)
option(EXPECT_SUCCESS "" ON)
file(WRITE "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" "void undefined_symbol(); void symbol() { undefined_symbol(); }")
diff --git a/Makefile b/Makefile
index cb6a24aab..99c8ed31d 100644
--- a/Makefile
+++ b/Makefile
@@ -104,7 +104,7 @@ release-all:
release-static:
mkdir -p $(builddir)/release
- cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE)
+ cd $(builddir)/release && cmake -D STATIC=ON -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE)
coverage:
mkdir -p $(builddir)/debug
diff --git a/contrib/depends/Makefile b/contrib/depends/Makefile
index dfb0f3cb4..ce74de184 100644
--- a/contrib/depends/Makefile
+++ b/contrib/depends/Makefile
@@ -68,21 +68,6 @@ $(host_arch)_$(host_os)_prefix=$(BASEDIR)/$(host)
$(host_arch)_$(host_os)_host=$(host)
host_prefix=$($(host_arch)_$(host_os)_prefix)
build_prefix=$(host_prefix)/native
-ifeq ($(host_os),mingw32)
-host_cmake=Windows
-endif
-ifeq ($(host_os),linux)
-host_cmake=Linux
-endif
-ifeq ($(host_os),freebsd)
-host_cmake=FreeBSD
-endif
-ifeq ($(host_os),darwin)
-host_cmake=Darwin
-endif
-ifeq ($(host_os),android)
-host_cmake=Android
-endif
AT_$(V):=
AT_:=@
@@ -151,7 +136,7 @@ $(host_prefix)/share/toolchain.cmake : toolchain.cmake.in $(host_prefix)/.stamp_
-e 's|@debug@|$(DEBUG)|' \
-e 's|@release_type@|$(release_type)|' \
-e 's|@build_tests@|$(build_tests)|' \
- -e 's|@depends@|$(host_cmake)|' \
+ -e 's|@cmake_system_name@|$($(host_os)_cmake_system)|' \
-e 's|@prefix@|$($(host_arch)_$(host_os)_prefix)|'\
-e 's|@arch@|$(host_arch)|'\
$< > $@
diff --git a/contrib/depends/config.guess b/contrib/depends/config.guess
index 69ed3e573..cdfc43920 100755
--- a/contrib/depends/config.guess
+++ b/contrib/depends/config.guess
@@ -1,12 +1,14 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2017 Free Software Foundation, Inc.
+# Copyright 1992-2023 Free Software Foundation, Inc.
-timestamp='2017-03-05'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2023-08-22'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@@ -15,7 +17,7 @@ timestamp='2017-03-05'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -27,19 +29,27 @@ timestamp='2017-03-05'
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
#
# Please send patches to <config-patches@gnu.org>.
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX. However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
+
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
-Output the configuration name of the system \`$me' is run on.
+Output the configuration name of the system '$me' is run on.
-Operation modes:
+Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
@@ -50,13 +60,13 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2017 Free Software Foundation, Inc.
+Copyright 1992-2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
-Try \`$me --help' for more information."
+Try '$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
@@ -84,78 +94,107 @@ if test $# != 0; then
exit 1
fi
-trap 'exit 1' 1 2 15
+# Just in case it came from the environment.
+GUESS=
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
+# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still
+# use 'HOST_CC' if defined, but it is deprecated.
# Portable tmp directory creation inspired by the Autoconf team.
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
- for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found ;
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
+tmp=
+# shellcheck disable=SC2172
+trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15
+
+set_cc_for_build() {
+ # prevent multiple calls if $tmp is already set
+ test "$tmp" && return 0
+ : "${TMPDIR=/tmp}"
+ # shellcheck disable=SC2039,SC3028
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
+ dummy=$tmp/dummy
+ case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
+ ,,) echo "int x;" > "$dummy.c"
+ for driver in cc gcc c89 c99 ; do
+ if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
+ CC_FOR_BUILD=$driver
+ break
+ fi
+ done
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+ esac
+}
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+if test -f /.attbin/uname ; then
PATH=$PATH:/.attbin ; export PATH
fi
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-case "${UNAME_SYSTEM}" in
+case $UNAME_SYSTEM in
Linux|GNU|GNU/*)
- # If the system lacks a compiler, then just pick glibc.
- # We could probably try harder.
- LIBC=gnu
+ LIBC=unknown
- eval $set_cc_for_build
- cat <<-EOF > $dummy.c
+ set_cc_for_build
+ cat <<-EOF > "$dummy.c"
+ #if defined(__ANDROID__)
+ LIBC=android
+ #else
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
#elif defined(__dietlibc__)
LIBC=dietlibc
- #else
+ #elif defined(__GLIBC__)
LIBC=gnu
+ #else
+ #include <stdarg.h>
+ /* First heuristic to detect musl libc. */
+ #ifdef __DEFINED_va_list
+ LIBC=musl
+ #endif
+ #endif
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ eval "$cc_set_libc"
+
+ # Second heuristic to detect musl libc.
+ if [ "$LIBC" = unknown ] &&
+ command -v ldd >/dev/null &&
+ ldd --version 2>&1 | grep -q ^musl; then
+ LIBC=musl
+ fi
+
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ if [ "$LIBC" = unknown ]; then
+ LIBC=gnu
+ fi
;;
esac
# Note: order is significant - the case branches are not exclusive.
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
@@ -167,32 +206,32 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
- /sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || \
+ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \
+ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
+ case $UNAME_MACHINE_ARCH in
+ aarch64eb) machine=aarch64_be-unknown ;;
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
earmv*)
- arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
- endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
+ arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
machine=${arch}${endian}-unknown
;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ *) machine=$UNAME_MACHINE_ARCH-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently (or will in the future) and ABI.
- case "${UNAME_MACHINE_ARCH}" in
+ case $UNAME_MACHINE_ARCH in
earm*)
os=netbsdelf
;;
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
+ set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
then
@@ -208,10 +247,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
;;
esac
# Determine ABI tags.
- case "${UNAME_MACHINE_ARCH}" in
+ case $UNAME_MACHINE_ARCH in
earm*)
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
- abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+ abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
;;
esac
# The OS release
@@ -219,47 +258,68 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
+ case $UNAME_VERSION in
Debian*)
release='-gnu'
;;
*)
- release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
+ release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}${abi}"
- exit ;;
+ GUESS=$machine-${os}${release}${abi-}
+ ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
- exit ;;
+ GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE
+ ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
- exit ;;
+ GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE
+ ;;
+ *:SecBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE
+ ;;
*:LibertyBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
- exit ;;
+ GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE
+ ;;
+ *:MidnightBSD:*:*)
+ GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE
+ ;;
*:ekkoBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE
+ ;;
*:SolidBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE
+ ;;
+ *:OS108:*:*)
+ GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE
+ ;;
macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
+ GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE
+ ;;
*:MirBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE
+ ;;
*:Sortix:*:*)
- echo ${UNAME_MACHINE}-unknown-sortix
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-sortix
+ ;;
+ *:Twizzler:*:*)
+ GUESS=$UNAME_MACHINE-unknown-twizzler
+ ;;
+ *:Redox:*:*)
+ GUESS=$UNAME_MACHINE-unknown-redox
+ ;;
+ mips:OSF1:*.*)
+ GUESS=mips-dec-osf1
+ ;;
alpha:OSF1:*:*)
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ trap '' 0
case $UNAME_RELEASE in
*4.0)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
@@ -273,7 +333,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
- case "$ALPHA_CPU_TYPE" in
+ case $ALPHA_CPU_TYPE in
"EV4 (21064)")
UNAME_MACHINE=alpha ;;
"EV4.5 (21064)")
@@ -310,126 +370,121 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
- # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
- exitcode=$?
- trap '' 0
- exit $exitcode ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
+ OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ GUESS=$UNAME_MACHINE-dec-osf$OSF_REL
+ ;;
Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
+ GUESS=m68k-unknown-sysv4
+ ;;
*:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-amigaos
+ ;;
*:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-morphos
+ ;;
*:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
+ GUESS=i370-ibm-openedition
+ ;;
*:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
+ GUESS=s390-ibm-zvmoe
+ ;;
*:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
+ GUESS=powerpc-ibm-os400
+ ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit ;;
+ GUESS=arm-acorn-riscix$UNAME_RELEASE
+ ;;
arm*:riscos:*:*|arm*:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
+ GUESS=arm-unknown-riscos
+ ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
+ GUESS=hppa1.1-hitachi-hiuxmpp
+ ;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
+ case `(/bin/universe) 2>/dev/null` in
+ att) GUESS=pyramid-pyramid-sysv3 ;;
+ *) GUESS=pyramid-pyramid-bsd ;;
+ esac
+ ;;
NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
+ GUESS=pyramid-pyramid-svr4
+ ;;
DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
+ GUESS=sparc-icl-nx6
+ ;;
DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
+ sparc) GUESS=sparc-icl-nx7 ;;
+ esac
+ ;;
s390x:SunOS:*:*)
- echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL
+ ;;
sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-hal-solaris2$SUN_REL
+ ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-sun-solaris2$SUN_REL
+ ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- echo i386-pc-auroraux${UNAME_RELEASE}
- exit ;;
+ GUESS=i386-pc-auroraux$UNAME_RELEASE
+ ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- eval $set_cc_for_build
+ set_cc_for_build
SUN_ARCH=i386
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
- if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if test "$CC_FOR_BUILD" != no_compiler_found; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
SUN_ARCH=x86_64
fi
fi
- echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=$SUN_ARCH-pc-solaris2$SUN_REL
+ ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-sun-solaris3$SUN_REL
+ ;;
sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
+ case `/usr/bin/arch -k` in
Series*|S4*)
UNAME_RELEASE=`uname -v`
;;
esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit ;;
+ # Japanese Language versions have a version number like '4.1.3-JL'.
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
+ GUESS=sparc-sun-sunos$SUN_REL
+ ;;
sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit ;;
+ GUESS=m68k-sun-sunos$UNAME_RELEASE
+ ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
- case "`/bin/arch`" in
+ test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
+ case `/bin/arch` in
sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
+ GUESS=m68k-sun-sunos$UNAME_RELEASE
;;
sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
+ GUESS=sparc-sun-sunos$UNAME_RELEASE
;;
esac
- exit ;;
+ ;;
aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- exit ;;
+ GUESS=sparc-auspex-sunos$UNAME_RELEASE
+ ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
@@ -439,44 +494,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
+ GUESS=m68k-milan-mint$UNAME_RELEASE
+ ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
+ GUESS=m68k-hades-mint$UNAME_RELEASE
+ ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
+ GUESS=m68k-unknown-mint$UNAME_RELEASE
+ ;;
m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
- exit ;;
+ GUESS=m68k-apple-machten$UNAME_RELEASE
+ ;;
powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
- exit ;;
+ GUESS=powerpc-apple-machten$UNAME_RELEASE
+ ;;
RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
+ GUESS=mips-dec-mach_bsd4.3
+ ;;
RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit ;;
+ GUESS=mips-dec-ultrix$UNAME_RELEASE
+ ;;
VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit ;;
+ GUESS=vax-dec-ultrix$UNAME_RELEASE
+ ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit ;;
+ GUESS=clipper-intergraph-clix$UNAME_RELEASE
+ ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ set_cc_for_build
+ sed 's/^ //' << EOF > "$dummy.c"
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
int main (int argc, char *argv[]) {
@@ -485,95 +540,96 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
- $CC_FOR_BUILD -o $dummy $dummy.c &&
- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
- SYSTEM_NAME=`$dummy $dummyarg` &&
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
+ dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos${UNAME_RELEASE}
- exit ;;
+ GUESS=mips-mips-riscos$UNAME_RELEASE
+ ;;
Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
+ GUESS=powerpc-motorola-powermax
+ ;;
Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
+ GUESS=powerpc-harris-powermax
+ ;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
+ GUESS=powerpc-harris-powermax
+ ;;
Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
+ GUESS=powerpc-harris-powerunix
+ ;;
m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
+ GUESS=m88k-harris-cxux7
+ ;;
m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
+ GUESS=m88k-motorola-sysv4
+ ;;
m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
+ GUESS=m88k-motorola-sysv3
+ ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
+ if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
+ test "$TARGET_BINARY_INTERFACE"x = x
then
- echo m88k-dg-dgux${UNAME_RELEASE}
+ GUESS=m88k-dg-dgux$UNAME_RELEASE
else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ GUESS=m88k-dg-dguxbcs$UNAME_RELEASE
fi
else
- echo i586-dg-dgux${UNAME_RELEASE}
+ GUESS=i586-dg-dgux$UNAME_RELEASE
fi
- exit ;;
+ ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
+ GUESS=m88k-dolphin-sysv3
+ ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
+ GUESS=m88k-motorola-sysv3
+ ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
+ GUESS=m88k-tektronix-sysv3
+ ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
+ GUESS=m68k-tektronix-bsd
+ ;;
*:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit ;;
+ IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'`
+ GUESS=mips-sgi-irix$IRIX_REL
+ ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
+ GUESS=i386-ibm-aix
+ ;;
ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
+ if test -x /usr/bin/oslevel ; then
IBM_REV=`/usr/bin/oslevel`
else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit ;;
+ GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV
+ ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ set_cc_for_build
+ sed 's/^ //' << EOF > "$dummy.c"
#include <sys/systemcfg.h>
main()
@@ -584,77 +640,77 @@ EOF
exit(0);
}
EOF
- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
then
- echo "$SYSTEM_NAME"
+ GUESS=$SYSTEM_NAME
else
- echo rs6000-ibm-aix3.2.5
+ GUESS=rs6000-ibm-aix3.2.5
fi
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
+ GUESS=rs6000-ibm-aix3.2.4
else
- echo rs6000-ibm-aix3.2
+ GUESS=rs6000-ibm-aix3.2
fi
- exit ;;
+ ;;
*:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
- if [ -x /usr/bin/lslpp ] ; then
- IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ if test -x /usr/bin/lslpp ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \
awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit ;;
+ GUESS=$IBM_ARCH-ibm-aix$IBM_REV
+ ;;
*:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
+ GUESS=rs6000-ibm-aix
+ ;;
+ ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
+ GUESS=romp-ibm-bsd4.4
+ ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
+ GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to
+ ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
+ GUESS=rs6000-bull-bosx
+ ;;
DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
+ GUESS=m68k-bull-sysv3
+ ;;
9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
+ GUESS=m68k-hp-bsd
+ ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
+ GUESS=m68k-hp-bsd4.4
+ ;;
9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
+ HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+ case $UNAME_MACHINE in
+ 9000/31?) HP_ARCH=m68000 ;;
+ 9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
+ if test -x /usr/bin/getconf; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
+ case $sc_cpu_version in
523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
+ case $sc_kernel_bits in
32) HP_ARCH=hppa2.0n ;;
64) HP_ARCH=hppa2.0w ;;
'') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
esac ;;
esac
fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ if test "$HP_ARCH" = ""; then
+ set_cc_for_build
+ sed 's/^ //' << EOF > "$dummy.c"
#define _HPUX_SOURCE
#include <stdlib.h>
@@ -687,13 +743,13 @@ EOF
exit (0);
}
EOF
- (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
- if [ ${HP_ARCH} = hppa2.0w ]
+ if test "$HP_ARCH" = hppa2.0w
then
- eval $set_cc_for_build
+ set_cc_for_build
# hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
# 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
@@ -712,15 +768,15 @@ EOF
HP_ARCH=hppa64
fi
fi
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit ;;
+ GUESS=$HP_ARCH-hp-hpux$HPUX_REV
+ ;;
ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
- exit ;;
+ HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+ GUESS=ia64-hp-hpux$HPUX_REV
+ ;;
3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ set_cc_for_build
+ sed 's/^ //' << EOF > "$dummy.c"
#include <unistd.h>
int
main ()
@@ -745,38 +801,38 @@ EOF
exit (0);
}
EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit ;;
+ GUESS=unknown-hitachi-hiuxwe2
+ ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
+ GUESS=hppa1.1-hp-bsd
+ ;;
9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
+ GUESS=hppa1.0-hp-bsd
+ ;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit ;;
+ GUESS=hppa1.0-hp-mpeix
+ ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
+ GUESS=hppa1.1-hp-osf
+ ;;
hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
+ GUESS=hppa1.0-hp-osf
+ ;;
i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
+ if test -x /usr/sbin/sysversion ; then
+ GUESS=$UNAME_MACHINE-unknown-osf1mk
else
- echo ${UNAME_MACHINE}-unknown-osf1
+ GUESS=$UNAME_MACHINE-unknown-osf1
fi
- exit ;;
+ ;;
parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
+ GUESS=hppa1.1-hp-lites
+ ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
+ GUESS=c1-convex-bsd
+ ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
@@ -784,140 +840,174 @@ EOF
fi
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
+ GUESS=c34-convex-bsd
+ ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
+ GUESS=c38-convex-bsd
+ ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
+ GUESS=c4-convex-bsd
+ ;;
CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=ymp-cray-unicos$CRAY_REL
+ ;;
CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
exit ;;
CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=t90-cray-unicos$CRAY_REL
+ ;;
CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=alphaev5-cray-unicosmk$CRAY_REL
+ ;;
CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=sv1-cray-unicos$CRAY_REL
+ ;;
*:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=craynv-cray-unicosmp$CRAY_REL
+ ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
+ GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+ ;;
5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+ GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+ ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE
+ ;;
sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit ;;
+ GUESS=sparc-unknown-bsdi$UNAME_RELEASE
+ ;;
*:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE
+ ;;
+ arm:FreeBSD:*:*)
+ UNAME_PROCESSOR=`uname -p`
+ set_cc_for_build
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi
+ else
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf
+ fi
+ ;;
*:FreeBSD:*:*)
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- case ${UNAME_PROCESSOR} in
+ UNAME_PROCESSOR=`uname -p`
+ case $UNAME_PROCESSOR in
amd64)
UNAME_PROCESSOR=x86_64 ;;
i386)
UNAME_PROCESSOR=i586 ;;
esac
- echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit ;;
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL
+ ;;
i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-cygwin
+ ;;
*:MINGW64*:*)
- echo ${UNAME_MACHINE}-pc-mingw64
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-mingw64
+ ;;
*:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-mingw32
+ ;;
*:MSYS*:*)
- echo ${UNAME_MACHINE}-pc-msys
- exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-msys
+ ;;
i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-pw32
+ ;;
+ *:SerenityOS:*:*)
+ GUESS=$UNAME_MACHINE-pc-serenity
+ ;;
*:Interix*:*)
- case ${UNAME_MACHINE} in
+ case $UNAME_MACHINE in
x86)
- echo i586-pc-interix${UNAME_RELEASE}
- exit ;;
+ GUESS=i586-pc-interix$UNAME_RELEASE
+ ;;
authenticamd | genuineintel | EM64T)
- echo x86_64-unknown-interix${UNAME_RELEASE}
- exit ;;
+ GUESS=x86_64-unknown-interix$UNAME_RELEASE
+ ;;
IA64)
- echo ia64-unknown-interix${UNAME_RELEASE}
- exit ;;
+ GUESS=ia64-unknown-interix$UNAME_RELEASE
+ ;;
esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- 8664:Windows_NT:*)
- echo x86_64-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-uwin
+ ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-unknown-cygwin
- exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
+ GUESS=x86_64-pc-cygwin
+ ;;
prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=powerpcle-unknown-solaris2$SUN_REL
+ ;;
*:GNU:*:*)
# the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit ;;
+ GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'`
+ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'`
+ GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL
+ ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
- exit ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit ;;
+ GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"`
+ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
+ ;;
+ x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*)
+ GUESS="$UNAME_MACHINE-pc-managarm-mlibc"
+ ;;
+ *:[Mm]anagarm:*:*)
+ GUESS="$UNAME_MACHINE-unknown-managarm-mlibc"
+ ;;
+ *:Minix:*:*)
+ GUESS=$UNAME_MACHINE-unknown-minix
+ ;;
aarch64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ set_cc_for_build
+ CPU=$UNAME_MACHINE
+ LIBCABI=$LIBC
+ if test "$CC_FOR_BUILD" != no_compiler_found; then
+ ABI=64
+ sed 's/^ //' << EOF > "$dummy.c"
+ #ifdef __ARM_EABI__
+ #ifdef __ARM_PCS_VFP
+ ABI=eabihf
+ #else
+ ABI=eabi
+ #endif
+ #endif
+EOF
+ cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
+ eval "$cc_set_abi"
+ case $ABI in
+ eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;;
+ esac
+ fi
+ GUESS=$CPU-unknown-linux-$LIBCABI
+ ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
@@ -928,183 +1018,245 @@ EOF
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- arc:Linux:*:* | arceb:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
+ arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*)
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
arm*:Linux:*:*)
- eval $set_cc_for_build
+ set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi
else
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf
fi
fi
- exit ;;
+ ;;
avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
cris:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+ ;;
crisv32:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+ ;;
e2k:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
frv:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
hexagon:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
i*86:Linux:*:*)
- echo ${UNAME_MACHINE}-pc-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-linux-$LIBC
+ ;;
ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
k1om:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
+ kvx:Linux:*:*)
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
+ kvx:cos:*:*)
+ GUESS=$UNAME_MACHINE-unknown-cos
+ ;;
+ kvx:mbr:*:*)
+ GUESS=$UNAME_MACHINE-unknown-mbr
+ ;;
+ loongarch32:Linux:*:* | loongarch64:Linux:*:*)
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
mips:Linux:*:* | mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ set_cc_for_build
+ IS_GLIBC=0
+ test x"${LIBC}" = xgnu && IS_GLIBC=1
+ sed 's/^ //' << EOF > "$dummy.c"
#undef CPU
- #undef ${UNAME_MACHINE}
- #undef ${UNAME_MACHINE}el
+ #undef mips
+ #undef mipsel
+ #undef mips64
+ #undef mips64el
+ #if ${IS_GLIBC} && defined(_ABI64)
+ LIBCABI=gnuabi64
+ #else
+ #if ${IS_GLIBC} && defined(_ABIN32)
+ LIBCABI=gnuabin32
+ #else
+ LIBCABI=${LIBC}
+ #endif
+ #endif
+
+ #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
+ CPU=mipsisa64r6
+ #else
+ #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
+ CPU=mipsisa32r6
+ #else
+ #if defined(__mips64)
+ CPU=mips64
+ #else
+ CPU=mips
+ #endif
+ #endif
+ #endif
+
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=${UNAME_MACHINE}el
+ MIPS_ENDIAN=el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=${UNAME_MACHINE}
+ MIPS_ENDIAN=
#else
- CPU=
+ MIPS_ENDIAN=
#endif
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`
+ eval "$cc_set_vars"
+ test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
;;
mips64el:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
openrisc*:Linux:*:*)
- echo or1k-unknown-linux-${LIBC}
- exit ;;
+ GUESS=or1k-unknown-linux-$LIBC
+ ;;
or32:Linux:*:* | or1k*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
padre:Linux:*:*)
- echo sparc-unknown-linux-${LIBC}
- exit ;;
+ GUESS=sparc-unknown-linux-$LIBC
+ ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-${LIBC}
- exit ;;
+ GUESS=hppa64-unknown-linux-$LIBC
+ ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
- PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
- *) echo hppa-unknown-linux-${LIBC} ;;
+ PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;;
+ PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;;
+ *) GUESS=hppa-unknown-linux-$LIBC ;;
esac
- exit ;;
+ ;;
ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-${LIBC}
- exit ;;
+ GUESS=powerpc64-unknown-linux-$LIBC
+ ;;
ppc:Linux:*:*)
- echo powerpc-unknown-linux-${LIBC}
- exit ;;
+ GUESS=powerpc-unknown-linux-$LIBC
+ ;;
ppc64le:Linux:*:*)
- echo powerpc64le-unknown-linux-${LIBC}
- exit ;;
+ GUESS=powerpc64le-unknown-linux-$LIBC
+ ;;
ppcle:Linux:*:*)
- echo powerpcle-unknown-linux-${LIBC}
- exit ;;
- riscv32:Linux:*:* | riscv64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=powerpcle-unknown-linux-$LIBC
+ ;;
+ riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-ibm-linux-$LIBC
+ ;;
sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
tile*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-dec-linux-$LIBC
+ ;;
x86_64:Linux:*:*)
- echo ${UNAME_MACHINE}-pc-linux-${LIBC}
- exit ;;
+ set_cc_for_build
+ CPU=$UNAME_MACHINE
+ LIBCABI=$LIBC
+ if test "$CC_FOR_BUILD" != no_compiler_found; then
+ ABI=64
+ sed 's/^ //' << EOF > "$dummy.c"
+ #ifdef __i386__
+ ABI=x86
+ #else
+ #ifdef __ILP32__
+ ABI=x32
+ #endif
+ #endif
+EOF
+ cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
+ eval "$cc_set_abi"
+ case $ABI in
+ x86) CPU=i686 ;;
+ x32) LIBCABI=${LIBC}x32 ;;
+ esac
+ fi
+ GUESS=$CPU-pc-linux-$LIBCABI
+ ;;
xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
+ GUESS=i386-sequent-sysv4
+ ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
+ ;;
i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
+ # If we were able to find 'uname', then EMX Unix compatibility
# is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-os2-emx
+ ;;
i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-stop
+ ;;
i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-atheos
+ ;;
i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-syllable
+ ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit ;;
+ GUESS=i386-unknown-lynxos$UNAME_RELEASE
+ ;;
i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ GUESS=$UNAME_MACHINE-pc-msdosdjgpp
+ ;;
+ i*86:*:4.*:*)
+ UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL
else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL
fi
- exit ;;
+ ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
@@ -1112,12 +1264,12 @@ EOF
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ GUESS=$UNAME_MACHINE-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
@@ -1127,11 +1279,11 @@ EOF
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL
else
- echo ${UNAME_MACHINE}-pc-sysv32
+ GUESS=$UNAME_MACHINE-pc-sysv32
fi
- exit ;;
+ ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
@@ -1139,31 +1291,31 @@ EOF
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configure will decide that
# this is a cross-build.
- echo i586-pc-msdosdjgpp
- exit ;;
+ GUESS=i586-pc-msdosdjgpp
+ ;;
Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
+ GUESS=i386-pc-mach3
+ ;;
paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
+ GUESS=i860-intel-osf1
+ ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4
fi
- exit ;;
+ ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
- echo m68010-convergent-sysv
- exit ;;
+ GUESS=m68010-convergent-sysv
+ ;;
mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
+ GUESS=m68k-convergent-sysv
+ ;;
M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
+ GUESS=m68k-diab-dnix
+ ;;
M68*:*:R3V[5678]*:*)
test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
@@ -1171,9 +1323,9 @@ EOF
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
@@ -1182,252 +1334,440 @@ EOF
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit ;;
+ GUESS=m68k-unknown-lynxos$UNAME_RELEASE
+ ;;
mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
+ GUESS=m68k-atari-sysv4
+ ;;
TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
+ GUESS=sparc-unknown-lynxos$UNAME_RELEASE
+ ;;
rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit ;;
+ GUESS=rs6000-unknown-lynxos$UNAME_RELEASE
+ ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
+ GUESS=powerpc-unknown-lynxos$UNAME_RELEASE
+ ;;
SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit ;;
+ GUESS=mips-dde-sysv$UNAME_RELEASE
+ ;;
RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
+ GUESS=mips-sni-sysv4
+ ;;
RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
+ GUESS=mips-sni-sysv4
+ ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
+ GUESS=$UNAME_MACHINE-sni-sysv4
else
- echo ns32k-sni-sysv
+ GUESS=ns32k-sni-sysv
fi
- exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ ;;
+ PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
+ GUESS=i586-unisys-sysv4
+ ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
+ GUESS=hppa1.1-stratus-sysv4
+ ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit ;;
+ GUESS=i860-stratus-sysv4
+ ;;
i*86:VOS:*:*)
# From Paul.Green@stratus.com.
- echo ${UNAME_MACHINE}-stratus-vos
- exit ;;
+ GUESS=$UNAME_MACHINE-stratus-vos
+ ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
- echo hppa1.1-stratus-vos
- exit ;;
+ GUESS=hppa1.1-stratus-vos
+ ;;
mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit ;;
+ GUESS=m68k-apple-aux$UNAME_RELEASE
+ ;;
news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
+ GUESS=mips-sony-newsos6
+ ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
+ if test -d /usr/nec; then
+ GUESS=mips-nec-sysv$UNAME_RELEASE
else
- echo mips-unknown-sysv${UNAME_RELEASE}
+ GUESS=mips-unknown-sysv$UNAME_RELEASE
fi
- exit ;;
+ ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
+ GUESS=powerpc-be-beos
+ ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
+ GUESS=powerpc-apple-beos
+ ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
+ GUESS=i586-pc-beos
+ ;;
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
- echo i586-pc-haiku
- exit ;;
- x86_64:Haiku:*:*)
- echo x86_64-unknown-haiku
- exit ;;
+ GUESS=i586-pc-haiku
+ ;;
+ ppc:Haiku:*:*) # Haiku running on Apple PowerPC
+ GUESS=powerpc-apple-haiku
+ ;;
+ *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat)
+ GUESS=$UNAME_MACHINE-unknown-haiku
+ ;;
SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit ;;
+ GUESS=sx4-nec-superux$UNAME_RELEASE
+ ;;
SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
- exit ;;
+ GUESS=sx5-nec-superux$UNAME_RELEASE
+ ;;
SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
- exit ;;
+ GUESS=sx6-nec-superux$UNAME_RELEASE
+ ;;
SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux${UNAME_RELEASE}
- exit ;;
+ GUESS=sx7-nec-superux$UNAME_RELEASE
+ ;;
SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux${UNAME_RELEASE}
- exit ;;
+ GUESS=sx8-nec-superux$UNAME_RELEASE
+ ;;
SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux${UNAME_RELEASE}
- exit ;;
+ GUESS=sx8r-nec-superux$UNAME_RELEASE
+ ;;
SX-ACE:SUPER-UX:*:*)
- echo sxace-nec-superux${UNAME_RELEASE}
- exit ;;
+ GUESS=sxace-nec-superux$UNAME_RELEASE
+ ;;
Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit ;;
+ GUESS=powerpc-apple-rhapsody$UNAME_RELEASE
+ ;;
*:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit ;;
+ GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE
+ ;;
+ arm64:Darwin:*:*)
+ GUESS=aarch64-apple-darwin$UNAME_RELEASE
+ ;;
*:Darwin:*:*)
- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- eval $set_cc_for_build
- if test "$UNAME_PROCESSOR" = unknown ; then
- UNAME_PROCESSOR=powerpc
+ UNAME_PROCESSOR=`uname -p`
+ case $UNAME_PROCESSOR in
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ if command -v xcode-select > /dev/null 2> /dev/null && \
+ ! xcode-select --print-path > /dev/null 2> /dev/null ; then
+ # Avoid executing cc if there is no toolchain installed as
+ # cc will be a stub that puts up a graphical alert
+ # prompting the user to install developer tools.
+ CC_FOR_BUILD=no_compiler_found
+ else
+ set_cc_for_build
fi
- if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
- if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- case $UNAME_PROCESSOR in
- i386) UNAME_PROCESSOR=x86_64 ;;
- powerpc) UNAME_PROCESSOR=powerpc64 ;;
- esac
- fi
+ if test "$CC_FOR_BUILD" != no_compiler_found; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+ if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_PPC >/dev/null
+ then
+ UNAME_PROCESSOR=powerpc
fi
elif test "$UNAME_PROCESSOR" = i386 ; then
- # Avoid executing cc on OS X 10.9, as it ships with a stub
- # that puts up a graphical alert prompting to install
- # developer tools. Any system running Mac OS X 10.7 or
- # later (Darwin 11 and later) is required to have a 64-bit
- # processor. This is not true of the ARM version of Darwin
- # that Apple uses in portable devices.
- UNAME_PROCESSOR=x86_64
+ # uname -m returns i386 or x86_64
+ UNAME_PROCESSOR=$UNAME_MACHINE
fi
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
- exit ;;
+ GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE
+ ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
- exit ;;
+ GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE
+ ;;
*:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
- NEO-?:NONSTOP_KERNEL:*:*)
- echo neo-tandem-nsk${UNAME_RELEASE}
- exit ;;
+ GUESS=i386-pc-qnx
+ ;;
+ NEO-*:NONSTOP_KERNEL:*:*)
+ GUESS=neo-tandem-nsk$UNAME_RELEASE
+ ;;
NSE-*:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSX-?:NONSTOP_KERNEL:*:*)
- echo nsx-tandem-nsk${UNAME_RELEASE}
- exit ;;
+ GUESS=nse-tandem-nsk$UNAME_RELEASE
+ ;;
+ NSR-*:NONSTOP_KERNEL:*:*)
+ GUESS=nsr-tandem-nsk$UNAME_RELEASE
+ ;;
+ NSV-*:NONSTOP_KERNEL:*:*)
+ GUESS=nsv-tandem-nsk$UNAME_RELEASE
+ ;;
+ NSX-*:NONSTOP_KERNEL:*:*)
+ GUESS=nsx-tandem-nsk$UNAME_RELEASE
+ ;;
*:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
+ GUESS=mips-compaq-nonstopux
+ ;;
BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
+ GUESS=bs2000-siemens-sysv
+ ;;
DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit ;;
+ GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE
+ ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
- if test "$cputype" = 386; then
+ if test "${cputype-}" = 386; then
UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
+ elif test "x${cputype-}" != x; then
+ UNAME_MACHINE=$cputype
fi
- echo ${UNAME_MACHINE}-unknown-plan9
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-plan9
+ ;;
*:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
+ GUESS=pdp10-unknown-tops10
+ ;;
*:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
+ GUESS=pdp10-unknown-tenex
+ ;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
+ GUESS=pdp10-dec-tops20
+ ;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
+ GUESS=pdp10-xkl-tops20
+ ;;
*:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
+ GUESS=pdp10-unknown-tops20
+ ;;
*:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
+ GUESS=pdp10-unknown-its
+ ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
- exit ;;
+ GUESS=mips-sei-seiux$UNAME_RELEASE
+ ;;
*:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit ;;
+ DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL
+ ;;
*:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
+ case $UNAME_MACHINE in
+ A*) GUESS=alpha-dec-vms ;;
+ I*) GUESS=ia64-dec-vms ;;
+ V*) GUESS=vax-dec-vms ;;
esac ;;
*:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
+ GUESS=i386-pc-xenix
+ ;;
i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
- exit ;;
+ SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`
+ GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL
+ ;;
i*86:rdos:*:*)
- echo ${UNAME_MACHINE}-pc-rdos
- exit ;;
- i*86:AROS:*:*)
- echo ${UNAME_MACHINE}-pc-aros
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-rdos
+ ;;
+ i*86:Fiwix:*:*)
+ GUESS=$UNAME_MACHINE-pc-fiwix
+ ;;
+ *:AROS:*:*)
+ GUESS=$UNAME_MACHINE-unknown-aros
+ ;;
x86_64:VMkernel:*:*)
- echo ${UNAME_MACHINE}-unknown-esx
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-esx
+ ;;
amd64:Isilon\ OneFS:*:*)
- echo x86_64-unknown-onefs
- exit ;;
+ GUESS=x86_64-unknown-onefs
+ ;;
+ *:Unleashed:*:*)
+ GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
+ ;;
+esac
+
+# Do we have a guess based on uname results?
+if test "x$GUESS" != x; then
+ echo "$GUESS"
+ exit
+fi
+
+# No uname command or uname output not recognized.
+set_cc_for_build
+cat > "$dummy.c" <<EOF
+#ifdef _SEQUENT_
+#include <sys/types.h>
+#include <sys/utsname.h>
+#endif
+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
+#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
+#include <signal.h>
+#if defined(_SIZE_T_) || defined(SIGLOST)
+#include <sys/utsname.h>
+#endif
+#endif
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+#include <sys/param.h>
+#if defined (BSD)
+#if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+#else
+#if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#else
+ printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#endif
+#else
+ printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#else
+#if defined(_SIZE_T_) || defined(SIGLOST)
+ struct utsname un;
+ uname (&un);
+ printf ("vax-dec-ultrix%s\n", un.release); exit (0);
+#else
+ printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#endif
+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
+#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
+#if defined(_SIZE_T_) || defined(SIGLOST)
+ struct utsname *un;
+ uname (&un);
+ printf ("mips-dec-ultrix%s\n", un.release); exit (0);
+#else
+ printf ("mips-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }
+
+echo "$0: unable to guess system type" >&2
+
+case $UNAME_MACHINE:$UNAME_SYSTEM in
+ mips:Linux | mips64:Linux)
+ # If we got here on MIPS GNU/Linux, output extra information.
+ cat >&2 <<EOF
+
+NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize
+the system type. Please install a C compiler and try again.
+EOF
+ ;;
esac
cat >&2 <<EOF
-$0: unable to guess system type
This script (version $timestamp), has failed to recognize the
-operating system you are using. If your script is old, overwrite
-config.guess and config.sub with the latest versions from:
+operating system you are using. If your script is old, overwrite *all*
+copies of config.guess and config.sub with the latest versions from:
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+ https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
and
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+ https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
+EOF
+
+our_year=`echo $timestamp | sed 's,-.*,,'`
+thisyear=`date +%Y`
+# shellcheck disable=SC2003
+script_age=`expr "$thisyear" - "$our_year"`
+if test "$script_age" -lt 3 ; then
+ cat >&2 <<EOF
If $0 has already been updated, send the following data and any
information you think might be pertinent to config-patches@gnu.org to
@@ -1450,16 +1790,17 @@ hostinfo = `(hostinfo) 2>/dev/null`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
+UNAME_MACHINE = "$UNAME_MACHINE"
+UNAME_RELEASE = "$UNAME_RELEASE"
+UNAME_SYSTEM = "$UNAME_SYSTEM"
+UNAME_VERSION = "$UNAME_VERSION"
EOF
+fi
exit 1
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff --git a/contrib/depends/config.sub b/contrib/depends/config.sub
index 40ea5dfe1..defe52c0c 100755
--- a/contrib/depends/config.sub
+++ b/contrib/depends/config.sub
@@ -1,12 +1,14 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2017 Free Software Foundation, Inc.
+# Copyright 1992-2023 Free Software Foundation, Inc.
-timestamp='2017-04-02'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2023-09-19'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@@ -15,7 +17,7 @@ timestamp='2017-04-02'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -33,7 +35,7 @@ timestamp='2017-04-02'
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
@@ -50,6 +52,13 @@ timestamp='2017-04-02'
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX. However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
@@ -57,7 +66,7 @@ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
Canonicalize a configuration name.
-Operation modes:
+Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
@@ -67,13 +76,13 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2017 Free Software Foundation, Inc.
+Copyright 1992-2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
-Try \`$me --help' for more information."
+Try '$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
@@ -89,12 +98,12 @@ while test $# -gt 0 ; do
- ) # Use stdin as input.
break ;;
-* )
- echo "$me: invalid option $1$help"
+ echo "$me: invalid option $1$help" >&2
exit 1 ;;
*local*)
# First pass through any local machine types.
- echo $1
+ echo "$1"
exit ;;
* )
@@ -110,1252 +119,1165 @@ case $# in
exit 1;;
esac
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
- linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
- knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
- kopensolaris*-gnu* | cloudabi*-eabi* | \
- storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- android-linux)
- os=-linux-android
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
+# Split fields of configuration type
+# shellcheck disable=SC2162
+saved_IFS=$IFS
+IFS="-" read field1 field2 field3 field4 <<EOF
+$1
+EOF
+IFS=$saved_IFS
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray | -microblaze*)
- os=
- basic_machine=$1
- ;;
- -bluegene*)
- os=-cnk
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco6)
- os=-sco5v6
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*178)
- os=-lynxos178
- ;;
- -lynx*5)
- os=-lynxos5
- ;;
- -lynx*)
- os=-lynxos
+# Separate into logical components for further validation
+case $1 in
+ *-*-*-*-*)
+ echo "Invalid configuration '$1': more than four components" >&2
+ exit 1
;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ *-*-*-*)
+ basic_machine=$field1-$field2
+ basic_os=$field3-$field4
;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ *-*-*)
+ # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
+ # parts
+ maybe_os=$field2-$field3
+ case $maybe_os in
+ nto-qnx* | linux-* | uclinux-uclibc* \
+ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
+ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
+ | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \
+ | windows-* )
+ basic_machine=$field1
+ basic_os=$maybe_os
+ ;;
+ android-linux)
+ basic_machine=$field1-unknown
+ basic_os=linux-android
+ ;;
+ *)
+ basic_machine=$field1-$field2
+ basic_os=$field3
+ ;;
+ esac
;;
- -psos*)
- os=-psos
+ *-*)
+ # A lone config we happen to match not fitting any pattern
+ case $field1-$field2 in
+ decstation-3100)
+ basic_machine=mips-dec
+ basic_os=
+ ;;
+ *-*)
+ # Second component is usually, but not always the OS
+ case $field2 in
+ # Prevent following clause from handling this valid os
+ sun*os*)
+ basic_machine=$field1
+ basic_os=$field2
+ ;;
+ zephyr*)
+ basic_machine=$field1-unknown
+ basic_os=$field2
+ ;;
+ # Manufacturers
+ dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
+ | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
+ | unicom* | ibm* | next | hp | isi* | apollo | altos* \
+ | convergent* | ncr* | news | 32* | 3600* | 3100* \
+ | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
+ | ultra | tti* | harris | dolphin | highlevel | gould \
+ | cbm | ns | masscomp | apple | axis | knuth | cray \
+ | microblaze* | sim | cisco \
+ | oki | wec | wrs | winbond)
+ basic_machine=$field1-$field2
+ basic_os=
+ ;;
+ *)
+ basic_machine=$field1
+ basic_os=$field2
+ ;;
+ esac
+ ;;
+ esac
;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
+ *)
+ # Convert single-component short-hands not valid as part of
+ # multi-component configurations.
+ case $field1 in
+ 386bsd)
+ basic_machine=i386-pc
+ basic_os=bsd
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ basic_os=udi
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ basic_os=scout
+ ;;
+ alliant)
+ basic_machine=fx80-alliant
+ basic_os=
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ basic_os=
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ basic_os=bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ basic_os=sysv
+ ;;
+ amiga)
+ basic_machine=m68k-unknown
+ basic_os=
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ basic_os=amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ basic_os=sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ basic_os=sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ basic_os=bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ basic_os=aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ basic_os=aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ basic_os=dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ basic_os=linux
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ basic_os=cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ basic_os=bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ basic_os=bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ basic_os=bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ basic_os=bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ basic_os=bsd
+ ;;
+ cray)
+ basic_machine=j90-cray
+ basic_os=unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ basic_os=
+ ;;
+ da30)
+ basic_machine=m68k-da30
+ basic_os=
+ ;;
+ decstation | pmax | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ basic_os=
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ basic_os=sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ basic_os=dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ basic_os=msdosdjgpp
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ basic_os=ebmon
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ basic_os=ose
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ basic_os=sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ basic_os=go32
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ basic_os=hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ basic_os=xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ basic_os=hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ basic_os=sysv3
+ ;;
+ hp300 | hp300hpux)
+ basic_machine=m68k-hp
+ basic_os=hpux
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ basic_os=bsd
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ basic_os=osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ basic_os=proelf
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ basic_os=mach
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ basic_os=sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ basic_os=linux
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ basic_os=sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ basic_os=sysv
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ basic_os=mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ basic_os=mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ basic_os=mingw32ce
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ basic_os=coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ basic_os=morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ basic_os=moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ basic_os=msdos
+ ;;
+ msys)
+ basic_machine=i686-pc
+ basic_os=msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ basic_os=mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ basic_os=nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ basic_os=sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-pc
+ basic_os=netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ basic_os=linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ basic_os=newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ basic_os=newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ basic_os=sysv
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ basic_os=cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ basic_os=cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ basic_os=nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ basic_os=mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ basic_os=nonstopux
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ basic_os=os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ basic_os=ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ basic_os=os68k
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ basic_os=osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ basic_os=linux
+ ;;
+ psp)
+ basic_machine=mipsallegrexel-sony
+ basic_os=psp
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ basic_os=pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ basic_os=rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ basic_os=rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ basic_os=coff
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ basic_os=udi
+ ;;
+ sei)
+ basic_machine=mips-sei
+ basic_os=seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ basic_os=
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ basic_os=sysv2
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ basic_os=
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ basic_os=sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ basic_os=
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ basic_os=sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ basic_os=sunos4
+ ;;
+ sun3)
+ basic_machine=m68k-sun
+ basic_os=
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ basic_os=sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ basic_os=sunos4
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ basic_os=
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ basic_os=sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ basic_os=sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ basic_os=solaris2
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ basic_os=
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ basic_os=unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ basic_os=dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ basic_os=unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ basic_os=unicos
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ basic_os=tops20
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ basic_os=tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ basic_os=udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ basic_os=sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ basic_os=none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ basic_os=sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ basic_os=vms
+ ;;
+ vsta)
+ basic_machine=i386-pc
+ basic_os=vsta
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ basic_os=vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ basic_os=vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ basic_os=vxworks
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ basic_os=mingw32
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ basic_os=unicos
+ ;;
+ *)
+ basic_machine=$1
+ basic_os=
+ ;;
+ esac
;;
esac
-# Decode aliases for certain CPU-COMPANY combinations.
+# Decode 1-component or ad-hoc basic machines
case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- | aarch64 | aarch64_be \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
- | am33_2.0 \
- | arc | arceb \
- | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
- | avr | avr32 \
- | ba \
- | be32 | be64 \
- | bfin \
- | c4x | c8051 | clipper \
- | d10v | d30v | dlx | dsp16xx \
- | e2k | epiphany \
- | fido | fr30 | frv | ft32 \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- | hexagon \
- | i370 | i860 | i960 | ia16 | ia64 \
- | ip2k | iq2000 \
- | k1om \
- | le32 | le64 \
- | lm32 \
- | m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64octeon | mips64octeonel \
- | mips64orion | mips64orionel \
- | mips64r5900 | mips64r5900el \
- | mips64vr | mips64vrel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa32r6 | mipsisa32r6el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- | mipsisa64r6 | mipsisa64r6el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipsr5900 | mipsr5900el \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- | moxie \
- | mt \
- | msp430 \
- | nds32 | nds32le | nds32be \
- | nios | nios2 | nios2eb | nios2el \
- | ns16k | ns32k \
- | open8 | or1k | or1knd | or32 \
- | pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle \
- | pru \
- | pyramid \
- | riscv32 | riscv64 \
- | rl78 | rx \
- | score \
- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu \
- | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
- | ubicom32 \
- | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
- | visium \
- | wasm32 \
- | we32k \
- | x86 | xc16x | xstormy16 | xtensa \
- | z8k | z80)
- basic_machine=$basic_machine-unknown
- ;;
- c54x)
- basic_machine=tic54x-unknown
- ;;
- c55x)
- basic_machine=tic55x-unknown
- ;;
- c6x)
- basic_machine=tic6x-unknown
- ;;
- leon|leon[3-9])
- basic_machine=sparc-$basic_machine
- ;;
- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
- basic_machine=$basic_machine-unknown
- os=-none
+ # Here we handle the default manufacturer of certain CPU types. It is in
+ # some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ cpu=hppa1.1
+ vendor=winbond
;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ op50n)
+ cpu=hppa1.1
+ vendor=oki
;;
- ms1)
- basic_machine=mt-unknown
+ op60c)
+ cpu=hppa1.1
+ vendor=oki
;;
-
- strongarm | thumb | xscale)
- basic_machine=arm-unknown
+ ibm*)
+ cpu=i370
+ vendor=ibm
;;
- xgate)
- basic_machine=$basic_machine-unknown
- os=-none
+ orion105)
+ cpu=clipper
+ vendor=highlevel
;;
- xscaleeb)
- basic_machine=armeb-unknown
+ mac | mpw | mac-mpw)
+ cpu=m68k
+ vendor=apple
;;
-
- xscaleel)
- basic_machine=armel-unknown
+ pmac | pmac-mpw)
+ cpu=powerpc
+ vendor=apple
;;
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- | aarch64-* | aarch64_be-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* | avr32-* \
- | ba-* \
- | be32-* | be64-* \
- | bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* \
- | c8051-* | clipper-* | craynv-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
- | e2k-* | elxsi-* \
- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- | hexagon-* \
- | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
- | ip2k-* | iq2000-* \
- | k1om-* \
- | le32-* | le64-* \
- | lm32-* \
- | m32c-* | m32r-* | m32rle-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
- | microblaze-* | microblazeel-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64octeon-* | mips64octeonel-* \
- | mips64orion-* | mips64orionel-* \
- | mips64r5900-* | mips64r5900el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mips64vr5900-* | mips64vr5900el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa32r6-* | mipsisa32r6el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64r2-* | mipsisa64r2el-* \
- | mipsisa64r6-* | mipsisa64r6el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- | mipsr5900-* | mipsr5900el-* \
- | mipstx39-* | mipstx39el-* \
- | mmix-* \
- | mt-* \
- | msp430-* \
- | nds32-* | nds32le-* | nds32be-* \
- | nios-* | nios2-* | nios2eb-* | nios2el-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
- | open8-* \
- | or1k*-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
- | pru-* \
- | pyramid-* \
- | riscv32-* | riscv64-* \
- | rl78-* | romp-* | rs6000-* | rx-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
- | sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
- | tahoe-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- | tile*-* \
- | tron-* \
- | ubicom32-* \
- | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
- | vax-* \
- | visium-* \
- | wasm32-* \
- | we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* \
- | xstormy16-* | xtensa*-* \
- | ymp-* \
- | z8k-* | z80-*)
- ;;
- # Recognize the basic CPU types without company name, with glob match.
- xtensa*)
- basic_machine=$basic_machine-unknown
- ;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
+ cpu=m68000
+ vendor=att
;;
3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- abacus)
- basic_machine=abacus-unknown
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amd64)
- basic_machine=x86_64-pc
- ;;
- amd64-*)
- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aros)
- basic_machine=i386-pc
- os=-aros
- ;;
- asmjs)
- basic_machine=asmjs-unknown
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- blackfin)
- basic_machine=bfin-unknown
- os=-linux
- ;;
- blackfin-*)
- basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
+ cpu=we32k
+ vendor=att
;;
bluegene*)
- basic_machine=powerpc-ibm
- os=-cnk
- ;;
- c54x-*)
- basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c55x-*)
- basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c6x-*)
- basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- cegcc)
- basic_machine=arm-unknown
- os=-cegcc
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | j90)
- basic_machine=j90-cray
- os=-unicos
- ;;
- craynv)
- basic_machine=craynv-cray
- os=-unicosmp
- ;;
- cr16 | cr16-*)
- basic_machine=cr16-unknown
- os=-elf
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- crisv32 | crisv32-* | etraxfs*)
- basic_machine=crisv32-axis
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- crx)
- basic_machine=crx-unknown
- os=-elf
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
+ cpu=powerpc
+ vendor=ibm
+ basic_os=cnk
;;
decsystem10* | dec10*)
- basic_machine=pdp10-dec
- os=-tops10
+ cpu=pdp10
+ vendor=dec
+ basic_os=tops10
;;
decsystem20* | dec20*)
- basic_machine=pdp10-dec
- os=-tops20
+ cpu=pdp10
+ vendor=dec
+ basic_os=tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dicos)
- basic_machine=i686-pc
- os=-dicos
+ cpu=m68k
+ vendor=motorola
;;
- djgpp)
- basic_machine=i586-pc
- os=-msdosdjgpp
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- e500v[12])
- basic_machine=powerpc-unknown
- os=$os"spe"
- ;;
- e500v[12]-*)
- basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=$os"spe"
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
+ dpx2*)
+ cpu=m68k
+ vendor=bull
+ basic_os=sysv3
;;
encore | umax | mmax)
- basic_machine=ns32k-encore
+ cpu=ns32k
+ vendor=encore
;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
+ elxsi)
+ cpu=elxsi
+ vendor=elxsi
+ basic_os=${basic_os:-bsd}
;;
fx2800)
- basic_machine=i860-alliant
+ cpu=i860
+ vendor=alliant
;;
genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
+ cpu=ns32k
+ vendor=ns
;;
h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
+ cpu=hppa1.1
+ vendor=hitachi
+ basic_os=hiuxwe2
;;
hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
+ cpu=hppa1.0
+ vendor=hp
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
+ cpu=m68000
+ vendor=hp
;;
hp9k3[2-9][0-9])
- basic_machine=m68k-hp
+ cpu=m68k
+ vendor=hp
;;
hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
+ cpu=hppa1.0
+ vendor=hp
;;
hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
+ cpu=hppa1.1
+ vendor=hp
;;
hp9k78[0-9] | hp78[0-9])
# FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
+ cpu=hppa1.1
+ vendor=hp
;;
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
# FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
+ cpu=hppa1.1
+ vendor=hp
;;
hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
+ cpu=hppa1.1
+ vendor=hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
+ cpu=hppa1.0
+ vendor=hp
;;
i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ vendor=pc
+ basic_os=sysv32
;;
i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ vendor=pc
+ basic_os=sysv4
;;
i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ vendor=pc
+ basic_os=sysv
;;
i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ vendor=pc
+ basic_os=solaris2
;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
+ j90 | j90-cray)
+ cpu=j90
+ vendor=cray
+ basic_os=${basic_os:-unicos}
;;
iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
+ cpu=mips
+ vendor=sgi
+ case $basic_os in
+ irix*)
;;
*)
- os=-irix4
+ basic_os=irix4
;;
esac
;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- leon-*|leon[3-9]-*)
- basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
- ;;
- m68knommu)
- basic_machine=m68k-unknown
- os=-linux
- ;;
- m68knommu-*)
- basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- microblaze*)
- basic_machine=microblaze-xilinx
- ;;
- mingw64)
- basic_machine=x86_64-pc
- os=-mingw64
- ;;
- mingw32)
- basic_machine=i686-pc
- os=-mingw32
- ;;
- mingw32ce)
- basic_machine=arm-unknown
- os=-mingw32ce
- ;;
miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- moxiebox)
- basic_machine=moxie-unknown
- os=-moxiebox
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- ms1-*)
- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ cpu=m68000
+ vendor=convergent
;;
- msys)
- basic_machine=i686-pc
- os=-msys
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- nacl)
- basic_machine=le32-unknown
- os=-nacl
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
+ *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ cpu=m68k
+ vendor=atari
+ basic_os=mint
;;
news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
+ cpu=mips
+ vendor=sony
+ basic_os=newsos
+ ;;
+ next | m*-next)
+ cpu=m68k
+ vendor=next
+ case $basic_os in
+ openstep*)
+ ;;
+ nextstep*)
;;
- -ns2*)
- os=-nextstep2
+ ns2*)
+ basic_os=nextstep2
;;
*)
- os=-nextstep3
+ basic_os=nextstep3
;;
esac
;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
np1)
- basic_machine=np1-gould
- ;;
- neo-tandem)
- basic_machine=neo-tandem
- ;;
- nse-tandem)
- basic_machine=nse-tandem
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- nsx-tandem)
- basic_machine=nsx-tandem
+ cpu=np1
+ vendor=gould
;;
op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- openrisc | openrisc-*)
- basic_machine=or32-unknown
- ;;
- os400)
- basic_machine=powerpc-ibm
- os=-os400
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
+ cpu=hppa1.1
+ vendor=oki
+ basic_os=proelf
;;
pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- parisc)
- basic_machine=hppa-unknown
- os=-linux
- ;;
- parisc-*)
- basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
+ cpu=hppa1.1
+ vendor=hitachi
+ basic_os=hiuxwe2
;;
pbd)
- basic_machine=sparc-tti
+ cpu=sparc
+ vendor=tti
;;
pbb)
- basic_machine=m68k-tti
+ cpu=m68k
+ vendor=tti
;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pc98)
- basic_machine=i386-pc
- ;;
- pc98-*)
- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium | p5 | k5 | k6 | nexgen | viac3)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon | athlon_*)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2 | pentiumiii | pentium3)
- basic_machine=i686-pc
- ;;
- pentium4)
- basic_machine=i786-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium4-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ pc532)
+ cpu=ns32k
+ vendor=pc532
;;
pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=power-ibm
+ cpu=pn
+ vendor=gould
;;
- ppc | ppcbe) basic_machine=powerpc-unknown
- ;;
- ppc-* | ppcbe-*)
- basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64) basic_machine=powerpc64-unknown
- ;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64le | powerpc64little)
- basic_machine=powerpc64le-unknown
- ;;
- ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ power)
+ cpu=power
+ vendor=ibm
;;
ps2)
- basic_machine=i386-ibm
- ;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rdos | rdos64)
- basic_machine=x86_64-pc
- os=-rdos
- ;;
- rdos32)
- basic_machine=i386-pc
- os=-rdos
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
+ cpu=i386
+ vendor=ibm
;;
rm[46]00)
- basic_machine=mips-siemens
+ cpu=mips
+ vendor=siemens
;;
rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- s390 | s390-*)
- basic_machine=s390-ibm
- ;;
- s390x | s390x-*)
- basic_machine=s390x-ibm
- ;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
- sb1)
- basic_machine=mipsisa64sb1-unknown
- ;;
- sb1el)
- basic_machine=mipsisa64sb1el-unknown
+ cpu=romp
+ vendor=ibm
;;
sde)
- basic_machine=mipsisa32-sde
- os=-elf
+ cpu=mipsisa32
+ vendor=sde
+ basic_os=${basic_os:-elf}
;;
- sei)
- basic_machine=mips-sei
- os=-seiux
+ simso-wrs)
+ cpu=sparclite
+ vendor=wrs
+ basic_os=vxworks
;;
- sequent)
- basic_machine=i386-sequent
+ tower | tower-32)
+ cpu=m68k
+ vendor=ncr
;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
+ vpp*|vx|vx-*)
+ cpu=f301
+ vendor=fujitsu
;;
- sh5el)
- basic_machine=sh5le-unknown
+ w65)
+ cpu=w65
+ vendor=wdc
;;
- sh64)
- basic_machine=sh64-unknown
+ w89k-*)
+ cpu=hppa1.1
+ vendor=winbond
+ basic_os=proelf
;;
- sparclite-wrs | simso-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
+ none)
+ cpu=none
+ vendor=none
;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
+ leon|leon[3-9])
+ cpu=sparc
+ vendor=$basic_machine
;;
- spur)
- basic_machine=spur-unknown
+ leon-*|leon[3-9]-*)
+ cpu=sparc
+ vendor=`echo "$basic_machine" | sed 's/-.*//'`
;;
- st2000)
- basic_machine=m68k-tandem
+
+ *-*)
+ # shellcheck disable=SC2162
+ saved_IFS=$IFS
+ IFS="-" read cpu vendor <<EOF
+$basic_machine
+EOF
+ IFS=$saved_IFS
+ ;;
+ # We use 'pc' rather than 'unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ cpu=$basic_machine
+ vendor=pc
;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
+ # These rules are duplicated from below for sake of the special case above;
+ # i.e. things that normalized to x86 arches should also default to "pc"
+ pc98)
+ cpu=i386
+ vendor=pc
;;
- strongarm-* | thumb-*)
- basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ x64 | amd64)
+ cpu=x86_64
+ vendor=pc
;;
- sun2)
- basic_machine=m68000-sun
+ # Recognize the basic CPU types without company name.
+ *)
+ cpu=$basic_machine
+ vendor=unknown
;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
+esac
+
+unset -v basic_machine
+
+# Decode basic machines in the full and proper CPU-Company form.
+case $cpu-$vendor in
+ # Here we handle the default manufacturer of certain CPU types in canonical form. It is in
+ # some cases the only manufacturer, in others, it is the most popular.
+ craynv-unknown)
+ vendor=cray
+ basic_os=${basic_os:-unicosmp}
;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
+ c90-unknown | c90-cray)
+ vendor=cray
+ basic_os=${Basic_os:-unicos}
;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
+ fx80-unknown)
+ vendor=alliant
;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
+ romp-unknown)
+ vendor=ibm
;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
+ mmix-unknown)
+ vendor=knuth
;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
+ microblaze-unknown | microblazeel-unknown)
+ vendor=xilinx
;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
+ rs6000-unknown)
+ vendor=ibm
;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
+ vax-unknown)
+ vendor=dec
;;
- sun4)
- basic_machine=sparc-sun
+ pdp11-unknown)
+ vendor=dec
;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
+ we32k-unknown)
+ vendor=att
;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
+ cydra-unknown)
+ vendor=cydrome
;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
+ i370-ibm*)
+ vendor=ibm
;;
- t3e)
- basic_machine=alphaev5-cray
- os=-unicos
+ orion-unknown)
+ vendor=highlevel
;;
- t90)
- basic_machine=t90-cray
- os=-unicos
+ xps-unknown | xps100-unknown)
+ cpu=xps100
+ vendor=honeywell
;;
- tile*)
- basic_machine=$basic_machine-unknown
- os=-linux-gnu
+
+ # Here we normalize CPU types with a missing or matching vendor
+ armh-unknown | armh-alt)
+ cpu=armv7l
+ vendor=alt
+ basic_os=${basic_os:-linux-gnueabihf}
;;
- tx39)
- basic_machine=mipstx39-unknown
+ dpx20-unknown | dpx20-bull)
+ cpu=rs6000
+ vendor=bull
+ basic_os=${basic_os:-bosx}
;;
- tx39el)
- basic_machine=mipstx39el-unknown
+
+ # Here we normalize CPU types irrespective of the vendor
+ amd64-*)
+ cpu=x86_64
;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
+ blackfin-*)
+ cpu=bfin
+ basic_os=linux
;;
- tower | tower-32)
- basic_machine=m68k-ncr
+ c54x-*)
+ cpu=tic54x
;;
- tpf)
- basic_machine=s390x-ibm
- os=-tpf
+ c55x-*)
+ cpu=tic55x
;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
+ c6x-*)
+ cpu=tic6x
;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
+ e500v[12]-*)
+ cpu=powerpc
+ basic_os=${basic_os}"spe"
;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
+ mips3*-*)
+ cpu=mips64
;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
+ ms1-*)
+ cpu=mt
;;
- vms)
- basic_machine=vax-dec
- os=-vms
+ m68knommu-*)
+ cpu=m68k
+ basic_os=linux
;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
+ m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
+ cpu=s12z
;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
+ openrisc-*)
+ cpu=or32
;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
+ parisc-*)
+ cpu=hppa
+ basic_os=linux
;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ cpu=i586
;;
- wasm32)
- basic_machine=wasm32-unknown
+ pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*)
+ cpu=i686
;;
- w65*)
- basic_machine=w65-wdc
- os=-none
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ cpu=i686
;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
+ pentium4-*)
+ cpu=i786
;;
- xbox)
- basic_machine=i686-pc
- os=-mingw32
+ pc98-*)
+ cpu=i386
;;
- xps | xps100)
- basic_machine=xps100-honeywell
+ ppc-* | ppcbe-*)
+ cpu=powerpc
;;
- xscale-* | xscalee[bl]-*)
- basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ppcle-* | powerpclittle-*)
+ cpu=powerpcle
;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
+ ppc64-*)
+ cpu=powerpc64
;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
+ ppc64le-* | powerpc64little-*)
+ cpu=powerpc64le
;;
- z80-*-coff)
- basic_machine=z80-unknown
- os=-sim
+ sb1-*)
+ cpu=mipsisa64sb1
;;
- none)
- basic_machine=none-none
- os=-none
+ sb1el-*)
+ cpu=mipsisa64sb1el
;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
+ sh5e[lb]-*)
+ cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
;;
- op50n)
- basic_machine=hppa1.1-oki
+ spur-*)
+ cpu=spur
;;
- op60c)
- basic_machine=hppa1.1-oki
+ strongarm-* | thumb-*)
+ cpu=arm
;;
- romp)
- basic_machine=romp-ibm
+ tx39-*)
+ cpu=mipstx39
;;
- mmix)
- basic_machine=mmix-knuth
+ tx39el-*)
+ cpu=mipstx39el
;;
- rs6000)
- basic_machine=rs6000-ibm
+ x64-*)
+ cpu=x86_64
;;
- vax)
- basic_machine=vax-dec
+ xscale-* | xscalee[bl]-*)
+ cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
+ arm64-* | aarch64le-*)
+ cpu=aarch64
;;
- pdp11)
- basic_machine=pdp11-dec
+
+ # Recognize the canonical CPU Types that limit and/or modify the
+ # company names they are paired with.
+ cr16-*)
+ basic_os=${basic_os:-elf}
;;
- we32k)
- basic_machine=we32k-att
+ crisv32-* | etraxfs*-*)
+ cpu=crisv32
+ vendor=axis
;;
- sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
- basic_machine=sh-unknown
+ cris-* | etrax*-*)
+ cpu=cris
+ vendor=axis
;;
- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
- basic_machine=sparc-sun
+ crx-*)
+ basic_os=${basic_os:-elf}
;;
- cydra)
- basic_machine=cydra-cydrome
+ neo-tandem)
+ cpu=neo
+ vendor=tandem
;;
- orion)
- basic_machine=orion-highlevel
+ nse-tandem)
+ cpu=nse
+ vendor=tandem
;;
- orion105)
- basic_machine=clipper-highlevel
+ nsr-tandem)
+ cpu=nsr
+ vendor=tandem
;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
+ nsv-tandem)
+ cpu=nsv
+ vendor=tandem
;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
+ nsx-tandem)
+ cpu=nsx
+ vendor=tandem
+ ;;
+ mipsallegrexel-sony)
+ cpu=mipsallegrexel
+ vendor=sony
;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
+ tile*-*)
+ basic_os=${basic_os:-linux-gnu}
;;
+
*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
+ # Recognize the canonical CPU types that are allowed with any
+ # company name.
+ case $cpu in
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be | aarch64c | arm64ec \
+ | abacus \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
+ | alphapca5[67] | alpha64pca5[67] \
+ | am33_2.0 \
+ | amdgcn \
+ | arc | arceb | arc32 | arc64 \
+ | arm | arm[lb]e | arme[lb] | armv* \
+ | avr | avr32 \
+ | asmjs \
+ | ba \
+ | be32 | be64 \
+ | bfin | bpf | bs2000 \
+ | c[123]* | c30 | [cjt]90 | c4x \
+ | c8051 | clipper | craynv | csky | cydra \
+ | d10v | d30v | dlx | dsp16xx \
+ | e2k | elxsi | epiphany \
+ | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
+ | javascript \
+ | h8300 | h8500 \
+ | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i*86 | i860 | i960 | ia16 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | kvx \
+ | le32 | le64 \
+ | lm32 \
+ | loongarch32 | loongarch64 \
+ | m32c | m32r | m32rle \
+ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
+ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
+ | m88110 | m88k | maxq | mb | mcore | mep | metag \
+ | microblaze | microblazeel \
+ | mips* \
+ | mmix \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nfp \
+ | nios | nios2 | nios2eb | nios2el \
+ | none | np1 | ns16k | ns32k | nvptx \
+ | open8 \
+ | or1k* \
+ | or32 \
+ | orion \
+ | picochip \
+ | pdp10 | pdp11 | pj | pjl | pn | power \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
+ | pru \
+ | pyramid \
+ | riscv | riscv32 | riscv32be | riscv64 | riscv64be \
+ | rl78 | romp | rs6000 | rx \
+ | s390 | s390x \
+ | score \
+ | sh | shl \
+ | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
+ | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
+ | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
+ | spu \
+ | tahoe \
+ | thumbv7* \
+ | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
+ | tron \
+ | ubicom32 \
+ | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
+ | vax \
+ | visium \
+ | w65 \
+ | wasm32 | wasm64 \
+ | we32k \
+ | x86 | x86_64 | xc16x | xgate | xps100 \
+ | xstormy16 | xtensa* \
+ | ymp \
+ | z8k | z80)
+ ;;
+
+ *)
+ echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2
+ exit 1
+ ;;
+ esac
;;
esac
# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+case $vendor in
+ digital*)
+ vendor=dec
;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ commodore*)
+ vendor=cbm
;;
*)
;;
@@ -1363,203 +1285,226 @@ esac
# Decode manufacturer-specific aliases for certain operating systems.
-if [ x"$os" != x"" ]
+if test x"$basic_os" != x
then
+
+# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just
+# set os.
+obj=
+case $basic_os in
+ gnu/linux*)
+ kernel=linux
+ os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'`
+ ;;
+ os2-emx)
+ kernel=os2
+ os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'`
+ ;;
+ nto-qnx*)
+ kernel=nto
+ os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'`
+ ;;
+ *-*)
+ # shellcheck disable=SC2162
+ saved_IFS=$IFS
+ IFS="-" read kernel os <<EOF
+$basic_os
+EOF
+ IFS=$saved_IFS
+ ;;
+ # Default OS when just kernel was specified
+ nto*)
+ kernel=nto
+ os=`echo "$basic_os" | sed -e 's|nto|qnx|'`
+ ;;
+ linux*)
+ kernel=linux
+ os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
+ ;;
+ managarm*)
+ kernel=managarm
+ os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'`
+ ;;
+ *)
+ kernel=
+ os=$basic_os
+ ;;
+esac
+
+# Now, normalize the OS (knowing we just have one component, it's not a kernel,
+# etc.)
case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -auroraux)
- os=-auroraux
+ # First match some system type aliases that might get confused
+ # with valid system types.
+ # solaris* is a basic system type, with this one exception.
+ auroraux)
+ os=auroraux
;;
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ bluegene*)
+ os=cnk
;;
- -solaris)
- os=-solaris2
+ solaris1 | solaris1.*)
+ os=`echo "$os" | sed -e 's|solaris1|sunos4|'`
;;
- -svr4*)
- os=-sysv4
+ solaris)
+ os=solaris2
;;
- -unixware*)
- os=-sysv4.2uw
+ unixware*)
+ os=sysv4.2uw
;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ # es1800 is here to avoid being matched by es* (a different OS)
+ es1800*)
+ os=ose
;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
- | -sym* | -kopensolaris* | -plan9* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* | -cloudabi* | -sortix* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
- | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
- | -linux-newlib* | -linux-musl* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
- | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
- ;;
- *)
- os=-nto$os
- ;;
- esac
+ # Some version numbers need modification
+ chorusos*)
+ os=chorusos
;;
- -nto-qnx*)
+ isc)
+ os=isc2.2
;;
- -nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ sco6)
+ os=sco5v6
;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ sco5)
+ os=sco3.2v5
;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
+ sco4)
+ os=sco3.2v4
;;
- -linux-dietlibc)
- os=-linux-dietlibc
+ sco3.2.[4-9]*)
+ os=`echo "$os" | sed -e 's/sco3.2./sco3.2v/'`
;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ sco*v* | scout)
+ # Don't match below
;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ sco*)
+ os=sco3.2v2
;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ psos*)
+ os=psos
;;
- -opened*)
- os=-openedition
+ qnx*)
+ os=qnx
;;
- -os400*)
- os=-os400
+ hiux*)
+ os=hiuxwe2
;;
- -wince*)
- os=-wince
+ lynx*178)
+ os=lynxos178
;;
- -osfrose*)
- os=-osfrose
+ lynx*5)
+ os=lynxos5
;;
- -osf*)
- os=-osf
+ lynxos*)
+ # don't get caught up in next wildcard
;;
- -utek*)
- os=-bsd
+ lynx*)
+ os=lynxos
;;
- -dynix*)
- os=-bsd
+ mac[0-9]*)
+ os=`echo "$os" | sed -e 's|mac|macos|'`
;;
- -acis*)
- os=-aos
+ opened*)
+ os=openedition
;;
- -atheos*)
- os=-atheos
+ os400*)
+ os=os400
;;
- -syllable*)
- os=-syllable
+ sunos5*)
+ os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
;;
- -386bsd)
- os=-bsd
+ sunos6*)
+ os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
;;
- -ctix* | -uts*)
- os=-sysv
+ wince*)
+ os=wince
;;
- -nova*)
- os=-rtmk-nova
+ utek*)
+ os=bsd
;;
- -ns2 )
- os=-nextstep2
+ dynix*)
+ os=bsd
;;
- -nsk*)
- os=-nsk
+ acis*)
+ os=aos
;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
+ atheos*)
+ os=atheos
;;
- -sinix*)
- os=-sysv4
+ syllable*)
+ os=syllable
;;
- -tpf*)
- os=-tpf
+ 386bsd)
+ os=bsd
;;
- -triton*)
- os=-sysv3
+ ctix* | uts*)
+ os=sysv
;;
- -oss*)
- os=-sysv3
+ nova*)
+ os=rtmk-nova
;;
- -svr4)
- os=-sysv4
+ ns2)
+ os=nextstep2
;;
- -svr3)
- os=-sysv3
+ # Preserve the version number of sinix5.
+ sinix5.*)
+ os=`echo "$os" | sed -e 's|sinix|sysv|'`
;;
- -sysvr4)
- os=-sysv4
+ sinix*)
+ os=sysv4
;;
- # This must come after -sysvr4.
- -sysv*)
+ tpf*)
+ os=tpf
;;
- -ose*)
- os=-ose
+ triton*)
+ os=sysv3
;;
- -es1800*)
- os=-ose
+ oss*)
+ os=sysv3
;;
- -xenix)
- os=-xenix
+ svr4*)
+ os=sysv4
;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
+ svr3)
+ os=sysv3
;;
- -aros*)
- os=-aros
+ sysvr4)
+ os=sysv4
;;
- -zvmoe)
- os=-zvmoe
+ ose*)
+ os=ose
;;
- -dicos*)
- os=-dicos
+ *mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
+ os=mint
;;
- -nacl*)
+ dicos*)
+ os=dicos
;;
- -ios)
+ pikeos*)
+ # Until real need of OS specific support for
+ # particular features comes up, bare metal
+ # configurations are quite functional.
+ case $cpu in
+ arm*)
+ os=eabi
+ ;;
+ *)
+ os=
+ obj=elf
+ ;;
+ esac
;;
- -none)
+ aout* | coff* | elf* | pe*)
+ # These are machine code file formats, not OSes
+ obj=$os
+ os=
;;
*)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
+ # No normalization, but not necessarily accepted, that comes below.
;;
esac
+
else
# Here we handle the default operating systems that come with various machines.
@@ -1572,264 +1517,443 @@ else
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.
-case $basic_machine in
+kernel=
+obj=
+case $cpu-$vendor in
score-*)
- os=-elf
+ os=
+ obj=elf
;;
spu-*)
- os=-elf
+ os=
+ obj=elf
;;
*-acorn)
- os=-riscix1.2
+ os=riscix1.2
;;
arm*-rebel)
- os=-linux
+ kernel=linux
+ os=gnu
;;
arm*-semi)
- os=-aout
+ os=
+ obj=aout
;;
c4x-* | tic4x-*)
- os=-coff
+ os=
+ obj=coff
;;
c8051-*)
- os=-elf
+ os=
+ obj=elf
+ ;;
+ clipper-intergraph)
+ os=clix
;;
hexagon-*)
- os=-elf
+ os=
+ obj=elf
;;
tic54x-*)
- os=-coff
+ os=
+ obj=coff
;;
tic55x-*)
- os=-coff
+ os=
+ obj=coff
;;
tic6x-*)
- os=-coff
+ os=
+ obj=coff
;;
# This must come before the *-dec entry.
pdp10-*)
- os=-tops20
+ os=tops20
;;
pdp11-*)
- os=-none
+ os=none
;;
*-dec | vax-*)
- os=-ultrix4.2
+ os=ultrix4.2
;;
m68*-apollo)
- os=-domain
+ os=domain
;;
i386-sun)
- os=-sunos4.0.2
+ os=sunos4.0.2
;;
m68000-sun)
- os=-sunos3
+ os=sunos3
;;
m68*-cisco)
- os=-aout
+ os=
+ obj=aout
;;
mep-*)
- os=-elf
+ os=
+ obj=elf
;;
mips*-cisco)
- os=-elf
+ os=
+ obj=elf
;;
mips*-*)
- os=-elf
+ os=
+ obj=elf
;;
or32-*)
- os=-coff
+ os=
+ obj=coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
+ os=sysv3
;;
sparc-* | *-sun)
- os=-sunos4.1.1
+ os=sunos4.1.1
;;
pru-*)
- os=-elf
+ os=
+ obj=elf
;;
*-be)
- os=-beos
- ;;
- *-haiku)
- os=-haiku
+ os=beos
;;
*-ibm)
- os=-aix
+ os=aix
;;
*-knuth)
- os=-mmixware
+ os=mmixware
;;
*-wec)
- os=-proelf
+ os=proelf
;;
*-winbond)
- os=-proelf
+ os=proelf
;;
*-oki)
- os=-proelf
+ os=proelf
;;
*-hp)
- os=-hpux
+ os=hpux
;;
*-hitachi)
- os=-hiux
+ os=hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
+ os=sysv
;;
*-cbm)
- os=-amigaos
+ os=amigaos
;;
*-dg)
- os=-dgux
+ os=dgux
;;
*-dolphin)
- os=-sysv3
+ os=sysv3
;;
m68k-ccur)
- os=-rtu
+ os=rtu
;;
m88k-omron*)
- os=-luna
+ os=luna
;;
- *-next )
- os=-nextstep
+ *-next)
+ os=nextstep
;;
*-sequent)
- os=-ptx
+ os=ptx
;;
*-crds)
- os=-unos
+ os=unos
;;
*-ns)
- os=-genix
+ os=genix
;;
i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
+ os=mvs
;;
*-gould)
- os=-sysv
+ os=sysv
;;
*-highlevel)
- os=-bsd
+ os=bsd
;;
*-encore)
- os=-bsd
+ os=bsd
;;
*-sgi)
- os=-irix
+ os=irix
;;
*-siemens)
- os=-sysv4
+ os=sysv4
;;
*-masscomp)
- os=-rtu
+ os=rtu
;;
f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
+ os=uxpv
;;
*-rom68k)
- os=-coff
+ os=
+ obj=coff
;;
*-*bug)
- os=-coff
+ os=
+ obj=coff
;;
*-apple)
- os=-macos
+ os=macos
;;
*-atari*)
- os=-mint
+ os=mint
+ ;;
+ *-wrs)
+ os=vxworks
;;
*)
- os=-none
+ os=none
;;
esac
+
fi
+# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ).
+
+case $os in
+ # Sometimes we do "kernel-libc", so those need to count as OSes.
+ musl* | newlib* | relibc* | uclibc*)
+ ;;
+ # Likewise for "kernel-abi"
+ eabi* | gnueabi*)
+ ;;
+ # VxWorks passes extra cpu info in the 4th filed.
+ simlinux | simwindows | spe)
+ ;;
+ # See `case $cpu-$os` validation below
+ ghcjs)
+ ;;
+ # Now accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST end in a * to match a version number.
+ gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
+ | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \
+ | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
+ | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \
+ | hiux* | abug | nacl* | netware* | windows* \
+ | os9* | macos* | osx* | ios* | tvos* | watchos* \
+ | mpw* | magic* | mmixware* | mon960* | lnews* \
+ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
+ | aos* | aros* | cloudabi* | sortix* | twizzler* \
+ | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
+ | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
+ | mirbsd* | netbsd* | dicos* | openedition* | ose* \
+ | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \
+ | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
+ | bosx* | nextstep* | cxux* | oabi* \
+ | ptx* | ecoff* | winnt* | domain* | vsta* \
+ | udi* | lites* | ieee* | go32* | aux* | hcos* \
+ | chorusrdb* | cegcc* | glidix* | serenity* \
+ | cygwin* | msys* | moss* | proelf* | rtems* \
+ | midipix* | mingw32* | mingw64* | mint* \
+ | uxpv* | beos* | mpeix* | udk* | moxiebox* \
+ | interix* | uwin* | mks* | rhapsody* | darwin* \
+ | openstep* | oskit* | conix* | pw32* | nonstopux* \
+ | storm-chaos* | tops10* | tenex* | tops20* | its* \
+ | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \
+ | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \
+ | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
+ | skyos* | haiku* | rdos* | toppers* | drops* | es* \
+ | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
+ | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
+ | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
+ | fiwix* | mlibc* | cos* | mbr* )
+ ;;
+ # This one is extra strict with allowed versions
+ sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ ;;
+ none)
+ ;;
+ kernel* | msvc* )
+ # Restricted further below
+ ;;
+ '')
+ if test x"$obj" = x
+ then
+ echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2
+ fi
+ ;;
+ *)
+ echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2
+ exit 1
+ ;;
+esac
+
+case $obj in
+ aout* | coff* | elf* | pe*)
+ ;;
+ '')
+ # empty is fine
+ ;;
+ *)
+ echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we handle the constraint that a (synthetic) cpu and os are
+# valid only in combination with each other and nowhere else.
+case $cpu-$os in
+ # The "javascript-unknown-ghcjs" triple is used by GHC; we
+ # accept it here in order to tolerate that, but reject any
+ # variations.
+ javascript-ghcjs)
+ ;;
+ javascript-* | *-ghcjs)
+ echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2
+ exit 1
+ ;;
+esac
+
+# As a final step for OS-related things, validate the OS-kernel combination
+# (given a valid OS), if there is a kernel.
+case $kernel-$os-$obj in
+ linux-gnu*- | linux-dietlibc*- | linux-android*- | linux-newlib*- \
+ | linux-musl*- | linux-relibc*- | linux-uclibc*- | linux-mlibc*- )
+ ;;
+ uclinux-uclibc*- )
+ ;;
+ managarm-mlibc*- | managarm-kernel*- )
+ ;;
+ windows*-msvc*-)
+ ;;
+ -dietlibc*- | -newlib*- | -musl*- | -relibc*- | -uclibc*- | -mlibc*- )
+ # These are just libc implementations, not actual OSes, and thus
+ # require a kernel.
+ echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2
+ exit 1
+ ;;
+ -kernel*- )
+ echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2
+ exit 1
+ ;;
+ *-kernel*- )
+ echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2
+ exit 1
+ ;;
+ *-msvc*- )
+ echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2
+ exit 1
+ ;;
+ kfreebsd*-gnu*- | kopensolaris*-gnu*-)
+ ;;
+ vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-)
+ ;;
+ nto-qnx*-)
+ ;;
+ os2-emx-)
+ ;;
+ *-eabi*- | *-gnueabi*-)
+ ;;
+ none--*)
+ # None (no kernel, i.e. freestanding / bare metal),
+ # can be paired with an machine code file format
+ ;;
+ -*-)
+ # Blank kernel with real OS is always fine.
+ ;;
+ --*)
+ # Blank kernel and OS with real machine code file format is always fine.
+ ;;
+ *-*-*)
+ echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2
+ exit 1
+ ;;
+esac
+
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
+case $vendor in
+ unknown)
+ case $cpu-$os in
+ *-riscix*)
vendor=acorn
;;
- -sunos*)
+ *-sunos*)
vendor=sun
;;
- -cnk*|-aix*)
+ *-cnk* | *-aix*)
vendor=ibm
;;
- -beos*)
+ *-beos*)
vendor=be
;;
- -hpux*)
+ *-hpux*)
vendor=hp
;;
- -mpeix*)
+ *-mpeix*)
vendor=hp
;;
- -hiux*)
+ *-hiux*)
vendor=hitachi
;;
- -unos*)
+ *-unos*)
vendor=crds
;;
- -dgux*)
+ *-dgux*)
vendor=dg
;;
- -luna*)
+ *-luna*)
vendor=omron
;;
- -genix*)
+ *-genix*)
vendor=ns
;;
- -mvs* | -opened*)
+ *-clix*)
+ vendor=intergraph
+ ;;
+ *-mvs* | *-opened*)
+ vendor=ibm
+ ;;
+ *-os400*)
vendor=ibm
;;
- -os400*)
+ s390-* | s390x-*)
vendor=ibm
;;
- -ptx*)
+ *-ptx*)
vendor=sequent
;;
- -tpf*)
+ *-tpf*)
vendor=ibm
;;
- -vxsim* | -vxworks* | -windiss*)
+ *-vxsim* | *-vxworks* | *-windiss*)
vendor=wrs
;;
- -aux*)
+ *-aux*)
vendor=apple
;;
- -hms*)
+ *-hms*)
vendor=hitachi
;;
- -mpw* | -macos*)
+ *-mpw* | *-macos*)
vendor=apple
;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*)
vendor=atari
;;
- -vos*)
+ *-vos*)
vendor=stratus
;;
esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
esac
-echo $basic_machine$os
+echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}"
exit
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff --git a/contrib/depends/hosts/android.mk b/contrib/depends/hosts/android.mk
index d6f8b99dd..b08126e86 100644
--- a/contrib/depends/hosts/android.mk
+++ b/contrib/depends/hosts/android.mk
@@ -20,3 +20,4 @@ android_debug_CXXFLAGS=$(android_debug_CFLAGS)
android_native_toolchain=android_ndk
+android_cmake_system=Android
diff --git a/contrib/depends/hosts/darwin.mk b/contrib/depends/hosts/darwin.mk
index d81fd4241..9a96e2601 100644
--- a/contrib/depends/hosts/darwin.mk
+++ b/contrib/depends/hosts/darwin.mk
@@ -19,3 +19,5 @@ darwin_debug_CFLAGS=-O1
darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS)
darwin_native_toolchain=native_cctools darwin_sdk
+
+darwin_cmake_system=Darwin
diff --git a/contrib/depends/hosts/freebsd.mk b/contrib/depends/hosts/freebsd.mk
index 2e3b5933e..d3c6c6149 100644
--- a/contrib/depends/hosts/freebsd.mk
+++ b/contrib/depends/hosts/freebsd.mk
@@ -16,3 +16,4 @@ freebsd_debug_CXXFLAGS=$(freebsd_debug_CFLAGS)
freebsd_native_toolchain=freebsd_base
+freebsd_cmake_system=FreeBSD
diff --git a/contrib/depends/hosts/linux.mk b/contrib/depends/hosts/linux.mk
index 912fdb03c..0f9379f4a 100644
--- a/contrib/depends/hosts/linux.mk
+++ b/contrib/depends/hosts/linux.mk
@@ -30,3 +30,5 @@ i686_linux_CXX=$(default_host_CXX) -m32
x86_64_linux_CC=$(default_host_CC) -m64
x86_64_linux_CXX=$(default_host_CXX) -m64
endif
+
+linux_cmake_system=Linux
diff --git a/contrib/depends/hosts/mingw32.mk b/contrib/depends/hosts/mingw32.mk
index ccc4c5082..58a9a929d 100644
--- a/contrib/depends/hosts/mingw32.mk
+++ b/contrib/depends/hosts/mingw32.mk
@@ -9,3 +9,5 @@ mingw32_debug_CFLAGS=-O1
mingw32_debug_CXXFLAGS=$(mingw32_debug_CFLAGS)
mingw32_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
+
+mingw32_cmake_system=Windows
diff --git a/contrib/depends/toolchain.cmake.in b/contrib/depends/toolchain.cmake.in
index 6fe4618ae..e44882f4c 100644
--- a/contrib/depends/toolchain.cmake.in
+++ b/contrib/depends/toolchain.cmake.in
@@ -1,5 +1,5 @@
# Set the system name to one of Android, Darwin, FreeBSD, Linux, or Windows
-SET(CMAKE_SYSTEM_NAME @depends@)
+SET(CMAKE_SYSTEM_NAME @cmake_system_name@)
SET(CMAKE_SYSTEM_PROCESSOR @arch@)
SET(CMAKE_BUILD_TYPE @release_type@)
diff --git a/contrib/epee/include/net/http_base.h b/contrib/epee/include/net/http_base.h
index 15fd30bf3..b53766780 100644
--- a/contrib/epee/include/net/http_base.h
+++ b/contrib/epee/include/net/http_base.h
@@ -34,6 +34,7 @@
#include <string>
#include <utility>
#include <list>
+#include <stdint.h>
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
diff --git a/contrib/epee/include/net/levin_protocol_handler.h b/contrib/epee/include/net/levin_protocol_handler.h
deleted file mode 100644
index fa7d1a5ab..000000000
--- a/contrib/epee/include/net/levin_protocol_handler.h
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
-//
-
-
-
-#ifndef _LEVIN_PROTOCOL_HANDLER_H_
-#define _LEVIN_PROTOCOL_HANDLER_H_
-
-#include <boost/uuid/uuid_generators.hpp>
-#include "levin_base.h"
-#include "int-util.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "net"
-
-namespace epee
-{
-namespace levin
-{
- template<class t_connection_context = net_utils::connection_context_base>
- struct protocl_handler_config
- {
- levin_commands_handler<t_connection_context>* m_pcommands_handler;
- void (*m_pcommands_handler_destroy)(levin_commands_handler<t_connection_context>*);
- ~protocl_handler_config() { if (m_pcommands_handler && m_pcommands_handler_destroy) (*m_pcommands_handler_destroy)(m_pcommands_handler); }
- };
-
- template<class t_connection_context = net_utils::connection_context_base>
- class protocol_handler
- {
- public:
- typedef t_connection_context connection_context;
- typedef protocl_handler_config<t_connection_context> config_type;
-
- protocol_handler(net_utils::i_service_endpoint* psnd_hndlr, config_type& config, t_connection_context& conn_context);
- virtual ~protocol_handler(){}
-
- virtual bool handle_recv(const void* ptr, size_t cb);
-
- bool after_init_connection(){return true;}
- private:
- enum connection_data_state
- {
- conn_state_reading_head,
- conn_state_reading_body
- };
-
-
- config_type& m_config;
- t_connection_context& m_conn_context;
- net_utils::i_service_endpoint* m_psnd_hndlr;
- std::string m_cach_in_buffer;
- connection_data_state m_state;
- bucket_head m_current_head;
- };
-
- template<class t_connection_context>
- protocol_handler<t_connection_context>::protocol_handler(net_utils::i_service_endpoint* psnd_hndlr, config_type& config, t_connection_context& conn_context):
- m_config(config),
- m_conn_context(conn_context),
- m_psnd_hndlr(psnd_hndlr),
- m_state(conn_state_reading_head),
- m_current_head(bucket_head())
- {}
-
- template<class t_connection_context>
- bool protocol_handler<t_connection_context>::handle_recv(const void* ptr, size_t cb)
- {
- if(!m_config.m_pcommands_handler)
- {
- LOG_ERROR_CC(m_conn_context, "Command handler not set!");
- return false;
- }
- m_cach_in_buffer.append((const char*)ptr, cb);
-
- bool is_continue = true;
- while(is_continue)
- {
- switch(m_state)
- {
- case conn_state_reading_head:
- if(m_cach_in_buffer.size() < sizeof(bucket_head))
- {
- if(m_cach_in_buffer.size() >= sizeof(uint64_t) && *((uint64_t*)m_cach_in_buffer.data()) != SWAP64LE(LEVIN_SIGNATURE))
- {
- LOG_ERROR_CC(m_conn_context, "Signature mismatch on accepted connection");
- return false;
- }
- is_continue = false;
- break;
- }
- {
-#if BYTE_ORDER == LITTLE_ENDIAN
- bucket_head &phead = *(bucket_head*)m_cach_in_buffer.data();
-#else
- bucket_head phead = *(bucket_head*)m_cach_in_buffer.data();
- phead.m_signature = SWAP64LE(phead.m_signature);
- phead.m_cb = SWAP64LE(phead.m_cb);
- phead.m_command = SWAP32LE(phead.m_command);
- phead.m_return_code = SWAP32LE(phead.m_return_code);
- phead.m_reservedA = SWAP32LE(phead.m_reservedA);
- phead.m_reservedB = SWAP32LE(phead.m_reservedB);
-#endif
- if(LEVIN_SIGNATURE != phead.m_signature)
- {
- LOG_ERROR_CC(m_conn_context, "Signature mismatch on accepted connection");
- return false;
- }
- m_current_head = phead;
- }
- m_cach_in_buffer.erase(0, sizeof(bucket_head));
- m_state = conn_state_reading_body;
- break;
- case conn_state_reading_body:
- if(m_cach_in_buffer.size() < m_current_head.m_cb)
- {
- is_continue = false;
- break;
- }
- {
- std::string buff_to_invoke;
- if(m_cach_in_buffer.size() == m_current_head.m_cb)
- buff_to_invoke.swap(m_cach_in_buffer);
- else
- {
- buff_to_invoke.assign(m_cach_in_buffer, 0, (std::string::size_type)m_current_head.m_cb);
- m_cach_in_buffer.erase(0, (std::string::size_type)m_current_head.m_cb);
- }
-
-
- if(m_current_head.m_have_to_return_data)
- {
- std::string return_buff;
- m_current_head.m_return_code = m_config.m_pcommands_handler->invoke(m_current_head.m_command, buff_to_invoke, return_buff, m_conn_context);
- m_current_head.m_cb = return_buff.size();
- m_current_head.m_have_to_return_data = 0;
-
- return_buff.insert(0, (const char*)&m_current_head, sizeof(m_current_head));
- if(!m_psnd_hndlr->do_send(byte_slice{std::move(return_buff)}))
- return false;
-
- }
- else
- m_config.m_pcommands_handler->notify(m_current_head.m_command, buff_to_invoke, m_conn_context);
- }
- m_state = conn_state_reading_head;
- break;
- default:
- LOG_ERROR_CC(m_conn_context, "Undefined state in levin_server_impl::connection_handler, m_state=" << m_state);
- return false;
- }
- }
-
- return true;
- }
-
-
-
-
-
-
-
-}
-}
-
-
-
-
-#endif //_LEVIN_PROTOCOL_HANDLER_H_
-
diff --git a/contrib/epee/include/serialization/wire/write.h b/contrib/epee/include/serialization/wire/write.h
index c18f7dbcc..c2359918c 100644
--- a/contrib/epee/include/serialization/wire/write.h
+++ b/contrib/epee/include/serialization/wire/write.h
@@ -30,6 +30,7 @@
#include <boost/utility/string_ref.hpp>
#include <boost/range/size.hpp>
#include <cstdint>
+#include <iterator>
#include <system_error>
#include <type_traits>
@@ -188,7 +189,13 @@ namespace wire_write
template<typename T>
inline std::size_t array_size(std::true_type, const T& source)
- { return boost::size(source); }
+ {
+ static_assert(
+ !std::is_same<typename std::iterator_traits<typename T::const_iterator>::iterator_category, std::input_iterator_tag>{},
+ "Input iterators must use json (or similar) derived classes directly"
+ );
+ return boost::size(source);
+ }
template<typename T>
inline constexpr std::size_t array_size(std::false_type, const T&) noexcept
diff --git a/contrib/epee/include/storages/portable_storage_from_bin.h b/contrib/epee/include/storages/portable_storage_from_bin.h
index b0af022f5..9fcaf5d01 100644
--- a/contrib/epee/include/storages/portable_storage_from_bin.h
+++ b/contrib/epee/include/storages/portable_storage_from_bin.h
@@ -231,6 +231,7 @@ namespace epee
default:
CHECK_AND_ASSERT_THROW_MES(false, "unknown entry_type code = " << type);
}
+ return read_ae<int8_t>(); // unreachable, dummy return to avoid compiler warning
}
inline
@@ -322,6 +323,7 @@ namespace epee
default:
CHECK_AND_ASSERT_THROW_MES(false, "unknown entry_type code = " << ent_type);
}
+ return read_se<int8_t>(); // unreachable, dummy return to avoid compiler warning
}
inline
void throwable_buffer_reader::read(section& sec)
diff --git a/contrib/epee/src/http_auth.cpp b/contrib/epee/src/http_auth.cpp
index 5071d2685..d6de6a0e1 100644
--- a/contrib/epee/src/http_auth.cpp
+++ b/contrib/epee/src/http_auth.cpp
@@ -217,15 +217,13 @@ namespace
//// Digest Authentication
template<typename Digest>
- typename std::result_of<Digest()>::type generate_a1(
- Digest digest, const http::login& creds, const boost::string_ref realm)
+ auto generate_a1(Digest digest, const http::login& creds, const boost::string_ref realm)
{
return digest(creds.username, u8":", realm, u8":", creds.password);
}
template<typename Digest>
- typename std::result_of<Digest()>::type generate_a1(
- Digest digest, const http::http_client_auth::session& user)
+ auto generate_a1(Digest digest, const http::http_client_auth::session& user)
{
return generate_a1(std::move(digest), user.credentials, user.server.realm);
}
diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp
index 9c10c420c..6fc784fb2 100644
--- a/src/common/dns_utils.cpp
+++ b/src/common/dns_utils.cpp
@@ -28,6 +28,7 @@
#include "common/dns_utils.h"
// check local first (in the event of static or in-source compilation of libunbound)
+#include "misc_language.h"
#include "unbound.h"
#include <deque>
@@ -195,36 +196,7 @@ boost::optional<std::string> tlsa_to_string(const char* src, size_t len)
return boost::none;
return std::string(src, len);
}
-
-// custom smart pointer.
-// TODO: see if std::auto_ptr and the like support custom destructors
-template<typename type, void (*freefunc)(type*)>
-class scoped_ptr
-{
-public:
- scoped_ptr():
- ptr(nullptr)
- {
- }
- scoped_ptr(type *p):
- ptr(p)
- {
- }
- ~scoped_ptr()
- {
- freefunc(ptr);
- }
- operator type *() { return ptr; }
- type **operator &() { return &ptr; }
- type *operator->() { return ptr; }
- operator const type*() const { return &ptr; }
-
-private:
- type* ptr;
-};
-
-typedef class scoped_ptr<ub_result,ub_resolve_free> ub_result_ptr;
-
+
struct DNSResolverData
{
ub_ctx* m_ub_context;
@@ -327,10 +299,14 @@ std::vector<std::string> DNSResolver::get_record(const std::string& url, int rec
std::vector<std::string> addresses;
dnssec_available = false;
dnssec_valid = false;
-
- // destructor takes care of cleanup
- ub_result_ptr result;
-
+
+ ub_result *result;
+ // Make sure we are cleaning after result.
+ epee::misc_utils::auto_scope_leave_caller scope_exit_handler =
+ epee::misc_utils::create_scope_leave_handler([&](){
+ ub_resolve_free(result);
+ });
+
MDEBUG("Performing DNSSEC " << get_record_name(record_type) << " record query for " << url);
// call DNS resolver, blocking. if return value not zero, something went wrong
diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp
index 9aeee3d55..c86e7d848 100644
--- a/src/cryptonote_basic/cryptonote_format_utils.cpp
+++ b/src/cryptonote_basic/cryptonote_format_utils.cpp
@@ -739,22 +739,28 @@ namespace cryptonote
return true;
}
//---------------------------------------------------------------
- bool add_mm_merkle_root_to_tx_extra(std::vector<uint8_t>& tx_extra, const crypto::hash& mm_merkle_root, size_t mm_merkle_tree_depth)
+ bool add_mm_merkle_root_to_tx_extra(std::vector<uint8_t>& tx_extra, const crypto::hash& mm_merkle_root, uint64_t mm_merkle_tree_depth)
{
- CHECK_AND_ASSERT_MES(mm_merkle_tree_depth < 32, false, "merge mining merkle tree depth should be less than 32");
size_t start_pos = tx_extra.size();
- tx_extra.resize(tx_extra.size() + 3 + 32);
+ static const size_t max_varint_size = 16;
+ tx_extra.resize(tx_extra.size() + 2 + 32 + max_varint_size);
//write tag
tx_extra[start_pos] = TX_EXTRA_MERGE_MINING_TAG;
//write data size
++start_pos;
- tx_extra[start_pos] = 33;
- //write depth varint (always one byte here)
+ const off_t len_bytes = start_pos;
+ // one byte placeholder for length since we'll only know the size later after writing a varint
+ tx_extra[start_pos] = 0;
+ //write depth varint
++start_pos;
- tx_extra[start_pos] = mm_merkle_tree_depth;
+ uint8_t *ptr = &tx_extra[start_pos], *start = ptr;
+ tools::write_varint(ptr, mm_merkle_tree_depth);
//write data
- ++start_pos;
+ const size_t varint_size = ptr - start;
+ start_pos += varint_size;
memcpy(&tx_extra[start_pos], &mm_merkle_root, 32);
+ tx_extra.resize(tx_extra.size() - (max_varint_size - varint_size));
+ tx_extra[len_bytes] = 32 + varint_size;
return true;
}
//---------------------------------------------------------------
diff --git a/src/cryptonote_basic/cryptonote_format_utils.h b/src/cryptonote_basic/cryptonote_format_utils.h
index 33fec238e..bd4dcd83d 100644
--- a/src/cryptonote_basic/cryptonote_format_utils.h
+++ b/src/cryptonote_basic/cryptonote_format_utils.h
@@ -83,7 +83,7 @@ namespace cryptonote
std::vector<crypto::public_key> get_additional_tx_pub_keys_from_extra(const transaction_prefix& tx);
bool add_additional_tx_pub_keys_to_extra(std::vector<uint8_t>& tx_extra, const std::vector<crypto::public_key>& additional_pub_keys);
bool add_extra_nonce_to_tx_extra(std::vector<uint8_t>& tx_extra, const blobdata& extra_nonce);
- bool add_mm_merkle_root_to_tx_extra(std::vector<uint8_t>& tx_extra, const crypto::hash& mm_merkle_root, size_t mm_merkle_tree_depth);
+ bool add_mm_merkle_root_to_tx_extra(std::vector<uint8_t>& tx_extra, const crypto::hash& mm_merkle_root, uint64_t mm_merkle_tree_depth);
bool remove_field_from_tx_extra(std::vector<uint8_t>& tx_extra, const std::type_info &type);
void set_payment_id_to_tx_extra_nonce(blobdata& extra_nonce, const crypto::hash& payment_id);
void set_encrypted_payment_id_to_tx_extra_nonce(blobdata& extra_nonce, const crypto::hash8& payment_id);
diff --git a/src/cryptonote_basic/merge_mining.cpp b/src/cryptonote_basic/merge_mining.cpp
index 0e649e095..3e26c00e3 100644
--- a/src/cryptonote_basic/merge_mining.cpp
+++ b/src/cryptonote_basic/merge_mining.cpp
@@ -71,21 +71,21 @@ uint32_t get_path_from_aux_slot(uint32_t slot, uint32_t n_aux_chains)
return path;
}
//---------------------------------------------------------------
-uint32_t encode_mm_depth(uint32_t n_aux_chains, uint32_t nonce)
+uint64_t encode_mm_depth(uint32_t n_aux_chains, uint32_t nonce)
{
CHECK_AND_ASSERT_THROW_MES(n_aux_chains > 0, "n_aux_chains is 0");
+ CHECK_AND_ASSERT_THROW_MES(n_aux_chains <= 256, "n_aux_chains is too large");
// how many bits to we need to representing n_aux_chains - 1
uint32_t n_bits = 1;
- while ((1u << n_bits) < n_aux_chains && n_bits < 16)
+ while ((1u << n_bits) < n_aux_chains)
++n_bits;
- CHECK_AND_ASSERT_THROW_MES(n_bits <= 16, "Way too many bits required");
- const uint32_t depth = (n_bits - 1) | ((n_aux_chains - 1) << 3) | (nonce << (3 + n_bits));
+ const uint64_t depth = (n_bits - 1) | ((n_aux_chains - 1) << 3) | (((uint64_t)nonce) << (3 + n_bits));
return depth;
}
//---------------------------------------------------------------
-bool decode_mm_depth(uint32_t depth, uint32_t &n_aux_chains, uint32_t &nonce)
+bool decode_mm_depth(uint64_t depth, uint32_t &n_aux_chains, uint32_t &nonce)
{
const uint32_t n_bits = 1 + (depth & 7);
n_aux_chains = 1 + (depth >> 3 & ((1 << n_bits) - 1));
diff --git a/src/cryptonote_basic/merge_mining.h b/src/cryptonote_basic/merge_mining.h
index acb70ebf0..ef4c92d67 100644
--- a/src/cryptonote_basic/merge_mining.h
+++ b/src/cryptonote_basic/merge_mining.h
@@ -36,6 +36,6 @@ namespace cryptonote
{
uint32_t get_aux_slot(const crypto::hash &id, uint32_t nonce, uint32_t n_aux_chains);
uint32_t get_path_from_aux_slot(uint32_t slot, uint32_t n_aux_chains);
- uint32_t encode_mm_depth(uint32_t n_aux_chains, uint32_t nonce);
- bool decode_mm_depth(uint32_t depth, uint32_t &n_aux_chains, uint32_t &nonce);
+ uint64_t encode_mm_depth(uint32_t n_aux_chains, uint32_t nonce);
+ bool decode_mm_depth(uint64_t depth, uint32_t &n_aux_chains, uint32_t &nonce);
}
diff --git a/src/cryptonote_basic/tx_extra.h b/src/cryptonote_basic/tx_extra.h
index af6ee5197..cbf942d4c 100644
--- a/src/cryptonote_basic/tx_extra.h
+++ b/src/cryptonote_basic/tx_extra.h
@@ -52,7 +52,7 @@ namespace cryptonote
// load
template <template <bool> class Archive>
- bool do_serialize(Archive<false>& ar)
+ bool member_do_serialize(Archive<false>& ar)
{
// size - 1 - because of variant tag
for (size = 1; size <= TX_EXTRA_PADDING_MAX_COUNT; ++size)
@@ -73,7 +73,7 @@ namespace cryptonote
// store
template <template <bool> class Archive>
- bool do_serialize(Archive<true>& ar)
+ bool member_do_serialize(Archive<true>& ar)
{
if(TX_EXTRA_PADDING_MAX_COUNT < size)
return false;
@@ -124,12 +124,12 @@ namespace cryptonote
END_SERIALIZE()
};
- size_t depth;
+ uint64_t depth;
crypto::hash merkle_root;
// load
template <template <bool> class Archive>
- bool do_serialize(Archive<false>& ar)
+ bool member_do_serialize(Archive<false>& ar)
{
std::string field;
if(!::do_serialize(ar, field))
@@ -142,7 +142,7 @@ namespace cryptonote
// store
template <template <bool> class Archive>
- bool do_serialize(Archive<true>& ar)
+ bool member_do_serialize(Archive<true>& ar)
{
std::ostringstream oss;
binary_archive<true> oar(oss);
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h
index cf2d212b3..459a6a396 100644
--- a/src/p2p/net_node.h
+++ b/src/p2p/net_node.h
@@ -48,7 +48,6 @@
#include "cryptonote_protocol/levin_notify.h"
#include "warnings.h"
#include "net/abstract_tcp_server2.h"
-#include "net/levin_protocol_handler.h"
#include "net/levin_protocol_handler_async.h"
#include "p2p_protocol_defs.h"
#include "storages/levin_abstract_invoke2.h"
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index fbca32f80..9a0b02f70 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -2082,11 +2082,12 @@ namespace cryptonote
}
crypto::hash merkle_root;
- size_t merkle_tree_depth = 0;
std::vector<std::pair<crypto::hash, crypto::hash>> aux_pow;
std::vector<crypto::hash> aux_pow_raw;
+ std::vector<crypto::hash> aux_pow_id_raw;
aux_pow.reserve(req.aux_pow.size());
- aux_pow_raw.reserve(req.aux_pow.size());
+ aux_pow_raw.resize(req.aux_pow.size());
+ aux_pow_id_raw.resize(req.aux_pow.size());
for (const auto &s: req.aux_pow)
{
aux_pow.push_back({});
@@ -2102,7 +2103,6 @@ namespace cryptonote
error_resp.message = "Invalid aux pow hash";
return false;
}
- aux_pow_raw.push_back(aux_pow.back().second);
}
size_t path_domain = 1;
@@ -2111,11 +2111,14 @@ namespace cryptonote
uint32_t nonce;
const uint32_t max_nonce = 65535;
bool collision = true;
+ std::vector<uint32_t> slots(aux_pow.size());
for (nonce = 0; nonce <= max_nonce; ++nonce)
{
- std::vector<bool> slots(aux_pow.size(), false);
+ std::vector<bool> slot_seen(aux_pow.size(), false);
collision = false;
for (size_t idx = 0; idx < aux_pow.size(); ++idx)
+ slots[idx] = 0xffffffff;
+ for (size_t idx = 0; idx < aux_pow.size(); ++idx)
{
const uint32_t slot = cryptonote::get_aux_slot(aux_pow[idx].first, nonce, aux_pow.size());
if (slot >= aux_pow.size())
@@ -2124,12 +2127,13 @@ namespace cryptonote
error_resp.message = "Computed slot is out of range";
return false;
}
- if (slots[slot])
+ if (slot_seen[slot])
{
collision = true;
break;
}
- slots[slot] = true;
+ slot_seen[slot] = true;
+ slots[idx] = slot;
}
if (!collision)
break;
@@ -2141,6 +2145,19 @@ namespace cryptonote
return false;
}
+ // set the order determined above
+ for (size_t i = 0; i < aux_pow.size(); ++i)
+ {
+ if (slots[i] >= aux_pow.size())
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
+ error_resp.message = "Slot value out of range";
+ return false;
+ }
+ aux_pow_raw[slots[i]] = aux_pow[i].second;
+ aux_pow_id_raw[slots[i]] = aux_pow[i].first;
+ }
+
crypto::tree_hash((const char(*)[crypto::HASH_SIZE])aux_pow_raw.data(), aux_pow_raw.size(), merkle_root.data);
res.merkle_root = epee::string_tools::pod_to_hex(merkle_root);
res.merkle_tree_depth = cryptonote::encode_mm_depth(aux_pow.size(), nonce);
@@ -2167,7 +2184,7 @@ namespace cryptonote
error_resp.message = "Error removing existing merkle root";
return false;
}
- if (!add_mm_merkle_root_to_tx_extra(b.miner_tx.extra, merkle_root, merkle_tree_depth))
+ if (!add_mm_merkle_root_to_tx_extra(b.miner_tx.extra, merkle_root, res.merkle_tree_depth))
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Error adding merkle root";
@@ -2181,7 +2198,8 @@ namespace cryptonote
res.blocktemplate_blob = string_tools::buff_to_hex_nodelimer(block_blob);
res.blockhashing_blob = string_tools::buff_to_hex_nodelimer(hashing_blob);
- res.aux_pow = req.aux_pow;
+ for (size_t i = 0; i < aux_pow_raw.size(); ++i)
+ res.aux_pow.push_back({epee::string_tools::pod_to_hex(aux_pow_id_raw[i]), epee::string_tools::pod_to_hex(aux_pow_raw[i])});
res.status = CORE_RPC_STATUS_OK;
return true;
}
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index c0330eed9..2a0a6201d 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -1094,7 +1094,7 @@ namespace cryptonote
blobdata blocktemplate_blob;
blobdata blockhashing_blob;
std::string merkle_root;
- uint32_t merkle_tree_depth;
+ uint64_t merkle_tree_depth;
std::vector<aux_pow_t> aux_pow;
BEGIN_KV_SERIALIZE_MAP()
diff --git a/src/rpc/daemon_messages.cpp b/src/rpc/daemon_messages.cpp
index 0da22f15f..36528fcea 100644
--- a/src/rpc/daemon_messages.cpp
+++ b/src/rpc/daemon_messages.cpp
@@ -48,6 +48,11 @@ void GetHeight::Response::doToJson(rapidjson::Writer<epee::byte_stream>& dest) c
void GetHeight::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, height, height);
}
@@ -61,6 +66,11 @@ void GetBlocksFast::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest
void GetBlocksFast::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, block_ids, block_ids);
GET_FROM_JSON_OBJECT(val, start_height, start_height);
GET_FROM_JSON_OBJECT(val, prune, prune);
@@ -76,6 +86,11 @@ void GetBlocksFast::Response::doToJson(rapidjson::Writer<epee::byte_stream>& des
void GetBlocksFast::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, blocks, blocks);
GET_FROM_JSON_OBJECT(val, start_height, start_height);
GET_FROM_JSON_OBJECT(val, current_height, current_height);
@@ -91,6 +106,11 @@ void GetHashesFast::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest
void GetHashesFast::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, known_hashes, known_hashes);
GET_FROM_JSON_OBJECT(val, start_height, start_height);
}
@@ -100,10 +120,16 @@ void GetHashesFast::Response::doToJson(rapidjson::Writer<epee::byte_stream>& des
INSERT_INTO_JSON_OBJECT(dest, hashes, hashes);
INSERT_INTO_JSON_OBJECT(dest, start_height, start_height);
INSERT_INTO_JSON_OBJECT(dest, current_height, current_height);
+
}
void GetHashesFast::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, hashes, hashes);
GET_FROM_JSON_OBJECT(val, start_height, start_height);
GET_FROM_JSON_OBJECT(val, current_height, current_height);
@@ -117,6 +143,11 @@ void GetTransactions::Request::doToJson(rapidjson::Writer<epee::byte_stream>& de
void GetTransactions::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, tx_hashes, tx_hashes);
}
@@ -128,6 +159,11 @@ void GetTransactions::Response::doToJson(rapidjson::Writer<epee::byte_stream>& d
void GetTransactions::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, txs, txs);
GET_FROM_JSON_OBJECT(val, missed_hashes, missed_hashes);
}
@@ -140,6 +176,11 @@ void KeyImagesSpent::Request::doToJson(rapidjson::Writer<epee::byte_stream>& des
void KeyImagesSpent::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, key_images, key_images);
}
@@ -150,6 +191,11 @@ void KeyImagesSpent::Response::doToJson(rapidjson::Writer<epee::byte_stream>& de
void KeyImagesSpent::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, spent_status, spent_status);
}
@@ -161,6 +207,11 @@ void GetTxGlobalOutputIndices::Request::doToJson(rapidjson::Writer<epee::byte_st
void GetTxGlobalOutputIndices::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, tx_hash, tx_hash);
}
@@ -171,6 +222,11 @@ void GetTxGlobalOutputIndices::Response::doToJson(rapidjson::Writer<epee::byte_s
void GetTxGlobalOutputIndices::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, output_indices, output_indices);
}
@@ -182,6 +238,11 @@ void SendRawTx::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest) co
void SendRawTx::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, tx, tx);
GET_FROM_JSON_OBJECT(val, relay, relay);
}
@@ -194,6 +255,11 @@ void SendRawTx::Response::doToJson(rapidjson::Writer<epee::byte_stream>& dest) c
void SendRawTx::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, relayed, relayed);
}
@@ -205,6 +271,11 @@ void SendRawTxHex::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest)
void SendRawTxHex::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, tx_as_hex, tx_as_hex);
GET_FROM_JSON_OBJECT(val, relay, relay);
}
@@ -219,6 +290,11 @@ void StartMining::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest)
void StartMining::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, miner_address, miner_address);
GET_FROM_JSON_OBJECT(val, threads_count, threads_count);
GET_FROM_JSON_OBJECT(val, do_background_mining, do_background_mining);
@@ -266,6 +342,11 @@ void MiningStatus::Response::doToJson(rapidjson::Writer<epee::byte_stream>& dest
void MiningStatus::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, active, active);
GET_FROM_JSON_OBJECT(val, speed, speed);
GET_FROM_JSON_OBJECT(val, threads_count, threads_count);
@@ -288,6 +369,11 @@ void GetInfo::Response::doToJson(rapidjson::Writer<epee::byte_stream>& dest) con
void GetInfo::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, info, info);
}
@@ -314,6 +400,11 @@ void GetBlockHash::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest)
void GetBlockHash::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, height, height);
}
@@ -324,6 +415,11 @@ void GetBlockHash::Response::doToJson(rapidjson::Writer<epee::byte_stream>& dest
void GetBlockHash::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, hash, hash);
}
@@ -342,6 +438,11 @@ void GetLastBlockHeader::Response::doToJson(rapidjson::Writer<epee::byte_stream>
void GetLastBlockHeader::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, header, header);
}
@@ -353,6 +454,11 @@ void GetBlockHeaderByHash::Request::doToJson(rapidjson::Writer<epee::byte_stream
void GetBlockHeaderByHash::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, hash, hash);
}
@@ -363,6 +469,11 @@ void GetBlockHeaderByHash::Response::doToJson(rapidjson::Writer<epee::byte_strea
void GetBlockHeaderByHash::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, header, header);
}
@@ -374,6 +485,11 @@ void GetBlockHeaderByHeight::Request::doToJson(rapidjson::Writer<epee::byte_stre
void GetBlockHeaderByHeight::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, height, height);
}
@@ -384,6 +500,11 @@ void GetBlockHeaderByHeight::Response::doToJson(rapidjson::Writer<epee::byte_str
void GetBlockHeaderByHeight::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, header, header);
}
@@ -395,6 +516,11 @@ void GetBlockHeadersByHeight::Request::doToJson(rapidjson::Writer<epee::byte_str
void GetBlockHeadersByHeight::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, heights, heights);
}
@@ -405,6 +531,11 @@ void GetBlockHeadersByHeight::Response::doToJson(rapidjson::Writer<epee::byte_st
void GetBlockHeadersByHeight::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, headers, headers);
}
@@ -424,6 +555,11 @@ void GetPeerList::Response::doToJson(rapidjson::Writer<epee::byte_stream>& dest)
void GetPeerList::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, white_list, white_list);
GET_FROM_JSON_OBJECT(val, gray_list, gray_list);
}
@@ -436,6 +572,11 @@ void SetLogLevel::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest)
void SetLogLevel::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, level, level);
}
@@ -462,6 +603,11 @@ void GetTransactionPool::Response::doToJson(rapidjson::Writer<epee::byte_stream>
void GetTransactionPool::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, transactions, transactions);
GET_FROM_JSON_OBJECT(val, key_images, key_images);
}
@@ -474,6 +620,11 @@ void HardForkInfo::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest)
void HardForkInfo::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, version, version);
}
@@ -484,6 +635,11 @@ void HardForkInfo::Response::doToJson(rapidjson::Writer<epee::byte_stream>& dest
void HardForkInfo::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, info, info);
}
@@ -499,6 +655,11 @@ void GetOutputHistogram::Request::doToJson(rapidjson::Writer<epee::byte_stream>&
void GetOutputHistogram::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, amounts, amounts);
GET_FROM_JSON_OBJECT(val, min_count, min_count);
GET_FROM_JSON_OBJECT(val, max_count, max_count);
@@ -513,6 +674,11 @@ void GetOutputHistogram::Response::doToJson(rapidjson::Writer<epee::byte_stream>
void GetOutputHistogram::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, histogram, histogram);
}
@@ -524,6 +690,11 @@ void GetOutputKeys::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest
void GetOutputKeys::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, outputs, outputs);
}
@@ -534,6 +705,11 @@ void GetOutputKeys::Response::doToJson(rapidjson::Writer<epee::byte_stream>& des
void GetOutputKeys::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, keys, keys);
}
@@ -552,6 +728,11 @@ void GetRPCVersion::Response::doToJson(rapidjson::Writer<epee::byte_stream>& des
void GetRPCVersion::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, version, version);
}
@@ -562,6 +743,11 @@ void GetFeeEstimate::Request::doToJson(rapidjson::Writer<epee::byte_stream>& des
void GetFeeEstimate::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, num_grace_blocks, num_grace_blocks);
}
@@ -575,6 +761,11 @@ void GetFeeEstimate::Response::doToJson(rapidjson::Writer<epee::byte_stream>& de
void GetFeeEstimate::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, estimated_base_fee, estimated_base_fee);
GET_FROM_JSON_OBJECT(val, fee_mask, fee_mask);
GET_FROM_JSON_OBJECT(val, size_scale, size_scale);
@@ -591,6 +782,11 @@ void GetOutputDistribution::Request::doToJson(rapidjson::Writer<epee::byte_strea
void GetOutputDistribution::Request::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, amounts, amounts);
GET_FROM_JSON_OBJECT(val, from_height, from_height);
GET_FROM_JSON_OBJECT(val, to_height, to_height);
@@ -605,6 +801,11 @@ void GetOutputDistribution::Response::doToJson(rapidjson::Writer<epee::byte_stre
void GetOutputDistribution::Response::fromJson(const rapidjson::Value& val)
{
+ if (!val.IsObject())
+ {
+ throw json::WRONG_TYPE("json object");
+ }
+
GET_FROM_JSON_OBJECT(val, status, status);
GET_FROM_JSON_OBJECT(val, distributions, distributions);
}
diff --git a/src/rpc/rpc_payment.h b/src/rpc/rpc_payment.h
index 4ead5a344..a4cc6db57 100644
--- a/src/rpc/rpc_payment.h
+++ b/src/rpc/rpc_payment.h
@@ -148,8 +148,8 @@ namespace cryptonote
template <class t_archive>
inline void serialize(t_archive &a, const unsigned int ver)
{
- a & m_client_info.parent();
- a & m_hashrate.parent();
+ a & m_client_info;
+ a & m_hashrate;
a & m_credits_total;
a & m_credits_used;
a & m_nonces_good;
@@ -177,9 +177,9 @@ namespace cryptonote
cryptonote::account_public_address m_address;
uint64_t m_diff;
uint64_t m_credits_per_hash_found;
- serializable_unordered_map<crypto::public_key, client_info> m_client_info;
+ std::unordered_map<crypto::public_key, client_info> m_client_info;
std::string m_directory;
- serializable_map<uint64_t, uint64_t> m_hashrate;
+ std::map<uint64_t, uint64_t> m_hashrate;
uint64_t m_credits_total;
uint64_t m_credits_used;
uint64_t m_nonces_good;
diff --git a/src/rpc/zmq_server.cpp b/src/rpc/zmq_server.cpp
index cb8a8bea4..d73ea3bc9 100644
--- a/src/rpc/zmq_server.cpp
+++ b/src/rpc/zmq_server.cpp
@@ -158,13 +158,22 @@ void ZmqServer::serve()
if (!pub || sockets[2].revents)
{
- std::string message = MONERO_UNWRAP(net::zmq::receive(rep.get(), read_flags));
- MDEBUG("Received RPC request: \"" << message << "\"");
- epee::byte_slice response = handler.handle(std::move(message));
-
- const boost::string_ref response_view{reinterpret_cast<const char*>(response.data()), response.size()};
- MDEBUG("Sending RPC reply: \"" << response_view << "\"");
- MONERO_UNWRAP(net::zmq::send(std::move(response), rep.get()));
+ expect<std::string> message = net::zmq::receive(rep.get(), read_flags);
+ if (!message)
+ {
+ // EAGAIN can occur when using `zmq_poll`, which doesn't inspect for message validity
+ if (message != net::zmq::make_error_code(EAGAIN))
+ MONERO_THROW(message.error(), "Read failure on ZMQ-RPC");
+ }
+ else // no errors
+ {
+ MDEBUG("Received RPC request: \"" << *message << "\"");
+ epee::byte_slice response = handler.handle(std::move(*message));
+
+ const boost::string_ref response_view{reinterpret_cast<const char*>(response.data()), response.size()};
+ MDEBUG("Sending RPC reply: \"" << response_view << "\"");
+ MONERO_UNWRAP(net::zmq::send(std::move(response), rep.get()));
+ }
}
}
}
diff --git a/src/serialization/container.h b/src/serialization/container.h
index 80e1892f2..6f0c48069 100644
--- a/src/serialization/container.h
+++ b/src/serialization/container.h
@@ -42,7 +42,7 @@ namespace serialization
typename std::enable_if<!use_container_varint<T>(), bool>::type
serialize_container_element(Archive& ar, T& e)
{
- return ::do_serialize(ar, e);
+ return do_serialize(ar, e);
}
template<typename Archive, typename T>
@@ -52,13 +52,33 @@ namespace serialization
static constexpr const bool previously_varint = std::is_same<uint64_t, T>() || std::is_same<uint32_t, T>();
if (!previously_varint && ar.varint_bug_backward_compatibility_enabled() && !typename Archive::is_saving())
- return ::do_serialize(ar, e);
+ return do_serialize(ar, e);
ar.serialize_varint(e);
return true;
}
- template <typename C>
- void do_reserve(C &c, size_t N) {}
+ //! @brief Add an element to a container, inserting at the back if applicable.
+ template <class Container>
+ auto do_add(Container &c, typename Container::value_type &&e) -> decltype(c.emplace_back(e))
+ { return c.emplace_back(e); }
+ template <class Container>
+ auto do_add(Container &c, typename Container::value_type &&e) -> decltype(c.emplace(e))
+ { return c.emplace(e); }
+
+ //! @brief Reserve space for N elements if applicable for container.
+ template<typename... C>
+ void do_reserve(const C&...) {}
+ template<typename C>
+ auto do_reserve(C &c, std::size_t N) -> decltype(c.reserve(N)) { return c.reserve(N); }
+
+ // The value_type of STL map-like containers come in the form std::pair<const K, V>.
+ // Since we can't {de}serialize const types in this lib, we must convert this to std::pair<K, V>
+ template <class Container, typename = void>
+ struct serializable_value_type
+ { using type = typename Container::value_type; };
+ template <class Container>
+ struct serializable_value_type<Container, std::conditional_t<false, typename Container::mapped_type, void>>
+ { using type = std::pair<typename Container::key_type, typename Container::mapped_type>; };
}
}
@@ -82,7 +102,7 @@ bool do_serialize_container(Archive<false> &ar, C &v)
for (size_t i = 0; i < cnt; i++) {
if (i > 0)
ar.delimit_array();
- typename C::value_type e;
+ typename ::serialization::detail::serializable_value_type<C>::type e;
if (!::serialization::detail::serialize_container_element(ar, e))
return false;
::serialization::detail::do_add(v, std::move(e));
@@ -104,7 +124,8 @@ bool do_serialize_container(Archive<true> &ar, C &v)
return false;
if (i != v.begin())
ar.delimit_array();
- if(!::serialization::detail::serialize_container_element(ar, (typename C::value_type&)*i))
+ using serializable_value_type = typename ::serialization::detail::serializable_value_type<C>::type;
+ if(!::serialization::detail::serialize_container_element(ar, (serializable_value_type&)*i))
return false;
if (!ar.good())
return false;
diff --git a/src/serialization/containers.h b/src/serialization/containers.h
index 65e6359b2..28eaa50fb 100644
--- a/src/serialization/containers.h
+++ b/src/serialization/containers.h
@@ -38,91 +38,26 @@
#include <set>
#include "serialization.h"
-template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::vector<T> &v);
-template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::vector<T> &v);
-
-template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::deque<T> &v);
-template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::deque<T> &v);
-
-template<typename K, typename V>
-class serializable_unordered_map: public std::unordered_map<K, V>
-{
-public:
- typedef typename std::pair<K, V> value_type;
- typename std::unordered_map<K, V> &parent() { return *this; }
-};
-
-template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<false> &ar, serializable_unordered_map<K, V> &v);
-template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<true> &ar, serializable_unordered_map<K, V> &v);
-
-template<typename K, typename V>
-class serializable_map: public std::map<K, V>
-{
-public:
- typedef typename std::pair<K, V> value_type;
- typename std::map<K, V> &parent() { return *this; }
-};
-
-template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<false> &ar, serializable_map<K, V> &v);
-template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<true> &ar, serializable_map<K, V> &v);
-
-template<typename K, typename V>
-class serializable_unordered_multimap: public std::unordered_multimap<K, V>
-{
-public:
- typedef typename std::pair<K, V> value_type;
- typename std::unordered_multimap<K, V> &parent() { return *this; }
-};
-
-template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<false> &ar, serializable_unordered_multimap<K, V> &v);
-template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<true> &ar, serializable_unordered_multimap<K, V> &v);
-
-template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::unordered_set<T> &v);
-template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::unordered_set<T> &v);
-
-template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::set<T> &v);
-template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::set<T> &v);
-
namespace serialization
{
- namespace detail
- {
- template <typename T> void do_reserve(std::vector<T> &c, size_t N) { c.reserve(N); }
- template <typename T> void do_add(std::vector<T> &c, T &&e) { c.emplace_back(std::forward<T>(e)); }
-
- template <typename T> void do_add(std::deque<T> &c, T &&e) { c.emplace_back(std::forward<T>(e)); }
-
- template <typename K, typename V> void do_add(serializable_unordered_map<K, V> &c, std::pair<K, V> &&e) { c.insert(std::forward<std::pair<K, V>>(e)); }
-
- template <typename K, typename V> void do_add(serializable_map<K, V> &c, std::pair<K, V> &&e) { c.insert(std::forward<std::pair<K, V>>(e)); }
-
- template <typename K, typename V> void do_add(serializable_unordered_multimap<K, V> &c, std::pair<K, V> &&e) { c.insert(std::forward<std::pair<K, V>>(e)); }
-
- template <typename T> void do_add(std::unordered_set<T> &c, T &&e) { c.insert(std::forward<T>(e)); }
-
- template <typename T> void do_add(std::set<T> &c, T &&e) { c.insert(std::forward<T>(e)); }
- }
+ //! @brief Is this type a STL-like container?
+ //! To add a new container to be serialized, partially specialize the template is_container like so:
+ template <typename T> struct is_container: std::false_type {};
+ template <typename... TA> struct is_container<std::deque<TA...>>: std::true_type {};
+ template <typename... TA> struct is_container<std::map<TA...>>: std::true_type {};
+ template <typename... TA> struct is_container<std::multimap<TA...>>: std::true_type {};
+ template <typename... TA> struct is_container<std::set<TA...>>: std::true_type {};
+ template <typename... TA> struct is_container<std::unordered_map<TA...>>: std::true_type {};
+ template <typename... TA> struct is_container<std::unordered_multimap<TA...>>: std::true_type {};
+ template <typename... TA> struct is_container<std::unordered_set<TA...>>: std::true_type {};
+ template <typename... TA> struct is_container<std::vector<TA...>>: std::true_type {};
}
#include "container.h"
-template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::vector<T> &v) { return do_serialize_container(ar, v); }
-template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::vector<T> &v) { return do_serialize_container(ar, v); }
-
-template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::deque<T> &v) { return do_serialize_container(ar, v); }
-template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::deque<T> &v) { return do_serialize_container(ar, v); }
-
-template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<false> &ar, serializable_unordered_map<K, V> &v) { return do_serialize_container(ar, v); }
-template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<true> &ar, serializable_unordered_map<K, V> &v) { return do_serialize_container(ar, v); }
-
-template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<false> &ar, serializable_map<K, V> &v) { return do_serialize_container(ar, v); }
-template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<true> &ar, serializable_map<K, V> &v) { return do_serialize_container(ar, v); }
-
-template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<false> &ar, serializable_unordered_multimap<K, V> &v) { return do_serialize_container(ar, v); }
-template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<true> &ar, serializable_unordered_multimap<K, V> &v) { return do_serialize_container(ar, v); }
-
-template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::unordered_set<T> &v) { return do_serialize_container(ar, v); }
-template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::unordered_set<T> &v) { return do_serialize_container(ar, v); }
-
-template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::set<T> &v) { return do_serialize_container(ar, v); }
-template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::set<T> &v) { return do_serialize_container(ar, v); }
+template <class Archive, class Container>
+std::enable_if_t<::serialization::is_container<Container>::value, bool>
+do_serialize(Archive &ar, Container &c)
+{
+ return ::do_serialize_container(ar, c);
+}
diff --git a/src/serialization/debug_archive.h b/src/serialization/debug_archive.h
index ef3bb4345..f4df963db 100644
--- a/src/serialization/debug_archive.h
+++ b/src/serialization/debug_archive.h
@@ -42,14 +42,12 @@ struct debug_archive : public json_archive<W> {
};
template <class T>
-struct serializer<debug_archive<true>, T>
+static inline bool do_serialize(debug_archive<true> &ar, T &v)
{
- static void serialize(debug_archive<true> &ar, T &v)
- {
ar.begin_object();
ar.tag(variant_serialization_traits<debug_archive<true>, T>::get_tag());
- serializer<json_archive<true>, T>::serialize(ar, v);
+ do_serialize(static_cast<json_archive<true>&>(ar), v);
ar.end_object();
ar.stream() << std::endl;
- }
-};
+ return true;
+}
diff --git a/src/serialization/difficulty_type.h b/src/serialization/difficulty_type.h
index 37761839b..c071f287b 100644
--- a/src/serialization/difficulty_type.h
+++ b/src/serialization/difficulty_type.h
@@ -31,8 +31,6 @@
#include "cryptonote_basic/difficulty.h"
#include "serialization.h"
-template<> struct is_basic_type<cryptonote::difficulty_type> { typedef boost::true_type type; };
-
template <template <bool> class Archive>
inline bool do_serialize(Archive<false>& ar, cryptonote::difficulty_type &diff)
{
diff --git a/src/serialization/pair.h b/src/serialization/pair.h
index f21041fe8..888033fb9 100644
--- a/src/serialization/pair.h
+++ b/src/serialization/pair.h
@@ -47,7 +47,7 @@ namespace serialization
typename std::enable_if<!use_pair_varint<T>(), bool>::type
serialize_pair_element(Archive& ar, T& e)
{
- return ::do_serialize(ar, e);
+ return do_serialize(ar, e);
}
template<typename Archive, typename T>
@@ -57,7 +57,7 @@ namespace serialization
static constexpr const bool previously_varint = std::is_same<uint64_t, T>();
if (!previously_varint && ar.varint_bug_backward_compatibility_enabled() && !typename Archive::is_saving())
- return ::do_serialize(ar, e);
+ return do_serialize(ar, e);
ar.serialize_varint(e);
return true;
}
diff --git a/src/serialization/serialization.h b/src/serialization/serialization.h
index efe1270a4..2911aecb5 100644
--- a/src/serialization/serialization.h
+++ b/src/serialization/serialization.h
@@ -57,73 +57,30 @@
template <class T>
struct is_blob_type { typedef boost::false_type type; };
-/*! \struct has_free_serializer
- *
- * \brief a descriptor for dispatching serialize
- */
-template <class T>
-struct has_free_serializer { typedef boost::true_type type; };
-
-/*! \struct is_basic_type
- *
- * \brief a descriptor for dispatching serialize
- */
-template <class T>
-struct is_basic_type { typedef boost::false_type type; };
-
-template<typename F, typename S>
-struct is_basic_type<std::pair<F,S>> { typedef boost::true_type type; };
-template<>
-struct is_basic_type<std::string> { typedef boost::true_type type; };
-
-/*! \struct serializer
+/*! \fn do_serialize(Archive &ar, T &v)
*
- * \brief ... wouldn't a class be better?
+ * \brief main function for dispatching serialization for a given pair of archive and value types
*
- * \detailed The logic behind serializing data. Places the archive
- * data into the supplied parameter. This dispatches based on the
- * supplied \a T template parameter's traits of is_blob_type or it is
- * an integral (as defined by the is_integral trait). Depends on the
- * \a Archive parameter to have overloaded the serialize_blob(T v,
- * size_t size) and serialize_int(T v) base on which trait it
- * applied. When the class has neither types, it falls to the
- * overloaded method do_serialize(Archive ar) in T to do the work.
+ * Types marked true with is_blob_type<T> will be serialized as a blob, integral types will be
+ * serialized as integers, and types who have a `member_do_serialize` method will be serialized
+ * using that method. Booleans are serialized like blobs.
*/
template <class Archive, class T>
-struct serializer{
- static bool serialize(Archive &ar, T &v) {
- return serialize(ar, v, typename boost::is_integral<T>::type(), typename is_blob_type<T>::type(), typename is_basic_type<T>::type());
- }
- template<typename A>
- static bool serialize(Archive &ar, T &v, boost::false_type, boost::true_type, A a) {
- ar.serialize_blob(&v, sizeof(v));
- return true;
- }
- template<typename A>
- static bool serialize(Archive &ar, T &v, boost::true_type, boost::false_type, A a) {
- ar.serialize_int(v);
- return true;
- }
- static bool serialize(Archive &ar, T &v, boost::false_type, boost::false_type, boost::false_type) {
- //serialize_custom(ar, v, typename has_free_serializer<T>::type());
- return v.do_serialize(ar);
- }
- static bool serialize(Archive &ar, T &v, boost::false_type, boost::false_type, boost::true_type) {
- //serialize_custom(ar, v, typename has_free_serializer<T>::type());
- return do_serialize(ar, v);
- }
- static void serialize_custom(Archive &ar, T &v, boost::true_type) {
- }
-};
-
-/*! \fn do_serialize(Archive &ar, T &v)
- *
- * \brief just calls the serialize function defined for ar and v...
- */
+inline std::enable_if_t<is_blob_type<T>::type::value, bool> do_serialize(Archive &ar, T &v)
+{
+ ar.serialize_blob(&v, sizeof(v));
+ return true;
+}
template <class Archive, class T>
-inline bool do_serialize(Archive &ar, T &v)
+inline std::enable_if_t<boost::is_integral<T>::value, bool> do_serialize(Archive &ar, T &v)
{
- return ::serializer<Archive, T>::serialize(ar, v);
+ ar.serialize_int(v);
+ return true;
+}
+template <class Archive, class T>
+inline auto do_serialize(Archive &ar, T &v) -> decltype(v.member_do_serialize(ar), true)
+{
+ return v.member_do_serialize(ar);
}
template <class Archive>
inline bool do_serialize(Archive &ar, bool &v)
@@ -144,16 +101,6 @@ inline bool do_serialize(Archive &ar, bool &v)
typedef boost::true_type type; \
}
-/*! \macro FREE_SERIALIZER
- *
- * \brief adds the has_free_serializer to the type
- */
-#define FREE_SERIALIZER(T) \
- template<> \
- struct has_free_serializer<T> { \
- typedef boost::true_type type; \
- }
-
/*! \macro VARIANT_TAG
*
* \brief Adds the tag \tag to the \a Archive of \a Type
@@ -174,7 +121,7 @@ inline bool do_serialize(Archive &ar, bool &v)
*/
#define BEGIN_SERIALIZE() \
template <bool W, template <bool> class Archive> \
- bool do_serialize(Archive<W> &ar) {
+ bool member_do_serialize(Archive<W> &ar) {
/*! \macro BEGIN_SERIALIZE_OBJECT
*
@@ -183,7 +130,7 @@ inline bool do_serialize(Archive &ar, bool &v)
*/
#define BEGIN_SERIALIZE_OBJECT() \
template <bool W, template <bool> class Archive> \
- bool do_serialize(Archive<W> &ar) { \
+ bool member_do_serialize(Archive<W> &ar) { \
ar.begin_object(); \
bool r = do_serialize_object(ar); \
ar.end_object(); \
@@ -197,11 +144,6 @@ inline bool do_serialize(Archive &ar, bool &v)
#define PREPARE_CUSTOM_VECTOR_SERIALIZATION(size, vec) \
::serialization::detail::prepare_custom_vector_serialization(size, vec, typename Archive<W>::is_saving())
-/*! \macro PREPARE_CUSTOM_DEQUE_SERIALIZATION
- */
-#define PREPARE_CUSTOM_DEQUE_SERIALIZATION(size, vec) \
- ::serialization::detail::prepare_custom_deque_serialization(size, vec, typename Archive<W>::is_saving())
-
/*! \macro END_SERIALIZE
* \brief self-explanatory
*/
@@ -209,16 +151,6 @@ inline bool do_serialize(Archive &ar, bool &v)
return ar.good(); \
}
-/*! \macro VALUE(f)
- * \brief the same as FIELD(f)
- */
-#define VALUE(f) \
- do { \
- ar.tag(#f); \
- bool r = ::do_serialize(ar, f); \
- if (!r || !ar.good()) return false; \
- } while(0);
-
/*! \macro FIELD_N(t,f)
*
* \brief serializes a field \a f tagged \a t
@@ -226,7 +158,7 @@ inline bool do_serialize(Archive &ar, bool &v)
#define FIELD_N(t, f) \
do { \
ar.tag(t); \
- bool r = ::do_serialize(ar, f); \
+ bool r = do_serialize(ar, f); \
if (!r || !ar.good()) return false; \
} while(0);
@@ -237,7 +169,7 @@ inline bool do_serialize(Archive &ar, bool &v)
#define FIELD(f) \
do { \
ar.tag(#f); \
- bool r = ::do_serialize(ar, f); \
+ bool r = do_serialize(ar, f); \
if (!r || !ar.good()) return false; \
} while(0);
@@ -247,7 +179,7 @@ inline bool do_serialize(Archive &ar, bool &v)
*/
#define FIELDS(f) \
do { \
- bool r = ::do_serialize(ar, f); \
+ bool r = do_serialize(ar, f); \
if (!r || !ar.good()) return false; \
} while(0);
@@ -317,17 +249,6 @@ namespace serialization {
vec.resize(size);
}
- template <typename T>
- void prepare_custom_deque_serialization(size_t size, std::deque<T>& vec, const boost::mpl::bool_<true>& /*is_saving*/)
- {
- }
-
- template <typename T>
- void prepare_custom_deque_serialization(size_t size, std::deque<T>& vec, const boost::mpl::bool_<false>& /*is_saving*/)
- {
- vec.resize(size);
- }
-
/*! \fn do_check_stream_state
*
* \brief self explanatory
diff --git a/src/serialization/tuple.h b/src/serialization/tuple.h
index e76ca0b99..d9592bc96 100644
--- a/src/serialization/tuple.h
+++ b/src/serialization/tuple.h
@@ -39,7 +39,7 @@ namespace serialization
template <typename Archive, class T>
bool serialize_tuple_element(Archive& ar, T& e)
{
- return ::do_serialize(ar, e);
+ return do_serialize(ar, e);
}
template <typename Archive>
diff --git a/src/serialization/variant.h b/src/serialization/variant.h
index 77d767a1c..1cf93c8cf 100644
--- a/src/serialization/variant.h
+++ b/src/serialization/variant.h
@@ -72,7 +72,7 @@ struct variant_reader
{
if(variant_serialization_traits<Archive, current_type>::get_tag() == t) {
current_type x;
- if(!::do_serialize(ar, x))
+ if(!do_serialize(ar, x))
{
ar.set_fail();
return false;
@@ -100,19 +100,13 @@ struct variant_reader<Archive, Variant, TBegin, TBegin>
}
};
-
-template <template <bool> class Archive, BOOST_VARIANT_ENUM_PARAMS(typename T)>
-struct serializer<Archive<false>, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
-{
- typedef boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> variant_type;
- typedef typename Archive<false>::variant_tag_type variant_tag_type;
- typedef typename variant_type::types types;
-
- static bool serialize(Archive<false> &ar, variant_type &v) {
- variant_tag_type t;
+template <template <bool> class Archive, typename... T>
+static bool do_serialize(Archive<false> &ar, boost::variant<T...> &v) {
+ using types = typename boost::variant<T...>::types;
+ typename Archive<false>::variant_tag_type t;
ar.begin_variant();
ar.read_variant_tag(t);
- if(!variant_reader<Archive<false>, variant_type,
+ if(!variant_reader<Archive<false>, boost::variant<T...>,
typename boost::mpl::begin<types>::type,
typename boost::mpl::end<types>::type>::read(ar, v, t))
{
@@ -121,27 +115,21 @@ struct serializer<Archive<false>, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
}
ar.end_variant();
return true;
- }
-};
+}
-template <template <bool> class Archive, BOOST_VARIANT_ENUM_PARAMS(typename T)>
-struct serializer<Archive<true>, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
+template <template <bool> class Archive>
+struct variant_write_visitor : public boost::static_visitor<bool>
{
- typedef boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> variant_type;
- //typedef typename Archive<true>::variant_tag_type variant_tag_type;
-
- struct visitor : public boost::static_visitor<bool>
- {
Archive<true> &ar;
- visitor(Archive<true> &a) : ar(a) { }
+ variant_write_visitor(Archive<true> &a) : ar(a) { }
template <class T>
bool operator ()(T &rv) const
{
ar.begin_variant();
ar.write_variant_tag(variant_serialization_traits<Archive<true>, T>::get_tag());
- if(!::do_serialize(ar, rv))
+ if(!do_serialize(ar, rv))
{
ar.set_fail();
return false;
@@ -149,9 +137,10 @@ struct serializer<Archive<true>, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
ar.end_variant();
return true;
}
- };
-
- static bool serialize(Archive<true> &ar, variant_type &v) {
- return boost::apply_visitor(visitor(ar), v);
- }
};
+
+template <template <bool> class Archive, typename... T>
+static bool do_serialize(Archive<true> &ar, boost::variant<T...> &v)
+{
+ return boost::apply_visitor(variant_write_visitor<Archive>(ar), v);
+}
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 6e5d0b1ec..bff62f1a8 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -188,7 +188,7 @@ namespace
const char* USAGE_INCOMING_TRANSFERS("incoming_transfers [available|unavailable] [verbose] [uses] [index=<N1>[,<N2>[,...]]]");
const char* USAGE_PAYMENTS("payments <PID_1> [<PID_2> ... <PID_N>]");
const char* USAGE_PAYMENT_ID("payment_id");
- const char* USAGE_TRANSFER("transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] (<URI> | <address> <amount>) [<payment_id>]");
+ const char* USAGE_TRANSFER("transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] (<URI> | <address> <amount>) [subtractfeefrom=<D0>[,<D1>,all,...]] [<payment_id>]");
const char* USAGE_LOCKED_TRANSFER("locked_transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] (<URI> | <addr> <amount>) <lockblocks> [<payment_id (obsolete)>]");
const char* USAGE_LOCKED_SWEEP_ALL("locked_sweep_all [index=<N1>[,<N2>,...] | index=all] [<priority>] [<ring_size>] <address> <lockblocks> [<payment_id (obsolete)>]");
const char* USAGE_SWEEP_ALL("sweep_all [index=<N1>[,<N2>,...] | index=all] [<priority>] [<ring_size>] [outputs=<N>] <address> [<payment_id (obsolete)>]");
@@ -520,7 +520,52 @@ namespace
fail_msg_writer() << sw::tr("invalid format for subaddress lookahead; must be <major>:<minor>");
return r;
}
-}
+
+ static constexpr std::string_view SFFD_ARG_NAME{"subtractfeefrom="};
+
+ bool parse_subtract_fee_from_outputs
+ (
+ const std::string& arg,
+ tools::wallet2::unique_index_container& subtract_fee_from_outputs,
+ bool& subtract_fee_from_all,
+ bool& matches
+ )
+ {
+ matches = false;
+ if (!boost::string_ref{arg}.starts_with(SFFD_ARG_NAME.data())) // if arg doesn't match
+ return true;
+ matches = true;
+
+ const char* arg_end = arg.c_str() + arg.size();
+ for (const char* p = arg.c_str() + SFFD_ARG_NAME.size(); p < arg_end;)
+ {
+ const char* new_p = nullptr;
+ const unsigned long dest_index = strtoul(p, const_cast<char**>(&new_p), 10);
+ if (dest_index == 0 && new_p == p) // numerical conversion failed
+ {
+ if (0 != strncmp(p, "all", 3))
+ {
+ fail_msg_writer() << tr("Failed to parse subtractfeefrom list");
+ return false;
+ }
+ subtract_fee_from_all = true;
+ break;
+ }
+ else if (dest_index > std::numeric_limits<uint32_t>::max())
+ {
+ fail_msg_writer() << tr("Destination index is too large") << ": " << dest_index;
+ return false;
+ }
+ else
+ {
+ subtract_fee_from_outputs.insert(dest_index);
+ p = new_p + 1; // skip the comma
+ }
+ }
+
+ return true;
+ }
+} // anonymous namespace
void simple_wallet::handle_transfer_exception(const std::exception_ptr &e, bool trusted_daemon)
{
@@ -3080,7 +3125,7 @@ simple_wallet::simple_wallet()
tr("Show the blockchain height."));
m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::on_command, this, &simple_wallet::transfer, _1),
tr(USAGE_TRANSFER),
- tr("Transfer <amount> to <address>. If the parameter \"index=<N1>[,<N2>,...]\" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command \"set priority\") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included)"));
+ tr("Transfer <amount> to <address>. If the parameter \"index=<N1>[,<N2>,...]\" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command \"set priority\") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included). The \"subtractfeefrom=\" list allows you to choose which destinations to fund the tx fee from instead of the change output. The fee will be split across the chosen destinations proportionally equally. For example, to make 3 transfers where the fee is taken from the first and third destinations, one could do: \"transfer <addr1> 3 <addr2> 0.5 <addr3> 1 subtractfeefrom=0,2\". Let's say the tx fee is 0.1. The balance would drop by exactly 4.5 XMR including fees, and addr1 & addr3 would receive 2.925 & 0.975 XMR, respectively. Use \"subtractfeefrom=all\" to spread the fee across all destinations."));
m_cmd_binder.set_handler("locked_transfer",
boost::bind(&simple_wallet::on_command, this, &simple_wallet::locked_transfer,_1),
tr(USAGE_LOCKED_TRANSFER),
@@ -6349,6 +6394,27 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
local_args.pop_back();
}
+ // Parse subtractfeefrom destination list
+ tools::wallet2::unique_index_container subtract_fee_from_outputs;
+ bool subtract_fee_from_all = false;
+ for (auto it = local_args.begin(); it < local_args.end();)
+ {
+ bool matches = false;
+ if (!parse_subtract_fee_from_outputs(*it, subtract_fee_from_outputs, subtract_fee_from_all, matches))
+ {
+ return false;
+ }
+ else if (matches)
+ {
+ it = local_args.erase(it);
+ break;
+ }
+ else
+ {
+ ++it;
+ }
+ }
+
vector<cryptonote::address_parse_info> dsts_info;
vector<cryptonote::tx_destination_entry> dsts;
for (size_t i = 0; i < local_args.size(); )
@@ -6445,6 +6511,13 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
dsts.push_back(de);
}
+ if (subtract_fee_from_all)
+ {
+ subtract_fee_from_outputs.clear();
+ for (decltype(subtract_fee_from_outputs)::value_type i = 0; i < dsts.size(); ++i)
+ subtract_fee_from_outputs.insert(i);
+ }
+
SCOPED_WALLET_UNLOCK_ON_BAD_PASSWORD(return false;);
try
@@ -6463,13 +6536,13 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
return false;
}
unlock_block = bc_height + locked_blocks;
- ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices);
+ ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
break;
default:
LOG_ERROR("Unknown transfer method, using default");
/* FALLTHRU */
case Transfer:
- ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices);
+ ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
break;
}
diff --git a/src/wallet/message_transporter.cpp b/src/wallet/message_transporter.cpp
index b4f6ce7bd..e6c26cba0 100644
--- a/src/wallet/message_transporter.cpp
+++ b/src/wallet/message_transporter.cpp
@@ -273,16 +273,29 @@ bool message_transporter::post_request(const std::string &request, std::string &
{
if ((string_value.find("API Error 0021") == 0) && (request.find("joinChan") != std::string::npos))
{
+ // "API Error 0021: Unexpected API Failure"
// Error that occurs if one tries to join an already joined chan, which can happen
// if several auto-config participants share one PyBitmessage instance: As a little
// hack simply ignore the error. (A clean solution would be to check for the chan
// with 'listAddresses2', but parsing the returned array is much more complicated.)
}
+ else if ((string_value.find("API Error 0024") == 0) && (request.find("joinChan") != std::string::npos))
+ {
+ // "API Error 0024: Chan address is already present."
+ // Maybe a result of creating the chan in a slightly different way i.e. not with
+ // 'createChan'; everything works by just ignoring this error
+ }
else if ((string_value.find("API Error 0013") == 0) && (request.find("leaveChan") != std::string::npos))
{
+ // "API Error 0013: Could not find your fromAddress in the keys.dat file."
// Error that occurs if one tries to leave an already left / deleted chan, which can happen
// if several auto-config participants share one PyBitmessage instance: Also ignore.
}
+ else if ((string_value.find("API Error 0025") == 0) && (request.find("leaveChan") != std::string::npos))
+ {
+ // "API Error 0025: Specified address is not a chan address. Use deleteAddress API call instead."
+ // Error does not really make sense, but everything works by just ignoring
+ }
else
{
THROW_WALLET_EXCEPTION(tools::error::bitmessage_api_error, string_value);
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index b5392d5f9..e9c48f9a8 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -1821,7 +1821,7 @@ void reattach_blockchain(hashchain &blockchain, wallet2::detached_blockchain_dat
}
//----------------------------------------------------------------------------------------------------
bool has_nonrequested_tx_at_height_or_above_requested(uint64_t height, const std::unordered_set<crypto::hash> &requested_txids, const wallet2::transfer_container &transfers,
- const wallet2::payment_container &payments, const serializable_unordered_map<crypto::hash, wallet2::confirmed_transfer_details> &confirmed_txs)
+ const wallet2::payment_container &payments, const std::unordered_map<crypto::hash, wallet2::confirmed_transfer_details> &confirmed_txs)
{
for (const auto &td : transfers)
if (td.m_block_height >= height && requested_txids.find(td.m_txid) == requested_txids.end())
@@ -4252,9 +4252,6 @@ wallet2::detached_blockchain_data wallet2::detach_blockchain(uint64_t height, st
++it;
}
- if (m_callback)
- m_callback->on_reorg(height, blocks_detached, transfers_detached);
-
LOG_PRINT_L0("Detached blockchain on height " << height << ", transfers detached " << transfers_detached << ", blocks detached " << blocks_detached);
return dbd;
}
@@ -4266,7 +4263,10 @@ void wallet2::handle_reorg(uint64_t height, std::map<std::pair<uint64_t, uint64_
// C
THROW_WALLET_EXCEPTION_IF(height < m_blockchain.offset() && m_blockchain.size() > m_blockchain.offset(),
error::wallet_internal_error, "Daemon claims reorg below last checkpoint");
- detach_blockchain(height, output_tracker_cache);
+ detached_blockchain_data dbd = detach_blockchain(height, output_tracker_cache);
+
+ if (m_callback)
+ m_callback->on_reorg(height, dbd.detached_blockchain.size(), dbd.detached_tx_hashes.size());
}
//----------------------------------------------------------------------------------------------------
bool wallet2::deinit()
@@ -7304,9 +7304,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin
crypto::key_derivation derivation;
std::vector<crypto::key_derivation> additional_derivations;
- // compute public keys from out secret keys
- crypto::public_key tx_pub_key;
- crypto::secret_key_to_public_key(txs[n].tx_key, tx_pub_key);
+ crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx);
std::vector<crypto::public_key> additional_tx_pub_keys;
for (const crypto::secret_key &skey: txs[n].additional_tx_keys)
{
@@ -8685,6 +8683,26 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
COMMAND_RPC_GET_OUTPUTS_BIN::request req = AUTO_VAL_INIT(req);
COMMAND_RPC_GET_OUTPUTS_BIN::response daemon_resp = AUTO_VAL_INIT(daemon_resp);
+ // The secret picking order contains outputs in the order that we selected them.
+ //
+ // We will later sort the output request entries in a pre-determined order so that the daemon
+ // that we're requesting information from doesn't learn any information about the true spend
+ // for each ring. However, internally, we want to prefer to construct our rings using the
+ // outputs that we picked first versus outputs picked later.
+ //
+ // The reason why is because each consecutive output pick within a ring becomes increasing less
+ // statistically independent from other picks, since we pick outputs from a finite set
+ // *without replacement*, due to the protocol not allowing duplicate ring members. This effect
+ // is exacerbated by the fact that we pick 1.5x + 75 as many outputs as we need per RPC
+ // request to account for unusable outputs. This effect is small, but non-neglibile and gets
+ // worse with larger ring sizes.
+ std::vector<get_outputs_out> secret_picking_order;
+
+ // Convenience/safety lambda to make sure that both output lists req.outputs and secret_picking_order are updated together
+ // Each ring section of req.outputs gets sorted later after selecting all outputs for that ring
+ const auto add_output_to_lists = [&req, &secret_picking_order](const get_outputs_out &goo)
+ { req.outputs.push_back(goo); secret_picking_order.push_back(goo); };
+
std::unique_ptr<gamma_picker> gamma;
if (has_rct)
gamma.reset(new gamma_picker(rct_offsets));
@@ -8819,7 +8837,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
if (out < num_outs)
{
MINFO("Using it");
- req.outputs.push_back({amount, out});
+ add_output_to_lists({amount, out});
++num_found;
seen_indices.emplace(out);
if (out == td.m_global_output_index)
@@ -8841,12 +8859,12 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
if (num_outs <= requested_outputs_count)
{
for (uint64_t i = 0; i < num_outs; i++)
- req.outputs.push_back({amount, i});
+ add_output_to_lists({amount, i});
// duplicate to make up shortfall: this will be caught after the RPC call,
// so we can also output the amounts for which we can't reach the required
// mixin after checking the actual unlockedness
for (uint64_t i = num_outs; i < requested_outputs_count; ++i)
- req.outputs.push_back({amount, num_outs - 1});
+ add_output_to_lists({amount, num_outs - 1});
}
else
{
@@ -8855,7 +8873,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
{
num_found = 1;
seen_indices.emplace(td.m_global_output_index);
- req.outputs.push_back({amount, td.m_global_output_index});
+ add_output_to_lists({amount, td.m_global_output_index});
LOG_PRINT_L1("Selecting real output: " << td.m_global_output_index << " for " << print_money(amount));
}
@@ -8963,7 +8981,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
seen_indices.emplace(i);
picks[type].insert(i);
- req.outputs.push_back({amount, i});
+ add_output_to_lists({amount, i});
++num_found;
MDEBUG("picked " << i << ", " << num_found << " now picked");
}
@@ -8977,7 +8995,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
// we'll error out later
while (num_found < requested_outputs_count)
{
- req.outputs.push_back({amount, 0});
+ add_output_to_lists({amount, 0});
++num_found;
}
}
@@ -8987,6 +9005,10 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
[](const get_outputs_out &a, const get_outputs_out &b) { return a.index < b.index; });
}
+ THROW_WALLET_EXCEPTION_IF(req.outputs.size() != secret_picking_order.size(), error::wallet_internal_error,
+ "bug: we did not update req.outputs/secret_picking_order in tandem");
+
+ // List all requested outputs to debug log
if (ELPP->vRegistry()->allowed(el::Level::Debug, MONERO_DEFAULT_LOG_CATEGORY))
{
std::map<uint64_t, std::set<uint64_t>> outs;
@@ -9104,18 +9126,21 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
}
}
- // then pick others in random order till we reach the required number
- // since we use an equiprobable pick here, we don't upset the triangular distribution
- std::vector<size_t> order;
- order.resize(requested_outputs_count);
- for (size_t n = 0; n < order.size(); ++n)
- order[n] = n;
- std::shuffle(order.begin(), order.end(), crypto::random_device{});
-
+ // While we are still lacking outputs in this result ring, in our secret pick order...
LOG_PRINT_L2("Looking for " << (fake_outputs_count+1) << " outputs of size " << print_money(td.is_rct() ? 0 : td.amount()));
- for (size_t o = 0; o < requested_outputs_count && outs.back().size() < fake_outputs_count + 1; ++o)
+ for (size_t ring_pick_idx = base; ring_pick_idx < base + requested_outputs_count && outs.back().size() < fake_outputs_count + 1; ++ring_pick_idx)
{
- size_t i = base + order[o];
+ const get_outputs_out attempted_output = secret_picking_order[ring_pick_idx];
+
+ // Find the index i of our pick in the request/response arrays
+ size_t i;
+ for (i = base; i < base + requested_outputs_count; ++i)
+ if (req.outputs[i].index == attempted_output.index)
+ break;
+ THROW_WALLET_EXCEPTION_IF(i == base + requested_outputs_count, error::wallet_internal_error,
+ "Could not find index of picked output in requested outputs");
+
+ // Try adding this output's information to result ring if output isn't invalid
LOG_PRINT_L2("Index " << i << "/" << requested_outputs_count << ": idx " << req.outputs[i].index << " (real " << td.m_global_output_index << "), unlocked " << daemon_resp.outs[i].unlocked << ", key " << daemon_resp.outs[i].key);
tx_add_fake_output(outs, req.outputs[i].index, daemon_resp.outs[i].key, daemon_resp.outs[i].mask, td.m_global_output_index, daemon_resp.outs[i].unlocked, valid_public_keys_cache);
}
@@ -9826,7 +9851,7 @@ static uint32_t get_count_above(const std::vector<wallet2::transfer_details> &tr
// This system allows for sending (almost) the entire balance, since it does
// not generate spurious change in all txes, thus decreasing the instantaneous
// usable balance.
-std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
+std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs)
{
//ensure device is let in NONE mode in any case
hw::device &hwdev = m_account.get_device();
@@ -9837,11 +9862,12 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
std::vector<std::pair<uint32_t, std::vector<size_t>>> unused_transfers_indices_per_subaddr;
std::vector<std::pair<uint32_t, std::vector<size_t>>> unused_dust_indices_per_subaddr;
- uint64_t needed_money;
+ uint64_t needed_money, total_needed_money; // 'needed_money' is the sum of the destination amounts, while 'total_needed_money' includes 'needed_money' plus the fee if not 'subtract_fee_from_outputs'
uint64_t accumulated_fee, accumulated_change;
struct TX {
std::vector<size_t> selected_transfers;
std::vector<cryptonote::tx_destination_entry> dsts;
+ std::vector<bool> dsts_are_fee_subtractable;
cryptonote::transaction tx;
pending_tx ptx;
size_t weight;
@@ -9851,9 +9877,11 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
TX() : weight(0), needed_fee(0) {}
/* Add an output to the transaction.
+ * If merge_destinations is true, when adding a destination with an existing address, to increment the amount of the existing tx output instead of creating a new one
+ * If subtracting_fee is true, when we generate a final list of destinations for transfer_selected[_rct], this destination will be used to fund the tx fee
* Returns True if the output was added, False if there are no more available output slots.
*/
- bool add(const cryptonote::tx_destination_entry &de, uint64_t amount, unsigned int original_output_index, bool merge_destinations, size_t max_dsts) {
+ bool add(const cryptonote::tx_destination_entry &de, uint64_t amount, unsigned int original_output_index, bool merge_destinations, size_t max_dsts, bool subtracting_fee) {
if (merge_destinations)
{
std::vector<cryptonote::tx_destination_entry>::iterator i;
@@ -9863,6 +9891,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
if (dsts.size() >= max_dsts)
return false;
dsts.push_back(de);
+ dsts_are_fee_subtractable.push_back(subtracting_fee);
i = dsts.end() - 1;
i->amount = 0;
}
@@ -9878,13 +9907,67 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
return false;
dsts.push_back(de);
dsts.back().amount = 0;
+ dsts_are_fee_subtractable.push_back(subtracting_fee);
}
THROW_WALLET_EXCEPTION_IF(memcmp(&dsts[original_output_index].addr, &de.addr, sizeof(de.addr)), error::wallet_internal_error, "Mismatched destination address");
dsts[original_output_index].amount += amount;
}
return true;
}
+
+ // Returns destinations adjusted for given fee if subtract_fee_from_outputs is enabled
+ std::vector<cryptonote::tx_destination_entry> get_adjusted_dsts(uint64_t needed_fee) const
+ {
+ uint64_t dest_total = 0;
+ uint64_t subtractable_dest_total = 0;
+ std::vector<size_t> subtractable_indices;
+ subtractable_indices.reserve(dsts.size());
+ for (size_t i = 0; i < dsts.size(); ++i)
+ {
+ dest_total += dsts[i].amount;
+ if (dsts_are_fee_subtractable[i])
+ {
+ subtractable_dest_total += dsts[i].amount;
+ subtractable_indices.push_back(i);
+ }
+ }
+
+ if (subtractable_indices.empty()) // if subtract_fee_from_outputs is not enabled for this tx
+ return dsts;
+
+ THROW_WALLET_EXCEPTION_IF(subtractable_dest_total < needed_fee, error::tx_not_possible,
+ subtractable_dest_total, dest_total, needed_fee);
+
+ std::vector<cryptonote::tx_destination_entry> res = dsts;
+
+ // subtract fees from destinations equally, rounded down, until dust is left where we subtract 1
+ uint64_t subtractable_remaining = needed_fee;
+ auto si_it = subtractable_indices.cbegin();
+ uint64_t amount_to_subtract = 0;
+ while (subtractable_remaining)
+ {
+ // Set the amount to subtract iterating at the beginning of the list so equal amounts are
+ // subtracted throughout the list of destinations. We use max(x, 1) so that we we still step
+ // forwards even when the amount remaining is less than the number of subtractable indices
+ if (si_it == subtractable_indices.cbegin())
+ amount_to_subtract = std::max<uint64_t>(subtractable_remaining / subtractable_indices.size(), 1);
+
+ cryptonote::tx_destination_entry& d = res[*si_it];
+ THROW_WALLET_EXCEPTION_IF(d.amount <= amount_to_subtract, error::zero_amount);
+
+ subtractable_remaining -= amount_to_subtract;
+ d.amount -= amount_to_subtract;
+ ++si_it;
+
+ // Wrap around to first subtractable index once we hit the end of the list
+ if (si_it == subtractable_indices.cend())
+ si_it = subtractable_indices.cbegin();
+ }
+
+ return res;
+ }
};
+
std::vector<TX> txes;
bool adding_fee; // true if new outputs go towards fee, rather than destinations
uint64_t needed_fee, available_for_fee = 0;
@@ -9907,6 +9990,14 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// throw if attempting a transaction with no destinations
THROW_WALLET_EXCEPTION_IF(dsts.empty(), error::zero_destination);
+ // throw if subtract_fee_from_outputs has a bad index
+ THROW_WALLET_EXCEPTION_IF(subtract_fee_from_outputs.size() && *subtract_fee_from_outputs.crbegin() >= dsts.size(),
+ error::subtract_fee_from_bad_index, *subtract_fee_from_outputs.crbegin());
+
+ // throw if subtract_fee_from_outputs is enabled and we have too many outputs to fit into one tx
+ THROW_WALLET_EXCEPTION_IF(subtract_fee_from_outputs.size() && dsts.size() > BULLETPROOF_MAX_OUTPUTS - 1,
+ error::wallet_internal_error, "subtractfeefrom transfers cannot be split over multiple transactions yet");
+
// calculate total amount being sent to all destinations
// throw if total amount overflows uint64_t
needed_money = 0;
@@ -9934,6 +10025,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// we could also check for being within FEE_PER_KB, but if the fee calculation
// ever changes, this might be missed, so let this go through
const uint64_t min_fee = (base_fee * estimate_tx_size(use_rct, 1, fake_outs_count, 2, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags));
+ total_needed_money = needed_money + (subtract_fee_from_outputs.size() ? 0 : min_fee);
uint64_t balance_subtotal = 0;
uint64_t unlocked_balance_subtotal = 0;
for (uint32_t index_minor : subaddr_indices)
@@ -9941,10 +10033,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
balance_subtotal += balance_per_subaddr[index_minor];
unlocked_balance_subtotal += unlocked_balance_per_subaddr[index_minor].first;
}
- THROW_WALLET_EXCEPTION_IF(needed_money + min_fee > balance_subtotal, error::not_enough_money,
+ THROW_WALLET_EXCEPTION_IF(total_needed_money > balance_subtotal || min_fee > balance_subtotal, error::not_enough_money,
balance_subtotal, needed_money, 0);
// first check overall balance is enough, then unlocked one, so we throw distinct exceptions
- THROW_WALLET_EXCEPTION_IF(needed_money + min_fee > unlocked_balance_subtotal, error::not_enough_unlocked_money,
+ THROW_WALLET_EXCEPTION_IF(total_needed_money > unlocked_balance_subtotal || min_fee > unlocked_balance_subtotal, error::not_enough_unlocked_money,
unlocked_balance_subtotal, needed_money, 0);
for (uint32_t i : subaddr_indices)
@@ -10047,7 +10139,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// this is used to build a tx that's 1 or 2 inputs, and 2 outputs, which
// will get us a known fee.
uint64_t estimated_fee = estimate_fee(use_per_byte_fee, use_rct, 2, fake_outs_count, 2, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags, base_fee, fee_quantization_mask);
- preferred_inputs = pick_preferred_rct_inputs(needed_money + estimated_fee, subaddr_account, subaddr_indices);
+ total_needed_money = needed_money + (subtract_fee_from_outputs.size() ? 0 : estimated_fee);
+ preferred_inputs = pick_preferred_rct_inputs(total_needed_money, subaddr_account, subaddr_indices);
if (!preferred_inputs.empty())
{
string s;
@@ -10080,7 +10173,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// - we have something to send
// - or we need to gather more fee
// - or we have just one input in that tx, which is rct (to try and make all/most rct txes 2/2)
- unsigned int original_output_index = 0;
+ unsigned int original_output_index = 0, destination_index = 0;
std::vector<size_t>* unused_transfers_indices = &unused_transfers_indices_per_subaddr[0].second;
std::vector<size_t>* unused_dust_indices = &unused_dust_indices_per_subaddr[0].second;
@@ -10163,7 +10256,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// we can fully pay that destination
LOG_PRINT_L2("We can fully pay " << get_account_address_as_str(m_nettype, dsts[0].is_subaddress, dsts[0].addr) <<
" for " << print_money(dsts[0].amount));
- if (!tx.add(dsts[0], dsts[0].amount, original_output_index, m_merge_destinations, BULLETPROOF_MAX_OUTPUTS-1))
+ const bool subtract_fee_from_this_dest = subtract_fee_from_outputs.count(destination_index);
+ if (!tx.add(dsts[0], dsts[0].amount, original_output_index, m_merge_destinations, BULLETPROOF_MAX_OUTPUTS-1, subtract_fee_from_this_dest))
{
LOG_PRINT_L2("Didn't pay: ran out of output slots");
out_slots_exhausted = true;
@@ -10173,6 +10267,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
dsts[0].amount = 0;
pop_index(dsts, 0);
++original_output_index;
+ ++destination_index;
}
if (!out_slots_exhausted && available_amount > 0 && !dsts.empty() &&
@@ -10180,7 +10275,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// we can partially fill that destination
LOG_PRINT_L2("We can partially pay " << get_account_address_as_str(m_nettype, dsts[0].is_subaddress, dsts[0].addr) <<
" for " << print_money(available_amount) << "/" << print_money(dsts[0].amount));
- if (tx.add(dsts[0], available_amount, original_output_index, m_merge_destinations, BULLETPROOF_MAX_OUTPUTS-1))
+ const bool subtract_fee_from_this_dest = subtract_fee_from_outputs.count(destination_index);
+ if (tx.add(dsts[0], available_amount, original_output_index, m_merge_destinations, BULLETPROOF_MAX_OUTPUTS-1, subtract_fee_from_this_dest))
{
dsts[0].amount -= available_amount;
available_amount = 0;
@@ -10259,9 +10355,13 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// Try to carve the estimated fee from the partial payment (if there is one)
available_for_fee = try_carving_from_partial_payment(needed_fee, available_for_fee);
- uint64_t inputs = 0, outputs = needed_fee;
+ uint64_t inputs = 0, outputs = 0;
for (size_t idx: tx.selected_transfers) inputs += m_transfers[idx].amount();
for (const auto &o: tx.dsts) outputs += o.amount;
+ if (subtract_fee_from_outputs.empty()) // if normal tx that doesn't subtract fees
+ {
+ outputs += needed_fee;
+ }
if (inputs < outputs)
{
@@ -10272,15 +10372,32 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
LOG_PRINT_L2("Trying to create a tx now, with " << tx.dsts.size() << " outputs and " <<
tx.selected_transfers.size() << " inputs");
+ auto tx_dsts = tx.get_adjusted_dsts(needed_fee);
if (use_rct)
- transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
+ transfer_selected_rct(tx_dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
test_tx, test_ptx, rct_config, use_view_tags);
else
- transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
+ transfer_selected(tx_dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags);
auto txBlob = t_serializable_object_to_blob(test_ptx.tx);
needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_quantization_mask);
- available_for_fee = test_ptx.fee + test_ptx.change_dts.amount + (!test_ptx.dust_added_to_fee ? test_ptx.dust : 0);
+
+ // Depending on the mode, we take extra fees from either our change output or the destination outputs for which subtract_fee_from_outputs is true
+ uint64_t output_available_for_fee = 0;
+ bool tx_has_subtractable_output = false;
+ for (size_t di = 0; di < tx.dsts.size(); ++di)
+ {
+ if (tx.dsts_are_fee_subtractable[di])
+ {
+ output_available_for_fee += tx.dsts[di].amount;
+ tx_has_subtractable_output = true;
+ }
+ }
+ if (!tx_has_subtractable_output)
+ {
+ output_available_for_fee = test_ptx.change_dts.amount;
+ }
+ available_for_fee = test_ptx.fee + output_available_for_fee + (!test_ptx.dust_added_to_fee ? test_ptx.dust : 0);
LOG_PRINT_L2("Made a " << get_weight_string(test_ptx.tx, txBlob.size()) << " tx, with " << print_money(available_for_fee) << " available for fee (" <<
print_money(needed_fee) << " needed)");
@@ -10296,18 +10413,24 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
else
{
LOG_PRINT_L2("We made a tx, adjusting fee and saving it, we need " << print_money(needed_fee) << " and we have " << print_money(test_ptx.fee));
- do {
+ size_t fee_tries;
+ for (fee_tries = 0; fee_tries < 10 && needed_fee > test_ptx.fee; ++fee_tries) {
+ tx_dsts = tx.get_adjusted_dsts(needed_fee);
+
if (use_rct)
- transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
+ transfer_selected_rct(tx_dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
test_tx, test_ptx, rct_config, use_view_tags);
else
- transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
+ transfer_selected(tx_dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags);
txBlob = t_serializable_object_to_blob(test_ptx.tx);
needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_quantization_mask);
LOG_PRINT_L2("Made an attempt at a final " << get_weight_string(test_ptx.tx, txBlob.size()) << " tx, with " << print_money(test_ptx.fee) <<
" fee and " << print_money(test_ptx.change_dts.amount) << " change");
- } while (needed_fee > test_ptx.fee);
+ };
+
+ THROW_WALLET_EXCEPTION_IF(fee_tries == 10, error::wallet_internal_error,
+ "Too many attempts to raise pending tx fee to level of needed fee");
LOG_PRINT_L2("Made a final " << get_weight_string(test_ptx.tx, txBlob.size()) << " tx, with " << print_money(test_ptx.fee) <<
" fee and " << print_money(test_ptx.change_dts.amount) << " change");
@@ -10360,10 +10483,13 @@ skip_tx:
for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i)
{
TX &tx = *i;
+
+ const auto tx_dsts = tx.get_adjusted_dsts(tx.needed_fee);
+
cryptonote::transaction test_tx;
pending_tx test_ptx;
if (use_rct) {
- transfer_selected_rct(tx.dsts, /* NOMOD std::vector<cryptonote::tx_destination_entry> dsts,*/
+ transfer_selected_rct(tx_dsts, /* NOMOD std::vector<cryptonote::tx_destination_entry> dsts,*/
tx.selected_transfers, /* const std::list<size_t> selected_transfers */
fake_outs_count, /* CONST size_t fake_outputs_count, */
tx.outs, /* MOD std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, */
@@ -10376,7 +10502,7 @@ skip_tx:
rct_config,
use_view_tags); /* const bool use_view_tags */
} else {
- transfer_selected(tx.dsts,
+ transfer_selected(tx_dsts,
tx.selected_transfers,
fake_outs_count,
tx.outs,
@@ -10410,23 +10536,38 @@ skip_tx:
ptx_vector.push_back(tx.ptx);
}
- THROW_WALLET_EXCEPTION_IF(!sanity_check(ptx_vector, original_dsts), error::wallet_internal_error, "Created transaction(s) failed sanity check");
+ THROW_WALLET_EXCEPTION_IF(!sanity_check(ptx_vector, original_dsts, subtract_fee_from_outputs), error::wallet_internal_error, "Created transaction(s) failed sanity check");
// if we made it this far, we're OK to actually send the transactions
return ptx_vector;
}
-bool wallet2::sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, std::vector<cryptonote::tx_destination_entry> dsts) const
+bool wallet2::sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, const std::vector<cryptonote::tx_destination_entry>& dsts, const unique_index_container& subtract_fee_from_outputs) const
{
- MDEBUG("sanity_check: " << ptx_vector.size() << " txes, " << dsts.size() << " destinations");
+ MDEBUG("sanity_check: " << ptx_vector.size() << " txes, " << dsts.size() << " destinations, subtract_fee_from_outputs " <<
+ (subtract_fee_from_outputs.size() ? "enabled" : "disabled"));
THROW_WALLET_EXCEPTION_IF(ptx_vector.empty(), error::wallet_internal_error, "No transactions");
+ THROW_WALLET_EXCEPTION_IF(!subtract_fee_from_outputs.empty() && ptx_vector.size() != 1,
+ error::wallet_internal_error, "feature subtractfeefrom not supported for split transactions");
+
+ // For destinations from where the fee is subtracted, the required amount has to be at least
+ // target amount - (tx fee / num_subtractable + 1). +1 since fee might not be evenly divisble by
+ // the number of subtractble destinations. For non-subtractable destinations, we need at least
+ // the target amount.
+ const size_t num_subtractable_dests = subtract_fee_from_outputs.size();
+ const uint64_t fee0 = ptx_vector[0].fee;
+ const uint64_t subtractable_fee_deduction = fee0 / std::max<size_t>(num_subtractable_dests, 1) + 1;
// check every party in there does receive at least the required amount
std::unordered_map<account_public_address, std::pair<uint64_t, bool>> required;
- for (const auto &d: dsts)
+ for (size_t i = 0; i < dsts.size(); ++i)
{
- required[d.addr].first += d.amount;
+ const cryptonote::tx_destination_entry& d = dsts[i];
+ const bool dest_is_subtractable = subtract_fee_from_outputs.count(i);
+ const uint64_t fee_deduction = dest_is_subtractable ? subtractable_fee_deduction : 0;
+ const uint64_t required_amount = d.amount - std::min(fee_deduction, d.amount);
+ required[d.addr].first += required_amount;
required[d.addr].second = d.is_subaddress;
}
@@ -12008,7 +12149,7 @@ std::string wallet2::get_reserve_proof(const boost::optional<std::pair<uint32_t,
}
// collect all subaddress spend keys that received those outputs and generate their signatures
- serializable_unordered_map<crypto::public_key, crypto::signature> subaddr_spendkeys;
+ std::unordered_map<crypto::public_key, crypto::signature> subaddr_spendkeys;
for (const cryptonote::subaddress_index &index : subaddr_indices)
{
crypto::secret_key subaddr_spend_skey = m_account.get_keys().m_spend_secret_key;
@@ -12053,7 +12194,7 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr
bool loaded = false;
std::vector<reserve_proof_entry> proofs;
- serializable_unordered_map<crypto::public_key, crypto::signature> subaddr_spendkeys;
+ std::unordered_map<crypto::public_key, crypto::signature> subaddr_spendkeys;
try
{
binary_archive<false> ar{epee::strspan<std::uint8_t>(sig_decoded)};
@@ -12067,7 +12208,7 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr
{
std::istringstream iss(sig_decoded);
boost::archive::portable_binary_iarchive ar(iss);
- ar >> proofs >> subaddr_spendkeys.parent();
+ ar >> proofs >> subaddr_spendkeys;
}
THROW_WALLET_EXCEPTION_IF(subaddr_spendkeys.count(address.m_spend_public_key) == 0, error::wallet_internal_error,
@@ -12311,7 +12452,7 @@ std::string wallet2::get_description() const
return "";
}
-const std::pair<serializable_map<std::string, std::string>, std::vector<std::string>>& wallet2::get_account_tags()
+const std::pair<std::map<std::string, std::string>, std::vector<std::string>>& wallet2::get_account_tags()
{
// ensure consistency
if (m_account_tags.second.size() != get_num_subaddress_accounts())
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index d93b9b9fb..c5d2dc90c 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -590,7 +590,8 @@ private:
};
typedef std::vector<transfer_details> transfer_container;
- typedef serializable_unordered_multimap<crypto::hash, payment_details> payment_container;
+ typedef std::unordered_multimap<crypto::hash, payment_details> payment_container;
+ typedef std::set<uint32_t> unique_index_container;
struct multisig_sig
{
@@ -701,7 +702,7 @@ private:
{
std::vector<pending_tx> ptx;
std::vector<crypto::key_image> key_images;
- serializable_unordered_map<crypto::public_key, crypto::key_image> tx_key_images;
+ std::unordered_map<crypto::public_key, crypto::key_image> tx_key_images;
BEGIN_SERIALIZE_OBJECT()
VERSION_FIELD(0)
@@ -1096,11 +1097,11 @@ private:
bool parse_unsigned_tx_from_str(const std::string &unsigned_tx_st, unsigned_tx_set &exported_txs) const;
bool load_tx(const std::string &signed_filename, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set&)> accept_func = NULL);
bool parse_tx_from_str(const std::string &signed_tx_st, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set &)> accept_func);
- std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices); // pass subaddr_indices by value on purpose
+ std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
std::vector<wallet2::pending_tx> create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices);
std::vector<wallet2::pending_tx> create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra);
std::vector<wallet2::pending_tx> create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra);
- bool sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, std::vector<cryptonote::tx_destination_entry> dsts) const;
+ bool sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, const std::vector<cryptonote::tx_destination_entry>& dsts, const unique_index_container& subtract_fee_from_outputs = {}) const;
void cold_tx_aux_import(const std::vector<pending_tx>& ptx, const std::vector<std::string>& tx_device_aux);
void cold_sign_tx(const std::vector<pending_tx>& ptx_vector, signed_tx_set &exported_txs, std::vector<cryptonote::address_parse_info> &dsts_info, std::vector<std::string> & tx_device_aux);
uint64_t cold_key_image_sync(uint64_t &spent, uint64_t &unspent);
@@ -1157,25 +1158,25 @@ private:
}
a & m_transfers;
a & m_account_public_address;
- a & m_key_images.parent();
+ a & m_key_images;
if(ver < 6)
return;
- a & m_unconfirmed_txs.parent();
+ a & m_unconfirmed_txs;
if(ver < 7)
return;
- a & m_payments.parent();
+ a & m_payments;
if(ver < 8)
return;
- a & m_tx_keys.parent();
+ a & m_tx_keys;
if(ver < 9)
return;
- a & m_confirmed_txs.parent();
+ a & m_confirmed_txs;
if(ver < 11)
return;
a & dummy_refresh_height;
if(ver < 12)
return;
- a & m_tx_notes.parent();
+ a & m_tx_notes;
if(ver < 13)
return;
if (ver < 17)
@@ -1200,7 +1201,7 @@ private:
}
return;
}
- a & m_pub_keys.parent();
+ a & m_pub_keys;
if(ver < 16)
return;
a & m_address_book;
@@ -1221,17 +1222,17 @@ private:
a & m_scanned_pool_txs[1];
if (ver < 20)
return;
- a & m_subaddresses.parent();
+ a & m_subaddresses;
std::unordered_map<cryptonote::subaddress_index, crypto::public_key> dummy_subaddresses_inv;
a & dummy_subaddresses_inv;
a & m_subaddress_labels;
- a & m_additional_tx_keys.parent();
+ a & m_additional_tx_keys;
if(ver < 21)
return;
- a & m_attributes.parent();
+ a & m_attributes;
if(ver < 22)
return;
- a & m_unconfirmed_payments.parent();
+ a & m_unconfirmed_payments;
if(ver < 23)
return;
a & (std::pair<std::map<std::string, std::string>, std::vector<std::string>>&)m_account_tags;
@@ -1243,13 +1244,13 @@ private:
a & m_last_block_reward;
if(ver < 26)
return;
- a & m_tx_device.parent();
+ a & m_tx_device;
if(ver < 27)
return;
a & m_device_last_key_image_sync;
if(ver < 28)
return;
- a & m_cold_key_images.parent();
+ a & m_cold_key_images;
if(ver < 29)
return;
crypto::secret_key dummy_rpc_client_secret_key; // Compatibility for old RPC payment system
@@ -1464,7 +1465,7 @@ private:
* \brief Get the list of registered account tags.
* \return first.Key=(tag's name), first.Value=(tag's label), second[i]=(i-th account's tag)
*/
- const std::pair<serializable_map<std::string, std::string>, std::vector<std::string>>& get_account_tags();
+ const std::pair<std::map<std::string, std::string>, std::vector<std::string>>& get_account_tags();
/*!
* \brief Set a tag to the given accounts.
* \param account_indices Indices of accounts.
@@ -1776,28 +1777,28 @@ private:
std::string m_mms_file;
const std::unique_ptr<epee::net_utils::http::abstract_http_client> m_http_client;
hashchain m_blockchain;
- serializable_unordered_map<crypto::hash, unconfirmed_transfer_details> m_unconfirmed_txs;
- serializable_unordered_map<crypto::hash, confirmed_transfer_details> m_confirmed_txs;
- serializable_unordered_multimap<crypto::hash, pool_payment_details> m_unconfirmed_payments;
- serializable_unordered_map<crypto::hash, crypto::secret_key> m_tx_keys;
+ std::unordered_map<crypto::hash, unconfirmed_transfer_details> m_unconfirmed_txs;
+ std::unordered_map<crypto::hash, confirmed_transfer_details> m_confirmed_txs;
+ std::unordered_multimap<crypto::hash, pool_payment_details> m_unconfirmed_payments;
+ std::unordered_map<crypto::hash, crypto::secret_key> m_tx_keys;
cryptonote::checkpoints m_checkpoints;
- serializable_unordered_map<crypto::hash, std::vector<crypto::secret_key>> m_additional_tx_keys;
+ std::unordered_map<crypto::hash, std::vector<crypto::secret_key>> m_additional_tx_keys;
transfer_container m_transfers;
payment_container m_payments;
- serializable_unordered_map<crypto::key_image, size_t> m_key_images;
- serializable_unordered_map<crypto::public_key, size_t> m_pub_keys;
+ std::unordered_map<crypto::key_image, size_t> m_key_images;
+ std::unordered_map<crypto::public_key, size_t> m_pub_keys;
cryptonote::account_public_address m_account_public_address;
- serializable_unordered_map<crypto::public_key, cryptonote::subaddress_index> m_subaddresses;
+ std::unordered_map<crypto::public_key, cryptonote::subaddress_index> m_subaddresses;
std::vector<std::vector<std::string>> m_subaddress_labels;
- serializable_unordered_map<crypto::hash, std::string> m_tx_notes;
- serializable_unordered_map<std::string, std::string> m_attributes;
+ std::unordered_map<crypto::hash, std::string> m_tx_notes;
+ std::unordered_map<std::string, std::string> m_attributes;
std::vector<tools::wallet2::address_book_row> m_address_book;
- std::pair<serializable_map<std::string, std::string>, std::vector<std::string>> m_account_tags;
+ std::pair<std::map<std::string, std::string>, std::vector<std::string>> m_account_tags;
uint64_t m_upper_transaction_weight_limit; //TODO: auto-calc this value or request from daemon, now use some fixed value
const std::vector<std::vector<tools::wallet2::multisig_info>> *m_multisig_rescan_info;
const std::vector<std::vector<rct::key>> *m_multisig_rescan_k;
- serializable_unordered_map<crypto::public_key, crypto::key_image> m_cold_key_images;
+ std::unordered_map<crypto::public_key, crypto::key_image> m_cold_key_images;
std::atomic<bool> m_run;
@@ -1868,7 +1869,7 @@ private:
bool m_allow_mismatched_daemon_version;
// Aux transaction data from device
- serializable_unordered_map<crypto::hash, std::string> m_tx_device;
+ std::unordered_map<crypto::hash, std::string> m_tx_device;
std::string m_ring_database;
bool m_ring_history_saved;
@@ -2313,7 +2314,7 @@ namespace boost
a & x.key_images;
if (ver < 1)
return;
- a & x.tx_key_images.parent();
+ a & x.tx_key_images;
}
template <class Archive>
diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h
index 6706e77ff..5166f868f 100644
--- a/src/wallet/wallet_errors.h
+++ b/src/wallet/wallet_errors.h
@@ -85,6 +85,7 @@ namespace tools
// tx_too_big
// zero_amount
// zero_destination
+ // subtract_fee_from_bad_index
// wallet_rpc_error *
// daemon_busy
// no_connection_to_daemon
@@ -779,6 +780,15 @@ namespace tools
}
};
//----------------------------------------------------------------------------------------------------
+ struct subtract_fee_from_bad_index : public transfer_error
+ {
+ explicit subtract_fee_from_bad_index(std::string&& loc, long bad_index)
+ : transfer_error(std::move(loc),
+ "subtractfeefrom: bad index: " + std::to_string(bad_index) + " (indexes are 0-based)")
+ {
+ }
+ };
+ //----------------------------------------------------------------------------------------------------
struct wallet_rpc_error : public wallet_logic_error
{
const std::string& request() const { return m_request; }
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index 0cc42ae3f..c43745dc6 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -987,9 +987,9 @@ namespace tools
return amount;
}
//------------------------------------------------------------------------------------------------------------------------------
- template<typename Ts, typename Tu, typename Tk>
+ template<typename Ts, typename Tu, typename Tk, typename Ta>
bool wallet_rpc_server::fill_response(std::vector<tools::wallet2::pending_tx> &ptx_vector,
- bool get_tx_key, Ts& tx_key, Tu &amount, Tu &fee, Tu &weight, std::string &multisig_txset, std::string &unsigned_txset, bool do_not_relay,
+ bool get_tx_key, Ts& tx_key, Tu &amount, Ta &amounts_by_dest, Tu &fee, Tu &weight, std::string &multisig_txset, std::string &unsigned_txset, bool do_not_relay,
Ts &tx_hash, bool get_tx_hex, Ts &tx_blob, bool get_tx_metadata, Ts &tx_metadata, Tk &spent_key_images, epee::json_rpc::error &er)
{
for (const auto & ptx : ptx_vector)
@@ -1006,6 +1006,12 @@ namespace tools
fill(fee, ptx.fee);
fill(weight, cryptonote::get_transaction_weight(ptx.tx));
+ // add amounts by destination
+ tools::wallet_rpc::amounts_list abd;
+ for (const auto& dst : ptx.dests)
+ abd.amounts.push_back(dst.amount);
+ fill(amounts_by_dest, abd);
+
// add spent key images
tools::wallet_rpc::key_image_list key_image_list;
bool all_are_txin_to_key = std::all_of(ptx.tx.vin.begin(), ptx.tx.vin.end(), [&](const cryptonote::txin_v& s_e) -> bool
@@ -1086,7 +1092,7 @@ namespace tools
{
uint64_t mixin = m_wallet->adjust_mixin(req.ring_size ? req.ring_size - 1 : 0);
uint32_t priority = m_wallet->adjust_priority(req.priority);
- std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices);
+ std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices, req.subtract_fee_from_outputs);
if (ptx_vector.empty())
{
@@ -1103,7 +1109,7 @@ namespace tools
return false;
}
- return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.fee, res.weight, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
+ return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.amounts_by_dest, res.fee, res.weight, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, res.spent_key_images, er);
}
catch (const std::exception& e)
@@ -1151,7 +1157,7 @@ namespace tools
return false;
}
- return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
+ return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.amounts_by_dest_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, res.spent_key_images_list, er);
}
catch (const std::exception& e)
@@ -1540,7 +1546,7 @@ namespace tools
{
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_unmixable_sweep_transactions();
- return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
+ return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.amounts_by_dest_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, res.spent_key_images_list, er);
}
catch (const std::exception& e)
@@ -1600,7 +1606,7 @@ namespace tools
uint32_t priority = m_wallet->adjust_priority(req.priority);
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, dsts[0].is_subaddress, req.outputs, mixin, req.unlock_time, priority, extra, req.account_index, subaddr_indices);
- return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
+ return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.amounts_by_dest_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, res.spent_key_images_list, er);
}
catch (const std::exception& e)
@@ -1677,7 +1683,7 @@ namespace tools
return false;
}
- return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.fee, res.weight, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
+ return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.amounts_by_dest, res.fee, res.weight, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, res.spent_key_images, er);
}
catch (const std::exception& e)
diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h
index 97fc0a278..bfb7013e2 100644
--- a/src/wallet/wallet_rpc_server.h
+++ b/src/wallet/wallet_rpc_server.h
@@ -262,9 +262,9 @@ namespace tools
bool not_open(epee::json_rpc::error& er);
void handle_rpc_exception(const std::exception_ptr& e, epee::json_rpc::error& er, int default_error_code);
- template<typename Ts, typename Tu, typename Tk>
+ template<typename Ts, typename Tu, typename Tk, typename Ta>
bool fill_response(std::vector<tools::wallet2::pending_tx> &ptx_vector,
- bool get_tx_key, Ts& tx_key, Tu &amount, Tu &fee, Tu &weight, std::string &multisig_txset, std::string &unsigned_txset, bool do_not_relay,
+ bool get_tx_key, Ts& tx_key, Tu &amount, Ta &amounts_by_dest, Tu &fee, Tu &weight, std::string &multisig_txset, std::string &unsigned_txset, bool do_not_relay,
Ts &tx_hash, bool get_tx_hex, Ts &tx_blob, bool get_tx_metadata, Ts &tx_metadata, Tk &spent_key_images, epee::json_rpc::error &er);
bool validate_transfer(const std::list<wallet_rpc::transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination, epee::json_rpc::error& er);
diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h
index 33afefb80..5d5579ced 100644
--- a/src/wallet/wallet_rpc_server_commands_defs.h
+++ b/src/wallet/wallet_rpc_server_commands_defs.h
@@ -47,7 +47,7 @@
// advance which version they will stop working with
// Don't go over 32767 for any of these
#define WALLET_RPC_VERSION_MAJOR 1
-#define WALLET_RPC_VERSION_MINOR 26
+#define WALLET_RPC_VERSION_MINOR 27
#define MAKE_WALLET_RPC_VERSION(major,minor) (((major)<<16)|(minor))
#define WALLET_RPC_VERSION MAKE_WALLET_RPC_VERSION(WALLET_RPC_VERSION_MAJOR, WALLET_RPC_VERSION_MINOR)
namespace tools
@@ -530,11 +530,23 @@ namespace wallet_rpc
END_KV_SERIALIZE_MAP()
};
+ struct amounts_list
+ {
+ std::list<uint64_t> amounts;
+
+ bool operator==(const amounts_list& other) const { return amounts == other.amounts; }
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(amounts)
+ END_KV_SERIALIZE_MAP()
+ };
+
struct single_transfer_response
{
std::string tx_hash;
std::string tx_key;
uint64_t amount;
+ amounts_list amounts_by_dest;
uint64_t fee;
uint64_t weight;
std::string tx_blob;
@@ -547,6 +559,7 @@ namespace wallet_rpc
KV_SERIALIZE(tx_hash)
KV_SERIALIZE(tx_key)
KV_SERIALIZE(amount)
+ KV_SERIALIZE_OPT(amounts_by_dest, decltype(amounts_by_dest)())
KV_SERIALIZE(fee)
KV_SERIALIZE(weight)
KV_SERIALIZE(tx_blob)
@@ -564,6 +577,7 @@ namespace wallet_rpc
std::list<transfer_destination> destinations;
uint32_t account_index;
std::set<uint32_t> subaddr_indices;
+ std::set<uint32_t> subtract_fee_from_outputs;
uint32_t priority;
uint64_t ring_size;
uint64_t unlock_time;
@@ -577,6 +591,7 @@ namespace wallet_rpc
KV_SERIALIZE(destinations)
KV_SERIALIZE(account_index)
KV_SERIALIZE(subaddr_indices)
+ KV_SERIALIZE_OPT(subtract_fee_from_outputs, decltype(subtract_fee_from_outputs)())
KV_SERIALIZE(priority)
KV_SERIALIZE_OPT(ring_size, (uint64_t)0)
KV_SERIALIZE(unlock_time)
@@ -598,6 +613,7 @@ namespace wallet_rpc
std::list<std::string> tx_hash_list;
std::list<std::string> tx_key_list;
std::list<uint64_t> amount_list;
+ std::list<amounts_list> amounts_by_dest_list;
std::list<uint64_t> fee_list;
std::list<uint64_t> weight_list;
std::list<std::string> tx_blob_list;
@@ -610,6 +626,7 @@ namespace wallet_rpc
KV_SERIALIZE(tx_hash_list)
KV_SERIALIZE(tx_key_list)
KV_SERIALIZE(amount_list)
+ KV_SERIALIZE_OPT(amounts_by_dest_list, decltype(amounts_by_dest_list)())
KV_SERIALIZE(fee_list)
KV_SERIALIZE(weight_list)
KV_SERIALIZE(tx_blob_list)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 736872b04..700039c90 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -83,7 +83,6 @@ else ()
add_subdirectory(crypto)
add_subdirectory(functional_tests)
add_subdirectory(performance_tests)
- add_subdirectory(core_proxy)
add_subdirectory(unit_tests)
add_subdirectory(difficulty)
add_subdirectory(block_weight)
@@ -159,7 +158,6 @@ set(enabled_tests
block_weight
hash
performance_tests
- core_proxy
fuzz
unit_tests)
diff --git a/tests/core_proxy/CMakeLists.txt b/tests/core_proxy/CMakeLists.txt
deleted file mode 100644
index e0ee5d7f5..000000000
--- a/tests/core_proxy/CMakeLists.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (c) 2014-2023, The Monero Project
-#
-# 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
-
-set(core_proxy_sources
- core_proxy.cpp)
-
-set(core_proxy_headers
- core_proxy.h)
-
-monero_add_minimal_executable(core_proxy
- ${core_proxy_sources}
- ${core_proxy_headers})
-target_link_libraries(core_proxy
- PRIVATE
- cryptonote_core
- cryptonote_protocol
- p2p
- version
- epee
- ${CMAKE_THREAD_LIBS_INIT}
- ${EXTRA_LIBRARIES})
-set_property(TARGET core_proxy
- PROPERTY
- FOLDER "tests")
diff --git a/tests/core_proxy/core_proxy.cpp b/tests/core_proxy/core_proxy.cpp
deleted file mode 100644
index fa5de5b3a..000000000
--- a/tests/core_proxy/core_proxy.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright (c) 2014-2023, The Monero Project
-//
-// 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
-//
-// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
-
-// node.cpp : Defines the entry point for the console application.
-//
-
-
-#include "include_base_utils.h"
-#include "version.h"
-#include <iostream>
-#include <sstream>
-
-#include <boost/program_options.hpp>
-
-#include "common/command_line.h"
-#include "console_handler.h"
-#include "p2p/net_node.h"
-#include "p2p/net_node.inl"
-//#include "cryptonote_core/cryptonote_core.h"
-#include "cryptonote_protocol/cryptonote_protocol_handler.h"
-#include "cryptonote_protocol/cryptonote_protocol_handler.inl"
-#include "core_proxy.h"
-
-#if defined(WIN32)
-#include <crtdbg.h>
-#endif
-
-namespace po = boost::program_options;
-using namespace std;
-using namespace epee;
-using namespace cryptonote;
-using namespace crypto;
-
-
-BOOST_CLASS_VERSION(nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> >, 1);
-
-int main(int argc, char* argv[])
-{
-
-#ifdef WIN32
- _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
-#endif
-
- TRY_ENTRY();
-
- tools::on_startup();
- string_tools::set_module_name_and_folder(argv[0]);
-
- //set up logging options
- mlog_configure(mlog_get_default_log_path("core_proxy.log"), true);
- mlog_set_log_level(2);
-
-
- po::options_description desc("Allowed options");
- command_line::add_arg(desc, cryptonote::arg_data_dir);
- nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> >::init_options(desc);
-
- po::variables_map vm;
- bool r = command_line::handle_error_helper(desc, [&]()
- {
- po::store(po::parse_command_line(argc, argv, desc), vm);
- po::notify(vm);
- return true;
- });
- if (!r)
- return 1;
-
- MGINFO("Module folder: " << argv[0]);
- MGINFO("Node starting ...");
-
-
- //create objects and link them
- tests::proxy_core pr_core;
- cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> cprotocol(pr_core, NULL);
- nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> > p2psrv {
- cprotocol
- };
- cprotocol.set_p2p_endpoint(&p2psrv);
- //pr_core.set_cryptonote_protocol(&cprotocol);
- //daemon_cmmands_handler dch(p2psrv);
-
- //initialize objects
-
- MGINFO("Initializing p2p server...");
- bool res = p2psrv.init(vm);
- CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize p2p server.");
- MGINFO("P2p server initialized OK");
-
- MGINFO("Initializing cryptonote protocol...");
- res = cprotocol.init(vm);
- CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize cryptonote protocol.");
- MGINFO("Cryptonote protocol initialized OK");
-
- //initialize core here
- MGINFO("Initializing proxy core...");
- res = pr_core.init(vm);
- CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core");
- MGINFO("Core initialized OK");
-
- MGINFO("Starting p2p net loop...");
- p2psrv.run();
- MGINFO("p2p net loop stopped");
-
- //deinitialize components
- MGINFO("Deinitializing core...");
- pr_core.deinit();
- MGINFO("Deinitializing cryptonote_protocol...");
- cprotocol.deinit();
- MGINFO("Deinitializing p2p...");
- p2psrv.deinit();
-
-
- //pr_core.set_cryptonote_protocol(NULL);
- cprotocol.set_p2p_endpoint(NULL);
-
-
- MGINFO("Node stopped.");
- return 0;
-
- CATCH_ENTRY_L0("main", 1);
-}
-
-/*
-string tx2str(const cryptonote::transaction& tx, const cryptonote::hash256& tx_hash, const cryptonote::hash256& tx_prefix_hash, const cryptonote::blobdata& blob) {
- stringstream ss;
-
- ss << "{" << endl;
- ss << "\tversion:" << tx.version << endl;
- ss << "\tunlock_time:" << tx.unlock_time << endl;
- ss << "\t"
-
- return ss.str();
-}*/
-
-bool tests::proxy_core::handle_incoming_tx(const cryptonote::tx_blob_entry& tx_blob, cryptonote::tx_verification_context& tvc, cryptonote::relay_method tx_relay, bool relayed) {
- if (tx_relay != cryptonote::relay_method::block)
- return true;
-
- crypto::hash tx_hash = null_hash;
- crypto::hash tx_prefix_hash = null_hash;
- transaction tx;
-
- if (tx_blob.prunable_hash != crypto::null_hash)
- {
- cerr << "WRONG TRANSACTION, pruned blob rejected" << endl;
- return false;
- }
-
- if (!parse_and_validate_tx_from_blob(tx_blob.blob, tx, tx_hash, tx_prefix_hash)) {
- cerr << "WRONG TRANSACTION BLOB, Failed to parse, rejected" << endl;
- return false;
- }
-
- cout << "TX " << endl << endl;
- cout << tx_hash << endl;
- cout << tx_prefix_hash << endl;
- cout << tx_blob.blob.size() << endl;
- //cout << string_tools::buff_to_hex_nodelimer(tx_blob) << endl << endl;
- cout << obj_to_json_str(tx) << endl;
- cout << endl << "ENDTX" << endl;
-
- return true;
-}
-
-bool tests::proxy_core::handle_incoming_txs(const std::vector<tx_blob_entry>& tx_blobs, std::vector<tx_verification_context>& tvc, cryptonote::relay_method tx_relay, bool relayed)
-{
- tvc.resize(tx_blobs.size());
- size_t i = 0;
- for (const auto &tx_blob: tx_blobs)
- {
- if (!handle_incoming_tx(tx_blob, tvc[i], tx_relay, relayed))
- return false;
- ++i;
- }
- return true;
-}
-
-bool tests::proxy_core::handle_incoming_block(const cryptonote::blobdata& block_blob, const cryptonote::block *block_, cryptonote::block_verification_context& bvc, bool update_miner_blocktemplate) {
- block b = AUTO_VAL_INIT(b);
-
- if(!parse_and_validate_block_from_blob(block_blob, b)) {
- cerr << "Failed to parse and validate new block" << endl;
- return false;
- }
-
- crypto::hash h;
- crypto::hash lh;
- cout << "BLOCK" << endl << endl;
- cout << (h = get_block_hash(b)) << endl;
- cout << (lh = get_block_longhash(NULL, b, 0, 0)) << endl;
- cout << get_transaction_hash(b.miner_tx) << endl;
- cout << ::get_object_blobsize(b.miner_tx) << endl;
- //cout << string_tools::buff_to_hex_nodelimer(block_blob) << endl;
- cout << obj_to_json_str(b) << endl;
-
- cout << endl << "ENDBLOCK" << endl << endl;
-
- if (!add_block(h, lh, b, block_blob))
- return false;
-
- return true;
-}
-
-bool tests::proxy_core::get_short_chain_history(std::list<crypto::hash>& ids) {
- build_short_history(ids, m_lastblk);
- return true;
-}
-
-void tests::proxy_core::get_blockchain_top(uint64_t& height, crypto::hash& top_id) {
- height = 0;
- top_id = get_block_hash(m_genesis);
-}
-
-bool tests::proxy_core::init(const boost::program_options::variables_map& /*vm*/) {
- generate_genesis_block(m_genesis, config::GENESIS_TX, config::GENESIS_NONCE);
- crypto::hash h = get_block_hash(m_genesis);
- add_block(h, get_block_longhash(NULL, m_genesis, 0, 0), m_genesis, block_to_blob(m_genesis));
- return true;
-}
-
-bool tests::proxy_core::have_block_unlocked(const crypto::hash& id, int *where) {
- if (m_hash2blkidx.end() == m_hash2blkidx.find(id))
- return false;
- if (where) *where = HAVE_BLOCK_MAIN_CHAIN;
- return true;
-}
-
-bool tests::proxy_core::have_block(const crypto::hash& id, int *where) {
- return have_block_unlocked(id, where);
-}
-
-void tests::proxy_core::build_short_history(std::list<crypto::hash> &m_history, const crypto::hash &m_start) {
- m_history.push_front(get_block_hash(m_genesis));
- /*std::unordered_map<crypto::hash, tests::block_index>::const_iterator cit = m_hash2blkidx.find(m_lastblk);
-
- do {
- m_history.push_front(cit->first);
-
- size_t n = 1 << m_history.size();
- while (m_hash2blkidx.end() != cit && crypto::null_hash != cit->second.blk.prev_id && n > 0) {
- n--;
- cit = m_hash2blkidx.find(cit->second.blk.prev_id);
- }
- } while (m_hash2blkidx.end() != cit && get_block_hash(cit->second.blk) != cit->first);*/
-}
-
-bool tests::proxy_core::add_block(const crypto::hash &_id, const crypto::hash &_longhash, const cryptonote::block &_blk, const cryptonote::blobdata &_blob) {
- size_t height = 0;
-
- if (crypto::null_hash != _blk.prev_id) {
- std::unordered_map<crypto::hash, tests::block_index>::const_iterator cit = m_hash2blkidx.find(_blk.prev_id);
- if (m_hash2blkidx.end() == cit) {
- cerr << "ERROR: can't find previous block with id \"" << _blk.prev_id << "\"" << endl;
- return false;
- }
-
- height = cit->second.height + 1;
- }
-
- m_known_block_list.push_back(_id);
-
- block_index bi(height, _id, _longhash, _blk, _blob, txes);
- m_hash2blkidx.insert(std::make_pair(_id, bi));
- txes.clear();
- m_lastblk = _id;
-
- return true;
-}
diff --git a/tests/core_proxy/core_proxy.h b/tests/core_proxy/core_proxy.h
deleted file mode 100644
index f1f9bdb66..000000000
--- a/tests/core_proxy/core_proxy.h
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) 2014-2023, The Monero Project
-//
-// 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
-//
-// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
-
-#pragma once
-
-#include <boost/program_options/variables_map.hpp>
-
-#include "cryptonote_basic/cryptonote_basic_impl.h"
-#include "cryptonote_basic/verification_context.h"
-#include "cryptonote_core/i_core_events.h"
-#include <unordered_map>
-
-namespace tests
-{
- struct block_index {
- size_t height;
- crypto::hash id;
- crypto::hash longhash;
- cryptonote::block blk;
- cryptonote::blobdata blob;
- std::list<cryptonote::transaction> txes;
-
- block_index() : height(0), id(crypto::null_hash), longhash(crypto::null_hash) { }
- block_index(size_t _height, const crypto::hash &_id, const crypto::hash &_longhash, const cryptonote::block &_blk, const cryptonote::blobdata &_blob, const std::list<cryptonote::transaction> &_txes)
- : height(_height), id(_id), longhash(_longhash), blk(_blk), blob(_blob), txes(_txes) { }
- };
-
- class proxy_core : public cryptonote::i_core_events
- {
- cryptonote::block m_genesis;
- std::list<crypto::hash> m_known_block_list;
- std::unordered_map<crypto::hash, block_index> m_hash2blkidx;
-
- crypto::hash m_lastblk;
- std::list<cryptonote::transaction> txes;
-
- bool add_block(const crypto::hash &_id, const crypto::hash &_longhash, const cryptonote::block &_blk, const cryptonote::blobdata &_blob);
- void build_short_history(std::list<crypto::hash> &m_history, const crypto::hash &m_start);
-
-
- public:
- virtual bool is_synchronized() const final { return true; }
- void on_synchronized(){}
- void safesyncmode(const bool){}
- virtual uint64_t get_current_blockchain_height() const final {return 1;}
- void set_target_blockchain_height(uint64_t) {}
- bool init(const boost::program_options::variables_map& vm);
- bool deinit(){return true;}
- bool get_short_chain_history(std::list<crypto::hash>& ids);
- bool have_block(const crypto::hash& id, int *where = NULL);
- bool have_block_unlocked(const crypto::hash& id, int *where = NULL);
- void get_blockchain_top(uint64_t& height, crypto::hash& top_id);
- bool handle_incoming_tx(const cryptonote::tx_blob_entry& tx_blob, cryptonote::tx_verification_context& tvc, cryptonote::relay_method tx_relay, bool relayed);
- bool handle_incoming_txs(const std::vector<cryptonote::tx_blob_entry>& tx_blobs, std::vector<cryptonote::tx_verification_context>& tvc, cryptonote::relay_method tx_relay, bool relayed);
- bool handle_incoming_block(const cryptonote::blobdata& block_blob, const cryptonote::block *block, cryptonote::block_verification_context& bvc, bool update_miner_blocktemplate = true);
- void pause_mine(){}
- void resume_mine(){}
- bool on_idle(){return true;}
- bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, bool clip_pruned, cryptonote::NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp){return true;}
- bool handle_get_objects(cryptonote::NOTIFY_REQUEST_GET_OBJECTS::request& arg, cryptonote::NOTIFY_RESPONSE_GET_OBJECTS::request& rsp, cryptonote::cryptonote_connection_context& context){return true;}
- cryptonote::Blockchain &get_blockchain_storage() { throw std::runtime_error("Called invalid member function: please never call get_blockchain_storage on the TESTING class proxy_core."); }
- bool get_test_drop_download() {return true;}
- bool get_test_drop_download_height() {return true;}
- bool prepare_handle_incoming_blocks(const std::vector<cryptonote::block_complete_entry> &blocks_entry, std::vector<cryptonote::block> &blocks) { return true; }
- bool cleanup_handle_incoming_blocks(bool force_sync = false) { return true; }
- bool update_checkpoints(const bool skip_dns = false) { return true; }
- uint64_t get_target_blockchain_height() const { return 1; }
- size_t get_block_sync_size(uint64_t height) const { return BLOCKS_SYNCHRONIZING_DEFAULT_COUNT; }
- virtual void on_transactions_relayed(epee::span<const cryptonote::blobdata> tx_blobs, cryptonote::relay_method tx_relay) {}
- cryptonote::network_type get_nettype() const { return cryptonote::MAINNET; }
- bool get_pool_transaction(const crypto::hash& id, cryptonote::blobdata& tx_blob, cryptonote::relay_category tx_category) const { return false; }
- bool pool_has_tx(const crypto::hash &txid) const { return false; }
- bool get_blocks(uint64_t start_offset, size_t count, std::vector<std::pair<cryptonote::blobdata, cryptonote::block>>& blocks, std::vector<cryptonote::blobdata>& txs) const { return false; }
- bool get_transactions(const std::vector<crypto::hash>& txs_ids, std::vector<cryptonote::transaction>& txs, std::vector<crypto::hash>& missed_txs) const { return false; }
- bool get_block_by_hash(const crypto::hash &h, cryptonote::block &blk, bool *orphan = NULL) const { return false; }
- uint8_t get_ideal_hard_fork_version() const { return 0; }
- uint8_t get_ideal_hard_fork_version(uint64_t height) const { return 0; }
- uint8_t get_hard_fork_version(uint64_t height) const { return 0; }
- uint64_t get_earliest_ideal_height_for_version(uint8_t version) const { return 0; }
- cryptonote::difficulty_type get_block_cumulative_difficulty(uint64_t height) const { return 0; }
- bool fluffy_blocks_enabled() const { return false; }
- uint64_t prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes, const std::vector<uint64_t> &weights) { return 0; }
- bool has_block_weights(uint64_t height, uint64_t nblocks) const { return false; }
- bool is_within_compiled_block_hash_area(uint64_t height) const { return false; }
- bool pad_transactions() const { return false; }
- uint32_t get_blockchain_pruning_seed() const { return 0; }
- bool prune_blockchain(uint32_t pruning_seed) const { return true; }
- bool get_txpool_complement(const std::vector<crypto::hash> &hashes, std::vector<cryptonote::blobdata> &txes) { return false; }
- bool get_pool_transaction_hashes(std::vector<crypto::hash>& txs, bool include_unrelayed_txes = true) const { return false; }
- crypto::hash get_block_id_by_height(uint64_t height) const { return crypto::null_hash; }
- };
-}
diff --git a/tests/functional_tests/transfer.py b/tests/functional_tests/transfer.py
index ddc930eb0..56a2514d9 100755
--- a/tests/functional_tests/transfer.py
+++ b/tests/functional_tests/transfer.py
@@ -63,6 +63,7 @@ class TransferTest():
self.check_is_key_image_spent()
self.check_multiple_submissions()
self.check_scan_tx()
+ self.check_subtract_fee_from_outputs()
def reset(self):
print('Resetting blockchain')
@@ -1081,5 +1082,85 @@ class TransferTest():
diff_transfers(receiver_wallet.get_transfers(), res)
assert receiver_wallet.get_balance().balance == expected_receiver_balance
+ def check_subtract_fee_from_outputs(self):
+ daemon = Daemon()
+
+ print('Testing fee-included transfers')
+
+ def inner_test_external_transfer(dsts, subtract_fee_from_outputs):
+ # refresh wallet and get balance
+ self.wallet[0].refresh()
+ balance1 = self.wallet[0].get_balance().balance
+
+ # Check that this transaction is possible with our current balance + other preconditions
+ dst_sum = sum(map(lambda x: x['amount'], dsts))
+ assert balance1 >= dst_sum
+ if subtract_fee_from_outputs:
+ assert max(subtract_fee_from_outputs) < len(dsts)
+
+ # transfer with subtractfeefrom=all
+ transfer_res = self.wallet[0].transfer(dsts, subtract_fee_from_outputs = subtract_fee_from_outputs, get_tx_metadata = True)
+ tx_hex = transfer_res.tx_metadata
+ tx_fee = transfer_res.fee
+ amount_spent = transfer_res.amount
+ amounts_by_dest = transfer_res.amounts_by_dest.amounts
+
+ # Assert that fee and amount spent to outputs adds up
+ assert tx_fee != 0
+ if subtract_fee_from_outputs:
+ assert tx_fee + amount_spent == dst_sum
+ else:
+ assert amount_spent == dst_sum
+
+ # Check the amounts by each destination that only the destinations set as subtractable
+ # got subtracted and that the subtracted dests are approximately correct
+ assert len(amounts_by_dest) == len(dsts) # if this fails... idk
+ for i in range(len(dsts)):
+ if i in subtract_fee_from_outputs: # dest is subtractable
+ approx_subtraction = tx_fee // len(subtract_fee_from_outputs)
+ assert amounts_by_dest[i] < dsts[i]['amount']
+ assert dsts[i]['amount'] - amounts_by_dest[i] - approx_subtraction <= 1
+ else:
+ assert amounts_by_dest[i] == dsts[i]['amount']
+
+ # relay tx and generate block (not to us, to simplify balance change calculations)
+ relay_res = self.wallet[0].relay_tx(tx_hex)
+ daemon.generateblocks('44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 1)
+
+ # refresh and get balance again
+ self.wallet[0].refresh()
+ balance2 = self.wallet[0].get_balance().balance
+
+ # Check that the wallet balance dropped by the correct amount
+ balance_drop = balance1 - balance2
+ if subtract_fee_from_outputs:
+ assert balance_drop == dst_sum
+ else:
+ assert balance_drop == dst_sum + tx_fee
+
+ dst1 = {'address': '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 'amount': 1100000000001}
+ dst2 = {'address': '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', 'amount': 1200000000000}
+ dst3 = {'address': '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', 'amount': 1}
+
+ inner_test_external_transfer([dst1, dst2], [0, 1])
+ inner_test_external_transfer([dst1, dst2], [0])
+ inner_test_external_transfer([dst1, dst2], [1])
+ inner_test_external_transfer([dst1, dst2], [])
+ inner_test_external_transfer([dst1], [0])
+ inner_test_external_transfer([dst1], [])
+ inner_test_external_transfer([dst3], [])
+ try:
+ inner_test_external_transfer([dst1, dst3], [0, 1]) # Test subtractfeefrom if one of the outputs would underflow w/o good checks
+ raise ValueError('transfer request with tiny subtractable destination should have thrown')
+ except:
+ pass
+
+ # Check for JSONRPC error on bad index
+ try:
+ transfer_res = self.wallet[0].transfer([dst1], subtract_fee_from_outputs = [1])
+ raise ValueError('transfer request with index should have thrown')
+ except AssertionError:
+ pass
+
if __name__ == '__main__':
TransferTest().run_test()
diff --git a/tests/unit_tests/crypto.cpp b/tests/unit_tests/crypto.cpp
index e41f3955f..88ecb5853 100644
--- a/tests/unit_tests/crypto.cpp
+++ b/tests/unit_tests/crypto.cpp
@@ -307,17 +307,21 @@ TEST(Crypto, tree_branch)
ASSERT_FALSE(crypto::tree_branch((const char(*)[32])inputs, 5, crypto::null_hash.data, (char(*)[32])branch, &depth, &path));
// depth encoding roundtrip
- for (uint32_t n_chains = 1; n_chains <= 65; ++n_chains)
+ for (uint32_t n_chains = 1; n_chains <= 256; ++n_chains)
{
- for (uint32_t nonce = 0; nonce < 1024; ++nonce)
+ for (uint32_t nonce = 0xffffffff - 512; nonce != 1025; ++nonce)
{
- const uint32_t depth = cryptonote::encode_mm_depth(n_chains, nonce);
+ const uint64_t depth = cryptonote::encode_mm_depth(n_chains, nonce);
uint32_t n_chains_2, nonce_2;
ASSERT_TRUE(cryptonote::decode_mm_depth(depth, n_chains_2, nonce_2));
ASSERT_EQ(n_chains, n_chains_2);
ASSERT_EQ(nonce, nonce_2);
}
}
+
+ // 257 chains is too much
+ try { cryptonote::encode_mm_depth(257, 0); ASSERT_TRUE(false); }
+ catch (...) {}
}
TEST(Crypto, generator_consistency)
diff --git a/tests/unit_tests/epee_serialization.cpp b/tests/unit_tests/epee_serialization.cpp
index 035f5e206..ecc26e971 100644
--- a/tests/unit_tests/epee_serialization.cpp
+++ b/tests/unit_tests/epee_serialization.cpp
@@ -29,8 +29,11 @@
#include <cstdint>
#include <gtest/gtest.h>
+#include <vector>
+#include "serialization/keyvalue_serialization.h"
#include "storages/portable_storage.h"
+#include "storages/portable_storage_template_helper.h"
#include "span.h"
TEST(epee_binary, two_keys)
@@ -54,3 +57,87 @@ TEST(epee_binary, duplicate_key)
epee::serialization::portable_storage storage{};
EXPECT_FALSE(storage.load_from_binary(data));
}
+
+namespace
+{
+struct ObjOfObjs
+{
+ std::vector<ObjOfObjs> x;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(x)
+ END_KV_SERIALIZE_MAP()
+};
+
+struct ObjOfInts
+{
+ std::list<int> x;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(x)
+ END_KV_SERIALIZE_MAP()
+};
+}
+
+TEST(epee_binary, any_empty_seq)
+{
+ // Test that any c++ sequence type (std::vector, std::list, etc) can deserialize without error
+ // from an *empty* epee binary array of any type. This property is useful for other projects who
+ // maintain code which serializes epee binary but don't know the type of arrays until runtime.
+ // Without any elements to actually serialize, they don't know what type code to use for arrays
+ // and should be able to choose a default typecode.
+
+ static constexpr const std::uint8_t data_empty_bool[] = {
+ 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x8B /*array of bools*/, 0x00 /*length 0*/
+ };
+
+ static constexpr const std::uint8_t data_empty_double[] = {
+ 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x89 /*array of doubles*/, 0x00 /*length 0*/
+ };
+
+ static constexpr const std::uint8_t data_empty_string[] = {
+ 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x8A /*array of strings*/, 0x00 /*length 0*/
+ };
+
+ static constexpr const std::uint8_t data_empty_int64[] = {
+ 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x81 /*array of int64s*/, 0x00 /*length 0*/
+ };
+
+ static constexpr const std::uint8_t data_empty_object[] = {
+ 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x8C /*array of objects*/, 0x00 /*length 0*/
+ };
+
+ ObjOfObjs o;
+
+ EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span<const std::uint8_t>(data_empty_bool)));
+ EXPECT_EQ(0, o.x.size());
+
+ EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span<const std::uint8_t>(data_empty_double)));
+ EXPECT_EQ(0, o.x.size());
+
+ EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span<const std::uint8_t>(data_empty_string)));
+ EXPECT_EQ(0, o.x.size());
+
+ EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span<const std::uint8_t>(data_empty_int64)));
+ EXPECT_EQ(0, o.x.size());
+
+ EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span<const std::uint8_t>(data_empty_object)));
+ EXPECT_EQ(0, o.x.size());
+
+ ObjOfInts i;
+
+ EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_bool)));
+ EXPECT_EQ(0, i.x.size());
+
+ EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_double)));
+ EXPECT_EQ(0, i.x.size());
+
+ EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_string)));
+ EXPECT_EQ(0, i.x.size());
+
+ EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_int64)));
+ EXPECT_EQ(0, i.x.size());
+
+ EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_object)));
+ EXPECT_EQ(0, i.x.size());
+}
diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp
index c776fbcc9..dd3aafaa6 100644
--- a/tests/unit_tests/epee_utils.cpp
+++ b/tests/unit_tests/epee_utils.cpp
@@ -1852,3 +1852,60 @@ TEST(parsing, unicode)
epee::misc_utils::parse::match_string2(si, s.end(), bs);
EXPECT_EQ(bs, "あまやかす");
}
+
+TEST(parsing, strtoul)
+{
+ long ul;
+ const char* p;
+ const char* endp;
+
+ errno = 0; // Some libc's only set errno on failure, some set it to 0 on success
+
+ p = "0";
+ endp = nullptr;
+ ul = std::strtoul(p, const_cast<char**>(&endp), 10);
+ EXPECT_EQ(0, errno);
+ EXPECT_EQ(0, ul);
+ EXPECT_EQ(p + 1, endp);
+
+ p = "000000";
+ endp = nullptr;
+ ul = std::strtoul(p, const_cast<char**>(&endp), 10);
+ EXPECT_EQ(0, errno);
+ EXPECT_EQ(0, ul);
+ EXPECT_EQ(p + 6, endp);
+
+ p = "1";
+ endp = nullptr;
+ ul = std::strtoul(p, const_cast<char**>(&endp), 10);
+ EXPECT_EQ(0, errno);
+ EXPECT_EQ(1, ul);
+ EXPECT_EQ(p + 1, endp);
+
+ p = "0q";
+ endp = nullptr;
+ ul = std::strtoul(p, const_cast<char**>(&endp), 10);
+ EXPECT_EQ(0, errno);
+ EXPECT_EQ(0, ul);
+ EXPECT_EQ(p + 1, endp);
+
+ p = " \t 0";
+ endp = nullptr;
+ ul = std::strtoul(p, const_cast<char**>(&endp), 10);
+ EXPECT_EQ(0, errno);
+ EXPECT_EQ(0, ul);
+ EXPECT_EQ(p + 9, endp);
+
+ p = "q";
+ endp = nullptr;
+ ul = std::strtoul(p, const_cast<char**>(&endp), 10);
+ EXPECT_EQ(0, errno);
+ EXPECT_EQ(0, ul);
+ EXPECT_EQ(p, endp);
+
+ p = "999999999999999999999999999999999999999";
+ endp = nullptr;
+ ul = std::strtoul(p, const_cast<char**>(&endp), 10);
+ EXPECT_EQ(ERANGE, errno);
+ EXPECT_EQ(ULLONG_MAX, ul);
+}
diff --git a/tests/unit_tests/json_serialization.cpp b/tests/unit_tests/json_serialization.cpp
index 9fa589139..aa46b68dc 100644
--- a/tests/unit_tests/json_serialization.cpp
+++ b/tests/unit_tests/json_serialization.cpp
@@ -13,6 +13,7 @@
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "cryptonote_core/cryptonote_tx_utils.h"
#include "serialization/json_object.h"
+#include "rpc/daemon_messages.h"
namespace test
@@ -240,3 +241,9 @@ TEST(JsonSerialization, BulletproofTransaction)
EXPECT_EQ(tx_bytes, tx_copy_bytes);
}
+TEST(JsonRpcSerialization, HandlerFromJson)
+{
+ cryptonote::rpc::FullMessage req_full("{\"jsonrpc\":\"2.0\",\"method\":\"get_hashes_fast\",\"params\":[1]}", true);
+ cryptonote::rpc::GetHashesFast::Request request{};
+ EXPECT_THROW(request.fromJson(req_full.getMessage()), cryptonote::json::WRONG_TYPE);
+}
diff --git a/tests/unit_tests/node_server.cpp b/tests/unit_tests/node_server.cpp
index 747778c69..6f490d7b9 100644
--- a/tests/unit_tests/node_server.cpp
+++ b/tests/unit_tests/node_server.cpp
@@ -306,8 +306,8 @@ TEST(node_server, bind_same_p2p_port)
Relevant part about REUSEADDR from man:
https://www.man7.org/linux/man-pages/man7/ip.7.html
- For Mac OSX, set the following alias, before running the test, or else it will fail:
- sudo ifconfig lo0 alias 127.0.0.2
+ For Mac OSX and OpenBSD, set the following alias (by running the command as root), before running the test, or else it will fail:
+ ifconfig lo0 alias 127.0.0.2
*/
vm.find(nodetool::arg_p2p_bind_ip.name)->second = boost::program_options::variable_value(std::string("127.0.0.2"), false);
vm.find(nodetool::arg_p2p_bind_port.name)->second = boost::program_options::variable_value(std::string(port), false);
diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp
index 49f1dc310..ab81acefc 100644
--- a/tests/unit_tests/serialization.cpp
+++ b/tests/unit_tests/serialization.cpp
@@ -59,9 +59,7 @@ struct Struct
};
template <class Archive>
-struct serializer<Archive, Struct>
-{
- static bool serialize(Archive &ar, Struct &s) {
+static bool do_serialize(Archive &ar, Struct &s) {
ar.begin_object();
ar.tag("a");
ar.serialize_int(s.a);
@@ -71,8 +69,7 @@ struct serializer<Archive, Struct>
ar.serialize_blob(s.blob, sizeof(s.blob));
ar.end_object();
return true;
- }
-};
+}
struct Struct1
{
@@ -122,6 +119,23 @@ bool try_parse(const string &blob)
return serialization::parse_binary(blob, s1);
}
+namespace example_namespace
+{
+ struct ADLExampleStruct
+ {
+ std::string msg;
+ };
+
+ template <class Archive>
+ static bool do_serialize(Archive &ar, ADLExampleStruct &aes)
+ {
+ ar.begin_object();
+ FIELD_N("custom_fieldname", aes.msg);
+ ar.end_object();
+ return ar.good();
+ }
+}
+
TEST(Serialization, BinaryArchiveInts) {
uint64_t x = 0xff00000000, x1;
@@ -1178,3 +1192,18 @@ TEST(Serialization, difficulty_type)
ASSERT_EQ(v_original, v_unserialized);
}
+
+TEST(Serialization, adl_free_function)
+{
+ std::stringstream ss;
+ json_archive<true> ar(ss);
+
+ const std::string msg = "Howdy, World!";
+ example_namespace::ADLExampleStruct aes{msg};
+
+ ASSERT_TRUE(serialization::serialize(ar, aes));
+
+ // VVVVVVVVVVVVVVVVVVVVVVVVVV weird string serialization artifact
+ const std::string expected = "{\"custom_fieldname\": " + std::to_string(msg.size()) + '"' + epee::string_tools::buff_to_hex_nodelimer(msg) + "\"}";
+ EXPECT_EQ(expected, ss.str());
+}
diff --git a/utils/gpg_keys/0xfffc0000.asc b/utils/gpg_keys/0xfffc0000.asc
new file mode 100644
index 000000000..6da5391a3
--- /dev/null
+++ b/utils/gpg_keys/0xfffc0000.asc
@@ -0,0 +1,13 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mDMEZZx2rhYJKwYBBAHaRw8BAQdADWrpnGYQMJB7m7OYO5QhLPbNZckNDp5XXX5C
+NRqQSv60ITB4ZmZmYzAwMDAgPDB4ZmZmYzAwMDBAcHJvdG9uLm1lPoiTBBMWCgA7
+FiEESleXwQVNMqPAAcfxZQ98K3vaOBkFAmWcdq4CGwMFCwkIBwICIgIGFQoJCAsC
+BBYCAwECHgcCF4AACgkQZQ98K3vaOBmm6QEA1l5FuxR7MtER+pl4XiL+UEH4rGjQ
+BHTD/Tv6Ar6uq2oA/34XecxRCKmj4ximF1aMucJSvS8nIjRbRQ9E5llcLOYMuDgE
+ZZx2rhIKKwYBBAGXVQEFAQEHQIxFNA2STqB1WQNDtPHalCrKOBxheB6Lg1U+ceOF
+rTFcAwEIB4h4BBgWCgAgFiEESleXwQVNMqPAAcfxZQ98K3vaOBkFAmWcdq4CGwwA
+CgkQZQ98K3vaOBnZ2gEAsrARrt+Mm+zfqVFZ7iAQHD5xmdj9Q0Qf3zl5dVbkFlQB
+APOdwpn/iY0zA6McjZ1H+Uiv+bw8uTVZadgjtJGb474O
+=J9WU
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/utils/gpg_keys/tobtoht.asc b/utils/gpg_keys/tobtoht.asc
new file mode 100644
index 000000000..16311b2d8
--- /dev/null
+++ b/utils/gpg_keys/tobtoht.asc
@@ -0,0 +1,51 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBGLhQcoBEADiEB9S7FRpHpnI8TpFhBoYgeugroHJgupRmSvMt+0myD9AkKbL
+6FG3F98HRyFA3ljq3UWd5kUxZIeljdwWn/sHd3eu+BXJ2gXU7jo8MzOFDQrW+bcE
+/4PFEdbLhsvmEvXkURFFZTyVA6CgAfsd86l2okG0X4dbDLwGRcVx30bYThH5a/lK
+buTKOANbP9Rw6hRkZAIZof2DDZgU4G5UEFvxf80lhbXQgPtQoCAad9b/cRGUnau8
+STtA6qKiVch1IS0Y2+EE91aN2MLmGxjTr5N6kQm/oYeIKqLiZuVBkGmNVVP5CyDw
+k4YjmrCyckewAWwsjDNZ6X/eAV06inblOxgX9g2VJKVHck4WtN9c+5SmTkWz5YZ0
+hXxj7h0ASukvud0uf9UwLOAIXRnXRUyxAAw0LhTmHIlsDHw1XJoqIjKnJNpCGIqE
+Hn/AQT5n8W5HYF7GJQAav1Qso7yclkUdXP1mfSpbC1Q+R92WAlgLrIwEeUG8iEeO
+6KZazSSzn8VwG7Z5VnE32LpIdGDDJOpqABd7CD7b9dtKP/QH8wbdZxVzcMsdD2Zk
+VARUSMsMRNKXpQuURN02zPPyu//jYwqrMXHbUE2Mt8quhJQya4xVRbjBW0LHwZQO
+/vpUm6reOO5vIJdkgqH0YP5WMyj4/BnhkkOGPjDgffzxMihue34fO+V05wARAQAB
+tB90b2J0b2h0IDx0b2JAZmVhdGhlcndhbGxldC5vcmc+iQJOBBMBCAA4FiEE6HvZ
+Ic3YhcnXijjF5FsQ3QJ9JHIFAmLhQcoCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgEC
+F4AACgkQ5FsQ3QJ9JHLw/hAA28cJgy2KOAFNaX3lSeOGC6ZdQUv4dtTkg1wZjmDq
+AKE8I1ANCaVHtB0Df7CJTnBnCvkLAhf8gA3ldNBD3PKySBmP1rnjRYjYmNOZ+9io
+EHwlgL7WyknXUtbitrpe/wM7xWN/cDdEmlRvOb9pf4GTPw2MaZLM+E43KnKoEWJ/
+Ms8vOLi2UIZNmpYhWzjS178EtC9AfvsCwWexVwYhIxlmqF++W2QYMVUEqDaVMKsJ
+BohhPrOb/SQJVd5D6vrcIGs/aZZOEuthvBp1ycFdCEGajwBNzmrmhLfl9CuP0NqM
+4KkYYHrvJio8QbsMxU27KJfDaGloNfSkk3V+MhZGvMqFUkTuabeyz6Uh/CREV6s/
+JApTPHvAmMeD9p6PNfxZvSq/jcbwbxPdqvWyy+dqEaaPIGbR1sOSJOOzxcJ84/1F
+VwA2FQENmlob6VRroqHWTZzKPmwOi2qFAjEleEHZrjfaaHlXrGbi1ucFOqn+2/Qh
+F4oi1gzFG0jQYajXxRC1CrM3ykKWgGt6cTeMDXQxEdQOkWdgP7pkVbpc9j4OW0aF
+WeUlr1i+BU6UwY6eibAwT57pBiU4A9TtJjHBBPUG+XGIB9JPAWD43mfXAONfmll3
+zyV0Y6Tq8NiQUs0yuWNWqo6fDn/EW5ldNsDz+PwDGGusEMJYrGc8emWqi+CsSg83
+imu5Ag0EYuFBygEQAMXwWjBPxiWN1wDrHNOwoVf4aX37mYjsgtQ+223x5uFD0ULl
+6pH2hUCg/FSVqsm+xvVqX6DV+WmzkGhhC1B2bnpEkzxQr79dXEq0V+hsKypa7t66
+8/e+4pNxeSz+4UMJApEc/lIGtEcWPgx2xNChagB2V/074hN3eZ6jpq4KJS4GG7ly
+ts+t2jNs8EArrWKWKzIp2vc+Upad5LD4SSWR5qQQUgXtVbJO3EoVfeK3+g0iiVOv
+o29yEStCUBrkbuK1Kwe1wjw6ePIDWKXkvo0vSRKxolCGALFhToLM0QNLjp1WNXJG
+TuZtcUYIY58b7WAcEoqM7uRc3YcFMjl1tW/e3UF8Ii6CBr69bxzeygfXEdXjM+XC
+H9WvxtHFFgelnloA2OHRqe1ehtsLtmlVHoJ1RArKEFYrMiApAiGSf9ztm/eQ3yX4
+6E28k3OOZSRUyyZHC++NxmNDKjQpcVQ2k5yCGje5xB4844n5fTMafWNGYnnveFTx
+ZlXwz+ZlwvGHKwwI6u+n+ZA5eV+R24mo9JaPQVlQ9MLpzbWhpUvGy8ugn4rhiaz2
+4gw6hdd1BaTzkMgrCh1uT4GxVSQxanX4ubHK06QiH5yiopAIcrLXQCtIaNwmQPD2
+1K9WvZ0xagrXDOInnsGAUM8V7ce5VhwWxwIjjP7QCh886P2HHg5KM7twSG6rABEB
+AAGJAjYEGAEIACAWIQToe9khzdiFydeKOMXkWxDdAn0kcgUCYuFBygIbDAAKCRDk
+WxDdAn0kcuc8EACCJWI0o5AYxDQ1tkbPcnfwzFQQ50vH6pfEmk3/YQXbaJxtNLVS
+ba13zC7rw5pBfVLXPDu7oOcf0x8/3HoeKfAFP/ChlU/PA2yojigZJV9zCpqCC0dm
+vV7N+Mgd/GD6FGwnSM3kHnkYPgbu1/uMDbm7OTq3fbNK5BTKikkmW8ZxDyNwGYlR
+5Smt2dymlxcEIYZSw27R5yyJhw6ri5trwJwJYay7LgKnWb+ePNDPUR0+ph0bXYl8
+DKa1c3vkNfmN17AUtzl0DByMZ+C0mJiu1cjWbbgg5PuQQXiNkV2xcDcMrLjVE686
+YkYI9KKLJQVLO8d57OEv0irE1bD7BlyILwemrdjuyHsPRBwHSnw8s1+Sy4qWg099
+rCGcK7wu+L9r/+fgTxONSyqb74pcO4JQDXZKKjsDfR1R2qhcvCbU4VpOvIdoiXh9
+wUBY4pBrMGDbtah3DOqvCEb7Jol754KWOaTkjDNbGrBZ5UBGdVa5flKOzIN+YOVQ
+ce9Nz8XeSVy8PzrUpf5P/DFBe4Gr/E4PZkuLtJGfzNHbzhBMVMv/vfbL24uACQM0
+DKQ3vplo+++Zcyey8Nz1MNJDYqcCD/o1SInMPWbtlytNNWLj+5i75K37TIOl3vkq
+Aa6OeR9y7rn8bJ88tKgnXiEalMy7HUyBDZbMCeE6IVGZvbUSdLz5VGpKmQ==
+=KI4D
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/utils/python-rpc/framework/wallet.py b/utils/python-rpc/framework/wallet.py
index 1c42f7f04..18af4edc4 100644
--- a/utils/python-rpc/framework/wallet.py
+++ b/utils/python-rpc/framework/wallet.py
@@ -38,13 +38,14 @@ class Wallet(object):
self.port = port
self.rpc = JSONRPC('{protocol}://{host}:{port}'.format(protocol=protocol, host=host, port=port if port else 18090+idx))
- def transfer(self, destinations, account_index = 0, subaddr_indices = [], priority = 0, ring_size = 0, unlock_time = 0, payment_id = '', get_tx_key = True, do_not_relay = False, get_tx_hex = False, get_tx_metadata = False):
+ def transfer(self, destinations, account_index = 0, subaddr_indices = [], priority = 0, ring_size = 0, unlock_time = 0, payment_id = '', get_tx_key = True, do_not_relay = False, get_tx_hex = False, get_tx_metadata = False, subtract_fee_from_outputs = []):
transfer = {
'method': 'transfer',
'params': {
'destinations': destinations,
'account_index': account_index,
'subaddr_indices': subaddr_indices,
+ 'subtract_fee_from_outputs': subtract_fee_from_outputs,
'priority': priority,
'ring_size' : ring_size,
'unlock_time' : unlock_time,