diff --git a/.gitignore b/.gitignore index bce5b5c..d2391b1 100644 --- a/.gitignore +++ b/.gitignore @@ -37,9 +37,11 @@ grenache-get grenache-put grenache-keygen grenache-lookup +grenache-request grenache-announce # # Distribution # +*.1 *.tar.* diff --git a/Makefile.am b/Makefile.am index d436237..ec45abc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # @@ -18,7 +18,7 @@ ACLOCAL_AMFLAGS = -I m4 -GRC_SUBDIRS = . src tests +GRC_SUBDIRS = . doc src tests SUBDIRS = $(GRC_SUBDIRS) DIST_SUBDIRS = $(GRC_SUBDIRS) include m4 @@ -29,18 +29,17 @@ EXTRA_DIST = \ LICENSE \ README.md \ autogen.sh \ -shtool +shtool \ +ed25519/readme.md \ +ed25519/license.txt DISTCLEANFILES = \ config.h.in~ MAINTAINERCLEANFILES = \ -$(DISTCLEANFILES) \ -README +$(DISTCLEANFILES) dist-hook: dist-ChangeLog - cp -fpR $(top_srcdir)/ed25519 $(distdir) - $(RM) -rf $(distdir)/ed25519/.git maintainer-clean-local: maintainer-clean-local-check diff --git a/README.md b/README.md index 337f7d2..b361463 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,44 @@ # Grenache CLI ![license](https://img.shields.io/github/license/bitfinexcom/grenache-cli.svg) -![GitHub (pre-)release](https://img.shields.io/github/release/bitfinexcom/grenache-cli/all.svg) -![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/bitfinexcom/grenache-cli.svg) +![GitHub release](https://img.shields.io/github/release/bitfinexcom/grenache-cli/all.svg) +![GitHub release date](https://img.shields.io/github/release-date/bitfinexcom/grenache-cli.svg) ![GitHub last commit](https://img.shields.io/github/last-commit/bitfinexcom/grenache-cli.svg) ![GitHub pull requests](https://img.shields.io/github/issues-pr/bitfinexcom/grenache-cli.svg) -![stability-unstable](https://img.shields.io/badge/stability-unstable-yellow.svg) +![stability-stable](https://img.shields.io/badge/stability-stable-green.svg) - * [Introduction](#introduction) - * [Prerequisites](#prerequisites) - * [Install](#install) - * [Initialize](#initialize) - * [Store items to the DHT](#store-items-to-the-dht) - * [Immutable items](#immutable-items) - * [Mutable items](#mutable-items) - * [Retreive items from the DHT](#retreive-items-from-the-dht) - * [Lookup peers](#lookup-peers) - * [Announce services](#announce-services) - * [Maintainers](#maintainers) + - [Introduction](#introduction) + - [Copying](#copying) + - [Prerequisites](#prerequisites) + - [Install](#install) + - [Verifying the distribution](#verifying-the-distribution) + - [Install from source](#install-from-source) + - [Initialize](#initialize) + - [Store items to the DHT](#store-items-to-the-dht) + - [Immutable items](#immutable-items) + - [Mutable items](#mutable-items) + - [Retrieve items from the DHT](#retrieve-items-from-the-dht) + - [Lookup peers](#lookup-peers) + - [Announce services](#announce-services) + - [Query services](#query-services) + - [Maintainers](#maintainers) ## Introduction The [**Grenache**](https://github.com/bitfinexcom/grenache) **C**ommand **L**ine **I**nterface is a set of tools to use the [grenache-grape](https://github.com/bitfinexcom/grenache-grape) suite directly from your command line. Using this set of tools you can create fancy scripts that communicate directly with the DHT. +All command lines presented in this document are for illustrative purposes only and could make use of tools not available on the user's operating system or provided in a different version, whereby some capabilities may not be available. + + +## Copying + +The [**Grenache**](https://github.com/bitfinexcom/grenache) **C**ommand **L**ine **I**nterface is free software. See the files whose names start with _LICENSE_ (case-insensitive) for copying permission. The manuals, and some of the runtime libraries, are under different terms; see the individual source files for details. + +Copyright years on [**Grenache**](https://github.com/bitfinexcom/grenache) **C**ommand **L**ine **I**nterface source files may be listed using range notation, e.g., 2017-2021, indicating that every year in the range, inclusive, is a copyrightable year that could otherwise be listed individually. + ## Prerequisites @@ -34,14 +47,65 @@ Be sure that your version of [grenache-grape](https://github.com/bitfinexcom/gre ## Install -Briefly, the shell command +The [**Grenache**](https://github.com/bitfinexcom/grenache) **C**ommand **L**ine **I**nterface relies on the [GNU Build System](https://www.gnu.org/software/automake/manual/html_node/GNU-Build-System.html). In the case where source code has been taken directly from this repository, several files related to the build system have to be generated manually; this can be achieved by running: ```bash -./configure && make && make install +./autogen.sh +``` + +However, this requires a number of development tools that are not needed to run the [**Grenache**](https://github.com/bitfinexcom/grenache) **C**ommand **L**ine **I**nterface and are, usually, unlikely to be already installed on the user's operating system. Refer to the [official documentation](https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html) for all the required tools as well as the operating system literature on how to install them. + +The preferred method of installing the [**Grenache**](https://github.com/bitfinexcom/grenache) **C**ommand **L**ine **I**nterface is to download the distribution archives, available under the [Releases](https://github.com/bitfinexcom/grenache-cli/releases) section of this repository. The download of the several files can be automated using something similar, which will always fetch all assets of the [latest release](https://github.com/bitfinexcom/grenache-cli/releases/latest) available: + +```bash +parallel --color --no-run-if-empty 'wget --no-verbose --continue' < <( \ + jq --raw-output 'try(.assets[]) | .browser_download_url // empty' < <( \ + curl --silent 'https://api.github.com/repos/bitfinexcom/grenache-cli/releases/latest' \ + ) \ +) ``` -should configure, build and install this package. +Although it is not required, it is worth verifying all the assets before taking any other action; refer to the [Verifying the distribution](#verifying-the-distribution) section for more details. + +### Verifying the distribution + +Unless already done in the past, it is required to import the [GnuPG](https://www.gnupg.org/) key of the packaging system in order to verify the authenticity of the distribution. Starting with version [0.8.0](https://github.com/bitfinexcom/grenache-cli/releases/tag/0.8.0), every released asset is signed using the key [94282D2E89053665952D3E7034C1AE501F0C2C6F](https://keys.openpgp.org/vks/v1/by-fingerprint/94282D2E89053665952D3E7034C1AE501F0C2C6F); older versions may have been signed with a different key, however, the same procedure applies. + +To import the packaging system key within the local keyring, something like this is enough: + +```bash +gpg --keyserver 'hkps://keys.openpgp.org' --recv-keys '94282D2E89053665952D3E7034C1AE501F0C2C6F' +``` +Optionally, the packaging system key can be marked as *trusted* within the local keyring, such as via `--lsign-key`, making the verification process straightforward. However, in cases where this does not meet a user's security standards and the version of [GnuPG](https://www.gnupg.org/) in use is fairly recent, setting a [TOFU](https://www.gnupg.org/documentation/manuals/gnupg/GPG-Configuration-Options.html#index-trust_002dmodel) trust policy might be a suitable trade-off: + +```bash +gpg --tofu-policy 'good' '94282D2E89053665952D3E7034C1AE501F0C2C6F' +``` + +In order to verify the authenticity of downloaded assets, something similar can be used: + +```bash +parallel --color 'gpg --trust-model "tofu+pgp" --verify' ::: *.asc +``` + +Finally, in case the downloaded release provides a list of file checksums, this can be verified using something like this: + +```bash +parallel --color --match '(\w+)sums\.asc$' \ + 'gpg --trust-model "tofu+pgp" --decrypt {} | cksum --algorithm {1.1} --check --ignore-missing' \ +::: *sums.asc +``` + +### Install from source + +Regardless of either source code has been taken directly from this repository or the sources archive has been unpacked, the shell command: + +```bash +./configure && make && make install +``` + +should configure, build and install the [**Grenache**](https://github.com/bitfinexcom/grenache) **C**ommand **L**ine **I**nterface. ## Initialize @@ -89,9 +153,9 @@ grenache-put --help to retrieve the complete options list. -## Retreive items from the DHT +## Retrieve items from the DHT -The `grenache-get` command reads a data record from the DHT (see [BEP 44](http://bittorrent.org/beps/bep_0044.html) for more information). There is no differences in retreiving a _mutable_ or an _immutable_ item; on both cases the key returned by the *PUT* request must be provided. In any case, `grenache-get` validates the payload it receive; this will ensure that the _key_ provided really match the payload and, in case of a _mutable_ item, that the signature is correct. This will protect you from evil nodes on the network. To read an item from the DHT simply run something like this: +The `grenache-get` command reads a data record from the DHT (see [BEP 44](http://bittorrent.org/beps/bep_0044.html) for more information). There is no differences in retrieving a _mutable_ or an _immutable_ item; in both cases the key returned by the *PUT* request must be provided. Furthermore, starting from version _[0.9.6](https://github.com/bitfinexcom/grenache-grape/commit/efbfc11)_ of [grenache-grape](https://github.com/bitfinexcom/grenache-grape), the _salt_ specified during the *PUT* operation must be provided if used. In any case, `grenache-get` validates the payload it receive; this will ensure that the _key_ provided really match the payload and, in case of a _mutable_ item, that the signature is correct. This will protect you from evil nodes on the network. To read an item from the DHT simply run something like this: ```bash grenache-get '81c2a8157780989af9a16661324fafbd7803877d' @@ -101,7 +165,7 @@ For example, you can format the previously stored available memory amount using ```bash numfmt --from=auto --to=iec-i < <( - grenache-get '81c2a8157780989af9a16661324fafbd7803877d' + grenache-get --salt 'sys:mem:available' '633def0b4349e2ed5bfbe0a5a1bb34e622f8c20d' ) ``` @@ -176,8 +240,57 @@ grenache-announce --help to retrieve the complete options list. +## Query services + +The `grenache-request` command sends a request to a service in the DHT. To query the [rest:ext:helpdesk:foo](https://github.com/bitfinexcom/bfx-ext-helpdesk-js) service, simply run something like this: + +```bash +grenache-request 'rest:ext:helpdesk:foo' 'getDepartments' +``` + +Action arguments are optional and can be omitted altogether. However, to pass an argument to an action, use the `-a` switch or its long form `--arg`; to query the [rest:net:util](https://github.com/bitfinexcom/bfx-util-net-js) service in order to get information about IP _208.67.222.222_, simply run something like this: + +```bash +grenache-request -a '"208.67.222.222"' 'rest:util:net' 'getIpInfo' +``` + +To send multiple arguments, simply repeat the `-a` switch or its long form `--arg` as many times as needed; arguments will be passed to the service action in the same order as they were supplied on the command line. To query the [rest:ext:gpg](https://github.com/bitfinexcom/bfx-ext-gpg-js) service in order to get a signature for the _hello_ message, simply run something like this: + +```bash +grenache-request -a '"68656c6c6f"' -a '{"userId":1}' 'rest:ext:gpg' 'getDigitalSignature' +``` + +Arguments are treated as _JSON_-encoded text; sometimes, when dealing with plain strings, this can be somewhat cumbersome. In such cases, the `-s` switch or its long form `--string` can be used to pass a string as-is or `-n` or its long form `--numeric` when accepting an option that is intended to be treated as a numeric value. + +Typically, the output is a _JSON_-encoded text. Sometimes, filtering this text can be useful; in such cases, output can be selected using the `-q` switch or its long form `--query`, as shown below: + +```bash +grenache-request -q 'map(select(.active_members > 3))' 'rest:ext:helpdesk:bar' 'getTeams' +``` + +The query is passed as-is to [jq](https://jqlang.github.io/jq/) and will be applied directly to the third position of the response array; refer to the official [filter documentation](https://jqlang.github.io/jq/manual/#basic-filters) for more details on the syntax to be used. However, there are cases where a plain string written directly to the standard output is preferable rather than formatted as a _JSON_ string with quotes, perhaps when pipe the output to another command; in such cases, the `-r` switch or its long form `--raw` can be used, as shown below: + +```bash +grenache-request -q '.[1].timezone' -r -s '208.67.222.222' 'rest:util:net' 'getIpGeo' +``` + +Under normal circumstances, workflow is to look up the service via [grenache-lookup](#lookup-peers) and then send the request to the worker. There might be cases, perhaps when dealing with a system without a running [grape](https://github.com/bitfinexcom/grenache-grape), where it would be useful to query a service without looking it up first; in such cases, the `-w` switch or its long form `--worker` can be used, as shown below: + +```bash +grenache-request -r -s '776f726c64' -a '{"userId":8}' -w '10.0.0.1:1337' 'rest:ext:gpg' 'getDigitalSignature' +``` + +Those are the main options; see + +```bash +grenache-request --help +``` + +to retrieve the complete options list. + + ## Maintainers Current maintainers: -* Davide Scola - davide@bitfinex.com +- [Davide Scola](https://github.com/davide-scola) diff --git a/autogen.sh b/autogen.sh index 065d654..9ac36e2 100755 --- a/autogen.sh +++ b/autogen.sh @@ -2,7 +2,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # @@ -25,8 +25,8 @@ case "${1}" in find . -type f -name 'Makefile.in' -print0 | xargs -r0 rm -f ;; * ) - autoreconf --force --install --include 'm4' - [[ -x shtool ]] || shtoolize -q 'echo' + autoreconf --force --install --warnings=all --include 'm4' [[ -d autom4te.cache ]] && rm -rf autom4te.cache + [[ -x shtool ]] || PERL5OPT='-M-warnings=deprecated' shtoolize -q 'echo' ;; esac diff --git a/configure.ac b/configure.ac index 3689104..b0cd5ac 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl This file is part of Grenache Command Line Interface. dnl -dnl Copyright (C) 2017, 2018 Davide Scola +dnl Copyright (C) 2017-2025 Davide Scola dnl dnl Licensed under the Apache License, Version 2.0 (the "License"); you may dnl not use this file except in compliance with the License. You may obtain @@ -14,14 +14,14 @@ dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or dnl implied. See the License for the specific language governing permissions dnl and limitations under the License. -AC_PREREQ(2.69) -AC_INIT([grenache-cli], [0.6.1], [davide@bitfinex.com]) +AC_PREREQ([2.69]) +AC_INIT([grenache-cli],[0.8.2],[davide@bitfinex.com]) -AC_SUBST([VERSION], [0.6.1]) +AC_SUBST([VERSION], [0.8.2]) AC_SUBST([SB], [`$srcdir/shtool echo -n -e %B`]) AC_SUBST([EB], [`$srcdir/shtool echo -n -e %b`]) -AC_COPYRIGHT([Copyright (c) 2017, 2018 Davide Scola, +AC_COPYRIGHT([Copyright (c) 2017-2025 Davide Scola, This configure script may be copied, distributed and modified under the terms of the Apache License 2.0 license; see LICENSE for more details.]) @@ -37,7 +37,8 @@ AC_CONFIG_SRCDIR([include/io.h]) AC_CONFIG_HEADERS([config.h]) AC_CANONICAL_HOST -AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-xz]) +AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-xz subdir-objects]) +AM_EXTRA_RECURSIVE_TARGETS([install-man]) AX_IS_RELEASE([git-directory]) AX_CHECK_ENABLE_DEBUG @@ -51,13 +52,14 @@ AX_MSG_BOLD([Checking for required programs]) LT_INIT AC_PROG_CC +AC_PROG_CXX AC_PROG_CPP AM_PROG_CC_C_O AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET -AC_PROG_LIBTOOL AC_PROG_AWK +AM_MISSING_PROG([HELP2MAN], [help2man]) AX_PROG_JQ AX_PROG_CAT @@ -101,9 +103,8 @@ dnl Checks for header files. dnl -------------------------------------------------------------------- AX_MSG_BOLD([Checking for required header files]) -AC_HEADER_STDC AC_CHECK_HEADERS([sys/random.h]) -AC_CHECK_HEADERS([fcntl.h unistd.h], [], [ +AC_CHECK_HEADERS([fcntl.h stdint.h unistd.h], [], [ AC_MSG_ERROR([missing $ac_header vital header file]) ]) @@ -115,6 +116,7 @@ AX_MSG_BOLD([Checking for compiler characteristics]) AC_C_CONST AC_C_INLINE AC_TYPE_SIZE_T +AC_TYPE_SSIZE_T AC_TYPE_INT32_T AC_TYPE_INT64_T AC_TYPE_UINT32_T @@ -133,7 +135,7 @@ AC_CHECK_FUNCS([getentropy], [ CPPFLAGS="-DED25519_NO_SEED ${CPPFLAGS}" ]) -AC_CHECK_FUNCS([explicit_bzero], [], [ +AC_CHECK_FUNCS([explicit_bzero select], [], [ AC_MSG_ERROR([missing $ac_func vital function]) ]) @@ -142,7 +144,7 @@ dnl Checks for user defined options. dnl -------------------------------------------------------------------- AX_MSG_BOLD([Checking user defined options]) -AC_ARG_ENABLE([x86-features], AC_HELP_STRING([--enable-x86-features], +AC_ARG_ENABLE([x86-features], AS_HELP_STRING([--enable-x86-features], [Enable the x86 features check @<:@default=yes@:>@]), [ax_cv_enable_x86_features="${enableval}"], [ax_cv_enable_x86_features='yes']) @@ -180,6 +182,7 @@ AX_MSG_BOLD([Writing output files]) AC_CONFIG_FILES([ \ Makefile \ + doc/Makefile \ m4/Makefile \ include/Makefile \ src/Makefile \ @@ -187,6 +190,7 @@ AC_CONFIG_FILES([ \ src/grenache-get \ src/grenache-keygen \ src/grenache-lookup \ + src/grenache-request \ src/grenache-announce \ tests/Makefile \ tests/sign-test-vector-1.sh \ diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..e9af795 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,33 @@ +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017-2025 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +dist_man1_MANS = \ +grenache-get.1 \ +grenache-put.1 \ +grenache-keygen.1 \ +grenache-lookup.1 \ +grenache-request.1 \ +grenache-announce.1 + +MAINTAINERCLEANFILES = \ +$(dist_man1_MANS) + +%.1: $(top_srcdir)/src/%.in $(top_srcdir)/doc/Makefile.am + $(HELP2MAN) --no-info --output=$@ \ + --name="manual page for $(PACKAGE_NAME) version $(PACKAGE_VERSION) on $(host_cpu)-$(host_os)" \ + "${SHELL} $(top_builddir)/src/$(notdir $(basename $<))$(EXEEXT)" diff --git a/ed25519 b/ed25519 index 7fa6712..b1f19fa 160000 --- a/ed25519 +++ b/ed25519 @@ -1 +1 @@ -Subproject commit 7fa6712ef5d581a6981ec2b08ee623314cd1d1c4 +Subproject commit b1f19fab4aebe607805620d25a5e42566ce46a0e diff --git a/include/Makefile.am b/include/Makefile.am index a202cfc..bbfcbb8 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,7 +1,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # diff --git a/include/common.h b/include/common.h index 5d33120..1c8d659 100644 --- a/include/common.h +++ b/include/common.h @@ -2,7 +2,7 @@ * @file * This file is part of Grenache Command Line Interface. * - * Copyright (C) 2017, 2018 Davide Scola + * Copyright (C) 2017-2025 Davide Scola * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain @@ -24,10 +24,10 @@ #ifdef HAVE_C99_INLINE # define INLINE inline #else -# define INLINE static inline +# define INLINE #endif -#ifdef HAVE_FUNC_ATTRIBUTE_ALWAYS_INLINE +#if defined(HAVE_C99_INLINE) && defined(HAVE_FUNC_ATTRIBUTE_ALWAYS_INLINE) # define ALWAYS_INLINE __attribute__ ((__always_inline__)) #else # define ALWAYS_INLINE diff --git a/include/encode.h b/include/encode.h index b118519..22ee305 100644 --- a/include/encode.h +++ b/include/encode.h @@ -2,7 +2,7 @@ * @file * This file is part of Grenache Command Line Interface. * - * Copyright (C) 2017, 2018 Davide Scola + * Copyright (C) 2017-2025 Davide Scola * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain diff --git a/include/io.h b/include/io.h index 0c3ee1f..057c907 100644 --- a/include/io.h +++ b/include/io.h @@ -2,7 +2,7 @@ * @file * This file is part of Grenache Command Line Interface. * - * Copyright (C) 2017, 2018 Davide Scola + * Copyright (C) 2017-2025 Davide Scola * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain @@ -21,6 +21,12 @@ #define _IO_H +/* + * Type of an IO operation. + */ +typedef ssize_t (*ioop_t) (int, void *, size_t); + + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ diff --git a/m4/Makefile.am b/m4/Makefile.am index 187d1bb..dd5623f 100644 --- a/m4/Makefile.am +++ b/m4/Makefile.am @@ -1,7 +1,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # diff --git a/m4/ax_append_compile_flags.m4 b/m4/ax_append_compile_flags.m4 index 5b6f1af..9c85635 100644 --- a/m4/ax_append_compile_flags.m4 +++ b/m4/ax_append_compile_flags.m4 @@ -30,33 +30,12 @@ # # Copyright (c) 2011 Maarten Bosmans # -# This program 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 (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 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 . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. -#serial 6 +#serial 7 AC_DEFUN([AX_APPEND_COMPILE_FLAGS], [AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4 index e8c5312..dd6d8b6 100644 --- a/m4/ax_append_flag.m4 +++ b/m4/ax_append_flag.m4 @@ -23,33 +23,12 @@ # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # -# This program 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 (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 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 . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. -#serial 7 +#serial 8 AC_DEFUN([AX_APPEND_FLAG], [dnl diff --git a/m4/ax_append_link_flags.m4 b/m4/ax_append_link_flags.m4 index 6f7f174..99b9fa5 100644 --- a/m4/ax_append_link_flags.m4 +++ b/m4/ax_append_link_flags.m4 @@ -28,33 +28,12 @@ # # Copyright (c) 2011 Maarten Bosmans # -# This program 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 (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 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 . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. -#serial 6 +#serial 7 AC_DEFUN([AX_APPEND_LINK_FLAGS], [AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) diff --git a/m4/ax_c99_inline.m4 b/m4/ax_c99_inline.m4 index 6675e02..bca6f9b 100644 --- a/m4/ax_c99_inline.m4 +++ b/m4/ax_c99_inline.m4 @@ -12,6 +12,11 @@ # and "extern inline" correctly. An application may replace "inline" with # "static inline" as a workaround for older compilers. # +# Note: a slightly modified version by Davide Scola +# - fix a warning with newer versions of autoconf (for more details +# see https://autotools.io/forwardporting/autoconf.html) +# - replaced obsolete macro `AC_PROG_CC_C99' with `AC_PROG_CC' +# # LICENSE # # Copyright (c) 2009 Michael McMaster @@ -21,11 +26,11 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 8 +#serial 9 AC_DEFUN([AX_C99_INLINE], [ AC_MSG_CHECKING([whether the compiler supports C99 inline functions]) - AC_REQUIRE([AC_PROG_CC_C99]) + AC_REQUIRE([AC_PROG_CC]) AC_LANG_PUSH([C]) @@ -35,10 +40,10 @@ AC_DEFUN([AX_C99_INLINE], [ dnl GCC versions before 4.3 would output the inline functions into all dnl translation units that could require the definition. AC_LINK_IFELSE( - AC_LANG_SOURCE([ - inline void* foo() { foo(); return &foo; } - int main() { return foo() != 0;} - ]), + [AC_LANG_SOURCE([ + inline void* foo(void) { foo(); return &foo; } + int main(void) { return foo() != 0;} + ])], dnl the invalid source compiled, so the inline keyword does not work dnl correctly. @@ -46,10 +51,10 @@ AC_DEFUN([AX_C99_INLINE], [ dnl Secondary test of valid source. AC_LINK_IFELSE( - AC_LANG_SOURCE([ - extern inline void* foo() { foo(); return &foo; } - int main() { return foo() != 0;} - ]), + [AC_LANG_SOURCE([ + extern inline void* foo(void) { foo(); return &foo; } + int main(void) { return foo() != 0;} + ])], AC_MSG_RESULT([yes]) AC_DEFINE([HAVE_C99_INLINE], [1], diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 index dcabb92..54191c5 100644 --- a/m4/ax_check_compile_flag.m4 +++ b/m4/ax_check_compile_flag.m4 @@ -29,40 +29,29 @@ # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # -# This program 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 (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 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 . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. -#serial 5 +#serial 11 AC_DEFUN([AX_CHECK_COMPILE_FLAG], [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl -AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ +AC_CACHE_CHECK([whether the _AC_LANG compiler accepts $1], CACHEVAR, [ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS - _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + if test x"m4_case(_AC_LANG, + [C], [$GCC], + [C++], [$GXX], + [Fortran], [$GFC], + [Fortran 77], [$G77], + [Objective C], [$GOBJC], + [Objective C++], [$GOBJCXX], + [no])" = xyes ; then + add_gnu_werror="-Werror" + fi + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1 $add_gnu_werror" AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) diff --git a/m4/ax_check_enable_debug.m4 b/m4/ax_check_enable_debug.m4 index d36bcdf..7bc7710 100644 --- a/m4/ax_check_enable_debug.m4 +++ b/m4/ax_check_enable_debug.m4 @@ -42,7 +42,7 @@ # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. -#serial 8 +#serial 9 AC_DEFUN([AX_CHECK_ENABLE_DEBUG],[ AC_BEFORE([$0],[AC_PROG_CC])dnl @@ -118,7 +118,7 @@ AC_DEFUN([AX_CHECK_ENABLE_DEBUG],[ dnl Define various variables if debugging is disabled. dnl assert.h is a NOP if NDEBUG is defined, so define it by default. AS_IF([test "x$enable_debug" = "xyes"], - [m4_map_args_w(ax_enable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is enabled])])], - [m4_map_args_w(ax_disable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is disabled])])]) + [m4_map_args_w(ax_enable_debug_vars, [AC_DEFINE(], [,[1],[Define if debugging is enabled])])], + [m4_map_args_w(ax_disable_debug_vars, [AC_DEFINE(], [,[1],[Define if debugging is disabled])])]) ax_enable_debug=$enable_debug ]) diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4 index 819409a..03a30ce 100644 --- a/m4/ax_check_link_flag.m4 +++ b/m4/ax_check_link_flag.m4 @@ -29,33 +29,12 @@ # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # -# This program 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 (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 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 . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. -#serial 5 +#serial 6 AC_DEFUN([AX_CHECK_LINK_FLAG], [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF diff --git a/m4/ax_compiler_flags_cflags.m4 b/m4/ax_compiler_flags_cflags.m4 index aeb16e3..916f918 100644 --- a/m4/ax_compiler_flags_cflags.m4 +++ b/m4/ax_compiler_flags_cflags.m4 @@ -19,13 +19,14 @@ # LICENSE # # Copyright (c) 2014, 2015 Philip Withnall +# Copyright (c) 2017, 2018 Reini Urban # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 14 +#serial 17 AC_DEFUN([AX_COMPILER_FLAGS_CFLAGS],[ AC_REQUIRE([AC_PROG_SED]) @@ -39,6 +40,13 @@ AC_DEFUN([AX_COMPILER_FLAGS_CFLAGS],[ AC_LANG_PUSH([C]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ + [#ifndef __cplusplus + #error "no C++" + #endif]])], + [ax_compiler_cxx=yes;], + [ax_compiler_cxx=no;]) + # Always pass -Werror=unknown-warning-option to get Clang to fail on bad # flags, otherwise they are always appended to the warn_cflags variable, and # Clang warns on them for every compilation unit. @@ -64,23 +72,31 @@ AC_DEFUN([AX_COMPILER_FLAGS_CFLAGS],[ ],ax_warn_cflags_variable,[$ax_compiler_flags_test]) AS_IF([test "$ax_enable_compile_warnings" != "no"],[ + if test "$ax_compiler_cxx" = "no" ; then + # C-only flags. Warn in C++ + AX_APPEND_COMPILE_FLAGS([ dnl + -Wnested-externs dnl + -Wmissing-prototypes dnl + -Wstrict-prototypes dnl + -Wdeclaration-after-statement dnl + -Wimplicit-function-declaration dnl + -Wold-style-definition dnl + -Wjump-misses-init dnl + ],ax_warn_cflags_variable,[$ax_compiler_flags_test]) + fi + # "yes" flags AX_APPEND_COMPILE_FLAGS([ dnl -Wall dnl -Wextra dnl -Wundef dnl - -Wnested-externs dnl -Wwrite-strings dnl -Wpointer-arith dnl -Wmissing-declarations dnl - -Wmissing-prototypes dnl - -Wstrict-prototypes dnl -Wredundant-decls dnl -Wno-unused-parameter dnl -Wno-missing-field-initializers dnl - -Wdeclaration-after-statement dnl -Wformat=2 dnl - -Wold-style-definition dnl -Wcast-align dnl -Wformat-nonliteral dnl -Wformat-security dnl @@ -96,10 +112,15 @@ AC_DEFUN([AX_COMPILER_FLAGS_CFLAGS],[ -Wmissing-include-dirs dnl -Wunused-but-set-variable dnl -Warray-bounds dnl - -Wimplicit-function-declaration dnl -Wreturn-type dnl -Wswitch-enum dnl -Wswitch-default dnl + -Wduplicated-cond dnl + -Wduplicated-branches dnl + -Wlogical-op dnl + -Wrestrict dnl + -Wnull-dereference dnl + -Wdouble-promotion dnl $4 dnl $5 dnl $6 dnl diff --git a/m4/ax_compiler_flags_ldflags.m4 b/m4/ax_compiler_flags_ldflags.m4 index 842e329..976d119 100644 --- a/m4/ax_compiler_flags_ldflags.m4 +++ b/m4/ax_compiler_flags_ldflags.m4 @@ -19,13 +19,14 @@ # LICENSE # # Copyright (c) 2014, 2015 Philip Withnall +# Copyright (c) 2017, 2018 Reini Urban # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 8 +#serial 9 AC_DEFUN([AX_COMPILER_FLAGS_LDFLAGS],[ AX_REQUIRE_DEFINED([AX_APPEND_LINK_FLAGS]) @@ -48,7 +49,25 @@ AC_DEFUN([AX_COMPILER_FLAGS_LDFLAGS],[ ax_compiler_flags_test="" ]) - # macOS linker does not have --as-needed + AX_CHECK_LINK_FLAG([-Wl,--as-needed], [ + AX_APPEND_LINK_FLAGS([-Wl,--as-needed], + [AM_LDFLAGS],[$ax_compiler_flags_test]) + ]) + AX_CHECK_LINK_FLAG([-Wl,-z,relro], [ + AX_APPEND_LINK_FLAGS([-Wl,-z,relro], + [AM_LDFLAGS],[$ax_compiler_flags_test]) + ]) + AX_CHECK_LINK_FLAG([-Wl,-z,now], [ + AX_APPEND_LINK_FLAGS([-Wl,-z,now], + [AM_LDFLAGS],[$ax_compiler_flags_test]) + ]) + AX_CHECK_LINK_FLAG([-Wl,-z,noexecstack], [ + AX_APPEND_LINK_FLAGS([-Wl,-z,noexecstack], + [AM_LDFLAGS],[$ax_compiler_flags_test]) + ]) + # textonly, retpolineplt not yet + + # macOS and cygwin linker do not have --as-needed AX_CHECK_LINK_FLAG([-Wl,--no-as-needed], [ ax_compiler_flags_as_needed_option="-Wl,--no-as-needed" ], [ diff --git a/m4/ax_compiler_vendor.m4 b/m4/ax_compiler_vendor.m4 index 4ca8089..039f99d 100644 --- a/m4/ax_compiler_vendor.m4 +++ b/m4/ax_compiler_vendor.m4 @@ -8,15 +8,30 @@ # # DESCRIPTION # -# Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, sun, -# hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, microsoft, -# watcom, etc. The vendor is returned in the cache variable -# $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++. +# Determine the vendor of the C, C++ or Fortran compiler. The vendor is +# returned in the cache variable $ax_cv_c_compiler_vendor for C, +# $ax_cv_cxx_compiler_vendor for C++ or $ax_cv_fc_compiler_vendor for +# (modern) Fortran. The value is one of "intel", "ibm", "pathscale", +# "clang" (LLVM), "cray", "fujitsu", "sdcc", "sx", "nvhpc" (NVIDIA HPC +# Compiler), "portland" (PGI), "gnu" (GCC), "sun" (Oracle Developer +# Studio), "hp", "dec", "borland", "comeau", "kai", "lcc", "sgi", +# "microsoft", "metrowerks", "watcom", "tcc" (Tiny CC) or "unknown" (if +# the compiler cannot be determined). +# +# To check for a Fortran compiler, you must first call AC_FC_PP_SRCEXT +# with an appropriate preprocessor-enabled extension. For example: +# +# AC_LANG_PUSH([Fortran]) +# AC_PROG_FC +# AC_FC_PP_SRCEXT([F]) +# AX_COMPILER_VENDOR +# AC_LANG_POP([Fortran]) # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2008 Matteo Frigo +# Copyright (c) 2018-19 John Zaitseff # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -44,44 +59,61 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 16 +#serial 32 + +AC_DEFUN([AX_COMPILER_VENDOR], [dnl + AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, [dnl + dnl If you modify this list of vendors, please add similar support + dnl to ax_compiler_version.m4 if at all possible. + dnl + dnl Note: Do NOT check for GCC first since some other compilers + dnl define __GNUC__ to remain compatible with it. Compilers that + dnl are very slow to start (such as Intel) are listed first. + + vendors=" + intel: __ICC,__ECC,__INTEL_COMPILER + ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__,__ibmxl__ + pathscale: __PATHCC__,__PATHSCALE__ + clang: __clang__ + cray: _CRAYC + fujitsu: __FUJITSU + sdcc: SDCC,__SDCC + sx: _SX + nvhpc: __NVCOMPILER + portland: __PGI + gnu: __GNUC__ + sun: __SUNPRO_C,__SUNPRO_CC,__SUNPRO_F90,__SUNPRO_F95 + hp: __HP_cc,__HP_aCC + dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER + borland: __BORLANDC__,__CODEGEARC__,__TURBOC__ + comeau: __COMO__ + kai: __KCC + lcc: __LCC__ + sgi: __sgi,sgi + microsoft: _MSC_VER + metrowerks: __MWERKS__ + watcom: __WATCOMC__ + tcc: __TINYC__ + unknown: UNKNOWN + " + for ventest in $vendors; do + case $ventest in + *:) + vendor=$ventest + continue + ;; + *) + vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" + ;; + esac + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +#if !($vencpp) + thisisanerror; +#endif + ]])], [break]) + done -AC_DEFUN([AX_COMPILER_VENDOR], -[AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, - dnl Please add if possible support to ax_compiler_version.m4 - [# note: don't check for gcc first since some other compilers define __GNUC__ - vendors="intel: __ICC,__ECC,__INTEL_COMPILER - ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__ - pathscale: __PATHCC__,__PATHSCALE__ - clang: __clang__ - cray: _CRAYC - fujitsu: __FUJITSU - gnu: __GNUC__ - sun: __SUNPRO_C,__SUNPRO_CC - hp: __HP_cc,__HP_aCC - dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER - borland: __BORLANDC__,__CODEGEARC__,__TURBOC__ - comeau: __COMO__ - kai: __KCC - lcc: __LCC__ - sgi: __sgi,sgi - microsoft: _MSC_VER - metrowerks: __MWERKS__ - watcom: __WATCOMC__ - portland: __PGI - tcc: __TINYC__ - unknown: UNKNOWN" - for ventest in $vendors; do - case $ventest in - *:) vendor=$ventest; continue ;; - *) vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" ;; - esac - AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[ - #if !($vencpp) - thisisanerror; - #endif - ])], [break]) - done - ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1` - ]) -]) + ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1` + ]) +])dnl diff --git a/m4/ax_define_descriptor.m4 b/m4/ax_define_descriptor.m4 index 15e3670..a73b555 100644 --- a/m4/ax_define_descriptor.m4 +++ b/m4/ax_define_descriptor.m4 @@ -17,7 +17,7 @@ AC_DEFUN([AX_DEFINE_DESCRIPTOR], [ AS_LITERAL_IF([$2], [], [AC_FATAL([$0: requires literal arguments])]) AS_LITERAL_IF([$3], [], [AC_FATAL([$0: requires literal arguments])]) - AC_ARG_WITH(m4_tolower($1), AC_HELP_STRING(m4_tolower(--with-$1), + AC_ARG_WITH(m4_tolower($1), AS_HELP_STRING(m4_tolower(--with-$1), [Set the $2 file descriptor @<:@default=$3@:>@]), ac_cv_[]m4_tolower($1)="${withval:-yes}", ac_cv_[]m4_tolower($1)="$3") diff --git a/m4/ax_define_size.m4 b/m4/ax_define_size.m4 index fefeb1b..207752c 100644 --- a/m4/ax_define_size.m4 +++ b/m4/ax_define_size.m4 @@ -17,7 +17,7 @@ AC_DEFUN([AX_DEFINE_SIZE], [ AS_LITERAL_IF([$2], [], [AC_FATAL([$0: requires literal arguments])]) AS_LITERAL_IF([$3], [], [AC_FATAL([$0: requires literal arguments])]) - AC_ARG_WITH(m4_tolower($1), AC_HELP_STRING(m4_tolower(--with-$1), + AC_ARG_WITH(m4_tolower($1), AS_HELP_STRING(m4_tolower(--with-$1), [Set the $2 size in bytes @<:@default=$3@:>@]), ac_cv_[]m4_tolower($1)="${withval:-yes}", ac_cv_[]m4_tolower($1)="$3") diff --git a/m4/ax_gcc_archflag.m4 b/m4/ax_gcc_archflag.m4 index d4a37f8..c52b9b2 100644 --- a/m4/ax_gcc_archflag.m4 +++ b/m4/ax_gcc_archflag.m4 @@ -37,7 +37,7 @@ # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2008 Matteo Frigo # Copyright (c) 2014 Tsukasa Oi -# Copyright (c) 2017 Alexey Kopytov +# Copyright (c) 2017-2018 Alexey Kopytov # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -65,7 +65,7 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 20 +#serial 22 AC_DEFUN([AX_GCC_ARCHFLAG], [AC_REQUIRE([AC_PROG_CC]) @@ -108,7 +108,7 @@ case $host_cpu in *2?6[[ad]]?:*:*:*) ax_gcc_arch="sandybridge corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; *3?6[[ae]]?:*:*:*) ax_gcc_arch="ivybridge core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; *3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*) ax_gcc_arch="haswell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; - *3?6d?:*:*:*) ax_gcc_arch="broadwell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; + *3?6d?:*:*:*|*4?6[[7f]]?:*:*:*|*5?66?:*:*:*) ax_gcc_arch="broadwell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; *1?6c?:*:*:*|*2?6[[67]]?:*:*:*|*3?6[[56]]?:*:*:*) ax_gcc_arch="bonnell atom core2 pentium-m pentium3 pentiumpro" ;; *3?67?:*:*:*|*[[45]]?6[[ad]]?:*:*:*) ax_gcc_arch="silvermont atom core2 pentium-m pentium3 pentiumpro" ;; *000?f[[012]]?:*:*:*|?f[[012]]?:*:*:*|f[[012]]?:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;; @@ -198,6 +198,10 @@ case $host_cpu in *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";; *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";; 603ev|8240) ax_gcc_arch="$cputype 603e 603";; + *POWER7*) ax_gcc_arch="power7";; + *POWER8*) ax_gcc_arch="power8";; + *POWER9*) ax_gcc_arch="power9";; + *POWER10*) ax_gcc_arch="power10";; *) ax_gcc_arch=$cputype ;; esac ax_gcc_arch="$ax_gcc_arch powerpc" diff --git a/m4/ax_gcc_func_attribute.m4 b/m4/ax_gcc_func_attribute.m4 index 077962f..fa4e089 100644 --- a/m4/ax_gcc_func_attribute.m4 +++ b/m4/ax_gcc_func_attribute.m4 @@ -38,9 +38,11 @@ # dllimport # error # externally_visible +# fallthrough # flatten # format # format_arg +# gnu_format # gnu_inline # hot # ifunc @@ -53,6 +55,8 @@ # nothrow # optimize # pure +# sentinel +# sentinel_position # unused # used # visibility @@ -74,7 +78,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 7 +#serial 13 AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1]) @@ -128,12 +132,18 @@ AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ [externally_visible], [ int foo( void ) __attribute__(($1)); ], + [fallthrough], [ + void foo( int x ) {switch (x) { case 1: __attribute__(($1)); case 2: break ; }}; + ], [flatten], [ int foo( void ) __attribute__(($1)); ], [format], [ int foo(const char *p, ...) __attribute__(($1(printf, 1, 2))); ], + [gnu_format], [ + int foo(const char *p, ...) __attribute__((format(gnu_printf, 1, 2))); + ], [format_arg], [ char *foo(const char *p) __attribute__(($1(1))); ], @@ -175,6 +185,12 @@ AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ [pure], [ int foo( void ) __attribute__(($1)); ], + [sentinel], [ + int foo(void *p, ...) __attribute__(($1)); + ], + [sentinel_position], [ + int foo(void *p, ...) __attribute__(($1(1))); + ], [returns_nonnull], [ void *foo( void ) __attribute__(($1)); ], @@ -212,7 +228,7 @@ AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ dnl GCC doesn't exit with an error if an unknown attribute is dnl provided but only outputs a warning, so accept the attribute dnl only if no warning were issued. - [AS_IF([test -s conftest.err], + [AS_IF([grep -- -Wattributes conftest.err], [AS_VAR_SET([ac_var], [no])], [AS_VAR_SET([ac_var], [yes])])], [AS_VAR_SET([ac_var], [no])]) diff --git a/m4/ax_gcc_x86_cpu_supports.m4 b/m4/ax_gcc_x86_cpu_supports.m4 index fd37b4f..12119ad 100644 --- a/m4/ax_gcc_x86_cpu_supports.m4 +++ b/m4/ax_gcc_x86_cpu_supports.m4 @@ -27,6 +27,10 @@ # See also AX_CHECK_X86_FEATURES, which checks all the possible # instruction set and export the corresponding CFLAGS. # +# Note: a slightly modified version by Davide Scola +# - default case during cross-compilation for the `AC_RUN_IFELSE' +# macro has been added +# # LICENSE # # Copyright (c) 2016 Felix Chern @@ -57,7 +61,7 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 3 +#serial 4 AC_DEFUN_ONCE([_AX_GCC_X86_CPU_INIT], [AC_LANG_PUSH([C]) @@ -68,7 +72,9 @@ AC_DEFUN_ONCE([_AX_GCC_X86_CPU_INIT], [__builtin_cpu_init ();]) ], [ax_cv_gcc_check_x86_cpu_init=yes], + [ax_cv_gcc_check_x86_cpu_init=no], [ax_cv_gcc_check_x86_cpu_init=no])]) + AC_LANG_POP([C]) AS_IF([test "X$ax_cv_gcc_check_x86_cpu_init" = "Xno"], [AC_MSG_ERROR([Need GCC to support X86 CPU features tests])]) ]) @@ -88,6 +94,7 @@ AC_DEFUN([AX_GCC_X86_CPU_SUPPORTS], return 1; ])], [gcc_x86_feature=yes], + [gcc_x86_feature=no], [gcc_x86_feature=no] )] ) diff --git a/m4/ax_is_release.m4 b/m4/ax_is_release.m4 index 9097ddb..4618a99 100644 --- a/m4/ax_is_release.m4 +++ b/m4/ax_is_release.m4 @@ -19,7 +19,8 @@ # The POLICY parameter specifies how ax_is_release is determined. It can # take the following values: # -# * git-directory: ax_is_release will be 'no' if a '.git' directory exists +# * git-directory: ax_is_release will be 'no' if a '.git' +# directory or git worktree exists # * minor-version: ax_is_release will be 'no' if the minor version number # in $PACKAGE_VERSION is odd; this assumes # $PACKAGE_VERSION follows the 'major.minor.micro' scheme @@ -44,7 +45,7 @@ # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. -#serial 7 +#serial 9 AC_DEFUN([AX_IS_RELEASE],[ AC_BEFORE([AC_INIT],[$0]) @@ -52,7 +53,7 @@ AC_DEFUN([AX_IS_RELEASE],[ m4_case([$1], [git-directory],[ # $is_release = (.git directory does not exist) - AS_IF([test -d ${srcdir}/.git],[ax_is_release=no],[ax_is_release=yes]) + AS_IF([test -d ${srcdir}/.git || (test -f ${srcdir}/.git && grep \.git/worktrees ${srcdir}/.git)],[ax_is_release=no],[ax_is_release=yes]) ], [minor-version],[ # $is_release = ($minor_version is even) @@ -75,6 +76,6 @@ AC_DEFUN([AX_IS_RELEASE],[ [always],[ax_is_release=yes], [never],[ax_is_release=no], [ - AC_MSG_ERROR([Invalid policy. Valid policies: git-directory, minor-version, micro-version, dash-version, always, never.]) + m4_if($1, [], m4_fatal([$0: invalid policy $1. Valid policies: git-directory, minor-version, micro-version, dash-version, always, never])) ]) ]) diff --git a/src/Makefile.am b/src/Makefile.am index 31bc212..36ab241 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # @@ -31,6 +31,7 @@ grenache-put \ grenache-get \ grenache-keygen \ grenache-lookup \ +grenache-request \ grenache-announce noinst_LTLIBRARIES = \ @@ -39,16 +40,23 @@ libcommon.la libed25519_la_SOURCES = \ -$(top_srcdir)/ed25519/src/add_scalar.c \ -$(top_srcdir)/ed25519/src/fe.c \ -$(top_srcdir)/ed25519/src/ge.c \ -$(top_srcdir)/ed25519/src/key_exchange.c \ -$(top_srcdir)/ed25519/src/keypair.c \ -$(top_srcdir)/ed25519/src/sc.c \ -$(top_srcdir)/ed25519/src/seed.c \ -$(top_srcdir)/ed25519/src/sha512.c \ -$(top_srcdir)/ed25519/src/sign.c \ -$(top_srcdir)/ed25519/src/verify.c +../ed25519/src/add_scalar.c \ +../ed25519/src/ed25519.h \ +../ed25519/src/fe.h \ +../ed25519/src/fe.c \ +../ed25519/src/fixedint.h \ +../ed25519/src/ge.h \ +../ed25519/src/ge.c \ +../ed25519/src/key_exchange.c \ +../ed25519/src/keypair.c \ +../ed25519/src/precomp_data.h \ +../ed25519/src/sc.h \ +../ed25519/src/sc.c \ +../ed25519/src/seed.c \ +../ed25519/src/sha512.h \ +../ed25519/src/sha512.c \ +../ed25519/src/sign.c \ +../ed25519/src/verify.c libcommon_la_SOURCES = \ diff --git a/src/encode.c b/src/encode.c index 7b58c9e..db51b3f 100644 --- a/src/encode.c +++ b/src/encode.c @@ -2,7 +2,7 @@ * @file * This file is part of Grenache Command Line Interface. * - * Copyright (C) 2017, 2018 Davide Scola + * Copyright (C) 2017-2025 Davide Scola * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain diff --git a/src/grc-keygen.c b/src/grc-keygen.c index 64bfebe..bdc8d95 100644 --- a/src/grc-keygen.c +++ b/src/grc-keygen.c @@ -2,7 +2,7 @@ * @file * This file is part of Grenache Command Line Interface. * - * Copyright (C) 2017, 2018 Davide Scola + * Copyright (C) 2017-2025 Davide Scola * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain diff --git a/src/grc-sign.c b/src/grc-sign.c index 6ba91e3..60b902f 100644 --- a/src/grc-sign.c +++ b/src/grc-sign.c @@ -2,7 +2,7 @@ * @file * This file is part of Grenache Command Line Interface. * - * Copyright (C) 2017, 2018 Davide Scola + * Copyright (C) 2017-2025 Davide Scola * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain diff --git a/src/grc-verify.c b/src/grc-verify.c index a126d53..a215492 100644 --- a/src/grc-verify.c +++ b/src/grc-verify.c @@ -2,7 +2,7 @@ * @file * This file is part of Grenache Command Line Interface. * - * Copyright (C) 2017, 2018 Davide Scola + * Copyright (C) 2017-2025 Davide Scola * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain diff --git a/src/grenache-announce.in b/src/grenache-announce.in index f767996..96a17be 100644 --- a/src/grenache-announce.in +++ b/src/grenache-announce.in @@ -2,7 +2,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # @@ -33,21 +33,25 @@ JQ_ARGV=(--unbuffered -r) # Show program's help. function show_help { @CAT@ <<_EOF -Usage: - ${ME##*/} [OPTIONS] ... -- announce a service on the DHT. +${ME##*/} announces a service on the DHT - Options: +Usage: ${ME##*/} [OPTION]... [SERVICE]... - -d, --delimiter Set the service/port delimiter - -g, --grape Set the Grape hostname - -j, --json Use JSON as data serializer - -p, --port Set the Grape port number - -t, --tls Enable TLS +Options: + -d, --delimiter Set the service,port delimiter + -g, --grape Set the Grape hostname + -j, --json Use JSON as data serializer + -p, --port Set the Grape port number + -t, --tls Enable TLS - -h, --help Show this message - -V, --version Show version information + -h, --help Show help message + -V, --version Show version information - The order of the specified options is not relevant. +Examples: + ${ME##*/} Announce services from stdin + ${ME##*/} -d/ The same thing, but use / as delimiter + +Report bugs to <@PACKAGE_BUGREPORT@>. _EOF exit 1 @@ -56,12 +60,14 @@ _EOF # Show program's version. function show_version { @CAT@ <<_EOF -${WHOAMI##*/} (@host_cpu@-@host_os@) @PACKAGE_NAME@/@PACKAGE_VERSION@ -Copyright (C) 2017, 2018 Davide Scola <@PACKAGE_BUGREPORT@> +${WHOAMI##*/} @PACKAGE_VERSION@ + +Copyright (C) 2017-2025 Davide Scola <@PACKAGE_BUGREPORT@> This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +Written by Davide Scola. _EOF exit 1 diff --git a/src/grenache-get.in b/src/grenache-get.in index b97bf68..1eed71a 100644 --- a/src/grenache-get.in +++ b/src/grenache-get.in @@ -2,7 +2,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # @@ -19,11 +19,11 @@ readonly ME="${BASH_SOURCE[0]}" readonly WHOAMI="$(@READLINK@ -snf "${ME}")" -readonly ARGV=$(@GETOPT@ -o 'g:hip:trvVw' --long 'grape:,help,id,port:,tls,raw,value,version,write' -n "${ME##*/}" -- "$@") || exit 1 +readonly ARGV=$(@GETOPT@ -o 'g:hip:trs:vVw' --long 'grape:,help,id,port:,tls,raw,salt:,value,version,write' -n "${ME##*/}" -- "$@") || exit 1 TLS='' +SALT='' PORT=30002 -EXIT_CODE=1 HOSTNAME='127.0.0.1' QUERY='select(.v) | .v' @@ -31,23 +31,28 @@ QUERY='select(.v) | .v' # Show program's help. function show_help { @CAT@ <<_EOF -Usage: - ${ME##*/} [OPTIONS] ... -- send a GET request to the DHT +${ME##*/} sends a GET request to the DHT - Options: +Usage: ${ME##*/} [OPTION]... HASH - -g, --grape Set the Grape hostname - -i. --id Get the id of sending node - -p, --port Set the Grape port number - -t, --tls Enable TLS - -r, --raw Get the raw response message - -v, --value Get the stored value - -w, --write Get the write token +Options: + -g, --grape Set the Grape hostname + -i. --id Get the id of sending node + -p, --port Set the Grape port number + -t, --tls Enable TLS + -r, --raw Get the raw response message + -s, --salt Set salt for this request + -v, --value Get the stored value + -w, --write Get the write token - -h, --help Show this message - -V, --version Show version information + -h, --help Show help message + -V, --version Show version information - The order of the specified options is not relevant. +Examples: + ${ME##*/} foo Read value whose hash is foo from the DHT + ${ME##*/} -s bar foo The same thing, using bar as salt + +Report bugs to <@PACKAGE_BUGREPORT@>. _EOF exit 1 @@ -56,12 +61,14 @@ _EOF # Show program's version. function show_version { @CAT@ <<_EOF -${WHOAMI##*/} (@host_cpu@-@host_os@) @PACKAGE_NAME@/@PACKAGE_VERSION@ -Copyright (C) 2017, 2018 Davide Scola <@PACKAGE_BUGREPORT@> +${WHOAMI##*/} @PACKAGE_VERSION@ + +Copyright (C) 2017-2025 Davide Scola <@PACKAGE_BUGREPORT@> This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +Written by Davide Scola. _EOF exit 1 @@ -108,6 +115,19 @@ while true; do -r | --raw ) QUERY='select(.)'; shift 1 ;; + -s | --salt ) + [[ -z "${2}" ]] && { + echo "${ME##*/}: error: empty salt string." >&2 + exit 1 + } + + [[ "${#2}" -gt 64 ]] && { + echo "${ME##*/}: error: salt is too big." >&2 + exit 1 + } + + SALT="${2}"; shift 2 + ;; -v | --value ) QUERY='select(.v) | .v'; shift 1 ;; @@ -132,70 +152,87 @@ done exit 1 } +HASH="${1}" exec {stderr}>&2 [[ x"${GRENACHE_CLI_DEBUG:+set}" != xset ]] && { exec 2>/dev/null } -for hash in "${@}" -do - [[ "${hash}" =~ ^[a-fA-F0-9]{40}$ ]] || { - echo "${ME##*/}: warning: invalid hash provided: ${hash}." >&"${stderr}" - continue - } +[[ "${HASH}" =~ ^[a-fA-F0-9]{40}$ ]] || { + echo "${ME##*/}: error: invalid hash provided: ${HASH}." >&"${stderr}" - JSON="$(@CURL@ -qK "${HOME}/.grenache-cli/grenache-cli.conf" -A '@PACKAGE@/@PACKAGE_VERSION@' "http${TLS:+s}://${HOSTNAME}:${PORT}/get" < <( \ - @JQ@ -cnM \ - --arg 'data' "${hash}" \ - --arg 'rid' "$(@UUIDGEN@)" \ - '{ "data": $data, "rid": $rid }' \ - ))" + exec {stderr}>&- + exit 1 +} - [[ -z "${JSON}" ]] && { - echo "${ME##*/}: warning: hash ${hash} not found." >&"${stderr}" - continue - } +JSON="$(@CURL@ -qK "${HOME}/.grenache-cli/grenache-cli.conf" -A '@PACKAGE@/@PACKAGE_VERSION@' "http${TLS:+s}://${HOSTNAME}:${PORT}/get" < <( \ + @JQ@ -cnM \ + --arg 'hash' "${HASH}" \ + --arg 'salt' "${SALT:-}" \ + --arg 'rid' "$(@UUIDGEN@)" \ + '{ "data": { "hash": $hash, "salt": $salt }, "rid": $rid }' +))" + +[[ -z "${JSON}" ]] && { + echo "${ME##*/}: error: hash ${HASH} not found." >&"${stderr}" + + exec {stderr}>&- + exit 1 +} - @JQ@ -e 'has("k")' >/dev/null <<<"${JSON}" && { - CHALLENGE='' +@JQ@ -e 'has("k")' >/dev/null <<<"${JSON}" && { + CHALLENGE='' + [[ -z "${SALT}" ]] || { @JQ@ -e 'has("salt")' >/dev/null <<<"${JSON}" && { - CHALLENGE+="$(@JQ@ -j '"4:salt\(.salt | length):\(.salt)"' <<<"${JSON}")" - } + GRENACHE_SALT="$(@JQ@ -r '.salt' <<<"${JSON}")" - CHALLENGE+="$(@JQ@ -j '"3:seqi" + "\(.seq)" + "e1:v" + "\(.v | length):\(.v)"' <<<"${JSON}")" - - ${WHOAMI%/*}/grc-verify "${CHALLENGE}" \ - @PKEY_FILENO@< <( \ - @JQ@ -r 'select(.k) | .k' <<<"${JSON}" - ) \ - @SIGN_FILENO@< <( \ - @JQ@ -r 'select(.sig) | .sig' <<<"${JSON}" - ) >/dev/null || { - echo "${ME##*/}: warning: cannot verify challenge buffer." >&"${stderr}" - continue + [[ "${GRENACHE_SALT}" = "${SALT}" ]] || { + echo "${ME##*/}: error: salt mismatch." >&"${stderr}" + + exec {stderr}>&- + exit 1 + } } - CHECK="$(@SHA1SUM@ < <( \ - printf '%s' \ - "$(@XXD@ -r -p < <( @JQ@ -r 'select(.k) | .k' <<<"${JSON}" ))" \ - "$(@JQ@ -r 'select(.salt) | .salt' <<<"${JSON}")" - ))" - } || { - CHECK="$(@SHA1SUM@ < <( \ - @JQ@ -j 'select(.v) | "\(.v | length):\(.v)"' <<<"${JSON}" - ))" + CHALLENGE+="4:salt${#SALT}:${SALT}" } - [[ "x${hash}" = "x${CHECK%% *}" ]] || { - echo "${ME##*/}: warning: unexpected value." >&"${stderr}" - continue + CHALLENGE+="$(@JQ@ -j '"3:seqi" + "\(.seq)" + "e1:v" + "\(.v | length):\(.v)"' <<<"${JSON}")" + + ${WHOAMI%/*}/grc-verify "${CHALLENGE}" \ + @PKEY_FILENO@< <( \ + @JQ@ -r 'select(.k) | .k' <<<"${JSON}" + ) \ + @SIGN_FILENO@< <( \ + @JQ@ -r 'select(.sig) | .sig' <<<"${JSON}" + ) >/dev/null || { + echo "${ME##*/}: error: cannot verify challenge buffer." >&"${stderr}" + + exec {stderr}>&- + exit 1 } - @JQ@ -r "${QUERY}" <<<"${JSON}" \ - && EXIT_CODE=0 -done + CHECK="$(@SHA1SUM@ < <( \ + printf '%s' \ + "$(@XXD@ -r -p < <( @JQ@ -r 'select(.k) | .k' <<<"${JSON}" ))" \ + "${SALT:-}" + ))" +} || { + CHECK="$(@SHA1SUM@ < <( \ + @JQ@ -j 'select(.v) | "\(.v | length):\(.v)"' <<<"${JSON}" + ))" +} + +[[ "x${HASH}" = "x${CHECK%% *}" ]] || { + echo "${ME##*/}: error: unexpected value." >&"${stderr}" + + exec {stderr}>&- + exit 1 +} + +@JQ@ -cMr "${QUERY}" <<<"${JSON}" exec {stderr}>&- -exit "${EXIT_CODE}" +exit 0 diff --git a/src/grenache-keygen.in b/src/grenache-keygen.in index 6761827..2b56251 100644 --- a/src/grenache-keygen.in +++ b/src/grenache-keygen.in @@ -2,7 +2,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # @@ -27,17 +27,21 @@ OVERWRITE='no' # Show program's help. function show_help { @CAT@ <<_EOF -Usage: - ${ME##*/} [OPTIONS] -- creates your grenache-cli keypair. +${ME##*/} generates and manages authentication keys - Options: +Usage: ${ME##*/} [OPTION]... - -f, --force Overwrite existing keypair +Options: + -f, --force Overwrite existing keypair - -h, --help Show this message - -V, --version Show version information + -h, --help Show help message + -V, --version Show version information - The order of the specified options is not relevant. +Examples: + ${ME##*/} Create a new keypair + ${ME##*/} -f The same thing, but overwrites the existing one + +Report bugs to <@PACKAGE_BUGREPORT@>. _EOF exit 1 @@ -46,12 +50,14 @@ _EOF # Show program's version. function show_version { @CAT@ <<_EOF -${WHOAMI##*/} (@host_cpu@-@host_os@) @PACKAGE_NAME@/@PACKAGE_VERSION@ -Copyright (C) 2017, 2018 Davide Scola <@PACKAGE_BUGREPORT@> +${WHOAMI##*/} @PACKAGE_VERSION@ + +Copyright (C) 2017-2025 Davide Scola <@PACKAGE_BUGREPORT@> This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +Written by Davide Scola. _EOF exit 1 diff --git a/src/grenache-lookup.in b/src/grenache-lookup.in index f82e5cc..48f6eb2 100644 --- a/src/grenache-lookup.in +++ b/src/grenache-lookup.in @@ -2,7 +2,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # @@ -36,23 +36,27 @@ readonly LOOKUP_RANDOM=8 # Show program's help. function show_help { @CAT@ <<_EOF -Usage: - ${ME##*/} [OPTIONS] ... -- lookup a service in the DHT. +${ME##*/} looks for a service in the DHT - Options: +Usage: ${ME##*/} [OPTION]... SERVICE... - -a, --all Pick all peers in list - -f, --first Pick the first peer in list - -g, --grape Set the Grape hostname - -l, --last Pick the last peer in list - -p, --port Set the Grape port number - -r, --random Pick a random peer in list - -t, --tls Enable TLS +Options: + -a, --all Pick all peers in list + -f, --first Pick the first peer in list + -g, --grape Set the Grape hostname + -l, --last Pick the last peer in list + -p, --port Set the Grape port number + -r, --random Pick a random peer in list + -t, --tls Enable TLS - -h, --help Show this message - -V, --version Show version information + -h, --help Show help message + -V, --version Show version information - The order of the specified options is not relevant. +Examples: + ${ME##*/} 'foo' Pick a random peer that provides the foo service + ${ME##*/} -a 'foo' The same thing, but retreive all peers + +Report bugs to <@PACKAGE_BUGREPORT@>. _EOF exit 1 @@ -61,12 +65,14 @@ _EOF # Show program's version. function show_version { @CAT@ <<_EOF -${WHOAMI##*/} (@host_cpu@-@host_os@) @PACKAGE_NAME@/@PACKAGE_VERSION@ -Copyright (C) 2017, 2018 Davide Scola <@PACKAGE_BUGREPORT@> +${WHOAMI##*/} @PACKAGE_VERSION@ + +Copyright (C) 2017-2025 Davide Scola <@PACKAGE_BUGREPORT@> This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +Written by Davide Scola. _EOF exit 1 diff --git a/src/grenache-put.in b/src/grenache-put.in index e11bf5b..bdbbdcd 100644 --- a/src/grenache-put.in +++ b/src/grenache-put.in @@ -2,7 +2,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # @@ -33,23 +33,27 @@ SEQUENCE="$(@DATE@ '+%s%6N')" # Show program's help. function show_help { @CAT@ <<_EOF -Usage: - ${ME##*/} [OPTIONS] ... -- send a PUT request to the DHT +${ME##*/} sends a PUT request to the DHT - Options: +Usage: ${ME##*/} [OPTION]... VALUE - -c, --cas Set the compare and swap number - -g, --grape Set the Grape hostname - -m, --mutable Send a mutable PUT request - -n, --number Set the sequence number of this PUT request - -p, --port Set the Grape port number - -s, --salt Set salt for this request - -t, --tls Enable TLS +Options: + -c, --cas Set the compare and swap number + -g, --grape Set the Grape hostname + -m, --mutable Send a mutable PUT request + -n, --number Set the sequence number of this PUT request + -p, --port Set the Grape port number + -s, --salt Set salt for this request + -t, --tls Enable TLS - -h, --help Show this message - -V, --version Show version information + -h, --help Show help message + -V, --version Show version information - The order of the specified options is not relevant. +Examples: + ${ME##*/} 'foo' Store the value foo to the DHT + ${ME##*/} -m 'foo' The same thing, but as mutable value + +Report bugs to <@PACKAGE_BUGREPORT@>. _EOF exit 1 @@ -58,12 +62,14 @@ _EOF # Show program's version. function show_version { @CAT@ <<_EOF -${WHOAMI##*/} (@host_cpu@-@host_os@) @PACKAGE_NAME@/@PACKAGE_VERSION@ -Copyright (C) 2017, 2018 Davide Scola <@PACKAGE_BUGREPORT@> +${WHOAMI##*/} @PACKAGE_VERSION@ + +Copyright (C) 2017-2025 Davide Scola <@PACKAGE_BUGREPORT@> This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +Written by Davide Scola. _EOF exit 1 diff --git a/src/grenache-request.in b/src/grenache-request.in new file mode 100644 index 0000000..b339c72 --- /dev/null +++ b/src/grenache-request.in @@ -0,0 +1,230 @@ +#!/bin/bash +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017-2025 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +readonly ME="${BASH_SOURCE[0]}" +readonly WHOAMI="$(@READLINK@ -snf "${ME}")" +readonly ARGV=$(@GETOPT@ -o 'a:cg:hn:p:q:rs:StVw:' --long 'arg:,color,grape:,help,numeric:,port:,query:,raw,string:,stream,tls,version,worker:' -n "${ME##*/}" -- "$@") || exit 1 + +TLS='' +COLOR='' +EXIT_CODE=1 +REQUEST_ARGC=0 +RESPONSE_ARGV=() +REQUEST_WORKER='' +REQUEST_QUERY='.' +RESPONSE_QUERY='.' +CURL_EXTRA_OPTS=() +REQUEST_ARGUMENTS='[]' +LOOKUP_ARGV=(--random) +REQUEST_ARGV=(--compact-output --monochrome-output) + + +# Show program's help. +function show_help { + @CAT@ <<_EOF +${ME##*/} sends a request to a service in the DHT + +Usage: ${ME##*/} [OPTION]... SERVICE ACTION + +Options: + -a, --arg Add an argument, JSON encoded + -c, --color Pretty print + -g, --grape Set the Grape hostname + -n, --numeric Add a numeric argument + -p, --port Set the Grape port number + -q, --query Filter response against query + -r, --raw Print string output as-is + -s, --string Add a string argument + -S, --stream Enable streaming data transfer + -t, --tls Enable TLS + -w, --worker Don't lookup, use this worker + + -h, --help Show help message + -V, --version Show version information + +The \`--arg', \`--numeric' and \`--string' options can be repeated several times +to add multiple arguments, which will be passed in the same order as they were +supplied on the command line. + +Examples: + ${ME##*/} 'foo' 'bar' Call the bar action of the foo service + ${ME##*/} -n 1 'foo' 'bar' The same thing, but passing a numeric argument + +Report bugs to <@PACKAGE_BUGREPORT@>. +_EOF + + exit 1 +} + +# Show program's version. +function show_version { + @CAT@ <<_EOF +${WHOAMI##*/} @PACKAGE_VERSION@ + +Copyright (C) 2017-2025 Davide Scola <@PACKAGE_BUGREPORT@> +This is free software; see the source for copying conditions. There is +NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. + +Written by Davide Scola. +_EOF + + exit 1 +} + + +while true; do + case "$1" in + -a | --arg ) + REQUEST_ARGV+=(--arg "a$((++REQUEST_ARGC))" "${2}") + REQUEST_QUERY+=' += [ $a'"${REQUEST_ARGC}"' | fromjson ] | .'; shift 2 + ;; + -c | --color ) + COLOR='yes'; shift 1 + ;; + -g | --grape ) + [[ -z "${2}" ]] && { + echo "${ME##*/}: error: empty Grape hostname." >&2 + exit 1 + } + + LOOKUP_ARGV+=(--grape "${2}"); shift 2 + ;; + -h | --help ) + show_help; shift 1 + ;; + -n | --numeric ) + REQUEST_ARGV+=(--arg "n$((++REQUEST_ARGC))" "${2}") + REQUEST_QUERY+=' += [ $n'"${REQUEST_ARGC}"' | tonumber ] | .'; shift 2 + ;; + -p | --port ) + [[ -z "${2}" ]] && { + echo "${ME##*/}: error: empty Grape port." >&2 + exit 1 + } + + LOOKUP_ARGV+=(--port "${2}"); shift 2 + ;; + -q | --query ) + [[ -z "${2}" ]] && { + echo "${ME##*/}: error: empty response query." >&2 + exit 1 + } + + RESPONSE_QUERY="${2}"; shift 2 + ;; + -r | --raw ) + RESPONSE_ARGV+=(--raw-output); shift 1 + ;; + -s | --string ) + REQUEST_ARGV+=(--arg "s$((++REQUEST_ARGC))" "${2}") + REQUEST_QUERY+=' += [ $s'"${REQUEST_ARGC}"' | tostring ] | .'; shift 2 + ;; + -S | --stream ) + CURL_EXTRA_OPTS+=(--http1.1 --header 'Transfer-Encoding: chunked'); shift 1 + ;; + -t | --tls ) + TLS='yes'; LOOKUP_ARGV+=(--tls); shift 1 + ;; + -V | --version ) + show_version; shift 1 + ;; + -w | --worker ) + [[ -z "${2}" ]] && { + echo "${ME##*/}: error: empty worker address." >&2 + exit 1 + } + + [[ "${2##*:}" =~ ^[0-9]+$ ]] || { + echo "${ME##*/}: error: invalid worker port number." >&2 + exit 1 + } + + [[ "$((${2##*:} & 0xFFFF))" -eq 0 ]] && { + echo "${ME##*/}: error: worker port number must be greater than zero." >&2 + exit 1 + } + + [[ "${2##*:}" -ne "$((${2##*:} & 0xFFFF))" ]] && { + echo "${ME##*/}: error: worker port number too big." >&2 + exit 1 + } + + REQUEST_WORKER="${2%:*}:$((${2##*:} & 0xFFFF))"; shift 2 + ;; + -- ) shift; break ;; + * ) break ;; + esac +done + +[[ -z "${COLOR}" ]] && { + RESPONSE_ARGV+=(--compact-output --monochrome-output) +} + +[[ "${#}" -lt 2 ]] && { + show_help +} + +[[ -f "${HOME}/.grenache-cli/grenache-cli.conf" ]] || { + echo "${ME##*/}: error: you need to run \`grenache-keygen' first." >&2 + exit "${EXIT_CODE}" +} + +exec {stderr}>&2 + +[[ x"${GRENACHE_CLI_DEBUG:+set}" != xset ]] && { + exec 2>/dev/null +} + +[[ "${REQUEST_ARGC}" -gt 0 ]] && { + REQUEST_ARGUMENTS="$(@JQ@ "${REQUEST_ARGV[@]}" --from-file <(echo "${REQUEST_QUERY}") <<<"${REQUEST_ARGUMENTS}")" + + [[ "${?}" -ne 0 ]] && { + echo "${ME##*/}: error: provided arguments are invalid." >&"${stderr}" + + exec {stderr}>&- + exit "${EXIT_CODE}" + } +} + +JSON="$(@CURL@ -qK "${HOME}/.grenache-cli/grenache-cli.conf" -A '@PACKAGE@/@PACKAGE_VERSION@' "${CURL_EXTRA_OPTS[@]}" "http${TLS:+s}://${REQUEST_WORKER:-$(grenache-lookup "${LOOKUP_ARGV[@]}" "${1}")}" < <( \ + @JQ@ --null-input --compact-output --monochrome-output \ + --arg 'action' "${2}" \ + --arg 'service' "${1}" \ + --arg 'rid' "$(@UUIDGEN@)" \ + --arg 'args' "${REQUEST_ARGUMENTS}" \ + '[ $rid, $service, { "action": $action, "args": $args | fromjson } ]' \ +))" + +[[ -z "${JSON}" ]] && { + echo "${ME##*/}: error: service ${1} cannot be queried." >&"${stderr}" + + exec {stderr}>&- + exit "${EXIT_CODE}" +} + +@JQ@ --exit-status '.[1]' >/dev/null <<<"${JSON}" && { + @JQ@ --raw-output '.[1]' <<<"${JSON}" >&"${stderr}" +} || { + EXIT_CODE=0 + @JQ@ "${RESPONSE_ARGV[@]}" --from-file <(printf '.[2] | %s' "${RESPONSE_QUERY}") <<<"${JSON}" +} + +exec {stderr}>&- +exit "${EXIT_CODE}" diff --git a/src/io.c b/src/io.c index dc4f759..35b5c86 100644 --- a/src/io.c +++ b/src/io.c @@ -2,7 +2,7 @@ * @file * This file is part of Grenache Command Line Interface. * - * Copyright (C) 2017, 2018 Davide Scola + * Copyright (C) 2017-2025 Davide Scola * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain @@ -32,6 +32,38 @@ #include "io.h" +/** + * Perform an I/O operation. + * + * @param ioop_t op + * The I/O operation. + * @param int fd + * The file descriptor. + * @param char *buffer + * The buffer to operate on. + * @param size_t length + * On how many bytes to operate. + * + * @return int + * The number of bytes it was operated on, -1 otherwise. + */ +static INLINE ALWAYS_INLINE ssize_t ioop(ioop_t op, int fd, char *buffer, size_t length) { + ssize_t size; + size_t nbytes = 0; + + while (nbytes < length) { + if ((size = op(fd, buffer + nbytes, length - nbytes)) < 1) { + /* Return error even when EINTR. */ + return -1; + } + + nbytes += size; + } + + return nbytes; +} + + /** * Read from a file descriptor. * @@ -46,16 +78,10 @@ * 0 if all the bytes have been read, -1 otherwise. */ int ioread(int fd, char *buffer, size_t length) { - size_t size; - size_t nread = 0; - - while (nread < length) { - if ((size = read(fd, buffer + nread, length - nread)) < 1) { - /* Return error even when EINTR. */ - return -1; - } + ssize_t nread; - nread += size; + if ((nread = ioop(read, fd, buffer, length)) == -1) { + return -1; } *(buffer + nread) = '\0'; @@ -76,16 +102,8 @@ int ioread(int fd, char *buffer, size_t length) { * 0 if all bytes have been written, -1 otherwise. */ int iowrite(int fd, char *buffer, size_t length) { - size_t size; - size_t nwrote = 0; - - while (nwrote < length) { - if ((size = write(fd, buffer + nwrote, length - nwrote)) < 1) { - /* Return error even when EINTR. */ - return -1; - } - - nwrote += size; + if (ioop((ioop_t) write, fd, buffer, length) == -1) { + return -1; } (void) fsync(fd); diff --git a/tests/Makefile.am b/tests/Makefile.am index 8a91ede..b228258 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,7 +1,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # diff --git a/tests/sign-test-vector-1.sh.in b/tests/sign-test-vector-1.sh.in index 0f73c93..1cf4c70 100644 --- a/tests/sign-test-vector-1.sh.in +++ b/tests/sign-test-vector-1.sh.in @@ -1,7 +1,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # diff --git a/tests/sign-test-vector-2.sh.in b/tests/sign-test-vector-2.sh.in index e032732..b6fea14 100644 --- a/tests/sign-test-vector-2.sh.in +++ b/tests/sign-test-vector-2.sh.in @@ -1,7 +1,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # diff --git a/tests/verify-test-vector-1.sh.in b/tests/verify-test-vector-1.sh.in index 7bd1dae..231b74a 100644 --- a/tests/verify-test-vector-1.sh.in +++ b/tests/verify-test-vector-1.sh.in @@ -1,7 +1,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # diff --git a/tests/verify-test-vector-2.sh.in b/tests/verify-test-vector-2.sh.in index c981a3d..abd1da1 100644 --- a/tests/verify-test-vector-2.sh.in +++ b/tests/verify-test-vector-2.sh.in @@ -1,7 +1,7 @@ ############################################################################ # This file is part of Grenache Command Line Interface. # # # -# Copyright (C) 2017, 2018 Davide Scola # +# Copyright (C) 2017-2025 Davide Scola # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain #